Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

61
.clang-format Normal file
View file

@ -0,0 +1,61 @@
# Configuration file for clang-format, based on docs/CPP_STYLE.md.
BasedOnStyle: Google
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: LeftWithLastLine
AlignOperands: AlignAfterOperator
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterExternBlock: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: true
BeforeWhile: true
SplitEmptyFunction: false
SplitEmptyNamespace: false
SplitEmptyRecord: false
BinPackArguments: true
BinPackParameters: true
BreakAfterJavaFieldAnnotations: true
BreakBeforeBraces: Custom
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
ColumnLimit: 120
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 4
DerivePointerAlignment: false
EmptyLineBeforeAccessModifier: Always
IncludeBlocks: Preserve
IndentAccessModifiers: false
IndentCaseLabels: false
IndentExternBlock: NoIndent
InsertBraces: false
InsertNewlineAtEOF: true
LambdaBodyIndentation: OuterScope
PackConstructorInitializers: CurrentLine
PointerAlignment: Middle
RemoveBracesLLVM: true
RemoveSemicolon: true
QualifierAlignment: Right
SpacesInContainerLiterals: false
Standard: Latest
TabWidth: 2
---
Language: Java
AllowShortFunctionsOnASingleLine: Empty

8
.clang-format-ignore Normal file
View file

@ -0,0 +1,8 @@
# Files that should not be formatted.
./3party
# A patched copy of the https://registry.khronos.org/OpenGL/api/GLES3/gl3.h
./android/sdk/src/main/cpp/app/organicmaps/sdk/opengl/gl3stub.h
# Formatting it leads to crashes in runtime. Newer protobuf may fix it.
./libs/indexer/drules_struct.pb.cc
# No need to format this 3party tool.
tools/osmctools/*.c

4
.git-blame-ignore-revs Normal file
View file

@ -0,0 +1,4 @@
6aa73face8b5eb8e026cfafa40d1983d4a0502c0
480fa6c2fcf53be296504ac6ba8e6b3d70f92b42
a6ede2b1466f0c9d8a443600ef337ba6b5832e58
1377b81bf1cac72bb6da192da7fed6696d5d5281

46
.gitattributes vendored Normal file
View file

@ -0,0 +1,46 @@
# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto
# Explicitly declare text files we want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.h text
*.cpp text
*.hpp text
*.cxx text
*.cc text
*.java text
*.mm text
# Declare files that will always have LF line endings on checkout.
*.txt text eol=lf
*.html text eol=lf
*.xml text eol=lf
*.csv text eol=lf
*.svg text eol=lf
*.py text eol=lf
*.sh text eol=lf
*.lst text eol=lf
*.mapcss text eol=lf
*.test text eol=lf
*.skn text eol=lf
*.meta text eol=lf
*.gitattributes text eol=lf
*.gitignore text eol=lf
# Declare files that will always have CRLF line endings on checkout.
*.dsp text eol=crlf
*.dsw text eol=crlf
# Binary files which doesn't need any normalization
*.bin binary
*.bz2 binary
*.kmz binary
*.mwm binary
*.png binary
*.jpg binary
*.jpeg binary
*.ttf binary
*.slf binary
*.borders binary
*.pdf binary

200
.gitignore vendored Normal file
View file

@ -0,0 +1,200 @@
# Please use android/.gitignore for all Android stuff
syntax: glob
*~
.DS_Store
Makefile
Makefile.Debug
Makefile.Release
object_script.*.Debug
object_script.*.Release
compile_commands.json
*.local.*
stxxl.errlog
stxxl.log
screenlog.0
# symbols png/sdf are now generated at build
data/symbols/**/symbols.png
data/symbols/**/symbols.sdf
data/bookmarks
data/edits.xml
data/World.mwm
data/WorldCoasts.mwm
data/world_mwm/*
data/*_hash
data/drules_proto*
data/classificator.txt*
data/types.txt*
data/visibility.txt*
data/colors.txt*
data/patterns.txt*
# TODO: designer is not used at the moment
# data/symbols/*/design/
# data/colors_design.txt
# data/patterns_design.txt
# Auto-generated from data/categories-strings/* by tools/unix/generate_categories.sh
data/categories.txt
# Compiled Python
*.pyc
# Windows generated files
*.vcxproj*
ipch/*
omim.sdf
*.vcproj
*.icproj
*.sln
*.idb
*.user
*.pro.user*
*.ncb
*.suo
*.aps
*.rc
!qt/res/windows/windows.rc
*.pdb
out/
# XCode
xcode/keys/*
xcode/build/*
xcode/metadata/review_information/*
xcode/fastlane/report.xml
xcode/fastlane/README.md
iphone/*/*.xcodeproj/*.pbxuser
iphone/*/*.xcodeproj/*.perspectivev3
iphone/*/*.xcodeproj/project.xcworkspace/*
iphone/*/build/*
tools/emacsmode/build
**/DerivedData/*
**/xcshareddata/*
!iphone/Maps/Maps.xcodeproj/xcshareddata/xcschemes/CoMaps.xcscheme
**/xcuserdata
**/xcschemes
iphone/**/*.moved-aside
iphone/**/*.swp
iphone/**/*.mode1v3
iphone/**/*.mode2v3
iphone/**/*.perspectivev3
# Carthage
iphone/Maps/3party/Carthage/Checkouts
iphone/Maps/3party/Carthage/Build/Mac/*.bcsymbolmap
iphone/Maps/3party/Carthage/Build/Mac/*.dSYM
iphone/Maps/3party/Carthage/Build/tvOS
iphone/Maps/3party/Carthage/Build/watchOS
iphone/Maps/3party/Carthage/Build/iOS/*.bcsymbolmap
iphone/Maps/3party/Carthage/Build/iOS/*.dSYM
iphone/Maps/3party/Carthage/Build/*.version
# GeneratedFiles
tools/win/MapsWithMe*
GeneratedFiles
# data
data/[0-9][0-9][0-9][0-9][0-9][0-9]
data/gps_track.dat
# temporary files for downloader
data/settings.ini
data/test_data/world_feed_integration_tests_data
# benchmark results
data/benchmarks/*.trace
data/benchmarks/iphone3g/*
data/benchmarks/ipod4/*
data/benchmarks/ipad/*
data/benchmarks/mac/*
data/benchmarks/kindle-fire/*
data/benchmarks/galaxy-s-2/*
data/benchmarks/ipad3/*
data/benchmarks/ipad2/*
data/benchmarks/iphone5/*
data/benchmarks/maps/*
qtc_packaging
tools/twine/.git
# shader preprocessing moc files
drape/shader_def.hpp
drape/shader_def.cpp
drape_frontend/shader_def.hpp
drape_frontend/shader_def.cpp
drape_frontend/drape_frontend_tests/shader_def_for_tests.hpp
drape_frontend/drape_frontend_tests/shader_def_for_tests.cpp
tizen/*/Debug/*
tizen/*/.*
!tizen/*/.cproject
!tizen/*/.project
3party/osrm/osrm-backend/util/fingerprint_impl.hpp
3party/osrm/osrm-backend/util/git_sha.cpp
3party/osrm/osrm-backend/build/
tizen/*/crash-info/*
.idea/*
.idea
!android/.idea/icon.svg
# Private repository files.
.private_repository_url
.private_repository_branch
private.h
# ignore old android secrets during the transition period to the new project structure
android/release.keystore
android/secure.properties
android/libnotify.properties
android/google-play.json
android/huawei-appgallery.json
android/res/xml/network_security_config.xml
./server/
iphone/Maps/app.omaps/
*.li
*.autosave
# CMake
cmake-build-*
build/
qt/res/Info.plist
designer_version.h
# Vim files
*.sw?
# Build version
platform/platform_qt_version.cpp
#python modules building
tools/python/*/build
tools/python/*/dist
tools/python/*/*.egg-info
tools/python/data/*/build
tools/python/data/*/dist
tools/python/data/*/*.egg-info
tools/python/*/venv/
# Configs
tools/python/maps_generator/var/etc/map_generator.ini
tools/python/routing/etc/*.ini
tools/unix/maps/settings.sh
# Helpers
/node_modules/
/package-lock.json
# Visual Studio
.vs
# VS Code
.vscode
.cache

71
.gitmodules vendored Normal file
View file

@ -0,0 +1,71 @@
[submodule "tools/osmctools"]
path = tools/osmctools
url = https://github.com/organicmaps/osmctools.git
[submodule "tools/kothic"]
path = tools/kothic
url = https://codeberg.org/comaps/kothic.git
[submodule "3party/protobuf/protobuf"]
path = 3party/protobuf/protobuf
url = https://codeberg.org/comaps/protobuf.git
[submodule "3party/Vulkan-Headers"]
path = 3party/Vulkan-Headers
url = https://github.com/KhronosGroup/Vulkan-Headers.git
[submodule "3party/boost"]
path = 3party/boost
url = https://github.com/boostorg/boost.git
branch = boost-1.85.0
ignore = dirty
[submodule "3party/just_gtfs"]
path = 3party/just_gtfs
url = https://github.com/organicmaps/just_gtfs.git
branch = for-usage-as-submodule
[submodule "3party/expat"]
path = 3party/expat
url = https://github.com/libexpat/libexpat.git
branch = R_2_2_9
[submodule "3party/glm"]
path = 3party/glm
url = https://github.com/g-truc/glm.git
[submodule "3party/icu/icu"]
path = 3party/icu/icu
url = https://github.com/unicode-org/icu.git
[submodule "3party/freetype/freetype"]
path = 3party/freetype/freetype
url = https://gitlab.freedesktop.org/freetype/freetype.git
[submodule "3party/googletest"]
path = 3party/googletest
url = https://github.com/google/googletest.git
[submodule "3party/fast_double_parser"]
path = 3party/fast_double_parser
url = https://github.com/lemire/fast_double_parser.git
[submodule "3party/pugixml/pugixml"]
path = 3party/pugixml/pugixml
url = https://github.com/zeux/pugixml.git
[submodule "3party/jansson/jansson"]
path = 3party/jansson/jansson
url = https://github.com/akheron/jansson.git
[submodule "3party/gflags"]
path = 3party/gflags
url = https://github.com/gflags/gflags
[submodule "3party/fast_obj"]
path = 3party/fast_obj
url = https://github.com/thisistherk/fast_obj
[submodule "3party/harfbuzz/harfbuzz"]
path = 3party/harfbuzz/harfbuzz
url = https://github.com/harfbuzz/harfbuzz.git
[submodule "3party/utfcpp"]
path = 3party/utfcpp
url = https://github.com/nemtrif/utfcpp.git
[submodule "3party/glfw"]
path = 3party/glfw
url = https://github.com/glfw/glfw.git
[submodule "3party/CMake-MetalShaderSupport"]
path = 3party/CMake-MetalShaderSupport
url = https://github.com/dpogue/CMake-MetalShaderSupport.git
[submodule "3party/imgui/imgui"]
path = 3party/imgui/imgui
url = https://github.com/ocornut/imgui
[submodule "3party/glaze"]
path = 3party/glaze
url = https://github.com/stephenberry/glaze
branch = main

5
.prettierrc.yaml Normal file
View file

@ -0,0 +1,5 @@
trailingComma: 'es5'
tabWidth: 2
printWidth: 80
semi: false
singleQuote: true

86
3party/CMakeLists.txt Normal file
View file

@ -0,0 +1,86 @@
# Fixes CMake deprecation warning:
# Compatibility with CMake < 3.5 will be removed from a future version of CMake.
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "" FORCE)
if (NOT WITH_SYSTEM_PROVIDED_3PARTY)
# Suppress "Policy CMP0077 is not set: option() honors normal variables"
# for the freetype, expat and jansson options.
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
# Suppress "Policy CMP0063 is not set: Honor visibility properties for all target types."
# for jansson
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
# Configure expat library.
set(EXPAT_BUILD_TOOLS OFF)
set(EXPAT_BUILD_EXAMPLES OFF)
set(EXPAT_BUILD_TESTS OFF)
set(EXPAT_BUILD_DOCS OFF)
set(EXPAT_BUILD_PKGCONFIG OFF)
set(EXPAT_ENABLE_INSTALL OFF)
set(EXPAT_SHARED_LIBS OFF)
set(EXPAT_GE OFF)
set(EXPAT_DTD OFF)
set(EXPAT_NS ON)
add_subdirectory(expat/expat)
# Configure Jansson library.
set(JANSSON_BUILD_DOCS OFF)
set(JANSSON_BUILD_MAN OFF)
set(JANSSON_EXAMPLES OFF)
set(JANSSON_INSTALL OFF)
set(JANSSON_WITHOUT_TESTS ON)
add_subdirectory(jansson/jansson/)
target_include_directories(jansson INTERFACE "${PROJECT_BINARY_DIR}/3party/jansson/jansson/include")
# Add gflags library.
set(GFLAGS_BUILD_TESTING OFF)
set(GFLAGS_BUILD_PACKAGING OFF)
add_subdirectory(gflags)
target_compile_options(gflags_nothreads_static PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wno-subobject-linkage>)
# Add pugixml library.
add_subdirectory(pugixml)
# Add protobuf library.
add_subdirectory(protobuf)
if (NOT PLATFORM_LINUX)
add_subdirectory(freetype)
add_subdirectory(icu)
add_subdirectory(harfbuzz)
endif()
add_library(utf8cpp INTERFACE)
add_library(utf8cpp::utf8cpp ALIAS utf8cpp)
target_include_directories(utf8cpp INTERFACE "${OMIM_ROOT}/3party/utfcpp/source")
endif()
add_subdirectory(agg)
add_subdirectory(bsdiff-courgette)
add_subdirectory(glaze)
add_subdirectory(minizip)
add_subdirectory(open-location-code)
add_subdirectory(opening_hours)
add_subdirectory(stb_image)
add_subdirectory(succinct)
add_subdirectory(vulkan_wrapper)
if (PLATFORM_DESKTOP)
add_subdirectory(libtess2)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "")
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "")
set(GLFW_BUILD_TESTS OFF CACHE BOOL "")
set(GLFW_INSTALL OFF CACHE BOOL "")
set(GLFW_VULKAN_STATIC OFF CACHE BOOL "")
set(GLFW_BUILD_WAYLAND OFF CACHE BOOL "")
# Disable ARC for glfw and re-enable after it because it's globally set in the root CMakeLists.txt
set(CMAKE_OBJC_FLAGS "")
add_subdirectory(glfw)
set_target_properties(glfw PROPERTIES UNITY_BUILD OFF)
set_target_properties(glfw PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC NO)
set(CMAKE_OBJC_FLAGS -fobjc-arc)
add_subdirectory(imgui)
endif()

3597
3party/GL/glcorearb.h Normal file

File diff suppressed because it is too large Load diff

11755
3party/GL/glext.h Normal file

File diff suppressed because it is too large Load diff

926
3party/GL/glxext.h Normal file
View file

@ -0,0 +1,926 @@
#ifndef __glxext_h_
#define __glxext_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2013-2014 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 28198 $ on $Date: 2014-09-18 07:42:14 -0700 (Thu, 18 Sep 2014) $
*/
#define GLX_GLXEXT_VERSION 20140918
/* Generated C header for:
* API: glx
* Versions considered: .*
* Versions emitted: 1\.[3-9]
* Default extensions included: glx
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef GLX_VERSION_1_3
#define GLX_VERSION_1_3 1
typedef XID GLXContextID;
typedef struct __GLXFBConfigRec *GLXFBConfig;
typedef XID GLXWindow;
typedef XID GLXPbuffer;
#define GLX_WINDOW_BIT 0x00000001
#define GLX_PIXMAP_BIT 0x00000002
#define GLX_PBUFFER_BIT 0x00000004
#define GLX_RGBA_BIT 0x00000001
#define GLX_COLOR_INDEX_BIT 0x00000002
#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
#define GLX_AUX_BUFFERS_BIT 0x00000010
#define GLX_DEPTH_BUFFER_BIT 0x00000020
#define GLX_STENCIL_BUFFER_BIT 0x00000040
#define GLX_ACCUM_BUFFER_BIT 0x00000080
#define GLX_CONFIG_CAVEAT 0x20
#define GLX_X_VISUAL_TYPE 0x22
#define GLX_TRANSPARENT_TYPE 0x23
#define GLX_TRANSPARENT_INDEX_VALUE 0x24
#define GLX_TRANSPARENT_RED_VALUE 0x25
#define GLX_TRANSPARENT_GREEN_VALUE 0x26
#define GLX_TRANSPARENT_BLUE_VALUE 0x27
#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
#define GLX_DONT_CARE 0xFFFFFFFF
#define GLX_NONE 0x8000
#define GLX_SLOW_CONFIG 0x8001
#define GLX_TRUE_COLOR 0x8002
#define GLX_DIRECT_COLOR 0x8003
#define GLX_PSEUDO_COLOR 0x8004
#define GLX_STATIC_COLOR 0x8005
#define GLX_GRAY_SCALE 0x8006
#define GLX_STATIC_GRAY 0x8007
#define GLX_TRANSPARENT_RGB 0x8008
#define GLX_TRANSPARENT_INDEX 0x8009
#define GLX_VISUAL_ID 0x800B
#define GLX_SCREEN 0x800C
#define GLX_NON_CONFORMANT_CONFIG 0x800D
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_X_RENDERABLE 0x8012
#define GLX_FBCONFIG_ID 0x8013
#define GLX_RGBA_TYPE 0x8014
#define GLX_COLOR_INDEX_TYPE 0x8015
#define GLX_MAX_PBUFFER_WIDTH 0x8016
#define GLX_MAX_PBUFFER_HEIGHT 0x8017
#define GLX_MAX_PBUFFER_PIXELS 0x8018
#define GLX_PRESERVED_CONTENTS 0x801B
#define GLX_LARGEST_PBUFFER 0x801C
#define GLX_WIDTH 0x801D
#define GLX_HEIGHT 0x801E
#define GLX_EVENT_MASK 0x801F
#define GLX_DAMAGED 0x8020
#define GLX_SAVED 0x8021
#define GLX_WINDOW 0x8022
#define GLX_PBUFFER 0x8023
#define GLX_PBUFFER_HEIGHT 0x8040
#define GLX_PBUFFER_WIDTH 0x8041
typedef GLXFBConfig *( *PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements);
typedef GLXFBConfig *( *PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
typedef int ( *PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
typedef GLXWindow ( *PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
typedef void ( *PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win);
typedef GLXPixmap ( *PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
typedef void ( *PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
typedef GLXPbuffer ( *PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
typedef void ( *PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
typedef void ( *PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
typedef GLXContext ( *PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
typedef Bool ( *PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLEPROC) (void);
typedef int ( *PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value);
typedef void ( *PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask);
typedef void ( *PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXFBConfig *glXGetFBConfigs (Display *dpy, int screen, int *nelements);
GLXFBConfig *glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements);
int glXGetFBConfigAttrib (Display *dpy, GLXFBConfig config, int attribute, int *value);
XVisualInfo *glXGetVisualFromFBConfig (Display *dpy, GLXFBConfig config);
GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
void glXDestroyWindow (Display *dpy, GLXWindow win);
GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
void glXDestroyPixmap (Display *dpy, GLXPixmap pixmap);
GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list);
void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf);
void glXQueryDrawable (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
GLXContext glXCreateNewContext (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
Bool glXMakeContextCurrent (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
GLXDrawable glXGetCurrentReadDrawable (void);
int glXQueryContext (Display *dpy, GLXContext ctx, int attribute, int *value);
void glXSelectEvent (Display *dpy, GLXDrawable draw, unsigned long event_mask);
void glXGetSelectedEvent (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
#endif
#endif /* GLX_VERSION_1_3 */
#ifndef GLX_VERSION_1_4
#define GLX_VERSION_1_4 1
typedef void ( *__GLXextFuncPtr)(void);
#define GLX_SAMPLE_BUFFERS 100000
#define GLX_SAMPLES 100001
typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName);
#ifdef GLX_GLXEXT_PROTOTYPES
__GLXextFuncPtr glXGetProcAddress (const GLubyte *procName);
#endif
#endif /* GLX_VERSION_1_4 */
#ifndef GLX_ARB_context_flush_control
#define GLX_ARB_context_flush_control 1
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#endif /* GLX_ARB_context_flush_control */
#ifndef GLX_ARB_create_context
#define GLX_ARB_create_context 1
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_CONTEXT_FLAGS_ARB 0x2094
typedef GLXContext ( *PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXContext glXCreateContextAttribsARB (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
#endif
#endif /* GLX_ARB_create_context */
#ifndef GLX_ARB_create_context_profile
#define GLX_ARB_create_context_profile 1
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
#endif /* GLX_ARB_create_context_profile */
#ifndef GLX_ARB_create_context_robustness
#define GLX_ARB_create_context_robustness 1
#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
#endif /* GLX_ARB_create_context_robustness */
#ifndef GLX_ARB_fbconfig_float
#define GLX_ARB_fbconfig_float 1
#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9
#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
#endif /* GLX_ARB_fbconfig_float */
#ifndef GLX_ARB_framebuffer_sRGB
#define GLX_ARB_framebuffer_sRGB 1
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
#endif /* GLX_ARB_framebuffer_sRGB */
#ifndef GLX_ARB_get_proc_address
#define GLX_ARB_get_proc_address 1
typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName);
#ifdef GLX_GLXEXT_PROTOTYPES
__GLXextFuncPtr glXGetProcAddressARB (const GLubyte *procName);
#endif
#endif /* GLX_ARB_get_proc_address */
#ifndef GLX_ARB_multisample
#define GLX_ARB_multisample 1
#define GLX_SAMPLE_BUFFERS_ARB 100000
#define GLX_SAMPLES_ARB 100001
#endif /* GLX_ARB_multisample */
#ifndef GLX_ARB_robustness_application_isolation
#define GLX_ARB_robustness_application_isolation 1
#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
#endif /* GLX_ARB_robustness_application_isolation */
#ifndef GLX_ARB_robustness_share_group_isolation
#define GLX_ARB_robustness_share_group_isolation 1
#endif /* GLX_ARB_robustness_share_group_isolation */
#ifndef GLX_ARB_vertex_buffer_object
#define GLX_ARB_vertex_buffer_object 1
#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
#endif /* GLX_ARB_vertex_buffer_object */
#ifndef GLX_3DFX_multisample
#define GLX_3DFX_multisample 1
#define GLX_SAMPLE_BUFFERS_3DFX 0x8050
#define GLX_SAMPLES_3DFX 0x8051
#endif /* GLX_3DFX_multisample */
#ifndef GLX_AMD_gpu_association
#define GLX_AMD_gpu_association 1
#define GLX_GPU_VENDOR_AMD 0x1F00
#define GLX_GPU_RENDERER_STRING_AMD 0x1F01
#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
#define GLX_GPU_RAM_AMD 0x21A3
#define GLX_GPU_CLOCK_AMD 0x21A4
#define GLX_GPU_NUM_PIPES_AMD 0x21A5
#define GLX_GPU_NUM_SIMD_AMD 0x21A6
#define GLX_GPU_NUM_RB_AMD 0x21A7
#define GLX_GPU_NUM_SPI_AMD 0x21A8
typedef unsigned int ( *PFNGLXGETGPUIDSAMDPROC) (unsigned int maxCount, unsigned int *ids);
typedef int ( *PFNGLXGETGPUINFOAMDPROC) (unsigned int id, int property, GLenum dataType, unsigned int size, void *data);
typedef unsigned int ( *PFNGLXGETCONTEXTGPUIDAMDPROC) (GLXContext ctx);
typedef GLXContext ( *PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) (unsigned int id, GLXContext share_list);
typedef GLXContext ( *PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (unsigned int id, GLXContext share_context, const int *attribList);
typedef Bool ( *PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) (GLXContext ctx);
typedef Bool ( *PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (GLXContext ctx);
typedef GLXContext ( *PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
typedef void ( *PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#ifdef GLX_GLXEXT_PROTOTYPES
unsigned int glXGetGPUIDsAMD (unsigned int maxCount, unsigned int *ids);
int glXGetGPUInfoAMD (unsigned int id, int property, GLenum dataType, unsigned int size, void *data);
unsigned int glXGetContextGPUIDAMD (GLXContext ctx);
GLXContext glXCreateAssociatedContextAMD (unsigned int id, GLXContext share_list);
GLXContext glXCreateAssociatedContextAttribsAMD (unsigned int id, GLXContext share_context, const int *attribList);
Bool glXDeleteAssociatedContextAMD (GLXContext ctx);
Bool glXMakeAssociatedContextCurrentAMD (GLXContext ctx);
GLXContext glXGetCurrentAssociatedContextAMD (void);
void glXBlitContextFramebufferAMD (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif
#endif /* GLX_AMD_gpu_association */
#ifndef GLX_EXT_buffer_age
#define GLX_EXT_buffer_age 1
#define GLX_BACK_BUFFER_AGE_EXT 0x20F4
#endif /* GLX_EXT_buffer_age */
#ifndef GLX_EXT_create_context_es2_profile
#define GLX_EXT_create_context_es2_profile 1
#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif /* GLX_EXT_create_context_es2_profile */
#ifndef GLX_EXT_create_context_es_profile
#define GLX_EXT_create_context_es_profile 1
#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
#endif /* GLX_EXT_create_context_es_profile */
#ifndef GLX_EXT_fbconfig_packed_float
#define GLX_EXT_fbconfig_packed_float 1
#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008
#endif /* GLX_EXT_fbconfig_packed_float */
#ifndef GLX_EXT_framebuffer_sRGB
#define GLX_EXT_framebuffer_sRGB 1
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
#endif /* GLX_EXT_framebuffer_sRGB */
#ifndef GLX_EXT_import_context
#define GLX_EXT_import_context 1
#define GLX_SHARE_CONTEXT_EXT 0x800A
#define GLX_VISUAL_ID_EXT 0x800B
#define GLX_SCREEN_EXT 0x800C
typedef Display *( *PFNGLXGETCURRENTDISPLAYEXTPROC) (void);
typedef int ( *PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value);
typedef GLXContextID ( *PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context);
typedef GLXContext ( *PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID);
typedef void ( *PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context);
#ifdef GLX_GLXEXT_PROTOTYPES
Display *glXGetCurrentDisplayEXT (void);
int glXQueryContextInfoEXT (Display *dpy, GLXContext context, int attribute, int *value);
GLXContextID glXGetContextIDEXT (const GLXContext context);
GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID);
void glXFreeContextEXT (Display *dpy, GLXContext context);
#endif
#endif /* GLX_EXT_import_context */
#ifndef GLX_EXT_stereo_tree
#define GLX_EXT_stereo_tree 1
typedef struct {
int type;
unsigned long serial;
Bool send_event;
Display *display;
int extension;
int evtype;
GLXDrawable window;
Bool stereo_tree;
} GLXStereoNotifyEventEXT;
#define GLX_STEREO_TREE_EXT 0x20F5
#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001
#define GLX_STEREO_NOTIFY_EXT 0x00000000
#endif /* GLX_EXT_stereo_tree */
#ifndef GLX_EXT_swap_control
#define GLX_EXT_swap_control 1
#define GLX_SWAP_INTERVAL_EXT 0x20F1
#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
typedef void ( *PFNGLXSWAPINTERVALEXTPROC) (Display *dpy, GLXDrawable drawable, int interval);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXSwapIntervalEXT (Display *dpy, GLXDrawable drawable, int interval);
#endif
#endif /* GLX_EXT_swap_control */
#ifndef GLX_EXT_swap_control_tear
#define GLX_EXT_swap_control_tear 1
#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
#endif /* GLX_EXT_swap_control_tear */
#ifndef GLX_EXT_texture_from_pixmap
#define GLX_EXT_texture_from_pixmap 1
#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
#define GLX_Y_INVERTED_EXT 0x20D4
#define GLX_TEXTURE_FORMAT_EXT 0x20D5
#define GLX_TEXTURE_TARGET_EXT 0x20D6
#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
#define GLX_TEXTURE_1D_EXT 0x20DB
#define GLX_TEXTURE_2D_EXT 0x20DC
#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
#define GLX_FRONT_LEFT_EXT 0x20DE
#define GLX_FRONT_RIGHT_EXT 0x20DF
#define GLX_BACK_LEFT_EXT 0x20E0
#define GLX_BACK_RIGHT_EXT 0x20E1
#define GLX_FRONT_EXT 0x20DE
#define GLX_BACK_EXT 0x20E0
#define GLX_AUX0_EXT 0x20E2
#define GLX_AUX1_EXT 0x20E3
#define GLX_AUX2_EXT 0x20E4
#define GLX_AUX3_EXT 0x20E5
#define GLX_AUX4_EXT 0x20E6
#define GLX_AUX5_EXT 0x20E7
#define GLX_AUX6_EXT 0x20E8
#define GLX_AUX7_EXT 0x20E9
#define GLX_AUX8_EXT 0x20EA
#define GLX_AUX9_EXT 0x20EB
typedef void ( *PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
typedef void ( *PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXBindTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
void glXReleaseTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer);
#endif
#endif /* GLX_EXT_texture_from_pixmap */
#ifndef GLX_EXT_visual_info
#define GLX_EXT_visual_info 1
#define GLX_X_VISUAL_TYPE_EXT 0x22
#define GLX_TRANSPARENT_TYPE_EXT 0x23
#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24
#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25
#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26
#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27
#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28
#define GLX_NONE_EXT 0x8000
#define GLX_TRUE_COLOR_EXT 0x8002
#define GLX_DIRECT_COLOR_EXT 0x8003
#define GLX_PSEUDO_COLOR_EXT 0x8004
#define GLX_STATIC_COLOR_EXT 0x8005
#define GLX_GRAY_SCALE_EXT 0x8006
#define GLX_STATIC_GRAY_EXT 0x8007
#define GLX_TRANSPARENT_RGB_EXT 0x8008
#define GLX_TRANSPARENT_INDEX_EXT 0x8009
#endif /* GLX_EXT_visual_info */
#ifndef GLX_EXT_visual_rating
#define GLX_EXT_visual_rating 1
#define GLX_VISUAL_CAVEAT_EXT 0x20
#define GLX_SLOW_VISUAL_EXT 0x8001
#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
#endif /* GLX_EXT_visual_rating */
#ifndef GLX_INTEL_swap_event
#define GLX_INTEL_swap_event 1
#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000
#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180
#define GLX_COPY_COMPLETE_INTEL 0x8181
#define GLX_FLIP_COMPLETE_INTEL 0x8182
#endif /* GLX_INTEL_swap_event */
#ifndef GLX_MESA_agp_offset
#define GLX_MESA_agp_offset 1
typedef unsigned int ( *PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer);
#ifdef GLX_GLXEXT_PROTOTYPES
unsigned int glXGetAGPOffsetMESA (const void *pointer);
#endif
#endif /* GLX_MESA_agp_offset */
#ifndef GLX_MESA_copy_sub_buffer
#define GLX_MESA_copy_sub_buffer 1
typedef void ( *PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXCopySubBufferMESA (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
#endif
#endif /* GLX_MESA_copy_sub_buffer */
#ifndef GLX_MESA_pixmap_colormap
#define GLX_MESA_pixmap_colormap 1
typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXPixmap glXCreateGLXPixmapMESA (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
#endif
#endif /* GLX_MESA_pixmap_colormap */
#ifndef GLX_MESA_query_renderer
#define GLX_MESA_query_renderer 1
#define GLX_RENDERER_VENDOR_ID_MESA 0x8183
#define GLX_RENDERER_DEVICE_ID_MESA 0x8184
#define GLX_RENDERER_VERSION_MESA 0x8185
#define GLX_RENDERER_ACCELERATED_MESA 0x8186
#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187
#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188
#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189
#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A
#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B
#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C
#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D
#define GLX_RENDERER_ID_MESA 0x818E
typedef Bool ( *PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int *value);
typedef const char *( *PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute);
typedef Bool ( *PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
typedef const char *( *PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXQueryCurrentRendererIntegerMESA (int attribute, unsigned int *value);
const char *glXQueryCurrentRendererStringMESA (int attribute);
Bool glXQueryRendererIntegerMESA (Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
const char *glXQueryRendererStringMESA (Display *dpy, int screen, int renderer, int attribute);
#endif
#endif /* GLX_MESA_query_renderer */
#ifndef GLX_MESA_release_buffers
#define GLX_MESA_release_buffers 1
typedef Bool ( *PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXReleaseBuffersMESA (Display *dpy, GLXDrawable drawable);
#endif
#endif /* GLX_MESA_release_buffers */
#ifndef GLX_MESA_set_3dfx_mode
#define GLX_MESA_set_3dfx_mode 1
#define GLX_3DFX_WINDOW_MODE_MESA 0x1
#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2
typedef Bool ( *PFNGLXSET3DFXMODEMESAPROC) (int mode);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXSet3DfxModeMESA (int mode);
#endif
#endif /* GLX_MESA_set_3dfx_mode */
#ifndef GLX_NV_copy_buffer
#define GLX_NV_copy_buffer 1
typedef void ( *PFNGLXCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
typedef void ( *PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
void glXNamedCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
#endif
#endif /* GLX_NV_copy_buffer */
#ifndef GLX_NV_copy_image
#define GLX_NV_copy_image 1
typedef void ( *PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXCopyImageSubDataNV (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif
#endif /* GLX_NV_copy_image */
#ifndef GLX_NV_delay_before_swap
#define GLX_NV_delay_before_swap 1
typedef Bool ( *PFNGLXDELAYBEFORESWAPNVPROC) (Display *dpy, GLXDrawable drawable, GLfloat seconds);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXDelayBeforeSwapNV (Display *dpy, GLXDrawable drawable, GLfloat seconds);
#endif
#endif /* GLX_NV_delay_before_swap */
#ifndef GLX_NV_float_buffer
#define GLX_NV_float_buffer 1
#define GLX_FLOAT_COMPONENTS_NV 0x20B0
#endif /* GLX_NV_float_buffer */
#ifndef GLX_NV_multisample_coverage
#define GLX_NV_multisample_coverage 1
#define GLX_COVERAGE_SAMPLES_NV 100001
#define GLX_COLOR_SAMPLES_NV 0x20B3
#endif /* GLX_NV_multisample_coverage */
#ifndef GLX_NV_present_video
#define GLX_NV_present_video 1
#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0
typedef unsigned int *( *PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements);
typedef int ( *PFNGLXBINDVIDEODEVICENVPROC) (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
#ifdef GLX_GLXEXT_PROTOTYPES
unsigned int *glXEnumerateVideoDevicesNV (Display *dpy, int screen, int *nelements);
int glXBindVideoDeviceNV (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
#endif
#endif /* GLX_NV_present_video */
#ifndef GLX_NV_swap_group
#define GLX_NV_swap_group 1
typedef Bool ( *PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint group);
typedef Bool ( *PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, GLuint group, GLuint barrier);
typedef Bool ( *PFNGLXQUERYSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
typedef Bool ( *PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
typedef Bool ( *PFNGLXQUERYFRAMECOUNTNVPROC) (Display *dpy, int screen, GLuint *count);
typedef Bool ( *PFNGLXRESETFRAMECOUNTNVPROC) (Display *dpy, int screen);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXJoinSwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint group);
Bool glXBindSwapBarrierNV (Display *dpy, GLuint group, GLuint barrier);
Bool glXQuerySwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
Bool glXQueryMaxSwapGroupsNV (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
Bool glXQueryFrameCountNV (Display *dpy, int screen, GLuint *count);
Bool glXResetFrameCountNV (Display *dpy, int screen);
#endif
#endif /* GLX_NV_swap_group */
#ifndef GLX_NV_video_capture
#define GLX_NV_video_capture 1
typedef XID GLXVideoCaptureDeviceNV;
#define GLX_DEVICE_ID_NV 0x20CD
#define GLX_UNIQUE_ID_NV 0x20CE
#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
typedef int ( *PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
typedef GLXVideoCaptureDeviceNV *( *PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display *dpy, int screen, int *nelements);
typedef void ( *PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
typedef int ( *PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
typedef void ( *PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXBindVideoCaptureDeviceNV (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
GLXVideoCaptureDeviceNV *glXEnumerateVideoCaptureDevicesNV (Display *dpy, int screen, int *nelements);
void glXLockVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device);
int glXQueryVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
void glXReleaseVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device);
#endif
#endif /* GLX_NV_video_capture */
#ifndef GLX_NV_video_out
#define GLX_NV_video_out 1
typedef unsigned int GLXVideoDeviceNV;
#define GLX_VIDEO_OUT_COLOR_NV 0x20C3
#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4
#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5
#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
#define GLX_VIDEO_OUT_FRAME_NV 0x20C8
#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9
#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA
#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB
#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC
typedef int ( *PFNGLXGETVIDEODEVICENVPROC) (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
typedef int ( *PFNGLXRELEASEVIDEODEVICENVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
typedef int ( *PFNGLXBINDVIDEOIMAGENVPROC) (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
typedef int ( *PFNGLXRELEASEVIDEOIMAGENVPROC) (Display *dpy, GLXPbuffer pbuf);
typedef int ( *PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
typedef int ( *PFNGLXGETVIDEOINFONVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXGetVideoDeviceNV (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
int glXReleaseVideoDeviceNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
int glXBindVideoImageNV (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
int glXReleaseVideoImageNV (Display *dpy, GLXPbuffer pbuf);
int glXSendPbufferToVideoNV (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
int glXGetVideoInfoNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#endif /* GLX_NV_video_out */
#ifndef GLX_OML_swap_method
#define GLX_OML_swap_method 1
#define GLX_SWAP_METHOD_OML 0x8060
#define GLX_SWAP_EXCHANGE_OML 0x8061
#define GLX_SWAP_COPY_OML 0x8062
#define GLX_SWAP_UNDEFINED_OML 0x8063
#endif /* GLX_OML_swap_method */
#ifndef GLX_OML_sync_control
#define GLX_OML_sync_control 1
#ifndef GLEXT_64_TYPES_DEFINED
/* This code block is duplicated in glext.h, so must be protected */
#define GLEXT_64_TYPES_DEFINED
/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
/* (as used in the GLX_OML_sync_control extension). */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#include <inttypes.h>
#elif defined(__sun__) || defined(__digital__)
#include <inttypes.h>
#if defined(__STDC__)
#if defined(__arch64__) || defined(_LP64)
typedef long int int64_t;
typedef unsigned long int uint64_t;
#else
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
#endif /* __arch64__ */
#endif /* __STDC__ */
#elif defined( __VMS ) || defined(__sgi)
#include <inttypes.h>
#elif defined(__SCO__) || defined(__USLC__)
#include <stdint.h>
#elif defined(__UNIXOS2__) || defined(__SOL64__)
typedef long int int32_t;
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
#elif defined(_WIN32) && defined(__GNUC__)
#include <stdint.h>
#elif defined(_WIN32)
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
/* Fallback if nothing above works */
#include <inttypes.h>
#endif
#endif
typedef Bool ( *PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
typedef Bool ( *PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
typedef int64_t ( *PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
typedef Bool ( *PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
typedef Bool ( *PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXGetSyncValuesOML (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
Bool glXGetMscRateOML (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
int64_t glXSwapBuffersMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
Bool glXWaitForMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
Bool glXWaitForSbcOML (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
#endif
#endif /* GLX_OML_sync_control */
#ifndef GLX_SGIS_blended_overlay
#define GLX_SGIS_blended_overlay 1
#define GLX_BLENDED_RGBA_SGIS 0x8025
#endif /* GLX_SGIS_blended_overlay */
#ifndef GLX_SGIS_multisample
#define GLX_SGIS_multisample 1
#define GLX_SAMPLE_BUFFERS_SGIS 100000
#define GLX_SAMPLES_SGIS 100001
#endif /* GLX_SGIS_multisample */
#ifndef GLX_SGIS_shared_multisample
#define GLX_SGIS_shared_multisample 1
#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026
#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027
#endif /* GLX_SGIS_shared_multisample */
#ifndef GLX_SGIX_dmbuffer
#define GLX_SGIX_dmbuffer 1
typedef XID GLXPbufferSGIX;
#ifdef _DM_BUFFER_H_
#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024
typedef Bool ( *PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXAssociateDMPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
#endif
#endif /* _DM_BUFFER_H_ */
#endif /* GLX_SGIX_dmbuffer */
#ifndef GLX_SGIX_fbconfig
#define GLX_SGIX_fbconfig 1
typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
#define GLX_WINDOW_BIT_SGIX 0x00000001
#define GLX_PIXMAP_BIT_SGIX 0x00000002
#define GLX_RGBA_BIT_SGIX 0x00000001
#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002
#define GLX_DRAWABLE_TYPE_SGIX 0x8010
#define GLX_RENDER_TYPE_SGIX 0x8011
#define GLX_X_RENDERABLE_SGIX 0x8012
#define GLX_FBCONFIG_ID_SGIX 0x8013
#define GLX_RGBA_TYPE_SGIX 0x8014
#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015
typedef int ( *PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
typedef GLXFBConfigSGIX *( *PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements);
typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
typedef GLXContext ( *PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config);
typedef GLXFBConfigSGIX ( *PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXGetFBConfigAttribSGIX (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
GLXFBConfigSGIX *glXChooseFBConfigSGIX (Display *dpy, int screen, int *attrib_list, int *nelements);
GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
GLXContext glXCreateContextWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
XVisualInfo *glXGetVisualFromFBConfigSGIX (Display *dpy, GLXFBConfigSGIX config);
GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *dpy, XVisualInfo *vis);
#endif
#endif /* GLX_SGIX_fbconfig */
#ifndef GLX_SGIX_hyperpipe
#define GLX_SGIX_hyperpipe 1
typedef struct {
char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int networkId;
} GLXHyperpipeNetworkSGIX;
typedef struct {
char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int channel;
unsigned int participationType;
int timeSlice;
} GLXHyperpipeConfigSGIX;
typedef struct {
char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int srcXOrigin, srcYOrigin, srcWidth, srcHeight;
int destXOrigin, destYOrigin, destWidth, destHeight;
} GLXPipeRect;
typedef struct {
char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
int XOrigin, YOrigin, maxHeight, maxWidth;
} GLXPipeRectLimits;
#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80
#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91
#define GLX_BAD_HYPERPIPE_SGIX 92
#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001
#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002
#define GLX_PIPE_RECT_SGIX 0x00000001
#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002
#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003
#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004
#define GLX_HYPERPIPE_ID_SGIX 0x8030
typedef GLXHyperpipeNetworkSGIX *( *PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes);
typedef int ( *PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
typedef GLXHyperpipeConfigSGIX *( *PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes);
typedef int ( *PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId);
typedef int ( *PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId);
typedef int ( *PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
typedef int ( *PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
typedef int ( *PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXHyperpipeNetworkSGIX *glXQueryHyperpipeNetworkSGIX (Display *dpy, int *npipes);
int glXHyperpipeConfigSGIX (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
GLXHyperpipeConfigSGIX *glXQueryHyperpipeConfigSGIX (Display *dpy, int hpId, int *npipes);
int glXDestroyHyperpipeConfigSGIX (Display *dpy, int hpId);
int glXBindHyperpipeSGIX (Display *dpy, int hpId);
int glXQueryHyperpipeBestAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
int glXHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
int glXQueryHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
#endif
#endif /* GLX_SGIX_hyperpipe */
#ifndef GLX_SGIX_pbuffer
#define GLX_SGIX_pbuffer 1
#define GLX_PBUFFER_BIT_SGIX 0x00000004
#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000
#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001
#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002
#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004
#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008
#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010
#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020
#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040
#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080
#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100
#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016
#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017
#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018
#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019
#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
#define GLX_PRESERVED_CONTENTS_SGIX 0x801B
#define GLX_LARGEST_PBUFFER_SGIX 0x801C
#define GLX_WIDTH_SGIX 0x801D
#define GLX_HEIGHT_SGIX 0x801E
#define GLX_EVENT_MASK_SGIX 0x801F
#define GLX_DAMAGED_SGIX 0x8020
#define GLX_SAVED_SGIX 0x8021
#define GLX_WINDOW_SGIX 0x8022
#define GLX_PBUFFER_SGIX 0x8023
typedef GLXPbufferSGIX ( *PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
typedef void ( *PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf);
typedef int ( *PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
typedef void ( *PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask);
typedef void ( *PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
void glXDestroyGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf);
int glXQueryGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
void glXSelectEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long mask);
void glXGetSelectedEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long *mask);
#endif
#endif /* GLX_SGIX_pbuffer */
#ifndef GLX_SGIX_swap_barrier
#define GLX_SGIX_swap_barrier 1
typedef void ( *PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier);
typedef Bool ( *PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXBindSwapBarrierSGIX (Display *dpy, GLXDrawable drawable, int barrier);
Bool glXQueryMaxSwapBarriersSGIX (Display *dpy, int screen, int *max);
#endif
#endif /* GLX_SGIX_swap_barrier */
#ifndef GLX_SGIX_swap_group
#define GLX_SGIX_swap_group 1
typedef void ( *PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXJoinSwapGroupSGIX (Display *dpy, GLXDrawable drawable, GLXDrawable member);
#endif
#endif /* GLX_SGIX_swap_group */
#ifndef GLX_SGIX_video_resize
#define GLX_SGIX_video_resize 1
#define GLX_SYNC_FRAME_SGIX 0x00000000
#define GLX_SYNC_SWAP_SGIX 0x00000001
typedef int ( *PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window);
typedef int ( *PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h);
typedef int ( *PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
typedef int ( *PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
typedef int ( *PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXBindChannelToWindowSGIX (Display *display, int screen, int channel, Window window);
int glXChannelRectSGIX (Display *display, int screen, int channel, int x, int y, int w, int h);
int glXQueryChannelRectSGIX (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
int glXQueryChannelDeltasSGIX (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
int glXChannelRectSyncSGIX (Display *display, int screen, int channel, GLenum synctype);
#endif
#endif /* GLX_SGIX_video_resize */
#ifndef GLX_SGIX_video_source
#define GLX_SGIX_video_source 1
typedef XID GLXVideoSourceSGIX;
#ifdef _VL_H
typedef GLXVideoSourceSGIX ( *PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
typedef void ( *PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource);
#ifdef GLX_GLXEXT_PROTOTYPES
GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
void glXDestroyGLXVideoSourceSGIX (Display *dpy, GLXVideoSourceSGIX glxvideosource);
#endif
#endif /* _VL_H */
#endif /* GLX_SGIX_video_source */
#ifndef GLX_SGIX_visual_select_group
#define GLX_SGIX_visual_select_group 1
#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028
#endif /* GLX_SGIX_visual_select_group */
#ifndef GLX_SGI_cushion
#define GLX_SGI_cushion 1
typedef void ( *PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion);
#ifdef GLX_GLXEXT_PROTOTYPES
void glXCushionSGI (Display *dpy, Window window, float cushion);
#endif
#endif /* GLX_SGI_cushion */
#ifndef GLX_SGI_make_current_read
#define GLX_SGI_make_current_read 1
typedef Bool ( *PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void);
#ifdef GLX_GLXEXT_PROTOTYPES
Bool glXMakeCurrentReadSGI (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
GLXDrawable glXGetCurrentReadDrawableSGI (void);
#endif
#endif /* GLX_SGI_make_current_read */
#ifndef GLX_SGI_swap_control
#define GLX_SGI_swap_control 1
typedef int ( *PFNGLXSWAPINTERVALSGIPROC) (int interval);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXSwapIntervalSGI (int interval);
#endif
#endif /* GLX_SGI_swap_control */
#ifndef GLX_SGI_video_sync
#define GLX_SGI_video_sync 1
typedef int ( *PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count);
typedef int ( *PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count);
#ifdef GLX_GLXEXT_PROTOTYPES
int glXGetVideoSyncSGI (unsigned int *count);
int glXWaitVideoSyncSGI (int divisor, int remainder, unsigned int *count);
#endif
#endif /* GLX_SGI_video_sync */
#ifndef GLX_SUN_get_transparent_index
#define GLX_SUN_get_transparent_index 1
typedef Status ( *PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex);
#ifdef GLX_GLXEXT_PROTOTYPES
Status glXGetTransparentIndexSUN (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex);
#endif
#endif /* GLX_SUN_get_transparent_index */
#ifdef __cplusplus
}
#endif
#endif

840
3party/GL/wglext.h Normal file
View file

@ -0,0 +1,840 @@
#ifndef __wglext_h_
#define __wglext_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2013-2014 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $
*/
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#define WGL_WGLEXT_VERSION 20140810
/* Generated C header for:
* API: wgl
* Versions considered: .*
* Versions emitted: _nomatch_^
* Default extensions included: wgl
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef WGL_ARB_buffer_region
#define WGL_ARB_buffer_region 1
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#ifdef WGL_WGLEXT_PROTOTYPES
HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#endif
#endif /* WGL_ARB_buffer_region */
#ifndef WGL_ARB_context_flush_control
#define WGL_ARB_context_flush_control 1
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#endif /* WGL_ARB_context_flush_control */
#ifndef WGL_ARB_create_context
#define WGL_ARB_create_context 1
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define ERROR_INVALID_VERSION_ARB 0x2095
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
#ifdef WGL_WGLEXT_PROTOTYPES
HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
#endif
#endif /* WGL_ARB_create_context */
#ifndef WGL_ARB_create_context_profile
#define WGL_ARB_create_context_profile 1
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define ERROR_INVALID_PROFILE_ARB 0x2096
#endif /* WGL_ARB_create_context_profile */
#ifndef WGL_ARB_create_context_robustness
#define WGL_ARB_create_context_robustness 1
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#endif /* WGL_ARB_create_context_robustness */
#ifndef WGL_ARB_extensions_string
#define WGL_ARB_extensions_string 1
typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
#ifdef WGL_WGLEXT_PROTOTYPES
const char *WINAPI wglGetExtensionsStringARB (HDC hdc);
#endif
#endif /* WGL_ARB_extensions_string */
#ifndef WGL_ARB_framebuffer_sRGB
#define WGL_ARB_framebuffer_sRGB 1
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
#endif /* WGL_ARB_framebuffer_sRGB */
#ifndef WGL_ARB_make_current_read
#define WGL_ARB_make_current_read 1
#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
HDC WINAPI wglGetCurrentReadDCARB (void);
#endif
#endif /* WGL_ARB_make_current_read */
#ifndef WGL_ARB_multisample
#define WGL_ARB_multisample 1
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
#endif /* WGL_ARB_multisample */
#ifndef WGL_ARB_pbuffer
#define WGL_ARB_pbuffer 1
DECLARE_HANDLE(HPBUFFERARB);
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
#define WGL_PBUFFER_LARGEST_ARB 0x2033
#define WGL_PBUFFER_WIDTH_ARB 0x2034
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
#define WGL_PBUFFER_LOST_ARB 0x2036
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#endif
#endif /* WGL_ARB_pbuffer */
#ifndef WGL_ARB_pixel_format
#define WGL_ARB_pixel_format 1
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#endif /* WGL_ARB_pixel_format */
#ifndef WGL_ARB_pixel_format_float
#define WGL_ARB_pixel_format_float 1
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif /* WGL_ARB_pixel_format_float */
#ifndef WGL_ARB_render_texture
#define WGL_ARB_render_texture 1
#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
#define WGL_TEXTURE_FORMAT_ARB 0x2072
#define WGL_TEXTURE_TARGET_ARB 0x2073
#define WGL_MIPMAP_TEXTURE_ARB 0x2074
#define WGL_TEXTURE_RGB_ARB 0x2075
#define WGL_TEXTURE_RGBA_ARB 0x2076
#define WGL_NO_TEXTURE_ARB 0x2077
#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
#define WGL_TEXTURE_1D_ARB 0x2079
#define WGL_TEXTURE_2D_ARB 0x207A
#define WGL_MIPMAP_LEVEL_ARB 0x207B
#define WGL_CUBE_MAP_FACE_ARB 0x207C
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
#define WGL_FRONT_LEFT_ARB 0x2083
#define WGL_FRONT_RIGHT_ARB 0x2084
#define WGL_BACK_LEFT_ARB 0x2085
#define WGL_BACK_RIGHT_ARB 0x2086
#define WGL_AUX0_ARB 0x2087
#define WGL_AUX1_ARB 0x2088
#define WGL_AUX2_ARB 0x2089
#define WGL_AUX3_ARB 0x208A
#define WGL_AUX4_ARB 0x208B
#define WGL_AUX5_ARB 0x208C
#define WGL_AUX6_ARB 0x208D
#define WGL_AUX7_ARB 0x208E
#define WGL_AUX8_ARB 0x208F
#define WGL_AUX9_ARB 0x2090
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
#endif
#endif /* WGL_ARB_render_texture */
#ifndef WGL_ARB_robustness_application_isolation
#define WGL_ARB_robustness_application_isolation 1
#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
#endif /* WGL_ARB_robustness_application_isolation */
#ifndef WGL_ARB_robustness_share_group_isolation
#define WGL_ARB_robustness_share_group_isolation 1
#endif /* WGL_ARB_robustness_share_group_isolation */
#ifndef WGL_3DFX_multisample
#define WGL_3DFX_multisample 1
#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
#define WGL_SAMPLES_3DFX 0x2061
#endif /* WGL_3DFX_multisample */
#ifndef WGL_3DL_stereo_control
#define WGL_3DL_stereo_control 1
#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
#endif
#endif /* WGL_3DL_stereo_control */
#ifndef WGL_AMD_gpu_association
#define WGL_AMD_gpu_association 1
#define WGL_GPU_VENDOR_AMD 0x1F00
#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
#define WGL_GPU_RAM_AMD 0x21A3
#define WGL_GPU_CLOCK_AMD 0x21A4
#define WGL_GPU_NUM_PIPES_AMD 0x21A5
#define WGL_GPU_NUM_SIMD_AMD 0x21A6
#define WGL_GPU_NUM_RB_AMD 0x21A7
#define WGL_GPU_NUM_SPI_AMD 0x21A8
typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#ifdef WGL_WGLEXT_PROTOTYPES
UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif
#endif /* WGL_AMD_gpu_association */
#ifndef WGL_ATI_pixel_format_float
#define WGL_ATI_pixel_format_float 1
#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
#endif /* WGL_ATI_pixel_format_float */
#ifndef WGL_EXT_create_context_es2_profile
#define WGL_EXT_create_context_es2_profile 1
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif /* WGL_EXT_create_context_es2_profile */
#ifndef WGL_EXT_create_context_es_profile
#define WGL_EXT_create_context_es_profile 1
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
#endif /* WGL_EXT_create_context_es_profile */
#ifndef WGL_EXT_depth_float
#define WGL_EXT_depth_float 1
#define WGL_DEPTH_FLOAT_EXT 0x2040
#endif /* WGL_EXT_depth_float */
#ifndef WGL_EXT_display_color_table
#define WGL_EXT_display_color_table 1
typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
#ifdef WGL_WGLEXT_PROTOTYPES
GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
#endif
#endif /* WGL_EXT_display_color_table */
#ifndef WGL_EXT_extensions_string
#define WGL_EXT_extensions_string 1
typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
const char *WINAPI wglGetExtensionsStringEXT (void);
#endif
#endif /* WGL_EXT_extensions_string */
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_EXT_framebuffer_sRGB 1
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
#endif /* WGL_EXT_framebuffer_sRGB */
#ifndef WGL_EXT_make_current_read
#define WGL_EXT_make_current_read 1
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
HDC WINAPI wglGetCurrentReadDCEXT (void);
#endif
#endif /* WGL_EXT_make_current_read */
#ifndef WGL_EXT_multisample
#define WGL_EXT_multisample 1
#define WGL_SAMPLE_BUFFERS_EXT 0x2041
#define WGL_SAMPLES_EXT 0x2042
#endif /* WGL_EXT_multisample */
#ifndef WGL_EXT_pbuffer
#define WGL_EXT_pbuffer 1
DECLARE_HANDLE(HPBUFFEREXT);
#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
#define WGL_PBUFFER_LARGEST_EXT 0x2033
#define WGL_PBUFFER_WIDTH_EXT 0x2034
#define WGL_PBUFFER_HEIGHT_EXT 0x2035
typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#endif
#endif /* WGL_EXT_pbuffer */
#ifndef WGL_EXT_pixel_format
#define WGL_EXT_pixel_format 1
#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
#define WGL_DRAW_TO_WINDOW_EXT 0x2001
#define WGL_DRAW_TO_BITMAP_EXT 0x2002
#define WGL_ACCELERATION_EXT 0x2003
#define WGL_NEED_PALETTE_EXT 0x2004
#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
#define WGL_SWAP_METHOD_EXT 0x2007
#define WGL_NUMBER_OVERLAYS_EXT 0x2008
#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
#define WGL_TRANSPARENT_EXT 0x200A
#define WGL_TRANSPARENT_VALUE_EXT 0x200B
#define WGL_SHARE_DEPTH_EXT 0x200C
#define WGL_SHARE_STENCIL_EXT 0x200D
#define WGL_SHARE_ACCUM_EXT 0x200E
#define WGL_SUPPORT_GDI_EXT 0x200F
#define WGL_SUPPORT_OPENGL_EXT 0x2010
#define WGL_DOUBLE_BUFFER_EXT 0x2011
#define WGL_STEREO_EXT 0x2012
#define WGL_PIXEL_TYPE_EXT 0x2013
#define WGL_COLOR_BITS_EXT 0x2014
#define WGL_RED_BITS_EXT 0x2015
#define WGL_RED_SHIFT_EXT 0x2016
#define WGL_GREEN_BITS_EXT 0x2017
#define WGL_GREEN_SHIFT_EXT 0x2018
#define WGL_BLUE_BITS_EXT 0x2019
#define WGL_BLUE_SHIFT_EXT 0x201A
#define WGL_ALPHA_BITS_EXT 0x201B
#define WGL_ALPHA_SHIFT_EXT 0x201C
#define WGL_ACCUM_BITS_EXT 0x201D
#define WGL_ACCUM_RED_BITS_EXT 0x201E
#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
#define WGL_DEPTH_BITS_EXT 0x2022
#define WGL_STENCIL_BITS_EXT 0x2023
#define WGL_AUX_BUFFERS_EXT 0x2024
#define WGL_NO_ACCELERATION_EXT 0x2025
#define WGL_GENERIC_ACCELERATION_EXT 0x2026
#define WGL_FULL_ACCELERATION_EXT 0x2027
#define WGL_SWAP_EXCHANGE_EXT 0x2028
#define WGL_SWAP_COPY_EXT 0x2029
#define WGL_SWAP_UNDEFINED_EXT 0x202A
#define WGL_TYPE_RGBA_EXT 0x202B
#define WGL_TYPE_COLORINDEX_EXT 0x202C
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#endif /* WGL_EXT_pixel_format */
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_EXT_pixel_format_packed_float 1
#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
#endif /* WGL_EXT_pixel_format_packed_float */
#ifndef WGL_EXT_swap_control
#define WGL_EXT_swap_control 1
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglSwapIntervalEXT (int interval);
int WINAPI wglGetSwapIntervalEXT (void);
#endif
#endif /* WGL_EXT_swap_control */
#ifndef WGL_EXT_swap_control_tear
#define WGL_EXT_swap_control_tear 1
#endif /* WGL_EXT_swap_control_tear */
#ifndef WGL_I3D_digital_video_control
#define WGL_I3D_digital_video_control 1
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
#endif
#endif /* WGL_I3D_digital_video_control */
#ifndef WGL_I3D_gamma
#define WGL_I3D_gamma 1
#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#endif
#endif /* WGL_I3D_gamma */
#ifndef WGL_I3D_genlock
#define WGL_I3D_genlock 1
#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045
#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046
#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047
#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#endif
#endif /* WGL_I3D_genlock */
#ifndef WGL_I3D_image_buffer
#define WGL_I3D_image_buffer 1
#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
#ifdef WGL_WGLEXT_PROTOTYPES
LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
#endif
#endif /* WGL_I3D_image_buffer */
#ifndef WGL_I3D_swap_frame_lock
#define WGL_I3D_swap_frame_lock 1
typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnableFrameLockI3D (void);
BOOL WINAPI wglDisableFrameLockI3D (void);
BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
#endif
#endif /* WGL_I3D_swap_frame_lock */
#ifndef WGL_I3D_swap_frame_usage
#define WGL_I3D_swap_frame_usage 1
typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
BOOL WINAPI wglBeginFrameTrackingI3D (void);
BOOL WINAPI wglEndFrameTrackingI3D (void);
BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#endif
#endif /* WGL_I3D_swap_frame_usage */
#ifndef WGL_NV_DX_interop
#define WGL_NV_DX_interop 1
#define WGL_ACCESS_READ_ONLY_NV 0x00000000
#define WGL_ACCESS_READ_WRITE_NV 0x00000001
#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
#endif
#endif /* WGL_NV_DX_interop */
#ifndef WGL_NV_DX_interop2
#define WGL_NV_DX_interop2 1
#endif /* WGL_NV_DX_interop2 */
#ifndef WGL_NV_copy_image
#define WGL_NV_copy_image 1
typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif
#endif /* WGL_NV_copy_image */
#ifndef WGL_NV_delay_before_swap
#define WGL_NV_delay_before_swap 1
typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds);
#endif
#endif /* WGL_NV_delay_before_swap */
#ifndef WGL_NV_float_buffer
#define WGL_NV_float_buffer 1
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
#endif /* WGL_NV_float_buffer */
#ifndef WGL_NV_gpu_affinity
#define WGL_NV_gpu_affinity 1
DECLARE_HANDLE(HGPUNV);
struct _GPU_DEVICE {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD Flags;
RECT rcVirtualScreen;
};
typedef struct _GPU_DEVICE *PGPU_DEVICE;
#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
BOOL WINAPI wglDeleteDCNV (HDC hdc);
#endif
#endif /* WGL_NV_gpu_affinity */
#ifndef WGL_NV_multisample_coverage
#define WGL_NV_multisample_coverage 1
#define WGL_COVERAGE_SAMPLES_NV 0x2042
#define WGL_COLOR_SAMPLES_NV 0x20B9
#endif /* WGL_NV_multisample_coverage */
#ifndef WGL_NV_present_video
#define WGL_NV_present_video 1
DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
#endif
#endif /* WGL_NV_present_video */
#ifndef WGL_NV_render_depth_texture
#define WGL_NV_render_depth_texture 1
#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
#define WGL_DEPTH_COMPONENT_NV 0x20A7
#endif /* WGL_NV_render_depth_texture */
#ifndef WGL_NV_render_texture_rectangle
#define WGL_NV_render_texture_rectangle 1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
#endif /* WGL_NV_render_texture_rectangle */
#ifndef WGL_NV_swap_group
#define WGL_NV_swap_group 1
typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
BOOL WINAPI wglResetFrameCountNV (HDC hDC);
#endif
#endif /* WGL_NV_swap_group */
#ifndef WGL_NV_vertex_array_range
#define WGL_NV_vertex_array_range 1
typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
#ifdef WGL_WGLEXT_PROTOTYPES
void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
void WINAPI wglFreeMemoryNV (void *pointer);
#endif
#endif /* WGL_NV_vertex_array_range */
#ifndef WGL_NV_video_capture
#define WGL_NV_video_capture 1
DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
#define WGL_UNIQUE_ID_NV 0x20CE
#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
#endif
#endif /* WGL_NV_video_capture */
#ifndef WGL_NV_video_output
#define WGL_NV_video_output 1
DECLARE_HANDLE(HPVIDEODEV);
#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
#define WGL_VIDEO_OUT_FRAME 0x20C8
#define WGL_VIDEO_OUT_FIELD_1 0x20C9
#define WGL_VIDEO_OUT_FIELD_2 0x20CA
#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#endif /* WGL_NV_video_output */
#ifndef WGL_OML_sync_control
#define WGL_OML_sync_control 1
typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#endif
#endif /* WGL_OML_sync_control */
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,8 @@
project(agg)
set(SRC
agg_curves.cpp
agg_vcgen_stroke.cpp
)
add_library(${PROJECT_NAME} ${SRC})

View file

@ -0,0 +1,499 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// scanline_u8 class
//
//----------------------------------------------------------------------------
#ifndef AGG_ALPHA_MASK_U8_INCLUDED
#define AGG_ALPHA_MASK_U8_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//===================================================one_component_mask_u8
struct one_component_mask_u8
{
static unsigned calculate(const int8u* p) { return *p; }
};
//=====================================================rgb_to_gray_mask_u8
template<unsigned R, unsigned G, unsigned B>
struct rgb_to_gray_mask_u8
{
static unsigned calculate(const int8u* p)
{
return (p[R]*77 + p[G]*150 + p[B]*29) >> 8;
}
};
//==========================================================alpha_mask_u8
template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
class alpha_mask_u8
{
public:
typedef int8u cover_type;
typedef alpha_mask_u8<Step, Offset, MaskF> self_type;
enum cover_scale_e
{
cover_shift = 8,
cover_none = 0,
cover_full = 255
};
alpha_mask_u8() : m_rbuf(0) {}
explicit alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
MaskF& mask_function() { return m_mask_function; }
const MaskF& mask_function() const { return m_mask_function; }
//--------------------------------------------------------------------
cover_type pixel(int x, int y) const
{
if(x >= 0 && y >= 0 &&
x < (int)m_rbuf->width() &&
y < (int)m_rbuf->height())
{
return (cover_type)m_mask_function.calculate(
m_rbuf->row_ptr(y) + x * Step + Offset);
}
return 0;
}
//--------------------------------------------------------------------
cover_type combine_pixel(int x, int y, cover_type val) const
{
if(x >= 0 && y >= 0 &&
x < (int)m_rbuf->width() &&
y < (int)m_rbuf->height())
{
return (cover_type)((cover_full + val *
m_mask_function.calculate(
m_rbuf->row_ptr(y) + x * Step + Offset)) >>
cover_shift);
}
return 0;
}
//--------------------------------------------------------------------
void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
{
int xmax = m_rbuf->width() - 1;
int ymax = m_rbuf->height() - 1;
int count = num_pix;
cover_type* covers = dst;
if(y < 0 || y > ymax)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
if(x < 0)
{
count += x;
if(count <= 0)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
memset(covers, 0, -x * sizeof(cover_type));
covers -= x;
x = 0;
}
if(x + count > xmax)
{
int rest = x + count - xmax - 1;
count -= rest;
if(count <= 0)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
memset(covers + count, 0, rest * sizeof(cover_type));
}
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers++ = (cover_type)m_mask_function.calculate(mask);
mask += Step;
}
while(--count);
}
//--------------------------------------------------------------------
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
{
int xmax = m_rbuf->width() - 1;
int ymax = m_rbuf->height() - 1;
int count = num_pix;
cover_type* covers = dst;
if(y < 0 || y > ymax)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
if(x < 0)
{
count += x;
if(count <= 0)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
memset(covers, 0, -x * sizeof(cover_type));
covers -= x;
x = 0;
}
if(x + count > xmax)
{
int rest = x + count - xmax - 1;
count -= rest;
if(count <= 0)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
memset(covers + count, 0, rest * sizeof(cover_type));
}
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers = (cover_type)((cover_full + (*covers) *
m_mask_function.calculate(mask)) >>
cover_shift);
++covers;
mask += Step;
}
while(--count);
}
//--------------------------------------------------------------------
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
{
int xmax = m_rbuf->width() - 1;
int ymax = m_rbuf->height() - 1;
int count = num_pix;
cover_type* covers = dst;
if(x < 0 || x > xmax)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
if(y < 0)
{
count += y;
if(count <= 0)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
memset(covers, 0, -y * sizeof(cover_type));
covers -= y;
y = 0;
}
if(y + count > ymax)
{
int rest = y + count - ymax - 1;
count -= rest;
if(count <= 0)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
memset(covers + count, 0, rest * sizeof(cover_type));
}
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers++ = (cover_type)m_mask_function.calculate(mask);
mask += m_rbuf->stride();
}
while(--count);
}
//--------------------------------------------------------------------
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
{
int xmax = m_rbuf->width() - 1;
int ymax = m_rbuf->height() - 1;
int count = num_pix;
cover_type* covers = dst;
if(x < 0 || x > xmax)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
if(y < 0)
{
count += y;
if(count <= 0)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
memset(covers, 0, -y * sizeof(cover_type));
covers -= y;
y = 0;
}
if(y + count > ymax)
{
int rest = y + count - ymax - 1;
count -= rest;
if(count <= 0)
{
memset(dst, 0, num_pix * sizeof(cover_type));
return;
}
memset(covers + count, 0, rest * sizeof(cover_type));
}
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers = (cover_type)((cover_full + (*covers) *
m_mask_function.calculate(mask)) >>
cover_shift);
++covers;
mask += m_rbuf->stride();
}
while(--count);
}
private:
alpha_mask_u8(const self_type&);
const self_type& operator = (const self_type&);
rendering_buffer* m_rbuf;
MaskF m_mask_function;
};
typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8
typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r
typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g
typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b
typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r
typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g
typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b
typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r
typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g
typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b
typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a
typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r
typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g
typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b
typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a
typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r
typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g
typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b
typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a
typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r
typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g
typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b
typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a
typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray
typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray
typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray
typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray
typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray
typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray
//==========================================================amask_no_clip_u8
template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
class amask_no_clip_u8
{
public:
typedef int8u cover_type;
typedef amask_no_clip_u8<Step, Offset, MaskF> self_type;
enum cover_scale_e
{
cover_shift = 8,
cover_none = 0,
cover_full = 255
};
amask_no_clip_u8() : m_rbuf(0) {}
explicit amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
MaskF& mask_function() { return m_mask_function; }
const MaskF& mask_function() const { return m_mask_function; }
//--------------------------------------------------------------------
cover_type pixel(int x, int y) const
{
return (cover_type)m_mask_function.calculate(
m_rbuf->row_ptr(y) + x * Step + Offset);
}
//--------------------------------------------------------------------
cover_type combine_pixel(int x, int y, cover_type val) const
{
return (cover_type)((cover_full + val *
m_mask_function.calculate(
m_rbuf->row_ptr(y) + x * Step + Offset)) >>
cover_shift);
}
//--------------------------------------------------------------------
void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
{
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst++ = (cover_type)m_mask_function.calculate(mask);
mask += Step;
}
while(--num_pix);
}
//--------------------------------------------------------------------
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
{
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst = (cover_type)((cover_full + (*dst) *
m_mask_function.calculate(mask)) >>
cover_shift);
++dst;
mask += Step;
}
while(--num_pix);
}
//--------------------------------------------------------------------
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
{
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst++ = (cover_type)m_mask_function.calculate(mask);
mask += m_rbuf->stride();
}
while(--num_pix);
}
//--------------------------------------------------------------------
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
{
const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst = (cover_type)((cover_full + (*dst) *
m_mask_function.calculate(mask)) >>
cover_shift);
++dst;
mask += m_rbuf->stride();
}
while(--num_pix);
}
private:
amask_no_clip_u8(const self_type&);
const self_type& operator = (const self_type&);
rendering_buffer* m_rbuf;
MaskF m_mask_function;
};
typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8
typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r
typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g
typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b
typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r
typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g
typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b
typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r
typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g
typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b
typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a
typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r
typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g
typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b
typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a
typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r
typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g
typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b
typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a
typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r
typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g
typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b
typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a
typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray
typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray
typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray
typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray
typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray
typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray
}
#endif

74
3party/agg/agg_arc.h Normal file
View file

@ -0,0 +1,74 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Arc vertex generator
//
//----------------------------------------------------------------------------
#ifndef AGG_ARC_INCLUDED
#define AGG_ARC_INCLUDED
#include <math.h>
#include "agg_basics.h"
namespace agg
{
//=====================================================================arc
//
// See Implementation agg_arc.cpp
//
class arc
{
public:
arc() : m_scale(1.0), m_initialized(false) {}
arc(double x, double y,
double rx, double ry,
double a1, double a2,
bool ccw=true);
void init(double x, double y,
double rx, double ry,
double a1, double a2,
bool ccw=true);
void approximation_scale(double s);
double approximation_scale() const { return m_scale; }
void rewind(unsigned);
unsigned vertex(double* x, double* y);
private:
void normalize(double a1, double a2, bool ccw);
double m_x;
double m_y;
double m_rx;
double m_ry;
double m_angle;
double m_start;
double m_end;
double m_scale;
double m_da;
bool m_ccw;
bool m_initialized;
unsigned m_path_cmd;
};
}
#endif

1119
3party/agg/agg_array.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,82 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Simple arrowhead/arrowtail generator
//
//----------------------------------------------------------------------------
#ifndef AGG_ARROWHEAD_INCLUDED
#define AGG_ARROWHEAD_INCLUDED
#include "agg_basics.h"
namespace agg
{
//===============================================================arrowhead
//
// See implementation agg_arrowhead.cpp
//
class arrowhead
{
public:
arrowhead();
void head(double d1, double d2, double d3, double d4)
{
m_head_d1 = d1;
m_head_d2 = d2;
m_head_d3 = d3;
m_head_d4 = d4;
m_head_flag = true;
}
void head() { m_head_flag = true; }
void no_head() { m_head_flag = false; }
void tail(double d1, double d2, double d3, double d4)
{
m_tail_d1 = d1;
m_tail_d2 = d2;
m_tail_d3 = d3;
m_tail_d4 = d4;
m_tail_flag = true;
}
void tail() { m_tail_flag = true; }
void no_tail() { m_tail_flag = false; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
double m_head_d1;
double m_head_d2;
double m_head_d3;
double m_head_d4;
double m_tail_d1;
double m_tail_d2;
double m_tail_d3;
double m_tail_d4;
bool m_head_flag;
bool m_tail_flag;
double m_coord[16];
unsigned m_cmd[8];
unsigned m_curr_id;
unsigned m_curr_coord;
};
}
#endif

535
3party/agg/agg_basics.h Normal file
View file

@ -0,0 +1,535 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_BASICS_INCLUDED
#define AGG_BASICS_INCLUDED
#include <math.h>
#include "agg_config.h"
//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
#ifdef AGG_CUSTOM_ALLOCATOR
#include "agg_allocator.h"
#else
namespace agg
{
// The policy of all AGG containers and memory allocation strategy
// in general is that no allocated data requires explicit construction.
// It means that the allocator can be really simple; you can even
// replace new/delete to malloc/free. The constructors and destructors
// won't be called in this case, however everything will remain working.
// The second argument of deallocate() is the size of the allocated
// block. You can use this information if you wish.
//------------------------------------------------------------pod_allocator
template<class T> struct pod_allocator
{
static T* allocate(unsigned num) { return new T [num]; }
static void deallocate(T* ptr, unsigned) { delete [] ptr; }
};
// Single object allocator. It's also can be replaced with your custom
// allocator. The difference is that it can only allocate a single
// object and the constructor and destructor must be called.
// In AGG there is no need to allocate an array of objects with
// calling their constructors (only single ones). So that, if you
// replace these new/delete to malloc/free make sure that the in-place
// new is called and take care of calling the destructor too.
//------------------------------------------------------------obj_allocator
template<class T> struct obj_allocator
{
static T* allocate() { return new T; }
static void deallocate(T* ptr) { delete ptr; }
};
}
#endif
//-------------------------------------------------------- Default basic types
//
// If the compiler has different capacity of the basic types you can redefine
// them via the compiler command line or by generating agg_config.h that is
// empty by default.
//
#ifndef AGG_INT8
#define AGG_INT8 signed char
#endif
#ifndef AGG_INT8U
#define AGG_INT8U unsigned char
#endif
#ifndef AGG_INT16
#define AGG_INT16 short
#endif
#ifndef AGG_INT16U
#define AGG_INT16U unsigned short
#endif
#ifndef AGG_INT32
#define AGG_INT32 int
#endif
#ifndef AGG_INT32U
#define AGG_INT32U unsigned
#endif
#ifndef AGG_INT64
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define AGG_INT64 signed __int64
#else
#define AGG_INT64 signed long long
#endif
#endif
#ifndef AGG_INT64U
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define AGG_INT64U unsigned __int64
#else
#define AGG_INT64U unsigned long long
#endif
#endif
//------------------------------------------------ Some fixes for MS Visual C++
#if defined(_MSC_VER)
#pragma warning(disable:4786) // Identifier was truncated...
#endif
#if defined(_MSC_VER)
#define AGG_INLINE __forceinline
#else
#define AGG_INLINE inline
#endif
namespace agg
{
//-------------------------------------------------------------------------
typedef AGG_INT8 int8; //----int8
typedef AGG_INT8U int8u; //----int8u
typedef AGG_INT16 int16; //----int16
typedef AGG_INT16U int16u; //----int16u
typedef AGG_INT32 int32; //----int32
typedef AGG_INT32U int32u; //----int32u
typedef AGG_INT64 int64; //----int64
typedef AGG_INT64U int64u; //----int64u
#if defined(AGG_FISTP)
#pragma warning(push)
#pragma warning(disable : 4035) //Disable warning "no return value"
AGG_INLINE int iround(double v) //-------iround
{
int t;
__asm fld qword ptr [v]
__asm fistp dword ptr [t]
__asm mov eax, dword ptr [t]
}
AGG_INLINE unsigned uround(double v) //-------uround
{
unsigned t;
__asm fld qword ptr [v]
__asm fistp dword ptr [t]
__asm mov eax, dword ptr [t]
}
#pragma warning(pop)
AGG_INLINE unsigned ufloor(double v) //-------ufloor
{
return unsigned(floor(v));
}
AGG_INLINE unsigned uceil(double v) //--------uceil
{
return unsigned(ceil(v));
}
#elif defined(AGG_QIFIST)
AGG_INLINE int iround(double v)
{
return int(v);
}
AGG_INLINE int uround(double v)
{
return unsigned(v);
}
AGG_INLINE unsigned ufloor(double v)
{
return unsigned(floor(v));
}
AGG_INLINE unsigned uceil(double v)
{
return unsigned(ceil(v));
}
#else
AGG_INLINE int iround(double v)
{
return int((v < 0.0) ? v - 0.5 : v + 0.5);
}
AGG_INLINE int uround(double v)
{
return unsigned(v + 0.5);
}
AGG_INLINE unsigned ufloor(double v)
{
return unsigned(v);
}
AGG_INLINE unsigned uceil(double v)
{
return unsigned(ceil(v));
}
#endif
//---------------------------------------------------------------saturation
template<int Limit> struct saturation
{
AGG_INLINE static int iround(double v)
{
if(v < double(-Limit)) return -Limit;
if(v > double( Limit)) return Limit;
return agg::iround(v);
}
};
//------------------------------------------------------------------mul_one
template<unsigned Shift> struct mul_one
{
AGG_INLINE static unsigned mul(unsigned a, unsigned b)
{
unsigned q = a * b + (1 << (Shift-1));
return (q + (q >> Shift)) >> Shift;
}
};
//-------------------------------------------------------------------------
typedef unsigned char cover_type; //----cover_type
enum cover_scale_e
{
cover_shift = 8, //----cover_shift
cover_size = 1 << cover_shift, //----cover_size
cover_mask = cover_size - 1, //----cover_mask
cover_none = 0, //----cover_none
cover_full = cover_mask //----cover_full
};
//----------------------------------------------------poly_subpixel_scale_e
// These constants determine the subpixel accuracy, to be more precise,
// the number of bits of the fractional part of the coordinates.
// The possible coordinate capacity in bits can be calculated by formula:
// sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
// 8-bits fractional part the capacity is 24 bits.
enum poly_subpixel_scale_e
{
poly_subpixel_shift = 8, //----poly_subpixel_shift
poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale
poly_subpixel_mask = poly_subpixel_scale-1 //----poly_subpixel_mask
};
//----------------------------------------------------------filling_rule_e
enum filling_rule_e
{
fill_non_zero,
fill_even_odd
};
//-----------------------------------------------------------------------pi
const double pi = 3.14159265358979323846;
//------------------------------------------------------------------deg2rad
inline double deg2rad(double deg)
{
return deg * pi / 180.0;
}
//------------------------------------------------------------------rad2deg
inline double rad2deg(double rad)
{
return rad * 180.0 / pi;
}
//----------------------------------------------------------------rect_base
template<class T> struct rect_base
{
typedef T value_type;
typedef rect_base<T> self_type;
T x1, y1, x2, y2;
rect_base() {}
rect_base(T x1_, T y1_, T x2_, T y2_) :
x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
void init(T x1_, T y1_, T x2_, T y2_)
{
x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_;
}
const self_type& normalize()
{
T t;
if(x1 > x2) { t = x1; x1 = x2; x2 = t; }
if(y1 > y2) { t = y1; y1 = y2; y2 = t; }
return *this;
}
bool clip(const self_type& r)
{
if(x2 > r.x2) x2 = r.x2;
if(y2 > r.y2) y2 = r.y2;
if(x1 < r.x1) x1 = r.x1;
if(y1 < r.y1) y1 = r.y1;
return x1 <= x2 && y1 <= y2;
}
bool is_valid() const
{
return x1 <= x2 && y1 <= y2;
}
bool hit_test(T x, T y) const
{
return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
}
bool overlaps(const self_type& r) const
{
return !(r.x1 > x2 || r.x2 < x1
|| r.y1 > y2 || r.y2 < y1);
}
};
//-----------------------------------------------------intersect_rectangles
template<class Rect>
inline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
{
Rect r = r1;
// First process x2,y2 because the other order
// results in Internal Compiler Error under
// Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in
// case of "Maximize Speed" optimization option.
//-----------------
if(r.x2 > r2.x2) r.x2 = r2.x2;
if(r.y2 > r2.y2) r.y2 = r2.y2;
if(r.x1 < r2.x1) r.x1 = r2.x1;
if(r.y1 < r2.y1) r.y1 = r2.y1;
return r;
}
//---------------------------------------------------------unite_rectangles
template<class Rect>
inline Rect unite_rectangles(const Rect& r1, const Rect& r2)
{
Rect r = r1;
if(r.x2 < r2.x2) r.x2 = r2.x2;
if(r.y2 < r2.y2) r.y2 = r2.y2;
if(r.x1 > r2.x1) r.x1 = r2.x1;
if(r.y1 > r2.y1) r.y1 = r2.y1;
return r;
}
typedef rect_base<int> rect_i; //----rect_i
typedef rect_base<float> rect_f; //----rect_f
typedef rect_base<double> rect_d; //----rect_d
//---------------------------------------------------------path_commands_e
enum path_commands_e
{
path_cmd_stop = 0, //----path_cmd_stop
path_cmd_move_to = 1, //----path_cmd_move_to
path_cmd_line_to = 2, //----path_cmd_line_to
path_cmd_curve3 = 3, //----path_cmd_curve3
path_cmd_curve4 = 4, //----path_cmd_curve4
path_cmd_curveN = 5, //----path_cmd_curveN
path_cmd_catrom = 6, //----path_cmd_catrom
path_cmd_ubspline = 7, //----path_cmd_ubspline
path_cmd_end_poly = 0x0F, //----path_cmd_end_poly
path_cmd_mask = 0x0F //----path_cmd_mask
};
//------------------------------------------------------------path_flags_e
enum path_flags_e
{
path_flags_none = 0, //----path_flags_none
path_flags_ccw = 0x10, //----path_flags_ccw
path_flags_cw = 0x20, //----path_flags_cw
path_flags_close = 0x40, //----path_flags_close
path_flags_mask = 0xF0 //----path_flags_mask
};
//---------------------------------------------------------------is_vertex
inline bool is_vertex(unsigned c)
{
return c >= path_cmd_move_to && c < path_cmd_end_poly;
}
//--------------------------------------------------------------is_drawing
inline bool is_drawing(unsigned c)
{
return c >= path_cmd_line_to && c < path_cmd_end_poly;
}
//-----------------------------------------------------------------is_stop
inline bool is_stop(unsigned c)
{
return c == path_cmd_stop;
}
//--------------------------------------------------------------is_move_to
inline bool is_move_to(unsigned c)
{
return c == path_cmd_move_to;
}
//--------------------------------------------------------------is_line_to
inline bool is_line_to(unsigned c)
{
return c == path_cmd_line_to;
}
//----------------------------------------------------------------is_curve
inline bool is_curve(unsigned c)
{
return c == path_cmd_curve3 || c == path_cmd_curve4;
}
//---------------------------------------------------------------is_curve3
inline bool is_curve3(unsigned c)
{
return c == path_cmd_curve3;
}
//---------------------------------------------------------------is_curve4
inline bool is_curve4(unsigned c)
{
return c == path_cmd_curve4;
}
//-------------------------------------------------------------is_end_poly
inline bool is_end_poly(unsigned c)
{
return (c & path_cmd_mask) == path_cmd_end_poly;
}
//----------------------------------------------------------------is_close
inline bool is_close(unsigned c)
{
return (c & ~(path_flags_cw | path_flags_ccw)) ==
(unsigned(path_cmd_end_poly) | path_flags_close);
}
//------------------------------------------------------------is_next_poly
inline bool is_next_poly(unsigned c)
{
return is_stop(c) || is_move_to(c) || is_end_poly(c);
}
//-------------------------------------------------------------------is_cw
inline bool is_cw(unsigned c)
{
return (c & path_flags_cw) != 0;
}
//------------------------------------------------------------------is_ccw
inline bool is_ccw(unsigned c)
{
return (c & path_flags_ccw) != 0;
}
//-------------------------------------------------------------is_oriented
inline bool is_oriented(unsigned c)
{
return (c & (path_flags_cw | path_flags_ccw)) != 0;
}
//---------------------------------------------------------------is_closed
inline bool is_closed(unsigned c)
{
return (c & path_flags_close) != 0;
}
//----------------------------------------------------------get_close_flag
inline unsigned get_close_flag(unsigned c)
{
return c & path_flags_close;
}
//-------------------------------------------------------clear_orientation
inline unsigned clear_orientation(unsigned c)
{
return c & ~(path_flags_cw | path_flags_ccw);
}
//---------------------------------------------------------get_orientation
inline unsigned get_orientation(unsigned c)
{
return c & (path_flags_cw | path_flags_ccw);
}
//---------------------------------------------------------set_orientation
inline unsigned set_orientation(unsigned c, unsigned o)
{
return clear_orientation(c) | o;
}
//--------------------------------------------------------------point_base
template<class T> struct point_base
{
typedef T value_type;
T x,y;
point_base() {}
point_base(T x_, T y_) : x(x_), y(y_) {}
};
typedef point_base<int> point_i; //-----point_i
typedef point_base<float> point_f; //-----point_f
typedef point_base<double> point_d; //-----point_d
//-------------------------------------------------------------vertex_base
template<class T> struct vertex_base
{
typedef T value_type;
T x,y;
unsigned cmd;
vertex_base() {}
vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {}
};
typedef vertex_base<int> vertex_i; //-----vertex_i
typedef vertex_base<float> vertex_f; //-----vertex_f
typedef vertex_base<double> vertex_d; //-----vertex_d
//----------------------------------------------------------------row_info
template<class T> struct row_info
{
int x1, x2;
T* ptr;
row_info() {}
row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {}
};
//----------------------------------------------------------const_row_info
template<class T> struct const_row_info
{
int x1, x2;
const T* ptr;
const_row_info() {}
const_row_info(int x1_, int x2_, const T* ptr_) :
x1(x1_), x2(x2_), ptr(ptr_) {}
};
//------------------------------------------------------------is_equal_eps
template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
{
return fabs(v1 - v2) <= double(epsilon);
}
}
#endif

159
3party/agg/agg_bezier_arc.h Normal file
View file

@ -0,0 +1,159 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
// 4, 7, 10, or 13 vertices.
//
//----------------------------------------------------------------------------
#ifndef AGG_BEZIER_ARC_INCLUDED
#define AGG_BEZIER_ARC_INCLUDED
#include "agg_conv_transform.h"
namespace agg
{
//-----------------------------------------------------------------------
void arc_to_bezier(double cx, double cy, double rx, double ry,
double start_angle, double sweep_angle,
double* curve);
//==============================================================bezier_arc
//
// See implemantaion agg_bezier_arc.cpp
//
class bezier_arc
{
public:
//--------------------------------------------------------------------
bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
bezier_arc(double x, double y,
double rx, double ry,
double start_angle,
double sweep_angle)
{
init(x, y, rx, ry, start_angle, sweep_angle);
}
//--------------------------------------------------------------------
void init(double x, double y,
double rx, double ry,
double start_angle,
double sweep_angle);
//--------------------------------------------------------------------
void rewind(unsigned)
{
m_vertex = 0;
}
//--------------------------------------------------------------------
unsigned vertex(double* x, double* y)
{
if(m_vertex >= m_num_vertices) return path_cmd_stop;
*x = m_vertices[m_vertex];
*y = m_vertices[m_vertex + 1];
m_vertex += 2;
return (m_vertex == 2) ? unsigned(path_cmd_move_to) : m_cmd;
}
// Supplemantary functions. num_vertices() actually returns doubled
// number of vertices. That is, for 1 vertex it returns 2.
//--------------------------------------------------------------------
unsigned num_vertices() const { return m_num_vertices; }
const double* vertices() const { return m_vertices; }
double* vertices() { return m_vertices; }
private:
unsigned m_vertex;
unsigned m_num_vertices;
double m_vertices[26];
unsigned m_cmd;
};
//==========================================================bezier_arc_svg
// Compute an SVG-style bezier arc.
//
// Computes an elliptical arc from (x1, y1) to (x2, y2). The size and
// orientation of the ellipse are defined by two radii (rx, ry)
// and an x-axis-rotation, which indicates how the ellipse as a whole
// is rotated relative to the current coordinate system. The center
// (cx, cy) of the ellipse is calculated automatically to satisfy the
// constraints imposed by the other parameters.
// large-arc-flag and sweep-flag contribute to the automatic calculations
// and help determine how the arc is drawn.
class bezier_arc_svg
{
public:
//--------------------------------------------------------------------
bezier_arc_svg() : m_arc(), m_radii_ok(false) {}
bezier_arc_svg(double x1, double y1,
double rx, double ry,
double angle,
bool large_arc_flag,
bool sweep_flag,
double x2, double y2) :
m_arc(), m_radii_ok(false)
{
init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2);
}
//--------------------------------------------------------------------
void init(double x1, double y1,
double rx, double ry,
double angle,
bool large_arc_flag,
bool sweep_flag,
double x2, double y2);
//--------------------------------------------------------------------
bool radii_ok() const { return m_radii_ok; }
//--------------------------------------------------------------------
void rewind(unsigned)
{
m_arc.rewind(0);
}
//--------------------------------------------------------------------
unsigned vertex(double* x, double* y)
{
return m_arc.vertex(x, y);
}
// Supplemantary functions. num_vertices() actually returns doubled
// number of vertices. That is, for 1 vertex it returns 2.
//--------------------------------------------------------------------
unsigned num_vertices() const { return m_arc.num_vertices(); }
const double* vertices() const { return m_arc.vertices(); }
double* vertices() { return m_arc.vertices(); }
private:
bezier_arc m_arc;
bool m_radii_ok;
};
}
#endif

View file

@ -0,0 +1,54 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_BITSET_ITERATOR_INCLUDED
#define AGG_BITSET_ITERATOR_INCLUDED
#include "agg_basics.h"
namespace agg
{
class bitset_iterator
{
public:
bitset_iterator(const int8u* bits, unsigned offset = 0) :
m_bits(bits + (offset >> 3)),
m_mask(0x80 >> (offset & 7))
{}
void operator ++ ()
{
m_mask >>= 1;
if(m_mask == 0)
{
++m_bits;
m_mask = 0x80;
}
}
unsigned bit() const
{
return (*m_bits) & m_mask;
}
private:
const int8u* m_bits;
int8u m_mask;
};
}
#endif

1467
3party/agg/agg_blur.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,116 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// bounding_rect function template
//
//----------------------------------------------------------------------------
#ifndef AGG_BOUNDING_RECT_INCLUDED
#define AGG_BOUNDING_RECT_INCLUDED
#include "agg_basics.h"
namespace agg
{
//-----------------------------------------------------------bounding_rect
template<class VertexSource, class GetId, class CoordT>
bool bounding_rect(VertexSource& vs, GetId& gi,
unsigned start, unsigned num,
CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
{
unsigned i;
double x;
double y;
bool first = true;
*x1 = CoordT(1);
*y1 = CoordT(1);
*x2 = CoordT(0);
*y2 = CoordT(0);
for(i = 0; i < num; i++)
{
vs.rewind(gi[start + i]);
unsigned cmd;
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
if(is_vertex(cmd))
{
if(first)
{
*x1 = CoordT(x);
*y1 = CoordT(y);
*x2 = CoordT(x);
*y2 = CoordT(y);
first = false;
}
else
{
if(CoordT(x) < *x1) *x1 = CoordT(x);
if(CoordT(y) < *y1) *y1 = CoordT(y);
if(CoordT(x) > *x2) *x2 = CoordT(x);
if(CoordT(y) > *y2) *y2 = CoordT(y);
}
}
}
}
return *x1 <= *x2 && *y1 <= *y2;
}
//-----------------------------------------------------bounding_rect_single
template<class VertexSource, class CoordT>
bool bounding_rect_single(VertexSource& vs, unsigned path_id,
CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
{
double x;
double y;
bool first = true;
*x1 = CoordT(1);
*y1 = CoordT(1);
*x2 = CoordT(0);
*y2 = CoordT(0);
vs.rewind(path_id);
unsigned cmd;
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
if(is_vertex(cmd))
{
if(first)
{
*x1 = CoordT(x);
*y1 = CoordT(y);
*x2 = CoordT(x);
*y2 = CoordT(y);
first = false;
}
else
{
if(CoordT(x) < *x1) *x1 = CoordT(x);
if(CoordT(y) < *y1) *y1 = CoordT(y);
if(CoordT(x) > *x2) *x2 = CoordT(x);
if(CoordT(y) > *y2) *y2 = CoordT(y);
}
}
}
return *x1 <= *x2 && *y1 <= *y2;
}
}
#endif

76
3party/agg/agg_bspline.h Normal file
View file

@ -0,0 +1,76 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class bspline
//
//----------------------------------------------------------------------------
#ifndef AGG_BSPLINE_INCLUDED
#define AGG_BSPLINE_INCLUDED
#include "agg_array.h"
namespace agg
{
//----------------------------------------------------------------bspline
// A very simple class of Bi-cubic Spline interpolation.
// First call init(num, x[], y[]) where num - number of source points,
// x, y - arrays of X and Y values respectively. Here Y must be a function
// of X. It means that all the X-coordinates must be arranged in the ascending
// order.
// Then call get(x) that calculates a value Y for the respective X.
// The class supports extrapolation, i.e. you can call get(x) where x is
// outside the given with init() X-range. Extrapolation is a simple linear
// function.
//
// See Implementation agg_bspline.cpp
//------------------------------------------------------------------------
class bspline
{
public:
bspline();
bspline(int num);
bspline(int num, const double* x, const double* y);
void init(int num);
void add_point(double x, double y);
void prepare();
void init(int num, const double* x, const double* y);
double get(double x) const;
double get_stateful(double x) const;
private:
bspline(const bspline&);
const bspline& operator = (const bspline&);
static void bsearch(int n, const double *x, double x0, int *i);
double extrapolation_left(double x) const;
double extrapolation_right(double x) const;
double interpolation(double x, int i) const;
int m_max;
int m_num;
double* m_x;
double* m_y;
pod_array<double> m_am;
mutable int m_last_idx;
};
}
#endif

View file

@ -0,0 +1,333 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Liang-Barsky clipping
//
//----------------------------------------------------------------------------
#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
#define AGG_CLIP_LIANG_BARSKY_INCLUDED
#include "agg_basics.h"
namespace agg
{
//------------------------------------------------------------------------
enum clipping_flags_e
{
clipping_flags_x1_clipped = 4,
clipping_flags_x2_clipped = 1,
clipping_flags_y1_clipped = 8,
clipping_flags_y2_clipped = 2,
clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped,
clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped
};
//----------------------------------------------------------clipping_flags
// Determine the clipping code of the vertex according to the
// Cyrus-Beck line clipping algorithm
//
// | |
// 0110 | 0010 | 0011
// | |
// -------+--------+-------- clip_box.y2
// | |
// 0100 | 0000 | 0001
// | |
// -------+--------+-------- clip_box.y1
// | |
// 1100 | 1000 | 1001
// | |
// clip_box.x1 clip_box.x2
//
//
template<class T>
inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
{
return (x > clip_box.x2) |
((y > clip_box.y2) << 1) |
((x < clip_box.x1) << 2) |
((y < clip_box.y1) << 3);
}
//--------------------------------------------------------clipping_flags_x
template<class T>
inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box)
{
return (x > clip_box.x2) | ((x < clip_box.x1) << 2);
}
//--------------------------------------------------------clipping_flags_y
template<class T>
inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box)
{
return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3);
}
//-------------------------------------------------------clip_liang_barsky
template<class T>
inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
const rect_base<T>& clip_box,
T* x, T* y)
{
const double nearzero = 1e-30;
double deltax = x2 - x1;
double deltay = y2 - y1;
double xin;
double xout;
double yin;
double yout;
double tinx;
double tiny;
double toutx;
double touty;
double tin1;
double tin2;
double tout1;
unsigned np = 0;
if(deltax == 0.0)
{
// bump off of the vertical
deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
}
if(deltay == 0.0)
{
// bump off of the horizontal
deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
}
if(deltax > 0.0)
{
// points to right
xin = clip_box.x1;
xout = clip_box.x2;
}
else
{
xin = clip_box.x2;
xout = clip_box.x1;
}
if(deltay > 0.0)
{
// points up
yin = clip_box.y1;
yout = clip_box.y2;
}
else
{
yin = clip_box.y2;
yout = clip_box.y1;
}
tinx = (xin - x1) / deltax;
tiny = (yin - y1) / deltay;
if (tinx < tiny)
{
// hits x first
tin1 = tinx;
tin2 = tiny;
}
else
{
// hits y first
tin1 = tiny;
tin2 = tinx;
}
if(tin1 <= 1.0)
{
if(0.0 < tin1)
{
*x++ = (T)xin;
*y++ = (T)yin;
++np;
}
if(tin2 <= 1.0)
{
toutx = (xout - x1) / deltax;
touty = (yout - y1) / deltay;
tout1 = (toutx < touty) ? toutx : touty;
if(tin2 > 0.0 || tout1 > 0.0)
{
if(tin2 <= tout1)
{
if(tin2 > 0.0)
{
if(tinx > tiny)
{
*x++ = (T)xin;
*y++ = (T)(y1 + tinx * deltay);
}
else
{
*x++ = (T)(x1 + tiny * deltax);
*y++ = (T)yin;
}
++np;
}
if(tout1 < 1.0)
{
if(toutx < touty)
{
*x++ = (T)xout;
*y++ = (T)(y1 + toutx * deltay);
}
else
{
*x++ = (T)(x1 + touty * deltax);
*y++ = (T)yout;
}
}
else
{
*x++ = x2;
*y++ = y2;
}
++np;
}
else
{
if(tinx > tiny)
{
*x++ = (T)xin;
*y++ = (T)yout;
}
else
{
*x++ = (T)xout;
*y++ = (T)yin;
}
++np;
}
}
}
}
return np;
}
//----------------------------------------------------------------------------
template<class T>
bool clip_move_point(T x1, T y1, T x2, T y2,
const rect_base<T>& clip_box,
T* x, T* y, unsigned flags)
{
T bound;
if(flags & clipping_flags_x_clipped)
{
if(x1 == x2)
{
return false;
}
bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2;
*y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1);
*x = bound;
}
flags = clipping_flags_y(*y, clip_box);
if(flags & clipping_flags_y_clipped)
{
if(y1 == y2)
{
return false;
}
bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2;
*x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1);
*y = bound;
}
return true;
}
//-------------------------------------------------------clip_line_segment
// Returns: ret >= 4 - Fully clipped
// (ret & 1) != 0 - First point has been moved
// (ret & 2) != 0 - Second point has been moved
//
template<class T>
unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2,
const rect_base<T>& clip_box)
{
unsigned f1 = clipping_flags(*x1, *y1, clip_box);
unsigned f2 = clipping_flags(*x2, *y2, clip_box);
unsigned ret = 0;
if((f2 | f1) == 0)
{
// Fully visible
return 0;
}
if((f1 & clipping_flags_x_clipped) != 0 &&
(f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped))
{
// Fully clipped
return 4;
}
if((f1 & clipping_flags_y_clipped) != 0 &&
(f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped))
{
// Fully clipped
return 4;
}
T tx1 = *x1;
T ty1 = *y1;
T tx2 = *x2;
T ty2 = *y2;
if(f1)
{
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1))
{
return 4;
}
if(*x1 == *x2 && *y1 == *y2)
{
return 4;
}
ret |= 1;
}
if(f2)
{
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2))
{
return 4;
}
if(*x1 == *x2 && *y1 == *y2)
{
return 4;
}
ret |= 2;
}
return ret;
}
}
#endif

1013
3party/agg/agg_color_gray.h Normal file

File diff suppressed because it is too large Load diff

1290
3party/agg/agg_color_rgba.h Normal file

File diff suppressed because it is too large Load diff

44
3party/agg/agg_config.h Normal file
View file

@ -0,0 +1,44 @@
#ifndef AGG_CONFIG_INCLUDED
#define AGG_CONFIG_INCLUDED
// This file can be used to redefine certain data types.
//---------------------------------------
// 1. Default basic types such as:
//
// AGG_INT8
// AGG_INT8U
// AGG_INT16
// AGG_INT16U
// AGG_INT32
// AGG_INT32U
// AGG_INT64
// AGG_INT64U
//
// Just replace this file with new defines if necessary.
// For example, if your compiler doesn't have a 64 bit integer type
// you can still use AGG if you define the follows:
//
// #define AGG_INT64 int
// #define AGG_INT64U unsigned
//
// It will result in overflow in 16 bit-per-component image/pattern resampling
// but it won't result any crash and the rest of the library will remain
// fully functional.
//---------------------------------------
// 2. Default rendering_buffer type. Can be:
//
// Provides faster access for massive pixel operations,
// such as blur, image filtering:
// #define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
//
// Provides cheaper creation and destruction (no mem allocs):
// #define AGG_RENDERING_BUFFER row_accessor<int8u>
//
// You can still use both of them simultaneously in your applications
// This #define is used only for default rendering_buffer type,
// in short hand typedefs like pixfmt_rgba32.
#endif

View file

@ -0,0 +1,159 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED
#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
#include "agg_basics.h"
namespace agg
{
//------------------------------------------------------------null_markers
struct null_markers
{
void remove_all() {}
void add_vertex(double, double, unsigned) {}
void prepare_src() {}
void rewind(unsigned) {}
unsigned vertex(double*, double*) { return path_cmd_stop; }
};
//------------------------------------------------------conv_adaptor_vcgen
template<class VertexSource,
class Generator,
class Markers=null_markers> class conv_adaptor_vcgen
{
enum status
{
initial,
accumulate,
generate
};
public:
explicit conv_adaptor_vcgen(VertexSource& source) :
m_source(&source),
m_status(initial)
{}
void attach(VertexSource& source) { m_source = &source; }
Generator& generator() { return m_generator; }
const Generator& generator() const { return m_generator; }
Markers& markers() { return m_markers; }
const Markers& markers() const { return m_markers; }
void rewind(unsigned path_id)
{
m_source->rewind(path_id);
m_status = initial;
}
unsigned vertex(double* x, double* y);
private:
// Prohibit copying
conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
const conv_adaptor_vcgen<VertexSource, Generator, Markers>&
operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
VertexSource* m_source;
Generator m_generator;
Markers m_markers;
status m_status;
unsigned m_last_cmd;
double m_start_x;
double m_start_y;
};
//------------------------------------------------------------------------
template<class VertexSource, class Generator, class Markers>
unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_stop;
bool done = false;
while(!done)
{
switch(m_status)
{
case initial:
m_markers.remove_all();
m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
m_status = accumulate;
[[fallthrough]];
case accumulate:
if(is_stop(m_last_cmd)) return path_cmd_stop;
m_generator.remove_all();
m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
for(;;)
{
cmd = m_source->vertex(x, y);
if(is_vertex(cmd))
{
m_last_cmd = cmd;
if(is_move_to(cmd))
{
m_start_x = *x;
m_start_y = *y;
break;
}
m_generator.add_vertex(*x, *y, cmd);
m_markers.add_vertex(*x, *y, path_cmd_line_to);
}
else
{
if(is_stop(cmd))
{
m_last_cmd = path_cmd_stop;
break;
}
if(is_end_poly(cmd))
{
m_generator.add_vertex(*x, *y, cmd);
break;
}
}
}
m_generator.rewind(0);
m_status = generate;
[[fallthrough]];
case generate:
cmd = m_generator.vertex(x, y);
if(is_stop(cmd))
{
m_status = accumulate;
break;
}
done = true;
break;
}
}
return cmd;
}
}
#endif

View file

@ -0,0 +1,159 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_ADAPTOR_VPGEN_INCLUDED
#define AGG_CONV_ADAPTOR_VPGEN_INCLUDED
#include "agg_basics.h"
namespace agg
{
//======================================================conv_adaptor_vpgen
template<class VertexSource, class VPGen> class conv_adaptor_vpgen
{
public:
explicit conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {}
void attach(VertexSource& source) { m_source = &source; }
VPGen& vpgen() { return m_vpgen; }
const VPGen& vpgen() const { return m_vpgen; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&);
const conv_adaptor_vpgen<VertexSource, VPGen>&
operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&);
VertexSource* m_source;
VPGen m_vpgen;
double m_start_x;
double m_start_y;
unsigned m_poly_flags;
int m_vertices;
};
//------------------------------------------------------------------------
template<class VertexSource, class VPGen>
void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id)
{
m_source->rewind(path_id);
m_vpgen.reset();
m_start_x = 0;
m_start_y = 0;
m_poly_flags = 0;
m_vertices = 0;
}
//------------------------------------------------------------------------
template<class VertexSource, class VPGen>
unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_stop;
for(;;)
{
cmd = m_vpgen.vertex(x, y);
if(!is_stop(cmd)) break;
if(m_poly_flags && !m_vpgen.auto_unclose())
{
*x = 0.0;
*y = 0.0;
cmd = m_poly_flags;
m_poly_flags = 0;
break;
}
if(m_vertices < 0)
{
if(m_vertices < -1)
{
m_vertices = 0;
return path_cmd_stop;
}
m_vpgen.move_to(m_start_x, m_start_y);
m_vertices = 1;
continue;
}
double tx, ty;
cmd = m_source->vertex(&tx, &ty);
if(is_vertex(cmd))
{
if(is_move_to(cmd))
{
if(m_vpgen.auto_close() && m_vertices > 2)
{
m_vpgen.line_to(m_start_x, m_start_y);
m_poly_flags = path_cmd_end_poly | path_flags_close;
m_start_x = tx;
m_start_y = ty;
m_vertices = -1;
continue;
}
m_vpgen.move_to(tx, ty);
m_start_x = tx;
m_start_y = ty;
m_vertices = 1;
}
else
{
m_vpgen.line_to(tx, ty);
++m_vertices;
}
}
else
{
if(is_end_poly(cmd))
{
m_poly_flags = cmd;
if(is_closed(cmd) || m_vpgen.auto_close())
{
if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close;
if(m_vertices > 2)
{
m_vpgen.line_to(m_start_x, m_start_y);
}
m_vertices = 0;
}
}
else
{
// path_cmd_stop
if(m_vpgen.auto_close() && m_vertices > 2)
{
m_vpgen.line_to(m_start_x, m_start_y);
m_poly_flags = path_cmd_end_poly | path_flags_close;
m_vertices = -2;
continue;
}
break;
}
}
}
return cmd;
}
}
#endif

View file

@ -0,0 +1,48 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_BSPLINE_INCLUDED
#define AGG_CONV_BSPLINE_INCLUDED
#include "agg_basics.h"
#include "agg_vcgen_bspline.h"
#include "agg_conv_adaptor_vcgen.h"
namespace agg
{
//---------------------------------------------------------conv_bspline
template<class VertexSource>
struct conv_bspline : public conv_adaptor_vcgen<VertexSource, vcgen_bspline>
{
typedef conv_adaptor_vcgen<VertexSource, vcgen_bspline> base_type;
conv_bspline(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_bspline>(vs) {}
void interpolation_step(double v) { base_type::generator().interpolation_step(v); }
double interpolation_step() const { return base_type::generator().interpolation_step(); }
private:
conv_bspline(const conv_bspline<VertexSource>&);
const conv_bspline<VertexSource>&
operator = (const conv_bspline<VertexSource>&);
};
}
#endif

View file

@ -0,0 +1,63 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Polygon clipping converter
// There an optimized Liang-Basky algorithm is used.
// The algorithm doesn't optimize the degenerate edges, i.e. it will never
// break a closed polygon into two or more ones, instead, there will be
// degenerate edges coinciding with the respective clipping boundaries.
// This is a sub-optimal solution, because that optimization would require
// extra, rather expensive math while the rasterizer tolerates it quite well,
// without any considerable overhead.
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CLIP_POLYGON_INCLUDED
#define AGG_CONV_CLIP_POLYGON_INCLUDED
#include "agg_basics.h"
#include "agg_conv_adaptor_vpgen.h"
#include "agg_vpgen_clip_polygon.h"
namespace agg
{
//=======================================================conv_clip_polygon
template<class VertexSource>
struct conv_clip_polygon : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>
{
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon> base_type;
conv_clip_polygon(VertexSource& vs) :
conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>(vs) {}
void clip_box(double x1, double y1, double x2, double y2)
{
base_type::vpgen().clip_box(x1, y1, x2, y2);
}
double x1() const { return base_type::vpgen().x1(); }
double y1() const { return base_type::vpgen().y1(); }
double x2() const { return base_type::vpgen().x2(); }
double y2() const { return base_type::vpgen().y2(); }
private:
conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
const conv_clip_polygon<VertexSource>&
operator = (const conv_clip_polygon<VertexSource>&);
};
}
#endif

View file

@ -0,0 +1,63 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// polyline clipping converter
// There an optimized Liang-Basky algorithm is used.
// The algorithm doesn't optimize the degenerate edges, i.e. it will never
// break a closed polyline into two or more ones, instead, there will be
// degenerate edges coinciding with the respective clipping boundaries.
// This is a sub-optimal solution, because that optimization would require
// extra, rather expensive math while the rasterizer tolerates it quite well,
// without any considerable overhead.
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CLIP_polyline_INCLUDED
#define AGG_CONV_CLIP_polyline_INCLUDED
#include "agg_basics.h"
#include "agg_conv_adaptor_vpgen.h"
#include "agg_vpgen_clip_polyline.h"
namespace agg
{
//=======================================================conv_clip_polyline
template<class VertexSource>
struct conv_clip_polyline : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>
{
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline> base_type;
conv_clip_polyline(VertexSource& vs) :
conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs) {}
void clip_box(double x1, double y1, double x2, double y2)
{
base_type::vpgen().clip_box(x1, y1, x2, y2);
}
double x1() const { return base_type::vpgen().x1(); }
double y1() const { return base_type::vpgen().y1(); }
double x2() const { return base_type::vpgen().x2(); }
double y2() const { return base_type::vpgen().y2(); }
private:
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
const conv_clip_polyline<VertexSource>&
operator = (const conv_clip_polyline<VertexSource>&);
};
}
#endif

View file

@ -0,0 +1,125 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CLOSE_POLYGON_INCLUDED
#define AGG_CONV_CLOSE_POLYGON_INCLUDED
#include "agg_basics.h"
namespace agg
{
//======================================================conv_close_polygon
template<class VertexSource> class conv_close_polygon
{
public:
explicit conv_close_polygon(VertexSource& vs) : m_source(&vs) {}
void attach(VertexSource& source) { m_source = &source; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
conv_close_polygon(const conv_close_polygon<VertexSource>&);
const conv_close_polygon<VertexSource>&
operator = (const conv_close_polygon<VertexSource>&);
VertexSource* m_source;
unsigned m_cmd[2];
double m_x[2];
double m_y[2];
unsigned m_vertex;
bool m_line_to;
};
//------------------------------------------------------------------------
template<class VertexSource>
void conv_close_polygon<VertexSource>::rewind(unsigned path_id)
{
m_source->rewind(path_id);
m_vertex = 2;
m_line_to = false;
}
//------------------------------------------------------------------------
template<class VertexSource>
unsigned conv_close_polygon<VertexSource>::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_stop;
for(;;)
{
if(m_vertex < 2)
{
*x = m_x[m_vertex];
*y = m_y[m_vertex];
cmd = m_cmd[m_vertex];
++m_vertex;
break;
}
cmd = m_source->vertex(x, y);
if(is_end_poly(cmd))
{
cmd |= path_flags_close;
break;
}
if(is_stop(cmd))
{
if(m_line_to)
{
m_cmd[0] = path_cmd_end_poly | path_flags_close;
m_cmd[1] = path_cmd_stop;
m_vertex = 0;
m_line_to = false;
continue;
}
break;
}
if(is_move_to(cmd))
{
if(m_line_to)
{
m_x[0] = 0.0;
m_y[0] = 0.0;
m_cmd[0] = path_cmd_end_poly | path_flags_close;
m_x[1] = *x;
m_y[1] = *y;
m_cmd[1] = cmd;
m_vertex = 0;
m_line_to = false;
continue;
}
break;
}
if(is_vertex(cmd))
{
m_line_to = true;
break;
}
}
return cmd;
}
}
#endif

View file

@ -0,0 +1,73 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CONCAT_INCLUDED
#define AGG_CONV_CONCAT_INCLUDED
#include "agg_basics.h"
namespace agg
{
//=============================================================conv_concat
// Concatenation of two paths. Usually used to combine lines or curves
// with markers such as arrowheads
template<class VS1, class VS2> class conv_concat
{
public:
conv_concat(VS1& source1, VS2& source2) :
m_source1(&source1), m_source2(&source2), m_status(2) {}
void attach1(VS1& source) { m_source1 = &source; }
void attach2(VS2& source) { m_source2 = &source; }
void rewind(unsigned path_id)
{
m_source1->rewind(path_id);
m_source2->rewind(0);
m_status = 0;
}
unsigned vertex(double* x, double* y)
{
unsigned cmd;
if(m_status == 0)
{
cmd = m_source1->vertex(x, y);
if(!is_stop(cmd)) return cmd;
m_status = 1;
}
if(m_status == 1)
{
cmd = m_source2->vertex(x, y);
if(!is_stop(cmd)) return cmd;
m_status = 2;
}
return path_cmd_stop;
}
private:
conv_concat(const conv_concat<VS1, VS2>&);
const conv_concat<VS1, VS2>&
operator = (const conv_concat<VS1, VS2>&);
VS1* m_source1;
VS2* m_source2;
int m_status;
};
}
#endif

View file

@ -0,0 +1,65 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// conv_stroke
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CONTOUR_INCLUDED
#define AGG_CONV_CONTOUR_INCLUDED
#include "agg_basics.h"
#include "agg_vcgen_contour.h"
#include "agg_conv_adaptor_vcgen.h"
namespace agg
{
//-----------------------------------------------------------conv_contour
template<class VertexSource>
struct conv_contour : public conv_adaptor_vcgen<VertexSource, vcgen_contour>
{
typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type;
conv_contour(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs)
{
}
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); }
line_join_e line_join() const { return base_type::generator().line_join(); }
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
double width() const { return base_type::generator().width(); }
double miter_limit() const { return base_type::generator().miter_limit(); }
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
double approximation_scale() const { return base_type::generator().approximation_scale(); }
bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); }
private:
conv_contour(const conv_contour<VertexSource>&);
const conv_contour<VertexSource>&
operator = (const conv_contour<VertexSource>&);
};
}
#endif

201
3party/agg/agg_conv_curve.h Normal file
View file

@ -0,0 +1,201 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// classes conv_curve
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CURVE_INCLUDED
#define AGG_CONV_CURVE_INCLUDED
#include "agg_basics.h"
#include "agg_curves.h"
namespace agg
{
//---------------------------------------------------------------conv_curve
// Curve converter class. Any path storage can have Bezier curves defined
// by their control points. There're two types of curves supported: curve3
// and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control
// point. Curve4 has 2 control points (4 points in total) and can be used
// to interpolate more complicated curves. Curve4, unlike curve3 can be used
// to approximate arcs, both circular and elliptical. Curves are approximated
// with straight lines and one of the approaches is just to store the whole
// sequence of vertices that approximate our curve. It takes additional
// memory, and at the same time the consecutive vertices can be calculated
// on demand.
//
// Initially, path storages are not suppose to keep all the vertices of the
// curves (although, nothing prevents us from doing so). Instead, path_storage
// keeps only vertices, needed to calculate a curve on demand. Those vertices
// are marked with special commands. So, if the path_storage contains curves
// (which are not real curves yet), and we render this storage directly,
// all we will see is only 2 or 3 straight line segments (for curve3 and
// curve4 respectively). If we need to see real curves drawn we need to
// include this class into the conversion pipeline.
//
// Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4
// and converts these vertices into a move_to/line_to sequence.
//-----------------------------------------------------------------------
template<class VertexSource,
class Curve3=curve3,
class Curve4=curve4> class conv_curve
{
public:
typedef Curve3 curve3_type;
typedef Curve4 curve4_type;
typedef conv_curve<VertexSource, Curve3, Curve4> self_type;
explicit conv_curve(VertexSource& source) :
m_source(&source), m_last_x(0.0), m_last_y(0.0) {}
void attach(VertexSource& source) { m_source = &source; }
void approximation_method(curve_approximation_method_e v)
{
m_curve3.approximation_method(v);
m_curve4.approximation_method(v);
}
curve_approximation_method_e approximation_method() const
{
return m_curve4.approximation_method();
}
void approximation_scale(double s)
{
m_curve3.approximation_scale(s);
m_curve4.approximation_scale(s);
}
double approximation_scale() const
{
return m_curve4.approximation_scale();
}
void angle_tolerance(double v)
{
m_curve3.angle_tolerance(v);
m_curve4.angle_tolerance(v);
}
double angle_tolerance() const
{
return m_curve4.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve3.cusp_limit(v);
m_curve4.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve4.cusp_limit();
}
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
conv_curve(const self_type&);
const self_type& operator = (const self_type&);
VertexSource* m_source;
double m_last_x;
double m_last_y;
curve3_type m_curve3;
curve4_type m_curve4;
};
//------------------------------------------------------------------------
template<class VertexSource, class Curve3, class Curve4>
void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id)
{
m_source->rewind(path_id);
m_last_x = 0.0;
m_last_y = 0.0;
m_curve3.reset();
m_curve4.reset();
}
//------------------------------------------------------------------------
template<class VertexSource, class Curve3, class Curve4>
unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
{
if(!is_stop(m_curve3.vertex(x, y)))
{
m_last_x = *x;
m_last_y = *y;
return path_cmd_line_to;
}
if(!is_stop(m_curve4.vertex(x, y)))
{
m_last_x = *x;
m_last_y = *y;
return path_cmd_line_to;
}
double ct2_x;
double ct2_y;
double end_x;
double end_y;
unsigned cmd = m_source->vertex(x, y);
switch(cmd)
{
case path_cmd_curve3:
m_source->vertex(&end_x, &end_y);
m_curve3.init(m_last_x, m_last_y,
*x, *y,
end_x, end_y);
m_curve3.vertex(x, y); // First call returns path_cmd_move_to
m_curve3.vertex(x, y); // This is the first vertex of the curve
cmd = path_cmd_line_to;
break;
case path_cmd_curve4:
m_source->vertex(&ct2_x, &ct2_y);
m_source->vertex(&end_x, &end_y);
m_curve4.init(m_last_x, m_last_y,
*x, *y,
ct2_x, ct2_y,
end_x, end_y);
m_curve4.vertex(x, y); // First call returns path_cmd_move_to
m_curve4.vertex(x, y); // This is the first vertex of the curve
cmd = path_cmd_line_to;
break;
}
m_last_x = *x;
m_last_y = *y;
return cmd;
}
}
#endif

View file

@ -0,0 +1,68 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// conv_dash
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_DASH_INCLUDED
#define AGG_CONV_DASH_INCLUDED
#include "agg_basics.h"
#include "agg_vcgen_dash.h"
#include "agg_conv_adaptor_vcgen.h"
namespace agg
{
//---------------------------------------------------------------conv_dash
template<class VertexSource, class Markers=null_markers>
struct conv_dash : public conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>
{
typedef Markers marker_type;
typedef conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers> base_type;
conv_dash(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>(vs)
{
}
void remove_all_dashes()
{
base_type::generator().remove_all_dashes();
}
void add_dash(double dash_len, double gap_len)
{
base_type::generator().add_dash(dash_len, gap_len);
}
void dash_start(double ds)
{
base_type::generator().dash_start(ds);
}
void shorten(double s) { base_type::generator().shorten(s); }
double shorten() const { return base_type::generator().shorten(); }
private:
conv_dash(const conv_dash<VertexSource, Markers>&);
const conv_dash<VertexSource, Markers>&
operator = (const conv_dash<VertexSource, Markers>&);
};
}
#endif

432
3party/agg/agg_conv_gpc.h Normal file
View file

@ -0,0 +1,432 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// General Polygon Clipper based on the GPC library by Alan Murta
// Union, Intersection, XOR, A-B, B-A
// Contact the author if you intend to use it in commercial applications!
// http://www.cs.man.ac.uk/aig/staff/alan/software/
// Alan Murta (email: gpc@cs.man.ac.uk)
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_GPC_INCLUDED
#define AGG_CONV_GPC_INCLUDED
#include <math.h>
#include "agg_basics.h"
#include "agg_array.h"
extern "C"
{
#include "gpc.h"
}
namespace agg
{
enum gpc_op_e
{
gpc_or,
gpc_and,
gpc_xor,
gpc_a_minus_b,
gpc_b_minus_a
};
//================================================================conv_gpc
template<class VSA, class VSB> class conv_gpc
{
enum status
{
status_move_to,
status_line_to,
status_stop
};
struct contour_header_type
{
int num_vertices;
int hole_flag;
gpc_vertex* vertices;
};
typedef pod_bvector<gpc_vertex, 8> vertex_array_type;
typedef pod_bvector<contour_header_type, 6> contour_header_array_type;
public:
typedef VSA source_a_type;
typedef VSB source_b_type;
typedef conv_gpc<source_a_type, source_b_type> self_type;
~conv_gpc()
{
free_gpc_data();
}
conv_gpc(source_a_type& a, source_b_type& b, gpc_op_e op = gpc_or) :
m_src_a(&a),
m_src_b(&b),
m_status(status_move_to),
m_vertex(-1),
m_contour(-1),
m_operation(op)
{
memset(&m_poly_a, 0, sizeof(m_poly_a));
memset(&m_poly_b, 0, sizeof(m_poly_b));
memset(&m_result, 0, sizeof(m_result));
}
void attach1(VSA& source) { m_src_a = &source; }
void attach2(VSB& source) { m_src_b = &source; }
void operation(gpc_op_e v) { m_operation = v; }
// Vertex Source Interface
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
conv_gpc(const conv_gpc<VSA, VSB>&);
const conv_gpc<VSA, VSB>& operator = (const conv_gpc<VSA, VSB>&);
//--------------------------------------------------------------------
void free_polygon(gpc_polygon& p);
void free_result();
void free_gpc_data();
void start_contour();
void add_vertex(double x, double y);
void end_contour(unsigned orientation);
void make_polygon(gpc_polygon& p);
void start_extracting();
bool next_contour();
bool next_vertex(double* x, double* y);
//--------------------------------------------------------------------
template<class VS> void add(VS& src, gpc_polygon& p)
{
unsigned cmd;
double x, y;
double start_x = 0.0;
double start_y = 0.0;
bool line_to = false;
unsigned orientation = 0;
m_contour_accumulator.remove_all();
while(!is_stop(cmd = src.vertex(&x, &y)))
{
if(is_vertex(cmd))
{
if(is_move_to(cmd))
{
if(line_to)
{
end_contour(orientation);
orientation = 0;
}
start_contour();
start_x = x;
start_y = y;
}
add_vertex(x, y);
line_to = true;
}
else
{
if(is_end_poly(cmd))
{
orientation = get_orientation(cmd);
if(line_to && is_closed(cmd))
{
add_vertex(start_x, start_y);
}
}
}
}
if(line_to)
{
end_contour(orientation);
}
make_polygon(p);
}
private:
//--------------------------------------------------------------------
source_a_type* m_src_a;
source_b_type* m_src_b;
status m_status;
int m_vertex;
int m_contour;
gpc_op_e m_operation;
vertex_array_type m_vertex_accumulator;
contour_header_array_type m_contour_accumulator;
gpc_polygon m_poly_a;
gpc_polygon m_poly_b;
gpc_polygon m_result;
};
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::free_polygon(gpc_polygon& p)
{
int i;
for(i = 0; i < p.num_contours; i++)
{
pod_allocator<gpc_vertex>::deallocate(p.contour[i].vertex,
p.contour[i].num_vertices);
}
pod_allocator<gpc_vertex_list>::deallocate(p.contour, p.num_contours);
memset(&p, 0, sizeof(gpc_polygon));
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::free_result()
{
if(m_result.contour)
{
gpc_free_polygon(&m_result);
}
memset(&m_result, 0, sizeof(m_result));
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::free_gpc_data()
{
free_polygon(m_poly_a);
free_polygon(m_poly_b);
free_result();
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::start_contour()
{
contour_header_type h;
memset(&h, 0, sizeof(h));
m_contour_accumulator.add(h);
m_vertex_accumulator.remove_all();
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
inline void conv_gpc<VSA, VSB>::add_vertex(double x, double y)
{
gpc_vertex v;
v.x = x;
v.y = y;
m_vertex_accumulator.add(v);
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::end_contour(unsigned orientation)
{
if(m_contour_accumulator.size())
{
if(m_vertex_accumulator.size() > 2)
{
contour_header_type& h =
m_contour_accumulator[m_contour_accumulator.size() - 1];
h.num_vertices = m_vertex_accumulator.size();
h.hole_flag = 0;
// TO DO: Clarify the "holes"
//if(is_cw(orientation)) h.hole_flag = 1;
h.vertices = pod_allocator<gpc_vertex>::allocate(h.num_vertices);
gpc_vertex* d = h.vertices;
int i;
for(i = 0; i < h.num_vertices; i++)
{
const gpc_vertex& s = m_vertex_accumulator[i];
d->x = s.x;
d->y = s.y;
++d;
}
}
else
{
m_vertex_accumulator.remove_last();
}
}
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::make_polygon(gpc_polygon& p)
{
free_polygon(p);
if(m_contour_accumulator.size())
{
p.num_contours = m_contour_accumulator.size();
p.hole = 0;
p.contour = pod_allocator<gpc_vertex_list>::allocate(p.num_contours);
int i;
gpc_vertex_list* pv = p.contour;
for(i = 0; i < p.num_contours; i++)
{
const contour_header_type& h = m_contour_accumulator[i];
pv->num_vertices = h.num_vertices;
pv->vertex = h.vertices;
++pv;
}
}
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::start_extracting()
{
m_status = status_move_to;
m_contour = -1;
m_vertex = -1;
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
bool conv_gpc<VSA, VSB>::next_contour()
{
if(++m_contour < m_result.num_contours)
{
m_vertex = -1;
return true;
}
return false;
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
inline bool conv_gpc<VSA, VSB>::next_vertex(double* x, double* y)
{
const gpc_vertex_list& vlist = m_result.contour[m_contour];
if(++m_vertex < vlist.num_vertices)
{
const gpc_vertex& v = vlist.vertex[m_vertex];
*x = v.x;
*y = v.y;
return true;
}
return false;
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
void conv_gpc<VSA, VSB>::rewind(unsigned path_id)
{
free_result();
m_src_a->rewind(path_id);
m_src_b->rewind(path_id);
add(*m_src_a, m_poly_a);
add(*m_src_b, m_poly_b);
switch(m_operation)
{
case gpc_or:
gpc_polygon_clip(GPC_UNION,
&m_poly_a,
&m_poly_b,
&m_result);
break;
case gpc_and:
gpc_polygon_clip(GPC_INT,
&m_poly_a,
&m_poly_b,
&m_result);
break;
case gpc_xor:
gpc_polygon_clip(GPC_XOR,
&m_poly_a,
&m_poly_b,
&m_result);
break;
case gpc_a_minus_b:
gpc_polygon_clip(GPC_DIFF,
&m_poly_a,
&m_poly_b,
&m_result);
break;
case gpc_b_minus_a:
gpc_polygon_clip(GPC_DIFF,
&m_poly_b,
&m_poly_a,
&m_result);
break;
}
start_extracting();
}
//------------------------------------------------------------------------
template<class VSA, class VSB>
unsigned conv_gpc<VSA, VSB>::vertex(double* x, double* y)
{
if(m_status == status_move_to)
{
if(next_contour())
{
if(next_vertex(x, y))
{
m_status = status_line_to;
return path_cmd_move_to;
}
m_status = status_stop;
return path_cmd_end_poly | path_flags_close;
}
}
else
{
if(next_vertex(x, y))
{
return path_cmd_line_to;
}
else
{
m_status = status_move_to;
}
return path_cmd_end_poly | path_flags_close;
}
return path_cmd_stop;
}
}
#endif

View file

@ -0,0 +1,148 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// conv_marker
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_MARKER_INCLUDED
#define AGG_CONV_MARKER_INCLUDED
#include "agg_basics.h"
#include "agg_trans_affine.h"
namespace agg
{
//-------------------------------------------------------------conv_marker
template<class MarkerLocator, class MarkerShapes>
class conv_marker
{
public:
conv_marker(MarkerLocator& ml, MarkerShapes& ms);
trans_affine& transform() { return m_transform; }
const trans_affine& transform() const { return m_transform; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&);
const conv_marker<MarkerLocator, MarkerShapes>&
operator = (const conv_marker<MarkerLocator, MarkerShapes>&);
enum status_e
{
initial,
markers,
polygon,
stop
};
MarkerLocator* m_marker_locator;
MarkerShapes* m_marker_shapes;
trans_affine m_transform;
trans_affine m_mtx;
status_e m_status;
unsigned m_marker;
unsigned m_num_markers;
};
//------------------------------------------------------------------------
template<class MarkerLocator, class MarkerShapes>
conv_marker<MarkerLocator, MarkerShapes>::conv_marker(MarkerLocator& ml, MarkerShapes& ms) :
m_marker_locator(&ml),
m_marker_shapes(&ms),
m_status(initial),
m_marker(0),
m_num_markers(1)
{
}
//------------------------------------------------------------------------
template<class MarkerLocator, class MarkerShapes>
void conv_marker<MarkerLocator, MarkerShapes>::rewind(unsigned)
{
m_status = initial;
m_marker = 0;
m_num_markers = 1;
}
//------------------------------------------------------------------------
template<class MarkerLocator, class MarkerShapes>
unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_move_to;
double x1, y1, x2, y2;
while(!is_stop(cmd))
{
switch(m_status)
{
case initial:
if(m_num_markers == 0)
{
cmd = path_cmd_stop;
break;
}
m_marker_locator->rewind(m_marker);
++m_marker;
m_num_markers = 0;
m_status = markers;
case markers:
if(is_stop(m_marker_locator->vertex(&x1, &y1)))
{
m_status = initial;
break;
}
if(is_stop(m_marker_locator->vertex(&x2, &y2)))
{
m_status = initial;
break;
}
++m_num_markers;
m_mtx = m_transform;
m_mtx *= trans_affine_rotation(atan2(y2 - y1, x2 - x1));
m_mtx *= trans_affine_translation(x1, y1);
m_marker_shapes->rewind(m_marker - 1);
m_status = polygon;
case polygon:
cmd = m_marker_shapes->vertex(x, y);
if(is_stop(cmd))
{
cmd = path_cmd_move_to;
m_status = markers;
break;
}
m_mtx.transform(x, y);
return cmd;
case stop:
cmd = path_cmd_stop;
break;
}
}
return cmd;
}
}
#endif

View file

@ -0,0 +1,51 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_MARKER_ADAPTOR_INCLUDED
#define AGG_CONV_MARKER_ADAPTOR_INCLUDED
#include "agg_basics.h"
#include "agg_conv_adaptor_vcgen.h"
#include "agg_vcgen_vertex_sequence.h"
namespace agg
{
//=====================================================conv_marker_adaptor
template<class VertexSource, class Markers=null_markers>
struct conv_marker_adaptor :
public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>
{
typedef Markers marker_type;
typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers> base_type;
conv_marker_adaptor(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>(vs)
{
}
void shorten(double s) { base_type::generator().shorten(s); }
double shorten() const { return base_type::generator().shorten(); }
private:
conv_marker_adaptor(const conv_marker_adaptor<VertexSource, Markers>&);
const conv_marker_adaptor<VertexSource, Markers>&
operator = (const conv_marker_adaptor<VertexSource, Markers>&);
};
}
#endif

View file

@ -0,0 +1,48 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_SEGMENTATOR_INCLUDED
#define AGG_CONV_SEGMENTATOR_INCLUDED
#include "agg_basics.h"
#include "agg_conv_adaptor_vpgen.h"
#include "agg_vpgen_segmentator.h"
namespace agg
{
//========================================================conv_segmentator
template<class VertexSource>
struct conv_segmentator : public conv_adaptor_vpgen<VertexSource, vpgen_segmentator>
{
typedef conv_adaptor_vpgen<VertexSource, vpgen_segmentator> base_type;
conv_segmentator(VertexSource& vs) :
conv_adaptor_vpgen<VertexSource, vpgen_segmentator>(vs) {}
void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); }
double approximation_scale() const { return base_type::vpgen().approximation_scale(); }
private:
conv_segmentator(const conv_segmentator<VertexSource>&);
const conv_segmentator<VertexSource>&
operator = (const conv_segmentator<VertexSource>&);
};
}
#endif

View file

@ -0,0 +1,50 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_SHORTEN_PATH_INCLUDED
#define AGG_CONV_SHORTEN_PATH_INCLUDED
#include "agg_basics.h"
#include "agg_conv_adaptor_vcgen.h"
#include "agg_vcgen_vertex_sequence.h"
namespace agg
{
//=======================================================conv_shorten_path
template<class VertexSource> class conv_shorten_path :
public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>
{
public:
typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence> base_type;
conv_shorten_path(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>(vs)
{
}
void shorten(double s) { base_type::generator().shorten(s); }
double shorten() const { return base_type::generator().shorten(); }
private:
conv_shorten_path(const conv_shorten_path<VertexSource>&);
const conv_shorten_path<VertexSource>&
operator = (const conv_shorten_path<VertexSource>&);
};
}
#endif

View file

@ -0,0 +1,80 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Smooth polygon generator
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_SMOOTH_POLY1_INCLUDED
#define AGG_CONV_SMOOTH_POLY1_INCLUDED
#include "agg_basics.h"
#include "agg_vcgen_smooth_poly1.h"
#include "agg_conv_adaptor_vcgen.h"
#include "agg_conv_curve.h"
namespace agg
{
//-------------------------------------------------------conv_smooth_poly1
template<class VertexSource>
struct conv_smooth_poly1 :
public conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1>
{
typedef conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1> base_type;
conv_smooth_poly1(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1>(vs)
{
}
void smooth_value(double v) { base_type::generator().smooth_value(v); }
double smooth_value() const { return base_type::generator().smooth_value(); }
private:
conv_smooth_poly1(const conv_smooth_poly1<VertexSource>&);
const conv_smooth_poly1<VertexSource>&
operator = (const conv_smooth_poly1<VertexSource>&);
};
//-------------------------------------------------conv_smooth_poly1_curve
template<class VertexSource>
struct conv_smooth_poly1_curve :
public conv_curve<conv_smooth_poly1<VertexSource> >
{
conv_smooth_poly1_curve(VertexSource& vs) :
conv_curve<conv_smooth_poly1<VertexSource> >(m_smooth),
m_smooth(vs)
{
}
void smooth_value(double v) { m_smooth.generator().smooth_value(v); }
double smooth_value() const { return m_smooth.generator().smooth_value(); }
private:
conv_smooth_poly1_curve(const conv_smooth_poly1_curve<VertexSource>&);
const conv_smooth_poly1_curve<VertexSource>&
operator = (const conv_smooth_poly1_curve<VertexSource>&);
conv_smooth_poly1<VertexSource> m_smooth;
};
}
#endif

View file

@ -0,0 +1,73 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// conv_stroke
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_STROKE_INCLUDED
#define AGG_CONV_STROKE_INCLUDED
#include "agg_basics.h"
#include "agg_vcgen_stroke.h"
#include "agg_conv_adaptor_vcgen.h"
namespace agg
{
//-------------------------------------------------------------conv_stroke
template<class VertexSource, class Markers=null_markers>
struct conv_stroke :
public conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>
{
typedef Markers marker_type;
typedef conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> base_type;
conv_stroke(VertexSource& vs) :
conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(vs)
{
}
void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
line_join_e line_join() const { return base_type::generator().line_join(); }
inner_join_e inner_join() const { return base_type::generator().inner_join(); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
double width() const { return base_type::generator().width(); }
double miter_limit() const { return base_type::generator().miter_limit(); }
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
double approximation_scale() const { return base_type::generator().approximation_scale(); }
void shorten(double s) { base_type::generator().shorten(s); }
double shorten() const { return base_type::generator().shorten(); }
private:
conv_stroke(const conv_stroke<VertexSource, Markers>&);
const conv_stroke<VertexSource, Markers>&
operator = (const conv_stroke<VertexSource, Markers>&);
};
}
#endif

View file

@ -0,0 +1,68 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class conv_transform
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_TRANSFORM_INCLUDED
#define AGG_CONV_TRANSFORM_INCLUDED
#include "agg_basics.h"
#include "agg_trans_affine.h"
namespace agg
{
//----------------------------------------------------------conv_transform
template<class VertexSource, class Transformer=trans_affine> class conv_transform
{
public:
conv_transform(VertexSource& source, const Transformer& tr) :
m_source(&source), m_trans(&tr) {}
void attach(VertexSource& source) { m_source = &source; }
void rewind(unsigned path_id)
{
m_source->rewind(path_id);
}
unsigned vertex(double* x, double* y)
{
unsigned cmd = m_source->vertex(x, y);
if(is_vertex(cmd))
{
m_trans->transform(x, y);
}
return cmd;
}
void transformer(const Transformer& tr)
{
m_trans = &tr;
}
private:
conv_transform(const conv_transform<VertexSource>&);
const conv_transform<VertexSource>&
operator = (const conv_transform<VertexSource>&);
VertexSource* m_source;
const Transformer* m_trans;
};
}
#endif

View file

@ -0,0 +1,52 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CONV_UNCLOSE_POLYGON_INCLUDED
#define AGG_CONV_UNCLOSE_POLYGON_INCLUDED
#include "agg_basics.h"
namespace agg
{
//====================================================conv_unclose_polygon
template<class VertexSource> class conv_unclose_polygon
{
public:
explicit conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {}
void attach(VertexSource& source) { m_source = &source; }
void rewind(unsigned path_id)
{
m_source->rewind(path_id);
}
unsigned vertex(double* x, double* y)
{
unsigned cmd = m_source->vertex(x, y);
if(is_end_poly(cmd)) cmd &= ~path_flags_close;
return cmd;
}
private:
conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
const conv_unclose_polygon<VertexSource>&
operator = (const conv_unclose_polygon<VertexSource>&);
VertexSource* m_source;
};
}
#endif

610
3party/agg/agg_curves.cpp Normal file
View file

@ -0,0 +1,610 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#include <math.h>
#include <3party/agg/agg_curves.h>
#include <3party/agg/agg_math.h>
namespace agg
{
//------------------------------------------------------------------------
// const double curve_distance_epsilon = 1e-30;
const double curve_collinearity_epsilon = 1e-30;
const double curve_angle_tolerance_epsilon = 0.01;
enum curve_recursion_limit_e { curve_recursion_limit = 32 };
//------------------------------------------------------------------------
void curve3_inc::approximation_scale(double s)
{
m_scale = s;
}
//------------------------------------------------------------------------
double curve3_inc::approximation_scale() const
{
return m_scale;
}
//------------------------------------------------------------------------
void curve3_inc::init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_start_x = x1;
m_start_y = y1;
m_end_x = x3;
m_end_y = y3;
double dx1 = x2 - x1;
double dy1 = y2 - y1;
double dx2 = x3 - x2;
double dy2 = y3 - y2;
double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2);
m_num_steps = uround(len * 0.25 * m_scale);
if(m_num_steps < 4)
{
m_num_steps = 4;
}
double subdivide_step = 1.0 / m_num_steps;
double subdivide_step2 = subdivide_step * subdivide_step;
double tmpx = (x1 - x2 * 2.0 + x3) * subdivide_step2;
double tmpy = (y1 - y2 * 2.0 + y3) * subdivide_step2;
m_saved_fx = m_fx = x1;
m_saved_fy = m_fy = y1;
m_saved_dfx = m_dfx = tmpx + (x2 - x1) * (2.0 * subdivide_step);
m_saved_dfy = m_dfy = tmpy + (y2 - y1) * (2.0 * subdivide_step);
m_ddfx = tmpx * 2.0;
m_ddfy = tmpy * 2.0;
m_step = m_num_steps;
}
//------------------------------------------------------------------------
void curve3_inc::rewind(unsigned)
{
if(m_num_steps == 0)
{
m_step = -1;
return;
}
m_step = m_num_steps;
m_fx = m_saved_fx;
m_fy = m_saved_fy;
m_dfx = m_saved_dfx;
m_dfy = m_saved_dfy;
}
//------------------------------------------------------------------------
unsigned curve3_inc::vertex(double* x, double* y)
{
if(m_step < 0) return path_cmd_stop;
if(m_step == m_num_steps)
{
*x = m_start_x;
*y = m_start_y;
--m_step;
return path_cmd_move_to;
}
if(m_step == 0)
{
*x = m_end_x;
*y = m_end_y;
--m_step;
return path_cmd_line_to;
}
m_fx += m_dfx;
m_fy += m_dfy;
m_dfx += m_ddfx;
m_dfy += m_ddfy;
*x = m_fx;
*y = m_fy;
--m_step;
return path_cmd_line_to;
}
//------------------------------------------------------------------------
void curve3_div::init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_points.remove_all();
m_distance_tolerance_square = 0.5 / m_approximation_scale;
m_distance_tolerance_square *= m_distance_tolerance_square;
bezier(x1, y1, x2, y2, x3, y3);
m_count = 0;
}
//------------------------------------------------------------------------
void curve3_div::recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
unsigned level)
{
if(level > curve_recursion_limit)
{
return;
}
// Calculate all the mid-points of the line segments
//----------------------
double x12 = (x1 + x2) / 2;
double y12 = (y1 + y2) / 2;
double x23 = (x2 + x3) / 2;
double y23 = (y2 + y3) / 2;
double x123 = (x12 + x23) / 2;
double y123 = (y12 + y23) / 2;
double dx = x3-x1;
double dy = y3-y1;
double d = fabs(((x2 - x3) * dy - (y2 - y3) * dx));
double da;
if(d > curve_collinearity_epsilon)
{
// Regular case
//-----------------
if(d * d <= m_distance_tolerance_square * (dx*dx + dy*dy))
{
// If the curvature doesn't exceed the distance_tolerance value
// we tend to finish subdivisions.
//----------------------
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_d(x123, y123));
return;
}
// Angle & Cusp Condition
//----------------------
da = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1));
if(da >= pi) da = 2*pi - da;
if(da < m_angle_tolerance)
{
// Finally we can stop the recursion
//----------------------
m_points.add(point_d(x123, y123));
return;
}
}
}
else
{
// Collinear case
//------------------
da = dx*dx + dy*dy;
if(da == 0)
{
d = calc_sq_distance(x1, y1, x2, y2);
}
else
{
d = ((x2 - x1)*dx + (y2 - y1)*dy) / da;
if(d > 0 && d < 1)
{
// Simple collinear case, 1---2---3
// We can leave just two endpoints
return;
}
if(d <= 0) d = calc_sq_distance(x2, y2, x1, y1);
else if(d >= 1) d = calc_sq_distance(x2, y2, x3, y3);
else d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy);
}
if(d < m_distance_tolerance_square)
{
m_points.add(point_d(x2, y2));
return;
}
}
// Continue subdivision
//----------------------
recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1);
recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1);
}
//------------------------------------------------------------------------
void curve3_div::bezier(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_points.add(point_d(x1, y1));
recursive_bezier(x1, y1, x2, y2, x3, y3, 0);
m_points.add(point_d(x3, y3));
}
//------------------------------------------------------------------------
void curve4_inc::approximation_scale(double s)
{
m_scale = s;
}
//------------------------------------------------------------------------
double curve4_inc::approximation_scale() const
{
return m_scale;
}
//------------------------------------------------------------------------
// static double MSC60_fix_ICE(double v) { return v; }
//------------------------------------------------------------------------
void curve4_inc::init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
m_start_x = x1;
m_start_y = y1;
m_end_x = x4;
m_end_y = y4;
double dx1 = x2 - x1;
double dy1 = y2 - y1;
double dx2 = x3 - x2;
double dy2 = y3 - y2;
double dx3 = x4 - x3;
double dy3 = y4 - y3;
double len = (sqrt(dx1 * dx1 + dy1 * dy1) +
sqrt(dx2 * dx2 + dy2 * dy2) +
sqrt(dx3 * dx3 + dy3 * dy3)) * 0.25 * m_scale;
#if defined(_MSC_VER) && _MSC_VER <= 1200
m_num_steps = uround(MSC60_fix_ICE(len));
#else
m_num_steps = uround(len);
#endif
if(m_num_steps < 4)
{
m_num_steps = 4;
}
double subdivide_step = 1.0 / m_num_steps;
double subdivide_step2 = subdivide_step * subdivide_step;
double subdivide_step3 = subdivide_step * subdivide_step * subdivide_step;
double pre1 = 3.0 * subdivide_step;
double pre2 = 3.0 * subdivide_step2;
double pre4 = 6.0 * subdivide_step2;
double pre5 = 6.0 * subdivide_step3;
double tmp1x = x1 - x2 * 2.0 + x3;
double tmp1y = y1 - y2 * 2.0 + y3;
double tmp2x = (x2 - x3) * 3.0 - x1 + x4;
double tmp2y = (y2 - y3) * 3.0 - y1 + y4;
m_saved_fx = m_fx = x1;
m_saved_fy = m_fy = y1;
m_saved_dfx = m_dfx = (x2 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdivide_step3;
m_saved_dfy = m_dfy = (y2 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdivide_step3;
m_saved_ddfx = m_ddfx = tmp1x * pre4 + tmp2x * pre5;
m_saved_ddfy = m_ddfy = tmp1y * pre4 + tmp2y * pre5;
m_dddfx = tmp2x * pre5;
m_dddfy = tmp2y * pre5;
m_step = m_num_steps;
}
//------------------------------------------------------------------------
void curve4_inc::rewind(unsigned)
{
if(m_num_steps == 0)
{
m_step = -1;
return;
}
m_step = m_num_steps;
m_fx = m_saved_fx;
m_fy = m_saved_fy;
m_dfx = m_saved_dfx;
m_dfy = m_saved_dfy;
m_ddfx = m_saved_ddfx;
m_ddfy = m_saved_ddfy;
}
//------------------------------------------------------------------------
unsigned curve4_inc::vertex(double* x, double* y)
{
if(m_step < 0) return path_cmd_stop;
if(m_step == m_num_steps)
{
*x = m_start_x;
*y = m_start_y;
--m_step;
return path_cmd_move_to;
}
if(m_step == 0)
{
*x = m_end_x;
*y = m_end_y;
--m_step;
return path_cmd_line_to;
}
m_fx += m_dfx;
m_fy += m_dfy;
m_dfx += m_ddfx;
m_dfy += m_ddfy;
m_ddfx += m_dddfx;
m_ddfy += m_dddfy;
*x = m_fx;
*y = m_fy;
--m_step;
return path_cmd_line_to;
}
//------------------------------------------------------------------------
void curve4_div::init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
m_points.remove_all();
m_distance_tolerance_square = 0.5 / m_approximation_scale;
m_distance_tolerance_square *= m_distance_tolerance_square;
bezier(x1, y1, x2, y2, x3, y3, x4, y4);
m_count = 0;
}
//------------------------------------------------------------------------
void curve4_div::recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4,
unsigned level)
{
if(level > curve_recursion_limit)
{
return;
}
// Calculate all the mid-points of the line segments
//----------------------
double x12 = (x1 + x2) / 2;
double y12 = (y1 + y2) / 2;
double x23 = (x2 + x3) / 2;
double y23 = (y2 + y3) / 2;
double x34 = (x3 + x4) / 2;
double y34 = (y3 + y4) / 2;
double x123 = (x12 + x23) / 2;
double y123 = (y12 + y23) / 2;
double x234 = (x23 + x34) / 2;
double y234 = (y23 + y34) / 2;
double x1234 = (x123 + x234) / 2;
double y1234 = (y123 + y234) / 2;
// Try to approximate the full cubic curve by a single straight line
//------------------
double dx = x4-x1;
double dy = y4-y1;
double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx));
double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx));
double da1, da2, k;
switch((int(d2 > curve_collinearity_epsilon) << 1) +
int(d3 > curve_collinearity_epsilon))
{
case 0:
// All collinear OR p1==p4
//----------------------
k = dx*dx + dy*dy;
if(k == 0)
{
d2 = calc_sq_distance(x1, y1, x2, y2);
d3 = calc_sq_distance(x4, y4, x3, y3);
}
else
{
k = 1 / k;
da1 = x2 - x1;
da2 = y2 - y1;
d2 = k * (da1*dx + da2*dy);
da1 = x3 - x1;
da2 = y3 - y1;
d3 = k * (da1*dx + da2*dy);
if(d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1)
{
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
return;
}
if(d2 <= 0) d2 = calc_sq_distance(x2, y2, x1, y1);
else if(d2 >= 1) d2 = calc_sq_distance(x2, y2, x4, y4);
else d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy);
if(d3 <= 0) d3 = calc_sq_distance(x3, y3, x1, y1);
else if(d3 >= 1) d3 = calc_sq_distance(x3, y3, x4, y4);
else d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy);
}
if(d2 > d3)
{
if(d2 < m_distance_tolerance_square)
{
m_points.add(point_d(x2, y2));
return;
}
}
else
{
if(d3 < m_distance_tolerance_square)
{
m_points.add(point_d(x3, y3));
return;
}
}
break;
case 1:
// p1,p2,p4 are collinear, p3 is significant
//----------------------
if(d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy))
{
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_d(x23, y23));
return;
}
// Angle Condition
//----------------------
da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2));
if(da1 >= pi) da1 = 2*pi - da1;
if(da1 < m_angle_tolerance)
{
m_points.add(point_d(x2, y2));
m_points.add(point_d(x3, y3));
return;
}
if(m_cusp_limit != 0.0)
{
if(da1 > m_cusp_limit)
{
m_points.add(point_d(x3, y3));
return;
}
}
}
break;
case 2:
// p1,p3,p4 are collinear, p2 is significant
//----------------------
if(d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy))
{
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_d(x23, y23));
return;
}
// Angle Condition
//----------------------
da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1));
if(da1 >= pi) da1 = 2*pi - da1;
if(da1 < m_angle_tolerance)
{
m_points.add(point_d(x2, y2));
m_points.add(point_d(x3, y3));
return;
}
if(m_cusp_limit != 0.0)
{
if(da1 > m_cusp_limit)
{
m_points.add(point_d(x2, y2));
return;
}
}
}
break;
case 3:
// Regular case
//-----------------
if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy))
{
// If the curvature doesn't exceed the distance_tolerance value
// we tend to finish subdivisions.
//----------------------
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_d(x23, y23));
return;
}
// Angle & Cusp Condition
//----------------------
k = atan2(y3 - y2, x3 - x2);
da1 = fabs(k - atan2(y2 - y1, x2 - x1));
da2 = fabs(atan2(y4 - y3, x4 - x3) - k);
if(da1 >= pi) da1 = 2*pi - da1;
if(da2 >= pi) da2 = 2*pi - da2;
if(da1 + da2 < m_angle_tolerance)
{
// Finally we can stop the recursion
//----------------------
m_points.add(point_d(x23, y23));
return;
}
if(m_cusp_limit != 0.0)
{
if(da1 > m_cusp_limit)
{
m_points.add(point_d(x2, y2));
return;
}
if(da2 > m_cusp_limit)
{
m_points.add(point_d(x3, y3));
return;
}
}
}
break;
}
// Continue subdivision
//----------------------
recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1);
recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);
}
//------------------------------------------------------------------------
void curve4_div::bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
m_points.add(point_d(x1, y1));
recursive_bezier(x1, y1, x2, y2, x3, y3, x4, y4, 0);
m_points.add(point_d(x4, y4));
}
}

693
3party/agg/agg_curves.h Normal file
View file

@ -0,0 +1,693 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
// Copyright (C) 2005 Tony Juricic (tonygeek@yahoo.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_CURVES_INCLUDED
#define AGG_CURVES_INCLUDED
#include "agg_array.h"
namespace agg
{
// See Implementation agg_curves.cpp
//--------------------------------------------curve_approximation_method_e
enum curve_approximation_method_e
{
curve_inc,
curve_div
};
//--------------------------------------------------------------curve3_inc
class curve3_inc
{
public:
curve3_inc() :
m_num_steps(0), m_step(0), m_scale(1.0) { }
curve3_inc(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(x1, y1, x2, y2, x3, y3);
}
void reset() { m_num_steps = 0; m_step = -1; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3);
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_inc; }
void approximation_scale(double s);
double approximation_scale() const;
void angle_tolerance(double) {}
double angle_tolerance() const { return 0.0; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
int m_num_steps;
int m_step;
double m_scale;
double m_start_x;
double m_start_y;
double m_end_x;
double m_end_y;
double m_fx;
double m_fy;
double m_dfx;
double m_dfy;
double m_ddfx;
double m_ddfy;
double m_saved_fx;
double m_saved_fy;
double m_saved_dfx;
double m_saved_dfy;
};
//-------------------------------------------------------------curve3_div
class curve3_div
{
public:
curve3_div() :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{}
curve3_div(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{
init(x1, y1, x2, y2, x3, y3);
}
void reset() { m_points.remove_all(); m_count = 0; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3);
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_div; }
void approximation_scale(double s) { m_approximation_scale = s; }
double approximation_scale() const { return m_approximation_scale; }
void angle_tolerance(double a) { m_angle_tolerance = a; }
double angle_tolerance() const { return m_angle_tolerance; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned)
{
m_count = 0;
}
unsigned vertex(double* x, double* y)
{
if(m_count >= m_points.size()) return path_cmd_stop;
const point_d& p = m_points[m_count++];
*x = p.x;
*y = p.y;
return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
}
private:
void bezier(double x1, double y1,
double x2, double y2,
double x3, double y3);
void recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
unsigned level);
double m_approximation_scale;
double m_distance_tolerance_square;
double m_angle_tolerance;
unsigned m_count;
pod_bvector<point_d> m_points;
};
//-------------------------------------------------------------curve4_points
struct curve4_points
{
double cp[8];
curve4_points() {}
curve4_points(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
}
double operator [] (unsigned i) const { return cp[i]; }
double& operator [] (unsigned i) { return cp[i]; }
};
//-------------------------------------------------------------curve4_inc
class curve4_inc
{
public:
curve4_inc() :
m_num_steps(0), m_step(0), m_scale(1.0) { }
curve4_inc(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4_inc(const curve4_points& cp) :
m_num_steps(0), m_step(0), m_scale(1.0)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset() { m_num_steps = 0; m_step = -1; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const { return curve_inc; }
void approximation_scale(double s);
double approximation_scale() const;
void angle_tolerance(double) {}
double angle_tolerance() const { return 0.0; }
void cusp_limit(double) {}
double cusp_limit() const { return 0.0; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
int m_num_steps;
int m_step;
double m_scale;
double m_start_x;
double m_start_y;
double m_end_x;
double m_end_y;
double m_fx;
double m_fy;
double m_dfx;
double m_dfy;
double m_ddfx;
double m_ddfy;
double m_dddfx;
double m_dddfy;
double m_saved_fx;
double m_saved_fy;
double m_saved_dfx;
double m_saved_dfy;
double m_saved_ddfx;
double m_saved_ddfy;
};
//-------------------------------------------------------catrom_to_bezier
inline curve4_points catrom_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Catmull-Rom to Bezier
//
// 0 1 0 0
// -1/6 1 1/6 0
// 0 1/6 1 -1/6
// 0 0 1 0
//
return curve4_points(
x2,
y2,
(-x1 + 6*x2 + x3) / 6,
(-y1 + 6*y2 + y3) / 6,
( x2 + 6*x3 - x4) / 6,
( y2 + 6*y3 - y4) / 6,
x3,
y3);
}
//-----------------------------------------------------------------------
inline curve4_points
catrom_to_bezier(const curve4_points& cp)
{
return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//-----------------------------------------------------ubspline_to_bezier
inline curve4_points ubspline_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Uniform BSpline to Bezier
//
// 1/6 4/6 1/6 0
// 0 4/6 2/6 0
// 0 2/6 4/6 0
// 0 1/6 4/6 1/6
//
return curve4_points(
(x1 + 4*x2 + x3) / 6,
(y1 + 4*y2 + y3) / 6,
(4*x2 + 2*x3) / 6,
(4*y2 + 2*y3) / 6,
(2*x2 + 4*x3) / 6,
(2*y2 + 4*y3) / 6,
(x2 + 4*x3 + x4) / 6,
(y2 + 4*y3 + y4) / 6);
}
//-----------------------------------------------------------------------
inline curve4_points
ubspline_to_bezier(const curve4_points& cp)
{
return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//------------------------------------------------------hermite_to_bezier
inline curve4_points hermite_to_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
// Trans. matrix Hermite to Bezier
//
// 1 0 0 0
// 1 0 1/3 0
// 0 1 0 -1/3
// 0 1 0 0
//
return curve4_points(
x1,
y1,
(3*x1 + x3) / 3,
(3*y1 + y3) / 3,
(3*x2 - x4) / 3,
(3*y2 - y4) / 3,
x2,
y2);
}
//-----------------------------------------------------------------------
inline curve4_points
hermite_to_bezier(const curve4_points& cp)
{
return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3],
cp[4], cp[5], cp[6], cp[7]);
}
//-------------------------------------------------------------curve4_div
class curve4_div
{
public:
curve4_div() :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_cusp_limit(0.0),
m_count(0)
{}
curve4_div(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_cusp_limit(0.0),
m_count(0)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4_div(const curve4_points& cp) :
m_approximation_scale(1.0),
m_angle_tolerance(0.0),
m_count(0)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset() { m_points.remove_all(); m_count = 0; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void approximation_method(curve_approximation_method_e) {}
curve_approximation_method_e approximation_method() const
{
return curve_div;
}
void approximation_scale(double s) { m_approximation_scale = s; }
double approximation_scale() const { return m_approximation_scale; }
void angle_tolerance(double a) { m_angle_tolerance = a; }
double angle_tolerance() const { return m_angle_tolerance; }
void cusp_limit(double v)
{
m_cusp_limit = (v == 0.0) ? 0.0 : pi - v;
}
double cusp_limit() const
{
return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit;
}
void rewind(unsigned)
{
m_count = 0;
}
unsigned vertex(double* x, double* y)
{
if(m_count >= m_points.size()) return path_cmd_stop;
const point_d& p = m_points[m_count++];
*x = p.x;
*y = p.y;
return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
}
private:
void bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
void recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4,
unsigned level);
double m_approximation_scale;
double m_distance_tolerance_square;
double m_angle_tolerance;
double m_cusp_limit;
unsigned m_count;
pod_bvector<point_d> m_points;
};
//-----------------------------------------------------------------curve3
class curve3
{
public:
curve3() : m_approximation_method(curve_div) {}
curve3(double x1, double y1,
double x2, double y2,
double x3, double y3) :
m_approximation_method(curve_div)
{
init(x1, y1, x2, y2, x3, y3);
}
void reset()
{
m_curve_inc.reset();
m_curve_div.reset();
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.init(x1, y1, x2, y2, x3, y3);
}
else
{
m_curve_div.init(x1, y1, x2, y2, x3, y3);
}
}
void approximation_method(curve_approximation_method_e v)
{
m_approximation_method = v;
}
curve_approximation_method_e approximation_method() const
{
return m_approximation_method;
}
void approximation_scale(double s)
{
m_curve_inc.approximation_scale(s);
m_curve_div.approximation_scale(s);
}
double approximation_scale() const
{
return m_curve_inc.approximation_scale();
}
void angle_tolerance(double a)
{
m_curve_div.angle_tolerance(a);
}
double angle_tolerance() const
{
return m_curve_div.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve_div.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve_div.cusp_limit();
}
void rewind(unsigned path_id)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.rewind(path_id);
}
else
{
m_curve_div.rewind(path_id);
}
}
unsigned vertex(double* x, double* y)
{
if(m_approximation_method == curve_inc)
{
return m_curve_inc.vertex(x, y);
}
return m_curve_div.vertex(x, y);
}
private:
curve3_inc m_curve_inc;
curve3_div m_curve_div;
curve_approximation_method_e m_approximation_method;
};
//-----------------------------------------------------------------curve4
class curve4
{
public:
curve4() : m_approximation_method(curve_div) {}
curve4(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4) :
m_approximation_method(curve_div)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
curve4(const curve4_points& cp) :
m_approximation_method(curve_div)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void reset()
{
m_curve_inc.reset();
m_curve_div.reset();
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4);
}
else
{
m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4);
}
}
void init(const curve4_points& cp)
{
init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
}
void approximation_method(curve_approximation_method_e v)
{
m_approximation_method = v;
}
curve_approximation_method_e approximation_method() const
{
return m_approximation_method;
}
void approximation_scale(double s)
{
m_curve_inc.approximation_scale(s);
m_curve_div.approximation_scale(s);
}
double approximation_scale() const { return m_curve_inc.approximation_scale(); }
void angle_tolerance(double v)
{
m_curve_div.angle_tolerance(v);
}
double angle_tolerance() const
{
return m_curve_div.angle_tolerance();
}
void cusp_limit(double v)
{
m_curve_div.cusp_limit(v);
}
double cusp_limit() const
{
return m_curve_div.cusp_limit();
}
void rewind(unsigned path_id)
{
if(m_approximation_method == curve_inc)
{
m_curve_inc.rewind(path_id);
}
else
{
m_curve_div.rewind(path_id);
}
}
unsigned vertex(double* x, double* y)
{
if(m_approximation_method == curve_inc)
{
return m_curve_inc.vertex(x, y);
}
return m_curve_div.vertex(x, y);
}
private:
curve4_inc m_curve_inc;
curve4_div m_curve_div;
curve_approximation_method_e m_approximation_method;
};
}
#endif

290
3party/agg/agg_dda_line.h Normal file
View file

@ -0,0 +1,290 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// classes dda_line_interpolator, dda2_line_interpolator
//
//----------------------------------------------------------------------------
#ifndef AGG_DDA_LINE_INCLUDED
#define AGG_DDA_LINE_INCLUDED
#include <stdlib.h>
#include "agg_basics.h"
namespace agg
{
//===================================================dda_line_interpolator
template<int FractionShift, int YShift=0> class dda_line_interpolator
{
public:
//--------------------------------------------------------------------
dda_line_interpolator() {}
//--------------------------------------------------------------------
dda_line_interpolator(int y1, int y2, unsigned count) :
m_y(y1),
m_inc(((y2 - y1) << FractionShift) / int(count)),
m_dy(0)
{
}
//--------------------------------------------------------------------
void operator ++ ()
{
m_dy += m_inc;
}
//--------------------------------------------------------------------
void operator -- ()
{
m_dy -= m_inc;
}
//--------------------------------------------------------------------
void operator += (unsigned n)
{
m_dy += m_inc * n;
}
//--------------------------------------------------------------------
void operator -= (unsigned n)
{
m_dy -= m_inc * n;
}
//--------------------------------------------------------------------
int y() const { return m_y + (m_dy >> (FractionShift-YShift)); }
int dy() const { return m_dy; }
private:
int m_y;
int m_inc;
int m_dy;
};
//=================================================dda2_line_interpolator
class dda2_line_interpolator
{
public:
typedef int save_data_type;
enum save_size_e { save_size = 2 };
//--------------------------------------------------------------------
dda2_line_interpolator() {}
//-------------------------------------------- Forward-adjusted line
dda2_line_interpolator(int y1, int y2, int count) :
m_cnt(count <= 0 ? 1 : count),
m_lft((y2 - y1) / m_cnt),
m_rem((y2 - y1) % m_cnt),
m_mod(m_rem),
m_y(y1)
{
if(m_mod <= 0)
{
m_mod += count;
m_rem += count;
m_lft--;
}
m_mod -= count;
}
//-------------------------------------------- Backward-adjusted line
dda2_line_interpolator(int y1, int y2, int count, int) :
m_cnt(count <= 0 ? 1 : count),
m_lft((y2 - y1) / m_cnt),
m_rem((y2 - y1) % m_cnt),
m_mod(m_rem),
m_y(y1)
{
if(m_mod <= 0)
{
m_mod += count;
m_rem += count;
m_lft--;
}
}
//-------------------------------------------- Backward-adjusted line
dda2_line_interpolator(int y, int count) :
m_cnt(count <= 0 ? 1 : count),
m_lft(y / m_cnt),
m_rem(y % m_cnt),
m_mod(m_rem),
m_y(0)
{
if(m_mod <= 0)
{
m_mod += count;
m_rem += count;
m_lft--;
}
}
//--------------------------------------------------------------------
void save(save_data_type* data) const
{
data[0] = m_mod;
data[1] = m_y;
}
//--------------------------------------------------------------------
void load(const save_data_type* data)
{
m_mod = data[0];
m_y = data[1];
}
//--------------------------------------------------------------------
void operator++()
{
m_mod += m_rem;
m_y += m_lft;
if(m_mod > 0)
{
m_mod -= m_cnt;
m_y++;
}
}
//--------------------------------------------------------------------
void operator--()
{
if(m_mod <= m_rem)
{
m_mod += m_cnt;
m_y--;
}
m_mod -= m_rem;
m_y -= m_lft;
}
//--------------------------------------------------------------------
void adjust_forward()
{
m_mod -= m_cnt;
}
//--------------------------------------------------------------------
void adjust_backward()
{
m_mod += m_cnt;
}
//--------------------------------------------------------------------
int mod() const { return m_mod; }
int rem() const { return m_rem; }
int lft() const { return m_lft; }
//--------------------------------------------------------------------
int y() const { return m_y; }
private:
int m_cnt;
int m_lft;
int m_rem;
int m_mod;
int m_y;
};
//---------------------------------------------line_bresenham_interpolator
class line_bresenham_interpolator
{
public:
enum subpixel_scale_e
{
subpixel_shift = 8,
subpixel_scale = 1 << subpixel_shift,
subpixel_mask = subpixel_scale - 1
};
//--------------------------------------------------------------------
static int line_lr(int v) { return v >> subpixel_shift; }
//--------------------------------------------------------------------
line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
m_x1_lr(line_lr(x1)),
m_y1_lr(line_lr(y1)),
m_x2_lr(line_lr(x2)),
m_y2_lr(line_lr(y2)),
m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
abs(m_x2_lr - m_x1_lr)),
m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
m_interpolator(m_ver ? x1 : y1,
m_ver ? x2 : y2,
m_len)
{
}
//--------------------------------------------------------------------
bool is_ver() const { return m_ver; }
unsigned len() const { return m_len; }
int inc() const { return m_inc; }
//--------------------------------------------------------------------
void hstep()
{
++m_interpolator;
m_x1_lr += m_inc;
}
//--------------------------------------------------------------------
void vstep()
{
++m_interpolator;
m_y1_lr += m_inc;
}
//--------------------------------------------------------------------
int x1() const { return m_x1_lr; }
int y1() const { return m_y1_lr; }
int x2() const { return line_lr(m_interpolator.y()); }
int y2() const { return line_lr(m_interpolator.y()); }
int x2_hr() const { return m_interpolator.y(); }
int y2_hr() const { return m_interpolator.y(); }
private:
int m_x1_lr;
int m_y1_lr;
int m_x2_lr;
int m_y2_lr;
bool m_ver;
unsigned m_len;
int m_inc;
dda2_line_interpolator m_interpolator;
};
}
#endif

123
3party/agg/agg_ellipse.h Normal file
View file

@ -0,0 +1,123 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class ellipse
//
//----------------------------------------------------------------------------
#ifndef AGG_ELLIPSE_INCLUDED
#define AGG_ELLIPSE_INCLUDED
#include "agg_basics.h"
#include <math.h>
namespace agg
{
//----------------------------------------------------------------ellipse
class ellipse
{
public:
ellipse() :
m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_scale(1.0),
m_num(4), m_step(0), m_cw(false) {}
ellipse(double x, double y, double rx, double ry,
unsigned num_steps=0, bool cw=false) :
m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0),
m_num(num_steps), m_step(0), m_cw(cw)
{
if(m_num == 0) calc_num_steps();
}
void init(double x, double y, double rx, double ry,
unsigned num_steps=0, bool cw=false);
void approximation_scale(double scale);
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
void calc_num_steps();
double m_x;
double m_y;
double m_rx;
double m_ry;
double m_scale;
unsigned m_num;
unsigned m_step;
bool m_cw;
};
//------------------------------------------------------------------------
inline void ellipse::init(double x, double y, double rx, double ry,
unsigned num_steps, bool cw)
{
m_x = x;
m_y = y;
m_rx = rx;
m_ry = ry;
m_num = num_steps;
m_step = 0;
m_cw = cw;
if(m_num == 0) calc_num_steps();
}
//------------------------------------------------------------------------
inline void ellipse::approximation_scale(double scale)
{
m_scale = scale;
calc_num_steps();
}
//------------------------------------------------------------------------
inline void ellipse::calc_num_steps()
{
double ra = (fabs(m_rx) + fabs(m_ry)) / 2;
double da = acos(ra / (ra + 0.125 / m_scale)) * 2;
m_num = uround(2*pi / da);
}
//------------------------------------------------------------------------
inline void ellipse::rewind(unsigned)
{
m_step = 0;
}
//------------------------------------------------------------------------
inline unsigned ellipse::vertex(double* x, double* y)
{
if(m_step == m_num)
{
++m_step;
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
}
if(m_step > m_num) return path_cmd_stop;
double angle = double(m_step) / double(m_num) * 2.0 * pi;
if(m_cw) angle = 2.0 * pi - angle;
*x = m_x + cos(angle) * m_rx;
*y = m_y + sin(angle) * m_ry;
m_step++;
return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
}
}
#endif

View file

@ -0,0 +1,113 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Simple Bresenham interpolator for ellipsees
//
//----------------------------------------------------------------------------
#ifndef AGG_ELLIPSE_BRESENHAM_INCLUDED
#define AGG_ELLIPSE_BRESENHAM_INCLUDED
#include "agg_basics.h"
namespace agg
{
//------------------------------------------ellipse_bresenham_interpolator
class ellipse_bresenham_interpolator
{
public:
ellipse_bresenham_interpolator(int rx, int ry) :
m_rx2(rx * rx),
m_ry2(ry * ry),
m_two_rx2(m_rx2 << 1),
m_two_ry2(m_ry2 << 1),
m_dx(0),
m_dy(0),
m_inc_x(0),
m_inc_y(-ry * m_two_rx2),
m_cur_f(0)
{}
int dx() const { return m_dx; }
int dy() const { return m_dy; }
void operator++ ()
{
int mx, my, mxy, min_m;
int fx, fy, fxy;
mx = fx = m_cur_f + m_inc_x + m_ry2;
if(mx < 0) mx = -mx;
my = fy = m_cur_f + m_inc_y + m_rx2;
if(my < 0) my = -my;
mxy = fxy = m_cur_f + m_inc_x + m_ry2 + m_inc_y + m_rx2;
if(mxy < 0) mxy = -mxy;
min_m = mx;
bool flag = true;
if(min_m > my)
{
min_m = my;
flag = false;
}
m_dx = m_dy = 0;
if(min_m > mxy)
{
m_inc_x += m_two_ry2;
m_inc_y += m_two_rx2;
m_cur_f = fxy;
m_dx = 1;
m_dy = 1;
return;
}
if(flag)
{
m_inc_x += m_two_ry2;
m_cur_f = fx;
m_dx = 1;
return;
}
m_inc_y += m_two_rx2;
m_cur_f = fy;
m_dy = 1;
}
private:
int m_rx2;
int m_ry2;
int m_two_rx2;
int m_two_ry2;
int m_dx;
int m_dy;
int m_inc_x;
int m_inc_y;
int m_cur_f;
};
}
#endif

View file

@ -0,0 +1,59 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_EMBEDDED_RASTER_FONTS_INCLUDED
#define AGG_EMBEDDED_RASTER_FONTS_INCLUDED
#include "agg_basics.h"
namespace agg
{
extern const int8u gse4x6[];
extern const int8u gse4x8[];
extern const int8u gse5x7[];
extern const int8u gse5x9[];
extern const int8u gse6x12[];
extern const int8u gse6x9[];
extern const int8u gse7x11[];
extern const int8u gse7x11_bold[];
extern const int8u gse7x15[];
extern const int8u gse7x15_bold[];
extern const int8u gse8x16[];
extern const int8u gse8x16_bold[];
extern const int8u mcs11_prop[];
extern const int8u mcs11_prop_condensed[];
extern const int8u mcs12_prop[];
extern const int8u mcs13_prop[];
extern const int8u mcs5x10_mono[];
extern const int8u mcs5x11_mono[];
extern const int8u mcs6x10_mono[];
extern const int8u mcs6x11_mono[];
extern const int8u mcs7x12_mono_high[];
extern const int8u mcs7x12_mono_low[];
extern const int8u verdana12[];
extern const int8u verdana12_bold[];
extern const int8u verdana13[];
extern const int8u verdana13_bold[];
extern const int8u verdana14[];
extern const int8u verdana14_bold[];
extern const int8u verdana16[];
extern const int8u verdana16_bold[];
extern const int8u verdana17[];
extern const int8u verdana17_bold[];
extern const int8u verdana18[];
extern const int8u verdana18_bold[];
}
#endif

View file

@ -0,0 +1,409 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_FONT_CACHE_MANAGER_INCLUDED
#define AGG_FONT_CACHE_MANAGER_INCLUDED
#include <string.h>
#include "agg_array.h"
namespace agg
{
//---------------------------------------------------------glyph_data_type
enum glyph_data_type
{
glyph_data_invalid = 0,
glyph_data_mono = 1,
glyph_data_gray8 = 2,
glyph_data_outline = 3
};
//-------------------------------------------------------------glyph_cache
struct glyph_cache
{
unsigned glyph_index;
int8u* data;
unsigned data_size;
glyph_data_type data_type;
rect_i bounds;
double advance_x;
double advance_y;
};
//--------------------------------------------------------------font_cache
class font_cache
{
public:
enum block_size_e { block_size = 16384-16 };
//--------------------------------------------------------------------
font_cache() :
m_allocator(block_size),
m_font_signature(0)
{}
//--------------------------------------------------------------------
void signature(const char* font_signature)
{
m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1);
strcpy(m_font_signature, font_signature);
memset(m_glyphs, 0, sizeof(m_glyphs));
}
//--------------------------------------------------------------------
bool font_is(const char* font_signature) const
{
return strcmp(font_signature, m_font_signature) == 0;
}
//--------------------------------------------------------------------
const glyph_cache* find_glyph(unsigned glyph_code) const
{
unsigned msb = (glyph_code >> 8) & 0xFF;
if(m_glyphs[msb])
{
return m_glyphs[msb][glyph_code & 0xFF];
}
return 0;
}
//--------------------------------------------------------------------
glyph_cache* cache_glyph(unsigned glyph_code,
unsigned glyph_index,
unsigned data_size,
glyph_data_type data_type,
const rect_i& bounds,
double advance_x,
double advance_y)
{
unsigned msb = (glyph_code >> 8) & 0xFF;
if(m_glyphs[msb] == 0)
{
m_glyphs[msb] =
(glyph_cache**)m_allocator.allocate(sizeof(glyph_cache*) * 256,
sizeof(glyph_cache*));
memset(m_glyphs[msb], 0, sizeof(glyph_cache*) * 256);
}
unsigned lsb = glyph_code & 0xFF;
if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite
glyph_cache* glyph =
(glyph_cache*)m_allocator.allocate(sizeof(glyph_cache),
sizeof(double));
glyph->glyph_index = glyph_index;
glyph->data = m_allocator.allocate(data_size);
glyph->data_size = data_size;
glyph->data_type = data_type;
glyph->bounds = bounds;
glyph->advance_x = advance_x;
glyph->advance_y = advance_y;
return m_glyphs[msb][lsb] = glyph;
}
private:
block_allocator m_allocator;
glyph_cache** m_glyphs[256];
char* m_font_signature;
};
//---------------------------------------------------------font_cache_pool
class font_cache_pool
{
public:
//--------------------------------------------------------------------
~font_cache_pool()
{
unsigned i;
for(i = 0; i < m_num_fonts; ++i)
{
obj_allocator<font_cache>::deallocate(m_fonts[i]);
}
pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts);
}
//--------------------------------------------------------------------
font_cache_pool(unsigned max_fonts=32) :
m_fonts(pod_allocator<font_cache*>::allocate(max_fonts)),
m_max_fonts(max_fonts),
m_num_fonts(0),
m_cur_font(0)
{}
//--------------------------------------------------------------------
void font(const char* font_signature, bool reset_cache = false)
{
int idx = find_font(font_signature);
if(idx >= 0)
{
if(reset_cache)
{
obj_allocator<font_cache>::deallocate(m_fonts[idx]);
m_fonts[idx] = obj_allocator<font_cache>::allocate();
m_fonts[idx]->signature(font_signature);
}
m_cur_font = m_fonts[idx];
}
else
{
if(m_num_fonts >= m_max_fonts)
{
obj_allocator<font_cache>::deallocate(m_fonts[0]);
memcpy(m_fonts,
m_fonts + 1,
(m_max_fonts - 1) * sizeof(font_cache*));
m_num_fonts = m_max_fonts - 1;
}
m_fonts[m_num_fonts] = obj_allocator<font_cache>::allocate();
m_fonts[m_num_fonts]->signature(font_signature);
m_cur_font = m_fonts[m_num_fonts];
++m_num_fonts;
}
}
//--------------------------------------------------------------------
const font_cache* font() const
{
return m_cur_font;
}
//--------------------------------------------------------------------
const glyph_cache* find_glyph(unsigned glyph_code) const
{
if(m_cur_font) return m_cur_font->find_glyph(glyph_code);
return 0;
}
//--------------------------------------------------------------------
glyph_cache* cache_glyph(unsigned glyph_code,
unsigned glyph_index,
unsigned data_size,
glyph_data_type data_type,
const rect_i& bounds,
double advance_x,
double advance_y)
{
if(m_cur_font)
{
return m_cur_font->cache_glyph(glyph_code,
glyph_index,
data_size,
data_type,
bounds,
advance_x,
advance_y);
}
return 0;
}
//--------------------------------------------------------------------
int find_font(const char* font_signature)
{
unsigned i;
for(i = 0; i < m_num_fonts; i++)
{
if(m_fonts[i]->font_is(font_signature)) return int(i);
}
return -1;
}
private:
font_cache** m_fonts;
unsigned m_max_fonts;
unsigned m_num_fonts;
font_cache* m_cur_font;
};
//------------------------------------------------------------------------
enum glyph_rendering
{
glyph_ren_native_mono,
glyph_ren_native_gray8,
glyph_ren_outline,
glyph_ren_agg_mono,
glyph_ren_agg_gray8
};
//------------------------------------------------------font_cache_manager
template<class FontEngine> class font_cache_manager
{
public:
typedef FontEngine font_engine_type;
typedef font_cache_manager<FontEngine> self_type;
typedef typename font_engine_type::path_adaptor_type path_adaptor_type;
typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type;
typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type;
typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type;
typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type;
//--------------------------------------------------------------------
font_cache_manager(font_engine_type& engine, unsigned max_fonts=32) :
m_fonts(max_fonts),
m_engine(engine),
m_change_stamp(-1),
m_prev_glyph(0),
m_last_glyph(0)
{}
//--------------------------------------------------------------------
void reset_last_glyph()
{
m_prev_glyph = m_last_glyph = 0;
}
//--------------------------------------------------------------------
const glyph_cache* glyph(unsigned glyph_code)
{
synchronize();
const glyph_cache* gl = m_fonts.find_glyph(glyph_code);
if(gl)
{
m_prev_glyph = m_last_glyph;
return m_last_glyph = gl;
}
else
{
if(m_engine.prepare_glyph(glyph_code))
{
m_prev_glyph = m_last_glyph;
m_last_glyph = m_fonts.cache_glyph(glyph_code,
m_engine.glyph_index(),
m_engine.data_size(),
m_engine.data_type(),
m_engine.bounds(),
m_engine.advance_x(),
m_engine.advance_y());
m_engine.write_glyph_to(m_last_glyph->data);
return m_last_glyph;
}
}
return 0;
}
//--------------------------------------------------------------------
void init_embedded_adaptors(const glyph_cache* gl,
double x, double y,
double scale=1.0)
{
if(gl)
{
switch(gl->data_type)
{
default: return;
case glyph_data_mono:
m_mono_adaptor.init(gl->data, gl->data_size, x, y);
break;
case glyph_data_gray8:
m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
break;
case glyph_data_outline:
m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
break;
}
}
}
//--------------------------------------------------------------------
path_adaptor_type& path_adaptor() { return m_path_adaptor; }
gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; }
gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; }
mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; }
mono_scanline_type& mono_scanline() { return m_mono_scanline; }
//--------------------------------------------------------------------
const glyph_cache* perv_glyph() const { return m_prev_glyph; }
const glyph_cache* last_glyph() const { return m_last_glyph; }
//--------------------------------------------------------------------
bool add_kerning(double* x, double* y)
{
if(m_prev_glyph && m_last_glyph)
{
return m_engine.add_kerning(m_prev_glyph->glyph_index,
m_last_glyph->glyph_index,
x, y);
}
return false;
}
//--------------------------------------------------------------------
void precache(unsigned from, unsigned to)
{
for(; from <= to; ++from) glyph(from);
}
//--------------------------------------------------------------------
void reset_cache()
{
m_fonts.font(m_engine.font_signature(), true);
m_change_stamp = m_engine.change_stamp();
m_prev_glyph = m_last_glyph = 0;
}
private:
//--------------------------------------------------------------------
font_cache_manager(const self_type&);
const self_type& operator = (const self_type&);
//--------------------------------------------------------------------
void synchronize()
{
if(m_change_stamp != m_engine.change_stamp())
{
m_fonts.font(m_engine.font_signature());
m_change_stamp = m_engine.change_stamp();
m_prev_glyph = m_last_glyph = 0;
}
}
font_cache_pool m_fonts;
font_engine_type& m_engine;
int m_change_stamp;
double m_dx;
double m_dy;
const glyph_cache* m_prev_glyph;
const glyph_cache* m_last_glyph;
path_adaptor_type m_path_adaptor;
gray8_adaptor_type m_gray8_adaptor;
gray8_scanline_type m_gray8_scanline;
mono_adaptor_type m_mono_adaptor;
mono_scanline_type m_mono_scanline;
};
}
#endif

View file

@ -0,0 +1,311 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_FONT_CACHE_MANAGER2_INCLUDED
#define AGG_FONT_CACHE_MANAGER2_INCLUDED
#include <cassert>
#include <exception>
#include <string.h>
#include "agg_array.h"
namespace agg {
namespace fman {
//---------------------------------------------------------glyph_data_type
enum glyph_data_type
{
glyph_data_invalid = 0,
glyph_data_mono = 1,
glyph_data_gray8 = 2,
glyph_data_outline = 3
};
//-------------------------------------------------------------cached_glyph
struct cached_glyph
{
void * cached_font;
unsigned glyph_code;
unsigned glyph_index;
int8u* data;
unsigned data_size;
glyph_data_type data_type;
rect_i bounds;
double advance_x;
double advance_y;
};
//--------------------------------------------------------------cached_glyphs
class cached_glyphs
{
public:
enum block_size_e { block_size = 16384-16 };
//--------------------------------------------------------------------
cached_glyphs()
: m_allocator(block_size)
{ memset(m_glyphs, 0, sizeof(m_glyphs)); }
//--------------------------------------------------------------------
const cached_glyph* find_glyph(unsigned glyph_code) const
{
unsigned msb = (glyph_code >> 8) & 0xFF;
if(m_glyphs[msb])
{
return m_glyphs[msb][glyph_code & 0xFF];
}
return 0;
}
//--------------------------------------------------------------------
cached_glyph* cache_glyph(
void * cached_font,
unsigned glyph_code,
unsigned glyph_index,
unsigned data_size,
glyph_data_type data_type,
const rect_i& bounds,
double advance_x,
double advance_y)
{
unsigned msb = (glyph_code >> 8) & 0xFF;
if(m_glyphs[msb] == 0)
{
m_glyphs[msb] =
(cached_glyph**)m_allocator.allocate(sizeof(cached_glyph*) * 256,
sizeof(cached_glyph*));
memset(m_glyphs[msb], 0, sizeof(cached_glyph*) * 256);
}
unsigned lsb = glyph_code & 0xFF;
if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite
cached_glyph* glyph =
(cached_glyph*)m_allocator.allocate(sizeof(cached_glyph),
sizeof(double));
glyph->cached_font = cached_font;
glyph->glyph_code = glyph_code;
glyph->glyph_index = glyph_index;
glyph->data = m_allocator.allocate(data_size);
glyph->data_size = data_size;
glyph->data_type = data_type;
glyph->bounds = bounds;
glyph->advance_x = advance_x;
glyph->advance_y = advance_y;
return m_glyphs[msb][lsb] = glyph;
}
private:
block_allocator m_allocator;
cached_glyph** m_glyphs[256];
};
//------------------------------------------------------------------------
enum glyph_rendering
{
glyph_ren_native_mono,
glyph_ren_native_gray8,
glyph_ren_outline,
glyph_ren_agg_mono,
glyph_ren_agg_gray8
};
//------------------------------------------------------font_cache_manager
template<class FontEngine> class font_cache_manager
{
public:
typedef FontEngine font_engine_type;
typedef font_cache_manager<FontEngine> self_type;
typedef typename font_engine_type::path_adaptor_type path_adaptor_type;
typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type;
typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type;
typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type;
typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type;
struct cached_font
{
cached_font(
font_engine_type& engine,
typename FontEngine::loaded_face *face,
double height,
double width,
bool hinting,
glyph_rendering rendering )
: m_engine( engine )
, m_face( face )
, m_height( height )
, m_width( width )
, m_hinting( hinting )
, m_rendering( rendering )
{
select_face();
m_face_height=m_face->height();
m_face_width=m_face->width();
m_face_ascent=m_face->ascent();
m_face_descent=m_face->descent();
m_face_ascent_b=m_face->ascent_b();
m_face_descent_b=m_face->descent_b();
}
double height() const
{
return m_face_height;
}
double width() const
{
return m_face_width;
}
double ascent() const
{
return m_face_ascent;
}
double descent() const
{
return m_face_descent;
}
double ascent_b() const
{
return m_face_ascent_b;
}
double descent_b() const
{
return m_face_descent_b;
}
bool add_kerning( const cached_glyph *first, const cached_glyph *second, double* x, double* y)
{
if( !first || !second )
return false;
select_face();
return m_face->add_kerning(
first->glyph_index, second->glyph_index, x, y );
}
void select_face()
{
m_face->select_instance( m_height, m_width, m_hinting, m_rendering );
}
const cached_glyph *get_glyph(unsigned cp)
{
const cached_glyph *glyph=m_glyphs.find_glyph(cp);
if( glyph==0 )
{
typename FontEngine::prepared_glyph prepared;
select_face();
bool success=m_face->prepare_glyph(cp, &prepared);
if( success )
{
glyph=m_glyphs.cache_glyph(
this,
prepared.glyph_code,
prepared.glyph_index,
prepared.data_size,
prepared.data_type,
prepared.bounds,
prepared.advance_x,
prepared.advance_y );
assert( glyph!=0 );
m_face->write_glyph_to(&prepared,glyph->data);
}
}
return glyph;
}
font_engine_type& m_engine;
typename FontEngine::loaded_face *m_face;
double m_height;
double m_width;
bool m_hinting;
glyph_rendering m_rendering;
double m_face_height;
double m_face_width;
double m_face_ascent;
double m_face_descent;
double m_face_ascent_b;
double m_face_descent_b;
cached_glyphs m_glyphs;
};
//--------------------------------------------------------------------
font_cache_manager(font_engine_type& engine, unsigned max_fonts=32)
:m_engine(engine)
{ }
//--------------------------------------------------------------------
void init_embedded_adaptors(const cached_glyph* gl,
double x, double y,
double scale=1.0)
{
if(gl)
{
switch(gl->data_type)
{
default: return;
case glyph_data_mono:
m_mono_adaptor.init(gl->data, gl->data_size, x, y);
break;
case glyph_data_gray8:
m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
break;
case glyph_data_outline:
m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
break;
}
}
}
//--------------------------------------------------------------------
path_adaptor_type& path_adaptor() { return m_path_adaptor; }
gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; }
gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; }
mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; }
mono_scanline_type& mono_scanline() { return m_mono_scanline; }
private:
//--------------------------------------------------------------------
font_cache_manager(const self_type&);
const self_type& operator = (const self_type&);
font_engine_type& m_engine;
path_adaptor_type m_path_adaptor;
gray8_adaptor_type m_gray8_adaptor;
gray8_scanline_type m_gray8_scanline;
mono_adaptor_type m_mono_adaptor;
mono_scanline_type m_mono_scanline;
};
}
}
#endif

View file

@ -0,0 +1,132 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_GAMMA_FUNCTIONS_INCLUDED
#define AGG_GAMMA_FUNCTIONS_INCLUDED
#include <math.h>
#include "agg_basics.h"
namespace agg
{
//===============================================================gamma_none
struct gamma_none
{
double operator()(double x) const { return x; }
};
//==============================================================gamma_power
class gamma_power
{
public:
gamma_power() : m_gamma(1.0) {}
gamma_power(double g) : m_gamma(g) {}
void gamma(double g) { m_gamma = g; }
double gamma() const { return m_gamma; }
double operator() (double x) const
{
return pow(x, m_gamma);
}
private:
double m_gamma;
};
//==========================================================gamma_threshold
class gamma_threshold
{
public:
gamma_threshold() : m_threshold(0.5) {}
gamma_threshold(double t) : m_threshold(t) {}
void threshold(double t) { m_threshold = t; }
double threshold() const { return m_threshold; }
double operator() (double x) const
{
return (x < m_threshold) ? 0.0 : 1.0;
}
private:
double m_threshold;
};
//============================================================gamma_linear
class gamma_linear
{
public:
gamma_linear() : m_start(0.0), m_end(1.0) {}
gamma_linear(double s, double e) : m_start(s), m_end(e) {}
void set(double s, double e) { m_start = s; m_end = e; }
void start(double s) { m_start = s; }
void end(double e) { m_end = e; }
double start() const { return m_start; }
double end() const { return m_end; }
double operator() (double x) const
{
if(x < m_start) return 0.0;
if(x > m_end) return 1.0;
return (x - m_start) / (m_end - m_start);
}
private:
double m_start;
double m_end;
};
//==========================================================gamma_multiply
class gamma_multiply
{
public:
gamma_multiply() : m_mul(1.0) {}
gamma_multiply(double v) : m_mul(v) {}
void value(double v) { m_mul = v; }
double value() const { return m_mul; }
double operator() (double x) const
{
double y = x * m_mul;
if(y > 1.0) y = 1.0;
return y;
}
private:
double m_mul;
};
inline double sRGB_to_linear(double x)
{
return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4);
}
inline double linear_to_sRGB(double x)
{
return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055);
}
}
#endif

305
3party/agg/agg_gamma_lut.h Normal file
View file

@ -0,0 +1,305 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_GAMMA_LUT_INCLUDED
#define AGG_GAMMA_LUT_INCLUDED
#include <math.h>
#include "agg_basics.h"
#include "agg_gamma_functions.h"
namespace agg
{
template<class LoResT=int8u,
class HiResT=int8u,
unsigned GammaShift=8,
unsigned HiResShift=8> class gamma_lut
{
public:
typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
enum gamma_scale_e
{
gamma_shift = GammaShift,
gamma_size = 1 << gamma_shift,
gamma_mask = gamma_size - 1
};
enum hi_res_scale_e
{
hi_res_shift = HiResShift,
hi_res_size = 1 << hi_res_shift,
hi_res_mask = hi_res_size - 1
};
~gamma_lut()
{
pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size);
pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size);
}
gamma_lut() :
m_gamma(1.0),
m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
{
unsigned i;
for(i = 0; i < gamma_size; i++)
{
m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift));
}
for(i = 0; i < hi_res_size; i++)
{
m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift));
}
}
gamma_lut(double g) :
m_gamma(1.0),
m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
{
gamma(g);
}
void gamma(double g)
{
m_gamma = g;
unsigned i;
for(i = 0; i < gamma_size; i++)
{
m_dir_gamma[i] = (HiResT)
uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask));
}
double inv_g = 1.0 / g;
for(i = 0; i < hi_res_size; i++)
{
m_inv_gamma[i] = (LoResT)
uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask));
}
}
double gamma() const
{
return m_gamma;
}
HiResT dir(LoResT v) const
{
return m_dir_gamma[unsigned(v)];
}
LoResT inv(HiResT v) const
{
return m_inv_gamma[unsigned(v)];
}
private:
gamma_lut(const self_type&);
const self_type& operator = (const self_type&);
double m_gamma;
HiResT* m_dir_gamma;
LoResT* m_inv_gamma;
};
//
// sRGB support classes
//
// Optimized sRGB lookup table. The direct conversion (sRGB to linear)
// is a straightforward lookup. The inverse conversion (linear to sRGB)
// is implemented using binary search.
template<class LinearType>
class sRGB_lut_base
{
public:
LinearType dir(int8u v) const
{
return m_dir_table[v];
}
int8u inv(LinearType v) const
{
// Unrolled binary search.
int8u x = 0;
if (v > m_inv_table[128]) x = 128;
if (v > m_inv_table[x + 64]) x += 64;
if (v > m_inv_table[x + 32]) x += 32;
if (v > m_inv_table[x + 16]) x += 16;
if (v > m_inv_table[x + 8]) x += 8;
if (v > m_inv_table[x + 4]) x += 4;
if (v > m_inv_table[x + 2]) x += 2;
if (v > m_inv_table[x + 1]) x += 1;
return x;
}
protected:
LinearType m_dir_table[256];
LinearType m_inv_table[256];
// Only derived classes may instantiate.
sRGB_lut_base()
{
}
};
// sRGB_lut - implements sRGB conversion for the various types.
// Base template is undefined, specializations are provided below.
template<class LinearType>
class sRGB_lut;
template<>
class sRGB_lut<float> : public sRGB_lut_base<float>
{
public:
sRGB_lut()
{
// Generate lookup tables.
m_dir_table[0] = 0;
m_inv_table[0] = 0;
for (unsigned i = 1; i <= 255; ++i)
{
// Floating-point RGB is in range [0,1].
m_dir_table[i] = float(sRGB_to_linear(i / 255.0));
m_inv_table[i] = float(sRGB_to_linear((i - 0.5) / 255.0));
}
}
};
template<>
class sRGB_lut<int16u> : public sRGB_lut_base<int16u>
{
public:
sRGB_lut()
{
// Generate lookup tables.
m_dir_table[0] = 0;
m_inv_table[0] = 0;
for (unsigned i = 1; i <= 255; ++i)
{
// 16-bit RGB is in range [0,65535].
m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0));
m_inv_table[i] = uround(65535.0 * sRGB_to_linear((i - 0.5) / 255.0));
}
}
};
template<>
class sRGB_lut<int8u> : public sRGB_lut_base<int8u>
{
public:
sRGB_lut()
{
// Generate lookup tables.
m_dir_table[0] = 0;
m_inv_table[0] = 0;
for (unsigned i = 1; i <= 255; ++i)
{
// 8-bit RGB is handled with simple bidirectional lookup tables.
m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0));
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0));
}
}
int8u inv(int8u v) const
{
// In this case, the inverse transform is a simple lookup.
return m_inv_table[v];
}
};
// Common base class for sRGB_conv objects. Defines an internal
// sRGB_lut object so that users don't have to.
template<class T>
class sRGB_conv_base
{
public:
static T rgb_from_sRGB(int8u x)
{
return lut.dir(x);
}
static int8u rgb_to_sRGB(T x)
{
return lut.inv(x);
}
private:
static sRGB_lut<T> lut;
};
// Definition of sRGB_conv_base::lut. Due to the fact that this a template,
// we don't need to place the definition in a cpp file. Hurrah.
template<class T>
sRGB_lut<T> sRGB_conv_base<T>::lut;
// Wrapper for sRGB-linear conversion.
// Base template is undefined, specializations are provided below.
template<class T>
class sRGB_conv;
template<>
class sRGB_conv<float> : public sRGB_conv_base<float>
{
public:
static float alpha_from_sRGB(int8u x)
{
return float(x / 255.0);
}
static int8u alpha_to_sRGB(float x)
{
if (x <= 0) return 0;
else if (x >= 1) return 255;
else return int8u(0.5 + x * 255);
}
};
template<>
class sRGB_conv<int16u> : public sRGB_conv_base<int16u>
{
public:
static int16u alpha_from_sRGB(int8u x)
{
return (x << 8) | x;
}
static int8u alpha_to_sRGB(int16u x)
{
return x >> 8;
}
};
template<>
class sRGB_conv<int8u> : public sRGB_conv_base<int8u>
{
public:
static int8u alpha_from_sRGB(int8u x)
{
return x;
}
static int8u alpha_to_sRGB(int8u x)
{
return x;
}
};
}
#endif

View file

@ -0,0 +1,155 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_GLYPH_RASTER_BIN_INCLUDED
#define AGG_GLYPH_RASTER_BIN_INCLUDED
#include <string.h>
#include "agg_basics.h"
namespace agg
{
//========================================================glyph_raster_bin
template<class ColorT> class glyph_raster_bin
{
public:
typedef ColorT color_type;
//--------------------------------------------------------------------
struct glyph_rect
{
int x1,y1,x2,y2;
double dx, dy;
};
//--------------------------------------------------------------------
glyph_raster_bin(const int8u* font) :
m_font(font),
m_big_endian(false)
{
int t = 1;
if(*(char*)&t == 0) m_big_endian = true;
memset(m_span, 0, sizeof(m_span));
}
//--------------------------------------------------------------------
const int8u* font() const { return m_font; }
void font(const int8u* f) { m_font = f; }
//--------------------------------------------------------------------
double height() const { return m_font[0]; }
double base_line() const { return m_font[1]; }
//--------------------------------------------------------------------
template<class CharT>
double width(const CharT* str) const
{
unsigned start_char = m_font[2];
unsigned num_chars = m_font[3];
unsigned w = 0;
while(*str)
{
unsigned glyph = *str;
const int8u* bits = m_font + 4 + num_chars * 2 +
value(m_font + 4 + (glyph - start_char) * 2);
w += *bits;
++str;
}
return w;
}
//--------------------------------------------------------------------
void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip)
{
unsigned start_char = m_font[2];
unsigned num_chars = m_font[3];
m_bits = m_font + 4 + num_chars * 2 +
value(m_font + 4 + (glyph - start_char) * 2);
m_glyph_width = *m_bits++;
m_glyph_byte_width = (m_glyph_width + 7) >> 3;
r->x1 = int(x);
r->x2 = r->x1 + m_glyph_width - 1;
if(flip)
{
r->y1 = int(y) - m_font[0] + m_font[1];
r->y2 = r->y1 + m_font[0] - 1;
}
else
{
r->y1 = int(y) - m_font[1] + 1;
r->y2 = r->y1 + m_font[0] - 1;
}
r->dx = m_glyph_width;
r->dy = 0;
}
//--------------------------------------------------------------------
const cover_type* span(unsigned i)
{
i = m_font[0] - i - 1;
const int8u* bits = m_bits + i * m_glyph_byte_width;
unsigned j;
unsigned val = *bits;
unsigned nb = 0;
for(j = 0; j < m_glyph_width; ++j)
{
m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none);
val <<= 1;
if(++nb >= 8)
{
val = *++bits;
nb = 0;
}
}
return m_span;
}
private:
//--------------------------------------------------------------------
int16u value(const int8u* p) const
{
int16u v;
if(m_big_endian)
{
*(int8u*)&v = p[1];
*((int8u*)&v + 1) = p[0];
}
else
{
*(int8u*)&v = p[0];
*((int8u*)&v + 1) = p[1];
}
return v;
}
//--------------------------------------------------------------------
const int8u* m_font;
bool m_big_endian;
cover_type m_span[32];
const int8u* m_bits;
unsigned m_glyph_width;
unsigned m_glyph_byte_width;
};
}
#endif

View file

@ -0,0 +1,244 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_GRADIENT_LUT_INCLUDED
#define AGG_GRADIENT_LUT_INCLUDED
#include "agg_array.h"
#include "agg_dda_line.h"
#include "agg_color_rgba.h"
#include "agg_color_gray.h"
namespace agg
{
//======================================================color_interpolator
template<class ColorT> struct color_interpolator
{
public:
typedef ColorT color_type;
color_interpolator(const color_type& c1,
const color_type& c2,
unsigned len) :
m_c1(c1),
m_c2(c2),
m_len(len),
m_count(0)
{}
void operator ++ ()
{
++m_count;
}
color_type color() const
{
return m_c1.gradient(m_c2, double(m_count) / m_len);
}
private:
color_type m_c1;
color_type m_c2;
unsigned m_len;
unsigned m_count;
};
//========================================================================
// Fast specialization for rgba8
template<> struct color_interpolator<rgba8>
{
public:
typedef rgba8 color_type;
color_interpolator(const color_type& c1,
const color_type& c2,
unsigned len) :
r(c1.r, c2.r, len),
g(c1.g, c2.g, len),
b(c1.b, c2.b, len),
a(c1.a, c2.a, len)
{}
void operator ++ ()
{
++r; ++g; ++b; ++a;
}
color_type color() const
{
return color_type(r.y(), g.y(), b.y(), a.y());
}
private:
agg::dda_line_interpolator<14> r, g, b, a;
};
//========================================================================
// Fast specialization for gray8
template<> struct color_interpolator<gray8>
{
public:
typedef gray8 color_type;
color_interpolator(const color_type& c1,
const color_type& c2,
unsigned len) :
v(c1.v, c2.v, len),
a(c1.a, c2.a, len)
{}
void operator ++ ()
{
++v; ++a;
}
color_type color() const
{
return color_type(v.y(), a.y());
}
private:
agg::dda_line_interpolator<14> v,a;
};
//============================================================gradient_lut
template<class ColorInterpolator,
unsigned ColorLutSize=256> class gradient_lut
{
public:
typedef ColorInterpolator interpolator_type;
typedef typename interpolator_type::color_type color_type;
enum { color_lut_size = ColorLutSize };
//--------------------------------------------------------------------
gradient_lut() : m_color_lut(color_lut_size) {}
// Build Gradient Lut
// First, call remove_all(), then add_color() at least twice,
// then build_lut(). Argument "offset" in add_color must be
// in range [0...1] and defines a color stop as it is described
// in SVG specification, section Gradients and Patterns.
// The simplest linear gradient is:
// gradient_lut.add_color(0.0, start_color);
// gradient_lut.add_color(1.0, end_color);
//--------------------------------------------------------------------
void remove_all();
void add_color(double offset, const color_type& color);
void build_lut();
// Size-index Interface. This class can be used directly as the
// ColorF in span_gradient. All it needs is two access methods
// size() and operator [].
//--------------------------------------------------------------------
static unsigned size()
{
return color_lut_size;
}
const color_type& operator [] (unsigned i) const
{
return m_color_lut[i];
}
private:
//--------------------------------------------------------------------
struct color_point
{
double offset;
color_type color;
color_point() {}
color_point(double off, const color_type& c) :
offset(off), color(c)
{
if(offset < 0.0) offset = 0.0;
if(offset > 1.0) offset = 1.0;
}
};
typedef agg::pod_bvector<color_point, 4> color_profile_type;
typedef agg::pod_array<color_type> color_lut_type;
static bool offset_less(const color_point& a, const color_point& b)
{
return a.offset < b.offset;
}
static bool offset_equal(const color_point& a, const color_point& b)
{
return a.offset == b.offset;
}
//--------------------------------------------------------------------
color_profile_type m_color_profile;
color_lut_type m_color_lut;
};
//------------------------------------------------------------------------
template<class T, unsigned S>
void gradient_lut<T,S>::remove_all()
{
m_color_profile.remove_all();
}
//------------------------------------------------------------------------
template<class T, unsigned S>
void gradient_lut<T,S>::add_color(double offset, const color_type& color)
{
m_color_profile.add(color_point(offset, color));
}
//------------------------------------------------------------------------
template<class T, unsigned S>
void gradient_lut<T,S>::build_lut()
{
quick_sort(m_color_profile, offset_less);
m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal));
if(m_color_profile.size() >= 2)
{
unsigned i;
unsigned start = uround(m_color_profile[0].offset * color_lut_size);
unsigned end;
color_type c = m_color_profile[0].color;
for(i = 0; i < start; i++)
{
m_color_lut[i] = c;
}
for(i = 1; i < m_color_profile.size(); i++)
{
end = uround(m_color_profile[i].offset * color_lut_size);
interpolator_type ci(m_color_profile[i-1].color,
m_color_profile[i ].color,
end - start + 1);
while(start < end)
{
m_color_lut[start] = ci.color();
++ci;
++start;
}
}
c = m_color_profile.last().color;
for(; end < m_color_lut.size(); end++)
{
m_color_lut[end] = c;
}
}
}
}
#endif

153
3party/agg/agg_gsv_text.h Normal file
View file

@ -0,0 +1,153 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Class gsv_text
//
//----------------------------------------------------------------------------
#ifndef AGG_GSV_TEXT_INCLUDED
#define AGG_GSV_TEXT_INCLUDED
#include "agg_array.h"
#include "agg_conv_stroke.h"
#include "agg_conv_transform.h"
namespace agg
{
//---------------------------------------------------------------gsv_text
//
// See Implementation agg_gsv_text.cpp
//
class gsv_text
{
enum status
{
initial,
next_char,
start_glyph,
glyph
};
public:
gsv_text();
void font(const void* font);
void flip(bool flip_y) { m_flip = flip_y; }
void load_font(const char* file);
void size(double height, double width=0.0);
void space(double space);
void line_space(double line_space);
void start_point(double x, double y);
void text(const char* text);
double text_width();
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
// not supposed to be copied
gsv_text(const gsv_text&);
const gsv_text& operator = (const gsv_text&);
int16u value(const int8u* p) const
{
int16u v;
if(m_big_endian)
{
*(int8u*)&v = p[1];
*((int8u*)&v + 1) = p[0];
}
else
{
*(int8u*)&v = p[0];
*((int8u*)&v + 1) = p[1];
}
return v;
}
private:
double m_x;
double m_y;
double m_start_x;
double m_width;
double m_height;
double m_space;
double m_line_space;
char m_chr[2];
char* m_text;
pod_array<char> m_text_buf;
char* m_cur_chr;
const void* m_font;
pod_array<char> m_loaded_font;
status m_status;
bool m_big_endian;
bool m_flip;
int8u* m_indices;
int8* m_glyphs;
int8* m_bglyph;
int8* m_eglyph;
double m_w;
double m_h;
};
//--------------------------------------------------------gsv_text_outline
template<class Transformer = trans_affine> class gsv_text_outline
{
public:
gsv_text_outline(gsv_text& text, 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);
}
void rewind(unsigned path_id)
{
m_trans.rewind(path_id);
m_polyline.line_join(round_join);
m_polyline.line_cap(round_cap);
}
unsigned vertex(double* x, double* y)
{
return m_trans.vertex(x, y);
}
private:
conv_stroke<gsv_text> m_polyline;
conv_transform<conv_stroke<gsv_text>, Transformer> m_trans;
};
}
#endif

View file

@ -0,0 +1,481 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_IMAGE_ACCESSORS_INCLUDED
#define AGG_IMAGE_ACCESSORS_INCLUDED
#include "agg_basics.h"
namespace agg
{
//-----------------------------------------------------image_accessor_clip
template<class PixFmt> class image_accessor_clip
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::order_type order_type;
typedef typename pixfmt_type::value_type value_type;
enum pix_width_e { pix_width = pixfmt_type::pix_width };
image_accessor_clip() {}
explicit image_accessor_clip(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)
{
m_pixf = &pixf;
}
void background_color(const color_type& bk)
{
pixfmt_type::make_pix(m_bk_buf, bk);
}
private:
AGG_INLINE const int8u* pixel() const
{
if(m_y >= 0 && m_y < (int)m_pixf->height() &&
m_x >= 0 && m_x < (int)m_pixf->width())
{
return m_pixf->pix_ptr(m_x, m_y);
}
return m_bk_buf;
}
public:
AGG_INLINE const int8u* span(int x, int y, unsigned len)
{
m_x = m_x0 = x;
m_y = y;
if(y >= 0 && y < (int)m_pixf->height() &&
x >= 0 && x+(int)len <= (int)m_pixf->width())
{
return m_pix_ptr = m_pixf->pix_ptr(x, y);
}
m_pix_ptr = 0;
return pixel();
}
AGG_INLINE const int8u* next_x()
{
if(m_pix_ptr) return m_pix_ptr += pix_width;
++m_x;
return pixel();
}
AGG_INLINE const int8u* next_y()
{
++m_y;
m_x = m_x0;
if(m_pix_ptr &&
m_y >= 0 && m_y < (int)m_pixf->height())
{
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
}
m_pix_ptr = 0;
return pixel();
}
private:
const pixfmt_type* m_pixf;
int8u m_bk_buf[pix_width];
int m_x, m_x0, m_y;
const int8u* m_pix_ptr;
};
//--------------------------------------------------image_accessor_no_clip
template<class PixFmt> class image_accessor_no_clip
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::order_type order_type;
typedef typename pixfmt_type::value_type value_type;
enum pix_width_e { pix_width = pixfmt_type::pix_width };
image_accessor_no_clip() {}
explicit image_accessor_no_clip(const pixfmt_type& pixf) :
m_pixf(&pixf)
{}
void attach(const pixfmt_type& pixf)
{
m_pixf = &pixf;
}
AGG_INLINE const int8u* span(int x, int y, unsigned)
{
m_x = x;
m_y = y;
return m_pix_ptr = m_pixf->pix_ptr(x, y);
}
AGG_INLINE const int8u* next_x()
{
return m_pix_ptr += pix_width;
}
AGG_INLINE const int8u* next_y()
{
++m_y;
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
}
private:
const pixfmt_type* m_pixf;
int m_x, m_y;
const int8u* m_pix_ptr;
};
//----------------------------------------------------image_accessor_clone
template<class PixFmt> class image_accessor_clone
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::order_type order_type;
typedef typename pixfmt_type::value_type value_type;
enum pix_width_e { pix_width = pixfmt_type::pix_width };
image_accessor_clone() {}
explicit image_accessor_clone(const pixfmt_type& pixf) :
m_pixf(&pixf)
{}
void attach(const pixfmt_type& pixf)
{
m_pixf = &pixf;
}
private:
AGG_INLINE const int8u* pixel() const
{
register int x = m_x;
register int y = m_y;
if(x < 0) x = 0;
if(y < 0) y = 0;
if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1;
if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1;
return m_pixf->pix_ptr(x, y);
}
public:
AGG_INLINE const int8u* span(int x, int y, unsigned len)
{
m_x = m_x0 = x;
m_y = y;
if(y >= 0 && y < (int)m_pixf->height() &&
x >= 0 && x+len <= (int)m_pixf->width())
{
return m_pix_ptr = m_pixf->pix_ptr(x, y);
}
m_pix_ptr = 0;
return pixel();
}
AGG_INLINE const int8u* next_x()
{
if(m_pix_ptr) return m_pix_ptr += pix_width;
++m_x;
return pixel();
}
AGG_INLINE const int8u* next_y()
{
++m_y;
m_x = m_x0;
if(m_pix_ptr &&
m_y >= 0 && m_y < (int)m_pixf->height())
{
return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
}
m_pix_ptr = 0;
return pixel();
}
private:
const pixfmt_type* m_pixf;
int m_x, m_x0, m_y;
const int8u* m_pix_ptr;
};
//-----------------------------------------------------image_accessor_wrap
template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::order_type order_type;
typedef typename pixfmt_type::value_type value_type;
enum pix_width_e { pix_width = pixfmt_type::pix_width };
image_accessor_wrap() {}
explicit image_accessor_wrap(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_add) % m_size;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
if(m_value >= m_size) m_value = 0;
return m_value;
}
private:
unsigned m_size;
unsigned m_add;
unsigned m_mask;
unsigned m_value;
};
//-------------------------------------------------------wrap_mode_reflect
class wrap_mode_reflect
{
public:
wrap_mode_reflect() {}
wrap_mode_reflect(unsigned size) :
m_size(size),
m_size2(size * 2),
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
m_value(0)
{}
AGG_INLINE unsigned operator() (int v)
{
m_value = (unsigned(v) + m_add) % m_size2;
if(m_value >= m_size) return m_size2 - m_value - 1;
return m_value;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
if(m_value >= m_size2) m_value = 0;
if(m_value >= m_size) return m_size2 - m_value - 1;
return m_value;
}
private:
unsigned m_size;
unsigned m_size2;
unsigned m_add;
unsigned m_value;
};
//--------------------------------------------------wrap_mode_reflect_pow2
class wrap_mode_reflect_pow2
{
public:
wrap_mode_reflect_pow2() {}
wrap_mode_reflect_pow2(unsigned size) : m_value(0)
{
m_mask = 1;
m_size = 1;
while(m_mask < size)
{
m_mask = (m_mask << 1) | 1;
m_size <<= 1;
}
}
AGG_INLINE unsigned operator() (int v)
{
m_value = unsigned(v) & m_mask;
if(m_value >= m_size) return m_mask - m_value;
return m_value;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
m_value &= m_mask;
if(m_value >= m_size) return m_mask - m_value;
return m_value;
}
private:
unsigned m_size;
unsigned m_mask;
unsigned m_value;
};
//---------------------------------------------wrap_mode_reflect_auto_pow2
class wrap_mode_reflect_auto_pow2
{
public:
wrap_mode_reflect_auto_pow2() {}
wrap_mode_reflect_auto_pow2(unsigned size) :
m_size(size),
m_size2(size * 2),
m_add(m_size2 * (0x3FFFFFFF / m_size2)),
m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
m_value(0)
{}
AGG_INLINE unsigned operator() (int v)
{
m_value = m_mask ? unsigned(v) & m_mask :
(unsigned(v) + m_add) % m_size2;
if(m_value >= m_size) return m_size2 - m_value - 1;
return m_value;
}
AGG_INLINE unsigned operator++ ()
{
++m_value;
if(m_value >= m_size2) m_value = 0;
if(m_value >= m_size) return m_size2 - m_value - 1;
return m_value;
}
private:
unsigned m_size;
unsigned m_size2;
unsigned m_add;
unsigned m_mask;
unsigned m_value;
};
}
#endif

View file

@ -0,0 +1,448 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Image transformation filters,
// Filtering classes (image_filter_lut, image_filter),
// Basic filter shape classes
//----------------------------------------------------------------------------
#ifndef AGG_IMAGE_FILTERS_INCLUDED
#define AGG_IMAGE_FILTERS_INCLUDED
#include "agg_array.h"
#include "agg_math.h"
namespace agg
{
// See Implementation agg_image_filters.cpp
enum image_filter_scale_e
{
image_filter_shift = 14, //----image_filter_shift
image_filter_scale = 1 << image_filter_shift, //----image_filter_scale
image_filter_mask = image_filter_scale - 1 //----image_filter_mask
};
enum image_subpixel_scale_e
{
image_subpixel_shift = 8, //----image_subpixel_shift
image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale
image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask
};
//-----------------------------------------------------image_filter_lut
class image_filter_lut
{
public:
template<class FilterF> void calculate(const FilterF& filter,
bool normalization=true)
{
double r = filter.radius();
realloc_lut(r);
unsigned i;
unsigned pivot = diameter() << (image_subpixel_shift - 1);
for(i = 0; i < pivot; i++)
{
double x = double(i) / double(image_subpixel_scale);
double y = filter.calc_weight(x);
m_weight_array[pivot + i] =
m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale);
}
unsigned end = (diameter() << image_subpixel_shift) - 1;
m_weight_array[0] = m_weight_array[end];
if(normalization)
{
normalize();
}
}
image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {}
template<class FilterF> image_filter_lut(const FilterF& filter,
bool normalization=true)
{
calculate(filter, normalization);
}
double radius() const { return m_radius; }
unsigned diameter() const { return m_diameter; }
int start() const { return m_start; }
const int16* weight_array() const { return &m_weight_array[0]; }
void normalize();
private:
void realloc_lut(double radius);
image_filter_lut(const image_filter_lut&);
const image_filter_lut& operator = (const image_filter_lut&);
double m_radius;
unsigned m_diameter;
int m_start;
pod_array<int16> m_weight_array;
};
//--------------------------------------------------------image_filter
template<class FilterF> class image_filter : public image_filter_lut
{
public:
image_filter()
{
calculate(m_filter_function);
}
private:
FilterF m_filter_function;
};
//-----------------------------------------------image_filter_bilinear
struct image_filter_bilinear
{
static double radius() { return 1.0; }
static double calc_weight(double x)
{
return 1.0 - x;
}
};
//-----------------------------------------------image_filter_hanning
struct image_filter_hanning
{
static double radius() { return 1.0; }
static double calc_weight(double x)
{
return 0.5 + 0.5 * cos(pi * x);
}
};
//-----------------------------------------------image_filter_hamming
struct image_filter_hamming
{
static double radius() { return 1.0; }
static double calc_weight(double x)
{
return 0.54 + 0.46 * cos(pi * x);
}
};
//-----------------------------------------------image_filter_hermite
struct image_filter_hermite
{
static double radius() { return 1.0; }
static double calc_weight(double x)
{
return (2.0 * x - 3.0) * x * x + 1.0;
}
};
//------------------------------------------------image_filter_quadric
struct image_filter_quadric
{
static double radius() { return 1.5; }
static double calc_weight(double x)
{
double t;
if(x < 0.5) return 0.75 - x * x;
if(x < 1.5) {t = x - 1.5; return 0.5 * t * t;}
return 0.0;
}
};
//------------------------------------------------image_filter_bicubic
class image_filter_bicubic
{
static double pow3(double x)
{
return (x <= 0.0) ? 0.0 : x * x * x;
}
public:
static double radius() { return 2.0; }
static double calc_weight(double x)
{
return
(1.0/6.0) *
(pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1));
}
};
//-------------------------------------------------image_filter_kaiser
class image_filter_kaiser
{
double a;
double i0a;
double epsilon;
public:
image_filter_kaiser(double b = 6.33) :
a(b), epsilon(1e-12)
{
i0a = 1.0 / bessel_i0(b);
}
static double radius() { return 1.0; }
double calc_weight(double x) const
{
return bessel_i0(a * sqrt(1. - x * x)) * i0a;
}
private:
double bessel_i0(double x) const
{
int i;
double sum, y, t;
sum = 1.;
y = x * x / 4.;
t = y;
for(i = 2; t > epsilon; i++)
{
sum += t;
t *= (double)y / (i * i);
}
return sum;
}
};
//----------------------------------------------image_filter_catrom
struct image_filter_catrom
{
static double radius() { return 2.0; }
static double calc_weight(double x)
{
if(x < 1.0) return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
if(x < 2.0) return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
return 0.;
}
};
//---------------------------------------------image_filter_mitchell
class image_filter_mitchell
{
double p0, p2, p3;
double q0, q1, q2, q3;
public:
image_filter_mitchell(double b = 1.0/3.0, double c = 1.0/3.0) :
p0((6.0 - 2.0 * b) / 6.0),
p2((-18.0 + 12.0 * b + 6.0 * c) / 6.0),
p3((12.0 - 9.0 * b - 6.0 * c) / 6.0),
q0((8.0 * b + 24.0 * c) / 6.0),
q1((-12.0 * b - 48.0 * c) / 6.0),
q2((6.0 * b + 30.0 * c) / 6.0),
q3((-b - 6.0 * c) / 6.0)
{}
static double radius() { return 2.0; }
double calc_weight(double x) const
{
if(x < 1.0) return p0 + x * x * (p2 + x * p3);
if(x < 2.0) return q0 + x * (q1 + x * (q2 + x * q3));
return 0.0;
}
};
//----------------------------------------------image_filter_spline16
struct image_filter_spline16
{
static double radius() { return 2.0; }
static double calc_weight(double x)
{
if(x < 1.0)
{
return ((x - 9.0/5.0 ) * x - 1.0/5.0 ) * x + 1.0;
}
return ((-1.0/3.0 * (x-1) + 4.0/5.0) * (x-1) - 7.0/15.0 ) * (x-1);
}
};
//---------------------------------------------image_filter_spline36
struct image_filter_spline36
{
static double radius() { return 3.0; }
static double calc_weight(double x)
{
if(x < 1.0)
{
return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0;
}
if(x < 2.0)
{
return ((-6.0/11.0 * (x-1) + 270.0/209.0) * (x-1) - 156.0/ 209.0) * (x-1);
}
return ((1.0/11.0 * (x-2) - 45.0/209.0) * (x-2) + 26.0/209.0) * (x-2);
}
};
//----------------------------------------------image_filter_gaussian
struct image_filter_gaussian
{
static double radius() { return 2.0; }
static double calc_weight(double x)
{
return exp(-2.0 * x * x) * sqrt(2.0 / pi);
}
};
//------------------------------------------------image_filter_bessel
struct image_filter_bessel
{
static double radius() { return 3.2383; }
static double calc_weight(double x)
{
return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x);
}
};
//-------------------------------------------------image_filter_sinc
class image_filter_sinc
{
public:
image_filter_sinc(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
double radius() const { return m_radius; }
double calc_weight(double x) const
{
if(x == 0.0) return 1.0;
x *= pi;
return sin(x) / x;
}
private:
double m_radius;
};
//-----------------------------------------------image_filter_lanczos
class image_filter_lanczos
{
public:
image_filter_lanczos(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
double radius() const { return m_radius; }
double calc_weight(double x) const
{
if(x == 0.0) return 1.0;
if(x > m_radius) return 0.0;
x *= pi;
double xr = x / m_radius;
return (sin(x) / x) * (sin(xr) / xr);
}
private:
double m_radius;
};
//----------------------------------------------image_filter_blackman
class image_filter_blackman
{
public:
image_filter_blackman(double r) : m_radius(r < 2.0 ? 2.0 : r) {}
double radius() const { return m_radius; }
double calc_weight(double x) const
{
if(x == 0.0) return 1.0;
if(x > m_radius) return 0.0;
x *= pi;
double xr = x / m_radius;
return (sin(x) / x) * (0.42 + 0.5*cos(xr) + 0.08*cos(2*xr));
}
private:
double m_radius;
};
//------------------------------------------------image_filter_sinc36
class image_filter_sinc36 : public image_filter_sinc
{ public: image_filter_sinc36() : image_filter_sinc(3.0){} };
//------------------------------------------------image_filter_sinc64
class image_filter_sinc64 : public image_filter_sinc
{ public: image_filter_sinc64() : image_filter_sinc(4.0){} };
//-----------------------------------------------image_filter_sinc100
class image_filter_sinc100 : public image_filter_sinc
{ public: image_filter_sinc100() : image_filter_sinc(5.0){} };
//-----------------------------------------------image_filter_sinc144
class image_filter_sinc144 : public image_filter_sinc
{ public: image_filter_sinc144() : image_filter_sinc(6.0){} };
//-----------------------------------------------image_filter_sinc196
class image_filter_sinc196 : public image_filter_sinc
{ public: image_filter_sinc196() : image_filter_sinc(7.0){} };
//-----------------------------------------------image_filter_sinc256
class image_filter_sinc256 : public image_filter_sinc
{ public: image_filter_sinc256() : image_filter_sinc(8.0){} };
//---------------------------------------------image_filter_lanczos36
class image_filter_lanczos36 : public image_filter_lanczos
{ public: image_filter_lanczos36() : image_filter_lanczos(3.0){} };
//---------------------------------------------image_filter_lanczos64
class image_filter_lanczos64 : public image_filter_lanczos
{ public: image_filter_lanczos64() : image_filter_lanczos(4.0){} };
//--------------------------------------------image_filter_lanczos100
class image_filter_lanczos100 : public image_filter_lanczos
{ public: image_filter_lanczos100() : image_filter_lanczos(5.0){} };
//--------------------------------------------image_filter_lanczos144
class image_filter_lanczos144 : public image_filter_lanczos
{ public: image_filter_lanczos144() : image_filter_lanczos(6.0){} };
//--------------------------------------------image_filter_lanczos196
class image_filter_lanczos196 : public image_filter_lanczos
{ public: image_filter_lanczos196() : image_filter_lanczos(7.0){} };
//--------------------------------------------image_filter_lanczos256
class image_filter_lanczos256 : public image_filter_lanczos
{ public: image_filter_lanczos256() : image_filter_lanczos(8.0){} };
//--------------------------------------------image_filter_blackman36
class image_filter_blackman36 : public image_filter_blackman
{ public: image_filter_blackman36() : image_filter_blackman(3.0){} };
//--------------------------------------------image_filter_blackman64
class image_filter_blackman64 : public image_filter_blackman
{ public: image_filter_blackman64() : image_filter_blackman(4.0){} };
//-------------------------------------------image_filter_blackman100
class image_filter_blackman100 : public image_filter_blackman
{ public: image_filter_blackman100() : image_filter_blackman(5.0){} };
//-------------------------------------------image_filter_blackman144
class image_filter_blackman144 : public image_filter_blackman
{ public: image_filter_blackman144() : image_filter_blackman(6.0){} };
//-------------------------------------------image_filter_blackman196
class image_filter_blackman196 : public image_filter_blackman
{ public: image_filter_blackman196() : image_filter_blackman(7.0){} };
//-------------------------------------------image_filter_blackman256
class image_filter_blackman256 : public image_filter_blackman
{ public: image_filter_blackman256() : image_filter_blackman(8.0){} };
}
#endif

View file

@ -0,0 +1,189 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_LINE_AA_BASICS_INCLUDED
#define AGG_LINE_AA_BASICS_INCLUDED
#include <stdlib.h>
#include "agg_basics.h"
namespace agg
{
// See Implementation agg_line_aa_basics.cpp
//-------------------------------------------------------------------------
enum line_subpixel_scale_e
{
line_subpixel_shift = 8, //----line_subpixel_shift
line_subpixel_scale = 1 << line_subpixel_shift, //----line_subpixel_scale
line_subpixel_mask = line_subpixel_scale - 1, //----line_subpixel_mask
line_max_coord = (1 << 28) - 1, //----line_max_coord
line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length
};
//-------------------------------------------------------------------------
enum line_mr_subpixel_scale_e
{
line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift
line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale
line_mr_subpixel_mask = line_mr_subpixel_scale - 1 //----line_mr_subpixel_mask
};
//------------------------------------------------------------------line_mr
AGG_INLINE int line_mr(int x)
{
return x >> (line_subpixel_shift - line_mr_subpixel_shift);
}
//-------------------------------------------------------------------line_hr
AGG_INLINE int line_hr(int x)
{
return x << (line_subpixel_shift - line_mr_subpixel_shift);
}
//---------------------------------------------------------------line_dbl_hr
AGG_INLINE int line_dbl_hr(int x)
{
return x << line_subpixel_shift;
}
//---------------------------------------------------------------line_coord
struct line_coord
{
AGG_INLINE static int conv(double x)
{
return iround(x * line_subpixel_scale);
}
};
//-----------------------------------------------------------line_coord_sat
struct line_coord_sat
{
AGG_INLINE static int conv(double x)
{
return saturation<line_max_coord>::iround(x * line_subpixel_scale);
}
};
//==========================================================line_parameters
struct line_parameters
{
//---------------------------------------------------------------------
line_parameters() {}
line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) :
x1(x1_), y1(y1_), x2(x2_), y2(y2_),
dx(abs(x2_ - x1_)),
dy(abs(y2_ - y1_)),
sx((x2_ > x1_) ? 1 : -1),
sy((y2_ > y1_) ? 1 : -1),
vertical(dy >= dx),
inc(vertical ? sy : sx),
len(len_),
octant((sy & 4) | (sx & 2) | int(vertical))
{
}
//---------------------------------------------------------------------
unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; }
unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; }
//---------------------------------------------------------------------
bool same_orthogonal_quadrant(const line_parameters& lp) const
{
return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant];
}
//---------------------------------------------------------------------
bool same_diagonal_quadrant(const line_parameters& lp) const
{
return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
}
//---------------------------------------------------------------------
void divide(line_parameters& lp1, line_parameters& lp2) const
{
int xmid = (x1 + x2) >> 1;
int ymid = (y1 + y2) >> 1;
int len2 = len >> 1;
lp1 = *this;
lp2 = *this;
lp1.x2 = xmid;
lp1.y2 = ymid;
lp1.len = len2;
lp1.dx = abs(lp1.x2 - lp1.x1);
lp1.dy = abs(lp1.y2 - lp1.y1);
lp2.x1 = xmid;
lp2.y1 = ymid;
lp2.len = len2;
lp2.dx = abs(lp2.x2 - lp2.x1);
lp2.dy = abs(lp2.y2 - lp2.y1);
}
//---------------------------------------------------------------------
int x1, y1, x2, y2, dx, dy, sx, sy;
bool vertical;
int inc;
int len;
int octant;
//---------------------------------------------------------------------
static const int8u s_orthogonal_quadrant[8];
static const int8u s_diagonal_quadrant[8];
};
// See Implementation agg_line_aa_basics.cpp
//----------------------------------------------------------------bisectrix
void bisectrix(const line_parameters& l1,
const line_parameters& l2,
int* x, int* y);
//-------------------------------------------fix_degenerate_bisectrix_start
void inline fix_degenerate_bisectrix_start(const line_parameters& lp,
int* x, int* y)
{
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
if(d < line_subpixel_scale/2)
{
*x = lp.x1 + (lp.y2 - lp.y1);
*y = lp.y1 - (lp.x2 - lp.x1);
}
}
//---------------------------------------------fix_degenerate_bisectrix_end
void inline fix_degenerate_bisectrix_end(const line_parameters& lp,
int* x, int* y)
{
int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
if(d < line_subpixel_scale/2)
{
*x = lp.x2 + (lp.y2 - lp.y1);
*y = lp.y2 - (lp.x2 - lp.x1);
}
}
}
#endif

437
3party/agg/agg_math.h Normal file
View file

@ -0,0 +1,437 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
// Bessel function (besj) was adapted for use in AGG library by Andy Wilk
// Contact: castor.vulgaris@gmail.com
//----------------------------------------------------------------------------
#ifndef AGG_MATH_INCLUDED
#define AGG_MATH_INCLUDED
#include <math.h>
#include "agg_basics.h"
namespace agg
{
//------------------------------------------------------vertex_dist_epsilon
// Coinciding points maximal distance (Epsilon)
const double vertex_dist_epsilon = 1e-14;
//-----------------------------------------------------intersection_epsilon
// See calc_intersection
const double intersection_epsilon = 1.0e-30;
//------------------------------------------------------------cross_product
AGG_INLINE double cross_product(double x1, double y1,
double x2, double y2,
double x, double y)
{
return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
}
//--------------------------------------------------------point_in_triangle
AGG_INLINE bool point_in_triangle(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x, double y)
{
bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
}
//-----------------------------------------------------------calc_distance
AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
{
double dx = x2-x1;
double dy = y2-y1;
return sqrt(dx * dx + dy * dy);
}
//--------------------------------------------------------calc_sq_distance
AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
{
double dx = x2-x1;
double dy = y2-y1;
return dx * dx + dy * dy;
}
//------------------------------------------------calc_line_point_distance
AGG_INLINE double calc_line_point_distance(double x1, double y1,
double x2, double y2,
double x, double y)
{
double dx = x2-x1;
double dy = y2-y1;
double d = sqrt(dx * dx + dy * dy);
if(d < vertex_dist_epsilon)
{
return calc_distance(x1, y1, x, y);
}
return ((x - x2) * dy - (y - y2) * dx) / d;
}
//-------------------------------------------------------calc_line_point_u
AGG_INLINE double calc_segment_point_u(double x1, double y1,
double x2, double y2,
double x, double y)
{
double dx = x2 - x1;
double dy = y2 - y1;
if(dx == 0 && dy == 0)
{
return 0;
}
double pdx = x - x1;
double pdy = y - y1;
return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
}
//---------------------------------------------calc_line_point_sq_distance
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
double x2, double y2,
double x, double y,
double u)
{
if(u <= 0)
{
return calc_sq_distance(x, y, x1, y1);
}
else
if(u >= 1)
{
return calc_sq_distance(x, y, x2, y2);
}
return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
}
//---------------------------------------------calc_line_point_sq_distance
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
double x2, double y2,
double x, double y)
{
return
calc_segment_point_sq_distance(
x1, y1, x2, y2, x, y,
calc_segment_point_u(x1, y1, x2, y2, x, y));
}
//-------------------------------------------------------calc_intersection
AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by,
double cx, double cy, double dx, double dy,
double* x, double* y)
{
double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy);
double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx);
if(fabs(den) < intersection_epsilon) return false;
double r = num / den;
*x = ax + r * (bx-ax);
*y = ay + r * (by-ay);
return true;
}
//-----------------------------------------------------intersection_exists
AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2,
double x3, double y3, double x4, double y4)
{
// It's less expensive but you can't control the
// boundary conditions: Less or LessEqual
double dx1 = x2 - x1;
double dy1 = y2 - y1;
double dx2 = x4 - x3;
double dy2 = y4 - y3;
return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) !=
((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
// It's is more expensive but more flexible
// in terms of boundary conditions.
//--------------------
//double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
//if(fabs(den) < intersection_epsilon) return false;
//double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
//double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);
//double ua = nom1 / den;
//double ub = nom2 / den;
//return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0;
}
//--------------------------------------------------------calc_orthogonal
AGG_INLINE void calc_orthogonal(double thickness,
double x1, double y1,
double x2, double y2,
double* x, double* y)
{
double dx = x2 - x1;
double dy = y2 - y1;
double d = sqrt(dx*dx + dy*dy);
*x = thickness * dy / d;
*y = -thickness * dx / d;
}
//--------------------------------------------------------dilate_triangle
AGG_INLINE void dilate_triangle(double x1, double y1,
double x2, double y2,
double x3, double y3,
double *x, double* y,
double d)
{
double dx1=0.0;
double dy1=0.0;
double dx2=0.0;
double dy2=0.0;
double dx3=0.0;
double dy3=0.0;
double loc = cross_product(x1, y1, x2, y2, x3, y3);
if(fabs(loc) > intersection_epsilon)
{
if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
{
d = -d;
}
calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1);
calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
}
*x++ = x1 + dx1; *y++ = y1 + dy1;
*x++ = x2 + dx1; *y++ = y2 + dy1;
*x++ = x2 + dx2; *y++ = y2 + dy2;
*x++ = x3 + dx2; *y++ = y3 + dy2;
*x++ = x3 + dx3; *y++ = y3 + dy3;
*x++ = x1 + dx3; *y++ = y1 + dy3;
}
//------------------------------------------------------calc_triangle_area
AGG_INLINE double calc_triangle_area(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
}
//-------------------------------------------------------calc_polygon_area
template<class Storage> double calc_polygon_area(const Storage& st)
{
unsigned i;
double sum = 0.0;
double x = st[0].x;
double y = st[0].y;
double xs = x;
double ys = y;
for(i = 1; i < st.size(); i++)
{
const typename Storage::value_type& v = st[i];
sum += x * v.y - y * v.x;
x = v.x;
y = v.y;
}
return (sum + x * ys - y * xs) * 0.5;
}
//------------------------------------------------------------------------
// Tables for fast sqrt
extern int16u g_sqrt_table[1024];
extern int8 g_elder_bit_table[256];
//---------------------------------------------------------------fast_sqrt
//Fast integer Sqrt - really fast: no cycles, divisions or multiplications
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4035) //Disable warning "no return value"
#endif
AGG_INLINE unsigned fast_sqrt(unsigned val)
{
#if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
//For Ix86 family processors this assembler code is used.
//The key command here is bsr - determination the number of the most
//significant bit of the value. For other processors
//(and maybe compilers) the pure C "#else" section is used.
__asm
{
mov ebx, val
mov edx, 11
bsr ecx, ebx
sub ecx, 9
jle less_than_9_bits
shr ecx, 1
adc ecx, 0
sub edx, ecx
shl ecx, 1
shr ebx, cl
less_than_9_bits:
xor eax, eax
mov ax, g_sqrt_table[ebx*2]
mov ecx, edx
shr eax, cl
}
#else
//This code is actually pure C and portable to most
//arcitectures including 64bit ones.
unsigned t = val;
int bit=0;
unsigned shift = 11;
//The following piece of code is just an emulation of the
//Ix86 assembler command "bsr" (see above). However on old
//Intels (like Intel MMX 233MHz) this code is about twice
//faster (sic!) then just one "bsr". On PIII and PIV the
//bsr is optimized quite well.
bit = t >> 24;
if(bit)
{
bit = g_elder_bit_table[bit] + 24;
}
else
{
bit = (t >> 16) & 0xFF;
if(bit)
{
bit = g_elder_bit_table[bit] + 16;
}
else
{
bit = (t >> 8) & 0xFF;
if(bit)
{
bit = g_elder_bit_table[bit] + 8;
}
else
{
bit = g_elder_bit_table[t];
}
}
}
//This code calculates the sqrt.
bit -= 9;
if(bit > 0)
{
bit = (bit >> 1) + (bit & 1);
shift -= bit;
val >>= (bit << 1);
}
return g_sqrt_table[val] >> shift;
#endif
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
//--------------------------------------------------------------------besj
// Function BESJ calculates Bessel function of first kind of order n
// Arguments:
// n - an integer (>=0), the order
// x - value at which the Bessel function is required
//--------------------
// C++ Mathematical Library
// Convereted from equivalent FORTRAN library
// Converetd by Gareth Walker for use by course 392 computational project
// All functions tested and yield the same results as the corresponding
// FORTRAN versions.
//
// If you have any problems using these functions please report them to
// M.Muldoon@UMIST.ac.uk
//
// Documentation available on the web
// http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
// Version 1.0 8/98
// 29 October, 1999
//--------------------
// Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com)
//------------------------------------------------------------------------
inline double besj(double x, int n)
{
if(n < 0)
{
return 0;
}
double d = 1E-6;
double b = 0;
if(fabs(x) <= d)
{
if(n != 0) return 0;
return 1;
}
double b1 = 0; // b1 is the value from the previous iteration
// Set up a starting order for recurrence
int m1 = (int)fabs(x) + 6;
if(fabs(x) > 5)
{
m1 = (int)(fabs(1.4 * x + 60 / x));
}
int m2 = (int)(n + 2 + fabs(x) / 4);
if (m1 > m2)
{
m2 = m1;
}
// Apply recurrence down from curent max order
for(;;)
{
double c3 = 0;
double c2 = 1E-30;
double c4 = 0;
int m8 = 1;
if (m2 / 2 * 2 == m2)
{
m8 = -1;
}
int imax = m2 - 2;
for (int i = 1; i <= imax; i++)
{
double c6 = 2 * (m2 - i) * c2 / x - c3;
c3 = c2;
c2 = c6;
if(m2 - i - 1 == n)
{
b = c6;
}
m8 = -1 * m8;
if (m8 > 0)
{
c4 = c4 + 2 * c6;
}
}
double c6 = 2 * c2 / x - c3;
if(n == 0)
{
b = c6;
}
c4 += c6;
b /= c4;
if(fabs(b - b1) < d)
{
return b;
}
b1 = b;
m2 += 3;
}
}
}
#endif

View file

@ -0,0 +1,526 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Stroke math
//
//----------------------------------------------------------------------------
#ifndef AGG_STROKE_MATH_INCLUDED
#define AGG_STROKE_MATH_INCLUDED
#include "agg_math.h"
#include "agg_vertex_sequence.h"
namespace agg
{
//-------------------------------------------------------------line_cap_e
enum line_cap_e
{
butt_cap,
square_cap,
round_cap
};
//------------------------------------------------------------line_join_e
enum line_join_e
{
miter_join = 0,
miter_join_revert = 1,
round_join = 2,
bevel_join = 3,
miter_join_round = 4
};
//-----------------------------------------------------------inner_join_e
enum inner_join_e
{
inner_bevel,
inner_miter,
inner_jag,
inner_round
};
//------------------------------------------------------------math_stroke
template<class VertexConsumer> class math_stroke
{
public:
typedef typename VertexConsumer::value_type coord_type;
math_stroke();
void line_cap(line_cap_e lc) { m_line_cap = lc; }
void line_join(line_join_e lj) { m_line_join = lj; }
void inner_join(inner_join_e ij) { m_inner_join = ij; }
line_cap_e line_cap() const { return m_line_cap; }
line_join_e line_join() const { return m_line_join; }
inner_join_e inner_join() const { return m_inner_join; }
void width(double w);
void miter_limit(double ml) { m_miter_limit = ml; }
void miter_limit_theta(double t);
void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
void approximation_scale(double as) { m_approx_scale = as; }
double width() const { return m_width * 2.0; }
double miter_limit() const { return m_miter_limit; }
double inner_miter_limit() const { return m_inner_miter_limit; }
double approximation_scale() const { return m_approx_scale; }
void calc_cap(VertexConsumer& vc,
const vertex_dist& v0,
const vertex_dist& v1,
double len);
void calc_join(VertexConsumer& vc,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1,
double len2);
private:
AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y)
{
vc.add(coord_type(x, y));
}
void calc_arc(VertexConsumer& vc,
double x, double y,
double dx1, double dy1,
double dx2, double dy2);
void calc_miter(VertexConsumer& vc,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
line_join_e lj,
double mlimit,
double dbevel);
double m_width;
double m_width_abs;
double m_width_eps;
int m_width_sign;
double m_miter_limit;
double m_inner_miter_limit;
double m_approx_scale;
line_cap_e m_line_cap;
line_join_e m_line_join;
inner_join_e m_inner_join;
};
//-----------------------------------------------------------------------
template<class VC> math_stroke<VC>::math_stroke() :
m_width(0.5),
m_width_abs(0.5),
m_width_eps(0.5/1024.0),
m_width_sign(1),
m_miter_limit(4.0),
m_inner_miter_limit(1.01),
m_approx_scale(1.0),
m_line_cap(butt_cap),
m_line_join(miter_join),
m_inner_join(inner_miter)
{
}
//-----------------------------------------------------------------------
template<class VC> void math_stroke<VC>::width(double w)
{
m_width = w * 0.5;
if(m_width < 0)
{
m_width_abs = -m_width;
m_width_sign = -1;
}
else
{
m_width_abs = m_width;
m_width_sign = 1;
}
m_width_eps = m_width / 1024.0;
}
//-----------------------------------------------------------------------
template<class VC> void math_stroke<VC>::miter_limit_theta(double t)
{
m_miter_limit = 1.0 / sin(t * 0.5) ;
}
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_arc(VC& vc,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
double a1 = atan2(dy1 * m_width_sign, dx1 * m_width_sign);
double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign);
double da = a1 - a2;
int i, n;
da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
add_vertex(vc, x + dx1, y + dy1);
if(m_width_sign > 0)
{
if(a1 > a2) a2 += 2 * pi;
n = int((a2 - a1) / da);
da = (a2 - a1) / (n + 1);
a1 += da;
for(i = 0; i < n; i++)
{
add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
a1 += da;
}
}
else
{
if(a1 < a2) a2 -= 2 * pi;
n = int((a1 - a2) / da);
da = (a1 - a2) / (n + 1);
a1 -= da;
for(i = 0; i < n; i++)
{
add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
a1 -= da;
}
}
add_vertex(vc, x + dx2, y + dy2);
}
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_miter(VC& vc,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
line_join_e lj,
double mlimit,
double dbevel)
{
double xi = v1.x;
double yi = v1.y;
double di = 1;
double lim = m_width_abs * mlimit;
bool miter_limit_exceeded = true; // Assume the worst
bool intersection_failed = true; // Assume the worst
if(calc_intersection(v0.x + dx1, v0.y - dy1,
v1.x + dx1, v1.y - dy1,
v1.x + dx2, v1.y - dy2,
v2.x + dx2, v2.y - dy2,
&xi, &yi))
{
// Calculation of the intersection succeeded
//---------------------
di = calc_distance(v1.x, v1.y, xi, yi);
if(di <= lim)
{
// Inside the miter limit
//---------------------
add_vertex(vc, xi, yi);
miter_limit_exceeded = false;
}
intersection_failed = false;
}
else
{
// Calculation of the intersection failed, most probably
// the three points lie one straight line.
// First check if v0 and v2 lie on the opposite sides of vector:
// (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
// to the line determined by vertices v0 and v1.
// This condition determines whether the next line segments continues
// the previous one or goes back.
//----------------
double x2 = v1.x + dx1;
double y2 = v1.y - dy1;
if((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) ==
(cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
{
// This case means that the next segment continues
// the previous one (straight line)
//-----------------
add_vertex(vc, v1.x + dx1, v1.y - dy1);
miter_limit_exceeded = false;
}
}
if(miter_limit_exceeded)
{
// Miter limit exceeded
//------------------------
switch(lj)
{
case miter_join_revert:
// For the compatibility with SVG, PDF, etc,
// we use a simple bevel join instead of
// "smart" bevel
//-------------------
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x + dx2, v1.y - dy2);
break;
case miter_join_round:
calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
break;
default:
// If no miter-revert, calculate new dx1, dy1, dx2, dy2
//----------------
if(intersection_failed)
{
mlimit *= m_width_sign;
add_vertex(vc, v1.x + dx1 + dy1 * mlimit,
v1.y - dy1 + dx1 * mlimit);
add_vertex(vc, v1.x + dx2 - dy2 * mlimit,
v1.y - dy2 - dx2 * mlimit);
}
else
{
double x1 = v1.x + dx1;
double y1 = v1.y - dy1;
double x2 = v1.x + dx2;
double y2 = v1.y - dy2;
di = (lim - dbevel) / (di - dbevel);
add_vertex(vc, x1 + (xi - x1) * di,
y1 + (yi - y1) * di);
add_vertex(vc, x2 + (xi - x2) * di,
y2 + (yi - y2) * di);
}
break;
}
}
}
//--------------------------------------------------------stroke_calc_cap
template<class VC>
void math_stroke<VC>::calc_cap(VC& vc,
const vertex_dist& v0,
const vertex_dist& v1,
double len)
{
vc.remove_all();
double dx1 = (v1.y - v0.y) / len;
double dy1 = (v1.x - v0.x) / len;
double dx2 = 0;
double dy2 = 0;
dx1 *= m_width;
dy1 *= m_width;
if(m_line_cap != round_cap)
{
if(m_line_cap == square_cap)
{
dx2 = dy1 * m_width_sign;
dy2 = dx1 * m_width_sign;
}
add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
}
else
{
double da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
double a1;
int i;
int n = int(pi / da);
da = pi / (n + 1);
add_vertex(vc, v0.x - dx1, v0.y + dy1);
if(m_width_sign > 0)
{
a1 = atan2(dy1, -dx1);
a1 += da;
for(i = 0; i < n; i++)
{
add_vertex(vc, v0.x + cos(a1) * m_width,
v0.y + sin(a1) * m_width);
a1 += da;
}
}
else
{
a1 = atan2(-dy1, dx1);
a1 -= da;
for(i = 0; i < n; i++)
{
add_vertex(vc, v0.x + cos(a1) * m_width,
v0.y + sin(a1) * m_width);
a1 -= da;
}
}
add_vertex(vc, v0.x + dx1, v0.y - dy1);
}
}
//-----------------------------------------------------------------------
template<class VC>
void math_stroke<VC>::calc_join(VC& vc,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1,
double len2)
{
double dx1 = m_width * (v1.y - v0.y) / len1;
double dy1 = m_width * (v1.x - v0.x) / len1;
double dx2 = m_width * (v2.y - v1.y) / len2;
double dy2 = m_width * (v2.x - v1.x) / len2;
vc.remove_all();
double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
if(cp != 0 && (cp > 0) == (m_width > 0))
{
// Inner join
//---------------
double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
if(limit < m_inner_miter_limit)
{
limit = m_inner_miter_limit;
}
switch(m_inner_join)
{
default: // inner_bevel
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x + dx2, v1.y - dy2);
break;
case inner_miter:
calc_miter(vc,
v0, v1, v2, dx1, dy1, dx2, dy2,
miter_join_revert,
limit, 0);
break;
case inner_jag:
case inner_round:
cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
if(cp < len1 * len1 && cp < len2 * len2)
{
calc_miter(vc,
v0, v1, v2, dx1, dy1, dx2, dy2,
miter_join_revert,
limit, 0);
}
else
{
if(m_inner_join == inner_jag)
{
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x, v1.y );
add_vertex(vc, v1.x + dx2, v1.y - dy2);
}
else
{
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x, v1.y );
calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
add_vertex(vc, v1.x, v1.y );
add_vertex(vc, v1.x + dx2, v1.y - dy2);
}
}
break;
}
}
else
{
// Outer join
//---------------
// Calculate the distance between v1 and
// the central point of the bevel line segment
//---------------
double dx = (dx1 + dx2) / 2;
double dy = (dy1 + dy2) / 2;
double dbevel = sqrt(dx * dx + dy * dy);
if(m_line_join == round_join || m_line_join == bevel_join)
{
// This is an optimization that reduces the number of points
// in cases of almost collinear segments. If there's no
// visible difference between bevel and miter joins we'd rather
// use miter join because it adds only one point instead of two.
//
// Here we calculate the middle point between the bevel points
// and then, the distance between v1 and this middle point.
// At outer joins this distance always less than stroke width,
// because it's actually the height of an isosceles triangle of
// v1 and its two bevel points. If the difference between this
// width and this value is small (no visible bevel) we can
// add just one point.
//
// The constant in the expression makes the result approximately
// the same as in round joins and caps. You can safely comment
// out this entire "if".
//-------------------
if(m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
{
if(calc_intersection(v0.x + dx1, v0.y - dy1,
v1.x + dx1, v1.y - dy1,
v1.x + dx2, v1.y - dy2,
v2.x + dx2, v2.y - dy2,
&dx, &dy))
{
add_vertex(vc, dx, dy);
}
else
{
add_vertex(vc, v1.x + dx1, v1.y - dy1);
}
return;
}
}
switch(m_line_join)
{
case miter_join:
case miter_join_revert:
case miter_join_round:
calc_miter(vc,
v0, v1, v2, dx1, dy1, dx2, dy2,
m_line_join,
m_miter_limit,
dbevel);
break;
case round_join:
calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
break;
default: // Bevel join
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x + dx2, v1.y - dy2);
break;
}
}
}
}
#endif

View file

@ -0,0 +1,65 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PATH_LENGTH_INCLUDED
#define AGG_PATH_LENGTH_INCLUDED
#include "agg_math.h"
namespace agg
{
template<class VertexSource>
double path_length(VertexSource& vs, unsigned path_id = 0)
{
double len = 0.0;
double start_x = 0.0;
double start_y = 0.0;
double x1 = 0.0;
double y1 = 0.0;
double x2 = 0.0;
double y2 = 0.0;
bool first = true;
unsigned cmd;
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x2, &y2)))
{
if(is_vertex(cmd))
{
if(first || is_move_to(cmd))
{
start_x = x2;
start_y = y2;
}
else
{
len += calc_distance(x1, y1, x2, y2);
}
x1 = x2;
y1 = y2;
first = false;
}
else
{
if(is_close(cmd) && !first)
{
len += calc_distance(x1, y1, start_x, start_y);
}
}
}
return len;
}
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,295 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PATH_STORAGE_INTEGER_INCLUDED
#define AGG_PATH_STORAGE_INTEGER_INCLUDED
#include <string.h>
#include "agg_array.h"
namespace agg
{
//---------------------------------------------------------vertex_integer
template<class T, unsigned CoordShift=6> struct vertex_integer
{
enum path_cmd
{
cmd_move_to = 0,
cmd_line_to = 1,
cmd_curve3 = 2,
cmd_curve4 = 3
};
enum coord_scale_e
{
coord_shift = CoordShift,
coord_scale = 1 << coord_shift
};
T x,y;
vertex_integer() {}
vertex_integer(T x_, T y_, unsigned flag) :
x(((x_ << 1) & ~1) | (flag & 1)),
y(((y_ << 1) & ~1) | (flag >> 1)) {}
unsigned vertex(double* x_, double* y_,
double dx=0, double dy=0,
double scale=1.0) const
{
*x_ = dx + (double(x >> 1) / coord_scale) * scale;
*y_ = dy + (double(y >> 1) / coord_scale) * scale;
switch(((y & 1) << 1) | (x & 1))
{
case cmd_move_to: return path_cmd_move_to;
case cmd_line_to: return path_cmd_line_to;
case cmd_curve3: return path_cmd_curve3;
case cmd_curve4: return path_cmd_curve4;
}
return path_cmd_stop;
}
};
//---------------------------------------------------path_storage_integer
template<class T, unsigned CoordShift=6> class path_storage_integer
{
public:
typedef T value_type;
typedef vertex_integer<T, CoordShift> vertex_integer_type;
//--------------------------------------------------------------------
path_storage_integer() : m_storage(), m_vertex_idx(0), m_closed(true) {}
//--------------------------------------------------------------------
void remove_all() { m_storage.remove_all(); }
//--------------------------------------------------------------------
void move_to(T x, T y)
{
m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to));
}
//--------------------------------------------------------------------
void line_to(T x, T y)
{
m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to));
}
//--------------------------------------------------------------------
void curve3(T x_ctrl, T y_ctrl,
T x_to, T y_to)
{
m_storage.add(vertex_integer_type(x_ctrl, y_ctrl, vertex_integer_type::cmd_curve3));
m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve3));
}
//--------------------------------------------------------------------
void curve4(T x_ctrl1, T y_ctrl1,
T x_ctrl2, T y_ctrl2,
T x_to, T y_to)
{
m_storage.add(vertex_integer_type(x_ctrl1, y_ctrl1, vertex_integer_type::cmd_curve4));
m_storage.add(vertex_integer_type(x_ctrl2, y_ctrl2, vertex_integer_type::cmd_curve4));
m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve4));
}
//--------------------------------------------------------------------
void close_polygon() {}
//--------------------------------------------------------------------
unsigned size() const { return m_storage.size(); }
unsigned vertex(unsigned idx, double* x, double* y) const
{
return m_storage[idx].vertex(x, y);
}
//--------------------------------------------------------------------
unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); }
void serialize(int8u* ptr) const
{
unsigned i;
for(i = 0; i < m_storage.size(); i++)
{
memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
ptr += sizeof(vertex_integer_type);
}
}
//--------------------------------------------------------------------
void rewind(unsigned)
{
m_vertex_idx = 0;
m_closed = true;
}
//--------------------------------------------------------------------
unsigned vertex(double* x, double* y)
{
if(m_storage.size() < 2 || m_vertex_idx > m_storage.size())
{
*x = 0;
*y = 0;
return path_cmd_stop;
}
if(m_vertex_idx == m_storage.size())
{
*x = 0;
*y = 0;
++m_vertex_idx;
return path_cmd_end_poly | path_flags_close;
}
unsigned cmd = m_storage[m_vertex_idx].vertex(x, y);
if(is_move_to(cmd) && !m_closed)
{
*x = 0;
*y = 0;
m_closed = true;
return path_cmd_end_poly | path_flags_close;
}
m_closed = false;
++m_vertex_idx;
return cmd;
}
//--------------------------------------------------------------------
rect_d bounding_rect() const
{
rect_d bounds(1e100, 1e100, -1e100, -1e100);
if(m_storage.size() == 0)
{
bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
}
else
{
unsigned i;
for(i = 0; i < m_storage.size(); i++)
{
double x, y;
m_storage[i].vertex(&x, &y);
if(x < bounds.x1) bounds.x1 = x;
if(y < bounds.y1) bounds.y1 = y;
if(x > bounds.x2) bounds.x2 = x;
if(y > bounds.y2) bounds.y2 = y;
}
}
return bounds;
}
private:
pod_bvector<vertex_integer_type, 6> m_storage;
unsigned m_vertex_idx;
bool m_closed;
};
//-----------------------------------------serialized_integer_path_adaptor
template<class T, unsigned CoordShift=6> class serialized_integer_path_adaptor
{
public:
typedef vertex_integer<T, CoordShift> vertex_integer_type;
//--------------------------------------------------------------------
serialized_integer_path_adaptor() :
m_data(0),
m_end(0),
m_ptr(0),
m_dx(0.0),
m_dy(0.0),
m_scale(1.0),
m_vertices(0)
{}
//--------------------------------------------------------------------
serialized_integer_path_adaptor(const int8u* data, unsigned size,
double dx, double dy) :
m_data(data),
m_end(data + size),
m_ptr(data),
m_dx(dx),
m_dy(dy),
m_vertices(0)
{}
//--------------------------------------------------------------------
void init(const int8u* data, unsigned size,
double dx, double dy, double scale=1.0)
{
m_data = data;
m_end = data + size;
m_ptr = data;
m_dx = dx;
m_dy = dy;
m_scale = scale;
m_vertices = 0;
}
//--------------------------------------------------------------------
void rewind(unsigned)
{
m_ptr = m_data;
m_vertices = 0;
}
//--------------------------------------------------------------------
unsigned vertex(double* x, double* y)
{
if(m_data == 0 || m_ptr > m_end)
{
*x = 0;
*y = 0;
return path_cmd_stop;
}
if(m_ptr == m_end)
{
*x = 0;
*y = 0;
m_ptr += sizeof(vertex_integer_type);
return path_cmd_end_poly | path_flags_close;
}
vertex_integer_type v;
memcpy(&v, m_ptr, sizeof(vertex_integer_type));
unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
if(is_move_to(cmd) && m_vertices > 2)
{
*x = 0;
*y = 0;
m_vertices = 0;
return path_cmd_end_poly | path_flags_close;
}
++m_vertices;
m_ptr += sizeof(vertex_integer_type);
return cmd;
}
private:
const int8u* m_data;
const int8u* m_end;
const int8u* m_ptr;
double m_dx;
double m_dy;
double m_scale;
unsigned m_vertices;
};
}
#endif

View file

@ -0,0 +1,123 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PATTERN_FILTERS_RGBA8_INCLUDED
#define AGG_PATTERN_FILTERS_RGBA8_INCLUDED
#include "agg_basics.h"
#include "agg_line_aa_basics.h"
#include "agg_color_rgba.h"
namespace agg
{
//=======================================================pattern_filter_nn
template<class ColorT> struct pattern_filter_nn
{
typedef ColorT color_type;
static unsigned dilation() { return 0; }
static void AGG_INLINE pixel_low_res(color_type const* const* buf,
color_type* p, int x, int y)
{
*p = buf[y][x];
}
static void AGG_INLINE pixel_high_res(color_type const* const* buf,
color_type* p, int x, int y)
{
*p = buf[y >> line_subpixel_shift]
[x >> line_subpixel_shift];
}
};
typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16;
//===========================================pattern_filter_bilinear_rgba
template<class ColorT> struct pattern_filter_bilinear_rgba
{
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
static unsigned dilation() { return 1; }
static AGG_INLINE void pixel_low_res(color_type const* const* buf,
color_type* p, int x, int y)
{
*p = buf[y][x];
}
static AGG_INLINE void pixel_high_res(color_type const* const* buf,
color_type* p, int x, int y)
{
calc_type r, g, b, a;
r = g = b = a = 0;
calc_type weight;
int x_lr = x >> line_subpixel_shift;
int y_lr = y >> line_subpixel_shift;
x &= line_subpixel_mask;
y &= line_subpixel_mask;
const color_type* ptr = buf[y_lr] + x_lr;
weight = (line_subpixel_scale - x) *
(line_subpixel_scale - y);
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
a += weight * ptr->a;
++ptr;
weight = x * (line_subpixel_scale - y);
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
a += weight * ptr->a;
ptr = buf[y_lr + 1] + x_lr;
weight = (line_subpixel_scale - x) * y;
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
a += weight * ptr->a;
++ptr;
weight = x * y;
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
a += weight * ptr->a;
p->r = color_type::downshift(r, line_subpixel_shift * 2);
p->g = color_type::downshift(g, line_subpixel_shift * 2);
p->b = color_type::downshift(b, line_subpixel_shift * 2);
p->a = color_type::downshift(a, line_subpixel_shift * 2);
}
};
typedef pattern_filter_bilinear_rgba<rgba8> pattern_filter_bilinear_rgba8;
typedef pattern_filter_bilinear_rgba<rgba16> pattern_filter_bilinear_rgba16;
typedef pattern_filter_bilinear_rgba<rgba32> pattern_filter_bilinear_rgba32;
}
#endif

View file

@ -0,0 +1,240 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
#define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED
#include <string.h>
#include "agg_array.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//==================================================pixfmt_amask_adaptor
template<class PixFmt, class AlphaMask> class pixfmt_amask_adaptor
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::row_data row_data;
typedef AlphaMask amask_type;
typedef typename amask_type::cover_type cover_type;
private:
enum span_extra_tail_e { span_extra_tail = 256 };
void realloc_span(unsigned len)
{
if(len > m_span.size())
{
m_span.resize(len + span_extra_tail);
}
}
void init_span(unsigned len)
{
realloc_span(len);
memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
}
void init_span(unsigned len, const cover_type* covers)
{
realloc_span(len);
memcpy(&m_span[0], covers, len * sizeof(cover_type));
}
public:
pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& 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);
}
//--------------------------------------------------------------------
unsigned width() const { return m_pixf->width(); }
unsigned height() const { return m_pixf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
{
return m_pixf->pixel(x, y);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
m_pixf->blend_pixel(x, y, c, m_mask->pixel(x, y));
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
{
m_pixf->blend_pixel(x, y, c, m_mask->combine_pixel(x, y, cover));
}
//--------------------------------------------------------------------
void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
realloc_span(len);
m_mask->fill_hspan(x, y, &m_span[0], len);
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y,
unsigned len,
const color_type& c,
cover_type cover)
{
init_span(len);
m_mask->combine_hspan(x, y, &m_span[0], len);
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
realloc_span(len);
m_mask->fill_vspan(x, y, &m_span[0], len);
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
void blend_vline(int x, int y,
unsigned len,
const color_type& c,
cover_type cover)
{
init_span(len);
m_mask->combine_vspan(x, y, &m_span[0], len);
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
m_pixf->copy_from(from, xdst, ydst, xsrc, ysrc, len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const cover_type* covers)
{
init_span(len, covers);
m_mask->combine_hspan(x, y, &m_span[0], len);
m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const cover_type* covers)
{
init_span(len, covers);
m_mask->combine_vspan(x, y, &m_span[0], len);
m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y, unsigned len, const color_type* colors)
{
realloc_span(len);
m_mask->fill_hspan(x, y, &m_span[0], len);
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover_full);
}
//--------------------------------------------------------------------
void copy_color_vspan(int x, int y, unsigned len, const color_type* colors)
{
realloc_span(len);
m_mask->fill_vspan(x, y, &m_span[0], len);
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover_full);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
if(covers)
{
init_span(len, covers);
m_mask->combine_hspan(x, y, &m_span[0], len);
}
else
{
realloc_span(len);
m_mask->fill_hspan(x, y, &m_span[0], len);
}
m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
if(covers)
{
init_span(len, covers);
m_mask->combine_vspan(x, y, &m_span[0], len);
}
else
{
realloc_span(len);
m_mask->fill_vspan(x, y, &m_span[0], len);
}
m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover);
}
private:
pixfmt_type* m_pixf;
const amask_type* m_mask;
pod_array<cover_type> m_span;
};
}
#endif

View file

@ -0,0 +1,97 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_BASE_INCLUDED
#define AGG_PIXFMT_BASE_INCLUDED
#include "agg_basics.h"
#include "agg_color_gray.h"
#include "agg_color_rgba.h"
namespace agg
{
struct pixfmt_gray_tag
{
};
struct pixfmt_rgb_tag
{
};
struct pixfmt_rgba_tag
{
};
//--------------------------------------------------------------blender_base
template<class ColorT, class Order = void>
struct blender_base
{
typedef ColorT color_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full)
{
if (cover > cover_none)
{
rgba c(
color_type::to_double(r),
color_type::to_double(g),
color_type::to_double(b),
color_type::to_double(a));
if (cover < cover_full)
{
double x = double(cover) / double(cover_full);
c.r *= x;
c.g *= x;
c.b *= x;
c.a *= x;
}
return c;
}
else return rgba::no_color();
}
static rgba get(const value_type* p, cover_type cover = cover_full)
{
return get(
p[order_type::R],
p[order_type::G],
p[order_type::B],
p[order_type::A],
cover);
}
static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
{
p[order_type::R] = r;
p[order_type::G] = g;
p[order_type::B] = b;
p[order_type::A] = a;
}
static void set(value_type* p, const rgba& c)
{
p[order_type::R] = color_type::from_double(c.r);
p[order_type::G] = color_type::from_double(c.g);
p[order_type::B] = color_type::from_double(c.b);
p[order_type::A] = color_type::from_double(c.a);
}
};
}
#endif

View file

@ -0,0 +1,738 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for high precision colors has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_GRAY_INCLUDED
#define AGG_PIXFMT_GRAY_INCLUDED
#include <string.h>
#include "agg_pixfmt_base.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//============================================================blender_gray
template<class ColorT> struct blender_gray
{
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
typedef typename color_type::long_type long_type;
// Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
// compositing function. Since the render buffer is opaque we skip the
// initial premultiply and final demultiply.
static AGG_INLINE void blend_pix(value_type* p,
value_type cv, value_type alpha, cover_type cover)
{
blend_pix(p, cv, color_type::mult_cover(alpha, cover));
}
static AGG_INLINE void blend_pix(value_type* p,
value_type cv, value_type alpha)
{
*p = color_type::lerp(*p, cv, alpha);
}
};
//======================================================blender_gray_pre
template<class ColorT> struct blender_gray_pre
{
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
typedef typename color_type::long_type long_type;
// Blend pixels using the premultiplied form of Alvy-Ray Smith's
// compositing function.
static AGG_INLINE void blend_pix(value_type* p,
value_type cv, value_type alpha, cover_type cover)
{
blend_pix(p, color_type::mult_cover(cv, cover), color_type::mult_cover(alpha, cover));
}
static AGG_INLINE void blend_pix(value_type* p,
value_type cv, value_type alpha)
{
*p = color_type::prelerp(*p, cv, alpha);
}
};
//=====================================================apply_gamma_dir_gray
template<class ColorT, class GammaLut> class apply_gamma_dir_gray
{
public:
typedef typename ColorT::value_type value_type;
apply_gamma_dir_gray(const GammaLut& gamma) : m_gamma(gamma) {}
AGG_INLINE void operator () (value_type* p)
{
*p = m_gamma.dir(*p);
}
private:
const GammaLut& m_gamma;
};
//=====================================================apply_gamma_inv_gray
template<class ColorT, class GammaLut> class apply_gamma_inv_gray
{
public:
typedef typename ColorT::value_type value_type;
apply_gamma_inv_gray(const GammaLut& gamma) : m_gamma(gamma) {}
AGG_INLINE void operator () (value_type* p)
{
*p = m_gamma.inv(*p);
}
private:
const GammaLut& m_gamma;
};
//=================================================pixfmt_alpha_blend_gray
template<class Blender, class RenBuf, unsigned Step = 1, unsigned Offset = 0>
class pixfmt_alpha_blend_gray
{
public:
typedef pixfmt_gray_tag pixfmt_category;
typedef RenBuf rbuf_type;
typedef typename rbuf_type::row_data row_data;
typedef Blender blender_type;
typedef typename blender_type::color_type color_type;
typedef int order_type; // A fake one
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum
{
num_components = 1,
pix_width = sizeof(value_type) * Step,
pix_step = Step,
pix_offset = Offset,
};
struct pixel_type
{
value_type c[num_components];
void set(value_type v)
{
c[0] = v;
}
void set(const color_type& color)
{
set(color.v);
}
void get(value_type& v) const
{
v = c[0];
}
color_type get() const
{
return color_type(c[0]);
}
pixel_type* next()
{
return (pixel_type*)(c + pix_step);
}
const pixel_type* next() const
{
return (const pixel_type*)(c + pix_step);
}
pixel_type* advance(int n)
{
return (pixel_type*)(c + n * pix_step);
}
const pixel_type* advance(int n) const
{
return (const pixel_type*)(c + n * pix_step);
}
};
private:
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p,
value_type v, value_type a,
unsigned cover)
{
blender_type::blend_pix(p->c, v, a, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p, value_type v, value_type a)
{
blender_type::blend_pix(p->c, v, a);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
{
blender_type::blend_pix(p->c, c.v, c.a, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
{
blender_type::blend_pix(p->c, c.v, c.a);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
{
if (!c.is_transparent())
{
if (c.is_opaque() && cover == cover_mask)
{
p->set(c);
}
else
{
blend_pix(p, c, cover);
}
}
}
//--------------------------------------------------------------------
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
{
if (!c.is_transparent())
{
if (c.is_opaque())
{
p->set(c);
}
else
{
blend_pix(p, c);
}
}
}
public:
//--------------------------------------------------------------------
explicit pixfmt_alpha_blend_gray(rbuf_type& rb) :
m_rbuf(&rb)
{}
void attach(rbuf_type& rb) { m_rbuf = &rb; }
//--------------------------------------------------------------------
template<class PixFmt>
bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
{
rect_i r(x1, y1, x2, y2);
if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
{
int stride = pixf.stride();
m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
(r.x2 - r.x1) + 1,
(r.y2 - r.y1) + 1,
stride);
return true;
}
return false;
}
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
row_data row(int y) const { return m_rbuf->row(y); }
//--------------------------------------------------------------------
AGG_INLINE int8u* pix_ptr(int x, int y)
{
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
}
AGG_INLINE const int8u* pix_ptr(int x, int y) const
{
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
}
// Return pointer to pixel value, forcing row to be allocated.
AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len)
{
return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset));
}
// Return pointer to pixel value, or null if row not allocated.
AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const
{
int8u* p = m_rbuf->row_ptr(y);
return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
}
// Get pixel pointer from raw buffer pointer.
AGG_INLINE static pixel_type* pix_value_ptr(void* p)
{
return (pixel_type*)((value_type*)p + pix_offset);
}
// Get pixel pointer from raw buffer pointer.
AGG_INLINE static const pixel_type* pix_value_ptr(const void* p)
{
return (const pixel_type*)((const value_type*)p + pix_offset);
}
//--------------------------------------------------------------------
AGG_INLINE static void write_plain_color(void* p, color_type c)
{
// Grayscale formats are implicitly premultiplied.
c.premultiply();
pix_value_ptr(p)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE static color_type read_plain_color(const void* p)
{
return pix_value_ptr(p)->get();
}
//--------------------------------------------------------------------
AGG_INLINE static void make_pix(int8u* p, const color_type& c)
{
((pixel_type*)p)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE color_type pixel(int x, int y) const
{
if (const pixel_type* p = pix_value_ptr(x, y))
{
return p->get();
}
return color_type::no_color();
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
pix_value_ptr(x, y, 1)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
pixel_type* p = pix_value_ptr(x, y, len);
do
{
p->set(c);
p = p->next();
}
while(--len);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
do
{
pix_value_ptr(x, y++, 1)->set(c);
}
while (--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
if (!c.is_transparent())
{
pixel_type* p = pix_value_ptr(x, y, len);
if (c.is_opaque() && cover == cover_mask)
{
do
{
p->set(c);
p = p->next();
}
while (--len);
}
else
{
do
{
blend_pix(p, c, cover);
p = p->next();
}
while (--len);
}
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
if (!c.is_transparent())
{
if (c.is_opaque() && cover == cover_mask)
{
do
{
pix_value_ptr(x, y++, 1)->set(c);
}
while (--len);
}
else
{
do
{
blend_pix(pix_value_ptr(x, y++, 1), c, cover);
}
while (--len);
}
}
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (!c.is_transparent())
{
pixel_type* p = pix_value_ptr(x, y, len);
do
{
if (c.is_opaque() && *covers == cover_mask)
{
p->set(c);
}
else
{
blend_pix(p, c, *covers);
}
p = p->next();
++covers;
}
while (--len);
}
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (!c.is_transparent())
{
do
{
pixel_type* p = pix_value_ptr(x, y++, 1);
if (c.is_opaque() && *covers == cover_mask)
{
p->set(c);
}
else
{
blend_pix(p, c, *covers);
}
++covers;
}
while (--len);
}
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y,
unsigned len,
const color_type* colors)
{
pixel_type* p = pix_value_ptr(x, y, len);
do
{
p->set(*colors++);
p = p->next();
}
while (--len);
}
//--------------------------------------------------------------------
void copy_color_vspan(int x, int y,
unsigned len,
const color_type* colors)
{
do
{
pix_value_ptr(x, y++, 1)->set(*colors++);
}
while (--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
pixel_type* p = pix_value_ptr(x, y, len);
if (covers)
{
do
{
copy_or_blend_pix(p, *colors++, *covers++);
p = p->next();
}
while (--len);
}
else
{
if (cover == cover_mask)
{
do
{
copy_or_blend_pix(p, *colors++);
p = p->next();
}
while (--len);
}
else
{
do
{
copy_or_blend_pix(p, *colors++, cover);
p = p->next();
}
while (--len);
}
}
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
if (covers)
{
do
{
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
}
while (--len);
}
else
{
if (cover == cover_mask)
{
do
{
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
}
while (--len);
}
else
{
do
{
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
}
while (--len);
}
}
}
//--------------------------------------------------------------------
template<class Function> void for_each_pixel(Function f)
{
unsigned y;
for (y = 0; y < height(); ++y)
{
row_data r = m_rbuf->row(y);
if (r.ptr)
{
unsigned len = r.x2 - r.x1 + 1;
pixel_type* p = pix_value_ptr(r.x1, y, len);
do
{
f(p->c);
p = p->next();
}
while (--len);
}
}
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
{
for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
{
for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class RenBuf2>
void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
if (const int8u* p = from.row_ptr(ysrc))
{
memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
p + xsrc * pix_width,
len * pix_width);
}
}
//--------------------------------------------------------------------
// Blend from single color, using grayscale surface as alpha channel.
template<class SrcPixelFormatRenderer>
void blend_from_color(const SrcPixelFormatRenderer& from,
const color_type& color,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len,
int8u cover)
{
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
typedef typename SrcPixelFormatRenderer::color_type src_color_type;
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
{
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
do
{
copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
psrc = psrc->next();
pdst = pdst->next();
}
while (--len);
}
}
//--------------------------------------------------------------------
// Blend from color table, using grayscale surface as indexes into table.
// Obviously, this only works for integer value types.
template<class SrcPixelFormatRenderer>
void blend_from_lut(const SrcPixelFormatRenderer& from,
const color_type* color_lut,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len,
int8u cover)
{
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
{
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
do
{
copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
psrc = psrc->next();
pdst = pdst->next();
}
while (--len);
}
}
private:
rbuf_type* m_rbuf;
};
typedef blender_gray<gray8> blender_gray8;
typedef blender_gray<sgray8> blender_sgray8;
typedef blender_gray<gray16> blender_gray16;
typedef blender_gray<gray32> blender_gray32;
typedef blender_gray_pre<gray8> blender_gray8_pre;
typedef blender_gray_pre<sgray8> blender_sgray8_pre;
typedef blender_gray_pre<gray16> blender_gray16_pre;
typedef blender_gray_pre<gray32> blender_gray32_pre;
typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8;
typedef pixfmt_alpha_blend_gray<blender_sgray8, rendering_buffer> pixfmt_sgray8;
typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16;
typedef pixfmt_alpha_blend_gray<blender_gray32, rendering_buffer> pixfmt_gray32;
typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre;
typedef pixfmt_alpha_blend_gray<blender_sgray8_pre, rendering_buffer> pixfmt_sgray8_pre;
typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre;
typedef pixfmt_alpha_blend_gray<blender_gray32_pre, rendering_buffer> pixfmt_gray32_pre;
}
#endif

995
3party/agg/agg_pixfmt_rgb.h Normal file
View file

@ -0,0 +1,995 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for high precision colors has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_RGB_INCLUDED
#define AGG_PIXFMT_RGB_INCLUDED
#include <string.h>
#include "agg_pixfmt_base.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//=====================================================apply_gamma_dir_rgb
template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb
{
public:
typedef typename ColorT::value_type value_type;
apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
AGG_INLINE void operator () (value_type* p)
{
p[Order::R] = m_gamma.dir(p[Order::R]);
p[Order::G] = m_gamma.dir(p[Order::G]);
p[Order::B] = m_gamma.dir(p[Order::B]);
}
private:
const GammaLut& m_gamma;
};
//=====================================================apply_gamma_inv_rgb
template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb
{
public:
typedef typename ColorT::value_type value_type;
apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
AGG_INLINE void operator () (value_type* p)
{
p[Order::R] = m_gamma.inv(p[Order::R]);
p[Order::G] = m_gamma.inv(p[Order::G]);
p[Order::B] = m_gamma.inv(p[Order::B]);
}
private:
const GammaLut& m_gamma;
};
//=========================================================blender_rgb
template<class ColorT, class Order>
struct blender_rgb
{
typedef ColorT color_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
typedef typename color_type::long_type long_type;
// Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
// compositing function. Since the render buffer is opaque we skip the
// initial premultiply and final demultiply.
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
{
blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
}
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
value_type cr, value_type cg, value_type cb, value_type alpha)
{
p[Order::R] = color_type::lerp(p[Order::R], cr, alpha);
p[Order::G] = color_type::lerp(p[Order::G], cg, alpha);
p[Order::B] = color_type::lerp(p[Order::B], cb, alpha);
}
};
//======================================================blender_rgb_pre
template<class ColorT, class Order>
struct blender_rgb_pre
{
typedef ColorT color_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
typedef typename color_type::long_type long_type;
// Blend pixels using the premultiplied form of Alvy-Ray Smith's
// compositing function.
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
{
blend_pix(p,
color_type::mult_cover(cr, cover),
color_type::mult_cover(cg, cover),
color_type::mult_cover(cb, cover),
color_type::mult_cover(alpha, cover));
}
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
value_type cr, value_type cg, value_type cb, value_type alpha)
{
p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha);
p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha);
p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha);
}
};
//===================================================blender_rgb_gamma
template<class ColorT, class Order, class Gamma>
class blender_rgb_gamma : public blender_base<ColorT, Order>
{
public:
typedef ColorT color_type;
typedef Order order_type;
typedef Gamma gamma_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
typedef typename color_type::long_type long_type;
//--------------------------------------------------------------------
blender_rgb_gamma() : m_gamma(0) {}
void gamma(const gamma_type& g) { m_gamma = &g; }
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(value_type* p,
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
{
blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(value_type* p,
value_type cr, value_type cg, value_type cb, value_type alpha)
{
calc_type r = m_gamma->dir(p[Order::R]);
calc_type g = m_gamma->dir(p[Order::G]);
calc_type b = m_gamma->dir(p[Order::B]);
p[Order::R] = m_gamma->inv(color_type::lerp(r, m_gamma->dir(cr), alpha));
p[Order::G] = m_gamma->inv(color_type::lerp(g, m_gamma->dir(cg), alpha));
p[Order::B] = m_gamma->inv(color_type::lerp(b, m_gamma->dir(cb), alpha));
}
private:
const gamma_type* m_gamma;
};
//==================================================pixfmt_alpha_blend_rgb
template<class Blender, class RenBuf, unsigned Step, unsigned Offset = 0>
class pixfmt_alpha_blend_rgb
{
public:
typedef pixfmt_rgb_tag pixfmt_category;
typedef RenBuf rbuf_type;
typedef Blender blender_type;
typedef typename rbuf_type::row_data row_data;
typedef typename blender_type::color_type color_type;
typedef typename blender_type::order_type order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
enum
{
num_components = 3,
pix_step = Step,
pix_offset = Offset,
pix_width = sizeof(value_type) * pix_step
};
struct pixel_type
{
value_type c[num_components];
void set(value_type r, value_type g, value_type b)
{
c[order_type::R] = r;
c[order_type::G] = g;
c[order_type::B] = b;
}
void set(const color_type& color)
{
set(color.r, color.g, color.b);
}
void get(value_type& r, value_type& g, value_type& b) const
{
r = c[order_type::R];
g = c[order_type::G];
b = c[order_type::B];
}
color_type get() const
{
return color_type(
c[order_type::R],
c[order_type::G],
c[order_type::B]);
}
pixel_type* next()
{
return (pixel_type*)(c + pix_step);
}
const pixel_type* next() const
{
return (const pixel_type*)(c + pix_step);
}
pixel_type* advance(int n)
{
return (pixel_type*)(c + n * pix_step);
}
const pixel_type* advance(int n) const
{
return (const pixel_type*)(c + n * pix_step);
}
};
private:
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p,
value_type r, value_type g, value_type b, value_type a,
unsigned cover)
{
m_blender.blend_pix(p->c, r, g, b, a, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p,
value_type r, value_type g, value_type b, value_type a)
{
m_blender.blend_pix(p->c, r, g, b, a);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
{
m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
{
m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
{
if (!c.is_transparent())
{
if (c.is_opaque() && cover == cover_mask)
{
p->set(c);
}
else
{
blend_pix(p, c, cover);
}
}
}
//--------------------------------------------------------------------
AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
{
if (!c.is_transparent())
{
if (c.is_opaque())
{
p->set(c);
}
else
{
blend_pix(p, c);
}
}
}
public:
//--------------------------------------------------------------------
explicit pixfmt_alpha_blend_rgb(rbuf_type& rb) :
m_rbuf(&rb)
{}
void attach(rbuf_type& rb) { m_rbuf = &rb; }
//--------------------------------------------------------------------
template<class PixFmt>
bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
{
rect_i r(x1, y1, x2, y2);
if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
{
int stride = pixf.stride();
m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
(r.x2 - r.x1) + 1,
(r.y2 - r.y1) + 1,
stride);
return true;
}
return false;
}
//--------------------------------------------------------------------
Blender& blender() { return m_blender; }
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
//--------------------------------------------------------------------
AGG_INLINE int8u* pix_ptr(int x, int y)
{
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
}
AGG_INLINE const int8u* pix_ptr(int x, int y) const
{
return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
}
// Return pointer to pixel value, forcing row to be allocated.
AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len)
{
return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset));
}
// Return pointer to pixel value, or null if row not allocated.
AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const
{
int8u* p = m_rbuf->row_ptr(y);
return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
}
// Get pixel pointer from raw buffer pointer.
AGG_INLINE static pixel_type* pix_value_ptr(void* p)
{
return (pixel_type*)((value_type*)p + pix_offset);
}
// Get pixel pointer from raw buffer pointer.
AGG_INLINE static const pixel_type* pix_value_ptr(const void* p)
{
return (const pixel_type*)((const value_type*)p + pix_offset);
}
//--------------------------------------------------------------------
AGG_INLINE static void write_plain_color(void* p, color_type c)
{
// RGB formats are implicitly premultiplied.
c.premultiply();
pix_value_ptr(p)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE static color_type read_plain_color(const void* p)
{
return pix_value_ptr(p)->get();
}
//--------------------------------------------------------------------
AGG_INLINE static void make_pix(int8u* p, const color_type& c)
{
((pixel_type*)p)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE color_type pixel(int x, int y) const
{
if (const pixel_type* p = pix_value_ptr(x, y))
{
return p->get();
}
return color_type::no_color();
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
pix_value_ptr(x, y, 1)->set(c);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
pixel_type* p = pix_value_ptr(x, y, len);
do
{
p->set(c);
p = p->next();
}
while(--len);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
do
{
pix_value_ptr(x, y++, 1)->set(c);
}
while (--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
if (!c.is_transparent())
{
pixel_type* p = pix_value_ptr(x, y, len);
if (c.is_opaque() && cover == cover_mask)
{
do
{
p->set(c);
p = p->next();
}
while (--len);
}
else
{
do
{
blend_pix(p, c, cover);
p = p->next();
}
while (--len);
}
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
if (!c.is_transparent())
{
if (c.is_opaque() && cover == cover_mask)
{
do
{
pix_value_ptr(x, y++, 1)->set(c);
}
while (--len);
}
else
{
do
{
blend_pix(pix_value_ptr(x, y++, 1), c, cover);
}
while (--len);
}
}
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (!c.is_transparent())
{
pixel_type* p = pix_value_ptr(x, y, len);
do
{
if (c.is_opaque() && *covers == cover_mask)
{
p->set(c);
}
else
{
blend_pix(p, c, *covers);
}
p = p->next();
++covers;
}
while (--len);
}
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (!c.is_transparent())
{
do
{
pixel_type* p = pix_value_ptr(x, y++, 1);
if (c.is_opaque() && *covers == cover_mask)
{
p->set(c);
}
else
{
blend_pix(p, c, *covers);
}
++covers;
}
while (--len);
}
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y,
unsigned len,
const color_type* colors)
{
pixel_type* p = pix_value_ptr(x, y, len);
do
{
p->set(*colors++);
p = p->next();
}
while (--len);
}
//--------------------------------------------------------------------
void copy_color_vspan(int x, int y,
unsigned len,
const color_type* colors)
{
do
{
pix_value_ptr(x, y++, 1)->set(*colors++);
}
while (--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
pixel_type* p = pix_value_ptr(x, y, len);
if (covers)
{
do
{
copy_or_blend_pix(p, *colors++, *covers++);
p = p->next();
}
while (--len);
}
else
{
if (cover == cover_mask)
{
do
{
copy_or_blend_pix(p, *colors++);
p = p->next();
}
while (--len);
}
else
{
do
{
copy_or_blend_pix(p, *colors++, cover);
p = p->next();
}
while (--len);
}
}
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
if (covers)
{
do
{
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
}
while (--len);
}
else
{
if (cover == cover_mask)
{
do
{
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
}
while (--len);
}
else
{
do
{
copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
}
while (--len);
}
}
}
//--------------------------------------------------------------------
template<class Function> void for_each_pixel(Function f)
{
for (unsigned y = 0; y < height(); ++y)
{
row_data r = m_rbuf->row(y);
if (r.ptr)
{
unsigned len = r.x2 - r.x1 + 1;
pixel_type* p = pix_value_ptr(r.x1, y, len);
do
{
f(p->c);
p = p->next();
}
while (--len);
}
}
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
{
for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
{
for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g));
}
//--------------------------------------------------------------------
template<class RenBuf2>
void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
if (const int8u* p = from.row_ptr(ysrc))
{
memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
p + xsrc * pix_width,
len * pix_width);
}
}
//--------------------------------------------------------------------
// Blend from an RGBA surface.
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len,
int8u cover)
{
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
typedef typename SrcPixelFormatRenderer::order_type src_order;
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
{
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
if (cover == cover_mask)
{
do
{
value_type alpha = psrc->c[src_order::A];
if (alpha <= color_type::empty_value())
{
if (alpha >= color_type::full_value())
{
pdst->c[order_type::R] = psrc->c[src_order::R];
pdst->c[order_type::G] = psrc->c[src_order::G];
pdst->c[order_type::B] = psrc->c[src_order::B];
}
else
{
blend_pix(pdst,
psrc->c[src_order::R],
psrc->c[src_order::G],
psrc->c[src_order::B],
alpha);
}
}
psrc = psrc->next();
pdst = pdst->next();
}
while(--len);
}
else
{
do
{
copy_or_blend_pix(pdst, psrc->get(), cover);
psrc = psrc->next();
pdst = pdst->next();
}
while (--len);
}
}
}
//--------------------------------------------------------------------
// Blend from single color, using grayscale surface as alpha channel.
template<class SrcPixelFormatRenderer>
void blend_from_color(const SrcPixelFormatRenderer& from,
const color_type& color,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len,
int8u cover)
{
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
typedef typename SrcPixelFormatRenderer::color_type src_color_type;
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
{
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
do
{
copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
psrc = psrc->next();
pdst = pdst->next();
}
while (--len);
}
}
//--------------------------------------------------------------------
// Blend from color table, using grayscale surface as indexes into table.
// Obviously, this only works for integer value types.
template<class SrcPixelFormatRenderer>
void blend_from_lut(const SrcPixelFormatRenderer& from,
const color_type* color_lut,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len,
int8u cover)
{
typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
{
pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
if (cover == cover_mask)
{
do
{
const color_type& color = color_lut[psrc->c[0]];
blend_pix(pdst, color);
psrc = psrc->next();
pdst = pdst->next();
}
while(--len);
}
else
{
do
{
copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
psrc = psrc->next();
pdst = pdst->next();
}
while(--len);
}
}
}
private:
rbuf_type* m_rbuf;
Blender m_blender;
};
//-----------------------------------------------------------------------
typedef blender_rgb<rgba8, order_rgb> blender_rgb24;
typedef blender_rgb<rgba8, order_bgr> blender_bgr24;
typedef blender_rgb<srgba8, order_rgb> blender_srgb24;
typedef blender_rgb<srgba8, order_bgr> blender_sbgr24;
typedef blender_rgb<rgba16, order_rgb> blender_rgb48;
typedef blender_rgb<rgba16, order_bgr> blender_bgr48;
typedef blender_rgb<rgba32, order_rgb> blender_rgb96;
typedef blender_rgb<rgba32, order_bgr> blender_bgr96;
typedef blender_rgb_pre<rgba8, order_rgb> blender_rgb24_pre;
typedef blender_rgb_pre<rgba8, order_bgr> blender_bgr24_pre;
typedef blender_rgb_pre<srgba8, order_rgb> blender_srgb24_pre;
typedef blender_rgb_pre<srgba8, order_bgr> blender_sbgr24_pre;
typedef blender_rgb_pre<rgba16, order_rgb> blender_rgb48_pre;
typedef blender_rgb_pre<rgba16, order_bgr> blender_bgr48_pre;
typedef blender_rgb_pre<rgba32, order_rgb> blender_rgb96_pre;
typedef blender_rgb_pre<rgba32, order_bgr> blender_bgr96_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 3> pixfmt_rgb24;
typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 3> pixfmt_bgr24;
typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 3> pixfmt_srgb24;
typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 3> pixfmt_sbgr24;
typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 3> pixfmt_rgb48;
typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 3> pixfmt_bgr48;
typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 3> pixfmt_rgb96;
typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 3> pixfmt_bgr96;
typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 3> pixfmt_rgb24_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 3> pixfmt_bgr24_pre;
typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 3> pixfmt_srgb24_pre;
typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 3> pixfmt_sbgr24_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 3> pixfmt_rgb48_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 3> pixfmt_bgr48_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 3> pixfmt_rgb96_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 3> pixfmt_bgr96_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 0> pixfmt_rgbx32;
typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 1> pixfmt_xrgb32;
typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 1> pixfmt_xbgr32;
typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 0> pixfmt_bgrx32;
typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 0> pixfmt_srgbx32;
typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 1> pixfmt_sxrgb32;
typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 1> pixfmt_sxbgr32;
typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 0> pixfmt_sbgrx32;
typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 0> pixfmt_rgbx64;
typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 1> pixfmt_xrgb64;
typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 1> pixfmt_xbgr64;
typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 0> pixfmt_bgrx64;
typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 0> pixfmt_rgbx128;
typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 1> pixfmt_xrgb128;
typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 1> pixfmt_xbgr128;
typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 0> pixfmt_bgrx128;
typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 0> pixfmt_rgbx32_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 1> pixfmt_xrgb32_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 1> pixfmt_xbgr32_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 0> pixfmt_bgrx32_pre;
typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 0> pixfmt_srgbx32_pre;
typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 1> pixfmt_sxrgb32_pre;
typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 1> pixfmt_sxbgr32_pre;
typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 0> pixfmt_sbgrx32_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 0> pixfmt_rgbx64_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 1> pixfmt_xrgb64_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 1> pixfmt_xbgr64_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 0> pixfmt_bgrx64_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 0> pixfmt_rgbx128_pre;
typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 1> pixfmt_xrgb128_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 1> pixfmt_xbgr128_pre;
typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 0> pixfmt_bgrx128_pre;
//-----------------------------------------------------pixfmt_rgb24_gamma
template<class Gamma> class pixfmt_rgb24_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3>
{
public:
pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb)
{
this->blender().gamma(g);
}
};
//-----------------------------------------------------pixfmt_srgb24_gamma
template<class Gamma> class pixfmt_srgb24_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3>
{
public:
pixfmt_srgb24_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb)
{
this->blender().gamma(g);
}
};
//-----------------------------------------------------pixfmt_bgr24_gamma
template<class Gamma> class pixfmt_bgr24_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3>
{
public:
pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb)
{
this->blender().gamma(g);
}
};
//-----------------------------------------------------pixfmt_sbgr24_gamma
template<class Gamma> class pixfmt_sbgr24_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3>
{
public:
pixfmt_sbgr24_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb)
{
this->blender().gamma(g);
}
};
//-----------------------------------------------------pixfmt_rgb48_gamma
template<class Gamma> class pixfmt_rgb48_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3>
{
public:
pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3>(rb)
{
this->blender().gamma(g);
}
};
//-----------------------------------------------------pixfmt_bgr48_gamma
template<class Gamma> class pixfmt_bgr48_gamma :
public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3>
{
public:
pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) :
pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3>(rb)
{
this->blender().gamma(g);
}
};
}
#endif

File diff suppressed because it is too large Load diff

2793
3party/agg/agg_pixfmt_rgba.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,157 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_TRANSPOSER_INCLUDED
#define AGG_PIXFMT_TRANSPOSER_INCLUDED
#include "agg_basics.h"
namespace agg
{
//=======================================================pixfmt_transposer
template<class PixFmt> class pixfmt_transposer
{
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::row_data row_data;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
//--------------------------------------------------------------------
pixfmt_transposer() : m_pixf(0) {}
explicit pixfmt_transposer(pixfmt_type& pixf) : m_pixf(&pixf) {}
void attach(pixfmt_type& pixf) { m_pixf = &pixf; }
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_pixf->height(); }
AGG_INLINE unsigned height() const { return m_pixf->width(); }
//--------------------------------------------------------------------
AGG_INLINE color_type pixel(int x, int y) const
{
return m_pixf->pixel(y, x);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
m_pixf->copy_pixel(y, x, c);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y,
const color_type& c,
int8u cover)
{
m_pixf->blend_pixel(y, x, c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
m_pixf->copy_vline(y, x, len, c);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
m_pixf->copy_hline(y, x, len, c);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_hline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
m_pixf->blend_vline(y, x, len, c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_vline(int x, int y,
unsigned len,
const color_type& c,
int8u cover)
{
m_pixf->blend_hline(y, x, len, c, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
m_pixf->blend_solid_vspan(y, x, len, c, covers);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
m_pixf->blend_solid_hspan(y, x, len, c, covers);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_color_hspan(int x, int y,
unsigned len,
const color_type* colors)
{
m_pixf->copy_color_vspan(y, x, len, colors);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_color_vspan(int x, int y,
unsigned len,
const color_type* colors)
{
m_pixf->copy_color_hspan(y, x, len, colors);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
m_pixf->blend_color_vspan(y, x, len, colors, covers, cover);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_color_vspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
m_pixf->blend_color_hspan(y, x, len, colors, covers, cover);
}
private:
pixfmt_type* m_pixf;
};
}
#endif

View file

@ -0,0 +1,738 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED
#define AGG_RASTERIZER_CELLS_AA_INCLUDED
#include <string.h>
#include <math.h>
#include "agg_math.h"
#include "agg_array.h"
namespace agg
{
//-----------------------------------------------------rasterizer_cells_aa
// An internal class that implements the main rasterization algorithm.
// Used in the rasterizer. Should not be used direcly.
template<class Cell> class rasterizer_cells_aa
{
enum cell_block_scale_e
{
cell_block_shift = 12,
cell_block_size = 1 << cell_block_shift,
cell_block_mask = cell_block_size - 1,
cell_block_pool = 256,
cell_block_limit = 1024
};
struct sorted_y
{
unsigned start;
unsigned num;
};
public:
typedef Cell cell_type;
typedef rasterizer_cells_aa<Cell> self_type;
~rasterizer_cells_aa();
rasterizer_cells_aa();
void reset();
void style(const cell_type& style_cell);
void line(int x1, int y1, int x2, int y2);
int min_x() const { return m_min_x; }
int min_y() const { return m_min_y; }
int max_x() const { return m_max_x; }
int max_y() const { return m_max_y; }
void sort_cells();
unsigned total_cells() const
{
return m_num_cells;
}
unsigned scanline_num_cells(unsigned y) const
{
return m_sorted_y[y - m_min_y].num;
}
const cell_type* const* scanline_cells(unsigned y) const
{
return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start;
}
bool sorted() const { return m_sorted; }
private:
rasterizer_cells_aa(const self_type&);
const self_type& operator = (const self_type&);
void set_curr_cell(int x, int y);
void add_curr_cell();
void render_hline(int ey, int x1, int y1, int x2, int y2);
void allocate_block();
private:
unsigned m_num_blocks;
unsigned m_max_blocks;
unsigned m_curr_block;
unsigned m_num_cells;
cell_type** m_cells;
cell_type* m_curr_cell_ptr;
pod_vector<cell_type*> m_sorted_cells;
pod_vector<sorted_y> m_sorted_y;
cell_type m_curr_cell;
cell_type m_style_cell;
int m_min_x;
int m_min_y;
int m_max_x;
int m_max_y;
bool m_sorted;
};
//------------------------------------------------------------------------
template<class Cell>
rasterizer_cells_aa<Cell>::~rasterizer_cells_aa()
{
if(m_num_blocks)
{
cell_type** ptr = m_cells + m_num_blocks - 1;
while(m_num_blocks--)
{
pod_allocator<cell_type>::deallocate(*ptr, cell_block_size);
ptr--;
}
pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
}
}
//------------------------------------------------------------------------
template<class Cell>
rasterizer_cells_aa<Cell>::rasterizer_cells_aa() :
m_num_blocks(0),
m_max_blocks(0),
m_curr_block(0),
m_num_cells(0),
m_cells(0),
m_curr_cell_ptr(0),
m_sorted_cells(),
m_sorted_y(),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF),
m_sorted(false)
{
m_style_cell.initial();
m_curr_cell.initial();
}
//------------------------------------------------------------------------
template<class Cell>
void rasterizer_cells_aa<Cell>::reset()
{
m_num_cells = 0;
m_curr_block = 0;
m_curr_cell.initial();
m_style_cell.initial();
m_sorted = false;
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
m_max_y = -0x7FFFFFFF;
}
//------------------------------------------------------------------------
template<class Cell>
AGG_INLINE void rasterizer_cells_aa<Cell>::add_curr_cell()
{
if(m_curr_cell.area | m_curr_cell.cover)
{
if((m_num_cells & cell_block_mask) == 0)
{
if(m_num_blocks >= cell_block_limit) return;
allocate_block();
}
*m_curr_cell_ptr++ = m_curr_cell;
++m_num_cells;
}
}
//------------------------------------------------------------------------
template<class Cell>
AGG_INLINE void rasterizer_cells_aa<Cell>::set_curr_cell(int x, int y)
{
if(m_curr_cell.not_equal(x, y, m_style_cell))
{
add_curr_cell();
m_curr_cell.style(m_style_cell);
m_curr_cell.x = x;
m_curr_cell.y = y;
m_curr_cell.cover = 0;
m_curr_cell.area = 0;
}
}
//------------------------------------------------------------------------
template<class Cell>
AGG_INLINE void rasterizer_cells_aa<Cell>::render_hline(int ey,
int x1, int y1,
int x2, int y2)
{
int ex1 = x1 >> poly_subpixel_shift;
int ex2 = x2 >> poly_subpixel_shift;
int fx1 = x1 & poly_subpixel_mask;
int fx2 = x2 & poly_subpixel_mask;
int delta, p, first, dx;
int incr, lift, mod, rem;
//trivial case. Happens often
if(y1 == y2)
{
set_curr_cell(ex2, ey);
return;
}
//everything is located in a single cell. That is easy!
if(ex1 == ex2)
{
delta = y2 - y1;
m_curr_cell.cover += delta;
m_curr_cell.area += (fx1 + fx2) * delta;
return;
}
//ok, we'll have to render a run of adjacent cells on the same
//hline...
p = (poly_subpixel_scale - fx1) * (y2 - y1);
first = poly_subpixel_scale;
incr = 1;
dx = x2 - x1;
if(dx < 0)
{
p = fx1 * (y2 - y1);
first = 0;
incr = -1;
dx = -dx;
}
delta = p / dx;
mod = p % dx;
if(mod < 0)
{
delta--;
mod += dx;
}
m_curr_cell.cover += delta;
m_curr_cell.area += (fx1 + first) * delta;
ex1 += incr;
set_curr_cell(ex1, ey);
y1 += delta;
if(ex1 != ex2)
{
p = poly_subpixel_scale * (y2 - y1 + delta);
lift = p / dx;
rem = p % dx;
if (rem < 0)
{
lift--;
rem += dx;
}
mod -= dx;
while (ex1 != ex2)
{
delta = lift;
mod += rem;
if(mod >= 0)
{
mod -= dx;
delta++;
}
m_curr_cell.cover += delta;
m_curr_cell.area += poly_subpixel_scale * delta;
y1 += delta;
ex1 += incr;
set_curr_cell(ex1, ey);
}
}
delta = y2 - y1;
m_curr_cell.cover += delta;
m_curr_cell.area += (fx2 + poly_subpixel_scale - first) * delta;
}
//------------------------------------------------------------------------
template<class Cell>
AGG_INLINE void rasterizer_cells_aa<Cell>::style(const cell_type& style_cell)
{
m_style_cell.style(style_cell);
}
//------------------------------------------------------------------------
template<class Cell>
void rasterizer_cells_aa<Cell>::line(int x1, int y1, int x2, int y2)
{
enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift };
int dx = x2 - x1;
if(dx >= dx_limit || dx <= -dx_limit)
{
int cx = (x1 + x2) >> 1;
int cy = (y1 + y2) >> 1;
line(x1, y1, cx, cy);
line(cx, cy, x2, y2);
}
int dy = y2 - y1;
int ex1 = x1 >> poly_subpixel_shift;
int ex2 = x2 >> poly_subpixel_shift;
int ey1 = y1 >> poly_subpixel_shift;
int ey2 = y2 >> poly_subpixel_shift;
int fy1 = y1 & poly_subpixel_mask;
int fy2 = y2 & poly_subpixel_mask;
int x_from, x_to;
int p, rem, mod, lift, delta, first, incr;
if(ex1 < m_min_x) m_min_x = ex1;
if(ex1 > m_max_x) m_max_x = ex1;
if(ey1 < m_min_y) m_min_y = ey1;
if(ey1 > m_max_y) m_max_y = ey1;
if(ex2 < m_min_x) m_min_x = ex2;
if(ex2 > m_max_x) m_max_x = ex2;
if(ey2 < m_min_y) m_min_y = ey2;
if(ey2 > m_max_y) m_max_y = ey2;
set_curr_cell(ex1, ey1);
//everything is on a single hline
if(ey1 == ey2)
{
render_hline(ey1, x1, fy1, x2, fy2);
return;
}
//Vertical line - we have to calculate start and end cells,
//and then - the common values of the area and coverage for
//all cells of the line. We know exactly there's only one
//cell, so, we don't have to call render_hline().
incr = 1;
if(dx == 0)
{
int ex = x1 >> poly_subpixel_shift;
int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1;
int area;
first = poly_subpixel_scale;
if(dy < 0)
{
first = 0;
incr = -1;
}
x_from = x1;
//render_hline(ey1, x_from, fy1, x_from, first);
delta = first - fy1;
m_curr_cell.cover += delta;
m_curr_cell.area += two_fx * delta;
ey1 += incr;
set_curr_cell(ex, ey1);
delta = first + first - poly_subpixel_scale;
area = two_fx * delta;
while(ey1 != ey2)
{
//render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, first);
m_curr_cell.cover = delta;
m_curr_cell.area = area;
ey1 += incr;
set_curr_cell(ex, ey1);
}
//render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, fy2);
delta = fy2 - poly_subpixel_scale + first;
m_curr_cell.cover += delta;
m_curr_cell.area += two_fx * delta;
return;
}
//ok, we have to render several hlines
p = (poly_subpixel_scale - fy1) * dx;
first = poly_subpixel_scale;
if(dy < 0)
{
p = fy1 * dx;
first = 0;
incr = -1;
dy = -dy;
}
delta = p / dy;
mod = p % dy;
if(mod < 0)
{
delta--;
mod += dy;
}
x_from = x1 + delta;
render_hline(ey1, x1, fy1, x_from, first);
ey1 += incr;
set_curr_cell(x_from >> poly_subpixel_shift, ey1);
if(ey1 != ey2)
{
p = poly_subpixel_scale * dx;
lift = p / dy;
rem = p % dy;
if(rem < 0)
{
lift--;
rem += dy;
}
mod -= dy;
while(ey1 != ey2)
{
delta = lift;
mod += rem;
if (mod >= 0)
{
mod -= dy;
delta++;
}
x_to = x_from + delta;
render_hline(ey1, x_from, poly_subpixel_scale - first, x_to, first);
x_from = x_to;
ey1 += incr;
set_curr_cell(x_from >> poly_subpixel_shift, ey1);
}
}
render_hline(ey1, x_from, poly_subpixel_scale - first, x2, fy2);
}
//------------------------------------------------------------------------
template<class Cell>
void rasterizer_cells_aa<Cell>::allocate_block()
{
if(m_curr_block >= m_num_blocks)
{
if(m_num_blocks >= m_max_blocks)
{
cell_type** new_cells =
pod_allocator<cell_type*>::allocate(m_max_blocks +
cell_block_pool);
if(m_cells)
{
memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*));
pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
}
m_cells = new_cells;
m_max_blocks += cell_block_pool;
}
m_cells[m_num_blocks++] =
pod_allocator<cell_type>::allocate(cell_block_size);
}
m_curr_cell_ptr = m_cells[m_curr_block++];
}
//------------------------------------------------------------------------
template <class T> static AGG_INLINE void swap_cells(T* a, T* b)
{
T temp = *a;
*a = *b;
*b = temp;
}
//------------------------------------------------------------------------
enum
{
qsort_threshold = 9
};
//------------------------------------------------------------------------
template<class Cell>
void qsort_cells(Cell** start, unsigned num)
{
Cell** stack[80];
Cell*** top;
Cell** limit;
Cell** base;
limit = start + num;
base = start;
top = stack;
for (;;)
{
int len = int(limit - base);
Cell** i;
Cell** j;
Cell** pivot;
if(len > qsort_threshold)
{
// we use base + len/2 as the pivot
pivot = base + len / 2;
swap_cells(base, pivot);
i = base + 1;
j = limit - 1;
// now ensure that *i <= *base <= *j
if((*j)->x < (*i)->x)
{
swap_cells(i, j);
}
if((*base)->x < (*i)->x)
{
swap_cells(base, i);
}
if((*j)->x < (*base)->x)
{
swap_cells(base, j);
}
for(;;)
{
int x = (*base)->x;
do i++; while( (*i)->x < x );
do j--; while( x < (*j)->x );
if(i > j)
{
break;
}
swap_cells(i, j);
}
swap_cells(base, j);
// now, push the largest sub-array
if(j - base > limit - i)
{
top[0] = base;
top[1] = j;
base = i;
}
else
{
top[0] = i;
top[1] = limit;
limit = j;
}
top += 2;
}
else
{
// the sub-array is small, perform insertion sort
j = base;
i = j + 1;
for(; i < limit; j = i, i++)
{
for(; j[1]->x < (*j)->x; j--)
{
swap_cells(j + 1, j);
if (j == base)
{
break;
}
}
}
if(top > stack)
{
top -= 2;
base = top[0];
limit = top[1];
}
else
{
break;
}
}
}
}
//------------------------------------------------------------------------
template<class Cell>
void rasterizer_cells_aa<Cell>::sort_cells()
{
if(m_sorted) return; //Perform sort only the first time.
add_curr_cell();
m_curr_cell.x = 0x7FFFFFFF;
m_curr_cell.y = 0x7FFFFFFF;
m_curr_cell.cover = 0;
m_curr_cell.area = 0;
if(m_num_cells == 0) return;
// DBG: Check to see if min/max works well.
//for(unsigned nc = 0; nc < m_num_cells; nc++)
//{
// cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask);
// if(cell->x < m_min_x ||
// cell->y < m_min_y ||
// cell->x > m_max_x ||
// cell->y > m_max_y)
// {
// cell = cell; // Breakpoint here
// }
//}
// Allocate the array of cell pointers
m_sorted_cells.allocate(m_num_cells, 16);
// Allocate and zero the Y array
m_sorted_y.allocate(m_max_y - m_min_y + 1, 16);
m_sorted_y.zero();
// Create the Y-histogram (count the numbers of cells for each Y)
cell_type** block_ptr = m_cells;
cell_type* cell_ptr;
unsigned nb = m_num_cells;
unsigned i;
while(nb)
{
cell_ptr = *block_ptr++;
i = (nb > unsigned(cell_block_size)) ? unsigned(cell_block_size) : nb;
nb -= i;
while(i--)
{
m_sorted_y[cell_ptr->y - m_min_y].start++;
++cell_ptr;
}
}
// Convert the Y-histogram into the array of starting indexes
unsigned start = 0;
for(i = 0; i < m_sorted_y.size(); i++)
{
unsigned v = m_sorted_y[i].start;
m_sorted_y[i].start = start;
start += v;
}
// Fill the cell pointer array sorted by Y
block_ptr = m_cells;
nb = m_num_cells;
while(nb)
{
cell_ptr = *block_ptr++;
i = (nb > unsigned(cell_block_size)) ? unsigned(cell_block_size) : nb;
nb -= i;
while(i--)
{
sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
++curr_y.num;
++cell_ptr;
}
}
// Finally arrange the X-arrays
for(i = 0; i < m_sorted_y.size(); i++)
{
const sorted_y& curr_y = m_sorted_y[i];
if(curr_y.num)
{
qsort_cells(m_sorted_cells.data() + curr_y.start, curr_y.num);
}
}
m_sorted = true;
}
//------------------------------------------------------scanline_hit_test
class scanline_hit_test
{
public:
scanline_hit_test(int x) : m_x(x), m_hit(false) {}
void reset_spans() {}
void finalize(int) {}
void add_cell(int x, int)
{
if(m_x == x) m_hit = true;
}
void add_span(int x, int len, int)
{
if(m_x >= x && m_x < x+len) m_hit = true;
}
unsigned num_spans() const { return 1; }
bool hit() const { return m_hit; }
private:
int m_x;
bool m_hit;
};
}
#endif

View file

@ -0,0 +1,663 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_COMPOUND_AA_INCLUDED
#define AGG_RASTERIZER_COMPOUND_AA_INCLUDED
#include "agg_rasterizer_cells_aa.h"
#include "agg_rasterizer_sl_clip.h"
namespace agg
{
//-----------------------------------------------------------cell_style_aa
// A pixel cell. There're no constructors defined and it was done
// intentionally in order to avoid extra overhead when allocating an
// array of cells.
struct cell_style_aa
{
int x;
int y;
int cover;
int area;
int16 left, right;
void initial()
{
x = 0x7FFFFFFF;
y = 0x7FFFFFFF;
cover = 0;
area = 0;
left = -1;
right = -1;
}
void style(const cell_style_aa& c)
{
left = c.left;
right = c.right;
}
int not_equal(int ex, int ey, const cell_style_aa& c) const
{
return (ex - x) | (ey - y) | (left - c.left) | (right - c.right);
}
};
//===========================================================layer_order_e
enum layer_order_e
{
layer_unsorted, //------layer_unsorted
layer_direct, //------layer_direct
layer_inverse //------layer_inverse
};
//==================================================rasterizer_compound_aa
template<class Clip=rasterizer_sl_clip_int> class rasterizer_compound_aa
{
struct style_info
{
unsigned start_cell;
unsigned num_cells;
int last_x;
};
struct cell_info
{
int x, area, cover;
};
public:
typedef Clip clip_type;
typedef typename Clip::conv_type conv_type;
typedef typename Clip::coord_type coord_type;
enum aa_scale_e
{
aa_shift = 8,
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1,
aa_scale2 = aa_scale * 2,
aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_compound_aa() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
m_layer_order(layer_direct),
m_styles(), // Active Styles
m_ast(), // Active Style Table (unique values)
m_asm(), // Active Style Mask
m_cells(),
m_cover_buf(),
m_min_style(0x7FFFFFFF),
m_max_style(-0x7FFFFFFF),
m_start_x(0),
m_start_y(0),
m_scan_y(0x7FFFFFFF),
m_sl_start(0),
m_sl_len(0)
{}
//--------------------------------------------------------------------
void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
void layer_order(layer_order_e order);
//--------------------------------------------------------------------
void styles(int left, int right);
void move_to(int x, int y);
void line_to(int x, int y);
void move_to_d(double x, double y);
void line_to_d(double x, double y);
void add_vertex(double x, double y, unsigned cmd);
void edge(int x1, int y1, int x2, int y2);
void edge_d(double x1, double y1, double x2, double y2);
//-------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
if(m_outline.sorted()) reset();
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
int min_y() const { return m_outline.min_y(); }
int max_x() const { return m_outline.max_x(); }
int max_y() const { return m_outline.max_y(); }
int min_style() const { return m_min_style; }
int max_style() const { return m_max_style; }
//--------------------------------------------------------------------
void sort();
bool rewind_scanlines();
unsigned sweep_styles();
int scanline_start() const { return m_sl_start; }
unsigned scanline_length() const { return m_sl_len; }
unsigned style(unsigned style_idx) const;
cover_type* allocate_cover_buffer(unsigned len);
//--------------------------------------------------------------------
bool navigate_scanline(int y);
bool hit_test(int tx, int ty);
//--------------------------------------------------------------------
AGG_INLINE unsigned calculate_alpha(int area) const
{
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_mask2;
if(cover > aa_scale)
{
cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return cover;
}
//--------------------------------------------------------------------
// Sweeps one scanline with one style index. The style ID can be
// determined by calling style().
template<class Scanline> bool sweep_scanline(Scanline& sl, int style_idx)
{
int scan_y = m_scan_y - 1;
if(scan_y > m_outline.max_y()) return false;
sl.reset_spans();
if(style_idx < 0)
{
style_idx = 0;
}
else
{
style_idx++;
}
const style_info& st = m_styles[m_ast[style_idx]];
unsigned num_cells = st.num_cells;
cell_info* cell = &m_cells[st.start_cell];
int cover = 0;
while(num_cells--)
{
unsigned alpha;
int x = cell->x;
int area = cell->area;
cover += cell->cover;
++cell;
if(area)
{
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
sl.add_cell(x, alpha);
x++;
}
if(num_cells && cell->x > x)
{
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
if(alpha)
{
sl.add_span(x, cell->x - x, alpha);
}
}
}
if(sl.num_spans() == 0) return false;
sl.finalize(scan_y);
return true;
}
private:
void add_style(int style_id);
//--------------------------------------------------------------------
// Disable copying
rasterizer_compound_aa(const rasterizer_compound_aa<Clip>&);
const rasterizer_compound_aa<Clip>&
operator = (const rasterizer_compound_aa<Clip>&);
private:
rasterizer_cells_aa<cell_style_aa> m_outline;
clip_type m_clipper;
filling_rule_e m_filling_rule;
layer_order_e m_layer_order;
pod_vector<style_info> m_styles; // Active Styles
pod_vector<unsigned> m_ast; // Active Style Table (unique values)
pod_vector<int8u> m_asm; // Active Style Mask
pod_vector<cell_info> m_cells;
pod_vector<cover_type> m_cover_buf;
int m_min_style;
int m_max_style;
coord_type m_start_x;
coord_type m_start_y;
int m_scan_y;
int m_sl_start;
unsigned m_sl_len;
};
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::reset()
{
m_outline.reset();
m_min_style = 0x7FFFFFFF;
m_max_style = -0x7FFFFFFF;
m_scan_y = 0x7FFFFFFF;
m_sl_start = 0;
m_sl_len = 0;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::layer_order(layer_order_e order)
{
m_layer_order = order;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::reset_clipping()
{
reset();
m_clipper.reset_clipping();
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::styles(int left, int right)
{
cell_style_aa cell;
cell.initial();
cell.left = (int16)left;
cell.right = (int16)right;
m_outline.style(cell);
if(left >= 0 && left < m_min_style) m_min_style = left;
if(left >= 0 && left > m_max_style) m_max_style = left;
if(right >= 0 && right < m_min_style) m_min_style = right;
if(right >= 0 && right > m_max_style) m_max_style = right;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::move_to(int x, int y)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::line_to(int x, int y)
{
m_clipper.line_to(m_outline,
conv_type::downscale(x),
conv_type::downscale(y));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::move_to_d(double x, double y)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
if(is_vertex(cmd))
{
line_to_d(x, y);
}
else
if(is_close(cmd))
{
m_clipper.line_to(m_outline, m_start_x, m_start_y);
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::edge(int x1, int y1, int x2, int y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
conv_type::downscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE void rasterizer_compound_aa<Clip>::sort()
{
m_outline.sort_cells();
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_compound_aa<Clip>::rewind_scanlines()
{
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
if(m_max_style < m_min_style)
{
return false;
}
m_scan_y = m_outline.min_y();
m_styles.allocate(m_max_style - m_min_style + 2, 128);
return true;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE void rasterizer_compound_aa<Clip>::add_style(int style_id)
{
if(style_id < 0) style_id = 0;
else style_id -= m_min_style - 1;
unsigned nbyte = style_id >> 3;
unsigned mask = 1 << (style_id & 7);
style_info* style = &m_styles[style_id];
if((m_asm[nbyte] & mask) == 0)
{
m_ast.add(style_id);
m_asm[nbyte] |= mask;
style->start_cell = 0;
style->num_cells = 0;
style->last_x = -0x7FFFFFFF;
}
++style->start_cell;
}
//------------------------------------------------------------------------
// Returns the number of styles
template<class Clip>
unsigned rasterizer_compound_aa<Clip>::sweep_styles()
{
for(;;)
{
if(m_scan_y > m_outline.max_y()) return 0;
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_style_aa* const* cells = m_outline.scanline_cells(m_scan_y);
unsigned num_styles = m_max_style - m_min_style + 2;
const cell_style_aa* curr_cell;
unsigned style_id;
style_info* style;
cell_info* cell;
m_cells.allocate(num_cells * 2, 256); // Each cell can have two styles
m_ast.capacity(num_styles, 64);
m_asm.allocate((num_styles + 7) >> 3, 8);
m_asm.zero();
if(num_cells)
{
// Pre-add zero (for no-fill style, that is, -1).
// We need that to ensure that the "-1 style" would go first.
m_asm[0] |= 1;
m_ast.add(0);
style = &m_styles[0];
style->start_cell = 0;
style->num_cells = 0;
style->last_x = -0x7FFFFFFF;
m_sl_start = cells[0]->x;
m_sl_len = cells[num_cells-1]->x - m_sl_start + 1;
while(num_cells--)
{
curr_cell = *cells++;
add_style(curr_cell->left);
add_style(curr_cell->right);
}
// Convert the Y-histogram into the array of starting indexes
unsigned i;
unsigned start_cell = 0;
for(i = 0; i < m_ast.size(); i++)
{
style_info& st = m_styles[m_ast[i]];
unsigned v = st.start_cell;
st.start_cell = start_cell;
start_cell += v;
}
cells = m_outline.scanline_cells(m_scan_y);
num_cells = m_outline.scanline_num_cells(m_scan_y);
while(num_cells--)
{
curr_cell = *cells++;
style_id = (curr_cell->left < 0) ? 0 :
curr_cell->left - m_min_style + 1;
style = &m_styles[style_id];
if(curr_cell->x == style->last_x)
{
cell = &m_cells[style->start_cell + style->num_cells - 1];
cell->area += curr_cell->area;
cell->cover += curr_cell->cover;
}
else
{
cell = &m_cells[style->start_cell + style->num_cells];
cell->x = curr_cell->x;
cell->area = curr_cell->area;
cell->cover = curr_cell->cover;
style->last_x = curr_cell->x;
style->num_cells++;
}
style_id = (curr_cell->right < 0) ? 0 :
curr_cell->right - m_min_style + 1;
style = &m_styles[style_id];
if(curr_cell->x == style->last_x)
{
cell = &m_cells[style->start_cell + style->num_cells - 1];
cell->area -= curr_cell->area;
cell->cover -= curr_cell->cover;
}
else
{
cell = &m_cells[style->start_cell + style->num_cells];
cell->x = curr_cell->x;
cell->area = -curr_cell->area;
cell->cover = -curr_cell->cover;
style->last_x = curr_cell->x;
style->num_cells++;
}
}
}
if(m_ast.size() > 1) break;
++m_scan_y;
}
++m_scan_y;
if(m_layer_order != layer_unsorted)
{
range_adaptor<pod_vector<unsigned> > ra(m_ast, 1, m_ast.size() - 1);
if(m_layer_order == layer_direct) quick_sort(ra, unsigned_greater);
else quick_sort(ra, unsigned_less);
}
return m_ast.size() - 1;
}
//------------------------------------------------------------------------
// Returns style ID depending of the existing style index
template<class Clip>
AGG_INLINE
unsigned rasterizer_compound_aa<Clip>::style(unsigned style_idx) const
{
return m_ast[style_idx + 1] + m_min_style - 1;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_compound_aa<Clip>::navigate_scanline(int y)
{
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
if(m_max_style < m_min_style)
{
return false;
}
if(y < m_outline.min_y() || y > m_outline.max_y())
{
return false;
}
m_scan_y = y;
m_styles.allocate(m_max_style - m_min_style + 2, 128);
return true;
}
//------------------------------------------------------------------------
template<class Clip>
bool rasterizer_compound_aa<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty))
{
return false;
}
unsigned num_styles = sweep_styles();
if(num_styles <= 0)
{
return false;
}
scanline_hit_test sl(tx);
sweep_scanline(sl, -1);
return sl.hit();
}
//------------------------------------------------------------------------
template<class Clip>
cover_type* rasterizer_compound_aa<Clip>::allocate_cover_buffer(unsigned len)
{
m_cover_buf.allocate(len, 256);
return &m_cover_buf[0];
}
}
#endif

View file

@ -0,0 +1,147 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_OUTLINE_INCLUDED
#define AGG_RASTERIZER_OUTLINE_INCLUDED
#include "agg_basics.h"
namespace agg
{
//======================================================rasterizer_outline
template<class Renderer> class rasterizer_outline
{
public:
explicit rasterizer_outline(Renderer& ren) :
m_ren(&ren),
m_start_x(0),
m_start_y(0),
m_vertices(0)
{}
void attach(Renderer& ren) { m_ren = &ren; }
//--------------------------------------------------------------------
void move_to(int x, int y)
{
m_vertices = 1;
m_ren->move_to(m_start_x = x, m_start_y = y);
}
//--------------------------------------------------------------------
void line_to(int x, int y)
{
++m_vertices;
m_ren->line_to(x, y);
}
//--------------------------------------------------------------------
void move_to_d(double x, double y)
{
move_to(m_ren->coord(x), m_ren->coord(y));
}
//--------------------------------------------------------------------
void line_to_d(double x, double y)
{
line_to(m_ren->coord(x), m_ren->coord(y));
}
//--------------------------------------------------------------------
void close()
{
if(m_vertices > 2)
{
line_to(m_start_x, m_start_y);
}
m_vertices = 0;
}
//--------------------------------------------------------------------
void add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
{
if(is_end_poly(cmd))
{
if(is_closed(cmd)) close();
}
else
{
line_to_d(x, y);
}
}
}
//--------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
template<class VertexSource, class ColorStorage, class PathId>
void render_all_paths(VertexSource& vs,
const ColorStorage& colors,
const PathId& path_id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
m_ren->line_color(colors[i]);
add_path(vs, path_id[i]);
}
}
//--------------------------------------------------------------------
template<class Ctrl> void render_ctrl(Ctrl& c)
{
unsigned i;
for(i = 0; i < c.num_paths(); i++)
{
m_ren->line_color(c.color(i));
add_path(c, i);
}
}
private:
Renderer* m_ren;
int m_start_x;
int m_start_y;
unsigned m_vertices;
};
}
#endif

View file

@ -0,0 +1,599 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_OUTLINE_AA_INCLUDED
#define AGG_RASTERIZER_OUTLINE_AA_INCLUDED
#include "agg_basics.h"
#include "agg_line_aa_basics.h"
#include "agg_vertex_sequence.h"
namespace agg
{
//-------------------------------------------------------------------------
inline bool cmp_dist_start(int d) { return d > 0; }
inline bool cmp_dist_end(int d) { return d <= 0; }
//-----------------------------------------------------------line_aa_vertex
// Vertex (x, y) with the distance to the next one. The last vertex has
// the distance between the last and the first points
struct line_aa_vertex
{
int x;
int y;
int len;
line_aa_vertex() {}
line_aa_vertex(int x_, int y_) :
x(x_),
y(y_),
len(0)
{
}
bool operator () (const line_aa_vertex& val)
{
double dx = val.x - x;
double dy = val.y - y;
return (len = uround(sqrt(dx * dx + dy * dy))) >
(line_subpixel_scale + line_subpixel_scale / 2);
}
};
//----------------------------------------------------------outline_aa_join_e
enum outline_aa_join_e
{
outline_no_join, //-----outline_no_join
outline_miter_join, //-----outline_miter_join
outline_round_join, //-----outline_round_join
outline_miter_accurate_join //-----outline_accurate_join
};
//=======================================================rasterizer_outline_aa
template<class Renderer, class Coord=line_coord> class rasterizer_outline_aa
{
private:
//------------------------------------------------------------------------
struct draw_vars
{
unsigned idx;
int x1, y1, x2, y2;
line_parameters curr, next;
int lcurr, lnext;
int xb1, yb1, xb2, yb2;
unsigned flags;
};
void draw(draw_vars& dv, unsigned start, unsigned end);
public:
typedef line_aa_vertex vertex_type;
typedef vertex_sequence<vertex_type, 6> vertex_storage_type;
explicit rasterizer_outline_aa(Renderer& ren) :
m_ren(&ren),
m_line_join(ren.accurate_join_only() ?
outline_miter_accurate_join :
outline_round_join),
m_round_cap(false),
m_start_x(0),
m_start_y(0)
{}
void attach(Renderer& ren) { m_ren = &ren; }
//------------------------------------------------------------------------
void line_join(outline_aa_join_e join)
{
m_line_join = m_ren->accurate_join_only() ?
outline_miter_accurate_join :
join;
}
bool line_join() const { return m_line_join; }
//------------------------------------------------------------------------
void round_cap(bool v) { m_round_cap = v; }
bool round_cap() const { return m_round_cap; }
//------------------------------------------------------------------------
void move_to(int x, int y)
{
m_src_vertices.modify_last(vertex_type(m_start_x = x, m_start_y = y));
}
//------------------------------------------------------------------------
void line_to(int x, int y)
{
m_src_vertices.add(vertex_type(x, y));
}
//------------------------------------------------------------------------
void move_to_d(double x, double y)
{
move_to(Coord::conv(x), Coord::conv(y));
}
//------------------------------------------------------------------------
void line_to_d(double x, double y)
{
line_to(Coord::conv(x), Coord::conv(y));
}
//------------------------------------------------------------------------
void render(bool close_polygon);
//------------------------------------------------------------------------
void add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
render(false);
move_to_d(x, y);
}
else
{
if(is_end_poly(cmd))
{
render(is_closed(cmd));
if(is_closed(cmd))
{
move_to(m_start_x, m_start_y);
}
}
else
{
line_to_d(x, y);
}
}
}
//------------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
render(false);
}
//------------------------------------------------------------------------
template<class VertexSource, class ColorStorage, class PathId>
void render_all_paths(VertexSource& vs,
const ColorStorage& colors,
const PathId& path_id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
m_ren->color(colors[i]);
add_path(vs, path_id[i]);
}
}
//------------------------------------------------------------------------
template<class Ctrl> void render_ctrl(Ctrl& c)
{
unsigned i;
for(i = 0; i < c.num_paths(); i++)
{
m_ren->color(c.color(i));
add_path(c, i);
}
}
private:
rasterizer_outline_aa(const rasterizer_outline_aa<Renderer, Coord>&);
const rasterizer_outline_aa<Renderer, Coord>& operator =
(const rasterizer_outline_aa<Renderer, Coord>&);
Renderer* m_ren;
vertex_storage_type m_src_vertices;
outline_aa_join_e m_line_join;
bool m_round_cap;
int m_start_x;
int m_start_y;
};
//----------------------------------------------------------------------------
template<class Renderer, class Coord>
void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv,
unsigned start,
unsigned end)
{
unsigned i;
const vertex_storage_type::value_type* v;
for(i = start; i < end; i++)
{
if(m_line_join == outline_round_join)
{
dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1);
dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1);
dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1);
dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1);
}
switch(dv.flags)
{
case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;
case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2); break;
case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1); break;
case 3: m_ren->line0(dv.curr); break;
}
if(m_line_join == outline_round_join && (dv.flags & 2) == 0)
{
m_ren->pie(dv.curr.x2, dv.curr.y2,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1),
dv.curr.x2 + (dv.next.y2 - dv.next.y1),
dv.curr.y2 - (dv.next.x2 - dv.next.x1));
}
dv.x1 = dv.x2;
dv.y1 = dv.y2;
dv.lcurr = dv.lnext;
dv.lnext = m_src_vertices[dv.idx].len;
++dv.idx;
if(dv.idx >= m_src_vertices.size()) dv.idx = 0;
v = &m_src_vertices[dv.idx];
dv.x2 = v->x;
dv.y2 = v->y;
dv.curr = dv.next;
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
dv.xb1 = dv.xb2;
dv.yb1 = dv.yb2;
switch(m_line_join)
{
case outline_no_join:
dv.flags = 3;
break;
case outline_miter_join:
dv.flags >>= 1;
dv.flags |= ((dv.curr.diagonal_quadrant() ==
dv.next.diagonal_quadrant()) << 1);
if((dv.flags & 2) == 0)
{
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
}
break;
case outline_round_join:
dv.flags >>= 1;
dv.flags |= ((dv.curr.diagonal_quadrant() ==
dv.next.diagonal_quadrant()) << 1);
break;
case outline_miter_accurate_join:
dv.flags = 0;
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
break;
}
}
}
//----------------------------------------------------------------------------
template<class Renderer, class Coord>
void rasterizer_outline_aa<Renderer, Coord>::render(bool close_polygon)
{
m_src_vertices.close(close_polygon);
draw_vars dv;
const vertex_storage_type::value_type* v;
int x1;
int y1;
int x2;
int y2;
int lprev;
if(close_polygon)
{
if(m_src_vertices.size() >= 3)
{
dv.idx = 2;
v = &m_src_vertices[m_src_vertices.size() - 1];
x1 = v->x;
y1 = v->y;
lprev = v->len;
v = &m_src_vertices[0];
x2 = v->x;
y2 = v->y;
dv.lcurr = v->len;
line_parameters prev(x1, y1, x2, y2, lprev);
v = &m_src_vertices[1];
dv.x1 = v->x;
dv.y1 = v->y;
dv.lnext = v->len;
dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
v = &m_src_vertices[dv.idx];
dv.x2 = v->x;
dv.y2 = v->y;
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
dv.xb1 = 0;
dv.yb1 = 0;
dv.xb2 = 0;
dv.yb2 = 0;
switch(m_line_join)
{
case outline_no_join:
dv.flags = 3;
break;
case outline_miter_join:
case outline_round_join:
dv.flags =
(prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
break;
case outline_miter_accurate_join:
dv.flags = 0;
break;
}
if((dv.flags & 1) == 0 && m_line_join != outline_round_join)
{
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
}
if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
{
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
}
draw(dv, 0, m_src_vertices.size());
}
}
else
{
switch(m_src_vertices.size())
{
case 0:
case 1:
break;
case 2:
{
v = &m_src_vertices[0];
x1 = v->x;
y1 = v->y;
lprev = v->len;
v = &m_src_vertices[1];
x2 = v->x;
y2 = v->y;
line_parameters lp(x1, y1, x2, y2, lprev);
if(m_round_cap)
{
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
m_ren->line3(lp,
x1 + (y2 - y1),
y1 - (x2 - x1),
x2 + (y2 - y1),
y2 - (x2 - x1));
if(m_round_cap)
{
m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
}
}
break;
case 3:
{
int x3, y3;
int lnext;
v = &m_src_vertices[0];
x1 = v->x;
y1 = v->y;
lprev = v->len;
v = &m_src_vertices[1];
x2 = v->x;
y2 = v->y;
lnext = v->len;
v = &m_src_vertices[2];
x3 = v->x;
y3 = v->y;
line_parameters lp1(x1, y1, x2, y2, lprev);
line_parameters lp2(x2, y2, x3, y3, lnext);
if(m_round_cap)
{
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
if(m_line_join == outline_round_join)
{
m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
x2 + (y2 - y1), y2 - (x2 - x1));
m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1),
x2 + (y3 - y2), y2 - (x3 - x2));
m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2),
x3 + (y3 - y2), y3 - (x3 - x2));
}
else
{
bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
dv.xb1, dv.yb1);
m_ren->line3(lp2, dv.xb1, dv.yb1,
x3 + (y3 - y2), y3 - (x3 - x2));
}
if(m_round_cap)
{
m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
}
}
break;
default:
{
dv.idx = 3;
v = &m_src_vertices[0];
x1 = v->x;
y1 = v->y;
lprev = v->len;
v = &m_src_vertices[1];
x2 = v->x;
y2 = v->y;
dv.lcurr = v->len;
line_parameters prev(x1, y1, x2, y2, lprev);
v = &m_src_vertices[2];
dv.x1 = v->x;
dv.y1 = v->y;
dv.lnext = v->len;
dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
v = &m_src_vertices[dv.idx];
dv.x2 = v->x;
dv.y2 = v->y;
dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
dv.xb1 = 0;
dv.yb1 = 0;
dv.xb2 = 0;
dv.yb2 = 0;
switch(m_line_join)
{
case outline_no_join:
dv.flags = 3;
break;
case outline_miter_join:
case outline_round_join:
dv.flags =
(prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
break;
case outline_miter_accurate_join:
dv.flags = 0;
break;
}
if(m_round_cap)
{
m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
if((dv.flags & 1) == 0)
{
if(m_line_join == outline_round_join)
{
m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
x2 + (y2 - y1), y2 - (x2 - x1));
m_ren->pie(prev.x2, prev.y2,
x2 + (y2 - y1), y2 - (x2 - x1),
dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y1 - (dv.curr.x2 - dv.curr.x1));
}
else
{
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
dv.xb1, dv.yb1);
}
}
else
{
m_ren->line1(prev,
x1 + (y2 - y1),
y1 - (x2 - x1));
}
if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
{
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
}
draw(dv, 1, m_src_vertices.size() - 2);
if((dv.flags & 1) == 0)
{
if(m_line_join == outline_round_join)
{
m_ren->line3(dv.curr,
dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y1 - (dv.curr.x2 - dv.curr.x1),
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
else
{
m_ren->line3(dv.curr, dv.xb1, dv.yb1,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
}
else
{
m_ren->line2(dv.curr,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
if(m_round_cap)
{
m_ren->semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
}
break;
}
}
m_src_vertices.remove_all();
}
}
#endif

View file

@ -0,0 +1,481 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#include "agg_rasterizer_cells_aa.h"
#include "agg_rasterizer_sl_clip.h"
#include "agg_rasterizer_scanline_aa_nogamma.h"
#include "agg_gamma_functions.h"
namespace agg
{
//==================================================rasterizer_scanline_aa
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses
// integer coordinates in format 24.8, i.e. 24 bits for integer part
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
// used in the following way:
//
// 1. filling_rule(filling_rule_e ft) - optional.
//
// 2. gamma() - optional.
//
// 3. reset()
//
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
// more than one contour, but each contour must consist of at least 3
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
// is the absolute minimum of vertices that define a triangle.
// The algorithm does not check either the number of vertices nor
// coincidence of their coordinates, but in the worst case it just
// won't draw anything.
// The orger of the vertices (clockwise or counterclockwise)
// is important when using the non-zero filling rule (fill_non_zero).
// In this case the vertex order of all the contours must be the same
// if you want your intersecting polygons to be without "holes".
// You actually can use different vertices order. If the contours do not
// intersect each other the order is not important anyway. If they do,
// contours with the same vertex order will be rendered without "holes"
// while the intersecting contours with different orders will have "holes".
//
// filling_rule() and gamma() can be called anytime before "sweeping".
//------------------------------------------------------------------------
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
{
enum status
{
status_initial,
status_move_to,
status_line_to,
status_closed
};
public:
typedef Clip clip_type;
typedef typename Clip::conv_type conv_type;
typedef typename Clip::coord_type coord_type;
enum aa_scale_e
{
aa_shift = 8,
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1,
aa_scale2 = aa_scale * 2,
aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_scanline_aa() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
m_auto_close(true),
m_start_x(0),
m_start_y(0),
m_status(status_initial)
{
int i;
for(i = 0; i < aa_scale; i++) m_gamma[i] = i;
}
//--------------------------------------------------------------------
template<class GammaF>
rasterizer_scanline_aa(const GammaF& gamma_function) :
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);
}
//--------------------------------------------------------------------
void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
void auto_close(bool flag) { m_auto_close = flag; }
//--------------------------------------------------------------------
template<class GammaF> void gamma(const GammaF& gamma_function)
{
int i;
for(i = 0; i < aa_scale; i++)
{
m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
}
}
//--------------------------------------------------------------------
unsigned apply_gamma(unsigned cover) const
{
return m_gamma[cover];
}
//--------------------------------------------------------------------
void move_to(int x, int y);
void line_to(int x, int y);
void move_to_d(double x, double y);
void line_to_d(double x, double y);
void close_polygon();
void add_vertex(double x, double y, unsigned cmd);
void edge(int x1, int y1, int x2, int y2);
void edge_d(double x1, double y1, double x2, double y2);
//-------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
if(m_outline.sorted()) reset();
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
int min_y() const { return m_outline.min_y(); }
int max_x() const { return m_outline.max_x(); }
int max_y() const { return m_outline.max_y(); }
//--------------------------------------------------------------------
void sort();
bool rewind_scanlines();
bool navigate_scanline(int y);
//--------------------------------------------------------------------
AGG_INLINE unsigned calculate_alpha(int area) const
{
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_mask2;
if(cover > aa_scale)
{
cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return m_gamma[cover];
}
//--------------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
for(;;)
{
if(m_scan_y > m_outline.max_y()) return false;
sl.reset_spans();
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
int cover = 0;
while(num_cells)
{
const cell_aa* cur_cell = *cells;
int x = cur_cell->x;
int area = cur_cell->area;
unsigned alpha;
cover += cur_cell->cover;
//accumulate all cells with the same X
while(--num_cells)
{
cur_cell = *++cells;
if(cur_cell->x != x) break;
area += cur_cell->area;
cover += cur_cell->cover;
}
if(area)
{
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
if(alpha)
{
sl.add_cell(x, alpha);
}
x++;
}
if(num_cells && cur_cell->x > x)
{
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
if(alpha)
{
sl.add_span(x, cur_cell->x - x, alpha);
}
}
}
if(sl.num_spans()) break;
++m_scan_y;
}
sl.finalize(m_scan_y);
++m_scan_y;
return true;
}
//--------------------------------------------------------------------
bool hit_test(int tx, int ty);
private:
//--------------------------------------------------------------------
// Disable copying
rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
const rasterizer_scanline_aa<Clip>&
operator = (const rasterizer_scanline_aa<Clip>&);
private:
rasterizer_cells_aa<cell_aa> m_outline;
clip_type m_clipper;
int m_gamma[aa_scale];
filling_rule_e m_filling_rule;
bool m_auto_close;
coord_type m_start_x;
coord_type m_start_y;
unsigned m_status;
int m_scan_y;
};
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::reset()
{
m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::reset_clipping()
{
reset();
m_clipper.reset_clipping();
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::close_polygon()
{
if(m_status == status_line_to)
{
m_clipper.line_to(m_outline, m_start_x, m_start_y);
m_status = status_closed;
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::move_to(int x, int y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::line_to(int x, int y)
{
m_clipper.line_to(m_outline,
conv_type::downscale(x),
conv_type::downscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
if(is_vertex(cmd))
{
line_to_d(x, y);
}
else
if(is_close(cmd))
{
close_polygon();
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
conv_type::downscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa<Clip>::sort()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
m_scan_y = m_outline.min_y();
return true;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0 ||
y < m_outline.min_y() ||
y > m_outline.max_y())
{
return false;
}
m_scan_y = y;
return true;
}
//------------------------------------------------------------------------
template<class Clip>
bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty)) return false;
scanline_hit_test sl(tx);
sweep_scanline(sl);
return sl.hit();
}
}
#endif

View file

@ -0,0 +1,482 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
#include "agg_rasterizer_cells_aa.h"
#include "agg_rasterizer_sl_clip.h"
namespace agg
{
//-----------------------------------------------------------------cell_aa
// A pixel cell. There're no constructors defined and it was done
// intentionally in order to avoid extra overhead when allocating an
// array of cells.
struct cell_aa
{
int x;
int y;
int cover;
int area;
void initial()
{
x = 0x7FFFFFFF;
y = 0x7FFFFFFF;
cover = 0;
area = 0;
}
void style(const cell_aa&) {}
int not_equal(int ex, int ey, const cell_aa&) const
{
return (ex - x) | (ey - y);
}
};
//==================================================rasterizer_scanline_aa_nogamma
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses
// integer coordinates in format 24.8, i.e. 24 bits for integer part
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
// used in the following way:
//
// 1. filling_rule(filling_rule_e ft) - optional.
//
// 2. gamma() - optional.
//
// 3. reset()
//
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
// more than one contour, but each contour must consist of at least 3
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
// is the absolute minimum of vertices that define a triangle.
// The algorithm does not check either the number of vertices nor
// coincidence of their coordinates, but in the worst case it just
// won't draw anything.
// The orger of the vertices (clockwise or counterclockwise)
// is important when using the non-zero filling rule (fill_non_zero).
// In this case the vertex order of all the contours must be the same
// if you want your intersecting polygons to be without "holes".
// You actually can use different vertices order. If the contours do not
// intersect each other the order is not important anyway. If they do,
// contours with the same vertex order will be rendered without "holes"
// while the intersecting contours with different orders will have "holes".
//
// filling_rule() and gamma() can be called anytime before "sweeping".
//------------------------------------------------------------------------
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_nogamma
{
enum status
{
status_initial,
status_move_to,
status_line_to,
status_closed
};
public:
typedef Clip clip_type;
typedef typename Clip::conv_type conv_type;
typedef typename Clip::coord_type coord_type;
enum aa_scale_e
{
aa_shift = 8,
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1,
aa_scale2 = aa_scale * 2,
aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_scanline_aa_nogamma() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
m_auto_close(true),
m_start_x(0),
m_start_y(0),
m_status(status_initial)
{
}
//--------------------------------------------------------------------
void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
void auto_close(bool flag) { m_auto_close = flag; }
//--------------------------------------------------------------------
unsigned apply_gamma(unsigned cover) const
{
return cover;
}
//--------------------------------------------------------------------
void move_to(int x, int y);
void line_to(int x, int y);
void move_to_d(double x, double y);
void line_to_d(double x, double y);
void close_polygon();
void add_vertex(double x, double y, unsigned cmd);
void edge(int x1, int y1, int x2, int y2);
void edge_d(double x1, double y1, double x2, double y2);
//-------------------------------------------------------------------
template<class VertexSource>
void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
vs.rewind(path_id);
if(m_outline.sorted()) reset();
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
}
}
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
int min_y() const { return m_outline.min_y(); }
int max_x() const { return m_outline.max_x(); }
int max_y() const { return m_outline.max_y(); }
//--------------------------------------------------------------------
void sort();
bool rewind_scanlines();
bool navigate_scanline(int y);
//--------------------------------------------------------------------
AGG_INLINE unsigned calculate_alpha(int area) const
{
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_mask2;
if(cover > aa_scale)
{
cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return cover;
}
//--------------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
for(;;)
{
if(m_scan_y > m_outline.max_y()) return false;
sl.reset_spans();
unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
int cover = 0;
while(num_cells)
{
const cell_aa* cur_cell = *cells;
int x = cur_cell->x;
int area = cur_cell->area;
unsigned alpha;
cover += cur_cell->cover;
//accumulate all cells with the same X
while(--num_cells)
{
cur_cell = *++cells;
if(cur_cell->x != x) break;
area += cur_cell->area;
cover += cur_cell->cover;
}
if(area)
{
alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
if(alpha)
{
sl.add_cell(x, alpha);
}
x++;
}
if(num_cells && cur_cell->x > x)
{
alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
if(alpha)
{
sl.add_span(x, cur_cell->x - x, alpha);
}
}
}
if(sl.num_spans()) break;
++m_scan_y;
}
sl.finalize(m_scan_y);
++m_scan_y;
return true;
}
//--------------------------------------------------------------------
bool hit_test(int tx, int ty);
private:
//--------------------------------------------------------------------
// Disable copying
rasterizer_scanline_aa_nogamma(const rasterizer_scanline_aa_nogamma<Clip>&);
const rasterizer_scanline_aa_nogamma<Clip>&
operator = (const rasterizer_scanline_aa_nogamma<Clip>&);
private:
rasterizer_cells_aa<cell_aa> m_outline;
clip_type m_clipper;
filling_rule_e m_filling_rule;
bool m_auto_close;
coord_type m_start_x;
coord_type m_start_y;
unsigned m_status;
int m_scan_y;
};
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::reset()
{
m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::clip_box(double x1, double y1,
double x2, double y2)
{
reset();
m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::reset_clipping()
{
reset();
m_clipper.reset_clipping();
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::close_polygon()
{
if(m_status == status_line_to)
{
m_clipper.line_to(m_outline, m_start_x, m_start_y);
m_status = status_closed;
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::move_to(int x, int y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::downscale(x),
m_start_y = conv_type::downscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::line_to(int x, int y)
{
m_clipper.line_to(m_outline,
conv_type::downscale(x),
conv_type::downscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::move_to_d(double x, double y)
{
if(m_outline.sorted()) reset();
if(m_auto_close) close_polygon();
m_clipper.move_to(m_start_x = conv_type::upscale(x),
m_start_y = conv_type::upscale(y));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::line_to_d(double x, double y)
{
m_clipper.line_to(m_outline,
conv_type::upscale(x),
conv_type::upscale(y));
m_status = status_line_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::add_vertex(double x, double y, unsigned cmd)
{
if(is_move_to(cmd))
{
move_to_d(x, y);
}
else
if(is_vertex(cmd))
{
line_to_d(x, y);
}
else
if(is_close(cmd))
{
close_polygon();
}
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::edge(int x1, int y1, int x2, int y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
m_clipper.line_to(m_outline,
conv_type::downscale(x2),
conv_type::downscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::edge_d(double x1, double y1,
double x2, double y2)
{
if(m_outline.sorted()) reset();
m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
m_clipper.line_to(m_outline,
conv_type::upscale(x2),
conv_type::upscale(y2));
m_status = status_move_to;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_scanline_aa_nogamma<Clip>::sort()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::rewind_scanlines()
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0)
{
return false;
}
m_scan_y = m_outline.min_y();
return true;
}
//------------------------------------------------------------------------
template<class Clip>
AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::navigate_scanline(int y)
{
if(m_auto_close) close_polygon();
m_outline.sort_cells();
if(m_outline.total_cells() == 0 ||
y < m_outline.min_y() ||
y > m_outline.max_y())
{
return false;
}
m_scan_y = y;
return true;
}
//------------------------------------------------------------------------
template<class Clip>
bool rasterizer_scanline_aa_nogamma<Clip>::hit_test(int tx, int ty)
{
if(!navigate_scanline(ty)) return false;
scanline_hit_test sl(tx);
sweep_scanline(sl);
return sl.hit();
}
}
#endif

View file

@ -0,0 +1,351 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED
#define AGG_RASTERIZER_SL_CLIP_INCLUDED
#include "agg_clip_liang_barsky.h"
namespace agg
{
//--------------------------------------------------------poly_max_coord_e
enum poly_max_coord_e
{
poly_max_coord = (1 << 30) - 1 //----poly_max_coord
};
//------------------------------------------------------------ras_conv_int
struct ras_conv_int
{
typedef int coord_type;
static AGG_INLINE int mul_div(double a, double b, double c)
{
return iround(a * b / c);
}
static int xi(int v) { return v; }
static int yi(int v) { return v; }
static int upscale(double v) { return iround(v * double(poly_subpixel_scale)); }
static int downscale(int v) { return v; }
};
//--------------------------------------------------------ras_conv_int_sat
struct ras_conv_int_sat
{
typedef int coord_type;
static AGG_INLINE int mul_div(double a, double b, double c)
{
return saturation<poly_max_coord>::iround(a * b / c);
}
static int xi(int v) { return v; }
static int yi(int v) { return v; }
static int upscale(double v)
{
return saturation<poly_max_coord>::iround(v * double(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 * double(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 * double(poly_subpixel_scale)); }
static int yi(double v) { return iround(v * double(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 * double(poly_subpixel_scale) * 3); }
static int yi(double v) { return iround(v * double(poly_subpixel_scale)); }
static double upscale(double v) { return v; }
static double downscale(int v) { return v / double(poly_subpixel_scale); }
};
//------------------------------------------------------rasterizer_sl_clip
template<class Conv> class rasterizer_sl_clip
{
public:
typedef Conv conv_type;
typedef typename Conv::coord_type coord_type;
typedef rect_base<coord_type> rect_type;
//--------------------------------------------------------------------
rasterizer_sl_clip() :
m_clip_box(0,0,0,0),
m_x1(0),
m_y1(0),
m_f1(0),
m_clipping(false)
{}
//--------------------------------------------------------------------
void reset_clipping()
{
m_clipping = false;
}
//--------------------------------------------------------------------
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2)
{
m_clip_box = rect_type(x1, y1, x2, y2);
m_clip_box.normalize();
m_clipping = true;
}
//--------------------------------------------------------------------
void move_to(coord_type x1, coord_type y1)
{
m_x1 = x1;
m_y1 = y1;
if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box);
}
private:
//------------------------------------------------------------------------
template<class Rasterizer>
AGG_INLINE void line_clip_y(Rasterizer& ras,
coord_type x1, coord_type y1,
coord_type x2, coord_type y2,
unsigned f1, unsigned f2) const
{
f1 &= 10;
f2 &= 10;
if((f1 | f2) == 0)
{
// Fully visible
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
}
else
{
if(f1 == f2)
{
// Invisible by Y
return;
}
coord_type tx1 = x1;
coord_type ty1 = y1;
coord_type tx2 = x2;
coord_type ty2 = y2;
if(f1 & 8) // y1 < clip.y1
{
tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
ty1 = m_clip_box.y1;
}
if(f1 & 2) // y1 > clip.y2
{
tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
ty1 = m_clip_box.y2;
}
if(f2 & 8) // y2 < clip.y1
{
tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
ty2 = m_clip_box.y1;
}
if(f2 & 2) // y2 > clip.y2
{
tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
ty2 = m_clip_box.y2;
}
ras.line(Conv::xi(tx1), Conv::yi(ty1),
Conv::xi(tx2), Conv::yi(ty2));
}
}
public:
//--------------------------------------------------------------------
template<class Rasterizer>
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
{
if(m_clipping)
{
unsigned f2 = clipping_flags(x2, y2, m_clip_box);
if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
{
// Invisible by Y
m_x1 = x2;
m_y1 = y2;
m_f1 = f2;
return;
}
coord_type x1 = m_x1;
coord_type y1 = m_y1;
unsigned f1 = m_f1;
coord_type y3, y4;
unsigned f3, f4;
switch(((f1 & 5) << 1) | (f2 & 5))
{
case 0: // Visible by X
line_clip_y(ras, x1, y1, x2, y2, f1, f2);
break;
case 1: // x2 > clip.x2
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3);
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2);
break;
case 2: // x1 > clip.x2
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
break;
case 3: // x1 > clip.x2 && x2 > clip.x2
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y2, f1, f2);
break;
case 4: // x2 < clip.x1
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3);
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2);
break;
case 6: // x1 > clip.x2 && x2 < clip.x1
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
f4 = clipping_flags_y(y4, m_clip_box);
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x1, y4, f3, f4);
line_clip_y(ras, m_clip_box.x1, y4, m_clip_box.x1, y2, f4, f2);
break;
case 8: // x1 < clip.x1
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
break;
case 9: // x1 < clip.x1 && x2 > clip.x2
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
f3 = clipping_flags_y(y3, m_clip_box);
f4 = clipping_flags_y(y4, m_clip_box);
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x2, y4, f3, f4);
line_clip_y(ras, m_clip_box.x2, y4, m_clip_box.x2, y2, f4, f2);
break;
case 12: // x1 < clip.x1 && x2 < clip.x1
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
break;
}
m_f1 = f2;
}
else
{
ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
Conv::xi(x2), Conv::yi(y2));
}
m_x1 = x2;
m_y1 = y2;
}
private:
rect_type m_clip_box;
coord_type m_x1;
coord_type m_y1;
unsigned m_f1;
bool m_clipping;
};
//---------------------------------------------------rasterizer_sl_no_clip
class rasterizer_sl_no_clip
{
public:
typedef ras_conv_int conv_type;
typedef int coord_type;
rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
void reset_clipping() {}
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2) {}
void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
template<class Rasterizer>
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
{
ras.line(m_x1, m_y1, x2, y2);
m_x1 = x2;
m_y1 = y2;
}
private:
int m_x1, m_y1;
};
// -----rasterizer_sl_clip_int
// -----rasterizer_sl_clip_int_sat
// -----rasterizer_sl_clip_int_3x
// -----rasterizer_sl_clip_dbl
// -----rasterizer_sl_clip_dbl_3x
//------------------------------------------------------------------------
typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int;
typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat;
typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x;
typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl;
typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x;
}
#endif

View file

@ -0,0 +1,731 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class renderer_base
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_BASE_INCLUDED
#define AGG_RENDERER_BASE_INCLUDED
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
namespace agg
{
//-----------------------------------------------------------renderer_base
template<class PixelFormat> class renderer_base
{
public:
typedef PixelFormat pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::row_data row_data;
//--------------------------------------------------------------------
renderer_base() : m_ren(0), m_clip_box(1, 1, 0, 0) {}
explicit renderer_base(pixfmt_type& ren) :
m_ren(&ren),
m_clip_box(0, 0, ren.width() - 1, ren.height() - 1)
{}
void attach(pixfmt_type& ren)
{
m_ren = &ren;
m_clip_box = rect_i(0, 0, ren.width() - 1, ren.height() - 1);
}
//--------------------------------------------------------------------
const pixfmt_type& ren() const { return *m_ren; }
pixfmt_type& ren() { return *m_ren; }
//--------------------------------------------------------------------
unsigned width() const { return m_ren->width(); }
unsigned height() const { return m_ren->height(); }
//--------------------------------------------------------------------
bool clip_box(int x1, int y1, int x2, int y2)
{
rect_i cb(x1, y1, x2, y2);
cb.normalize();
if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
{
m_clip_box = cb;
return true;
}
m_clip_box.x1 = 1;
m_clip_box.y1 = 1;
m_clip_box.x2 = 0;
m_clip_box.y2 = 0;
return false;
}
//--------------------------------------------------------------------
void reset_clipping(bool visibility)
{
if(visibility)
{
m_clip_box.x1 = 0;
m_clip_box.y1 = 0;
m_clip_box.x2 = width() - 1;
m_clip_box.y2 = height() - 1;
}
else
{
m_clip_box.x1 = 1;
m_clip_box.y1 = 1;
m_clip_box.x2 = 0;
m_clip_box.y2 = 0;
}
}
//--------------------------------------------------------------------
void clip_box_naked(int x1, int y1, int x2, int y2)
{
m_clip_box.x1 = x1;
m_clip_box.y1 = y1;
m_clip_box.x2 = x2;
m_clip_box.y2 = y2;
}
//--------------------------------------------------------------------
bool inbox(int x, int y) const
{
return x >= m_clip_box.x1 && y >= m_clip_box.y1 &&
x <= m_clip_box.x2 && y <= m_clip_box.y2;
}
//--------------------------------------------------------------------
const rect_i& clip_box() const { return m_clip_box; }
int xmin() const { return m_clip_box.x1; }
int ymin() const { return m_clip_box.y1; }
int xmax() const { return m_clip_box.x2; }
int ymax() const { return m_clip_box.y2; }
//--------------------------------------------------------------------
const rect_i& bounding_clip_box() const { return m_clip_box; }
int bounding_xmin() const { return m_clip_box.x1; }
int bounding_ymin() const { return m_clip_box.y1; }
int bounding_xmax() const { return m_clip_box.x2; }
int bounding_ymax() const { return m_clip_box.y2; }
//--------------------------------------------------------------------
void clear(const color_type& c)
{
unsigned y;
if(width())
{
for(y = 0; y < height(); y++)
{
m_ren->copy_hline(0, y, width(), c);
}
}
}
//--------------------------------------------------------------------
void fill(const color_type& c)
{
unsigned y;
if(width())
{
for(y = 0; y < height(); y++)
{
m_ren->blend_hline(0, y, width(), c, cover_mask);
}
}
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
if(inbox(x, y))
{
m_ren->copy_pixel(x, y, c);
}
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
{
if(inbox(x, y))
{
m_ren->blend_pixel(x, y, c, cover);
}
}
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
return inbox(x, y) ?
m_ren->pixel(x, y) :
color_type::no_color();
}
//--------------------------------------------------------------------
void copy_hline(int x1, int y, int x2, const color_type& c)
{
if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
if(y > ymax()) return;
if(y < ymin()) return;
if(x1 > xmax()) return;
if(x2 < xmin()) return;
if(x1 < xmin()) x1 = xmin();
if(x2 > xmax()) x2 = xmax();
m_ren->copy_hline(x1, y, x2 - x1 + 1, c);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y1, int y2, const color_type& c)
{
if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
if(x > xmax()) return;
if(x < xmin()) return;
if(y1 > ymax()) return;
if(y2 < ymin()) return;
if(y1 < ymin()) y1 = ymin();
if(y2 > ymax()) y2 = ymax();
m_ren->copy_vline(x, y1, y2 - y1 + 1, c);
}
//--------------------------------------------------------------------
void blend_hline(int x1, int y, int x2,
const color_type& c, cover_type cover)
{
if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
if(y > ymax()) return;
if(y < ymin()) return;
if(x1 > xmax()) return;
if(x2 < xmin()) return;
if(x1 < xmin()) x1 = xmin();
if(x2 > xmax()) x2 = xmax();
m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover);
}
//--------------------------------------------------------------------
void blend_vline(int x, int y1, int y2,
const color_type& c, cover_type cover)
{
if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
if(x > xmax()) return;
if(x < xmin()) return;
if(y1 > ymax()) return;
if(y2 < ymin()) return;
if(y1 < ymin()) y1 = ymin();
if(y2 > ymax()) y2 = ymax();
m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover);
}
//--------------------------------------------------------------------
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
{
rect_i rc(x1, y1, x2, y2);
rc.normalize();
if(rc.clip(clip_box()))
{
int y;
for(y = rc.y1; y <= rc.y2; y++)
{
m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c);
}
}
}
//--------------------------------------------------------------------
void blend_bar(int x1, int y1, int x2, int y2,
const color_type& c, cover_type cover)
{
rect_i rc(x1, y1, x2, y2);
rc.normalize();
if(rc.clip(clip_box()))
{
int y;
for(y = rc.y1; y <= rc.y2; y++)
{
m_ren->blend_hline(rc.x1,
y,
unsigned(rc.x2 - rc.x1 + 1),
c,
cover);
}
}
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, int len,
const color_type& c,
const cover_type* covers)
{
if(y > ymax()) return;
if(y < ymin()) return;
if(x < xmin())
{
len -= xmin() - x;
if(len <= 0) return;
covers += xmin() - x;
x = xmin();
}
if(x + len > xmax())
{
len = xmax() - x + 1;
if(len <= 0) return;
}
m_ren->blend_solid_hspan(x, y, len, c, covers);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, int len,
const color_type& c,
const cover_type* covers)
{
if(x > xmax()) return;
if(x < xmin()) return;
if(y < ymin())
{
len -= ymin() - y;
if(len <= 0) return;
covers += ymin() - y;
y = ymin();
}
if(y + len > ymax())
{
len = ymax() - y + 1;
if(len <= 0) return;
}
m_ren->blend_solid_vspan(x, y, len, c, covers);
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y, int len, const color_type* colors)
{
if(y > ymax()) return;
if(y < ymin()) return;
if(x < xmin())
{
int d = xmin() - x;
len -= d;
if(len <= 0) return;
colors += d;
x = xmin();
}
if(x + len > xmax())
{
len = xmax() - x + 1;
if(len <= 0) return;
}
m_ren->copy_color_hspan(x, y, len, colors);
}
//--------------------------------------------------------------------
void copy_color_vspan(int x, int y, int len, const color_type* colors)
{
if(x > xmax()) return;
if(x < xmin()) return;
if(y < ymin())
{
int d = ymin() - y;
len -= d;
if(len <= 0) return;
colors += d;
y = ymin();
}
if(y + len > ymax())
{
len = ymax() - y + 1;
if(len <= 0) return;
}
m_ren->copy_color_vspan(x, y, len, colors);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = agg::cover_full)
{
if(y > ymax()) return;
if(y < ymin()) return;
if(x < xmin())
{
int d = xmin() - x;
len -= d;
if(len <= 0) return;
if(covers) covers += d;
colors += d;
x = xmin();
}
if(x + len > xmax())
{
len = xmax() - x + 1;
if(len <= 0) return;
}
m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = agg::cover_full)
{
if(x > xmax()) return;
if(x < xmin()) return;
if(y < ymin())
{
int d = ymin() - y;
len -= d;
if(len <= 0) return;
if(covers) covers += d;
colors += d;
y = ymin();
}
if(y + len > ymax())
{
len = ymax() - y + 1;
if(len <= 0) return;
}
m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
rect_i clip_rect_area(rect_i& dst, rect_i& src, int wsrc, int hsrc) const
{
rect_i rc(0,0,0,0);
rect_i cb = clip_box();
++cb.x2;
++cb.y2;
if(src.x1 < 0)
{
dst.x1 -= src.x1;
src.x1 = 0;
}
if(src.y1 < 0)
{
dst.y1 -= src.y1;
src.y1 = 0;
}
if(src.x2 > wsrc) src.x2 = wsrc;
if(src.y2 > hsrc) src.y2 = hsrc;
if(dst.x1 < cb.x1)
{
src.x1 += cb.x1 - dst.x1;
dst.x1 = cb.x1;
}
if(dst.y1 < cb.y1)
{
src.y1 += cb.y1 - dst.y1;
dst.y1 = cb.y1;
}
if(dst.x2 > cb.x2) dst.x2 = cb.x2;
if(dst.y2 > cb.y2) dst.y2 = cb.y2;
rc.x2 = dst.x2 - dst.x1;
rc.y2 = dst.y2 - dst.y1;
if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1;
if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1;
return rc;
}
//--------------------------------------------------------------------
template<class RenBuf>
void copy_from(const RenBuf& src,
const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0)
{
rect_i rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
rsrc.y1 = rect_src_ptr->y1;
rsrc.x2 = rect_src_ptr->x2 + 1;
rsrc.y2 = rect_src_ptr->y2 + 1;
}
// Version with xdst, ydst (absolute positioning)
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
// Version with dx, dy (relative positioning)
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
int incy = 1;
if(rdst.y1 > rsrc.y1)
{
rsrc.y1 += rc.y2 - 1;
rdst.y1 += rc.y2 - 1;
incy = -1;
}
while(rc.y2 > 0)
{
m_ren->copy_from(src,
rdst.x1, rdst.y1,
rsrc.x1, rsrc.y1,
rc.x2);
rdst.y1 += incy;
rsrc.y1 += incy;
--rc.y2;
}
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& src,
const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0,
cover_type cover = agg::cover_full)
{
rect_i rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
rsrc.y1 = rect_src_ptr->y1;
rsrc.x2 = rect_src_ptr->x2 + 1;
rsrc.y2 = rect_src_ptr->y2 + 1;
}
// Version with xdst, ydst (absolute positioning)
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
// Version with dx, dy (relative positioning)
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
int incy = 1;
if(rdst.y1 > rsrc.y1)
{
rsrc.y1 += rc.y2 - 1;
rdst.y1 += rc.y2 - 1;
incy = -1;
}
while(rc.y2 > 0)
{
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
if(rw.ptr)
{
int x1src = rsrc.x1;
int x1dst = rdst.x1;
int len = rc.x2;
if(rw.x1 > x1src)
{
x1dst += rw.x1 - x1src;
len -= rw.x1 - x1src;
x1src = rw.x1;
}
if(len > 0)
{
if(x1src + len-1 > rw.x2)
{
len -= x1src + len - rw.x2 - 1;
}
if(len > 0)
{
m_ren->blend_from(src,
x1dst, rdst.y1,
x1src, rsrc.y1,
len,
cover);
}
}
}
rdst.y1 += incy;
rsrc.y1 += incy;
--rc.y2;
}
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from_color(const SrcPixelFormatRenderer& src,
const color_type& color,
const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0,
cover_type cover = agg::cover_full)
{
rect_i rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
rsrc.y1 = rect_src_ptr->y1;
rsrc.x2 = rect_src_ptr->x2 + 1;
rsrc.y2 = rect_src_ptr->y2 + 1;
}
// Version with xdst, ydst (absolute positioning)
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
// Version with dx, dy (relative positioning)
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
int incy = 1;
if(rdst.y1 > rsrc.y1)
{
rsrc.y1 += rc.y2 - 1;
rdst.y1 += rc.y2 - 1;
incy = -1;
}
while(rc.y2 > 0)
{
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
if(rw.ptr)
{
int x1src = rsrc.x1;
int x1dst = rdst.x1;
int len = rc.x2;
if(rw.x1 > x1src)
{
x1dst += rw.x1 - x1src;
len -= rw.x1 - x1src;
x1src = rw.x1;
}
if(len > 0)
{
if(x1src + len-1 > rw.x2)
{
len -= x1src + len - rw.x2 - 1;
}
if(len > 0)
{
m_ren->blend_from_color(src,
color,
x1dst, rdst.y1,
x1src, rsrc.y1,
len,
cover);
}
}
}
rdst.y1 += incy;
rsrc.y1 += incy;
--rc.y2;
}
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from_lut(const SrcPixelFormatRenderer& src,
const color_type* color_lut,
const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0,
cover_type cover = agg::cover_full)
{
rect_i rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
rsrc.y1 = rect_src_ptr->y1;
rsrc.x2 = rect_src_ptr->x2 + 1;
rsrc.y2 = rect_src_ptr->y2 + 1;
}
// Version with xdst, ydst (absolute positioning)
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
// Version with dx, dy (relative positioning)
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
int incy = 1;
if(rdst.y1 > rsrc.y1)
{
rsrc.y1 += rc.y2 - 1;
rdst.y1 += rc.y2 - 1;
incy = -1;
}
while(rc.y2 > 0)
{
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
if(rw.ptr)
{
int x1src = rsrc.x1;
int x1dst = rdst.x1;
int len = rc.x2;
if(rw.x1 > x1src)
{
x1dst += rw.x1 - x1src;
len -= rw.x1 - x1src;
x1src = rw.x1;
}
if(len > 0)
{
if(x1src + len-1 > rw.x2)
{
len -= x1src + len - rw.x2 - 1;
}
if(len > 0)
{
m_ren->blend_from_lut(src,
color_lut,
x1dst, rdst.y1,
x1src, rsrc.y1,
len,
cover);
}
}
}
rdst.y1 += incy;
rsrc.y1 += incy;
--rc.y2;
}
}
}
private:
pixfmt_type* m_ren;
rect_i m_clip_box;
};
}
#endif

View file

@ -0,0 +1,706 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class renderer_markers
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_MARKERS_INCLUDED
#define AGG_RENDERER_MARKERS_INCLUDED
#include "agg_basics.h"
#include "agg_renderer_primitives.h"
namespace agg
{
//---------------------------------------------------------------marker_e
enum marker_e
{
marker_square,
marker_diamond,
marker_circle,
marker_crossed_circle,
marker_semiellipse_left,
marker_semiellipse_right,
marker_semiellipse_up,
marker_semiellipse_down,
marker_triangle_left,
marker_triangle_right,
marker_triangle_up,
marker_triangle_down,
marker_four_rays,
marker_cross,
marker_x,
marker_dash,
marker_dot,
marker_pixel,
end_of_markers
};
//--------------------------------------------------------renderer_markers
template<class BaseRenderer> class renderer_markers :
public renderer_primitives<BaseRenderer>
{
public:
typedef renderer_primitives<BaseRenderer> base_type;
typedef BaseRenderer base_ren_type;
typedef typename base_ren_type::color_type color_type;
//--------------------------------------------------------------------
renderer_markers(base_ren_type& rbuf) :
base_type(rbuf)
{}
//--------------------------------------------------------------------
bool visible(int x, int y, int r) const
{
rect_i rc(x-r, y-r, x+y, y+r);
return rc.clip(base_type::ren().bounding_clip_box());
}
//--------------------------------------------------------------------
void square(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r) base_type::outlined_rectangle(x-r, y-r, x+r, y+r);
else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
//--------------------------------------------------------------------
void diamond(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int dy = -r;
int dx = 0;
do
{
base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
if(dx)
{
base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
}
++dy;
++dx;
}
while(dy <= 0);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void circle(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r) base_type::outlined_ellipse(x, y, r, r);
else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
//--------------------------------------------------------------------
void crossed_circle(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
base_type::outlined_ellipse(x, y, r, r);
int r6 = r + (r >> 1);
if(r <= 2) r6++;
r >>= 1;
base_type::ren().blend_hline(x-r6, y, x-r, base_type::line_color(), cover_full);
base_type::ren().blend_hline(x+r, y, x+r6, base_type::line_color(), cover_full);
base_type::ren().blend_vline(x, y-r6, y-r, base_type::line_color(), cover_full);
base_type::ren().blend_vline(x, y+r, y+r6, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//------------------------------------------------------------------------
void semiellipse_left(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int r8 = r * 4 / 5;
int dy = -r;
int dx = 0;
ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
do
{
dx += ei.dx();
dy += ei.dy();
base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
if(ei.dy() && dx)
{
base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
}
++ei;
}
while(dy < r8);
base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void semiellipse_right(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int r8 = r * 4 / 5;
int dy = -r;
int dx = 0;
ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
do
{
dx += ei.dx();
dy += ei.dy();
base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
if(ei.dy() && dx)
{
base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
}
++ei;
}
while(dy < r8);
base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void semiellipse_up(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int r8 = r * 4 / 5;
int dy = -r;
int dx = 0;
ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
do
{
dx += ei.dx();
dy += ei.dy();
base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
if(ei.dy() && dx)
{
base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
}
++ei;
}
while(dy < r8);
base_type::ren().blend_hline(x-dx, y-dy-1, x+dx, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void semiellipse_down(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int r8 = r * 4 / 5;
int dy = -r;
int dx = 0;
ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
do
{
dx += ei.dx();
dy += ei.dy();
base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
if(ei.dy() && dx)
{
base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
}
++ei;
}
while(dy < r8);
base_type::ren().blend_hline(x-dx, y+dy+1, x+dx, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void triangle_left(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int dy = -r;
int dx = 0;
int flip = 0;
int r6 = r * 3 / 5;
do
{
base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
if(dx)
{
base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
}
++dy;
dx += flip;
flip ^= 1;
}
while(dy < r6);
base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void triangle_right(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int dy = -r;
int dx = 0;
int flip = 0;
int r6 = r * 3 / 5;
do
{
base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
if(dx)
{
base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
}
++dy;
dx += flip;
flip ^= 1;
}
while(dy < r6);
base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void triangle_up(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int dy = -r;
int dx = 0;
int flip = 0;
int r6 = r * 3 / 5;
do
{
base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
if(dx)
{
base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
}
++dy;
dx += flip;
flip ^= 1;
}
while(dy < r6);
base_type::ren().blend_hline(x-dx, y-dy, x+dx, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void triangle_down(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int dy = -r;
int dx = 0;
int flip = 0;
int r6 = r * 3 / 5;
do
{
base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
if(dx)
{
base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
}
++dy;
dx += flip;
flip ^= 1;
}
while(dy < r6);
base_type::ren().blend_hline(x-dx, y+dy, x+dx, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void four_rays(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int dy = -r;
int dx = 0;
int flip = 0;
int r3 = -(r / 3);
do
{
base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
if(dx)
{
base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
}
++dy;
dx += flip;
flip ^= 1;
}
while(dy <= r3);
base_type::solid_rectangle(x+r3+1, y+r3+1, x-r3-1, y-r3-1);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void cross(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
base_type::ren().blend_vline(x, y-r, y+r, base_type::line_color(), cover_full);
base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full);
}
else
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
}
//--------------------------------------------------------------------
void xing(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r)
{
int dy = -r * 7 / 10;
do
{
base_type::ren().blend_pixel(x + dy, y + dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dy, y + dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x + dy, y - dy, base_type::line_color(), cover_full);
base_type::ren().blend_pixel(x - dy, y - dy, base_type::line_color(), cover_full);
++dy;
}
while(dy < 0);
}
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
//--------------------------------------------------------------------
void dash(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r) base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full);
else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
//--------------------------------------------------------------------
void dot(int x, int y, int r)
{
if(visible(x, y, r))
{
if(r) base_type::solid_ellipse(x, y, r, r);
else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
}
//--------------------------------------------------------------------
void pixel(int x, int y, int)
{
base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
}
//--------------------------------------------------------------------
void marker(int x, int y, int r, marker_e type)
{
switch(type)
{
case marker_square: square(x, y, r); break;
case marker_diamond: diamond(x, y, r); break;
case marker_circle: circle(x, y, r); break;
case marker_crossed_circle: crossed_circle(x, y, r); break;
case marker_semiellipse_left: semiellipse_left(x, y, r); break;
case marker_semiellipse_right: semiellipse_right(x, y, r); break;
case marker_semiellipse_up: semiellipse_up(x, y, r); break;
case marker_semiellipse_down: semiellipse_down(x, y, r); break;
case marker_triangle_left: triangle_left(x, y, r); break;
case marker_triangle_right: triangle_right(x, y, r); break;
case marker_triangle_up: triangle_up(x, y, r); break;
case marker_triangle_down: triangle_down(x, y, r); break;
case marker_four_rays: four_rays(x, y, r); break;
case marker_cross: cross(x, y, r); break;
case marker_x: xing(x, y, r); break;
case marker_dash: dash(x, y, r); break;
case marker_dot: dot(x, y, r); break;
case marker_pixel: pixel(x, y, r); break;
}
}
//--------------------------------------------------------------------
template<class T>
void markers(int n, const T* x, const T* y, T r, marker_e type)
{
if(n <= 0) return;
if(r == 0)
{
do
{
base_type::ren().blend_pixel(int(*x), int(*y), base_type::fill_color(), cover_full);
++x;
++y;
}
while(--n);
return;
}
switch(type)
{
case marker_square: do { square (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_diamond: do { diamond (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_circle: do { circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_four_rays: do { four_rays (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_cross: do { cross (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_x: do { xing (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_dash: do { dash (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_dot: do { dot (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
case marker_pixel: do { pixel (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
}
}
//--------------------------------------------------------------------
template<class T>
void markers(int n, const T* x, const T* y, const T* r, marker_e type)
{
if(n <= 0) return;
switch(type)
{
case marker_square: do { square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_diamond: do { diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_circle: do { circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_four_rays: do { four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_cross: do { cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_x: do { xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_dash: do { dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_dot: do { dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
case marker_pixel: do { pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
}
}
//--------------------------------------------------------------------
template<class T>
void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, marker_e type)
{
if(n <= 0) return;
switch(type)
{
case marker_square: do { base_type::fill_color(*fc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_diamond: do { base_type::fill_color(*fc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_circle: do { base_type::fill_color(*fc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_crossed_circle: do { base_type::fill_color(*fc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_semiellipse_left: do { base_type::fill_color(*fc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_semiellipse_right: do { base_type::fill_color(*fc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_semiellipse_up: do { base_type::fill_color(*fc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_semiellipse_down: do { base_type::fill_color(*fc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_triangle_left: do { base_type::fill_color(*fc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_triangle_right: do { base_type::fill_color(*fc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_triangle_up: do { base_type::fill_color(*fc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_triangle_down: do { base_type::fill_color(*fc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_four_rays: do { base_type::fill_color(*fc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_cross: do { base_type::fill_color(*fc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_x: do { base_type::fill_color(*fc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_dash: do { base_type::fill_color(*fc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_dot: do { base_type::fill_color(*fc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
case marker_pixel: do { base_type::fill_color(*fc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
}
}
//--------------------------------------------------------------------
template<class T>
void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, const color_type* lc, marker_e type)
{
if(n <= 0) return;
switch(type)
{
case marker_square: do { base_type::fill_color(*fc); base_type::line_color(*lc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_diamond: do { base_type::fill_color(*fc); base_type::line_color(*lc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_crossed_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_semiellipse_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_semiellipse_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_semiellipse_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_semiellipse_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_triangle_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_triangle_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_triangle_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_triangle_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_four_rays: do { base_type::fill_color(*fc); base_type::line_color(*lc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_cross: do { base_type::fill_color(*fc); base_type::line_color(*lc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_x: do { base_type::fill_color(*fc); base_type::line_color(*lc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_dash: do { base_type::fill_color(*fc); base_type::line_color(*lc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_dot: do { base_type::fill_color(*fc); base_type::line_color(*lc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
case marker_pixel: do { base_type::fill_color(*fc); base_type::line_color(*lc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
}
}
};
}
#endif

View file

@ -0,0 +1,349 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class renderer_mclip
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_MCLIP_INCLUDED
#define AGG_RENDERER_MCLIP_INCLUDED
#include "agg_basics.h"
#include "agg_array.h"
#include "agg_renderer_base.h"
namespace agg
{
//----------------------------------------------------------renderer_mclip
template<class PixelFormat> class renderer_mclip
{
public:
typedef PixelFormat pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
typedef typename pixfmt_type::row_data row_data;
typedef renderer_base<pixfmt_type> base_ren_type;
//--------------------------------------------------------------------
explicit renderer_mclip(pixfmt_type& pixf) :
m_ren(pixf),
m_curr_cb(0),
m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
{}
void attach(pixfmt_type& pixf)
{
m_ren.attach(pixf);
reset_clipping(true);
}
//--------------------------------------------------------------------
const pixfmt_type& ren() const { return m_ren.ren(); }
pixfmt_type& ren() { return m_ren.ren(); }
//--------------------------------------------------------------------
unsigned width() const { return m_ren.width(); }
unsigned height() const { return m_ren.height(); }
//--------------------------------------------------------------------
const rect_i& clip_box() const { return m_ren.clip_box(); }
int xmin() const { return m_ren.xmin(); }
int ymin() const { return m_ren.ymin(); }
int xmax() const { return m_ren.xmax(); }
int ymax() const { return m_ren.ymax(); }
//--------------------------------------------------------------------
const rect_i& bounding_clip_box() const { return m_bounds; }
int bounding_xmin() const { return m_bounds.x1; }
int bounding_ymin() const { return m_bounds.y1; }
int bounding_xmax() const { return m_bounds.x2; }
int bounding_ymax() const { return m_bounds.y2; }
//--------------------------------------------------------------------
void first_clip_box()
{
m_curr_cb = 0;
if(m_clip.size())
{
const rect_i& cb = m_clip[0];
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
}
}
//--------------------------------------------------------------------
bool next_clip_box()
{
if(++m_curr_cb < m_clip.size())
{
const rect_i& cb = m_clip[m_curr_cb];
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
return true;
}
return false;
}
//--------------------------------------------------------------------
void reset_clipping(bool visibility)
{
m_ren.reset_clipping(visibility);
m_clip.remove_all();
m_curr_cb = 0;
m_bounds = m_ren.clip_box();
}
//--------------------------------------------------------------------
void add_clip_box(int x1, int y1, int x2, int y2)
{
rect_i cb(x1, y1, x2, y2);
cb.normalize();
if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
{
m_clip.add(cb);
if(cb.x1 < m_bounds.x1) m_bounds.x1 = cb.x1;
if(cb.y1 < m_bounds.y1) m_bounds.y1 = cb.y1;
if(cb.x2 > m_bounds.x2) m_bounds.x2 = cb.x2;
if(cb.y2 > m_bounds.y2) m_bounds.y2 = cb.y2;
}
}
//--------------------------------------------------------------------
void clear(const color_type& c)
{
m_ren.clear(c);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
m_ren.ren().copy_pixel(x, y, c);
break;
}
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
m_ren.ren().blend_pixel(x, y, c, cover);
break;
}
}
while(next_clip_box());
}
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
first_clip_box();
do
{
if(m_ren.inbox(x, y))
{
return m_ren.ren().pixel(x, y);
}
}
while(next_clip_box());
return color_type::no_color();
}
//--------------------------------------------------------------------
void copy_hline(int x1, int y, int x2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_hline(x1, y, x2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_vline(int x, int y1, int y2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_vline(x, y1, y2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_hline(int x1, int y, int x2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_hline(x1, y, x2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_vline(int x, int y1, int y2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_vline(x, y1, y2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
{
first_clip_box();
do
{
m_ren.copy_bar(x1, y1, x2, y2, c);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_bar(int x1, int y1, int x2, int y2,
const color_type& c, cover_type cover)
{
first_clip_box();
do
{
m_ren.blend_bar(x1, y1, x2, y2, c, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, int len,
const color_type& c, const cover_type* covers)
{
first_clip_box();
do
{
m_ren.blend_solid_hspan(x, y, len, c, covers);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, int len,
const color_type& c, const cover_type* covers)
{
first_clip_box();
do
{
m_ren.blend_solid_vspan(x, y, len, c, covers);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_color_hspan(int x, int y, int len, const color_type* colors)
{
first_clip_box();
do
{
m_ren.copy_color_hspan(x, y, len, colors);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
first_clip_box();
do
{
m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
{
first_clip_box();
do
{
m_ren.blend_color_vspan(x, y, len, colors, covers, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
const rect_i* rc=0,
int x_to=0,
int y_to=0)
{
first_clip_box();
do
{
m_ren.copy_from(from, rc, x_to, y_to);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& src,
const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0,
cover_type cover = cover_full)
{
first_clip_box();
do
{
m_ren.blend_from(src, rect_src_ptr, dx, dy, cover);
}
while(next_clip_box());
}
private:
renderer_mclip(const renderer_mclip<PixelFormat>&);
const renderer_mclip<PixelFormat>&
operator = (const renderer_mclip<PixelFormat>&);
base_ren_type m_ren;
pod_bvector<rect_i, 4> m_clip;
unsigned m_curr_cb;
rect_i m_bounds;
};
}
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,224 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class renderer_primitives
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_PRIMITIVES_INCLUDED
#define AGG_RENDERER_PRIMITIVES_INCLUDED
#include "agg_basics.h"
#include "agg_renderer_base.h"
#include "agg_dda_line.h"
#include "agg_ellipse_bresenham.h"
namespace agg
{
//-----------------------------------------------------renderer_primitives
template<class BaseRenderer> class renderer_primitives
{
public:
typedef BaseRenderer base_ren_type;
typedef typename base_ren_type::color_type color_type;
//--------------------------------------------------------------------
explicit renderer_primitives(base_ren_type& ren) :
m_ren(&ren),
m_fill_color(),
m_line_color(),
m_curr_x(0),
m_curr_y(0)
{}
void attach(base_ren_type& ren) { m_ren = &ren; }
//--------------------------------------------------------------------
static int coord(double c)
{
return iround(c * line_bresenham_interpolator::subpixel_scale);
}
//--------------------------------------------------------------------
void fill_color(const color_type& c) { m_fill_color = c; }
void line_color(const color_type& c) { m_line_color = c; }
const color_type& fill_color() const { return m_fill_color; }
const color_type& line_color() const { return m_line_color; }
//--------------------------------------------------------------------
void rectangle(int x1, int y1, int x2, int y2)
{
m_ren->blend_hline(x1, y1, x2-1, m_line_color, cover_full);
m_ren->blend_vline(x2, y1, y2-1, m_line_color, cover_full);
m_ren->blend_hline(x1+1, y2, x2, m_line_color, cover_full);
m_ren->blend_vline(x1, y1+1, y2, m_line_color, cover_full);
}
//--------------------------------------------------------------------
void solid_rectangle(int x1, int y1, int x2, int y2)
{
m_ren->blend_bar(x1, y1, x2, y2, m_fill_color, cover_full);
}
//--------------------------------------------------------------------
void outlined_rectangle(int x1, int y1, int x2, int y2)
{
rectangle(x1, y1, x2, y2);
m_ren->blend_bar(x1+1, y1+1, x2-1, y2-1, m_fill_color, cover_full);
}
//--------------------------------------------------------------------
void ellipse(int x, int y, int rx, int ry)
{
ellipse_bresenham_interpolator ei(rx, ry);
int dx = 0;
int dy = -ry;
do
{
dx += ei.dx();
dy += ei.dy();
m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
++ei;
}
while(dy < 0);
}
//--------------------------------------------------------------------
void solid_ellipse(int x, int y, int rx, int ry)
{
ellipse_bresenham_interpolator ei(rx, ry);
int dx = 0;
int dy = -ry;
int dy0 = dy;
int dx0 = dx;
do
{
dx += ei.dx();
dy += ei.dy();
if(dy != dy0)
{
m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full);
m_ren->blend_hline(x-dx0, y-dy0, x+dx0, m_fill_color, cover_full);
}
dx0 = dx;
dy0 = dy;
++ei;
}
while(dy < 0);
m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full);
}
//--------------------------------------------------------------------
void outlined_ellipse(int x, int y, int rx, int ry)
{
ellipse_bresenham_interpolator ei(rx, ry);
int dx = 0;
int dy = -ry;
do
{
dx += ei.dx();
dy += ei.dy();
m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
if(ei.dy() && dx)
{
m_ren->blend_hline(x-dx+1, y+dy, x+dx-1, m_fill_color, cover_full);
m_ren->blend_hline(x-dx+1, y-dy, x+dx-1, m_fill_color, cover_full);
}
++ei;
}
while(dy < 0);
}
//--------------------------------------------------------------------
void line(int x1, int y1, int x2, int y2, bool last=false)
{
line_bresenham_interpolator li(x1, y1, x2, y2);
unsigned len = li.len();
if(len == 0)
{
if(last)
{
m_ren->blend_pixel(li.line_lr(x1), li.line_lr(y1), m_line_color, cover_full);
}
return;
}
if(last) ++len;
if(li.is_ver())
{
do
{
m_ren->blend_pixel(li.x2(), li.y1(), m_line_color, cover_full);
li.vstep();
}
while(--len);
}
else
{
do
{
m_ren->blend_pixel(li.x1(), li.y2(), m_line_color, cover_full);
li.hstep();
}
while(--len);
}
}
//--------------------------------------------------------------------
void move_to(int x, int y)
{
m_curr_x = x;
m_curr_y = y;
}
//--------------------------------------------------------------------
void line_to(int x, int y, bool last=false)
{
line(m_curr_x, m_curr_y, x, y, last);
m_curr_x = x;
m_curr_y = y;
}
//--------------------------------------------------------------------
const base_ren_type& ren() const { return *m_ren; }
base_ren_type& ren() { return *m_ren; }
//--------------------------------------------------------------------
const rendering_buffer& rbuf() const { return m_ren->rbuf(); }
rendering_buffer& rbuf() { return m_ren->rbuf(); }
private:
base_ren_type* m_ren;
color_type m_fill_color;
color_type m_line_color;
int m_curr_x;
int m_curr_y;
};
}
#endif

View file

@ -0,0 +1,264 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_RASTER_TEXT_INCLUDED
#define AGG_RENDERER_RASTER_TEXT_INCLUDED
#include "agg_basics.h"
namespace agg
{
//==============================================renderer_raster_htext_solid
template<class BaseRenderer, class GlyphGenerator>
class renderer_raster_htext_solid
{
public:
typedef BaseRenderer ren_type;
typedef GlyphGenerator glyph_gen_type;
typedef typename glyph_gen_type::glyph_rect glyph_rect;
typedef typename ren_type::color_type color_type;
renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) :
m_ren(&ren),
m_glyph(&glyph)
{}
void attach(ren_type& ren) { m_ren = &ren; }
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
template<class CharT>
void render_text(double x, double y, const CharT* str, bool flip=false)
{
glyph_rect r;
while(*str)
{
m_glyph->prepare(&r, x, y, *str, flip);
if(r.x2 >= r.x1)
{
int i;
if(flip)
{
for(i = r.y1; i <= r.y2; i++)
{
m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
m_color,
m_glyph->span(r.y2 - i));
}
}
else
{
for(i = r.y1; i <= r.y2; i++)
{
m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
m_color,
m_glyph->span(i - r.y1));
}
}
}
x += r.dx;
y += r.dy;
++str;
}
}
private:
ren_type* m_ren;
glyph_gen_type* m_glyph;
color_type m_color;
};
//=============================================renderer_raster_vtext_solid
template<class BaseRenderer, class GlyphGenerator>
class renderer_raster_vtext_solid
{
public:
typedef BaseRenderer ren_type;
typedef GlyphGenerator glyph_gen_type;
typedef typename glyph_gen_type::glyph_rect glyph_rect;
typedef typename ren_type::color_type color_type;
renderer_raster_vtext_solid(ren_type& ren, glyph_gen_type& glyph) :
m_ren(&ren),
m_glyph(&glyph)
{
}
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
template<class CharT>
void render_text(double x, double y, const CharT* str, bool flip=false)
{
glyph_rect r;
while(*str)
{
m_glyph->prepare(&r, x, y, *str, !flip);
if(r.x2 >= r.x1)
{
int i;
if(flip)
{
for(i = r.y1; i <= r.y2; i++)
{
m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
m_color,
m_glyph->span(i - r.y1));
}
}
else
{
for(i = r.y1; i <= r.y2; i++)
{
m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
m_color,
m_glyph->span(r.y2 - i));
}
}
}
x += r.dx;
y += r.dy;
++str;
}
}
private:
ren_type* m_ren;
glyph_gen_type* m_glyph;
color_type m_color;
};
//===================================================renderer_raster_htext
template<class ScanlineRenderer, class GlyphGenerator>
class renderer_raster_htext
{
public:
typedef ScanlineRenderer ren_type;
typedef GlyphGenerator glyph_gen_type;
typedef typename glyph_gen_type::glyph_rect glyph_rect;
class scanline_single_span
{
public:
typedef agg::cover_type cover_type;
//----------------------------------------------------------------
struct const_span
{
int x;
unsigned len;
const cover_type* covers;
const_span() {}
const_span(int x_, unsigned len_, const cover_type* covers_) :
x(x_), len(len_), covers(covers_)
{}
};
typedef const const_span* const_iterator;
//----------------------------------------------------------------
scanline_single_span(int x, int y, unsigned len,
const cover_type* covers) :
m_y(y),
m_span(x, len, covers)
{}
//----------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return 1; }
const_iterator begin() const { return &m_span; }
private:
//----------------------------------------------------------------
int m_y;
const_span m_span;
};
//--------------------------------------------------------------------
renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph) :
m_ren(&ren),
m_glyph(&glyph)
{
}
//--------------------------------------------------------------------
template<class CharT>
void render_text(double x, double y, const CharT* str, bool flip=false)
{
glyph_rect r;
while(*str)
{
m_glyph->prepare(&r, x, y, *str, flip);
if(r.x2 >= r.x1)
{
m_ren->prepare();
int i;
if(flip)
{
for(i = r.y1; i <= r.y2; i++)
{
m_ren->render(
scanline_single_span(r.x1,
i,
(r.x2 - r.x1 + 1),
m_glyph->span(r.y2 - i)));
}
}
else
{
for(i = r.y1; i <= r.y2; i++)
{
m_ren->render(
scanline_single_span(r.x1,
i,
(r.x2 - r.x1 + 1),
m_glyph->span(i - r.y1)));
}
}
}
x += r.dx;
y += r.dy;
++str;
}
}
private:
ren_type* m_ren;
glyph_gen_type* m_glyph;
};
}
#endif

View file

@ -0,0 +1,852 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_SCANLINE_INCLUDED
#define AGG_RENDERER_SCANLINE_INCLUDED
#include "agg_basics.h"
#include "agg_renderer_base.h"
namespace agg
{
//================================================render_scanline_aa_solid
template<class Scanline, class BaseRenderer, class ColorT>
void render_scanline_aa_solid(const Scanline& sl,
BaseRenderer& ren,
const ColorT& color)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
if(span->len > 0)
{
ren.blend_solid_hspan(x, y, (unsigned)span->len,
color,
span->covers);
}
else
{
ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
color,
*(span->covers));
}
if(--num_spans == 0) break;
++span;
}
}
//===============================================render_scanlines_aa_solid
template<class Rasterizer, class Scanline,
class BaseRenderer, class ColorT>
void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl,
BaseRenderer& ren, const ColorT& color)
{
if(ras.rewind_scanlines())
{
// Explicitly convert "color" to the BaseRenderer color type.
// For example, it can be called with color type "rgba", while
// "rgba8" is needed. Otherwise it will be implicitly
// converted in the loop many times.
//----------------------
typename BaseRenderer::color_type ren_color(color);
sl.reset(ras.min_x(), ras.max_x());
while(ras.sweep_scanline(sl))
{
//render_scanline_aa_solid(sl, ren, ren_color);
// This code is equivalent to the above call (copy/paste).
// It's just a "manual" optimization for old compilers,
// like Microsoft Visual C++ v6.0
//-------------------------------
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
if(span->len > 0)
{
ren.blend_solid_hspan(x, y, (unsigned)span->len,
ren_color,
span->covers);
}
else
{
ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
ren_color,
*(span->covers));
}
if(--num_spans == 0) break;
++span;
}
}
}
}
//==============================================renderer_scanline_aa_solid
template<class BaseRenderer> class renderer_scanline_aa_solid
{
public:
typedef BaseRenderer base_ren_type;
typedef typename base_ren_type::color_type color_type;
//--------------------------------------------------------------------
renderer_scanline_aa_solid() : m_ren(0) {}
explicit renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {}
void attach(base_ren_type& ren)
{
m_ren = &ren;
}
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
void prepare() {}
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
render_scanline_aa_solid(sl, *m_ren, m_color);
}
private:
base_ren_type* m_ren;
color_type m_color;
};
//======================================================render_scanline_aa
template<class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanline_aa(const Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
int len = span->len;
const typename Scanline::cover_type* covers = span->covers;
if(len < 0) len = -len;
typename BaseRenderer::color_type* colors = alloc.allocate(len);
span_gen.generate(colors, x, y, len);
ren.blend_color_hspan(x, y, len, colors,
(span->len < 0) ? 0 : covers, *covers);
if(--num_spans == 0) break;
++span;
}
}
//=====================================================render_scanlines_aa
template<class Rasterizer, class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
if(ras.rewind_scanlines())
{
sl.reset(ras.min_x(), ras.max_x());
span_gen.prepare();
while(ras.sweep_scanline(sl))
{
render_scanline_aa(sl, ren, alloc, span_gen);
}
}
}
//====================================================renderer_scanline_aa
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
class renderer_scanline_aa
{
public:
typedef BaseRenderer base_ren_type;
typedef SpanAllocator alloc_type;
typedef SpanGenerator span_gen_type;
//--------------------------------------------------------------------
renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {}
renderer_scanline_aa(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen) :
m_ren(&ren),
m_alloc(&alloc),
m_span_gen(&span_gen)
{}
void attach(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen)
{
m_ren = &ren;
m_alloc = &alloc;
m_span_gen = &span_gen;
}
//--------------------------------------------------------------------
void prepare() { m_span_gen->prepare(); }
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen);
}
private:
base_ren_type* m_ren;
alloc_type* m_alloc;
span_gen_type* m_span_gen;
};
//===============================================render_scanline_bin_solid
template<class Scanline, class BaseRenderer, class ColorT>
void render_scanline_bin_solid(const Scanline& sl,
BaseRenderer& ren,
const ColorT& color)
{
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
ren.blend_hline(span->x,
sl.y(),
span->x - 1 + ((span->len < 0) ?
-span->len :
span->len),
color,
cover_full);
if(--num_spans == 0) break;
++span;
}
}
//==============================================render_scanlines_bin_solid
template<class Rasterizer, class Scanline,
class BaseRenderer, class ColorT>
void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl,
BaseRenderer& ren, const ColorT& color)
{
if(ras.rewind_scanlines())
{
// Explicitly convert "color" to the BaseRenderer color type.
// For example, it can be called with color type "rgba", while
// "rgba8" is needed. Otherwise it will be implicitly
// converted in the loop many times.
//----------------------
typename BaseRenderer::color_type ren_color(color);
sl.reset(ras.min_x(), ras.max_x());
while(ras.sweep_scanline(sl))
{
//render_scanline_bin_solid(sl, ren, ren_color);
// This code is equivalent to the above call (copy/paste).
// It's just a "manual" optimization for old compilers,
// like Microsoft Visual C++ v6.0
//-------------------------------
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
ren.blend_hline(span->x,
sl.y(),
span->x - 1 + ((span->len < 0) ?
-span->len :
span->len),
ren_color,
cover_full);
if(--num_spans == 0) break;
++span;
}
}
}
}
//=============================================renderer_scanline_bin_solid
template<class BaseRenderer> class renderer_scanline_bin_solid
{
public:
typedef BaseRenderer base_ren_type;
typedef typename base_ren_type::color_type color_type;
//--------------------------------------------------------------------
renderer_scanline_bin_solid() : m_ren(0) {}
explicit renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) {}
void attach(base_ren_type& ren)
{
m_ren = &ren;
}
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
void prepare() {}
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
render_scanline_bin_solid(sl, *m_ren, m_color);
}
private:
base_ren_type* m_ren;
color_type m_color;
};
//======================================================render_scanline_bin
template<class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanline_bin(const Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
int len = span->len;
if(len < 0) len = -len;
typename BaseRenderer::color_type* colors = alloc.allocate(len);
span_gen.generate(colors, x, y, len);
ren.blend_color_hspan(x, y, len, colors, 0, cover_full);
if(--num_spans == 0) break;
++span;
}
}
//=====================================================render_scanlines_bin
template<class Rasterizer, class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
if(ras.rewind_scanlines())
{
sl.reset(ras.min_x(), ras.max_x());
span_gen.prepare();
while(ras.sweep_scanline(sl))
{
render_scanline_bin(sl, ren, alloc, span_gen);
}
}
}
//====================================================renderer_scanline_bin
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
class renderer_scanline_bin
{
public:
typedef BaseRenderer base_ren_type;
typedef SpanAllocator alloc_type;
typedef SpanGenerator span_gen_type;
//--------------------------------------------------------------------
renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {}
renderer_scanline_bin(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen) :
m_ren(&ren),
m_alloc(&alloc),
m_span_gen(&span_gen)
{}
void attach(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen)
{
m_ren = &ren;
m_alloc = &alloc;
m_span_gen = &span_gen;
}
//--------------------------------------------------------------------
void prepare() { m_span_gen->prepare(); }
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen);
}
private:
base_ren_type* m_ren;
alloc_type* m_alloc;
span_gen_type* m_span_gen;
};
//========================================================render_scanlines
template<class Rasterizer, class Scanline, class Renderer>
void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
{
if(ras.rewind_scanlines())
{
sl.reset(ras.min_x(), ras.max_x());
ren.prepare();
while(ras.sweep_scanline(sl))
{
ren.render(sl);
}
}
}
//========================================================render_all_paths
template<class Rasterizer, class Scanline, class Renderer,
class VertexSource, class ColorStorage, class PathId>
void render_all_paths(Rasterizer& ras,
Scanline& sl,
Renderer& r,
VertexSource& vs,
const ColorStorage& as,
const PathId& path_id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
ras.reset();
ras.add_path(vs, path_id[i]);
r.color(as[i]);
render_scanlines(ras, sl, r);
}
}
//=============================================render_scanlines_compound
template<class Rasterizer,
class ScanlineAA,
class ScanlineBin,
class BaseRenderer,
class SpanAllocator,
class StyleHandler>
void render_scanlines_compound(Rasterizer& ras,
ScanlineAA& sl_aa,
ScanlineBin& sl_bin,
BaseRenderer& ren,
SpanAllocator& alloc,
StyleHandler& sh)
{
if(ras.rewind_scanlines())
{
int min_x = ras.min_x();
int len = ras.max_x() - min_x + 2;
sl_aa.reset(min_x, ras.max_x());
sl_bin.reset(min_x, ras.max_x());
typedef typename BaseRenderer::color_type color_type;
color_type* color_span = alloc.allocate(len * 2);
color_type* mix_buffer = color_span + len;
unsigned num_spans;
unsigned num_styles;
unsigned style;
bool solid;
while((num_styles = ras.sweep_styles()) > 0)
{
typename ScanlineAA::const_iterator span_aa;
if(num_styles == 1)
{
// Optimization for a single style. Happens often
//-------------------------
if(ras.sweep_scanline(sl_aa, 0))
{
style = ras.style(0);
if(sh.is_solid(style))
{
// Just solid fill
//-----------------------
render_scanline_aa_solid(sl_aa, ren, sh.color(style));
}
else
{
// Arbitrary span generator
//-----------------------
span_aa = sl_aa.begin();
num_spans = sl_aa.num_spans();
for(;;)
{
len = span_aa->len;
sh.generate_span(color_span,
span_aa->x,
sl_aa.y(),
len,
style);
ren.blend_color_hspan(span_aa->x,
sl_aa.y(),
span_aa->len,
color_span,
span_aa->covers);
if(--num_spans == 0) break;
++span_aa;
}
}
}
}
else
{
if(ras.sweep_scanline(sl_bin, -1))
{
// Clear the spans of the mix_buffer
//--------------------
typename ScanlineBin::const_iterator span_bin = sl_bin.begin();
num_spans = sl_bin.num_spans();
for(;;)
{
memset(mix_buffer + span_bin->x - min_x,
0,
span_bin->len * sizeof(color_type));
if(--num_spans == 0) break;
++span_bin;
}
unsigned i;
for(i = 0; i < num_styles; i++)
{
style = ras.style(i);
solid = sh.is_solid(style);
if(ras.sweep_scanline(sl_aa, i))
{
color_type* colors;
color_type* cspan;
typename ScanlineAA::cover_type* covers;
span_aa = sl_aa.begin();
num_spans = sl_aa.num_spans();
if(solid)
{
// Just solid fill
//-----------------------
for(;;)
{
color_type c = sh.color(style);
len = span_aa->len;
colors = mix_buffer + span_aa->x - min_x;
covers = span_aa->covers;
do
{
if(*covers == cover_full)
{
*colors = c;
}
else
{
colors->add(c, *covers);
}
++colors;
++covers;
}
while(--len);
if(--num_spans == 0) break;
++span_aa;
}
}
else
{
// Arbitrary span generator
//-----------------------
for(;;)
{
len = span_aa->len;
colors = mix_buffer + span_aa->x - min_x;
cspan = color_span;
sh.generate_span(cspan,
span_aa->x,
sl_aa.y(),
len,
style);
covers = span_aa->covers;
do
{
if(*covers == cover_full)
{
*colors = *cspan;
}
else
{
colors->add(*cspan, *covers);
}
++cspan;
++colors;
++covers;
}
while(--len);
if(--num_spans == 0) break;
++span_aa;
}
}
}
}
// Emit the blended result as a color hspan
//-------------------------
span_bin = sl_bin.begin();
num_spans = sl_bin.num_spans();
for(;;)
{
ren.blend_color_hspan(span_bin->x,
sl_bin.y(),
span_bin->len,
mix_buffer + span_bin->x - min_x,
0,
cover_full);
if(--num_spans == 0) break;
++span_bin;
}
} // if(ras.sweep_scanline(sl_bin, -1))
} // if(num_styles == 1) ... else
} // while((num_styles = ras.sweep_styles()) > 0)
} // if(ras.rewind_scanlines())
}
//=======================================render_scanlines_compound_layered
template<class Rasterizer,
class ScanlineAA,
class BaseRenderer,
class SpanAllocator,
class StyleHandler>
void render_scanlines_compound_layered(Rasterizer& ras,
ScanlineAA& sl_aa,
BaseRenderer& ren,
SpanAllocator& alloc,
StyleHandler& sh)
{
if(ras.rewind_scanlines())
{
int min_x = ras.min_x();
int len = ras.max_x() - min_x + 2;
sl_aa.reset(min_x, ras.max_x());
typedef typename BaseRenderer::color_type color_type;
color_type* color_span = alloc.allocate(len * 2);
color_type* mix_buffer = color_span + len;
cover_type* cover_buffer = ras.allocate_cover_buffer(len);
unsigned num_spans;
unsigned num_styles;
unsigned style;
bool solid;
while((num_styles = ras.sweep_styles()) > 0)
{
typename ScanlineAA::const_iterator span_aa;
if(num_styles == 1)
{
// Optimization for a single style. Happens often
//-------------------------
if(ras.sweep_scanline(sl_aa, 0))
{
style = ras.style(0);
if(sh.is_solid(style))
{
// Just solid fill
//-----------------------
render_scanline_aa_solid(sl_aa, ren, sh.color(style));
}
else
{
// Arbitrary span generator
//-----------------------
span_aa = sl_aa.begin();
num_spans = sl_aa.num_spans();
for(;;)
{
len = span_aa->len;
sh.generate_span(color_span,
span_aa->x,
sl_aa.y(),
len,
style);
ren.blend_color_hspan(span_aa->x,
sl_aa.y(),
span_aa->len,
color_span,
span_aa->covers);
if(--num_spans == 0) break;
++span_aa;
}
}
}
}
else
{
int sl_start = ras.scanline_start();
unsigned sl_len = ras.scanline_length();
if(sl_len)
{
memset(mix_buffer + sl_start - min_x,
0,
sl_len * sizeof(color_type));
memset(cover_buffer + sl_start - min_x,
0,
sl_len * sizeof(cover_type));
int sl_y = 0x7FFFFFFF;
unsigned i;
for(i = 0; i < num_styles; i++)
{
style = ras.style(i);
solid = sh.is_solid(style);
if(ras.sweep_scanline(sl_aa, i))
{
unsigned cover;
color_type* colors;
color_type* cspan;
cover_type* src_covers;
cover_type* dst_covers;
span_aa = sl_aa.begin();
num_spans = sl_aa.num_spans();
sl_y = sl_aa.y();
if(solid)
{
// Just solid fill
//-----------------------
for(;;)
{
color_type c = sh.color(style);
len = span_aa->len;
colors = mix_buffer + span_aa->x - min_x;
src_covers = span_aa->covers;
dst_covers = cover_buffer + span_aa->x - min_x;
do
{
cover = *src_covers;
if(*dst_covers + cover > cover_full)
{
cover = cover_full - *dst_covers;
}
if(cover)
{
colors->add(c, cover);
*dst_covers += cover;
}
++colors;
++src_covers;
++dst_covers;
}
while(--len);
if(--num_spans == 0) break;
++span_aa;
}
}
else
{
// Arbitrary span generator
//-----------------------
for(;;)
{
len = span_aa->len;
colors = mix_buffer + span_aa->x - min_x;
cspan = color_span;
sh.generate_span(cspan,
span_aa->x,
sl_aa.y(),
len,
style);
src_covers = span_aa->covers;
dst_covers = cover_buffer + span_aa->x - min_x;
do
{
cover = *src_covers;
if(*dst_covers + cover > cover_full)
{
cover = cover_full - *dst_covers;
}
if(cover)
{
colors->add(*cspan, cover);
*dst_covers += cover;
}
++cspan;
++colors;
++src_covers;
++dst_covers;
}
while(--len);
if(--num_spans == 0) break;
++span_aa;
}
}
}
}
ren.blend_color_hspan(sl_start,
sl_y,
sl_len,
mix_buffer + sl_start - min_x,
0,
cover_full);
} //if(sl_len)
} //if(num_styles == 1) ... else
} //while((num_styles = ras.sweep_styles()) > 0)
} //if(ras.rewind_scanlines())
}
}
#endif

View file

@ -0,0 +1,300 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class rendering_buffer
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERING_BUFFER_INCLUDED
#define AGG_RENDERING_BUFFER_INCLUDED
#include "agg_array.h"
namespace agg
{
//===========================================================row_accessor
template<class T> class row_accessor
{
public:
typedef const_row_info<T> row_data;
//-------------------------------------------------------------------
row_accessor() :
m_buf(0),
m_start(0),
m_width(0),
m_height(0),
m_stride(0)
{
}
//--------------------------------------------------------------------
row_accessor(T* buf, unsigned width, unsigned height, int stride) :
m_buf(0),
m_start(0),
m_width(0),
m_height(0),
m_stride(0)
{
attach(buf, width, height, stride);
}
//--------------------------------------------------------------------
void attach(T* buf, unsigned width, unsigned height, int stride)
{
m_buf = m_start = buf;
m_width = width;
m_height = height;
m_stride = stride;
if(stride < 0)
{
m_start = m_buf - 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 renrdering buffer
T* m_start; // Pointer to first pixel depending on stride
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels
int m_stride; // Number of bytes per row. Can be < 0
};
//==========================================================row_ptr_cache
template<class T> class row_ptr_cache
{
public:
typedef const_row_info<T> row_data;
//-------------------------------------------------------------------
row_ptr_cache() :
m_buf(0),
m_rows(),
m_width(0),
m_height(0),
m_stride(0)
{
}
//--------------------------------------------------------------------
row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) :
m_buf(0),
m_rows(),
m_width(0),
m_height(0),
m_stride(0)
{
attach(buf, width, height, stride);
}
//--------------------------------------------------------------------
void attach(T* buf, unsigned width, unsigned height, int stride)
{
m_buf = buf;
m_width = width;
m_height = height;
m_stride = stride;
if(height > m_rows.size())
{
m_rows.resize(height);
}
T* row_ptr = m_buf;
if(stride < 0)
{
row_ptr = m_buf - int(height - 1) * stride;
}
T** rows = &m_rows[0];
while(height--)
{
*rows++ = row_ptr;
row_ptr += stride;
}
}
//--------------------------------------------------------------------
AGG_INLINE T* buf() { return m_buf; }
AGG_INLINE const T* buf() const { return m_buf; }
AGG_INLINE unsigned width() const { return m_width; }
AGG_INLINE unsigned height() const { return m_height; }
AGG_INLINE int stride() const { return m_stride; }
AGG_INLINE unsigned stride_abs() const
{
return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
}
//--------------------------------------------------------------------
AGG_INLINE T* row_ptr(int, int y, unsigned)
{
return m_rows[y];
}
AGG_INLINE T* row_ptr(int y) { return m_rows[y]; }
AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; }
AGG_INLINE row_data row (int y) const
{
return row_data(0, m_width-1, m_rows[y]);
}
//--------------------------------------------------------------------
T const* const* rows() const { return &m_rows[0]; }
//--------------------------------------------------------------------
template<class RenBuf>
void copy_from(const RenBuf& src)
{
unsigned h = height();
if(src.height() < h) h = src.height();
unsigned l = stride_abs();
if(src.stride_abs() < l) l = src.stride_abs();
l *= sizeof(T);
unsigned y;
unsigned w = width();
for (y = 0; y < h; y++)
{
memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
}
}
//--------------------------------------------------------------------
void clear(T value)
{
unsigned y;
unsigned w = width();
unsigned stride = stride_abs();
for(y = 0; y < height(); y++)
{
T* p = row_ptr(0, y, w);
unsigned x;
for(x = 0; x < stride; x++)
{
*p++ = value;
}
}
}
private:
//--------------------------------------------------------------------
T* m_buf; // Pointer to renrdering buffer
pod_array<T*> m_rows; // Pointers to each row of the buffer
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels
int m_stride; // Number of bytes per row. Can be < 0
};
//========================================================rendering_buffer
//
// The definition of the main type for accessing the rows in the frame
// buffer. It provides functionality to navigate to the rows in a
// rectangular matrix, from top to bottom or from bottom to top depending
// on stride.
//
// row_accessor is cheap to create/destroy, but performs one multiplication
// when calling row_ptr().
//
// row_ptr_cache creates an array of pointers to rows, so, the access
// via row_ptr() may be faster. But it requires memory allocation
// when creating. For example, on typical Intel Pentium hardware
// row_ptr_cache speeds span_image_filter_rgb_nn up to 10%
//
// It's used only in short hand typedefs like pixfmt_rgba32 and can be
// redefined in agg_config.h
// In real applications you can use both, depending on your needs
//------------------------------------------------------------------------
#ifdef AGG_RENDERING_BUFFER
typedef AGG_RENDERING_BUFFER rendering_buffer;
#else
// typedef row_ptr_cache<int8u> rendering_buffer;
typedef row_accessor<int8u> rendering_buffer;
#endif
}
#endif

View file

@ -0,0 +1,137 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class rendering_buffer_dynarow
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
#define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
#include "agg_array.h"
namespace agg
{
//===============================================rendering_buffer_dynarow
// Rendering buffer class with dynamic allocation of the rows.
// The rows are allocated as needed when requesting for span_ptr().
// The class automatically calculates min_x and max_x for each row.
// Generally it's more efficient to use this class as a temporary buffer
// for rendering a few lines and then to blend it with another buffer.
//
class rendering_buffer_dynarow
{
public:
typedef row_info<int8u> row_data;
//-------------------------------------------------------------------
~rendering_buffer_dynarow()
{
init(0,0,0);
}
//-------------------------------------------------------------------
rendering_buffer_dynarow() :
m_rows(),
m_width(0),
m_height(0),
m_byte_width(0)
{
}
// Allocate and clear the buffer
//--------------------------------------------------------------------
rendering_buffer_dynarow(unsigned width, unsigned height,
unsigned byte_width) :
m_rows(height),
m_width(width),
m_height(height),
m_byte_width(byte_width)
{
memset(&m_rows[0], 0, sizeof(row_data) * height);
}
// Allocate and clear the buffer
//--------------------------------------------------------------------
void init(unsigned width, unsigned height, unsigned byte_width)
{
unsigned i;
for(i = 0; i < m_height; ++i)
{
pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
}
if(width && height)
{
m_width = width;
m_height = height;
m_byte_width = byte_width;
m_rows.resize(height);
memset(&m_rows[0], 0, sizeof(row_data) * height);
}
}
//--------------------------------------------------------------------
unsigned width() const { return m_width; }
unsigned height() const { return m_height; }
unsigned byte_width() const { return m_byte_width; }
// The main function used for rendering. Returns pointer to the
// pre-allocated span. Memory for the row is allocated as needed.
//--------------------------------------------------------------------
int8u* row_ptr(int x, int y, unsigned len)
{
row_data* r = &m_rows[y];
int x2 = x + len - 1;
if(r->ptr)
{
if(x < r->x1) { r->x1 = x; }
if(x2 > r->x2) { r->x2 = x2; }
}
else
{
int8u* p = pod_allocator<int8u>::allocate(m_byte_width);
r->ptr = p;
r->x1 = x;
r->x2 = x2;
memset(p, 0, m_byte_width);
}
return (int8u*)r->ptr;
}
//--------------------------------------------------------------------
const int8u* row_ptr(int y) const { return m_rows[y].ptr; }
int8u* row_ptr(int y) { return row_ptr(0, y, m_width); }
row_data row (int y) const { return m_rows[y]; }
private:
//--------------------------------------------------------------------
// Prohibit copying
rendering_buffer_dynarow(const rendering_buffer_dynarow&);
const rendering_buffer_dynarow& operator = (const rendering_buffer_dynarow&);
private:
//--------------------------------------------------------------------
pod_array<row_data> m_rows; // Pointers to each row of the buffer
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels
unsigned m_byte_width; // Width in bytes
};
}
#endif

View file

@ -0,0 +1,72 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Rounded rectangle vertex generator
//
//----------------------------------------------------------------------------
#ifndef AGG_ROUNDED_RECT_INCLUDED
#define AGG_ROUNDED_RECT_INCLUDED
#include "agg_basics.h"
#include "agg_arc.h"
namespace agg
{
//------------------------------------------------------------rounded_rect
//
// See Implemantation agg_rounded_rect.cpp
//
class rounded_rect
{
public:
rounded_rect() {}
rounded_rect(double x1, double y1, double x2, double y2, double r);
void rect(double x1, double y1, double x2, double y2);
void radius(double r);
void radius(double rx, double ry);
void radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top);
void radius(double rx1, double ry1, double rx2, double ry2,
double rx3, double ry3, double rx4, double ry4);
void normalize_radius();
void approximation_scale(double s) { m_arc.approximation_scale(s); }
double approximation_scale() const { return m_arc.approximation_scale(); }
void rewind(unsigned);
unsigned vertex(double* x, double* y);
private:
double m_x1;
double m_y1;
double m_x2;
double m_y2;
double m_rx1;
double m_ry1;
double m_rx2;
double m_ry2;
double m_rx3;
double m_ry3;
double m_rx4;
double m_ry4;
unsigned m_status;
arc m_arc;
};
}
#endif

View file

@ -0,0 +1,264 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Class scanline_bin - binary scanline.
//
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates (scanline32_bin) has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_BIN_INCLUDED
#define AGG_SCANLINE_BIN_INCLUDED
#include "agg_array.h"
namespace agg
{
//=============================================================scanline_bin
//
// This is binary scaline container which supports the interface
// used in the rasterizer::render(). See description of agg_scanline_u8
// for details.
//
//------------------------------------------------------------------------
class scanline_bin
{
public:
typedef int32 coord_type;
struct span
{
int16 x;
int16 len;
};
typedef const span* const_iterator;
//--------------------------------------------------------------------
scanline_bin() :
m_last_x(0x7FFFFFF0),
m_spans(),
m_cur_span(0)
{
}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 3;
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned)
{
if(x == m_last_x+1)
{
m_cur_span->len++;
}
else
{
++m_cur_span;
m_cur_span->x = (int16)x;
m_cur_span->len = 1;
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned)
{
if(x == m_last_x+1)
{
m_cur_span->len = (int16)(m_cur_span->len + len);
}
else
{
++m_cur_span;
m_cur_span->x = (int16)x;
m_cur_span->len = (int16)len;
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const void*)
{
add_span(x, len, 0);
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
private:
scanline_bin(const scanline_bin&);
const scanline_bin operator = (const scanline_bin&);
int m_last_x;
int m_y;
pod_array<span> m_spans;
span* m_cur_span;
};
//===========================================================scanline32_bin
class scanline32_bin
{
public:
typedef int32 coord_type;
//--------------------------------------------------------------------
struct span
{
span() {}
span(coord_type x_, coord_type len_) : x(x_), len(len_) {}
coord_type x;
coord_type len;
};
typedef pod_bvector<span, 4> span_array_type;
//--------------------------------------------------------------------
class const_iterator
{
public:
const_iterator(const span_array_type& spans) :
m_spans(spans),
m_span_idx(0)
{}
const span& operator*() const { return m_spans[m_span_idx]; }
const span* operator->() const { return &m_spans[m_span_idx]; }
void operator ++ () { ++m_span_idx; }
private:
const span_array_type& m_spans;
unsigned m_span_idx;
};
//--------------------------------------------------------------------
scanline32_bin() : m_max_len(0), m_last_x(0x7FFFFFF0) {}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
m_last_x = 0x7FFFFFF0;
m_spans.remove_all();
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned)
{
if(x == m_last_x+1)
{
m_spans.last().len++;
}
else
{
m_spans.add(span(coord_type(x), 1));
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned)
{
if(x == m_last_x+1)
{
m_spans.last().len += coord_type(len);
}
else
{
m_spans.add(span(coord_type(x), coord_type(len)));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const void*)
{
add_span(x, len, 0);
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_spans.remove_all();
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return m_spans.size(); }
const_iterator begin() const { return const_iterator(m_spans); }
private:
scanline32_bin(const scanline32_bin&);
const scanline32_bin operator = (const scanline32_bin&);
unsigned m_max_len;
int m_last_x;
int m_y;
span_array_type m_spans;
};
}
#endif

File diff suppressed because it is too large Load diff

329
3party/agg/agg_scanline_p.h Normal file
View file

@ -0,0 +1,329 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Class scanline_p - a general purpose scanline container with packed spans.
//
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_P_INCLUDED
#define AGG_SCANLINE_P_INCLUDED
#include "agg_array.h"
namespace agg
{
//=============================================================scanline_p8
//
// This is a general purpose scaline container which supports the interface
// used in the rasterizer::render(). See description of scanline_u8
// for details.
//
//------------------------------------------------------------------------
class scanline_p8
{
public:
typedef scanline_p8 self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
coord_type x;
coord_type len; // If negative, it's a solid span, covers is valid
const cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
scanline_p8() :
m_last_x(0x7FFFFFF0),
m_covers(),
m_cover_ptr(0),
m_spans(),
m_cur_span(0)
{
}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 3;
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_cur_span = &m_spans[0];
m_cur_span->len = 0;
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover)
{
*m_cover_ptr = (cover_type)cover;
if(x == m_last_x+1 && m_cur_span->len > 0)
{
m_cur_span->len++;
}
else
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = 1;
}
m_last_x = x;
m_cover_ptr++;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
if(x == m_last_x+1 && m_cur_span->len > 0)
{
m_cur_span->len += (int16)len;
}
else
{
m_cur_span++;
m_cur_span->covers = m_cover_ptr;
m_cur_span->x = (int16)x;
m_cur_span->len = (int16)len;
}
m_cover_ptr += len;
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
if(x == m_last_x+1 &&
m_cur_span->len < 0 &&
cover == *m_cur_span->covers)
{
m_cur_span->len -= (int16)len;
}
else
{
*m_cover_ptr = (cover_type)cover;
m_cur_span++;
m_cur_span->covers = m_cover_ptr++;
m_cur_span->x = (int16)x;
m_cur_span->len = (int16)(-int(len));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_cur_span = &m_spans[0];
m_cur_span->len = 0;
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
private:
scanline_p8(const self_type&);
const self_type& operator = (const self_type&);
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
cover_type* m_cover_ptr;
pod_array<span> m_spans;
span* m_cur_span;
};
//==========================================================scanline32_p8
class scanline32_p8
{
public:
typedef scanline32_p8 self_type;
typedef int8u cover_type;
typedef int32 coord_type;
struct span
{
span() {}
span(coord_type x_, coord_type len_, const cover_type* covers_) :
x(x_), len(len_), covers(covers_) {}
coord_type x;
coord_type len; // If negative, it's a solid span, covers is valid
const cover_type* covers;
};
typedef pod_bvector<span, 4> span_array_type;
//--------------------------------------------------------------------
class const_iterator
{
public:
const_iterator(const span_array_type& spans) :
m_spans(spans),
m_span_idx(0)
{}
const span& operator*() const { return m_spans[m_span_idx]; }
const span* operator->() const { return &m_spans[m_span_idx]; }
void operator ++ () { ++m_span_idx; }
private:
const span_array_type& m_spans;
unsigned m_span_idx;
};
//--------------------------------------------------------------------
scanline32_p8() :
m_max_len(0),
m_last_x(0x7FFFFFF0),
m_covers(),
m_cover_ptr(0)
{
}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 3;
if(max_len > m_covers.size())
{
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_spans.remove_all();
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover)
{
*m_cover_ptr = cover_type(cover);
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
{
m_spans.last().len++;
}
else
{
m_spans.add(span(coord_type(x), 1, m_cover_ptr));
}
m_last_x = x;
m_cover_ptr++;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
{
m_spans.last().len += coord_type(len);
}
else
{
m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
}
m_cover_ptr += len;
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
if(x == m_last_x+1 &&
m_spans.size() &&
m_spans.last().len < 0 &&
cover == *m_spans.last().covers)
{
m_spans.last().len -= coord_type(len);
}
else
{
*m_cover_ptr = cover_type(cover);
m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cover_ptr = &m_covers[0];
m_spans.remove_all();
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return m_spans.size(); }
const_iterator begin() const { return const_iterator(m_spans); }
private:
scanline32_p8(const self_type&);
const self_type& operator = (const self_type&);
unsigned m_max_len;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
cover_type* m_cover_ptr;
span_array_type m_spans;
};
}
#endif

View file

@ -0,0 +1,815 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED
#define AGG_SCANLINE_STORAGE_AA_INCLUDED
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "agg_array.h"
namespace agg
{
//----------------------------------------------scanline_cell_storage
template<class T> class scanline_cell_storage
{
struct extra_span
{
unsigned len;
T* ptr;
};
public:
typedef T value_type;
//---------------------------------------------------------------
~scanline_cell_storage()
{
remove_all();
}
//---------------------------------------------------------------
scanline_cell_storage() :
m_cells(128-2),
m_extra_storage()
{}
// Copying
//---------------------------------------------------------------
scanline_cell_storage(const scanline_cell_storage<T>& v) :
m_cells(v.m_cells),
m_extra_storage()
{
copy_extra_storage(v);
}
//---------------------------------------------------------------
const scanline_cell_storage<T>&
operator = (const scanline_cell_storage<T>& v)
{
remove_all();
m_cells = v.m_cells;
copy_extra_storage(v);
return *this;
}
//---------------------------------------------------------------
void remove_all()
{
int i;
for(i = m_extra_storage.size()-1; i >= 0; --i)
{
pod_allocator<T>::deallocate(m_extra_storage[i].ptr,
m_extra_storage[i].len);
}
m_extra_storage.remove_all();
m_cells.remove_all();
}
//---------------------------------------------------------------
int add_cells(const T* cells, unsigned num_cells)
{
int idx = m_cells.allocate_continuous_block(num_cells);
if(idx >= 0)
{
T* ptr = &m_cells[idx];
memcpy(ptr, cells, sizeof(T) * num_cells);
return idx;
}
extra_span s;
s.len = num_cells;
s.ptr = pod_allocator<T>::allocate(num_cells);
memcpy(s.ptr, cells, sizeof(T) * num_cells);
m_extra_storage.add(s);
return -int(m_extra_storage.size());
}
//---------------------------------------------------------------
const T* operator [] (int idx) const
{
if(idx >= 0)
{
if((unsigned)idx >= m_cells.size()) return 0;
return &m_cells[(unsigned)idx];
}
unsigned i = unsigned(-idx - 1);
if(i >= m_extra_storage.size()) return 0;
return m_extra_storage[i].ptr;
}
//---------------------------------------------------------------
T* operator [] (int idx)
{
if(idx >= 0)
{
if((unsigned)idx >= m_cells.size()) return 0;
return &m_cells[(unsigned)idx];
}
unsigned i = unsigned(-idx - 1);
if(i >= m_extra_storage.size()) return 0;
return m_extra_storage[i].ptr;
}
private:
void copy_extra_storage(const scanline_cell_storage<T>& v)
{
unsigned i;
for(i = 0; i < v.m_extra_storage.size(); ++i)
{
const extra_span& src = v.m_extra_storage[i];
extra_span dst;
dst.len = src.len;
dst.ptr = pod_allocator<T>::allocate(dst.len);
memcpy(dst.ptr, src.ptr, dst.len * sizeof(T));
m_extra_storage.add(dst);
}
}
pod_bvector<T, 12> m_cells;
pod_bvector<extra_span, 6> m_extra_storage;
};
//-----------------------------------------------scanline_storage_aa
template<class T> class scanline_storage_aa
{
public:
typedef T cover_type;
//---------------------------------------------------------------
struct span_data
{
int32 x;
int32 len; // If negative, it's a solid span, covers is valid
int covers_id; // The index of the cells in the scanline_cell_storage
};
//---------------------------------------------------------------
struct scanline_data
{
int y;
unsigned num_spans;
unsigned start_span;
};
//---------------------------------------------------------------
class embedded_scanline
{
public:
//-----------------------------------------------------------
class const_iterator
{
public:
struct span
{
int32 x;
int32 len; // If negative, it's a solid span, covers is valid
const T* covers;
};
const_iterator() : m_storage(0) {}
const_iterator(const embedded_scanline& sl) :
m_storage(sl.m_storage),
m_span_idx(sl.m_scanline.start_span)
{
init_span();
}
const span& operator*() const { return m_span; }
const span* operator->() const { return &m_span; }
void operator ++ ()
{
++m_span_idx;
init_span();
}
private:
void init_span()
{
const span_data& s = m_storage->span_by_index(m_span_idx);
m_span.x = s.x;
m_span.len = s.len;
m_span.covers = m_storage->covers_by_index(s.covers_id);
}
const scanline_storage_aa* m_storage;
unsigned m_span_idx;
span m_span;
};
friend class const_iterator;
//-----------------------------------------------------------
embedded_scanline(const scanline_storage_aa& storage) :
m_storage(&storage)
{
init(0);
}
//-----------------------------------------------------------
void reset(int, int) {}
unsigned num_spans() const { return m_scanline.num_spans; }
int y() const { return m_scanline.y; }
const_iterator begin() const { return const_iterator(*this); }
//-----------------------------------------------------------
void init(unsigned scanline_idx)
{
m_scanline_idx = scanline_idx;
m_scanline = m_storage->scanline_by_index(m_scanline_idx);
}
private:
const scanline_storage_aa* m_storage;
scanline_data m_scanline;
unsigned m_scanline_idx;
};
//---------------------------------------------------------------
scanline_storage_aa() :
m_covers(),
m_spans(256-2), // Block increment size
m_scanlines(),
m_min_x( 0x7FFFFFFF),
m_min_y( 0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF),
m_cur_scanline(0)
{
m_fake_scanline.y = 0;
m_fake_scanline.num_spans = 0;
m_fake_scanline.start_span = 0;
m_fake_span.x = 0;
m_fake_span.len = 0;
m_fake_span.covers_id = 0;
}
// Renderer Interface
//---------------------------------------------------------------
void prepare()
{
m_covers.remove_all();
m_scanlines.remove_all();
m_spans.remove_all();
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
m_max_y = -0x7FFFFFFF;
m_cur_scanline = 0;
}
//---------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
scanline_data sl_this;
int y = sl.y();
if(y < m_min_y) m_min_y = y;
if(y > m_max_y) m_max_y = y;
sl_this.y = y;
sl_this.num_spans = sl.num_spans();
sl_this.start_span = m_spans.size();
typename Scanline::const_iterator span_iterator = sl.begin();
unsigned num_spans = sl_this.num_spans;
for(;;)
{
span_data sp;
sp.x = span_iterator->x;
sp.len = span_iterator->len;
int len = abs(int(sp.len));
sp.covers_id =
m_covers.add_cells(span_iterator->covers,
unsigned(len));
m_spans.add(sp);
int x1 = sp.x;
int x2 = sp.x + len - 1;
if(x1 < m_min_x) m_min_x = x1;
if(x2 > m_max_x) m_max_x = x2;
if(--num_spans == 0) break;
++span_iterator;
}
m_scanlines.add(sl_this);
}
//---------------------------------------------------------------
// Iterate scanlines interface
int min_x() const { return m_min_x; }
int min_y() const { return m_min_y; }
int max_x() const { return m_max_x; }
int max_y() const { return m_max_y; }
//---------------------------------------------------------------
bool rewind_scanlines()
{
m_cur_scanline = 0;
return m_scanlines.size() > 0;
}
//---------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
sl.reset_spans();
for(;;)
{
if(m_cur_scanline >= m_scanlines.size()) return false;
const scanline_data& sl_this = m_scanlines[m_cur_scanline];
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
do
{
const span_data& sp = m_spans[span_idx++];
const T* covers = covers_by_index(sp.covers_id);
if(sp.len < 0)
{
sl.add_span(sp.x, unsigned(-sp.len), *covers);
}
else
{
sl.add_cells(sp.x, sp.len, covers);
}
}
while(--num_spans);
++m_cur_scanline;
if(sl.num_spans())
{
sl.finalize(sl_this.y);
break;
}
}
return true;
}
//---------------------------------------------------------------
// Specialization for embedded_scanline
bool sweep_scanline(embedded_scanline& sl)
{
do
{
if(m_cur_scanline >= m_scanlines.size()) return false;
sl.init(m_cur_scanline);
++m_cur_scanline;
}
while(sl.num_spans() == 0);
return true;
}
//---------------------------------------------------------------
unsigned byte_size() const
{
unsigned i;
unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
for(i = 0; i < m_scanlines.size(); ++i)
{
size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans
const scanline_data& sl_this = m_scanlines[i];
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
do
{
const span_data& sp = m_spans[span_idx++];
size += sizeof(int32) * 2; // X, span_len
if(sp.len < 0)
{
size += sizeof(T); // cover
}
else
{
size += sizeof(T) * unsigned(sp.len); // covers
}
}
while(--num_spans);
}
return size;
}
//---------------------------------------------------------------
static void write_int32(int8u* dst, int32 val)
{
dst[0] = ((const int8u*)&val)[0];
dst[1] = ((const int8u*)&val)[1];
dst[2] = ((const int8u*)&val)[2];
dst[3] = ((const int8u*)&val)[3];
}
//---------------------------------------------------------------
void serialize(int8u* data) const
{
unsigned i;
write_int32(data, min_x()); // min_x
data += sizeof(int32);
write_int32(data, min_y()); // min_y
data += sizeof(int32);
write_int32(data, max_x()); // max_x
data += sizeof(int32);
write_int32(data, max_y()); // max_y
data += sizeof(int32);
for(i = 0; i < m_scanlines.size(); ++i)
{
const scanline_data& sl_this = m_scanlines[i];
int8u* size_ptr = data;
data += sizeof(int32); // Reserve space for scanline size in bytes
write_int32(data, sl_this.y); // Y
data += sizeof(int32);
write_int32(data, sl_this.num_spans); // num_spans
data += sizeof(int32);
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
do
{
const span_data& sp = m_spans[span_idx++];
const T* covers = covers_by_index(sp.covers_id);
write_int32(data, sp.x); // X
data += sizeof(int32);
write_int32(data, sp.len); // span_len
data += sizeof(int32);
if(sp.len < 0)
{
memcpy(data, covers, sizeof(T));
data += sizeof(T);
}
else
{
memcpy(data, covers, unsigned(sp.len) * sizeof(T));
data += sizeof(T) * unsigned(sp.len);
}
}
while(--num_spans);
write_int32(size_ptr, int32(unsigned(data - size_ptr)));
}
}
//---------------------------------------------------------------
const scanline_data& scanline_by_index(unsigned i) const
{
return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
}
//---------------------------------------------------------------
const span_data& span_by_index(unsigned i) const
{
return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
}
//---------------------------------------------------------------
const T* covers_by_index(int i) const
{
return m_covers[i];
}
private:
scanline_cell_storage<T> m_covers;
pod_bvector<span_data, 10> m_spans;
pod_bvector<scanline_data, 8> m_scanlines;
span_data m_fake_span;
scanline_data m_fake_scanline;
int m_min_x;
int m_min_y;
int m_max_x;
int m_max_y;
unsigned m_cur_scanline;
};
typedef scanline_storage_aa<int8u> scanline_storage_aa8; //--------scanline_storage_aa8
typedef scanline_storage_aa<int16u> scanline_storage_aa16; //--------scanline_storage_aa16
typedef scanline_storage_aa<int32u> scanline_storage_aa32; //--------scanline_storage_aa32
//------------------------------------------serialized_scanlines_adaptor_aa
template<class T> class serialized_scanlines_adaptor_aa
{
public:
typedef T cover_type;
//---------------------------------------------------------------------
class embedded_scanline
{
public:
typedef T cover_type;
//-----------------------------------------------------------------
class const_iterator
{
public:
struct span
{
int32 x;
int32 len; // If negative, it's a solid span, "covers" is valid
const T* covers;
};
const_iterator() : m_ptr(0) {}
const_iterator(const embedded_scanline& sl) :
m_ptr(sl.m_ptr),
m_dx(sl.m_dx)
{
init_span();
}
const span& operator*() const { return m_span; }
const span* operator->() const { return &m_span; }
void operator ++ ()
{
if(m_span.len < 0)
{
m_ptr += sizeof(T);
}
else
{
m_ptr += m_span.len * sizeof(T);
}
init_span();
}
private:
int read_int32()
{
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
void init_span()
{
m_span.x = read_int32() + m_dx;
m_span.len = read_int32();
m_span.covers = m_ptr;
}
const int8u* m_ptr;
span m_span;
int m_dx;
};
friend class const_iterator;
//-----------------------------------------------------------------
embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
//-----------------------------------------------------------------
void reset(int, int) {}
unsigned num_spans() const { return m_num_spans; }
int y() const { return m_y; }
const_iterator begin() const { return const_iterator(*this); }
private:
//-----------------------------------------------------------------
int read_int32()
{
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
public:
//-----------------------------------------------------------------
void init(const int8u* ptr, int dx, int dy)
{
m_ptr = ptr;
m_y = read_int32() + dy;
m_num_spans = unsigned(read_int32());
m_dx = dx;
}
private:
const int8u* m_ptr;
int m_y;
unsigned m_num_spans;
int m_dx;
};
public:
//--------------------------------------------------------------------
serialized_scanlines_adaptor_aa() :
m_data(0),
m_end(0),
m_ptr(0),
m_dx(0),
m_dy(0),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF)
{}
//--------------------------------------------------------------------
serialized_scanlines_adaptor_aa(const int8u* data, unsigned size,
double dx, double dy) :
m_data(data),
m_end(data + size),
m_ptr(data),
m_dx(iround(dx)),
m_dy(iround(dy)),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF)
{}
//--------------------------------------------------------------------
void init(const int8u* data, unsigned size, double dx, double dy)
{
m_data = data;
m_end = data + size;
m_ptr = data;
m_dx = iround(dx);
m_dy = iround(dy);
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
m_max_y = -0x7FFFFFFF;
}
private:
//--------------------------------------------------------------------
int read_int32()
{
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
//--------------------------------------------------------------------
unsigned read_int32u()
{
int32u val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
public:
// Iterate scanlines interface
//--------------------------------------------------------------------
bool rewind_scanlines()
{
m_ptr = m_data;
if(m_ptr < m_end)
{
m_min_x = read_int32() + m_dx;
m_min_y = read_int32() + m_dy;
m_max_x = read_int32() + m_dx;
m_max_y = read_int32() + m_dy;
}
return m_ptr < m_end;
}
//--------------------------------------------------------------------
int min_x() const { return m_min_x; }
int min_y() const { return m_min_y; }
int max_x() const { return m_max_x; }
int max_y() const { return m_max_y; }
//--------------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
sl.reset_spans();
for(;;)
{
if(m_ptr >= m_end) return false;
read_int32(); // Skip scanline size in bytes
int y = read_int32() + m_dy;
unsigned num_spans = read_int32();
do
{
int x = read_int32() + m_dx;
int len = read_int32();
if(len < 0)
{
sl.add_span(x, unsigned(-len), *m_ptr);
m_ptr += sizeof(T);
}
else
{
sl.add_cells(x, len, m_ptr);
m_ptr += len * sizeof(T);
}
}
while(--num_spans);
if(sl.num_spans())
{
sl.finalize(y);
break;
}
}
return true;
}
//--------------------------------------------------------------------
// Specialization for embedded_scanline
bool sweep_scanline(embedded_scanline& sl)
{
do
{
if(m_ptr >= m_end) return false;
unsigned byte_size = read_int32u();
sl.init(m_ptr, m_dx, m_dy);
m_ptr += byte_size - sizeof(int32);
}
while(sl.num_spans() == 0);
return true;
}
private:
const int8u* m_data;
const int8u* m_end;
const int8u* m_ptr;
int m_dx;
int m_dy;
int m_min_x;
int m_min_y;
int m_max_x;
int m_max_y;
};
typedef serialized_scanlines_adaptor_aa<int8u> serialized_scanlines_adaptor_aa8; //----serialized_scanlines_adaptor_aa8
typedef serialized_scanlines_adaptor_aa<int16u> serialized_scanlines_adaptor_aa16; //----serialized_scanlines_adaptor_aa16
typedef serialized_scanlines_adaptor_aa<int32u> serialized_scanlines_adaptor_aa32; //----serialized_scanlines_adaptor_aa32
}
#endif

View file

@ -0,0 +1,586 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
#define AGG_SCANLINE_STORAGE_BIN_INCLUDED
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "agg_array.h"
namespace agg
{
//-----------------------------------------------scanline_storage_bin
class scanline_storage_bin
{
public:
//---------------------------------------------------------------
struct span_data
{
int32 x;
int32 len;
};
//---------------------------------------------------------------
struct scanline_data
{
int y;
unsigned num_spans;
unsigned start_span;
};
//---------------------------------------------------------------
class embedded_scanline
{
public:
//-----------------------------------------------------------
class const_iterator
{
public:
const_iterator() : m_storage(0) {}
const_iterator(const embedded_scanline& sl) :
m_storage(sl.m_storage),
m_span_idx(sl.m_scanline.start_span)
{
m_span = m_storage->span_by_index(m_span_idx);
}
const span_data& operator*() const { return m_span; }
const span_data* operator->() const { return &m_span; }
void operator ++ ()
{
++m_span_idx;
m_span = m_storage->span_by_index(m_span_idx);
}
private:
const scanline_storage_bin* m_storage;
unsigned m_span_idx;
span_data m_span;
};
friend class const_iterator;
//-----------------------------------------------------------
embedded_scanline(const scanline_storage_bin& storage) :
m_storage(&storage)
{
setup(0);
}
//-----------------------------------------------------------
void reset(int, int) {}
unsigned num_spans() const { return m_scanline.num_spans; }
int y() const { return m_scanline.y; }
const_iterator begin() const { return const_iterator(*this); }
//-----------------------------------------------------------
void setup(unsigned scanline_idx)
{
m_scanline_idx = scanline_idx;
m_scanline = m_storage->scanline_by_index(m_scanline_idx);
}
private:
const scanline_storage_bin* m_storage;
scanline_data m_scanline;
unsigned m_scanline_idx;
};
//---------------------------------------------------------------
scanline_storage_bin() :
m_spans(256-2), // Block increment size
m_scanlines(),
m_min_x( 0x7FFFFFFF),
m_min_y( 0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF),
m_cur_scanline(0)
{
m_fake_scanline.y = 0;
m_fake_scanline.num_spans = 0;
m_fake_scanline.start_span = 0;
m_fake_span.x = 0;
m_fake_span.len = 0;
}
// Renderer Interface
//---------------------------------------------------------------
void prepare()
{
m_scanlines.remove_all();
m_spans.remove_all();
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
m_max_y = -0x7FFFFFFF;
m_cur_scanline = 0;
}
//---------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
scanline_data sl_this;
int y = sl.y();
if(y < m_min_y) m_min_y = y;
if(y > m_max_y) m_max_y = y;
sl_this.y = y;
sl_this.num_spans = sl.num_spans();
sl_this.start_span = m_spans.size();
typename Scanline::const_iterator span_iterator = sl.begin();
unsigned num_spans = sl_this.num_spans;
for(;;)
{
span_data sp;
sp.x = span_iterator->x;
sp.len = (int32)abs((int)(span_iterator->len));
m_spans.add(sp);
int x1 = sp.x;
int x2 = sp.x + sp.len - 1;
if(x1 < m_min_x) m_min_x = x1;
if(x2 > m_max_x) m_max_x = x2;
if(--num_spans == 0) break;
++span_iterator;
}
m_scanlines.add(sl_this);
}
//---------------------------------------------------------------
// Iterate scanlines interface
int min_x() const { return m_min_x; }
int min_y() const { return m_min_y; }
int max_x() const { return m_max_x; }
int max_y() const { return m_max_y; }
//---------------------------------------------------------------
bool rewind_scanlines()
{
m_cur_scanline = 0;
return m_scanlines.size() > 0;
}
//---------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
sl.reset_spans();
for(;;)
{
if(m_cur_scanline >= m_scanlines.size()) return false;
const scanline_data& sl_this = m_scanlines[m_cur_scanline];
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
do
{
const span_data& sp = m_spans[span_idx++];
sl.add_span(sp.x, sp.len, cover_full);
}
while(--num_spans);
++m_cur_scanline;
if(sl.num_spans())
{
sl.finalize(sl_this.y);
break;
}
}
return true;
}
//---------------------------------------------------------------
// Specialization for embedded_scanline
bool sweep_scanline(embedded_scanline& sl)
{
do
{
if(m_cur_scanline >= m_scanlines.size()) return false;
sl.setup(m_cur_scanline);
++m_cur_scanline;
}
while(sl.num_spans() == 0);
return true;
}
//---------------------------------------------------------------
unsigned byte_size() const
{
unsigned i;
unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
for(i = 0; i < m_scanlines.size(); ++i)
{
size += sizeof(int32) * 2 + // Y, num_spans
unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len
}
return size;
}
//---------------------------------------------------------------
static void write_int32(int8u* dst, int32 val)
{
dst[0] = ((const int8u*)&val)[0];
dst[1] = ((const int8u*)&val)[1];
dst[2] = ((const int8u*)&val)[2];
dst[3] = ((const int8u*)&val)[3];
}
//---------------------------------------------------------------
void serialize(int8u* data) const
{
unsigned i;
write_int32(data, min_x()); // min_x
data += sizeof(int32);
write_int32(data, min_y()); // min_y
data += sizeof(int32);
write_int32(data, max_x()); // max_x
data += sizeof(int32);
write_int32(data, max_y()); // max_y
data += sizeof(int32);
for(i = 0; i < m_scanlines.size(); ++i)
{
const scanline_data& sl_this = m_scanlines[i];
write_int32(data, sl_this.y); // Y
data += sizeof(int32);
write_int32(data, sl_this.num_spans); // num_spans
data += sizeof(int32);
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
do
{
const span_data& sp = m_spans[span_idx++];
write_int32(data, sp.x); // X
data += sizeof(int32);
write_int32(data, sp.len); // len
data += sizeof(int32);
}
while(--num_spans);
}
}
//---------------------------------------------------------------
const scanline_data& scanline_by_index(unsigned i) const
{
return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
}
//---------------------------------------------------------------
const span_data& span_by_index(unsigned i) const
{
return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
}
private:
pod_bvector<span_data, 10> m_spans;
pod_bvector<scanline_data, 8> m_scanlines;
span_data m_fake_span;
scanline_data m_fake_scanline;
int m_min_x;
int m_min_y;
int m_max_x;
int m_max_y;
unsigned m_cur_scanline;
};
//---------------------------------------serialized_scanlines_adaptor_bin
class serialized_scanlines_adaptor_bin
{
public:
typedef bool cover_type;
//--------------------------------------------------------------------
class embedded_scanline
{
public:
//----------------------------------------------------------------
class const_iterator
{
public:
struct span
{
int32 x;
int32 len;
};
const_iterator() : m_ptr(0) {}
const_iterator(const embedded_scanline& sl) :
m_ptr(sl.m_ptr),
m_dx(sl.m_dx)
{
m_span.x = read_int32() + m_dx;
m_span.len = read_int32();
}
const span& operator*() const { return m_span; }
const span* operator->() const { return &m_span; }
void operator ++ ()
{
m_span.x = read_int32() + m_dx;
m_span.len = read_int32();
}
private:
int read_int32()
{
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
const int8u* m_ptr;
span m_span;
int m_dx;
};
friend class const_iterator;
//----------------------------------------------------------------
embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
//----------------------------------------------------------------
void reset(int, int) {}
unsigned num_spans() const { return m_num_spans; }
int y() const { return m_y; }
const_iterator begin() const { return const_iterator(*this); }
private:
//----------------------------------------------------------------
int read_int32()
{
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
public:
//----------------------------------------------------------------
void init(const int8u* ptr, int dx, int dy)
{
m_ptr = ptr;
m_y = read_int32() + dy;
m_num_spans = unsigned(read_int32());
m_dx = dx;
}
private:
const int8u* m_ptr;
int m_y;
unsigned m_num_spans;
int m_dx;
};
public:
//--------------------------------------------------------------------
serialized_scanlines_adaptor_bin() :
m_data(0),
m_end(0),
m_ptr(0),
m_dx(0),
m_dy(0),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF)
{}
//--------------------------------------------------------------------
serialized_scanlines_adaptor_bin(const int8u* data, unsigned size,
double dx, double dy) :
m_data(data),
m_end(data + size),
m_ptr(data),
m_dx(iround(dx)),
m_dy(iround(dy)),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
m_max_y(-0x7FFFFFFF)
{}
//--------------------------------------------------------------------
void init(const int8u* data, unsigned size, double dx, double dy)
{
m_data = data;
m_end = data + size;
m_ptr = data;
m_dx = iround(dx);
m_dy = iround(dy);
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
m_max_y = -0x7FFFFFFF;
}
private:
//--------------------------------------------------------------------
int read_int32()
{
int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
((int8u*)&val)[2] = *m_ptr++;
((int8u*)&val)[3] = *m_ptr++;
return val;
}
public:
// Iterate scanlines interface
//--------------------------------------------------------------------
bool rewind_scanlines()
{
m_ptr = m_data;
if(m_ptr < m_end)
{
m_min_x = read_int32() + m_dx;
m_min_y = read_int32() + m_dy;
m_max_x = read_int32() + m_dx;
m_max_y = read_int32() + m_dy;
}
return m_ptr < m_end;
}
//--------------------------------------------------------------------
int min_x() const { return m_min_x; }
int min_y() const { return m_min_y; }
int max_x() const { return m_max_x; }
int max_y() const { return m_max_y; }
//--------------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
sl.reset_spans();
for(;;)
{
if(m_ptr >= m_end) return false;
int y = read_int32() + m_dy;
unsigned num_spans = read_int32();
do
{
int x = read_int32() + m_dx;
int len = read_int32();
if(len < 0) len = -len;
sl.add_span(x, unsigned(len), cover_full);
}
while(--num_spans);
if(sl.num_spans())
{
sl.finalize(y);
break;
}
}
return true;
}
//--------------------------------------------------------------------
// Specialization for embedded_scanline
bool sweep_scanline(embedded_scanline& sl)
{
do
{
if(m_ptr >= m_end) return false;
sl.init(m_ptr, m_dx, m_dy);
// Jump to the next scanline
//--------------------------
read_int32(); // Y
int num_spans = read_int32(); // num_spans
m_ptr += num_spans * sizeof(int32) * 2;
}
while(sl.num_spans() == 0);
return true;
}
private:
const int8u* m_data;
const int8u* m_end;
const int8u* m_ptr;
int m_dx;
int m_dy;
int m_min_x;
int m_min_y;
int m_max_x;
int m_max_y;
};
}
#endif

499
3party/agg/agg_scanline_u.h Normal file
View file

@ -0,0 +1,499 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by
// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
// Liberty Technology Systems, Inc. is the provider of
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_U_INCLUDED
#define AGG_SCANLINE_U_INCLUDED
#include "agg_array.h"
namespace agg
{
//=============================================================scanline_u8
//
// Unpacked scanline container class
//
// This class is used to transfer data from a scanline rasterizer
// to the rendering buffer. It's organized very simple. The class stores
// information of horizontal spans to render it into a pixel-map buffer.
// Each span has staring X, length, and an array of bytes that determine the
// cover-values for each pixel.
// Before using this class you should know the minimal and maximal pixel
// coordinates of your scanline. The protocol of using is:
// 1. reset(min_x, max_x)
// 2. add_cell() / add_span() - accumulate scanline.
// When forming one scanline the next X coordinate must be always greater
// than the last stored one, i.e. it works only with ordered coordinates.
// 3. Call finalize(y) and render the scanline.
// 3. Call reset_spans() to prepare for the new scanline.
//
// 4. Rendering:
//
// Scanline provides an iterator class that allows you to extract
// the spans and the cover values for each pixel. Be aware that clipping
// has not been done yet, so you should perform it yourself.
// Use scanline_u8::iterator to render spans:
//-------------------------------------------------------------------------
//
// int y = sl.y(); // Y-coordinate of the scanline
//
// ************************************
// ...Perform vertical clipping here...
// ************************************
//
// scanline_u8::const_iterator span = sl.begin();
//
// unsigned char* row = m_rbuf->row(y); // The the address of the beginning
// // of the current row
//
// unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that
// // num_spans is always greater than 0.
//
// do
// {
// const scanline_u8::cover_type* covers =
// span->covers; // The array of the cover values
//
// int num_pix = span->len; // Number of pixels of the span.
// // Always greater than 0, still it's
// // better to use "int" instead of
// // "unsigned" because it's more
// // convenient for clipping
// int x = span->x;
//
// **************************************
// ...Perform horizontal clipping here...
// ...you have x, covers, and pix_count..
// **************************************
//
// unsigned char* dst = row + x; // Calculate the start address of the row.
// // In this case we assume a simple
// // grayscale image 1-byte per pixel.
// do
// {
// *dst++ = *covers++; // Hypotetical rendering.
// }
// while(--num_pix);
//
// ++span;
// }
// while(--num_spans); // num_spans cannot be 0, so this loop is quite safe
//------------------------------------------------------------------------
//
// The question is: why should we accumulate the whole scanline when we
// could render just separate spans when they're ready?
// That's because using the scanline is generally faster. When is consists
// of more than one span the conditions for the processor cash system
// are better, because switching between two different areas of memory
// (that can be very large) occurs less frequently.
//------------------------------------------------------------------------
class scanline_u8
{
public:
typedef scanline_u8 self_type;
typedef int8u cover_type;
typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
coord_type x;
coord_type len;
cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
//--------------------------------------------------------------------
scanline_u8() :
m_min_x(0),
m_last_x(0x7FFFFFF0),
m_cur_span(0)
{}
//--------------------------------------------------------------------
void reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 2;
if(max_len > m_spans.size())
{
m_spans.resize(max_len);
m_covers.resize(max_len);
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
void add_cell(int x, unsigned cover)
{
x -= m_min_x;
m_covers[x] = (cover_type)cover;
if(x == m_last_x+1)
{
m_cur_span->len++;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = 1;
m_cur_span->covers = &m_covers[x];
}
m_last_x = x;
}
//--------------------------------------------------------------------
void add_cells(int x, unsigned len, const cover_type* covers)
{
x -= m_min_x;
memcpy(&m_covers[x], covers, len * sizeof(cover_type));
if(x == m_last_x+1)
{
m_cur_span->len += (coord_type)len;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = (coord_type)len;
m_cur_span->covers = &m_covers[x];
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void add_span(int x, unsigned len, unsigned cover)
{
x -= m_min_x;
memset(&m_covers[x], cover, len);
if(x == m_last_x+1)
{
m_cur_span->len += (coord_type)len;
}
else
{
m_cur_span++;
m_cur_span->x = (coord_type)(x + m_min_x);
m_cur_span->len = (coord_type)len;
m_cur_span->covers = &m_covers[x];
}
m_last_x = x + len - 1;
}
//--------------------------------------------------------------------
void finalize(int y)
{
m_y = y;
}
//--------------------------------------------------------------------
void reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = &m_spans[0];
}
//--------------------------------------------------------------------
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
const_iterator begin() const { return &m_spans[1]; }
iterator begin() { return &m_spans[1]; }
private:
scanline_u8(const self_type&);
const self_type& operator = (const self_type&);
private:
int m_min_x;
int m_last_x;
int m_y;
pod_array<cover_type> m_covers;
pod_array<span> m_spans;
span* m_cur_span;
};
//==========================================================scanline_u8_am
//
// The scanline container with alpha-masking
//
//------------------------------------------------------------------------
template<class AlphaMask>
class scanline_u8_am : public scanline_u8
{
public:
typedef scanline_u8 base_type;
typedef AlphaMask alpha_mask_type;
typedef base_type::cover_type cover_type;
typedef base_type::coord_type coord_type;
scanline_u8_am() : base_type(), m_alpha_mask(0) {}
scanline_u8_am(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()
{}
//--------------------------------------------------------------------
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;
};
}
#endif

View file

@ -0,0 +1,66 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_SHORTEN_PATH_INCLUDED
#define AGG_SHORTEN_PATH_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_sequence.h"
namespace agg
{
//===========================================================shorten_path
template<class VertexSequence>
void shorten_path(VertexSequence& vs, double s, unsigned closed = 0)
{
typedef typename VertexSequence::value_type vertex_type;
if(s > 0.0 && vs.size() > 1)
{
double d;
int n = int(vs.size() - 2);
while(n)
{
d = vs[n].dist;
if(d > s) break;
vs.remove_last();
s -= d;
--n;
}
if(vs.size() < 2)
{
vs.remove_all();
}
else
{
n = vs.size() - 1;
vertex_type& prev = vs[n-1];
vertex_type& last = vs[n];
d = (prev.dist - s) / prev.dist;
double x = prev.x + (last.x - prev.x) * d;
double y = prev.y + (last.y - prev.y) * d;
last.x = x;
last.y = y;
if(!prev(last)) vs.remove_last();
vs.close(closed != 0);
}
}
}
}
#endif

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