precommit
This commit is contained in:
parent
f6bcdac258
commit
f48589738f
234 changed files with 58907 additions and 58207 deletions
16
.pre-commit-config.yaml
Normal file
16
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# See https://pre-commit.com for more information
|
||||||
|
# See https://pre-commit.com/hooks.html for more hooks
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.3.0
|
||||||
|
hooks:
|
||||||
|
- id: trailing-whitespace
|
||||||
|
files: ^.*\.cmake|CMakeLists\.txt$
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
files: ^.*\.cmake|CMakeLists\.txt$
|
||||||
|
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: v14.0.6
|
||||||
|
hooks:
|
||||||
|
- id: clang-format
|
||||||
|
types_or: [c++, c]
|
|
@ -5,11 +5,11 @@ cmake_minimum_required(VERSION 3.15)
|
||||||
include(cmake/GetVersion.cmake)
|
include(cmake/GetVersion.cmake)
|
||||||
get_mapnik_version()
|
get_mapnik_version()
|
||||||
|
|
||||||
project(mapnik
|
project(mapnik
|
||||||
VERSION ${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION}.${MAPNIK_PATCH_VERSION}
|
VERSION ${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION}.${MAPNIK_PATCH_VERSION}
|
||||||
HOMEPAGE_URL "https://mapnik.org/"
|
HOMEPAGE_URL "https://mapnik.org/"
|
||||||
DESCRIPTION "Mapnik is an open source toolkit for developing mapping applications"
|
DESCRIPTION "Mapnik is an open source toolkit for developing mapping applications"
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
)
|
)
|
||||||
message(STATUS "mapnik version: ${PROJECT_VERSION}")
|
message(STATUS "mapnik version: ${PROJECT_VERSION}")
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ if(harfbuzz_FOUND)
|
||||||
message(STATUS "Found harfbuzz native cmake")
|
message(STATUS "Found harfbuzz native cmake")
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS harfbuzz::harfbuzz)
|
list(APPEND MAPNIK_OPTIONAL_LIBS harfbuzz::harfbuzz)
|
||||||
else()
|
else()
|
||||||
# Use pkg-config when harfbuzz is not found.
|
# Use pkg-config when harfbuzz is not found.
|
||||||
# It might be possible that in future version harfbuzz could only be found via pkg-config.
|
# It might be possible that in future version harfbuzz could only be found via pkg-config.
|
||||||
# harfbuzz related discussion: https://github.com/harfbuzz/harfbuzz/issues/2653
|
# harfbuzz related discussion: https://github.com/harfbuzz/harfbuzz/issues/2653
|
||||||
message(STATUS "harfbuzz not found via cmake. Searching via pkg-config...")
|
message(STATUS "harfbuzz not found via cmake. Searching via pkg-config...")
|
||||||
|
@ -182,13 +182,13 @@ if(USE_EXTERNAL_MAPBOX_GEOMETRY)
|
||||||
find_path(MAPBOX_GEOMETRY_INCLUDE_DIRS "mapbox/geometry.hpp" REQUIRED)
|
find_path(MAPBOX_GEOMETRY_INCLUDE_DIRS "mapbox/geometry.hpp" REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(MAPBOX_GEOMETRY_INCLUDE_DIRS
|
set(MAPBOX_GEOMETRY_INCLUDE_DIRS
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/geometry/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/geometry/include>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
if(NOT MAPBOX_GEOMETRY_INCLUDE_DIRS)
|
if(NOT MAPBOX_GEOMETRY_INCLUDE_DIRS)
|
||||||
message(FATAL_ERROR "Set -DMAPBOX_GEOMETRY_INCLUDE_DIRS to the mapbox/geometry.hpp include dir")
|
message(FATAL_ERROR "Set -DMAPBOX_GEOMETRY_INCLUDE_DIRS to the mapbox/geometry.hpp include dir")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_EXTERNAL_MAPBOX_POLYLABEL)
|
if(USE_EXTERNAL_MAPBOX_POLYLABEL)
|
||||||
|
@ -197,13 +197,13 @@ if(USE_EXTERNAL_MAPBOX_POLYLABEL)
|
||||||
find_path(MAPBOX_POLYLABEL_INCLUDE_DIRS "mapbox/polylabel.hpp")
|
find_path(MAPBOX_POLYLABEL_INCLUDE_DIRS "mapbox/polylabel.hpp")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(MAPBOX_POLYLABEL_INCLUDE_DIRS
|
set(MAPBOX_POLYLABEL_INCLUDE_DIRS
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/polylabel/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/polylabel/include>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
if(NOT MAPBOX_POLYLABEL_INCLUDE_DIRS)
|
if(NOT MAPBOX_POLYLABEL_INCLUDE_DIRS)
|
||||||
message(FATAL_ERROR "Set MAPBOX_POLYLABEL_INCLUDE_DIRS to the mapbox/geometry include dir")
|
message(FATAL_ERROR "Set MAPBOX_POLYLABEL_INCLUDE_DIRS to the mapbox/geometry include dir")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_EXTERNAL_MAPBOX_PROTOZERO)
|
if(USE_EXTERNAL_MAPBOX_PROTOZERO)
|
||||||
|
@ -212,13 +212,13 @@ if(USE_EXTERNAL_MAPBOX_PROTOZERO)
|
||||||
find_path(MAPBOX_PROTOZERO_INCLUDE_DIRS "protozero/pbf_message.hpp")
|
find_path(MAPBOX_PROTOZERO_INCLUDE_DIRS "protozero/pbf_message.hpp")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(MAPBOX_PROTOZERO_INCLUDE_DIRS
|
set(MAPBOX_PROTOZERO_INCLUDE_DIRS
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/protozero/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/protozero/include>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
if(NOT MAPBOX_PROTOZERO_INCLUDE_DIRS)
|
if(NOT MAPBOX_PROTOZERO_INCLUDE_DIRS)
|
||||||
message(FATAL_ERROR "Set MAPBOX_PROTOZERO_INCLUDE_DIRS to the mapbox/protozero include dir")
|
message(FATAL_ERROR "Set MAPBOX_PROTOZERO_INCLUDE_DIRS to the mapbox/protozero include dir")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_EXTERNAL_MAPBOX_VARIANT)
|
if(USE_EXTERNAL_MAPBOX_VARIANT)
|
||||||
|
@ -227,13 +227,13 @@ if(USE_EXTERNAL_MAPBOX_VARIANT)
|
||||||
find_path(MAPBOX_VARIANT_INCLUDE_DIRS "mapbox/variant.hpp")
|
find_path(MAPBOX_VARIANT_INCLUDE_DIRS "mapbox/variant.hpp")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(MAPBOX_VARIANT_INCLUDE_DIRS
|
set(MAPBOX_VARIANT_INCLUDE_DIRS
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/variant/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/variant/include>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
if(NOT MAPBOX_VARIANT_INCLUDE_DIRS)
|
if(NOT MAPBOX_VARIANT_INCLUDE_DIRS)
|
||||||
message(FATAL_ERROR "Set MAPBOX_VARIANT_INCLUDE_DIRS to the mapbox/variant include dir")
|
message(FATAL_ERROR "Set MAPBOX_VARIANT_INCLUDE_DIRS to the mapbox/variant include dir")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# (used by MapnikInstall.cmake. properties are needed since "set(...)" will be out of scope
|
# (used by MapnikInstall.cmake. properties are needed since "set(...)" will be out of scope
|
||||||
|
@ -245,7 +245,7 @@ if(USE_GLIBC_WORKAROUND)
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_ENABLE_GLIBC_WORKAROUND)
|
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_ENABLE_GLIBC_WORKAROUND)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_BIGINT)
|
if(USE_BIGINT)
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS BIGINT)
|
list(APPEND MAPNIK_COMPILE_DEFS BIGINT)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ if(USE_SVG_RENDERER)
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS SVG_RENDERER)
|
list(APPEND MAPNIK_COMPILE_DEFS SVG_RENDERER)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
message(STATUS "Compiling with -DMAPNIK_HAS_DLCFN")
|
message(STATUS "Compiling with -DMAPNIK_HAS_DLCFN")
|
||||||
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_HAS_DLCFN)
|
list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_HAS_DLCFN)
|
||||||
list(APPEND MAPNIK_OPTIONAL_LIBS ${CMAKE_DL_LIBS})
|
list(APPEND MAPNIK_OPTIONAL_LIBS ${CMAKE_DL_LIBS})
|
||||||
|
@ -365,8 +365,8 @@ add_compile_options(
|
||||||
add_library(core INTERFACE)
|
add_library(core INTERFACE)
|
||||||
add_library(mapnik::core ALIAS core)
|
add_library(mapnik::core ALIAS core)
|
||||||
|
|
||||||
target_include_directories(core INTERFACE
|
target_include_directories(core INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<BUILD_INTERFACE:${MAPBOX_GEOMETRY_INCLUDE_DIRS}>
|
$<BUILD_INTERFACE:${MAPBOX_GEOMETRY_INCLUDE_DIRS}>
|
||||||
$<BUILD_INTERFACE:${MAPBOX_POLYLABEL_INCLUDE_DIRS}>
|
$<BUILD_INTERFACE:${MAPBOX_POLYLABEL_INCLUDE_DIRS}>
|
||||||
$<BUILD_INTERFACE:${MAPBOX_VARIANT_INCLUDE_DIRS}>
|
$<BUILD_INTERFACE:${MAPBOX_VARIANT_INCLUDE_DIRS}>
|
||||||
|
@ -375,7 +375,7 @@ target_include_directories(core INTERFACE
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
${MAPNIK_OPTIONAL_LIBS_INCLUDE}
|
${MAPNIK_OPTIONAL_LIBS_INCLUDE}
|
||||||
)
|
)
|
||||||
target_link_libraries(core INTERFACE
|
target_link_libraries(core INTERFACE
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
ICU::uc
|
ICU::uc
|
||||||
ICU::data
|
ICU::data
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
project(mapnik-benchmark)
|
project(mapnik-benchmark)
|
||||||
|
|
||||||
set(BENCHMARK_SRCS
|
set(BENCHMARK_SRCS
|
||||||
src/normalize_angle.cpp
|
src/normalize_angle.cpp
|
||||||
src/test_array_allocation.cpp
|
src/test_array_allocation.cpp
|
||||||
src/test_expression_parse.cpp
|
src/test_expression_parse.cpp
|
||||||
|
@ -32,7 +32,7 @@ function(mapnik_create_benchmark)
|
||||||
add_executable(${TARGET_NAME} ${ARGV0})
|
add_executable(${TARGET_NAME} ${ARGV0})
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE include)
|
target_include_directories(${TARGET_NAME} PRIVATE include)
|
||||||
target_link_libraries(${TARGET_NAME} PRIVATE mapnik::agg mapnik::mapnik)
|
target_link_libraries(${TARGET_NAME} PRIVATE mapnik::agg mapnik::mapnik)
|
||||||
set_target_properties(${TARGET_NAME} PROPERTIES
|
set_target_properties(${TARGET_NAME} PROPERTIES
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
||||||
ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib"
|
ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib"
|
||||||
|
@ -46,7 +46,7 @@ foreach(benchmark ${BENCHMARK_SRCS})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
file(COPY data DESTINATION "${MAPNIK_OUTPUT_DIR}/benchmark")
|
file(COPY data DESTINATION "${MAPNIK_OUTPUT_DIR}/benchmark")
|
||||||
file(COPY run_benchmarks
|
file(COPY run_benchmarks
|
||||||
DESTINATION "${MAPNIK_OUTPUT_DIR}"
|
DESTINATION "${MAPNIK_OUTPUT_DIR}"
|
||||||
FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE GROUP_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ
|
FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE GROUP_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ Name: @_lib_name@
|
||||||
Description: @_description@
|
Description: @_description@
|
||||||
Version: @MAPNIK_VERSION@
|
Version: @MAPNIK_VERSION@
|
||||||
Libs: -L"${libdir}" -l$<TARGET_FILE_BASE_NAME:@_target@>$<TARGET_PROPERTY:@_target@,$<CONFIG>_POSTFIX>
|
Libs: -L"${libdir}" -l$<TARGET_FILE_BASE_NAME:@_target@>$<TARGET_PROPERTY:@_target@,$<CONFIG>_POSTFIX>
|
||||||
Cflags: -I"${includedir}" ]]
|
Cflags: -I"${includedir}" ]]
|
||||||
_contents @ONLY)
|
_contents @ONLY)
|
||||||
|
|
||||||
file(GENERATE
|
file(GENERATE
|
||||||
|
@ -26,11 +26,11 @@ endfunction()
|
||||||
function(create_pkg_config_file_mapnik _lib_name _description)
|
function(create_pkg_config_file_mapnik _lib_name _description)
|
||||||
get_target_property(m_compile_defs core INTERFACE_COMPILE_DEFINITIONS)
|
get_target_property(m_compile_defs core INTERFACE_COMPILE_DEFINITIONS)
|
||||||
string(JOIN " -D" m_str_compile_defs ${m_compile_defs})
|
string(JOIN " -D" m_str_compile_defs ${m_compile_defs})
|
||||||
if(m_str_compile_defs)
|
if(m_str_compile_defs)
|
||||||
set(m_str_compile_defs "-D${m_str_compile_defs}")
|
set(m_str_compile_defs "-D${m_str_compile_defs}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(m_requires
|
set(m_requires
|
||||||
libmapnikwkt
|
libmapnikwkt
|
||||||
libmapnikjson
|
libmapnikjson
|
||||||
icu-uc
|
icu-uc
|
||||||
|
@ -71,7 +71,7 @@ Description: @_description@
|
||||||
Version: @MAPNIK_VERSION@
|
Version: @MAPNIK_VERSION@
|
||||||
Requires: @m_requires@
|
Requires: @m_requires@
|
||||||
Libs: -L"${libdir}" -l$<TARGET_FILE_BASE_NAME:mapnik>$<TARGET_PROPERTY:mapnik,$<CONFIG>_POSTFIX>
|
Libs: -L"${libdir}" -l$<TARGET_FILE_BASE_NAME:mapnik>$<TARGET_PROPERTY:mapnik,$<CONFIG>_POSTFIX>
|
||||||
Cflags: -I"${includedir}" @m_str_compile_defs@]]
|
Cflags: -I"${includedir}" @m_str_compile_defs@]]
|
||||||
_contents @ONLY)
|
_contents @ONLY)
|
||||||
file(GENERATE
|
file(GENERATE
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_lib_name}-$<CONFIG>.pc
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_lib_name}-$<CONFIG>.pc
|
||||||
|
|
|
@ -90,7 +90,7 @@ function(mapnik_install_targets)
|
||||||
message(STATUS \"internal_executables: ${_internal_executables}\")
|
message(STATUS \"internal_executables: ${_internal_executables}\")
|
||||||
message(STATUS \"internal_libraries: ${_internal_libraries}\")
|
message(STATUS \"internal_libraries: ${_internal_libraries}\")
|
||||||
message(STATUS \"ADDITIONAL_LIBARIES_PATHS: ${ADDITIONAL_LIBARIES_PATHS}\")
|
message(STATUS \"ADDITIONAL_LIBARIES_PATHS: ${ADDITIONAL_LIBARIES_PATHS}\")
|
||||||
|
|
||||||
include(BundleUtilities)
|
include(BundleUtilities)
|
||||||
fixup_bundle(\"${_internal_executables}\" \"${_internal_libraries}\" \"${ADDITIONAL_LIBARIES_PATHS}\")
|
fixup_bundle(\"${_internal_executables}\" \"${_internal_libraries}\" \"${ADDITIONAL_LIBARIES_PATHS}\")
|
||||||
" COMPONENT MapnikRuntime)
|
" COMPONENT MapnikRuntime)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
function(format_dir dir)
|
function(format_dir dir)
|
||||||
file(GLOB_RECURSE sources
|
file(GLOB_RECURSE sources
|
||||||
"${dir}/*.cpp"
|
"${dir}/*.cpp"
|
||||||
"${dir}/*.hpp"
|
"${dir}/*.hpp"
|
||||||
)
|
)
|
||||||
|
|
|
@ -32,14 +32,14 @@ function(mapnik_find_plugin_dir PLUGIN_DIR)
|
||||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_l)
|
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_l)
|
||||||
set(_plugin_dir "${MAPNIK_PLUGINS_DIR_${_build_type_l}}")
|
set(_plugin_dir "${MAPNIK_PLUGINS_DIR_${_build_type_l}}")
|
||||||
# only release has more then one configuration
|
# only release has more then one configuration
|
||||||
if(NOT _plugin_dir)
|
if(NOT _plugin_dir)
|
||||||
set(_all_rel_cfgs RELEASE RELWITHDEBINFO MINSIZEREL)
|
set(_all_rel_cfgs RELEASE RELWITHDEBINFO MINSIZEREL)
|
||||||
list(FIND _all_rel_cfgs ${_build_type_l} _is_rel_cfg)
|
list(FIND _all_rel_cfgs ${_build_type_l} _is_rel_cfg)
|
||||||
# check if the current configuration is a known release configuration
|
# check if the current configuration is a known release configuration
|
||||||
if(${_is_rel_cfg} GREATER_EQUAL 0)
|
if(${_is_rel_cfg} GREATER_EQUAL 0)
|
||||||
foreach(_rel_cfg IN LISTS _all_rel_cfgs)
|
foreach(_rel_cfg IN LISTS _all_rel_cfgs)
|
||||||
set(_plugin_dir "${MAPNIK_PLUGINS_DIR_${_rel_cfg}}")
|
set(_plugin_dir "${MAPNIK_PLUGINS_DIR_${_rel_cfg}}")
|
||||||
if(_plugin_dir)
|
if(_plugin_dir)
|
||||||
break()
|
break()
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
@ -49,4 +49,4 @@ function(mapnik_find_plugin_dir PLUGIN_DIR)
|
||||||
message(WARNING "Could not find a plugin install dir for configuration ${_build_type_l}")
|
message(WARNING "Could not find a plugin install dir for configuration ${_build_type_l}")
|
||||||
endif()
|
endif()
|
||||||
set(${PLUGIN_DIR} ${_plugin_dir} PARENT_SCOPE)
|
set(${PLUGIN_DIR} ${_plugin_dir} PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
add_executable(mapnik-demo rundemo.cpp)
|
add_executable(mapnik-demo rundemo.cpp)
|
||||||
set_target_properties(mapnik-demo PROPERTIES
|
set_target_properties(mapnik-demo PROPERTIES
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
||||||
ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib"
|
ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib"
|
||||||
|
|
|
@ -14,7 +14,7 @@ set(PROJECT_SOURCES
|
||||||
styles_model.cpp
|
styles_model.cpp
|
||||||
forms/about.ui
|
forms/about.ui
|
||||||
forms/info.ui
|
forms/info.ui
|
||||||
forms/layer_info.ui
|
forms/layer_info.ui
|
||||||
mapnik_viewer.qrc
|
mapnik_viewer.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ endif()
|
||||||
|
|
||||||
set_target_properties(mapnik-viewer PROPERTIES
|
set_target_properties(mapnik-viewer PROPERTIES
|
||||||
AUTOUIC_SEARCH_PATHS forms
|
AUTOUIC_SEARCH_PATHS forms
|
||||||
AUTORCC ON
|
AUTORCC ON
|
||||||
AUTOUIC ON
|
AUTOUIC ON
|
||||||
AUTOMOC ON
|
AUTOMOC ON
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}"
|
||||||
|
@ -46,13 +46,13 @@ set_target_properties(mapnik-viewer PROPERTIES
|
||||||
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>$<$<BOOL:${BUILD_SHARED_CRT}>:DLL>"
|
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>$<$<BOOL:${BUILD_SHARED_CRT}>:DLL>"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(mapnik-viewer PRIVATE
|
target_link_libraries(mapnik-viewer PRIVATE
|
||||||
Qt${QT_VERSION_MAJOR}::Widgets
|
Qt${QT_VERSION_MAJOR}::Widgets
|
||||||
mapnik::agg
|
mapnik::agg
|
||||||
mapnik::mapnik
|
mapnik::mapnik
|
||||||
)
|
)
|
||||||
|
|
||||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/viewer.ini
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/viewer.ini
|
||||||
"[mapnik]
|
"[mapnik]
|
||||||
plugins_dir=${PLUGINS_INSTALL_DIR}
|
plugins_dir=${PLUGINS_INSTALL_DIR}
|
||||||
fonts/1/dir=${FONTS_INSTALL_DIR}"
|
fonts/1/dir=${FONTS_INSTALL_DIR}"
|
||||||
|
|
4
deps/agg/CMakeLists.txt
vendored
4
deps/agg/CMakeLists.txt
vendored
|
@ -3,8 +3,8 @@ project(agg)
|
||||||
add_library(agg INTERFACE)
|
add_library(agg INTERFACE)
|
||||||
add_library(mapnik::agg ALIAS agg)
|
add_library(mapnik::agg ALIAS agg)
|
||||||
|
|
||||||
target_include_directories(agg INTERFACE
|
target_include_directories(agg INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
target_link_libraries(agg INTERFACE mapnik::core)
|
target_link_libraries(agg INTERFACE mapnik::core)
|
||||||
|
|
786
deps/agg/include/agg_alpha_mask_u8.h
vendored
786
deps/agg/include/agg_alpha_mask_u8.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,477 +23,427 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_rendering_buffer.h"
|
#include "agg_rendering_buffer.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//===================================================one_component_mask_u8
|
||||||
|
struct one_component_mask_u8
|
||||||
{
|
{
|
||||||
//===================================================one_component_mask_u8
|
static unsigned calculate(const int8u* p) { return *p; }
|
||||||
struct one_component_mask_u8
|
};
|
||||||
|
|
||||||
|
//=====================================================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
|
||||||
{
|
{
|
||||||
static unsigned calculate(const int8u* p) { return *p; }
|
if (x >= 0 && y >= 0 && x < (int)m_rbuf->width() && y < (int)m_rbuf->height())
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//=====================================================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 &&
|
return (cover_type)m_mask_function.calculate(m_rbuf->row_ptr(y) + x * Step + Offset);
|
||||||
x < (int)m_rbuf->width() &&
|
}
|
||||||
y < (int)m_rbuf->height())
|
return 0;
|
||||||
{
|
}
|
||||||
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 0;
|
{
|
||||||
|
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)
|
||||||
cover_type combine_pixel(int x, int y, cover_type val) const
|
|
||||||
{
|
{
|
||||||
if(x >= 0 && y >= 0 &&
|
count += x;
|
||||||
x < (int)m_rbuf->width() &&
|
if (count <= 0)
|
||||||
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));
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
memset(covers, 0, -x * sizeof(cover_type));
|
||||||
if(x < 0)
|
covers -= x;
|
||||||
{
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x + count > xmax)
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
|
||||||
{
|
{
|
||||||
int xmax = m_rbuf->width() - 1;
|
int rest = x + count - xmax - 1;
|
||||||
int ymax = m_rbuf->height() - 1;
|
count -= rest;
|
||||||
|
if (count <= 0)
|
||||||
int count = num_pix;
|
|
||||||
cover_type* covers = dst;
|
|
||||||
|
|
||||||
if(y < 0 || y > ymax)
|
|
||||||
{
|
{
|
||||||
memset(dst, 0, num_pix * sizeof(cover_type));
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||||
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
|
do
|
||||||
{
|
{
|
||||||
int xmax = m_rbuf->width() - 1;
|
*covers++ = (cover_type)m_mask_function.calculate(mask);
|
||||||
int ymax = m_rbuf->height() - 1;
|
mask += Step;
|
||||||
|
} while (--count);
|
||||||
|
}
|
||||||
|
|
||||||
int count = num_pix;
|
//--------------------------------------------------------------------
|
||||||
cover_type* covers = dst;
|
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
|
||||||
|
|
||||||
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:
|
int xmax = m_rbuf->width() - 1;
|
||||||
typedef int8u cover_type;
|
int ymax = m_rbuf->height() - 1;
|
||||||
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) {}
|
int count = num_pix;
|
||||||
explicit amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
|
cover_type* covers = dst;
|
||||||
|
|
||||||
void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
|
if (y < 0 || y > ymax)
|
||||||
|
|
||||||
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(
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
m_rbuf->row_ptr(y) + x * Step + Offset);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x < 0)
|
||||||
//--------------------------------------------------------------------
|
|
||||||
cover_type combine_pixel(int x, int y, cover_type val) const
|
|
||||||
{
|
{
|
||||||
return (cover_type)((cover_full + val *
|
count += x;
|
||||||
m_mask_function.calculate(
|
if (count <= 0)
|
||||||
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);
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
mask += Step;
|
return;
|
||||||
}
|
}
|
||||||
while(--num_pix);
|
memset(covers, 0, -x * sizeof(cover_type));
|
||||||
|
covers -= x;
|
||||||
|
x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x + count > xmax)
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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;
|
int rest = x + count - xmax - 1;
|
||||||
do
|
count -= rest;
|
||||||
|
if (count <= 0)
|
||||||
{
|
{
|
||||||
*dst = (cover_type)((cover_full + (*dst) *
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
m_mask_function.calculate(mask)) >>
|
return;
|
||||||
cover_shift);
|
|
||||||
++dst;
|
|
||||||
mask += Step;
|
|
||||||
}
|
}
|
||||||
while(--num_pix);
|
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||||
//--------------------------------------------------------------------
|
do
|
||||||
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;
|
*covers = (cover_type)((cover_full + (*covers) * m_mask_function.calculate(mask)) >> cover_shift);
|
||||||
do
|
++covers;
|
||||||
{
|
mask += Step;
|
||||||
*dst++ = (cover_type)m_mask_function.calculate(mask);
|
} while (--count);
|
||||||
mask += m_rbuf->stride();
|
}
|
||||||
}
|
|
||||||
while(--num_pix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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;
|
||||||
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
|
cover_type* covers = dst;
|
||||||
|
|
||||||
|
if (x < 0 || x > xmax)
|
||||||
{
|
{
|
||||||
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
do
|
return;
|
||||||
{
|
|
||||||
*dst = (cover_type)((cover_full + (*dst) *
|
|
||||||
m_mask_function.calculate(mask)) >>
|
|
||||||
cover_shift);
|
|
||||||
++dst;
|
|
||||||
mask += m_rbuf->stride();
|
|
||||||
}
|
|
||||||
while(--num_pix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
if (y < 0)
|
||||||
amask_no_clip_u8(const self_type&);
|
{
|
||||||
const self_type& operator = (const self_type&);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
rendering_buffer* m_rbuf;
|
if (y + count > ymax)
|
||||||
MaskF m_mask_function;
|
{
|
||||||
};
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
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
|
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
|
||||||
typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b
|
{
|
||||||
|
int xmax = m_rbuf->width() - 1;
|
||||||
|
int ymax = m_rbuf->height() - 1;
|
||||||
|
|
||||||
typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r
|
int count = num_pix;
|
||||||
typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g
|
cover_type* covers = dst;
|
||||||
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
|
if (x < 0 || x > xmax)
|
||||||
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
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r
|
if (y < 0)
|
||||||
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
|
count += y;
|
||||||
typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a
|
if (count <= 0)
|
||||||
|
{
|
||||||
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(covers, 0, -y * sizeof(cover_type));
|
||||||
|
covers -= y;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r
|
if (y + count > ymax)
|
||||||
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
|
int rest = y + count - ymax - 1;
|
||||||
typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a
|
count -= rest;
|
||||||
|
if (count <= 0)
|
||||||
|
{
|
||||||
|
memset(dst, 0, num_pix * sizeof(cover_type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(covers + count, 0, rest * sizeof(cover_type));
|
||||||
|
}
|
||||||
|
|
||||||
typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r
|
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
|
||||||
typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g
|
do
|
||||||
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
|
*covers = (cover_type)((cover_full + (*covers) * m_mask_function.calculate(mask)) >> cover_shift);
|
||||||
|
++covers;
|
||||||
|
mask += m_rbuf->stride();
|
||||||
|
} while (--count);
|
||||||
|
}
|
||||||
|
|
||||||
typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray
|
private:
|
||||||
typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray
|
alpha_mask_u8(const self_type&);
|
||||||
typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray
|
const self_type& operator=(const self_type&);
|
||||||
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
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
78
deps/agg/include/agg_arc.h
vendored
78
deps/agg/include/agg_arc.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,52 +23,46 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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);
|
||||||
|
|
||||||
//=====================================================================arc
|
void init(double x, double y, double rx, double ry, double a1, double a2, bool ccw = true);
|
||||||
//
|
|
||||||
// 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,
|
void approximation_scale(double s);
|
||||||
double rx, double ry,
|
double approximation_scale() const { return m_scale; }
|
||||||
double a1, double a2,
|
|
||||||
bool ccw=true);
|
|
||||||
|
|
||||||
void approximation_scale(double s);
|
void rewind(unsigned);
|
||||||
double approximation_scale() const { return m_scale; }
|
unsigned vertex(double* x, double* y);
|
||||||
|
|
||||||
void rewind(unsigned);
|
private:
|
||||||
unsigned vertex(double* x, double* y);
|
void normalize(double a1, double a2, bool ccw);
|
||||||
|
|
||||||
private:
|
double m_x;
|
||||||
void normalize(double a1, double a2, bool ccw);
|
double m_y;
|
||||||
|
double m_rx;
|
||||||
double m_x;
|
double m_ry;
|
||||||
double m_y;
|
double m_angle;
|
||||||
double m_rx;
|
double m_start;
|
||||||
double m_ry;
|
double m_end;
|
||||||
double m_angle;
|
double m_scale;
|
||||||
double m_start;
|
double m_da;
|
||||||
double m_end;
|
bool m_ccw;
|
||||||
double m_scale;
|
bool m_initialized;
|
||||||
double m_da;
|
unsigned m_path_cmd;
|
||||||
bool m_ccw;
|
};
|
||||||
bool m_initialized;
|
|
||||||
unsigned m_path_cmd;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1993
deps/agg/include/agg_array.h
vendored
1993
deps/agg/include/agg_array.h
vendored
File diff suppressed because it is too large
Load diff
101
deps/agg/include/agg_arrowhead.h
vendored
101
deps/agg/include/agg_arrowhead.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
// http://www.antigrain.com
|
// http://www.antigrain.com
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Simple arrowhead/arrowtail generator
|
// Simple arrowhead/arrowtail generator
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
#ifndef AGG_ARROWHEAD_INCLUDED
|
#ifndef AGG_ARROWHEAD_INCLUDED
|
||||||
|
@ -21,62 +21,61 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//===============================================================arrowhead
|
||||||
|
//
|
||||||
|
// See implementation agg_arrowhead.cpp
|
||||||
|
//
|
||||||
|
class arrowhead
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
arrowhead();
|
||||||
|
|
||||||
//===============================================================arrowhead
|
void head(double d1, double d2, double d3, double d4)
|
||||||
//
|
|
||||||
// See implementation agg_arrowhead.cpp
|
|
||||||
//
|
|
||||||
class arrowhead
|
|
||||||
{
|
{
|
||||||
public:
|
m_head_d1 = d1;
|
||||||
arrowhead();
|
m_head_d2 = d2;
|
||||||
|
m_head_d3 = d3;
|
||||||
|
m_head_d4 = d4;
|
||||||
|
m_head_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
void head(double d1, double d2, double d3, double d4)
|
void head() { m_head_flag = true; }
|
||||||
{
|
void no_head() { m_head_flag = false; }
|
||||||
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 tail(double d1, double d2, double d3, double d4)
|
||||||
void no_head() { m_head_flag = false; }
|
{
|
||||||
|
m_tail_d1 = d1;
|
||||||
|
m_tail_d2 = d2;
|
||||||
|
m_tail_d3 = d3;
|
||||||
|
m_tail_d4 = d4;
|
||||||
|
m_tail_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
void tail(double d1, double d2, double d3, double d4)
|
void tail() { m_tail_flag = true; }
|
||||||
{
|
void no_tail() { m_tail_flag = false; }
|
||||||
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 rewind(unsigned path_id);
|
||||||
void no_tail() { m_tail_flag = false; }
|
unsigned vertex(double* x, double* y);
|
||||||
|
|
||||||
void rewind(unsigned path_id);
|
private:
|
||||||
unsigned vertex(double* x, double* y);
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
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
|
#endif
|
||||||
|
|
827
deps/agg/include/agg_basics.h
vendored
827
deps/agg/include/agg_basics.h
vendored
|
@ -23,41 +23,41 @@
|
||||||
#ifdef AGG_CUSTOM_ALLOCATOR
|
#ifdef AGG_CUSTOM_ALLOCATOR
|
||||||
#include "agg_allocator.h"
|
#include "agg_allocator.h"
|
||||||
#else
|
#else
|
||||||
namespace agg
|
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
|
||||||
{
|
{
|
||||||
// The policy of all AGG containers and memory allocation strategy
|
// static T* allocate(unsigned num) { return static_cast<T*>(::operator new(sizeof(T)*num));}
|
||||||
// in general is that no allocated data requires explicit construction.
|
// static void deallocate(T* ptr, unsigned) { ::operator delete(ptr) ;}
|
||||||
// It means that the allocator can be really simple; you can even
|
static T* allocate(unsigned num) { return new T[num]; }
|
||||||
// replace new/delete to malloc/free. The constructors and destructors
|
static void deallocate(T* ptr, unsigned) { delete[] ptr; }
|
||||||
// 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 static_cast<T*>(::operator new(sizeof(T)*num));}
|
|
||||||
//static void deallocate(T* ptr, unsigned) { ::operator delete(ptr) ;}
|
|
||||||
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
|
// Single object allocator. It's also can be replaced with your custom
|
||||||
// allocator. The difference is that it can only allocate a single
|
// allocator. The difference is that it can only allocate a single
|
||||||
// object and the constructor and destructor must be called.
|
// object and the constructor and destructor must be called.
|
||||||
// In AGG there is no need to allocate an array of objects with
|
// In AGG there is no need to allocate an array of objects with
|
||||||
// calling their constructors (only single ones). So that, if you
|
// calling their constructors (only single ones). So that, if you
|
||||||
// replace these new/delete to malloc/free make sure that the in-place
|
// replace these new/delete to malloc/free make sure that the in-place
|
||||||
// new is called and take care of calling the destructor too.
|
// new is called and take care of calling the destructor too.
|
||||||
//------------------------------------------------------------obj_allocator
|
//------------------------------------------------------------obj_allocator
|
||||||
template<class T> struct obj_allocator
|
template<class T>
|
||||||
{
|
struct obj_allocator
|
||||||
static T* allocate() { return new T; }
|
{
|
||||||
static void deallocate(T* ptr) { delete ptr; }
|
static T* allocate() { return new T; }
|
||||||
};
|
static void deallocate(T* ptr) { delete ptr; }
|
||||||
}
|
};
|
||||||
|
} // namespace agg
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------- Default basic types
|
//-------------------------------------------------------- Default basic types
|
||||||
//
|
//
|
||||||
// If the compiler has different capacity of the basic types you can redefine
|
// If the compiler has different capacity of the basic types you can redefine
|
||||||
|
@ -98,7 +98,7 @@ namespace agg
|
||||||
|
|
||||||
//------------------------------------------------ Some fixes for MS Visual C++
|
//------------------------------------------------ Some fixes for MS Visual C++
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable:4786) // Identifier was truncated...
|
#pragma warning(disable: 4786) // Identifier was truncated...
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
@ -107,372 +107,407 @@ namespace agg
|
||||||
#define AGG_INLINE inline
|
#define AGG_INLINE inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace agg
|
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
|
||||||
|
|
||||||
|
AGG_INLINE int iround(double v)
|
||||||
{
|
{
|
||||||
//-------------------------------------------------------------------------
|
return int((v < 0.0) ? v - 0.5 : v + 0.5);
|
||||||
typedef AGG_INT8 int8; //----int8
|
}
|
||||||
typedef AGG_INT8U int8u; //----int8u
|
AGG_INLINE int uround(double v)
|
||||||
typedef AGG_INT16 int16; //----int16
|
{
|
||||||
typedef AGG_INT16U int16u; //----int16u
|
return unsigned(v + 0.5);
|
||||||
typedef AGG_INT32 int32; //----int32
|
}
|
||||||
typedef AGG_INT32U int32u; //----int32u
|
AGG_INLINE unsigned ufloor(double v)
|
||||||
typedef AGG_INT64 int64; //----int64
|
{
|
||||||
typedef AGG_INT64U int64u; //----int64u
|
return unsigned(v);
|
||||||
|
}
|
||||||
AGG_INLINE int iround(double v)
|
AGG_INLINE unsigned uceil(double v)
|
||||||
{
|
{
|
||||||
return int((v < 0.0) ? v - 0.5 : v + 0.5);
|
return unsigned(std::ceil(v));
|
||||||
}
|
|
||||||
AGG_INLINE int uround(double v)
|
|
||||||
{
|
|
||||||
return unsigned(v + 0.5);
|
|
||||||
}
|
|
||||||
AGG_INLINE unsigned ufloor(double v)
|
|
||||||
{
|
|
||||||
return unsigned(v);
|
|
||||||
}
|
|
||||||
AGG_INLINE unsigned uceil(double v)
|
|
||||||
{
|
|
||||||
return unsigned(std::ceil(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------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 std::fabs(v1 - v2) <= double(epsilon);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------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); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------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 std::fabs(v1 - v2) <= double(epsilon);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
226
deps/agg/include/agg_bezier_arc.h
vendored
226
deps/agg/include/agg_bezier_arc.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
// http://www.antigrain.com
|
// http://www.antigrain.com
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
|
// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
|
||||||
// 4, 7, 10, or 13 vertices.
|
// 4, 7, 10, or 13 vertices.
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -23,137 +23,127 @@
|
||||||
|
|
||||||
#include "agg_conv_transform.h"
|
#include "agg_conv_transform.h"
|
||||||
|
|
||||||
namespace agg
|
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:
|
||||||
//-----------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void arc_to_bezier(double cx, double cy, double rx, double ry,
|
bezier_arc()
|
||||||
double start_angle, double sweep_angle,
|
: m_vertex(26)
|
||||||
double* curve);
|
, m_num_vertices(0)
|
||||||
|
, m_cmd(path_cmd_line_to)
|
||||||
|
{}
|
||||||
//==============================================================bezier_arc
|
bezier_arc(double x, double y, double rx, double ry, double start_angle, double sweep_angle)
|
||||||
//
|
|
||||||
// See implemantaion agg_bezier_arc.cpp
|
|
||||||
//
|
|
||||||
class bezier_arc
|
|
||||||
{
|
{
|
||||||
public:
|
init(x, y, rx, ry, start_angle, sweep_angle);
|
||||||
//--------------------------------------------------------------------
|
}
|
||||||
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,
|
void init(double x, double y, double rx, double ry, double start_angle, double sweep_angle);
|
||||||
double rx, double ry,
|
|
||||||
double start_angle,
|
|
||||||
double sweep_angle);
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void rewind(unsigned)
|
void rewind(unsigned) { m_vertex = 0; }
|
||||||
{
|
|
||||||
m_vertex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
unsigned vertex(double* x, double* y)
|
unsigned vertex(double* x, double* y)
|
||||||
{
|
|
||||||
if(m_vertex >= m_num_vertices) return path_cmd_stop;
|
|
||||||
*x = m_vertices[m_vertex];
|
|
||||||
*y = m_vertices[m_vertex + 1];
|
|
||||||
m_vertex += 2;
|
|
||||||
return (m_vertex == 2) ? (unsigned)path_cmd_move_to : m_cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Supplemantary functions. num_vertices() actually returns doubled
|
|
||||||
// number of vertices. That is, for 1 vertex it returns 2.
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
unsigned num_vertices() const { return m_num_vertices; }
|
|
||||||
const double* vertices() const { return m_vertices; }
|
|
||||||
double* vertices() { return m_vertices; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned m_vertex;
|
|
||||||
unsigned m_num_vertices;
|
|
||||||
double m_vertices[26];
|
|
||||||
unsigned m_cmd;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================bezier_arc_svg
|
|
||||||
// Compute an SVG-style bezier arc.
|
|
||||||
//
|
|
||||||
// Computes an elliptical arc from (x1, y1) to (x2, y2). The size and
|
|
||||||
// orientation of the ellipse are defined by two radii (rx, ry)
|
|
||||||
// and an x-axis-rotation, which indicates how the ellipse as a whole
|
|
||||||
// is rotated relative to the current coordinate system. The center
|
|
||||||
// (cx, cy) of the ellipse is calculated automatically to satisfy the
|
|
||||||
// constraints imposed by the other parameters.
|
|
||||||
// large-arc-flag and sweep-flag contribute to the automatic calculations
|
|
||||||
// and help determine how the arc is drawn.
|
|
||||||
class bezier_arc_svg
|
|
||||||
{
|
{
|
||||||
public:
|
if (m_vertex >= m_num_vertices)
|
||||||
//--------------------------------------------------------------------
|
return path_cmd_stop;
|
||||||
bezier_arc_svg() : m_arc(), m_radii_ok(false) {}
|
*x = m_vertices[m_vertex];
|
||||||
|
*y = m_vertices[m_vertex + 1];
|
||||||
|
m_vertex += 2;
|
||||||
|
return (m_vertex == 2) ? (unsigned)path_cmd_move_to : m_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
bezier_arc_svg(double x1, double y1,
|
// Supplemantary functions. num_vertices() actually returns doubled
|
||||||
double rx, double ry,
|
// number of vertices. That is, for 1 vertex it returns 2.
|
||||||
double angle,
|
//--------------------------------------------------------------------
|
||||||
bool large_arc_flag,
|
unsigned num_vertices() const { return m_num_vertices; }
|
||||||
bool sweep_flag,
|
const double* vertices() const { return m_vertices; }
|
||||||
double x2, double y2) :
|
double* vertices() { return m_vertices; }
|
||||||
m_arc(), m_radii_ok(false)
|
|
||||||
{
|
|
||||||
init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void init(double x1, double y1,
|
unsigned m_vertex;
|
||||||
double rx, double ry,
|
unsigned m_num_vertices;
|
||||||
double angle,
|
double m_vertices[26];
|
||||||
bool large_arc_flag,
|
unsigned m_cmd;
|
||||||
bool sweep_flag,
|
};
|
||||||
double x2, double y2);
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//==========================================================bezier_arc_svg
|
||||||
bool radii_ok() const { return m_radii_ok; }
|
// 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,
|
||||||
void rewind(unsigned)
|
double y1,
|
||||||
{
|
double rx,
|
||||||
m_arc.rewind(0);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
unsigned vertex(double* x, double* y)
|
void init(double x1,
|
||||||
{
|
double y1,
|
||||||
return m_arc.vertex(x, y);
|
double rx,
|
||||||
}
|
double ry,
|
||||||
|
double angle,
|
||||||
|
bool large_arc_flag,
|
||||||
|
bool sweep_flag,
|
||||||
|
double x2,
|
||||||
|
double y2);
|
||||||
|
|
||||||
// Supplemantary functions. num_vertices() actually returns doubled
|
//--------------------------------------------------------------------
|
||||||
// number of vertices. That is, for 1 vertex it returns 2.
|
bool radii_ok() const { return m_radii_ok; }
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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;
|
void rewind(unsigned) { m_arc.rewind(0); }
|
||||||
bool m_radii_ok;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
} // namespace agg
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
50
deps/agg/include/agg_bitset_iterator.h
vendored
50
deps/agg/include/agg_bitset_iterator.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,37 +18,33 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
class bitset_iterator
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
class bitset_iterator
|
bitset_iterator(const int8u* bits, unsigned offset = 0)
|
||||||
|
: m_bits(bits + (offset >> 3))
|
||||||
|
, m_mask(0x80 >> (offset & 7))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator++()
|
||||||
{
|
{
|
||||||
public:
|
m_mask >>= 1;
|
||||||
bitset_iterator(const int8u* bits, unsigned offset = 0) :
|
if (m_mask == 0)
|
||||||
m_bits(bits + (offset >> 3)),
|
|
||||||
m_mask(0x80 >> (offset & 7))
|
|
||||||
{}
|
|
||||||
|
|
||||||
void operator ++ ()
|
|
||||||
{
|
{
|
||||||
m_mask >>= 1;
|
++m_bits;
|
||||||
if(m_mask == 0)
|
m_mask = 0x80;
|
||||||
{
|
|
||||||
++m_bits;
|
|
||||||
m_mask = 0x80;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned bit() const
|
unsigned bit() const { return (*m_bits) & m_mask; }
|
||||||
{
|
|
||||||
return (*m_bits) & m_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int8u* m_bits;
|
const int8u* m_bits;
|
||||||
int8u m_mask;
|
int8u m_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2419
deps/agg/include/agg_blur.h
vendored
2419
deps/agg/include/agg_blur.h
vendored
File diff suppressed because it is too large
Load diff
155
deps/agg/include/agg_bounding_rect.h
vendored
155
deps/agg/include/agg_bounding_rect.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -21,76 +21,38 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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;
|
||||||
|
|
||||||
//-----------------------------------------------------------bounding_rect
|
*x1 = CoordT(1);
|
||||||
template<class VertexSource, class GetId, class CoordT>
|
*y1 = CoordT(1);
|
||||||
bool bounding_rect(VertexSource& vs, GetId& gi,
|
*x2 = CoordT(0);
|
||||||
unsigned start, unsigned num,
|
*y2 = CoordT(0);
|
||||||
CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
|
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
unsigned i;
|
vs.rewind(gi[start + 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;
|
unsigned cmd;
|
||||||
while(!is_stop(cmd = vs.vertex(&x, &y)))
|
while (!is_stop(cmd = vs.vertex(&x, &y)))
|
||||||
{
|
{
|
||||||
if(is_vertex(cmd))
|
if (is_vertex(cmd))
|
||||||
{
|
{
|
||||||
if(first)
|
if (first)
|
||||||
{
|
{
|
||||||
*x1 = CoordT(x);
|
*x1 = CoordT(x);
|
||||||
*y1 = CoordT(y);
|
*y1 = CoordT(y);
|
||||||
|
@ -100,17 +62,64 @@ namespace agg
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(CoordT(x) < *x1) *x1 = CoordT(x);
|
if (CoordT(x) < *x1)
|
||||||
if(CoordT(y) < *y1) *y1 = CoordT(y);
|
*x1 = CoordT(x);
|
||||||
if(CoordT(x) > *x2) *x2 = CoordT(x);
|
if (CoordT(y) < *y1)
|
||||||
if(CoordT(y) > *y2) *y2 = CoordT(y);
|
*y1 = CoordT(y);
|
||||||
|
if (CoordT(x) > *x2)
|
||||||
|
*x2 = CoordT(x);
|
||||||
|
if (CoordT(y) > *y2)
|
||||||
|
*y2 = CoordT(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *x1 <= *x2 && *y1 <= *y2;
|
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
86
deps/agg/include/agg_bspline.h
vendored
86
deps/agg/include/agg_bspline.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -22,55 +22,53 @@
|
||||||
|
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
||||||
{
|
{
|
||||||
//----------------------------------------------------------------bspline
|
public:
|
||||||
// A very simple class of Bi-cubic Spline interpolation.
|
bspline();
|
||||||
// First call init(num, x[], y[]) where num - number of source points,
|
bspline(int num);
|
||||||
// x, y - arrays of X and Y values respectively. Here Y must be a function
|
bspline(int num, const double* x, const double* y);
|
||||||
// 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 init(int num);
|
||||||
void add_point(double x, double y);
|
void add_point(double x, double y);
|
||||||
void prepare();
|
void prepare();
|
||||||
|
|
||||||
void init(int num, const double* x, const double* y);
|
void init(int num, const double* x, const double* y);
|
||||||
|
|
||||||
double get(double x) const;
|
double get(double x) const;
|
||||||
double get_stateful(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);
|
private:
|
||||||
double extrapolation_left(double x) const;
|
bspline(const bspline&);
|
||||||
double extrapolation_right(double x) const;
|
const bspline& operator=(const bspline&);
|
||||||
double interpolation(double x, int i) const;
|
|
||||||
|
|
||||||
int m_max;
|
static void bsearch(int n, const double* x, double x0, int* i);
|
||||||
int m_num;
|
double extrapolation_left(double x) const;
|
||||||
double* m_x;
|
double extrapolation_right(double x) const;
|
||||||
double* m_y;
|
double interpolation(double x, int i) const;
|
||||||
pod_array<double> m_am;
|
|
||||||
mutable int m_last_idx;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
int m_max;
|
||||||
|
int m_num;
|
||||||
|
double* m_x;
|
||||||
|
double* m_y;
|
||||||
|
pod_array<double> m_am;
|
||||||
|
mutable int m_last_idx;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
521
deps/agg/include/agg_clip_liang_barsky.h
vendored
521
deps/agg/include/agg_clip_liang_barsky.h
vendored
|
@ -21,313 +21,296 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
||||||
enum clipping_flags_e
|
template<class T>
|
||||||
{
|
inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box)
|
||||||
clipping_flags_x1_clipped = 4,
|
{
|
||||||
clipping_flags_x2_clipped = 1,
|
return (x > clip_box.x2) | ((x < clip_box.x1) << 2);
|
||||||
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
|
//--------------------------------------------------------clipping_flags_y
|
||||||
// Determine the clipping code of the vertex according to the
|
template<class T>
|
||||||
// Cyrus-Beck line clipping algorithm
|
inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box)
|
||||||
//
|
{
|
||||||
// | |
|
return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3);
|
||||||
// 0110 | 0010 | 0011
|
}
|
||||||
// | |
|
|
||||||
// -------+--------+-------- clip_box.y2
|
//-------------------------------------------------------clip_liang_barsky
|
||||||
// | |
|
template<class T>
|
||||||
// 0100 | 0000 | 0001
|
inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2, const rect_base<T>& clip_box, T* x, T* y)
|
||||||
// | |
|
{
|
||||||
// -------+--------+-------- clip_box.y1
|
const double nearzero = 1e-30;
|
||||||
// | |
|
|
||||||
// 1100 | 1000 | 1001
|
double deltax = x2 - x1;
|
||||||
// | |
|
double deltay = y2 - y1;
|
||||||
// clip_box.x1 clip_box.x2
|
double xin;
|
||||||
//
|
double xout;
|
||||||
//
|
double yin;
|
||||||
template<class T>
|
double yout;
|
||||||
inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
|
double tinx;
|
||||||
|
double tiny;
|
||||||
|
double toutx;
|
||||||
|
double touty;
|
||||||
|
double tin1;
|
||||||
|
double tin2;
|
||||||
|
double tout1;
|
||||||
|
unsigned np = 0;
|
||||||
|
|
||||||
|
if (deltax == 0.0)
|
||||||
{
|
{
|
||||||
return (x > clip_box.x2) |
|
// bump off of the vertical
|
||||||
((y > clip_box.y2) << 1) |
|
deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
|
||||||
((x < clip_box.x1) << 2) |
|
|
||||||
((y < clip_box.y1) << 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------clipping_flags_x
|
if (deltay == 0.0)
|
||||||
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);
|
// bump off of the horizontal
|
||||||
|
deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (deltax > 0.0)
|
||||||
//--------------------------------------------------------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);
|
// points to right
|
||||||
|
xin = clip_box.x1;
|
||||||
|
xout = clip_box.x2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xin = clip_box.x2;
|
||||||
|
xout = clip_box.x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (deltay > 0.0)
|
||||||
//-------------------------------------------------------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;
|
// points up
|
||||||
|
yin = clip_box.y1;
|
||||||
|
yout = clip_box.y2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yin = clip_box.y2;
|
||||||
|
yout = clip_box.y1;
|
||||||
|
}
|
||||||
|
|
||||||
double deltax = x2 - x1;
|
tinx = (xin - x1) / deltax;
|
||||||
double deltay = y2 - y1;
|
tiny = (yin - y1) / deltay;
|
||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
// bump off of the vertical
|
*x++ = (T)xin;
|
||||||
deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
|
*y++ = (T)yin;
|
||||||
|
++np;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(deltay == 0.0)
|
if (tin2 <= 1.0)
|
||||||
{
|
{
|
||||||
// bump off of the horizontal
|
toutx = (xout - x1) / deltax;
|
||||||
deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
|
touty = (yout - y1) / deltay;
|
||||||
}
|
|
||||||
|
|
||||||
if(deltax > 0.0)
|
tout1 = (toutx < touty) ? toutx : touty;
|
||||||
{
|
|
||||||
// points to right
|
|
||||||
xin = clip_box.x1;
|
|
||||||
xout = clip_box.x2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xin = clip_box.x2;
|
|
||||||
xout = clip_box.x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(deltay > 0.0)
|
if (tin2 > 0.0 || tout1 > 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;
|
if (tin2 <= tout1)
|
||||||
*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(tin2 > 0.0)
|
if (tinx > tiny)
|
||||||
{
|
|
||||||
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;
|
*x++ = (T)xin;
|
||||||
*y++ = (T)yout;
|
*y++ = (T)(y1 + tinx * deltay);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*x++ = (T)xout;
|
*x++ = (T)(x1 + tiny * deltax);
|
||||||
*y++ = (T)yin;
|
*y++ = (T)yin;
|
||||||
}
|
}
|
||||||
++np;
|
++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;
|
|
||||||
}
|
}
|
||||||
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
524
deps/agg/include/agg_color_gray.h
vendored
524
deps/agg/include/agg_color_gray.h
vendored
|
@ -31,21 +31,19 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_color_rgba.h"
|
#include "agg_color_rgba.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
{
|
|
||||||
|
|
||||||
//===================================================================gray8
|
//===================================================================gray8
|
||||||
template<class Colorspace>
|
template<class Colorspace>
|
||||||
struct gray8T
|
struct gray8T
|
||||||
{
|
{
|
||||||
typedef int8u value_type;
|
typedef int8u value_type;
|
||||||
typedef int32u calc_type;
|
typedef int32u calc_type;
|
||||||
typedef int32 long_type;
|
typedef int32 long_type;
|
||||||
enum base_scale_e
|
enum base_scale_e {
|
||||||
{
|
|
||||||
base_shift = 8,
|
base_shift = 8,
|
||||||
base_scale = 1 << base_shift,
|
base_scale = 1 << base_shift,
|
||||||
base_mask = base_scale - 1,
|
base_mask = base_scale - 1,
|
||||||
base_MSB = 1 << (base_shift - 1)
|
base_MSB = 1 << (base_shift - 1)
|
||||||
};
|
};
|
||||||
typedef gray8T self_type;
|
typedef gray8T self_type;
|
||||||
|
@ -105,17 +103,22 @@ struct gray8T
|
||||||
gray8T() {}
|
gray8T() {}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray8T(unsigned v_, unsigned a_=base_mask) :
|
gray8T(unsigned v_, unsigned a_ = base_mask)
|
||||||
v(int8u(v_)), a(int8u(a_)) {}
|
: v(int8u(v_))
|
||||||
|
, a(int8u(a_))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray8T(const self_type& c, unsigned a_) :
|
gray8T(const self_type& c, unsigned a_)
|
||||||
v(c.v), a(value_type(a_)) {}
|
: v(c.v)
|
||||||
|
, a(value_type(a_))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray8T(const rgba& c) :
|
gray8T(const rgba& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a(value_type(uround(c.a * base_mask))) {}
|
, a(value_type(uround(c.a * base_mask)))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -147,36 +150,18 @@ struct gray8T
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba8 make_rgba8(const linear&) const
|
rgba8 make_rgba8(const linear&) const { return rgba8(v, v, v, a); }
|
||||||
{
|
|
||||||
return rgba8(v, v, v, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
rgba8 make_rgba8(const sRGB&) const
|
rgba8 make_rgba8(const sRGB&) const { return convert_from_sRGB<srgba8>(); }
|
||||||
{
|
|
||||||
return convert_from_sRGB<srgba8>();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator rgba8() const
|
operator rgba8() const { return make_rgba8(Colorspace()); }
|
||||||
{
|
|
||||||
return make_rgba8(Colorspace());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
srgba8 make_srgba8(const linear&) const
|
srgba8 make_srgba8(const linear&) const { return convert_to_sRGB<rgba8>(); }
|
||||||
{
|
|
||||||
return convert_to_sRGB<rgba8>();
|
|
||||||
}
|
|
||||||
|
|
||||||
srgba8 make_srgba8(const sRGB&) const
|
srgba8 make_srgba8(const sRGB&) const { return srgba8(v, v, v, a); }
|
||||||
{
|
|
||||||
return srgba8(v, v, v, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator srgba8() const
|
operator srgba8() const { return make_rgba8(Colorspace()); }
|
||||||
{
|
|
||||||
return make_rgba8(Colorspace());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba16 make_rgba16(const linear&) const
|
rgba16 make_rgba16(const linear&) const
|
||||||
|
@ -185,15 +170,9 @@ struct gray8T
|
||||||
return rgba16(rgb, rgb, rgb, (a << 8) | a);
|
return rgba16(rgb, rgb, rgb, (a << 8) | a);
|
||||||
}
|
}
|
||||||
|
|
||||||
rgba16 make_rgba16(const sRGB&) const
|
rgba16 make_rgba16(const sRGB&) const { return convert_from_sRGB<rgba16>(); }
|
||||||
{
|
|
||||||
return convert_from_sRGB<rgba16>();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator rgba16() const
|
operator rgba16() const { return make_rgba16(Colorspace()); }
|
||||||
{
|
|
||||||
return make_rgba16(Colorspace());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba32 make_rgba32(const linear&) const
|
rgba32 make_rgba32(const linear&) const
|
||||||
|
@ -202,51 +181,27 @@ struct gray8T
|
||||||
return rgba32(v32, v32, v32, a / 255.0);
|
return rgba32(v32, v32, v32, a / 255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
rgba32 make_rgba32(const sRGB&) const
|
rgba32 make_rgba32(const sRGB&) const { return convert_from_sRGB<rgba32>(); }
|
||||||
{
|
|
||||||
return convert_from_sRGB<rgba32>();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator rgba32() const
|
operator rgba32() const { return make_rgba32(Colorspace()); }
|
||||||
{
|
|
||||||
return make_rgba32(Colorspace());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE double to_double(value_type a)
|
static AGG_INLINE double to_double(value_type a) { return double(a) / base_mask; }
|
||||||
{
|
|
||||||
return double(a) / base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type from_double(double a)
|
static AGG_INLINE value_type from_double(double a) { return value_type(uround(a * base_mask)); }
|
||||||
{
|
|
||||||
return value_type(uround(a * base_mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type empty_value()
|
static AGG_INLINE value_type empty_value() { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type full_value()
|
static AGG_INLINE value_type full_value() { return base_mask; }
|
||||||
{
|
|
||||||
return base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_transparent() const
|
AGG_INLINE bool is_transparent() const { return a == 0; }
|
||||||
{
|
|
||||||
return a == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_opaque() const
|
AGG_INLINE bool is_opaque() const { return a == base_mask; }
|
||||||
{
|
|
||||||
return a == base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Fixed-point multiply, exact over int8u.
|
// Fixed-point multiply, exact over int8u.
|
||||||
|
@ -267,7 +222,8 @@ struct gray8T
|
||||||
{
|
{
|
||||||
return base_mask;
|
return base_mask;
|
||||||
}
|
}
|
||||||
else return value_type((a * base_mask + (b >> 1)) / b);
|
else
|
||||||
|
return value_type((a * base_mask + (b >> 1)) / b);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
@ -287,23 +243,14 @@ struct gray8T
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Fixed-point multiply, exact over int8u.
|
// Fixed-point multiply, exact over int8u.
|
||||||
// Specifically for multiplying a color component by a cover.
|
// Specifically for multiplying a color component by a cover.
|
||||||
static AGG_INLINE value_type mult_cover(value_type a, value_type b)
|
static AGG_INLINE value_type mult_cover(value_type a, value_type b) { return multiply(a, b); }
|
||||||
{
|
|
||||||
return multiply(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply(b, a); }
|
||||||
{
|
|
||||||
return multiply(b, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a, assuming q is premultiplied by 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)
|
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); }
|
||||||
{
|
|
||||||
return p + q - multiply(p, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a.
|
// Interpolate p to q by a.
|
||||||
|
@ -330,25 +277,27 @@ struct gray8T
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type& opacity(double a_)
|
self_type& opacity(double a_)
|
||||||
{
|
{
|
||||||
if (a_ < 0) a = 0;
|
if (a_ < 0)
|
||||||
else if (a_ > 1) a = 1;
|
a = 0;
|
||||||
else a = (value_type)uround(a_ * double(base_mask));
|
else if (a_ > 1)
|
||||||
|
a = 1;
|
||||||
|
else
|
||||||
|
a = (value_type)uround(a_ * double(base_mask));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
double opacity() const
|
double opacity() const { return double(a) / double(base_mask); }
|
||||||
{
|
|
||||||
return double(a) / double(base_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type& premultiply()
|
self_type& premultiply()
|
||||||
{
|
{
|
||||||
if (a < base_mask)
|
if (a < base_mask)
|
||||||
{
|
{
|
||||||
if (a == 0) v = 0;
|
if (a == 0)
|
||||||
else v = multiply(v, a);
|
v = 0;
|
||||||
|
else
|
||||||
|
v = multiply(v, a);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -408,24 +357,22 @@ struct gray8T
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type no_color() { return self_type(0,0); }
|
static self_type no_color() { return self_type(0, 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef gray8T<linear> gray8;
|
typedef gray8T<linear> gray8;
|
||||||
typedef gray8T<sRGB> sgray8;
|
typedef gray8T<sRGB> sgray8;
|
||||||
|
|
||||||
|
|
||||||
//==================================================================gray16
|
//==================================================================gray16
|
||||||
struct gray16
|
struct gray16
|
||||||
{
|
{
|
||||||
typedef int16u value_type;
|
typedef int16u value_type;
|
||||||
typedef int32u calc_type;
|
typedef int32u calc_type;
|
||||||
typedef int64 long_type;
|
typedef int64 long_type;
|
||||||
enum base_scale_e
|
enum base_scale_e {
|
||||||
{
|
|
||||||
base_shift = 16,
|
base_shift = 16,
|
||||||
base_scale = 1 << base_shift,
|
base_scale = 1 << base_shift,
|
||||||
base_mask = base_scale - 1,
|
base_mask = base_scale - 1,
|
||||||
base_MSB = 1 << (base_shift - 1)
|
base_MSB = 1 << (base_shift - 1)
|
||||||
};
|
};
|
||||||
typedef gray16 self_type;
|
typedef gray16 self_type;
|
||||||
|
@ -445,67 +392,65 @@ struct gray16
|
||||||
return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16);
|
return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static value_type luminance(const rgba8& c)
|
static value_type luminance(const rgba8& c) { return luminance(rgba16(c)); }
|
||||||
{
|
|
||||||
return luminance(rgba16(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_type luminance(const srgba8& c)
|
static value_type luminance(const srgba8& c) { return luminance(rgba16(c)); }
|
||||||
{
|
|
||||||
return luminance(rgba16(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_type luminance(const rgba32& c)
|
static value_type luminance(const rgba32& c) { return luminance(rgba(c)); }
|
||||||
{
|
|
||||||
return luminance(rgba(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16() {}
|
gray16() {}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16(unsigned v_, unsigned a_ = base_mask) :
|
gray16(unsigned v_, unsigned a_ = base_mask)
|
||||||
v(int16u(v_)), a(int16u(a_)) {}
|
: v(int16u(v_))
|
||||||
|
, a(int16u(a_))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16(const self_type& c, unsigned a_) :
|
gray16(const self_type& c, unsigned a_)
|
||||||
v(c.v), a(value_type(a_)) {}
|
: v(c.v)
|
||||||
|
, a(value_type(a_))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16(const rgba& c) :
|
gray16(const rgba& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a((value_type)uround(c.a * double(base_mask))) {}
|
, a((value_type)uround(c.a * double(base_mask)))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16(const rgba8& c) :
|
gray16(const rgba8& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a((value_type(c.a) << 8) | c.a) {}
|
, a((value_type(c.a) << 8) | c.a)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16(const srgba8& c) :
|
gray16(const srgba8& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a((value_type(c.a) << 8) | c.a) {}
|
, a((value_type(c.a) << 8) | c.a)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16(const rgba16& c) :
|
gray16(const rgba16& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a(c.a) {}
|
, a(c.a)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16(const gray8& c) :
|
gray16(const gray8& c)
|
||||||
v((value_type(c.v) << 8) | c.v),
|
: v((value_type(c.v) << 8) | c.v)
|
||||||
a((value_type(c.a) << 8) | c.a) {}
|
, a((value_type(c.a) << 8) | c.a)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray16(const sgray8& c) :
|
gray16(const sgray8& c)
|
||||||
v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)),
|
: v(sRGB_conv<value_type>::rgb_from_sRGB(c.v))
|
||||||
a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
|
, a(sRGB_conv<value_type>::alpha_from_sRGB(c.a))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba8() const
|
operator rgba8() const { return rgba8(v >> 8, v >> 8, v >> 8, a >> 8); }
|
||||||
{
|
|
||||||
return rgba8(v >> 8, v >> 8, v >> 8, a >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator srgba8() const
|
operator srgba8() const
|
||||||
|
@ -515,60 +460,34 @@ struct gray16
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba16() const
|
operator rgba16() const { return rgba16(v, v, v, a); }
|
||||||
{
|
|
||||||
return rgba16(v, v, v, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator gray8() const
|
operator gray8() const { return gray8(v >> 8, a >> 8); }
|
||||||
{
|
|
||||||
return gray8(v >> 8, a >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator sgray8() const
|
operator sgray8() const
|
||||||
{
|
{
|
||||||
return sgray8(
|
return sgray8(sRGB_conv<value_type>::rgb_to_sRGB(v), sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||||
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)
|
static AGG_INLINE double to_double(value_type a) { return double(a) / base_mask; }
|
||||||
{
|
|
||||||
return double(a) / base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type from_double(double a)
|
static AGG_INLINE value_type from_double(double a) { return value_type(uround(a * base_mask)); }
|
||||||
{
|
|
||||||
return value_type(uround(a * base_mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type empty_value()
|
static AGG_INLINE value_type empty_value() { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type full_value()
|
static AGG_INLINE value_type full_value() { return base_mask; }
|
||||||
{
|
|
||||||
return base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_transparent() const
|
AGG_INLINE bool is_transparent() const { return a == 0; }
|
||||||
{
|
|
||||||
return a == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_opaque() const
|
AGG_INLINE bool is_opaque() const { return a == base_mask; }
|
||||||
{
|
|
||||||
return a == base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Fixed-point multiply, exact over int16u.
|
// Fixed-point multiply, exact over int16u.
|
||||||
|
@ -589,7 +508,8 @@ struct gray16
|
||||||
{
|
{
|
||||||
return base_mask;
|
return base_mask;
|
||||||
}
|
}
|
||||||
else return value_type((a * base_mask + (b >> 1)) / b);
|
else
|
||||||
|
return value_type((a * base_mask + (b >> 1)) / b);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
@ -609,23 +529,14 @@ struct gray16
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Fixed-point multiply, almost exact over int16u.
|
// Fixed-point multiply, almost exact over int16u.
|
||||||
// Specifically for multiplying a color component by a cover.
|
// Specifically for multiplying a color component by a cover.
|
||||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, b << 8 | b); }
|
||||||
{
|
|
||||||
return multiply(a, b << 8 | b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return mult_cover(b, a) >> 8; }
|
||||||
{
|
|
||||||
return mult_cover(b, a) >> 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a, assuming q is premultiplied by 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)
|
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); }
|
||||||
{
|
|
||||||
return p + q - multiply(p, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a.
|
// Interpolate p to q by a.
|
||||||
|
@ -652,26 +563,27 @@ struct gray16
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type& opacity(double a_)
|
self_type& opacity(double a_)
|
||||||
{
|
{
|
||||||
if (a_ < 0) a = 0;
|
if (a_ < 0)
|
||||||
else if(a_ > 1) a = 1;
|
a = 0;
|
||||||
else a = (value_type)uround(a_ * double(base_mask));
|
else if (a_ > 1)
|
||||||
|
a = 1;
|
||||||
|
else
|
||||||
|
a = (value_type)uround(a_ * double(base_mask));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
double opacity() const
|
double opacity() const { return double(a) / double(base_mask); }
|
||||||
{
|
|
||||||
return double(a) / double(base_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type& premultiply()
|
self_type& premultiply()
|
||||||
{
|
{
|
||||||
if (a < base_mask)
|
if (a < base_mask)
|
||||||
{
|
{
|
||||||
if(a == 0) v = 0;
|
if (a == 0)
|
||||||
else v = multiply(v, a);
|
v = 0;
|
||||||
|
else
|
||||||
|
v = multiply(v, a);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -731,10 +643,9 @@ struct gray16
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type no_color() { return self_type(0,0); }
|
static self_type no_color() { return self_type(0, 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//===================================================================gray32
|
//===================================================================gray32
|
||||||
struct gray32
|
struct gray32
|
||||||
{
|
{
|
||||||
|
@ -746,11 +657,10 @@ struct gray32
|
||||||
value_type v;
|
value_type v;
|
||||||
value_type a;
|
value_type a;
|
||||||
|
|
||||||
enum base_scale_e
|
enum base_scale_e {
|
||||||
{
|
|
||||||
base_shift = 8,
|
base_shift = 8,
|
||||||
base_scale = 1 << base_shift,
|
base_scale = 1 << base_shift,
|
||||||
base_mask = base_scale - 1,
|
base_mask = base_scale - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate grayscale value as per ITU-R BT.709.
|
// Calculate grayscale value as per ITU-R BT.709.
|
||||||
|
@ -759,103 +669,92 @@ struct gray32
|
||||||
return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b);
|
return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static value_type luminance(const rgba& c)
|
static value_type luminance(const rgba& c) { return luminance(c.r, c.g, c.b); }
|
||||||
{
|
|
||||||
return luminance(c.r, c.g, c.b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_type luminance(const rgba32& c)
|
static value_type luminance(const rgba32& c) { return luminance(c.r, c.g, c.b); }
|
||||||
{
|
|
||||||
return luminance(c.r, c.g, c.b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_type luminance(const rgba8& c)
|
static value_type luminance(const rgba8& c) { return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0); }
|
||||||
{
|
|
||||||
return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_type luminance(const rgba16& c)
|
static value_type luminance(const rgba16& c) { return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0); }
|
||||||
{
|
|
||||||
return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32() {}
|
gray32() {}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(value_type v_, value_type a_ = 1) :
|
gray32(value_type v_, value_type a_ = 1)
|
||||||
v(v_), a(a_) {}
|
: v(v_)
|
||||||
|
, a(a_)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const self_type& c, value_type a_) :
|
gray32(const self_type& c, value_type a_)
|
||||||
v(c.v), a(a_) {}
|
: v(c.v)
|
||||||
|
, a(a_)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const rgba& c) :
|
gray32(const rgba& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a(value_type(c.a)) {}
|
, a(value_type(c.a))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const rgba8& c) :
|
gray32(const rgba8& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a(value_type(c.a / 255.0)) {}
|
, a(value_type(c.a / 255.0))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const srgba8& c) :
|
gray32(const srgba8& c)
|
||||||
v(luminance(rgba32(c))),
|
: v(luminance(rgba32(c)))
|
||||||
a(value_type(c.a / 255.0)) {}
|
, a(value_type(c.a / 255.0))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const rgba16& c) :
|
gray32(const rgba16& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a(value_type(c.a / 65535.0)) {}
|
, a(value_type(c.a / 65535.0))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const rgba32& c) :
|
gray32(const rgba32& c)
|
||||||
v(luminance(c)),
|
: v(luminance(c))
|
||||||
a(value_type(c.a)) {}
|
, a(value_type(c.a))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const gray8& c) :
|
gray32(const gray8& c)
|
||||||
v(value_type(c.v / 255.0)),
|
: v(value_type(c.v / 255.0))
|
||||||
a(value_type(c.a / 255.0)) {}
|
, a(value_type(c.a / 255.0))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const sgray8& c) :
|
gray32(const sgray8& c)
|
||||||
v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)),
|
: v(sRGB_conv<value_type>::rgb_from_sRGB(c.v))
|
||||||
a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
|
, a(sRGB_conv<value_type>::alpha_from_sRGB(c.a))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
gray32(const gray16& c) :
|
gray32(const gray16& c)
|
||||||
v(value_type(c.v / 65535.0)),
|
: v(value_type(c.v / 65535.0))
|
||||||
a(value_type(c.a / 65535.0)) {}
|
, a(value_type(c.a / 65535.0))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba() const
|
operator rgba() const { return rgba(v, v, v, a); }
|
||||||
{
|
|
||||||
return rgba(v, v, v, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator gray8() const
|
operator gray8() const { return gray8(uround(v * 255.0), uround(a * 255.0)); }
|
||||||
{
|
|
||||||
return gray8(uround(v * 255.0), uround(a * 255.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator sgray8() const
|
operator sgray8() const
|
||||||
{
|
{
|
||||||
// Return (non-premultiplied) sRGB values.
|
// Return (non-premultiplied) sRGB values.
|
||||||
return sgray8(
|
return sgray8(sRGB_conv<value_type>::rgb_to_sRGB(v), sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||||
sRGB_conv<value_type>::rgb_to_sRGB(v),
|
|
||||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator gray16() const
|
operator gray16() const { return gray16(uround(v * 65535.0), uround(a * 65535.0)); }
|
||||||
{
|
|
||||||
return gray16(uround(v * 65535.0), uround(a * 65535.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba8() const
|
operator rgba8() const
|
||||||
|
@ -879,58 +778,31 @@ struct gray32
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE double to_double(value_type a)
|
static AGG_INLINE double to_double(value_type a) { return a; }
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type from_double(double a)
|
static AGG_INLINE value_type from_double(double a) { return value_type(a); }
|
||||||
{
|
|
||||||
return value_type(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type empty_value()
|
static AGG_INLINE value_type empty_value() { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type full_value()
|
static AGG_INLINE value_type full_value() { return 1; }
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_transparent() const
|
AGG_INLINE bool is_transparent() const { return a <= 0; }
|
||||||
{
|
|
||||||
return a <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_opaque() const
|
AGG_INLINE bool is_opaque() const { return a >= 1; }
|
||||||
{
|
|
||||||
return a >= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type invert(value_type x)
|
static AGG_INLINE value_type invert(value_type x) { return 1 - x; }
|
||||||
{
|
|
||||||
return 1 - x;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type multiply(value_type a, value_type b)
|
static AGG_INLINE value_type multiply(value_type a, value_type b) { return value_type(a * b); }
|
||||||
{
|
|
||||||
return value_type(a * b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type demultiply(value_type a, value_type b)
|
static AGG_INLINE value_type demultiply(value_type a, value_type b) { return (b == 0) ? 0 : value_type(a / b); }
|
||||||
{
|
|
||||||
return (b == 0) ? 0 : value_type(a / b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -947,16 +819,10 @@ struct gray32
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return value_type(a * b / cover_mask); }
|
||||||
{
|
|
||||||
return value_type(a * b / cover_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return cover_type(uround(a * b)); }
|
||||||
{
|
|
||||||
return cover_type(uround(a * b));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a, assuming q is premultiplied by a.
|
// Interpolate p to q by a, assuming q is premultiplied by a.
|
||||||
|
@ -993,49 +859,47 @@ struct gray32
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type& opacity(double a_)
|
self_type& opacity(double a_)
|
||||||
{
|
{
|
||||||
if (a_ < 0) a = 0;
|
if (a_ < 0)
|
||||||
else if (a_ > 1) a = 1;
|
a = 0;
|
||||||
else a = value_type(a_);
|
else if (a_ > 1)
|
||||||
|
a = 1;
|
||||||
|
else
|
||||||
|
a = value_type(a_);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
double opacity() const
|
double opacity() const { return a; }
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type& premultiply()
|
self_type& premultiply()
|
||||||
{
|
{
|
||||||
if (a < 0) v = 0;
|
if (a < 0)
|
||||||
else if(a < 1) v *= a;
|
v = 0;
|
||||||
|
else if (a < 1)
|
||||||
|
v *= a;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type& demultiply()
|
self_type& demultiply()
|
||||||
{
|
{
|
||||||
if (a < 0) v = 0;
|
if (a < 0)
|
||||||
else if (a < 1) v /= a;
|
v = 0;
|
||||||
|
else if (a < 1)
|
||||||
|
v /= a;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type gradient(self_type c, double k) const
|
self_type gradient(self_type c, double k) const
|
||||||
{
|
{
|
||||||
return self_type(
|
return self_type(value_type(v + (c.v - v) * k), value_type(a + (c.a - a) * k));
|
||||||
value_type(v + (c.v - v) * k),
|
|
||||||
value_type(a + (c.a - a) * k));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type no_color() { return self_type(0,0); }
|
static self_type no_color() { return self_type(0, 0); }
|
||||||
};
|
};
|
||||||
}
|
} // namespace agg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
525
deps/agg/include/agg_color_rgba.h
vendored
525
deps/agg/include/agg_color_rgba.h
vendored
|
@ -28,20 +28,39 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_gamma_lut.h"
|
#include "agg_gamma_lut.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
{
|
|
||||||
// Supported byte orders for RGB and RGBA pixel formats
|
// Supported byte orders for RGB and RGBA pixel formats
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag, hasAlpha=false }; }; //----order_rgb
|
struct order_rgb
|
||||||
struct order_bgr { enum bgr_e { B=0, G=1, R=2, rgb_tag, hasAlpha=false }; }; //----order_bgr
|
{
|
||||||
struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, rgba_tag, hasAlpha=true }; }; //----order_rgba
|
enum rgb_e { R = 0, G = 1, B = 2, rgb_tag, hasAlpha = false };
|
||||||
struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, rgba_tag, hasAlpha=true }; }; //----order_argb
|
}; //----order_rgb
|
||||||
struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, rgba_tag, hasAlpha=true }; }; //----order_abgr
|
struct order_bgr
|
||||||
struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, rgba_tag, hasAlpha=true }; }; //----order_bgra
|
{
|
||||||
|
enum bgr_e { B = 0, G = 1, R = 2, rgb_tag, hasAlpha = false };
|
||||||
|
}; //----order_bgr
|
||||||
|
struct order_rgba
|
||||||
|
{
|
||||||
|
enum rgba_e { R = 0, G = 1, B = 2, A = 3, rgba_tag, hasAlpha = true };
|
||||||
|
}; //----order_rgba
|
||||||
|
struct order_argb
|
||||||
|
{
|
||||||
|
enum argb_e { A = 0, R = 1, G = 2, B = 3, rgba_tag, hasAlpha = true };
|
||||||
|
}; //----order_argb
|
||||||
|
struct order_abgr
|
||||||
|
{
|
||||||
|
enum abgr_e { A = 0, B = 1, G = 2, R = 3, rgba_tag, hasAlpha = true };
|
||||||
|
}; //----order_abgr
|
||||||
|
struct order_bgra
|
||||||
|
{
|
||||||
|
enum bgra_e { B = 0, G = 1, R = 2, A = 3, rgba_tag, hasAlpha = true };
|
||||||
|
}; //----order_bgra
|
||||||
|
|
||||||
// Colorspace tag types.
|
// Colorspace tag types.
|
||||||
struct linear {};
|
struct linear
|
||||||
struct sRGB {};
|
{};
|
||||||
|
struct sRGB
|
||||||
|
{};
|
||||||
|
|
||||||
//====================================================================rgba
|
//====================================================================rgba
|
||||||
struct rgba
|
struct rgba
|
||||||
|
@ -57,11 +76,20 @@ struct rgba
|
||||||
rgba() {}
|
rgba() {}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba(double r_, double g_, double b_, double a_=1.0) :
|
rgba(double r_, double g_, double b_, double a_ = 1.0)
|
||||||
r(r_), g(g_), b(b_), a(a_) {}
|
: 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(const rgba& c, double a_)
|
||||||
|
: r(c.r)
|
||||||
|
, g(c.g)
|
||||||
|
, b(c.b)
|
||||||
|
, a(a_)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba& clear()
|
rgba& clear()
|
||||||
|
@ -80,17 +108,17 @@ struct rgba
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba& opacity(double a_)
|
rgba& opacity(double a_)
|
||||||
{
|
{
|
||||||
if (a_ < 0) a = 0;
|
if (a_ < 0)
|
||||||
else if (a_ > 1) a = 1;
|
a = 0;
|
||||||
else a = a_;
|
else if (a_ > 1)
|
||||||
|
a = 1;
|
||||||
|
else
|
||||||
|
a = a_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
double opacity() const
|
double opacity() const { return a; }
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba& premultiply()
|
rgba& premultiply()
|
||||||
|
@ -114,7 +142,7 @@ struct rgba
|
||||||
r *= a_;
|
r *= a_;
|
||||||
g *= a_;
|
g *= a_;
|
||||||
b *= a_;
|
b *= a_;
|
||||||
a = a_;
|
a = a_;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +164,6 @@ struct rgba
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba gradient(rgba c, double k) const
|
rgba gradient(rgba c, double k) const
|
||||||
{
|
{
|
||||||
|
@ -167,17 +194,13 @@ struct rgba
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static rgba no_color() { return rgba(0,0,0,0); }
|
static rgba no_color() { return rgba(0, 0, 0, 0); }
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static rgba from_wavelength(double wl, double gamma = 1.0);
|
static rgba from_wavelength(double wl, double gamma = 1.0);
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
explicit rgba(double wavelen, double gamma=1.0)
|
explicit rgba(double wavelen, double gamma = 1.0) { *this = from_wavelength(wavelen, gamma); }
|
||||||
{
|
|
||||||
*this = from_wavelength(wavelen, gamma);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline rgba operator+(const rgba& a, const rgba& b)
|
inline rgba operator+(const rgba& a, const rgba& b)
|
||||||
|
@ -226,8 +249,10 @@ inline rgba rgba::from_wavelength(double wl, double gamma)
|
||||||
}
|
}
|
||||||
|
|
||||||
double s = 1.0;
|
double s = 1.0;
|
||||||
if (wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
|
if (wl > 700.0)
|
||||||
else if (wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.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.r = pow(t.r * s, gamma);
|
||||||
t.g = pow(t.g * s, gamma);
|
t.g = pow(t.g * s, gamma);
|
||||||
|
@ -240,24 +265,21 @@ inline rgba rgba_pre(double r, double g, double b, double a)
|
||||||
return rgba(r, g, b, a).premultiply();
|
return rgba(r, g, b, a).premultiply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//===================================================================rgba8
|
//===================================================================rgba8
|
||||||
template<class Colorspace>
|
template<class Colorspace>
|
||||||
struct rgba8T
|
struct rgba8T
|
||||||
{
|
{
|
||||||
typedef int8u value_type;
|
typedef int8u value_type;
|
||||||
typedef int32u calc_type;
|
typedef int32u calc_type;
|
||||||
typedef int32 long_type;
|
typedef int32 long_type;
|
||||||
enum base_scale_e
|
enum base_scale_e {
|
||||||
{
|
|
||||||
base_shift = 8,
|
base_shift = 8,
|
||||||
base_scale = 1 << base_shift,
|
base_scale = 1 << base_shift,
|
||||||
base_mask = base_scale - 1,
|
base_mask = base_scale - 1,
|
||||||
base_MSB = 1 << (base_shift - 1)
|
base_MSB = 1 << (base_shift - 1)
|
||||||
};
|
};
|
||||||
typedef rgba8T self_type;
|
typedef rgba8T self_type;
|
||||||
|
|
||||||
|
|
||||||
value_type r;
|
value_type r;
|
||||||
value_type g;
|
value_type g;
|
||||||
value_type b;
|
value_type b;
|
||||||
|
@ -317,21 +339,23 @@ struct rgba8T
|
||||||
rgba8T() {}
|
rgba8T() {}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) :
|
rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask)
|
||||||
r(value_type(r_)),
|
: r(value_type(r_))
|
||||||
g(value_type(g_)),
|
, g(value_type(g_))
|
||||||
b(value_type(b_)),
|
, b(value_type(b_))
|
||||||
a(value_type(a_)) {}
|
, a(value_type(a_))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba8T(const rgba& c)
|
rgba8T(const rgba& c) { convert(*this, c); }
|
||||||
{
|
|
||||||
convert(*this, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba8T(const self_type& c, unsigned a_) :
|
rgba8T(const self_type& c, unsigned a_)
|
||||||
r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
|
: r(c.r)
|
||||||
|
, g(c.g)
|
||||||
|
, b(c.b)
|
||||||
|
, a(value_type(a_))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -349,46 +373,25 @@ struct rgba8T
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE double to_double(value_type a)
|
static AGG_INLINE double to_double(value_type a) { return double(a) / base_mask; }
|
||||||
{
|
|
||||||
return double(a) / base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type from_double(double a)
|
static AGG_INLINE value_type from_double(double a) { return value_type(uround(a * base_mask)); }
|
||||||
{
|
|
||||||
return value_type(uround(a * base_mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type empty_value()
|
static AGG_INLINE value_type empty_value() { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type full_value()
|
static AGG_INLINE value_type full_value() { return base_mask; }
|
||||||
{
|
|
||||||
return base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_transparent() const
|
AGG_INLINE bool is_transparent() const { return a == 0; }
|
||||||
{
|
|
||||||
return a == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_opaque() const
|
AGG_INLINE bool is_opaque() const { return a == base_mask; }
|
||||||
{
|
|
||||||
return a == base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type invert(value_type x)
|
static AGG_INLINE value_type invert(value_type x) { return base_mask - x; }
|
||||||
{
|
|
||||||
return base_mask - x;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Fixed-point multiply, exact over int8u.
|
// Fixed-point multiply, exact over int8u.
|
||||||
|
@ -409,7 +412,8 @@ struct rgba8T
|
||||||
{
|
{
|
||||||
return base_mask;
|
return base_mask;
|
||||||
}
|
}
|
||||||
else return value_type((a * base_mask + (b >> 1)) / b);
|
else
|
||||||
|
return value_type((a * base_mask + (b >> 1)) / b);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
@ -429,23 +433,14 @@ struct rgba8T
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Fixed-point multiply, exact over int8u.
|
// Fixed-point multiply, exact over int8u.
|
||||||
// Specifically for multiplying a color component by a cover.
|
// Specifically for multiplying a color component by a cover.
|
||||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, b); }
|
||||||
{
|
|
||||||
return multiply(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply(b, a); }
|
||||||
{
|
|
||||||
return multiply(b, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a, assuming q is premultiplied by 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)
|
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); }
|
||||||
{
|
|
||||||
return p + q - multiply(p, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a.
|
// Interpolate p to q by a.
|
||||||
|
@ -472,17 +467,17 @@ struct rgba8T
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
self_type& opacity(double a_)
|
self_type& opacity(double a_)
|
||||||
{
|
{
|
||||||
if (a_ < 0) a = 0;
|
if (a_ < 0)
|
||||||
else if (a_ > 1) a = 1;
|
a = 0;
|
||||||
else a = (value_type)uround(a_ * double(base_mask));
|
else if (a_ > 1)
|
||||||
|
a = 1;
|
||||||
|
else
|
||||||
|
a = (value_type)uround(a_ * double(base_mask));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
double opacity() const
|
double opacity() const { return double(a) / double(base_mask); }
|
||||||
{
|
|
||||||
return double(a) / double(base_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE self_type& premultiply()
|
AGG_INLINE self_type& premultiply()
|
||||||
|
@ -604,7 +599,7 @@ struct rgba8T
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type no_color() { return self_type(0,0,0,0); }
|
static self_type no_color() { return self_type(0, 0, 0, 0); }
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type from_wavelength(double wl, double gamma = 1.0)
|
static self_type from_wavelength(double wl, double gamma = 1.0)
|
||||||
|
@ -617,10 +612,9 @@ typedef rgba8T<linear> rgba8;
|
||||||
typedef rgba8T<sRGB> srgba8;
|
typedef rgba8T<sRGB> srgba8;
|
||||||
|
|
||||||
//-------------------------------------------------------------rgba8_pre
|
//-------------------------------------------------------------rgba8_pre
|
||||||
inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b,
|
inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, unsigned a = rgba8::base_mask)
|
||||||
unsigned a = rgba8::base_mask)
|
|
||||||
{
|
{
|
||||||
return rgba8(r,g,b,a).premultiply();
|
return rgba8(r, g, b, a).premultiply();
|
||||||
}
|
}
|
||||||
inline rgba8 rgba8_pre(const rgba8& c)
|
inline rgba8 rgba8_pre(const rgba8& c)
|
||||||
{
|
{
|
||||||
|
@ -628,7 +622,7 @@ inline rgba8 rgba8_pre(const rgba8& c)
|
||||||
}
|
}
|
||||||
inline rgba8 rgba8_pre(const rgba8& c, unsigned a)
|
inline rgba8 rgba8_pre(const rgba8& c, unsigned a)
|
||||||
{
|
{
|
||||||
return rgba8(c,a).premultiply();
|
return rgba8(c, a).premultiply();
|
||||||
}
|
}
|
||||||
inline rgba8 rgba8_pre(const rgba& c)
|
inline rgba8 rgba8_pre(const rgba& c)
|
||||||
{
|
{
|
||||||
|
@ -636,12 +630,9 @@ inline rgba8 rgba8_pre(const rgba& c)
|
||||||
}
|
}
|
||||||
inline rgba8 rgba8_pre(const rgba& c, double a)
|
inline rgba8 rgba8_pre(const rgba& c, double a)
|
||||||
{
|
{
|
||||||
return rgba8(c,a).premultiply();
|
return rgba8(c, a).premultiply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------rgb8_packed
|
//-------------------------------------------------------------rgb8_packed
|
||||||
inline rgba8 rgb8_packed(unsigned v)
|
inline rgba8 rgb8_packed(unsigned v)
|
||||||
{
|
{
|
||||||
|
@ -674,19 +665,16 @@ 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);
|
return rgba8(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================================rgba16
|
//==================================================================rgba16
|
||||||
struct rgba16
|
struct rgba16
|
||||||
{
|
{
|
||||||
typedef int16u value_type;
|
typedef int16u value_type;
|
||||||
typedef int32u calc_type;
|
typedef int32u calc_type;
|
||||||
typedef int64 long_type;
|
typedef int64 long_type;
|
||||||
enum base_scale_e
|
enum base_scale_e {
|
||||||
{
|
|
||||||
base_shift = 16,
|
base_shift = 16,
|
||||||
base_scale = 1 << base_shift,
|
base_scale = 1 << base_shift,
|
||||||
base_mask = base_scale - 1,
|
base_mask = base_scale - 1,
|
||||||
base_MSB = 1 << (base_shift - 1)
|
base_MSB = 1 << (base_shift - 1)
|
||||||
};
|
};
|
||||||
typedef rgba16 self_type;
|
typedef rgba16 self_type;
|
||||||
|
@ -700,105 +688,81 @@ struct rgba16
|
||||||
rgba16() {}
|
rgba16() {}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
|
rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask)
|
||||||
r(value_type(r_)),
|
: r(value_type(r_))
|
||||||
g(value_type(g_)),
|
, g(value_type(g_))
|
||||||
b(value_type(b_)),
|
, b(value_type(b_))
|
||||||
a(value_type(a_)) {}
|
, a(value_type(a_))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba16(const self_type& c, unsigned a_) :
|
rgba16(const self_type& c, unsigned a_)
|
||||||
r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
|
: r(c.r)
|
||||||
|
, g(c.g)
|
||||||
|
, b(c.b)
|
||||||
|
, a(value_type(a_))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba16(const rgba& c) :
|
rgba16(const rgba& c)
|
||||||
r((value_type)uround(c.r * double(base_mask))),
|
: r((value_type)uround(c.r * double(base_mask)))
|
||||||
g((value_type)uround(c.g * double(base_mask))),
|
, g((value_type)uround(c.g * double(base_mask)))
|
||||||
b((value_type)uround(c.b * double(base_mask))),
|
, b((value_type)uround(c.b * double(base_mask)))
|
||||||
a((value_type)uround(c.a * double(base_mask))) {}
|
, a((value_type)uround(c.a * double(base_mask)))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba16(const rgba8& c) :
|
rgba16(const rgba8& c)
|
||||||
r(value_type((value_type(c.r) << 8) | c.r)),
|
: r(value_type((value_type(c.r) << 8) | c.r))
|
||||||
g(value_type((value_type(c.g) << 8) | c.g)),
|
, g(value_type((value_type(c.g) << 8) | c.g))
|
||||||
b(value_type((value_type(c.b) << 8) | c.b)),
|
, b(value_type((value_type(c.b) << 8) | c.b))
|
||||||
a(value_type((value_type(c.a) << 8) | c.a)) {}
|
, a(value_type((value_type(c.a) << 8) | c.a))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba16(const srgba8& c) :
|
rgba16(const srgba8& c)
|
||||||
r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)),
|
: r(sRGB_conv<value_type>::rgb_from_sRGB(c.r))
|
||||||
g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)),
|
, g(sRGB_conv<value_type>::rgb_from_sRGB(c.g))
|
||||||
b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)),
|
, b(sRGB_conv<value_type>::rgb_from_sRGB(c.b))
|
||||||
a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
|
, a(sRGB_conv<value_type>::alpha_from_sRGB(c.a))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba() const
|
operator rgba() const { return rgba(r / 65535.0, g / 65535.0, b / 65535.0, a / 65535.0); }
|
||||||
{
|
|
||||||
return rgba(
|
|
||||||
r / 65535.0,
|
|
||||||
g / 65535.0,
|
|
||||||
b / 65535.0,
|
|
||||||
a / 65535.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba8() const
|
operator rgba8() const { return rgba8(r >> 8, g >> 8, b >> 8, a >> 8); }
|
||||||
{
|
|
||||||
return rgba8(r >> 8, g >> 8, b >> 8, a >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator srgba8() const
|
operator srgba8() const
|
||||||
{
|
{
|
||||||
// Return (non-premultiplied) sRGB values.
|
// Return (non-premultiplied) sRGB values.
|
||||||
return srgba8(
|
return srgba8(sRGB_conv<value_type>::rgb_to_sRGB(r),
|
||||||
sRGB_conv<value_type>::rgb_to_sRGB(r),
|
sRGB_conv<value_type>::rgb_to_sRGB(g),
|
||||||
sRGB_conv<value_type>::rgb_to_sRGB(g),
|
sRGB_conv<value_type>::rgb_to_sRGB(b),
|
||||||
sRGB_conv<value_type>::rgb_to_sRGB(b),
|
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE double to_double(value_type a)
|
static AGG_INLINE double to_double(value_type a) { return double(a) / base_mask; }
|
||||||
{
|
|
||||||
return double(a) / base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type from_double(double a)
|
static AGG_INLINE value_type from_double(double a) { return value_type(uround(a * base_mask)); }
|
||||||
{
|
|
||||||
return value_type(uround(a * base_mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type empty_value()
|
static AGG_INLINE value_type empty_value() { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type full_value()
|
static AGG_INLINE value_type full_value() { return base_mask; }
|
||||||
{
|
|
||||||
return base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_transparent() const
|
AGG_INLINE bool is_transparent() const { return a == 0; }
|
||||||
{
|
|
||||||
return a == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_opaque() const
|
AGG_INLINE bool is_opaque() const { return a == base_mask; }
|
||||||
{
|
|
||||||
return a == base_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type invert(value_type x)
|
static AGG_INLINE value_type invert(value_type x) { return base_mask - x; }
|
||||||
{
|
|
||||||
return base_mask - x;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Fixed-point multiply, exact over int16u.
|
// Fixed-point multiply, exact over int16u.
|
||||||
|
@ -819,7 +783,8 @@ struct rgba16
|
||||||
{
|
{
|
||||||
return base_mask;
|
return base_mask;
|
||||||
}
|
}
|
||||||
else return value_type((a * base_mask + (b >> 1)) / b);
|
else
|
||||||
|
return value_type((a * base_mask + (b >> 1)) / b);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
@ -839,23 +804,14 @@ struct rgba16
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Fixed-point multiply, almost exact over int16u.
|
// Fixed-point multiply, almost exact over int16u.
|
||||||
// Specifically for multiplying a color component by a cover.
|
// Specifically for multiplying a color component by a cover.
|
||||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, (b << 8) | b); }
|
||||||
{
|
|
||||||
return multiply(a, (b << 8) | b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply((a << 8) | a, b) >> 8; }
|
||||||
{
|
|
||||||
return multiply((a << 8) | a, b) >> 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a, assuming q is premultiplied by 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)
|
static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); }
|
||||||
{
|
|
||||||
return p + q - multiply(p, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a.
|
// Interpolate p to q by a.
|
||||||
|
@ -882,17 +838,16 @@ struct rgba16
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE self_type& opacity(double a_)
|
AGG_INLINE self_type& opacity(double a_)
|
||||||
{
|
{
|
||||||
if (a_ < 0) a = 0;
|
if (a_ < 0)
|
||||||
if (a_ > 1) a = 1;
|
a = 0;
|
||||||
|
if (a_ > 1)
|
||||||
|
a = 1;
|
||||||
a = value_type(uround(a_ * double(base_mask)));
|
a = value_type(uround(a_ * double(base_mask)));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
double opacity() const
|
double opacity() const { return double(a) / double(base_mask); }
|
||||||
{
|
|
||||||
return double(a) / double(base_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE self_type& premultiply()
|
AGG_INLINE self_type& premultiply()
|
||||||
|
@ -1014,7 +969,7 @@ struct rgba16
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type no_color() { return self_type(0,0,0,0); }
|
static self_type no_color() { return self_type(0, 0, 0, 0); }
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type from_wavelength(double wl, double gamma = 1.0)
|
static self_type from_wavelength(double wl, double gamma = 1.0)
|
||||||
|
@ -1023,7 +978,6 @@ struct rgba16
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------rgba16_gamma_dir
|
//------------------------------------------------------rgba16_gamma_dir
|
||||||
template<class GammaLUT>
|
template<class GammaLUT>
|
||||||
rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma)
|
rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma)
|
||||||
|
@ -1055,127 +1009,100 @@ struct rgba32
|
||||||
rgba32() {}
|
rgba32() {}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba32(value_type r_, value_type g_, value_type b_, value_type a_= 1) :
|
rgba32(value_type r_, value_type g_, value_type b_, value_type a_ = 1)
|
||||||
r(r_), g(g_), b(b_), a(a_) {}
|
: r(r_)
|
||||||
|
, g(g_)
|
||||||
|
, b(b_)
|
||||||
|
, a(a_)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba32(const self_type& c, float a_) :
|
rgba32(const self_type& c, float a_)
|
||||||
r(c.r), g(c.g), b(c.b), a(a_) {}
|
: r(c.r)
|
||||||
|
, g(c.g)
|
||||||
|
, b(c.b)
|
||||||
|
, a(a_)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba32(const rgba& c) :
|
rgba32(const rgba& c)
|
||||||
r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {}
|
: r(value_type(c.r))
|
||||||
|
, g(value_type(c.g))
|
||||||
|
, b(value_type(c.b))
|
||||||
|
, a(value_type(c.a))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba32(const rgba8& c) :
|
rgba32(const rgba8& c)
|
||||||
r(value_type(c.r / 255.0)),
|
: r(value_type(c.r / 255.0))
|
||||||
g(value_type(c.g / 255.0)),
|
, g(value_type(c.g / 255.0))
|
||||||
b(value_type(c.b / 255.0)),
|
, b(value_type(c.b / 255.0))
|
||||||
a(value_type(c.a / 255.0)) {}
|
, a(value_type(c.a / 255.0))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba32(const srgba8& c) :
|
rgba32(const srgba8& c)
|
||||||
r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)),
|
: r(sRGB_conv<value_type>::rgb_from_sRGB(c.r))
|
||||||
g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)),
|
, g(sRGB_conv<value_type>::rgb_from_sRGB(c.g))
|
||||||
b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)),
|
, b(sRGB_conv<value_type>::rgb_from_sRGB(c.b))
|
||||||
a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
|
, a(sRGB_conv<value_type>::alpha_from_sRGB(c.a))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rgba32(const rgba16& c) :
|
rgba32(const rgba16& c)
|
||||||
r(value_type(c.r / 65535.0)),
|
: r(value_type(c.r / 65535.0))
|
||||||
g(value_type(c.g / 65535.0)),
|
, g(value_type(c.g / 65535.0))
|
||||||
b(value_type(c.b / 65535.0)),
|
, b(value_type(c.b / 65535.0))
|
||||||
a(value_type(c.a / 65535.0)) {}
|
, a(value_type(c.a / 65535.0))
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba() const
|
operator rgba() const { return rgba(r, g, b, a); }
|
||||||
{
|
|
||||||
return rgba(r, g, b, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba8() const
|
operator rgba8() const { return rgba8(uround(r * 255.0), uround(g * 255.0), uround(b * 255.0), uround(a * 255.0)); }
|
||||||
{
|
|
||||||
return rgba8(
|
|
||||||
uround(r * 255.0),
|
|
||||||
uround(g * 255.0),
|
|
||||||
uround(b * 255.0),
|
|
||||||
uround(a * 255.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator srgba8() const
|
operator srgba8() const
|
||||||
{
|
{
|
||||||
return srgba8(
|
return srgba8(sRGB_conv<value_type>::rgb_to_sRGB(r),
|
||||||
sRGB_conv<value_type>::rgb_to_sRGB(r),
|
sRGB_conv<value_type>::rgb_to_sRGB(g),
|
||||||
sRGB_conv<value_type>::rgb_to_sRGB(g),
|
sRGB_conv<value_type>::rgb_to_sRGB(b),
|
||||||
sRGB_conv<value_type>::rgb_to_sRGB(b),
|
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
||||||
sRGB_conv<value_type>::alpha_to_sRGB(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
operator rgba16() const
|
operator rgba16() const
|
||||||
{
|
{
|
||||||
return rgba8(
|
return rgba8(uround(r * 65535.0), uround(g * 65535.0), uround(b * 65535.0), uround(a * 65535.0));
|
||||||
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)
|
static AGG_INLINE double to_double(value_type a) { return a; }
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type from_double(double a)
|
static AGG_INLINE value_type from_double(double a) { return value_type(a); }
|
||||||
{
|
|
||||||
return value_type(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type empty_value()
|
static AGG_INLINE value_type empty_value() { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type full_value()
|
static AGG_INLINE value_type full_value() { return 1; }
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_transparent() const
|
AGG_INLINE bool is_transparent() const { return a <= 0; }
|
||||||
{
|
|
||||||
return a <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool is_opaque() const
|
AGG_INLINE bool is_opaque() const { return a >= 1; }
|
||||||
{
|
|
||||||
return a >= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type invert(value_type x)
|
static AGG_INLINE value_type invert(value_type x) { return 1 - x; }
|
||||||
{
|
|
||||||
return 1 - x;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type multiply(value_type a, value_type b)
|
static AGG_INLINE value_type multiply(value_type a, value_type b) { return value_type(a * b); }
|
||||||
{
|
|
||||||
return value_type(a * b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type demultiply(value_type a, value_type b)
|
static AGG_INLINE value_type demultiply(value_type a, value_type b) { return (b == 0) ? 0 : value_type(a / b); }
|
||||||
{
|
|
||||||
return (b == 0) ? 0 : value_type(a / b);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -1192,16 +1119,10 @@ struct rgba32
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return value_type(a * b / cover_mask); }
|
||||||
{
|
|
||||||
return value_type(a * b / cover_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
|
static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return cover_type(uround(a * b)); }
|
||||||
{
|
|
||||||
return cover_type(uround(a * b));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Interpolate p to q by a, assuming q is premultiplied by a.
|
// Interpolate p to q by a, assuming q is premultiplied by a.
|
||||||
|
@ -1238,17 +1159,17 @@ struct rgba32
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE self_type& opacity(double a_)
|
AGG_INLINE self_type& opacity(double a_)
|
||||||
{
|
{
|
||||||
if (a_ < 0) a = 0;
|
if (a_ < 0)
|
||||||
else if (a_ > 1) a = 1;
|
a = 0;
|
||||||
else a = value_type(a_);
|
else if (a_ > 1)
|
||||||
|
a = 1;
|
||||||
|
else
|
||||||
|
a = value_type(a_);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
double opacity() const
|
double opacity() const { return a; }
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE self_type& premultiply()
|
AGG_INLINE self_type& premultiply()
|
||||||
|
@ -1324,10 +1245,14 @@ struct rgba32
|
||||||
b += mult_cover(c.b, cover);
|
b += mult_cover(c.b, cover);
|
||||||
a += mult_cover(c.a, cover);
|
a += mult_cover(c.a, cover);
|
||||||
}
|
}
|
||||||
if (a > 1) a = 1;
|
if (a > 1)
|
||||||
if (r > a) r = a;
|
a = 1;
|
||||||
if (g > a) g = a;
|
if (r > a)
|
||||||
if (b > a) b = a;
|
r = a;
|
||||||
|
if (g > a)
|
||||||
|
g = a;
|
||||||
|
if (b > a)
|
||||||
|
b = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
@ -1349,7 +1274,7 @@ struct rgba32
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type no_color() { return self_type(0,0,0,0); }
|
static self_type no_color() { return self_type(0, 0, 0, 0); }
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static self_type from_wavelength(double wl, double gamma = 1)
|
static self_type from_wavelength(double wl, double gamma = 1)
|
||||||
|
@ -1357,8 +1282,6 @@ struct rgba32
|
||||||
return self_type(rgba::from_wavelength(wl, gamma));
|
return self_type(rgba::from_wavelength(wl, gamma));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace agg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
13
deps/agg/include/agg_config.h
vendored
13
deps/agg/include/agg_config.h
vendored
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
// 1. Default basic types such as:
|
// 1. Default basic types such as:
|
||||||
//
|
//
|
||||||
// AGG_INT8
|
// AGG_INT8
|
||||||
// AGG_INT8U
|
// AGG_INT8U
|
||||||
// AGG_INT16
|
// AGG_INT16
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
// AGG_INT64
|
// AGG_INT64
|
||||||
// AGG_INT64U
|
// AGG_INT64U
|
||||||
//
|
//
|
||||||
// Just replace this file with new defines if necessary.
|
// Just replace this file with new defines if necessary.
|
||||||
// For example, if your compiler doesn't have a 64 bit integer type
|
// For example, if your compiler doesn't have a 64 bit integer type
|
||||||
// you can still use AGG if you define the follows:
|
// you can still use AGG if you define the follows:
|
||||||
//
|
//
|
||||||
|
@ -23,22 +23,21 @@
|
||||||
// #define AGG_INT64U unsigned
|
// #define AGG_INT64U unsigned
|
||||||
//
|
//
|
||||||
// It will result in overflow in 16 bit-per-component image/pattern resampling
|
// 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
|
// but it won't result any crash and the rest of the library will remain
|
||||||
// fully functional.
|
// fully functional.
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
// 2. Default rendering_buffer type. Can be:
|
// 2. Default rendering_buffer type. Can be:
|
||||||
//
|
//
|
||||||
// Provides faster access for massive pixel operations,
|
// Provides faster access for massive pixel operations,
|
||||||
// such as blur, image filtering:
|
// such as blur, image filtering:
|
||||||
|
|
||||||
#define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
|
#define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
|
||||||
//
|
//
|
||||||
// Provides cheaper creation and destruction (no mem allocs):
|
// Provides cheaper creation and destruction (no mem allocs):
|
||||||
// #define AGG_RENDERING_BUFFER row_accessor<int8u>
|
// #define AGG_RENDERING_BUFFER row_accessor<int8u>
|
||||||
//
|
//
|
||||||
// You can still use both of them simultaneouslyin your applications
|
// You can still use both of them simultaneouslyin your applications
|
||||||
// This #define is used only for default rendering_buffer type,
|
// This #define is used only for default rendering_buffer type,
|
||||||
// in short hand typedefs like pixfmt_rgba32.
|
// in short hand typedefs like pixfmt_rgba32.
|
||||||
|
|
||||||
|
|
161
deps/agg/include/agg_conv_adaptor_vcgen.h
vendored
161
deps/agg/include/agg_conv_adaptor_vcgen.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,106 +18,95 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//------------------------------------------------------------null_markers
|
||||||
|
struct null_markers
|
||||||
{
|
{
|
||||||
//------------------------------------------------------------null_markers
|
void remove_all() {}
|
||||||
struct null_markers
|
void add_vertex(double, double, unsigned) {}
|
||||||
|
void prepare_src() {}
|
||||||
|
|
||||||
|
void rewind(unsigned) {}
|
||||||
|
unsigned vertex(double*, double*) { return path_cmd_stop; }
|
||||||
|
unsigned type() const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------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)
|
||||||
|
{}
|
||||||
|
|
||||||
|
conv_adaptor_vcgen(conv_adaptor_vcgen<VertexSource, Generator, Markers>&&) = default;
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
void remove_all() {}
|
m_source->rewind(path_id);
|
||||||
void add_vertex(double, double, unsigned) {}
|
m_status = initial;
|
||||||
void prepare_src() {}
|
}
|
||||||
|
|
||||||
void rewind(unsigned) {}
|
unsigned vertex(double* x, double* y);
|
||||||
unsigned vertex(double*, double*) { return path_cmd_stop; }
|
unsigned type() const { return m_source->type(); }
|
||||||
unsigned type() const { return 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
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>&);
|
||||||
|
|
||||||
//------------------------------------------------------conv_adaptor_vcgen
|
VertexSource* m_source;
|
||||||
template<class VertexSource,
|
Generator m_generator;
|
||||||
class Generator,
|
Markers m_markers;
|
||||||
class Markers=null_markers> class conv_adaptor_vcgen
|
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)
|
||||||
{
|
{
|
||||||
enum status
|
switch (m_status)
|
||||||
{
|
{
|
||||||
initial,
|
|
||||||
accumulate,
|
|
||||||
generate
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit conv_adaptor_vcgen(VertexSource& source) :
|
|
||||||
m_source(&source),
|
|
||||||
m_status(initial)
|
|
||||||
{}
|
|
||||||
|
|
||||||
conv_adaptor_vcgen(conv_adaptor_vcgen<VertexSource, Generator, Markers> &&) = default;
|
|
||||||
|
|
||||||
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);
|
|
||||||
unsigned type() const { return m_source->type(); }
|
|
||||||
|
|
||||||
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:
|
case initial:
|
||||||
m_markers.remove_all();
|
m_markers.remove_all();
|
||||||
m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
|
m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
|
||||||
m_status = accumulate;
|
m_status = accumulate;
|
||||||
|
|
||||||
case accumulate:
|
case accumulate:
|
||||||
if(is_stop(m_last_cmd)) return path_cmd_stop;
|
if (is_stop(m_last_cmd))
|
||||||
|
return path_cmd_stop;
|
||||||
|
|
||||||
m_generator.remove_all();
|
m_generator.remove_all();
|
||||||
m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
|
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);
|
m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
|
||||||
|
|
||||||
for(;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
cmd = m_source->vertex(x, y);
|
cmd = m_source->vertex(x, y);
|
||||||
if(is_vertex(cmd))
|
if (is_vertex(cmd))
|
||||||
{
|
{
|
||||||
m_last_cmd = cmd;
|
m_last_cmd = cmd;
|
||||||
if(is_move_to(cmd))
|
if (is_move_to(cmd))
|
||||||
{
|
{
|
||||||
m_start_x = *x;
|
m_start_x = *x;
|
||||||
m_start_y = *y;
|
m_start_y = *y;
|
||||||
|
@ -128,12 +117,12 @@ namespace agg
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(is_stop(cmd))
|
if (is_stop(cmd))
|
||||||
{
|
{
|
||||||
m_last_cmd = path_cmd_stop;
|
m_last_cmd = path_cmd_stop;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(is_end_poly(cmd))
|
if (is_end_poly(cmd))
|
||||||
{
|
{
|
||||||
m_generator.add_vertex(*x, *y, cmd);
|
m_generator.add_vertex(*x, *y, cmd);
|
||||||
break;
|
break;
|
||||||
|
@ -145,18 +134,18 @@ namespace agg
|
||||||
|
|
||||||
case generate:
|
case generate:
|
||||||
cmd = m_generator.vertex(x, y);
|
cmd = m_generator.vertex(x, y);
|
||||||
if(is_stop(cmd))
|
if (is_stop(cmd))
|
||||||
{
|
{
|
||||||
m_status = accumulate;
|
m_status = accumulate;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return cmd;
|
|
||||||
}
|
}
|
||||||
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
217
deps/agg/include/agg_conv_adaptor_vpgen.h
vendored
217
deps/agg/include/agg_conv_adaptor_vpgen.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,143 +18,140 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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; }
|
||||||
|
|
||||||
//======================================================conv_adaptor_vpgen
|
VPGen& vpgen() { return m_vpgen; }
|
||||||
template<class VertexSource, class VPGen> class conv_adaptor_vpgen
|
const VPGen& vpgen() const { return m_vpgen; }
|
||||||
|
|
||||||
|
void rewind(unsigned path_id);
|
||||||
|
unsigned vertex(double* x, double* y);
|
||||||
|
unsigned type() const { return m_source->type(); }
|
||||||
|
|
||||||
|
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 (;;)
|
||||||
{
|
{
|
||||||
public:
|
cmd = m_vpgen.vertex(x, y);
|
||||||
explicit conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {}
|
if (!is_stop(cmd))
|
||||||
void attach(VertexSource& source) { m_source = &source; }
|
break;
|
||||||
|
|
||||||
VPGen& vpgen() { return m_vpgen; }
|
if (m_poly_flags && !m_vpgen.auto_unclose())
|
||||||
const VPGen& vpgen() const { return m_vpgen; }
|
|
||||||
|
|
||||||
void rewind(unsigned path_id);
|
|
||||||
unsigned vertex(double* x, double* y);
|
|
||||||
unsigned type() const { return m_source->type(); }
|
|
||||||
|
|
||||||
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);
|
*x = 0.0;
|
||||||
if(!is_stop(cmd)) break;
|
*y = 0.0;
|
||||||
|
cmd = m_poly_flags;
|
||||||
|
m_poly_flags = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(m_poly_flags && !m_vpgen.auto_unclose())
|
if (m_vertices < 0)
|
||||||
|
{
|
||||||
|
if (m_vertices < -1)
|
||||||
{
|
{
|
||||||
*x = 0.0;
|
m_vertices = 0;
|
||||||
*y = 0.0;
|
return path_cmd_stop;
|
||||||
cmd = m_poly_flags;
|
|
||||||
m_poly_flags = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
m_vpgen.move_to(m_start_x, m_start_y);
|
||||||
|
m_vertices = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(m_vertices < 0)
|
double tx, ty;
|
||||||
|
cmd = m_source->vertex(&tx, &ty);
|
||||||
|
if (is_vertex(cmd))
|
||||||
|
{
|
||||||
|
if (is_move_to(cmd))
|
||||||
{
|
{
|
||||||
if(m_vertices < -1)
|
if (m_vpgen.auto_close() && m_vertices > 2)
|
||||||
{
|
{
|
||||||
m_vertices = 0;
|
m_vpgen.line_to(m_start_x, m_start_y);
|
||||||
return path_cmd_stop;
|
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(m_start_x, m_start_y);
|
m_vpgen.move_to(tx, ty);
|
||||||
|
m_start_x = tx;
|
||||||
|
m_start_y = ty;
|
||||||
m_vertices = 1;
|
m_vertices = 1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
double tx, ty;
|
|
||||||
cmd = m_source->vertex(&tx, &ty);
|
|
||||||
if(is_vertex(cmd))
|
|
||||||
{
|
{
|
||||||
if(is_move_to(cmd))
|
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_vertices > 2)
|
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_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_vertices = 0;
|
||||||
m_start_x = tx;
|
|
||||||
m_start_y = ty;
|
|
||||||
m_vertices = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_vpgen.line_to(tx, ty);
|
|
||||||
++m_vertices;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(is_end_poly(cmd))
|
// path_cmd_stop
|
||||||
|
if (m_vpgen.auto_close() && m_vertices > 2)
|
||||||
{
|
{
|
||||||
m_poly_flags = cmd;
|
m_vpgen.line_to(m_start_x, m_start_y);
|
||||||
if(is_closed(cmd) || m_vpgen.auto_close())
|
m_poly_flags = path_cmd_end_poly | path_flags_close;
|
||||||
{
|
m_vertices = -2;
|
||||||
if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close;
|
continue;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cmd;
|
|
||||||
}
|
}
|
||||||
|
return cmd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
38
deps/agg/include/agg_conv_bspline.h
vendored
38
deps/agg/include/agg_conv_bspline.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -19,30 +19,26 @@
|
||||||
#include "agg_vcgen_bspline.h"
|
#include "agg_vcgen_bspline.h"
|
||||||
#include "agg_conv_adaptor_vcgen.h"
|
#include "agg_conv_adaptor_vcgen.h"
|
||||||
|
|
||||||
|
namespace agg {
|
||||||
|
|
||||||
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
|
conv_bspline(VertexSource& vs)
|
||||||
template<class VertexSource>
|
: conv_adaptor_vcgen<VertexSource, vcgen_bspline>(vs)
|
||||||
struct conv_bspline : public conv_adaptor_vcgen<VertexSource, vcgen_bspline>
|
{}
|
||||||
{
|
|
||||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_bspline> base_type;
|
|
||||||
|
|
||||||
conv_bspline(VertexSource& vs) :
|
void interpolation_step(double v) { base_type::generator().interpolation_step(v); }
|
||||||
conv_adaptor_vcgen<VertexSource, vcgen_bspline>(vs) {}
|
double interpolation_step() const { return base_type::generator().interpolation_step(); }
|
||||||
|
|
||||||
void interpolation_step(double v) { base_type::generator().interpolation_step(v); }
|
private:
|
||||||
double interpolation_step() const { return base_type::generator().interpolation_step(); }
|
conv_bspline(const conv_bspline<VertexSource>&);
|
||||||
|
const conv_bspline<VertexSource>& operator=(const conv_bspline<VertexSource>&);
|
||||||
private:
|
};
|
||||||
conv_bspline(const conv_bspline<VertexSource>&);
|
|
||||||
const conv_bspline<VertexSource>&
|
|
||||||
operator = (const conv_bspline<VertexSource>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
56
deps/agg/include/agg_conv_clip_polygon.h
vendored
56
deps/agg/include/agg_conv_clip_polygon.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -14,12 +14,12 @@
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Polygon clipping converter
|
// Polygon clipping converter
|
||||||
// There an optimized Liang-Basky algorithm is used.
|
// There an optimized Liang-Basky algorithm is used.
|
||||||
// The algorithm doesn't optimize the degenerate edges, i.e. it will never
|
// 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
|
// break a closed polygon into two or more ones, instead, there will be
|
||||||
// degenerate edges coinciding with the respective clipping boundaries.
|
// degenerate edges coinciding with the respective clipping boundaries.
|
||||||
// This is a sub-optimal solution, because that optimization would require
|
// This is a sub-optimal solution, because that optimization would require
|
||||||
// extra, rather expensive math while the rasterizer tolerates it quite well,
|
// extra, rather expensive math while the rasterizer tolerates it quite well,
|
||||||
// without any considerable overhead.
|
// without any considerable overhead.
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -30,35 +30,31 @@
|
||||||
#include "agg_conv_adaptor_vpgen.h"
|
#include "agg_conv_adaptor_vpgen.h"
|
||||||
#include "agg_vpgen_clip_polygon.h"
|
#include "agg_vpgen_clip_polygon.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
conv_clip_polygon(VertexSource& vs)
|
||||||
template<class VertexSource>
|
: conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>(vs)
|
||||||
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) :
|
void clip_box(double _x1, double _y1, double _x2, double _y2) { base_type::vpgen().clip_box(_x1, _y1, _x2, _y2); }
|
||||||
conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>(vs) {}
|
|
||||||
|
|
||||||
void clip_box(double _x1, double _y1, double _x2, double _y2)
|
double x1() const { return base_type::vpgen().x1(); }
|
||||||
{
|
double y1() const { return base_type::vpgen().y1(); }
|
||||||
base_type::vpgen().clip_box(_x1, _y1, _x2, _y2);
|
double x2() const { return base_type::vpgen().x2(); }
|
||||||
}
|
double y2() const { return base_type::vpgen().y2(); }
|
||||||
|
unsigned type() const { return base_type::type(); }
|
||||||
|
|
||||||
double x1() const { return base_type::vpgen().x1(); }
|
private:
|
||||||
double y1() const { return base_type::vpgen().y1(); }
|
conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
|
||||||
double x2() const { return base_type::vpgen().x2(); }
|
const conv_clip_polygon<VertexSource>& operator=(const conv_clip_polygon<VertexSource>&);
|
||||||
double y2() const { return base_type::vpgen().y2(); }
|
};
|
||||||
unsigned type() const { return base_type::type(); }
|
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
|
|
||||||
const conv_clip_polygon<VertexSource>&
|
|
||||||
operator = (const conv_clip_polygon<VertexSource>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
56
deps/agg/include/agg_conv_clip_polyline.h
vendored
56
deps/agg/include/agg_conv_clip_polyline.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -14,12 +14,12 @@
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// polyline clipping converter
|
// polyline clipping converter
|
||||||
// There an optimized Liang-Basky algorithm is used.
|
// There an optimized Liang-Basky algorithm is used.
|
||||||
// The algorithm doesn't optimize the degenerate edges, i.e. it will never
|
// 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
|
// break a closed polyline into two or more ones, instead, there will be
|
||||||
// degenerate edges coinciding with the respective clipping boundaries.
|
// degenerate edges coinciding with the respective clipping boundaries.
|
||||||
// This is a sub-optimal solution, because that optimization would require
|
// This is a sub-optimal solution, because that optimization would require
|
||||||
// extra, rather expensive math while the rasterizer tolerates it quite well,
|
// extra, rather expensive math while the rasterizer tolerates it quite well,
|
||||||
// without any considerable overhead.
|
// without any considerable overhead.
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -30,35 +30,31 @@
|
||||||
#include "agg_conv_adaptor_vpgen.h"
|
#include "agg_conv_adaptor_vpgen.h"
|
||||||
#include "agg_vpgen_clip_polyline.h"
|
#include "agg_vpgen_clip_polyline.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
conv_clip_polyline(VertexSource& vs)
|
||||||
template<class VertexSource>
|
: conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs)
|
||||||
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) :
|
void clip_box(double _x1, double _y1, double _x2, double _y2) { base_type::vpgen().clip_box(_x1, _y1, _x2, _y2); }
|
||||||
conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs) {}
|
|
||||||
|
|
||||||
void clip_box(double _x1, double _y1, double _x2, double _y2)
|
double x1() const { return base_type::vpgen().x1(); }
|
||||||
{
|
double y1() const { return base_type::vpgen().y1(); }
|
||||||
base_type::vpgen().clip_box(_x1, _y1, _x2, _y2);
|
double x2() const { return base_type::vpgen().x2(); }
|
||||||
}
|
double y2() const { return base_type::vpgen().y2(); }
|
||||||
|
unsigned type() const { return base_type::type(); }
|
||||||
|
|
||||||
double x1() const { return base_type::vpgen().x1(); }
|
private:
|
||||||
double y1() const { return base_type::vpgen().y1(); }
|
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
|
||||||
double x2() const { return base_type::vpgen().x2(); }
|
const conv_clip_polyline<VertexSource>& operator=(const conv_clip_polyline<VertexSource>&);
|
||||||
double y2() const { return base_type::vpgen().y2(); }
|
};
|
||||||
unsigned type() const { return base_type::type(); }
|
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
|
|
||||||
const conv_clip_polyline<VertexSource>&
|
|
||||||
operator = (const conv_clip_polyline<VertexSource>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
195
deps/agg/include/agg_conv_close_polygon.h
vendored
195
deps/agg/include/agg_conv_close_polygon.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,108 +18,105 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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; }
|
||||||
|
|
||||||
//======================================================conv_close_polygon
|
void rewind(unsigned path_id);
|
||||||
template<class VertexSource> class conv_close_polygon
|
unsigned vertex(double* x, double* y);
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit conv_close_polygon(VertexSource& vs) : m_source(&vs) {}
|
|
||||||
void attach(VertexSource& source) { m_source = &source; }
|
|
||||||
|
|
||||||
void rewind(unsigned path_id);
|
private:
|
||||||
unsigned vertex(double* x, double* y);
|
conv_close_polygon(const conv_close_polygon<VertexSource>&);
|
||||||
|
const conv_close_polygon<VertexSource>& operator=(const conv_close_polygon<VertexSource>&);
|
||||||
|
|
||||||
private:
|
VertexSource* m_source;
|
||||||
conv_close_polygon(const conv_close_polygon<VertexSource>&);
|
unsigned m_cmd[2];
|
||||||
const conv_close_polygon<VertexSource>&
|
double m_x[2];
|
||||||
operator = (const conv_close_polygon<VertexSource>&);
|
double m_y[2];
|
||||||
|
unsigned m_vertex;
|
||||||
VertexSource* m_source;
|
bool m_line_to;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
93
deps/agg/include/agg_conv_concat.h
vendored
93
deps/agg/include/agg_conv_concat.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,56 +18,57 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
||||||
{
|
{
|
||||||
//=============================================================conv_concat
|
public:
|
||||||
// Concatenation of two paths. Usually used to combine lines or curves
|
conv_concat(VS1& source1, VS2& source2)
|
||||||
// with markers such as arrowheads
|
: m_source1(&source1)
|
||||||
template<class VS1, class VS2> class conv_concat
|
, 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)
|
||||||
{
|
{
|
||||||
public:
|
m_source1->rewind(path_id);
|
||||||
conv_concat(VS1& source1, VS2& source2) :
|
m_source2->rewind(0);
|
||||||
m_source1(&source1), m_source2(&source2), m_status(2) {}
|
m_status = 0;
|
||||||
void attach1(VS1& source) { m_source1 = &source; }
|
}
|
||||||
void attach2(VS2& source) { m_source2 = &source; }
|
|
||||||
|
|
||||||
|
unsigned vertex(double* x, double* y)
|
||||||
void rewind(unsigned path_id)
|
{
|
||||||
{
|
unsigned cmd;
|
||||||
m_source1->rewind(path_id);
|
if (m_status == 0)
|
||||||
m_source2->rewind(0);
|
|
||||||
m_status = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned vertex(double* x, double* y)
|
|
||||||
{
|
{
|
||||||
unsigned cmd;
|
cmd = m_source1->vertex(x, y);
|
||||||
if(m_status == 0)
|
if (!is_stop(cmd))
|
||||||
{
|
return cmd;
|
||||||
cmd = m_source1->vertex(x, y);
|
m_status = 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
if (m_status == 1)
|
||||||
|
{
|
||||||
|
cmd = m_source2->vertex(x, y);
|
||||||
|
if (!is_stop(cmd))
|
||||||
|
return cmd;
|
||||||
|
m_status = 2;
|
||||||
|
}
|
||||||
|
return path_cmd_stop;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
conv_concat(const conv_concat<VS1, VS2>&);
|
conv_concat(const conv_concat<VS1, VS2>&);
|
||||||
const conv_concat<VS1, VS2>&
|
const conv_concat<VS1, VS2>& operator=(const conv_concat<VS1, VS2>&);
|
||||||
operator = (const conv_concat<VS1, VS2>&);
|
|
||||||
|
|
||||||
VS1* m_source1;
|
|
||||||
VS2* m_source2;
|
|
||||||
int m_status;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
VS1* m_source1;
|
||||||
|
VS2* m_source2;
|
||||||
|
int m_status;
|
||||||
|
};
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
65
deps/agg/include/agg_conv_contour.h
vendored
65
deps/agg/include/agg_conv_contour.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,43 +23,40 @@
|
||||||
#include "agg_vcgen_contour.h"
|
#include "agg_vcgen_contour.h"
|
||||||
#include "agg_conv_adaptor_vcgen.h"
|
#include "agg_conv_adaptor_vcgen.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
conv_contour(VertexSource& vs)
|
||||||
template<class VertexSource>
|
: conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs)
|
||||||
struct conv_contour : public conv_adaptor_vcgen<VertexSource, vcgen_contour>
|
{}
|
||||||
{
|
|
||||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type;
|
|
||||||
|
|
||||||
conv_contour(VertexSource& vs) :
|
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
|
||||||
conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs)
|
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); }
|
||||||
|
|
||||||
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
|
line_join_e line_join() const { return base_type::generator().line_join(); }
|
||||||
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
|
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
|
||||||
void width(double w) { base_type::generator().width(w); }
|
double width() const { return base_type::generator().width(); }
|
||||||
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
|
double miter_limit() const { return base_type::generator().miter_limit(); }
|
||||||
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
|
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
|
||||||
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
|
double approximation_scale() const { return base_type::generator().approximation_scale(); }
|
||||||
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
|
bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); }
|
||||||
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(); }
|
private:
|
||||||
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
|
conv_contour(const conv_contour<VertexSource>&);
|
||||||
double width() const { return base_type::generator().width(); }
|
const conv_contour<VertexSource>& operator=(const conv_contour<VertexSource>&);
|
||||||
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:
|
} // namespace agg
|
||||||
conv_contour(const conv_contour<VertexSource>&);
|
|
||||||
const conv_contour<VertexSource>&
|
|
||||||
operator = (const conv_contour<VertexSource>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
279
deps/agg/include/agg_conv_curve.h
vendored
279
deps/agg/include/agg_conv_curve.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,157 +23,140 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_curves.h"
|
#include "agg_curves.h"
|
||||||
|
|
||||||
namespace agg
|
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)
|
||||||
|
{}
|
||||||
|
|
||||||
//---------------------------------------------------------------conv_curve
|
conv_curve(self_type&&) = default;
|
||||||
// Curve converter class. Any path storage can have Bezier curves defined
|
|
||||||
// by their control points. There're two types of curves supported: curve3
|
void attach(VertexSource& source) { m_source = &source; }
|
||||||
// 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
|
void approximation_method(curve_approximation_method_e v)
|
||||||
// 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:
|
m_curve3.approximation_method(v);
|
||||||
typedef Curve3 curve3_type;
|
m_curve4.approximation_method(v);
|
||||||
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) {}
|
|
||||||
|
|
||||||
conv_curve(self_type &&) = default;
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curve_approximation_method_e approximation_method() const { return m_curve4.approximation_method(); }
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
void approximation_scale(double s)
|
||||||
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_curve3.approximation_scale(s);
|
||||||
{
|
m_curve4.approximation_scale(s);
|
||||||
m_last_x = *x;
|
}
|
||||||
m_last_y = *y;
|
|
||||||
return path_cmd_line_to;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!is_stop(m_curve4.vertex(x, y)))
|
double approximation_scale() const { return m_curve4.approximation_scale(); }
|
||||||
{
|
|
||||||
m_last_x = *x;
|
|
||||||
m_last_y = *y;
|
|
||||||
return path_cmd_line_to;
|
|
||||||
}
|
|
||||||
|
|
||||||
double ct2_x=0;
|
void angle_tolerance(double v)
|
||||||
double ct2_y=0;
|
{
|
||||||
double end_x=0;
|
m_curve3.angle_tolerance(v);
|
||||||
double end_y=0;
|
m_curve4.angle_tolerance(v);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned cmd = m_source->vertex(x, y);
|
double angle_tolerance() const { return m_curve4.angle_tolerance(); }
|
||||||
switch(cmd)
|
|
||||||
{
|
void cusp_limit(double v)
|
||||||
|
{
|
||||||
|
m_curve3.cusp_limit(v);
|
||||||
|
m_curve4.cusp_limit(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
double cusp_limit() const { return m_curve4.cusp_limit(); }
|
||||||
|
|
||||||
|
void rewind(unsigned path_id);
|
||||||
|
unsigned vertex(double* x, double* y);
|
||||||
|
|
||||||
|
private:
|
||||||
|
conv_curve(const self_type&);
|
||||||
|
const self_type& operator=(const self_type&);
|
||||||
|
|
||||||
|
VertexSource* m_source;
|
||||||
|
double m_last_x;
|
||||||
|
double m_last_y;
|
||||||
|
curve3_type m_curve3;
|
||||||
|
curve4_type m_curve4;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
template<class VertexSource, class Curve3, class Curve4>
|
||||||
|
void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id)
|
||||||
|
{
|
||||||
|
m_source->rewind(path_id);
|
||||||
|
m_last_x = 0.0;
|
||||||
|
m_last_y = 0.0;
|
||||||
|
m_curve3.reset();
|
||||||
|
m_curve4.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
template<class VertexSource, class Curve3, class Curve4>
|
||||||
|
unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
|
||||||
|
{
|
||||||
|
if (!is_stop(m_curve3.vertex(x, y)))
|
||||||
|
{
|
||||||
|
m_last_x = *x;
|
||||||
|
m_last_y = *y;
|
||||||
|
return path_cmd_line_to;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_stop(m_curve4.vertex(x, y)))
|
||||||
|
{
|
||||||
|
m_last_x = *x;
|
||||||
|
m_last_y = *y;
|
||||||
|
return path_cmd_line_to;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ct2_x = 0;
|
||||||
|
double ct2_y = 0;
|
||||||
|
double end_x = 0;
|
||||||
|
double end_y = 0;
|
||||||
|
|
||||||
|
unsigned cmd = m_source->vertex(x, y);
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
case path_cmd_curve3:
|
case path_cmd_curve3:
|
||||||
m_source->vertex(&end_x, &end_y);
|
m_source->vertex(&end_x, &end_y);
|
||||||
|
|
||||||
m_curve3.init(m_last_x, m_last_y,
|
m_curve3.init(m_last_x, m_last_y, *x, *y, end_x, end_y);
|
||||||
*x, *y,
|
|
||||||
end_x, end_y);
|
|
||||||
|
|
||||||
m_curve3.vertex(x, y); // First call returns path_cmd_move_to
|
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
|
m_curve3.vertex(x, y); // This is the first vertex of the curve
|
||||||
cmd = path_cmd_line_to;
|
cmd = path_cmd_line_to;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -181,24 +164,18 @@ namespace agg
|
||||||
m_source->vertex(&ct2_x, &ct2_y);
|
m_source->vertex(&ct2_x, &ct2_y);
|
||||||
m_source->vertex(&end_x, &end_y);
|
m_source->vertex(&end_x, &end_y);
|
||||||
|
|
||||||
m_curve4.init(m_last_x, m_last_y,
|
m_curve4.init(m_last_x, m_last_y, *x, *y, ct2_x, ct2_y, end_x, end_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); // First call returns path_cmd_move_to
|
||||||
m_curve4.vertex(x, y); // This is the first vertex of the curve
|
m_curve4.vertex(x, y); // This is the first vertex of the curve
|
||||||
cmd = path_cmd_line_to;
|
cmd = path_cmd_line_to;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
m_last_x = *x;
|
|
||||||
m_last_y = *y;
|
|
||||||
return cmd;
|
|
||||||
}
|
}
|
||||||
|
m_last_x = *x;
|
||||||
|
m_last_y = *y;
|
||||||
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
57
deps/agg/include/agg_conv_dash.h
vendored
57
deps/agg/include/agg_conv_dash.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,46 +23,33 @@
|
||||||
#include "agg_vcgen_dash.h"
|
#include "agg_vcgen_dash.h"
|
||||||
#include "agg_conv_adaptor_vcgen.h"
|
#include "agg_conv_adaptor_vcgen.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
conv_dash(VertexSource& vs)
|
||||||
template<class VertexSource, class Markers=null_markers>
|
: conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>(vs)
|
||||||
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) :
|
void remove_all_dashes() { base_type::generator().remove_all_dashes(); }
|
||||||
conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>(vs)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_all_dashes()
|
void add_dash(double dash_len, double gap_len) { base_type::generator().add_dash(dash_len, gap_len); }
|
||||||
{
|
|
||||||
base_type::generator().remove_all_dashes();
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_dash(double dash_len, double gap_len)
|
void dash_start(double ds) { base_type::generator().dash_start(ds); }
|
||||||
{
|
|
||||||
base_type::generator().add_dash(dash_len, gap_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dash_start(double ds)
|
void shorten(double s) { base_type::generator().shorten(s); }
|
||||||
{
|
double shorten() const { return base_type::generator().shorten(); }
|
||||||
base_type::generator().dash_start(ds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shorten(double s) { base_type::generator().shorten(s); }
|
private:
|
||||||
double shorten() const { return base_type::generator().shorten(); }
|
conv_dash(const conv_dash<VertexSource, Markers>&);
|
||||||
|
const conv_dash<VertexSource, Markers>& operator=(const conv_dash<VertexSource, Markers>&);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
conv_dash(const conv_dash<VertexSource, Markers>&);
|
|
||||||
const conv_dash<VertexSource, Markers>&
|
|
||||||
operator = (const conv_dash<VertexSource, Markers>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
690
deps/agg/include/agg_conv_gpc.h
vendored
690
deps/agg/include/agg_conv_gpc.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
// http://www.antigrain.com
|
// http://www.antigrain.com
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// General Polygon Clipper based on the GPC library by Alan Murta
|
// General Polygon Clipper based on the GPC library by Alan Murta
|
||||||
// Union, Intersection, XOR, A-B, B-A
|
// Union, Intersection, XOR, A-B, B-A
|
||||||
// Contact the author if you intend to use it in commercial applications!
|
// Contact the author if you intend to use it in commercial applications!
|
||||||
// http://www.cs.man.ac.uk/aig/staff/alan/software/
|
// http://www.cs.man.ac.uk/aig/staff/alan/software/
|
||||||
|
@ -28,405 +28,353 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "gpc.h"
|
#include "gpc.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace agg
|
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 gpc_op_e
|
enum status { status_move_to, status_line_to, status_stop };
|
||||||
|
|
||||||
|
struct contour_header_type
|
||||||
{
|
{
|
||||||
gpc_or,
|
int num_vertices;
|
||||||
gpc_and,
|
int hole_flag;
|
||||||
gpc_xor,
|
gpc_vertex* vertices;
|
||||||
gpc_a_minus_b,
|
|
||||||
gpc_b_minus_a
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef pod_bvector<gpc_vertex, 8> vertex_array_type;
|
||||||
|
typedef pod_bvector<contour_header_type, 6> contour_header_array_type;
|
||||||
|
|
||||||
//================================================================conv_gpc
|
public:
|
||||||
template<class VSA, class VSB> class conv_gpc
|
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)
|
||||||
{
|
{
|
||||||
enum status
|
memset(&m_poly_a, 0, sizeof(m_poly_a));
|
||||||
{
|
memset(&m_poly_b, 0, sizeof(m_poly_b));
|
||||||
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));
|
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; }
|
||||||
template<class VSA, class VSB>
|
|
||||||
void conv_gpc<VSA, VSB>::free_gpc_data()
|
// 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)
|
||||||
{
|
{
|
||||||
free_polygon(m_poly_a);
|
unsigned cmd;
|
||||||
free_polygon(m_poly_b);
|
double x, y;
|
||||||
free_result();
|
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)))
|
||||||
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)
|
if (is_vertex(cmd))
|
||||||
{
|
{
|
||||||
contour_header_type& h =
|
if (is_move_to(cmd))
|
||||||
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];
|
if (line_to)
|
||||||
d->x = s.x;
|
{
|
||||||
d->y = s.y;
|
end_contour(orientation);
|
||||||
++d;
|
orientation = 0;
|
||||||
|
}
|
||||||
|
start_contour();
|
||||||
|
start_x = x;
|
||||||
|
start_y = y;
|
||||||
}
|
}
|
||||||
|
add_vertex(x, y);
|
||||||
|
line_to = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_vertex_accumulator.remove_last();
|
if (is_end_poly(cmd))
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
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;
|
orientation = get_orientation(cmd);
|
||||||
return path_cmd_move_to;
|
if (line_to && is_closed(cmd))
|
||||||
|
{
|
||||||
|
add_vertex(start_x, start_y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_status = status_stop;
|
}
|
||||||
return path_cmd_end_poly | path_flags_close;
|
}
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
if(next_vertex(x, y))
|
m_vertex_accumulator.remove_last();
|
||||||
{
|
|
||||||
return path_cmd_line_to;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_status = status_move_to;
|
|
||||||
}
|
|
||||||
return path_cmd_end_poly | path_flags_close;
|
|
||||||
}
|
}
|
||||||
return path_cmd_stop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
146
deps/agg/include/agg_conv_marker.h
vendored
146
deps/agg/include/agg_conv_marker.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -22,82 +22,70 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_trans_affine.h"
|
#include "agg_trans_affine.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//-------------------------------------------------------------conv_marker
|
||||||
|
template<class MarkerLocator, class MarkerShapes>
|
||||||
|
class conv_marker
|
||||||
{
|
{
|
||||||
//-------------------------------------------------------------conv_marker
|
public:
|
||||||
template<class MarkerLocator, class MarkerShapes>
|
conv_marker(MarkerLocator& ml, MarkerShapes& ms);
|
||||||
class conv_marker
|
|
||||||
|
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))
|
||||||
{
|
{
|
||||||
public:
|
switch (m_status)
|
||||||
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:
|
case initial:
|
||||||
if(m_num_markers == 0)
|
if (m_num_markers == 0)
|
||||||
{
|
{
|
||||||
cmd = path_cmd_stop;
|
cmd = path_cmd_stop;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_marker_locator->rewind(m_marker);
|
m_marker_locator->rewind(m_marker);
|
||||||
++m_marker;
|
++m_marker;
|
||||||
|
@ -105,12 +93,12 @@ namespace agg
|
||||||
m_status = markers;
|
m_status = markers;
|
||||||
|
|
||||||
case markers:
|
case markers:
|
||||||
if(is_stop(m_marker_locator->vertex(&x1, &y1)))
|
if (is_stop(m_marker_locator->vertex(&x1, &y1)))
|
||||||
{
|
{
|
||||||
m_status = initial;
|
m_status = initial;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(is_stop(m_marker_locator->vertex(&x2, &y2)))
|
if (is_stop(m_marker_locator->vertex(&x2, &y2)))
|
||||||
{
|
{
|
||||||
m_status = initial;
|
m_status = initial;
|
||||||
break;
|
break;
|
||||||
|
@ -124,7 +112,7 @@ namespace agg
|
||||||
|
|
||||||
case polygon:
|
case polygon:
|
||||||
cmd = m_marker_shapes->vertex(x, y);
|
cmd = m_marker_shapes->vertex(x, y);
|
||||||
if(is_stop(cmd))
|
if (is_stop(cmd))
|
||||||
{
|
{
|
||||||
cmd = path_cmd_move_to;
|
cmd = path_cmd_move_to;
|
||||||
m_status = markers;
|
m_status = markers;
|
||||||
|
@ -136,13 +124,11 @@ namespace agg
|
||||||
case stop:
|
case stop:
|
||||||
cmd = path_cmd_stop;
|
cmd = path_cmd_stop;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return cmd;
|
|
||||||
}
|
}
|
||||||
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
43
deps/agg/include/agg_conv_marker_adaptor.h
vendored
43
deps/agg/include/agg_conv_marker_adaptor.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -20,32 +20,27 @@
|
||||||
#include "agg_conv_adaptor_vcgen.h"
|
#include "agg_conv_adaptor_vcgen.h"
|
||||||
#include "agg_vcgen_vertex_sequence.h"
|
#include "agg_vcgen_vertex_sequence.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
conv_marker_adaptor(VertexSource& vs)
|
||||||
template<class VertexSource, class Markers=null_markers>
|
: conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>(vs)
|
||||||
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) :
|
void shorten(double s) { base_type::generator().shorten(s); }
|
||||||
conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>(vs)
|
double shorten() const { return base_type::generator().shorten(); }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void shorten(double s) { base_type::generator().shorten(s); }
|
private:
|
||||||
double shorten() const { return base_type::generator().shorten(); }
|
conv_marker_adaptor(const conv_marker_adaptor<VertexSource, Markers>&);
|
||||||
|
const conv_marker_adaptor<VertexSource, Markers>& operator=(const conv_marker_adaptor<VertexSource, Markers>&);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
conv_marker_adaptor(const conv_marker_adaptor<VertexSource, Markers>&);
|
|
||||||
const conv_marker_adaptor<VertexSource, Markers>&
|
|
||||||
operator = (const conv_marker_adaptor<VertexSource, Markers>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
139
deps/agg/include/agg_conv_offset.h
vendored
139
deps/agg/include/agg_conv_offset.h
vendored
|
@ -22,59 +22,53 @@
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
#include "clipper.hpp"
|
#include "clipper.hpp"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
{
|
|
||||||
|
|
||||||
template<class VSA> class conv_offset
|
template<class VSA>
|
||||||
|
class conv_offset
|
||||||
{
|
{
|
||||||
enum status { status_move_to, status_line_to, status_stop };
|
enum status { status_move_to, status_line_to, status_stop };
|
||||||
typedef VSA source_a_type;
|
typedef VSA source_a_type;
|
||||||
typedef conv_offset<source_a_type> self_type;
|
typedef conv_offset<source_a_type> self_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
source_a_type* m_src_a;
|
source_a_type* m_src_a;
|
||||||
double m_offset;
|
double m_offset;
|
||||||
status m_status;
|
status m_status;
|
||||||
int m_vertex;
|
int m_vertex;
|
||||||
int m_contour;
|
int m_contour;
|
||||||
int m_scaling_factor;
|
int m_scaling_factor;
|
||||||
pod_bvector<ClipperLib::IntPoint, 8> m_vertex_accumulator;
|
pod_bvector<ClipperLib::IntPoint, 8> m_vertex_accumulator;
|
||||||
ClipperLib::Paths m_poly_a;
|
ClipperLib::Paths m_poly_a;
|
||||||
ClipperLib::Paths m_result;
|
ClipperLib::Paths m_result;
|
||||||
ClipperLib::ClipperOffset m_clipper_offset;
|
ClipperLib::ClipperOffset m_clipper_offset;
|
||||||
|
|
||||||
int Round(double val)
|
int Round(double val)
|
||||||
{
|
{
|
||||||
if ((val < 0)) return (int)(val - 0.5); else return (int)(val + 0.5);
|
if ((val < 0))
|
||||||
|
return (int)(val - 0.5);
|
||||||
|
else
|
||||||
|
return (int)(val + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
conv_offset(source_a_type &a, double offset = 0.0,
|
conv_offset(source_a_type& a, double offset = 0.0, int scaling_factor = 0)
|
||||||
int scaling_factor = 0)
|
: m_src_a(&a)
|
||||||
: m_src_a(&a),
|
, m_offset(offset)
|
||||||
m_offset(offset),
|
, m_status(status_move_to)
|
||||||
m_status(status_move_to),
|
, m_vertex(-1)
|
||||||
m_vertex(-1),
|
, m_contour(-1)
|
||||||
m_contour(-1)
|
|
||||||
{
|
{
|
||||||
m_scaling_factor = std::max(std::min(scaling_factor, 6),0);
|
m_scaling_factor = std::max(std::min(scaling_factor, 6), 0);
|
||||||
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
|
m_scaling_factor = Round(std::pow((double)10, m_scaling_factor));
|
||||||
}
|
}
|
||||||
|
|
||||||
~conv_offset()
|
~conv_offset() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_offset(double offset) { m_offset = offset;}
|
void set_offset(double offset) { m_offset = offset; }
|
||||||
unsigned type() const
|
unsigned type() const { return static_cast<unsigned>(m_src_a->type()); }
|
||||||
{
|
|
||||||
return static_cast<unsigned>(m_src_a->type());
|
|
||||||
}
|
|
||||||
|
|
||||||
double get_offset() const
|
double get_offset() const { return m_offset; }
|
||||||
{
|
|
||||||
return m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rewind(unsigned path_id);
|
void rewind(unsigned path_id);
|
||||||
unsigned vertex(double* x, double* y);
|
unsigned vertex(double* x, double* y);
|
||||||
|
@ -82,13 +76,17 @@ public:
|
||||||
bool next_contour();
|
bool next_contour();
|
||||||
bool next_vertex(double* x, double* y);
|
bool next_vertex(double* x, double* y);
|
||||||
void start_extracting();
|
void start_extracting();
|
||||||
void add_vertex_(double &x, double &y);
|
void add_vertex_(double& x, double& y);
|
||||||
void end_contour(ClipperLib::Paths &p);
|
void end_contour(ClipperLib::Paths& p);
|
||||||
|
|
||||||
template<class VS> void add(VS &src, ClipperLib::Paths &p)
|
template<class VS>
|
||||||
|
void add(VS& src, ClipperLib::Paths& p)
|
||||||
{
|
{
|
||||||
unsigned cmd;
|
unsigned cmd;
|
||||||
double x; double y; double start_x; double start_y;
|
double x;
|
||||||
|
double y;
|
||||||
|
double start_x;
|
||||||
|
double start_y;
|
||||||
bool starting_first_line;
|
bool starting_first_line;
|
||||||
|
|
||||||
start_x = 0.0;
|
start_x = 0.0;
|
||||||
|
@ -96,26 +94,27 @@ public:
|
||||||
starting_first_line = true;
|
starting_first_line = true;
|
||||||
p.resize(0);
|
p.resize(0);
|
||||||
|
|
||||||
cmd = src->vertex( &x , &y );
|
cmd = src->vertex(&x, &y);
|
||||||
while(!is_stop(cmd))
|
while (!is_stop(cmd))
|
||||||
{
|
{
|
||||||
if(is_vertex(cmd))
|
if (is_vertex(cmd))
|
||||||
{
|
{
|
||||||
if(is_move_to(cmd))
|
if (is_move_to(cmd))
|
||||||
{
|
{
|
||||||
if(!starting_first_line ) end_contour(p);
|
if (!starting_first_line)
|
||||||
|
end_contour(p);
|
||||||
start_x = x;
|
start_x = x;
|
||||||
start_y = y;
|
start_y = y;
|
||||||
}
|
}
|
||||||
add_vertex_( x, y );
|
add_vertex_(x, y);
|
||||||
starting_first_line = false;
|
starting_first_line = false;
|
||||||
}
|
}
|
||||||
else if(is_end_poly(cmd))
|
else if (is_end_poly(cmd))
|
||||||
{
|
{
|
||||||
if(!starting_first_line && is_closed(cmd))
|
if (!starting_first_line && is_closed(cmd))
|
||||||
add_vertex_( start_x, start_y );
|
add_vertex_(start_x, start_y);
|
||||||
}
|
}
|
||||||
cmd = src->vertex( &x, &y );
|
cmd = src->vertex(&x, &y);
|
||||||
}
|
}
|
||||||
end_contour(p);
|
end_contour(p);
|
||||||
}
|
}
|
||||||
|
@ -135,42 +134,43 @@ void conv_offset<VSA>::start_extracting()
|
||||||
template<class VSA>
|
template<class VSA>
|
||||||
void conv_offset<VSA>::rewind(unsigned path_id)
|
void conv_offset<VSA>::rewind(unsigned path_id)
|
||||||
{
|
{
|
||||||
m_src_a->rewind( path_id );
|
m_src_a->rewind(path_id);
|
||||||
//m_src_b->rewind( path_id );
|
// m_src_b->rewind( path_id );
|
||||||
|
|
||||||
add( m_src_a , m_poly_a );
|
add(m_src_a, m_poly_a);
|
||||||
//add( m_src_b , m_poly_b );
|
// add( m_src_b , m_poly_b );
|
||||||
m_result.resize(0);
|
m_result.resize(0);
|
||||||
m_clipper_offset.Clear();
|
m_clipper_offset.Clear();
|
||||||
m_clipper_offset.AddPaths(m_poly_a,ClipperLib::jtMiter, ClipperLib::etOpenButt);//ClosedLine);//Polygon);
|
m_clipper_offset.AddPaths(m_poly_a, ClipperLib::jtMiter, ClipperLib::etOpenButt); // ClosedLine);//Polygon);
|
||||||
m_clipper_offset.Execute(m_result, m_offset * m_scaling_factor);
|
m_clipper_offset.Execute(m_result, m_offset * m_scaling_factor);
|
||||||
start_extracting();
|
start_extracting();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class VSA>
|
template<class VSA>
|
||||||
void conv_offset<VSA>::end_contour( ClipperLib::Paths &p)
|
void conv_offset<VSA>::end_contour(ClipperLib::Paths& p)
|
||||||
{
|
{
|
||||||
unsigned i, len;
|
unsigned i, len;
|
||||||
|
|
||||||
if( m_vertex_accumulator.size() < 3 ) return;
|
if (m_vertex_accumulator.size() < 3)
|
||||||
|
return;
|
||||||
len = p.size();
|
len = p.size();
|
||||||
p.resize(len+1);
|
p.resize(len + 1);
|
||||||
p[len].resize(m_vertex_accumulator.size());
|
p[len].resize(m_vertex_accumulator.size());
|
||||||
for( i = 0 ; i < m_vertex_accumulator.size() ; i++ )
|
for (i = 0; i < m_vertex_accumulator.size(); i++)
|
||||||
p[len][i] = m_vertex_accumulator[i];
|
p[len][i] = m_vertex_accumulator[i];
|
||||||
m_vertex_accumulator.remove_all();
|
m_vertex_accumulator.remove_all();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class VSA>
|
template<class VSA>
|
||||||
void conv_offset<VSA>::add_vertex_(double &x, double &y)
|
void conv_offset<VSA>::add_vertex_(double& x, double& y)
|
||||||
{
|
{
|
||||||
ClipperLib::IntPoint v;
|
ClipperLib::IntPoint v;
|
||||||
|
|
||||||
v.X = Round(x * m_scaling_factor);
|
v.X = Round(x * m_scaling_factor);
|
||||||
v.Y = Round(y * m_scaling_factor);
|
v.Y = Round(y * m_scaling_factor);
|
||||||
m_vertex_accumulator.add( v );
|
m_vertex_accumulator.add(v);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -178,33 +178,35 @@ template<class VSA>
|
||||||
bool conv_offset<VSA>::next_contour()
|
bool conv_offset<VSA>::next_contour()
|
||||||
{
|
{
|
||||||
m_contour++;
|
m_contour++;
|
||||||
if(m_contour >= (int)m_result.size()) return false;
|
if (m_contour >= (int)m_result.size())
|
||||||
m_vertex =-1;
|
return false;
|
||||||
|
m_vertex = -1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class VSA>
|
template<class VSA>
|
||||||
bool conv_offset<VSA>::next_vertex(double *x, double *y)
|
bool conv_offset<VSA>::next_vertex(double* x, double* y)
|
||||||
{
|
{
|
||||||
m_vertex++;
|
m_vertex++;
|
||||||
if(m_vertex >= (int)m_result[m_contour].size()) return false;
|
if (m_vertex >= (int)m_result[m_contour].size())
|
||||||
*x = (double)m_result[ m_contour ][ m_vertex ].X / m_scaling_factor;
|
return false;
|
||||||
*y = (double)m_result[ m_contour ][ m_vertex ].Y / m_scaling_factor;
|
*x = (double)m_result[m_contour][m_vertex].X / m_scaling_factor;
|
||||||
|
*y = (double)m_result[m_contour][m_vertex].Y / m_scaling_factor;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class VSA>
|
template<class VSA>
|
||||||
unsigned conv_offset<VSA>::vertex(double *x, double *y)
|
unsigned conv_offset<VSA>::vertex(double* x, double* y)
|
||||||
{
|
{
|
||||||
if( m_status == status_move_to )
|
if (m_status == status_move_to)
|
||||||
{
|
{
|
||||||
if( next_contour() )
|
if (next_contour())
|
||||||
{
|
{
|
||||||
if( next_vertex( x, y ) )
|
if (next_vertex(x, y))
|
||||||
{
|
{
|
||||||
m_status =status_line_to;
|
m_status = status_line_to;
|
||||||
return path_cmd_move_to;
|
return path_cmd_move_to;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -218,7 +220,7 @@ unsigned conv_offset<VSA>::vertex(double *x, double *y)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( next_vertex( x, y ) )
|
if (next_vertex(x, y))
|
||||||
{
|
{
|
||||||
return path_cmd_line_to;
|
return path_cmd_line_to;
|
||||||
}
|
}
|
||||||
|
@ -231,6 +233,5 @@ unsigned conv_offset<VSA>::vertex(double *x, double *y)
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
} //namespace agg
|
#endif // AGG_CONV_OFFSET_INCLUDED
|
||||||
#endif //AGG_CONV_OFFSET_INCLUDED
|
|
||||||
|
|
39
deps/agg/include/agg_conv_segmentator.h
vendored
39
deps/agg/include/agg_conv_segmentator.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -20,29 +20,26 @@
|
||||||
#include "agg_conv_adaptor_vpgen.h"
|
#include "agg_conv_adaptor_vpgen.h"
|
||||||
#include "agg_vpgen_segmentator.h"
|
#include "agg_vpgen_segmentator.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
conv_segmentator(VertexSource& vs)
|
||||||
template<class VertexSource>
|
: conv_adaptor_vpgen<VertexSource, vpgen_segmentator>(vs)
|
||||||
struct conv_segmentator : public conv_adaptor_vpgen<VertexSource, vpgen_segmentator>
|
{}
|
||||||
{
|
|
||||||
typedef conv_adaptor_vpgen<VertexSource, vpgen_segmentator> base_type;
|
|
||||||
|
|
||||||
conv_segmentator(VertexSource& vs) :
|
void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); }
|
||||||
conv_adaptor_vpgen<VertexSource, vpgen_segmentator>(vs) {}
|
double approximation_scale() const { return base_type::vpgen().approximation_scale(); }
|
||||||
|
|
||||||
void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); }
|
private:
|
||||||
double approximation_scale() const { return base_type::vpgen().approximation_scale(); }
|
conv_segmentator(const conv_segmentator<VertexSource>&);
|
||||||
|
const conv_segmentator<VertexSource>& operator=(const conv_segmentator<VertexSource>&);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
conv_segmentator(const conv_segmentator<VertexSource>&);
|
|
||||||
const conv_segmentator<VertexSource>&
|
|
||||||
operator = (const conv_segmentator<VertexSource>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
42
deps/agg/include/agg_conv_shorten_path.h
vendored
42
deps/agg/include/agg_conv_shorten_path.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -20,31 +20,27 @@
|
||||||
#include "agg_conv_adaptor_vcgen.h"
|
#include "agg_conv_adaptor_vcgen.h"
|
||||||
#include "agg_vcgen_vertex_sequence.h"
|
#include "agg_vcgen_vertex_sequence.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
conv_shorten_path(VertexSource& vs)
|
||||||
template<class VertexSource> class conv_shorten_path :
|
: conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>(vs)
|
||||||
public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>
|
{}
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence> base_type;
|
|
||||||
|
|
||||||
conv_shorten_path(VertexSource& vs) :
|
void shorten(double s) { base_type::generator().shorten(s); }
|
||||||
conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>(vs)
|
double shorten() const { return base_type::generator().shorten(); }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void shorten(double s) { base_type::generator().shorten(s); }
|
private:
|
||||||
double shorten() const { return base_type::generator().shorten(); }
|
conv_shorten_path(const conv_shorten_path<VertexSource>&);
|
||||||
|
const conv_shorten_path<VertexSource>& operator=(const conv_shorten_path<VertexSource>&);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
conv_shorten_path(const conv_shorten_path<VertexSource>&);
|
|
||||||
const conv_shorten_path<VertexSource>&
|
|
||||||
operator = (const conv_shorten_path<VertexSource>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
110
deps/agg/include/agg_conv_smooth_poly1.h
vendored
110
deps/agg/include/agg_conv_smooth_poly1.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -24,70 +24,62 @@
|
||||||
#include "agg_conv_adaptor_vcgen.h"
|
#include "agg_conv_adaptor_vcgen.h"
|
||||||
#include "agg_conv_curve.h"
|
#include "agg_conv_curve.h"
|
||||||
|
|
||||||
|
namespace agg {
|
||||||
|
|
||||||
namespace agg
|
//-------------------------------------------------------conv_smooth
|
||||||
|
template<class VertexSource, class VertexGenerator>
|
||||||
|
struct conv_smooth : public conv_adaptor_vcgen<VertexSource, VertexGenerator>
|
||||||
{
|
{
|
||||||
|
typedef conv_adaptor_vcgen<VertexSource, VertexGenerator> base_type;
|
||||||
|
|
||||||
//-------------------------------------------------------conv_smooth
|
conv_smooth(VertexSource& vs)
|
||||||
template<class VertexSource, class VertexGenerator>
|
: conv_adaptor_vcgen<VertexSource, VertexGenerator>(vs)
|
||||||
struct conv_smooth :
|
{}
|
||||||
public conv_adaptor_vcgen<VertexSource, VertexGenerator>
|
|
||||||
|
conv_smooth(conv_smooth<VertexSource, VertexGenerator>&&) = default;
|
||||||
|
|
||||||
|
conv_smooth(const conv_smooth<VertexSource, VertexGenerator>&) = delete;
|
||||||
|
const conv_smooth<VertexSource, VertexGenerator>&
|
||||||
|
operator=(const conv_smooth<VertexSource, VertexGenerator>&) = delete;
|
||||||
|
|
||||||
|
void smooth_value(double v) { base_type::generator().smooth_value(v); }
|
||||||
|
double smooth_value() const { return base_type::generator().smooth_value(); }
|
||||||
|
unsigned type() const { return base_type::type(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class VertexSource>
|
||||||
|
using conv_smooth_poly1 = conv_smooth<VertexSource, vcgen_smooth_poly1>;
|
||||||
|
|
||||||
|
//-------------------------------------------------conv_smooth_curve
|
||||||
|
template<class VertexSource, class VertexGenerator>
|
||||||
|
struct conv_smooth_curve : public conv_curve<conv_smooth<VertexSource, VertexGenerator>>
|
||||||
|
{
|
||||||
|
conv_smooth_curve(VertexSource& vs)
|
||||||
|
: conv_curve<conv_smooth<VertexSource, VertexGenerator>>(m_smooth)
|
||||||
|
, m_smooth(vs)
|
||||||
|
{}
|
||||||
|
|
||||||
|
conv_smooth_curve(conv_smooth_curve<VertexSource, VertexGenerator>&& rhs)
|
||||||
|
: conv_curve<conv_smooth<VertexSource, VertexGenerator>>(std::move(rhs))
|
||||||
|
, m_smooth(std::move(rhs.m_smooth))
|
||||||
{
|
{
|
||||||
typedef conv_adaptor_vcgen<VertexSource, VertexGenerator> base_type;
|
this->attach(m_smooth);
|
||||||
|
}
|
||||||
|
|
||||||
conv_smooth(VertexSource& vs) :
|
conv_smooth_curve(const conv_smooth_curve<VertexSource, VertexGenerator>&) = delete;
|
||||||
conv_adaptor_vcgen<VertexSource, VertexGenerator>(vs)
|
const conv_smooth_curve<VertexSource, VertexGenerator>&
|
||||||
{
|
operator=(const conv_smooth_curve<VertexSource, VertexGenerator>&) = delete;
|
||||||
}
|
|
||||||
|
|
||||||
conv_smooth(conv_smooth<VertexSource, VertexGenerator> &&) = default;
|
void smooth_value(double v) { m_smooth.generator().smooth_value(v); }
|
||||||
|
double smooth_value() const { return m_smooth.generator().smooth_value(); }
|
||||||
|
unsigned type() const { return m_smooth.type(); }
|
||||||
|
|
||||||
conv_smooth(const conv_smooth<VertexSource, VertexGenerator>&) = delete;
|
private:
|
||||||
const conv_smooth<VertexSource, VertexGenerator>&
|
conv_smooth<VertexSource, VertexGenerator> m_smooth;
|
||||||
operator = (const conv_smooth<VertexSource, VertexGenerator>&) = delete;
|
};
|
||||||
|
|
||||||
void smooth_value(double v) { base_type::generator().smooth_value(v); }
|
|
||||||
double smooth_value() const { return base_type::generator().smooth_value(); }
|
|
||||||
unsigned type() const { return base_type::type(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class VertexSource>
|
|
||||||
using conv_smooth_poly1 = conv_smooth<VertexSource, vcgen_smooth_poly1>;
|
|
||||||
|
|
||||||
//-------------------------------------------------conv_smooth_curve
|
|
||||||
template<class VertexSource, class VertexGenerator>
|
|
||||||
struct conv_smooth_curve :
|
|
||||||
public conv_curve<conv_smooth<VertexSource, VertexGenerator>>
|
|
||||||
{
|
|
||||||
conv_smooth_curve(VertexSource& vs) :
|
|
||||||
conv_curve<conv_smooth<VertexSource, VertexGenerator>>(m_smooth),
|
|
||||||
m_smooth(vs)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
conv_smooth_curve(conv_smooth_curve<VertexSource, VertexGenerator> && rhs) :
|
|
||||||
conv_curve<conv_smooth<VertexSource, VertexGenerator>>(std::move(rhs)),
|
|
||||||
m_smooth(std::move(rhs.m_smooth))
|
|
||||||
{
|
|
||||||
this->attach(m_smooth);
|
|
||||||
}
|
|
||||||
|
|
||||||
conv_smooth_curve(const conv_smooth_curve<VertexSource, VertexGenerator>&) = delete;
|
|
||||||
const conv_smooth_curve<VertexSource, VertexGenerator>&
|
|
||||||
operator = (const conv_smooth_curve<VertexSource, VertexGenerator>&) = delete;
|
|
||||||
|
|
||||||
void smooth_value(double v) { m_smooth.generator().smooth_value(v); }
|
|
||||||
double smooth_value() const { return m_smooth.generator().smooth_value(); }
|
|
||||||
unsigned type() const { return m_smooth.type(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
conv_smooth<VertexSource, VertexGenerator> m_smooth;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class VertexSource>
|
|
||||||
using conv_smooth_poly1_curve = conv_smooth_curve<VertexSource, vcgen_smooth_poly1>;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
template<class VertexSource>
|
||||||
|
using conv_smooth_poly1_curve = conv_smooth_curve<VertexSource, vcgen_smooth_poly1>;
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
73
deps/agg/include/agg_conv_stroke.h
vendored
73
deps/agg/include/agg_conv_stroke.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,51 +23,46 @@
|
||||||
#include "agg_vcgen_stroke.h"
|
#include "agg_vcgen_stroke.h"
|
||||||
#include "agg_conv_adaptor_vcgen.h"
|
#include "agg_conv_adaptor_vcgen.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
conv_stroke(VertexSource& vs)
|
||||||
template<class VertexSource, class Markers=null_markers>
|
: conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(vs)
|
||||||
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) :
|
void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
|
||||||
conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(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 line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
|
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
|
||||||
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
|
line_join_e line_join() const { return base_type::generator().line_join(); }
|
||||||
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
|
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
|
||||||
|
|
||||||
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
|
void width(double w) { base_type::generator().width(w); }
|
||||||
line_join_e line_join() const { return base_type::generator().line_join(); }
|
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
|
||||||
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
|
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 width(double w) { base_type::generator().width(w); }
|
double width() const { return base_type::generator().width(); }
|
||||||
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
|
double miter_limit() const { return base_type::generator().miter_limit(); }
|
||||||
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
|
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
|
||||||
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
|
double approximation_scale() const { return base_type::generator().approximation_scale(); }
|
||||||
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
|
|
||||||
|
|
||||||
double width() const { return base_type::generator().width(); }
|
void shorten(double s) { base_type::generator().shorten(s); }
|
||||||
double miter_limit() const { return base_type::generator().miter_limit(); }
|
double shorten() const { return base_type::generator().shorten(); }
|
||||||
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); }
|
private:
|
||||||
double shorten() const { return base_type::generator().shorten(); }
|
conv_stroke(const conv_stroke<VertexSource, Markers>&);
|
||||||
|
const conv_stroke<VertexSource, Markers>& operator=(const conv_stroke<VertexSource, Markers>&);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
conv_stroke(const conv_stroke<VertexSource, Markers>&);
|
|
||||||
const conv_stroke<VertexSource, Markers>&
|
|
||||||
operator = (const conv_stroke<VertexSource, Markers>&);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
68
deps/agg/include/agg_conv_transform.h
vendored
68
deps/agg/include/agg_conv_transform.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -22,50 +22,44 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_trans_affine.h"
|
#include "agg_trans_affine.h"
|
||||||
|
|
||||||
namespace agg
|
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)
|
||||||
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------conv_transform
|
void attach(VertexSource& source) { m_source = &source; }
|
||||||
template<class VertexSource, class Transformer=trans_affine> class conv_transform
|
|
||||||
|
void rewind(unsigned path_id) { m_source->rewind(path_id); }
|
||||||
|
|
||||||
|
unsigned vertex(double* x, double* y)
|
||||||
{
|
{
|
||||||
public:
|
unsigned cmd = m_source->vertex(x, y);
|
||||||
conv_transform(VertexSource& source, Transformer& tr) :
|
if (is_vertex(cmd))
|
||||||
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);
|
m_trans->transform(x, y);
|
||||||
if(is_vertex(cmd))
|
|
||||||
{
|
|
||||||
m_trans->transform(x, y);
|
|
||||||
}
|
|
||||||
return cmd;
|
|
||||||
}
|
}
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
void transformer(Transformer& tr)
|
void transformer(Transformer& tr) { m_trans = &tr; }
|
||||||
{
|
|
||||||
m_trans = &tr;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned type() const { return m_source->type(); }
|
unsigned type() const { return m_source->type(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
conv_transform(const conv_transform<VertexSource>&);
|
conv_transform(const conv_transform<VertexSource>&);
|
||||||
const conv_transform<VertexSource>&
|
const conv_transform<VertexSource>& operator=(const conv_transform<VertexSource>&);
|
||||||
operator = (const conv_transform<VertexSource>&);
|
|
||||||
|
|
||||||
VertexSource* m_source;
|
VertexSource* m_source;
|
||||||
const Transformer* m_trans;
|
const Transformer* m_trans;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
53
deps/agg/include/agg_conv_unclose_polygon.h
vendored
53
deps/agg/include/agg_conv_unclose_polygon.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,35 +18,34 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//====================================================conv_unclose_polygon
|
||||||
|
template<class VertexSource>
|
||||||
|
class conv_unclose_polygon
|
||||||
{
|
{
|
||||||
//====================================================conv_unclose_polygon
|
public:
|
||||||
template<class VertexSource> class conv_unclose_polygon
|
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)
|
||||||
{
|
{
|
||||||
public:
|
unsigned cmd = m_source->vertex(x, y);
|
||||||
explicit conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {}
|
if (is_end_poly(cmd))
|
||||||
void attach(VertexSource& source) { m_source = &source; }
|
cmd &= ~path_flags_close;
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
void rewind(unsigned path_id)
|
private:
|
||||||
{
|
conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
|
||||||
m_source->rewind(path_id);
|
const conv_unclose_polygon<VertexSource>& operator=(const conv_unclose_polygon<VertexSource>&);
|
||||||
}
|
|
||||||
|
|
||||||
unsigned vertex(double* x, double* y)
|
VertexSource* m_source;
|
||||||
{
|
};
|
||||||
unsigned cmd = m_source->vertex(x, y);
|
|
||||||
if(is_end_poly(cmd)) cmd &= ~path_flags_close;
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
|
|
||||||
const conv_unclose_polygon<VertexSource>&
|
|
||||||
operator = (const conv_unclose_polygon<VertexSource>&);
|
|
||||||
|
|
||||||
VertexSource* m_source;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1170
deps/agg/include/agg_curves.h
vendored
1170
deps/agg/include/agg_curves.h
vendored
File diff suppressed because it is too large
Load diff
417
deps/agg/include/agg_dda_line.h
vendored
417
deps/agg/include/agg_dda_line.h
vendored
|
@ -23,268 +23,229 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//===================================================dda_line_interpolator
|
||||||
|
template<int FractionShift, int YShift = 0>
|
||||||
|
class dda_line_interpolator
|
||||||
{
|
{
|
||||||
|
static constexpr int factor = 2 << (FractionShift - 1);
|
||||||
|
|
||||||
//===================================================dda_line_interpolator
|
public:
|
||||||
template<int FractionShift, int YShift = 0> class dda_line_interpolator
|
//--------------------------------------------------------------------
|
||||||
|
dda_line_interpolator() {}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
dda_line_interpolator(int y1, int y2, unsigned count)
|
||||||
|
: m_y(y1)
|
||||||
|
, m_inc(((y2 - y1) * factor) / static_cast<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)
|
||||||
{
|
{
|
||||||
static constexpr int factor = 2 << (FractionShift - 1);
|
if (m_mod <= 0)
|
||||||
public:
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
dda_line_interpolator() {}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
dda_line_interpolator(int y1, int y2, unsigned count) :
|
|
||||||
m_y(y1),
|
|
||||||
m_inc(((y2 - y1) * factor) / static_cast<int>(count)),
|
|
||||||
m_dy(0)
|
|
||||||
{
|
{
|
||||||
|
m_mod += count;
|
||||||
|
m_rem += count;
|
||||||
|
m_lft--;
|
||||||
}
|
}
|
||||||
|
m_mod -= count;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//-------------------------------------------- Backward-adjusted line
|
||||||
void operator ++ ()
|
dda2_line_interpolator(int y1, int y2, int count, int)
|
||||||
{
|
: m_cnt(count <= 0 ? 1 : count)
|
||||||
m_dy += m_inc;
|
, m_lft((y2 - y1) / m_cnt)
|
||||||
}
|
, m_rem((y2 - y1) % m_cnt)
|
||||||
|
, m_mod(m_rem)
|
||||||
//--------------------------------------------------------------------
|
, m_y(y1)
|
||||||
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:
|
if (m_mod <= 0)
|
||||||
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_mod += count;
|
m_lft--;
|
||||||
m_rem += count;
|
|
||||||
m_lft--;
|
|
||||||
}
|
|
||||||
m_mod -= count;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------- Backward-adjusted line
|
//-------------------------------------------- Backward-adjusted line
|
||||||
dda2_line_interpolator(int y1, int y2, int count, int) :
|
dda2_line_interpolator(int y, int count)
|
||||||
m_cnt(count <= 0 ? 1 : count),
|
: m_cnt(count <= 0 ? 1 : count)
|
||||||
m_lft((y2 - y1) / m_cnt),
|
, m_lft(y / m_cnt)
|
||||||
m_rem((y2 - y1) % m_cnt),
|
, m_rem(y % m_cnt)
|
||||||
m_mod(m_rem),
|
, m_mod(m_rem)
|
||||||
m_y(y1)
|
, m_y(0)
|
||||||
|
{
|
||||||
|
if (m_mod <= 0)
|
||||||
{
|
{
|
||||||
if(m_mod <= 0)
|
m_mod += count;
|
||||||
{
|
m_rem += count;
|
||||||
m_mod += count;
|
m_lft--;
|
||||||
m_rem += count;
|
|
||||||
m_lft--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------- Backward-adjusted line
|
//--------------------------------------------------------------------
|
||||||
dda2_line_interpolator(int y, int count) :
|
void save(save_data_type* data) const
|
||||||
m_cnt(count <= 0 ? 1 : count),
|
{
|
||||||
m_lft(y / m_cnt),
|
data[0] = m_mod;
|
||||||
m_rem(y % m_cnt),
|
data[1] = m_y;
|
||||||
m_mod(m_rem),
|
}
|
||||||
m_y(0)
|
|
||||||
{
|
|
||||||
if(m_mod <= 0)
|
|
||||||
{
|
|
||||||
m_mod += count;
|
|
||||||
m_rem += count;
|
|
||||||
m_lft--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void load(const save_data_type* data)
|
||||||
|
{
|
||||||
|
m_mod = data[0];
|
||||||
|
m_y = data[1];
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void save(save_data_type* data) const
|
void operator++()
|
||||||
{
|
{
|
||||||
data[0] = m_mod;
|
m_mod += m_rem;
|
||||||
data[1] = m_y;
|
m_y += m_lft;
|
||||||
}
|
if (m_mod > 0)
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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;
|
m_mod -= m_cnt;
|
||||||
|
m_y++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void adjust_backward()
|
void operator--()
|
||||||
|
{
|
||||||
|
if (m_mod <= m_rem)
|
||||||
{
|
{
|
||||||
m_mod += m_cnt;
|
m_mod += m_cnt;
|
||||||
|
m_y--;
|
||||||
}
|
}
|
||||||
|
m_mod -= m_rem;
|
||||||
|
m_y -= m_lft;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
int mod() const { return m_mod; }
|
void adjust_forward() { m_mod -= m_cnt; }
|
||||||
int rem() const { return m_rem; }
|
|
||||||
int lft() const { return m_lft; }
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
int y() const { return m_y; }
|
void adjust_backward() { m_mod += m_cnt; }
|
||||||
|
|
||||||
private:
|
//--------------------------------------------------------------------
|
||||||
int m_cnt;
|
int mod() const { return m_mod; }
|
||||||
int m_lft;
|
int rem() const { return m_rem; }
|
||||||
int m_rem;
|
int lft() const { return m_lft; }
|
||||||
int m_mod;
|
|
||||||
int m_y;
|
//--------------------------------------------------------------------
|
||||||
|
int y() const { return m_y; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_cnt;
|
||||||
|
int m_lft;
|
||||||
|
int m_rem;
|
||||||
|
int m_mod;
|
||||||
|
int m_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------line_bresenham_interpolator
|
||||||
|
class line_bresenham_interpolator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum subpixel_scale_e {
|
||||||
|
subpixel_shift = 8,
|
||||||
|
subpixel_scale = 1 << subpixel_shift,
|
||||||
|
subpixel_mask = subpixel_scale - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
static int line_lr(int v) { return v >> subpixel_shift; }
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
line_bresenham_interpolator(int x1, int y1, int x2, int y2)
|
||||||
|
: m_x1_lr(line_lr(x1))
|
||||||
|
, m_y1_lr(line_lr(y1))
|
||||||
|
, m_x2_lr(line_lr(x2))
|
||||||
|
, m_y2_lr(line_lr(y2))
|
||||||
|
, m_ver(std::abs(m_x2_lr - m_x1_lr) < std::abs(m_y2_lr - m_y1_lr))
|
||||||
|
, m_len(m_ver ? std::abs(m_y2_lr - m_y1_lr) : std::abs(m_x2_lr - m_x1_lr))
|
||||||
|
, m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1))
|
||||||
|
, m_interpolator(m_ver ? x1 : y1, m_ver ? x2 : y2, m_len)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
bool is_ver() const { return m_ver; }
|
||||||
|
unsigned len() const { return m_len; }
|
||||||
|
int inc() const { return m_inc; }
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void hstep()
|
||||||
|
|
||||||
//---------------------------------------------line_bresenham_interpolator
|
|
||||||
class line_bresenham_interpolator
|
|
||||||
{
|
{
|
||||||
public:
|
++m_interpolator;
|
||||||
enum subpixel_scale_e
|
m_x1_lr += m_inc;
|
||||||
{
|
}
|
||||||
subpixel_shift = 8,
|
|
||||||
subpixel_scale = 1 << subpixel_shift,
|
|
||||||
subpixel_mask = subpixel_scale - 1
|
|
||||||
};
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
static int line_lr(int v) { return v >> subpixel_shift; }
|
void vstep()
|
||||||
|
{
|
||||||
|
++m_interpolator;
|
||||||
|
m_y1_lr += m_inc;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
|
int x1() const { return m_x1_lr; }
|
||||||
m_x1_lr(line_lr(x1)),
|
int y1() const { return m_y1_lr; }
|
||||||
m_y1_lr(line_lr(y1)),
|
int x2() const { return line_lr(m_interpolator.y()); }
|
||||||
m_x2_lr(line_lr(x2)),
|
int y2() const { return line_lr(m_interpolator.y()); }
|
||||||
m_y2_lr(line_lr(y2)),
|
int x2_hr() const { return m_interpolator.y(); }
|
||||||
m_ver(std::abs(m_x2_lr - m_x1_lr) < std::abs(m_y2_lr - m_y1_lr)),
|
int y2_hr() const { return m_interpolator.y(); }
|
||||||
m_len(m_ver ? std::abs(m_y2_lr - m_y1_lr) :
|
|
||||||
std::abs(m_x2_lr - m_x1_lr)),
|
|
||||||
m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
|
|
||||||
m_interpolator(m_ver ? x1 : y1,
|
|
||||||
m_ver ? x2 : y2,
|
|
||||||
m_len)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
bool is_ver() const { return m_ver; }
|
|
||||||
unsigned len() const { return m_len; }
|
|
||||||
int inc() const { return m_inc; }
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void hstep()
|
|
||||||
{
|
|
||||||
++m_interpolator;
|
|
||||||
m_x1_lr += m_inc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void vstep()
|
|
||||||
{
|
|
||||||
++m_interpolator;
|
|
||||||
m_y1_lr += m_inc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
int x1() const { return m_x1_lr; }
|
|
||||||
int y1() const { return m_y1_lr; }
|
|
||||||
int x2() const { return line_lr(m_interpolator.y()); }
|
|
||||||
int y2() const { return line_lr(m_interpolator.y()); }
|
|
||||||
int x2_hr() const { return m_interpolator.y(); }
|
|
||||||
int y2_hr() const { return m_interpolator.y(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_x1_lr;
|
|
||||||
int m_y1_lr;
|
|
||||||
int m_x2_lr;
|
|
||||||
int m_y2_lr;
|
|
||||||
bool m_ver;
|
|
||||||
unsigned m_len;
|
|
||||||
int m_inc;
|
|
||||||
dda2_line_interpolator m_interpolator;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
189
deps/agg/include/agg_ellipse.h
vendored
189
deps/agg/include/agg_ellipse.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,102 +23,111 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace agg
|
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
|
ellipse(double x, double y, double rx, double ry, unsigned num_steps = 0, bool cw = false)
|
||||||
class ellipse
|
: 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)
|
||||||
{
|
{
|
||||||
public:
|
if (m_num == 0)
|
||||||
ellipse() :
|
calc_num_steps();
|
||||||
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);
|
|
||||||
unsigned num_steps() { return m_num; }
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
void init(double x, double y, double rx, double ry, unsigned num_steps = 0, bool cw = false);
|
||||||
inline void ellipse::approximation_scale(double scale)
|
|
||||||
{
|
void approximation_scale(double scale);
|
||||||
m_scale = scale;
|
void rewind(unsigned path_id);
|
||||||
|
unsigned vertex(double* x, double* y);
|
||||||
|
unsigned num_steps() { return m_num; }
|
||||||
|
|
||||||
|
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();
|
calc_num_steps();
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
inline void ellipse::calc_num_steps()
|
|
||||||
{
|
|
||||||
double ra = (std::fabs(m_rx) + std::fabs(m_ry)) / 2;
|
|
||||||
double da = std::acos(ra / (ra + 0.125 / m_scale)) * 2;
|
|
||||||
m_num = uround(2*pi / da);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
inline void ellipse::rewind(unsigned)
|
|
||||||
{
|
|
||||||
m_step = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
inline unsigned ellipse::vertex(double* x, double* y)
|
|
||||||
{
|
|
||||||
if(m_step == m_num)
|
|
||||||
{
|
|
||||||
++m_step;
|
|
||||||
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
|
|
||||||
}
|
|
||||||
if(m_step > m_num) return path_cmd_stop;
|
|
||||||
double angle = double(m_step) / double(m_num) * 2.0 * pi;
|
|
||||||
if(m_cw) angle = 2.0 * pi - angle;
|
|
||||||
*x = m_x + std::cos(angle) * m_rx;
|
|
||||||
*y = m_y + std::sin(angle) * m_ry;
|
|
||||||
m_step++;
|
|
||||||
return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
inline void ellipse::approximation_scale(double scale)
|
||||||
|
{
|
||||||
|
m_scale = scale;
|
||||||
|
calc_num_steps();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
inline void ellipse::calc_num_steps()
|
||||||
|
{
|
||||||
|
double ra = (std::fabs(m_rx) + std::fabs(m_ry)) / 2;
|
||||||
|
double da = std::acos(ra / (ra + 0.125 / m_scale)) * 2;
|
||||||
|
m_num = uround(2 * pi / da);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
inline void ellipse::rewind(unsigned)
|
||||||
|
{
|
||||||
|
m_step = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
inline unsigned ellipse::vertex(double* x, double* y)
|
||||||
|
{
|
||||||
|
if (m_step == m_num)
|
||||||
|
{
|
||||||
|
++m_step;
|
||||||
|
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
|
||||||
|
}
|
||||||
|
if (m_step > m_num)
|
||||||
|
return path_cmd_stop;
|
||||||
|
double angle = double(m_step) / double(m_num) * 2.0 * pi;
|
||||||
|
if (m_cw)
|
||||||
|
angle = 2.0 * pi - angle;
|
||||||
|
*x = m_x + std::cos(angle) * m_rx;
|
||||||
|
*y = m_y + std::sin(angle) * m_ry;
|
||||||
|
m_step++;
|
||||||
|
return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
156
deps/agg/include/agg_ellipse_bresenham.h
vendored
156
deps/agg/include/agg_ellipse_bresenham.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -20,94 +20,92 @@
|
||||||
#ifndef AGG_ELLIPSE_BRESENHAM_INCLUDED
|
#ifndef AGG_ELLIPSE_BRESENHAM_INCLUDED
|
||||||
#define AGG_ELLIPSE_BRESENHAM_INCLUDED
|
#define AGG_ELLIPSE_BRESENHAM_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
|
namespace agg {
|
||||||
|
|
||||||
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)
|
||||||
|
{}
|
||||||
|
|
||||||
//------------------------------------------ellipse_bresenham_interpolator
|
int dx() const { return m_dx; }
|
||||||
class ellipse_bresenham_interpolator
|
int dy() const { return m_dy; }
|
||||||
|
|
||||||
|
void operator++()
|
||||||
{
|
{
|
||||||
public:
|
int mx, my, mxy, min_m;
|
||||||
ellipse_bresenham_interpolator(int rx, int ry) :
|
int fx, fy, fxy;
|
||||||
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++ ()
|
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)
|
||||||
{
|
{
|
||||||
int mx, my, mxy, min_m;
|
min_m = my;
|
||||||
int fx, fy, fxy;
|
flag = false;
|
||||||
|
|
||||||
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:
|
m_dx = m_dy = 0;
|
||||||
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;
|
|
||||||
|
|
||||||
};
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
77
deps/agg/include/agg_embedded_raster_fonts.h
vendored
77
deps/agg/include/agg_embedded_raster_fonts.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,42 +18,41 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
{
|
extern const int8u gse4x6[];
|
||||||
extern const int8u gse4x6[];
|
extern const int8u gse4x8[];
|
||||||
extern const int8u gse4x8[];
|
extern const int8u gse5x7[];
|
||||||
extern const int8u gse5x7[];
|
extern const int8u gse5x9[];
|
||||||
extern const int8u gse5x9[];
|
extern const int8u gse6x12[];
|
||||||
extern const int8u gse6x12[];
|
extern const int8u gse6x9[];
|
||||||
extern const int8u gse6x9[];
|
extern const int8u gse7x11[];
|
||||||
extern const int8u gse7x11[];
|
extern const int8u gse7x11_bold[];
|
||||||
extern const int8u gse7x11_bold[];
|
extern const int8u gse7x15[];
|
||||||
extern const int8u gse7x15[];
|
extern const int8u gse7x15_bold[];
|
||||||
extern const int8u gse7x15_bold[];
|
extern const int8u gse8x16[];
|
||||||
extern const int8u gse8x16[];
|
extern const int8u gse8x16_bold[];
|
||||||
extern const int8u gse8x16_bold[];
|
extern const int8u mcs11_prop[];
|
||||||
extern const int8u mcs11_prop[];
|
extern const int8u mcs11_prop_condensed[];
|
||||||
extern const int8u mcs11_prop_condensed[];
|
extern const int8u mcs12_prop[];
|
||||||
extern const int8u mcs12_prop[];
|
extern const int8u mcs13_prop[];
|
||||||
extern const int8u mcs13_prop[];
|
extern const int8u mcs5x10_mono[];
|
||||||
extern const int8u mcs5x10_mono[];
|
extern const int8u mcs5x11_mono[];
|
||||||
extern const int8u mcs5x11_mono[];
|
extern const int8u mcs6x10_mono[];
|
||||||
extern const int8u mcs6x10_mono[];
|
extern const int8u mcs6x11_mono[];
|
||||||
extern const int8u mcs6x11_mono[];
|
extern const int8u mcs7x12_mono_high[];
|
||||||
extern const int8u mcs7x12_mono_high[];
|
extern const int8u mcs7x12_mono_low[];
|
||||||
extern const int8u mcs7x12_mono_low[];
|
extern const int8u verdana12[];
|
||||||
extern const int8u verdana12[];
|
extern const int8u verdana12_bold[];
|
||||||
extern const int8u verdana12_bold[];
|
extern const int8u verdana13[];
|
||||||
extern const int8u verdana13[];
|
extern const int8u verdana13_bold[];
|
||||||
extern const int8u verdana13_bold[];
|
extern const int8u verdana14[];
|
||||||
extern const int8u verdana14[];
|
extern const int8u verdana14_bold[];
|
||||||
extern const int8u verdana14_bold[];
|
extern const int8u verdana16[];
|
||||||
extern const int8u verdana16[];
|
extern const int8u verdana16_bold[];
|
||||||
extern const int8u verdana16_bold[];
|
extern const int8u verdana17[];
|
||||||
extern const int8u verdana17[];
|
extern const int8u verdana17_bold[];
|
||||||
extern const int8u verdana17_bold[];
|
extern const int8u verdana18[];
|
||||||
extern const int8u verdana18[];
|
extern const int8u verdana18_bold[];
|
||||||
extern const int8u verdana18_bold[];
|
} // namespace agg
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
617
deps/agg/include/agg_font_cache_manager.h
vendored
617
deps/agg/include/agg_font_cache_manager.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -19,307 +19,265 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------glyph_data_type
|
//--------------------------------------------------------------font_cache
|
||||||
enum glyph_data_type
|
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)
|
||||||
{
|
{
|
||||||
glyph_data_invalid = 0,
|
m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1);
|
||||||
glyph_data_mono = 1,
|
strcpy(m_font_signature, font_signature);
|
||||||
glyph_data_gray8 = 2,
|
memset(m_glyphs, 0, sizeof(m_glyphs));
|
||||||
glyph_data_outline = 3
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
bool font_is(const char* font_signature) const { return strcmp(font_signature, m_font_signature) == 0; }
|
||||||
|
|
||||||
//-------------------------------------------------------------glyph_cache
|
//--------------------------------------------------------------------
|
||||||
struct glyph_cache
|
const glyph_cache* find_glyph(unsigned glyph_code) const
|
||||||
{
|
{
|
||||||
unsigned glyph_index;
|
unsigned msb = (glyph_code >> 8) & 0xFF;
|
||||||
int8u* data;
|
if (m_glyphs[msb])
|
||||||
unsigned data_size;
|
{
|
||||||
glyph_data_type data_type;
|
return m_glyphs[msb][glyph_code & 0xFF];
|
||||||
rect_i bounds;
|
}
|
||||||
double advance_x;
|
return 0;
|
||||||
double advance_y;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
//--------------------------------------------------------------font_cache
|
glyph_cache* cache_glyph(unsigned glyph_code,
|
||||||
class font_cache
|
unsigned glyph_index,
|
||||||
|
unsigned data_size,
|
||||||
|
glyph_data_type data_type,
|
||||||
|
const rect_i& bounds,
|
||||||
|
double advance_x,
|
||||||
|
double advance_y)
|
||||||
{
|
{
|
||||||
public:
|
unsigned msb = (glyph_code >> 8) & 0xFF;
|
||||||
enum block_size_e { block_size = 16384-16 };
|
if (m_glyphs[msb] == 0)
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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);
|
m_glyphs[msb] = (glyph_cache**)m_allocator.allocate(sizeof(glyph_cache*) * 256, sizeof(glyph_cache*));
|
||||||
strcpy(m_font_signature, font_signature);
|
memset(m_glyphs[msb], 0, sizeof(glyph_cache*) * 256);
|
||||||
memset(m_glyphs, 0, sizeof(m_glyphs));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
unsigned lsb = glyph_code & 0xFF;
|
||||||
bool font_is(const char* font_signature) const
|
if (m_glyphs[msb][lsb])
|
||||||
{
|
return 0; // Already exists, do not overwrite
|
||||||
return strcmp(font_signature, m_font_signature) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
glyph_cache* glyph = (glyph_cache*)m_allocator.allocate(sizeof(glyph_cache), sizeof(double));
|
||||||
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->glyph_index = glyph_index;
|
||||||
glyph_cache* cache_glyph(unsigned glyph_code,
|
glyph->data = m_allocator.allocate(data_size);
|
||||||
unsigned glyph_index,
|
glyph->data_size = data_size;
|
||||||
unsigned data_size,
|
glyph->data_type = data_type;
|
||||||
glyph_data_type data_type,
|
glyph->bounds = bounds;
|
||||||
const rect_i& bounds,
|
glyph->advance_x = advance_x;
|
||||||
double advance_x,
|
glyph->advance_y = advance_y;
|
||||||
double advance_y)
|
return m_glyphs[msb][lsb] = glyph;
|
||||||
{
|
}
|
||||||
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;
|
private:
|
||||||
if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite
|
block_allocator m_allocator;
|
||||||
|
glyph_cache** m_glyphs[256];
|
||||||
|
char* m_font_signature;
|
||||||
|
};
|
||||||
|
|
||||||
glyph_cache* glyph =
|
//---------------------------------------------------------font_cache_pool
|
||||||
(glyph_cache*)m_allocator.allocate(sizeof(glyph_cache),
|
class font_cache_pool
|
||||||
sizeof(double));
|
{
|
||||||
|
public:
|
||||||
glyph->glyph_index = glyph_index;
|
//--------------------------------------------------------------------
|
||||||
glyph->data = m_allocator.allocate(data_size);
|
~font_cache_pool()
|
||||||
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:
|
unsigned i;
|
||||||
//--------------------------------------------------------------------
|
for (i = 0; i < m_num_fonts; ++i)
|
||||||
~font_cache_pool()
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
obj_allocator<font_cache>::deallocate(m_fonts[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);
|
|
||||||
}
|
}
|
||||||
|
pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
font_cache_pool(unsigned max_fonts=32) :
|
font_cache_pool(unsigned max_fonts = 32)
|
||||||
m_fonts(pod_allocator<font_cache*>::allocate(max_fonts)),
|
: m_fonts(pod_allocator<font_cache*>::allocate(max_fonts))
|
||||||
m_max_fonts(max_fonts),
|
, m_max_fonts(max_fonts)
|
||||||
m_num_fonts(0),
|
, m_num_fonts(0)
|
||||||
m_cur_font(0)
|
, m_cur_font(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
//--------------------------------------------------------------------
|
void font(const char* font_signature, bool reset_cache = false)
|
||||||
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,
|
int idx = find_font(font_signature);
|
||||||
glyph_ren_native_gray8,
|
if (idx >= 0)
|
||||||
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;
|
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
|
||||||
//--------------------------------------------------------------------
|
|
||||||
const glyph_cache* glyph(unsigned glyph_code)
|
|
||||||
{
|
{
|
||||||
synchronize();
|
if (m_num_fonts >= m_max_fonts)
|
||||||
const glyph_cache* gl = m_fonts.find_glyph(glyph_code);
|
{
|
||||||
if(gl)
|
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_prev_glyph = m_last_glyph;
|
||||||
return m_last_glyph = gl;
|
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;
|
||||||
}
|
}
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void init_embedded_adaptors(const glyph_cache* gl,
|
void init_embedded_adaptors(const glyph_cache* gl, double x, double y, double scale = 1.0)
|
||||||
double x, double y,
|
{
|
||||||
double scale=1.0)
|
if (gl)
|
||||||
{
|
{
|
||||||
if(gl)
|
switch (gl->data_type)
|
||||||
{
|
{
|
||||||
switch(gl->data_type)
|
default:
|
||||||
{
|
return;
|
||||||
default: return;
|
|
||||||
case glyph_data_mono:
|
case glyph_data_mono:
|
||||||
m_mono_adaptor.init(gl->data, gl->data_size, x, y);
|
m_mono_adaptor.init(gl->data, gl->data_size, x, y);
|
||||||
break;
|
break;
|
||||||
|
@ -331,79 +289,76 @@ namespace agg
|
||||||
case glyph_data_outline:
|
case glyph_data_outline:
|
||||||
m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
|
m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
|
||||||
break;
|
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; }
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
path_adaptor_type& path_adaptor() { return m_path_adaptor; }
|
const glyph_cache* perv_glyph() const { return m_prev_glyph; }
|
||||||
gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; }
|
const glyph_cache* last_glyph() const { return m_last_glyph; }
|
||||||
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; }
|
bool add_kerning(double* x, double* y)
|
||||||
const glyph_cache* last_glyph() const { return m_last_glyph; }
|
{
|
||||||
|
if (m_prev_glyph && 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 m_engine.add_kerning(m_prev_glyph->glyph_index,
|
|
||||||
m_last_glyph->glyph_index,
|
|
||||||
x, y);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void precache(unsigned from, unsigned to)
|
void precache(unsigned from, unsigned to)
|
||||||
{
|
{
|
||||||
for(; from <= to; ++from) glyph(from);
|
for (; from <= to; ++from)
|
||||||
}
|
glyph(from);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void reset_cache()
|
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(), true);
|
m_fonts.font(m_engine.font_signature());
|
||||||
m_change_stamp = m_engine.change_stamp();
|
m_change_stamp = m_engine.change_stamp();
|
||||||
m_prev_glyph = m_last_glyph = 0;
|
m_prev_glyph = m_last_glyph = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
font_cache_pool m_fonts;
|
||||||
//--------------------------------------------------------------------
|
font_engine_type& m_engine;
|
||||||
font_cache_manager(const self_type&);
|
int m_change_stamp;
|
||||||
const self_type& operator = (const self_type&);
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
} // namespace agg
|
||||||
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
|
#endif
|
||||||
|
|
||||||
|
|
227
deps/agg/include/agg_gamma_functions.h
vendored
227
deps/agg/include/agg_gamma_functions.h
vendored
|
@ -19,116 +19,135 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//===============================================================gamma_none
|
||||||
|
struct gamma_none
|
||||||
{
|
{
|
||||||
//===============================================================gamma_none
|
double operator()(double x) const { return x; }
|
||||||
struct gamma_none
|
};
|
||||||
|
|
||||||
|
//==============================================================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
|
||||||
{
|
{
|
||||||
double operator()(double x) const { return x; }
|
if (x == 0.0)
|
||||||
};
|
return 0.0;
|
||||||
|
return pow(x, m_gamma);
|
||||||
|
|
||||||
//==============================================================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
|
|
||||||
{
|
|
||||||
if (x == 0.0) return 0.0;
|
|
||||||
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;
|
|
||||||
double delta = m_end - m_start;
|
|
||||||
// avoid nan from potential zero division
|
|
||||||
// https://github.com/mapnik/mapnik/issues/761
|
|
||||||
if (delta <= 0.0) return 0.0;
|
|
||||||
return (x - m_start) / delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055);
|
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;
|
||||||
|
double delta = m_end - m_start;
|
||||||
|
// avoid nan from potential zero division
|
||||||
|
// https://github.com/mapnik/mapnik/issues/761
|
||||||
|
if (delta <= 0.0)
|
||||||
|
return 0.0;
|
||||||
|
return (x - m_start) / delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
461
deps/agg/include/agg_gamma_lut.h
vendored
461
deps/agg/include/agg_gamma_lut.h
vendored
|
@ -20,286 +20,247 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_gamma_functions.h"
|
#include "agg_gamma_functions.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
template<class LoResT = int8u, class HiResT = int8u, unsigned GammaShift = 8, unsigned HiResShift = 8>
|
||||||
|
class gamma_lut
|
||||||
{
|
{
|
||||||
template<class LoResT=int8u,
|
public:
|
||||||
class HiResT=int8u,
|
typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
|
||||||
unsigned GammaShift=8,
|
|
||||||
unsigned HiResShift=8> class gamma_lut
|
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()
|
||||||
{
|
{
|
||||||
public:
|
pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size);
|
||||||
typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
|
pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size);
|
||||||
|
}
|
||||||
|
|
||||||
enum gamma_scale_e
|
gamma_lut()
|
||||||
{
|
: m_gamma(1.0)
|
||||||
gamma_shift = GammaShift,
|
, m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size))
|
||||||
gamma_size = 1 << gamma_shift,
|
, m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
|
||||||
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:
|
unsigned i;
|
||||||
LinearType dir(int8u v) const
|
for (i = 0; i < gamma_size; i++)
|
||||||
{
|
{
|
||||||
return m_dir_table[v];
|
m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
int8u inv(LinearType v) const
|
for (i = 0; i < hi_res_size; i++)
|
||||||
{
|
{
|
||||||
// Unrolled binary search.
|
m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift));
|
||||||
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:
|
gamma_lut(double g)
|
||||||
LinearType m_dir_table[256];
|
: m_gamma(1.0)
|
||||||
LinearType m_inv_table[256];
|
, m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size))
|
||||||
|
, m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
|
||||||
// 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:
|
gamma(g);
|
||||||
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<>
|
void gamma(double g)
|
||||||
class sRGB_lut<int16u> : public sRGB_lut_base<int16u>
|
|
||||||
{
|
{
|
||||||
public:
|
m_gamma = g;
|
||||||
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<>
|
unsigned i;
|
||||||
class sRGB_lut<int8u> : public sRGB_lut_base<int8u>
|
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
|
||||||
{
|
{
|
||||||
public:
|
// Unrolled binary search.
|
||||||
sRGB_lut()
|
int8u x = 0;
|
||||||
{
|
if (v > m_inv_table[128])
|
||||||
// Generate lookup tables.
|
x = 128;
|
||||||
m_dir_table[0] = 0;
|
if (v > m_inv_table[x + 64])
|
||||||
m_inv_table[0] = 0;
|
x += 64;
|
||||||
for (unsigned i = 1; i <= 255; ++i)
|
if (v > m_inv_table[x + 32])
|
||||||
{
|
x += 32;
|
||||||
// 8-bit RGB is handled with simple bidirectional lookup tables.
|
if (v > m_inv_table[x + 16])
|
||||||
m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0));
|
x += 16;
|
||||||
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0));
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
int8u inv(int8u v) const
|
protected:
|
||||||
{
|
LinearType m_dir_table[256];
|
||||||
// In this case, the inverse transform is a simple lookup.
|
LinearType m_inv_table[256];
|
||||||
return m_inv_table[v];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Common base class for sRGB_conv objects. Defines an internal
|
// Only derived classes may instantiate.
|
||||||
// sRGB_lut object so that users don't have to.
|
sRGB_lut_base() {}
|
||||||
template<class T>
|
};
|
||||||
class sRGB_conv_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()
|
||||||
{
|
{
|
||||||
public:
|
// Generate lookup tables.
|
||||||
static T rgb_from_sRGB(int8u x)
|
m_dir_table[0] = 0;
|
||||||
|
m_inv_table[0] = 0;
|
||||||
|
for (unsigned i = 1; i <= 255; ++i)
|
||||||
{
|
{
|
||||||
return lut.dir(x);
|
// 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));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static int8u rgb_to_sRGB(T x)
|
template<>
|
||||||
{
|
class sRGB_lut<int16u> : public sRGB_lut_base<int16u>
|
||||||
return lut.inv(x);
|
{
|
||||||
}
|
public:
|
||||||
|
sRGB_lut()
|
||||||
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:
|
// Generate lookup tables.
|
||||||
static float alpha_from_sRGB(int8u x)
|
m_dir_table[0] = 0;
|
||||||
|
m_inv_table[0] = 0;
|
||||||
|
for (unsigned i = 1; i <= 255; ++i)
|
||||||
{
|
{
|
||||||
return float(x / 255.0);
|
// 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));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static int8u alpha_to_sRGB(float x)
|
template<>
|
||||||
{
|
class sRGB_lut<int8u> : public sRGB_lut_base<int8u>
|
||||||
if (x <= 0) return 0;
|
{
|
||||||
else if (x >= 1) return 255;
|
public:
|
||||||
else return int8u(0.5 + x * 255);
|
sRGB_lut()
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
class sRGB_conv<int16u> : public sRGB_conv_base<int16u>
|
|
||||||
{
|
{
|
||||||
public:
|
// Generate lookup tables.
|
||||||
static int16u alpha_from_sRGB(int8u x)
|
m_dir_table[0] = 0;
|
||||||
|
m_inv_table[0] = 0;
|
||||||
|
for (unsigned i = 1; i <= 255; ++i)
|
||||||
{
|
{
|
||||||
return (x << 8) | x;
|
// 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));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int8u alpha_to_sRGB(int16u x)
|
int8u inv(int8u v) const
|
||||||
{
|
|
||||||
return x >> 8;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
class sRGB_conv<int8u> : public sRGB_conv_base<int8u>
|
|
||||||
{
|
{
|
||||||
public:
|
// In this case, the inverse transform is a simple lookup.
|
||||||
static int8u alpha_from_sRGB(int8u x)
|
return m_inv_table[v];
|
||||||
{
|
}
|
||||||
return x;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
static int8u alpha_to_sRGB(int8u x)
|
// Common base class for sRGB_conv objects. Defines an internal
|
||||||
{
|
// sRGB_lut object so that users don't have to.
|
||||||
return x;
|
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; }
|
||||||
|
};
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
253
deps/agg/include/agg_glyph_raster_bin.h
vendored
253
deps/agg/include/agg_glyph_raster_bin.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -19,137 +19,134 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//========================================================glyph_raster_bin
|
||||||
|
template<class ColorT>
|
||||||
|
class glyph_raster_bin
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
typedef ColorT color_type;
|
||||||
|
|
||||||
//========================================================glyph_raster_bin
|
//--------------------------------------------------------------------
|
||||||
template<class ColorT> class glyph_raster_bin
|
struct glyph_rect
|
||||||
{
|
{
|
||||||
public:
|
int x1, y1, x2, y2;
|
||||||
typedef ColorT color_type;
|
double dx, dy;
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
392
deps/agg/include/agg_gradient_lut.h
vendored
392
deps/agg/include/agg_gradient_lut.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -21,226 +21,200 @@
|
||||||
#include "agg_color_rgba.h"
|
#include "agg_color_rgba.h"
|
||||||
#include "agg_color_gray.h"
|
#include "agg_color_gray.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//======================================================color_interpolator
|
||||||
|
template<class ColorT>
|
||||||
|
struct color_interpolator
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
typedef ColorT color_type;
|
||||||
|
|
||||||
//======================================================color_interpolator
|
color_interpolator(const color_type& c1, const color_type& c2, unsigned len)
|
||||||
template<class ColorT> struct color_interpolator
|
: 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++()
|
||||||
{
|
{
|
||||||
public:
|
++r;
|
||||||
typedef ColorT color_type;
|
++g;
|
||||||
|
++b;
|
||||||
color_interpolator(const color_type& c1,
|
++a;
|
||||||
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);
|
|
||||||
bool 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
color_type color() const { return color_type(r.y(), g.y(), b.y(), a.y()); }
|
||||||
template<class T, unsigned S>
|
|
||||||
void gradient_lut<T,S>::add_color(double offset, const color_type& color)
|
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++()
|
||||||
{
|
{
|
||||||
m_color_profile.add(color_point(offset, color));
|
++v;
|
||||||
|
++a;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
color_type color() const { return color_type(v.y(), a.y()); }
|
||||||
template<class T, unsigned S>
|
|
||||||
bool gradient_lut<T,S>::build_lut()
|
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);
|
||||||
|
bool 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
|
||||||
{
|
{
|
||||||
quick_sort(m_color_profile, offset_less);
|
double offset;
|
||||||
m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal));
|
color_type color;
|
||||||
if(m_color_profile.size() >= 2)
|
|
||||||
|
color_point() {}
|
||||||
|
color_point(double off, const color_type& c)
|
||||||
|
: offset(off)
|
||||||
|
, color(c)
|
||||||
{
|
{
|
||||||
unsigned i;
|
if (offset < 0.0)
|
||||||
unsigned start = uround(m_color_profile[0].offset * color_lut_size);
|
offset = 0.0;
|
||||||
unsigned end = 0;
|
if (offset > 1.0)
|
||||||
color_type c = m_color_profile[0].color;
|
offset = 1.0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
};
|
||||||
}
|
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>
|
||||||
|
bool 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 = 0;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
201
deps/agg/include/agg_gsv_text.h
vendored
201
deps/agg/include/agg_gsv_text.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -24,130 +24,107 @@
|
||||||
#include "agg_conv_stroke.h"
|
#include "agg_conv_stroke.h"
|
||||||
#include "agg_conv_transform.h"
|
#include "agg_conv_transform.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//---------------------------------------------------------------gsv_text
|
||||||
|
//
|
||||||
|
// See Implementation agg_gsv_text.cpp
|
||||||
|
//
|
||||||
|
class gsv_text
|
||||||
{
|
{
|
||||||
|
enum status { initial, next_char, start_glyph, glyph };
|
||||||
|
|
||||||
|
public:
|
||||||
|
gsv_text();
|
||||||
|
|
||||||
//---------------------------------------------------------------gsv_text
|
void font(const void* font);
|
||||||
//
|
void flip(bool flip_y) { m_flip = flip_y; }
|
||||||
// See Implementation agg_gsv_text.cpp
|
void load_font(const char* file);
|
||||||
//
|
void size(double height, double width = 0.0);
|
||||||
class gsv_text
|
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
|
||||||
{
|
{
|
||||||
enum status
|
int16u v;
|
||||||
|
if (m_big_endian)
|
||||||
{
|
{
|
||||||
initial,
|
*(int8u*)&v = p[1];
|
||||||
next_char,
|
*((int8u*)&v + 1) = p[0];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(int8u*)&v = p[0];
|
||||||
|
*((int8u*)&v + 1) = p[1];
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double m_x;
|
double m_x;
|
||||||
double m_y;
|
double m_y;
|
||||||
double m_start_x;
|
double m_start_x;
|
||||||
double m_width;
|
double m_width;
|
||||||
double m_height;
|
double m_height;
|
||||||
double m_space;
|
double m_space;
|
||||||
double m_line_space;
|
double m_line_space;
|
||||||
char m_chr[2];
|
char m_chr[2];
|
||||||
char* m_text;
|
char* m_text;
|
||||||
pod_array<char> m_text_buf;
|
pod_array<char> m_text_buf;
|
||||||
char* m_cur_chr;
|
char* m_cur_chr;
|
||||||
const void* m_font;
|
const void* m_font;
|
||||||
pod_array<char> m_loaded_font;
|
pod_array<char> m_loaded_font;
|
||||||
status m_status;
|
status m_status;
|
||||||
bool m_big_endian;
|
bool m_big_endian;
|
||||||
bool m_flip;
|
bool m_flip;
|
||||||
int8u* m_indices;
|
int8u* m_indices;
|
||||||
int8* m_glyphs;
|
int8* m_glyphs;
|
||||||
int8* m_bglyph;
|
int8* m_bglyph;
|
||||||
int8* m_eglyph;
|
int8* m_eglyph;
|
||||||
double m_w;
|
double m_w;
|
||||||
double m_h;
|
double m_h;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------gsv_text_outline
|
||||||
|
template<class Transformer = trans_affine>
|
||||||
|
class gsv_text_outline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
gsv_text_outline(gsv_text& text, const 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); }
|
||||||
|
|
||||||
//--------------------------------------------------------gsv_text_outline
|
void rewind(unsigned path_id)
|
||||||
template<class Transformer = trans_affine> class gsv_text_outline
|
|
||||||
{
|
{
|
||||||
public:
|
m_trans.rewind(path_id);
|
||||||
gsv_text_outline(gsv_text& text, const Transformer& trans) :
|
m_polyline.line_join(round_join);
|
||||||
m_polyline(text),
|
m_polyline.line_cap(round_cap);
|
||||||
m_trans(m_polyline, trans)
|
}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void width(double w)
|
unsigned vertex(double* x, double* y) { return m_trans.vertex(x, y); }
|
||||||
{
|
|
||||||
m_polyline.width(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
void transformer(const Transformer* trans)
|
private:
|
||||||
{
|
conv_stroke<gsv_text> m_polyline;
|
||||||
m_trans->transformer(trans);
|
conv_transform<conv_stroke<gsv_text>, Transformer> m_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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
781
deps/agg/include/agg_image_accessors.h
vendored
781
deps/agg/include/agg_image_accessors.h
vendored
|
@ -18,464 +18,439 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
image_accessor_clip() {}
|
||||||
template<class PixFmt> class image_accessor_clip
|
explicit image_accessor_clip(const pixfmt_type& pixf, const color_type& bk)
|
||||||
|
: m_pixf(&pixf)
|
||||||
{
|
{
|
||||||
public:
|
pixfmt_type::make_pix(m_bk_buf, bk);
|
||||||
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() {}
|
void attach(const pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||||
explicit image_accessor_clip(const pixfmt_type& pixf,
|
|
||||||
const color_type& bk) :
|
|
||||||
m_pixf(&pixf)
|
|
||||||
{
|
|
||||||
pixfmt_type::make_pix(m_bk_buf, bk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void attach(const pixfmt_type& pixf)
|
void background_color(const color_type& bk) { pixfmt_type::make_pix(m_bk_buf, bk); }
|
||||||
{
|
|
||||||
m_pixf = &pixf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void background_color(const color_type& bk)
|
private:
|
||||||
{
|
AGG_INLINE const int8u* pixel() const
|
||||||
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[4];
|
|
||||||
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:
|
if (m_y >= 0 && m_y < (int)m_pixf->height() && m_x >= 0 && m_x < (int)m_pixf->width())
|
||||||
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(const pixfmt_type& pixf) :
|
|
||||||
m_pixf(&pixf)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void attach(const pixfmt_type& pixf)
|
|
||||||
{
|
{
|
||||||
m_pixf = &pixf;
|
return m_pixf->pix_ptr(m_x, m_y);
|
||||||
}
|
}
|
||||||
|
return m_bk_buf;
|
||||||
|
}
|
||||||
|
|
||||||
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
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())
|
||||||
{
|
{
|
||||||
m_x = x;
|
|
||||||
m_y = y;
|
|
||||||
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
||||||
}
|
}
|
||||||
|
m_pix_ptr = 0;
|
||||||
|
return pixel();
|
||||||
|
}
|
||||||
|
|
||||||
AGG_INLINE const int8u* next_x()
|
AGG_INLINE const int8u* next_x()
|
||||||
{
|
{
|
||||||
|
if (m_pix_ptr)
|
||||||
return m_pix_ptr += pix_width;
|
return m_pix_ptr += pix_width;
|
||||||
}
|
++m_x;
|
||||||
|
return pixel();
|
||||||
|
}
|
||||||
|
|
||||||
AGG_INLINE const int8u* next_y()
|
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())
|
||||||
{
|
{
|
||||||
++m_y;
|
|
||||||
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
||||||
}
|
}
|
||||||
|
m_pix_ptr = 0;
|
||||||
|
return pixel();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const pixfmt_type* m_pixf;
|
const pixfmt_type* m_pixf;
|
||||||
int m_x, m_y;
|
int8u m_bk_buf[4];
|
||||||
const int8u* m_pix_ptr;
|
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(const pixfmt_type& pixf)
|
||||||
|
: m_pixf(&pixf)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void attach(const pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||||
|
|
||||||
//----------------------------------------------------image_accessor_clone
|
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
||||||
template<class PixFmt> class image_accessor_clone
|
|
||||||
{
|
{
|
||||||
public:
|
m_x = x;
|
||||||
typedef PixFmt pixfmt_type;
|
m_y = y;
|
||||||
typedef typename pixfmt_type::color_type color_type;
|
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
||||||
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() {}
|
AGG_INLINE const int8u* next_x() { return m_pix_ptr += pix_width; }
|
||||||
explicit image_accessor_clone(const pixfmt_type& pixf) :
|
|
||||||
m_pixf(&pixf)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void attach(const pixfmt_type& pixf)
|
AGG_INLINE const int8u* next_y()
|
||||||
{
|
|
||||||
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+(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;
|
|
||||||
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:
|
++m_y;
|
||||||
typedef PixFmt pixfmt_type;
|
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
|
||||||
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() {}
|
private:
|
||||||
explicit image_accessor_wrap(const pixfmt_type& pixf) :
|
const pixfmt_type* m_pixf;
|
||||||
m_pixf(&pixf),
|
int m_x, m_y;
|
||||||
m_wrap_x(pixf.width()),
|
const int8u* m_pix_ptr;
|
||||||
m_wrap_y(pixf.height())
|
};
|
||||||
{}
|
|
||||||
|
|
||||||
void attach(const pixfmt_type& pixf)
|
//----------------------------------------------------image_accessor_clone
|
||||||
{
|
template<class PixFmt>
|
||||||
m_pixf = &pixf;
|
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 };
|
||||||
|
|
||||||
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
image_accessor_clone() {}
|
||||||
{
|
explicit image_accessor_clone(const pixfmt_type& pixf)
|
||||||
m_x = x;
|
: m_pixf(&pixf)
|
||||||
m_row_ptr = m_pixf->row_ptr(m_wrap_y(y));
|
{}
|
||||||
return m_row_ptr + m_wrap_x(x) * pix_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
AGG_INLINE const int8u* next_x()
|
void attach(const pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||||
{
|
|
||||||
int x = ++m_wrap_x;
|
|
||||||
return m_row_ptr + x * pix_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
AGG_INLINE const int8u* next_y()
|
private:
|
||||||
{
|
AGG_INLINE const int8u* pixel() const
|
||||||
m_row_ptr = m_pixf->row_ptr(++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:
|
int x = m_x;
|
||||||
wrap_mode_repeat() {}
|
int y = m_y;
|
||||||
wrap_mode_repeat(unsigned size) :
|
if (x < 0)
|
||||||
m_size(size),
|
x = 0;
|
||||||
m_add(size * (0x3FFFFFFF / size)),
|
if (y < 0)
|
||||||
m_value(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);
|
||||||
|
}
|
||||||
|
|
||||||
AGG_INLINE unsigned operator() (int v)
|
public:
|
||||||
{
|
AGG_INLINE const int8u* span(int x, int y, unsigned len)
|
||||||
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:
|
m_x = m_x0 = x;
|
||||||
wrap_mode_repeat_pow2() {}
|
m_y = y;
|
||||||
wrap_mode_repeat_pow2(unsigned size) : m_value(0)
|
if (y >= 0 && y < (int)m_pixf->height() && x >= 0 && x + (int)len <= (int)m_pixf->width())
|
||||||
{
|
{
|
||||||
m_mask = 1;
|
return m_pix_ptr = m_pixf->pix_ptr(x, y);
|
||||||
while(m_mask < size) m_mask = (m_mask << 1) | 1;
|
|
||||||
m_mask >>= 1;
|
|
||||||
}
|
}
|
||||||
AGG_INLINE unsigned operator() (int v)
|
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(const pixfmt_type& pixf)
|
||||||
|
: m_pixf(&pixf)
|
||||||
|
, m_wrap_x(pixf.width())
|
||||||
|
, m_wrap_y(pixf.height())
|
||||||
|
{}
|
||||||
|
|
||||||
|
void attach(const pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||||
|
|
||||||
|
AGG_INLINE const int8u* span(int x, int y, unsigned)
|
||||||
|
{
|
||||||
|
m_x = x;
|
||||||
|
m_row_ptr = m_pixf->row_ptr(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->row_ptr(++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_mask;
|
||||||
}
|
return m_value = (unsigned(v) + m_add) % m_size;
|
||||||
AGG_INLINE unsigned operator++ ()
|
}
|
||||||
{
|
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:
|
++m_value;
|
||||||
wrap_mode_repeat_auto_pow2() {}
|
if (m_value >= m_size)
|
||||||
wrap_mode_repeat_auto_pow2(unsigned size) :
|
m_value = 0;
|
||||||
m_size(size),
|
return m_value;
|
||||||
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)
|
private:
|
||||||
{
|
unsigned m_size;
|
||||||
if(m_mask) return m_value = unsigned(v) & m_mask;
|
unsigned m_add;
|
||||||
return m_value = (unsigned(v) + m_add) % m_size;
|
unsigned m_mask;
|
||||||
}
|
unsigned m_value;
|
||||||
AGG_INLINE unsigned operator++ ()
|
};
|
||||||
{
|
|
||||||
++m_value;
|
|
||||||
if(m_value >= m_size) m_value = 0;
|
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
//-------------------------------------------------------wrap_mode_reflect
|
||||||
unsigned m_size;
|
class wrap_mode_reflect
|
||||||
unsigned m_add;
|
{
|
||||||
unsigned m_mask;
|
public:
|
||||||
unsigned m_value;
|
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)
|
||||||
//-------------------------------------------------------wrap_mode_reflect
|
|
||||||
class wrap_mode_reflect
|
|
||||||
{
|
{
|
||||||
public:
|
m_value = (unsigned(v) + m_add) % m_size2;
|
||||||
wrap_mode_reflect() {}
|
if (m_value >= m_size)
|
||||||
wrap_mode_reflect(unsigned size) :
|
return m_size2 - m_value - 1;
|
||||||
m_size(size),
|
return m_value;
|
||||||
m_size2(size * 2),
|
}
|
||||||
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
|
|
||||||
m_value(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
AGG_INLINE unsigned operator() (int v)
|
AGG_INLINE unsigned operator++()
|
||||||
{
|
|
||||||
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:
|
++m_value;
|
||||||
wrap_mode_reflect_pow2() {}
|
if (m_value >= m_size2)
|
||||||
wrap_mode_reflect_pow2(unsigned size) : m_value(0)
|
m_value = 0;
|
||||||
{
|
if (m_value >= m_size)
|
||||||
m_mask = 1;
|
return m_size2 - m_value - 1;
|
||||||
m_size = 1;
|
return m_value;
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned m_size;
|
||||||
|
unsigned m_size2;
|
||||||
|
unsigned m_add;
|
||||||
|
unsigned m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------wrap_mode_reflect_pow2
|
||||||
//---------------------------------------------wrap_mode_reflect_auto_pow2
|
class wrap_mode_reflect_pow2
|
||||||
class wrap_mode_reflect_auto_pow2
|
{
|
||||||
|
public:
|
||||||
|
wrap_mode_reflect_pow2() {}
|
||||||
|
wrap_mode_reflect_pow2(unsigned size)
|
||||||
|
: m_value(0)
|
||||||
{
|
{
|
||||||
public:
|
m_mask = 1;
|
||||||
wrap_mode_reflect_auto_pow2() {}
|
m_size = 1;
|
||||||
wrap_mode_reflect_auto_pow2(unsigned size) :
|
while (m_mask < 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 :
|
m_mask = (m_mask << 1) | 1;
|
||||||
(unsigned(v) + m_add) % m_size2;
|
m_size <<= 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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:
|
private:
|
||||||
unsigned m_size;
|
unsigned m_size;
|
||||||
unsigned m_size2;
|
unsigned m_mask;
|
||||||
unsigned m_add;
|
unsigned m_value;
|
||||||
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
817
deps/agg/include/agg_image_filters.h
vendored
817
deps/agg/include/agg_image_filters.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,426 +23,499 @@
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
#include "agg_math.h"
|
#include "agg_math.h"
|
||||||
|
|
||||||
namespace agg
|
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:
|
||||||
// See Implementation agg_image_filters.cpp
|
template<class FilterF>
|
||||||
|
void calculate(const FilterF& filter, bool normalization = true)
|
||||||
enum image_filter_scale_e
|
|
||||||
{
|
{
|
||||||
image_filter_shift = 14, //----image_filter_shift
|
double r = filter.radius();
|
||||||
image_filter_scale = 1 << image_filter_shift, //----image_filter_scale
|
realloc_lut(r);
|
||||||
image_filter_mask = image_filter_scale - 1 //----image_filter_mask
|
unsigned i;
|
||||||
};
|
unsigned pivot = diameter() << (image_subpixel_shift - 1);
|
||||||
|
for (i = 0; i < pivot; i++)
|
||||||
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();
|
double x = double(i) / double(image_subpixel_scale);
|
||||||
realloc_lut(r);
|
double y = filter.calc_weight(x);
|
||||||
unsigned i;
|
m_weight_array[pivot + i] = m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
unsigned end = (diameter() << image_subpixel_shift) - 1;
|
||||||
image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {}
|
m_weight_array[0] = m_weight_array[end];
|
||||||
|
if (normalization)
|
||||||
template<class FilterF> image_filter_lut(const FilterF& filter,
|
|
||||||
bool normalization=true)
|
|
||||||
{
|
{
|
||||||
calculate(filter, normalization);
|
normalize();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double radius() const { return m_radius; }
|
image_filter_lut()
|
||||||
unsigned diameter() const { return m_diameter; }
|
: m_radius(0)
|
||||||
int start() const { return m_start; }
|
, m_diameter(0)
|
||||||
const int16* weight_array() const { return &m_weight_array[0]; }
|
, m_start(0)
|
||||||
void normalize();
|
{}
|
||||||
|
|
||||||
private:
|
template<class FilterF>
|
||||||
void realloc_lut(double radius);
|
image_filter_lut(const FilterF& filter, bool normalization = true)
|
||||||
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:
|
calculate(filter, normalization);
|
||||||
image_filter()
|
}
|
||||||
|
|
||||||
|
double radius() const { return m_radius; }
|
||||||
|
unsigned diameter() const { return m_diameter; }
|
||||||
|
int start() const { return m_start; }
|
||||||
|
const int16* weight_array() const { return &m_weight_array[0]; }
|
||||||
|
void normalize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void realloc_lut(double radius);
|
||||||
|
image_filter_lut(const image_filter_lut&);
|
||||||
|
const image_filter_lut& operator=(const image_filter_lut&);
|
||||||
|
|
||||||
|
double m_radius;
|
||||||
|
unsigned m_diameter;
|
||||||
|
int m_start;
|
||||||
|
pod_array<int16> m_weight_array;
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------image_filter
|
||||||
|
template<class FilterF>
|
||||||
|
class image_filter : public image_filter_lut
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
image_filter() { calculate(m_filter_function); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
FilterF m_filter_function;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------image_filter_bilinear
|
||||||
|
struct image_filter_bilinear
|
||||||
|
{
|
||||||
|
static double radius() { return 1.0; }
|
||||||
|
static double calc_weight(double x) { return 1.0 - x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------image_filter_hanning
|
||||||
|
struct image_filter_hanning
|
||||||
|
{
|
||||||
|
static double radius() { return 1.0; }
|
||||||
|
static double calc_weight(double x) { return 0.5 + 0.5 * std::cos(pi * x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------image_filter_hamming
|
||||||
|
struct image_filter_hamming
|
||||||
|
{
|
||||||
|
static double radius() { return 1.0; }
|
||||||
|
static double calc_weight(double x) { return 0.54 + 0.46 * std::cos(pi * x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------image_filter_hermite
|
||||||
|
struct image_filter_hermite
|
||||||
|
{
|
||||||
|
static double radius() { return 1.0; }
|
||||||
|
static double calc_weight(double x) { return (2.0 * x - 3.0) * x * x + 1.0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------image_filter_quadric
|
||||||
|
struct image_filter_quadric
|
||||||
|
{
|
||||||
|
static double radius() { return 1.5; }
|
||||||
|
static double calc_weight(double x)
|
||||||
|
{
|
||||||
|
double t;
|
||||||
|
if (x < 0.5)
|
||||||
|
return 0.75 - x * x;
|
||||||
|
if (x < 1.5)
|
||||||
{
|
{
|
||||||
calculate(m_filter_function);
|
t = x - 1.5;
|
||||||
|
return 0.5 * t * t;
|
||||||
}
|
}
|
||||||
private:
|
return 0.0;
|
||||||
FilterF m_filter_function;
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------image_filter_bicubic
|
||||||
|
class image_filter_bicubic
|
||||||
|
{
|
||||||
|
static double pow3(double x) { return (x <= 0.0) ? 0.0 : x * x * x; }
|
||||||
|
|
||||||
//-----------------------------------------------image_filter_bilinear
|
public:
|
||||||
struct image_filter_bilinear
|
static double radius() { return 2.0; }
|
||||||
|
static double calc_weight(double x)
|
||||||
{
|
{
|
||||||
static double radius() { return 1.0; }
|
return (1.0 / 6.0) * (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1));
|
||||||
static double calc_weight(double x)
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------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++)
|
||||||
{
|
{
|
||||||
return 1.0 - x;
|
sum += t;
|
||||||
|
t *= (double)y / (i * i);
|
||||||
}
|
}
|
||||||
};
|
return sum;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------image_filter_catrom
|
||||||
//-----------------------------------------------image_filter_hanning
|
struct image_filter_catrom
|
||||||
struct image_filter_hanning
|
{
|
||||||
|
static double radius() { return 2.0; }
|
||||||
|
static double calc_weight(double x)
|
||||||
{
|
{
|
||||||
static double radius() { return 1.0; }
|
if (x < 1.0)
|
||||||
static double calc_weight(double x)
|
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 0.5 + 0.5 * std::cos(pi * x);
|
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
|
||||||
//-----------------------------------------------image_filter_hamming
|
struct image_filter_spline36
|
||||||
struct image_filter_hamming
|
{
|
||||||
|
static double radius() { return 3.0; }
|
||||||
|
static double calc_weight(double x)
|
||||||
{
|
{
|
||||||
static double radius() { return 1.0; }
|
if (x < 1.0)
|
||||||
static double calc_weight(double x)
|
|
||||||
{
|
{
|
||||||
return 0.54 + 0.46 * std::cos(pi * x);
|
return ((13.0 / 11.0 * x - 453.0 / 209.0) * x - 3.0 / 209.0) * x + 1.0;
|
||||||
}
|
}
|
||||||
};
|
if (x < 2.0)
|
||||||
|
|
||||||
//-----------------------------------------------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;
|
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_quadric
|
};
|
||||||
struct image_filter_quadric
|
|
||||||
|
//----------------------------------------------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
|
||||||
{
|
{
|
||||||
static double radius() { return 1.5; }
|
if (x == 0.0)
|
||||||
static double calc_weight(double x)
|
return 1.0;
|
||||||
{
|
x *= pi;
|
||||||
double t;
|
return std::sin(x) / x;
|
||||||
if(x < 0.5) return 0.75 - x * x;
|
}
|
||||||
if(x < 1.5) {t = x - 1.5; return 0.5 * t * t;}
|
|
||||||
|
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;
|
return 0.0;
|
||||||
}
|
x *= pi;
|
||||||
};
|
double xr = x / m_radius;
|
||||||
|
return (std::sin(x) / x) * (std::sin(xr) / xr);
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------image_filter_bicubic
|
private:
|
||||||
class image_filter_bicubic
|
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
|
||||||
{
|
{
|
||||||
static double pow3(double x)
|
if (x == 0.0)
|
||||||
{
|
return 1.0;
|
||||||
return (x <= 0.0) ? 0.0 : x * x * x;
|
if (x > m_radius)
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
return 0.0;
|
||||||
}
|
x *= pi;
|
||||||
};
|
double xr = x / m_radius;
|
||||||
|
return (std::sin(x) / x) * (0.42 + 0.5 * std::cos(xr) + 0.08 * std::cos(2 * xr));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double m_radius;
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------image_filter_spline16
|
//------------------------------------------------image_filter_sinc36
|
||||||
struct image_filter_spline16
|
class image_filter_sinc36 : public image_filter_sinc
|
||||||
{
|
{
|
||||||
static double radius() { return 2.0; }
|
public:
|
||||||
static double calc_weight(double x)
|
image_filter_sinc36()
|
||||||
{
|
: image_filter_sinc(3.0)
|
||||||
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_sinc64
|
||||||
|
class image_filter_sinc64 : public image_filter_sinc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
image_filter_sinc64()
|
||||||
|
: image_filter_sinc(4.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------image_filter_spline36
|
//-----------------------------------------------image_filter_sinc100
|
||||||
struct image_filter_spline36
|
class image_filter_sinc100 : public image_filter_sinc
|
||||||
{
|
{
|
||||||
static double radius() { return 3.0; }
|
public:
|
||||||
static double calc_weight(double x)
|
image_filter_sinc100()
|
||||||
{
|
: image_filter_sinc(5.0)
|
||||||
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_sinc144
|
||||||
|
class image_filter_sinc144 : public image_filter_sinc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
image_filter_sinc144()
|
||||||
|
: image_filter_sinc(6.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------image_filter_gaussian
|
//-----------------------------------------------image_filter_sinc196
|
||||||
struct image_filter_gaussian
|
class image_filter_sinc196 : public image_filter_sinc
|
||||||
{
|
{
|
||||||
static double radius() { return 2.0; }
|
public:
|
||||||
static double calc_weight(double x)
|
image_filter_sinc196()
|
||||||
{
|
: image_filter_sinc(7.0)
|
||||||
return exp(-2.0 * x * x) * sqrt(2.0 / pi);
|
{}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
//-----------------------------------------------image_filter_sinc256
|
||||||
|
class image_filter_sinc256 : public image_filter_sinc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
image_filter_sinc256()
|
||||||
|
: image_filter_sinc(8.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------------------------image_filter_bessel
|
//---------------------------------------------image_filter_lanczos36
|
||||||
struct image_filter_bessel
|
class image_filter_lanczos36 : public image_filter_lanczos
|
||||||
{
|
{
|
||||||
static double radius() { return 3.2383; }
|
public:
|
||||||
static double calc_weight(double x)
|
image_filter_lanczos36()
|
||||||
{
|
: image_filter_lanczos(3.0)
|
||||||
return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x);
|
{}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
//---------------------------------------------image_filter_lanczos64
|
||||||
|
class image_filter_lanczos64 : public image_filter_lanczos
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
image_filter_lanczos64()
|
||||||
|
: image_filter_lanczos(4.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//-------------------------------------------------image_filter_sinc
|
//--------------------------------------------image_filter_lanczos100
|
||||||
class image_filter_sinc
|
class image_filter_lanczos100 : public image_filter_lanczos
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
image_filter_sinc(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
|
image_filter_lanczos100()
|
||||||
double radius() const { return m_radius; }
|
: image_filter_lanczos(5.0)
|
||||||
double calc_weight(double x) const
|
{}
|
||||||
{
|
};
|
||||||
if(x == 0.0) return 1.0;
|
|
||||||
x *= pi;
|
|
||||||
return std::sin(x) / x;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
double m_radius;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
//--------------------------------------------image_filter_lanczos144
|
||||||
|
class image_filter_lanczos144 : public image_filter_lanczos
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
image_filter_lanczos144()
|
||||||
|
: image_filter_lanczos(6.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------image_filter_lanczos
|
//--------------------------------------------image_filter_lanczos196
|
||||||
class image_filter_lanczos
|
class image_filter_lanczos196 : public image_filter_lanczos
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
image_filter_lanczos(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
|
image_filter_lanczos196()
|
||||||
double radius() const { return m_radius; }
|
: image_filter_lanczos(7.0)
|
||||||
double calc_weight(double x) const
|
{}
|
||||||
{
|
};
|
||||||
if(x == 0.0) return 1.0;
|
|
||||||
if(x > m_radius) return 0.0;
|
|
||||||
x *= pi;
|
|
||||||
double xr = x / m_radius;
|
|
||||||
return (std::sin(x) / x) * (std::sin(xr) / xr);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
double m_radius;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
//--------------------------------------------image_filter_lanczos256
|
||||||
|
class image_filter_lanczos256 : public image_filter_lanczos
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
image_filter_lanczos256()
|
||||||
|
: image_filter_lanczos(8.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------image_filter_blackman
|
//--------------------------------------------image_filter_blackman36
|
||||||
class image_filter_blackman
|
class image_filter_blackman36 : public image_filter_blackman
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
image_filter_blackman(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
|
image_filter_blackman36()
|
||||||
double radius() const { return m_radius; }
|
: image_filter_blackman(3.0)
|
||||||
double calc_weight(double x) const
|
{}
|
||||||
{
|
};
|
||||||
if(x == 0.0) return 1.0;
|
|
||||||
if(x > m_radius) return 0.0;
|
|
||||||
x *= pi;
|
|
||||||
double xr = x / m_radius;
|
|
||||||
return (std::sin(x) / x) * (0.42 + 0.5 * std::cos(xr) + 0.08 * std::cos(2*xr));
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
double m_radius;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------image_filter_sinc36
|
//--------------------------------------------image_filter_blackman64
|
||||||
class image_filter_sinc36 : public image_filter_sinc
|
class image_filter_blackman64 : public image_filter_blackman
|
||||||
{ public: image_filter_sinc36() : image_filter_sinc(3.0){} };
|
{
|
||||||
|
public:
|
||||||
|
image_filter_blackman64()
|
||||||
|
: image_filter_blackman(4.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------------------------image_filter_sinc64
|
//-------------------------------------------image_filter_blackman100
|
||||||
class image_filter_sinc64 : public image_filter_sinc
|
class image_filter_blackman100 : public image_filter_blackman
|
||||||
{ public: image_filter_sinc64() : image_filter_sinc(4.0){} };
|
{
|
||||||
|
public:
|
||||||
|
image_filter_blackman100()
|
||||||
|
: image_filter_blackman(5.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------image_filter_sinc100
|
//-------------------------------------------image_filter_blackman144
|
||||||
class image_filter_sinc100 : public image_filter_sinc
|
class image_filter_blackman144 : public image_filter_blackman
|
||||||
{ public: image_filter_sinc100() : image_filter_sinc(5.0){} };
|
{
|
||||||
|
public:
|
||||||
|
image_filter_blackman144()
|
||||||
|
: image_filter_blackman(6.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------image_filter_sinc144
|
//-------------------------------------------image_filter_blackman196
|
||||||
class image_filter_sinc144 : public image_filter_sinc
|
class image_filter_blackman196 : public image_filter_blackman
|
||||||
{ public: image_filter_sinc144() : image_filter_sinc(6.0){} };
|
{
|
||||||
|
public:
|
||||||
|
image_filter_blackman196()
|
||||||
|
: image_filter_blackman(7.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------image_filter_sinc196
|
//-------------------------------------------image_filter_blackman256
|
||||||
class image_filter_sinc196 : public image_filter_sinc
|
class image_filter_blackman256 : public image_filter_blackman
|
||||||
{ public: image_filter_sinc196() : image_filter_sinc(7.0){} };
|
{
|
||||||
|
public:
|
||||||
|
image_filter_blackman256()
|
||||||
|
: image_filter_blackman(8.0)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------image_filter_sinc256
|
} // namespace agg
|
||||||
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
|
#endif
|
||||||
|
|
312
deps/agg/include/agg_line_aa_basics.h
vendored
312
deps/agg/include/agg_line_aa_basics.h
vendored
|
@ -18,172 +18,154 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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);
|
||||||
// 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_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------line_coord
|
|
||||||
struct line_coord
|
|
||||||
{
|
|
||||||
AGG_INLINE static int conv(double x)
|
|
||||||
{
|
|
||||||
return iround(x * line_subpixel_scale);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------line_coord_sat
|
|
||||||
struct line_coord_sat
|
|
||||||
{
|
|
||||||
AGG_INLINE static int conv(double x)
|
|
||||||
{
|
|
||||||
return saturation<line_max_coord>::iround(x * line_subpixel_scale);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//==========================================================line_parameters
|
|
||||||
struct line_parameters
|
|
||||||
{
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
line_parameters() {}
|
|
||||||
line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) :
|
|
||||||
x1(x1_), y1(y1_), x2(x2_), y2(y2_),
|
|
||||||
dx(std::abs(x2_ - x1_)),
|
|
||||||
dy(std::abs(y2_ - y1_)),
|
|
||||||
sx((x2_ > x1_) ? 1 : -1),
|
|
||||||
sy((y2_ > y1_) ? 1 : -1),
|
|
||||||
vertical(dy >= dx),
|
|
||||||
inc(vertical ? sy : sx),
|
|
||||||
len(len_),
|
|
||||||
octant((sy & 4) | (sx & 2) | int(vertical))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; }
|
|
||||||
unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; }
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
bool same_orthogonal_quadrant(const line_parameters& lp) const
|
|
||||||
{
|
|
||||||
return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant];
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
bool same_diagonal_quadrant(const line_parameters& lp) const
|
|
||||||
{
|
|
||||||
return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
void divide(line_parameters& lp1, line_parameters& lp2) const
|
|
||||||
{
|
|
||||||
int xmid = (x1 + x2) >> 1;
|
|
||||||
int ymid = (y1 + y2) >> 1;
|
|
||||||
int len2 = len >> 1;
|
|
||||||
|
|
||||||
lp1 = *this;
|
|
||||||
lp2 = *this;
|
|
||||||
|
|
||||||
lp1.x2 = xmid;
|
|
||||||
lp1.y2 = ymid;
|
|
||||||
lp1.len = len2;
|
|
||||||
lp1.dx = std::abs(lp1.x2 - lp1.x1);
|
|
||||||
lp1.dy = std::abs(lp1.y2 - lp1.y1);
|
|
||||||
|
|
||||||
lp2.x1 = xmid;
|
|
||||||
lp2.y1 = ymid;
|
|
||||||
lp2.len = len2;
|
|
||||||
lp2.dx = std::abs(lp2.x2 - lp2.x1);
|
|
||||||
lp2.dy = std::abs(lp2.y2 - lp2.y1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
int x1, y1, x2, y2, dx, dy, sx, sy;
|
|
||||||
bool vertical;
|
|
||||||
int inc;
|
|
||||||
int len;
|
|
||||||
int octant;
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
static const int8u s_orthogonal_quadrant[8];
|
|
||||||
static const int8u s_diagonal_quadrant[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// See Implementation agg_line_aa_basics.cpp
|
|
||||||
|
|
||||||
//----------------------------------------------------------------bisectrix
|
|
||||||
void bisectrix(const line_parameters& l1,
|
|
||||||
const line_parameters& l2,
|
|
||||||
int* x, int* y);
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------fix_degenerate_bisectrix_start
|
|
||||||
void inline fix_degenerate_bisectrix_start(const line_parameters& lp,
|
|
||||||
int* x, int* y)
|
|
||||||
{
|
|
||||||
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
|
|
||||||
double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
|
|
||||||
if(d < line_subpixel_scale/2)
|
|
||||||
{
|
|
||||||
*x = lp.x1 + (lp.y2 - lp.y1);
|
|
||||||
*y = lp.y1 - (lp.x2 - lp.x1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------fix_degenerate_bisectrix_end
|
|
||||||
void inline fix_degenerate_bisectrix_end(const line_parameters& lp,
|
|
||||||
int* x, int* y)
|
|
||||||
{
|
|
||||||
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
|
|
||||||
double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
|
|
||||||
if(d < line_subpixel_scale/2)
|
|
||||||
{
|
|
||||||
*x = lp.x2 + (lp.y2 - lp.y1);
|
|
||||||
*y = lp.y2 - (lp.x2 - lp.x1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------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_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------line_coord
|
||||||
|
struct line_coord
|
||||||
|
{
|
||||||
|
AGG_INLINE static int conv(double x) { return iround(x * line_subpixel_scale); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------line_coord_sat
|
||||||
|
struct line_coord_sat
|
||||||
|
{
|
||||||
|
AGG_INLINE static int conv(double x) { return saturation<line_max_coord>::iround(x * line_subpixel_scale); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================line_parameters
|
||||||
|
struct line_parameters
|
||||||
|
{
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
line_parameters() {}
|
||||||
|
line_parameters(int x1_, int y1_, int x2_, int y2_, int len_)
|
||||||
|
: x1(x1_)
|
||||||
|
, y1(y1_)
|
||||||
|
, x2(x2_)
|
||||||
|
, y2(y2_)
|
||||||
|
, dx(std::abs(x2_ - x1_))
|
||||||
|
, dy(std::abs(y2_ - y1_))
|
||||||
|
, sx((x2_ > x1_) ? 1 : -1)
|
||||||
|
, sy((y2_ > y1_) ? 1 : -1)
|
||||||
|
, vertical(dy >= dx)
|
||||||
|
, inc(vertical ? sy : sx)
|
||||||
|
, len(len_)
|
||||||
|
, octant((sy & 4) | (sx & 2) | int(vertical))
|
||||||
|
{}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; }
|
||||||
|
unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; }
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
bool same_orthogonal_quadrant(const line_parameters& lp) const
|
||||||
|
{
|
||||||
|
return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant];
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
bool same_diagonal_quadrant(const line_parameters& lp) const
|
||||||
|
{
|
||||||
|
return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
void divide(line_parameters& lp1, line_parameters& lp2) const
|
||||||
|
{
|
||||||
|
int xmid = (x1 + x2) >> 1;
|
||||||
|
int ymid = (y1 + y2) >> 1;
|
||||||
|
int len2 = len >> 1;
|
||||||
|
|
||||||
|
lp1 = *this;
|
||||||
|
lp2 = *this;
|
||||||
|
|
||||||
|
lp1.x2 = xmid;
|
||||||
|
lp1.y2 = ymid;
|
||||||
|
lp1.len = len2;
|
||||||
|
lp1.dx = std::abs(lp1.x2 - lp1.x1);
|
||||||
|
lp1.dy = std::abs(lp1.y2 - lp1.y1);
|
||||||
|
|
||||||
|
lp2.x1 = xmid;
|
||||||
|
lp2.y1 = ymid;
|
||||||
|
lp2.len = len2;
|
||||||
|
lp2.dx = std::abs(lp2.x2 - lp2.x1);
|
||||||
|
lp2.dy = std::abs(lp2.y2 - lp2.y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
int x1, y1, x2, y2, dx, dy, sx, sy;
|
||||||
|
bool vertical;
|
||||||
|
int inc;
|
||||||
|
int len;
|
||||||
|
int octant;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
static const int8u s_orthogonal_quadrant[8];
|
||||||
|
static const int8u s_diagonal_quadrant[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
// See Implementation agg_line_aa_basics.cpp
|
||||||
|
|
||||||
|
//----------------------------------------------------------------bisectrix
|
||||||
|
void bisectrix(const line_parameters& l1, const line_parameters& l2, int* x, int* y);
|
||||||
|
|
||||||
|
//-------------------------------------------fix_degenerate_bisectrix_start
|
||||||
|
void inline fix_degenerate_bisectrix_start(const line_parameters& lp, int* x, int* y)
|
||||||
|
{
|
||||||
|
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
|
||||||
|
if (d < line_subpixel_scale / 2)
|
||||||
|
{
|
||||||
|
*x = lp.x1 + (lp.y2 - lp.y1);
|
||||||
|
*y = lp.y1 - (lp.x2 - lp.x1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------fix_degenerate_bisectrix_end
|
||||||
|
void inline fix_degenerate_bisectrix_end(const line_parameters& lp, int* x, int* y)
|
||||||
|
{
|
||||||
|
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
|
||||||
|
if (d < line_subpixel_scale / 2)
|
||||||
|
{
|
||||||
|
*x = lp.x2 + (lp.y2 - lp.y1);
|
||||||
|
*y = lp.y2 - (lp.x2 - lp.x1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
684
deps/agg/include/agg_math.h
vendored
684
deps/agg/include/agg_math.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
// mcseemagg@yahoo.com
|
// mcseemagg@yahoo.com
|
||||||
// http://www.antigrain.com
|
// http://www.antigrain.com
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Bessel function (besj) was adapted for use in AGG library by Andy Wilk
|
// Bessel function (besj) was adapted for use in AGG library by Andy Wilk
|
||||||
// Contact: castor.vulgaris@gmail.com
|
// Contact: castor.vulgaris@gmail.com
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -22,251 +22,236 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//------------------------------------------------------vertex_dist_epsilon
|
||||||
|
// Coinciding points maximal distance (Epsilon)
|
||||||
|
const double vertex_dist_epsilon = 1e-5;
|
||||||
|
|
||||||
|
//-----------------------------------------------------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);
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------vertex_dist_epsilon
|
//--------------------------------------------------------point_in_triangle
|
||||||
// Coinciding points maximal distance (Epsilon)
|
AGG_INLINE bool point_in_triangle(double x1, double y1, double x2, double y2, double x3, double y3, double x, double y)
|
||||||
const double vertex_dist_epsilon = 1e-5;
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------intersection_epsilon
|
//-----------------------------------------------------------calc_distance
|
||||||
// See calc_intersection
|
AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
|
||||||
const double intersection_epsilon = 1.0e-30;
|
{
|
||||||
|
double dx = x2 - x1;
|
||||||
|
double dy = y2 - y1;
|
||||||
|
return sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------cross_product
|
//--------------------------------------------------------calc_sq_distance
|
||||||
AGG_INLINE double cross_product(double x1, double y1,
|
AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
|
||||||
double x2, double y2,
|
{
|
||||||
double x, double y)
|
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 (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------point_in_triangle
|
double pdx = x - x1;
|
||||||
AGG_INLINE bool point_in_triangle(double x1, double y1,
|
double pdy = y - 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
|
return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
|
||||||
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
|
//---------------------------------------------calc_line_point_sq_distance
|
||||||
AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
|
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)
|
||||||
{
|
{
|
||||||
double dx = x2-x1;
|
return calc_sq_distance(x, y, x1, y1);
|
||||||
double dy = y2-y1;
|
|
||||||
return dx * dx + dy * dy;
|
|
||||||
}
|
}
|
||||||
|
else if (u >= 1)
|
||||||
//------------------------------------------------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;
|
return calc_sq_distance(x, y, x2, y2);
|
||||||
double dy = y2-y1;
|
}
|
||||||
double d = sqrt(dx * dx + dy * dy);
|
return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
|
||||||
if(d < vertex_dist_epsilon)
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------calc_line_point_sq_distance
|
||||||
|
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, double x2, double y2, double x, double y)
|
||||||
|
{
|
||||||
|
return calc_segment_point_sq_distance(x1, y1, x2, y2, x, y, calc_segment_point_u(x1, y1, x2, y2, x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------calc_intersection
|
||||||
|
AGG_INLINE bool calc_intersection(double ax,
|
||||||
|
double ay,
|
||||||
|
double bx,
|
||||||
|
double by,
|
||||||
|
double cx,
|
||||||
|
double cy,
|
||||||
|
double dx,
|
||||||
|
double dy,
|
||||||
|
double* x,
|
||||||
|
double* y)
|
||||||
|
{
|
||||||
|
double num = (ay - cy) * (dx - cx) - (ax - cx) * (dy - cy);
|
||||||
|
double den = (bx - ax) * (dy - cy) - (by - ay) * (dx - cx);
|
||||||
|
if (std::fabs(den) < intersection_epsilon)
|
||||||
|
return false;
|
||||||
|
double r = num / den;
|
||||||
|
*x = ax + r * (bx - ax);
|
||||||
|
*y = ay + r * (by - ay);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------intersection_exists
|
||||||
|
AGG_INLINE bool
|
||||||
|
intersection_exists(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
|
||||||
|
{
|
||||||
|
// It's less expensive but you can't control the
|
||||||
|
// boundary conditions: Less or LessEqual
|
||||||
|
double dx1 = x2 - x1;
|
||||||
|
double dy1 = y2 - y1;
|
||||||
|
double dx2 = x4 - x3;
|
||||||
|
double dy2 = y4 - y3;
|
||||||
|
return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) != ((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
|
||||||
|
((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) != ((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
|
||||||
|
|
||||||
|
// It's is more expensive but more flexible
|
||||||
|
// in terms of boundary conditions.
|
||||||
|
//--------------------
|
||||||
|
// double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
|
||||||
|
// if(std::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 (std::fabs(loc) > intersection_epsilon)
|
||||||
|
{
|
||||||
|
if (cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
|
||||||
{
|
{
|
||||||
return calc_distance(x1, y1, x, y);
|
d = -d;
|
||||||
}
|
}
|
||||||
return ((x - x2) * dy - (y - y2) * dx) / 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_line_point_u
|
//------------------------------------------------------calc_triangle_area
|
||||||
AGG_INLINE double calc_segment_point_u(double x1, double y1,
|
AGG_INLINE double calc_triangle_area(double x1, double y1, double x2, double y2, double x3, double y3)
|
||||||
double x2, double y2,
|
{
|
||||||
double x, double y)
|
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++)
|
||||||
{
|
{
|
||||||
double dx = x2 - x1;
|
const typename Storage::value_type& v = st[i];
|
||||||
double dy = y2 - y1;
|
sum += x * v.y - y * v.x;
|
||||||
|
x = v.x;
|
||||||
if(dx == 0 && dy == 0)
|
y = v.y;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
double pdx = x - x1;
|
|
||||||
double pdy = y - y1;
|
|
||||||
|
|
||||||
return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
|
|
||||||
}
|
}
|
||||||
|
return (sum + x * ys - y * xs) * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------calc_line_point_sq_distance
|
//------------------------------------------------------------------------
|
||||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
|
// Tables for fast sqrt
|
||||||
double x2, double y2,
|
extern int16u g_sqrt_table[1024];
|
||||||
double x, double y,
|
extern int8 g_elder_bit_table[256];
|
||||||
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
|
//---------------------------------------------------------------fast_sqrt
|
||||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
|
// Fast integer Sqrt - really fast: no cycles, divisions or multiplications
|
||||||
double x2, double y2,
|
#if defined(_MSC_VER)
|
||||||
double x, double y)
|
#pragma warning(push)
|
||||||
{
|
#pragma warning(disable: 4035) // Disable warning "no return value"
|
||||||
return
|
#endif
|
||||||
calc_segment_point_sq_distance(
|
AGG_INLINE unsigned fast_sqrt(unsigned val)
|
||||||
x1, y1, x2, y2, x, y,
|
{
|
||||||
calc_segment_point_u(x1, y1, x2, y2, x, y));
|
#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
|
||||||
//-------------------------------------------------------calc_intersection
|
// significant bit of the value. For other processors
|
||||||
AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by,
|
//(and maybe compilers) the pure C "#else" section is used.
|
||||||
double cx, double cy, double dx, double dy,
|
__asm {
|
||||||
double* x, double* y)
|
|
||||||
{
|
|
||||||
double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy);
|
|
||||||
double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx);
|
|
||||||
if(std::fabs(den) < intersection_epsilon) return false;
|
|
||||||
double r = num / den;
|
|
||||||
*x = ax + r * (bx-ax);
|
|
||||||
*y = ay + r * (by-ay);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------intersection_exists
|
|
||||||
AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2,
|
|
||||||
double x3, double y3, double x4, double y4)
|
|
||||||
{
|
|
||||||
// It's less expensive but you can't control the
|
|
||||||
// boundary conditions: Less or LessEqual
|
|
||||||
double dx1 = x2 - x1;
|
|
||||||
double dy1 = y2 - y1;
|
|
||||||
double dx2 = x4 - x3;
|
|
||||||
double dy2 = y4 - y3;
|
|
||||||
return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) !=
|
|
||||||
((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
|
|
||||||
((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
|
|
||||||
((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
|
|
||||||
|
|
||||||
// It's is more expensive but more flexible
|
|
||||||
// in terms of boundary conditions.
|
|
||||||
//--------------------
|
|
||||||
//double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
|
|
||||||
//if(std::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(std::fabs(loc) > intersection_epsilon)
|
|
||||||
{
|
|
||||||
if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
|
|
||||||
{
|
|
||||||
d = -d;
|
|
||||||
}
|
|
||||||
calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1);
|
|
||||||
calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
|
|
||||||
calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
|
|
||||||
}
|
|
||||||
*x++ = x1 + dx1; *y++ = y1 + dy1;
|
|
||||||
*x++ = x2 + dx1; *y++ = y2 + dy1;
|
|
||||||
*x++ = x2 + dx2; *y++ = y2 + dy2;
|
|
||||||
*x++ = x3 + dx2; *y++ = y3 + dy2;
|
|
||||||
*x++ = x3 + dx3; *y++ = y3 + dy3;
|
|
||||||
*x++ = x1 + dx3; *y++ = y1 + dy3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------calc_triangle_area
|
|
||||||
AGG_INLINE double calc_triangle_area(double x1, double y1,
|
|
||||||
double x2, double y2,
|
|
||||||
double x3, double y3)
|
|
||||||
{
|
|
||||||
return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------calc_polygon_area
|
|
||||||
template<class Storage> double calc_polygon_area(const Storage& st)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
double sum = 0.0;
|
|
||||||
double x = st[0].x;
|
|
||||||
double y = st[0].y;
|
|
||||||
double xs = x;
|
|
||||||
double ys = y;
|
|
||||||
|
|
||||||
for(i = 1; i < st.size(); i++)
|
|
||||||
{
|
|
||||||
const typename Storage::value_type& v = st[i];
|
|
||||||
sum += x * v.y - y * v.x;
|
|
||||||
x = v.x;
|
|
||||||
y = v.y;
|
|
||||||
}
|
|
||||||
return (sum + x * ys - y * xs) * 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Tables for fast sqrt
|
|
||||||
extern int16u g_sqrt_table[1024];
|
|
||||||
extern int8 g_elder_bit_table[256];
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------fast_sqrt
|
|
||||||
//Fast integer Sqrt - really fast: no cycles, divisions or multiplications
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4035) //Disable warning "no return value"
|
|
||||||
#endif
|
|
||||||
AGG_INLINE unsigned fast_sqrt(unsigned val)
|
|
||||||
{
|
|
||||||
#if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
|
|
||||||
//For Ix86 family processors this assembler code is used.
|
|
||||||
//The key command here is bsr - determination the number of the most
|
|
||||||
//significant bit of the value. For other processors
|
|
||||||
//(and maybe compilers) the pure C "#else" section is used.
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
mov ebx, val
|
mov ebx, val
|
||||||
mov edx, 11
|
mov edx, 11
|
||||||
bsr ecx, ebx
|
bsr ecx, ebx
|
||||||
|
@ -282,156 +267,153 @@ namespace agg
|
||||||
mov ax, g_sqrt_table[ebx*2]
|
mov ax, g_sqrt_table[ebx*2]
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
shr eax, cl
|
shr eax, cl
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
//This code is actually pure C and portable to most
|
// This code is actually pure C and portable to most
|
||||||
//arcitectures including 64bit ones.
|
// arcitectures including 64bit ones.
|
||||||
unsigned t = val;
|
unsigned t = val;
|
||||||
int bit=0;
|
int bit = 0;
|
||||||
unsigned shift = 11;
|
unsigned shift = 11;
|
||||||
|
|
||||||
//The following piece of code is just an emulation of the
|
// The following piece of code is just an emulation of the
|
||||||
//Ix86 assembler command "bsr" (see above). However on old
|
// Ix86 assembler command "bsr" (see above). However on old
|
||||||
//Intels (like Intel MMX 233MHz) this code is about twice
|
// Intels (like Intel MMX 233MHz) this code is about twice
|
||||||
//faster (sic!) then just one "bsr". On PIII and PIV the
|
// faster (sic!) then just one "bsr". On PIII and PIV the
|
||||||
//bsr is optimized quite well.
|
// bsr is optimized quite well.
|
||||||
bit = t >> 24;
|
bit = t >> 24;
|
||||||
if(bit)
|
if (bit)
|
||||||
|
{
|
||||||
|
bit = g_elder_bit_table[bit] + 24;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bit = (t >> 16) & 0xFF;
|
||||||
|
if (bit)
|
||||||
{
|
{
|
||||||
bit = g_elder_bit_table[bit] + 24;
|
bit = g_elder_bit_table[bit] + 16;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bit = (t >> 16) & 0xFF;
|
bit = (t >> 8) & 0xFF;
|
||||||
if(bit)
|
if (bit)
|
||||||
{
|
{
|
||||||
bit = g_elder_bit_table[bit] + 16;
|
bit = g_elder_bit_table[bit] + 8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bit = (t >> 8) & 0xFF;
|
bit = g_elder_bit_table[t];
|
||||||
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
|
|
||||||
|
|
||||||
|
// This code calculates the sqrt.
|
||||||
|
bit -= 9;
|
||||||
|
if (bit > 0)
|
||||||
//--------------------------------------------------------------------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)
|
bit = (bit >> 1) + (bit & 1);
|
||||||
{
|
shift -= bit;
|
||||||
|
val >>= (bit << 1);
|
||||||
|
}
|
||||||
|
return g_sqrt_table[val] >> shift;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------besj
|
||||||
|
// Function BESJ calculates Bessel function of first kind of order n
|
||||||
|
// Arguments:
|
||||||
|
// n - an integer (>=0), the order
|
||||||
|
// x - value at which the Bessel function is required
|
||||||
|
//--------------------
|
||||||
|
// C++ Mathematical Library
|
||||||
|
// Convereted from equivalent FORTRAN library
|
||||||
|
// Converetd by Gareth Walker for use by course 392 computational project
|
||||||
|
// All functions tested and yield the same results as the corresponding
|
||||||
|
// FORTRAN versions.
|
||||||
|
//
|
||||||
|
// If you have any problems using these functions please report them to
|
||||||
|
// M.Muldoon@UMIST.ac.uk
|
||||||
|
//
|
||||||
|
// Documentation available on the web
|
||||||
|
// http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
|
||||||
|
// Version 1.0 8/98
|
||||||
|
// 29 October, 1999
|
||||||
|
//--------------------
|
||||||
|
// Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com)
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
inline double besj(double x, int n)
|
||||||
|
{
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
double d = 1E-6;
|
||||||
|
double b = 0;
|
||||||
|
if (std::fabs(x) <= d)
|
||||||
|
{
|
||||||
|
if (n != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
return 1;
|
||||||
double d = 1E-6;
|
}
|
||||||
double b = 0;
|
double b1 = 0; // b1 is the value from the previous iteration
|
||||||
if(std::fabs(x) <= d)
|
// Set up a starting order for recurrence
|
||||||
|
int m1 = (int)fabs(x) + 6;
|
||||||
|
if (std::fabs(x) > 5)
|
||||||
|
{
|
||||||
|
m1 = (int)(std::fabs(1.4 * x + 60 / x));
|
||||||
|
}
|
||||||
|
int m2 = (int)(n + 2 + std::fabs(x) / 4);
|
||||||
|
if (m1 > m2)
|
||||||
|
{
|
||||||
|
m2 = m1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply recurrence down from curent max order
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
double c3 = 0;
|
||||||
|
double c2 = 1E-30;
|
||||||
|
double c4 = 0;
|
||||||
|
int m8 = 1;
|
||||||
|
if (m2 / 2 * 2 == m2)
|
||||||
{
|
{
|
||||||
if(n != 0) return 0;
|
m8 = -1;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
double b1 = 0; // b1 is the value from the previous iteration
|
int imax = m2 - 2;
|
||||||
// Set up a starting order for recurrence
|
for (int i = 1; i <= imax; i++)
|
||||||
int m1 = (int)fabs(x) + 6;
|
|
||||||
if(std::fabs(x) > 5)
|
|
||||||
{
|
{
|
||||||
m1 = (int)(std::fabs(1.4 * x + 60 / x));
|
double c6 = 2 * (m2 - i) * c2 / x - c3;
|
||||||
}
|
c3 = c2;
|
||||||
int m2 = (int)(n + 2 + std::fabs(x) / 4);
|
c2 = c6;
|
||||||
if (m1 > m2)
|
if (m2 - i - 1 == n)
|
||||||
{
|
|
||||||
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;
|
b = c6;
|
||||||
}
|
}
|
||||||
c4 += c6;
|
m8 = -1 * m8;
|
||||||
b /= c4;
|
if (m8 > 0)
|
||||||
if(std::fabs(b - b1) < d)
|
|
||||||
{
|
{
|
||||||
return b;
|
c4 = c4 + 2 * c6;
|
||||||
}
|
}
|
||||||
b1 = b;
|
|
||||||
m2 += 3;
|
|
||||||
}
|
}
|
||||||
|
double c6 = 2 * c2 / x - c3;
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
b = c6;
|
||||||
|
}
|
||||||
|
c4 += c6;
|
||||||
|
b /= c4;
|
||||||
|
if (std::fabs(b - b1) < d)
|
||||||
|
{
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
b1 = b;
|
||||||
|
m2 += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
745
deps/agg/include/agg_math_stroke.h
vendored
745
deps/agg/include/agg_math_stroke.h
vendored
|
@ -23,254 +23,236 @@
|
||||||
#include "agg_math.h"
|
#include "agg_math.h"
|
||||||
#include "agg_vertex_sequence.h"
|
#include "agg_vertex_sequence.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
||||||
{
|
{
|
||||||
//-------------------------------------------------------------line_cap_e
|
public:
|
||||||
enum line_cap_e
|
typedef typename VertexConsumer::value_type coord_type;
|
||||||
{
|
|
||||||
butt_cap,
|
math_stroke();
|
||||||
square_cap,
|
|
||||||
round_cap
|
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_join_e
|
|
||||||
enum line_join_e
|
line_cap_e line_cap() const { return m_line_cap; }
|
||||||
{
|
line_join_e line_join() const { return m_line_join; }
|
||||||
miter_join = 0,
|
inner_join_e inner_join() const { return m_inner_join; }
|
||||||
miter_join_revert = 1,
|
|
||||||
round_join = 2,
|
void width(double w);
|
||||||
bevel_join = 3,
|
void miter_limit(double ml) { m_miter_limit = ml; }
|
||||||
miter_join_round = 4
|
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; }
|
||||||
|
|
||||||
//-----------------------------------------------------------inner_join_e
|
double width() const { return m_width * 2.0; }
|
||||||
enum inner_join_e
|
double miter_limit() const { return m_miter_limit; }
|
||||||
{
|
double inner_miter_limit() const { return m_inner_miter_limit; }
|
||||||
inner_bevel,
|
double approximation_scale() const { return m_approx_scale; }
|
||||||
inner_miter,
|
|
||||||
inner_jag,
|
void calc_cap(VertexConsumer& vc, const vertex_dist& v0, const vertex_dist& v1, double len);
|
||||||
inner_round
|
|
||||||
};
|
void calc_join(VertexConsumer& vc,
|
||||||
|
const vertex_dist& v0,
|
||||||
//------------------------------------------------------------math_stroke
|
const vertex_dist& v1,
|
||||||
template<class VertexConsumer> class math_stroke
|
const vertex_dist& v2,
|
||||||
{
|
double len1,
|
||||||
public:
|
double len2);
|
||||||
typedef typename VertexConsumer::value_type coord_type;
|
|
||||||
|
private:
|
||||||
math_stroke();
|
AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y) { vc.add(coord_type(x, y)); }
|
||||||
|
|
||||||
void line_cap(line_cap_e lc) { m_line_cap = lc; }
|
void calc_arc(VertexConsumer& vc, double x, double y, double dx1, double dy1, double dx2, double dy2);
|
||||||
void line_join(line_join_e lj) { m_line_join = lj; }
|
|
||||||
void inner_join(inner_join_e ij) { m_inner_join = ij; }
|
void calc_miter(VertexConsumer& vc,
|
||||||
|
const vertex_dist& v0,
|
||||||
line_cap_e line_cap() const { return m_line_cap; }
|
const vertex_dist& v1,
|
||||||
line_join_e line_join() const { return m_line_join; }
|
const vertex_dist& v2,
|
||||||
inner_join_e inner_join() const { return m_inner_join; }
|
double dx1,
|
||||||
|
double dy1,
|
||||||
void width(double w);
|
double dx2,
|
||||||
void miter_limit(double ml) { m_miter_limit = ml; }
|
double dy2,
|
||||||
void miter_limit_theta(double t);
|
line_join_e lj,
|
||||||
void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
|
double mlimit,
|
||||||
void approximation_scale(double as) { m_approx_scale = as; }
|
double dbevel);
|
||||||
|
|
||||||
double width() const { return m_width * 2.0; }
|
double m_width;
|
||||||
double miter_limit() const { return m_miter_limit; }
|
double m_width_abs;
|
||||||
double inner_miter_limit() const { return m_inner_miter_limit; }
|
double m_width_eps;
|
||||||
double approximation_scale() const { return m_approx_scale; }
|
int m_width_sign;
|
||||||
|
double m_miter_limit;
|
||||||
void calc_cap(VertexConsumer& vc,
|
double m_inner_miter_limit;
|
||||||
const vertex_dist& v0,
|
double m_approx_scale;
|
||||||
const vertex_dist& v1,
|
line_cap_e m_line_cap;
|
||||||
double len);
|
line_join_e m_line_join;
|
||||||
|
inner_join_e m_inner_join;
|
||||||
void calc_join(VertexConsumer& vc,
|
};
|
||||||
const vertex_dist& v0,
|
|
||||||
const vertex_dist& v1,
|
//-----------------------------------------------------------------------
|
||||||
const vertex_dist& v2,
|
template<class VC>
|
||||||
double len1,
|
math_stroke<VC>::math_stroke()
|
||||||
double len2);
|
: m_width(0.5)
|
||||||
|
, m_width_abs(0.5)
|
||||||
private:
|
, m_width_eps(0.5 / 1024.0)
|
||||||
AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y)
|
, m_width_sign(1)
|
||||||
{
|
, m_miter_limit(4.0)
|
||||||
vc.add(coord_type(x, y));
|
, m_inner_miter_limit(1.01)
|
||||||
}
|
, m_approx_scale(1.0)
|
||||||
|
, m_line_cap(butt_cap)
|
||||||
void calc_arc(VertexConsumer& vc,
|
, m_line_join(miter_join)
|
||||||
double x, double y,
|
, m_inner_join(inner_miter)
|
||||||
double dx1, double dy1,
|
{}
|
||||||
double dx2, double dy2);
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
void calc_miter(VertexConsumer& vc,
|
template<class VC>
|
||||||
const vertex_dist& v0,
|
void math_stroke<VC>::width(double w)
|
||||||
const vertex_dist& v1,
|
{
|
||||||
const vertex_dist& v2,
|
m_width = w * 0.5;
|
||||||
double dx1, double dy1,
|
if (m_width < 0)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
m_width_abs = -m_width;
|
||||||
|
m_width_sign = -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//-----------------------------------------------------------------------
|
|
||||||
template<class VC> void math_stroke<VC>::width(double w)
|
|
||||||
{
|
{
|
||||||
m_width = w * 0.5;
|
m_width_abs = m_width;
|
||||||
if(m_width < 0)
|
m_width_sign = 1;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
m_width_eps = m_width / 1024.0;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
template<class VC> void math_stroke<VC>::miter_limit_theta(double t)
|
template<class VC>
|
||||||
|
void math_stroke<VC>::miter_limit_theta(double t)
|
||||||
|
{
|
||||||
|
m_miter_limit = 1.0 / std::sin(t * 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
template<class VC>
|
||||||
|
void math_stroke<VC>::calc_arc(VC& vc, double x, double y, double dx1, double dy1, double dx2, double dy2)
|
||||||
|
{
|
||||||
|
double a1 = std::atan2(dy1 * m_width_sign, dx1 * m_width_sign);
|
||||||
|
double a2 = std::atan2(dy2 * m_width_sign, dx2 * m_width_sign);
|
||||||
|
double da = a1 - a2;
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
da = std::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)
|
||||||
{
|
{
|
||||||
m_miter_limit = 1.0 / std::sin(t * 0.5) ;
|
if (a1 > a2)
|
||||||
}
|
a2 += 2 * pi;
|
||||||
|
n = int((a2 - a1) / da);
|
||||||
//-----------------------------------------------------------------------
|
da = (a2 - a1) / (n + 1);
|
||||||
template<class VC>
|
a1 += da;
|
||||||
void math_stroke<VC>::calc_arc(VC& vc,
|
for (i = 0; i < n; i++)
|
||||||
double x, double y,
|
|
||||||
double dx1, double dy1,
|
|
||||||
double dx2, double dy2)
|
|
||||||
{
|
|
||||||
double a1 = std::atan2(dy1 * m_width_sign, dx1 * m_width_sign);
|
|
||||||
double a2 = std::atan2(dy2 * m_width_sign, dx2 * m_width_sign);
|
|
||||||
double da = a1 - a2;
|
|
||||||
int i, n;
|
|
||||||
|
|
||||||
da = std::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;
|
add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width);
|
||||||
n = int((a2 - a1) / da);
|
|
||||||
da = (a2 - a1) / (n + 1);
|
|
||||||
a1 += da;
|
a1 += da;
|
||||||
for(i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width);
|
|
||||||
a1 += da;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
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++)
|
||||||
{
|
{
|
||||||
if(a1 < a2) a2 -= 2 * pi;
|
add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width);
|
||||||
n = int((a1 - a2) / da);
|
|
||||||
da = (a1 - a2) / (n + 1);
|
|
||||||
a1 -= da;
|
a1 -= da;
|
||||||
for(i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width);
|
|
||||||
a1 -= da;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
add_vertex(vc, x + dx2, y + dy2);
|
}
|
||||||
|
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)
|
||||||
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;
|
// Miter limit exceeded
|
||||||
double yi = v1.y;
|
//------------------------
|
||||||
double di = 1;
|
switch (lj)
|
||||||
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:
|
case miter_join_revert:
|
||||||
// For the compatibility with SVG, PDF, etc,
|
// For the compatibility with SVG, PDF, etc,
|
||||||
// we use a simple bevel join instead of
|
// we use a simple bevel join instead of
|
||||||
|
@ -287,13 +269,11 @@ namespace agg
|
||||||
default:
|
default:
|
||||||
// If no miter-revert, calculate new dx1, dy1, dx2, dy2
|
// If no miter-revert, calculate new dx1, dy1, dx2, dy2
|
||||||
//----------------
|
//----------------
|
||||||
if(intersection_failed)
|
if (intersection_failed)
|
||||||
{
|
{
|
||||||
mlimit *= m_width_sign;
|
mlimit *= m_width_sign;
|
||||||
add_vertex(vc, v1.x + dx1 + dy1 * mlimit,
|
add_vertex(vc, v1.x + dx1 + dy1 * mlimit, v1.y - dy1 + dx1 * mlimit);
|
||||||
v1.y - dy1 + dx1 * mlimit);
|
add_vertex(vc, v1.x + dx2 - dy2 * mlimit, v1.y - dy2 - dx2 * mlimit);
|
||||||
add_vertex(vc, v1.x + dx2 - dy2 * mlimit,
|
|
||||||
v1.y - dy2 - dx2 * mlimit);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -302,208 +282,196 @@ namespace agg
|
||||||
double x2 = v1.x + dx2;
|
double x2 = v1.x + dx2;
|
||||||
double y2 = v1.y - dy2;
|
double y2 = v1.y - dy2;
|
||||||
di = (lim - dbevel) / (di - dbevel);
|
di = (lim - dbevel) / (di - dbevel);
|
||||||
add_vertex(vc, x1 + (xi - x1) * di,
|
add_vertex(vc, x1 + (xi - x1) * di, y1 + (yi - y1) * di);
|
||||||
y1 + (yi - y1) * di);
|
add_vertex(vc, x2 + (xi - x2) * di, y2 + (yi - y2) * di);
|
||||||
add_vertex(vc, x2 + (xi - x2) * di,
|
|
||||||
y2 + (yi - y2) * di);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------stroke_calc_cap
|
//--------------------------------------------------------stroke_calc_cap
|
||||||
template<class VC>
|
template<class VC>
|
||||||
void math_stroke<VC>::calc_cap(VC& vc,
|
void math_stroke<VC>::calc_cap(VC& vc, const vertex_dist& v0, const vertex_dist& v1, double len)
|
||||||
const vertex_dist& v0,
|
{
|
||||||
const vertex_dist& v1,
|
vc.remove_all();
|
||||||
double len)
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
vc.remove_all();
|
if (m_line_cap == square_cap)
|
||||||
|
|
||||||
double dx1 = (v1.y - v0.y) / len;
|
|
||||||
double dy1 = (v1.x - v0.x) / len;
|
|
||||||
double dx2 = 0;
|
|
||||||
double dy2 = 0;
|
|
||||||
|
|
||||||
dx1 *= m_width;
|
|
||||||
dy1 *= m_width;
|
|
||||||
|
|
||||||
if(m_line_cap != round_cap)
|
|
||||||
{
|
{
|
||||||
if(m_line_cap == square_cap)
|
dx2 = dy1 * m_width_sign;
|
||||||
|
dy2 = dx1 * m_width_sign;
|
||||||
|
}
|
||||||
|
add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
|
||||||
|
add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double da = std::acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
|
||||||
|
double a1;
|
||||||
|
int i;
|
||||||
|
int n = int(pi / da);
|
||||||
|
|
||||||
|
da = pi / (n + 1);
|
||||||
|
add_vertex(vc, v0.x - dx1, v0.y + dy1);
|
||||||
|
if (m_width_sign > 0)
|
||||||
|
{
|
||||||
|
a1 = std::atan2(dy1, -dx1);
|
||||||
|
a1 += da;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
dx2 = dy1 * m_width_sign;
|
add_vertex(vc, v0.x + std::cos(a1) * m_width, v0.y + std::sin(a1) * m_width);
|
||||||
dy2 = dx1 * m_width_sign;
|
a1 += da;
|
||||||
}
|
}
|
||||||
add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
|
|
||||||
add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double da = std::acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
|
a1 = std::atan2(-dy1, dx1);
|
||||||
double a1;
|
a1 -= da;
|
||||||
int i;
|
for (i = 0; i < n; i++)
|
||||||
int n = int(pi / da);
|
|
||||||
|
|
||||||
da = pi / (n + 1);
|
|
||||||
add_vertex(vc, v0.x - dx1, v0.y + dy1);
|
|
||||||
if(m_width_sign > 0)
|
|
||||||
{
|
{
|
||||||
a1 = std::atan2(dy1, -dx1);
|
add_vertex(vc, v0.x + std::cos(a1) * m_width, v0.y + std::sin(a1) * m_width);
|
||||||
a1 += da;
|
|
||||||
for(i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
add_vertex(vc, v0.x + std::cos(a1) * m_width,
|
|
||||||
v0.y + std::sin(a1) * m_width);
|
|
||||||
a1 += da;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a1 = std::atan2(-dy1, dx1);
|
|
||||||
a1 -= da;
|
a1 -= da;
|
||||||
for(i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
add_vertex(vc, v0.x + std::cos(a1) * m_width,
|
|
||||||
v0.y + std::sin(a1) * m_width);
|
|
||||||
a1 -= da;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
add_vertex(vc, v0.x + dx1, v0.y - dy1);
|
|
||||||
}
|
}
|
||||||
|
add_vertex(vc, v0.x + dx1, v0.y - dy1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
template<class VC>
|
template<class VC>
|
||||||
void math_stroke<VC>::calc_join(VC& vc,
|
void math_stroke<VC>::calc_join(VC& vc,
|
||||||
const vertex_dist& v0,
|
const vertex_dist& v0,
|
||||||
const vertex_dist& v1,
|
const vertex_dist& v1,
|
||||||
const vertex_dist& v2,
|
const vertex_dist& v2,
|
||||||
double len1,
|
double len1,
|
||||||
double len2)
|
double len2)
|
||||||
|
{
|
||||||
|
double dx1 = m_width * (v1.y - v0.y) / len1;
|
||||||
|
double dy1 = m_width * (v1.x - v0.x) / len1;
|
||||||
|
double dx2 = m_width * (v2.y - v1.y) / len2;
|
||||||
|
double dy2 = m_width * (v2.x - v1.x) / len2;
|
||||||
|
|
||||||
|
vc.remove_all();
|
||||||
|
|
||||||
|
double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
|
||||||
|
if (cp != 0 && (cp > 0) == (m_width > 0) && m_width_abs > 0)
|
||||||
{
|
{
|
||||||
double dx1 = m_width * (v1.y - v0.y) / len1;
|
// Inner join
|
||||||
double dy1 = m_width * (v1.x - v0.x) / len1;
|
//---------------
|
||||||
double dx2 = m_width * (v2.y - v1.y) / len2;
|
double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
|
||||||
double dy2 = m_width * (v2.x - v1.x) / len2;
|
if (limit < m_inner_miter_limit)
|
||||||
|
|
||||||
vc.remove_all();
|
|
||||||
|
|
||||||
double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
|
|
||||||
if (cp != 0 && (cp > 0) == (m_width > 0) && m_width_abs > 0)
|
|
||||||
{
|
{
|
||||||
// Inner join
|
limit = m_inner_miter_limit;
|
||||||
//---------------
|
}
|
||||||
double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
|
|
||||||
if (limit < m_inner_miter_limit)
|
|
||||||
{
|
|
||||||
limit = m_inner_miter_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(m_inner_join)
|
switch (m_inner_join)
|
||||||
{
|
{
|
||||||
default: // inner_bevel
|
default: // inner_bevel
|
||||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case inner_miter:
|
case inner_miter:
|
||||||
calc_miter(vc,
|
calc_miter(vc, v0, v1, v2, dx1, dy1, dx2, dy2, miter_join_revert, limit, 0);
|
||||||
v0, v1, v2, dx1, dy1, dx2, dy2,
|
|
||||||
miter_join_revert,
|
|
||||||
limit, 0);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case inner_jag:
|
case inner_jag:
|
||||||
case inner_round:
|
case inner_round:
|
||||||
cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
|
cp = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2);
|
||||||
if(cp < len1 * len1 && cp < len2 * len2)
|
if (cp < len1 * len1 && cp < len2 * len2)
|
||||||
{
|
{
|
||||||
calc_miter(vc,
|
calc_miter(vc, v0, v1, v2, dx1, dy1, dx2, dy2, miter_join_revert, limit, 0);
|
||||||
v0, v1, v2, dx1, dy1, dx2, dy2,
|
|
||||||
miter_join_revert,
|
|
||||||
limit, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(m_inner_join == inner_jag)
|
if (m_inner_join == inner_jag)
|
||||||
{
|
{
|
||||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||||
add_vertex(vc, v1.x, v1.y );
|
add_vertex(vc, v1.x, v1.y);
|
||||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||||
add_vertex(vc, v1.x, v1.y );
|
add_vertex(vc, v1.x, v1.y);
|
||||||
calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
|
calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
|
||||||
add_vertex(vc, v1.x, v1.y );
|
add_vertex(vc, v1.x, v1.y);
|
||||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
switch (m_line_join)
|
||||||
{
|
{
|
||||||
// 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:
|
||||||
case miter_join_revert:
|
case miter_join_revert:
|
||||||
case miter_join_round:
|
case miter_join_round:
|
||||||
calc_miter(vc,
|
calc_miter(vc, v0, v1, v2, dx1, dy1, dx2, dy2, m_line_join, m_miter_limit, dbevel);
|
||||||
v0, v1, v2, dx1, dy1, dx2, dy2,
|
|
||||||
m_line_join,
|
|
||||||
m_miter_limit,
|
|
||||||
dbevel);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case round_join:
|
case round_join:
|
||||||
|
@ -514,13 +482,10 @@ namespace agg
|
||||||
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
add_vertex(vc, v1.x + dx1, v1.y - dy1);
|
||||||
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
add_vertex(vc, v1.x + dx2, v1.y - dy2);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
69
deps/agg/include/agg_path_length.h
vendored
69
deps/agg/include/agg_path_length.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -17,49 +17,48 @@
|
||||||
|
|
||||||
#include "agg_math.h"
|
#include "agg_math.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
template<class VertexSource>
|
||||||
|
double path_length(VertexSource& vs, unsigned path_id = 0)
|
||||||
{
|
{
|
||||||
template<class VertexSource>
|
double len = 0.0;
|
||||||
double path_length(VertexSource& vs, unsigned path_id = 0)
|
double start_x = 0.0;
|
||||||
{
|
double start_y = 0.0;
|
||||||
double len = 0.0;
|
double x1 = 0.0;
|
||||||
double start_x = 0.0;
|
double y1 = 0.0;
|
||||||
double start_y = 0.0;
|
double x2 = 0.0;
|
||||||
double x1 = 0.0;
|
double y2 = 0.0;
|
||||||
double y1 = 0.0;
|
bool first = true;
|
||||||
double x2 = 0.0;
|
|
||||||
double y2 = 0.0;
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
unsigned cmd;
|
unsigned cmd;
|
||||||
vs.rewind(path_id);
|
vs.rewind(path_id);
|
||||||
while(!is_stop(cmd = vs.vertex(&x2, &y2)))
|
while (!is_stop(cmd = vs.vertex(&x2, &y2)))
|
||||||
|
{
|
||||||
|
if (is_vertex(cmd))
|
||||||
{
|
{
|
||||||
if(is_vertex(cmd))
|
if (first || is_move_to(cmd))
|
||||||
{
|
{
|
||||||
if(first || is_move_to(cmd))
|
start_x = x2;
|
||||||
{
|
start_y = y2;
|
||||||
start_x = x2;
|
|
||||||
start_y = y2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
len += calc_distance(x1, y1, x2, y2);
|
|
||||||
}
|
|
||||||
x1 = x2;
|
|
||||||
y1 = y2;
|
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(is_close(cmd) && !first)
|
len += calc_distance(x1, y1, x2, y2);
|
||||||
{
|
}
|
||||||
len += calc_distance(x1, y1, start_x, start_y);
|
x1 = x2;
|
||||||
}
|
y1 = y2;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (is_close(cmd) && !first)
|
||||||
|
{
|
||||||
|
len += calc_distance(x1, y1, start_x, start_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2787
deps/agg/include/agg_path_storage.h
vendored
2787
deps/agg/include/agg_path_storage.h
vendored
File diff suppressed because it is too large
Load diff
458
deps/agg/include/agg_path_storage_integer.h
vendored
458
deps/agg/include/agg_path_storage_integer.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -19,277 +19,259 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//---------------------------------------------------------vertex_integer
|
||||||
|
template<class T, unsigned CoordShift = 6>
|
||||||
|
struct vertex_integer
|
||||||
{
|
{
|
||||||
//---------------------------------------------------------vertex_integer
|
enum path_cmd { cmd_move_to = 0, cmd_line_to = 1, cmd_curve3 = 2, cmd_curve4 = 3 };
|
||||||
template<class T, unsigned CoordShift=6> struct vertex_integer
|
|
||||||
|
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
|
||||||
{
|
{
|
||||||
enum path_cmd
|
*x_ = dx + (double(x >> 1) / coord_scale) * scale;
|
||||||
|
*y_ = dy + (double(y >> 1) / coord_scale) * scale;
|
||||||
|
switch (((y & 1) << 1) | (x & 1))
|
||||||
{
|
{
|
||||||
cmd_move_to = 0,
|
case cmd_move_to:
|
||||||
cmd_line_to = 1,
|
return path_cmd_move_to;
|
||||||
cmd_curve3 = 2,
|
case cmd_line_to:
|
||||||
cmd_curve4 = 3
|
return path_cmd_line_to;
|
||||||
};
|
case cmd_curve3:
|
||||||
|
return path_cmd_curve3;
|
||||||
|
case cmd_curve4:
|
||||||
|
return path_cmd_curve4;
|
||||||
|
}
|
||||||
|
return path_cmd_stop;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
enum coord_scale_e
|
//---------------------------------------------------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++)
|
||||||
{
|
{
|
||||||
coord_shift = CoordShift,
|
memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
|
||||||
coord_scale = 1 << coord_shift
|
ptr += sizeof(vertex_integer_type);
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
T x,y;
|
//--------------------------------------------------------------------
|
||||||
vertex_integer() {}
|
void rewind(unsigned)
|
||||||
vertex_integer(T x_, T y_, unsigned flag) :
|
{
|
||||||
x(((x_ << 1) & ~1) | (flag & 1)),
|
m_vertex_idx = 0;
|
||||||
y(((y_ << 1) & ~1) | (flag >> 1)) {}
|
m_closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned vertex(double* x_, double* y_,
|
//--------------------------------------------------------------------
|
||||||
double dx=0, double dy=0,
|
unsigned vertex(double* x, double* y)
|
||||||
double scale=1.0) const
|
{
|
||||||
|
if (m_storage.size() < 2 || m_vertex_idx > m_storage.size())
|
||||||
{
|
{
|
||||||
*x_ = dx + (double(x >> 1) / coord_scale) * scale;
|
*x = 0;
|
||||||
*y_ = dy + (double(y >> 1) / coord_scale) * scale;
|
*y = 0;
|
||||||
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;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
//---------------------------------------------------path_storage_integer
|
rect_d bounding_rect() const
|
||||||
template<class T, unsigned CoordShift=6> class path_storage_integer
|
|
||||||
{
|
{
|
||||||
public:
|
rect_d bounds(1e100, 1e100, -1e100, -1e100);
|
||||||
typedef T value_type;
|
if (m_storage.size() == 0)
|
||||||
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));
|
bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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;
|
unsigned i;
|
||||||
for(i = 0; i < m_storage.size(); i++)
|
for (i = 0; i < m_storage.size(); i++)
|
||||||
{
|
{
|
||||||
memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
|
double x, y;
|
||||||
ptr += sizeof(vertex_integer_type);
|
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:
|
||||||
void rewind(unsigned)
|
pod_bvector<vertex_integer_type, 6> m_storage;
|
||||||
{
|
unsigned m_vertex_idx;
|
||||||
m_vertex_idx = 0;
|
bool m_closed;
|
||||||
m_closed = true;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//-----------------------------------------serialized_integer_path_adaptor
|
||||||
unsigned vertex(double* x, double* y)
|
template<class T, unsigned CoordShift = 6>
|
||||||
{
|
class serialized_integer_path_adaptor
|
||||||
if(m_storage.size() < 2 || m_vertex_idx > m_storage.size())
|
{
|
||||||
{
|
public:
|
||||||
*x = 0;
|
typedef vertex_integer<T, CoordShift> vertex_integer_type;
|
||||||
*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
|
serialized_integer_path_adaptor()
|
||||||
{
|
: m_data(0)
|
||||||
rect_d bounds(1e100, 1e100, -1e100, -1e100);
|
, m_end(0)
|
||||||
if(m_storage.size() == 0)
|
, m_ptr(0)
|
||||||
{
|
, m_dx(0.0)
|
||||||
bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
|
, m_dy(0.0)
|
||||||
}
|
, m_scale(1.0)
|
||||||
else
|
, m_vertices(0)
|
||||||
{
|
{}
|
||||||
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;
|
serialized_integer_path_adaptor(const int8u* data, unsigned size, double dx, double dy)
|
||||||
unsigned m_vertex_idx;
|
: m_data(data)
|
||||||
bool m_closed;
|
, 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)
|
||||||
|
|
||||||
//-----------------------------------------serialized_integer_path_adaptor
|
|
||||||
template<class T, unsigned CoordShift=6> class serialized_integer_path_adaptor
|
|
||||||
{
|
{
|
||||||
public:
|
m_data = data;
|
||||||
typedef vertex_integer<T, CoordShift> vertex_integer_type;
|
m_end = data + size;
|
||||||
|
m_ptr = data;
|
||||||
|
m_dx = dx;
|
||||||
|
m_dy = dy;
|
||||||
|
m_scale = scale;
|
||||||
|
m_vertices = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
serialized_integer_path_adaptor() :
|
void rewind(unsigned)
|
||||||
m_data(0),
|
{
|
||||||
m_end(0),
|
m_ptr = m_data;
|
||||||
m_ptr(0),
|
m_vertices = 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,
|
unsigned vertex(double* x, double* y)
|
||||||
double dx, double dy) :
|
{
|
||||||
m_data(data),
|
if (m_data == 0 || m_ptr > m_end)
|
||||||
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;
|
*x = 0;
|
||||||
m_end = data + size;
|
*y = 0;
|
||||||
m_ptr = data;
|
return path_cmd_stop;
|
||||||
m_dx = dx;
|
|
||||||
m_dy = dy;
|
|
||||||
m_scale = scale;
|
|
||||||
m_vertices = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_ptr == m_end)
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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;
|
||||||
*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);
|
m_ptr += sizeof(vertex_integer_type);
|
||||||
return cmd;
|
return path_cmd_end_poly | path_flags_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
vertex_integer_type v;
|
||||||
const int8u* m_data;
|
memcpy(&v, m_ptr, sizeof(vertex_integer_type));
|
||||||
const int8u* m_end;
|
unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
|
||||||
const int8u* m_ptr;
|
if (is_move_to(cmd) && m_vertices > 2)
|
||||||
double m_dx;
|
{
|
||||||
double m_dy;
|
*x = 0;
|
||||||
double m_scale;
|
*y = 0;
|
||||||
unsigned m_vertices;
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
146
deps/agg/include/agg_pattern_filters_rgba.h
vendored
146
deps/agg/include/agg_pattern_filters_rgba.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -19,104 +19,90 @@
|
||||||
#include "agg_line_aa_basics.h"
|
#include "agg_line_aa_basics.h"
|
||||||
#include "agg_color_rgba.h"
|
#include "agg_color_rgba.h"
|
||||||
|
|
||||||
|
namespace agg {
|
||||||
|
|
||||||
namespace agg
|
//=======================================================pattern_filter_nn
|
||||||
|
template<class ColorT>
|
||||||
|
struct pattern_filter_nn
|
||||||
{
|
{
|
||||||
|
typedef ColorT color_type;
|
||||||
|
static unsigned dilation() { return 0; }
|
||||||
|
|
||||||
//=======================================================pattern_filter_nn
|
static void AGG_INLINE pixel_low_res(color_type const* const* buf, color_type* p, int x, int y) { *p = buf[y][x]; }
|
||||||
template<class ColorT> struct pattern_filter_nn
|
|
||||||
|
static void AGG_INLINE pixel_high_res(color_type const* const* buf, color_type* p, int x, int y)
|
||||||
{
|
{
|
||||||
typedef ColorT color_type;
|
*p = buf[y >> line_subpixel_shift][x >> line_subpixel_shift];
|
||||||
static unsigned dilation() { return 0; }
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void AGG_INLINE pixel_low_res(color_type const* const* buf,
|
typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
|
||||||
color_type* p, int x, int y)
|
typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16;
|
||||||
{
|
|
||||||
*p = buf[y][x];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AGG_INLINE pixel_high_res(color_type const* const* buf,
|
//===========================================pattern_filter_bilinear_rgba
|
||||||
color_type* p, int x, int y)
|
template<class ColorT>
|
||||||
{
|
struct pattern_filter_bilinear_rgba
|
||||||
*p = buf[y >> line_subpixel_shift]
|
{
|
||||||
[x >> line_subpixel_shift];
|
typedef ColorT color_type;
|
||||||
}
|
typedef typename color_type::value_type value_type;
|
||||||
};
|
typedef typename color_type::calc_type calc_type;
|
||||||
|
|
||||||
typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
|
static unsigned dilation() { return 1; }
|
||||||
typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16;
|
|
||||||
|
|
||||||
|
static AGG_INLINE void pixel_low_res(color_type const* const* buf, color_type* p, int x, int y) { *p = buf[y][x]; }
|
||||||
|
|
||||||
//===========================================pattern_filter_bilinear_rgba
|
static AGG_INLINE void pixel_high_res(color_type const* const* buf, color_type* p, int x, int y)
|
||||||
template<class ColorT> struct pattern_filter_bilinear_rgba
|
|
||||||
{
|
{
|
||||||
typedef ColorT color_type;
|
calc_type r, g, b, a;
|
||||||
typedef typename color_type::value_type value_type;
|
r = g = b = a = line_subpixel_scale * line_subpixel_scale / 2;
|
||||||
typedef typename color_type::calc_type calc_type;
|
|
||||||
|
|
||||||
|
calc_type weight;
|
||||||
|
int x_lr = x >> line_subpixel_shift;
|
||||||
|
int y_lr = y >> line_subpixel_shift;
|
||||||
|
|
||||||
static unsigned dilation() { return 1; }
|
x &= line_subpixel_mask;
|
||||||
|
y &= line_subpixel_mask;
|
||||||
|
const color_type* ptr = buf[y_lr] + x_lr;
|
||||||
|
|
||||||
static AGG_INLINE void pixel_low_res(color_type const* const* buf,
|
weight = (line_subpixel_scale - x) * (line_subpixel_scale - y);
|
||||||
color_type* p, int x, int y)
|
r += weight * ptr->r;
|
||||||
{
|
g += weight * ptr->g;
|
||||||
*p = buf[y][x];
|
b += weight * ptr->b;
|
||||||
}
|
a += weight * ptr->a;
|
||||||
|
|
||||||
static AGG_INLINE void pixel_high_res(color_type const* const* buf,
|
++ptr;
|
||||||
color_type* p, int x, int y)
|
|
||||||
{
|
|
||||||
calc_type r, g, b, a;
|
|
||||||
r = g = b = a = line_subpixel_scale * line_subpixel_scale / 2;
|
|
||||||
|
|
||||||
calc_type weight;
|
weight = x * (line_subpixel_scale - y);
|
||||||
int x_lr = x >> line_subpixel_shift;
|
r += weight * ptr->r;
|
||||||
int y_lr = y >> line_subpixel_shift;
|
g += weight * ptr->g;
|
||||||
|
b += weight * ptr->b;
|
||||||
|
a += weight * ptr->a;
|
||||||
|
|
||||||
x &= line_subpixel_mask;
|
ptr = buf[y_lr + 1] + x_lr;
|
||||||
y &= line_subpixel_mask;
|
|
||||||
const color_type* ptr = buf[y_lr] + x_lr;
|
|
||||||
|
|
||||||
weight = (line_subpixel_scale - x) *
|
weight = (line_subpixel_scale - x) * y;
|
||||||
(line_subpixel_scale - y);
|
r += weight * ptr->r;
|
||||||
r += weight * ptr->r;
|
g += weight * ptr->g;
|
||||||
g += weight * ptr->g;
|
b += weight * ptr->b;
|
||||||
b += weight * ptr->b;
|
a += weight * ptr->a;
|
||||||
a += weight * ptr->a;
|
|
||||||
|
|
||||||
++ptr;
|
++ptr;
|
||||||
|
|
||||||
weight = x * (line_subpixel_scale - y);
|
weight = x * y;
|
||||||
r += weight * ptr->r;
|
r += weight * ptr->r;
|
||||||
g += weight * ptr->g;
|
g += weight * ptr->g;
|
||||||
b += weight * ptr->b;
|
b += weight * ptr->b;
|
||||||
a += weight * ptr->a;
|
a += weight * ptr->a;
|
||||||
|
|
||||||
ptr = buf[y_lr + 1] + x_lr;
|
p->r = (value_type)(r >> line_subpixel_shift * 2);
|
||||||
|
p->g = (value_type)(g >> line_subpixel_shift * 2);
|
||||||
|
p->b = (value_type)(b >> line_subpixel_shift * 2);
|
||||||
|
p->a = (value_type)(a >> line_subpixel_shift * 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
weight = (line_subpixel_scale - x) * y;
|
typedef pattern_filter_bilinear_rgba<rgba8> pattern_filter_bilinear_rgba8;
|
||||||
r += weight * ptr->r;
|
typedef pattern_filter_bilinear_rgba<rgba16> pattern_filter_bilinear_rgba16;
|
||||||
g += weight * ptr->g;
|
} // namespace agg
|
||||||
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)(r >> line_subpixel_shift * 2);
|
|
||||||
p->g = (value_type)(g >> line_subpixel_shift * 2);
|
|
||||||
p->b = (value_type)(b >> line_subpixel_shift * 2);
|
|
||||||
p->a = (value_type)(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
335
deps/agg/include/agg_pixfmt_amask_adaptor.h
vendored
335
deps/agg/include/agg_pixfmt_amask_adaptor.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -16,225 +16,196 @@
|
||||||
#ifndef AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
|
#ifndef AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
|
||||||
#define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
|
#define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
#include "agg_rendering_buffer.h"
|
#include "agg_rendering_buffer.h"
|
||||||
|
|
||||||
|
namespace agg {
|
||||||
namespace agg
|
//==================================================pixfmt_amask_adaptor
|
||||||
|
template<class PixFmt, class AlphaMask>
|
||||||
|
class pixfmt_amask_adaptor
|
||||||
{
|
{
|
||||||
//==================================================pixfmt_amask_adaptor
|
public:
|
||||||
template<class PixFmt, class AlphaMask> class pixfmt_amask_adaptor
|
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)
|
||||||
{
|
{
|
||||||
public:
|
if (len > m_span.size())
|
||||||
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);
|
||||||
{
|
|
||||||
m_span.resize(len + span_extra_tail);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init_span(unsigned len)
|
void init_span(unsigned len)
|
||||||
{
|
{
|
||||||
realloc_span(len);
|
realloc_span(len);
|
||||||
memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
|
memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_span(unsigned len, const cover_type* covers)
|
void init_span(unsigned len, const cover_type* covers)
|
||||||
{
|
{
|
||||||
realloc_span(len);
|
realloc_span(len);
|
||||||
memcpy(&m_span[0], covers, len * sizeof(cover_type));
|
memcpy(&m_span[0], covers, len * sizeof(cover_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask)
|
||||||
|
: m_pixf(&pixf)
|
||||||
|
, m_mask(&mask)
|
||||||
|
, m_span()
|
||||||
|
{}
|
||||||
|
|
||||||
public:
|
void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; }
|
||||||
pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask) :
|
void attach_alpha_mask(const amask_type& mask) { m_mask = &mask; }
|
||||||
m_pixf(&pixf), m_mask(&mask), m_span()
|
|
||||||
{}
|
|
||||||
|
|
||||||
void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; }
|
//--------------------------------------------------------------------
|
||||||
void attach_alpha_mask(const 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);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
template<class PixFmt2>
|
unsigned width() const { return m_pixf->width(); }
|
||||||
bool attach_pixfmt(PixFmt2& pixf, int x1, int y1, int x2, int y2)
|
unsigned height() const { return m_pixf->height(); }
|
||||||
{
|
|
||||||
return m_pixf->attach(pixf, x1, y1, x2, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
unsigned width() const { return m_pixf->width(); }
|
color_type pixel(int x, int y) { return m_pixf->pixel(x, y); }
|
||||||
unsigned height() const { return m_pixf->height(); }
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
color_type pixel(int x, int y)
|
void copy_pixel(int x, int y, const color_type& c) { m_pixf->blend_pixel(x, y, c, m_mask->pixel(x, y)); }
|
||||||
{
|
|
||||||
return m_pixf->pixel(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void copy_pixel(int x, int y, const color_type& c)
|
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||||
{
|
{
|
||||||
m_pixf->blend_pixel(x, y, c, m_mask->pixel(x, y));
|
m_pixf->blend_pixel(x, y, c, m_mask->combine_pixel(x, y, cover));
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
void copy_hline(int x, int y, unsigned len, const color_type& c)
|
||||||
{
|
{
|
||||||
m_pixf->blend_pixel(x, y, c, m_mask->combine_pixel(x, y, cover));
|
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 copy_hline(int x, int y,
|
void blend_hline(int x, int y, unsigned len, const color_type& c, cover_type cover)
|
||||||
unsigned len,
|
{
|
||||||
const color_type& c)
|
init_span(len);
|
||||||
{
|
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||||
realloc_span(len);
|
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
||||||
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,
|
void copy_vline(int x, int y, unsigned len, const color_type& c)
|
||||||
unsigned len,
|
{
|
||||||
const color_type& c,
|
realloc_span(len);
|
||||||
cover_type cover)
|
m_mask->fill_vspan(x, y, &m_span[0], len);
|
||||||
{
|
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
|
||||||
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,
|
void blend_vline(int x, int y, unsigned len, const color_type& c, cover_type cover)
|
||||||
unsigned len,
|
{
|
||||||
const color_type& c)
|
init_span(len);
|
||||||
{
|
m_mask->combine_vspan(x, y, &m_span[0], len);
|
||||||
realloc_span(len);
|
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
|
||||||
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,
|
void copy_from(const rendering_buffer& from, int xdst, int ydst, int xsrc, int ysrc, unsigned len)
|
||||||
unsigned len,
|
{
|
||||||
const color_type& c,
|
m_pixf->copy_from(from, xdst, ydst, xsrc, ysrc, len);
|
||||||
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,
|
void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const cover_type* covers)
|
||||||
int xdst, int ydst,
|
{
|
||||||
int xsrc, int ysrc,
|
init_span(len, covers);
|
||||||
unsigned len)
|
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||||
{
|
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
||||||
m_pixf->copy_from(from, xdst, ydst, xsrc, ysrc, len);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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 blend_solid_hspan(int x, int y,
|
void copy_color_hspan(int x, int y, unsigned len, const color_type* colors)
|
||||||
unsigned len,
|
{
|
||||||
const color_type& c,
|
realloc_span(len);
|
||||||
const cover_type* covers)
|
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);
|
init_span(len, covers);
|
||||||
m_mask->combine_hspan(x, y, &m_span[0], len);
|
m_mask->combine_hspan(x, y, &m_span[0], len);
|
||||||
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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);
|
realloc_span(len);
|
||||||
m_mask->fill_hspan(x, y, &m_span[0], 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);
|
|
||||||
}
|
}
|
||||||
|
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void copy_color_vspan(int x, int y, unsigned len, const color_type* colors)
|
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);
|
realloc_span(len);
|
||||||
m_mask->fill_vspan(x, y, &m_span[0], 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);
|
|
||||||
}
|
}
|
||||||
|
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void blend_color_hspan(int x, int y,
|
pixfmt_type* m_pixf;
|
||||||
unsigned len,
|
const amask_type* m_mask;
|
||||||
const color_type* colors,
|
pod_array<cover_type> m_span;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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
|
#endif
|
||||||
|
|
||||||
|
|
121
deps/agg/include/agg_pixfmt_base.h
vendored
121
deps/agg/include/agg_pixfmt_base.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -20,78 +20,69 @@
|
||||||
#include "agg_color_gray.h"
|
#include "agg_color_gray.h"
|
||||||
#include "agg_color_rgba.h"
|
#include "agg_color_rgba.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
||||||
{
|
{
|
||||||
struct pixfmt_gray_tag
|
typedef ColorT color_type;
|
||||||
{
|
typedef Order order_type;
|
||||||
};
|
typedef typename color_type::value_type value_type;
|
||||||
|
|
||||||
struct pixfmt_rgb_tag
|
static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full)
|
||||||
{
|
{
|
||||||
};
|
if (cover > cover_none)
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
rgba c(
|
double x = double(cover) / cover_full;
|
||||||
color_type::to_double(r),
|
c.r *= x;
|
||||||
color_type::to_double(g),
|
c.g *= x;
|
||||||
color_type::to_double(b),
|
c.b *= x;
|
||||||
color_type::to_double(a));
|
c.a *= x;
|
||||||
|
|
||||||
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 c;
|
||||||
{
|
|
||||||
return get(
|
|
||||||
p[order_type::R],
|
|
||||||
p[order_type::G],
|
|
||||||
p[order_type::B],
|
|
||||||
p[order_type::A],
|
|
||||||
cover);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return rgba::no_color();
|
||||||
|
}
|
||||||
|
|
||||||
static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
|
static rgba get(const value_type* p, cover_type cover = cover_full)
|
||||||
{
|
{
|
||||||
p[order_type::R] = r;
|
return get(p[order_type::R], p[order_type::G], p[order_type::B], p[order_type::A], cover);
|
||||||
p[order_type::G] = g;
|
}
|
||||||
p[order_type::B] = b;
|
|
||||||
p[order_type::A] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set(value_type* p, const rgba& c)
|
static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
|
||||||
{
|
{
|
||||||
p[order_type::R] = color_type::from_double(c.r);
|
p[order_type::R] = r;
|
||||||
p[order_type::G] = color_type::from_double(c.g);
|
p[order_type::G] = g;
|
||||||
p[order_type::B] = color_type::from_double(c.b);
|
p[order_type::B] = b;
|
||||||
p[order_type::A] = color_type::from_double(c.a);
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1114
deps/agg/include/agg_pixfmt_gray.h
vendored
1114
deps/agg/include/agg_pixfmt_gray.h
vendored
File diff suppressed because it is too large
Load diff
1356
deps/agg/include/agg_pixfmt_rgb.h
vendored
1356
deps/agg/include/agg_pixfmt_rgb.h
vendored
File diff suppressed because it is too large
Load diff
2205
deps/agg/include/agg_pixfmt_rgb_packed.h
vendored
2205
deps/agg/include/agg_pixfmt_rgb_packed.h
vendored
File diff suppressed because it is too large
Load diff
1886
deps/agg/include/agg_pixfmt_rgba.h
vendored
1886
deps/agg/include/agg_pixfmt_rgba.h
vendored
File diff suppressed because it is too large
Load diff
213
deps/agg/include/agg_pixfmt_transposer.h
vendored
213
deps/agg/include/agg_pixfmt_transposer.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,140 +18,99 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//=======================================================pixfmt_transposer
|
||||||
|
template<class PixFmt>
|
||||||
|
class pixfmt_transposer
|
||||||
{
|
{
|
||||||
//=======================================================pixfmt_transposer
|
public:
|
||||||
template<class PixFmt> class pixfmt_transposer
|
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)
|
||||||
{
|
{
|
||||||
public:
|
m_pixf->blend_vline(y, x, len, c, cover);
|
||||||
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) {}
|
AGG_INLINE void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover)
|
||||||
explicit pixfmt_transposer(pixfmt_type& pixf) : m_pixf(&pixf) {}
|
{
|
||||||
void attach(pixfmt_type& pixf) { m_pixf = &pixf; }
|
m_pixf->blend_hline(y, x, len, c, cover);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE unsigned width() const { return m_pixf->height(); }
|
AGG_INLINE void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers)
|
||||||
AGG_INLINE unsigned height() const { return m_pixf->width(); }
|
{
|
||||||
|
m_pixf->blend_solid_vspan(y, x, len, c, covers);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE color_type pixel(int x, int y) const
|
AGG_INLINE void blend_solid_vspan(int x, int y, unsigned len, const color_type& c, const int8u* covers)
|
||||||
{
|
{
|
||||||
return m_pixf->pixel(y, x);
|
m_pixf->blend_solid_hspan(y, x, len, c, covers);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
|
AGG_INLINE void copy_color_hspan(int x, int y, unsigned len, const color_type* colors)
|
||||||
{
|
{
|
||||||
m_pixf->copy_pixel(y, x, c);
|
m_pixf->copy_color_vspan(y, x, len, colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE void blend_pixel(int x, int y,
|
AGG_INLINE void copy_color_vspan(int x, int y, unsigned len, const color_type* colors)
|
||||||
const color_type& c,
|
{
|
||||||
int8u cover)
|
m_pixf->copy_color_hspan(y, x, len, colors);
|
||||||
{
|
}
|
||||||
m_pixf->blend_pixel(y, x, c, cover);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE void copy_hline(int x, int y,
|
AGG_INLINE void
|
||||||
unsigned len,
|
blend_color_hspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover)
|
||||||
const color_type& c)
|
{
|
||||||
{
|
m_pixf->blend_color_vspan(y, x, len, colors, covers, cover);
|
||||||
m_pixf->copy_vline(y, x, len, c);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE void copy_vline(int x, int y,
|
AGG_INLINE void
|
||||||
unsigned len,
|
blend_color_vspan(int x, int y, unsigned len, const color_type* colors, const int8u* covers, int8u cover)
|
||||||
const color_type& c)
|
{
|
||||||
{
|
m_pixf->blend_color_hspan(y, x, len, colors, covers, cover);
|
||||||
m_pixf->copy_hline(y, x, len, c);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
AGG_INLINE void blend_hline(int x, int y,
|
pixfmt_type* m_pixf;
|
||||||
unsigned len,
|
};
|
||||||
const color_type& c,
|
} // namespace agg
|
||||||
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
1269
deps/agg/include/agg_rasterizer_cells_aa.h
vendored
1269
deps/agg/include/agg_rasterizer_cells_aa.h
vendored
File diff suppressed because it is too large
Load diff
1177
deps/agg/include/agg_rasterizer_compound_aa.h
vendored
1177
deps/agg/include/agg_rasterizer_compound_aa.h
vendored
File diff suppressed because it is too large
Load diff
187
deps/agg/include/agg_rasterizer_outline.h
vendored
187
deps/agg/include/agg_rasterizer_outline.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -17,131 +17,116 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//======================================================rasterizer_outline
|
||||||
|
template<class Renderer>
|
||||||
|
class rasterizer_outline
|
||||||
{
|
{
|
||||||
//======================================================rasterizer_outline
|
public:
|
||||||
template<class Renderer> class rasterizer_outline
|
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)
|
||||||
{
|
{
|
||||||
public:
|
m_vertices = 1;
|
||||||
explicit rasterizer_outline(Renderer& ren) :
|
m_ren->move_to(m_start_x = x, m_start_y = y);
|
||||||
m_ren(&ren),
|
}
|
||||||
m_start_x(0),
|
|
||||||
m_start_y(0),
|
|
||||||
m_vertices(0)
|
|
||||||
{}
|
|
||||||
void attach(Renderer& ren) { m_ren = &ren; }
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void line_to(int x, int y)
|
||||||
|
{
|
||||||
|
++m_vertices;
|
||||||
|
m_ren->line_to(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void move_to(int x, int 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)
|
||||||
{
|
{
|
||||||
m_vertices = 1;
|
line_to(m_start_x, m_start_y);
|
||||||
m_ren->move_to(m_start_x = x, m_start_y = y);
|
|
||||||
}
|
}
|
||||||
|
m_vertices = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void line_to(int x, int y)
|
void add_vertex(double x, double y, unsigned cmd)
|
||||||
|
{
|
||||||
|
if (is_move_to(cmd))
|
||||||
{
|
{
|
||||||
++m_vertices;
|
move_to_d(x, y);
|
||||||
m_ren->line_to(x, y);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void move_to_d(double x, double y)
|
|
||||||
{
|
{
|
||||||
move_to(m_ren->coord(x), m_ren->coord(y));
|
if (is_end_poly(cmd))
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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);
|
if (is_closed(cmd))
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
m_vertices = 0;
|
else
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void add_vertex(double x, double y, unsigned cmd)
|
|
||||||
{
|
|
||||||
if(is_move_to(cmd))
|
|
||||||
{
|
{
|
||||||
move_to_d(x, y);
|
line_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;
|
||||||
template<class VertexSource>
|
vs.rewind(path_id);
|
||||||
void add_path(VertexSource& vs, unsigned path_id=0)
|
while (!is_stop(cmd = vs.vertex(&x, &y)))
|
||||||
{
|
{
|
||||||
double x;
|
add_vertex(x, y, cmd);
|
||||||
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>
|
||||||
template<class VertexSource, class ColorStorage, class PathId>
|
void render_all_paths(VertexSource& vs, const ColorStorage& colors, const PathId& path_id, unsigned num_paths)
|
||||||
void render_all_paths(VertexSource& vs,
|
{
|
||||||
const ColorStorage& colors,
|
for (unsigned i = 0; i < num_paths; i++)
|
||||||
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]);
|
||||||
m_ren->line_color(colors[i]);
|
|
||||||
add_path(vs, path_id[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
//--------------------------------------------------------------------
|
template<class Ctrl>
|
||||||
template<class Ctrl> void render_ctrl(Ctrl& c)
|
void render_ctrl(Ctrl& c)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < c.num_paths(); i++)
|
||||||
{
|
{
|
||||||
unsigned i;
|
m_ren->line_color(c.color(i));
|
||||||
for(i = 0; i < c.num_paths(); i++)
|
add_path(c, 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;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
Renderer* m_ren;
|
|
||||||
int m_start_x;
|
|
||||||
int m_start_y;
|
|
||||||
unsigned m_vertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
875
deps/agg/include/agg_rasterizer_outline_aa.h
vendored
875
deps/agg/include/agg_rasterizer_outline_aa.h
vendored
File diff suppressed because it is too large
Load diff
816
deps/agg/include/agg_rasterizer_scanline_aa.h
vendored
816
deps/agg/include/agg_rasterizer_scanline_aa.h
vendored
|
@ -33,477 +33,445 @@
|
||||||
#include "agg_rasterizer_sl_clip.h"
|
#include "agg_rasterizer_sl_clip.h"
|
||||||
#include "agg_gamma_functions.h"
|
#include "agg_gamma_functions.h"
|
||||||
|
|
||||||
|
namespace agg {
|
||||||
|
|
||||||
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()
|
||||||
//-----------------------------------------------------------------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;
|
x = 0x7FFFFFFF;
|
||||||
int y;
|
y = 0x7FFFFFFF;
|
||||||
int cover;
|
cover = 0;
|
||||||
int area;
|
area = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void initial()
|
void style(const cell_aa&) {}
|
||||||
{
|
|
||||||
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); }
|
||||||
|
};
|
||||||
|
|
||||||
int not_equal(int ex, int ey, const cell_aa&) const
|
//==================================================rasterizer_scanline_aa
|
||||||
{
|
// Polygon rasterizer that is used to render filled polygons with
|
||||||
return (ex - x) | (ey - y);
|
// 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
|
rasterizer_scanline_aa()
|
||||||
// Polygon rasterizer that is used to render filled polygons with
|
: m_outline()
|
||||||
// high-quality Anti-Aliasing. Internally, by default, the class uses
|
, m_clipper()
|
||||||
// integer coordinates in format 24.8, i.e. 24 bits for integer part
|
, m_filling_rule(fill_non_zero)
|
||||||
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
|
, m_auto_close(true)
|
||||||
// used in the following way:
|
, m_start_x(0)
|
||||||
//
|
, m_start_y(0)
|
||||||
// 1. filling_rule(filling_rule_e ft) - optional.
|
, m_status(status_initial)
|
||||||
//
|
|
||||||
// 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
|
int i;
|
||||||
{
|
for (i = 0; i < aa_scale; i++)
|
||||||
status_initial,
|
m_gamma[i] = i;
|
||||||
status_move_to,
|
}
|
||||||
status_line_to,
|
|
||||||
status_closed
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
//--------------------------------------------------------------------
|
||||||
typedef Clip clip_type;
|
template<class GammaF>
|
||||||
typedef typename Clip::conv_type conv_type;
|
rasterizer_scanline_aa(const GammaF& gamma_function)
|
||||||
typedef typename Clip::coord_type coord_type;
|
: m_outline()
|
||||||
|
, 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);
|
||||||
|
}
|
||||||
|
|
||||||
enum aa_scale_e
|
//--------------------------------------------------------------------
|
||||||
{
|
void reset();
|
||||||
aa_shift = 8,
|
void reset_clipping();
|
||||||
aa_scale = 1 << aa_shift,
|
void clip_box(double x1, double y1, double x2, double y2);
|
||||||
aa_mask = aa_scale - 1,
|
void filling_rule(filling_rule_e filling_rule);
|
||||||
aa_scale2 = aa_scale * 2,
|
void auto_close(bool flag) { m_auto_close = flag; }
|
||||||
aa_mask2 = aa_scale2 - 1
|
|
||||||
};
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
rasterizer_scanline_aa() :
|
template<class GammaF>
|
||||||
m_outline(),
|
void gamma(const GammaF& gamma_function)
|
||||||
m_clipper(),
|
{
|
||||||
m_filling_rule(fill_non_zero),
|
int i;
|
||||||
m_auto_close(true),
|
for (i = 0; i < aa_scale; i++)
|
||||||
m_start_x(0),
|
|
||||||
m_start_y(0),
|
|
||||||
m_status(status_initial)
|
|
||||||
{
|
{
|
||||||
int i;
|
m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
|
||||||
for(i = 0; i < aa_scale; i++) m_gamma[i] = i;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
template<class GammaF>
|
unsigned apply_gamma(unsigned cover) const { return m_gamma[cover]; }
|
||||||
rasterizer_scanline_aa(const GammaF& gamma_function) :
|
|
||||||
m_outline(),
|
//--------------------------------------------------------------------
|
||||||
m_clipper(m_outline),
|
void move_to(int x, int y);
|
||||||
m_filling_rule(fill_non_zero),
|
void line_to(int x, int y);
|
||||||
m_auto_close(true),
|
void move_to_d(double x, double y);
|
||||||
m_start_x(0),
|
void line_to_d(double x, double y);
|
||||||
m_start_y(0),
|
void close_polygon();
|
||||||
m_status(status_initial)
|
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)))
|
||||||
{
|
{
|
||||||
gamma(gamma_function);
|
add_vertex(x, y, cmd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void reset();
|
int min_x() const { return m_outline.min_x(); }
|
||||||
void reset_clipping();
|
int min_y() const { return m_outline.min_y(); }
|
||||||
void clip_box(double x1, double y1, double x2, double y2);
|
int max_x() const { return m_outline.max_x(); }
|
||||||
void filling_rule(filling_rule_e filling_rule);
|
int max_y() const { return m_outline.max_y(); }
|
||||||
void auto_close(bool flag) { m_auto_close = flag; }
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
template<class GammaF> void gamma(const GammaF& gamma_function)
|
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)
|
||||||
{
|
{
|
||||||
int i;
|
cover &= aa_mask2;
|
||||||
for(i = 0; i < aa_scale; i++)
|
if (cover > aa_scale)
|
||||||
{
|
{
|
||||||
m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
|
cover = aa_scale2 - cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cover > aa_mask)
|
||||||
|
cover = aa_mask;
|
||||||
|
return m_gamma[cover];
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
unsigned apply_gamma(unsigned cover) const
|
template<class Scanline>
|
||||||
|
bool sweep_scanline(Scanline& sl)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
return m_gamma[cover];
|
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);
|
||||||
|
unsigned cover = 0;
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
while (num_cells)
|
||||||
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);
|
const cell_aa* cur_cell = *cells;
|
||||||
}
|
int x = cur_cell->x;
|
||||||
}
|
int area = cur_cell->area;
|
||||||
|
unsigned alpha;
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
cover += cur_cell->cover;
|
||||||
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(); }
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
// accumulate all cells with the same X
|
||||||
void sort();
|
while (--num_cells)
|
||||||
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;
|
cur_cell = *++cells;
|
||||||
}
|
if (cur_cell->x != x)
|
||||||
}
|
break;
|
||||||
if(cover > aa_mask) cover = aa_mask;
|
area += cur_cell->area;
|
||||||
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);
|
|
||||||
unsigned 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;
|
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;
|
if (area)
|
||||||
++m_scan_y;
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sl.finalize(m_scan_y);
|
if (sl.num_spans())
|
||||||
|
break;
|
||||||
++m_scan_y;
|
++m_scan_y;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
sl.finalize(m_scan_y);
|
||||||
bool hit_test(int tx, int ty);
|
++m_scan_y;
|
||||||
|
|
||||||
|
|
||||||
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
bool hit_test(int tx, int ty);
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
private:
|
||||||
template<class Clip>
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
|
// Disable copying
|
||||||
{
|
rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
|
||||||
if(m_auto_close) close_polygon();
|
const rasterizer_scanline_aa<Clip>& operator=(const rasterizer_scanline_aa<Clip>&);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
479
deps/agg/include/agg_rasterizer_sl_clip.h
vendored
479
deps/agg/include/agg_rasterizer_sl_clip.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -17,226 +17,201 @@
|
||||||
|
|
||||||
#include "agg_clip_liang_barsky.h"
|
#include "agg_clip_liang_barsky.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
||||||
{
|
{
|
||||||
//--------------------------------------------------------poly_max_coord_e
|
typedef int coord_type;
|
||||||
enum poly_max_coord_e
|
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)
|
||||||
{
|
{
|
||||||
poly_max_coord = (1 << 30) - 1 //----poly_max_coord
|
return saturation<poly_max_coord>::iround(a * b / c);
|
||||||
};
|
}
|
||||||
|
static int xi(int v) { return v; }
|
||||||
//------------------------------------------------------------ras_conv_int
|
static int yi(int v) { return v; }
|
||||||
struct ras_conv_int
|
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)
|
||||||
{
|
{
|
||||||
typedef int coord_type;
|
m_clip_box = rect_type(x1, y1, x2, y2);
|
||||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
m_clip_box.normalize();
|
||||||
{
|
m_clipping = true;
|
||||||
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
|
void move_to(coord_type x1, coord_type y1)
|
||||||
{
|
{
|
||||||
typedef int coord_type;
|
m_x1 = x1;
|
||||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
m_y1 = y1;
|
||||||
{
|
if (m_clipping)
|
||||||
return saturation<poly_max_coord>::iround(a * b / c);
|
m_f1 = clipping_flags(x1, y1, m_clip_box);
|
||||||
}
|
}
|
||||||
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
|
private:
|
||||||
struct ras_conv_int_3x
|
//------------------------------------------------------------------------
|
||||||
|
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
|
||||||
{
|
{
|
||||||
typedef int coord_type;
|
f1 &= 10;
|
||||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
f2 &= 10;
|
||||||
|
if ((f1 | f2) == 0)
|
||||||
{
|
{
|
||||||
return iround(a * b / c);
|
// Fully visible
|
||||||
|
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
|
||||||
}
|
}
|
||||||
static int xi(int v) { return v * 3; }
|
else
|
||||||
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;
|
if (f1 == f2)
|
||||||
}
|
|
||||||
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
|
// Invisible by Y
|
||||||
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
coord_type tx1 = x1;
|
||||||
|
coord_type ty1 = y1;
|
||||||
|
coord_type tx2 = x2;
|
||||||
|
coord_type ty2 = y2;
|
||||||
|
|
||||||
|
if (f1 & 8) // y1 < clip.y1
|
||||||
{
|
{
|
||||||
if(f1 == f2)
|
tx1 = x1 + Conv::mul_div(m_clip_box.y1 - y1, x2 - x1, y2 - y1);
|
||||||
{
|
ty1 = m_clip_box.y1;
|
||||||
// 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));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (f1 & 2) // y1 > clip.y2
|
||||||
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);
|
tx1 = x1 + Conv::mul_div(m_clip_box.y2 - y1, x2 - x1, y2 - y1);
|
||||||
|
ty1 = m_clip_box.y2;
|
||||||
|
}
|
||||||
|
|
||||||
if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
|
if (f2 & 8) // y2 < clip.y1
|
||||||
{
|
{
|
||||||
// Invisible by Y
|
tx2 = x1 + Conv::mul_div(m_clip_box.y1 - y1, x2 - x1, y2 - y1);
|
||||||
m_x1 = x2;
|
ty2 = m_clip_box.y1;
|
||||||
m_y1 = y2;
|
}
|
||||||
m_f1 = f2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
coord_type x1 = m_x1;
|
if (f2 & 2) // y2 > clip.y2
|
||||||
coord_type y1 = m_y1;
|
{
|
||||||
unsigned f1 = m_f1;
|
tx2 = x1 + Conv::mul_div(m_clip_box.y2 - y1, x2 - x1, y2 - y1);
|
||||||
coord_type y3, y4;
|
ty2 = m_clip_box.y2;
|
||||||
unsigned f3, f4;
|
}
|
||||||
|
ras.line(Conv::xi(tx1), Conv::yi(ty1), Conv::xi(tx2), Conv::yi(ty2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch(((f1 & 5) << 1) | (f2 & 5))
|
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
|
case 0: // Visible by X
|
||||||
line_clip_y(ras, x1, y1, x2, y2, f1, f2);
|
line_clip_y(ras, x1, y1, x2, y2, f1, f2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // x2 > clip.x2
|
case 1: // x2 > clip.x2
|
||||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
y3 = y1 + Conv::mul_div(m_clip_box.x2 - x1, y2 - y1, x2 - x1);
|
||||||
f3 = clipping_flags_y(y3, m_clip_box);
|
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, 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);
|
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // x1 > clip.x2
|
case 2: // x1 > clip.x2
|
||||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
y3 = y1 + Conv::mul_div(m_clip_box.x2 - x1, y2 - y1, x2 - x1);
|
||||||
f3 = clipping_flags_y(y3, m_clip_box);
|
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, y1, m_clip_box.x2, y3, f1, f3);
|
||||||
line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
|
line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
|
||||||
|
@ -247,15 +222,15 @@ namespace agg
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // x2 < clip.x1
|
case 4: // x2 < clip.x1
|
||||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
y3 = y1 + Conv::mul_div(m_clip_box.x1 - x1, y2 - y1, x2 - x1);
|
||||||
f3 = clipping_flags_y(y3, m_clip_box);
|
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, 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);
|
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: // x1 > clip.x2 && x2 < clip.x1
|
case 6: // x1 > clip.x2 && x2 < clip.x1
|
||||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-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);
|
y4 = y1 + Conv::mul_div(m_clip_box.x1 - x1, y2 - y1, x2 - x1);
|
||||||
f3 = clipping_flags_y(y3, m_clip_box);
|
f3 = clipping_flags_y(y3, m_clip_box);
|
||||||
f4 = clipping_flags_y(y4, 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, y1, m_clip_box.x2, y3, f1, f3);
|
||||||
|
@ -264,15 +239,15 @@ namespace agg
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: // x1 < clip.x1
|
case 8: // x1 < clip.x1
|
||||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
y3 = y1 + Conv::mul_div(m_clip_box.x1 - x1, y2 - y1, x2 - x1);
|
||||||
f3 = clipping_flags_y(y3, m_clip_box);
|
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, y1, m_clip_box.x1, y3, f1, f3);
|
||||||
line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
|
line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9: // x1 < clip.x1 && x2 > clip.x2
|
case 9: // x1 < clip.x1 && x2 > clip.x2
|
||||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
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);
|
y4 = y1 + Conv::mul_div(m_clip_box.x2 - x1, y2 - y1, x2 - x1);
|
||||||
f3 = clipping_flags_y(y3, m_clip_box);
|
f3 = clipping_flags_y(y3, m_clip_box);
|
||||||
f4 = clipping_flags_y(y4, 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, y1, m_clip_box.x1, y3, f1, f3);
|
||||||
|
@ -283,69 +258,69 @@ namespace agg
|
||||||
case 12: // x1 < clip.x1 && x2 < clip.x1
|
case 12: // x1 < clip.x1 && x2 < clip.x1
|
||||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
|
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
m_f1 = f2;
|
|
||||||
}
|
}
|
||||||
else
|
m_f1 = f2;
|
||||||
{
|
|
||||||
ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
|
|
||||||
Conv::xi(x2), Conv::yi(y2));
|
|
||||||
}
|
|
||||||
m_x1 = x2;
|
|
||||||
m_y1 = y2;
|
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
//---------------------------------------------------rasterizer_sl_no_clip
|
||||||
rect_type m_clip_box;
|
class rasterizer_sl_no_clip
|
||||||
coord_type m_x1;
|
{
|
||||||
coord_type m_y1;
|
public:
|
||||||
unsigned m_f1;
|
typedef ras_conv_int conv_type;
|
||||||
bool m_clipping;
|
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*/) {}
|
||||||
//---------------------------------------------------rasterizer_sl_no_clip
|
void move_to(coord_type x1, coord_type y1)
|
||||||
class rasterizer_sl_no_clip
|
|
||||||
{
|
{
|
||||||
public:
|
m_x1 = x1;
|
||||||
typedef ras_conv_int conv_type;
|
m_y1 = y1;
|
||||||
typedef int coord_type;
|
}
|
||||||
|
|
||||||
rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
void reset_clipping() {}
|
private:
|
||||||
void clip_box(coord_type /*x1*/, coord_type /*y1*/, coord_type /*x2*/, coord_type /*y2*/) {}
|
int m_x1, m_y1;
|
||||||
void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
|
};
|
||||||
|
|
||||||
template<class Rasterizer>
|
// -----rasterizer_sl_clip_int
|
||||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
// -----rasterizer_sl_clip_int_sat
|
||||||
{
|
// -----rasterizer_sl_clip_int_3x
|
||||||
ras.line(m_x1, m_y1, x2, y2);
|
// -----rasterizer_sl_clip_dbl
|
||||||
m_x1 = x2;
|
// -----rasterizer_sl_clip_dbl_3x
|
||||||
m_y1 = y2;
|
//------------------------------------------------------------------------
|
||||||
}
|
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;
|
||||||
|
|
||||||
private:
|
} // namespace agg
|
||||||
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
|
#endif
|
||||||
|
|
1355
deps/agg/include/agg_renderer_base.h
vendored
1355
deps/agg/include/agg_renderer_base.h
vendored
File diff suppressed because it is too large
Load diff
2044
deps/agg/include/agg_renderer_markers.h
vendored
2044
deps/agg/include/agg_renderer_markers.h
vendored
File diff suppressed because it is too large
Load diff
533
deps/agg/include/agg_renderer_mclip.h
vendored
533
deps/agg/include/agg_renderer_mclip.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -24,326 +24,303 @@
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
#include "agg_renderer_base.h"
|
#include "agg_renderer_base.h"
|
||||||
|
|
||||||
namespace agg
|
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;
|
||||||
|
|
||||||
//----------------------------------------------------------renderer_mclip
|
//--------------------------------------------------------------------
|
||||||
template<class PixelFormat> class renderer_mclip
|
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)
|
||||||
{
|
{
|
||||||
public:
|
m_ren.attach(pixf);
|
||||||
typedef PixelFormat pixfmt_type;
|
reset_clipping(true);
|
||||||
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) :
|
const pixfmt_type& ren() const { return m_ren.ren(); }
|
||||||
m_ren(pixf),
|
pixfmt_type& ren() { return m_ren.ren(); }
|
||||||
m_curr_cb(0),
|
|
||||||
m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
|
//--------------------------------------------------------------------
|
||||||
{}
|
unsigned width() const { return m_ren.width(); }
|
||||||
void attach(pixfmt_type& pixf)
|
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())
|
||||||
{
|
{
|
||||||
m_ren.attach(pixf);
|
const rect_i& cb = m_clip[0];
|
||||||
reset_clipping(true);
|
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//--------------------------------------------------------------------
|
|
||||||
const pixfmt_type& ren() const { return m_ren.ren(); }
|
|
||||||
pixfmt_type& ren() { return m_ren.ren(); }
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
unsigned width() const { return m_ren.width(); }
|
bool next_clip_box()
|
||||||
unsigned height() const { return m_ren.height(); }
|
{
|
||||||
|
if (++m_curr_cb < m_clip.size())
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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;
|
const rect_i& cb = m_clip[m_curr_cb];
|
||||||
if(m_clip.size())
|
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))
|
||||||
{
|
{
|
||||||
const rect_i& cb = m_clip[0];
|
m_ren.ren().copy_pixel(x, y, c);
|
||||||
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (next_clip_box());
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
bool next_clip_box()
|
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||||
{
|
{
|
||||||
if(++m_curr_cb < m_clip.size())
|
first_clip_box();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (m_ren.inbox(x, y))
|
||||||
{
|
{
|
||||||
const rect_i& cb = m_clip[m_curr_cb];
|
m_ren.ren().blend_pixel(x, y, c, cover);
|
||||||
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
|
break;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
} while (next_clip_box());
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void reset_clipping(bool visibility)
|
color_type pixel(int x, int y) const
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
m_ren.reset_clipping(visibility);
|
if (m_ren.inbox(x, y))
|
||||||
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);
|
return m_ren.ren().pixel(x, y);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
} while (next_clip_box());
|
||||||
|
return color_type::no_color();
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void clear(const color_type& c)
|
void copy_hline(int x1, int y, int x2, const color_type& c)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
m_ren.clear(c);
|
m_ren.copy_hline(x1, y, x2, c);
|
||||||
}
|
} while (next_clip_box());
|
||||||
|
}
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void copy_pixel(int x, int y, const color_type& c)
|
//--------------------------------------------------------------------
|
||||||
|
void copy_vline(int x, int y1, int y2, const color_type& c)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.copy_vline(x, y1, y2, c);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
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)
|
void blend_hline(int x1, int y, int x2, const color_type& c, cover_type cover)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.blend_hline(x1, y, x2, c, cover);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
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
|
void blend_vline(int x, int y1, int y2, const color_type& c, cover_type cover)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.blend_vline(x, y1, y2, c, cover);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
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)
|
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.copy_bar(x1, y1, x2, y2, c);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
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)
|
void blend_bar(int x1, int y1, int x2, int y2, const color_type& c, cover_type cover)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.blend_bar(x1, y1, x2, y2, c, cover);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
m_ren.copy_vline(x, y1, y2, c);
|
|
||||||
}
|
|
||||||
while(next_clip_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void blend_hline(int x1, int y, int x2,
|
void blend_solid_hspan(int x, int y, int len, const color_type& c, const cover_type* covers)
|
||||||
const color_type& c, cover_type cover)
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.blend_solid_hspan(x, y, len, c, covers);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
m_ren.blend_hline(x1, y, x2, c, cover);
|
|
||||||
}
|
|
||||||
while(next_clip_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void blend_vline(int x, int y1, int y2,
|
void blend_solid_vspan(int x, int y, int len, const color_type& c, const cover_type* covers)
|
||||||
const color_type& c, cover_type cover)
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.blend_solid_vspan(x, y, len, c, covers);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
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)
|
void copy_color_hspan(int x, int y, int len, const color_type* colors)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.copy_color_hspan(x, y, len, colors);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
m_ren.copy_bar(x1, y1, x2, y2, c);
|
|
||||||
}
|
|
||||||
while(next_clip_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void blend_bar(int x1, int y1, int x2, int y2,
|
void blend_color_hspan(int x,
|
||||||
const color_type& c, cover_type cover)
|
int y,
|
||||||
|
int len,
|
||||||
|
const color_type* colors,
|
||||||
|
const cover_type* covers,
|
||||||
|
cover_type cover = cover_full)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
m_ren.blend_bar(x1, y1, x2, y2, c, cover);
|
|
||||||
}
|
|
||||||
while(next_clip_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void blend_solid_hspan(int x, int y, int len,
|
void blend_color_vspan(int x,
|
||||||
const color_type& c, const cover_type* covers)
|
int y,
|
||||||
|
int len,
|
||||||
|
const color_type* colors,
|
||||||
|
const cover_type* covers,
|
||||||
|
cover_type cover = cover_full)
|
||||||
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.blend_color_vspan(x, y, len, colors, covers, cover);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
m_ren.blend_solid_hspan(x, y, len, c, covers);
|
|
||||||
}
|
|
||||||
while(next_clip_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void blend_solid_vspan(int x, int y, int len,
|
void copy_from(const rendering_buffer& from, const rect_i* rc = 0, int x_to = 0, int y_to = 0)
|
||||||
const color_type& c, const cover_type* covers)
|
{
|
||||||
|
first_clip_box();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.copy_from(from, rc, x_to, y_to);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
m_ren.blend_solid_vspan(x, y, len, c, covers);
|
|
||||||
}
|
|
||||||
while(next_clip_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
//--------------------------------------------------------------------
|
template<class SrcPixelFormatRenderer>
|
||||||
void copy_color_hspan(int x, int y, int len, const color_type* colors)
|
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
|
||||||
{
|
{
|
||||||
first_clip_box();
|
m_ren.blend_from(src, rect_src_ptr, dx, dy, cover);
|
||||||
do
|
} while (next_clip_box());
|
||||||
{
|
}
|
||||||
m_ren.copy_color_hspan(x, y, len, colors);
|
|
||||||
}
|
|
||||||
while(next_clip_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void blend_color_hspan(int x, int y, int len,
|
renderer_mclip(const renderer_mclip<PixelFormat>&);
|
||||||
const color_type* colors,
|
const renderer_mclip<PixelFormat>& operator=(const renderer_mclip<PixelFormat>&);
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
base_ren_type m_ren;
|
||||||
void blend_color_vspan(int x, int y, int len,
|
pod_bvector<rect_i, 4> m_clip;
|
||||||
const color_type* colors,
|
unsigned m_curr_cb;
|
||||||
const cover_type* covers,
|
rect_i m_bounds;
|
||||||
cover_type cover = cover_full)
|
};
|
||||||
{
|
|
||||||
first_clip_box();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
m_ren.blend_color_vspan(x, y, len, colors, covers, cover);
|
|
||||||
}
|
|
||||||
while(next_clip_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
} // namespace agg
|
||||||
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
|
#endif
|
||||||
|
|
3340
deps/agg/include/agg_renderer_outline_aa.h
vendored
3340
deps/agg/include/agg_renderer_outline_aa.h
vendored
File diff suppressed because it is too large
Load diff
1732
deps/agg/include/agg_renderer_outline_image.h
vendored
1732
deps/agg/include/agg_renderer_outline_image.h
vendored
File diff suppressed because it is too large
Load diff
342
deps/agg/include/agg_renderer_primitives.h
vendored
342
deps/agg/include/agg_renderer_primitives.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -25,200 +25,190 @@
|
||||||
#include "agg_dda_line.h"
|
#include "agg_dda_line.h"
|
||||||
#include "agg_ellipse_bresenham.h"
|
#include "agg_ellipse_bresenham.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//-----------------------------------------------------renderer_primitives
|
||||||
|
template<class BaseRenderer>
|
||||||
|
class renderer_primitives
|
||||||
{
|
{
|
||||||
//-----------------------------------------------------renderer_primitives
|
public:
|
||||||
template<class BaseRenderer> class renderer_primitives
|
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)
|
||||||
{
|
{
|
||||||
public:
|
m_ren->blend_hline(x1, y1, x2 - 1, m_line_color, cover_full);
|
||||||
typedef BaseRenderer base_ren_type;
|
m_ren->blend_vline(x2, y1, y2 - 1, m_line_color, cover_full);
|
||||||
typedef typename base_ren_type::color_type color_type;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
explicit renderer_primitives(base_ren_type& ren) :
|
void solid_rectangle(int x1, int y1, int x2, int y2) { m_ren->blend_bar(x1, y1, x2, y2, m_fill_color, cover_full); }
|
||||||
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)
|
void outlined_rectangle(int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
return iround(c * line_bresenham_interpolator::subpixel_scale);
|
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)
|
||||||
void fill_color(const color_type& c) { m_fill_color = c; }
|
++len;
|
||||||
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; }
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
if (li.is_ver())
|
||||||
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
|
do
|
||||||
{
|
{
|
||||||
dx += ei.dx();
|
m_ren->blend_pixel(li.x2(), li.y1(), m_line_color, cover_full);
|
||||||
dy += ei.dy();
|
li.vstep();
|
||||||
m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
|
} while (--len);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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
|
do
|
||||||
{
|
{
|
||||||
dx += ei.dx();
|
m_ren->blend_pixel(li.x1(), li.y2(), m_line_color, cover_full);
|
||||||
dy += ei.dy();
|
li.hstep();
|
||||||
|
} while (--len);
|
||||||
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)
|
void move_to(int x, int y)
|
||||||
{
|
{
|
||||||
ellipse_bresenham_interpolator ei(rx, ry);
|
m_curr_x = x;
|
||||||
int dx = 0;
|
m_curr_y = y;
|
||||||
int dy = -ry;
|
}
|
||||||
|
|
||||||
do
|
//--------------------------------------------------------------------
|
||||||
{
|
void line_to(int x, int y, bool last = false)
|
||||||
dx += ei.dx();
|
{
|
||||||
dy += ei.dy();
|
line(m_curr_x, m_curr_y, x, y, last);
|
||||||
|
m_curr_x = x;
|
||||||
|
m_curr_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
const base_ren_type& ren() const { return *m_ren; }
|
||||||
m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
|
base_ren_type& ren() { return *m_ren; }
|
||||||
m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
|
|
||||||
|
|
||||||
if(ei.dy() && dx)
|
//--------------------------------------------------------------------
|
||||||
{
|
const rendering_buffer& rbuf() const { return m_ren->rbuf(); }
|
||||||
m_ren->blend_hline(x-dx+1, y+dy, x+dx-1, m_fill_color, cover_full);
|
rendering_buffer& rbuf() { return m_ren->rbuf(); }
|
||||||
m_ren->blend_hline(x-dx+1, y-dy, x+dx-1, m_fill_color, cover_full);
|
|
||||||
}
|
|
||||||
++ei;
|
|
||||||
}
|
|
||||||
while(dy < 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void line(int x1, int y1, int x2, int y2, bool last=false)
|
base_ren_type* m_ren;
|
||||||
{
|
color_type m_fill_color;
|
||||||
line_bresenham_interpolator li(x1, y1, x2, y2);
|
color_type m_line_color;
|
||||||
|
int m_curr_x;
|
||||||
|
int m_curr_y;
|
||||||
|
};
|
||||||
|
|
||||||
unsigned len = li.len();
|
} // namespace agg
|
||||||
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
|
#endif
|
||||||
|
|
382
deps/agg/include/agg_renderer_raster_text.h
vendored
382
deps/agg/include/agg_renderer_raster_text.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,247 +18,215 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph)
|
||||||
template<class BaseRenderer, class GlyphGenerator>
|
: m_ren(&ren)
|
||||||
class renderer_raster_htext_solid
|
, 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)
|
||||||
{
|
{
|
||||||
public:
|
glyph_rect r;
|
||||||
typedef BaseRenderer ren_type;
|
while (*str)
|
||||||
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;
|
m_glyph->prepare(&r, x, y, *str, flip);
|
||||||
while(*str)
|
if (r.x2 >= r.x1)
|
||||||
{
|
{
|
||||||
m_glyph->prepare(&r, x, y, *str, flip);
|
int i;
|
||||||
if(r.x2 >= r.x1)
|
if (flip)
|
||||||
{
|
{
|
||||||
int i;
|
for (i = r.y1; i <= r.y2; 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));
|
||||||
{
|
|
||||||
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;
|
else
|
||||||
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;
|
for (i = r.y1; i <= r.y2; 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(i - r.y1));
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
x += r.dx;
|
||||||
|
y += r.dy;
|
||||||
|
++str;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ren_type* m_ren;
|
ren_type* m_ren;
|
||||||
glyph_gen_type* m_glyph;
|
glyph_gen_type* m_glyph;
|
||||||
color_type m_color;
|
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>
|
||||||
//===================================================renderer_raster_htext
|
void render_text(double x, double y, const CharT* str, bool flip = false)
|
||||||
template<class ScanlineRenderer, class GlyphGenerator>
|
|
||||||
class renderer_raster_htext
|
|
||||||
{
|
{
|
||||||
public:
|
glyph_rect r;
|
||||||
typedef ScanlineRenderer ren_type;
|
while (*str)
|
||||||
typedef GlyphGenerator glyph_gen_type;
|
|
||||||
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
|
||||||
|
|
||||||
class scanline_single_span
|
|
||||||
{
|
{
|
||||||
public:
|
m_glyph->prepare(&r, x, y, *str, !flip);
|
||||||
typedef agg::cover_type cover_type;
|
if (r.x2 >= r.x1)
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
struct const_span
|
|
||||||
{
|
{
|
||||||
int x;
|
int i;
|
||||||
unsigned len;
|
if (flip)
|
||||||
const cover_type* covers;
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const_span() {}
|
private:
|
||||||
const_span(int x_, unsigned len_, const cover_type* covers_) :
|
ren_type* m_ren;
|
||||||
x(x_), len(len_), covers(covers_)
|
glyph_gen_type* m_glyph;
|
||||||
{}
|
color_type m_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef const const_span* const_iterator;
|
//===================================================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
|
||||||
scanline_single_span(int x, int y, unsigned len,
|
{
|
||||||
const cover_type* covers) :
|
public:
|
||||||
m_y(y),
|
typedef agg::cover_type cover_type;
|
||||||
m_span(x, len, covers)
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
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_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph) :
|
int y() const { return m_y; }
|
||||||
m_ren(&ren),
|
unsigned num_spans() const { return 1; }
|
||||||
m_glyph(&glyph)
|
const_iterator begin() const { return &m_span; }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private:
|
||||||
//--------------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
template<class CharT>
|
int m_y;
|
||||||
void render_text(double x, double y, const CharT* str, bool flip=false)
|
const_span m_span;
|
||||||
{
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
1610
deps/agg/include/agg_renderer_scanline.h
vendored
1610
deps/agg/include/agg_renderer_scanline.h
vendored
File diff suppressed because it is too large
Load diff
481
deps/agg/include/agg_rendering_buffer.h
vendored
481
deps/agg/include/agg_rendering_buffer.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -22,284 +22,261 @@
|
||||||
|
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//===========================================================row_accessor
|
||||||
|
template<class T>
|
||||||
|
class row_accessor
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
typedef const_row_info<T> row_data;
|
||||||
|
|
||||||
//===========================================================row_accessor
|
//-------------------------------------------------------------------
|
||||||
template<class T> class row_accessor
|
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)
|
||||||
{
|
{
|
||||||
public:
|
attach(buf, width, height, stride);
|
||||||
typedef const_row_info<T> row_data;
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
row_accessor() :
|
void attach(T* buf, unsigned width, unsigned height, int stride)
|
||||||
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 - int(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 * m_stride;
|
|
||||||
}
|
|
||||||
AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; }
|
|
||||||
AGG_INLINE const T* row_ptr(int y) const { return m_start + y * 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 rendering 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:
|
m_buf = m_start = buf;
|
||||||
typedef const_row_info<T> row_data;
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
//-------------------------------------------------------------------
|
m_stride = stride;
|
||||||
row_ptr_cache() :
|
if (stride < 0)
|
||||||
m_buf(0),
|
|
||||||
m_rows(),
|
|
||||||
m_width(0),
|
|
||||||
m_height(0),
|
|
||||||
m_stride(0)
|
|
||||||
{
|
{
|
||||||
|
m_start = m_buf - int(height - 1) * stride;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) :
|
AGG_INLINE T* buf() { return m_buf; }
|
||||||
m_buf(0),
|
AGG_INLINE const T* buf() const { return m_buf; }
|
||||||
m_rows(),
|
AGG_INLINE unsigned width() const { return m_width; }
|
||||||
m_width(0),
|
AGG_INLINE unsigned height() const { return m_height; }
|
||||||
m_height(0),
|
AGG_INLINE int stride() const { return m_stride; }
|
||||||
m_stride(0)
|
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 * m_stride; }
|
||||||
|
AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; }
|
||||||
|
AGG_INLINE const T* row_ptr(int y) const { return m_start + y * 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++)
|
||||||
{
|
{
|
||||||
attach(buf, width, height, stride);
|
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void attach(T* buf, unsigned width, unsigned height, int stride)
|
void clear(T value)
|
||||||
|
{
|
||||||
|
unsigned y;
|
||||||
|
unsigned w = width();
|
||||||
|
unsigned stride = stride_abs();
|
||||||
|
for (y = 0; y < height(); y++)
|
||||||
{
|
{
|
||||||
m_buf = buf;
|
T* p = row_ptr(0, y, w);
|
||||||
m_width = width;
|
unsigned x;
|
||||||
m_height = height;
|
for (x = 0; x < stride; x++)
|
||||||
m_stride = stride;
|
|
||||||
if(height > m_rows.size())
|
|
||||||
{
|
{
|
||||||
m_rows.resize(height);
|
*p++ = value;
|
||||||
}
|
|
||||||
else if(height == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* row_ptr = m_buf;
|
|
||||||
|
|
||||||
if(stride < 0)
|
|
||||||
{
|
|
||||||
row_ptr = m_buf - int(height - 1) * stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
T** rows = &m_rows[0];
|
|
||||||
|
|
||||||
while(height > 0)
|
|
||||||
{
|
|
||||||
*rows++ = row_ptr;
|
|
||||||
row_ptr += stride;
|
|
||||||
--height;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
AGG_INLINE T* buf() { return m_buf; }
|
//--------------------------------------------------------------------
|
||||||
AGG_INLINE const T* buf() const { return m_buf; }
|
T* m_buf; // Pointer to rendering buffer
|
||||||
AGG_INLINE unsigned width() const { return m_width; }
|
T* m_start; // Pointer to first pixel depending on stride
|
||||||
AGG_INLINE unsigned height() const { return m_height; }
|
unsigned m_width; // Width in pixels
|
||||||
AGG_INLINE int stride() const { return m_stride; }
|
unsigned m_height; // Height in pixels
|
||||||
AGG_INLINE unsigned stride_abs() const
|
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())
|
||||||
{
|
{
|
||||||
return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
|
m_rows.resize(height);
|
||||||
}
|
}
|
||||||
|
else if (height == 0)
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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();
|
return;
|
||||||
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;
|
T* row_ptr = m_buf;
|
||||||
unsigned w = width();
|
|
||||||
for (y = 0; y < h; y++)
|
if (stride < 0)
|
||||||
|
{
|
||||||
|
row_ptr = m_buf - int(height - 1) * stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
T** rows = &m_rows[0];
|
||||||
|
|
||||||
|
while (height > 0)
|
||||||
|
{
|
||||||
|
*rows++ = row_ptr;
|
||||||
|
row_ptr += stride;
|
||||||
|
--height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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++)
|
||||||
{
|
{
|
||||||
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
|
*p++ = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void clear(T value)
|
//--------------------------------------------------------------------
|
||||||
{
|
T* m_buf; // Pointer to rendering buffer
|
||||||
unsigned y;
|
pod_array<T*> m_rows; // Pointers to each row of the buffer
|
||||||
unsigned w = width();
|
unsigned m_width; // Width in pixels
|
||||||
unsigned stride = stride_abs();
|
unsigned m_height; // Height in pixels
|
||||||
for(y = 0; y < height(); y++)
|
int m_stride; // Number of bytes per row. Can be < 0
|
||||||
{
|
};
|
||||||
T* p = row_ptr(0, y, w);
|
|
||||||
unsigned x;
|
|
||||||
for(x = 0; x < stride; x++)
|
|
||||||
{
|
|
||||||
*p++ = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
//========================================================rendering_buffer
|
||||||
//--------------------------------------------------------------------
|
//
|
||||||
T* m_buf; // Pointer to rendering buffer
|
// The definition of the main type for accessing the rows in the frame
|
||||||
pod_array<T*> m_rows; // Pointers to each row of the buffer
|
// buffer. It provides functionality to navigate to the rows in a
|
||||||
unsigned m_width; // Width in pixels
|
// rectangular matrix, from top to bottom or from bottom to top depending
|
||||||
unsigned m_height; // Height in pixels
|
// on stride.
|
||||||
int m_stride; // Number of bytes per row. Can be < 0
|
//
|
||||||
};
|
// 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
|
||||||
//========================================================rendering_buffer
|
// when creating. For example, on typical Intel Pentium hardware
|
||||||
//
|
// row_ptr_cache speeds span_image_filter_rgb_nn up to 10%
|
||||||
// The definition of the main type for accessing the rows in the frame
|
//
|
||||||
// buffer. It provides functionality to navigate to the rows in a
|
// It's used only in short hand typedefs like pixfmt_rgba32 and can be
|
||||||
// rectangular matrix, from top to bottom or from bottom to top depending
|
// redefined in agg_config.h
|
||||||
// on stride.
|
// In real applications you can use both, depending on your needs
|
||||||
//
|
//------------------------------------------------------------------------
|
||||||
// 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
|
#ifdef AGG_RENDERING_BUFFER
|
||||||
typedef AGG_RENDERING_BUFFER rendering_buffer;
|
typedef AGG_RENDERING_BUFFER rendering_buffer;
|
||||||
#else
|
#else
|
||||||
typedef row_ptr_cache<int8u> rendering_buffer;
|
typedef row_ptr_cache<int8u> rendering_buffer;
|
||||||
//typedef row_accessor<int8u> rendering_buffer;
|
// typedef row_accessor<int8u> rendering_buffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
} // namespace agg
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
180
deps/agg/include/agg_rendering_buffer_dynarow.h
vendored
180
deps/agg/include/agg_rendering_buffer_dynarow.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -22,116 +22,114 @@
|
||||||
|
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
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
|
//-------------------------------------------------------------------
|
||||||
// Rendering buffer class with dynamic allocation of the rows.
|
~rendering_buffer_dynarow() { init(0, 0, 0); }
|
||||||
// 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
|
rendering_buffer_dynarow()
|
||||||
// for rendering a few lines and then to blend it with another buffer.
|
: m_rows()
|
||||||
//
|
, m_width(0)
|
||||||
class rendering_buffer_dynarow
|
, 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)
|
||||||
{
|
{
|
||||||
public:
|
memset(&m_rows[0], 0, sizeof(row_data) * height);
|
||||||
typedef row_info<int8u> row_data;
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
// Allocate and clear the buffer
|
||||||
~rendering_buffer_dynarow()
|
//--------------------------------------------------------------------
|
||||||
|
void init(unsigned width, unsigned height, unsigned byte_width)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < m_height; ++i)
|
||||||
{
|
{
|
||||||
init(0,0,0);
|
pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
|
||||||
}
|
}
|
||||||
|
if (width && height)
|
||||||
//-------------------------------------------------------------------
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
|
m_byte_width = byte_width;
|
||||||
|
m_rows.resize(height);
|
||||||
memset(&m_rows[0], 0, sizeof(row_data) * height);
|
memset(&m_rows[0], 0, sizeof(row_data) * height);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate and clear the buffer
|
//--------------------------------------------------------------------
|
||||||
//--------------------------------------------------------------------
|
unsigned width() const { return m_width; }
|
||||||
void init(unsigned width, unsigned height, unsigned byte_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)
|
||||||
{
|
{
|
||||||
unsigned i;
|
if (x < r->x1)
|
||||||
for(i = 0; i < m_height; ++i)
|
|
||||||
{
|
{
|
||||||
pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
|
r->x1 = x;
|
||||||
}
|
}
|
||||||
if(width && height)
|
if (x2 > r->x2)
|
||||||
{
|
{
|
||||||
m_width = width;
|
r->x2 = x2;
|
||||||
m_height = height;
|
|
||||||
m_byte_width = byte_width;
|
|
||||||
m_rows.resize(height);
|
|
||||||
memset(&m_rows[0], 0, sizeof(row_data) * height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//--------------------------------------------------------------------
|
|
||||||
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];
|
int8u* p = pod_allocator<int8u>::allocate(m_byte_width);
|
||||||
int x2 = x + len - 1;
|
r->ptr = p;
|
||||||
if(r->ptr)
|
r->x1 = x;
|
||||||
{
|
r->x2 = x2;
|
||||||
if(x < r->x1) { r->x1 = x; }
|
memset(p, 0, m_byte_width);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
return (int8u*)r->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
const int8u* row_ptr(int y) const { return m_rows[y].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); }
|
int8u* row_ptr(int y) { return row_ptr(0, y, m_width); }
|
||||||
row_data row (int y) const { return m_rows[y]; }
|
row_data row(int y) const { return m_rows[y]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Prohibit copying
|
// Prohibit copying
|
||||||
rendering_buffer_dynarow(const rendering_buffer_dynarow&);
|
rendering_buffer_dynarow(const rendering_buffer_dynarow&);
|
||||||
const rendering_buffer_dynarow& operator = (const rendering_buffer_dynarow&);
|
const rendering_buffer_dynarow& operator=(const rendering_buffer_dynarow&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
pod_array<row_data> m_rows; // Pointers to each row of the buffer
|
pod_array<row_data> m_rows; // Pointers to each row of the buffer
|
||||||
unsigned m_width; // Width in pixels
|
unsigned m_width; // Width in pixels
|
||||||
unsigned m_height; // Height in pixels
|
unsigned m_height; // Height in pixels
|
||||||
unsigned m_byte_width; // Width in bytes
|
unsigned m_byte_width; // Width in bytes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
79
deps/agg/include/agg_rounded_rect.h
vendored
79
deps/agg/include/agg_rounded_rect.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -23,50 +23,47 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_arc.h"
|
#include "agg_arc.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//------------------------------------------------------------rounded_rect
|
||||||
|
//
|
||||||
|
// See Implemantation agg_rounded_rect.cpp
|
||||||
|
//
|
||||||
|
class rounded_rect
|
||||||
{
|
{
|
||||||
//------------------------------------------------------------rounded_rect
|
public:
|
||||||
//
|
rounded_rect() {}
|
||||||
// See Implemantation agg_rounded_rect.cpp
|
rounded_rect(double x1, double y1, double x2, double y2, double r);
|
||||||
//
|
|
||||||
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 rect(double x1, double y1, double x2, double y2);
|
||||||
void radius(double r);
|
void radius(double r);
|
||||||
void radius(double rx, double ry);
|
void radius(double rx, double ry);
|
||||||
void radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top);
|
void radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top);
|
||||||
void radius(double rx1, double ry1, double rx2, double ry2,
|
void radius(double rx1, double ry1, double rx2, double ry2, double rx3, double ry3, double rx4, double ry4);
|
||||||
double rx3, double ry3, double rx4, double ry4);
|
void normalize_radius();
|
||||||
void normalize_radius();
|
|
||||||
|
|
||||||
void approximation_scale(double s) { m_arc.approximation_scale(s); }
|
void approximation_scale(double s) { m_arc.approximation_scale(s); }
|
||||||
double approximation_scale() const { return m_arc.approximation_scale(); }
|
double approximation_scale() const { return m_arc.approximation_scale(); }
|
||||||
|
|
||||||
void rewind(unsigned);
|
void rewind(unsigned);
|
||||||
unsigned vertex(double* x, double* y);
|
unsigned vertex(double* x, double* y);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double m_x1;
|
double m_x1;
|
||||||
double m_y1;
|
double m_y1;
|
||||||
double m_x2;
|
double m_x2;
|
||||||
double m_y2;
|
double m_y2;
|
||||||
double m_rx1;
|
double m_rx1;
|
||||||
double m_ry1;
|
double m_ry1;
|
||||||
double m_rx2;
|
double m_rx2;
|
||||||
double m_ry2;
|
double m_ry2;
|
||||||
double m_rx3;
|
double m_rx3;
|
||||||
double m_ry3;
|
double m_ry3;
|
||||||
double m_rx4;
|
double m_rx4;
|
||||||
double m_ry4;
|
double m_ry4;
|
||||||
unsigned m_status;
|
unsigned m_status;
|
||||||
arc m_arc;
|
arc m_arc;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
388
deps/agg/include/agg_scanline_bin.h
vendored
388
deps/agg/include/agg_scanline_bin.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -17,12 +17,12 @@
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Adaptation for 32-bit screen coordinates (scanline32_bin) has been sponsored by
|
// 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., visit http://lib-sys.com
|
||||||
//
|
//
|
||||||
// Liberty Technology Systems, Inc. is the provider of
|
// Liberty Technology Systems, Inc. is the provider of
|
||||||
// PostScript and PDF technology for software developers.
|
// PostScript and PDF technology for software developers.
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef AGG_SCANLINE_BIN_INCLUDED
|
#ifndef AGG_SCANLINE_BIN_INCLUDED
|
||||||
|
@ -30,235 +30,215 @@
|
||||||
|
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
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;
|
||||||
|
|
||||||
//=============================================================scanline_bin
|
struct span
|
||||||
//
|
|
||||||
// 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:
|
int16 x;
|
||||||
typedef int32 coord_type;
|
int16 len;
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
//===========================================================scanline32_bin
|
|
||||||
class scanline32_bin
|
|
||||||
{
|
{
|
||||||
public:
|
unsigned max_len = max_x - min_x + 3;
|
||||||
typedef int32 coord_type;
|
if (max_len > m_spans.size())
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
struct span
|
|
||||||
{
|
{
|
||||||
span() {}
|
m_spans.resize(max_len);
|
||||||
span(coord_type x_, coord_type len_) : x(x_), len(len_) {}
|
|
||||||
|
|
||||||
coord_type x;
|
|
||||||
coord_type len;
|
|
||||||
};
|
|
||||||
typedef pod_bvector<span, 4> span_array_type;
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
class const_iterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const_iterator(const span_array_type& spans) :
|
|
||||||
m_spans(spans),
|
|
||||||
m_span_idx(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
|
||||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
|
||||||
|
|
||||||
void operator ++ () { ++m_span_idx; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const span_array_type& m_spans;
|
|
||||||
unsigned m_span_idx;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
scanline32_bin() : m_max_len(0), m_last_x(0x7FFFFFF0) {}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void reset(int, int)
|
|
||||||
{
|
|
||||||
m_last_x = 0x7FFFFFF0;
|
|
||||||
m_spans.remove_all();
|
|
||||||
}
|
}
|
||||||
|
m_last_x = 0x7FFFFFF0;
|
||||||
|
m_cur_span = &m_spans[0];
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void add_cell(int x, unsigned)
|
void add_cell(int x, unsigned)
|
||||||
|
{
|
||||||
|
if (x == m_last_x + 1)
|
||||||
{
|
{
|
||||||
if(x == m_last_x+1)
|
m_cur_span->len++;
|
||||||
{
|
|
||||||
m_spans.last().len++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_spans.add(span(coord_type(x), 1));
|
|
||||||
}
|
|
||||||
m_last_x = x;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void add_span(int x, unsigned len, unsigned)
|
|
||||||
{
|
{
|
||||||
if(x == m_last_x+1)
|
++m_cur_span;
|
||||||
{
|
m_cur_span->x = (int16)x;
|
||||||
m_spans.last().len += coord_type(len);
|
m_cur_span->len = 1;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_spans.add(span(coord_type(x), coord_type(len)));
|
|
||||||
}
|
|
||||||
m_last_x = x + len - 1;
|
|
||||||
}
|
}
|
||||||
|
m_last_x = x;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void add_cells(int x, unsigned len, const void*)
|
void add_span(int x, unsigned len, unsigned)
|
||||||
|
{
|
||||||
|
if (x == m_last_x + 1)
|
||||||
{
|
{
|
||||||
add_span(x, len, 0);
|
m_cur_span->len = (int16)(m_cur_span->len + len);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void finalize(int y)
|
|
||||||
{
|
|
||||||
m_y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
void reset_spans()
|
|
||||||
{
|
{
|
||||||
m_last_x = 0x7FFFFFF0;
|
++m_cur_span;
|
||||||
m_spans.remove_all();
|
m_cur_span->x = (int16)x;
|
||||||
|
m_cur_span->len = (int16)len;
|
||||||
}
|
}
|
||||||
|
m_last_x = x + len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
int y() const { return m_y; }
|
void add_cells(int x, unsigned len, const void*) { add_span(x, len, 0); }
|
||||||
unsigned num_spans() const { return m_spans.size(); }
|
|
||||||
const_iterator begin() const { return const_iterator(m_spans); }
|
|
||||||
|
|
||||||
private:
|
//--------------------------------------------------------------------
|
||||||
scanline32_bin(const scanline32_bin&);
|
void finalize(int y) { m_y = y; }
|
||||||
const scanline32_bin operator = (const scanline32_bin&);
|
|
||||||
|
|
||||||
unsigned m_max_len;
|
//--------------------------------------------------------------------
|
||||||
int m_last_x;
|
void reset_spans()
|
||||||
int m_y;
|
{
|
||||||
span_array_type m_spans;
|
m_last_x = 0x7FFFFFF0;
|
||||||
|
m_cur_span = &m_spans[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
int y() const { return m_y; }
|
||||||
|
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||||
|
const_iterator begin() const { return &m_spans[1]; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
scanline_bin(const scanline_bin&);
|
||||||
|
const scanline_bin operator=(const scanline_bin&);
|
||||||
|
|
||||||
|
int m_last_x;
|
||||||
|
int m_y;
|
||||||
|
pod_array<span> m_spans;
|
||||||
|
span* m_cur_span;
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================================scanline32_bin
|
||||||
|
class scanline32_bin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef int32 coord_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
struct span
|
||||||
|
{
|
||||||
|
span() {}
|
||||||
|
span(coord_type x_, coord_type len_)
|
||||||
|
: x(x_)
|
||||||
|
, len(len_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
coord_type x;
|
||||||
|
coord_type len;
|
||||||
|
};
|
||||||
|
typedef pod_bvector<span, 4> span_array_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
class const_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const_iterator(const span_array_type& spans)
|
||||||
|
: m_spans(spans)
|
||||||
|
, m_span_idx(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||||
|
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||||
|
|
||||||
|
void operator++() { ++m_span_idx; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const span_array_type& m_spans;
|
||||||
|
unsigned m_span_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
scanline32_bin()
|
||||||
|
: m_max_len(0)
|
||||||
|
, m_last_x(0x7FFFFFF0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void reset(int, int)
|
||||||
|
{
|
||||||
|
m_last_x = 0x7FFFFFF0;
|
||||||
|
m_spans.remove_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void add_cell(int x, unsigned)
|
||||||
|
{
|
||||||
|
if (x == m_last_x + 1)
|
||||||
|
{
|
||||||
|
m_spans.last().len++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_spans.add(span(coord_type(x), 1));
|
||||||
|
}
|
||||||
|
m_last_x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void add_span(int x, unsigned len, unsigned)
|
||||||
|
{
|
||||||
|
if (x == m_last_x + 1)
|
||||||
|
{
|
||||||
|
m_spans.last().len += coord_type(len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_spans.add(span(coord_type(x), coord_type(len)));
|
||||||
|
}
|
||||||
|
m_last_x = x + len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
//--------------------------------------------------------------------
|
||||||
|
void add_cells(int x, unsigned len, const void*) { add_span(x, len, 0); }
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void finalize(int y) { m_y = y; }
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void reset_spans()
|
||||||
|
{
|
||||||
|
m_last_x = 0x7FFFFFF0;
|
||||||
|
m_spans.remove_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
int y() const { return m_y; }
|
||||||
|
unsigned num_spans() const { return m_spans.size(); }
|
||||||
|
const_iterator begin() const { return const_iterator(m_spans); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
scanline32_bin(const scanline32_bin&);
|
||||||
|
const scanline32_bin operator=(const scanline32_bin&);
|
||||||
|
|
||||||
|
unsigned m_max_len;
|
||||||
|
int m_last_x;
|
||||||
|
int m_y;
|
||||||
|
span_array_type m_spans;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2481
deps/agg/include/agg_scanline_boolean_algebra.h
vendored
2481
deps/agg/include/agg_scanline_boolean_algebra.h
vendored
File diff suppressed because it is too large
Load diff
500
deps/agg/include/agg_scanline_p.h
vendored
500
deps/agg/include/agg_scanline_p.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -17,313 +17,291 @@
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
|
// 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., visit http://lib-sys.com
|
||||||
//
|
//
|
||||||
// Liberty Technology Systems, Inc. is the provider of
|
// Liberty Technology Systems, Inc. is the provider of
|
||||||
// PostScript and PDF technology for software developers.
|
// PostScript and PDF technology for software developers.
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
#ifndef AGG_SCANLINE_P_INCLUDED
|
#ifndef AGG_SCANLINE_P_INCLUDED
|
||||||
#define AGG_SCANLINE_P_INCLUDED
|
#define AGG_SCANLINE_P_INCLUDED
|
||||||
|
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
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;
|
||||||
|
|
||||||
//=============================================================scanline_p8
|
//--------------------------------------------------------------------
|
||||||
//
|
struct span
|
||||||
// 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:
|
coord_type x;
|
||||||
typedef scanline_p8 self_type;
|
coord_type len; // If negative, it's a solid span, covers is valid
|
||||||
typedef int8u cover_type;
|
const cover_type* covers;
|
||||||
typedef int16 coord_type;
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
typedef span* iterator;
|
||||||
struct span
|
typedef const span* const_iterator;
|
||||||
{
|
|
||||||
coord_type x;
|
scanline_p8()
|
||||||
coord_type len; // If negative, it's a solid span, covers is valid
|
: m_last_x(0x7FFFFFF0)
|
||||||
const cover_type* covers;
|
, m_covers()
|
||||||
};
|
, m_cover_ptr(0)
|
||||||
|
, m_spans()
|
||||||
typedef span* iterator;
|
, m_cur_span(0)
|
||||||
typedef const span* const_iterator;
|
{}
|
||||||
|
|
||||||
scanline_p8() :
|
//--------------------------------------------------------------------
|
||||||
m_last_x(0x7FFFFFF0),
|
void reset(int min_x, int max_x)
|
||||||
m_covers(),
|
{
|
||||||
m_cover_ptr(0),
|
unsigned max_len = max_x - min_x + 3;
|
||||||
m_spans(),
|
if (max_len > m_spans.size())
|
||||||
m_cur_span(0)
|
|
||||||
{
|
{
|
||||||
|
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 reset(int min_x, int max_x)
|
void add_cell(int x, unsigned cover)
|
||||||
|
{
|
||||||
|
*m_cover_ptr = (cover_type)cover;
|
||||||
|
if (x == m_last_x + 1 && m_cur_span->len > 0)
|
||||||
{
|
{
|
||||||
unsigned max_len = max_x - min_x + 3;
|
m_cur_span->len++;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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_cell(int x, unsigned cover)
|
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_cover_ptr = (cover_type)cover;
|
||||||
if(x == m_last_x+1 && m_cur_span->len > 0)
|
m_cur_span++;
|
||||||
{
|
m_cur_span->covers = m_cover_ptr++;
|
||||||
m_cur_span->len++;
|
m_cur_span->x = (int16)x;
|
||||||
}
|
m_cur_span->len = (int16)(-int(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++;
|
|
||||||
}
|
}
|
||||||
|
m_last_x = x + len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
void finalize(int y) { m_y = y; }
|
||||||
{
|
|
||||||
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)
|
void reset_spans()
|
||||||
{
|
{
|
||||||
if(x == m_last_x+1 &&
|
m_last_x = 0x7FFFFFF0;
|
||||||
m_cur_span->len < 0 &&
|
m_cover_ptr = &m_covers[0];
|
||||||
cover == *m_cur_span->covers)
|
m_cur_span = &m_spans[0];
|
||||||
{
|
m_cur_span->len = 0;
|
||||||
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)
|
int y() const { return m_y; }
|
||||||
{
|
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||||
m_y = y;
|
const_iterator begin() const { return &m_spans[1]; }
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void reset_spans()
|
scanline_p8(const self_type&);
|
||||||
{
|
const self_type& operator=(const self_type&);
|
||||||
m_last_x = 0x7FFFFFF0;
|
|
||||||
m_cover_ptr = &m_covers[0];
|
|
||||||
m_cur_span = &m_spans[0];
|
|
||||||
m_cur_span->len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
int m_last_x;
|
||||||
int y() const { return m_y; }
|
int m_y;
|
||||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
pod_array<cover_type> m_covers;
|
||||||
const_iterator begin() const { return &m_spans[1]; }
|
cover_type* m_cover_ptr;
|
||||||
|
pod_array<span> m_spans;
|
||||||
|
span* m_cur_span;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
//==========================================================scanline32_p8
|
||||||
scanline_p8(const self_type&);
|
class scanline32_p8
|
||||||
const self_type& operator = (const self_type&);
|
{
|
||||||
|
public:
|
||||||
|
typedef scanline32_p8 self_type;
|
||||||
|
typedef int8u cover_type;
|
||||||
|
typedef int32 coord_type;
|
||||||
|
|
||||||
int m_last_x;
|
struct span
|
||||||
int m_y;
|
{
|
||||||
pod_array<cover_type> m_covers;
|
span() {}
|
||||||
cover_type* m_cover_ptr;
|
span(coord_type x_, coord_type len_, const cover_type* covers_)
|
||||||
pod_array<span> m_spans;
|
: x(x_)
|
||||||
span* m_cur_span;
|
, 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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================scanline32_p8
|
|
||||||
class scanline32_p8
|
|
||||||
{
|
{
|
||||||
public:
|
unsigned max_len = max_x - min_x + 3;
|
||||||
typedef scanline32_p8 self_type;
|
if (max_len > m_covers.size())
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
m_covers.resize(max_len);
|
||||||
}
|
}
|
||||||
|
m_last_x = 0x7FFFFFF0;
|
||||||
|
m_cover_ptr = &m_covers[0];
|
||||||
|
m_spans.remove_all();
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void reset(int min_x, int max_x)
|
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)
|
||||||
{
|
{
|
||||||
unsigned max_len = max_x - min_x + 3;
|
m_spans.last().len++;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_spans.add(span(coord_type(x), 1, m_cover_ptr));
|
||||||
|
}
|
||||||
|
m_last_x = x;
|
||||||
|
m_cover_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void add_cell(int x, unsigned cover)
|
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_cover_ptr = cover_type(cover);
|
||||||
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
|
m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
|
||||||
{
|
|
||||||
m_spans.last().len++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_spans.add(span(coord_type(x), 1, m_cover_ptr));
|
|
||||||
}
|
|
||||||
m_last_x = x;
|
|
||||||
m_cover_ptr++;
|
|
||||||
}
|
}
|
||||||
|
m_last_x = x + len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
void finalize(int y) { m_y = y; }
|
||||||
{
|
|
||||||
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)
|
void reset_spans()
|
||||||
{
|
{
|
||||||
if(x == m_last_x+1 &&
|
m_last_x = 0x7FFFFFF0;
|
||||||
m_spans.size() &&
|
m_cover_ptr = &m_covers[0];
|
||||||
m_spans.last().len < 0 &&
|
m_spans.remove_all();
|
||||||
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)
|
int y() const { return m_y; }
|
||||||
{
|
unsigned num_spans() const { return m_spans.size(); }
|
||||||
m_y = y;
|
const_iterator begin() const { return const_iterator(m_spans); }
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void reset_spans()
|
scanline32_p8(const self_type&);
|
||||||
{
|
const self_type& operator=(const self_type&);
|
||||||
m_last_x = 0x7FFFFFF0;
|
|
||||||
m_cover_ptr = &m_covers[0];
|
|
||||||
m_spans.remove_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
unsigned m_max_len;
|
||||||
int y() const { return m_y; }
|
int m_last_x;
|
||||||
unsigned num_spans() const { return m_spans.size(); }
|
int m_y;
|
||||||
const_iterator begin() const { return const_iterator(m_spans); }
|
pod_array<cover_type> m_covers;
|
||||||
|
cover_type* m_cover_ptr;
|
||||||
private:
|
span_array_type m_spans;
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
1352
deps/agg/include/agg_scanline_storage_aa.h
vendored
1352
deps/agg/include/agg_scanline_storage_aa.h
vendored
File diff suppressed because it is too large
Load diff
987
deps/agg/include/agg_scanline_storage_bin.h
vendored
987
deps/agg/include/agg_scanline_storage_bin.h
vendored
File diff suppressed because it is too large
Load diff
879
deps/agg/include/agg_scanline_u.h
vendored
879
deps/agg/include/agg_scanline_u.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -13,12 +13,12 @@
|
||||||
// http://www.antigrain.com
|
// http://www.antigrain.com
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by
|
// 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., visit http://lib-sys.com
|
||||||
//
|
//
|
||||||
// Liberty Technology Systems, Inc. is the provider of
|
// Liberty Technology Systems, Inc. is the provider of
|
||||||
// PostScript and PDF technology for software developers.
|
// PostScript and PDF technology for software developers.
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef AGG_SCANLINE_U_INCLUDED
|
#ifndef AGG_SCANLINE_U_INCLUDED
|
||||||
|
@ -26,475 +26,456 @@
|
||||||
|
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
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 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
|
||||||
{
|
{
|
||||||
//=============================================================scanline_u8
|
public:
|
||||||
//
|
typedef scanline_u8 self_type;
|
||||||
// Unpacked scanline container class
|
typedef int8u cover_type;
|
||||||
//
|
typedef int16 coord_type;
|
||||||
// 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.
|
struct span
|
||||||
// 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 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:
|
coord_type x;
|
||||||
typedef scanline_u8 self_type;
|
coord_type len;
|
||||||
typedef int8u cover_type;
|
cover_type* covers;
|
||||||
typedef int16 coord_type;
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
typedef span* iterator;
|
||||||
struct span
|
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())
|
||||||
{
|
{
|
||||||
coord_type x;
|
m_spans.resize(max_len);
|
||||||
coord_type len;
|
m_covers.resize(max_len);
|
||||||
cover_type* covers;
|
}
|
||||||
};
|
m_last_x = 0x7FFFFFF0;
|
||||||
|
m_min_x = min_x;
|
||||||
|
m_cur_span = &m_spans[0];
|
||||||
|
}
|
||||||
|
|
||||||
typedef span* iterator;
|
//--------------------------------------------------------------------
|
||||||
typedef const span* const_iterator;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
scanline_u8() :
|
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||||
m_min_x(0),
|
{
|
||||||
m_last_x(0x7FFFFFF0),
|
x -= m_min_x;
|
||||||
m_cur_span(0)
|
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(const 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:
|
||||||
|
const 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;
|
||||||
void reset(int min_x, int max_x)
|
coord_type len;
|
||||||
{
|
cover_type* covers;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef pod_bvector<span, 4> span_array_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
class const_iterator
|
||||||
//==========================================================scanline_u8_am
|
|
||||||
//
|
|
||||||
// The scanline container with alpha-masking
|
|
||||||
//
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
template<class AlphaMask>
|
|
||||||
class scanline_u8_am : public scanline_u8
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef scanline_u8 base_type;
|
const_iterator(const span_array_type& spans)
|
||||||
typedef AlphaMask alpha_mask_type;
|
: m_spans(spans)
|
||||||
typedef base_type::cover_type cover_type;
|
, m_span_idx(0)
|
||||||
typedef base_type::coord_type coord_type;
|
|
||||||
|
|
||||||
scanline_u8_am() : base_type(), m_alpha_mask(0) {}
|
|
||||||
scanline_u8_am(const 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:
|
|
||||||
const 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()
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||||
void reset(int min_x, int max_x)
|
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||||
{
|
|
||||||
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 operator++() { ++m_span_idx; }
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
const span_array_type& m_spans;
|
||||||
{
|
unsigned m_span_idx;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
class iterator
|
||||||
|
|
||||||
//========================================================scanline32_u8_am
|
|
||||||
//
|
|
||||||
// The scanline container with alpha-masking
|
|
||||||
//
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class AlphaMask>
|
|
||||||
class scanline32_u8_am : public scanline32_u8
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef scanline32_u8 base_type;
|
iterator(span_array_type& spans)
|
||||||
typedef AlphaMask alpha_mask_type;
|
: m_spans(spans)
|
||||||
typedef base_type::cover_type cover_type;
|
, m_span_idx(0)
|
||||||
typedef base_type::coord_type coord_type;
|
{}
|
||||||
|
|
||||||
|
span& operator*() { return m_spans[m_span_idx]; }
|
||||||
|
span* operator->() { return &m_spans[m_span_idx]; }
|
||||||
|
|
||||||
scanline32_u8_am() : base_type(), m_alpha_mask(0) {}
|
void operator++() { ++m_span_idx; }
|
||||||
scanline32_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
private:
|
||||||
void finalize(int span_y)
|
span_array_type& m_spans;
|
||||||
{
|
unsigned m_span_idx;
|
||||||
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:
|
|
||||||
const AlphaMask* m_alpha_mask;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
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(const 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:
|
||||||
|
const AlphaMask* m_alpha_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
74
deps/agg/include/agg_shorten_path.h
vendored
74
deps/agg/include/agg_shorten_path.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -19,48 +19,48 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_vertex_sequence.h"
|
#include "agg_vertex_sequence.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//===========================================================shorten_path
|
||||||
|
template<class VertexSequence>
|
||||||
|
void shorten_path(VertexSequence& vs, double s, unsigned closed = 0)
|
||||||
{
|
{
|
||||||
|
typedef typename VertexSequence::value_type vertex_type;
|
||||||
|
|
||||||
//===========================================================shorten_path
|
if (s > 0.0 && vs.size() > 1)
|
||||||
template<class VertexSequence>
|
|
||||||
void shorten_path(VertexSequence& vs, double s, unsigned closed = 0)
|
|
||||||
{
|
{
|
||||||
typedef typename VertexSequence::value_type vertex_type;
|
double d;
|
||||||
|
int n = int(vs.size() - 2);
|
||||||
if(s > 0.0 && vs.size() > 1)
|
while (n)
|
||||||
{
|
{
|
||||||
double d;
|
d = vs[n].dist;
|
||||||
int n = int(vs.size() - 2);
|
if (d > s)
|
||||||
while(n)
|
break;
|
||||||
{
|
vs.remove_last();
|
||||||
d = vs[n].dist;
|
s -= d;
|
||||||
if(d > s) break;
|
--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.remove_last();
|
||||||
s -= d;
|
vs.close(closed != 0);
|
||||||
--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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
231
deps/agg/include/agg_simul_eq.h
vendored
231
deps/agg/include/agg_simul_eq.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -22,126 +22,119 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//=============================================================swap_arrays
|
||||||
|
template<class T>
|
||||||
|
void swap_arrays(T* a1, T* a2, unsigned n)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
//=============================================================swap_arrays
|
for (i = 0; i < n; i++)
|
||||||
template<class T> void swap_arrays(T* a1, T* a2, unsigned n)
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
T tmp = *a1;
|
||||||
for(i = 0; i < n; i++)
|
*a1++ = *a2;
|
||||||
{
|
*a2++ = tmp;
|
||||||
T tmp = *a1;
|
|
||||||
*a1++ = *a2;
|
|
||||||
*a2++ = tmp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================matrix_pivot
|
|
||||||
template<unsigned Rows, unsigned Cols>
|
|
||||||
struct matrix_pivot
|
|
||||||
{
|
|
||||||
static int pivot(double m[Rows][Cols], unsigned row)
|
|
||||||
{
|
|
||||||
int k = int(row);
|
|
||||||
double max_val, tmp;
|
|
||||||
|
|
||||||
max_val = -1.0;
|
|
||||||
unsigned i;
|
|
||||||
for(i = row; i < Rows; i++)
|
|
||||||
{
|
|
||||||
if((tmp = std::fabs(m[i][row])) > max_val && tmp != 0.0)
|
|
||||||
{
|
|
||||||
max_val = tmp;
|
|
||||||
k = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m[k][row] == 0.0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(k != int(row))
|
|
||||||
{
|
|
||||||
swap_arrays(m[k], m[row], Cols);
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============================================================simul_eq
|
|
||||||
template<unsigned Size, unsigned RightCols>
|
|
||||||
struct simul_eq
|
|
||||||
{
|
|
||||||
static bool solve(const double left[Size][Size],
|
|
||||||
const double right[Size][RightCols],
|
|
||||||
double result[Size][RightCols])
|
|
||||||
{
|
|
||||||
unsigned i, j, k;
|
|
||||||
double a1;
|
|
||||||
|
|
||||||
double tmp[Size][Size + RightCols];
|
|
||||||
|
|
||||||
for(i = 0; i < Size; i++)
|
|
||||||
{
|
|
||||||
for(j = 0; j < Size; j++)
|
|
||||||
{
|
|
||||||
tmp[i][j] = left[i][j];
|
|
||||||
}
|
|
||||||
for(j = 0; j < RightCols; j++)
|
|
||||||
{
|
|
||||||
tmp[i][Size + j] = right[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(k = 0; k < Size; k++)
|
|
||||||
{
|
|
||||||
if(matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0)
|
|
||||||
{
|
|
||||||
return false; // Singularity....
|
|
||||||
}
|
|
||||||
|
|
||||||
a1 = tmp[k][k];
|
|
||||||
|
|
||||||
for(j = k; j < Size + RightCols; j++)
|
|
||||||
{
|
|
||||||
tmp[k][j] /= a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = k + 1; i < Size; i++)
|
|
||||||
{
|
|
||||||
a1 = tmp[i][k];
|
|
||||||
for (j = k; j < Size + RightCols; j++)
|
|
||||||
{
|
|
||||||
tmp[i][j] -= a1 * tmp[k][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for(k = 0; k < RightCols; k++)
|
|
||||||
{
|
|
||||||
int m;
|
|
||||||
for(m = int(Size - 1); m >= 0; m--)
|
|
||||||
{
|
|
||||||
result[m][k] = tmp[m][Size + k];
|
|
||||||
for(j = m + 1; j < Size; j++)
|
|
||||||
{
|
|
||||||
result[m][k] -= tmp[m][j] * result[j][k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================matrix_pivot
|
||||||
|
template<unsigned Rows, unsigned Cols>
|
||||||
|
struct matrix_pivot
|
||||||
|
{
|
||||||
|
static int pivot(double m[Rows][Cols], unsigned row)
|
||||||
|
{
|
||||||
|
int k = int(row);
|
||||||
|
double max_val, tmp;
|
||||||
|
|
||||||
|
max_val = -1.0;
|
||||||
|
unsigned i;
|
||||||
|
for (i = row; i < Rows; i++)
|
||||||
|
{
|
||||||
|
if ((tmp = std::fabs(m[i][row])) > max_val && tmp != 0.0)
|
||||||
|
{
|
||||||
|
max_val = tmp;
|
||||||
|
k = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m[k][row] == 0.0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k != int(row))
|
||||||
|
{
|
||||||
|
swap_arrays(m[k], m[row], Cols);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//===============================================================simul_eq
|
||||||
|
template<unsigned Size, unsigned RightCols>
|
||||||
|
struct simul_eq
|
||||||
|
{
|
||||||
|
static bool
|
||||||
|
solve(const double left[Size][Size], const double right[Size][RightCols], double result[Size][RightCols])
|
||||||
|
{
|
||||||
|
unsigned i, j, k;
|
||||||
|
double a1;
|
||||||
|
|
||||||
|
double tmp[Size][Size + RightCols];
|
||||||
|
|
||||||
|
for (i = 0; i < Size; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < Size; j++)
|
||||||
|
{
|
||||||
|
tmp[i][j] = left[i][j];
|
||||||
|
}
|
||||||
|
for (j = 0; j < RightCols; j++)
|
||||||
|
{
|
||||||
|
tmp[i][Size + j] = right[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = 0; k < Size; k++)
|
||||||
|
{
|
||||||
|
if (matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0)
|
||||||
|
{
|
||||||
|
return false; // Singularity....
|
||||||
|
}
|
||||||
|
|
||||||
|
a1 = tmp[k][k];
|
||||||
|
|
||||||
|
for (j = k; j < Size + RightCols; j++)
|
||||||
|
{
|
||||||
|
tmp[k][j] /= a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = k + 1; i < Size; i++)
|
||||||
|
{
|
||||||
|
a1 = tmp[i][k];
|
||||||
|
for (j = k; j < Size + RightCols; j++)
|
||||||
|
{
|
||||||
|
tmp[i][j] -= a1 * tmp[k][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = 0; k < RightCols; k++)
|
||||||
|
{
|
||||||
|
int m;
|
||||||
|
for (m = int(Size - 1); m >= 0; m--)
|
||||||
|
{
|
||||||
|
result[m][k] = tmp[m][Size + k];
|
||||||
|
for (j = m + 1; j < Size; j++)
|
||||||
|
{
|
||||||
|
result[m][k] -= tmp[m][j] * result[j][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
53
deps/agg/include/agg_span_allocator.h
vendored
53
deps/agg/include/agg_span_allocator.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,37 +18,34 @@
|
||||||
|
|
||||||
#include "agg_array.h"
|
#include "agg_array.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//----------------------------------------------------------span_allocator
|
||||||
|
template<class ColorT>
|
||||||
|
class span_allocator
|
||||||
{
|
{
|
||||||
//----------------------------------------------------------span_allocator
|
public:
|
||||||
template<class ColorT> class span_allocator
|
typedef ColorT color_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
AGG_INLINE color_type* allocate(unsigned span_len)
|
||||||
{
|
{
|
||||||
public:
|
if (span_len > m_span.size())
|
||||||
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.
|
||||||
// To reduce the number of reallocs we align the
|
// Well, I just like this number and it looks reasonable.
|
||||||
// span_len to 256 color elements.
|
//-----------------------
|
||||||
// Well, I just like this number and it looks reasonable.
|
m_span.resize(((span_len + 255) >> 8) << 8);
|
||||||
//-----------------------
|
|
||||||
m_span.resize(((span_len + 255) >> 8) << 8);
|
|
||||||
}
|
|
||||||
return &m_span[0];
|
|
||||||
}
|
}
|
||||||
|
return &m_span[0];
|
||||||
|
}
|
||||||
|
|
||||||
AGG_INLINE color_type* span() { return &m_span[0]; }
|
AGG_INLINE color_type* span() { return &m_span[0]; }
|
||||||
AGG_INLINE unsigned max_span_len() const { return m_span.size(); }
|
AGG_INLINE unsigned max_span_len() const { return m_span.size(); }
|
||||||
|
|
||||||
private:
|
|
||||||
pod_array<color_type> m_span;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
pod_array<color_type> m_span;
|
||||||
|
};
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
64
deps/agg/include/agg_span_converter.h
vendored
64
deps/agg/include/agg_span_converter.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -18,39 +18,41 @@
|
||||||
|
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
//----------------------------------------------------------span_converter
|
||||||
|
template<class SpanGenerator, class SpanConverter>
|
||||||
|
class span_converter
|
||||||
{
|
{
|
||||||
//----------------------------------------------------------span_converter
|
public:
|
||||||
template<class SpanGenerator, class SpanConverter> class span_converter
|
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()
|
||||||
{
|
{
|
||||||
public:
|
m_span_gen->prepare();
|
||||||
typedef typename SpanGenerator::color_type color_type;
|
m_span_cnv->prepare();
|
||||||
|
}
|
||||||
|
|
||||||
span_converter(SpanGenerator& span_gen, SpanConverter& span_cnv) :
|
//--------------------------------------------------------------------
|
||||||
m_span_gen(&span_gen), m_span_cnv(&span_cnv) {}
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
void attach_generator(SpanGenerator& span_gen) { m_span_gen = &span_gen; }
|
private:
|
||||||
void attach_converter(SpanConverter& span_cnv) { m_span_cnv = &span_cnv; }
|
SpanGenerator* m_span_gen;
|
||||||
|
SpanConverter* m_span_cnv;
|
||||||
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
} // namespace agg
|
||||||
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
|
#endif
|
||||||
|
|
314
deps/agg/include/agg_span_gouraud.h
vendored
314
deps/agg/include/agg_span_gouraud.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -19,154 +19,176 @@
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_math.h"
|
#include "agg_math.h"
|
||||||
|
|
||||||
namespace agg
|
namespace agg {
|
||||||
|
|
||||||
|
//============================================================span_gouraud
|
||||||
|
template<class ColorT>
|
||||||
|
class span_gouraud
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
typedef ColorT color_type;
|
||||||
|
|
||||||
//============================================================span_gouraud
|
struct coord_type
|
||||||
template<class ColorT> class span_gouraud
|
|
||||||
{
|
{
|
||||||
public:
|
double x;
|
||||||
typedef ColorT color_type;
|
double y;
|
||||||
|
color_type color;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
//--------------------------------------------------------------------
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
409
deps/agg/include/agg_span_gouraud_gray.h
vendored
409
deps/agg/include/agg_span_gouraud_gray.h
vendored
|
@ -2,8 +2,8 @@
|
||||||
// Anti-Grain Geometry - Version 2.4
|
// Anti-Grain Geometry - Version 2.4
|
||||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
@ -13,12 +13,12 @@
|
||||||
// http://www.antigrain.com
|
// http://www.antigrain.com
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Adaptation for high precision colors has been sponsored by
|
// Adaptation for high precision colors has been sponsored by
|
||||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||||
//
|
//
|
||||||
// Liberty Technology Systems, Inc. is the provider of
|
// Liberty Technology Systems, Inc. is the provider of
|
||||||
// PostScript and PDF technology for software developers.
|
// PostScript and PDF technology for software developers.
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef AGG_SPAN_GOURAUD_GRAY_INCLUDED
|
#ifndef AGG_SPAN_GOURAUD_GRAY_INCLUDED
|
||||||
|
@ -29,213 +29,222 @@
|
||||||
#include "agg_dda_line.h"
|
#include "agg_dda_line.h"
|
||||||
#include "agg_span_gouraud.h"
|
#include "agg_span_gouraud.h"
|
||||||
|
|
||||||
namespace agg
|
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 };
|
||||||
|
|
||||||
//=======================================================span_gouraud_gray
|
private:
|
||||||
template<class ColorT> class span_gouraud_gray : public span_gouraud<ColorT>
|
//--------------------------------------------------------------------
|
||||||
|
struct gray_calc
|
||||||
{
|
{
|
||||||
public:
|
void init(const coord_type& c1, const coord_type& c2)
|
||||||
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_x1 = c1.x - 0.5;
|
m_dx = c2.x - c1.x;
|
||||||
m_y1 = c1.y - 0.5;
|
double dy = c2.y - c1.y;
|
||||||
m_dx = c2.x - c1.x;
|
m_1dy = (std::fabs(dy) < 1e-10) ? 1e10 : 1.0 / dy;
|
||||||
double dy = c2.y - c1.y;
|
m_v1 = c1.color.v;
|
||||||
m_1dy = (std::fabs(dy) < 1e-10) ? 1e10 : 1.0 / dy;
|
m_a1 = c1.color.a;
|
||||||
m_v1 = c1.color.v;
|
m_dv = c2.color.v - m_v1;
|
||||||
m_a1 = c1.color.a;
|
m_da = c2.color.a - m_a1;
|
||||||
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 calc(double y)
|
||||||
void generate(color_type* span, int x, int y, unsigned len)
|
|
||||||
{
|
{
|
||||||
m_c1.calc(y);
|
double k = (y - m_y1) * m_1dy;
|
||||||
const gray_calc* pc1 = &m_c1;
|
if (k < 0.0)
|
||||||
const gray_calc* pc2 = &m_c2;
|
k = 0.0;
|
||||||
|
if (k > 1.0)
|
||||||
if(y < m_y2)
|
k = 1.0;
|
||||||
{
|
m_v = m_v1 + iround(m_dv * k);
|
||||||
// Bottom part of the triangle (first subtriangle)
|
m_a = m_a1 + iround(m_da * k);
|
||||||
//-------------------------
|
m_x = iround((m_x1 + m_dx * k) * subpixel_scale);
|
||||||
m_c2.calc(y + m_c2.m_1dy);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Upper part (second subtriangle)
|
|
||||||
//-------------------------
|
|
||||||
m_c3.calc(y - m_c3.m_1dy);
|
|
||||||
pc2 = &m_c3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_swap)
|
|
||||||
{
|
|
||||||
// It means that the triangle is oriented clockwise,
|
|
||||||
// so that we need to swap the controlling structures
|
|
||||||
//-------------------------
|
|
||||||
const gray_calc* t = pc2;
|
|
||||||
pc2 = pc1;
|
|
||||||
pc1 = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the horizontal length with subpixel accuracy
|
|
||||||
// and protect it from division by zero
|
|
||||||
//-------------------------
|
|
||||||
int nlen = std::abs(pc2->m_x - pc1->m_x);
|
|
||||||
if(nlen <= 0) nlen = 1;
|
|
||||||
|
|
||||||
dda_line_interpolator<14> v(pc1->m_v, pc2->m_v, nlen);
|
|
||||||
dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
|
|
||||||
|
|
||||||
// Calculate the starting point of the gradient with subpixel
|
|
||||||
// accuracy and correct (roll back) the interpolators.
|
|
||||||
// This operation will also clip the beginning of the span
|
|
||||||
// if necessary.
|
|
||||||
//-------------------------
|
|
||||||
int start = pc1->m_x - (x << subpixel_shift);
|
|
||||||
v -= start;
|
|
||||||
a -= start;
|
|
||||||
nlen += start;
|
|
||||||
|
|
||||||
int vv, va;
|
|
||||||
enum lim_e { lim = color_type::base_mask };
|
|
||||||
|
|
||||||
// Beginning part of the span. Since we rolled back the
|
|
||||||
// interpolators, the color values may have overflow.
|
|
||||||
// So that, we render the beginning part with checking
|
|
||||||
// for overflow. It lasts until "start" is positive;
|
|
||||||
// typically it's 1-2 pixels, but may be more in some cases.
|
|
||||||
//-------------------------
|
|
||||||
while(len && start > 0)
|
|
||||||
{
|
|
||||||
vv = v.y();
|
|
||||||
va = a.y();
|
|
||||||
if(vv < 0) vv = 0; if(vv > lim) vv = lim;
|
|
||||||
if(va < 0) va = 0; if(va > lim) va = lim;
|
|
||||||
span->v = (value_type)vv;
|
|
||||||
span->a = (value_type)va;
|
|
||||||
v += subpixel_scale;
|
|
||||||
a += subpixel_scale;
|
|
||||||
nlen -= subpixel_scale;
|
|
||||||
start -= subpixel_scale;
|
|
||||||
++span;
|
|
||||||
--len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Middle part, no checking for overflow.
|
|
||||||
// Actual spans can be longer than the calculated length
|
|
||||||
// because of anti-aliasing, thus, the interpolators can
|
|
||||||
// overflow. But while "nlen" is positive we are safe.
|
|
||||||
//-------------------------
|
|
||||||
while(len && nlen > 0)
|
|
||||||
{
|
|
||||||
span->v = (value_type)v.y();
|
|
||||||
span->a = (value_type)a.y();
|
|
||||||
v += subpixel_scale;
|
|
||||||
a += subpixel_scale;
|
|
||||||
nlen -= subpixel_scale;
|
|
||||||
++span;
|
|
||||||
--len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ending part; checking for overflow.
|
|
||||||
// Typically it's 1-2 pixels, but may be more in some cases.
|
|
||||||
//-------------------------
|
|
||||||
while(len)
|
|
||||||
{
|
|
||||||
vv = v.y();
|
|
||||||
va = a.y();
|
|
||||||
if(vv < 0) vv = 0; if(vv > lim) vv = lim;
|
|
||||||
if(va < 0) va = 0; if(va > lim) va = lim;
|
|
||||||
span->v = (value_type)vv;
|
|
||||||
span->a = (value_type)va;
|
|
||||||
v += subpixel_scale;
|
|
||||||
a += subpixel_scale;
|
|
||||||
++span;
|
|
||||||
--len;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double m_x1;
|
||||||
private:
|
double m_y1;
|
||||||
bool m_swap;
|
double m_dx;
|
||||||
int m_y2;
|
double m_1dy;
|
||||||
gray_calc m_c1;
|
int m_v1;
|
||||||
gray_calc m_c2;
|
int m_a1;
|
||||||
gray_calc m_c3;
|
int m_dv;
|
||||||
|
int m_da;
|
||||||
|
int m_v;
|
||||||
|
int m_a;
|
||||||
|
int m_x;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
span_gouraud_gray() {}
|
||||||
|
span_gouraud_gray(const color_type& c1,
|
||||||
|
const color_type& c2,
|
||||||
|
const color_type& c3,
|
||||||
|
double x1,
|
||||||
|
double y1,
|
||||||
|
double x2,
|
||||||
|
double y2,
|
||||||
|
double x3,
|
||||||
|
double y3,
|
||||||
|
double d = 0)
|
||||||
|
: base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
|
||||||
|
{}
|
||||||
|
|
||||||
}
|
//--------------------------------------------------------------------
|
||||||
|
void prepare()
|
||||||
|
{
|
||||||
|
coord_type coord[3];
|
||||||
|
base_type::arrange_vertices(coord);
|
||||||
|
|
||||||
|
m_y2 = int(coord[1].y);
|
||||||
|
|
||||||
|
m_swap = cross_product(coord[0].x, coord[0].y, coord[2].x, coord[2].y, coord[1].x, coord[1].y) < 0.0;
|
||||||
|
|
||||||
|
m_c1.init(coord[0], coord[2]);
|
||||||
|
m_c2.init(coord[0], coord[1]);
|
||||||
|
m_c3.init(coord[1], coord[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void generate(color_type* span, int x, int y, unsigned len)
|
||||||
|
{
|
||||||
|
m_c1.calc(y);
|
||||||
|
const gray_calc* pc1 = &m_c1;
|
||||||
|
const gray_calc* pc2 = &m_c2;
|
||||||
|
|
||||||
|
if (y < m_y2)
|
||||||
|
{
|
||||||
|
// Bottom part of the triangle (first subtriangle)
|
||||||
|
//-------------------------
|
||||||
|
m_c2.calc(y + m_c2.m_1dy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Upper part (second subtriangle)
|
||||||
|
//-------------------------
|
||||||
|
m_c3.calc(y - m_c3.m_1dy);
|
||||||
|
pc2 = &m_c3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_swap)
|
||||||
|
{
|
||||||
|
// It means that the triangle is oriented clockwise,
|
||||||
|
// so that we need to swap the controlling structures
|
||||||
|
//-------------------------
|
||||||
|
const gray_calc* t = pc2;
|
||||||
|
pc2 = pc1;
|
||||||
|
pc1 = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the horizontal length with subpixel accuracy
|
||||||
|
// and protect it from division by zero
|
||||||
|
//-------------------------
|
||||||
|
int nlen = std::abs(pc2->m_x - pc1->m_x);
|
||||||
|
if (nlen <= 0)
|
||||||
|
nlen = 1;
|
||||||
|
|
||||||
|
dda_line_interpolator<14> v(pc1->m_v, pc2->m_v, nlen);
|
||||||
|
dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
|
||||||
|
|
||||||
|
// Calculate the starting point of the gradient with subpixel
|
||||||
|
// accuracy and correct (roll back) the interpolators.
|
||||||
|
// This operation will also clip the beginning of the span
|
||||||
|
// if necessary.
|
||||||
|
//-------------------------
|
||||||
|
int start = pc1->m_x - (x << subpixel_shift);
|
||||||
|
v -= start;
|
||||||
|
a -= start;
|
||||||
|
nlen += start;
|
||||||
|
|
||||||
|
int vv, va;
|
||||||
|
enum lim_e { lim = color_type::base_mask };
|
||||||
|
|
||||||
|
// Beginning part of the span. Since we rolled back the
|
||||||
|
// interpolators, the color values may have overflow.
|
||||||
|
// So that, we render the beginning part with checking
|
||||||
|
// for overflow. It lasts until "start" is positive;
|
||||||
|
// typically it's 1-2 pixels, but may be more in some cases.
|
||||||
|
//-------------------------
|
||||||
|
while (len && start > 0)
|
||||||
|
{
|
||||||
|
vv = v.y();
|
||||||
|
va = a.y();
|
||||||
|
if (vv < 0)
|
||||||
|
vv = 0;
|
||||||
|
if (vv > lim)
|
||||||
|
vv = lim;
|
||||||
|
if (va < 0)
|
||||||
|
va = 0;
|
||||||
|
if (va > lim)
|
||||||
|
va = lim;
|
||||||
|
span->v = (value_type)vv;
|
||||||
|
span->a = (value_type)va;
|
||||||
|
v += subpixel_scale;
|
||||||
|
a += subpixel_scale;
|
||||||
|
nlen -= subpixel_scale;
|
||||||
|
start -= subpixel_scale;
|
||||||
|
++span;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Middle part, no checking for overflow.
|
||||||
|
// Actual spans can be longer than the calculated length
|
||||||
|
// because of anti-aliasing, thus, the interpolators can
|
||||||
|
// overflow. But while "nlen" is positive we are safe.
|
||||||
|
//-------------------------
|
||||||
|
while (len && nlen > 0)
|
||||||
|
{
|
||||||
|
span->v = (value_type)v.y();
|
||||||
|
span->a = (value_type)a.y();
|
||||||
|
v += subpixel_scale;
|
||||||
|
a += subpixel_scale;
|
||||||
|
nlen -= subpixel_scale;
|
||||||
|
++span;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ending part; checking for overflow.
|
||||||
|
// Typically it's 1-2 pixels, but may be more in some cases.
|
||||||
|
//-------------------------
|
||||||
|
while (len)
|
||||||
|
{
|
||||||
|
vv = v.y();
|
||||||
|
va = a.y();
|
||||||
|
if (vv < 0)
|
||||||
|
vv = 0;
|
||||||
|
if (vv > lim)
|
||||||
|
vv = lim;
|
||||||
|
if (va < 0)
|
||||||
|
va = 0;
|
||||||
|
if (va > lim)
|
||||||
|
va = lim;
|
||||||
|
span->v = (value_type)vv;
|
||||||
|
span->a = (value_type)va;
|
||||||
|
v += subpixel_scale;
|
||||||
|
a += subpixel_scale;
|
||||||
|
++span;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_swap;
|
||||||
|
int m_y2;
|
||||||
|
gray_calc m_c1;
|
||||||
|
gray_calc m_c2;
|
||||||
|
gray_calc m_c3;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace agg
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue