Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c788763960 | ||
|
|
215957b549 | ||
|
|
c5549f3d04 |
121
.clang-format
@@ -1,121 +0,0 @@
|
||||
#
|
||||
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
#
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- forever
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^<Q.*'
|
||||
Priority: 200
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
#KeepLineBreaksForNonEmptyLines: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 150
|
||||
PenaltyBreakBeforeFirstCallParameter: 300
|
||||
PenaltyBreakComment: 500
|
||||
PenaltyBreakFirstLessLess: 400
|
||||
PenaltyBreakString: 600
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 50
|
||||
PenaltyReturnTypeOnItsOwnLine: 300
|
||||
PenaltyIndentedWhitespace: 10
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: false
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
|
||||
54
.gitignore
vendored
@@ -1,24 +1,32 @@
|
||||
Build
|
||||
Build.bat
|
||||
/build/
|
||||
MYMETA.json
|
||||
MYMETA.yml
|
||||
_build
|
||||
blib
|
||||
xs/buildtmp
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
MANIFEST.bak
|
||||
xs/MANIFEST.bak
|
||||
xs/assertlib*
|
||||
.init_bundle.ini
|
||||
.vs/*
|
||||
/src/TAGS
|
||||
/.vscode/
|
||||
build-linux/*
|
||||
deps/build*
|
||||
deps/build-linux/*
|
||||
**/.DS_Store
|
||||
**/.idea/
|
||||
.pkg_cache
|
||||
CMakeUserPresets.json
|
||||
/src/slic3r/QIDI
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
644
CMakeLists.txt
@@ -1,644 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(QIDISlicer)
|
||||
|
||||
include("version.inc")
|
||||
include(GNUInstallDirs)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
set(SLIC3R_RESOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/resources")
|
||||
file(TO_NATIVE_PATH "${SLIC3R_RESOURCES_DIR}" SLIC3R_RESOURCES_DIR_WIN)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "No build type selected, default to Release")
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (default Release)" FORCE)
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{SLIC3R_STATIC})
|
||||
set(SLIC3R_STATIC_INITIAL $ENV{SLIC3R_STATIC})
|
||||
else()
|
||||
if (MSVC OR MINGW OR APPLE)
|
||||
set(SLIC3R_STATIC_INITIAL 1)
|
||||
else()
|
||||
set(SLIC3R_STATIC_INITIAL 0)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(SLIC3R_STATIC "Compile QIDISlicer with static libraries (Boost, TBB, glew)" ${SLIC3R_STATIC_INITIAL})
|
||||
option(SLIC3R_GUI "Compile QIDISlicer with GUI components (OpenGL, wxWidgets)" 1)
|
||||
option(SLIC3R_FHS "Assume QIDISlicer is to be installed in a FHS directory structure" 0)
|
||||
option(SLIC3R_PCH "Use precompiled headers" 1)
|
||||
option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
|
||||
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
|
||||
option(SLIC3R_UBSAN "Enable UBSan on Clang and GCC" 0)
|
||||
option(SLIC3R_ENABLE_FORMAT_STEP "Enable compilation of STEP file support" ON)
|
||||
option(SLIC3R_LOG_TO_FILE "Enable logging into file")
|
||||
option(SLIC3R_REPO_URL "Preset repo URL")
|
||||
|
||||
# SLIC3R_OPENGL_ES can be enabled only if SLIC3R_GUI is enabled.
|
||||
CMAKE_DEPENDENT_OPTION(SLIC3R_OPENGL_ES "Compile QIDISlicer targeting OpenGL ES" OFF "SLIC3R_GUI" OFF)
|
||||
|
||||
# If SLIC3R_FHS is 1 -> SLIC3R_DESKTOP_INTEGRATION is always 0, otherwise variable.
|
||||
CMAKE_DEPENDENT_OPTION(SLIC3R_DESKTOP_INTEGRATION "Allow perfoming desktop integration during runtime" 1 "NOT SLIC3R_FHS" 0)
|
||||
|
||||
set(OPENVDB_FIND_MODULE_PATH "" CACHE PATH "Path to OpenVDB installation's find modules.")
|
||||
|
||||
set(SLIC3R_GTK "2" CACHE STRING "GTK version to use with wxWidgets on Linux")
|
||||
|
||||
set(IS_CROSS_COMPILE FALSE)
|
||||
|
||||
if (SLIC3R_STATIC)
|
||||
# Prefer config scripts over find modules. This is helpful when building with
|
||||
# the static dependencies. Many libraries have their own export scripts
|
||||
# while having a Find<PkgName> module in standard cmake installation.
|
||||
# (e.g. CURL)
|
||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
|
||||
endif ()
|
||||
|
||||
# Dependency build management
|
||||
option(${PROJECT_NAME}_BUILD_DEPS "Build dependencies before the project" OFF)
|
||||
option(${PROJECT_NAME}_DEPS_OUTPUT_QUIET "Don't print build output for dependencies" OFF)
|
||||
set(${PROJECT_NAME}_DEPS_PRESET "default" CACHE STRING "Preset of the dependencies when ${PROJECT_NAME}_BUILD_DEPS is ON")
|
||||
set(${PROJECT_NAME}_DEPS_BUILD_DIR "" CACHE PATH "Binary dir of the dependencies build when ${PROJECT_NAME}_BUILD_DEPS is ON")
|
||||
if (${PROJECT_NAME}_BUILD_DEPS)
|
||||
include(deps/autobuild.cmake)
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
set(CMAKE_FIND_FRAMEWORK LAST)
|
||||
set(CMAKE_FIND_APPBUNDLE LAST)
|
||||
list(FIND CMAKE_OSX_ARCHITECTURES ${CMAKE_SYSTEM_PROCESSOR} _arch_idx)
|
||||
if (CMAKE_OSX_ARCHITECTURES AND _arch_idx LESS 0)
|
||||
set(IS_CROSS_COMPILE TRUE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
option(SLIC3R_BUILD_SANDBOXES "Build development sandboxes" OFF)
|
||||
option(SLIC3R_BUILD_TESTS "Build unit tests" ON)
|
||||
|
||||
if (IS_CROSS_COMPILE)
|
||||
message("Detected cross compilation setup. Tests and encoding checks will be forcedly disabled!")
|
||||
set(SLIC3R_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
endif ()
|
||||
|
||||
# Print out the SLIC3R_* cache options
|
||||
get_cmake_property(_cache_vars CACHE_VARIABLES)
|
||||
list (SORT _cache_vars)
|
||||
foreach (_cache_var ${_cache_vars})
|
||||
if("${_cache_var}" MATCHES "^SLIC3R_")
|
||||
message(STATUS "${_cache_var}: ${${_cache_var}}")
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
if (SLIC3R_LOG_TO_FILE)
|
||||
add_definitions(-DSLIC3R_LOG_TO_FILE)
|
||||
endif ()
|
||||
if (SLIC3R_REPO_URL)
|
||||
add_definitions(-DSLIC3R_REPO_URL="${SLIC3R_REPO_URL}")
|
||||
endif()
|
||||
if (SLIC3R_GUI)
|
||||
add_definitions(-DSLIC3R_GUI)
|
||||
endif ()
|
||||
|
||||
if (SLIC3R_OPENGL_ES)
|
||||
add_definitions(-DSLIC3R_OPENGL_ES)
|
||||
endif()
|
||||
|
||||
if(SLIC3R_DESKTOP_INTEGRATION)
|
||||
add_definitions(-DSLIC3R_DESKTOP_INTEGRATION)
|
||||
endif ()
|
||||
|
||||
if (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
set(IS_CLANG_CL TRUE)
|
||||
|
||||
# clang-cl can interpret SYSTEM header paths if -imsvc is used
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-imsvc")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall \
|
||||
-Wno-old-style-cast -Wno-reserved-id-macro -Wno-c++98-compat-pedantic")
|
||||
else ()
|
||||
set(IS_CLANG_CL FALSE)
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
if (SLIC3R_MSVC_COMPILE_PARALLEL AND NOT IS_CLANG_CL)
|
||||
add_compile_options(/MP)
|
||||
endif ()
|
||||
# /bigobj (Increase Number of Sections in .Obj file)
|
||||
# error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of '-Zm90' or greater
|
||||
# Generate symbols at every build target, even for the release.
|
||||
add_compile_options(-bigobj -Zm520 /Zi)
|
||||
# Disable STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17.
|
||||
#FIXME Remove this line after eigen library adapts to the new C++17 adaptor rules.
|
||||
add_compile_options(-D_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING)
|
||||
# Disable warnings on conversion from unsigned to signed (possible loss of data)
|
||||
# C4244: 'conversion' conversion from 'type1' to 'type2', possible loss of data. An integer type is converted to a smaller integer type.
|
||||
# C4267: The compiler detected a conversion from size_t to a smaller type.
|
||||
add_compile_options(/wd4244 /wd4267)
|
||||
# Enforce strict C++ conformance, so our code that compiles on MSVC also compiles on GCC and clang.
|
||||
add_compile_options(/permissive-)
|
||||
endif ()
|
||||
|
||||
if (MINGW)
|
||||
add_compile_options(-Wa,-mbig-obj)
|
||||
endif ()
|
||||
|
||||
if (NOT MSVC)
|
||||
# ARMs (Raspberry PI) use an unsigned char by default. Let's make it consistent for QIDISlicer on all platforms.
|
||||
add_compile_options(-fsigned-char)
|
||||
endif ()
|
||||
|
||||
# Display and check CMAKE_PREFIX_PATH
|
||||
message(STATUS "SLIC3R_STATIC: ${SLIC3R_STATIC}")
|
||||
if (NOT "${CMAKE_PREFIX_PATH}" STREQUAL "")
|
||||
message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH} (from cache or command line)")
|
||||
set(PREFIX_PATH_CHECK ${CMAKE_PREFIX_PATH})
|
||||
elseif (NOT "$ENV{CMAKE_PREFIX_PATH}" STREQUAL "")
|
||||
message(STATUS "CMAKE_PREFIX_PATH: $ENV{CMAKE_PREFIX_PATH} (from environment)")
|
||||
set(PREFIX_PATH_CHECK $ENV{CMAKE_PREFIX_PATH})
|
||||
else ()
|
||||
message(STATUS "CMAKE_PREFIX_PATH: (default)")
|
||||
endif ()
|
||||
|
||||
foreach (DIR ${PREFIX_PATH_CHECK})
|
||||
if (NOT EXISTS "${DIR}")
|
||||
message(WARNING "CMAKE_PREFIX_PATH element doesn't exist: ${DIR}")
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# Add our own cmake module path.
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules/)
|
||||
|
||||
enable_testing ()
|
||||
|
||||
# Enable C++17 language standard.
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(NOT WIN32)
|
||||
# Add DEBUG flags to debug builds.
|
||||
add_compile_options("$<$<CONFIG:DEBUG>:-DDEBUG>")
|
||||
endif()
|
||||
|
||||
# WIN10SDK_PATH is used to point CMake to the WIN10 SDK installation directory.
|
||||
# We pick it from environment if it is not defined in another way
|
||||
if(WIN32)
|
||||
if(NOT DEFINED WIN10SDK_PATH)
|
||||
if(DEFINED ENV{WIN10SDK_PATH})
|
||||
set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}")
|
||||
endif()
|
||||
endif()
|
||||
if(DEFINED WIN10SDK_PATH)
|
||||
if (EXISTS "${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h")
|
||||
set(WIN10SDK_INCLUDE_PATH "${WIN10SDK_PATH}/Include")
|
||||
else()
|
||||
message("WIN10SDK_PATH is invalid: ${WIN10SDK_PATH}")
|
||||
message("${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h was not found")
|
||||
message("STL fixing by WinSDK will not be compiled")
|
||||
unset(WIN10SDK_PATH)
|
||||
endif()
|
||||
else()
|
||||
# Try to use the default Windows 10 SDK path.
|
||||
set(WIN10SDK_INCLUDE_PATH "$ENV{WindowsSdkDir}/Include/$ENV{WindowsSDKVersion}")
|
||||
if (NOT EXISTS "${WIN10SDK_INCLUDE_PATH}/winrt/windows.graphics.printing3d.h")
|
||||
message("${WIN10SDK_INCLUDE_PATH}/winrt/windows.graphics.printing3d.h was not found")
|
||||
message("STL fixing by WinSDK will not be compiled")
|
||||
unset(WIN10SDK_INCLUDE_PATH)
|
||||
endif()
|
||||
endif()
|
||||
if(WIN10SDK_INCLUDE_PATH)
|
||||
message("Building with Win10 STL fixing service support")
|
||||
add_definitions(-DHAS_WIN10SDK)
|
||||
include_directories("${WIN10SDK_INCLUDE_PATH}")
|
||||
else()
|
||||
message("Building without Win10 STL fixing service support")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
message("OS X SDK Path: ${CMAKE_OSX_SYSROOT}")
|
||||
if (CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
message("OS X Deployment Target: ${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
else ()
|
||||
message("OS X Deployment Target: (default)")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS "3.1")
|
||||
# Workaround for an old CMake, which does not understand CMAKE_CXX_STANDARD.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
|
||||
# Boost on Raspberry-Pi does not link to pthreads.
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(DBus1 REQUIRED)
|
||||
endif()
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX)
|
||||
# Adding -fext-numeric-literals to enable GCC extensions on definitions of quad float literals, which are required by Boost.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals" )
|
||||
endif()
|
||||
|
||||
if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
|
||||
if (NOT MINGW)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
|
||||
endif ()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder" )
|
||||
|
||||
# On GCC and Clang, no return from a non-void function is a warning only. Here, we make it an error.
|
||||
add_compile_options(-Werror=return-type)
|
||||
|
||||
# removes LOTS of extraneous Eigen warnings (GCC only supports it since 6.1)
|
||||
# https://eigen.tuxfamily.org/bz/show_bug.cgi?id=1221
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
|
||||
add_compile_options(-Wno-ignored-attributes) # Tamas: Eigen include dirs are marked as SYSTEM
|
||||
endif()
|
||||
|
||||
# Clang reports legacy OpenGL calls as deprecated. Turn off the warning for now
|
||||
# to reduce the clutter, we know about this one. It should be reenabled after
|
||||
# we finally get rid of the deprecated code.
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
add_compile_options(-Wno-deprecated-declarations)
|
||||
endif()
|
||||
|
||||
# Clang reports misleading indentation for some IF blocks because of mixing tabs with spaces.
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
add_compile_options(-Wno-misleading-indentation)
|
||||
endif()
|
||||
|
||||
#GCC generates loads of -Wunknown-pragmas when compiling igl. The fix is not easy due to a bug in gcc, see
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66943 or
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431
|
||||
# We will turn the warning of for GCC for now:
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
add_compile_options(-Wno-unknown-pragmas)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if (SLIC3R_ASAN)
|
||||
# ASAN should be available on MSVC starting with Visual Studio 2019 16.9
|
||||
# https://devblogs.microsoft.com/cppblog/address-sanitizer-for-msvc-now-generally-available/
|
||||
add_compile_options(-fsanitize=address)
|
||||
|
||||
if (NOT MSVC)
|
||||
add_compile_options(-fno-omit-frame-pointer)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address")
|
||||
endif ()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (SLIC3R_UBSAN)
|
||||
# Stacktrace for every report is enabled by default. It can be disabled by running QIDISlicer with "UBSAN_OPTIONS=print_stacktrace=0".
|
||||
|
||||
# Define macro SLIC3R_UBSAN to allow detection in the source code if this sanitizer is enabled.
|
||||
add_compile_definitions(SLIC3R_UBSAN)
|
||||
|
||||
# Clang supports much more useful checks than GCC, so when Clang is detected, another checks will be enabled.
|
||||
# List of what GCC is checking: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
|
||||
# List of what Clang is checking: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(_ubsan_flags "-fsanitize=undefined,integer")
|
||||
else ()
|
||||
set(_ubsan_flags "-fsanitize=undefined")
|
||||
endif ()
|
||||
|
||||
add_compile_options(${_ubsan_flags} -fno-omit-frame-pointer)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_ubsan_flags}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_ubsan_flags}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${_ubsan_flags}")
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lubsan")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
|
||||
endif ()
|
||||
|
||||
set(LIBDIR_BIN ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
# For generated header files
|
||||
include_directories(${LIBDIR_BIN}/platform)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
|
||||
if(MSVC)
|
||||
# BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking.
|
||||
add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x601 -DBOOST_SYSTEM_USE_UTF8 )
|
||||
# Force the source code encoding to UTF-8. See QIDISlicer GH pull request #5583
|
||||
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
||||
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
||||
endif(MSVC)
|
||||
endif(WIN32)
|
||||
|
||||
add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE -DWXINTL_NO_GETTEXT_MACRO)
|
||||
|
||||
# Disable unsafe implicit wxString to const char* / std::string and vice versa. This implicit conversion breaks the UTF-8 encoding quite often.
|
||||
add_definitions(-DwxNO_UNSAFE_WXSTRING_CONV)
|
||||
|
||||
# Find and configure boost
|
||||
if(SLIC3R_STATIC)
|
||||
# Use static boost libraries.
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
# Use boost libraries linked statically to the C++ runtime.
|
||||
# set(Boost_USE_STATIC_RUNTIME ON)
|
||||
endif()
|
||||
#set(Boost_DEBUG ON)
|
||||
# set(Boost_COMPILER "-mgw81")
|
||||
# boost::process was introduced first in version 1.64.0,
|
||||
# boost::beast::detail::base64 was introduced first in version 1.66.0
|
||||
set(MINIMUM_BOOST_VERSION "1.83.0")
|
||||
set(_boost_components "system;filesystem;thread;log;locale;regex;chrono;atomic;date_time;iostreams;nowide")
|
||||
find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS ${_boost_components})
|
||||
|
||||
find_package(Eigen3 3.3.7 REQUIRED)
|
||||
|
||||
add_library(boost_libs INTERFACE)
|
||||
add_library(boost_headeronly INTERFACE)
|
||||
|
||||
if (APPLE)
|
||||
# BOOST_ASIO_DISABLE_KQUEUE : prevents a Boost ASIO bug on OS X: https://svn.boost.org/trac/boost/ticket/5339
|
||||
target_compile_definitions(boost_headeronly INTERFACE BOOST_ASIO_DISABLE_KQUEUE)
|
||||
endif()
|
||||
|
||||
if(NOT SLIC3R_STATIC)
|
||||
target_compile_definitions(boost_headeronly INTERFACE BOOST_LOG_DYN_LINK)
|
||||
endif()
|
||||
|
||||
function(slic3r_remap_configs targets from_Cfg to_Cfg)
|
||||
if(MSVC)
|
||||
string(TOUPPER ${from_Cfg} from_CFG)
|
||||
|
||||
foreach(tgt ${targets})
|
||||
if(TARGET ${tgt})
|
||||
set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if(TARGET Boost::system)
|
||||
message(STATUS "Boost::boost exists")
|
||||
target_link_libraries(boost_headeronly INTERFACE Boost::boost)
|
||||
|
||||
# Only from cmake 3.12
|
||||
# list(TRANSFORM _boost_components PREPEND Boost:: OUTPUT_VARIABLE _boost_targets)
|
||||
set(_boost_targets "")
|
||||
foreach(comp ${_boost_components})
|
||||
list(APPEND _boost_targets "Boost::${comp}")
|
||||
endforeach()
|
||||
|
||||
target_link_libraries(boost_libs INTERFACE
|
||||
boost_headeronly # includes the custom compile definitions as well
|
||||
${_boost_targets}
|
||||
)
|
||||
slic3r_remap_configs("${_boost_targets}" RelWithDebInfo Release)
|
||||
else()
|
||||
target_include_directories(boost_headeronly INTERFACE ${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(boost_libs INTERFACE boost_headeronly ${Boost_LIBRARIES})
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# Find and configure intel-tbb
|
||||
if(SLIC3R_STATIC)
|
||||
set(TBB_STATIC 1)
|
||||
endif()
|
||||
set(TBB_DEBUG 1)
|
||||
find_package(TBB REQUIRED)
|
||||
slic3r_remap_configs(TBB::tbb RelWithDebInfo Release)
|
||||
slic3r_remap_configs(TBB::tbbmalloc RelWithDebInfo Release)
|
||||
# include_directories(${TBB_INCLUDE_DIRS})
|
||||
# add_definitions(${TBB_DEFINITIONS})
|
||||
# if(MSVC)
|
||||
# # Suppress implicit linking of the TBB libraries by the Visual Studio compiler.
|
||||
# add_definitions(-D__TBB_NO_IMPLICIT_LINKAGE)
|
||||
# endif()
|
||||
# The Intel TBB library will use the std::exception_ptr feature of C++11.
|
||||
# add_definitions(-DTBB_USE_CAPTURED_EXCEPTION=0)
|
||||
|
||||
find_package(CURL REQUIRED)
|
||||
|
||||
add_library(libcurl INTERFACE)
|
||||
target_link_libraries(libcurl INTERFACE CURL::libcurl)
|
||||
|
||||
# Fixing curl's cmake config script bugs
|
||||
if (NOT WIN32)
|
||||
# Required by libcurl
|
||||
find_package(ZLIB REQUIRED)
|
||||
target_link_libraries(libcurl INTERFACE ZLIB::ZLIB)
|
||||
else()
|
||||
target_link_libraries(libcurl INTERFACE crypt32)
|
||||
endif()
|
||||
|
||||
## OPTIONAL packages
|
||||
|
||||
# Find expat. We have our overriden FindEXPAT which exports libexpat target
|
||||
# no matter what.
|
||||
find_package(EXPAT REQUIRED)
|
||||
|
||||
add_library(libexpat INTERFACE)
|
||||
|
||||
if (TARGET EXPAT::EXPAT ) # found by a newer Find script
|
||||
target_link_libraries(libexpat INTERFACE EXPAT::EXPAT)
|
||||
elseif(TARGET expat::expat) # found by a config script
|
||||
target_link_libraries(libexpat INTERFACE expat::expat)
|
||||
else() # found by an older Find script
|
||||
target_link_libraries(libexpat INTERFACE ${EXPAT_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
set(OpenGL_GL_PREFERENCE "LEGACY")
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
# Find glew or use bundled version
|
||||
if (SLIC3R_STATIC AND NOT SLIC3R_STATIC_EXCLUDE_GLEW)
|
||||
set(GLEW_USE_STATIC_LIBS ON)
|
||||
set(GLEW_VERBOSE ON)
|
||||
endif()
|
||||
|
||||
find_package(GLEW REQUIRED)
|
||||
|
||||
# Find the Cereal serialization library
|
||||
find_package(cereal REQUIRED)
|
||||
add_library(libcereal INTERFACE)
|
||||
if (NOT TARGET cereal::cereal)
|
||||
target_link_libraries(libcereal INTERFACE cereal)
|
||||
else()
|
||||
target_link_libraries(libcereal INTERFACE cereal::cereal)
|
||||
endif()
|
||||
|
||||
# l10n
|
||||
set(L10N_DIR "${SLIC3R_RESOURCES_DIR}/localization")
|
||||
add_custom_target(gettext_make_pot
|
||||
COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --debug --boost
|
||||
-f "${L10N_DIR}/list.txt"
|
||||
-o "${L10N_DIR}/QIDISlicer.pot"
|
||||
COMMAND hintsToPot ${SLIC3R_RESOURCES_DIR} ${L10N_DIR}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
COMMENT "Generate pot file from strings in the source tree"
|
||||
)
|
||||
|
||||
add_custom_target(gettext_merge_community_po_with_pot
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
COMMENT "Merge community po with new generated pot file"
|
||||
)
|
||||
file(GLOB L10N_PO_FILES "${L10N_DIR}/*/QIDISlicer*.po")
|
||||
# list of names of directories, which are licalized by PS internally
|
||||
list(APPEND PS_L10N_DIRS "cs" "de" "es" "fr" "it" "ja" "pl")
|
||||
foreach(po_file ${L10N_PO_FILES})
|
||||
GET_FILENAME_COMPONENT(po_dir "${po_file}" DIRECTORY)
|
||||
GET_FILENAME_COMPONENT(po_dir_name "${po_dir}" NAME)
|
||||
list(FIND PS_L10N_DIRS ${po_dir_name} found_dir_id)
|
||||
# found_dir_id==-1 means that po_dir_name wasn't found in PS_L10N_DIRS
|
||||
if(found_dir_id LESS 0)
|
||||
add_custom_command(
|
||||
TARGET gettext_merge_community_po_with_pot PRE_BUILD
|
||||
COMMAND msgmerge -N -o ${po_file} ${po_file} "${L10N_DIR}/QIDISlicer.pot"
|
||||
# delete obsolete lines from resulting PO to avoid conflicts after a merging of it with wxWidgets.po
|
||||
COMMAND msgattrib --no-obsolete -o ${po_file} ${po_file}
|
||||
DEPENDS ${po_file}
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_custom_target(gettext_concat_wx_po_with_po
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
COMMENT "Concatenate and merge wxWidgets localization po with QIDISlicer po file"
|
||||
)
|
||||
file(GLOB L10N_PO_FILES "${L10N_DIR}/*/QIDISlicer*.po")
|
||||
foreach(po_file ${L10N_PO_FILES})
|
||||
GET_FILENAME_COMPONENT(po_dir "${po_file}" DIRECTORY)
|
||||
GET_FILENAME_COMPONENT(po_dir_name "${po_dir}" NAME)
|
||||
SET(wx_po_file "${L10N_DIR}/wx_locale/${po_dir_name}.po")
|
||||
#SET(po_new_file "${po_dir}/QIDISlicer_.po")
|
||||
add_custom_command(
|
||||
TARGET gettext_concat_wx_po_with_po PRE_BUILD
|
||||
COMMAND msgcat --use-first -o ${po_file} ${po_file} ${wx_po_file}
|
||||
# delete obsolete lines from resulting PO
|
||||
COMMAND msgattrib --no-obsolete -o ${po_file} ${po_file}
|
||||
DEPENDS ${po_file}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
add_custom_target(gettext_po_to_mo
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
COMMENT "Generate localization mo files (binary) from po files (texts)"
|
||||
)
|
||||
file(GLOB L10N_PO_FILES "${L10N_DIR}/*/QIDISlicer*.po")
|
||||
foreach(po_file ${L10N_PO_FILES})
|
||||
GET_FILENAME_COMPONENT(po_dir "${po_file}" DIRECTORY)
|
||||
SET(mo_file "${po_dir}/QIDISlicer.mo")
|
||||
add_custom_command(
|
||||
TARGET gettext_po_to_mo PRE_BUILD
|
||||
COMMAND msgfmt ARGS --check-format -o ${mo_file} ${po_file}
|
||||
#COMMAND msgfmt ARGS --check-compatibility -o ${mo_file} ${po_file}
|
||||
DEPENDS ${po_file}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
find_package(NLopt 1.4 REQUIRED)
|
||||
slic3r_remap_configs(NLopt::nlopt RelWithDebInfo Release)
|
||||
|
||||
if(SLIC3R_STATIC)
|
||||
set(OPENVDB_USE_STATIC_LIBS ON)
|
||||
set(USE_BLOSC TRUE)
|
||||
endif ()
|
||||
|
||||
find_package(OpenVDB 5.0 COMPONENTS openvdb)
|
||||
if(OpenVDB_FOUND)
|
||||
slic3r_remap_configs(IlmBase::Half RelWithDebInfo Release)
|
||||
slic3r_remap_configs(Blosc::blosc RelWithDebInfo Release)
|
||||
else ()
|
||||
message(FATAL_ERROR "OpenVDB could not be found with the bundled find module. "
|
||||
"You can try to specify the find module location of your "
|
||||
"OpenVDB installation with the OPENVDB_FIND_MODULE_PATH cache variable.")
|
||||
endif ()
|
||||
|
||||
set(TOP_LEVEL_PROJECT_DIR ${PROJECT_SOURCE_DIR})
|
||||
function(qidislicer_copy_dlls target)
|
||||
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(_bits 64)
|
||||
elseif ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
|
||||
set(_bits 32)
|
||||
endif ()
|
||||
|
||||
get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
get_target_property(_alt_out_dir ${target} RUNTIME_OUTPUT_DIRECTORY)
|
||||
|
||||
if (_alt_out_dir)
|
||||
set (_out_dir "${_alt_out_dir}")
|
||||
elseif (_is_multi)
|
||||
set (_out_dir "$<TARGET_PROPERTY:${target},BINARY_DIR>/$<CONFIG>")
|
||||
else ()
|
||||
set (_out_dir "$<TARGET_PROPERTY:${target},BINARY_DIR>")
|
||||
endif ()
|
||||
|
||||
# This has to be a separate target due to the windows command line lenght limits
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${TOP_LEVEL_PROJECT_DIR}/deps/+GMP/gmp/lib/win${_bits}/libgmp-10.dll ${_out_dir}
|
||||
COMMENT "Copy gmp runtime to build tree"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${TOP_LEVEL_PROJECT_DIR}/deps/+MPFR/mpfr/lib/win${_bits}/libmpfr-4.dll ${_out_dir}
|
||||
COMMENT "Copy mpfr runtime to build tree"
|
||||
VERBATIM)
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(build-utils)
|
||||
add_subdirectory(bundled_deps)
|
||||
# libslic3r, QIDISlicer GUI and the QIDISlicer executable.
|
||||
add_subdirectory(src)
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT QIDISlicer_app_console)
|
||||
|
||||
add_dependencies(gettext_make_pot hintsToPot)
|
||||
|
||||
if(SLIC3R_BUILD_SANDBOXES)
|
||||
add_subdirectory(sandboxes)
|
||||
endif()
|
||||
|
||||
if(SLIC3R_BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
|
||||
if (WIN32)
|
||||
install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources")
|
||||
elseif (SLIC3R_FHS)
|
||||
# CMAKE_INSTALL_FULL_DATAROOTDIR: read-only architecture-independent data root (share)
|
||||
set(SLIC3R_FHS_RESOURCES "${CMAKE_INSTALL_FULL_DATAROOTDIR}/QIDISlicer")
|
||||
install(DIRECTORY ${SLIC3R_RESOURCES_DIR}/ DESTINATION ${SLIC3R_FHS_RESOURCES}
|
||||
PATTERN "*/udev" EXCLUDE
|
||||
)
|
||||
install(FILES src/platform/unix/QIDISlicer.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
|
||||
install(FILES src/platform/unix/QIDIGcodeviewer.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
|
||||
foreach(SIZE 32 128 192)
|
||||
install(FILES ${SLIC3R_RESOURCES_DIR}/icons/QIDISlicer_${SIZE}px.png
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}x${SIZE}/apps RENAME QIDISlicer.png
|
||||
)
|
||||
install(FILES ${SLIC3R_RESOURCES_DIR}/icons/QIDISlicer-gcodeviewer_${SIZE}px.png
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}x${SIZE}/apps RENAME QIDISlicer-gcodeviewer.png
|
||||
)
|
||||
endforeach()
|
||||
install(DIRECTORY ${SLIC3R_RESOURCES_DIR}/udev/ DESTINATION lib/udev/rules.d)
|
||||
target_compile_definitions(QIDISlicer PUBLIC SLIC3R_FHS SLIC3R_FHS_RESOURCES="${SLIC3R_FHS_RESOURCES}")
|
||||
else ()
|
||||
install(FILES src/platform/unix/QIDISlicer.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/resources/applications)
|
||||
install(FILES src/platform/unix/QIDIGcodeviewer.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/resources/applications)
|
||||
install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources")
|
||||
endif ()
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"displayName": "Default Config",
|
||||
"description": "Building with statically linked dependencies",
|
||||
"binaryDir": "${sourceDir}/build-default",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"SLIC3R_STATIC": true,
|
||||
"SLIC3R_GTK": "3",
|
||||
"SLIC3R_ENC_CHECK": false,
|
||||
"SLIC3R_PCH": true,
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build-default/dist",
|
||||
"QIDISlicer_DEPS_PRESET": "default",
|
||||
"QIDISlicer_DEPS_OUTPUT_QUIET": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "no-occt",
|
||||
"displayName": "Without STEP",
|
||||
"description": "Building with statically linked dependencies without STEP file support",
|
||||
"inherits": "default",
|
||||
"binaryDir": "${sourceDir}/build-no-occt",
|
||||
"cacheVariables": {
|
||||
"SLIC3R_ENABLE_FORMAT_STEP": false,
|
||||
"QIDISlicer_DEPS_PRESET": "no-occt"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "shareddeps",
|
||||
"displayName": "Shared dependencies",
|
||||
"description": "Building with dynamically linked dependencies from the system",
|
||||
"binaryDir": "${sourceDir}/shareddeps",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"SLIC3R_STATIC": false,
|
||||
"SLIC3R_GTK": "3",
|
||||
"SLIC3R_ENC_CHECK": false,
|
||||
"SLIC3R_PCH": true,
|
||||
"QIDISlicer_BUILD_DEPS": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
10
LICENSE
@@ -1,7 +1,7 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -633,8 +633,8 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
@@ -643,7 +643,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -658,4 +658,4 @@ specific requirements.
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
BIN
QIDISlicer.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
@@ -1,21 +1,21 @@
|
||||
1.0.5
|
||||
alpha=1.0.5-alpha1
|
||||
beta=1.0.5-beta1
|
||||
1.0.1
|
||||
alpha=1.0.1-alpha1
|
||||
beta=1.0.1-beta1
|
||||
|
||||
[common]
|
||||
release = 1.0.5
|
||||
alpha = 1.0.5-alpha1
|
||||
beta = 1.0.5-beta1
|
||||
rc = 1.0.5-rc2
|
||||
release = 1.0.1
|
||||
alpha = 1.0.1-alpha1
|
||||
beta = 1.0.1-beta1
|
||||
rc = 1.0.1-rc2
|
||||
|
||||
[release:win64]
|
||||
url = https://github.com/QIDITECH/QIDISlicer/releases/download/V1.0.5/QIDISlicer_Setup_1.0.5_Win64.exe
|
||||
size = 71118761
|
||||
url = https://qidi3d.com/
|
||||
size = 85814296
|
||||
|
||||
[release:linux]
|
||||
url = https://github.com/QIDITECH/QIDISlicer/releases/download/V1.0.4/QIDISlicer-1.0.4.AppImage
|
||||
url = https://qidi3d.com
|
||||
size = 69915840
|
||||
|
||||
[release:osx]
|
||||
url = https://github.com/QIDITECH/QIDISlicer/releases/download/V1.0.5/QIDISlicer_Setup_1.0.5_Win64.exe
|
||||
url = https://qidi3d.com/
|
||||
size = 90237989
|
||||
130
README.md
@@ -1,131 +1,5 @@
|
||||
|
||||

|
||||

|
||||
|
||||
# QIDISlicer
|
||||
QIDISlicer is a professional 3D printer slicing software,which is perfectly compatible with all printers and 3D printing filaments of QIDI Technology. Multi-platform support, simple inerface, easy to use, complate functions, easy to learn 3D printing.
|
||||
|
||||
QIDISlicer is based on [PrusaSlicer](https://github.com/prusa3d/PrusaSlicer) by Prusa Research, which is from [Slic3r](https://github.com/Slic3r/Slic3r) by Alessandro Ranellucci and the RepRap community.
|
||||
Thanks to PrusaSlicer, Bambulab and OrcaSlicer for their contributions to the 3D printing community.
|
||||
|
||||
See the [QIDI's homepage](https://qidi3d.com) for more information.
|
||||
|
||||
<details open>
|
||||
<summary>Content Navigation</summary>
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#function-introduction">Function Introduction</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#wiki">Wiki</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#Supporting-QIDI-Link-App">Supporting QIDI Link App</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#report-issues-and-make-suggestions">Report Issues and Make Suggestions</a>
|
||||
<ul>
|
||||
<li><a href="#some-formatting-requirements">Some Formatting Requirements</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#license">License</a>
|
||||
</li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
----
|
||||
|
||||
## Function Introduction
|
||||
|
||||
<p align="center">
|
||||
<img src="/readmeRes/UI.png" alt="UI">
|
||||
</p>
|
||||
|
||||
### Key features are:
|
||||
|
||||
* **Slicer:** Fast and stable 3D model slicer
|
||||
* **Printer:** Perfect compatibility with all high-speed 3D printers of QIDI TECH
|
||||
* **Filament:** Perfect compatibility with all filaments of QIDI TECH and some general filaments
|
||||
* **LAN:** The printer can be directly connected through IP, convenient, safe and stable
|
||||
* **Internet:** Remote connection, start printing anytime, anywhere
|
||||
|
||||
### Other major features are:
|
||||
|
||||
* **Model:** A variety of model operations, move, scale, rotate, crop, color, repair, combine, split, and more
|
||||
* **Parameter:** Rich parameter Settings, fine adjustment for a variety of complex models and application scenarios
|
||||
* **Calibration:** Multiple calibration functions to adjust the best parameters according to the actual situation
|
||||
|
||||
----
|
||||
|
||||
## wiki
|
||||
|
||||
The wiki below aims to provide a detailed explanation of the QIDISlicer settings, how to get the most out of them as
|
||||
well as how to calibrate and setup your printer.
|
||||
|
||||
The wiki is work in progress so bear with us while we get it up and running!
|
||||
|
||||
**[Access the wiki here](https://wiki.qidi3d.com/en/software/QIDISlicier)**
|
||||
|
||||
----
|
||||
|
||||
## Supporting QIDI Link App
|
||||
|
||||
**[Access QIDI Link App Guide Here](https://wiki.qidi3d.com/en/app)**
|
||||
|
||||
The supporting QIDI Link App supports IOS and Android platforms. In the app, you can scan the code to connect to the printer, remotely monitor the printer's printing progress, control the printer's printing parameters, and perform operations such as feeding and returning materials.
|
||||
<p align="center">
|
||||
<img src="/readmeRes/qidilink.png" alt="Add filament option ——Seal">
|
||||
</p>
|
||||
|
||||
----
|
||||
|
||||
## Report Issues and Make Suggestions
|
||||
|
||||
Please send your question in the form of video or pictures to us through
|
||||
the [After-Sales Service](https://qidi3d.com/pages/warranty-policy-after-sales-support), we will reply to your
|
||||
information within 12 hours.
|
||||
|
||||
Please try to contact us through [After-Sales Service](https://qidi3d.com/pages/warranty-policy-after-sales-support) and
|
||||
report problems or suggestions. On github, we cannot obtain your order information, operation records and other private
|
||||
intelligence, nor can we generate after-sales orders, send repair files, etc. Thank you for your understanding and
|
||||
cooperation.
|
||||
|
||||
### Some formatting requirements
|
||||
|
||||
#### Issue Title:
|
||||
|
||||
Briefly describe the issue (e.g., `could not open file`)
|
||||
|
||||
#### Description:
|
||||
|
||||
Provide a detailed description of the issue.This will help our engineers quickly locate the problem and assist you in
|
||||
resolving it
|
||||
|
||||
- **Issue Description**:
|
||||
- A clear explanation of the problem.
|
||||
- Compare the expected behavior with the actual behavior.
|
||||
|
||||
- **Steps to Reproduce**:
|
||||
1. Step one
|
||||
2. Step two
|
||||
3. Step three
|
||||
|
||||
- Specific steps to reproduce the issue. Include a precise sequence of actions if possible.
|
||||
|
||||
- **Additional Information**:
|
||||
- **Screenshots/Images**: Attach relevant screenshots or images that help in understanding the issue. Please add or
|
||||
link to images here.
|
||||
- **Environment Information**:
|
||||
- Operating System Version
|
||||
- Browser/Application Version
|
||||
- Other relevant environment details
|
||||
|
||||
## License
|
||||
|
||||
QIDISlicer is licensed under the _GNU Affero General Public License, version 3_. QIDISlicer is based on PrusaSlicer by PrusaResearch.
|
||||
|
||||
PrusaSlicer is licensed under the _GNU Affero General Public License, version 3_. PrusaSlicer is owned by Prusa Research. PrusaSlicer is originally based on Slic3r by Alessandro Ranellucci.
|
||||
|
||||
Slic3r is licensed under the _GNU Affero General Public License, version 3_. Slic3r was created by Alessandro Ranellucci with the help of many other contributors.
|
||||
|
||||
The _GNU Affero General Public License, version 3_ ensures that if you use any part of this software in any way (even behind a web server), your software must be released under the same license.
|
||||
This branch is used to upload version check information.
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
option(SLIC3R_ENC_CHECK "Verify encoding of source files" 1)
|
||||
|
||||
if (IS_CROSS_COMPILE)
|
||||
# Force disable due to cross compilation. This fact is already printed on cli for users
|
||||
set(SLIC3R_ENC_CHECK OFF CACHE BOOL "" FORCE)
|
||||
endif ()
|
||||
|
||||
if (SLIC3R_ENC_CHECK)
|
||||
add_executable(encoding-check encoding-check.cpp)
|
||||
|
||||
# A global no-op target which depends on all encodings checks,
|
||||
# and on which in turn all checked targets depend.
|
||||
# This is done to make encoding checks the first thing to be
|
||||
# performed before actually compiling any sources of the checked targets
|
||||
# to make the check fail as early as possible.
|
||||
add_custom_target(global-encoding-check
|
||||
ALL
|
||||
DEPENDS encoding-check
|
||||
)
|
||||
endif()
|
||||
|
||||
# Function that adds source file encoding check to a target
|
||||
# using the above encoding-check binary
|
||||
|
||||
function(encoding_check TARGET)
|
||||
if (SLIC3R_ENC_CHECK)
|
||||
# Obtain target source files
|
||||
get_target_property(T_SOURCES ${TARGET} SOURCES)
|
||||
|
||||
# Define top-level encoding check target for this ${TARGET}
|
||||
add_custom_target(encoding-check-${TARGET}
|
||||
DEPENDS encoding-check ${T_SOURCES}
|
||||
COMMENT "Checking source files encodings for target ${TARGET}"
|
||||
)
|
||||
|
||||
# Add checking of each source file as a subcommand of encoding-check-${TARGET}
|
||||
foreach(file ${T_SOURCES})
|
||||
add_custom_command(TARGET encoding-check-${TARGET}
|
||||
COMMAND $<TARGET_FILE:encoding-check> ${TARGET} ${file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# This adds dependency on encoding-check-${TARGET} to ${TARET}
|
||||
# via the global-encoding-check
|
||||
add_dependencies(global-encoding-check encoding-check-${TARGET})
|
||||
add_dependencies(${TARGET} global-encoding-check)
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -1,119 +0,0 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
/*
|
||||
* The utf8_check() function scans the '\0'-terminated string starting
|
||||
* at s. It returns a pointer to the first byte of the first malformed
|
||||
* or overlong UTF-8 sequence found, or NULL if the string contains
|
||||
* only correct UTF-8. It also spots UTF-8 sequences that could cause
|
||||
* trouble if converted to UTF-16, namely surrogate characters
|
||||
* (U+D800..U+DFFF) and non-Unicode positions (U+FFFE..U+FFFF). This
|
||||
* routine is very likely to find a malformed sequence if the input
|
||||
* uses any other encoding than UTF-8. It therefore can be used as a
|
||||
* very effective heuristic for distinguishing between UTF-8 and other
|
||||
* encodings.
|
||||
*
|
||||
* I wrote this code mainly as a specification of functionality; there
|
||||
* are no doubt performance optimizations possible for certain CPUs.
|
||||
*
|
||||
* Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> -- 2005-03-30
|
||||
* License: http://www.cl.cam.ac.uk/~mgk25/short-license.html
|
||||
*/
|
||||
|
||||
unsigned char *utf8_check(unsigned char *s)
|
||||
{
|
||||
while (*s) {
|
||||
if (*s < 0x80) {
|
||||
// 0xxxxxxx
|
||||
s++;
|
||||
} else if ((s[0] & 0xe0) == 0xc0) {
|
||||
// 110xxxxx 10xxxxxx
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[0] & 0xfe) == 0xc0) { // overlong?
|
||||
return s;
|
||||
} else {
|
||||
s += 2;
|
||||
}
|
||||
} else if ((s[0] & 0xf0) == 0xe0) {
|
||||
// 1110xxxx 10xxxxxx 10xxxxxx
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[2] & 0xc0) != 0x80 ||
|
||||
(s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || // overlong?
|
||||
(s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || // surrogate?
|
||||
(s[0] == 0xef && s[1] == 0xbf &&
|
||||
(s[2] & 0xfe) == 0xbe)) { // U+FFFE or U+FFFF?
|
||||
return s;
|
||||
} else {
|
||||
s += 3;
|
||||
}
|
||||
} else if ((s[0] & 0xf8) == 0xf0) {
|
||||
// 11110xxX 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[2] & 0xc0) != 0x80 ||
|
||||
(s[3] & 0xc0) != 0x80 ||
|
||||
(s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || // overlong?
|
||||
(s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) { // > U+10FFFF?
|
||||
return s;
|
||||
} else {
|
||||
s += 4;
|
||||
}
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " <program/library> <file>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* target = argv[1];
|
||||
const char* filename = argv[2];
|
||||
|
||||
const auto error_exit = [=](const char* error) {
|
||||
std::cerr << "\n\tError: " << error << ": " << filename << "\n"
|
||||
<< "\tTarget: " << target << "\n"
|
||||
<< std::endl;
|
||||
std::exit(-2);
|
||||
};
|
||||
|
||||
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||
const auto size = file.tellg();
|
||||
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::beg);
|
||||
std::vector<char> buffer(size);
|
||||
|
||||
if (file.read(buffer.data(), size)) {
|
||||
buffer.push_back('\0');
|
||||
|
||||
// Check UTF-8 validity
|
||||
if (utf8_check(reinterpret_cast<unsigned char*>(buffer.data())) != nullptr) {
|
||||
error_exit("Source file does not contain (valid) UTF-8");
|
||||
}
|
||||
|
||||
// Check against a BOM mark
|
||||
if (buffer.size() >= 3
|
||||
&& buffer[0] == '\xef'
|
||||
&& buffer[1] == '\xbb'
|
||||
&& buffer[2] == '\xbf') {
|
||||
error_exit("Source file is valid UTF-8 but contains a BOM mark");
|
||||
}
|
||||
} else {
|
||||
error_exit("Could not read source file");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
510
build_win.bat
@@ -1,510 +0,0 @@
|
||||
@setlocal disableDelayedExpansion enableExtensions
|
||||
@IF "%PS_ECHO_ON%" NEQ "" (echo on) ELSE (echo off)
|
||||
@GOTO :MAIN
|
||||
:HELP
|
||||
@ECHO.
|
||||
@ECHO Performs initial build or rebuild of the app (build) and deps (build/deps).
|
||||
@ECHO Default options are determined from build directories and system state.
|
||||
@ECHO.
|
||||
@ECHO Usage: build_win [-ARCH ^<arch^>] [-CONFIG ^<config^>] [-VERSION ^<version^>]
|
||||
@ECHO [-PRODUCT ^<product^>] [-DESTDIR ^<directory^>]
|
||||
@ECHO [-STEPS ^<all^|all-dirty^|app^|app-dirty^|deps^|deps-dirty^>]
|
||||
@ECHO [-RUN ^<console^|custom^|none^|viewer^|window^>]
|
||||
@ECHO [-PRIORITY ^<normal^|low^>]
|
||||
@ECHO.
|
||||
@ECHO -a -ARCH Target processor architecture
|
||||
@ECHO Default: %PS_ARCH_HOST%
|
||||
@ECHO -c -CONFIG MSVC project config
|
||||
@ECHO Default: %PS_CONFIG_DEFAULT%
|
||||
@ECHO -v -VERSION Major version number of MSVC installation to use for build
|
||||
@ECHO Default: %PS_VERSION_SUPPORTED%
|
||||
@ECHO -p -PRODUCT Product ID of MSVC installation to use for build
|
||||
@ECHO Default: %PS_PRODUCT_DEFAULT%
|
||||
@ECHO -s -STEPS Performs only the specified build steps:
|
||||
@ECHO all - clean and build deps and app
|
||||
@ECHO all-dirty - build deps and app without cleaning
|
||||
@ECHO app - clean and build main applications
|
||||
@ECHO app-dirty - build main applications without cleaning
|
||||
@ECHO deps - clean and build deps
|
||||
@ECHO deps-dirty - build deps without cleaning
|
||||
@ECHO Default: %PS_STEPS_DEFAULT%
|
||||
@ECHO -r -RUN Specifies what to perform at the run step:
|
||||
@ECHO console - run and wait on qidi-slicer-console.exe
|
||||
@ECHO custom - run and wait on your custom build/%PS_CUSTOM_RUN_FILE%
|
||||
@ECHO ide - open project in Visual Studio if not open (no wait)
|
||||
@ECHO none - run step does nothing
|
||||
@ECHO viewer - run qidi-gcodeviewer.exe (no wait)
|
||||
@ECHO window - run qidi-slicer.exe (no wait)
|
||||
@ECHO Default: none
|
||||
@ECHO -d -DESTDIR Deps destination directory
|
||||
@ECHO Warning: Changing destdir path will not delete the old destdir.
|
||||
@ECHO Default: %PS_DESTDIR_DEFAULT_MSG%
|
||||
@ECHO -p -PRIORITY Build CPU priority
|
||||
@ECHO Default: normal
|
||||
@ECHO.
|
||||
@ECHO Examples:
|
||||
@ECHO.
|
||||
@ECHO Initial build: build_win -d "c:\src\QIDISlicer-deps"
|
||||
@ECHO Build post deps change: build_win -s all
|
||||
@ECHO App dirty build: build_win
|
||||
@ECHO App dirty build ^& run: build_win -r console
|
||||
@ECHO All clean build ^& run: build_win -s all -r console -d "deps\build\out_deps"
|
||||
@ECHO.
|
||||
GOTO :END
|
||||
|
||||
:MAIN
|
||||
REM Script constants
|
||||
SET START_TIME=%TIME%
|
||||
SET PS_START_DIR=%CD%
|
||||
SET PS_SOLUTION_NAME=QIDISlicer
|
||||
SET PS_CHOICE_TIMEOUT=30
|
||||
SET PS_CUSTOM_RUN_FILE=custom_run.bat
|
||||
SET PS_DEPS_PATH_FILE_NAME=.DEPS_PATH.txt
|
||||
SET PS_DEPS_PATH_FILE=%~dp0deps\build\%PS_DEPS_PATH_FILE_NAME%
|
||||
SET PS_CONFIG_LIST="Debug;MinSizeRel;Release;RelWithDebInfo"
|
||||
|
||||
REM Update this script for new versions by setting PS_VERSION_SUPPORTED to a
|
||||
REM new minimum version and setting PS_VERSION_EXCEEDED to the maximum supported
|
||||
REM version plus one.
|
||||
REM The officially supported toolchain versions are:
|
||||
REM Minimum: 16 (Visual Studio 2019)
|
||||
REM Maximum: 17 (Visual Studio 2022)
|
||||
SET PS_VERSION_SUPPORTED=16
|
||||
SET PS_VERSION_EXCEEDED=18
|
||||
SET VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe
|
||||
IF NOT EXIST "%VSWHERE%" SET VSWHERE=%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe
|
||||
FOR /F "tokens=4 USEBACKQ delims=." %%I IN (`"%VSWHERE%" -nologo -property productId`) DO SET PS_PRODUCT_DEFAULT=%%I
|
||||
IF "%PS_PRODUCT_DEFAULT%" EQU "" (
|
||||
SET EXIT_STATUS=-1
|
||||
@ECHO ERROR: No Visual Studio installation found. 1>&2
|
||||
GOTO :HELP
|
||||
)
|
||||
REM Default to the latest supported version if multiple are available
|
||||
FOR /F "tokens=1 USEBACKQ delims=." %%I IN (
|
||||
`^""%VSWHERE%" -version "[%PS_VERSION_SUPPORTED%,%PS_VERSION_EXCEEDED%)" -latest -nologo -property catalog_buildVersion^"`
|
||||
) DO SET PS_VERSION_SUPPORTED=%%I
|
||||
|
||||
REM Probe build directories and system state for reasonable default arguments
|
||||
pushd %~dp0
|
||||
SET PS_CONFIG=RelWithDebInfo
|
||||
SET PS_ARCH=%PROCESSOR_ARCHITECTURE:amd64=x64%
|
||||
CALL :TOLOWER PS_ARCH
|
||||
SET PS_RUN=none
|
||||
SET PS_DESTDIR=
|
||||
SET PS_VERSION=
|
||||
SET PS_PRODUCT=%PS_PRODUCT_DEFAULT%
|
||||
SET PS_PRIORITY=normal
|
||||
CALL :RESOLVE_DESTDIR_CACHE
|
||||
|
||||
REM Set up parameters used by help menu
|
||||
SET EXIT_STATUS=0
|
||||
SET PS_CONFIG_DEFAULT=%PS_CONFIG%
|
||||
SET PS_ARCH_HOST=%PS_ARCH%
|
||||
(echo " -help /help -h /h -? /? ")| findstr /I /C:" %~1 ">nul && GOTO :HELP
|
||||
|
||||
REM Parse arguments
|
||||
SET EXIT_STATUS=1
|
||||
SET PS_CURRENT_STEP=arguments
|
||||
SET PARSER_STATE=
|
||||
SET PARSER_FAIL=
|
||||
FOR %%I in (%*) DO CALL :PARSE_OPTION "ARCH CONFIG DESTDIR STEPS RUN VERSION PRODUCT PRIORITY" PARSER_STATE "%%~I"
|
||||
IF "%PARSER_FAIL%" NEQ "" (
|
||||
@ECHO ERROR: Invalid switch: %PARSER_FAIL% 1>&2
|
||||
GOTO :HELP
|
||||
)ELSE IF "%PARSER_STATE%" NEQ "" (
|
||||
@ECHO ERROR: Missing parameter for: %PARSER_STATE% 1>&2
|
||||
GOTO :HELP
|
||||
)
|
||||
|
||||
REM Validate arguments
|
||||
SET PS_ASK_TO_CONTINUE=
|
||||
CALL :TOLOWER PS_ARCH
|
||||
SET PS_ARCH=%PS_ARCH:amd64=x64%
|
||||
CALL :PARSE_OPTION_VALUE %PS_CONFIG_LIST:;= % PS_CONFIG
|
||||
IF "%PS_CONFIG%" EQU "" GOTO :HELP
|
||||
CALL :PARSE_OPTION_VALUE "normal low" PS_PRIORITY
|
||||
SET PS_PRIORITY=%PS_PRIORITY:normal= %
|
||||
SET PS_PRIORITY=%PS_PRIORITY:low=-low%
|
||||
REM RESOLVE_DESTDIR_CACHE must go after PS_ARCH and PS_CONFIG, but before PS STEPS
|
||||
CALL :RESOLVE_DESTDIR_CACHE
|
||||
IF "%PS_STEPS%" EQU "" SET PS_STEPS=%PS_STEPS_DEFAULT%
|
||||
CALL :PARSE_OPTION_VALUE "all all-dirty deps-dirty deps app-dirty app app-cmake" PS_STEPS
|
||||
IF "%PS_STEPS%" EQU "" GOTO :HELP
|
||||
(echo %PS_STEPS%)| findstr /I /C:"dirty">nul && SET PS_STEPS_DIRTY=1 || SET PS_STEPS_DIRTY=
|
||||
IF "%PS_STEPS%" EQU "app-cmake" SET PS_STEPS_DIRTY=1
|
||||
IF "%PS_DESTDIR%" EQU "" SET PS_DESTDIR=%PS_DESTDIR_CACHED%
|
||||
IF "%PS_DESTDIR%" EQU "" (
|
||||
@ECHO ERROR: Parameter required: -DESTDIR 1>&2
|
||||
GOTO :HELP
|
||||
)
|
||||
CALL :CANONICALIZE_PATH PS_DESTDIR "%PS_START_DIR%"
|
||||
IF "%PS_DESTDIR%" NEQ "%PS_DESTDIR_CACHED%" (
|
||||
(echo "all deps all-dirty deps-dirty")| findstr /I /C:"%PS_STEPS%">nul || (
|
||||
IF EXIST "%PS_DESTDIR%" (
|
||||
@ECHO WARNING: DESTDIR does not match cache: 1>&2
|
||||
@ECHO WARNING: new: %PS_DESTDIR% 1>&2
|
||||
@ECHO WARNING: old: %PS_DESTDIR_CACHED% 1>&2
|
||||
SET PS_ASK_TO_CONTINUE=1
|
||||
) ELSE (
|
||||
@ECHO ERROR: Invalid parameter: DESTDIR=%PS_DESTDIR% 1>&2
|
||||
GOTO :HELP
|
||||
)
|
||||
)
|
||||
)
|
||||
SET PS_DESTDIR_DEFAULT_MSG=
|
||||
CALL :PARSE_OPTION_VALUE "console custom ide none viewer window" PS_RUN
|
||||
IF "%PS_RUN%" EQU "" GOTO :HELP
|
||||
IF "%PS_RUN%" NEQ "none" IF "%PS_STEPS:~0,4%" EQU "deps" (
|
||||
@ECHO ERROR: RUN=%PS_RUN% specified with STEPS=%PS_STEPS%
|
||||
@ECHO ERROR: RUN=none is the only valid option for STEPS "deps" or "deps-dirty"
|
||||
GOTO :HELP
|
||||
)
|
||||
IF DEFINED PS_VERSION (
|
||||
SET /A PS_VERSION_EXCEEDED=%PS_VERSION% + 1
|
||||
) ELSE SET PS_VERSION=%PS_VERSION_SUPPORTED%
|
||||
SET MSVC_FILTER=-products Microsoft.VisualStudio.Product.%PS_PRODUCT% -version "[%PS_VERSION%,%PS_VERSION_EXCEEDED%)"
|
||||
FOR /F "tokens=* USEBACKQ" %%I IN (`^""%VSWHERE%" %MSVC_FILTER% -nologo -property installationPath^"`) DO SET MSVC_DIR=%%I
|
||||
IF NOT EXIST "%MSVC_DIR%" (
|
||||
@ECHO ERROR: Compatible Visual Studio installation not found. 1>&2
|
||||
GOTO :HELP
|
||||
)
|
||||
REM Cmake always defaults to latest supported MSVC generator. Let's make sure it uses what we select.
|
||||
FOR /F "tokens=* USEBACKQ" %%I IN (`^""%VSWHERE%" %MSVC_FILTER% -nologo -property catalog_productLineVersion^"`) DO SET PS_PRODUCT_VERSION=%%I
|
||||
|
||||
REM Give the user a chance to cancel if we found something odd.
|
||||
IF "%PS_ASK_TO_CONTINUE%" EQU "" GOTO :BUILD_ENV
|
||||
@ECHO.
|
||||
@ECHO Unexpected parameters detected. Build paused for %PS_CHOICE_TIMEOUT% seconds.
|
||||
choice /T %PS_CHOICE_TIMEOUT% /C YN /D N /M "Continue"
|
||||
IF %ERRORLEVEL% NEQ 1 GOTO :HELP
|
||||
|
||||
REM Set up MSVC environment
|
||||
:BUILD_ENV
|
||||
SET EXIT_STATUS=2
|
||||
SET PS_CURRENT_STEP=environment
|
||||
@ECHO **********************************************************************
|
||||
@ECHO ** Build Config: %PS_CONFIG%
|
||||
@ECHO ** Target Arch: %PS_ARCH%
|
||||
@ECHO ** Build Steps: %PS_STEPS%
|
||||
@ECHO ** Run App: %PS_RUN%
|
||||
@ECHO ** Deps path: %PS_DESTDIR%
|
||||
@ECHO ** Using Microsoft Visual Studio installation found at:
|
||||
@ECHO ** %MSVC_DIR%
|
||||
SET CMAKE_GENERATOR=Visual Studio %PS_VERSION% %PS_PRODUCT_VERSION%
|
||||
CALL "%MSVC_DIR%\Common7\Tools\vsdevcmd.bat" -arch=%PS_ARCH% -host_arch=%PS_ARCH_HOST% -app_platform=Desktop
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO :END
|
||||
REM Need to reset the echo state after vsdevcmd.bat clobbers it.
|
||||
@IF "%PS_ECHO_ON%" NEQ "" (echo on) ELSE (echo off)
|
||||
IF "%PS_DRY_RUN_ONLY%" NEQ "" (
|
||||
@ECHO Script terminated early because PS_DRY_RUN_ONLY is set. 1>&2
|
||||
GOTO :END
|
||||
)
|
||||
IF /I "%PS_STEPS:~0,3%" EQU "app" GOTO :BUILD_APP
|
||||
|
||||
REM Build deps
|
||||
:BUILD_DEPS
|
||||
SET EXIT_STATUS=3
|
||||
SET PS_CURRENT_STEP=deps
|
||||
IF "%PS_STEPS_DIRTY%" EQU "" (
|
||||
CALL :MAKE_OR_CLEAN_DIRECTORY deps\build "%PS_DEPS_PATH_FILE_NAME%" .vs
|
||||
CALL :MAKE_OR_CLEAN_DIRECTORY "%PS_DESTDIR%"
|
||||
)
|
||||
cd deps\build || GOTO :END
|
||||
cmake.exe .. -DDESTDIR="%PS_DESTDIR%"
|
||||
IF %ERRORLEVEL% NEQ 0 IF "%PS_STEPS_DIRTY%" NEQ "" (
|
||||
(del CMakeCache.txt && cmake.exe .. -DDESTDIR="%PS_DESTDIR%") || GOTO :END
|
||||
) ELSE GOTO :END
|
||||
(echo %PS_DESTDIR%)> "%PS_DEPS_PATH_FILE%"
|
||||
msbuild /m ALL_BUILD.vcxproj /p:Configuration=%PS_CONFIG% /v:quiet %PS_PRIORITY% || GOTO :END
|
||||
cd ..\..
|
||||
IF /I "%PS_STEPS:~0,4%" EQU "deps" GOTO :RUN_APP
|
||||
|
||||
REM Build app
|
||||
:BUILD_APP
|
||||
SET EXIT_STATUS=4
|
||||
SET PS_CURRENT_STEP=app
|
||||
IF "%PS_STEPS_DIRTY%" EQU "" CALL :MAKE_OR_CLEAN_DIRECTORY build "%PS_CUSTOM_RUN_FILE%" .vs
|
||||
cd build || GOTO :END
|
||||
REM Make sure we have a custom batch file skeleton for the run stage
|
||||
set PS_CUSTOM_BAT=%PS_CUSTOM_RUN_FILE%
|
||||
CALL :CANONICALIZE_PATH PS_CUSTOM_BAT
|
||||
IF NOT EXIST %PS_CUSTOM_BAT% CALL :WRITE_CUSTOM_SCRIPT_SKELETON %PS_CUSTOM_BAT%
|
||||
SET PS_PROJECT_IS_OPEN=
|
||||
FOR /F "tokens=2 delims=," %%I in (
|
||||
'tasklist /V /FI "IMAGENAME eq devenv.exe " /NH /FO CSV ^| find "%PS_SOLUTION_NAME%"'
|
||||
) do SET PS_PROJECT_IS_OPEN=%%~I
|
||||
cmake.exe .. -DCMAKE_PREFIX_PATH="%PS_DESTDIR%\usr\local" -DCMAKE_CONFIGURATION_TYPES=%PS_CONFIG_LIST%
|
||||
IF %ERRORLEVEL% NEQ 0 IF "%PS_STEPS_DIRTY%" NEQ "" (
|
||||
(del CMakeCache.txt && cmake.exe .. -DCMAKE_PREFIX_PATH="%PS_DESTDIR%\usr\local" -DCMAKE_CONFIGURATION_TYPES=%PS_CONFIG_LIST% -DQDT_RELEASE_TO_PUBLIC=1) || GOTO :END
|
||||
) ELSE GOTO :END
|
||||
REM Skip the build step if we're using the undocumented app-cmake to regenerate the full config from inside devenv
|
||||
IF "%PS_STEPS%" NEQ "app-cmake" msbuild /m ALL_BUILD.vcxproj /p:Configuration=%PS_CONFIG% /v:quiet %PS_PRIORITY% || GOTO :END
|
||||
(echo %PS_DESTDIR%)> "%PS_DEPS_PATH_FILE_FOR_CONFIG%"
|
||||
|
||||
REM Run app
|
||||
:RUN_APP
|
||||
REM All build steps complete.
|
||||
CALL :DIFF_TIME ELAPSED_TIME %START_TIME% %TIME%
|
||||
IF "%PS_CURRENT_STEP%" NEQ "arguments" (
|
||||
@ECHO.
|
||||
@ECHO Total Build Time Elapsed %ELAPSED_TIME%
|
||||
)
|
||||
SET EXIT_STATUS=5
|
||||
SET PS_CURRENT_STEP=run
|
||||
IF "%PS_RUN%" EQU "none" GOTO :PROLOGUE
|
||||
cd src\%PS_CONFIG% || GOTO :END
|
||||
SET PS_PROJECT_IS_OPEN=
|
||||
FOR /F "tokens=2 delims=," %%I in (
|
||||
'tasklist /V /FI "IMAGENAME eq devenv.exe " /NH /FO CSV ^| find "%PS_SOLUTION_NAME%"'
|
||||
) do SET PS_PROJECT_IS_OPEN=%%~I
|
||||
@ECHO.
|
||||
@ECHO Running %PS_RUN% application...
|
||||
@REM icacls below is just a hack for file-not-found error handling
|
||||
IF "%PS_RUN%" EQU "console" (
|
||||
icacls qidi-slicer-console.exe >nul || GOTO :END
|
||||
start /wait /b qidi-slicer-console.exe
|
||||
) ELSE IF "%PS_RUN%" EQU "window" (
|
||||
icacls qidi-slicer.exe >nul || GOTO :END
|
||||
start qidi-slicer.exe
|
||||
) ELSE IF "%PS_RUN%" EQU "viewer" (
|
||||
icacls qidi-gcodeviewer.exe >nul || GOTO :END
|
||||
start qidi-gcodeviewer.exe
|
||||
) ELSE IF "%PS_RUN%" EQU "custom" (
|
||||
icacls %PS_CUSTOM_BAT% >nul || GOTO :END
|
||||
CALL %PS_CUSTOM_BAT%
|
||||
) ELSE IF "%PS_RUN%" EQU "ide" (
|
||||
IF "%PS_PROJECT_IS_OPEN%" NEQ "" (
|
||||
@ECHO WARNING: Solution is already open in Visual Studio. Skipping ide run step. 1>&2
|
||||
) ELSE (
|
||||
@ECHO Preparing to run Visual Studio...
|
||||
cd ..\.. || GOTO :END
|
||||
REM This hack generates a single config for MSVS, guaranteeing it gets set as the active config.
|
||||
cmake.exe .. -DCMAKE_PREFIX_PATH="%PS_DESTDIR%\usr\local" -DCMAKE_CONFIGURATION_TYPES=%PS_CONFIG% > nul 2> nul || GOTO :END
|
||||
REM Now launch devenv with the single config (setting it active) and a /command switch to re-run cmake and generate the full config list
|
||||
start devenv.exe %PS_SOLUTION_NAME%.sln /command ^"shell /o ^^^"%~f0^^^" -d ^^^"%PS_DESTDIR%^^^" -c %PS_CONFIG% -a %PS_ARCH% -r none -s app-cmake^"
|
||||
REM If devenv fails to launch just directly regenerate the full config list.
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
cmake.exe .. -DCMAKE_PREFIX_PATH="%PS_DESTDIR%\usr\local" -DCMAKE_CONFIGURATION_TYPES=%PS_CONFIG_LIST% 2> nul 1> nul || GOTO :END
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@REM ********** DON'T ADD ANY CODE BETWEEN THESE TWO SECTIONS **********
|
||||
@REM RUN_APP may hand off control, so let exit codes fall through to PROLOGUE.
|
||||
|
||||
:PROLOGUE
|
||||
SET EXIT_STATUS=%ERRORLEVEL%
|
||||
:END
|
||||
@IF "%PS_ECHO_ON%%PS_DRY_RUN_ONLY%" NEQ "" (
|
||||
@ECHO **********************************************************************
|
||||
@ECHO ** Script Parameters:
|
||||
@ECHO **********************************************************************
|
||||
@SET PS_
|
||||
)
|
||||
IF "%EXIT_STATUS%" NEQ "0" (
|
||||
IF "%PS_CURRENT_STEP%" NEQ "arguments" (
|
||||
@ECHO.
|
||||
@ECHO ERROR: *** Build process failed at %PS_CURRENT_STEP% step. *** 1>&2
|
||||
)
|
||||
) ELSE (
|
||||
@ECHO All steps completed successfully.
|
||||
)
|
||||
popd
|
||||
exit /B %EXIT_STATUS%
|
||||
|
||||
GOTO :EOF
|
||||
REM Functions and stubs start here.
|
||||
|
||||
:RESOLVE_DESTDIR_CACHE
|
||||
@REM Resolves all DESTDIR cache values and sets PS_STEPS_DEFAULT
|
||||
@REM Note: This just sets global variables, so it doesn't use setlocal.
|
||||
SET PS_DEPS_PATH_FILE_FOR_CONFIG=%~dp0build\.vs\%PS_ARCH%\%PS_CONFIG%\%PS_DEPS_PATH_FILE_NAME%
|
||||
mkdir "%~dp0build\.vs\%PS_ARCH%\%PS_CONFIG%" > nul 2> nul
|
||||
REM Copy a legacy file if we don't have one in the proper location.
|
||||
echo f|xcopy /D "%~dp0build\%PS_ARCH%\%PS_CONFIG%\%PS_DEPS_PATH_FILE_NAME%" "%PS_DEPS_PATH_FILE_FOR_CONFIG%" > nul 2> nul
|
||||
CALL :CANONICALIZE_PATH PS_DEPS_PATH_FILE_FOR_CONFIG
|
||||
IF EXIST "%PS_DEPS_PATH_FILE_FOR_CONFIG%" (
|
||||
FOR /F "tokens=* USEBACKQ" %%I IN ("%PS_DEPS_PATH_FILE_FOR_CONFIG%") DO (
|
||||
SET PS_DESTDIR_CACHED=%%I
|
||||
SET PS_DESTDIR_DEFAULT_MSG=%%I
|
||||
)
|
||||
SET PS_STEPS_DEFAULT=app-dirty
|
||||
) ELSE IF EXIST "%PS_DEPS_PATH_FILE%" (
|
||||
FOR /F "tokens=* USEBACKQ" %%I IN ("%PS_DEPS_PATH_FILE%") DO (
|
||||
SET PS_DESTDIR_CACHED=%%I
|
||||
SET PS_DESTDIR_DEFAULT_MSG=%%I
|
||||
)
|
||||
SET PS_STEPS_DEFAULT=app
|
||||
) ELSE (
|
||||
SET PS_DESTDIR_CACHED=
|
||||
SET PS_DESTDIR_DEFAULT_MSG=Cache missing. Argument required.
|
||||
SET PS_STEPS_DEFAULT=all
|
||||
)
|
||||
GOTO :EOF
|
||||
|
||||
:PARSE_OPTION
|
||||
@REM Argument parser called for each argument
|
||||
@REM %1 - Valid option list
|
||||
@REM %2 - Variable name for parser state; must be unset when parsing finished
|
||||
@REM %3 - Current argument value
|
||||
@REM PARSER_FAIL will be set on an error
|
||||
@REM Note: Must avoid delayed expansion since filenames may contain ! character
|
||||
setlocal disableDelayedExpansion
|
||||
IF "%PARSER_FAIL%" NEQ "" GOTO :EOF
|
||||
CALL SET LAST_ARG=%%%2%%
|
||||
IF "%LAST_ARG%" EQU "" (
|
||||
CALL :PARSE_OPTION_NAME %1 %~2 %~3 1
|
||||
SET ARG_TYPE=NAME
|
||||
) ELSE (
|
||||
SET PS_SET_COMMAND=SET PS_%LAST_ARG%=%~3
|
||||
SET ARG_TYPE=LAST_ARG
|
||||
SET %~2=
|
||||
)
|
||||
CALL SET LAST_ARG=%%%2%%
|
||||
IF "%LAST_ARG%%ARG_TYPE%" EQU "NAME" SET PARSER_FAIL=%~3
|
||||
(
|
||||
endlocal
|
||||
SET PARSER_FAIL=%PARSER_FAIL%
|
||||
SET %~2=%LAST_ARG%
|
||||
%PS_SET_COMMAND%
|
||||
)
|
||||
GOTO :EOF
|
||||
|
||||
:PARSE_OPTION_VALUE
|
||||
setlocal disableDelayedExpansion
|
||||
@REM Parses value and verifies it is within the supplied list
|
||||
@REM %1 - Valid option list
|
||||
@REM %2 - In/out variable name; unset on error
|
||||
CALL SET NAME=%~2
|
||||
CALL SET SAVED_VALUE=%%%NAME%%%
|
||||
CALL :PARSE_OPTION_NAME %1 %NAME% -%SAVED_VALUE%
|
||||
CALL SET NEW_VALUE=%%%NAME%%%
|
||||
IF "%NEW_VALUE%" EQU "" (
|
||||
@ECHO ERROR: Invalid parameter: %NAME:~3%=%SAVED_VALUE% 1>&2
|
||||
)
|
||||
endlocal & SET %NAME%=%NEW_VALUE%
|
||||
GOTO :EOF
|
||||
|
||||
:PARSE_OPTION_NAME
|
||||
@REM Parses an option name
|
||||
@REM %1 - Valid option list
|
||||
@REM %2 - Out variable name; unset on error
|
||||
@REM %3 - Current argument value
|
||||
@REM %4 - Boolean indicating single character switches are valid
|
||||
@REM Note: Delayed expansion safe because ! character is invalid in option name
|
||||
setlocal enableDelayedExpansion
|
||||
IF "%4" NEQ "" FOR %%I IN (%~1) DO @(
|
||||
SET SHORT_NAME=%%~I
|
||||
SET SHORT_ARG_!SHORT_NAME:~0,1!=%%~I
|
||||
)
|
||||
@SET OPTION_NAME=%~3
|
||||
@(echo %OPTION_NAME%)| findstr /R /C:"[-/]..*">nul || GOTO :PARSE_OPTION_NAME_FAIL
|
||||
@SET OPTION_NAME=%OPTION_NAME:~1%
|
||||
IF "%4" NEQ "" (
|
||||
IF "%OPTION_NAME%" EQU "%OPTION_NAME:~0,1%" (
|
||||
IF "!SHORT_ARG_%OPTION_NAME:~0,1%!" NEQ "" SET OPTION_NAME=!SHORT_ARG_%OPTION_NAME:~0,1%!
|
||||
)
|
||||
)
|
||||
@(echo %OPTION_NAME%)| findstr /R /C:".[ ][ ]*.">nul && GOTO :PARSE_OPTION_NAME_FAIL
|
||||
@(echo %~1 )| findstr /I /C:" %OPTION_NAME% ">nul || GOTO :PARSE_OPTION_NAME_FAIL
|
||||
FOR %%I IN (%~1) DO SET OPTION_NAME=!OPTION_NAME:%%~I=%%~I!
|
||||
endlocal & SET %~2=%OPTION_NAME%
|
||||
GOTO :EOF
|
||||
:PARSE_OPTION_NAME_FAIL
|
||||
endlocal & SET %~2=
|
||||
GOTO :EOF
|
||||
|
||||
:MAKE_OR_CLEAN_DIRECTORY
|
||||
@REM Create directory if it doesn't exist or clean it if it does
|
||||
@REM %1 - Directory path to clean or create
|
||||
@REM %* - Optional list of files/dirs to keep (in the base directory only)
|
||||
setlocal disableDelayedExpansion
|
||||
IF NOT EXIST "%~1" (
|
||||
@ECHO Creating %~1
|
||||
mkdir "%~1" && (
|
||||
endlocal
|
||||
GOTO :EOF
|
||||
)
|
||||
)
|
||||
@ECHO Cleaning %~1 ...
|
||||
SET KEEP_LIST=
|
||||
:MAKE_OR_CLEAN_DIRECTORY_ARG_LOOP
|
||||
IF "%~2" NEQ "" (
|
||||
SET KEEP_LIST=%KEEP_LIST% "%~2"
|
||||
SHIFT /2
|
||||
GOTO :MAKE_OR_CLEAN_DIRECTORY_ARG_LOOP
|
||||
)
|
||||
for /F "usebackq delims=" %%I in (`dir /a /b "%~1"`) do (
|
||||
(echo %KEEP_LIST%)| findstr /I /L /C:"\"%%I\"">nul || (
|
||||
rmdir /s /q "%~1\%%I" 2>nul ) || del /q /f "%~1\%%I"
|
||||
)
|
||||
endlocal
|
||||
GOTO :EOF
|
||||
|
||||
:TOLOWER
|
||||
@REM Converts supplied environment variable to lowercase
|
||||
@REM %1 - Input/output variable name
|
||||
@REM Note: This is slow on very long strings, but is used only on very short ones
|
||||
setlocal disableDelayedExpansion
|
||||
@FOR %%b IN (a b c d e f g h i j k l m n o p q r s t u v w x y z) DO @CALL set %~1=%%%1:%%b=%%b%%
|
||||
@CALL SET OUTPUT=%%%~1%%
|
||||
endlocal & SET %~1=%OUTPUT%
|
||||
GOTO :EOF
|
||||
|
||||
:CANONICALIZE_PATH
|
||||
@REM Canonicalizes the path in the supplied variable
|
||||
@REM %1 - Input/output variable containing path to canonicalize
|
||||
@REM %2 - Optional base directory
|
||||
setlocal
|
||||
CALL :CANONICALIZE_PATH_INNER %1 %%%~1%% %2
|
||||
endlocal & SET %~1=%OUTPUT%
|
||||
GOTO :EOF
|
||||
:CANONICALIZE_PATH_INNER
|
||||
if "%~3" NEQ "" (pushd %3 || GOTO :EOF)
|
||||
SET OUTPUT=%~f2
|
||||
if "%~3" NEQ "" popd
|
||||
GOTO :EOF
|
||||
|
||||
:DIFF_TIME
|
||||
@REM Calculates elapsed time between two timestamps (TIME environment variable format)
|
||||
@REM %1 - Output variable
|
||||
@REM %2 - Start time
|
||||
@REM %3 - End time
|
||||
setlocal EnableDelayedExpansion
|
||||
set START_ARG=%2
|
||||
set END_ARG=%3
|
||||
set END=!END_ARG:%TIME:~8,1%=%%100)*100+1!
|
||||
set START=!START_ARG:%TIME:~8,1%=%%100)*100+1!
|
||||
set /A DIFF=((((10!END:%TIME:~2,1%=%%100)*60+1!%%100)-((((10!START:%TIME:~2,1%=%%100)*60+1!%%100), DIFF-=(DIFF^>^>31)*24*60*60*100
|
||||
set /A CC=DIFF%%100+100,DIFF/=100,SS=DIFF%%60+100,DIFF/=60,MM=DIFF%%60+100,HH=DIFF/60+100
|
||||
@endlocal & set %1=%HH:~1%%TIME:~2,1%%MM:~1%%TIME:~2,1%%SS:~1%%TIME:~8,1%%CC:~1%
|
||||
@GOTO :EOF
|
||||
|
||||
:WRITE_CUSTOM_SCRIPT_SKELETON
|
||||
@REM Writes the following text to the supplied file
|
||||
@REM %1 - Output filename
|
||||
setlocal
|
||||
@(
|
||||
ECHO @ECHO.
|
||||
ECHO @ECHO ********************************************************************************
|
||||
ECHO @ECHO ** This is a custom run script skeleton.
|
||||
ECHO @ECHO ********************************************************************************
|
||||
ECHO @ECHO.
|
||||
ECHO @ECHO ********************************************************************************
|
||||
ECHO @ECHO ** The working directory is:
|
||||
ECHO @ECHO ********************************************************************************
|
||||
ECHO dir
|
||||
ECHO @ECHO.
|
||||
ECHO @ECHO ********************************************************************************
|
||||
ECHO @ECHO ** The environment is:
|
||||
ECHO @ECHO ********************************************************************************
|
||||
ECHO set
|
||||
ECHO @ECHO.
|
||||
ECHO @ECHO ********************************************************************************
|
||||
ECHO @ECHO ** Edit or replace this script to run custom steps after a successful build:
|
||||
ECHO @ECHO ** %~1
|
||||
ECHO @ECHO ********************************************************************************
|
||||
ECHO @ECHO.
|
||||
) > "%~1"
|
||||
endlocal
|
||||
GOTO :EOF
|
||||
@@ -1,52 +0,0 @@
|
||||
add_subdirectory(admesh)
|
||||
add_subdirectory(avrdude)
|
||||
add_subdirectory(miniz)
|
||||
add_subdirectory(glu-libtess)
|
||||
add_subdirectory(agg)
|
||||
add_subdirectory(libigl)
|
||||
add_subdirectory(hints)
|
||||
add_subdirectory(libnest2d)
|
||||
|
||||
add_library(semver STATIC
|
||||
semver/semver.c
|
||||
semver/semver.h
|
||||
)
|
||||
target_include_directories(semver PUBLIC semver)
|
||||
encoding_check(semver)
|
||||
|
||||
add_library(qoi STATIC
|
||||
qoi/qoilib.c
|
||||
qoi/qoi.h
|
||||
)
|
||||
target_include_directories(qoi PUBLIC qoi)
|
||||
encoding_check(qoi)
|
||||
|
||||
add_library(fastfloat INTERFACE)
|
||||
target_include_directories(fastfloat INTERFACE fast_float)
|
||||
|
||||
add_library(int128 INTERFACE)
|
||||
target_include_directories(int128 INTERFACE int128)
|
||||
|
||||
add_library(localesutils STATIC
|
||||
localesutils/LocalesUtils.cpp
|
||||
localesutils/LocalesUtils.hpp
|
||||
)
|
||||
target_include_directories(localesutils PUBLIC localesutils)
|
||||
target_link_libraries(localesutils PRIVATE fastfloat)
|
||||
|
||||
add_library(ankerl INTERFACE)
|
||||
target_include_directories(ankerl INTERFACE ankerl)
|
||||
|
||||
add_library(stb_dxt INTERFACE)
|
||||
target_include_directories(stb_dxt INTERFACE stb_dxt)
|
||||
|
||||
add_library(stb_image INTERFACE)
|
||||
target_include_directories(stb_image INTERFACE stb_image)
|
||||
|
||||
add_library(tcbspan INTERFACE)
|
||||
target_include_directories(tcbspan INTERFACE tcbspan)
|
||||
|
||||
if (SLIC3R_GUI)
|
||||
add_subdirectory(imgui)
|
||||
add_subdirectory(hidapi)
|
||||
endif ()
|
||||
@@ -1,16 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(admesh)
|
||||
|
||||
add_library(admesh STATIC
|
||||
admesh/connect.cpp
|
||||
admesh/normals.cpp
|
||||
admesh/shared.cpp
|
||||
admesh/stl.h
|
||||
admesh/stl_io.cpp
|
||||
admesh/stlinit.cpp
|
||||
admesh/util.cpp
|
||||
)
|
||||
|
||||
target_include_directories(admesh PUBLIC .)
|
||||
target_link_libraries(admesh PRIVATE boost_headeronly localesutils)
|
||||
target_link_libraries(admesh PUBLIC Eigen3::Eigen)
|
||||
@@ -1,743 +0,0 @@
|
||||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/predef/other/endian.h>
|
||||
#include <boost/log/trivial.hpp>
|
||||
// Boost pool: Don't use mutexes to synchronize memory allocation.
|
||||
#define BOOST_POOL_NO_MT
|
||||
#include <boost/pool/object_pool.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
struct HashEdge {
|
||||
// Key of a hash edge: sorted vertices of the edge.
|
||||
uint32_t key[6];
|
||||
// Compare two keys.
|
||||
bool operator==(const HashEdge &rhs) const { return memcmp(key, rhs.key, sizeof(key)) == 0; }
|
||||
bool operator!=(const HashEdge &rhs) const { return ! (*this == rhs); }
|
||||
int hash(int M) const { return ((key[0] / 11 + key[1] / 7 + key[2] / 3) ^ (key[3] / 11 + key[4] / 7 + key[5] / 3)) % M; }
|
||||
|
||||
// Index of a facet owning this edge.
|
||||
int facet_number;
|
||||
// Index of this edge inside the facet with an index of facet_number.
|
||||
// If this edge is stored backwards, which_edge is increased by 3.
|
||||
int which_edge;
|
||||
HashEdge *next;
|
||||
|
||||
void load_exact(stl_file *stl, const stl_vertex *a, const stl_vertex *b)
|
||||
{
|
||||
{
|
||||
stl_vertex diff = (*a - *b).cwiseAbs();
|
||||
float max_diff = std::max(diff(0), std::max(diff(1), diff(2)));
|
||||
stl->stats.shortest_edge = std::min(max_diff, stl->stats.shortest_edge);
|
||||
}
|
||||
|
||||
// Ensure identical vertex ordering of equal edges.
|
||||
// This method is numerically robust.
|
||||
if (vertex_lower(*a, *b)) {
|
||||
} else {
|
||||
// This edge is loaded backwards.
|
||||
std::swap(a, b);
|
||||
this->which_edge += 3;
|
||||
}
|
||||
memcpy(&this->key[0], a->data(), sizeof(stl_vertex));
|
||||
memcpy(&this->key[3], b->data(), sizeof(stl_vertex));
|
||||
// Switch negative zeros to positive zeros, so memcmp will consider them to be equal.
|
||||
for (size_t i = 0; i < 6; ++ i) {
|
||||
unsigned char *p = (unsigned char*)(this->key + i);
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
if (p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0x80)
|
||||
// Negative zero, switch to positive zero.
|
||||
p[3] = 0;
|
||||
#else /* BOOST_ENDIAN_LITTLE_BYTE */
|
||||
if (p[0] == 0x80 && p[1] == 0 && p[2] == 0 && p[3] == 0)
|
||||
// Negative zero, switch to positive zero.
|
||||
p[0] = 0;
|
||||
#endif /* BOOST_ENDIAN_LITTLE_BYTE */
|
||||
}
|
||||
}
|
||||
|
||||
bool load_nearby(const stl_file *stl, const stl_vertex &a, const stl_vertex &b, float tolerance)
|
||||
{
|
||||
// Index of a grid cell spaced by tolerance.
|
||||
typedef Eigen::Matrix<int32_t, 3, 1, Eigen::DontAlign> Vec3i;
|
||||
Vec3i vertex1 = ((a - stl->stats.min) / tolerance).cast<int32_t>();
|
||||
Vec3i vertex2 = ((b - stl->stats.min) / tolerance).cast<int32_t>();
|
||||
static_assert(sizeof(Vec3i) == 12, "size of Vec3i incorrect");
|
||||
|
||||
if (vertex1 == vertex2)
|
||||
// Both vertices hash to the same value
|
||||
return false;
|
||||
|
||||
// Ensure identical vertex ordering of edges, which vertices land into equal grid cells.
|
||||
// This method is numerically robust.
|
||||
if ((vertex1[0] != vertex2[0]) ?
|
||||
(vertex1[0] < vertex2[0]) :
|
||||
((vertex1[1] != vertex2[1]) ?
|
||||
(vertex1[1] < vertex2[1]) :
|
||||
(vertex1[2] < vertex2[2]))) {
|
||||
memcpy(&this->key[0], vertex1.data(), sizeof(stl_vertex));
|
||||
memcpy(&this->key[3], vertex2.data(), sizeof(stl_vertex));
|
||||
} else {
|
||||
memcpy(&this->key[0], vertex2.data(), sizeof(stl_vertex));
|
||||
memcpy(&this->key[3], vertex1.data(), sizeof(stl_vertex));
|
||||
this->which_edge += 3; /* this edge is loaded backwards */
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool vertex_lower(const stl_vertex &a, const stl_vertex &b) {
|
||||
return (a(0) != b(0)) ? (a(0) < b(0)) :
|
||||
((a(1) != b(1)) ? (a(1) < b(1)) : (a(2) < b(2)));
|
||||
}
|
||||
};
|
||||
|
||||
struct HashTableEdges {
|
||||
HashTableEdges(size_t number_of_faces) {
|
||||
this->M = (int)hash_size_from_nr_faces(number_of_faces);
|
||||
this->heads.assign(this->M, nullptr);
|
||||
this->tail = pool.construct();
|
||||
this->tail->next = this->tail;
|
||||
for (int i = 0; i < this->M; ++ i)
|
||||
this->heads[i] = this->tail;
|
||||
}
|
||||
~HashTableEdges() {
|
||||
#ifndef NDEBUG
|
||||
for (int i = 0; i < this->M; ++ i)
|
||||
for (HashEdge *temp = this->heads[i]; temp != this->tail; temp = temp->next)
|
||||
++ this->freed;
|
||||
this->tail = nullptr;
|
||||
#endif /* NDEBUG */
|
||||
}
|
||||
|
||||
void insert_edge_exact(stl_file *stl, const HashEdge &edge)
|
||||
{
|
||||
this->insert_edge(stl, edge, [stl](const HashEdge& edge1, const HashEdge& edge2) { record_neighbors(stl, edge1, edge2); });
|
||||
}
|
||||
|
||||
void insert_edge_nearby(stl_file *stl, const HashEdge &edge)
|
||||
{
|
||||
this->insert_edge(stl, edge, [stl](const HashEdge& edge1, const HashEdge& edge2) { match_neighbors_nearby(stl, edge1, edge2); });
|
||||
}
|
||||
|
||||
// Hash table on edges
|
||||
std::vector<HashEdge*> heads;
|
||||
HashEdge* tail;
|
||||
int M;
|
||||
boost::object_pool<HashEdge> pool;
|
||||
|
||||
#ifndef NDEBUG
|
||||
size_t malloced = 0;
|
||||
size_t freed = 0;
|
||||
size_t collisions = 0;
|
||||
#endif /* NDEBUG */
|
||||
|
||||
private:
|
||||
static inline size_t hash_size_from_nr_faces(const size_t nr_faces)
|
||||
{
|
||||
// Good primes for addressing a cca. 30 bit space.
|
||||
// https://planetmath.org/goodhashtableprimes
|
||||
static std::vector<uint32_t> primes{ 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741 };
|
||||
// Find a prime number for 50% filling of the shared triangle edges in the mesh.
|
||||
auto it = std::upper_bound(primes.begin(), primes.end(), nr_faces * 3 * 2 - 1);
|
||||
return (it == primes.end()) ? primes.back() : *it;
|
||||
}
|
||||
|
||||
|
||||
// MatchNeighbors(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b)
|
||||
template<typename MatchNeighbors>
|
||||
void insert_edge(stl_file *stl, const HashEdge &edge, MatchNeighbors match_neighbors)
|
||||
{
|
||||
int chain_number = edge.hash(this->M);
|
||||
HashEdge *link = this->heads[chain_number];
|
||||
if (link == this->tail) {
|
||||
// This list doesn't have any edges currently in it. Add this one.
|
||||
HashEdge *new_edge = pool.construct(edge);
|
||||
#ifndef NDEBUG
|
||||
++ this->malloced;
|
||||
#endif /* NDEBUG */
|
||||
new_edge->next = this->tail;
|
||||
this->heads[chain_number] = new_edge;
|
||||
} else if (edges_equal(edge, *link)) {
|
||||
// This is a match. Record result in neighbors list.
|
||||
match_neighbors(edge, *link);
|
||||
// Delete the matched edge from the list.
|
||||
this->heads[chain_number] = link->next;
|
||||
// pool.destroy(link);
|
||||
#ifndef NDEBUG
|
||||
++ this->freed;
|
||||
#endif /* NDEBUG */
|
||||
} else {
|
||||
// Continue through the rest of the list.
|
||||
for (;;) {
|
||||
if (link->next == this->tail) {
|
||||
// This is the last item in the list. Insert a new edge.
|
||||
HashEdge *new_edge = pool.construct();
|
||||
#ifndef NDEBUG
|
||||
++ this->malloced;
|
||||
#endif /* NDEBUG */
|
||||
*new_edge = edge;
|
||||
new_edge->next = this->tail;
|
||||
link->next = new_edge;
|
||||
#ifndef NDEBUG
|
||||
++ this->collisions;
|
||||
#endif /* NDEBUG */
|
||||
break;
|
||||
}
|
||||
if (edges_equal(edge, *link->next)) {
|
||||
// This is a match. Record result in neighbors list.
|
||||
match_neighbors(edge, *link->next);
|
||||
// Delete the matched edge from the list.
|
||||
HashEdge *temp = link->next;
|
||||
link->next = link->next->next;
|
||||
// pool.destroy(temp);
|
||||
#ifndef NDEBUG
|
||||
++ this->freed;
|
||||
#endif /* NDEBUG */
|
||||
break;
|
||||
}
|
||||
// This is not a match. Go to the next link.
|
||||
link = link->next;
|
||||
#ifndef NDEBUG
|
||||
++ this->collisions;
|
||||
#endif /* NDEBUG */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Edges equal for hashing. Edgesof different facet are allowed to be matched.
|
||||
static inline bool edges_equal(const HashEdge &edge_a, const HashEdge &edge_b)
|
||||
{
|
||||
return edge_a.facet_number != edge_b.facet_number && edge_a == edge_b;
|
||||
}
|
||||
|
||||
// Connect edge_a with edge_b, update edge connection statistics.
|
||||
static void record_neighbors(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b)
|
||||
{
|
||||
// Facet a's neighbor is facet b
|
||||
stl->neighbors_start[edge_a.facet_number].neighbor[edge_a.which_edge % 3] = edge_b.facet_number; /* sets the .neighbor part */
|
||||
stl->neighbors_start[edge_a.facet_number].which_vertex_not[edge_a.which_edge % 3] = (edge_b.which_edge + 2) % 3; /* sets the .which_vertex_not part */
|
||||
|
||||
// Facet b's neighbor is facet a
|
||||
stl->neighbors_start[edge_b.facet_number].neighbor[edge_b.which_edge % 3] = edge_a.facet_number; /* sets the .neighbor part */
|
||||
stl->neighbors_start[edge_b.facet_number].which_vertex_not[edge_b.which_edge % 3] = (edge_a.which_edge + 2) % 3; /* sets the .which_vertex_not part */
|
||||
|
||||
if ((edge_a.which_edge < 3 && edge_b.which_edge < 3) || (edge_a.which_edge > 2 && edge_b.which_edge > 2)) {
|
||||
// These facets are oriented in opposite directions, their normals are probably messed up.
|
||||
stl->neighbors_start[edge_a.facet_number].which_vertex_not[edge_a.which_edge % 3] += 3;
|
||||
stl->neighbors_start[edge_b.facet_number].which_vertex_not[edge_b.which_edge % 3] += 3;
|
||||
}
|
||||
|
||||
// Count successful connects:
|
||||
// Total connects:
|
||||
stl->stats.connected_edges += 2;
|
||||
// Count individual connects:
|
||||
switch (stl->neighbors_start[edge_a.facet_number].num_neighbors()) {
|
||||
case 1: ++ stl->stats.connected_facets_1_edge; break;
|
||||
case 2: ++ stl->stats.connected_facets_2_edge; break;
|
||||
case 3: ++ stl->stats.connected_facets_3_edge; break;
|
||||
default: assert(false);
|
||||
}
|
||||
switch (stl->neighbors_start[edge_b.facet_number].num_neighbors()) {
|
||||
case 1: ++ stl->stats.connected_facets_1_edge; break;
|
||||
case 2: ++ stl->stats.connected_facets_2_edge; break;
|
||||
case 3: ++ stl->stats.connected_facets_3_edge; break;
|
||||
default: assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void match_neighbors_nearby(stl_file *stl, const HashEdge &edge_a, const HashEdge &edge_b)
|
||||
{
|
||||
record_neighbors(stl, edge_a, edge_b);
|
||||
|
||||
// Which vertices to change
|
||||
int facet1 = -1;
|
||||
int facet2 = -1;
|
||||
int vertex1, vertex2;
|
||||
stl_vertex new_vertex1, new_vertex2;
|
||||
{
|
||||
int v1a; // pair 1, facet a
|
||||
int v1b; // pair 1, facet b
|
||||
int v2a; // pair 2, facet a
|
||||
int v2b; // pair 2, facet b
|
||||
// Find first pair.
|
||||
if (edge_a.which_edge < 3) {
|
||||
v1a = edge_a.which_edge;
|
||||
v2a = (edge_a.which_edge + 1) % 3;
|
||||
} else {
|
||||
v2a = edge_a.which_edge % 3;
|
||||
v1a = (edge_a.which_edge + 1) % 3;
|
||||
}
|
||||
if (edge_b.which_edge < 3) {
|
||||
v1b = edge_b.which_edge;
|
||||
v2b = (edge_b.which_edge + 1) % 3;
|
||||
} else {
|
||||
v2b = edge_b.which_edge % 3;
|
||||
v1b = (edge_b.which_edge + 1) % 3;
|
||||
}
|
||||
|
||||
// Of the first pair, which vertex, if any, should be changed
|
||||
if (stl->facet_start[edge_a.facet_number].vertex[v1a] != stl->facet_start[edge_b.facet_number].vertex[v1b]) {
|
||||
// These facets are different.
|
||||
if ( (stl->neighbors_start[edge_a.facet_number].neighbor[v1a] == -1)
|
||||
&& (stl->neighbors_start[edge_a.facet_number].neighbor[(v1a + 2) % 3] == -1)) {
|
||||
// This vertex has no neighbors. This is a good one to change.
|
||||
facet1 = edge_a.facet_number;
|
||||
vertex1 = v1a;
|
||||
new_vertex1 = stl->facet_start[edge_b.facet_number].vertex[v1b];
|
||||
} else {
|
||||
facet1 = edge_b.facet_number;
|
||||
vertex1 = v1b;
|
||||
new_vertex1 = stl->facet_start[edge_a.facet_number].vertex[v1a];
|
||||
}
|
||||
}
|
||||
|
||||
// Of the second pair, which vertex, if any, should be changed.
|
||||
if (stl->facet_start[edge_a.facet_number].vertex[v2a] == stl->facet_start[edge_b.facet_number].vertex[v2b]) {
|
||||
// These facets are different.
|
||||
if ( (stl->neighbors_start[edge_a.facet_number].neighbor[v2a] == -1)
|
||||
&& (stl->neighbors_start[edge_a.facet_number].neighbor[(v2a + 2) % 3] == -1)) {
|
||||
// This vertex has no neighbors. This is a good one to change.
|
||||
facet2 = edge_a.facet_number;
|
||||
vertex2 = v2a;
|
||||
new_vertex2 = stl->facet_start[edge_b.facet_number].vertex[v2b];
|
||||
} else {
|
||||
facet2 = edge_b.facet_number;
|
||||
vertex2 = v2b;
|
||||
new_vertex2 = stl->facet_start[edge_a.facet_number].vertex[v2a];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto change_vertices = [stl](int facet_num, int vnot, stl_vertex new_vertex)
|
||||
{
|
||||
int first_facet = facet_num;
|
||||
bool direction = false;
|
||||
|
||||
for (;;) {
|
||||
int pivot_vertex;
|
||||
int next_edge;
|
||||
if (vnot > 2) {
|
||||
if (direction) {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot % 3;
|
||||
}
|
||||
else {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
}
|
||||
direction = !direction;
|
||||
}
|
||||
else {
|
||||
if (direction) {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
}
|
||||
else {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (stl->facet_start[facet_num].vertex[pivot_vertex](0) == new_vertex(0) &&
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](1) == new_vertex(1) &&
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](2) == new_vertex(2))
|
||||
printf("Changing vertex %f,%f,%f: Same !!!\r\n", new_vertex(0), new_vertex(1), new_vertex(2));
|
||||
else {
|
||||
if (stl->facet_start[facet_num].vertex[pivot_vertex](0) != new_vertex(0))
|
||||
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](0),
|
||||
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](0)),
|
||||
new_vertex(0),
|
||||
*reinterpret_cast<const int*>(&new_vertex(0)));
|
||||
if (stl->facet_start[facet_num].vertex[pivot_vertex](1) != new_vertex(1))
|
||||
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](1),
|
||||
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](1)),
|
||||
new_vertex(1),
|
||||
*reinterpret_cast<const int*>(&new_vertex(1)));
|
||||
if (stl->facet_start[facet_num].vertex[pivot_vertex](2) != new_vertex(2))
|
||||
printf("Changing coordinate x, vertex %e (0x%08x) to %e(0x%08x)\r\n",
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex](2),
|
||||
*reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex](2)),
|
||||
new_vertex(2),
|
||||
*reinterpret_cast<const int*>(&new_vertex(2)));
|
||||
}
|
||||
#endif
|
||||
stl->facet_start[facet_num].vertex[pivot_vertex] = new_vertex;
|
||||
vnot = stl->neighbors_start[facet_num].which_vertex_not[next_edge];
|
||||
facet_num = stl->neighbors_start[facet_num].neighbor[next_edge];
|
||||
if (facet_num == -1)
|
||||
break;
|
||||
|
||||
if (facet_num == first_facet) {
|
||||
// back to the beginning
|
||||
BOOST_LOG_TRIVIAL(info) << "Back to the first facet changing vertices: probably a mobius part. Try using a smaller tolerance or don't do a nearby check.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (facet1 != -1) {
|
||||
int vnot1 = (facet1 == edge_a.facet_number) ?
|
||||
(edge_a.which_edge + 2) % 3 :
|
||||
(edge_b.which_edge + 2) % 3;
|
||||
if (((vnot1 + 2) % 3) == vertex1)
|
||||
vnot1 += 3;
|
||||
change_vertices(facet1, vnot1, new_vertex1);
|
||||
}
|
||||
if (facet2 != -1) {
|
||||
int vnot2 = (facet2 == edge_a.facet_number) ?
|
||||
(edge_a.which_edge + 2) % 3 :
|
||||
(edge_b.which_edge + 2) % 3;
|
||||
if (((vnot2 + 2) % 3) == vertex2)
|
||||
vnot2 += 3;
|
||||
change_vertices(facet2, vnot2, new_vertex2);
|
||||
}
|
||||
stl->stats.edges_fixed += 2;
|
||||
}
|
||||
};
|
||||
|
||||
// This function builds the neighbors list. No modifications are made
|
||||
// to any of the facets. The edges are said to match only if all six
|
||||
// floats of the first edge matches all six floats of the second edge.
|
||||
void stl_check_facets_exact(stl_file *stl)
|
||||
{
|
||||
assert(stl->facet_start.size() == stl->neighbors_start.size());
|
||||
|
||||
stl->stats.connected_edges = 0;
|
||||
stl->stats.connected_facets_1_edge = 0;
|
||||
stl->stats.connected_facets_2_edge = 0;
|
||||
stl->stats.connected_facets_3_edge = 0;
|
||||
|
||||
// If any two of the three vertices are found to be exactally the same, call them degenerate and remove the facet.
|
||||
// Do it before the next step, as the next step stores references to the face indices in the hash tables and removing a facet
|
||||
// will break the references.
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets;) {
|
||||
stl_facet &facet = stl->facet_start[i];
|
||||
if (facet.vertex[0] == facet.vertex[1] || facet.vertex[1] == facet.vertex[2] || facet.vertex[0] == facet.vertex[2]) {
|
||||
// Remove the degenerate facet.
|
||||
facet = stl->facet_start[-- stl->stats.number_of_facets];
|
||||
stl->facet_start.pop_back();
|
||||
stl->neighbors_start.pop_back();
|
||||
stl->stats.facets_removed += 1;
|
||||
stl->stats.degenerate_facets += 1;
|
||||
} else
|
||||
++ i;
|
||||
}
|
||||
|
||||
// Initialize hash table.
|
||||
HashTableEdges hash_table(stl->stats.number_of_facets);
|
||||
for (auto &neighbor : stl->neighbors_start)
|
||||
neighbor.reset();
|
||||
|
||||
// Connect neighbor edges.
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
const stl_facet &facet = stl->facet_start[i];
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
HashEdge edge;
|
||||
edge.facet_number = i;
|
||||
edge.which_edge = j;
|
||||
edge.load_exact(stl, &facet.vertex[j], &facet.vertex[(j + 1) % 3]);
|
||||
hash_table.insert_edge_exact(stl, edge);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("Number of faces: %d, number of manifold edges: %d, number of connected edges: %d, number of unconnected edges: %d\r\n",
|
||||
stl->stats.number_of_facets, stl->stats.number_of_facets * 3,
|
||||
stl->stats.connected_edges, stl->stats.number_of_facets * 3 - stl->stats.connected_edges);
|
||||
#endif
|
||||
}
|
||||
|
||||
void stl_check_facets_nearby(stl_file *stl, float tolerance)
|
||||
{
|
||||
assert(stl->stats.connected_facets_3_edge <= stl->stats.connected_facets_2_edge);
|
||||
assert(stl->stats.connected_facets_2_edge <= stl->stats.connected_facets_1_edge);
|
||||
assert(stl->stats.connected_facets_1_edge <= stl->stats.number_of_facets);
|
||||
|
||||
if (stl->stats.connected_facets_3_edge == stl->stats.number_of_facets)
|
||||
// No need to check any further. All facets are connected.
|
||||
return;
|
||||
|
||||
HashTableEdges hash_table(stl->stats.number_of_facets);
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
//FIXME is the copy necessary?
|
||||
stl_facet facet = stl->facet_start[i];
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (stl->neighbors_start[i].neighbor[j] == -1) {
|
||||
HashEdge edge;
|
||||
edge.facet_number = i;
|
||||
edge.which_edge = j;
|
||||
if (edge.load_nearby(stl, facet.vertex[j], facet.vertex[(j + 1) % 3], tolerance))
|
||||
// Only insert edges that have different keys.
|
||||
hash_table.insert_edge_nearby(stl, edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stl_remove_unconnected_facets(stl_file *stl)
|
||||
{
|
||||
// A couple of things need to be done here. One is to remove any completely unconnected facets (0 edges connected) since these are
|
||||
// useless and could be completely wrong. The second thing that needs to be done is to remove any degenerate facets that were created during
|
||||
// stl_check_facets_nearby().
|
||||
auto remove_facet = [stl](int facet_number)
|
||||
{
|
||||
++ stl->stats.facets_removed;
|
||||
/* Update list of connected edges */
|
||||
stl_neighbors &neighbors = stl->neighbors_start[facet_number];
|
||||
// Update statistics on unconnected triangle edges.
|
||||
switch (neighbors.num_neighbors()) {
|
||||
case 3: -- stl->stats.connected_facets_3_edge; // fall through
|
||||
case 2: -- stl->stats.connected_facets_2_edge; // fall through
|
||||
case 1: -- stl->stats.connected_facets_1_edge; // fall through
|
||||
case 0: break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
if (facet_number < int(-- stl->stats.number_of_facets)) {
|
||||
// Removing a face, which was not the last one.
|
||||
// Copy the face and neighborship from the last face to facet_number.
|
||||
stl->facet_start[facet_number] = stl->facet_start[stl->stats.number_of_facets];
|
||||
neighbors = stl->neighbors_start[stl->stats.number_of_facets];
|
||||
// Update neighborship of faces, which used to point to the last face, now moved to facet_number.
|
||||
for (int i = 0; i < 3; ++ i)
|
||||
if (neighbors.neighbor[i] != -1) {
|
||||
int &other_face_idx = stl->neighbors_start[neighbors.neighbor[i]].neighbor[(neighbors.which_vertex_not[i] + 1) % 3];
|
||||
if (other_face_idx != stl->stats.number_of_facets) {
|
||||
BOOST_LOG_TRIVIAL(info) << "in remove_facet: neighbor = " << other_face_idx << " numfacets = " << stl->stats.number_of_facets << " this is wrong";
|
||||
return;
|
||||
}
|
||||
other_face_idx = facet_number;
|
||||
}
|
||||
}
|
||||
|
||||
stl->facet_start.pop_back();
|
||||
stl->neighbors_start.pop_back();
|
||||
};
|
||||
|
||||
auto remove_degenerate = [stl, remove_facet](int facet)
|
||||
{
|
||||
// Update statistics on face connectivity after one edge was disconnected on the facet "facet_num".
|
||||
auto update_connects_remove_1 = [stl](int facet_num) {
|
||||
switch (stl->neighbors_start[facet_num].num_neighbors()) {
|
||||
case 0: assert(false); break;
|
||||
case 1: -- stl->stats.connected_facets_1_edge; break;
|
||||
case 2: -- stl->stats.connected_facets_2_edge; break;
|
||||
case 3: -- stl->stats.connected_facets_3_edge; break;
|
||||
default: assert(false);
|
||||
}
|
||||
};
|
||||
|
||||
int edge_to_collapse = 0;
|
||||
if (stl->facet_start[facet].vertex[0] == stl->facet_start[facet].vertex[1]) {
|
||||
if (stl->facet_start[facet].vertex[1] == stl->facet_start[facet].vertex[2]) {
|
||||
// All 3 vertices are equal. Collapse the edge with no neighbor if it exists.
|
||||
const int *nbr = stl->neighbors_start[facet].neighbor;
|
||||
edge_to_collapse = (nbr[0] == -1) ? 0 : (nbr[1] == -1) ? 1 : 2;
|
||||
} else {
|
||||
edge_to_collapse = 0;
|
||||
}
|
||||
} else if (stl->facet_start[facet].vertex[1] == stl->facet_start[facet].vertex[2]) {
|
||||
edge_to_collapse = 1;
|
||||
} else if (stl->facet_start[facet].vertex[2] == stl->facet_start[facet].vertex[0]) {
|
||||
edge_to_collapse = 2;
|
||||
} else {
|
||||
// No degenerate. Function shouldn't have been called.
|
||||
return;
|
||||
}
|
||||
|
||||
int edge[3] = { (edge_to_collapse + 1) % 3, (edge_to_collapse + 2) % 3, edge_to_collapse };
|
||||
int neighbor[] = {
|
||||
stl->neighbors_start[facet].neighbor[edge[0]],
|
||||
stl->neighbors_start[facet].neighbor[edge[1]],
|
||||
stl->neighbors_start[facet].neighbor[edge[2]]
|
||||
};
|
||||
int vnot[] = {
|
||||
stl->neighbors_start[facet].which_vertex_not[edge[0]],
|
||||
stl->neighbors_start[facet].which_vertex_not[edge[1]],
|
||||
stl->neighbors_start[facet].which_vertex_not[edge[2]]
|
||||
};
|
||||
|
||||
// Update statistics on edge connectivity.
|
||||
if ((neighbor[0] == -1) && (neighbor[1] != -1))
|
||||
update_connects_remove_1(neighbor[1]);
|
||||
if ((neighbor[1] == -1) && (neighbor[0] != -1))
|
||||
update_connects_remove_1(neighbor[0]);
|
||||
|
||||
if (neighbor[0] >= 0) {
|
||||
if (neighbor[1] >= 0) {
|
||||
// Adjust the "flip" flag for the which_vertex_not values.
|
||||
if (vnot[0] > 2) {
|
||||
if (vnot[1] > 2) {
|
||||
// The face to be removed has its normal flipped compared to the left & right neighbors, therefore after removing this face
|
||||
// the two remaining neighbors will be oriented correctly.
|
||||
vnot[0] -= 3;
|
||||
vnot[1] -= 3;
|
||||
} else
|
||||
// One neighbor has its normal inverted compared to the face to be removed, the other is oriented equally.
|
||||
// After removal, the two neighbors will have their normals flipped.
|
||||
vnot[1] += 3;
|
||||
} else if (vnot[1] > 2)
|
||||
// One neighbor has its normal inverted compared to the face to be removed, the other is oriented equally.
|
||||
// After removal, the two neighbors will have their normals flipped.
|
||||
vnot[0] += 3;
|
||||
}
|
||||
stl->neighbors_start[neighbor[0]].neighbor[(vnot[0] + 1) % 3] = (neighbor[0] == neighbor[1]) ? -1 : neighbor[1];
|
||||
stl->neighbors_start[neighbor[0]].which_vertex_not[(vnot[0] + 1) % 3] = vnot[1];
|
||||
}
|
||||
if (neighbor[1] >= 0) {
|
||||
stl->neighbors_start[neighbor[1]].neighbor[(vnot[1] + 1) % 3] = (neighbor[0] == neighbor[1]) ? -1 : neighbor[0];
|
||||
stl->neighbors_start[neighbor[1]].which_vertex_not[(vnot[1] + 1) % 3] = vnot[0];
|
||||
}
|
||||
if (neighbor[2] >= 0) {
|
||||
update_connects_remove_1(neighbor[2]);
|
||||
stl->neighbors_start[neighbor[2]].neighbor[(vnot[2] + 1) % 3] = -1;
|
||||
}
|
||||
|
||||
remove_facet(facet);
|
||||
};
|
||||
|
||||
// remove degenerate facets
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets;)
|
||||
if (stl->facet_start[i].vertex[0] == stl->facet_start[i].vertex[1] ||
|
||||
stl->facet_start[i].vertex[0] == stl->facet_start[i].vertex[2] ||
|
||||
stl->facet_start[i].vertex[1] == stl->facet_start[i].vertex[2]) {
|
||||
remove_degenerate(i);
|
||||
// assert(stl_validate(stl));
|
||||
} else
|
||||
++ i;
|
||||
|
||||
if (stl->stats.connected_facets_1_edge < (int)stl->stats.number_of_facets) {
|
||||
// There are some faces with no connected edge at all. Remove completely unconnected facets.
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets;)
|
||||
if (stl->neighbors_start[i].num_neighbors() == 0) {
|
||||
// This facet is completely unconnected. Remove it.
|
||||
remove_facet(i);
|
||||
assert(stl_validate(stl));
|
||||
} else
|
||||
++ i;
|
||||
}
|
||||
}
|
||||
|
||||
void stl_fill_holes(stl_file *stl)
|
||||
{
|
||||
// Insert all unconnected edges into hash list.
|
||||
HashTableEdges hash_table(stl->stats.number_of_facets);
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_facet facet = stl->facet_start[i];
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
if(stl->neighbors_start[i].neighbor[j] != -1)
|
||||
continue;
|
||||
HashEdge edge;
|
||||
edge.facet_number = i;
|
||||
edge.which_edge = j;
|
||||
edge.load_exact(stl, &facet.vertex[j], &facet.vertex[(j + 1) % 3]);
|
||||
hash_table.insert_edge_exact(stl, edge);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_facet facet = stl->facet_start[i];
|
||||
int neighbors_initial[3] = { stl->neighbors_start[i].neighbor[0], stl->neighbors_start[i].neighbor[1], stl->neighbors_start[i].neighbor[2] };
|
||||
int first_facet = i;
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
if (stl->neighbors_start[i].neighbor[j] != -1)
|
||||
continue;
|
||||
|
||||
stl_facet new_facet;
|
||||
new_facet.vertex[0] = facet.vertex[j];
|
||||
new_facet.vertex[1] = facet.vertex[(j + 1) % 3];
|
||||
bool direction = neighbors_initial[(j + 2) % 3] == -1;
|
||||
int facet_num = i;
|
||||
int vnot = (j + 2) % 3;
|
||||
|
||||
for (;;) {
|
||||
int pivot_vertex = 0;
|
||||
int next_edge = 0;
|
||||
if (vnot > 2) {
|
||||
if (direction) {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot % 3;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
}
|
||||
direction = ! direction;
|
||||
} else {
|
||||
if(direction == 0) {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
}
|
||||
}
|
||||
|
||||
int next_facet = stl->neighbors_start[facet_num].neighbor[next_edge];
|
||||
if (next_facet == -1) {
|
||||
new_facet.vertex[2] = stl->facet_start[facet_num].vertex[vnot % 3];
|
||||
stl_add_facet(stl, &new_facet);
|
||||
for (int k = 0; k < 3; ++ k) {
|
||||
HashEdge edge;
|
||||
edge.facet_number = stl->stats.number_of_facets - 1;
|
||||
edge.which_edge = k;
|
||||
edge.load_exact(stl, &new_facet.vertex[k], &new_facet.vertex[(k + 1) % 3]);
|
||||
hash_table.insert_edge_exact(stl, edge);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
vnot = stl->neighbors_start[facet_num].which_vertex_not[next_edge];
|
||||
facet_num = next_facet;
|
||||
|
||||
if (facet_num == first_facet) {
|
||||
// back to the beginning
|
||||
BOOST_LOG_TRIVIAL(info) << "Back to the first facet filling holes: probably a mobius part. Try using a smaller tolerance or don't do a nearby check.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stl_add_facet(stl_file *stl, const stl_facet *new_facet)
|
||||
{
|
||||
assert(stl->facet_start.size() == stl->stats.number_of_facets);
|
||||
assert(stl->neighbors_start.size() == stl->stats.number_of_facets);
|
||||
stl->facet_start.emplace_back(*new_facet);
|
||||
// note that the normal vector is not set here, just initialized to 0.
|
||||
stl->facet_start[stl->stats.number_of_facets].normal = stl_normal::Zero();
|
||||
stl->neighbors_start.emplace_back();
|
||||
++ stl->stats.facets_added;
|
||||
++ stl->stats.number_of_facets;
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
// Boost pool: Don't use mutexes to synchronize memory allocation.
|
||||
#define BOOST_POOL_NO_MT
|
||||
#include <boost/pool/object_pool.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
static void reverse_facet(stl_file *stl, int facet_num)
|
||||
{
|
||||
++ stl->stats.facets_reversed;
|
||||
|
||||
int neighbor[3] = { stl->neighbors_start[facet_num].neighbor[0], stl->neighbors_start[facet_num].neighbor[1], stl->neighbors_start[facet_num].neighbor[2] };
|
||||
int vnot[3] = { stl->neighbors_start[facet_num].which_vertex_not[0], stl->neighbors_start[facet_num].which_vertex_not[1], stl->neighbors_start[facet_num].which_vertex_not[2] };
|
||||
|
||||
// reverse the facet
|
||||
stl_vertex tmp_vertex = stl->facet_start[facet_num].vertex[0];
|
||||
stl->facet_start[facet_num].vertex[0] = stl->facet_start[facet_num].vertex[1];
|
||||
stl->facet_start[facet_num].vertex[1] = tmp_vertex;
|
||||
|
||||
// fix the vnots of the neighboring facets
|
||||
if (neighbor[0] != -1)
|
||||
stl->neighbors_start[neighbor[0]].which_vertex_not[(vnot[0] + 1) % 3] = (stl->neighbors_start[neighbor[0]].which_vertex_not[(vnot[0] + 1) % 3] + 3) % 6;
|
||||
if (neighbor[1] != -1)
|
||||
stl->neighbors_start[neighbor[1]].which_vertex_not[(vnot[1] + 1) % 3] = (stl->neighbors_start[neighbor[1]].which_vertex_not[(vnot[1] + 1) % 3] + 4) % 6;
|
||||
if (neighbor[2] != -1)
|
||||
stl->neighbors_start[neighbor[2]].which_vertex_not[(vnot[2] + 1) % 3] = (stl->neighbors_start[neighbor[2]].which_vertex_not[(vnot[2] + 1) % 3] + 2) % 6;
|
||||
|
||||
// swap the neighbors of the facet that is being reversed
|
||||
stl->neighbors_start[facet_num].neighbor[1] = neighbor[2];
|
||||
stl->neighbors_start[facet_num].neighbor[2] = neighbor[1];
|
||||
|
||||
// swap the vnots of the facet that is being reversed
|
||||
stl->neighbors_start[facet_num].which_vertex_not[1] = vnot[2];
|
||||
stl->neighbors_start[facet_num].which_vertex_not[2] = vnot[1];
|
||||
|
||||
// reverse the values of the vnots of the facet that is being reversed
|
||||
stl->neighbors_start[facet_num].which_vertex_not[0] = (stl->neighbors_start[facet_num].which_vertex_not[0] + 3) % 6;
|
||||
stl->neighbors_start[facet_num].which_vertex_not[1] = (stl->neighbors_start[facet_num].which_vertex_not[1] + 3) % 6;
|
||||
stl->neighbors_start[facet_num].which_vertex_not[2] = (stl->neighbors_start[facet_num].which_vertex_not[2] + 3) % 6;
|
||||
}
|
||||
|
||||
// Returns true if the normal was flipped.
|
||||
static bool check_normal_vector(stl_file *stl, int facet_num, int normal_fix_flag)
|
||||
{
|
||||
stl_facet *facet = &stl->facet_start[facet_num];
|
||||
|
||||
stl_normal normal;
|
||||
stl_calculate_normal(normal, facet);
|
||||
stl_normalize_vector(normal);
|
||||
stl_normal normal_dif = (normal - facet->normal).cwiseAbs();
|
||||
|
||||
const float eps = 0.001f;
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
// Normal is within tolerance. It is not really necessary to change the values here, but just for consistency, I will.
|
||||
facet->normal = normal;
|
||||
return false;
|
||||
}
|
||||
|
||||
stl_normal test_norm = facet->normal;
|
||||
stl_normalize_vector(test_norm);
|
||||
normal_dif = (normal - test_norm).cwiseAbs();
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
// The normal is not within tolerance, but direction is OK.
|
||||
if (normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
++ stl->stats.normals_fixed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
test_norm *= -1.f;
|
||||
normal_dif = (normal - test_norm).cwiseAbs();
|
||||
if (normal_dif(0) < eps && normal_dif(1) < eps && normal_dif(2) < eps) {
|
||||
// The normal is not within tolerance and backwards.
|
||||
if (normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
++ stl->stats.normals_fixed;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (normal_fix_flag) {
|
||||
facet->normal = normal;
|
||||
++ stl->stats.normals_fixed;
|
||||
}
|
||||
// Status is unknown.
|
||||
return false;
|
||||
}
|
||||
|
||||
void stl_fix_normal_directions(stl_file *stl)
|
||||
{
|
||||
// This may happen for malformed models, see: https://github.com/QIDITECH/QIDISlicer/issues/2209
|
||||
if (stl->stats.number_of_facets == 0)
|
||||
return;
|
||||
|
||||
struct stl_normal {
|
||||
int facet_num;
|
||||
stl_normal *next;
|
||||
};
|
||||
|
||||
// Initialize linked list.
|
||||
boost::object_pool<stl_normal> pool;
|
||||
stl_normal *head = pool.construct();
|
||||
stl_normal *tail = pool.construct();
|
||||
head->next = tail;
|
||||
tail->next = tail;
|
||||
|
||||
// Initialize list that keeps track of already fixed facets.
|
||||
std::vector<char> norm_sw(stl->stats.number_of_facets, 0);
|
||||
// Initialize list that keeps track of reversed facets.
|
||||
std::vector<int> reversed_ids;
|
||||
reversed_ids.reserve(stl->stats.number_of_facets);
|
||||
|
||||
int facet_num = 0;
|
||||
// If normal vector is not within tolerance and backwards:
|
||||
// Arbitrarily starts at face 0. If this one is wrong, we're screwed. Thankfully, the chances
|
||||
// of it being wrong randomly are low if most of the triangles are right:
|
||||
if (check_normal_vector(stl, 0, 0)) {
|
||||
reverse_facet(stl, 0);
|
||||
reversed_ids.emplace_back(0);
|
||||
}
|
||||
|
||||
// Say that we've fixed this facet:
|
||||
norm_sw[facet_num] = 1;
|
||||
int checked = 1;
|
||||
|
||||
for (;;) {
|
||||
// Add neighbors_to_list. Add unconnected neighbors to the list.
|
||||
bool force_exit = false;
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
// Reverse the neighboring facets if necessary.
|
||||
if (stl->neighbors_start[facet_num].which_vertex_not[j] > 2) {
|
||||
// If the facet has a neighbor that is -1, it means that edge isn't shared by another facet
|
||||
if (stl->neighbors_start[facet_num].neighbor[j] != -1) {
|
||||
if (norm_sw[stl->neighbors_start[facet_num].neighbor[j]] == 1) {
|
||||
// trying to modify a facet already marked as fixed, revert all changes made until now and exit (fixes: #716, #574, #413, #269, #262, #259, #230, #228, #206)
|
||||
for (int id = int(reversed_ids.size()) - 1; id >= 0; -- id)
|
||||
reverse_facet(stl, reversed_ids[id]);
|
||||
force_exit = true;
|
||||
break;
|
||||
}
|
||||
reverse_facet(stl, stl->neighbors_start[facet_num].neighbor[j]);
|
||||
reversed_ids.emplace_back(stl->neighbors_start[facet_num].neighbor[j]);
|
||||
}
|
||||
}
|
||||
// If this edge of the facet is connected:
|
||||
if (stl->neighbors_start[facet_num].neighbor[j] != -1) {
|
||||
// If we haven't fixed this facet yet, add it to the list:
|
||||
if (norm_sw[stl->neighbors_start[facet_num].neighbor[j]] != 1) {
|
||||
// Add node to beginning of list.
|
||||
stl_normal *newn = pool.construct();
|
||||
newn->facet_num = stl->neighbors_start[facet_num].neighbor[j];
|
||||
newn->next = head->next;
|
||||
head->next = newn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// an error occourred, quit the for loop and exit
|
||||
if (force_exit)
|
||||
break;
|
||||
|
||||
// Get next facet to fix from top of list.
|
||||
if (head->next != tail) {
|
||||
facet_num = head->next->facet_num;
|
||||
assert(facet_num < stl->stats.number_of_facets);
|
||||
if (norm_sw[facet_num] != 1) { // If facet is in list mutiple times
|
||||
norm_sw[facet_num] = 1; // Record this one as being fixed.
|
||||
++ checked;
|
||||
}
|
||||
stl_normal *temp = head->next; // Delete this facet from the list.
|
||||
head->next = head->next->next;
|
||||
// pool.destroy(temp);
|
||||
} else { // If we ran out of facets to fix: All of the facets in this part have been fixed.
|
||||
++ stl->stats.number_of_parts;
|
||||
if (checked >= int(stl->stats.number_of_facets))
|
||||
// All of the facets have been checked. Bail out.
|
||||
break;
|
||||
// There is another part here. Find it and continue.
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
if (norm_sw[i] == 0) {
|
||||
// This is the first facet of the next part.
|
||||
facet_num = i;
|
||||
if (check_normal_vector(stl, i, 0)) {
|
||||
reverse_facet(stl, i);
|
||||
reversed_ids.emplace_back(i);
|
||||
}
|
||||
norm_sw[facet_num] = 1;
|
||||
++ checked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pool.destroy(head);
|
||||
// pool.destroy(tail);
|
||||
}
|
||||
|
||||
void stl_fix_normal_values(stl_file *stl)
|
||||
{
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
check_normal_vector(stl, i, 1);
|
||||
}
|
||||
|
||||
void stl_reverse_all_facets(stl_file *stl)
|
||||
{
|
||||
stl_normal normal;
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
reverse_facet(stl, i);
|
||||
stl_calculate_normal(normal, &stl->facet_start[i]);
|
||||
stl_normalize_vector(normal);
|
||||
stl->facet_start[i].normal = normal;
|
||||
}
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
#include <LocalesUtils.hpp>
|
||||
|
||||
void stl_generate_shared_vertices(stl_file *stl, indexed_triangle_set &its)
|
||||
{
|
||||
// 3 indices to vertex per face
|
||||
its.indices.assign(stl->stats.number_of_facets, stl_triangle_vertex_indices(-1, -1, -1));
|
||||
// Shared vertices (3D coordinates)
|
||||
its.vertices.clear();
|
||||
its.vertices.reserve(stl->stats.number_of_facets / 2);
|
||||
|
||||
// A degenerate mesh may contain loops: Traversing a fan will end up in an endless loop
|
||||
// while never reaching the starting face. To avoid these endless loops, traversed faces at each fan traversal
|
||||
// are marked with a unique fan_traversal_stamp.
|
||||
unsigned int fan_traversal_stamp = 0;
|
||||
std::vector<unsigned int> fan_traversal_facet_visited(stl->stats.number_of_facets, 0);
|
||||
|
||||
for (uint32_t facet_idx = 0; facet_idx < stl->stats.number_of_facets; ++ facet_idx) {
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
if (its.indices[facet_idx][j] != -1)
|
||||
// Shared vertex was already assigned.
|
||||
continue;
|
||||
// Create a new shared vertex.
|
||||
its.vertices.emplace_back(stl->facet_start[facet_idx].vertex[j]);
|
||||
// Traverse the fan around the j-th vertex of the i-th face, assign the newly created shared vertex index to all the neighboring triangles in the triangle fan.
|
||||
int facet_in_fan_idx = facet_idx;
|
||||
bool edge_direction = false;
|
||||
bool traversal_reversed = false;
|
||||
int vnot = (j + 2) % 3;
|
||||
// Increase the
|
||||
++ fan_traversal_stamp;
|
||||
for (;;) {
|
||||
// Next edge on facet_in_fan_idx to be traversed. The edge is indexed by its starting vertex index.
|
||||
int next_edge = 0;
|
||||
// Vertex index in facet_in_fan_idx, which is being pivoted around, and which is being assigned a new shared vertex.
|
||||
int pivot_vertex = 0;
|
||||
if (vnot > 2) {
|
||||
// The edge of facet_in_fan_idx opposite to vnot is equally oriented, therefore
|
||||
// the neighboring facet is flipped.
|
||||
if (! edge_direction) {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot % 3;
|
||||
}
|
||||
edge_direction = ! edge_direction;
|
||||
} else {
|
||||
// The neighboring facet is correctly oriented.
|
||||
if (! edge_direction) {
|
||||
pivot_vertex = (vnot + 1) % 3;
|
||||
next_edge = vnot;
|
||||
} else {
|
||||
pivot_vertex = (vnot + 2) % 3;
|
||||
next_edge = pivot_vertex;
|
||||
}
|
||||
}
|
||||
its.indices[facet_in_fan_idx][pivot_vertex] = its.vertices.size() - 1;
|
||||
fan_traversal_facet_visited[facet_in_fan_idx] = fan_traversal_stamp;
|
||||
|
||||
// next_edge is an index of the starting vertex of the edge, not an index of the opposite vertex to the edge!
|
||||
int next_facet = stl->neighbors_start[facet_in_fan_idx].neighbor[next_edge];
|
||||
if (next_facet == -1) {
|
||||
// No neighbor going in the current direction.
|
||||
if (traversal_reversed) {
|
||||
// Went to one limit, then turned back and reached the other limit. Quit the fan traversal.
|
||||
break;
|
||||
} else {
|
||||
// Reached the first limit. Now try to reverse and traverse up to the other limit.
|
||||
edge_direction = true;
|
||||
vnot = (j + 1) % 3;
|
||||
traversal_reversed = true;
|
||||
facet_in_fan_idx = facet_idx;
|
||||
}
|
||||
} else if (next_facet == facet_idx) {
|
||||
// Traversed a closed fan all around.
|
||||
// assert(! traversal_reversed);
|
||||
break;
|
||||
} else if (next_facet >= (int)stl->stats.number_of_facets) {
|
||||
// The mesh is not valid!
|
||||
// assert(false);
|
||||
break;
|
||||
} else if (fan_traversal_facet_visited[next_facet] == fan_traversal_stamp) {
|
||||
// Traversed a closed fan all around, but did not reach the starting face.
|
||||
// This indicates an invalid geometry (non-manifold).
|
||||
//assert(false);
|
||||
break;
|
||||
} else {
|
||||
// Continue traversal.
|
||||
// next_edge is an index of the starting vertex of the edge, not an index of the opposite vertex to the edge!
|
||||
vnot = stl->neighbors_start[facet_in_fan_idx].which_vertex_not[next_edge];
|
||||
facet_in_fan_idx = next_facet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool its_write_off(const indexed_triangle_set &its, const char *file)
|
||||
{
|
||||
Slic3r::CNumericLocalesSetter locales_setter;
|
||||
/* Open the file */
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_ascii: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "OFF\n");
|
||||
fprintf(fp, "%d %d 0\n", (int)its.vertices.size(), (int)its.indices.size());
|
||||
for (int i = 0; i < its.vertices.size(); ++ i)
|
||||
fprintf(fp, "\t%f %f %f\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2));
|
||||
for (uint32_t i = 0; i < its.indices.size(); ++ i)
|
||||
fprintf(fp, "\t3 %d %d %d\n", its.indices[i][0], its.indices[i][1], its.indices[i][2]);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool its_write_vrml(const indexed_triangle_set &its, const char *file)
|
||||
{
|
||||
Slic3r::CNumericLocalesSetter locales_setter;
|
||||
/* Open the file */
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_vrml: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "#VRML V1.0 ascii\n\n");
|
||||
fprintf(fp, "Separator {\n");
|
||||
fprintf(fp, "\tDEF STLShape ShapeHints {\n");
|
||||
fprintf(fp, "\t\tvertexOrdering COUNTERCLOCKWISE\n");
|
||||
fprintf(fp, "\t\tfaceType CONVEX\n");
|
||||
fprintf(fp, "\t\tshapeType SOLID\n");
|
||||
fprintf(fp, "\t\tcreaseAngle 0.0\n");
|
||||
fprintf(fp, "\t}\n");
|
||||
fprintf(fp, "\tDEF STLModel Separator {\n");
|
||||
fprintf(fp, "\t\tDEF STLColor Material {\n");
|
||||
fprintf(fp, "\t\t\temissiveColor 0.700000 0.700000 0.000000\n");
|
||||
fprintf(fp, "\t\t}\n");
|
||||
fprintf(fp, "\t\tDEF STLVertices Coordinate3 {\n");
|
||||
fprintf(fp, "\t\t\tpoint [\n");
|
||||
|
||||
int i = 0;
|
||||
for (; i + 1 < its.vertices.size(); ++ i)
|
||||
fprintf(fp, "\t\t\t\t%f %f %f,\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2));
|
||||
fprintf(fp, "\t\t\t\t%f %f %f]\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2));
|
||||
fprintf(fp, "\t\t}\n");
|
||||
fprintf(fp, "\t\tDEF STLTriangles IndexedFaceSet {\n");
|
||||
fprintf(fp, "\t\t\tcoordIndex [\n");
|
||||
|
||||
for (size_t i = 0; i + 1 < its.indices.size(); ++ i)
|
||||
fprintf(fp, "\t\t\t\t%d, %d, %d, -1,\n", its.indices[i][0], its.indices[i][1], its.indices[i][2]);
|
||||
fprintf(fp, "\t\t\t\t%d, %d, %d, -1]\n", its.indices[i][0], its.indices[i][1], its.indices[i][2]);
|
||||
fprintf(fp, "\t\t}\n");
|
||||
fprintf(fp, "\t}\n");
|
||||
fprintf(fp, "}\n");
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool its_write_obj(const indexed_triangle_set &its, const char *file)
|
||||
{
|
||||
Slic3r::CNumericLocalesSetter locales_setter;
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_obj: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < its.vertices.size(); ++ i)
|
||||
fprintf(fp, "v %f %f %f\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2));
|
||||
for (size_t i = 0; i < its.indices.size(); ++ i)
|
||||
fprintf(fp, "f %d %d %d\n", its.indices[i][0]+1, its.indices[i][1]+1, its.indices[i][2]+1);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool its_write_obj(const indexed_triangle_set& its, const std::vector<obj_color> &color, const char* file)
|
||||
{
|
||||
Slic3r::CNumericLocalesSetter locales_setter;
|
||||
FILE* fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_obj: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < its.vertices.size(); ++i)
|
||||
fprintf(fp, "v %f %f %f %f %f %f\n",
|
||||
its.vertices[i](0),
|
||||
its.vertices[i](1),
|
||||
its.vertices[i](2),
|
||||
color[i](0),
|
||||
color[i](1),
|
||||
color[i](2));
|
||||
for (size_t i = 0; i < its.indices.size(); ++i)
|
||||
fprintf(fp, "f %d %d %d\n",
|
||||
its.indices[i][0] + 1,
|
||||
its.indices[i][1] + 1,
|
||||
its.indices[i][2] + 1);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check validity of the mesh, assert on error.
|
||||
bool stl_validate(const stl_file *stl, const indexed_triangle_set &its)
|
||||
{
|
||||
assert(! stl->facet_start.empty());
|
||||
assert(stl->facet_start.size() == stl->stats.number_of_facets);
|
||||
assert(stl->neighbors_start.size() == stl->stats.number_of_facets);
|
||||
assert(stl->facet_start.size() == stl->neighbors_start.size());
|
||||
assert(! stl->neighbors_start.empty());
|
||||
assert((its.indices.empty()) == (its.vertices.empty()));
|
||||
assert(stl->stats.number_of_facets > 0);
|
||||
assert(its.vertices.empty() || its.indices.size() == stl->stats.number_of_facets);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Verify validity of neighborship data.
|
||||
for (int facet_idx = 0; facet_idx < (int)stl->stats.number_of_facets; ++ facet_idx) {
|
||||
const stl_neighbors &nbr = stl->neighbors_start[facet_idx];
|
||||
const int *vertices = its.indices.empty() ? nullptr : its.indices[facet_idx].data();
|
||||
for (int nbr_idx = 0; nbr_idx < 3; ++ nbr_idx) {
|
||||
int nbr_face = stl->neighbors_start[facet_idx].neighbor[nbr_idx];
|
||||
assert(nbr_face < (int)stl->stats.number_of_facets);
|
||||
if (nbr_face != -1) {
|
||||
int nbr_vnot = nbr.which_vertex_not[nbr_idx];
|
||||
assert(nbr_vnot >= 0 && nbr_vnot < 6);
|
||||
// Neighbor of the neighbor is the original face.
|
||||
assert(stl->neighbors_start[nbr_face].neighbor[(nbr_vnot + 1) % 3] == facet_idx);
|
||||
int vnot_back = stl->neighbors_start[nbr_face].which_vertex_not[(nbr_vnot + 1) % 3];
|
||||
assert(vnot_back >= 0 && vnot_back < 6);
|
||||
assert((nbr_vnot < 3) == (vnot_back < 3));
|
||||
assert(vnot_back % 3 == (nbr_idx + 2) % 3);
|
||||
if (vertices != nullptr) {
|
||||
// Has shared vertices.
|
||||
if (nbr_vnot < 3) {
|
||||
// Faces facet_idx and nbr_face share two vertices accross the common edge. Faces are correctly oriented.
|
||||
assert((its.indices[nbr_face][(nbr_vnot + 1) % 3] == vertices[(nbr_idx + 1) % 3] && its.indices[nbr_face][(nbr_vnot + 2) % 3] == vertices[nbr_idx]));
|
||||
} else {
|
||||
// Faces facet_idx and nbr_face share two vertices accross the common edge. Faces are incorrectly oriented, one of them is flipped.
|
||||
assert((its.indices[nbr_face][(nbr_vnot + 2) % 3] == vertices[(nbr_idx + 1) % 3] && its.indices[nbr_face][(nbr_vnot + 1) % 3] == vertices[nbr_idx]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check validity of the mesh, assert on error.
|
||||
bool stl_validate(const stl_file *stl)
|
||||
{
|
||||
indexed_triangle_set its;
|
||||
return stl_validate(stl, its);
|
||||
}
|
||||
@@ -1,343 +0,0 @@
|
||||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#ifndef __admesh_stl__
|
||||
#define __admesh_stl__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <vector>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
// Size of the binary STL header, free form.
|
||||
#define LABEL_SIZE 80
|
||||
// Binary STL, length of the "number of faces" counter.
|
||||
#define NUM_FACET_SIZE 4
|
||||
// Binary STL, sizeof header + number of faces.
|
||||
#define HEADER_SIZE 84
|
||||
#define STL_MIN_FILE_SIZE 284
|
||||
#define ASCII_LINES_PER_FACET 7
|
||||
|
||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> stl_vertex;
|
||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> stl_normal;
|
||||
typedef Eigen::Matrix<int, 3, 1, Eigen::DontAlign> stl_triangle_vertex_indices;
|
||||
static_assert(sizeof(stl_vertex) == 12, "size of stl_vertex incorrect");
|
||||
static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect");
|
||||
|
||||
struct stl_facet {
|
||||
stl_normal normal;
|
||||
stl_vertex vertex[3];
|
||||
char extra[2];
|
||||
|
||||
stl_facet rotated(const Eigen::Quaternion<float, Eigen::DontAlign> &rot) const {
|
||||
stl_facet out;
|
||||
out.normal = rot * this->normal;
|
||||
out.vertex[0] = rot * this->vertex[0];
|
||||
out.vertex[1] = rot * this->vertex[1];
|
||||
out.vertex[2] = rot * this->vertex[2];
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
#define SIZEOF_STL_FACET 50
|
||||
|
||||
static_assert(offsetof(stl_facet, normal) == 0, "stl_facet.normal has correct offset");
|
||||
static_assert(offsetof(stl_facet, vertex) == 12, "stl_facet.vertex has correct offset");
|
||||
static_assert(offsetof(stl_facet, extra ) == 48, "stl_facet.extra has correct offset");
|
||||
static_assert(sizeof(stl_facet) >= SIZEOF_STL_FACET, "size of stl_facet incorrect");
|
||||
|
||||
typedef enum {binary, ascii, inmemory} stl_type;
|
||||
|
||||
struct stl_neighbors {
|
||||
stl_neighbors() { reset(); }
|
||||
void reset() {
|
||||
neighbor[0] = -1;
|
||||
neighbor[1] = -1;
|
||||
neighbor[2] = -1;
|
||||
which_vertex_not[0] = -1;
|
||||
which_vertex_not[1] = -1;
|
||||
which_vertex_not[2] = -1;
|
||||
}
|
||||
int num_neighbors() const { return 3 - ((this->neighbor[0] == -1) + (this->neighbor[1] == -1) + (this->neighbor[2] == -1)); }
|
||||
|
||||
// Index of a neighbor facet.
|
||||
int neighbor[3];
|
||||
// Index of an opposite vertex at the neighbor face.
|
||||
char which_vertex_not[3];
|
||||
};
|
||||
|
||||
struct stl_stats {
|
||||
stl_stats() { memset(&header, 0, 81); }
|
||||
char header[81];
|
||||
stl_type type = (stl_type)0;
|
||||
// Should always match the number of facets stored inside stl_file::facet_start.
|
||||
uint32_t number_of_facets = 0;
|
||||
// Bounding box.
|
||||
stl_vertex max = stl_vertex::Zero();
|
||||
stl_vertex min = stl_vertex::Zero();
|
||||
stl_vertex size = stl_vertex::Zero();
|
||||
float bounding_diameter = 0.f;
|
||||
float shortest_edge = 0.f;
|
||||
// After repair, the volume shall always be positive.
|
||||
float volume = -1.f;
|
||||
// Number of face edges connected to another face.
|
||||
// Don't use this statistics after repair, use the connected_facets_1/2/3_edge instead!
|
||||
int connected_edges = 0;
|
||||
// Faces with >=1, >=2 and 3 edges connected to another face.
|
||||
int connected_facets_1_edge = 0;
|
||||
int connected_facets_2_edge = 0;
|
||||
int connected_facets_3_edge = 0;
|
||||
// Faces with 1, 2 and 3 open edges after exact chaining, but before repair.
|
||||
int facets_w_1_bad_edge = 0;
|
||||
int facets_w_2_bad_edge = 0;
|
||||
int facets_w_3_bad_edge = 0;
|
||||
// Number of faces read form an STL file.
|
||||
int original_num_facets = 0;
|
||||
// Number of edges connected one to another by snapping their end vertices.
|
||||
int edges_fixed = 0;
|
||||
// Number of faces removed because they were degenerated.
|
||||
int degenerate_facets = 0;
|
||||
// Total number of facets removed: Degenerate faces and unconnected faces.
|
||||
int facets_removed = 0;
|
||||
// Number of faces added by hole filling.
|
||||
int facets_added = 0;
|
||||
// Number of faces reversed because of negative volume or because one patch was connected to another patch with incompatible normals.
|
||||
int facets_reversed = 0;
|
||||
// Number of incompatible edges remaining after the patches were connected together and possibly their normals flipped.
|
||||
int backwards_edges = 0;
|
||||
// Number of triangles, which were flipped during the fixing process.
|
||||
int normals_fixed = 0;
|
||||
// Number of connected triangle patches.
|
||||
int number_of_parts = 0;
|
||||
|
||||
void clear() { *this = stl_stats(); }
|
||||
};
|
||||
|
||||
struct stl_file {
|
||||
stl_file() {}
|
||||
|
||||
void clear() {
|
||||
this->facet_start.clear();
|
||||
this->neighbors_start.clear();
|
||||
this->stats.clear();
|
||||
}
|
||||
|
||||
size_t memsize() const {
|
||||
return sizeof(*this) + sizeof(stl_facet) * facet_start.size() + sizeof(stl_neighbors) * neighbors_start.size();
|
||||
}
|
||||
|
||||
std::vector<stl_facet> facet_start;
|
||||
std::vector<stl_neighbors> neighbors_start;
|
||||
// Statistics
|
||||
stl_stats stats;
|
||||
};
|
||||
|
||||
struct indexed_triangle_set
|
||||
{
|
||||
void clear() { indices.clear(); vertices.clear(); }
|
||||
|
||||
size_t memsize() const {
|
||||
return sizeof(*this) + sizeof(stl_triangle_vertex_indices) * indices.size() + sizeof(stl_vertex) * vertices.size();
|
||||
}
|
||||
|
||||
std::vector<stl_triangle_vertex_indices> indices;
|
||||
std::vector<stl_vertex> vertices;
|
||||
|
||||
bool empty() const { return indices.empty() || vertices.empty(); }
|
||||
bool operator==(const indexed_triangle_set& other) const { return this->indices == other.indices && this->vertices == other.vertices; }
|
||||
};
|
||||
|
||||
extern bool stl_open(stl_file *stl, const char *file);
|
||||
extern void stl_stats_out(stl_file *stl, FILE *file, char *input_file);
|
||||
extern bool stl_print_neighbors(stl_file *stl, char *file);
|
||||
extern bool stl_write_ascii(stl_file *stl, const char *file, const char *label);
|
||||
extern bool stl_write_binary(stl_file *stl, const char *file, const char *label);
|
||||
extern void stl_check_facets_exact(stl_file *stl);
|
||||
extern void stl_check_facets_nearby(stl_file *stl, float tolerance);
|
||||
extern void stl_remove_unconnected_facets(stl_file *stl);
|
||||
extern void stl_write_vertex(stl_file *stl, int facet, int vertex);
|
||||
extern void stl_write_facet(stl_file *stl, char *label, int facet);
|
||||
extern void stl_write_neighbor(stl_file *stl, int facet);
|
||||
extern bool stl_write_quad_object(stl_file *stl, char *file);
|
||||
extern void stl_verify_neighbors(stl_file *stl);
|
||||
extern void stl_fill_holes(stl_file *stl);
|
||||
extern void stl_fix_normal_directions(stl_file *stl);
|
||||
extern void stl_fix_normal_values(stl_file *stl);
|
||||
extern void stl_reverse_all_facets(stl_file *stl);
|
||||
extern void stl_translate(stl_file *stl, float x, float y, float z);
|
||||
extern void stl_translate_relative(stl_file *stl, float x, float y, float z);
|
||||
extern void stl_scale_versor(stl_file *stl, const stl_vertex &versor);
|
||||
inline void stl_scale(stl_file *stl, float factor) { stl_scale_versor(stl, stl_vertex(factor, factor, factor)); }
|
||||
extern void stl_rotate_x(stl_file *stl, float angle);
|
||||
extern void stl_rotate_y(stl_file *stl, float angle);
|
||||
extern void stl_rotate_z(stl_file *stl, float angle);
|
||||
extern void stl_mirror_xy(stl_file *stl);
|
||||
extern void stl_mirror_yz(stl_file *stl);
|
||||
extern void stl_mirror_xz(stl_file *stl);
|
||||
|
||||
extern void stl_get_size(stl_file *stl);
|
||||
|
||||
// the following function is not used
|
||||
/*
|
||||
template<typename T>
|
||||
extern void stl_transform(stl_file *stl, T *trafo3x4)
|
||||
{
|
||||
Eigen::Matrix<T, 3, 3, Eigen::DontAlign> trafo3x3;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
trafo3x3(i, j) = (i * 4) + j;
|
||||
}
|
||||
}
|
||||
Eigen::Matrix<T, 3, 3, Eigen::DontAlign> r = trafo3x3.inverse().transpose();
|
||||
for (uint32_t i_face = 0; i_face < stl->stats.number_of_facets; ++ i_face) {
|
||||
stl_facet &face = stl->facet_start[i_face];
|
||||
for (int i_vertex = 0; i_vertex < 3; ++ i_vertex) {
|
||||
stl_vertex &v_dst = face.vertex[i_vertex];
|
||||
stl_vertex v_src = v_dst;
|
||||
v_dst(0) = T(trafo3x4[0] * v_src(0) + trafo3x4[1] * v_src(1) + trafo3x4[2] * v_src(2) + trafo3x4[3]);
|
||||
v_dst(1) = T(trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2) + trafo3x4[7]);
|
||||
v_dst(2) = T(trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2) + trafo3x4[11]);
|
||||
}
|
||||
face.normal = (r * face.normal.template cast<T>()).template cast<float>().eval();
|
||||
}
|
||||
|
||||
stl_get_size(stl);
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
inline void stl_transform(stl_file *stl, const Eigen::Transform<T, 3, Eigen::Affine, Eigen::DontAlign>& t)
|
||||
{
|
||||
const Eigen::Matrix<T, 3, 3, Eigen::DontAlign> r = t.matrix().template block<3, 3>(0, 0).inverse().transpose();
|
||||
for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_facet &f = stl->facet_start[i];
|
||||
for (size_t j = 0; j < 3; ++j)
|
||||
f.vertex[j] = (t * f.vertex[j].template cast<T>()).template cast<float>().eval();
|
||||
f.normal = (r * f.normal.template cast<T>()).template cast<float>().eval();
|
||||
}
|
||||
|
||||
stl_get_size(stl);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void stl_transform(stl_file *stl, const Eigen::Matrix<T, 3, 3, Eigen::DontAlign>& m)
|
||||
{
|
||||
const Eigen::Matrix<T, 3, 3, Eigen::DontAlign> r = m.inverse().transpose();
|
||||
for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_facet &f = stl->facet_start[i];
|
||||
for (size_t j = 0; j < 3; ++j)
|
||||
f.vertex[j] = (m * f.vertex[j].template cast<T>()).template cast<float>().eval();
|
||||
f.normal = (r * f.normal.template cast<T>()).template cast<float>().eval();
|
||||
}
|
||||
|
||||
stl_get_size(stl);
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
inline void its_translate(indexed_triangle_set &its, const V v)
|
||||
{
|
||||
for (stl_vertex &v_dst : its.vertices)
|
||||
v_dst += v;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void its_transform(indexed_triangle_set &its, T *trafo3x4)
|
||||
{
|
||||
for (stl_vertex &v_dst : its.vertices) {
|
||||
stl_vertex v_src = v_dst;
|
||||
v_dst(0) = T(trafo3x4[0] * v_src(0) + trafo3x4[1] * v_src(1) + trafo3x4[2] * v_src(2) + trafo3x4[3]);
|
||||
v_dst(1) = T(trafo3x4[4] * v_src(0) + trafo3x4[5] * v_src(1) + trafo3x4[6] * v_src(2) + trafo3x4[7]);
|
||||
v_dst(2) = T(trafo3x4[8] * v_src(0) + trafo3x4[9] * v_src(1) + trafo3x4[10] * v_src(2) + trafo3x4[11]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void its_transform(indexed_triangle_set &its, const Eigen::Transform<T, 3, Eigen::Affine, Eigen::DontAlign>& t, bool fix_left_handed = false)
|
||||
{
|
||||
//const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> r = t.matrix().template block<3, 3>(0, 0);
|
||||
for (stl_vertex &v : its.vertices)
|
||||
v = (t * v.template cast<T>()).template cast<float>().eval();
|
||||
if (fix_left_handed && t.matrix().block(0, 0, 3, 3).determinant() < 0.)
|
||||
for (stl_triangle_vertex_indices &i : its.indices)
|
||||
std::swap(i[0], i[1]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void its_transform(indexed_triangle_set &its, const Eigen::Matrix<T, 3, 3, Eigen::DontAlign>& m, bool fix_left_handed = false)
|
||||
{
|
||||
for (stl_vertex &v : its.vertices)
|
||||
v = (m * v.template cast<T>()).template cast<float>().eval();
|
||||
if (fix_left_handed && m.determinant() < 0.)
|
||||
for (stl_triangle_vertex_indices &i : its.indices)
|
||||
std::swap(i[0], i[1]);
|
||||
}
|
||||
|
||||
extern void its_rotate_x(indexed_triangle_set &its, float angle);
|
||||
extern void its_rotate_y(indexed_triangle_set &its, float angle);
|
||||
extern void its_rotate_z(indexed_triangle_set &its, float angle);
|
||||
|
||||
extern void stl_generate_shared_vertices(stl_file *stl, indexed_triangle_set &its);
|
||||
extern bool its_write_obj(const indexed_triangle_set &its, const char *file);
|
||||
extern bool its_write_off(const indexed_triangle_set &its, const char *file);
|
||||
extern bool its_write_vrml(const indexed_triangle_set &its, const char *file);
|
||||
|
||||
|
||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> obj_color; // Vec3f
|
||||
/// <summary>
|
||||
/// write idexed triangle set into obj file with color
|
||||
/// </summary>
|
||||
/// <param name="its">input model</param>
|
||||
/// <param name="color">color of stored model</param>
|
||||
/// <param name="file">define place to store</param>
|
||||
/// <returns>True on success otherwise FALSE</returns>
|
||||
extern bool its_write_obj(const indexed_triangle_set& its, const std::vector<obj_color> &color, const char* file);
|
||||
|
||||
extern bool stl_write_dxf(stl_file *stl, const char *file, char *label);
|
||||
inline void stl_calculate_normal(stl_normal &normal, stl_facet *facet) {
|
||||
normal = (facet->vertex[1] - facet->vertex[0]).cross(facet->vertex[2] - facet->vertex[0]);
|
||||
}
|
||||
inline void stl_normalize_vector(stl_normal &normal) {
|
||||
double length = normal.cast<double>().norm();
|
||||
if (length < 0.000000000001)
|
||||
normal = stl_normal::Zero();
|
||||
else
|
||||
normal *= float(1.0 / length);
|
||||
}
|
||||
extern void stl_calculate_volume(stl_file *stl);
|
||||
|
||||
extern void stl_repair(stl_file *stl, bool fixall_flag, bool exact_flag, bool tolerance_flag, float tolerance, bool increment_flag, float increment, bool nearby_flag, int iterations, bool remove_unconnected_flag, bool fill_holes_flag, bool normal_directions_flag, bool normal_values_flag, bool reverse_all_flag, bool verbose_flag);
|
||||
|
||||
extern void stl_allocate(stl_file *stl);
|
||||
extern void stl_read(stl_file *stl, int first_facet, bool first);
|
||||
extern void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first);
|
||||
extern void stl_reallocate(stl_file *stl);
|
||||
extern void stl_add_facet(stl_file *stl, const stl_facet *new_facet);
|
||||
|
||||
// Validate the mesh, assert on error.
|
||||
extern bool stl_validate(const stl_file *stl);
|
||||
extern bool stl_validate(const stl_file *stl, const indexed_triangle_set &its);
|
||||
|
||||
#endif
|
||||
@@ -1,251 +0,0 @@
|
||||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
void stl_stats_out(stl_file *stl, FILE *file, char *input_file)
|
||||
{
|
||||
// This is here for Slic3r, without our config.h it won't use this part of the code anyway.
|
||||
#ifndef VERSION
|
||||
#define VERSION "unknown"
|
||||
#endif
|
||||
fprintf(file, "\n================= Results produced by ADMesh version " VERSION " ================\n");
|
||||
fprintf(file, "Input file : %s\n", input_file);
|
||||
if (stl->stats.type == binary)
|
||||
fprintf(file, "File type : Binary STL file\n");
|
||||
else
|
||||
fprintf(file, "File type : ASCII STL file\n");
|
||||
fprintf(file, "Header : %s\n", stl->stats.header);
|
||||
fprintf(file, "============== Size ==============\n");
|
||||
fprintf(file, "Min X = % f, Max X = % f\n", stl->stats.min(0), stl->stats.max(0));
|
||||
fprintf(file, "Min Y = % f, Max Y = % f\n", stl->stats.min(1), stl->stats.max(1));
|
||||
fprintf(file, "Min Z = % f, Max Z = % f\n", stl->stats.min(2), stl->stats.max(2));
|
||||
fprintf(file, "========= Facet Status ========== Original ============ Final ====\n");
|
||||
fprintf(file, "Number of facets : %5d %5d\n", stl->stats.original_num_facets, stl->stats.number_of_facets);
|
||||
fprintf(file, "Facets with 1 disconnected edge : %5d %5d\n",
|
||||
stl->stats.facets_w_1_bad_edge, stl->stats.connected_facets_2_edge - stl->stats.connected_facets_3_edge);
|
||||
fprintf(file, "Facets with 2 disconnected edges : %5d %5d\n",
|
||||
stl->stats.facets_w_2_bad_edge, stl->stats.connected_facets_1_edge - stl->stats.connected_facets_2_edge);
|
||||
fprintf(file, "Facets with 3 disconnected edges : %5d %5d\n",
|
||||
stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets - stl->stats.connected_facets_1_edge);
|
||||
fprintf(file, "Total disconnected facets : %5d %5d\n",
|
||||
stl->stats.facets_w_1_bad_edge + stl->stats.facets_w_2_bad_edge + stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets - stl->stats.connected_facets_3_edge);
|
||||
fprintf(file, "=== Processing Statistics === ===== Other Statistics =====\n");
|
||||
fprintf(file, "Number of parts : %5d Volume : %f\n", stl->stats.number_of_parts, stl->stats.volume);
|
||||
fprintf(file, "Degenerate facets : %5d\n", stl->stats.degenerate_facets);
|
||||
fprintf(file, "Edges fixed : %5d\n", stl->stats.edges_fixed);
|
||||
fprintf(file, "Facets removed : %5d\n", stl->stats.facets_removed);
|
||||
fprintf(file, "Facets added : %5d\n", stl->stats.facets_added);
|
||||
fprintf(file, "Facets reversed : %5d\n", stl->stats.facets_reversed);
|
||||
fprintf(file, "Backwards edges : %5d\n", stl->stats.backwards_edges);
|
||||
fprintf(file, "Normals fixed : %5d\n", stl->stats.normals_fixed);
|
||||
}
|
||||
|
||||
bool stl_write_ascii(stl_file *stl, const char *file, const char *label)
|
||||
{
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_ascii: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "solid %s\n", label);
|
||||
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
fprintf(fp, " facet normal % .8E % .8E % .8E\n", stl->facet_start[i].normal(0), stl->facet_start[i].normal(1), stl->facet_start[i].normal(2));
|
||||
fprintf(fp, " outer loop\n");
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n", stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1), stl->facet_start[i].vertex[0](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n", stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1), stl->facet_start[i].vertex[1](2));
|
||||
fprintf(fp, " vertex % .8E % .8E % .8E\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, " endloop\n");
|
||||
fprintf(fp, " endfacet\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "endsolid %s\n", label);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stl_print_neighbors(stl_file *stl, char *file)
|
||||
{
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_print_neighbors: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
fprintf(fp, "%d, %d,%d, %d,%d, %d,%d\n",
|
||||
i,
|
||||
stl->neighbors_start[i].neighbor[0],
|
||||
(int)stl->neighbors_start[i].which_vertex_not[0],
|
||||
stl->neighbors_start[i].neighbor[1],
|
||||
(int)stl->neighbors_start[i].which_vertex_not[1],
|
||||
stl->neighbors_start[i].neighbor[2],
|
||||
(int)stl->neighbors_start[i].which_vertex_not[2]);
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
// Swap a buffer of 32bit data from little endian to big endian and vice versa.
|
||||
void stl_internal_reverse_quads(char *buf, size_t cnt)
|
||||
{
|
||||
for (size_t i = 0; i < cnt; i += 4) {
|
||||
std::swap(buf[i], buf[i+3]);
|
||||
std::swap(buf[i+1], buf[i+2]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool stl_write_binary(stl_file *stl, const char *file, const char *label)
|
||||
{
|
||||
FILE *fp = boost::nowide::fopen(file, "wb");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_binary: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "%s", label);
|
||||
for (size_t i = strlen(label); i < LABEL_SIZE; ++ i)
|
||||
putc(0, fp);
|
||||
|
||||
#if !defined(SEEK_SET)
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
fseek(fp, LABEL_SIZE, SEEK_SET);
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
fwrite(&stl->stats.number_of_facets, 4, 1, fp);
|
||||
for (const stl_facet &facet : stl->facet_start)
|
||||
fwrite(&facet, SIZEOF_STL_FACET, 1, fp);
|
||||
#else /* BOOST_ENDIAN_LITTLE_BYTE */
|
||||
char buffer[50];
|
||||
// Convert the number of facets to little endian.
|
||||
memcpy(buffer, &stl->stats.number_of_facets, 4);
|
||||
stl_internal_reverse_quads(buffer, 4);
|
||||
fwrite(buffer, 4, 1, fp);
|
||||
for (const stl_facet &facet : stl->facet_start) {
|
||||
memcpy(buffer, &facet, 50);
|
||||
// Convert to little endian.
|
||||
stl_internal_reverse_quads(buffer, 48);
|
||||
fwrite(buffer, SIZEOF_STL_FACET, 1, fp);
|
||||
}
|
||||
#endif /* BOOST_ENDIAN_LITTLE_BYTE */
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void stl_write_vertex(stl_file *stl, int facet, int vertex)
|
||||
{
|
||||
printf(" vertex %d/%d % .8E % .8E % .8E\n", vertex, facet,
|
||||
stl->facet_start[facet].vertex[vertex](0),
|
||||
stl->facet_start[facet].vertex[vertex](1),
|
||||
stl->facet_start[facet].vertex[vertex](2));
|
||||
}
|
||||
|
||||
void stl_write_facet(stl_file *stl, char *label, int facet)
|
||||
{
|
||||
printf("facet (%d)/ %s\n", facet, label);
|
||||
stl_write_vertex(stl, facet, 0);
|
||||
stl_write_vertex(stl, facet, 1);
|
||||
stl_write_vertex(stl, facet, 2);
|
||||
}
|
||||
|
||||
void stl_write_neighbor(stl_file *stl, int facet)
|
||||
{
|
||||
printf("Neighbors %d: %d, %d, %d ; %d, %d, %d\n", facet,
|
||||
stl->neighbors_start[facet].neighbor[0],
|
||||
stl->neighbors_start[facet].neighbor[1],
|
||||
stl->neighbors_start[facet].neighbor[2],
|
||||
stl->neighbors_start[facet].which_vertex_not[0],
|
||||
stl->neighbors_start[facet].which_vertex_not[1],
|
||||
stl->neighbors_start[facet].which_vertex_not[2]);
|
||||
}
|
||||
|
||||
bool stl_write_quad_object(stl_file *stl, char *file)
|
||||
{
|
||||
stl_vertex connect_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_1_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_2_color = stl_vertex::Zero();
|
||||
stl_vertex uncon_3_color = stl_vertex::Zero();
|
||||
stl_vertex color;
|
||||
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_quad_object: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "CQUAD\n");
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
switch (stl->neighbors_start[i].num_neighbors()) {
|
||||
case 0:
|
||||
default: color = uncon_3_color; break;
|
||||
case 1: color = uncon_2_color; break;
|
||||
case 2: color = uncon_1_color; break;
|
||||
case 3: color = connect_color; break;
|
||||
}
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1), stl->facet_start[i].vertex[0](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1), stl->facet_start[i].vertex[1](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
|
||||
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2), color(0), color(1), color(2));
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stl_write_dxf(stl_file *stl, const char *file, char *label)
|
||||
{
|
||||
FILE *fp = boost::nowide::fopen(file, "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_write_quad_object: Couldn't open " << file << " for writing";
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "999\n%s\n", label);
|
||||
fprintf(fp, "0\nSECTION\n2\nHEADER\n0\nENDSEC\n");
|
||||
fprintf(fp, "0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLAYER\n70\n1\n\
|
||||
0\nLAYER\n2\n0\n70\n0\n62\n7\n6\nCONTINUOUS\n0\nENDTAB\n0\nENDSEC\n");
|
||||
fprintf(fp, "0\nSECTION\n2\nBLOCKS\n0\nENDSEC\n");
|
||||
|
||||
fprintf(fp, "0\nSECTION\n2\nENTITIES\n");
|
||||
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
fprintf(fp, "0\n3DFACE\n8\n0\n");
|
||||
fprintf(fp, "10\n%f\n20\n%f\n30\n%f\n", stl->facet_start[i].vertex[0](0), stl->facet_start[i].vertex[0](1), stl->facet_start[i].vertex[0](2));
|
||||
fprintf(fp, "11\n%f\n21\n%f\n31\n%f\n", stl->facet_start[i].vertex[1](0), stl->facet_start[i].vertex[1](1), stl->facet_start[i].vertex[1](2));
|
||||
fprintf(fp, "12\n%f\n22\n%f\n32\n%f\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2));
|
||||
fprintf(fp, "13\n%f\n23\n%f\n33\n%f\n", stl->facet_start[i].vertex[2](0), stl->facet_start[i].vertex[2](1), stl->facet_start[i].vertex[2](2));
|
||||
}
|
||||
|
||||
fprintf(fp, "0\nENDSEC\n0\nEOF\n");
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
#include <LocalesUtils.hpp>
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#error "SEEK_SET not defined"
|
||||
#endif
|
||||
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
extern void stl_internal_reverse_quads(char *buf, size_t cnt);
|
||||
#endif /* BOOST_ENDIAN_BIG_BYTE */
|
||||
|
||||
static FILE* stl_open_count_facets(stl_file *stl, const char *file)
|
||||
{
|
||||
// Open the file in binary mode first.
|
||||
FILE *fp = boost::nowide::fopen(file, "rb");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: Couldn't open " << file << " for reading";
|
||||
return nullptr;
|
||||
}
|
||||
// Find size of file.
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long file_size = ftell(fp);
|
||||
|
||||
// Check for binary or ASCII file.
|
||||
fseek(fp, HEADER_SIZE, SEEK_SET);
|
||||
unsigned char chtest[128];
|
||||
if (! fread(chtest, sizeof(chtest), 1, fp)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The input is an empty file: " << file;
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
stl->stats.type = ascii;
|
||||
for (size_t s = 0; s < sizeof(chtest); s++) {
|
||||
if (chtest[s] > 127) {
|
||||
stl->stats.type = binary;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rewind(fp);
|
||||
|
||||
uint32_t num_facets = 0;
|
||||
|
||||
// Get the header and the number of facets in the .STL file.
|
||||
// If the .STL file is binary, then do the following:
|
||||
if (stl->stats.type == binary) {
|
||||
// Test if the STL file has the right size.
|
||||
if (((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0) || (file_size < STL_MIN_FILE_SIZE)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The file " << file << " has the wrong size.";
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET;
|
||||
|
||||
// Read the header.
|
||||
if (fread(stl->stats.header, LABEL_SIZE, 1, fp) > 79)
|
||||
stl->stats.header[80] = '\0';
|
||||
|
||||
// Read the int following the header. This should contain # of facets.
|
||||
uint32_t header_num_facets;
|
||||
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, fp) != 0;
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
// Convert from little endian to big endian.
|
||||
stl_internal_reverse_quads((char*)&header_num_facets, 4);
|
||||
#endif /* BOOST_ENDIAN_BIG_BYTE */
|
||||
if (! header_num_faces_read || num_facets != header_num_facets)
|
||||
BOOST_LOG_TRIVIAL(info) << "stl_open_count_facets: Warning: File size doesn't match number of facets in the header: " << file;
|
||||
}
|
||||
// Otherwise, if the .STL file is ASCII, then do the following:
|
||||
else
|
||||
{
|
||||
// Reopen the file in text mode (for getting correct newlines on Windows)
|
||||
// fix to silence a warning about unused return value.
|
||||
// obviously if it fails we have problems....
|
||||
fp = boost::nowide::freopen(file, "r", fp);
|
||||
|
||||
// do another null check to be safe
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: Couldn't open " << file << " for reading";
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Find the number of facets.
|
||||
char linebuf[100];
|
||||
int num_lines = 1;
|
||||
while (fgets(linebuf, 100, fp) != nullptr) {
|
||||
// Don't count short lines.
|
||||
if (strlen(linebuf) <= 4)
|
||||
continue;
|
||||
// Skip solid/endsolid lines as broken STL file generators may put several of them.
|
||||
if (strncmp(linebuf, "solid", 5) == 0 || strncmp(linebuf, "endsolid", 8) == 0)
|
||||
continue;
|
||||
++ num_lines;
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
|
||||
// Get the header.
|
||||
int i = 0;
|
||||
for (; i < 80 && (stl->stats.header[i] = getc(fp)) != '\n'; ++ i) ;
|
||||
stl->stats.header[i] = '\0'; // Lose the '\n'
|
||||
stl->stats.header[80] = '\0';
|
||||
|
||||
num_facets = num_lines / ASCII_LINES_PER_FACET;
|
||||
}
|
||||
|
||||
stl->stats.number_of_facets += num_facets;
|
||||
stl->stats.original_num_facets = stl->stats.number_of_facets;
|
||||
return fp;
|
||||
}
|
||||
|
||||
/* Reads the contents of the file pointed to by fp into the stl structure,
|
||||
starting at facet first_facet. The second argument says if it's our first
|
||||
time running this for the stl and therefore we should reset our max and min stats. */
|
||||
static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first)
|
||||
{
|
||||
if (stl->stats.type == binary)
|
||||
fseek(fp, HEADER_SIZE, SEEK_SET);
|
||||
else
|
||||
rewind(fp);
|
||||
|
||||
char normal_buf[3][32];
|
||||
for (uint32_t i = first_facet; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_facet facet;
|
||||
|
||||
if (stl->stats.type == binary) {
|
||||
// Read a single facet from a binary .STL file. We assume little-endian architecture!
|
||||
if (fread(&facet, 1, SIZEOF_STL_FACET, fp) != SIZEOF_STL_FACET)
|
||||
return false;
|
||||
#if BOOST_ENDIAN_BIG_BYTE
|
||||
// Convert the loaded little endian data to big endian.
|
||||
stl_internal_reverse_quads((char*)&facet, 48);
|
||||
#endif /* BOOST_ENDIAN_BIG_BYTE */
|
||||
} else {
|
||||
// Read a single facet from an ASCII .STL file
|
||||
// skip solid/endsolid
|
||||
// (in this order, otherwise it won't work when they are paired in the middle of a file)
|
||||
fscanf(fp, " endsolid%*[^\n]\n");
|
||||
fscanf(fp, " solid%*[^\n]\n"); // name might contain spaces so %*s doesn't work and it also can be empty (just "solid")
|
||||
// Leading space in the fscanf format skips all leading white spaces including numerous new lines and tabs.
|
||||
int res_normal = fscanf(fp, " facet normal %31s %31s %31s", normal_buf[0], normal_buf[1], normal_buf[2]);
|
||||
assert(res_normal == 3);
|
||||
int res_outer_loop = fscanf(fp, " outer loop");
|
||||
assert(res_outer_loop == 0);
|
||||
int res_vertex1 = fscanf(fp, " vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2));
|
||||
assert(res_vertex1 == 3);
|
||||
int res_vertex2 = fscanf(fp, " vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2));
|
||||
assert(res_vertex2 == 3);
|
||||
// Trailing whitespace is there to eat all whitespaces and empty lines up to the next non-whitespace.
|
||||
int res_vertex3 = fscanf(fp, " vertex %f %f %f ", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2));
|
||||
assert(res_vertex3 == 3);
|
||||
// Some G-code generators tend to produce text after "endloop" and "endfacet". Just ignore it.
|
||||
char buf[2048];
|
||||
fgets(buf, 2047, fp);
|
||||
bool endloop_ok = strncmp(buf, "endloop", 7) == 0 && (buf[7] == '\r' || buf[7] == '\n' || buf[7] == ' ' || buf[7] == '\t');
|
||||
assert(endloop_ok);
|
||||
// Skip the trailing whitespaces and empty lines.
|
||||
fscanf(fp, " ");
|
||||
fgets(buf, 2047, fp);
|
||||
bool endfacet_ok = strncmp(buf, "endfacet", 8) == 0 && (buf[8] == '\r' || buf[8] == '\n' || buf[8] == ' ' || buf[8] == '\t');
|
||||
assert(endfacet_ok);
|
||||
if (res_normal != 3 || res_outer_loop != 0 || res_vertex1 != 3 || res_vertex2 != 3 || res_vertex3 != 3 || ! endloop_ok || ! endfacet_ok) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Something is syntactically very wrong with this ASCII STL! ";
|
||||
return false;
|
||||
}
|
||||
|
||||
// The facet normal has been parsed as a single string as to workaround for not a numbers in the normal definition.
|
||||
if (sscanf(normal_buf[0], "%f", &facet.normal(0)) != 1 ||
|
||||
sscanf(normal_buf[1], "%f", &facet.normal(1)) != 1 ||
|
||||
sscanf(normal_buf[2], "%f", &facet.normal(2)) != 1) {
|
||||
// Normal was mangled. Maybe denormals or "not a number" were stored?
|
||||
// Just reset the normal and silently ignore it.
|
||||
memset(&facet.normal, 0, sizeof(facet.normal));
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Report close to zero vertex coordinates. Due to the nature of the floating point numbers,
|
||||
// close to zero values may be represented with singificantly higher precision than the rest of the vertices.
|
||||
// It may be worth to round these numbers to zero during loading to reduce the number of errors reported
|
||||
// during the STL import.
|
||||
for (size_t j = 0; j < 3; ++ j) {
|
||||
if (facet.vertex[j](0) > -1e-12f && facet.vertex[j](0) < 1e-12f)
|
||||
printf("stl_read: facet %d(0) = %e\r\n", j, facet.vertex[j](0));
|
||||
if (facet.vertex[j](1) > -1e-12f && facet.vertex[j](1) < 1e-12f)
|
||||
printf("stl_read: facet %d(1) = %e\r\n", j, facet.vertex[j](1));
|
||||
if (facet.vertex[j](2) > -1e-12f && facet.vertex[j](2) < 1e-12f)
|
||||
printf("stl_read: facet %d(2) = %e\r\n", j, facet.vertex[j](2));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
for (int u = 0; u < 3; ++u) {
|
||||
if (std::isnan(facet.vertex[j](u)) || std::isinf(facet.vertex[j](u))) {
|
||||
BOOST_LOG_TRIVIAL(error) << "stl_read: facet " << i << ": vertex " << j << "contains invalid coordinate";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write the facet into memory.
|
||||
stl->facet_start[i] = facet;
|
||||
stl_facet_stats(stl, facet, first);
|
||||
}
|
||||
|
||||
stl->stats.size = stl->stats.max - stl->stats.min;
|
||||
stl->stats.bounding_diameter = stl->stats.size.norm();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stl_open(stl_file *stl, const char *file)
|
||||
{
|
||||
Slic3r::CNumericLocalesSetter locales_setter;
|
||||
stl->clear();
|
||||
FILE *fp = stl_open_count_facets(stl, file);
|
||||
if (fp == nullptr)
|
||||
return false;
|
||||
stl_allocate(stl);
|
||||
bool result = stl_read(stl, fp, 0, true);
|
||||
fclose(fp);
|
||||
return result;
|
||||
}
|
||||
|
||||
void stl_allocate(stl_file *stl)
|
||||
{
|
||||
// Allocate memory for the entire .STL file.
|
||||
stl->facet_start.assign(stl->stats.number_of_facets, stl_facet());
|
||||
// Allocate memory for the neighbors list.
|
||||
stl->neighbors_start.assign(stl->stats.number_of_facets, stl_neighbors());
|
||||
}
|
||||
|
||||
void stl_reallocate(stl_file *stl)
|
||||
{
|
||||
stl->facet_start.resize(stl->stats.number_of_facets);
|
||||
stl->neighbors_start.resize(stl->stats.number_of_facets);
|
||||
}
|
||||
|
||||
void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first)
|
||||
{
|
||||
// While we are going through all of the facets, let's find the
|
||||
// maximum and minimum values for x, y, and z
|
||||
|
||||
if (first) {
|
||||
// Initialize the max and min values the first time through
|
||||
stl->stats.min = facet.vertex[0];
|
||||
stl->stats.max = facet.vertex[0];
|
||||
stl_vertex diff = (facet.vertex[1] - facet.vertex[0]).cwiseAbs();
|
||||
stl->stats.shortest_edge = std::max(diff(0), std::max(diff(1), diff(2)));
|
||||
first = false;
|
||||
}
|
||||
|
||||
// Now find the max and min values.
|
||||
for (size_t i = 0; i < 3; ++ i) {
|
||||
stl->stats.min = stl->stats.min.cwiseMin(facet.vertex[i]);
|
||||
stl->stats.max = stl->stats.max.cwiseMax(facet.vertex[i]);
|
||||
}
|
||||
}
|
||||
@@ -1,399 +0,0 @@
|
||||
/* ADMesh -- process triangulated solid meshes
|
||||
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
||||
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Questions, comments, suggestions, etc to
|
||||
* https://github.com/admesh/admesh/issues
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
void stl_verify_neighbors(stl_file *stl)
|
||||
{
|
||||
stl->stats.backwards_edges = 0;
|
||||
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
struct stl_edge {
|
||||
stl_vertex p1;
|
||||
stl_vertex p2;
|
||||
int facet_number;
|
||||
};
|
||||
stl_edge edge_a;
|
||||
edge_a.p1 = stl->facet_start[i].vertex[j];
|
||||
edge_a.p2 = stl->facet_start[i].vertex[(j + 1) % 3];
|
||||
int neighbor = stl->neighbors_start[i].neighbor[j];
|
||||
if (neighbor == -1)
|
||||
continue; // this edge has no neighbor... Continue.
|
||||
int vnot = stl->neighbors_start[i].which_vertex_not[j];
|
||||
stl_edge edge_b;
|
||||
if (vnot < 3) {
|
||||
edge_b.p1 = stl->facet_start[neighbor].vertex[(vnot + 2) % 3];
|
||||
edge_b.p2 = stl->facet_start[neighbor].vertex[(vnot + 1) % 3];
|
||||
} else {
|
||||
stl->stats.backwards_edges += 1;
|
||||
edge_b.p1 = stl->facet_start[neighbor].vertex[(vnot + 1) % 3];
|
||||
edge_b.p2 = stl->facet_start[neighbor].vertex[(vnot + 2) % 3];
|
||||
}
|
||||
if (edge_a.p1 != edge_b.p1 || edge_a.p2 != edge_b.p2) {
|
||||
// These edges should match but they don't. Print results.
|
||||
BOOST_LOG_TRIVIAL(info) << "edge " << j << " of facet " << i << " doesn't match edge " << (vnot + 1) << " of facet " << neighbor;
|
||||
stl_write_facet(stl, (char*)"first facet", i);
|
||||
stl_write_facet(stl, (char*)"second facet", neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stl_translate(stl_file *stl, float x, float y, float z)
|
||||
{
|
||||
stl_vertex new_min(x, y, z);
|
||||
stl_vertex shift = new_min - stl->stats.min;
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j] += shift;
|
||||
stl->stats.min = new_min;
|
||||
stl->stats.max += shift;
|
||||
}
|
||||
|
||||
/* Translates the stl by x,y,z, relatively from wherever it is currently */
|
||||
void stl_translate_relative(stl_file *stl, float x, float y, float z)
|
||||
{
|
||||
stl_vertex shift(x, y, z);
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j] += shift;
|
||||
stl->stats.min += shift;
|
||||
stl->stats.max += shift;
|
||||
}
|
||||
|
||||
void stl_scale_versor(stl_file *stl, const stl_vertex &versor)
|
||||
{
|
||||
// Scale extents.
|
||||
auto s = versor.array();
|
||||
stl->stats.min.array() *= s;
|
||||
stl->stats.max.array() *= s;
|
||||
// Scale size.
|
||||
stl->stats.size.array() *= s;
|
||||
// Scale volume.
|
||||
if (stl->stats.volume > 0.0)
|
||||
stl->stats.volume *= versor(0) * versor(1) * versor(2);
|
||||
// Scale the mesh.
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j].array() *= s;
|
||||
}
|
||||
|
||||
static void calculate_normals(stl_file *stl)
|
||||
{
|
||||
stl_normal normal;
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
stl_calculate_normal(normal, &stl->facet_start[i]);
|
||||
stl_normalize_vector(normal);
|
||||
stl->facet_start[i].normal = normal;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rotate_point_2d(float &x, float &y, const double c, const double s)
|
||||
{
|
||||
double xold = x;
|
||||
double yold = y;
|
||||
x = float(c * xold - s * yold);
|
||||
y = float(s * xold + c * yold);
|
||||
}
|
||||
|
||||
void stl_rotate_x(stl_file *stl, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
rotate_point_2d(stl->facet_start[i].vertex[j](1), stl->facet_start[i].vertex[j](2), c, s);
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void stl_rotate_y(stl_file *stl, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
rotate_point_2d(stl->facet_start[i].vertex[j](2), stl->facet_start[i].vertex[j](0), c, s);
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void stl_rotate_z(stl_file *stl, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
rotate_point_2d(stl->facet_start[i].vertex[j](0), stl->facet_start[i].vertex[j](1), c, s);
|
||||
stl_get_size(stl);
|
||||
calculate_normals(stl);
|
||||
}
|
||||
|
||||
void its_rotate_x(indexed_triangle_set &its, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (stl_vertex &v : its.vertices)
|
||||
rotate_point_2d(v(1), v(2), c, s);
|
||||
}
|
||||
|
||||
void its_rotate_y(indexed_triangle_set& its, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (stl_vertex& v : its.vertices)
|
||||
rotate_point_2d(v(2), v(0), c, s);
|
||||
}
|
||||
|
||||
void its_rotate_z(indexed_triangle_set& its, float angle)
|
||||
{
|
||||
double radian_angle = (angle / 180.0) * M_PI;
|
||||
double c = cos(radian_angle);
|
||||
double s = sin(radian_angle);
|
||||
for (stl_vertex& v : its.vertices)
|
||||
rotate_point_2d(v(0), v(1), c, s);
|
||||
}
|
||||
|
||||
void stl_get_size(stl_file *stl)
|
||||
{
|
||||
if (stl->stats.number_of_facets == 0)
|
||||
return;
|
||||
stl->stats.min = stl->facet_start[0].vertex[0];
|
||||
stl->stats.max = stl->stats.min;
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
const stl_facet &face = stl->facet_start[i];
|
||||
for (int j = 0; j < 3; ++ j) {
|
||||
stl->stats.min = stl->stats.min.cwiseMin(face.vertex[j]);
|
||||
stl->stats.max = stl->stats.max.cwiseMax(face.vertex[j]);
|
||||
}
|
||||
}
|
||||
stl->stats.size = stl->stats.max - stl->stats.min;
|
||||
stl->stats.bounding_diameter = stl->stats.size.norm();
|
||||
}
|
||||
|
||||
void stl_mirror_xy(stl_file *stl)
|
||||
{
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j](2) *= -1.0;
|
||||
float temp_size = stl->stats.min(2);
|
||||
stl->stats.min(2) = stl->stats.max(2);
|
||||
stl->stats.max(2) = temp_size;
|
||||
stl->stats.min(2) *= -1.0;
|
||||
stl->stats.max(2) *= -1.0;
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.facets_reversed -= stl->stats.number_of_facets; /* for not altering stats */
|
||||
}
|
||||
|
||||
void stl_mirror_yz(stl_file *stl)
|
||||
{
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; j++)
|
||||
stl->facet_start[i].vertex[j](0) *= -1.0;
|
||||
float temp_size = stl->stats.min(0);
|
||||
stl->stats.min(0) = stl->stats.max(0);
|
||||
stl->stats.max(0) = temp_size;
|
||||
stl->stats.min(0) *= -1.0;
|
||||
stl->stats.max(0) *= -1.0;
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.facets_reversed -= stl->stats.number_of_facets; /* for not altering stats */
|
||||
}
|
||||
|
||||
void stl_mirror_xz(stl_file *stl)
|
||||
{
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i)
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
stl->facet_start[i].vertex[j](1) *= -1.0;
|
||||
float temp_size = stl->stats.min(1);
|
||||
stl->stats.min(1) = stl->stats.max(1);
|
||||
stl->stats.max(1) = temp_size;
|
||||
stl->stats.min(1) *= -1.0;
|
||||
stl->stats.max(1) *= -1.0;
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.facets_reversed -= stl->stats.number_of_facets; // for not altering stats
|
||||
}
|
||||
|
||||
static float get_area(stl_facet *facet)
|
||||
{
|
||||
/* cast to double before calculating cross product because large coordinates
|
||||
can result in overflowing product
|
||||
(bad area is responsible for bad volume and bad facets reversal) */
|
||||
double cross[3][3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
cross[i][0]=(((double)facet->vertex[i](1) * (double)facet->vertex[(i + 1) % 3](2)) -
|
||||
((double)facet->vertex[i](2) * (double)facet->vertex[(i + 1) % 3](1)));
|
||||
cross[i][1]=(((double)facet->vertex[i](2) * (double)facet->vertex[(i + 1) % 3](0)) -
|
||||
((double)facet->vertex[i](0) * (double)facet->vertex[(i + 1) % 3](2)));
|
||||
cross[i][2]=(((double)facet->vertex[i](0) * (double)facet->vertex[(i + 1) % 3](1)) -
|
||||
((double)facet->vertex[i](1) * (double)facet->vertex[(i + 1) % 3](0)));
|
||||
}
|
||||
|
||||
stl_normal sum;
|
||||
sum(0) = cross[0][0] + cross[1][0] + cross[2][0];
|
||||
sum(1) = cross[0][1] + cross[1][1] + cross[2][1];
|
||||
sum(2) = cross[0][2] + cross[1][2] + cross[2][2];
|
||||
|
||||
// This should already be done. But just in case, let's do it again.
|
||||
//FIXME this is questionable. the "sum" normal should be accurate, while the normal "n" may be calculated with a low accuracy.
|
||||
stl_normal n;
|
||||
stl_calculate_normal(n, facet);
|
||||
stl_normalize_vector(n);
|
||||
return 0.5f * n.dot(sum);
|
||||
}
|
||||
|
||||
static float get_volume(stl_file *stl)
|
||||
{
|
||||
// Choose a point, any point as the reference.
|
||||
stl_vertex p0 = stl->facet_start[0].vertex[0];
|
||||
float volume = 0.f;
|
||||
for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) {
|
||||
// Do dot product to get distance from point to plane.
|
||||
float height = stl->facet_start[i].normal.dot(stl->facet_start[i].vertex[0] - p0);
|
||||
float area = get_area(&stl->facet_start[i]);
|
||||
volume += (area * height) / 3.0f;
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
|
||||
void stl_calculate_volume(stl_file *stl)
|
||||
{
|
||||
stl->stats.volume = get_volume(stl);
|
||||
if (stl->stats.volume < 0.0) {
|
||||
stl_reverse_all_facets(stl);
|
||||
stl->stats.volume = -stl->stats.volume;
|
||||
}
|
||||
}
|
||||
|
||||
void stl_repair(
|
||||
stl_file *stl,
|
||||
bool fixall_flag,
|
||||
bool exact_flag,
|
||||
bool tolerance_flag,
|
||||
float tolerance,
|
||||
bool increment_flag,
|
||||
float increment,
|
||||
bool nearby_flag,
|
||||
int iterations,
|
||||
bool remove_unconnected_flag,
|
||||
bool fill_holes_flag,
|
||||
bool normal_directions_flag,
|
||||
bool normal_values_flag,
|
||||
bool reverse_all_flag,
|
||||
bool verbose_flag)
|
||||
{
|
||||
if (exact_flag || fixall_flag || nearby_flag || remove_unconnected_flag || fill_holes_flag || normal_directions_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking exact...\n");
|
||||
exact_flag = true;
|
||||
stl_check_facets_exact(stl);
|
||||
stl->stats.facets_w_1_bad_edge = (stl->stats.connected_facets_2_edge - stl->stats.connected_facets_3_edge);
|
||||
stl->stats.facets_w_2_bad_edge = (stl->stats.connected_facets_1_edge - stl->stats.connected_facets_2_edge);
|
||||
stl->stats.facets_w_3_bad_edge = (stl->stats.number_of_facets - stl->stats.connected_facets_1_edge);
|
||||
}
|
||||
|
||||
if (nearby_flag || fixall_flag) {
|
||||
if (! tolerance_flag)
|
||||
tolerance = stl->stats.shortest_edge;
|
||||
if (! increment_flag)
|
||||
increment = stl->stats.bounding_diameter / 10000.0;
|
||||
}
|
||||
|
||||
if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) {
|
||||
int last_edges_fixed = 0;
|
||||
for (int i = 0; i < iterations; ++ i) {
|
||||
if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) {
|
||||
if (verbose_flag)
|
||||
printf("Checking nearby. Tolerance= %f Iteration=%d of %d...", tolerance, i + 1, iterations);
|
||||
stl_check_facets_nearby(stl, tolerance);
|
||||
if (verbose_flag)
|
||||
printf(" Fixed %d edges.\n", stl->stats.edges_fixed - last_edges_fixed);
|
||||
last_edges_fixed = stl->stats.edges_fixed;
|
||||
tolerance += increment;
|
||||
} else {
|
||||
if (verbose_flag)
|
||||
printf("All facets connected. No further nearby check necessary.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (verbose_flag)
|
||||
printf("All facets connected. No nearby check necessary.\n");
|
||||
|
||||
if (remove_unconnected_flag || fixall_flag || fill_holes_flag) {
|
||||
if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) {
|
||||
if (verbose_flag)
|
||||
printf("Removing unconnected facets...\n");
|
||||
stl_remove_unconnected_facets(stl);
|
||||
} else if (verbose_flag)
|
||||
printf("No unconnected need to be removed.\n");
|
||||
}
|
||||
|
||||
if (fill_holes_flag || fixall_flag) {
|
||||
if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) {
|
||||
if (verbose_flag)
|
||||
printf("Filling holes...\n");
|
||||
stl_fill_holes(stl);
|
||||
} else if (verbose_flag)
|
||||
printf("No holes need to be filled.\n");
|
||||
}
|
||||
|
||||
if (reverse_all_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Reversing all facets...\n");
|
||||
stl_reverse_all_facets(stl);
|
||||
}
|
||||
|
||||
if (normal_directions_flag || fixall_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking normal directions...\n");
|
||||
stl_fix_normal_directions(stl);
|
||||
}
|
||||
|
||||
if (normal_values_flag || fixall_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Checking normal values...\n");
|
||||
stl_fix_normal_values(stl);
|
||||
}
|
||||
|
||||
// Always calculate the volume. It shouldn't take too long.
|
||||
if (verbose_flag)
|
||||
printf("Calculating volume...\n");
|
||||
stl_calculate_volume(stl);
|
||||
|
||||
if (exact_flag) {
|
||||
if (verbose_flag)
|
||||
printf("Verifying neighbors...\n");
|
||||
stl_verify_neighbors(stl);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(agg)
|
||||
|
||||
add_library(agg INTERFACE)
|
||||
target_include_directories(agg INTERFACE .)
|
||||
@@ -1,2 +0,0 @@
|
||||
Anti-Grain Geometry - Version 2.4
|
||||
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
||||
@@ -1,2 +0,0 @@
|
||||
2.4
|
||||
svn revision 128
|
||||
@@ -1,574 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_BASICS_INCLUDED
|
||||
#define AGG_BASICS_INCLUDED
|
||||
|
||||
#include <cmath>
|
||||
#include "agg_config.h"
|
||||
|
||||
//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
|
||||
#ifdef AGG_CUSTOM_ALLOCATOR
|
||||
#include "agg_allocator.h"
|
||||
#else
|
||||
namespace agg
|
||||
{
|
||||
// The policy of all AGG containers and memory allocation strategy
|
||||
// in general is that no allocated data requires explicit construction.
|
||||
// It means that the allocator can be really simple; you can even
|
||||
// replace new/delete to malloc/free. The constructors and destructors
|
||||
// won't be called in this case, however everything will remain working.
|
||||
// The second argument of deallocate() is the size of the allocated
|
||||
// block. You can use this information if you wish.
|
||||
//------------------------------------------------------------pod_allocator
|
||||
template<class T> struct pod_allocator
|
||||
{
|
||||
static T* allocate(unsigned num) { return new T [num]; }
|
||||
static void deallocate(T* ptr, unsigned) { delete [] ptr; }
|
||||
};
|
||||
|
||||
// Single object allocator. It's also can be replaced with your custom
|
||||
// allocator. The difference is that it can only allocate a single
|
||||
// object and the constructor and destructor must be called.
|
||||
// In AGG there is no need to allocate an array of objects with
|
||||
// calling their constructors (only single ones). So that, if you
|
||||
// replace these new/delete to malloc/free make sure that the in-place
|
||||
// new is called and take care of calling the destructor too.
|
||||
//------------------------------------------------------------obj_allocator
|
||||
template<class T> struct obj_allocator
|
||||
{
|
||||
static T* allocate() { return new T; }
|
||||
static void deallocate(T* ptr) { delete ptr; }
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-------------------------------------------------------- Default basic types
|
||||
//
|
||||
// If the compiler has different capacity of the basic types you can redefine
|
||||
// them via the compiler command line or by generating agg_config.h that is
|
||||
// empty by default.
|
||||
//
|
||||
#ifndef AGG_INT8
|
||||
#define AGG_INT8 signed char
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT8U
|
||||
#define AGG_INT8U unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT16
|
||||
#define AGG_INT16 short
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT16U
|
||||
#define AGG_INT16U unsigned short
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT32
|
||||
#define AGG_INT32 int
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT32U
|
||||
#define AGG_INT32U unsigned
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT64
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#define AGG_INT64 signed __int64
|
||||
#else
|
||||
#define AGG_INT64 signed long long
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AGG_INT64U
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#define AGG_INT64U unsigned __int64
|
||||
#else
|
||||
#define AGG_INT64U unsigned long long
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//------------------------------------------------ Some fixes for MS Visual C++
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable:4786) // Identifier was truncated...
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define AGG_INLINE __forceinline
|
||||
#else
|
||||
#define AGG_INLINE inline
|
||||
#endif
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
typedef AGG_INT8 int8; //----int8
|
||||
typedef AGG_INT8U int8u; //----int8u
|
||||
typedef AGG_INT16 int16; //----int16
|
||||
typedef AGG_INT16U int16u; //----int16u
|
||||
typedef AGG_INT32 int32; //----int32
|
||||
typedef AGG_INT32U int32u; //----int32u
|
||||
typedef AGG_INT64 int64; //----int64
|
||||
typedef AGG_INT64U int64u; //----int64u
|
||||
|
||||
#if defined(AGG_FISTP)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4035) //Disable warning "no return value"
|
||||
AGG_INLINE int iround(double v) //-------iround
|
||||
{
|
||||
int t;
|
||||
__asm fld qword ptr [v]
|
||||
__asm fistp dword ptr [t]
|
||||
__asm mov eax, dword ptr [t]
|
||||
}
|
||||
AGG_INLINE unsigned uround(double v) //-------uround
|
||||
{
|
||||
unsigned t;
|
||||
__asm fld qword ptr [v]
|
||||
__asm fistp dword ptr [t]
|
||||
__asm mov eax, dword ptr [t]
|
||||
}
|
||||
#pragma warning(pop)
|
||||
AGG_INLINE int ifloor(double v)
|
||||
{
|
||||
return int(floor(v));
|
||||
}
|
||||
AGG_INLINE unsigned ufloor(double v) //-------ufloor
|
||||
{
|
||||
return unsigned(floor(v));
|
||||
}
|
||||
AGG_INLINE int iceil(double v)
|
||||
{
|
||||
return int(ceil(v));
|
||||
}
|
||||
AGG_INLINE unsigned uceil(double v) //--------uceil
|
||||
{
|
||||
return unsigned(ceil(v));
|
||||
}
|
||||
#elif defined(AGG_QIFIST)
|
||||
AGG_INLINE int iround(double v)
|
||||
{
|
||||
return int(v);
|
||||
}
|
||||
AGG_INLINE int uround(double v)
|
||||
{
|
||||
return unsigned(v);
|
||||
}
|
||||
AGG_INLINE int ifloor(double v)
|
||||
{
|
||||
return int(floor(v));
|
||||
}
|
||||
AGG_INLINE unsigned ufloor(double v)
|
||||
{
|
||||
return unsigned(floor(v));
|
||||
}
|
||||
AGG_INLINE int iceil(double v)
|
||||
{
|
||||
return int(ceil(v));
|
||||
}
|
||||
AGG_INLINE unsigned uceil(double v)
|
||||
{
|
||||
return unsigned(ceil(v));
|
||||
}
|
||||
#else
|
||||
AGG_INLINE int iround(double v)
|
||||
{
|
||||
return int((v < 0.0) ? v - 0.5 : v + 0.5);
|
||||
}
|
||||
AGG_INLINE int uround(double v)
|
||||
{
|
||||
return unsigned(v + 0.5);
|
||||
}
|
||||
AGG_INLINE int ifloor(double v)
|
||||
{
|
||||
int i = int(v);
|
||||
return i - (i > v);
|
||||
}
|
||||
AGG_INLINE unsigned ufloor(double v)
|
||||
{
|
||||
return unsigned(v);
|
||||
}
|
||||
AGG_INLINE int iceil(double v)
|
||||
{
|
||||
return int(ceil(v));
|
||||
}
|
||||
AGG_INLINE unsigned uceil(double v)
|
||||
{
|
||||
return unsigned(ceil(v));
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------saturation
|
||||
template<int Limit> struct saturation
|
||||
{
|
||||
AGG_INLINE static int iround(double v)
|
||||
{
|
||||
if(v < double(-Limit)) return -Limit;
|
||||
if(v > double( Limit)) return Limit;
|
||||
return agg::iround(v);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------mul_one
|
||||
template<unsigned Shift> struct mul_one
|
||||
{
|
||||
AGG_INLINE static unsigned mul(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned q = a * b + (1 << (Shift-1));
|
||||
return (q + (q >> Shift)) >> Shift;
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
typedef unsigned char cover_type; //----cover_type
|
||||
enum cover_scale_e
|
||||
{
|
||||
cover_shift = 8, //----cover_shift
|
||||
cover_size = 1 << cover_shift, //----cover_size
|
||||
cover_mask = cover_size - 1, //----cover_mask
|
||||
cover_none = 0, //----cover_none
|
||||
cover_full = cover_mask //----cover_full
|
||||
};
|
||||
|
||||
//----------------------------------------------------poly_subpixel_scale_e
|
||||
// These constants determine the subpixel accuracy, to be more precise,
|
||||
// the number of bits of the fractional part of the coordinates.
|
||||
// The possible coordinate capacity in bits can be calculated by formula:
|
||||
// sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
|
||||
// 8-bits fractional part the capacity is 24 bits.
|
||||
enum poly_subpixel_scale_e
|
||||
{
|
||||
poly_subpixel_shift = 8, //----poly_subpixel_shift
|
||||
poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale
|
||||
poly_subpixel_mask = poly_subpixel_scale-1 //----poly_subpixel_mask
|
||||
};
|
||||
|
||||
//----------------------------------------------------------filling_rule_e
|
||||
enum filling_rule_e
|
||||
{
|
||||
fill_non_zero,
|
||||
fill_even_odd
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------pi
|
||||
const double pi = 3.14159265358979323846;
|
||||
|
||||
//------------------------------------------------------------------deg2rad
|
||||
inline double deg2rad(double deg)
|
||||
{
|
||||
return deg * pi / 180.0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------rad2deg
|
||||
inline double rad2deg(double rad)
|
||||
{
|
||||
return rad * 180.0 / pi;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------rect_base
|
||||
template<class T> struct rect_base
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef rect_base<T> self_type;
|
||||
T x1, y1, x2, y2;
|
||||
|
||||
rect_base() {}
|
||||
rect_base(T x1_, T y1_, T x2_, T y2_) :
|
||||
x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
|
||||
|
||||
void init(T x1_, T y1_, T x2_, T y2_)
|
||||
{
|
||||
x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_;
|
||||
}
|
||||
|
||||
const self_type& normalize()
|
||||
{
|
||||
T t;
|
||||
if(x1 > x2) { t = x1; x1 = x2; x2 = t; }
|
||||
if(y1 > y2) { t = y1; y1 = y2; y2 = t; }
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool clip(const self_type& r)
|
||||
{
|
||||
if(x2 > r.x2) x2 = r.x2;
|
||||
if(y2 > r.y2) y2 = r.y2;
|
||||
if(x1 < r.x1) x1 = r.x1;
|
||||
if(y1 < r.y1) y1 = r.y1;
|
||||
return x1 <= x2 && y1 <= y2;
|
||||
}
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
return x1 <= x2 && y1 <= y2;
|
||||
}
|
||||
|
||||
bool hit_test(T x, T y) const
|
||||
{
|
||||
return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
|
||||
}
|
||||
|
||||
bool overlaps(const self_type& r) const
|
||||
{
|
||||
return !(r.x1 > x2 || r.x2 < x1
|
||||
|| r.y1 > y2 || r.y2 < y1);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------intersect_rectangles
|
||||
template<class Rect>
|
||||
inline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
|
||||
{
|
||||
Rect r = r1;
|
||||
|
||||
// First process x2,y2 because the other order
|
||||
// results in Internal Compiler Error under
|
||||
// Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in
|
||||
// case of "Maximize Speed" optimization option.
|
||||
//-----------------
|
||||
if(r.x2 > r2.x2) r.x2 = r2.x2;
|
||||
if(r.y2 > r2.y2) r.y2 = r2.y2;
|
||||
if(r.x1 < r2.x1) r.x1 = r2.x1;
|
||||
if(r.y1 < r2.y1) r.y1 = r2.y1;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------unite_rectangles
|
||||
template<class Rect>
|
||||
inline Rect unite_rectangles(const Rect& r1, const Rect& r2)
|
||||
{
|
||||
Rect r = r1;
|
||||
if(r.x2 < r2.x2) r.x2 = r2.x2;
|
||||
if(r.y2 < r2.y2) r.y2 = r2.y2;
|
||||
if(r.x1 > r2.x1) r.x1 = r2.x1;
|
||||
if(r.y1 > r2.y1) r.y1 = r2.y1;
|
||||
return r;
|
||||
}
|
||||
|
||||
typedef rect_base<int> rect_i; //----rect_i
|
||||
typedef rect_base<float> rect_f; //----rect_f
|
||||
typedef rect_base<double> rect_d; //----rect_d
|
||||
|
||||
//---------------------------------------------------------path_commands_e
|
||||
enum path_commands_e
|
||||
{
|
||||
path_cmd_stop = 0, //----path_cmd_stop
|
||||
path_cmd_move_to = 1, //----path_cmd_move_to
|
||||
path_cmd_line_to = 2, //----path_cmd_line_to
|
||||
path_cmd_curve3 = 3, //----path_cmd_curve3
|
||||
path_cmd_curve4 = 4, //----path_cmd_curve4
|
||||
path_cmd_curveN = 5, //----path_cmd_curveN
|
||||
path_cmd_catrom = 6, //----path_cmd_catrom
|
||||
path_cmd_ubspline = 7, //----path_cmd_ubspline
|
||||
path_cmd_end_poly = 0x0F, //----path_cmd_end_poly
|
||||
path_cmd_mask = 0x0F //----path_cmd_mask
|
||||
};
|
||||
|
||||
//------------------------------------------------------------path_flags_e
|
||||
enum path_flags_e
|
||||
{
|
||||
path_flags_none = 0, //----path_flags_none
|
||||
path_flags_ccw = 0x10, //----path_flags_ccw
|
||||
path_flags_cw = 0x20, //----path_flags_cw
|
||||
path_flags_close = 0x40, //----path_flags_close
|
||||
path_flags_mask = 0xF0 //----path_flags_mask
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------is_vertex
|
||||
inline bool is_vertex(unsigned c)
|
||||
{
|
||||
return c >= path_cmd_move_to && c < path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_drawing
|
||||
inline bool is_drawing(unsigned c)
|
||||
{
|
||||
return c >= path_cmd_line_to && c < path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------is_stop
|
||||
inline bool is_stop(unsigned c)
|
||||
{
|
||||
return c == path_cmd_stop;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_move_to
|
||||
inline bool is_move_to(unsigned c)
|
||||
{
|
||||
return c == path_cmd_move_to;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------is_line_to
|
||||
inline bool is_line_to(unsigned c)
|
||||
{
|
||||
return c == path_cmd_line_to;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------is_curve
|
||||
inline bool is_curve(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve3 || c == path_cmd_curve4;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_curve3
|
||||
inline bool is_curve3(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve3;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_curve4
|
||||
inline bool is_curve4(unsigned c)
|
||||
{
|
||||
return c == path_cmd_curve4;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------is_end_poly
|
||||
inline bool is_end_poly(unsigned c)
|
||||
{
|
||||
return (c & path_cmd_mask) == path_cmd_end_poly;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------is_close
|
||||
inline bool is_close(unsigned c)
|
||||
{
|
||||
return (c & ~(path_flags_cw | path_flags_ccw)) ==
|
||||
(path_cmd_end_poly | path_flags_close);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------is_next_poly
|
||||
inline bool is_next_poly(unsigned c)
|
||||
{
|
||||
return is_stop(c) || is_move_to(c) || is_end_poly(c);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------is_cw
|
||||
inline bool is_cw(unsigned c)
|
||||
{
|
||||
return (c & path_flags_cw) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------is_ccw
|
||||
inline bool is_ccw(unsigned c)
|
||||
{
|
||||
return (c & path_flags_ccw) != 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------is_oriented
|
||||
inline bool is_oriented(unsigned c)
|
||||
{
|
||||
return (c & (path_flags_cw | path_flags_ccw)) != 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------is_closed
|
||||
inline bool is_closed(unsigned c)
|
||||
{
|
||||
return (c & path_flags_close) != 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------get_close_flag
|
||||
inline unsigned get_close_flag(unsigned c)
|
||||
{
|
||||
return c & path_flags_close;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clear_orientation
|
||||
inline unsigned clear_orientation(unsigned c)
|
||||
{
|
||||
return c & ~(path_flags_cw | path_flags_ccw);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------get_orientation
|
||||
inline unsigned get_orientation(unsigned c)
|
||||
{
|
||||
return c & (path_flags_cw | path_flags_ccw);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------set_orientation
|
||||
inline unsigned set_orientation(unsigned c, unsigned o)
|
||||
{
|
||||
return clear_orientation(c) | o;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------point_base
|
||||
template<class T> struct point_base
|
||||
{
|
||||
typedef T value_type;
|
||||
T x,y;
|
||||
point_base() {}
|
||||
point_base(T x_, T y_) : x(x_), y(y_) {}
|
||||
};
|
||||
typedef point_base<int> point_i; //-----point_i
|
||||
typedef point_base<float> point_f; //-----point_f
|
||||
typedef point_base<double> point_d; //-----point_d
|
||||
|
||||
//-------------------------------------------------------------vertex_base
|
||||
template<class T> struct vertex_base
|
||||
{
|
||||
typedef T value_type;
|
||||
T x,y;
|
||||
unsigned cmd;
|
||||
vertex_base() {}
|
||||
vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {}
|
||||
};
|
||||
typedef vertex_base<int> vertex_i; //-----vertex_i
|
||||
typedef vertex_base<float> vertex_f; //-----vertex_f
|
||||
typedef vertex_base<double> vertex_d; //-----vertex_d
|
||||
|
||||
//----------------------------------------------------------------row_info
|
||||
template<class T> struct row_info
|
||||
{
|
||||
int x1, x2;
|
||||
T* ptr;
|
||||
row_info() {}
|
||||
row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------const_row_info
|
||||
template<class T> struct const_row_info
|
||||
{
|
||||
int x1, x2;
|
||||
const T* ptr;
|
||||
const_row_info() {}
|
||||
const_row_info(int x1_, int x2_, const T* ptr_) :
|
||||
x1(x1_), x2(x2_), ptr(ptr_) {}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------is_equal_eps
|
||||
template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
|
||||
{
|
||||
bool neg1 = v1 < 0.0;
|
||||
bool neg2 = v2 < 0.0;
|
||||
|
||||
if (neg1 != neg2)
|
||||
return std::fabs(v1) < epsilon && std::fabs(v2) < epsilon;
|
||||
|
||||
int int1, int2;
|
||||
std::frexp(v1, &int1);
|
||||
std::frexp(v2, &int2);
|
||||
int min12 = int1 < int2 ? int1 : int2;
|
||||
|
||||
v1 = std::ldexp(v1, -min12);
|
||||
v2 = std::ldexp(v2, -min12);
|
||||
|
||||
return std::fabs(v1 - v2) < epsilon;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
|
||||
// 4, 7, 10, or 13 vertices.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_BEZIER_ARC_INCLUDED
|
||||
#define AGG_BEZIER_ARC_INCLUDED
|
||||
|
||||
#include "agg_conv_transform.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void arc_to_bezier(double cx, double cy, double rx, double ry,
|
||||
double start_angle, double sweep_angle,
|
||||
double* curve);
|
||||
|
||||
|
||||
//==============================================================bezier_arc
|
||||
//
|
||||
// See implemantaion agg_bezier_arc.cpp
|
||||
//
|
||||
class bezier_arc
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
|
||||
bezier_arc(double x, double y,
|
||||
double rx, double ry,
|
||||
double start_angle,
|
||||
double sweep_angle)
|
||||
{
|
||||
init(x, y, rx, ry, start_angle, sweep_angle);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void init(double x, double y,
|
||||
double rx, double ry,
|
||||
double start_angle,
|
||||
double sweep_angle);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void rewind(unsigned)
|
||||
{
|
||||
m_vertex = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
if(m_vertex >= m_num_vertices) return path_cmd_stop;
|
||||
*x = m_vertices[m_vertex];
|
||||
*y = m_vertices[m_vertex + 1];
|
||||
m_vertex += 2;
|
||||
return (m_vertex == 2) ? 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
|
||||
@@ -1,333 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Liang-Barsky clipping
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
|
||||
#define AGG_CLIP_LIANG_BARSKY_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum clipping_flags_e
|
||||
{
|
||||
clipping_flags_x1_clipped = 4,
|
||||
clipping_flags_x2_clipped = 1,
|
||||
clipping_flags_y1_clipped = 8,
|
||||
clipping_flags_y2_clipped = 2,
|
||||
clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped,
|
||||
clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped
|
||||
};
|
||||
|
||||
//----------------------------------------------------------clipping_flags
|
||||
// Determine the clipping code of the vertex according to the
|
||||
// Cyrus-Beck line clipping algorithm
|
||||
//
|
||||
// | |
|
||||
// 0110 | 0010 | 0011
|
||||
// | |
|
||||
// -------+--------+-------- clip_box.y2
|
||||
// | |
|
||||
// 0100 | 0000 | 0001
|
||||
// | |
|
||||
// -------+--------+-------- clip_box.y1
|
||||
// | |
|
||||
// 1100 | 1000 | 1001
|
||||
// | |
|
||||
// clip_box.x1 clip_box.x2
|
||||
//
|
||||
//
|
||||
template<class T>
|
||||
inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
|
||||
{
|
||||
return (x > clip_box.x2) |
|
||||
((y > clip_box.y2) << 1) |
|
||||
((x < clip_box.x1) << 2) |
|
||||
((y < clip_box.y1) << 3);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------clipping_flags_x
|
||||
template<class T>
|
||||
inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box)
|
||||
{
|
||||
return (x > clip_box.x2) | ((x < clip_box.x1) << 2);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------clipping_flags_y
|
||||
template<class T>
|
||||
inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box)
|
||||
{
|
||||
return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------clip_liang_barsky
|
||||
template<class T>
|
||||
inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
|
||||
const rect_base<T>& clip_box,
|
||||
T* x, T* y)
|
||||
{
|
||||
const double nearzero = 1e-30;
|
||||
|
||||
double deltax = x2 - x1;
|
||||
double deltay = y2 - y1;
|
||||
double xin;
|
||||
double xout;
|
||||
double yin;
|
||||
double yout;
|
||||
double tinx;
|
||||
double tiny;
|
||||
double toutx;
|
||||
double touty;
|
||||
double tin1;
|
||||
double tin2;
|
||||
double tout1;
|
||||
unsigned np = 0;
|
||||
|
||||
if(deltax == 0.0)
|
||||
{
|
||||
// bump off of the vertical
|
||||
deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
|
||||
}
|
||||
|
||||
if(deltay == 0.0)
|
||||
{
|
||||
// bump off of the horizontal
|
||||
deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
|
||||
}
|
||||
|
||||
if(deltax > 0.0)
|
||||
{
|
||||
// points to right
|
||||
xin = clip_box.x1;
|
||||
xout = clip_box.x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
xin = clip_box.x2;
|
||||
xout = clip_box.x1;
|
||||
}
|
||||
|
||||
if(deltay > 0.0)
|
||||
{
|
||||
// points up
|
||||
yin = clip_box.y1;
|
||||
yout = clip_box.y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
yin = clip_box.y2;
|
||||
yout = clip_box.y1;
|
||||
}
|
||||
|
||||
tinx = (xin - x1) / deltax;
|
||||
tiny = (yin - y1) / deltay;
|
||||
|
||||
if (tinx < tiny)
|
||||
{
|
||||
// hits x first
|
||||
tin1 = tinx;
|
||||
tin2 = tiny;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hits y first
|
||||
tin1 = tiny;
|
||||
tin2 = tinx;
|
||||
}
|
||||
|
||||
if(tin1 <= 1.0)
|
||||
{
|
||||
if(0.0 < tin1)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)yin;
|
||||
++np;
|
||||
}
|
||||
|
||||
if(tin2 <= 1.0)
|
||||
{
|
||||
toutx = (xout - x1) / deltax;
|
||||
touty = (yout - y1) / deltay;
|
||||
|
||||
tout1 = (toutx < touty) ? toutx : touty;
|
||||
|
||||
if(tin2 > 0.0 || tout1 > 0.0)
|
||||
{
|
||||
if(tin2 <= tout1)
|
||||
{
|
||||
if(tin2 > 0.0)
|
||||
{
|
||||
if(tinx > tiny)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)(y1 + tinx * deltay);
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)(x1 + tiny * deltax);
|
||||
*y++ = (T)yin;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
|
||||
if(tout1 < 1.0)
|
||||
{
|
||||
if(toutx < touty)
|
||||
{
|
||||
*x++ = (T)xout;
|
||||
*y++ = (T)(y1 + toutx * deltay);
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)(x1 + touty * deltax);
|
||||
*y++ = (T)yout;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = x2;
|
||||
*y++ = y2;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tinx > tiny)
|
||||
{
|
||||
*x++ = (T)xin;
|
||||
*y++ = (T)yout;
|
||||
}
|
||||
else
|
||||
{
|
||||
*x++ = (T)xout;
|
||||
*y++ = (T)yin;
|
||||
}
|
||||
++np;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return np;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class T>
|
||||
bool clip_move_point(T x1, T y1, T x2, T y2,
|
||||
const rect_base<T>& clip_box,
|
||||
T* x, T* y, unsigned flags)
|
||||
{
|
||||
T bound;
|
||||
|
||||
if(flags & clipping_flags_x_clipped)
|
||||
{
|
||||
if(x1 == x2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2;
|
||||
*y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1);
|
||||
*x = bound;
|
||||
}
|
||||
|
||||
flags = clipping_flags_y(*y, clip_box);
|
||||
if(flags & clipping_flags_y_clipped)
|
||||
{
|
||||
if(y1 == y2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2;
|
||||
*x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1);
|
||||
*y = bound;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------clip_line_segment
|
||||
// Returns: ret >= 4 - Fully clipped
|
||||
// (ret & 1) != 0 - First point has been moved
|
||||
// (ret & 2) != 0 - Second point has been moved
|
||||
//
|
||||
template<class T>
|
||||
unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2,
|
||||
const rect_base<T>& clip_box)
|
||||
{
|
||||
unsigned f1 = clipping_flags(*x1, *y1, clip_box);
|
||||
unsigned f2 = clipping_flags(*x2, *y2, clip_box);
|
||||
unsigned ret = 0;
|
||||
|
||||
if((f2 | f1) == 0)
|
||||
{
|
||||
// Fully visible
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((f1 & clipping_flags_x_clipped) != 0 &&
|
||||
(f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped))
|
||||
{
|
||||
// Fully clipped
|
||||
return 4;
|
||||
}
|
||||
|
||||
if((f1 & clipping_flags_y_clipped) != 0 &&
|
||||
(f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped))
|
||||
{
|
||||
// Fully clipped
|
||||
return 4;
|
||||
}
|
||||
|
||||
T tx1 = *x1;
|
||||
T ty1 = *y1;
|
||||
T tx2 = *x2;
|
||||
T ty2 = *y2;
|
||||
if(f1)
|
||||
{
|
||||
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if(*x1 == *x2 && *y1 == *y2)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
ret |= 1;
|
||||
}
|
||||
if(f2)
|
||||
{
|
||||
if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2))
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
if(*x1 == *x2 && *y1 == *y2)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
ret |= 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef AGG_CONFIG_INCLUDED
|
||||
#define AGG_CONFIG_INCLUDED
|
||||
|
||||
// This file can be used to redefine certain data types.
|
||||
|
||||
//---------------------------------------
|
||||
// 1. Default basic types such as:
|
||||
//
|
||||
// AGG_INT8
|
||||
// AGG_INT8U
|
||||
// AGG_INT16
|
||||
// AGG_INT16U
|
||||
// AGG_INT32
|
||||
// AGG_INT32U
|
||||
// AGG_INT64
|
||||
// AGG_INT64U
|
||||
//
|
||||
// Just replace this file with new defines if necessary.
|
||||
// For example, if your compiler doesn't have a 64 bit integer type
|
||||
// you can still use AGG if you define the follows:
|
||||
//
|
||||
// #define AGG_INT64 int
|
||||
// #define AGG_INT64U unsigned
|
||||
//
|
||||
// It will result in overflow in 16 bit-per-component image/pattern resampling
|
||||
// but it won't result any crash and the rest of the library will remain
|
||||
// fully functional.
|
||||
|
||||
|
||||
//---------------------------------------
|
||||
// 2. Default rendering_buffer type. Can be:
|
||||
//
|
||||
// Provides faster access for massive pixel operations,
|
||||
// such as blur, image filtering:
|
||||
// #define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
|
||||
//
|
||||
// Provides cheaper creation and destruction (no mem allocs):
|
||||
// #define AGG_RENDERING_BUFFER row_accessor<int8u>
|
||||
//
|
||||
// You can still use both of them simultaneously in your applications
|
||||
// This #define is used only for default rendering_buffer type,
|
||||
// in short hand typedefs like pixfmt_rgba32.
|
||||
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class conv_transform
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_CONV_TRANSFORM_INCLUDED
|
||||
#define AGG_CONV_TRANSFORM_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//----------------------------------------------------------conv_transform
|
||||
template<class VertexSource, class Transformer=trans_affine> class conv_transform
|
||||
{
|
||||
public:
|
||||
conv_transform(VertexSource& source, Transformer& tr) :
|
||||
m_source(&source), m_trans(&tr) {}
|
||||
void attach(VertexSource& source) { m_source = &source; }
|
||||
|
||||
void rewind(unsigned path_id)
|
||||
{
|
||||
m_source->rewind(path_id);
|
||||
}
|
||||
|
||||
unsigned vertex(double* x, double* y)
|
||||
{
|
||||
unsigned cmd = m_source->vertex(x, y);
|
||||
if(is_vertex(cmd))
|
||||
{
|
||||
m_trans->transform(x, y);
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void transformer(Transformer& tr)
|
||||
{
|
||||
m_trans = &tr;
|
||||
}
|
||||
|
||||
private:
|
||||
conv_transform(const conv_transform<VertexSource>&);
|
||||
const conv_transform<VertexSource>&
|
||||
operator = (const conv_transform<VertexSource>&);
|
||||
|
||||
VertexSource* m_source;
|
||||
Transformer* m_trans;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,132 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_GAMMA_FUNCTIONS_INCLUDED
|
||||
#define AGG_GAMMA_FUNCTIONS_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//===============================================================gamma_none
|
||||
struct gamma_none
|
||||
{
|
||||
double operator()(double x) const { return x; }
|
||||
};
|
||||
|
||||
|
||||
//==============================================================gamma_power
|
||||
class gamma_power
|
||||
{
|
||||
public:
|
||||
gamma_power() : m_gamma(1.0) {}
|
||||
gamma_power(double g) : m_gamma(g) {}
|
||||
|
||||
void gamma(double g) { m_gamma = g; }
|
||||
double gamma() const { return m_gamma; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
return pow(x, m_gamma);
|
||||
}
|
||||
|
||||
private:
|
||||
double m_gamma;
|
||||
};
|
||||
|
||||
|
||||
//==========================================================gamma_threshold
|
||||
class gamma_threshold
|
||||
{
|
||||
public:
|
||||
gamma_threshold() : m_threshold(0.5) {}
|
||||
gamma_threshold(double t) : m_threshold(t) {}
|
||||
|
||||
void threshold(double t) { m_threshold = t; }
|
||||
double threshold() const { return m_threshold; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
return (x < m_threshold) ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_threshold;
|
||||
};
|
||||
|
||||
|
||||
//============================================================gamma_linear
|
||||
class gamma_linear
|
||||
{
|
||||
public:
|
||||
gamma_linear() : m_start(0.0), m_end(1.0) {}
|
||||
gamma_linear(double s, double e) : m_start(s), m_end(e) {}
|
||||
|
||||
void set(double s, double e) { m_start = s; m_end = e; }
|
||||
void start(double s) { m_start = s; }
|
||||
void end(double e) { m_end = e; }
|
||||
double start() const { return m_start; }
|
||||
double end() const { return m_end; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
if(x < m_start) return 0.0;
|
||||
if(x > m_end) return 1.0;
|
||||
return (x - m_start) / (m_end - m_start);
|
||||
}
|
||||
|
||||
private:
|
||||
double m_start;
|
||||
double m_end;
|
||||
};
|
||||
|
||||
|
||||
//==========================================================gamma_multiply
|
||||
class gamma_multiply
|
||||
{
|
||||
public:
|
||||
gamma_multiply() : m_mul(1.0) {}
|
||||
gamma_multiply(double v) : m_mul(v) {}
|
||||
|
||||
void value(double v) { m_mul = v; }
|
||||
double value() const { return m_mul; }
|
||||
|
||||
double operator() (double x) const
|
||||
{
|
||||
double y = x * m_mul;
|
||||
if(y > 1.0) y = 1.0;
|
||||
return y;
|
||||
}
|
||||
|
||||
private:
|
||||
double m_mul;
|
||||
};
|
||||
|
||||
inline double sRGB_to_linear(double x)
|
||||
{
|
||||
return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4);
|
||||
}
|
||||
|
||||
inline double linear_to_sRGB(double x)
|
||||
{
|
||||
return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,300 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#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
|
||||
//
|
||||
|
||||
// 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()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
for (int i = 0; i <= 255; ++i)
|
||||
{
|
||||
m_dir_table[i] = float(sRGB_to_linear(i / 255.0));
|
||||
}
|
||||
for (int i = 0; i <= 65535; ++i)
|
||||
{
|
||||
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 65535.0));
|
||||
}
|
||||
}
|
||||
|
||||
float dir(int8u v) const
|
||||
{
|
||||
return m_dir_table[v];
|
||||
}
|
||||
|
||||
int8u inv(float v) const
|
||||
{
|
||||
return m_inv_table[int16u(0.5 + v * 65535)];
|
||||
}
|
||||
|
||||
private:
|
||||
float m_dir_table[256];
|
||||
int8u m_inv_table[65536];
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_lut<int16u>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
for (int i = 0; i <= 255; ++i)
|
||||
{
|
||||
m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0));
|
||||
}
|
||||
for (int i = 0; i <= 65535; ++i)
|
||||
{
|
||||
m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 65535.0));
|
||||
}
|
||||
}
|
||||
|
||||
int16u dir(int8u v) const
|
||||
{
|
||||
return m_dir_table[v];
|
||||
}
|
||||
|
||||
int8u inv(int16u v) const
|
||||
{
|
||||
return m_inv_table[v];
|
||||
}
|
||||
|
||||
private:
|
||||
int16u m_dir_table[256];
|
||||
int8u m_inv_table[65536];
|
||||
};
|
||||
|
||||
template<>
|
||||
class sRGB_lut<int8u>
|
||||
{
|
||||
public:
|
||||
sRGB_lut()
|
||||
{
|
||||
// Generate lookup tables.
|
||||
for (int i = 0; i <= 255; ++i)
|
||||
{
|
||||
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 dir(int8u v) const
|
||||
{
|
||||
return m_dir_table[v];
|
||||
}
|
||||
|
||||
int8u inv(int8u v) const
|
||||
{
|
||||
return m_inv_table[v];
|
||||
}
|
||||
|
||||
private:
|
||||
int8u m_dir_table[256];
|
||||
int8u m_inv_table[256];
|
||||
};
|
||||
|
||||
// Common base class for sRGB_conv objects. Defines an internal
|
||||
// sRGB_lut object so that users don't have to.
|
||||
template<class T>
|
||||
class sRGB_conv_base
|
||||
{
|
||||
public:
|
||||
static T rgb_from_sRGB(int8u x)
|
||||
{
|
||||
return lut.dir(x);
|
||||
}
|
||||
|
||||
static int8u rgb_to_sRGB(T x)
|
||||
{
|
||||
return lut.inv(x);
|
||||
}
|
||||
|
||||
private:
|
||||
static sRGB_lut<T> lut;
|
||||
};
|
||||
|
||||
// Definition of sRGB_conv_base::lut. Due to the fact that this a template,
|
||||
// we don't need to place the definition in a cpp file. Hurrah.
|
||||
template<class T>
|
||||
sRGB_lut<T> sRGB_conv_base<T>::lut;
|
||||
|
||||
// Wrapper for sRGB-linear conversion.
|
||||
// Base template is undefined, specializations are provided below.
|
||||
template<class T>
|
||||
class sRGB_conv;
|
||||
|
||||
template<>
|
||||
class sRGB_conv<float> : public sRGB_conv_base<float>
|
||||
{
|
||||
public:
|
||||
static float alpha_from_sRGB(int8u x)
|
||||
{
|
||||
static const double y = 1 / 255.0;
|
||||
return float(x * y);
|
||||
}
|
||||
|
||||
static int8u alpha_to_sRGB(float x)
|
||||
{
|
||||
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
|
||||
@@ -1,437 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
// Bessel function (besj) was adapted for use in AGG library by Andy Wilk
|
||||
// Contact: castor.vulgaris@gmail.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_MATH_INCLUDED
|
||||
#define AGG_MATH_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//------------------------------------------------------vertex_dist_epsilon
|
||||
// Coinciding points maximal distance (Epsilon)
|
||||
const double vertex_dist_epsilon = 1e-14;
|
||||
|
||||
//-----------------------------------------------------intersection_epsilon
|
||||
// See calc_intersection
|
||||
const double intersection_epsilon = 1.0e-30;
|
||||
|
||||
//------------------------------------------------------------cross_product
|
||||
AGG_INLINE double cross_product(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------point_in_triangle
|
||||
AGG_INLINE bool point_in_triangle(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double x, double y)
|
||||
{
|
||||
bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
|
||||
bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
|
||||
bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
|
||||
return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------calc_distance
|
||||
AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
return sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------calc_sq_distance
|
||||
AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
//------------------------------------------------calc_line_point_distance
|
||||
AGG_INLINE double calc_line_point_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
double dx = x2-x1;
|
||||
double dy = y2-y1;
|
||||
double d = sqrt(dx * dx + dy * dy);
|
||||
if(d < vertex_dist_epsilon)
|
||||
{
|
||||
return calc_distance(x1, y1, x, y);
|
||||
}
|
||||
return ((x - x2) * dy - (y - y2) * dx) / d;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_line_point_u
|
||||
AGG_INLINE double calc_segment_point_u(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
|
||||
if(dx == 0 && dy == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double pdx = x - x1;
|
||||
double pdy = y - y1;
|
||||
|
||||
return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
//---------------------------------------------calc_line_point_sq_distance
|
||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y,
|
||||
double u)
|
||||
{
|
||||
if(u <= 0)
|
||||
{
|
||||
return calc_sq_distance(x, y, x1, y1);
|
||||
}
|
||||
else
|
||||
if(u >= 1)
|
||||
{
|
||||
return calc_sq_distance(x, y, x2, y2);
|
||||
}
|
||||
return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
|
||||
}
|
||||
|
||||
//---------------------------------------------calc_line_point_sq_distance
|
||||
AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x, double y)
|
||||
{
|
||||
return
|
||||
calc_segment_point_sq_distance(
|
||||
x1, y1, x2, y2, x, y,
|
||||
calc_segment_point_u(x1, y1, x2, y2, x, y));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_intersection
|
||||
AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by,
|
||||
double cx, double cy, double dx, double dy,
|
||||
double* x, double* y)
|
||||
{
|
||||
double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy);
|
||||
double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx);
|
||||
if(fabs(den) < intersection_epsilon) return false;
|
||||
double r = num / den;
|
||||
*x = ax + r * (bx-ax);
|
||||
*y = ay + r * (by-ay);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------intersection_exists
|
||||
AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2,
|
||||
double x3, double y3, double x4, double y4)
|
||||
{
|
||||
// It's less expensive but you can't control the
|
||||
// boundary conditions: Less or LessEqual
|
||||
double dx1 = x2 - x1;
|
||||
double dy1 = y2 - y1;
|
||||
double dx2 = x4 - x3;
|
||||
double dy2 = y4 - y3;
|
||||
return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) !=
|
||||
((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
|
||||
((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
|
||||
((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
|
||||
|
||||
// It's is more expensive but more flexible
|
||||
// in terms of boundary conditions.
|
||||
//--------------------
|
||||
//double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
|
||||
//if(fabs(den) < intersection_epsilon) return false;
|
||||
//double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
|
||||
//double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);
|
||||
//double ua = nom1 / den;
|
||||
//double ub = nom2 / den;
|
||||
//return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------calc_orthogonal
|
||||
AGG_INLINE void calc_orthogonal(double thickness,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double* x, double* y)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
double d = sqrt(dx*dx + dy*dy);
|
||||
*x = thickness * dy / d;
|
||||
*y = -thickness * dx / d;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------dilate_triangle
|
||||
AGG_INLINE void dilate_triangle(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3,
|
||||
double *x, double* y,
|
||||
double d)
|
||||
{
|
||||
double dx1=0.0;
|
||||
double dy1=0.0;
|
||||
double dx2=0.0;
|
||||
double dy2=0.0;
|
||||
double dx3=0.0;
|
||||
double dy3=0.0;
|
||||
double loc = cross_product(x1, y1, x2, y2, x3, y3);
|
||||
if(fabs(loc) > intersection_epsilon)
|
||||
{
|
||||
if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
|
||||
{
|
||||
d = -d;
|
||||
}
|
||||
calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1);
|
||||
calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
|
||||
calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
|
||||
}
|
||||
*x++ = x1 + dx1; *y++ = y1 + dy1;
|
||||
*x++ = x2 + dx1; *y++ = y2 + dy1;
|
||||
*x++ = x2 + dx2; *y++ = y2 + dy2;
|
||||
*x++ = x3 + dx2; *y++ = y3 + dy2;
|
||||
*x++ = x3 + dx3; *y++ = y3 + dy3;
|
||||
*x++ = x1 + dx3; *y++ = y1 + dy3;
|
||||
}
|
||||
|
||||
//------------------------------------------------------calc_triangle_area
|
||||
AGG_INLINE double calc_triangle_area(double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------calc_polygon_area
|
||||
template<class Storage> double calc_polygon_area(const Storage& st)
|
||||
{
|
||||
unsigned i;
|
||||
double sum = 0.0;
|
||||
double x = st[0].x;
|
||||
double y = st[0].y;
|
||||
double xs = x;
|
||||
double ys = y;
|
||||
|
||||
for(i = 1; i < st.size(); i++)
|
||||
{
|
||||
const typename Storage::value_type& v = st[i];
|
||||
sum += x * v.y - y * v.x;
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
}
|
||||
return (sum + x * ys - y * xs) * 0.5;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Tables for fast sqrt
|
||||
extern int16u g_sqrt_table[1024];
|
||||
extern int8 g_elder_bit_table[256];
|
||||
|
||||
|
||||
//---------------------------------------------------------------fast_sqrt
|
||||
//Fast integer Sqrt - really fast: no cycles, divisions or multiplications
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4035) //Disable warning "no return value"
|
||||
#endif
|
||||
AGG_INLINE unsigned fast_sqrt(unsigned val)
|
||||
{
|
||||
#if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
|
||||
//For Ix86 family processors this assembler code is used.
|
||||
//The key command here is bsr - determination the number of the most
|
||||
//significant bit of the value. For other processors
|
||||
//(and maybe compilers) the pure C "#else" section is used.
|
||||
__asm
|
||||
{
|
||||
mov ebx, val
|
||||
mov edx, 11
|
||||
bsr ecx, ebx
|
||||
sub ecx, 9
|
||||
jle less_than_9_bits
|
||||
shr ecx, 1
|
||||
adc ecx, 0
|
||||
sub edx, ecx
|
||||
shl ecx, 1
|
||||
shr ebx, cl
|
||||
less_than_9_bits:
|
||||
xor eax, eax
|
||||
mov ax, g_sqrt_table[ebx*2]
|
||||
mov ecx, edx
|
||||
shr eax, cl
|
||||
}
|
||||
#else
|
||||
|
||||
//This code is actually pure C and portable to most
|
||||
//arcitectures including 64bit ones.
|
||||
unsigned t = val;
|
||||
int bit=0;
|
||||
unsigned shift = 11;
|
||||
|
||||
//The following piece of code is just an emulation of the
|
||||
//Ix86 assembler command "bsr" (see above). However on old
|
||||
//Intels (like Intel MMX 233MHz) this code is about twice
|
||||
//faster (sic!) then just one "bsr". On PIII and PIV the
|
||||
//bsr is optimized quite well.
|
||||
bit = t >> 24;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = (t >> 16) & 0xFF;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = (t >> 8) & 0xFF;
|
||||
if(bit)
|
||||
{
|
||||
bit = g_elder_bit_table[bit] + 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = g_elder_bit_table[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//This code calculates the sqrt.
|
||||
bit -= 9;
|
||||
if(bit > 0)
|
||||
{
|
||||
bit = (bit >> 1) + (bit & 1);
|
||||
shift -= bit;
|
||||
val >>= (bit << 1);
|
||||
}
|
||||
return g_sqrt_table[val] >> shift;
|
||||
#endif
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------besj
|
||||
// Function BESJ calculates Bessel function of first kind of order n
|
||||
// Arguments:
|
||||
// n - an integer (>=0), the order
|
||||
// x - value at which the Bessel function is required
|
||||
//--------------------
|
||||
// C++ Mathematical Library
|
||||
// Convereted from equivalent FORTRAN library
|
||||
// Converetd by Gareth Walker for use by course 392 computational project
|
||||
// All functions tested and yield the same results as the corresponding
|
||||
// FORTRAN versions.
|
||||
//
|
||||
// If you have any problems using these functions please report them to
|
||||
// M.Muldoon@UMIST.ac.uk
|
||||
//
|
||||
// Documentation available on the web
|
||||
// http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
|
||||
// Version 1.0 8/98
|
||||
// 29 October, 1999
|
||||
//--------------------
|
||||
// Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com)
|
||||
//------------------------------------------------------------------------
|
||||
inline double besj(double x, int n)
|
||||
{
|
||||
if(n < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
double d = 1E-6;
|
||||
double b = 0;
|
||||
if(fabs(x) <= d)
|
||||
{
|
||||
if(n != 0) return 0;
|
||||
return 1;
|
||||
}
|
||||
double b1 = 0; // b1 is the value from the previous iteration
|
||||
// Set up a starting order for recurrence
|
||||
int m1 = (int)fabs(x) + 6;
|
||||
if(fabs(x) > 5)
|
||||
{
|
||||
m1 = (int)(fabs(1.4 * x + 60 / x));
|
||||
}
|
||||
int m2 = (int)(n + 2 + fabs(x) / 4);
|
||||
if (m1 > m2)
|
||||
{
|
||||
m2 = m1;
|
||||
}
|
||||
|
||||
// Apply recurrence down from curent max order
|
||||
for(;;)
|
||||
{
|
||||
double c3 = 0;
|
||||
double c2 = 1E-30;
|
||||
double c4 = 0;
|
||||
int m8 = 1;
|
||||
if (m2 / 2 * 2 == m2)
|
||||
{
|
||||
m8 = -1;
|
||||
}
|
||||
int imax = m2 - 2;
|
||||
for (int i = 1; i <= imax; i++)
|
||||
{
|
||||
double c6 = 2 * (m2 - i) * c2 / x - c3;
|
||||
c3 = c2;
|
||||
c2 = c6;
|
||||
if(m2 - i - 1 == n)
|
||||
{
|
||||
b = c6;
|
||||
}
|
||||
m8 = -1 * m8;
|
||||
if (m8 > 0)
|
||||
{
|
||||
c4 = c4 + 2 * c6;
|
||||
}
|
||||
}
|
||||
double c6 = 2 * c2 / x - c3;
|
||||
if(n == 0)
|
||||
{
|
||||
b = c6;
|
||||
}
|
||||
c4 += c6;
|
||||
b /= c4;
|
||||
if(fabs(b - b1) < d)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
b1 = b;
|
||||
m2 += 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_PIXFMT_BASE_INCLUDED
|
||||
#define AGG_PIXFMT_BASE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_color_gray.h"
|
||||
#include "agg_color_rgba.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
struct pixfmt_gray_tag
|
||||
{
|
||||
};
|
||||
|
||||
struct pixfmt_rgb_tag
|
||||
{
|
||||
};
|
||||
|
||||
struct pixfmt_rgba_tag
|
||||
{
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------blender_base
|
||||
template<class ColorT, class Order = void>
|
||||
struct blender_base
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
|
||||
static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full)
|
||||
{
|
||||
if (cover > cover_none)
|
||||
{
|
||||
rgba c(
|
||||
color_type::to_double(r),
|
||||
color_type::to_double(g),
|
||||
color_type::to_double(b),
|
||||
color_type::to_double(a));
|
||||
|
||||
if (cover < cover_full)
|
||||
{
|
||||
double x = double(cover) / cover_full;
|
||||
c.r *= x;
|
||||
c.g *= x;
|
||||
c.b *= x;
|
||||
c.a *= x;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
else return rgba::no_color();
|
||||
}
|
||||
|
||||
static rgba get(const value_type* p, cover_type cover = cover_full)
|
||||
{
|
||||
return get(
|
||||
p[order_type::R],
|
||||
p[order_type::G],
|
||||
p[order_type::B],
|
||||
p[order_type::A],
|
||||
cover);
|
||||
}
|
||||
|
||||
static void set(value_type* p, value_type r, value_type g, value_type b, value_type a)
|
||||
{
|
||||
p[order_type::R] = r;
|
||||
p[order_type::G] = g;
|
||||
p[order_type::B] = b;
|
||||
p[order_type::A] = a;
|
||||
}
|
||||
|
||||
static void set(value_type* p, const rgba& c)
|
||||
{
|
||||
p[order_type::R] = color_type::from_double(c.r);
|
||||
p[order_type::G] = color_type::from_double(c.g);
|
||||
p[order_type::B] = color_type::from_double(c.b);
|
||||
p[order_type::A] = color_type::from_double(c.a);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,738 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or 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
|
||||
|
||||
@@ -1,995 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for high precision colors has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_PIXFMT_RGB_INCLUDED
|
||||
#define AGG_PIXFMT_RGB_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
#include "agg_pixfmt_base.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=====================================================apply_gamma_dir_rgb
|
||||
template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb
|
||||
{
|
||||
public:
|
||||
typedef typename ColorT::value_type value_type;
|
||||
|
||||
apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
|
||||
|
||||
AGG_INLINE void operator () (value_type* p)
|
||||
{
|
||||
p[Order::R] = m_gamma.dir(p[Order::R]);
|
||||
p[Order::G] = m_gamma.dir(p[Order::G]);
|
||||
p[Order::B] = m_gamma.dir(p[Order::B]);
|
||||
}
|
||||
|
||||
private:
|
||||
const GammaLut& m_gamma;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=====================================================apply_gamma_inv_rgb
|
||||
template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb
|
||||
{
|
||||
public:
|
||||
typedef typename ColorT::value_type value_type;
|
||||
|
||||
apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
|
||||
|
||||
AGG_INLINE void operator () (value_type* p)
|
||||
{
|
||||
p[Order::R] = m_gamma.inv(p[Order::R]);
|
||||
p[Order::G] = m_gamma.inv(p[Order::G]);
|
||||
p[Order::B] = m_gamma.inv(p[Order::B]);
|
||||
}
|
||||
|
||||
private:
|
||||
const GammaLut& m_gamma;
|
||||
};
|
||||
|
||||
|
||||
//=========================================================blender_rgb
|
||||
template<class ColorT, class Order>
|
||||
struct blender_rgb
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
// Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
|
||||
// compositing function. Since the render buffer is opaque we skip the
|
||||
// initial premultiply and final demultiply.
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
|
||||
{
|
||||
blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha)
|
||||
{
|
||||
p[Order::R] = color_type::lerp(p[Order::R], cr, alpha);
|
||||
p[Order::G] = color_type::lerp(p[Order::G], cg, alpha);
|
||||
p[Order::B] = color_type::lerp(p[Order::B], cb, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
//======================================================blender_rgb_pre
|
||||
template<class ColorT, class Order>
|
||||
struct blender_rgb_pre
|
||||
{
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
// Blend pixels using the premultiplied form of Alvy-Ray Smith's
|
||||
// compositing function.
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
|
||||
{
|
||||
blend_pix(p,
|
||||
color_type::mult_cover(cr, cover),
|
||||
color_type::mult_cover(cg, cover),
|
||||
color_type::mult_cover(cb, cover),
|
||||
color_type::mult_cover(alpha, cover));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha)
|
||||
{
|
||||
p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha);
|
||||
p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha);
|
||||
p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
//===================================================blender_rgb_gamma
|
||||
template<class ColorT, class Order, class Gamma>
|
||||
class blender_rgb_gamma : public blender_base<ColorT, Order>
|
||||
{
|
||||
public:
|
||||
typedef ColorT color_type;
|
||||
typedef Order order_type;
|
||||
typedef Gamma gamma_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
typedef typename color_type::long_type long_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
blender_rgb_gamma() : m_gamma(0) {}
|
||||
void gamma(const gamma_type& g) { m_gamma = &g; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
|
||||
{
|
||||
blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
AGG_INLINE void blend_pix(value_type* p,
|
||||
value_type cr, value_type cg, value_type cb, value_type alpha)
|
||||
{
|
||||
calc_type r = m_gamma->dir(p[Order::R]);
|
||||
calc_type g = m_gamma->dir(p[Order::G]);
|
||||
calc_type b = m_gamma->dir(p[Order::B]);
|
||||
p[Order::R] = m_gamma->inv(color_type::downscale((m_gamma->dir(cr) - r) * alpha) + r);
|
||||
p[Order::G] = m_gamma->inv(color_type::downscale((m_gamma->dir(cg) - g) * alpha) + g);
|
||||
p[Order::B] = m_gamma->inv(color_type::downscale((m_gamma->dir(cb) - b) * alpha) + b);
|
||||
}
|
||||
|
||||
private:
|
||||
const gamma_type* m_gamma;
|
||||
};
|
||||
|
||||
|
||||
//==================================================pixfmt_alpha_blend_rgb
|
||||
template<class Blender, class RenBuf, unsigned Step, unsigned Offset = 0>
|
||||
class pixfmt_alpha_blend_rgb
|
||||
{
|
||||
public:
|
||||
typedef pixfmt_rgb_tag pixfmt_category;
|
||||
typedef RenBuf rbuf_type;
|
||||
typedef Blender blender_type;
|
||||
typedef typename rbuf_type::row_data row_data;
|
||||
typedef typename blender_type::color_type color_type;
|
||||
typedef typename blender_type::order_type order_type;
|
||||
typedef typename color_type::value_type value_type;
|
||||
typedef typename color_type::calc_type calc_type;
|
||||
enum
|
||||
{
|
||||
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
|
||||
|
||||
@@ -1,741 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in 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 <cstdlib>
|
||||
#include <limits>
|
||||
#include "agg_math.h"
|
||||
#include "agg_array.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------------rasterizer_cells_aa
|
||||
// An internal class that implements the main rasterization algorithm.
|
||||
// Used in the rasterizer. Should not be used direcly.
|
||||
template<class Cell> class rasterizer_cells_aa
|
||||
{
|
||||
enum cell_block_scale_e
|
||||
{
|
||||
cell_block_shift = 12,
|
||||
cell_block_size = 1 << cell_block_shift,
|
||||
cell_block_mask = cell_block_size - 1,
|
||||
cell_block_pool = 256,
|
||||
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(std::numeric_limits<int>::max()),
|
||||
m_min_y(std::numeric_limits<int>::max()),
|
||||
m_max_x(std::numeric_limits<int>::min()),
|
||||
m_max_y(std::numeric_limits<int>::min()),
|
||||
m_sorted(false)
|
||||
{
|
||||
m_style_cell.initial();
|
||||
m_curr_cell.initial();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
void rasterizer_cells_aa<Cell>::reset()
|
||||
{
|
||||
m_num_cells = 0;
|
||||
m_curr_block = 0;
|
||||
m_curr_cell.initial();
|
||||
m_style_cell.initial();
|
||||
m_sorted = false;
|
||||
m_min_x = std::numeric_limits<int>::max();
|
||||
m_min_y = std::numeric_limits<int>::max();
|
||||
m_max_x = std::numeric_limits<int>::min();
|
||||
m_max_y = std::numeric_limits<int>::min();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
AGG_INLINE void rasterizer_cells_aa<Cell>::add_curr_cell()
|
||||
{
|
||||
if(m_curr_cell.area | m_curr_cell.cover)
|
||||
{
|
||||
if((m_num_cells & cell_block_mask) == 0)
|
||||
{
|
||||
if(m_num_blocks >= cell_block_limit) return;
|
||||
allocate_block();
|
||||
}
|
||||
*m_curr_cell_ptr++ = m_curr_cell;
|
||||
++m_num_cells;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
AGG_INLINE void rasterizer_cells_aa<Cell>::set_curr_cell(int x, int y)
|
||||
{
|
||||
if(m_curr_cell.not_equal(x, y, m_style_cell))
|
||||
{
|
||||
add_curr_cell();
|
||||
m_curr_cell.style(m_style_cell);
|
||||
m_curr_cell.x = x;
|
||||
m_curr_cell.y = y;
|
||||
m_curr_cell.cover = 0;
|
||||
m_curr_cell.area = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
AGG_INLINE void rasterizer_cells_aa<Cell>::render_hline(int ey,
|
||||
int x1, int y1,
|
||||
int x2, int y2)
|
||||
{
|
||||
int ex1 = x1 >> poly_subpixel_shift;
|
||||
int ex2 = x2 >> poly_subpixel_shift;
|
||||
int fx1 = x1 & poly_subpixel_mask;
|
||||
int fx2 = x2 & poly_subpixel_mask;
|
||||
|
||||
int delta, p, first;
|
||||
long long dx;
|
||||
int incr, lift, mod, rem;
|
||||
|
||||
//trivial case. Happens often
|
||||
if(y1 == y2)
|
||||
{
|
||||
set_curr_cell(ex2, ey);
|
||||
return;
|
||||
}
|
||||
|
||||
//everything is located in a single cell. That is easy!
|
||||
if(ex1 == ex2)
|
||||
{
|
||||
delta = y2 - y1;
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += (fx1 + fx2) * delta;
|
||||
return;
|
||||
}
|
||||
|
||||
//ok, we'll have to render a run of adjacent cells on the same
|
||||
//hline...
|
||||
p = (poly_subpixel_scale - fx1) * (y2 - y1);
|
||||
first = poly_subpixel_scale;
|
||||
incr = 1;
|
||||
|
||||
dx = (long long)x2 - (long long)x1;
|
||||
|
||||
if(dx < 0)
|
||||
{
|
||||
p = fx1 * (y2 - y1);
|
||||
first = 0;
|
||||
incr = -1;
|
||||
dx = -dx;
|
||||
}
|
||||
|
||||
delta = (int)(p / dx);
|
||||
mod = (int)(p % dx);
|
||||
|
||||
if(mod < 0)
|
||||
{
|
||||
delta--;
|
||||
mod += static_cast<int>(dx);
|
||||
}
|
||||
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += (fx1 + first) * delta;
|
||||
|
||||
ex1 += incr;
|
||||
set_curr_cell(ex1, ey);
|
||||
y1 += delta;
|
||||
|
||||
if(ex1 != ex2)
|
||||
{
|
||||
p = poly_subpixel_scale * (y2 - y1 + delta);
|
||||
lift = (int)(p / dx);
|
||||
rem = (int)(p % dx);
|
||||
|
||||
if (rem < 0)
|
||||
{
|
||||
lift--;
|
||||
rem += static_cast<int>(dx);
|
||||
}
|
||||
|
||||
mod -= static_cast<int>(dx);
|
||||
|
||||
while (ex1 != ex2)
|
||||
{
|
||||
delta = lift;
|
||||
mod += rem;
|
||||
if(mod >= 0)
|
||||
{
|
||||
mod -= static_cast<int>(dx);
|
||||
delta++;
|
||||
}
|
||||
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += poly_subpixel_scale * delta;
|
||||
y1 += delta;
|
||||
ex1 += incr;
|
||||
set_curr_cell(ex1, ey);
|
||||
}
|
||||
}
|
||||
delta = y2 - y1;
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += (fx2 + poly_subpixel_scale - first) * delta;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
AGG_INLINE void rasterizer_cells_aa<Cell>::style(const cell_type& style_cell)
|
||||
{
|
||||
m_style_cell.style(style_cell);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<class Cell>
|
||||
void rasterizer_cells_aa<Cell>::line(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift };
|
||||
|
||||
long long dx = (long long)x2 - (long long)x1;
|
||||
|
||||
if(dx >= dx_limit || dx <= -dx_limit)
|
||||
{
|
||||
int cx = (int)(((long long)x1 + (long long)x2) >> 1);
|
||||
int cy = (int)(((long long)y1 + (long long)y2) >> 1);
|
||||
line(x1, y1, cx, cy);
|
||||
line(cx, cy, x2, y2);
|
||||
}
|
||||
|
||||
long long dy = (long long)y2 - (long long)y1;
|
||||
int ex1 = x1 >> poly_subpixel_shift;
|
||||
int ex2 = x2 >> poly_subpixel_shift;
|
||||
int ey1 = y1 >> poly_subpixel_shift;
|
||||
int ey2 = y2 >> poly_subpixel_shift;
|
||||
int fy1 = y1 & poly_subpixel_mask;
|
||||
int fy2 = y2 & poly_subpixel_mask;
|
||||
|
||||
int x_from, x_to;
|
||||
int rem, mod, lift, delta, first, incr;
|
||||
long long p;
|
||||
|
||||
if(ex1 < m_min_x) m_min_x = ex1;
|
||||
if(ex1 > m_max_x) m_max_x = ex1;
|
||||
if(ey1 < m_min_y) m_min_y = ey1;
|
||||
if(ey1 > m_max_y) m_max_y = ey1;
|
||||
if(ex2 < m_min_x) m_min_x = ex2;
|
||||
if(ex2 > m_max_x) m_max_x = ex2;
|
||||
if(ey2 < m_min_y) m_min_y = ey2;
|
||||
if(ey2 > m_max_y) m_max_y = ey2;
|
||||
|
||||
set_curr_cell(ex1, ey1);
|
||||
|
||||
//everything is on a single hline
|
||||
if(ey1 == ey2)
|
||||
{
|
||||
render_hline(ey1, x1, fy1, x2, fy2);
|
||||
return;
|
||||
}
|
||||
|
||||
//Vertical line - we have to calculate start and end cells,
|
||||
//and then - the common values of the area and coverage for
|
||||
//all cells of the line. We know exactly there's only one
|
||||
//cell, so, we don't have to call render_hline().
|
||||
incr = 1;
|
||||
if(dx == 0)
|
||||
{
|
||||
int ex = x1 >> poly_subpixel_shift;
|
||||
int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1;
|
||||
int area;
|
||||
|
||||
first = poly_subpixel_scale;
|
||||
if(dy < 0)
|
||||
{
|
||||
first = 0;
|
||||
incr = -1;
|
||||
}
|
||||
|
||||
x_from = x1;
|
||||
|
||||
//render_hline(ey1, x_from, fy1, x_from, first);
|
||||
delta = first - fy1;
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += two_fx * delta;
|
||||
|
||||
ey1 += incr;
|
||||
set_curr_cell(ex, ey1);
|
||||
|
||||
delta = first + first - poly_subpixel_scale;
|
||||
area = two_fx * delta;
|
||||
while(ey1 != ey2)
|
||||
{
|
||||
//render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, first);
|
||||
m_curr_cell.cover = delta;
|
||||
m_curr_cell.area = area;
|
||||
ey1 += incr;
|
||||
set_curr_cell(ex, ey1);
|
||||
}
|
||||
//render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, fy2);
|
||||
delta = fy2 - poly_subpixel_scale + first;
|
||||
m_curr_cell.cover += delta;
|
||||
m_curr_cell.area += two_fx * delta;
|
||||
return;
|
||||
}
|
||||
|
||||
//ok, we have to render several hlines
|
||||
p = (poly_subpixel_scale - fy1) * dx;
|
||||
first = poly_subpixel_scale;
|
||||
|
||||
if(dy < 0)
|
||||
{
|
||||
p = fy1 * dx;
|
||||
first = 0;
|
||||
incr = -1;
|
||||
dy = -dy;
|
||||
}
|
||||
|
||||
delta = (int)(p / dy);
|
||||
mod = (int)(p % dy);
|
||||
|
||||
if(mod < 0)
|
||||
{
|
||||
delta--;
|
||||
mod += static_cast<int>(dy);
|
||||
}
|
||||
|
||||
x_from = x1 + delta;
|
||||
render_hline(ey1, x1, fy1, x_from, first);
|
||||
|
||||
ey1 += incr;
|
||||
set_curr_cell(x_from >> poly_subpixel_shift, ey1);
|
||||
|
||||
if(ey1 != ey2)
|
||||
{
|
||||
p = poly_subpixel_scale * dx;
|
||||
lift = (int)(p / dy);
|
||||
rem = (int)(p % dy);
|
||||
|
||||
if(rem < 0)
|
||||
{
|
||||
lift--;
|
||||
rem += static_cast<int>(dy);
|
||||
}
|
||||
mod -= static_cast<int>(dy);
|
||||
|
||||
while(ey1 != ey2)
|
||||
{
|
||||
delta = lift;
|
||||
mod += rem;
|
||||
if (mod >= 0)
|
||||
{
|
||||
mod -= static_cast<int>(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 = std::numeric_limits<int>::max();
|
||||
m_curr_cell.y = std::numeric_limits<int>::max();
|
||||
m_curr_cell.cover = 0;
|
||||
m_curr_cell.area = 0;
|
||||
|
||||
if(m_num_cells == 0) return;
|
||||
|
||||
// DBG: Check to see if min/max works well.
|
||||
//for(unsigned nc = 0; nc < m_num_cells; nc++)
|
||||
//{
|
||||
// cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask);
|
||||
// if(cell->x < m_min_x ||
|
||||
// cell->y < m_min_y ||
|
||||
// cell->x > m_max_x ||
|
||||
// cell->y > m_max_y)
|
||||
// {
|
||||
// cell = cell; // Breakpoint here
|
||||
// }
|
||||
//}
|
||||
// Allocate the array of cell pointers
|
||||
m_sorted_cells.allocate(m_num_cells, 16);
|
||||
|
||||
// Allocate and zero the Y array
|
||||
m_sorted_y.allocate(m_max_y - m_min_y + 1, 16);
|
||||
m_sorted_y.zero();
|
||||
|
||||
// Create the Y-histogram (count the numbers of cells for each Y)
|
||||
cell_type** block_ptr = m_cells;
|
||||
cell_type* cell_ptr;
|
||||
unsigned nb = m_num_cells;
|
||||
unsigned i;
|
||||
while(nb)
|
||||
{
|
||||
cell_ptr = *block_ptr++;
|
||||
i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb;
|
||||
nb -= i;
|
||||
while(i--)
|
||||
{
|
||||
m_sorted_y[cell_ptr->y - m_min_y].start++;
|
||||
++cell_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the Y-histogram into the array of starting indexes
|
||||
unsigned start = 0;
|
||||
for(i = 0; i < m_sorted_y.size(); i++)
|
||||
{
|
||||
unsigned v = m_sorted_y[i].start;
|
||||
m_sorted_y[i].start = start;
|
||||
start += v;
|
||||
}
|
||||
|
||||
// Fill the cell pointer array sorted by Y
|
||||
block_ptr = m_cells;
|
||||
nb = m_num_cells;
|
||||
while(nb)
|
||||
{
|
||||
cell_ptr = *block_ptr++;
|
||||
i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb;
|
||||
nb -= i;
|
||||
while(i--)
|
||||
{
|
||||
sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
|
||||
m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
|
||||
++curr_y.num;
|
||||
++cell_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally arrange the X-arrays
|
||||
for(i = 0; i < m_sorted_y.size(); i++)
|
||||
{
|
||||
const sorted_y& curr_y = m_sorted_y[i];
|
||||
if(curr_y.num)
|
||||
{
|
||||
qsort_cells(m_sorted_cells.data() + curr_y.start, curr_y.num);
|
||||
}
|
||||
}
|
||||
m_sorted = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------scanline_hit_test
|
||||
class scanline_hit_test
|
||||
{
|
||||
public:
|
||||
scanline_hit_test(int x) : m_x(x), m_hit(false) {}
|
||||
|
||||
void reset_spans() {}
|
||||
void finalize(int) {}
|
||||
void add_cell(int x, int)
|
||||
{
|
||||
if(m_x == x) m_hit = true;
|
||||
}
|
||||
void add_span(int x, int len, int)
|
||||
{
|
||||
if(m_x >= x && m_x < x+len) m_hit = true;
|
||||
}
|
||||
unsigned num_spans() const { return 1; }
|
||||
bool hit() const { return m_hit; }
|
||||
|
||||
private:
|
||||
int m_x;
|
||||
bool m_hit;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,481 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// The author gratefully acknowleges the support of David Turner,
|
||||
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
|
||||
// libray - in producing this work. See http://www.freetype.org for details.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
|
||||
#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
|
||||
|
||||
#include "agg_rasterizer_cells_aa.h"
|
||||
#include "agg_rasterizer_sl_clip.h"
|
||||
#include "agg_rasterizer_scanline_aa_nogamma.h"
|
||||
#include "agg_gamma_functions.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//==================================================rasterizer_scanline_aa
|
||||
// Polygon rasterizer that is used to render filled polygons with
|
||||
// high-quality Anti-Aliasing. Internally, by default, the class uses
|
||||
// integer coordinates in format 24.8, i.e. 24 bits for integer part
|
||||
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
|
||||
// used in the following way:
|
||||
//
|
||||
// 1. filling_rule(filling_rule_e ft) - optional.
|
||||
//
|
||||
// 2. gamma() - optional.
|
||||
//
|
||||
// 3. reset()
|
||||
//
|
||||
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
|
||||
// more than one contour, but each contour must consist of at least 3
|
||||
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
|
||||
// is the absolute minimum of vertices that define a triangle.
|
||||
// The algorithm does not check either the number of vertices nor
|
||||
// coincidence of their coordinates, but in the worst case it just
|
||||
// won't draw anything.
|
||||
// The orger of the vertices (clockwise or counterclockwise)
|
||||
// is important when using the non-zero filling rule (fill_non_zero).
|
||||
// In this case the vertex order of all the contours must be the same
|
||||
// if you want your intersecting polygons to be without "holes".
|
||||
// You actually can use different vertices order. If the contours do not
|
||||
// intersect each other the order is not important anyway. If they do,
|
||||
// contours with the same vertex order will be rendered without "holes"
|
||||
// while the intersecting contours with different orders will have "holes".
|
||||
//
|
||||
// filling_rule() and gamma() can be called anytime before "sweeping".
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
|
||||
{
|
||||
enum status
|
||||
{
|
||||
status_initial,
|
||||
status_move_to,
|
||||
status_line_to,
|
||||
status_closed
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Clip clip_type;
|
||||
typedef typename Clip::conv_type conv_type;
|
||||
typedef typename Clip::coord_type coord_type;
|
||||
|
||||
enum aa_scale_e
|
||||
{
|
||||
aa_shift = 8,
|
||||
aa_scale = 1 << aa_shift,
|
||||
aa_mask = aa_scale - 1,
|
||||
aa_scale2 = aa_scale * 2,
|
||||
aa_mask2 = aa_scale2 - 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_scanline_aa() :
|
||||
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
|
||||
|
||||
@@ -1,483 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// The author gratefully acknowleges the support of David Turner,
|
||||
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
|
||||
// libray - in producing this work. See http://www.freetype.org for details.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
|
||||
#define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED
|
||||
|
||||
#include <limits>
|
||||
#include "agg_rasterizer_cells_aa.h"
|
||||
#include "agg_rasterizer_sl_clip.h"
|
||||
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
|
||||
//-----------------------------------------------------------------cell_aa
|
||||
// A pixel cell. There're no constructors defined and it was done
|
||||
// intentionally in order to avoid extra overhead when allocating an
|
||||
// array of cells.
|
||||
struct cell_aa
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int cover;
|
||||
int area;
|
||||
|
||||
void initial()
|
||||
{
|
||||
x = std::numeric_limits<int>::max();
|
||||
y = std::numeric_limits<int>::max();
|
||||
cover = 0;
|
||||
area = 0;
|
||||
}
|
||||
|
||||
void style(const cell_aa&) {}
|
||||
|
||||
int not_equal(int ex, int ey, const cell_aa&) const
|
||||
{
|
||||
return ((unsigned)ex - (unsigned)x) | ((unsigned)ey - (unsigned)y);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==================================================rasterizer_scanline_aa_nogamma
|
||||
// Polygon rasterizer that is used to render filled polygons with
|
||||
// high-quality Anti-Aliasing. Internally, by default, the class uses
|
||||
// integer coordinates in format 24.8, i.e. 24 bits for integer part
|
||||
// and 8 bits for fractional - see poly_subpixel_shift. This class can be
|
||||
// used in the following way:
|
||||
//
|
||||
// 1. filling_rule(filling_rule_e ft) - optional.
|
||||
//
|
||||
// 2. gamma() - optional.
|
||||
//
|
||||
// 3. reset()
|
||||
//
|
||||
// 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create
|
||||
// more than one contour, but each contour must consist of at least 3
|
||||
// vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3);
|
||||
// is the absolute minimum of vertices that define a triangle.
|
||||
// The algorithm does not check either the number of vertices nor
|
||||
// coincidence of their coordinates, but in the worst case it just
|
||||
// won't draw anything.
|
||||
// The orger of the vertices (clockwise or counterclockwise)
|
||||
// is important when using the non-zero filling rule (fill_non_zero).
|
||||
// In this case the vertex order of all the contours must be the same
|
||||
// if you want your intersecting polygons to be without "holes".
|
||||
// You actually can use different vertices order. If the contours do not
|
||||
// intersect each other the order is not important anyway. If they do,
|
||||
// contours with the same vertex order will be rendered without "holes"
|
||||
// while the intersecting contours with different orders will have "holes".
|
||||
//
|
||||
// filling_rule() and gamma() can be called anytime before "sweeping".
|
||||
//------------------------------------------------------------------------
|
||||
template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_nogamma
|
||||
{
|
||||
enum status
|
||||
{
|
||||
status_initial,
|
||||
status_move_to,
|
||||
status_line_to,
|
||||
status_closed
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Clip clip_type;
|
||||
typedef typename Clip::conv_type conv_type;
|
||||
typedef typename Clip::coord_type coord_type;
|
||||
|
||||
enum aa_scale_e
|
||||
{
|
||||
aa_shift = 8,
|
||||
aa_scale = 1 << aa_shift,
|
||||
aa_mask = aa_scale - 1,
|
||||
aa_scale2 = aa_scale * 2,
|
||||
aa_mask2 = aa_scale2 - 1
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_scanline_aa_nogamma() :
|
||||
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
|
||||
|
||||
@@ -1,351 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED
|
||||
#define AGG_RASTERIZER_SL_CLIP_INCLUDED
|
||||
|
||||
#include "agg_clip_liang_barsky.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
//--------------------------------------------------------poly_max_coord_e
|
||||
enum poly_max_coord_e
|
||||
{
|
||||
poly_max_coord = (1 << 30) - 1 //----poly_max_coord
|
||||
};
|
||||
|
||||
//------------------------------------------------------------ras_conv_int
|
||||
struct ras_conv_int
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
return iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------ras_conv_int_sat
|
||||
struct ras_conv_int_sat
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
return saturation<poly_max_coord>::iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v)
|
||||
{
|
||||
return saturation<poly_max_coord>::iround(v * poly_subpixel_scale);
|
||||
}
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//---------------------------------------------------------ras_conv_int_3x
|
||||
struct ras_conv_int_3x
|
||||
{
|
||||
typedef int coord_type;
|
||||
static AGG_INLINE int mul_div(double a, double b, double c)
|
||||
{
|
||||
return iround(a * b / c);
|
||||
}
|
||||
static int xi(int v) { return v * 3; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------ras_conv_dbl
|
||||
struct ras_conv_dbl
|
||||
{
|
||||
typedef double coord_type;
|
||||
static AGG_INLINE double mul_div(double a, double b, double c)
|
||||
{
|
||||
return a * b / c;
|
||||
}
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------ras_conv_dbl_3x
|
||||
struct ras_conv_dbl_3x
|
||||
{
|
||||
typedef double coord_type;
|
||||
static AGG_INLINE double mul_div(double a, double b, double c)
|
||||
{
|
||||
return a * b / c;
|
||||
}
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale * 3); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------rasterizer_sl_clip
|
||||
template<class Conv> class rasterizer_sl_clip
|
||||
{
|
||||
public:
|
||||
typedef Conv conv_type;
|
||||
typedef typename Conv::coord_type coord_type;
|
||||
typedef rect_base<coord_type> rect_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rasterizer_sl_clip() :
|
||||
m_clip_box(0,0,0,0),
|
||||
m_x1(0),
|
||||
m_y1(0),
|
||||
m_f1(0),
|
||||
m_clipping(false)
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_clipping()
|
||||
{
|
||||
m_clipping = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2)
|
||||
{
|
||||
m_clip_box = rect_type(x1, y1, x2, y2);
|
||||
m_clip_box.normalize();
|
||||
m_clipping = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void move_to(coord_type x1, coord_type y1)
|
||||
{
|
||||
m_x1 = x1;
|
||||
m_y1 = y1;
|
||||
if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box);
|
||||
}
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------------
|
||||
template<class Rasterizer>
|
||||
AGG_INLINE void line_clip_y(Rasterizer& ras,
|
||||
coord_type x1, coord_type y1,
|
||||
coord_type x2, coord_type y2,
|
||||
unsigned f1, unsigned f2) const
|
||||
{
|
||||
f1 &= 10;
|
||||
f2 &= 10;
|
||||
if((f1 | f2) == 0)
|
||||
{
|
||||
// Fully visible
|
||||
ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(f1 == f2)
|
||||
{
|
||||
// Invisible by Y
|
||||
return;
|
||||
}
|
||||
|
||||
coord_type tx1 = x1;
|
||||
coord_type ty1 = y1;
|
||||
coord_type tx2 = x2;
|
||||
coord_type ty2 = y2;
|
||||
|
||||
if(f1 & 8) // y1 < clip.y1
|
||||
{
|
||||
tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
|
||||
ty1 = m_clip_box.y1;
|
||||
}
|
||||
|
||||
if(f1 & 2) // y1 > clip.y2
|
||||
{
|
||||
tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
|
||||
ty1 = m_clip_box.y2;
|
||||
}
|
||||
|
||||
if(f2 & 8) // y2 < clip.y1
|
||||
{
|
||||
tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
|
||||
ty2 = m_clip_box.y1;
|
||||
}
|
||||
|
||||
if(f2 & 2) // y2 > clip.y2
|
||||
{
|
||||
tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
|
||||
ty2 = m_clip_box.y2;
|
||||
}
|
||||
ras.line(Conv::xi(tx1), Conv::yi(ty1),
|
||||
Conv::xi(tx2), Conv::yi(ty2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------
|
||||
template<class Rasterizer>
|
||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
||||
{
|
||||
if(m_clipping)
|
||||
{
|
||||
unsigned f2 = clipping_flags(x2, y2, m_clip_box);
|
||||
|
||||
if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
|
||||
{
|
||||
// Invisible by Y
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
m_f1 = f2;
|
||||
return;
|
||||
}
|
||||
|
||||
coord_type x1 = m_x1;
|
||||
coord_type y1 = m_y1;
|
||||
unsigned f1 = m_f1;
|
||||
coord_type y3, y4;
|
||||
unsigned f3, f4;
|
||||
|
||||
switch(((f1 & 5) << 1) | (f2 & 5))
|
||||
{
|
||||
case 0: // Visible by X
|
||||
line_clip_y(ras, x1, y1, x2, y2, f1, f2);
|
||||
break;
|
||||
|
||||
case 1: // x2 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 2: // x1 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 3: // x1 > clip.x2 && x2 > clip.x2
|
||||
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y2, f1, f2);
|
||||
break;
|
||||
|
||||
case 4: // x2 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 6: // x1 > clip.x2 && x2 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
f4 = clipping_flags_y(y4, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x1, y4, f3, f4);
|
||||
line_clip_y(ras, m_clip_box.x1, y4, m_clip_box.x1, y2, f4, f2);
|
||||
break;
|
||||
|
||||
case 8: // x1 < clip.x1
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
|
||||
break;
|
||||
|
||||
case 9: // x1 < clip.x1 && x2 > clip.x2
|
||||
y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
|
||||
y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
|
||||
f3 = clipping_flags_y(y3, m_clip_box);
|
||||
f4 = clipping_flags_y(y4, m_clip_box);
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
|
||||
line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x2, y4, f3, f4);
|
||||
line_clip_y(ras, m_clip_box.x2, y4, m_clip_box.x2, y2, f4, f2);
|
||||
break;
|
||||
|
||||
case 12: // x1 < clip.x1 && x2 < clip.x1
|
||||
line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
|
||||
break;
|
||||
}
|
||||
m_f1 = f2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
|
||||
Conv::xi(x2), Conv::yi(y2));
|
||||
}
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
rect_type m_clip_box;
|
||||
coord_type m_x1;
|
||||
coord_type m_y1;
|
||||
unsigned m_f1;
|
||||
bool m_clipping;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------rasterizer_sl_no_clip
|
||||
class rasterizer_sl_no_clip
|
||||
{
|
||||
public:
|
||||
typedef ras_conv_int conv_type;
|
||||
typedef int coord_type;
|
||||
|
||||
rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
|
||||
|
||||
void reset_clipping() {}
|
||||
void clip_box(coord_type, coord_type, coord_type, coord_type) {}
|
||||
void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
|
||||
|
||||
template<class Rasterizer>
|
||||
void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
|
||||
{
|
||||
ras.line(m_x1, m_y1, x2, y2);
|
||||
m_x1 = x2;
|
||||
m_y1 = y2;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_x1, m_y1;
|
||||
};
|
||||
|
||||
|
||||
// -----rasterizer_sl_clip_int
|
||||
// -----rasterizer_sl_clip_int_sat
|
||||
// -----rasterizer_sl_clip_int_3x
|
||||
// -----rasterizer_sl_clip_dbl
|
||||
// -----rasterizer_sl_clip_dbl_3x
|
||||
//------------------------------------------------------------------------
|
||||
typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int;
|
||||
typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat;
|
||||
typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x;
|
||||
typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl;
|
||||
typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,731 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class renderer_base
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERER_BASE_INCLUDED
|
||||
#define AGG_RENDERER_BASE_INCLUDED
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------renderer_base
|
||||
template<class PixelFormat> class renderer_base
|
||||
{
|
||||
public:
|
||||
typedef PixelFormat pixfmt_type;
|
||||
typedef typename pixfmt_type::color_type color_type;
|
||||
typedef typename pixfmt_type::row_data row_data;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
renderer_base() : m_ren(0), m_clip_box(1, 1, 0, 0) {}
|
||||
explicit renderer_base(pixfmt_type& ren) :
|
||||
m_ren(&ren),
|
||||
m_clip_box(0, 0, ren.width() - 1, ren.height() - 1)
|
||||
{}
|
||||
void attach(pixfmt_type& ren)
|
||||
{
|
||||
m_ren = &ren;
|
||||
m_clip_box = rect_i(0, 0, ren.width() - 1, ren.height() - 1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const pixfmt_type& ren() const { return *m_ren; }
|
||||
pixfmt_type& ren() { return *m_ren; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
unsigned width() const { return m_ren->width(); }
|
||||
unsigned height() const { return m_ren->height(); }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool clip_box(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
rect_i cb(x1, y1, x2, y2);
|
||||
cb.normalize();
|
||||
if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
|
||||
{
|
||||
m_clip_box = cb;
|
||||
return true;
|
||||
}
|
||||
m_clip_box.x1 = 1;
|
||||
m_clip_box.y1 = 1;
|
||||
m_clip_box.x2 = 0;
|
||||
m_clip_box.y2 = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_clipping(bool visibility)
|
||||
{
|
||||
if(visibility)
|
||||
{
|
||||
m_clip_box.x1 = 0;
|
||||
m_clip_box.y1 = 0;
|
||||
m_clip_box.x2 = width() - 1;
|
||||
m_clip_box.y2 = height() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clip_box.x1 = 1;
|
||||
m_clip_box.y1 = 1;
|
||||
m_clip_box.x2 = 0;
|
||||
m_clip_box.y2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clip_box_naked(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
m_clip_box.x1 = x1;
|
||||
m_clip_box.y1 = y1;
|
||||
m_clip_box.x2 = x2;
|
||||
m_clip_box.y2 = y2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool inbox(int x, int y) const
|
||||
{
|
||||
return x >= m_clip_box.x1 && y >= m_clip_box.y1 &&
|
||||
x <= m_clip_box.x2 && y <= m_clip_box.y2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rect_i& clip_box() const { return m_clip_box; }
|
||||
int xmin() const { return m_clip_box.x1; }
|
||||
int ymin() const { return m_clip_box.y1; }
|
||||
int xmax() const { return m_clip_box.x2; }
|
||||
int ymax() const { return m_clip_box.y2; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
const rect_i& bounding_clip_box() const { return m_clip_box; }
|
||||
int bounding_xmin() const { return m_clip_box.x1; }
|
||||
int bounding_ymin() const { return m_clip_box.y1; }
|
||||
int bounding_xmax() const { return m_clip_box.x2; }
|
||||
int bounding_ymax() const { return m_clip_box.y2; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void clear(const color_type& c)
|
||||
{
|
||||
unsigned y;
|
||||
if(width())
|
||||
{
|
||||
for(y = 0; y < height(); y++)
|
||||
{
|
||||
m_ren->copy_hline(0, y, width(), c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void fill(const color_type& c)
|
||||
{
|
||||
unsigned y;
|
||||
if(width())
|
||||
{
|
||||
for(y = 0; y < height(); y++)
|
||||
{
|
||||
m_ren->blend_hline(0, y, width(), c, cover_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_pixel(int x, int y, const color_type& c)
|
||||
{
|
||||
if(inbox(x, y))
|
||||
{
|
||||
m_ren->copy_pixel(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_pixel(int x, int y, const color_type& c, cover_type cover)
|
||||
{
|
||||
if(inbox(x, y))
|
||||
{
|
||||
m_ren->blend_pixel(x, y, c, cover);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
color_type pixel(int x, int y) const
|
||||
{
|
||||
return inbox(x, y) ?
|
||||
m_ren->pixel(x, y) :
|
||||
color_type::no_color();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_hline(int x1, int y, int x2, const color_type& c)
|
||||
{
|
||||
if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
if(x1 > xmax()) return;
|
||||
if(x2 < xmin()) return;
|
||||
|
||||
if(x1 < xmin()) x1 = xmin();
|
||||
if(x2 > xmax()) x2 = xmax();
|
||||
|
||||
m_ren->copy_hline(x1, y, x2 - x1 + 1, c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_vline(int x, int y1, int y2, const color_type& c)
|
||||
{
|
||||
if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
if(y1 > ymax()) return;
|
||||
if(y2 < ymin()) return;
|
||||
|
||||
if(y1 < ymin()) y1 = ymin();
|
||||
if(y2 > ymax()) y2 = ymax();
|
||||
|
||||
m_ren->copy_vline(x, y1, y2 - y1 + 1, c);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_hline(int x1, int y, int x2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
if(x1 > xmax()) return;
|
||||
if(x2 < xmin()) return;
|
||||
|
||||
if(x1 < xmin()) x1 = xmin();
|
||||
if(x2 > xmax()) x2 = xmax();
|
||||
|
||||
m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_vline(int x, int y1, int y2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
if(y1 > ymax()) return;
|
||||
if(y2 < ymin()) return;
|
||||
|
||||
if(y1 < ymin()) y1 = ymin();
|
||||
if(y2 > ymax()) y2 = ymax();
|
||||
|
||||
m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
|
||||
{
|
||||
rect_i rc(x1, y1, x2, y2);
|
||||
rc.normalize();
|
||||
if(rc.clip(clip_box()))
|
||||
{
|
||||
int y;
|
||||
for(y = rc.y1; y <= rc.y2; y++)
|
||||
{
|
||||
m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_bar(int x1, int y1, int x2, int y2,
|
||||
const color_type& c, cover_type cover)
|
||||
{
|
||||
rect_i rc(x1, y1, x2, y2);
|
||||
rc.normalize();
|
||||
if(rc.clip(clip_box()))
|
||||
{
|
||||
int y;
|
||||
for(y = rc.y1; y <= rc.y2; y++)
|
||||
{
|
||||
m_ren->blend_hline(rc.x1,
|
||||
y,
|
||||
unsigned(rc.x2 - rc.x1 + 1),
|
||||
c,
|
||||
cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_hspan(int x, int y, int len,
|
||||
const color_type& c,
|
||||
const cover_type* covers)
|
||||
{
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
|
||||
if(x < xmin())
|
||||
{
|
||||
len -= xmin() - x;
|
||||
if(len <= 0) return;
|
||||
covers += xmin() - x;
|
||||
x = xmin();
|
||||
}
|
||||
if(x + len > xmax())
|
||||
{
|
||||
len = xmax() - x + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->blend_solid_hspan(x, y, len, c, covers);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_solid_vspan(int x, int y, int len,
|
||||
const color_type& c,
|
||||
const cover_type* covers)
|
||||
{
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
|
||||
if(y < ymin())
|
||||
{
|
||||
len -= ymin() - y;
|
||||
if(len <= 0) return;
|
||||
covers += ymin() - y;
|
||||
y = ymin();
|
||||
}
|
||||
if(y + len > ymax())
|
||||
{
|
||||
len = ymax() - y + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->blend_solid_vspan(x, y, len, c, covers);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_hspan(int x, int y, int len, const color_type* colors)
|
||||
{
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
|
||||
if(x < xmin())
|
||||
{
|
||||
int d = xmin() - x;
|
||||
len -= d;
|
||||
if(len <= 0) return;
|
||||
colors += d;
|
||||
x = xmin();
|
||||
}
|
||||
if(x + len > xmax())
|
||||
{
|
||||
len = xmax() - x + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->copy_color_hspan(x, y, len, colors);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void copy_color_vspan(int x, int y, int len, const color_type* colors)
|
||||
{
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
|
||||
if(y < ymin())
|
||||
{
|
||||
int d = ymin() - y;
|
||||
len -= d;
|
||||
if(len <= 0) return;
|
||||
colors += d;
|
||||
y = ymin();
|
||||
}
|
||||
if(y + len > ymax())
|
||||
{
|
||||
len = ymax() - y + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->copy_color_vspan(x, y, len, colors);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_hspan(int x, int y, int len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
if(y > ymax()) return;
|
||||
if(y < ymin()) return;
|
||||
|
||||
if(x < xmin())
|
||||
{
|
||||
int d = xmin() - x;
|
||||
len -= d;
|
||||
if(len <= 0) return;
|
||||
if(covers) covers += d;
|
||||
colors += d;
|
||||
x = xmin();
|
||||
}
|
||||
if(x + len > xmax())
|
||||
{
|
||||
len = xmax() - x + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void blend_color_vspan(int x, int y, int len,
|
||||
const color_type* colors,
|
||||
const cover_type* covers,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
if(x > xmax()) return;
|
||||
if(x < xmin()) return;
|
||||
|
||||
if(y < ymin())
|
||||
{
|
||||
int d = ymin() - y;
|
||||
len -= d;
|
||||
if(len <= 0) return;
|
||||
if(covers) covers += d;
|
||||
colors += d;
|
||||
y = ymin();
|
||||
}
|
||||
if(y + len > ymax())
|
||||
{
|
||||
len = ymax() - y + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
rect_i clip_rect_area(rect_i& dst, rect_i& src, int wsrc, int hsrc) const
|
||||
{
|
||||
rect_i rc(0,0,0,0);
|
||||
rect_i cb = clip_box();
|
||||
++cb.x2;
|
||||
++cb.y2;
|
||||
|
||||
if(src.x1 < 0)
|
||||
{
|
||||
dst.x1 -= src.x1;
|
||||
src.x1 = 0;
|
||||
}
|
||||
if(src.y1 < 0)
|
||||
{
|
||||
dst.y1 -= src.y1;
|
||||
src.y1 = 0;
|
||||
}
|
||||
|
||||
if(src.x2 > wsrc) src.x2 = wsrc;
|
||||
if(src.y2 > hsrc) src.y2 = hsrc;
|
||||
|
||||
if(dst.x1 < cb.x1)
|
||||
{
|
||||
src.x1 += cb.x1 - dst.x1;
|
||||
dst.x1 = cb.x1;
|
||||
}
|
||||
if(dst.y1 < cb.y1)
|
||||
{
|
||||
src.y1 += cb.y1 - dst.y1;
|
||||
dst.y1 = cb.y1;
|
||||
}
|
||||
|
||||
if(dst.x2 > cb.x2) dst.x2 = cb.x2;
|
||||
if(dst.y2 > cb.y2) dst.y2 = cb.y2;
|
||||
|
||||
rc.x2 = dst.x2 - dst.x1;
|
||||
rc.y2 = dst.y2 - dst.y1;
|
||||
|
||||
if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1;
|
||||
if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class RenBuf>
|
||||
void copy_from(const RenBuf& src,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0)
|
||||
{
|
||||
rect_i rsrc(0, 0, src.width(), src.height());
|
||||
if(rect_src_ptr)
|
||||
{
|
||||
rsrc.x1 = rect_src_ptr->x1;
|
||||
rsrc.y1 = rect_src_ptr->y1;
|
||||
rsrc.x2 = rect_src_ptr->x2 + 1;
|
||||
rsrc.y2 = rect_src_ptr->y2 + 1;
|
||||
}
|
||||
|
||||
// Version with xdst, ydst (absolute positioning)
|
||||
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
|
||||
|
||||
// Version with dx, dy (relative positioning)
|
||||
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
|
||||
|
||||
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
|
||||
|
||||
if(rc.x2 > 0)
|
||||
{
|
||||
int incy = 1;
|
||||
if(rdst.y1 > rsrc.y1)
|
||||
{
|
||||
rsrc.y1 += rc.y2 - 1;
|
||||
rdst.y1 += rc.y2 - 1;
|
||||
incy = -1;
|
||||
}
|
||||
while(rc.y2 > 0)
|
||||
{
|
||||
m_ren->copy_from(src,
|
||||
rdst.x1, rdst.y1,
|
||||
rsrc.x1, rsrc.y1,
|
||||
rc.x2);
|
||||
rdst.y1 += incy;
|
||||
rsrc.y1 += incy;
|
||||
--rc.y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from(const SrcPixelFormatRenderer& src,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
rect_i rsrc(0, 0, src.width(), src.height());
|
||||
if(rect_src_ptr)
|
||||
{
|
||||
rsrc.x1 = rect_src_ptr->x1;
|
||||
rsrc.y1 = rect_src_ptr->y1;
|
||||
rsrc.x2 = rect_src_ptr->x2 + 1;
|
||||
rsrc.y2 = rect_src_ptr->y2 + 1;
|
||||
}
|
||||
|
||||
// Version with xdst, ydst (absolute positioning)
|
||||
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
|
||||
|
||||
// Version with dx, dy (relative positioning)
|
||||
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
|
||||
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
|
||||
|
||||
if(rc.x2 > 0)
|
||||
{
|
||||
int incy = 1;
|
||||
if(rdst.y1 > rsrc.y1)
|
||||
{
|
||||
rsrc.y1 += rc.y2 - 1;
|
||||
rdst.y1 += rc.y2 - 1;
|
||||
incy = -1;
|
||||
}
|
||||
while(rc.y2 > 0)
|
||||
{
|
||||
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
|
||||
if(rw.ptr)
|
||||
{
|
||||
int x1src = rsrc.x1;
|
||||
int x1dst = rdst.x1;
|
||||
int len = rc.x2;
|
||||
if(rw.x1 > x1src)
|
||||
{
|
||||
x1dst += rw.x1 - x1src;
|
||||
len -= rw.x1 - x1src;
|
||||
x1src = rw.x1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
if(x1src + len-1 > rw.x2)
|
||||
{
|
||||
len -= x1src + len - rw.x2 - 1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
m_ren->blend_from(src,
|
||||
x1dst, rdst.y1,
|
||||
x1src, rsrc.y1,
|
||||
len,
|
||||
cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
rdst.y1 += incy;
|
||||
rsrc.y1 += incy;
|
||||
--rc.y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from_color(const SrcPixelFormatRenderer& src,
|
||||
const color_type& color,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
rect_i rsrc(0, 0, src.width(), src.height());
|
||||
if(rect_src_ptr)
|
||||
{
|
||||
rsrc.x1 = rect_src_ptr->x1;
|
||||
rsrc.y1 = rect_src_ptr->y1;
|
||||
rsrc.x2 = rect_src_ptr->x2 + 1;
|
||||
rsrc.y2 = rect_src_ptr->y2 + 1;
|
||||
}
|
||||
|
||||
// Version with xdst, ydst (absolute positioning)
|
||||
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
|
||||
|
||||
// Version with dx, dy (relative positioning)
|
||||
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
|
||||
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
|
||||
|
||||
if(rc.x2 > 0)
|
||||
{
|
||||
int incy = 1;
|
||||
if(rdst.y1 > rsrc.y1)
|
||||
{
|
||||
rsrc.y1 += rc.y2 - 1;
|
||||
rdst.y1 += rc.y2 - 1;
|
||||
incy = -1;
|
||||
}
|
||||
while(rc.y2 > 0)
|
||||
{
|
||||
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
|
||||
if(rw.ptr)
|
||||
{
|
||||
int x1src = rsrc.x1;
|
||||
int x1dst = rdst.x1;
|
||||
int len = rc.x2;
|
||||
if(rw.x1 > x1src)
|
||||
{
|
||||
x1dst += rw.x1 - x1src;
|
||||
len -= rw.x1 - x1src;
|
||||
x1src = rw.x1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
if(x1src + len-1 > rw.x2)
|
||||
{
|
||||
len -= x1src + len - rw.x2 - 1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
m_ren->blend_from_color(src,
|
||||
color,
|
||||
x1dst, rdst.y1,
|
||||
x1src, rsrc.y1,
|
||||
len,
|
||||
cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
rdst.y1 += incy;
|
||||
rsrc.y1 += incy;
|
||||
--rc.y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
template<class SrcPixelFormatRenderer>
|
||||
void blend_from_lut(const SrcPixelFormatRenderer& src,
|
||||
const color_type* color_lut,
|
||||
const rect_i* rect_src_ptr = 0,
|
||||
int dx = 0,
|
||||
int dy = 0,
|
||||
cover_type cover = agg::cover_full)
|
||||
{
|
||||
rect_i rsrc(0, 0, src.width(), src.height());
|
||||
if(rect_src_ptr)
|
||||
{
|
||||
rsrc.x1 = rect_src_ptr->x1;
|
||||
rsrc.y1 = rect_src_ptr->y1;
|
||||
rsrc.x2 = rect_src_ptr->x2 + 1;
|
||||
rsrc.y2 = rect_src_ptr->y2 + 1;
|
||||
}
|
||||
|
||||
// Version with xdst, ydst (absolute positioning)
|
||||
//rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
|
||||
|
||||
// Version with dx, dy (relative positioning)
|
||||
rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
|
||||
rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
|
||||
|
||||
if(rc.x2 > 0)
|
||||
{
|
||||
int incy = 1;
|
||||
if(rdst.y1 > rsrc.y1)
|
||||
{
|
||||
rsrc.y1 += rc.y2 - 1;
|
||||
rdst.y1 += rc.y2 - 1;
|
||||
incy = -1;
|
||||
}
|
||||
while(rc.y2 > 0)
|
||||
{
|
||||
typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
|
||||
if(rw.ptr)
|
||||
{
|
||||
int x1src = rsrc.x1;
|
||||
int x1dst = rdst.x1;
|
||||
int len = rc.x2;
|
||||
if(rw.x1 > x1src)
|
||||
{
|
||||
x1dst += rw.x1 - x1src;
|
||||
len -= rw.x1 - x1src;
|
||||
x1src = rw.x1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
if(x1src + len-1 > rw.x2)
|
||||
{
|
||||
len -= x1src + len - rw.x2 - 1;
|
||||
}
|
||||
if(len > 0)
|
||||
{
|
||||
m_ren->blend_from_lut(src,
|
||||
color_lut,
|
||||
x1dst, rdst.y1,
|
||||
x1src, rsrc.y1,
|
||||
len,
|
||||
cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
rdst.y1 += incy;
|
||||
rsrc.y1 += incy;
|
||||
--rc.y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
pixfmt_type* m_ren;
|
||||
rect_i m_clip_box;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,854 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERER_SCANLINE_INCLUDED
|
||||
#define AGG_RENDERER_SCANLINE_INCLUDED
|
||||
|
||||
#include <limits>
|
||||
#include <cstdlib>
|
||||
#include "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 = std::numeric_limits<int>::max();
|
||||
unsigned i;
|
||||
for(i = 0; i < num_styles; i++)
|
||||
{
|
||||
style = ras.style(i);
|
||||
solid = sh.is_solid(style);
|
||||
|
||||
if(ras.sweep_scanline(sl_aa, i))
|
||||
{
|
||||
unsigned cover;
|
||||
color_type* colors;
|
||||
color_type* cspan;
|
||||
cover_type* src_covers;
|
||||
cover_type* dst_covers;
|
||||
span_aa = sl_aa.begin();
|
||||
num_spans = sl_aa.num_spans();
|
||||
sl_y = sl_aa.y();
|
||||
if(solid)
|
||||
{
|
||||
// Just solid fill
|
||||
//-----------------------
|
||||
for(;;)
|
||||
{
|
||||
color_type c = sh.color(style);
|
||||
len = span_aa->len;
|
||||
colors = mix_buffer + span_aa->x - min_x;
|
||||
src_covers = span_aa->covers;
|
||||
dst_covers = cover_buffer + span_aa->x - min_x;
|
||||
do
|
||||
{
|
||||
cover = *src_covers;
|
||||
if(*dst_covers + cover > cover_full)
|
||||
{
|
||||
cover = cover_full - *dst_covers;
|
||||
}
|
||||
if(cover)
|
||||
{
|
||||
colors->add(c, cover);
|
||||
*dst_covers += cover;
|
||||
}
|
||||
++colors;
|
||||
++src_covers;
|
||||
++dst_covers;
|
||||
}
|
||||
while(--len);
|
||||
if(--num_spans == 0) break;
|
||||
++span_aa;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Arbitrary span generator
|
||||
//-----------------------
|
||||
for(;;)
|
||||
{
|
||||
len = span_aa->len;
|
||||
colors = mix_buffer + span_aa->x - min_x;
|
||||
cspan = color_span;
|
||||
sh.generate_span(cspan,
|
||||
span_aa->x,
|
||||
sl_aa.y(),
|
||||
len,
|
||||
style);
|
||||
src_covers = span_aa->covers;
|
||||
dst_covers = cover_buffer + span_aa->x - min_x;
|
||||
do
|
||||
{
|
||||
cover = *src_covers;
|
||||
if(*dst_covers + cover > cover_full)
|
||||
{
|
||||
cover = cover_full - *dst_covers;
|
||||
}
|
||||
if(cover)
|
||||
{
|
||||
colors->add(*cspan, cover);
|
||||
*dst_covers += cover;
|
||||
}
|
||||
++cspan;
|
||||
++colors;
|
||||
++src_covers;
|
||||
++dst_covers;
|
||||
}
|
||||
while(--len);
|
||||
if(--num_spans == 0) break;
|
||||
++span_aa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ren.blend_color_hspan(sl_start,
|
||||
sl_y,
|
||||
sl_len,
|
||||
mix_buffer + sl_start - min_x,
|
||||
0,
|
||||
cover_full);
|
||||
} //if(sl_len)
|
||||
} //if(num_styles == 1) ... else
|
||||
} //while((num_styles = ras.sweep_styles()) > 0)
|
||||
} //if(ras.rewind_scanlines())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,300 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// class rendering_buffer
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef AGG_RENDERING_BUFFER_INCLUDED
|
||||
#define AGG_RENDERING_BUFFER_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//===========================================================row_accessor
|
||||
template<class T> class row_accessor
|
||||
{
|
||||
public:
|
||||
typedef const_row_info<T> row_data;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
row_accessor() :
|
||||
m_buf(0),
|
||||
m_start(0),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
row_accessor(T* buf, unsigned width, unsigned height, int stride) :
|
||||
m_buf(0),
|
||||
m_start(0),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
attach(buf, width, height, stride);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void attach(T* buf, unsigned width, unsigned height, int stride)
|
||||
{
|
||||
m_buf = m_start = buf;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
if(stride < 0)
|
||||
{
|
||||
m_start = m_buf - 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
|
||||
@@ -1,329 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Class scanline_p - a general purpose scanline container with packed spans.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
|
||||
// Liberty Technology Systems, Inc., visit http://lib-sys.com
|
||||
//
|
||||
// Liberty Technology Systems, Inc. is the provider of
|
||||
// PostScript and PDF technology for software developers.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_SCANLINE_P_INCLUDED
|
||||
#define AGG_SCANLINE_P_INCLUDED
|
||||
|
||||
#include "agg_array.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
|
||||
//=============================================================scanline_p8
|
||||
//
|
||||
// This is a general purpose scaline container which supports the interface
|
||||
// used in the rasterizer::render(). See description of scanline_u8
|
||||
// for details.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class scanline_p8
|
||||
{
|
||||
public:
|
||||
typedef scanline_p8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int16 coord_type;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
struct span
|
||||
{
|
||||
coord_type x;
|
||||
coord_type len; // If negative, it's a solid span, covers is valid
|
||||
const cover_type* covers;
|
||||
};
|
||||
|
||||
typedef span* iterator;
|
||||
typedef const span* const_iterator;
|
||||
|
||||
scanline_p8() :
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_covers(),
|
||||
m_cover_ptr(0),
|
||||
m_spans(),
|
||||
m_cur_span(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if(max_len > m_spans.size())
|
||||
{
|
||||
m_spans.resize(max_len);
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_cur_span = &m_spans[0];
|
||||
m_cur_span->len = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
*m_cover_ptr = (cover_type)cover;
|
||||
if(x == m_last_x+1 && m_cur_span->len > 0)
|
||||
{
|
||||
m_cur_span->len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = 1;
|
||||
}
|
||||
m_last_x = x;
|
||||
m_cover_ptr++;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
|
||||
if(x == m_last_x+1 && m_cur_span->len > 0)
|
||||
{
|
||||
m_cur_span->len += (int16)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)len;
|
||||
}
|
||||
m_cover_ptr += len;
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned cover)
|
||||
{
|
||||
if(x == m_last_x+1 &&
|
||||
m_cur_span->len < 0 &&
|
||||
cover == *m_cur_span->covers)
|
||||
{
|
||||
m_cur_span->len -= (int16)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_cover_ptr = (cover_type)cover;
|
||||
m_cur_span++;
|
||||
m_cur_span->covers = m_cover_ptr++;
|
||||
m_cur_span->x = (int16)x;
|
||||
m_cur_span->len = (int16)(-int(len));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_cur_span = &m_spans[0];
|
||||
m_cur_span->len = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
|
||||
const_iterator begin() const { return &m_spans[1]; }
|
||||
|
||||
private:
|
||||
scanline_p8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
cover_type* m_cover_ptr;
|
||||
pod_array<span> m_spans;
|
||||
span* m_cur_span;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================scanline32_p8
|
||||
class scanline32_p8
|
||||
{
|
||||
public:
|
||||
typedef scanline32_p8 self_type;
|
||||
typedef int8u cover_type;
|
||||
typedef int32 coord_type;
|
||||
|
||||
struct span
|
||||
{
|
||||
span() {}
|
||||
span(coord_type x_, coord_type len_, const cover_type* covers_) :
|
||||
x(x_), len(len_), covers(covers_) {}
|
||||
|
||||
coord_type x;
|
||||
coord_type len; // If negative, it's a solid span, covers is valid
|
||||
const cover_type* covers;
|
||||
};
|
||||
typedef pod_bvector<span, 4> span_array_type;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator(const span_array_type& spans) :
|
||||
m_spans(spans),
|
||||
m_span_idx(0)
|
||||
{}
|
||||
|
||||
const span& operator*() const { return m_spans[m_span_idx]; }
|
||||
const span* operator->() const { return &m_spans[m_span_idx]; }
|
||||
|
||||
void operator ++ () { ++m_span_idx; }
|
||||
|
||||
private:
|
||||
const span_array_type& m_spans;
|
||||
unsigned m_span_idx;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
scanline32_p8() :
|
||||
m_max_len(0),
|
||||
m_last_x(0x7FFFFFF0),
|
||||
m_covers(),
|
||||
m_cover_ptr(0)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset(int min_x, int max_x)
|
||||
{
|
||||
unsigned max_len = max_x - min_x + 3;
|
||||
if(max_len > m_covers.size())
|
||||
{
|
||||
m_covers.resize(max_len);
|
||||
}
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cell(int x, unsigned cover)
|
||||
{
|
||||
*m_cover_ptr = cover_type(cover);
|
||||
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
|
||||
{
|
||||
m_spans.last().len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), 1, m_cover_ptr));
|
||||
}
|
||||
m_last_x = x;
|
||||
m_cover_ptr++;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_cells(int x, unsigned len, const cover_type* covers)
|
||||
{
|
||||
memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
|
||||
if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
|
||||
{
|
||||
m_spans.last().len += coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
|
||||
}
|
||||
m_cover_ptr += len;
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void add_span(int x, unsigned len, unsigned cover)
|
||||
{
|
||||
if(x == m_last_x+1 &&
|
||||
m_spans.size() &&
|
||||
m_spans.last().len < 0 &&
|
||||
cover == *m_spans.last().covers)
|
||||
{
|
||||
m_spans.last().len -= coord_type(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_cover_ptr = cover_type(cover);
|
||||
m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
|
||||
}
|
||||
m_last_x = x + len - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void finalize(int y)
|
||||
{
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void reset_spans()
|
||||
{
|
||||
m_last_x = 0x7FFFFFF0;
|
||||
m_cover_ptr = &m_covers[0];
|
||||
m_spans.remove_all();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
int y() const { return m_y; }
|
||||
unsigned num_spans() const { return m_spans.size(); }
|
||||
const_iterator begin() const { return const_iterator(m_spans); }
|
||||
|
||||
private:
|
||||
scanline32_p8(const self_type&);
|
||||
const self_type& operator = (const self_type&);
|
||||
|
||||
unsigned m_max_len;
|
||||
int m_last_x;
|
||||
int m_y;
|
||||
pod_array<cover_type> m_covers;
|
||||
cover_type* m_cover_ptr;
|
||||
span_array_type m_spans;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,518 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Affine transformation classes.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef AGG_TRANS_AFFINE_INCLUDED
|
||||
#define AGG_TRANS_AFFINE_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
#include "agg_basics.h"
|
||||
|
||||
namespace agg
|
||||
{
|
||||
const double affine_epsilon = 1e-14;
|
||||
|
||||
//============================================================trans_affine
|
||||
//
|
||||
// See Implementation agg_trans_affine.cpp
|
||||
//
|
||||
// Affine transformation are linear transformations in Cartesian coordinates
|
||||
// (strictly speaking not only in Cartesian, but for the beginning we will
|
||||
// think so). They are rotation, scaling, translation and skewing.
|
||||
// After any affine transformation a line segment remains a line segment
|
||||
// and it will never become a curve.
|
||||
//
|
||||
// There will be no math about matrix calculations, since it has been
|
||||
// described many times. Ask yourself a very simple question:
|
||||
// "why do we need to understand and use some matrix stuff instead of just
|
||||
// rotating, scaling and so on". The answers are:
|
||||
//
|
||||
// 1. Any combination of transformations can be done by only 4 multiplications
|
||||
// and 4 additions in floating point.
|
||||
// 2. One matrix transformation is equivalent to the number of consecutive
|
||||
// discrete transformations, i.e. the matrix "accumulates" all transformations
|
||||
// in the order of their settings. Suppose we have 4 transformations:
|
||||
// * rotate by 30 degrees,
|
||||
// * scale X to 2.0,
|
||||
// * scale Y to 1.5,
|
||||
// * move to (100, 100).
|
||||
// The result will depend on the order of these transformations,
|
||||
// and the advantage of matrix is that the sequence of discret calls:
|
||||
// rotate(30), scaleX(2.0), scaleY(1.5), move(100,100)
|
||||
// will have exactly the same result as the following matrix transformations:
|
||||
//
|
||||
// affine_matrix m;
|
||||
// m *= rotate_matrix(30);
|
||||
// m *= scaleX_matrix(2.0);
|
||||
// m *= scaleY_matrix(1.5);
|
||||
// m *= move_matrix(100,100);
|
||||
//
|
||||
// m.transform_my_point_at_last(x, y);
|
||||
//
|
||||
// What is the good of it? In real life we will set-up the matrix only once
|
||||
// and then transform many points, let alone the convenience to set any
|
||||
// combination of transformations.
|
||||
//
|
||||
// So, how to use it? Very easy - literally as it's shown above. Not quite,
|
||||
// let us write a correct example:
|
||||
//
|
||||
// agg::trans_affine m;
|
||||
// m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0);
|
||||
// m *= agg::trans_affine_scaling(2.0, 1.5);
|
||||
// m *= agg::trans_affine_translation(100.0, 100.0);
|
||||
// m.transform(&x, &y);
|
||||
//
|
||||
// The affine matrix is all you need to perform any linear transformation,
|
||||
// but all transformations have origin point (0,0). It means that we need to
|
||||
// use 2 translations if we want to rotate someting around (100,100):
|
||||
//
|
||||
// m *= agg::trans_affine_translation(-100.0, -100.0); // move to (0,0)
|
||||
// m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate
|
||||
// m *= agg::trans_affine_translation(100.0, 100.0); // move back to (100,100)
|
||||
//----------------------------------------------------------------------
|
||||
struct trans_affine
|
||||
{
|
||||
double sx, shy, shx, sy, tx, ty;
|
||||
|
||||
//------------------------------------------ Construction
|
||||
// Identity matrix
|
||||
trans_affine() :
|
||||
sx(1.0), shy(0.0), shx(0.0), sy(1.0), tx(0.0), ty(0.0)
|
||||
{}
|
||||
|
||||
// Custom matrix. Usually used in derived classes
|
||||
trans_affine(double v0, double v1, double v2,
|
||||
double v3, double v4, double v5) :
|
||||
sx(v0), shy(v1), shx(v2), sy(v3), tx(v4), ty(v5)
|
||||
{}
|
||||
|
||||
// Custom matrix from m[6]
|
||||
explicit trans_affine(const double* m) :
|
||||
sx(m[0]), shy(m[1]), shx(m[2]), sy(m[3]), tx(m[4]), ty(m[5])
|
||||
{}
|
||||
|
||||
// Rectangle to a parallelogram.
|
||||
trans_affine(double x1, double y1, double x2, double y2,
|
||||
const double* parl)
|
||||
{
|
||||
rect_to_parl(x1, y1, x2, y2, parl);
|
||||
}
|
||||
|
||||
// Parallelogram to a rectangle.
|
||||
trans_affine(const double* parl,
|
||||
double x1, double y1, double x2, double y2)
|
||||
{
|
||||
parl_to_rect(parl, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
// Arbitrary parallelogram transformation.
|
||||
trans_affine(const double* src, const double* dst)
|
||||
{
|
||||
parl_to_parl(src, dst);
|
||||
}
|
||||
|
||||
//---------------------------------- Parellelogram transformations
|
||||
// transform a parallelogram to another one. Src and dst are
|
||||
// pointers to arrays of three points (double[6], x1,y1,...) that
|
||||
// identify three corners of the parallelograms assuming implicit
|
||||
// fourth point. The arguments are arrays of double[6] mapped
|
||||
// to x1,y1, x2,y2, x3,y3 where the coordinates are:
|
||||
// *-----------------*
|
||||
// / (x3,y3)/
|
||||
// / /
|
||||
// /(x1,y1) (x2,y2)/
|
||||
// *-----------------*
|
||||
const trans_affine& parl_to_parl(const double* src,
|
||||
const double* dst);
|
||||
|
||||
const trans_affine& rect_to_parl(double x1, double y1,
|
||||
double x2, double y2,
|
||||
const double* parl);
|
||||
|
||||
const trans_affine& parl_to_rect(const double* parl,
|
||||
double x1, double y1,
|
||||
double x2, double y2);
|
||||
|
||||
|
||||
//------------------------------------------ Operations
|
||||
// Reset - load an identity matrix
|
||||
const trans_affine& reset();
|
||||
|
||||
// Direct transformations operations
|
||||
const trans_affine& translate(double x, double y);
|
||||
const trans_affine& rotate(double a);
|
||||
const trans_affine& scale(double s);
|
||||
const trans_affine& scale(double x, double y);
|
||||
|
||||
// Multiply matrix to another one
|
||||
const trans_affine& multiply(const trans_affine& m);
|
||||
|
||||
// Multiply "m" to "this" and assign the result to "this"
|
||||
const trans_affine& premultiply(const trans_affine& m);
|
||||
|
||||
// Multiply matrix to inverse of another one
|
||||
const trans_affine& multiply_inv(const trans_affine& m);
|
||||
|
||||
// Multiply inverse of "m" to "this" and assign the result to "this"
|
||||
const trans_affine& premultiply_inv(const trans_affine& m);
|
||||
|
||||
// Invert matrix. Do not try to invert degenerate matrices,
|
||||
// there's no check for validity. If you set scale to 0 and
|
||||
// then try to invert matrix, expect unpredictable result.
|
||||
const trans_affine& invert();
|
||||
|
||||
// Mirroring around X
|
||||
const trans_affine& flip_x();
|
||||
|
||||
// Mirroring around Y
|
||||
const trans_affine& flip_y();
|
||||
|
||||
//------------------------------------------- Load/Store
|
||||
// Store matrix to an array [6] of double
|
||||
void store_to(double* m) const
|
||||
{
|
||||
*m++ = sx; *m++ = shy; *m++ = shx; *m++ = sy; *m++ = tx; *m++ = ty;
|
||||
}
|
||||
|
||||
// Load matrix from an array [6] of double
|
||||
const trans_affine& load_from(const double* m)
|
||||
{
|
||||
sx = *m++; shy = *m++; shx = *m++; sy = *m++; tx = *m++; ty = *m++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------- Operators
|
||||
|
||||
// Multiply the matrix by another one
|
||||
const trans_affine& operator *= (const trans_affine& m)
|
||||
{
|
||||
return multiply(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by inverse of another one
|
||||
const trans_affine& operator /= (const trans_affine& m)
|
||||
{
|
||||
return multiply_inv(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by another one and return
|
||||
// the result in a separete matrix.
|
||||
trans_affine operator * (const trans_affine& m) const
|
||||
{
|
||||
return trans_affine(*this).multiply(m);
|
||||
}
|
||||
|
||||
// Multiply the matrix by inverse of another one
|
||||
// and return the result in a separete matrix.
|
||||
trans_affine operator / (const trans_affine& m) const
|
||||
{
|
||||
return trans_affine(*this).multiply_inv(m);
|
||||
}
|
||||
|
||||
// Calculate and return the inverse matrix
|
||||
trans_affine operator ~ () const
|
||||
{
|
||||
trans_affine ret = *this;
|
||||
return ret.invert();
|
||||
}
|
||||
|
||||
// Equal operator with default epsilon
|
||||
bool operator == (const trans_affine& m) const
|
||||
{
|
||||
return is_equal(m, affine_epsilon);
|
||||
}
|
||||
|
||||
// Not Equal operator with default epsilon
|
||||
bool operator != (const trans_affine& m) const
|
||||
{
|
||||
return !is_equal(m, affine_epsilon);
|
||||
}
|
||||
|
||||
//-------------------------------------------- Transformations
|
||||
// Direct transformation of x and y
|
||||
void transform(double* x, double* y) const;
|
||||
|
||||
// Direct transformation of x and y, 2x2 matrix only, no translation
|
||||
void transform_2x2(double* x, double* y) const;
|
||||
|
||||
// Inverse transformation of x and y. It works slower than the
|
||||
// direct transformation. For massive operations it's better to
|
||||
// invert() the matrix and then use direct transformations.
|
||||
void inverse_transform(double* x, double* y) const;
|
||||
|
||||
//-------------------------------------------- Auxiliary
|
||||
// Calculate the determinant of matrix
|
||||
double determinant() const
|
||||
{
|
||||
return sx * sy - shy * shx;
|
||||
}
|
||||
|
||||
// Calculate the reciprocal of the determinant
|
||||
double determinant_reciprocal() const
|
||||
{
|
||||
return 1.0 / (sx * sy - shy * shx);
|
||||
}
|
||||
|
||||
// Get the average scale (by X and Y).
|
||||
// Basically used to calculate the approximation_scale when
|
||||
// decomposinting curves into line segments.
|
||||
double scale() const;
|
||||
|
||||
// Check to see if the matrix is not degenerate
|
||||
bool is_valid(double epsilon = affine_epsilon) const;
|
||||
|
||||
// Check to see if it's an identity matrix
|
||||
bool is_identity(double epsilon = affine_epsilon) const;
|
||||
|
||||
// Check to see if two matrices are equal
|
||||
bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const;
|
||||
|
||||
// Determine the major parameters. Use with caution considering
|
||||
// possible degenerate cases.
|
||||
double rotation() const;
|
||||
void translation(double* dx, double* dy) const;
|
||||
void scaling(double* x, double* y) const;
|
||||
void scaling_abs(double* x, double* y) const;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_affine::transform(double* x, double* y) const
|
||||
{
|
||||
double tmp = *x;
|
||||
*x = tmp * sx + *y * shx + tx;
|
||||
*y = tmp * shy + *y * sy + ty;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_affine::transform_2x2(double* x, double* y) const
|
||||
{
|
||||
double tmp = *x;
|
||||
*x = tmp * sx + *y * shx;
|
||||
*y = tmp * shy + *y * sy;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_affine::inverse_transform(double* x, double* y) const
|
||||
{
|
||||
double d = determinant_reciprocal();
|
||||
double a = (*x - tx) * d;
|
||||
double b = (*y - ty) * d;
|
||||
*x = a * sy - b * shx;
|
||||
*y = b * sx - a * shy;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline double trans_affine::scale() const
|
||||
{
|
||||
double x = 0.707106781 * sx + 0.707106781 * shx;
|
||||
double y = 0.707106781 * shy + 0.707106781 * sy;
|
||||
return sqrt(x*x + y*y);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::translate(double x, double y)
|
||||
{
|
||||
tx += x;
|
||||
ty += y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::rotate(double a)
|
||||
{
|
||||
double ca = cos(a);
|
||||
double sa = sin(a);
|
||||
double t0 = sx * ca - shy * sa;
|
||||
double t2 = shx * ca - sy * sa;
|
||||
double t4 = tx * ca - ty * sa;
|
||||
shy = sx * sa + shy * ca;
|
||||
sy = shx * sa + sy * ca;
|
||||
ty = tx * sa + ty * ca;
|
||||
sx = t0;
|
||||
shx = t2;
|
||||
tx = t4;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::scale(double x, double y)
|
||||
{
|
||||
double mm0 = x; // Possible hint for the optimizer
|
||||
double mm3 = y;
|
||||
sx *= mm0;
|
||||
shx *= mm0;
|
||||
tx *= mm0;
|
||||
shy *= mm3;
|
||||
sy *= mm3;
|
||||
ty *= mm3;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::scale(double s)
|
||||
{
|
||||
double m = s; // Possible hint for the optimizer
|
||||
sx *= m;
|
||||
shx *= m;
|
||||
tx *= m;
|
||||
shy *= m;
|
||||
sy *= m;
|
||||
ty *= m;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::premultiply(const trans_affine& m)
|
||||
{
|
||||
trans_affine t = m;
|
||||
return *this = t.multiply(*this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::multiply_inv(const trans_affine& m)
|
||||
{
|
||||
trans_affine t = m;
|
||||
t.invert();
|
||||
return multiply(t);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline const trans_affine& trans_affine::premultiply_inv(const trans_affine& m)
|
||||
{
|
||||
trans_affine t = m;
|
||||
t.invert();
|
||||
return *this = t.multiply(*this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void trans_affine::scaling_abs(double* x, double* y) const
|
||||
{
|
||||
// Used to calculate scaling coefficients in image resampling.
|
||||
// When there is considerable shear this method gives us much
|
||||
// better estimation than just sx, sy.
|
||||
*x = sqrt(sx * sx + shx * shx);
|
||||
*y = sqrt(shy * shy + sy * sy);
|
||||
}
|
||||
|
||||
//====================================================trans_affine_rotation
|
||||
// Rotation matrix. sin() and cos() are calculated twice for the same angle.
|
||||
// There's no harm because the performance of sin()/cos() is very good on all
|
||||
// modern processors. Besides, this operation is not going to be invoked too
|
||||
// often.
|
||||
class trans_affine_rotation : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_rotation(double a) :
|
||||
trans_affine(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//====================================================trans_affine_scaling
|
||||
// Scaling matrix. x, y - scale coefficients by X and Y respectively
|
||||
class trans_affine_scaling : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_scaling(double x, double y) :
|
||||
trans_affine(x, 0.0, 0.0, y, 0.0, 0.0)
|
||||
{}
|
||||
|
||||
trans_affine_scaling(double s) :
|
||||
trans_affine(s, 0.0, 0.0, s, 0.0, 0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
//================================================trans_affine_translation
|
||||
// Translation matrix
|
||||
class trans_affine_translation : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_translation(double x, double y) :
|
||||
trans_affine(1.0, 0.0, 0.0, 1.0, x, y)
|
||||
{}
|
||||
};
|
||||
|
||||
//====================================================trans_affine_skewing
|
||||
// Sckewing (shear) matrix
|
||||
class trans_affine_skewing : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_skewing(double x, double y) :
|
||||
trans_affine(1.0, tan(y), tan(x), 1.0, 0.0, 0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//===============================================trans_affine_line_segment
|
||||
// Rotate, Scale and Translate, associating 0...dist with line segment
|
||||
// x1,y1,x2,y2
|
||||
class trans_affine_line_segment : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_line_segment(double x1, double y1, double x2, double y2,
|
||||
double dist)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
if(dist > 0.0)
|
||||
{
|
||||
multiply(trans_affine_scaling(sqrt(dx * dx + dy * dy) / dist));
|
||||
}
|
||||
multiply(trans_affine_rotation(atan2(dy, dx)));
|
||||
multiply(trans_affine_translation(x1, y1));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//============================================trans_affine_reflection_unit
|
||||
// Reflection matrix. Reflect coordinates across the line through
|
||||
// the origin containing the unit vector (ux, uy).
|
||||
// Contributed by John Horigan
|
||||
class trans_affine_reflection_unit : public trans_affine
|
||||
{
|
||||
public:
|
||||
trans_affine_reflection_unit(double ux, double uy) :
|
||||
trans_affine(2.0 * ux * ux - 1.0,
|
||||
2.0 * ux * uy,
|
||||
2.0 * ux * uy,
|
||||
2.0 * uy * uy - 1.0,
|
||||
0.0, 0.0)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//=================================================trans_affine_reflection
|
||||
// Reflection matrix. Reflect coordinates across the line through
|
||||
// the origin at the angle a or containing the non-unit vector (x, y).
|
||||
// Contributed by John Horigan
|
||||
class trans_affine_reflection : public trans_affine_reflection_unit
|
||||
{
|
||||
public:
|
||||
trans_affine_reflection(double a) :
|
||||
trans_affine_reflection_unit(cos(a), sin(a))
|
||||
{}
|
||||
|
||||
|
||||
trans_affine_reflection(double x, double y) :
|
||||
trans_affine_reflection_unit(x / sqrt(x * x + y * y), y / sqrt(x * x + y * y))
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
The Anti-Grain Geometry Project
|
||||
A high quality rendering engine for C++
|
||||
http://antigrain.com
|
||||
|
||||
Anti-Grain Geometry has dual licensing model. The Modified BSD
|
||||
License was first added in version v2.4 just for convenience.
|
||||
It is a simple, permissive non-copyleft free software license,
|
||||
compatible with the GNU GPL. It's well proven and recognizable.
|
||||
See http://www.fsf.org/licensing/licenses/index_html#ModifiedBSD
|
||||
for details.
|
||||
|
||||
Note that the Modified BSD license DOES NOT restrict your rights
|
||||
if you choose the Anti-Grain Geometry Public License.
|
||||
|
||||
|
||||
|
||||
|
||||
Anti-Grain Geometry Public License
|
||||
====================================================
|
||||
|
||||
Anti-Grain Geometry - Version 2.4
|
||||
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
||||
|
||||
Permission to copy, use, modify, sell and distribute this software
|
||||
is granted provided this copyright notice appears in all copies.
|
||||
This software is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Modified BSD License
|
||||
====================================================
|
||||
Anti-Grain Geometry - Version 2.4
|
||||
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
THIS DIRECTORY CONTAINS PIECES OF THE
|
||||
ankerl::unordered_dense::{map, set}
|
||||
https://github.com/martinus/unordered_dense
|
||||
unordered_dense 3.1.1 10782bfc651c2bb75b11bf90491f50da122e5432
|
||||
SOURCE DISTRIBUTION.
|
||||
|
||||
THIS IS NOT THE COMPLETE unordered_dense DISTRIBUTION. ONLY FILES NEEDED FOR COMPILING QIDISLICER WERE PUT INTO THE QIDISLICER SOURCE DISTRIBUTION.
|
||||
@@ -1,107 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
add_definitions(-D_BSD_SOURCE -D_DEFAULT_SOURCE) # To enable various useful macros and functions on Unices
|
||||
remove_definitions(-D_UNICODE -DUNICODE)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# Workaround for an old CMake, which does not understand CMAKE_C_STANDARD.
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall")
|
||||
endif()
|
||||
|
||||
|
||||
set(AVRDUDE_SOURCES
|
||||
avrdude/arduino.c
|
||||
avrdude/avr.c
|
||||
# avrdude/avrftdi.c
|
||||
# avrdude/avrftdi_tpi.c
|
||||
avrdude/avrpart.c
|
||||
avrdude/avr910.c
|
||||
avrdude/bitbang.c
|
||||
avrdude/buspirate.c
|
||||
avrdude/butterfly.c
|
||||
avrdude/config.c
|
||||
avrdude/config_gram.c
|
||||
# avrdude/confwin.c
|
||||
avrdude/crc16.c
|
||||
# avrdude/dfu.c
|
||||
avrdude/fileio.c
|
||||
# avrdude/flip1.c
|
||||
# avrdude/flip2.c
|
||||
# avrdude/ft245r.c
|
||||
# avrdude/jtagmkI.c
|
||||
# avrdude/jtagmkII.c
|
||||
# avrdude/jtag3.c
|
||||
avrdude/lexer.c
|
||||
avrdude/linuxgpio.c
|
||||
avrdude/lists.c
|
||||
# avrdude/par.c
|
||||
avrdude/pgm.c
|
||||
avrdude/pgm_type.c
|
||||
avrdude/pickit2.c
|
||||
avrdude/pindefs.c
|
||||
# avrdude/ppi.c
|
||||
# avrdude/ppiwin.c
|
||||
avrdude/safemode.c
|
||||
avrdude/ser_avrdoper.c
|
||||
avrdude/serbb_posix.c
|
||||
avrdude/serbb_win32.c
|
||||
avrdude/ser_posix.c
|
||||
avrdude/ser_win32.c
|
||||
avrdude/stk500.c
|
||||
avrdude/stk500generic.c
|
||||
avrdude/stk500v2.c
|
||||
avrdude/term.c
|
||||
avrdude/update.c
|
||||
# avrdude/usbasp.c
|
||||
# avrdude/usb_hidapi.c
|
||||
# avrdude/usb_libusb.c
|
||||
# avrdude/usbtiny.c
|
||||
avrdude/wiring.c
|
||||
|
||||
avrdude/main.c
|
||||
avrdude/avrdude-slic3r.hpp
|
||||
avrdude/avrdude-slic3r.cpp
|
||||
)
|
||||
if (MSVC)
|
||||
set(AVRDUDE_SOURCES ${AVRDUDE_SOURCES}
|
||||
avrdude/windows/utf8.c
|
||||
avrdude/windows/unistd.cpp
|
||||
avrdude/windows/getopt.c
|
||||
)
|
||||
elseif (MINGW)
|
||||
set(AVRDUDE_SOURCES ${AVRDUDE_SOURCES}
|
||||
avrdude/windows/utf8.c
|
||||
)
|
||||
endif()
|
||||
|
||||
include(bin2h)
|
||||
|
||||
bin2h(
|
||||
SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/avrdude/avrdude-slic3r.conf
|
||||
VARIABLE_NAME avrdude_slic3r_conf
|
||||
HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/avrdude-slic3r.conf.h
|
||||
ADD_WARNING_TEXT
|
||||
)
|
||||
|
||||
add_library(avrdude STATIC ${AVRDUDE_SOURCES})
|
||||
target_link_libraries(avrdude PRIVATE localesutils)
|
||||
|
||||
add_executable(avrdude-slic3r avrdude/main-standalone.cpp)
|
||||
target_link_libraries(avrdude-slic3r avrdude)
|
||||
|
||||
encoding_check(avrdude)
|
||||
encoding_check(avrdude-slic3r)
|
||||
|
||||
# Make avrdude-slic3r.conf.h includable:
|
||||
target_include_directories(avrdude SYSTEM PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_include_directories(avrdude PUBLIC .)
|
||||
|
||||
if (WIN32)
|
||||
target_compile_definitions(avrdude PRIVATE WIN32NATIVE=1)
|
||||
if(MSVC)
|
||||
target_include_directories(avrdude SYSTEM PRIVATE avrdude/windows) # So that sources find the getopt.h windows drop-in
|
||||
endif(MSVC)
|
||||
endif()
|
||||
@@ -1,28 +0,0 @@
|
||||
AVRDUDE was written by:
|
||||
|
||||
Brian S. Dean <bsd@bdmicro.com>
|
||||
|
||||
Contributors:
|
||||
|
||||
Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
Eric Weddington <ericw@evcohs.com>
|
||||
Jan-Hinnerk Reichert <hinni@despammed.com>
|
||||
Alex Shepherd <maillists@ajsystems.co.nz>
|
||||
Martin Thomas <mthomas@rhrk.uni-kl.de>
|
||||
Theodore A. Roth <troth@openavr.org>
|
||||
Michael Holzt <kju-avr@fqdn.org>
|
||||
Colin O'Flynn <coflynn@newae.com>
|
||||
Thomas Fischl <tfischl@gmx.de>
|
||||
David Hoerl <dhoerl@mac.com>
|
||||
Michal Ludvig <mludvig@logix.net.nz>
|
||||
Darell Tan <darell.tan@gmail.com>
|
||||
Wolfgang Moser
|
||||
Ville Voipio
|
||||
Hannes Weisbach
|
||||
Doug Springer
|
||||
Brett Hagman <bhagman@roguerobotics.com>
|
||||
Rene Liebscher <r.liebscher@gmx.de>
|
||||
Jim Paris <jim@jtan.com>
|
||||
|
||||
For minor contributions, please see the ChangeLog files.
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
$Id$
|
||||
|
||||
How to build avrdude from SVN:
|
||||
|
||||
1. svn co svn://svn.savannah.nongnu.org/avrdude/trunk
|
||||
|
||||
2. cd trunk/avrdude
|
||||
|
||||
3. ./bootstrap
|
||||
|
||||
4. ./configure
|
||||
|
||||
5. make
|
||||
@@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -1,99 +0,0 @@
|
||||
2018-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
(cherry-picked)
|
||||
Submitted by Reinhard Max
|
||||
patch #8311: Add IPv6 support to the -Pnet:host:port option
|
||||
* ser_posix.c (net_open): Rewrite to use getaddrinfo()
|
||||
rather than gethostbyname()
|
||||
* avrdude.1: Document IPv6 feature
|
||||
* doc/avrdude.texi: (Dito)
|
||||
|
||||
2016-05-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Hannes Jochriem:
|
||||
* avrdude.conf.in (ehajo-isp): New programmer.
|
||||
|
||||
2016-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (libftdi1): Rather than hardcoding the library
|
||||
providing the libusb-1.0 API, use the result from the previous
|
||||
probe. This helps detecting libftdi1 on FreeBSD where the
|
||||
libusb-1.0 API is provided by the system's libusb.
|
||||
|
||||
2016-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_hidapi.c (usbhid_open): Correctly calculate the
|
||||
offset for serial number matching
|
||||
|
||||
2016-03-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #47550: Linux GPIO broken
|
||||
* linuxgpio.c: Replace %ud by %u in snprintf calls.
|
||||
|
||||
2016-03-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_hidapi.c (usbhid_recv): Bump read timeout to 300 ms.
|
||||
|
||||
2016-02-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: add support for libhidapi as (optional) transport for
|
||||
CMSIS-DAP compliant debuggers (JTAGICE3 with firmware 3+,
|
||||
AtmelICE, EDBG, mEDBG)
|
||||
* usb_hidapi.c: (New file)
|
||||
* libavrdude.h: Mention usbhid_serdev
|
||||
* configure.ac: Bump version date
|
||||
|
||||
2016-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
(Obtained from patch #8717: pattch for mcprog and libhidapi support)
|
||||
* configure.ac: Probe for libhidapi
|
||||
* Makefile.am: Add @LIBHIDAPI@
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Bump copyright year.
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-release 6.3.
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 6.3.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8894: Spelling in 6.2 doc
|
||||
* doc/avrdude.texi: Various spelling fixes.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8895: Spelling in 6.2 code
|
||||
* avrftdi.c (avrftdi_open): Spell fix.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8896: Silence cppcheck warnings in 6.2 code
|
||||
* linuxgpio.c: Use %ud to print GPIO values.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8735: ATtiny28 support in avrdude.conf
|
||||
* avrdude.conf.in (ATtiny28): New device.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega48PB, ATmega88PB, ATmega168PB): New
|
||||
devices.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8435: Implementing mEDBG CMSIS-DAP protocol
|
||||
* usb_libusb.c: Add endpoint IDs for Xplained Mini, correctly
|
||||
transfer trailing ZLP when needed
|
||||
* avrdude.conf.in (xplainedmini, xplainedmini_dw): New entries.
|
||||
* jtag3.c (jtag3_edbg_send, jtag3_edbg_recv_frame): Implement
|
||||
fragmentation needed for the 64-byte EP size of the Xplained Mini
|
||||
* avrdude.1: Document the change
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
|
||||
@@ -1,598 +0,0 @@
|
||||
2001-12-30 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Update version.
|
||||
|
||||
* avrdude.conf.sample: Clarify a comment.
|
||||
|
||||
* avrdude.conf.sample: fix address bits
|
||||
|
||||
* avrdude.1: Bring up to date.
|
||||
|
||||
2001-12-29 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample: Add the AVR3 progammer.
|
||||
|
||||
* avr.c, avrdude.conf.sample, config_gram.y, main.c, pindefs.h:
|
||||
Fix VCC assertion.
|
||||
|
||||
Make the BUFF pin a mask like VCC to allow multiple pins to be
|
||||
asserted at the same time (STK200 has two buffer enable lines).
|
||||
|
||||
Add the STK200 programmer.
|
||||
|
||||
Fix EEPROM address line selection for several parts.
|
||||
|
||||
2001-12-15 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample: fix spelling error
|
||||
|
||||
2001-11-24 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile:
|
||||
Change "WARNING" to "NOTE" when overwriting the avrprog.conf file.
|
||||
|
||||
* avrdude.1: Add my e-mail address.
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Add comments about instruction formats. Correct an instruction
|
||||
specification (cut&paste error).
|
||||
|
||||
2001-11-21 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, config_gram.y, lexer.l, term.c:
|
||||
In interactive mode, reset the address and length if we start dumping
|
||||
a memory type different than the previous one.
|
||||
|
||||
* avr.c, avrdude.conf.sample, config_gram.y:
|
||||
Allow instruction data to be specified more flexibly, which can be
|
||||
used to make the instruction input more readable in the config file.
|
||||
|
||||
* main.c: Bump version number.
|
||||
|
||||
* Makefile, avr.c, avr.h, avrdude.conf.sample, config.c, config.h:
|
||||
* config_gram.y, fileio.c, fileio.h, lexer.l, main.c, term.c:
|
||||
This is a major re-write of the programming algorithms. The Atmel
|
||||
serial programming instructions are not very orthoganal, i.e., the
|
||||
"read fuse bits" instruction on an ATMega103 is an entirely different
|
||||
opcode and data format from the _same_ instruction for an ATMega163!
|
||||
Thus, it becomes impossible to have a single instruction encoding
|
||||
(varying the data) across the chip lines.
|
||||
|
||||
This set of changes allows and requires instruction encodings to be
|
||||
defined on a per-part basis within the configuration file. Hopefully
|
||||
I've defined the encoding scheme in a general enough way so it is
|
||||
useful in describing the instruction formats for yet-to-be invented
|
||||
Atmel chips. I've tried hard to make it match very closely with the
|
||||
specification in Atmel's data sheets for their parts. It's a little
|
||||
more verbose than what I initially hoped for, but I've tried to keep
|
||||
it as concise as I could, while still remaining reasonably flexible.
|
||||
|
||||
2001-11-19 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avr.h, avrdude.conf.sample, main.c, ppi.c, term.c:
|
||||
Add support for ATMega163.
|
||||
|
||||
Add support for reading/writing ATMega163 lock and fuse bits.
|
||||
Unfortunately, in looking at the specs for other ATMega parts, they
|
||||
use entirely different instruction formats for these commands. Thus,
|
||||
these routines won't work for the ATMega103, for example.
|
||||
|
||||
Add support for sending raw command bytes via the interactive terminal
|
||||
interface. This allows one to execute any programming instruction on
|
||||
the target device, whether or not avrprog supports it explicitly or
|
||||
not. Thus, one can use this feature to program fuse / lock bits, or
|
||||
access any other feature of a current or future device that avrprog
|
||||
does not know how to do.
|
||||
|
||||
Add in comments, an experimental instruction format in the
|
||||
configuration file. If this works out, it would allow supporting new
|
||||
parts and non-orthoganal instructions across existing parts without
|
||||
making avrprog code changes.
|
||||
|
||||
2001-11-17 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample: Add ATMEGA163 part.
|
||||
|
||||
2001-11-11 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: output formatting
|
||||
|
||||
2001-11-05 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* ppi.c: Get ppi.h from /usr/include, not /sys.
|
||||
|
||||
2001-10-31 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avrdude.conf.sample, main.c: Correct version string.
|
||||
Update read/write status more frequently.
|
||||
Prefix ATMega parts with an 'm'.
|
||||
|
||||
2001-10-16 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c: Change ording for memory display.
|
||||
|
||||
* config_gram.y: comment
|
||||
|
||||
* avr.c, avr.h, avrdude.conf.sample, config_gram.y, lexer.l, term.c:
|
||||
Fix (again, hopefully) page addressing for the ATMega parts.
|
||||
|
||||
Rename the poorly chosen name "bank" to "page" for page addressing.
|
||||
Atmel calls it "page" in their documentation.
|
||||
|
||||
* config_gram.y, main.c: Fix an (non)exit.
|
||||
Silence a couple of compiler warnings.
|
||||
|
||||
* avr.c, avr.h, avrdude.conf.sample, config_gram.y, main.c:
|
||||
Fix ATMega flash addressing. Add an ATMEGA16 part. Perform sanity
|
||||
checking on the memory parameters for parts that do bank addressing.
|
||||
|
||||
2001-10-15 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* config.c, config.h, lists.h: Add copyright.
|
||||
|
||||
* config_gram.y, lexer.l, lists.c: Add copyrights.
|
||||
|
||||
* Makefile: Attempt to install avrprog.conf.
|
||||
|
||||
* avrdude.conf.sample: Correct dt006 pinout.
|
||||
|
||||
* Makefile, lexer.l:
|
||||
Try and detect an old-style config file and print an appropriate error
|
||||
message and a suggestion for correcting it.
|
||||
|
||||
* Makefile, avr.c, avrdude.1, avrdude.conf.sample: Update the man page.
|
||||
|
||||
Miscellaneous minor cleanups.
|
||||
|
||||
2001-10-14 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, Makefile.inc, avr.c, avr.h, avrdude.conf.sample:
|
||||
* config.c, config.h, config_gram.y, lexer.l, lists.c, lists.h:
|
||||
* main.c, pindefs.h, term.c:
|
||||
Use lex/yacc for parsing the config file. Re-work the config file
|
||||
format using a more human-readable format.
|
||||
|
||||
Read part descriptions from the config file now instead of hard-coding
|
||||
them.
|
||||
|
||||
Update usage().
|
||||
|
||||
Cleanup unused code.
|
||||
|
||||
* Makefile, avr.c, avr.h, fileio.c, term.c:
|
||||
First cut at supporting the ATmega 103 which uses bank addressing and
|
||||
has a 128K flash.
|
||||
|
||||
Due to the bank addressing required, interactive update of the flash
|
||||
is not supported, though the eeprom can be updated interactively.
|
||||
Both memories can be programmed via non-interactive mode.
|
||||
|
||||
Intel Hex Record type '04' is now generated as required for outputing
|
||||
memory contents that go beyond 64K.
|
||||
|
||||
2001-10-13 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avr.h, fileio.c, fileio.h, main.c, ppi.c, ppi.h, term.c:
|
||||
* term.h:
|
||||
Style fixes.
|
||||
|
||||
* avr.c, avr.h, fileio.c, fileio.h, main.c, term.c:
|
||||
Commit changes in preparation for support the ATMega line.
|
||||
|
||||
2001-10-01 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile: Don't override CFLAGS.
|
||||
|
||||
* avrdude.1: Correct default pin assignment.
|
||||
|
||||
* avr.c, fileio.c, main.c, ppi.c, term.c:
|
||||
Remove debugging code - it served its purpose.
|
||||
|
||||
Update copyrights.
|
||||
|
||||
2001-09-21 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c:
|
||||
Be sure to read the exit specs after the pin configuration has been
|
||||
assigned, otherwise, we may apply the exit specs to the wrong pins.
|
||||
|
||||
* main.c: debugging
|
||||
|
||||
2001-09-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1, avrdude.conf.sample, main.c:
|
||||
Prefix pin config entries in the config file with a "c:". Later, I
|
||||
might make part descriptions read in this way and we can use a
|
||||
different letter for those (p). This will make the parsing easier to
|
||||
distinguish between the entry types.
|
||||
|
||||
* main.c: Initialize pin configuration description.
|
||||
|
||||
2001-09-19 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* AVRprog.pdf, Makefile, avr.c, avrdude.1, avrdude.conf.sample:
|
||||
* avrdude.pdf, fileio.c, fileio.h, main.c, pindefs.h, term.c:
|
||||
Make the pin definitions configurable based on entries in a config
|
||||
file. This makes supporting other programmers much easier.
|
||||
|
||||
Rename AVRprog.pdf to avrprog.pdf.
|
||||
|
||||
2001-04-29 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog-programmer.jpg: Remove this image file from the repository.
|
||||
|
||||
2001-04-26 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog-schematic.jpg:
|
||||
Remove this image, use AVRprog.pdf as the preferred schematic for the
|
||||
programmer.
|
||||
|
||||
2001-04-25 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* AVRprog.pdf, Makefile, avrdude.1:
|
||||
Add a schematic provided by Joerg Wunch and also update the manual
|
||||
page (also updated by Joerg) to reference the schematic.
|
||||
|
||||
2001-02-25 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, Makefile.inc: Automate dependency generation.
|
||||
|
||||
2001-02-08 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Turn off ready led when finished programming.
|
||||
|
||||
* main.c: update version
|
||||
|
||||
* avr.c, main.c: Correct a few comments.
|
||||
|
||||
* Makefile, avr.c, term.c: Makefile : update dependencies
|
||||
|
||||
avr.c : correct status led updates
|
||||
|
||||
term.c : update status leds on write, make the address and length
|
||||
arguments for dump optional.
|
||||
|
||||
2001-01-26 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Version 1.1
|
||||
|
||||
* main.c:
|
||||
Hmmm ... cvs co -D <timestamp> does not work. Change the revision
|
||||
timestamp to a full date/time value.
|
||||
|
||||
* avr.c, fileio.c, main.c, ppi.c, term.c:
|
||||
Add a -V option to display the version information about each
|
||||
component module. This is intended for support purposes, so that I
|
||||
can tell unambiguously what version a binary out in the field is.
|
||||
|
||||
Additionally, display a revision timestamp along with the version
|
||||
number. This also is intended for aiding in support and is the Unix
|
||||
time of the latest component module. Having this, should allow me to
|
||||
do a "cvs co -D timestamp avrprog" and get exactly the source of the
|
||||
version that is being reported.
|
||||
|
||||
* fileio.c:
|
||||
Return the maximum address (+1) written as opposed to the actual
|
||||
number of bytes written. The presence of an Intel Hex address
|
||||
record can cause these two number to be different; but the callers
|
||||
of this routine need the former.
|
||||
|
||||
* main.c:
|
||||
Fix a place where we were exiting without applying the exit-specs.
|
||||
|
||||
Wrap a long line.
|
||||
|
||||
* avr.c, fileio.c: avr.c: Update a comment.
|
||||
|
||||
fileio.c: Properly handle all the Intel Hex record types that I can
|
||||
find information about.
|
||||
|
||||
2001-01-25 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Usage, avr.h: Get rid of the Usage file.
|
||||
|
||||
2001-01-24 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avr.c, avr.h, main.c, pindefs.h, ppi.c:
|
||||
Move pin definitions to their own file.
|
||||
|
||||
First pass at providing feedback via the optionally connected leds. I
|
||||
don't actually have any of these attached to my programmer, so I can
|
||||
only guess as whether this is toggling them on and off correctly.
|
||||
|
||||
Also, enable and disable the optional 74367 buffer.
|
||||
|
||||
* avr.h, main.c, ppi.c, ppi.h, avr.c:
|
||||
Rearrange the pinout for the programmer to be a little more logical.
|
||||
Provide hooks to support a buffered programmer, pin 6 is now used to
|
||||
enable a buffer that can be used to isolate the target system from the
|
||||
parallel port pins. This is important when programming the target
|
||||
in-system.
|
||||
|
||||
Totally change the way the pin definitions are defined. Actually
|
||||
set/clear pins based on the way more intuitive pin number, instead of
|
||||
PPI data register, bit number combination. A table of pin data is
|
||||
used so that any hardware inversion done by the parallel port is
|
||||
accounted for, what you set is actually what appears at the pin.
|
||||
Retain the old method for handling Vcc, however, because the hold
|
||||
method is much easier to use when setting / retrieving multiple pins
|
||||
simultaneously.
|
||||
|
||||
2001-01-22 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile: Don't gzip the man page.
|
||||
|
||||
* avrdude.1: .Nm macro fix. Submitted by Joerg.
|
||||
|
||||
* main.c: Cosmetic, don't output a preceding linefeed for usage().
|
||||
|
||||
* Makefile, avr.c, avr.h, fileio.c, term.c:
|
||||
Makefile : use gzip -f for man page installation so that we don't get
|
||||
prompted.
|
||||
|
||||
avr.c avr.h fileio.c term.c :
|
||||
|
||||
Change the avrpart data structure so that the typedef AVRMEM is
|
||||
used as an index into an array for the sizes of the memory types
|
||||
and also for pointers to buffers that represent the chip data for
|
||||
that memory type. This removes a lot of conditional code of the
|
||||
form:
|
||||
|
||||
switch (memtype) {
|
||||
case AVR_FLASH :
|
||||
...
|
||||
}
|
||||
|
||||
Also, re-code avr_read_byte() and avr_write_byte() to properly
|
||||
handle the flash memory type without having to tell them whether
|
||||
they should program the high byte or the low byte - figure that
|
||||
out from the address itself. For flash memory type, these
|
||||
routines now take the actual byte address instead of the word
|
||||
address. This _greatly_ simplifies many otherwise simple
|
||||
operations, such a reading or writing a range of memory, by not
|
||||
having to worry about whether the address starts on an odd byte
|
||||
or an even byte.
|
||||
|
||||
2001-01-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avr.h, fileio.c, fileio.h, main.c:
|
||||
Return error codes instead of exiting, thus making sure that we exit
|
||||
only via main() so that the exitspecs are properly applied.
|
||||
|
||||
When reading input data from a file, remember how many bytes were read
|
||||
and write and verify only that many bytes.
|
||||
|
||||
Don't complain when an input file size is smaller than the memory size
|
||||
we are programming. This is normal.
|
||||
|
||||
* fileio.c:
|
||||
Correct checksum calculation; failure to account for the value of the
|
||||
record type was causing non-zero record types to be calculated
|
||||
incorrectly.
|
||||
|
||||
* Makefile, main.c: Makefile : install the man page
|
||||
|
||||
main.c : drop the giant usage text now that we have a man page.
|
||||
|
||||
* avrdude.1:
|
||||
Add initial man page graciously contributed by Joerg Wunsch. Thanks
|
||||
Joerg!
|
||||
|
||||
2001-01-19 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* term.c:
|
||||
Accept abbreviations for eeprom and flash for the dump and write
|
||||
commands.
|
||||
|
||||
Fix small bug keeping 1 character command lines from being added to
|
||||
the history.
|
||||
|
||||
* term.c:
|
||||
Implement enough state in cmd_dump so that if it is called with no
|
||||
arguments, it successively dumps the next chunk of data of the same
|
||||
previously specified length.
|
||||
|
||||
* term.c, term.h, fileio.c, fileio.h, main.c, ppi.c, ppi.h:
|
||||
* Makefile, avr.c, avr.h, avrprog.c:
|
||||
The program was getting too large for a single file. Split it up into
|
||||
more modular pieces.
|
||||
|
||||
Also, accept command abbreviations as long as they are not ambiguous.
|
||||
|
||||
* avrprog.c:
|
||||
Add ability to specify the state of the power and reset pins on
|
||||
program exit. Default to leaving the pins in the state they were when
|
||||
we found them.
|
||||
|
||||
Contributed by: Joerg Wunsch
|
||||
|
||||
2001-01-18 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrprog.c:
|
||||
Switch to using readline() for getting terminal input. I can't seem
|
||||
to get the history capabilities working yet, but even so, it does
|
||||
better handling of the prompt and strips newlines for us, so it's
|
||||
still a win.
|
||||
|
||||
Add a few new commands for terminal mode: help, sig, part, erase.
|
||||
Display rudimentory help using the help command.
|
||||
|
||||
Add some function prototypes.
|
||||
|
||||
* Usage, avrprog.c:
|
||||
Change -c (interactive command mode) to the more intuitive -t
|
||||
(terminal mode).
|
||||
|
||||
Make binary format the default for output.
|
||||
|
||||
Update the parts table with corrections for old values and add some
|
||||
new values.
|
||||
|
||||
2001-01-15 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c:
|
||||
Automatically verify on-chip data with what we just programmed.
|
||||
|
||||
* avrprog.c, Makefile:
|
||||
Prepare the Makefile for integration into the FreeBSD ports tree.
|
||||
|
||||
Fix a few "may be used uninitialized" bugs found by -Wall.
|
||||
|
||||
2001-01-14 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: Free a buffer.
|
||||
|
||||
* avrprog.c:
|
||||
Use a smarter programming algorithm - read the existing data byte
|
||||
first and only write the new one if it is different.
|
||||
|
||||
Add -n option which is a test mode in which the chip is not actually
|
||||
updated. This option does not affect writes in interactive mode.
|
||||
|
||||
* avrprog.c: Add the "dump" and "write" interactive commands.
|
||||
|
||||
* avrprog.c:
|
||||
Correctly produce and handle "end of record" for intel hex files.
|
||||
|
||||
2001-01-13 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c:
|
||||
Re-enable writing to the chip. I should probably should make this a
|
||||
command-line selectable option so that I don't keep forgetting and
|
||||
committing it with it disabled.
|
||||
|
||||
* avrprog.c:
|
||||
Add a newline before exiting due to command line errors. Perform a
|
||||
bit more option compatibility testing between -c, -i, and -o.
|
||||
|
||||
* avrprog.c: Add input file format auto-detection support.
|
||||
|
||||
* Usage, avrprog.c: Say what the defaults are.
|
||||
|
||||
* avrprog-programmer.jpg, Usage, avrprog-schematic.jpg: New files.
|
||||
|
||||
* avrprog.c: Correct usage text.
|
||||
|
||||
* avrprog.c:
|
||||
Parameterize a few additional items per chip. Print out all per-chip
|
||||
parameters on startup. Use the per-chip parameters in the code
|
||||
instead of hard-coded values for the 2313.
|
||||
|
||||
* avrprog.c: Fix filename assignment error.
|
||||
|
||||
Clean up debugging code a little, utilize fileio() instead of making
|
||||
direct calls to b2ihex().
|
||||
|
||||
* avrprog.c: A lot of general code cleanup.
|
||||
|
||||
Re-work command line options to be more intuitive.
|
||||
|
||||
Support Intel Hex input and output file formats. Provide hooks to
|
||||
support Motorola S-Record as well.
|
||||
|
||||
Add a few more part-specific parameters to the avrpart structure.
|
||||
|
||||
Only write the flash or eeprom if the data to be written is not 0xff.
|
||||
|
||||
2000-12-31 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: Update a comment.
|
||||
|
||||
* avrprog.c:
|
||||
Provide the ability to tie additionally tie pins 6-9 of the parallel
|
||||
port to Vcc in order to supply more current.
|
||||
|
||||
Fix a typo on the size of the S1200's Flash.
|
||||
|
||||
Bring RESET low when programming is completed.
|
||||
|
||||
* avrprog.c:
|
||||
Correct pin connection comments. Elaborate a bit on Vcc connection.
|
||||
|
||||
* avrprog.c:
|
||||
Update after receiving some good feedback from Joerg Wunsch. We
|
||||
should now be able to program AT90S1200's.
|
||||
|
||||
2000-12-30 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: Don't limit eeprom addresses.
|
||||
|
||||
2000-12-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrprog.c:
|
||||
Add support for the 8515. Make the addition for other devices easier.
|
||||
|
||||
2000-08-27 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c:
|
||||
Clear all bits except AVR_RESET when finished reading or programming
|
||||
the Atmel device.
|
||||
|
||||
2000-08-07 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: update announcement message
|
||||
|
||||
* avrprog.c: Update announcement message.
|
||||
|
||||
* avrprog.c: Return the correct return code from 'main()'.
|
||||
|
||||
* avrprog.c:
|
||||
Add ppi_pulse() function and fix ppi_toggle() to actully toggle
|
||||
instead of pulse.
|
||||
|
||||
Make all abnormal returns after the parallel port has been opened go
|
||||
through a single exit point at the bottom of 'main()'.
|
||||
|
||||
2000-08-06 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrprog.c: Makefile: add --pedantic compiler option
|
||||
|
||||
avrprog.c:
|
||||
|
||||
Add lots of comments, move getop() variable declarations to
|
||||
the top of the program.
|
||||
|
||||
Add a typedef name to the AVR memory type and use it for
|
||||
function declarations.
|
||||
|
||||
Add a usleep() delay in the sense loop to avoid becoming a cpu
|
||||
hog.
|
||||
|
||||
Print out a version string so that folks know what version of
|
||||
the software they are running.
|
||||
|
||||
Be sure and close the parallel device and the i/o file when
|
||||
terminating abnormally.
|
||||
|
||||
* avrprog.c: Print out version information when invoked.
|
||||
|
||||
* Makefile, avrprog.c: Makefile: Add an install target.
|
||||
|
||||
avrprog.c:
|
||||
|
||||
Add license.
|
||||
|
||||
Document the header a bit better.
|
||||
|
||||
Add capability to read out and display the device signature bytes.
|
||||
|
||||
Add capability to power the device from the parallel port.
|
||||
|
||||
Eliminate debug print facility.
|
||||
|
||||
Provide 'avr_cmd()' function.
|
||||
|
||||
When memory locations don't program, generate a newline so that the
|
||||
information is not overwritten and lost.
|
||||
|
||||
Don't print out the message about needing to specify a file if the
|
||||
user is not requesting an operation that requires the file.
|
||||
|
||||
2000-08-05 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrprog.c: Pring usage when no arguments are supplied.
|
||||
|
||||
* Makefile, avrprog.c: Initial check-in
|
||||
|
||||
* Makefile, avrprog.c: New file.
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
2002-12-12 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: minor cleanup
|
||||
|
||||
2002-12-07 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1, main.c:
|
||||
If the stk500 is being used, default to using the first serial port.
|
||||
|
||||
2002-12-03 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1: Mention STK500 support.
|
||||
|
||||
2002-12-01 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* stk500.c: Remove unused code.
|
||||
|
||||
* CHANGELOG, stk500.c:
|
||||
Document changes since the previous version in the CHANGELOG.
|
||||
|
||||
Cleanup stk500.c a bit.
|
||||
|
||||
* stk500.c: Fix cut and paste braino.
|
||||
|
||||
* avr.c, avrdude.conf.sample, main.c, pgm.h, stk500.c:
|
||||
The STK500 can perform paged read/write operations even on standard
|
||||
"non-paged" parts. Take advantage of that and use the faster internal
|
||||
routines of the STK500 for those parts as well.
|
||||
|
||||
* avr.c, avr.h, avrpart.h, main.c, pgm.c, pgm.h, stk500.c:
|
||||
Optimize reading and writing for the STK500 programmer if the part
|
||||
supports paged reads and writes. This greatly decreases the
|
||||
program/verify time from about 4.5 minutes down to about 10 seconds in
|
||||
a 12K program size test case.
|
||||
|
||||
Print out the hardware and firmware version for the STK500 if verbose
|
||||
is enabled.
|
||||
|
||||
* avrdude.conf.sample, avrpart.h, config_gram.y, lexer.l, pgm.h:
|
||||
* ppi.c, ppi.h, stk500.c, stk500.h, stk500_private.h:
|
||||
Add basic support for STK500.
|
||||
|
||||
2002-11-30 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample, config.c, config.h, config_gram.y, lexer.l:
|
||||
* main.c, pgm.c, pgm.h, ppi.c, ppi.h, term.c, term.h, Makefile:
|
||||
* avr.c, avr.h:
|
||||
Seperate programmer operations out into a driver-like interface so
|
||||
that programmers other than the direct parallel port connection can be
|
||||
supported.
|
||||
|
||||
2002-11-23 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, main.c, term.c:
|
||||
term.c - when in interactive terminal mode and dumping memory using
|
||||
the 'dump <memtype>' command without any address information,
|
||||
and the end of memory is reached, wrap back around to zero on
|
||||
the next invocation.
|
||||
|
||||
CHANGELOG - describe changes
|
||||
|
||||
main.c - update version number
|
||||
|
||||
* main.c:
|
||||
When getting ready to initiate communications with the AVR device,
|
||||
first pull /RESET low for a short period of time before enabling the
|
||||
buffer chip. This sequence allows the AVR to be reset before the
|
||||
buffer is enabled to avoid a short period of time where the AVR may be
|
||||
driving the programming lines at the same time the programmer tries
|
||||
to. Of course, if a buffer is being used, then the /RESET line from
|
||||
the programmer needs to be directly connected to the AVR /RESET line
|
||||
and not via the buffer chip.
|
||||
|
||||
2002-11-06 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Update changelog.
|
||||
|
||||
* avr.c, avr.h, main.c: Fix -Y option. Reported by Joerg Wunsch.
|
||||
|
||||
2002-11-01 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, main.c: Version update and CHANGELOG entry.
|
||||
|
||||
* avr.c:
|
||||
Be backward compatible with the 2-byte rewrite cycle counter which
|
||||
appeared in version 2.1.0, but was changed to a 4 byte counter in
|
||||
version 2.1.1. Reminded by Joerg Wunsch.
|
||||
|
||||
2002-10-29 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, avrdude.1, main.c:
|
||||
Add '-V' (no verify) flag requested by Joerg Wunsch. Update the man
|
||||
page.
|
||||
|
||||
2002-10-13 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, avrdude.1: Update man page and changelog.
|
||||
|
||||
* main.c: Update version number.
|
||||
|
||||
2002-10-12 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile: Remove --pedantic and -g from the compiler options.
|
||||
|
||||
2002-10-11 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, term.c:
|
||||
Use a four byte value instead of a two byte value for the programming
|
||||
cycle count stored at the end of EEPROM. It seems as though Atmel was
|
||||
greatly conservative in claiming a 1000 count reliability for the
|
||||
FLASH. I current have a part that has been reprogrammed 173330 times,
|
||||
and counting.
|
||||
|
||||
Fix a compiler warning.
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Fix ATMega128 instruction encoding for reading the low and high fuse
|
||||
bits. Thanks to Joerg Wunsch for tripping over this.
|
||||
|
||||
2002-08-01 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avrdude.1, main.c:
|
||||
Move erase-rewrite cycle increment to within the chip erase routine so
|
||||
that it is tracked no matter where the erase was initiated: command
|
||||
line mode or interactive mode, without code duplicaiton.
|
||||
|
||||
* CHANGELOG: Recent updates.
|
||||
|
||||
* avr.c: Eliminate unused variables.
|
||||
|
||||
* avr.c, avr.h, avrdude.1, fileio.c, main.c:
|
||||
Implement a way of tracking how many erase-rewrite cycles a part has
|
||||
undergone. This utilizes the last two bytes of EEPROM to maintain a
|
||||
counter that is incremented each time the part is erased.
|
||||
|
||||
2002-07-27 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, main.c:
|
||||
Fix a typo in a comment. Display the size of memory being written.
|
||||
Display the correct memory name in an error message (previously
|
||||
hardcoded).
|
||||
|
||||
2002-06-22 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG, avrdude.conf.sample:
|
||||
Add support for ATtiny15 - contributed by Asher Hoskins
|
||||
<asher@crumbly.freeserve.co.uk>
|
||||
|
||||
2002-04-23 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Say what changed.
|
||||
|
||||
2002-04-07 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrdude.conf.sample:
|
||||
Backup the config file to a timestamped name to keep from possibly
|
||||
overwriting user-modified configs.
|
||||
|
||||
Add read/write instructions for all memory types for ATMEGA103,
|
||||
ATMEGA128, ATMEGA16, and ATMEGA8.
|
||||
|
||||
2002-04-05 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Add support for ATMEGA128; untested; requested by Jeff Gardner
|
||||
<gardner@journey.com>.
|
||||
|
||||
2002-02-15 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample: Minor ordering.
|
||||
|
||||
* CHANGELOG, main.c: Update version numbers.
|
||||
|
||||
2002-02-14 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Summarize latest updates.
|
||||
|
||||
* avrdude.conf.sample, config_gram.y:
|
||||
Make pwroff_after_write a yes/no field instead of a numeric.
|
||||
|
||||
* avrdude.conf.sample: Document the pwroff_after_write flag.
|
||||
|
||||
* avr.c: Enable the extra part verbosity when verbosity >= 3.
|
||||
|
||||
* avr.c, avr.h, avrdude.conf.sample, config_gram.y, lexer.l:
|
||||
* main.c, term.c:
|
||||
Fix error reporting by avr_write_byte().
|
||||
|
||||
Fix setting of status LEDs under various write-fail conditions.
|
||||
|
||||
Add a flag to indicate that a memory type requires the device to
|
||||
possibly be powered off and back on after a write to it. This is due
|
||||
to a hardware problem on some Atmel devices, see:
|
||||
|
||||
http://www.atmel.com/atmel/acrobat/doc1280.pdf
|
||||
|
||||
Add greater verbosity to the part-display code when verbose>1 to
|
||||
display avrprog's encoding of the defined programming instructions.
|
||||
This is primarily for debugging purposes.
|
||||
|
||||
|
||||
Part updates:
|
||||
|
||||
* add the AT90S4414 part
|
||||
|
||||
* add fuse and lock bit access instructions for the AT90S1200,
|
||||
AT90S4434, and AT90S8515.
|
||||
|
||||
* add the pwroff_after_write flag to the fuse bits for the AT90S2333
|
||||
and AT90S4433 parts
|
||||
|
||||
2002-02-09 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Updates to the 2333 and 4433 parts, contributed by Joerg Wunsh.
|
||||
|
||||
2002-01-18 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Add changelog.
|
||||
|
||||
2002-01-12 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c: Add (c) to copyright.
|
||||
|
||||
* fileio.c, fileio.h, lexer.l, lists.c, lists.h, main.c:
|
||||
* pindefs.h, ppi.c, ppi.h, term.c, term.h, avr.c, avr.h:
|
||||
* config.c, config.h, config_gram.y:
|
||||
Update version number. Update copyright.
|
||||
|
||||
* avrdude.1: Update copyright and add description of "default".
|
||||
|
||||
Submitted by: Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr.c, term.c:
|
||||
Fix programming of write-only memories (such as lock bits on the
|
||||
2313).
|
||||
|
||||
@@ -1,364 +0,0 @@
|
||||
2007-11-08 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Partially revert the line buffered output change,
|
||||
and turn stderr into unbuffered output while producing the
|
||||
progress report.
|
||||
|
||||
2007-11-07 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add setup and teardown hooks to the programmer
|
||||
definition. If present, call the setup hook immediately after
|
||||
finding the respective programmer object, and schedule the
|
||||
teardown hook to be called upon exit. This allows the
|
||||
programmer implementation to dynamically allocate private
|
||||
programmer data.
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* avr910.c: Convert static programmer data into dynamically
|
||||
allocated data.
|
||||
* butterfly.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c: Remove the no_show_func_info() calls, as Brian
|
||||
promised some 4 years ago.
|
||||
|
||||
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add the -x option to pass extended parameters to
|
||||
the programmer backend.
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* jtagmkII.c: Implement the extended parameter jtagchain=
|
||||
to support JTAG daisy-chains.
|
||||
* avrdude.1: Document all of the above.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2007-10-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-release.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.5.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <bikenomad@gmail.com>:
|
||||
patch #5007: Patch for line-buffering of stdout and stderr
|
||||
* main.c: call setvbuf() for stdout and stderr.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <graceindustries@gmail.com>:
|
||||
patch #5953: Add AT90CAN64 and AT90CAN32 to avrdude.conf
|
||||
* avrdude.conf.in: Add entry for AT90CAN64 and AT90CAN32.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Wolfgang Moser:
|
||||
patch #6121: ISP support for the C2N232I device (serial port
|
||||
bitbanging)
|
||||
* avrdude.conf.in: Add entry for c2n232i.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <karl.yerkes@gmail.com>:
|
||||
patch #6141: accept binary format immediate values
|
||||
* fileio.c: Detect a 0b prefix, and call strtoul() differently
|
||||
in that case.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21076: -vvvv serial receive prints are empty in Win32 build
|
||||
* ser_win32.c (ser_recv): Drop the essentially unused variable
|
||||
"len", and use the variable "read" in order to track how many
|
||||
bytes have just been read in.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21145: atmega329p not recognized
|
||||
* avrdude.conf.in: Add definitions for the ATmega329P/3290P.
|
||||
Same as ATmega329/3290 except of the different signature.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21152: Unable to program atmega324p with avrdude 5.4 and AVRISP
|
||||
using default configuration file.
|
||||
* avrdude.conf.in: Uncomment the (bogus) stk500_devcode lines for
|
||||
the ATmega164P, ATmega324P, ATmega644, and ATmega644P definitions.
|
||||
This only affects users of STK500v1 firmware.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <ladyada@gmail.com>:
|
||||
Patch #6233: Add support for USBtinyISP programmer
|
||||
* usbtiny.c: New file.
|
||||
* usbtiny.h: (Ditto.)
|
||||
* Makefile.am: Include usbtiny into the build.
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.1: Document the usbtiny support.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Sort list of supported programmers into
|
||||
alphabetical order, add all missing programmers.
|
||||
|
||||
2007-07-24 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* usbasp.c: Added long addresses to support devices with more
|
||||
than 64kB flash. Closes bug #20558: Long address problem with
|
||||
USBasp.
|
||||
|
||||
2007-06-27 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Add ChangeLog-2004-2006.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-release.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.4.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix AVR910 devcodes. It seems that the AVR109
|
||||
listing refers to "BOOT"-type code, while the standard codes are
|
||||
different (usually one below).
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr.c (avr_read, avr_write): only use the paged_load and
|
||||
paged_write backend functions iff the memory area in question has
|
||||
a page_size != 0.
|
||||
This is supposed to fix bug #19234: avrdude-5.3.1 segfaults when
|
||||
stk500v1 tries to program an ATtiny15
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Fall back to avr_{read,write}_byte_default(). Fixes
|
||||
bug #18803: Fuse reading regression in avrdude 5.3.1 with avr910
|
||||
programmer
|
||||
|
||||
2007-05-15 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* avrdude.conf.in: Rename the ATmega164 and ATmega324 into
|
||||
ATmega164P and ATmega324P, resp. Add an entry for the ATmega644P.
|
||||
Fixes bug #19769: ATmega164p not recognized
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* ser_posix.c (ser_send): Don't select() on the output fd before
|
||||
trying to write something to the serial line. That kind of
|
||||
polling isn't very useful anyway, and it seems it breaks for the
|
||||
Linux CP210x USB<->RS-232 bridge driver which is certainly a bug
|
||||
in the driver, but we can just avoid that bug alltogether.
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix the STK500v2 ISP delay parameter for
|
||||
ATmega640/1280/1281/2560/2561. Atmel has changed the XML
|
||||
files after the initial release.
|
||||
|
||||
2007-05-01 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* safemode.c: -Oops - bug in verbose output. Fixed.
|
||||
-Fixed handling of cases where programmer cannot read fuses (AVR910)
|
||||
* main.c: -Also fixing handling of cases where programmer cannot
|
||||
read fuses
|
||||
This should close one or more bugs (18803, 19570)
|
||||
|
||||
2007-05-01 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* safemode.c: Added verbose output from safemode routines.
|
||||
|
||||
2007-03-25 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* stk500generic.c: Forgot to close the serial port before trying to
|
||||
open it again, caused problems on Windows machines.
|
||||
Closes bug #19411
|
||||
|
||||
2007-02-26 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add the AT90PWM2/3B devices.
|
||||
|
||||
2007-02-02 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* usbasp.c: Changed return value of function usbasp_initialize to stop
|
||||
avrdude on communication errors between programmer and target.
|
||||
Closes bug #18581: safemode destroys fuse bits
|
||||
|
||||
2007-02-01 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Remove duplicate definition of token K_WRITEPAGE
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c: Implement ATmega256x support for butterfly/avr109.
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Fix subdir handling. Now finally, "make
|
||||
distcheck" will include the documentation into the tarball even if
|
||||
the configure had been run without the --enable-doc.
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* safemode.c: Obtain progname from avrdude.h rather than trying to
|
||||
roll our own (duplicate) copy of it.
|
||||
* avr910.c: Constify char pointers.
|
||||
* avrpart.c: (Ditto.)
|
||||
* avrpart.h: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config.h: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* serbb_posix.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
|
||||
2007-01-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrpart.c: More backend/library abstraction and generalization:
|
||||
turn the list_parts() and list_programmers() functions into
|
||||
general list iteration functions that call a caller-supplied
|
||||
callback for each element. Implement list_parts() and
|
||||
list_programmers() as private functions in main.c based on that
|
||||
approach.
|
||||
* avrpart.h: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
|
||||
2007-01-25 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: Rearrange everything so it is now built into a
|
||||
libavrdude.a library, and link main.c against that library.
|
||||
* configure.ac: Add AC_PROG_RANLIB as we are building a library
|
||||
now.
|
||||
|
||||
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Major code cleanup.
|
||||
- Make all internal functions "static".
|
||||
- Make sure each module's header and implementation file match.
|
||||
- Remove all library-like functionality from main.c, so only
|
||||
the actual frontend remains in main.c.
|
||||
- Add C++ brackets to all header files.
|
||||
* avr.c: (Ditto.)
|
||||
* avr.h: (Ditto.)
|
||||
* avr910.c: (Ditto.)
|
||||
* avr910.h: (Ditto.)
|
||||
* avrdude.h: (Ditto.)
|
||||
* avrpart.c: (Ditto.)
|
||||
* avrpart.h: (Ditto.)
|
||||
* bitbang.h: (Ditto.)
|
||||
* butterfly.h: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config.h: (Ditto.)
|
||||
* confwin.h: (Ditto.)
|
||||
* crc16.c: (Ditto.)
|
||||
* crc16.h: (Ditto.)
|
||||
* fileio.c: (Ditto.)
|
||||
* fileio.h: (Ditto.)
|
||||
* jtagmkI.h: (Ditto.)
|
||||
* jtagmkII.h: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* lists.h: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* par.h: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* ppi.c: (Ditto.)
|
||||
* ppi.h: (Ditto.)
|
||||
* safemode.h: (Ditto.)
|
||||
* serbb.h: (Ditto.)
|
||||
* serial.h: (Ditto.)
|
||||
* stk500.h: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* stk500v2.h: (Ditto.)
|
||||
* term.c: (Ditto.)
|
||||
* term.h: (Ditto.)
|
||||
* usbasp.h: (Ditto.)
|
||||
* update.c: New file.
|
||||
* update.h: New file.
|
||||
* Makefile.am: Include update.c and update.h.
|
||||
|
||||
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Move all "extern" declarations into a centreal header file.
|
||||
* Makefile.am: Add new avrdude.h.
|
||||
* avrdude.h: New file.
|
||||
* avr.c: Replace private extern decl's by #include "avrdude.h".
|
||||
* avr910.c: (Ditto.)
|
||||
* avrpart.c: (Ditto.)
|
||||
* bitbang.c: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* fileio.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* ppi.c: (Ditto.)
|
||||
* ppiwin.c: (Ditto.)
|
||||
* ser_avrdoper.c: (Ditto.)
|
||||
* ser_posix.c: (Ditto.)
|
||||
* ser_win32.c: (Ditto.)
|
||||
* serbb_posix.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* stk500generic.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* term.c: (Ditto.)
|
||||
* usb_libusb.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
|
||||
2007-01-13 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega8): Bump the delay values for flash
|
||||
and EEPROM, based on the current Atmel XML file.
|
||||
|
||||
2007-01-12 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Improve the detection of the Win32 HID library,
|
||||
and the presence of the header ddk/hidsdi.h. It now works
|
||||
correctly under Cygwin and several flavours of MinGW.
|
||||
* Makefile.am: Add new LIBHID pattern.
|
||||
|
||||
2007-01-11 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c (butterfly_initialize): when sending the 'T'
|
||||
command (which is ignored by current AVR109 bootloaders),
|
||||
send the first reply from the list of supported device
|
||||
codes back rather than using avrdude.conf's idea about
|
||||
an AVR910 device code. Apparently, this solves disagreements
|
||||
between different versions of at least the ATmega8 AVR910
|
||||
device code.
|
||||
Closes bug #18727: Writing flash failed
|
||||
|
||||
2007-01-07 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Reported by Till Harbaum:
|
||||
* avrdude.conf.in (ATtiny25/45/85): Change HVSP reset from
|
||||
500 microseconds to 1 ms, matching the most recent Atmel XML
|
||||
specs.
|
||||
@@ -1,185 +0,0 @@
|
||||
2008-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.h: Change the prototype for usleep() to be more Cygwin-
|
||||
friendly.
|
||||
* ppiwin.c: (Ditto.)
|
||||
|
||||
2008-11-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by limor <limor@ladyada.net>
|
||||
* usbtiny.c (usbtiny_cmd): Replace sizeof() by a fixed constant
|
||||
4 for the result array, because otherwise it would take the size
|
||||
of a pointer which miserably fails on 64-bit machines.
|
||||
|
||||
2008-11-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #6609: Using PCI parallel port cards on Windows
|
||||
* ppiwin.c (ppi_open): If the port parameter passed from the
|
||||
-p option is neither lpt1/2/3, try interpreting it directly as
|
||||
a base address.
|
||||
* avrdude.1: Document the change.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22882: Erase Cycle Counter does not work for stk500v2
|
||||
* stk500v2.c (stk500v2_chip_erase,stk500hv_chip_erase): Return
|
||||
the expected 0 for success rather than a protocol-dependant
|
||||
number.
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22883: Chip Erase performed even with no-write flag (-n)
|
||||
* main.c: Do not erase the chip if both, -e and -n options have
|
||||
been specified.
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #24589: AT90USB64* have wrong signature
|
||||
* avrdude.conf.in: Uncomment the correct, and delete the wrong
|
||||
signature for AT90USB646/647. Alas, the datasheet has never been
|
||||
corrected for years.
|
||||
|
||||
2008-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Fix a serious memory corruption that happened when
|
||||
using the JTAG ICE mkII (or AVR Dragon) in ISP mode. The wrong
|
||||
set of per-programmer private data had been allocated (stk500v2
|
||||
vs. jtagmkII) which was too small to hold the actual data.
|
||||
* jtagmkII.h: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Implement Xmega JTAG support.
|
||||
* jtagmkII_private.h: Add EMULATOR_MODE_JTAG_XMEGA.
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Remember whether the device initialization worked, and
|
||||
allow to continue with -F if it failed yet do not attempt to
|
||||
perform anything on the device itself. That way, -tF could be
|
||||
specified for programmers like the STK500/STK600 even without a
|
||||
device connected, just in order to allow changing parameters on
|
||||
the programmer itself.
|
||||
* avrdude.1: Document that possible use of the -F option.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_paged_write): Fix a fatal miscalculation
|
||||
of the number of bytes to be written which caused a malloc chunk
|
||||
corruption.
|
||||
|
||||
2008-07-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
First implementation of ATxmega support. By now, only the
|
||||
PDI mode of the STK600 is supported. Single-byte EEPROM
|
||||
(and flash) updates do not work yet.
|
||||
* avr.c: "boot" memory is a candidate memory region for paged
|
||||
operations, besides "flash" and "eeprom".
|
||||
* avrdude.conf.in: add ATxmega128A1 and ATxmega128A1revD
|
||||
* avrpart.h: add the AVRPART_HAS_PDI flag (used to distinguish
|
||||
ATxmega parts from classic AVRs), the nvm_base part field, and
|
||||
the offset field for a memory region.
|
||||
* config_gram.y: add "has_pdi", "nvm_base", and "offset"
|
||||
* lexer.l: (Ditto.)
|
||||
* main.c: disable auto_erase for ATxmega parts
|
||||
* stk500v2.c: implement the XPROG functionality, and divert to
|
||||
this for ATxmega parts
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix a bunch of warnings.
|
||||
* avr910.c (avr910_paged_load): possible unitialized use of
|
||||
rd_size
|
||||
* jtagmkI.c (jtagmkI_initialize): pointer signedness mixup
|
||||
* jtagmkII.c (jtagmkII_print_parms1): propagate const'ness
|
||||
of parameter
|
||||
* usbasp.c (usbasp_transmit): pointer signedness mixup
|
||||
* ser_avrdoper.c (usbGetReport): remove useless pointer deref
|
||||
|
||||
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Ville Voipio:
|
||||
patch #6501: New autotools support for avrdude
|
||||
* Makefile.am: add @WINDOWS_DIRS@ to SUBDIR
|
||||
* bootstrap: allow for autconf-2.61 and automake-1.10, too
|
||||
* configure.ac: fix @WINDOWS_DIRS@ recursion, replace
|
||||
AC_PROG_CC by AM_PROG_CC_C_O, for esoteric reasons
|
||||
|
||||
2008-06-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Janos Sallai <janos.sallai@vanderbilt.edu>:
|
||||
patch #6074: added support for crossbow's MIB510 programmer
|
||||
* avrdude.conf.in: Add entry for mib510.
|
||||
* stk500.c: Add special hooks to handle the MIB510 programmer.
|
||||
It mostly talks STK500v1 protocol but has a special hello and
|
||||
goodbye sequence, and uses a fixed block size of 256 bytes.
|
||||
* doc/avrdude.texi: Document support for mib510.
|
||||
|
||||
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
|
||||
* main.c: Realign verbose messages.
|
||||
* avrpart.c: (Ditto.)
|
||||
* avr910.c: Print the device code selected in verbose mode.
|
||||
* butterfly.c: (Ditto.)
|
||||
|
||||
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
|
||||
Add check for buffermode feature, and use it if present. Can be
|
||||
turned off using -x no_blockmode.
|
||||
* avr910.c: Implement buffermode test and usage.
|
||||
* avrdude.1: Document -x no_blockmode.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c: #undef interface for Win32
|
||||
|
||||
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Add support for the -x devcode option.
|
||||
* avrdude.1: Document -x devcode for avr910.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-03-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Add initial support for the Atmel STK600, for
|
||||
"classic" AVRs (AT90, ATtiny, ATmega) in both,
|
||||
ISP and high-voltage programming modes.
|
||||
* Makefile.am: Add -lm.
|
||||
* avrdude.conf.in: Add stk600, stk600pp, and stk600hvsp.
|
||||
* config_gram.y: Add support for the stk600* keywords.
|
||||
* lexer.l: (Ditto.)
|
||||
* pgm.h: Add the "chan" parameter to set_varef().
|
||||
* stk500.c: (Ditto.)
|
||||
* serial.h: Add USB endpoint support to struct filedescriptor.
|
||||
* stk500v2.c: Implement the meat of the STK600 support.
|
||||
* stk500v2.h: Add new prototypes for stk600*() programmers.
|
||||
* stk500v2_private.h: Add new constants used in the STK600.
|
||||
* term.c: Add AREF channel support.
|
||||
* usb_libusb.c: Automatically determine the correct write
|
||||
endpoint ID, the STK600 uses 0x83 while all other tools use
|
||||
0x82. Propagate the EP to use through struct filedescriptor.
|
||||
* usbdevs.h: Add the STK600 USB product ID.
|
||||
* tools/get-stk600-cards.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the list of socket and routing
|
||||
card IDs, to be used in stk500v2.c (for displaying the
|
||||
names).
|
||||
* tools/get-stk600-devices.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the table of socket/routing cards
|
||||
and their respective AVR device support for doc/avrdude.texi.
|
||||
* avrdude.1: Document all the STK600 stuff.
|
||||
* doc/avrdude.texi: Ditto. Added a new chapter for
|
||||
Programmer Specific Information.
|
||||
|
||||
2008-01-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_recv): Make length computation unsigned so
|
||||
it cannot accidentally become negative.
|
||||
|
||||
@@ -1,411 +0,0 @@
|
||||
2009-11-09 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* fileio.c: ihex2bin did not properly handle files > 64K bytes
|
||||
* usb_libusb.c: re-enabled usb_reset for Macs (no reset causes lots of failures)
|
||||
* avrdude.1: spacing issue for avr32 fixed.
|
||||
|
||||
2009-11-09 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Implemented reset= and speed= extended parameters.
|
||||
* avrdude.1: Document the change.
|
||||
|
||||
2009-11-04 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* configure.ac, Makefile.am: Test if GCC accepts -Wno-pointer-sign
|
||||
|
||||
2009-11-04 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Implemented 'BinMode' support for
|
||||
firmware 2.7 and higher.
|
||||
* avrdude.1: Added info about BusPirate.
|
||||
|
||||
2009-11-03 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* arduino.c: Add on to bug #26703 / patch #6866 - clear DTR/RTS
|
||||
when closing the port.
|
||||
* Makefile.am: Silent warnings about signedness - they're useless
|
||||
and annoying, especially for 'char' vars.
|
||||
|
||||
2009-10-22 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* usb_libusb.c: disabled usb_reset for Macs (same as FreeBSD)
|
||||
|
||||
2009-10-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* main.c: Re-added default to serial port for BusPirate.
|
||||
|
||||
2009-10-12 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* main.c: removed some avr32 code that was pushed into jtagmkII.c
|
||||
* jtagmkII.c: consolodated the avr32 reset code and avr32_chipreset
|
||||
* avrpart.h: modified AVRPART flags for avr32
|
||||
* lexer.l: added is_avr32 flag - only way to get yacc code to set flag
|
||||
* avrdude.conf.in: updated avr32 section to include "is_avr32" flag
|
||||
|
||||
2009-10-12 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* config_gram.y: Restored inadvertantly removed buspirate entry
|
||||
* lexer.l: Restored inadvertantly removed buspirate entry
|
||||
|
||||
2009-10-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Replace GNU-only %as with %s in sscanf call.
|
||||
* ser_win32.c(ser_set_dtr_rts): Fixed typo in parameter name.
|
||||
* NEWS: Announce BusPirate.
|
||||
|
||||
2009-10-11 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
Support for AVR32
|
||||
|
||||
* AUTHORS: added myself
|
||||
* NEWS: announced AVR32 support
|
||||
* main.c: AVR32 flag tests to avoid several code blocks
|
||||
* fileio.c: mods to ihex read function to handle address offsets and
|
||||
size of avr32
|
||||
* jtagmkI.c: added cast to printf call to remove warning
|
||||
* arduino.c: added header file to bring in prototype for usleep()
|
||||
* config_gram.y: added defines for avr32, new jtag_mkii variant for avr32
|
||||
* jtagmkII_private.h: new jtag_mkii message types defined (used by
|
||||
avr32program)
|
||||
* jtagmkII.h: extern jtagmkII_avr32_initpgm() addition
|
||||
* jtagmkII.c: huge amount of code in support of avr32
|
||||
* avrpart.h: additional flags to AVRPART for avr32
|
||||
* usb_libusb.c: modified verbose test for USB read per-byte messages by
|
||||
by one, so with verbose=3 you get just full messages, 4 gives you bytes
|
||||
too
|
||||
* lexer.l: additions for avr32
|
||||
|
||||
2009-10-10 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
Support for Arduino auto-reset:
|
||||
* serial.h, ser_avrdoper.c, ser_posix.c, ser_win32.c: Added
|
||||
serial_device.set_dtr_rts implementations.
|
||||
* arduino.c, stk500.c, stk500.h: Call serial_set_dtr_rts()
|
||||
to reset Arduino board before program upload.
|
||||
Inspired by patch #6866, resolves bug #26703
|
||||
|
||||
2009-10-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Optimised buspirate_cmd() - reading 1kB EEPROM now
|
||||
takes only 14 sec instead of almost 2 mins with the original
|
||||
implementation.
|
||||
|
||||
2009-10-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c, buspirate.h: Support for the BusPirate programmer
|
||||
* config_gram.y, avrdude.conf.in, main.c, lexer.l, Makefile.am:
|
||||
Glue for BusPirate.
|
||||
|
||||
2009-08-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_close): Repair the logic around the
|
||||
conditional compilation of usb_reset() introduced in r798.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: We are post-5.8 now.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.8
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Roger Wolff:
|
||||
bug #26527: bug in unicode conversion
|
||||
* ser_avrdoper.c (convertUniToAscii): when encountering a UTF-16
|
||||
character that cannot be converted to ASCII, increment the UTF-16
|
||||
pointer anyway when proceeding.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkI.c (jtagmkI_send): Replace %zd format by %u since not all
|
||||
implementations do understand the C99 formatting options (sigh).
|
||||
* jtagmkII.c (jtagmkII_send): (Ditto.)
|
||||
* stk500v2.c (stk500v2_recv): (Ditto.)
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26002: HVPP of EEPROM with AVR Dragon and ATmega8 Fails
|
||||
* avrdude.conf.in (ATmega8): add page size for EEPROM.
|
||||
|
||||
2009-07-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Fix a serious memory corruption problem resulting
|
||||
out of the chaining of both, the stk500v2 and the jtagmkII
|
||||
programmers for some programming hardware (JTAG ICE mkII and AVR
|
||||
Dragon running in ISP, HVSP or PP mode), where both programmers
|
||||
have to maintain their private programmer data.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Post-release (is pre-release...)
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.7
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add my name to the copyright output when being verbose.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Shaun Jackman <sjackman@gmail.com>
|
||||
bug #21798: Fix both XSLT scripts
|
||||
* tools/get-dw-params.xsl (format-hex): Add the parameter count.
|
||||
* tools/get-hv-params.xsl (format_cstack): Ditto.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #21922: ATmega163 still not working in version 5.5
|
||||
* avrdude.conf.in (atmega163): fill in stk500v2 parameters, correct
|
||||
some flash programming parameters as well.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22206: avrdude: ser_setspeed(): tcsetattr() failed
|
||||
* ser_posix.c (ser_setspeed): Don't pass TCSAFLUSH to tcsetattr() as
|
||||
it apparently fails to work on Solaris. After reading the
|
||||
documentation again, it seems TCSAFLUSH and TCSANOW are indeed
|
||||
mutually exclusive.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22234: WINDOWS version: HOWTO: Specify Serial Ports Larger than COM9
|
||||
* ser_win32.c (ser_open): prepend \\.\ to any COM port name, so it is
|
||||
safe to be used for COM ports above 9.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26408: Crash in stk500v2_open()
|
||||
* stk500generic.c: Implement setup and teardown hooks, calling in turn
|
||||
the respective hooks of the stk500v2 implementation.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26130: Avrdude doesn't display it's version.
|
||||
* main.c (usage): add a version number display to the default usage
|
||||
message.
|
||||
|
||||
2009-07-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26412: avrdude segfaults when called with a programmer that does not
|
||||
support it
|
||||
* main.c: do not call pgm->perform_osccal() unless it is != 0.
|
||||
|
||||
2009-06-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Zoltan Laday:
|
||||
patch #6825: xmega problems with JTAGICEmkII
|
||||
* jtagmkII.c: Many fixes for Xmega devices.
|
||||
* jtagmkII_private.h: Add various new constants required for
|
||||
Xmega devices.
|
||||
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
|
||||
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
|
||||
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
|
||||
ATXMEGA64A4, ATXMEGA128A4
|
||||
* avr.c (avr_read, avr_write): Add more names for (Xmega)
|
||||
memory areas that require paged operation.
|
||||
|
||||
2009-06-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_write_byte): Handle writing fuse bytes.
|
||||
|
||||
2009-04-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Carl Hamilton:
|
||||
* update.c (parse_op): correctly \0-terminate buf after filling
|
||||
it, before it is potentially used as the source of a call to
|
||||
strlen or strcpy.
|
||||
|
||||
2009-04-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Merge the -P 0xXXX option description from
|
||||
avrdude.1.
|
||||
|
||||
2009-04-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: declare AM_PROG_CC_C_O to avoid the warning
|
||||
"compiling `config_gram.c' with per-target flags
|
||||
requires `AM_PROG_CC_C_O' in `configure.ac'"
|
||||
|
||||
2009-03-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #25971: "error writing to <stdout>" with multiple -U params.
|
||||
* fileio.c: Do not close the input/output stream when working on an
|
||||
stdio stream.
|
||||
|
||||
2009-02-28 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
Based on patch #6484 commited by Jurgis Brigmanis:
|
||||
* usbasp.c: added software control for ISP speed
|
||||
* usbasp.h: (Ditto.)
|
||||
|
||||
2009-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c (avr910_read_byte_flash): Eliminate a static variable that
|
||||
hasn't been in use for 5 years.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Post-release 5.6.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.6.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Ed Okerson:
|
||||
* jtagmkII.c (jtagmkII_read_byte): Fix signature reading of
|
||||
Xmega.
|
||||
|
||||
2009-02-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Mikael Hermansson:
|
||||
* avrdude.conf.in (ATxmega256A3): new device.
|
||||
* stk500v2 (stk500v2_initialize): Enable the AVRISPmkII as a
|
||||
PDI-capable device for ATxmega parts.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lars Immisch:
|
||||
patch #6750: Arduino support - new programmer-id
|
||||
* arduino.c: New file, inherits stk500.c.
|
||||
* arduino.h: New file.
|
||||
* Makefile.am: Add arduino.c and arduino.h.
|
||||
* config_gram.y: Add arduino keyword.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* avrdude.1: Document the new programmer type.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Turn all non-const static data into instance data.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: Move term.[ch] from the library into the CLI
|
||||
application section, as it is not useful for anything else but
|
||||
the CLI frontend.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega1284P): new device.
|
||||
|
||||
2009-02-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
More fixes for Solaris, including fixes for the Sunpro compiler:
|
||||
* avr.h: Remove stray semicolon.
|
||||
* configure.ac: Add check for predefined types uint_t and ulong_t.
|
||||
* confwin.c: Include "avrdude.h" on top to avoid empty translation
|
||||
unit warning.
|
||||
* ppwin.c: (Ditto.)
|
||||
* ser_win32.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* jtagmkII.c (jtagmkII_recv): remove unreachable "return".
|
||||
* stk500.c (stk500_initialize): (Ditto.)
|
||||
* par.c: Test for both, __sun__ and __sun to see whether we are
|
||||
being compiled on Solaris.
|
||||
* ppi.c: (Ditto.)
|
||||
* stk500v2.c: Implement the DEBUG and DEBUGRECV macros in a way
|
||||
that is compatible with the ISO C99 standard.
|
||||
* usbtiny.c: Only typedef uint_t and ulong_t if they have not
|
||||
been found already by the autoconf checks.
|
||||
|
||||
2009-02-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22204: Solaris10/11 Undefiniertes Symbol gethostbyname socket
|
||||
connect
|
||||
* configure.ac: Add checks for gethostent() and socket().
|
||||
While being here, remove some old cruft left from ancient days.
|
||||
|
||||
2009-02-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Bump the %p size so AT&T lex will continue to work.
|
||||
|
||||
2009-02-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
(Partially) submitted by John Voltz:
|
||||
bug #20004: AVRDUDE update (-U) operations do not close files
|
||||
* fileio.c (fmt_autodetect, fileio): fclose() files.
|
||||
|
||||
2009-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbtiny.c: Replace all but one (very unlikely to trigger) exit(1)
|
||||
by return -1.
|
||||
|
||||
2009-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Dick Streefland:
|
||||
patch #6749: make reading from the USBtinyISP programmer more robust
|
||||
* usbtiny.c: Add code to retry failed communication attempts.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Nick Hibma:
|
||||
bug #22271: usb_reset in usb_libusb.c not necessary in FreeBSD 6.x
|
||||
* usb_libusb.c (usbdev_close): Do not call usb_reset() on FreeBSD.
|
||||
It is not necessary there.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Andrew O. Shadoura:
|
||||
bug #25156: add direct SPI transfer mode
|
||||
* bitbang.c: Implement direct SPI transfers.
|
||||
* bitbang.h: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* term.c: Add the "spi" and "pgm" commands.
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Limor ("Lady Ada"):
|
||||
bug #24749: add support for '328p
|
||||
* avrdude.conf.in (ATmega328P): new device support.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by "Womo":
|
||||
bug #25241: AT90USB162, AT90USB82 device support patch for avrdude-5.5
|
||||
(also: bug #21745: AT90USBxx2 support)
|
||||
* avrdude.conf.in (AT90USB162, AT90USB82): new device support.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Evangelos Arkalis:
|
||||
patch #6069: Atmel AT89ISP Cable
|
||||
* avrdude.conf.in (89isp): new programmer support.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Bob Paddock:
|
||||
patch #6748: ATTiny88 Config
|
||||
* avrdude.conf.in (ATtiny88): new device support.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Mark Litwack:
|
||||
patch #6261: avrdude won't use dragon/debugwire to write a file
|
||||
to eeprom
|
||||
* jtagmkII.c (jtagmkII_paged_write): when in debugWire mode,
|
||||
implement a paged write to EEPROM as a series of byte writes.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Janos Sallai:
|
||||
patch #6542: paged_load fails on the MIB510 programming board
|
||||
* stk500.c: Add a workaround for the different signon sequence on
|
||||
MIB510 programmers.
|
||||
|
||||
2009-02-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add the ATmega128RFA1.
|
||||
* avrdude.1: document the addition of ATmega128RFA1.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
2010-12-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega128RFA1): Bump two timing values in order to
|
||||
improve ISP programming stability, in particular with the STK600.
|
||||
|
||||
2010-12-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_command): Detect warning status codes.
|
||||
|
||||
2010-10-22 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* serial.h: serial_open() calls will now return -1 on error (no call to exit())
|
||||
* buspirate.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* arduino.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2010-07-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30566: MinGW + Ubuntu 9.04
|
||||
* stk500v2.c (stk500v2_open): use same condition to refer to the AVR
|
||||
Doper support as used in the definition in ser_avrdoper.c.
|
||||
(Thanks to Christian Starkjohann for the analysis of the problem.)
|
||||
|
||||
2010-07-19 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Added compatibility with BusPirate "NewUI" firmware 5.x
|
||||
(contributed by Kari Knuuttila)
|
||||
|
||||
2010-07-12 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* avrdude.conf.in (atmega88p): New device.
|
||||
|
||||
2010-06-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29913: 246 Byte Bug - AVRdude crashes
|
||||
doc/avrdude.texi (Troubleshooting): Mention the libusb 0.1 API
|
||||
wrapper issue that is present in some Linux versions.
|
||||
|
||||
2010-03-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29263: Can't build avrdude on windows using latest cygwin 1.7.1
|
||||
* doc/avrdude.texi: Remove the recommendation for building
|
||||
Win32 binaries under Cygwin; mention MinGW as an alternative
|
||||
environment.
|
||||
|
||||
2010-03-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* ser_posix.c(ser_set_dtr_rts): Fixed DTR on/off to make
|
||||
Arduino auto-reset work. (bug #29108, patch #7100)
|
||||
|
||||
2010-03-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Replace printf() by fprintf(stderr)
|
||||
* safemode.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2010-01-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Cleanup Cygwin builds.
|
||||
* windows/Makefile.am (loaddrv_LDFLAGS): remove, the -mno-cygwin
|
||||
flag is supposed to be set in CFLAGS by ./configure
|
||||
* configure.ac: add a check for the presence of usleep(), add a
|
||||
check whether the linker accepts -static
|
||||
* avrdude.h: protect prototype for usleep by !defined(HAVE_USLEEP)
|
||||
* ppwin.c (usleep): protect by !defined(HAVE_USLEEP)
|
||||
* main.c: silence "array subscript of type char" compiler warnings
|
||||
by casting all arguments to tolower()/toupper() and isspace()/
|
||||
isdigit()/ispunct() to "int"
|
||||
* butterfly.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-5.10.
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 5.10.
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28677: Cygwin's GCC no longer supports -mno-cygwin option
|
||||
* configure.ac: For Win32 environments, add a check whether the
|
||||
compiler understands the -mno-cygwin option. If not, don't use
|
||||
it but suggest using a different compiler.
|
||||
|
||||
2010-01-18 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
bug #28660: Problem with loading intel hex rom files that exceed
|
||||
0x10000 bytes
|
||||
* fileio.c: Fix two byte shifts.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Michael biebl:
|
||||
* configure.ac: Fix FreeBSD default serial port name.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: If entering JTAG mode fails with a bad JTAG ID
|
||||
message, retry with external reset applied (in case the target
|
||||
is in sleep mode or has asserted the JTD bit).
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Aurelien Jarno:
|
||||
* configure.ac: Fix build for GNU/kFreeBSD.
|
||||
* ppi.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for post-5.8.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for release 5.8.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Soren Jorvang:
|
||||
bug #28611: -i delay not being applied to all serial port
|
||||
bit banging state transitions
|
||||
* serbb_win32.c: Apply ispdelay everywhere.
|
||||
* serbb_posix.c: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2_private.h: Implement TPI mode for AVRISPmkII/STK600
|
||||
* config_gram.y: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in: Add ATtiny4/5/9/10
|
||||
* avrdude.1: Document TPI and new device support.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by clint fisher:
|
||||
patch #7038: Adding Atmega32U4 Device to avrdude.conf.in
|
||||
* avrdude.conf.in (atmega32u4): New device.
|
||||
* avrdude.1: Document the new device support.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Thomas Pircher:
|
||||
patch #6927: Documentation patches
|
||||
* doc/avrdude.texi: Fix various typos, and remove the last
|
||||
remnants of obsoleted options -i/-o/-m/-f.
|
||||
* avrdude.1: Merge typo fixes from avrdude.texi where
|
||||
applicable.
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Update documentation to match the reality (device
|
||||
support, memory areas).
|
||||
* doc/avrdude.texi: Update documentation to match the
|
||||
reality (device support, programmer support, memory areas).
|
||||
Merge buspirate-specific comments from avrdude.1.
|
||||
* jtagmkII.c: Add some firmware feature checks.
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Implement PDI mode support for the JTAG ICE mkII
|
||||
and the AVR Dragon.
|
||||
* jtagmkII.h: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* jtagmkII_private.h: (Dito.)
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Update STK600 routing and socket card data from XML
|
||||
file.
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Cleanup the open/close handling to avoid accessing
|
||||
unallocated memory (in the atexit handler) in case of bailing out.
|
||||
* main.c: (Ditto.)
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Stylistic changes: move #defines out into
|
||||
jtagmkII_private.h, drop all #if 0 blocks, fold overly long lines,
|
||||
move the *_initpgm() functions to the end of the file; while being
|
||||
here, remove all trailing whitespace.
|
||||
* jtagmkII_private.h: move AVR32 #defines here.
|
||||
|
||||
2010-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bootstrap: autoconf 2.62 works well.
|
||||
|
||||
2010-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Various fixes for Xmega devices.
|
||||
* avrdude.conf.in: Correctly declare EEPROM page sizes for
|
||||
all Xmega devices (0x20 instead of 0x100).
|
||||
* avr.c: If a memory region has a page size declared, try
|
||||
using the paged IO routines regardless of the target memory
|
||||
name. Xmega EEPROM requires to be written in paged mode.
|
||||
Correctly use a long (rather than unsigned long) variable to
|
||||
evaluate the success status of the paged mode write attempt.
|
||||
* stk500v2.c: Don't apply TIF space offsets twice (bug #27995:
|
||||
AVRDUDE 5.8svn fails to program and read XMEGA); use
|
||||
stk500v2_loadaddr() prior to paged mode (EEPROM and flash) writes,
|
||||
otherwise programming of flash areas will fail; while being there,
|
||||
check the return value of stk500v2_loadaddr() everywhere; use the
|
||||
correct write/erase mode bits (same as AVR Studio does).
|
||||
|
||||
2010-01-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Initialise firmware version to v0.0
|
||||
prior to parsing the buspirate banner.
|
||||
|
||||
2010-01-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Clean-up the Xmega erase functions.
|
||||
* jtagmkII_private.h: Add CMND_XMEGA_ERASE as well as
|
||||
the various XMEGA_ERASE_* definitions (from updated
|
||||
appnote AVR067)
|
||||
* jtagmkII.c (jtagmkII_chip_erase): Correctly implement Xmega chip
|
||||
erase based on CMND_XMEGA_ERASE. After erasing an Xmega part, do
|
||||
*not* reinitialize the world, as a subsequent programming
|
||||
operation will fail (for unknown reasons). Actually, this was
|
||||
really only required for ancient AVRs, but doesn't hurt on mega
|
||||
and tiny devices.
|
||||
* jtagmkII.c (jtagmkII_pre_write): Remove, this turned out
|
||||
to be just a chip erase.
|
||||
* jtagmkII.c (jtagmkII_program_disable): Don't try reading
|
||||
"hfuse" for Xmega parts; they don't have it.
|
||||
* main.c (main): Re-enable auto-erase. It's been done
|
||||
before (as "jtagmkII_pre_write") in jtagmkII_paged_write()
|
||||
anyway. Xmega boot and application flash areas should be
|
||||
handled separately in the future, so auto_erase can only
|
||||
affect the area just being programmed.
|
||||
|
||||
2010-01-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c (main): disable safemode for Xmega parts.
|
||||
|
||||
2010-01-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: If the BusPirate doesn't respond
|
||||
to a standard a reset command assume it was in binmode
|
||||
and attempt to exit to text mode first.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bitbang.c: Fix Win32 build error: move freq up to the file
|
||||
level.
|
||||
* buspirate.c: Fix Win32 build warning: include <malloc.h> to
|
||||
to get a declaration for alloca().
|
||||
|
||||
2010-01-08 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
bug #28520: Programming with USBasp with low clock speed fails
|
||||
* usbasp.c: Change blocksize depending on sck frequency to
|
||||
avoid usb transmition timeouts.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #27505: serbb_posix does not cope with inverted pins
|
||||
* serbb_posix (serbb_highpulsepin): apply PIN_MASK when
|
||||
checking pin numbers.
|
||||
* serbb_win32 (serbb_highpulsepin): (Dito.)
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28516: Linux/Dragon: Error message on exit
|
||||
* stk500v2.c: Fix the "bad response to GO command:
|
||||
RSP_ILLEGAL_EMULATOR_MODE" message. jtagmkII_close()
|
||||
has been called with the wrong pgm->cookie. Wrap it
|
||||
inside stk500v2_jtagmkII_close(), adjusting the cookie
|
||||
data appropriately.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Doug:
|
||||
patch #7010: Win32 enhanced bitbang_delay
|
||||
* bitbang.c (bitbang_calibrate_delay, bitbang_delay): On Win32,
|
||||
use the high-resolution performance counter rather than the
|
||||
uneducated delay loop guess if it is available on the target
|
||||
hardware.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Gerard:
|
||||
patch #6828: Using arbitrary BAUD rates
|
||||
* ser_posix.c (serial_baud_lookup): Allow non-standard baud
|
||||
rates.
|
||||
* ser_win32.c (serial_baud_lookup): (Dito.)
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Eric Trein:
|
||||
bug #27596: AT90s2333 is not correctly supported in avrdude.conf
|
||||
* avrdude.conf.in (at90s2333): add various STK500v2 parameters.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Gyorgy Szekely:
|
||||
bug #28458: Buffer line is incorrectly released for PP programmers
|
||||
* par.c (par_close): use par_setmany() rather than par_setpin()
|
||||
for PPI_AVR_BUFF.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lukasz Goralczyk:
|
||||
bug #27507: SIGSEGV when using avrdragon (avrdude 5.8)
|
||||
* stk500v2.c (stk500v2_dragon_isp_initpgm): Use
|
||||
stk500v2_jtagmkII_setup/stk500v2_jtagmkII_rather than their
|
||||
jtagII counterparts, to get the private data properly
|
||||
initialized.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Cosmetics: remove UTF-8 dashes, adjust for 8-column
|
||||
hard tabs.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: add $ Id $ line.
|
||||
* buspirate.h: add $ Id $ line.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix a few warnings that came up recently (some of them only triggered
|
||||
by recent GCC versions).
|
||||
* config_gram.y (parse_cmdbits): "brkt possibly used uninitialized"
|
||||
(GCC errs here)
|
||||
* jtagmkII.c (jtagmkII_reset32): "status possibly used uninitialized"
|
||||
(I think GCC errs, too)
|
||||
* buspirate.c: "pointers differ in signedness" (mismatch between
|
||||
string processing and the use of "unsigned char" throughought the
|
||||
AVRDUDE API)
|
||||
|
||||
2010-01-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_smc_init32): replace sleep() by usleep() for
|
||||
win32 compatibility.
|
||||
@@ -1,489 +0,0 @@
|
||||
2011-12-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Added is_at90s1200 option to part description
|
||||
* doc/avrdude.texi: Added missing options to part definition
|
||||
* config_gram.y: Fixed resetting of is_at90s1200 and is_avr32 flags
|
||||
|
||||
2011-12-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7693: Fix config file atmel URLs
|
||||
* avrdude.conf.in: Updated URLs
|
||||
* avrpart.h: Updated URLs
|
||||
* doc/avrdude.texi: Updated URLs
|
||||
|
||||
2011-12-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ser_posix.c (baud_lookup_table): Conditionalize the inclusion of
|
||||
non-standard baud rates (only baud rates up to B38400 are
|
||||
standardized by the Single UNIX Specification).
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34302: Feature request : device configuration with parent classes
|
||||
* config_gram.y: Added part parent rule and allow overwriting existing
|
||||
data at several places
|
||||
* avrdude.conf.in: Added description comment and m328/m328p as example
|
||||
* avrpart.c: avr_dup_mem-functions now copy buf and tags memory block
|
||||
only they are already allocated.
|
||||
* lexer.l: Added parent as valid token
|
||||
|
||||
(not in original patch)
|
||||
* avrpart.c: New function avr_dup_opcode. avr_dup_mem/avr_dup_part-
|
||||
functions now duplicate the opcodes in their op-array to avoid memory leaks.
|
||||
* doc/avrdude.texi: Added description of part parent feature
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the parts lists, programmers lists follows later)
|
||||
* doc/Makefile.am: Add rule how to create avrdude before generating parts list
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the parts lists, programmers lists follows later)
|
||||
* doc/avrdude.texi: Add include of generated table of parts
|
||||
* doc/Makefile.am: Add generating of table of parts in parts.texi
|
||||
* doc/parts_comments.txt: Adding file containing part commenz references
|
||||
* avrdude.1: Remove table of parts and mention "-p ?" option
|
||||
* avrpart.c: Use AVR_DESCLEN for strncasecmp at list sorting
|
||||
|
||||
2011-12-22 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: Add writing of definition of confsubst to config.status,
|
||||
so it can run alone, not only called by configure.
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7680: Fixing timeout problem in ser_recv in ser_win32.c
|
||||
* ser_win32.c: Return -1 at timeout in ser_recv().
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y: Fixed another memory leak, when define an operation
|
||||
more than once
|
||||
* avrdude.conf.in: Fixed double definition at ATmega6490
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y: Restructuring and compacting programmer definition
|
||||
part of grammar (in preparation of patch #7688)
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Update documentation of programmer definition
|
||||
* doc/avrdude.texi: Update documentation of programmer definition
|
||||
and add list of implemented programmer types
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7667: Minor memory handling fixes
|
||||
* config_gram.y: Added several free_token() calls.
|
||||
|
||||
2011-12-16 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7671: Sorting programmers and parts lists for console output
|
||||
* avrdude.conf.in: change part desc of several parts to common pattern
|
||||
AT(mega|tiny|xmega)[0-9]+[A-Z]* (Upper case AT, lower case in middle)
|
||||
* list.[ch]: added sorting function lsort()
|
||||
* pgm.[ch]: added function sort_programmers()
|
||||
* avrpart.[ch]: added function sort_avrparts()
|
||||
* main.c: use sort functions in list_programmers() and list_parts()
|
||||
* main.c: list functions show config file info only at verbose mode
|
||||
|
||||
2011-10-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Replace "cvs" in version number by "svn".
|
||||
|
||||
2011-10-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34518: loading intel hex files > 64k using record-type 4
|
||||
(Extended Linear Address Record)
|
||||
fileio.c: Replace the change from r928 (handling of 0x8000000
|
||||
offset in AVR32 files) by a completely different logic that no
|
||||
longer breaks hex files for other devices starting with an
|
||||
offset; also apply a similar change to S-record files, as well
|
||||
as when writing files.
|
||||
fileio.c: (Ditto.)
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrftdi.c: Remove stray printf()s by fprintf(stderr)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Restrict the cyclecounter readout to those cases where
|
||||
it has been explicitly requested (by -y or -Y), rather than always
|
||||
attempting to read the last EEPROM bytes.
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_paged_load, stk600_xprog_paged_write):
|
||||
Fix regression in the AVRISPmkII/STK600 TPI handling introduced
|
||||
by the USBasp's TPI implementation which added a pagesize even for
|
||||
the minor memory regions of TPI devices. Also fix wrong offset
|
||||
introduced by the memory tagging patch.
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr.c (avr_read, avr_write): Don't bail out on TPI parts if
|
||||
their programmer doesn't provide a (low-level) cmd_tpi method;
|
||||
instead, fall back to the normal programmer methods which are
|
||||
supposed to handle the situation.
|
||||
This fixes a regression where the recent bitbang-TPI implementation
|
||||
broke TPI handling of STK600/AVRISPmkII.
|
||||
|
||||
2011-09-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Mega-commit to bring in memory tagging.
|
||||
Each memory image byte is now tagged as it's being read from a file.
|
||||
Only bytes read from a file will be written or verified (modulo page
|
||||
granularity requirements).
|
||||
* avrpart.h: Add memory tags.
|
||||
* avrpart.c: Allocate and initialize tag area.
|
||||
* update.h: Drop unused parameter "verify" from do_op().
|
||||
* pgm.h: Add parameter base_addr to the paged_load and paged_write
|
||||
methods, respectively.
|
||||
* avr.h: New parameter to avr_read: second AVRPART to verify against.
|
||||
* fileio.c: Track all memory regions that have been read from an
|
||||
input file by tagging them.
|
||||
* update.c: Call avr_read() with the new parameter list.
|
||||
* main.c: Call avr_initmem() to initialize the memory regions, rather
|
||||
than trying to duplicate an unitialized part, and then let the
|
||||
original part rot away.
|
||||
* avr.c: Implement the heart of the new featureset. For paged memory
|
||||
areas, when writing or verifying, call the paged_write and paged_load
|
||||
methods, respectively, once per page instead of on the entire memory.
|
||||
When writing, only write bytes or pages that have content read from a
|
||||
file. Whe verifying, only read memory bytes or pages where the
|
||||
verification data have been read from a file. Only verify those bytes
|
||||
that have been read from a file.
|
||||
* avrftdi.c: Implement the new API for paged_load and paged_write,
|
||||
respectively.
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* avr910.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2011-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_command): Treat warnings as errors rather than
|
||||
success.
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 3 - documentation)
|
||||
* avrdude.1: Document the programmer type restrictions for AT90S1200
|
||||
devices.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 2 - stk500v2 and relatives)
|
||||
* stk500v2.c (stk500v2_initialize): For the AT90S1200, release
|
||||
/RESET for a moment before reinitializing, as this is required by
|
||||
its programming protocol.
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: In AC_CHECK_LIB for libftdi, check for
|
||||
ftdi_usb_get_strings() rathern than ftdi_init(), as this is a more
|
||||
specific thing to search for in order to make sure getting a
|
||||
recent enough libftdi.
|
||||
|
||||
2011-08-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 1 - bitbang
|
||||
programmers)
|
||||
* config_gram.y: Introduce new keyword "is_at90s1200".
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Applew new keyword to the AT90S1200 device.
|
||||
* avrpart.h: Introduce new flag AVRPART_IS_AT90S1200, reflecting
|
||||
the is_at90s1200 configuration keyword.
|
||||
* bitbang.c (bitbang_initialize): Replace existing test for
|
||||
AT90S1200 by AVRPART_IS_AT90S1200
|
||||
* avr.c (avr_write_byte_default): Avoid the pre-write reading for
|
||||
the AT90S1200, as this appears to sometimes corrupt the high byte
|
||||
by pre-programming the low byte just written into it.
|
||||
|
||||
2011-08-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for post-5.11.
|
||||
|
||||
2011-08-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for releasing AVRDUDE 5.11.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Update the list of supported AVR devices.
|
||||
* doc/avrdude.texi: (Ditto).
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: add -lusb as "other libraries" when checking
|
||||
for libftdi.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Juergen Weigert:
|
||||
patch #7056: adding support for mikrokopter bootloader to butterfly
|
||||
* butterfly.c: Add some specific logic to handle the
|
||||
mikrokopter.de butterfly bootloader.
|
||||
* butterfly.h: Add one related function declaration.
|
||||
* config_gram.y: Add butterfly_mk keyword.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Add entry for butterfly_mk.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Stefan Tomanek:
|
||||
patch #7542: add default_bitclock to configuration files
|
||||
* config.c: Add the new keyword and its handling.
|
||||
* config.h: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.1: Document the change.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Brett Hagman:
|
||||
patch #7603: wiring - programmer type for Wiring boards
|
||||
(based on STK500v2)
|
||||
* wiring.c: New file.
|
||||
* wiring.h: (Ditto.)
|
||||
* Makefile.am: Add new files.
|
||||
* stk500v2_private.h: Reorganize so some functions and struct
|
||||
pdata are globally known.
|
||||
* stk500v2.c: (Ditto.)
|
||||
* stk500v2.h: (Ditto.)
|
||||
* lexer.l: Add new programmer keywords.
|
||||
* config_gram.y: (Ditto.)
|
||||
* avrdude.conf.in: Add "wiring" programmer entry.
|
||||
* avrdude.1: Document the new programmer.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
* AUTHORS: Add Brett Hagman.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by an anonymous contributor on the mailinglist:
|
||||
* avrdude.conf (jtagkey): Add a definition for the Amontec
|
||||
JTAGKey
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Juergen Weigert:
|
||||
bug #22720: avrdude-5.5 ignores buff settings in avrdude.conf
|
||||
(Note that the actual bug the subject is about has been fixed
|
||||
long ago.)
|
||||
* update.c (do_op): fix a diagnostic message
|
||||
* pgm.h: add exit_datahigh field
|
||||
* par.c: set and act upon the exit_datahigh field
|
||||
* avrdude.1: document the new -E options
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #33811: Parallel make fails
|
||||
* Makefile.am (BUILT_SOURCES): Add this macro.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #33114: Segfault after setting the DWEN fuse with Dragon
|
||||
* jtagII.c (jtagmkII_getsync): Instead of exit()ing from
|
||||
deep within the tree when detecting the "need debugWIRE"
|
||||
situation, properly pass this up as a return code.
|
||||
* jtagII_private.h (JTAGII_GETSYNC_FAIL_GRACEFUL): New constant.
|
||||
* stk500v2.c (stk500v2_jtagmkII_open): Don't tell anything
|
||||
anymore when receiving a JTAGII_GETSYNC_FAIL_GRACEFUL from
|
||||
jtagmkII_getsync(); silently give up (all necessary has been
|
||||
said already).
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Reported by Jason Hecker:
|
||||
* usbasp.c (libusb_to_errno): Conditionalize some error codes
|
||||
that apparently are lacking on MinGW.
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix warnings.
|
||||
* ser_avrdoper.c: add <stdlib.h> so exit() is declared.
|
||||
* usbtiny.c (usbtiny_open): provide an initializer to a
|
||||
"may be used uninitialized" variable (since GCC could not
|
||||
fully detect the logic behind).
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Add a check for FreeBSD's libusb-1.0
|
||||
compatible library that is found in libusb.a/.so on
|
||||
FreeBSD 8+.
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Doug Springer, based on work by
|
||||
Wolfgang Moser, Ville Voipio, Hannes Weisbach
|
||||
patch #7486: Patch to add FT2232C/D, FT2232H, FT4232H,
|
||||
usbvid, usbpid, usbdev for USB support - Based on #7062
|
||||
* avrftdi.c: New file.
|
||||
* avrftdi.h: (Ditto.)
|
||||
* configure.ac: Add check for libftdi.
|
||||
* config_gram.y: Add AVRFTDI and per-programmer USB string
|
||||
keywords.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Add avrftdi and 2232HIO programmers.
|
||||
* pgm.h: Add USB parameters.
|
||||
* Makefile.am: Add avrftdi.c and avrftdi.h.
|
||||
* AUTHORS: Mention the new authors.
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29585: Fix license
|
||||
* doc/avrdude.texi: Add FDL as an option to the licensing
|
||||
statement, as the savannah administration would like it
|
||||
that way.
|
||||
|
||||
2011-08-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Darell Tan:
|
||||
patch #7244: TPI bitbang implementation
|
||||
* bitbang.c: Add TPI bitbang stuff.
|
||||
* bitbang.h: (Ditto.)
|
||||
* avr.c: (Ditto.)
|
||||
* avr.h: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* serbb_posix.c: Wire bitbang_cmd_tpi into the struct pgm.
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* doc/avrdude.texi: Document the TPI bitbang support.
|
||||
|
||||
2011-08-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Grygoriy Fuchedzhy:
|
||||
bug #31779: Add support for addressing usbtinyisp with -P option
|
||||
* usbtiny.c (usbtiny_open): Add logic to distinguish multiple USBtinyISP
|
||||
programmers by their bus:device tuple.
|
||||
* doc/avrdude.texi: Document the new functionality.
|
||||
* avrdude.1: (Ditto.)
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Timon Van Overveldt:
|
||||
bug #30268: Debugwire broken in avrdude-5.10
|
||||
* jtagmkII.c (jtagmkII_initialize): only try setting up a JTAG chain when
|
||||
the programmer is using JTAG.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29636: AVRDude issues invalid CMD_CHECK_TARGET_CONNECTION
|
||||
on the AVRISP-MKII
|
||||
* stk500v2.c (stk500v2_program_enable): Rewrite the logic to
|
||||
explain ISP activation failures.
|
||||
* stk500v2_private.h: Fix the various STATUS_* constants;
|
||||
AVR069 and AVR079 disagreed in their values, even though they
|
||||
are apparently implementing the same logic behind.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29650: Programming timeouts in ATmega128RFA1 are too slow
|
||||
* avrdude.conf.in (ATmega128RFA1): Bump write delay values for flash and
|
||||
EEPROM to 50 ms.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega8515, ATmega8535, ATmega48, ATmega88, ATmega88P,
|
||||
ATtiny88, ATmega168, ATmega168P, ATmega328P): Bump delay value for STK500v2
|
||||
EEPROM write operation to 5, according to the respective XML files.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Darcy Houlahan:
|
||||
bug #29694: error in avrdude.conf for attiny84 eeprom
|
||||
* avrdude.conf.in (ATtiny84, ATtiny85): fix A7 bit in EEPROM write
|
||||
command.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Durant Gilles:
|
||||
* avrdude.conf.in (ATtiny4313): Fix flash addressing bits for manual ISP
|
||||
algorithm.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Philip:
|
||||
bug #31386: A "BUILD.svn" or similar "how to get started" doc would be helpful
|
||||
* BUILD-FROM-SVN: New file.
|
||||
|
||||
2011-08-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Nic Jones:
|
||||
bug #32539: [Documentation][Patch] Man page is misleading
|
||||
re: Dragon & PDI
|
||||
* doc/avrdude.texi: Update information about PDI connections
|
||||
on AVR Dragon
|
||||
|
||||
2011-08-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c: Add <stdint.h> so this actually compiles
|
||||
again.
|
||||
|
||||
2011-08-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by tixiv@gmx.net:
|
||||
bug #33345: File auto detection as binary doesn't open
|
||||
file in binary mode on Windows
|
||||
* fileio.c: Move the decision about opening files in
|
||||
binary mode until before the fopen() call.
|
||||
|
||||
2011-06-16 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Fix part id of ATtiny9.
|
||||
|
||||
2011-05-28 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
Based on patch #7440 commited by Slawomir Fraś:
|
||||
* usbasp.c: added TPI support for USBasp
|
||||
* usbasp.h: (Ditto.)
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add support for ATmega168P.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix abbreviated name for ATmega324PA.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lech Perczak:
|
||||
bug #30946: Added support for ATmega8/16/32U2
|
||||
* avrdude.conf.in: Add ATmega8/16/32U2 entries.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David A Lyons:
|
||||
patch #7393: Adding ATtiny4313 Device to avrdude.conf.in
|
||||
* avrdude.conf.in: Add ATtiny4313 data.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c: Bump timeout values to allow for slow clock
|
||||
speeds.
|
||||
* jtagmkII.c: (Ditto.)
|
||||
|
||||
2011-03-04 Eric B. Weddington <eric.weddington@atmel.com>
|
||||
|
||||
Thanks to Vitaly Chernookiy for the patch.
|
||||
* avrdude.conf.in: Add support for atmega324pa.
|
||||
* ChangeLog-2010: New file, rotate ChangeLog for new year.
|
||||
@@ -1,729 +0,0 @@
|
||||
2012-12-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbdefs.h (USBDEV_BULK_EP_WRITE_STK600)
|
||||
(USBDEV_BULK_EP_READ_STK600): new define values
|
||||
* stk500v2.c (stk600_open): use the STK600 EP values,
|
||||
as they are different from AVRISPmkII
|
||||
|
||||
2012-12-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37942: Latest SVN can't program in dragon_jtag mode
|
||||
* jtagmkII.c (jtagmkII_initialize): For Xmega devices, and
|
||||
firmware >= 7.x, don't trigger a RESET, in order to work around a
|
||||
firmware bug that appears to be present in at least firmware 7.24
|
||||
for the Dragon.
|
||||
|
||||
2012-12-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Implement the "ocdrev" keyword
|
||||
* avrpart.c: (Dito)
|
||||
* avrpart.h: (Dito)
|
||||
* lexer.l: (Dito)
|
||||
* avrdude.conf.in: Add "ocdrev" key/value pairs, based
|
||||
on the AS6 XML file information.
|
||||
* jtag3.c: Use the ocdrev in the parameter block.
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Make jtag3_command() public
|
||||
* jtag3.h: (Dito.)
|
||||
* jtag3_private.h: Add two new commands
|
||||
* stk500v2.c: Implement the "MonCon disable" hack that
|
||||
allows temporarily falling back to ISP when trying to
|
||||
talk to a part that has debugWIRE enabled
|
||||
|
||||
2012-12-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* pickit2.c: reordered #includes for non-usb configuration
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Enable interactive adjustment of the various
|
||||
clock frequencies (JTAG Xmega, JTAG megaAVR, PDI Xmega)
|
||||
through the set_sck_period() callback.
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Remove unused code that was left over from
|
||||
cloning the jtagmkII.c implementation
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* pgm_type.c: Add "jtagice3_isp" programmer hook
|
||||
* avrdude.conf.in: Add "jtag3isp" programmer
|
||||
* jtag3.c: jtag3_setparm() is now public
|
||||
* jtag3.h: (Dito)
|
||||
* stk500v2_private.h: Command 0x1D is CMD_SPI_MULTI only
|
||||
for STK500v2, AVRISPmkII, and JTAGICEmkII; for JTAGICE3,
|
||||
it's CMD_SET_SCK now; also add CMD_GET_SCK
|
||||
* avrpart.c (avr_get_output_index): New function
|
||||
* avrpart.h: (Dito)
|
||||
* stk500v2.c: Implement the pasthrough programmer glue logic
|
||||
for JTAGICE3 in ISP mode
|
||||
* stk500v2.h: (Dito)
|
||||
* avrdude.1: Document the JTAGICE3 support.
|
||||
|
||||
2012-11-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_read_byte, jtag3_write_byte): Remove the
|
||||
m->offset from addr, JTAGICE3 doesn't need it anymore (similar
|
||||
to JTAGICEmkII with 7+ firmware)
|
||||
* jtag3.c (jtag3_read_byte): Allow for full-page reads of
|
||||
EEPROM also for Xmega and debugWIRE, allow for signature
|
||||
read in debugWIRE
|
||||
|
||||
2012-11-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3_private.h: Add two more error detail codes I stumbled
|
||||
across during development
|
||||
* jtag3.c: (Dito.)
|
||||
* usb_libusb.c: Reduce timeouts from 100 to 10 s, still long
|
||||
enough, but not getting cold feet when something goes wrong.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Handle events returned by the ICE
|
||||
* usbdevs.h: Add defines that mark an event in return
|
||||
from usb_recv_frame().
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Remove "has_jtag" from Xmega A4 and D4
|
||||
devices, as they only have PDI.
|
||||
* jtag3.c (jtag3_page_erase): Actually implement this.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37265: wrong page sizes for XMega64xx in avrdude.conf
|
||||
* avrdude.conf.in: Fix page sizes for all Xmega devices,
|
||||
by cross-checking against Atmel Studio's device XML files
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Fill in the missing pieces for Xmega support (both,
|
||||
PDI and JTAG).
|
||||
* jtagmkII.c (jtagmkII_set_xmega_params): Use "fuse1" rather
|
||||
than "fuse0" memory space to fill in the NVM offset from, as
|
||||
there is no "fuse0" on some Xmega devices.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega256RFR2, ATmega128RFR2, ATmega64RFR2):
|
||||
New devices
|
||||
|
||||
2012-11-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
First support for Atmel JTAGICE3. Guessed from USB sniffer
|
||||
traces made by Knut Schwichtenberg, and by similarity to
|
||||
JTAGICEmkII.
|
||||
Still quite incomplete, just megaAVR/JTAG is done by now.
|
||||
* jtag3.c: New file.
|
||||
* jtag3.h: (Dito.)
|
||||
* jtag3_private.h: (Dito.)
|
||||
* pgm_type.c: Add new programmers
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* usbdevs.h: Add new parameters
|
||||
* Makefile.am: Add new files
|
||||
* usb_libusb.c: Handle separate event endpoint, and larger
|
||||
(USB 2.0) packet sizes
|
||||
|
||||
2012-11-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Change all the USB details (endpoint numbers,
|
||||
max transfer size etc.) to a per-programmer adjustable value.
|
||||
* serial.h: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2012-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Replace outdated FSF postal address by a reference to
|
||||
the GPL info on their website.
|
||||
* jtagmkII.c: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
* linux_ppdev.h: (Dito.)
|
||||
* serbb.h: (Dito.)
|
||||
* usbtiny.h: (Dito.)
|
||||
* confwin.c: (Dito.)
|
||||
* buspirate.h: (Dito.)
|
||||
* avrftdi.h: (Dito.)
|
||||
* wiring.h: (Dito.)
|
||||
* jtagmkII.h: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* confwin.h: (Dito.)
|
||||
* avrdude.1: (Dito.)
|
||||
* windows/Makefile.am: (Dito.)
|
||||
* config.h: (Dito.)
|
||||
* pickit2.h: (Dito.)
|
||||
* term.h: (Dito.)
|
||||
* tools/get-hv-params.xsl: (Dito.)
|
||||
* tools/get-stk600-cards.xsl: (Dito.)
|
||||
* tools/get-stk600-devices.xsl: (Dito.)
|
||||
* tools/get-dw-params.xsl: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* configure.ac: (Dito.)
|
||||
* doc/Makefile.am: (Dito.)
|
||||
* pgm_type.c: (Dito.)
|
||||
* butterfly.h: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* COPYING: (Dito.)
|
||||
* pgm_type.h: (Dito.)
|
||||
* jtagmkI.h: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* arduino.c: (Dito.)
|
||||
* arduino.h: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* freebsd_ppi.h: (Dito.)
|
||||
* avr910.h: (Dito.)
|
||||
* solaris_ecpp.h: (Dito.)
|
||||
* stk500.h: (Dito.)
|
||||
* jtagmkII_private.h: (Dito.)
|
||||
* avrdude.h: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* bitbang.h: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* jtagmkI_private.h: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* safemode.h: (Dito.)
|
||||
* stk500generic.h: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* avr.h: (Dito.)
|
||||
* ppi.h: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* lists.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* my_ddk_hidsdi.h: (Dito.)
|
||||
* tpi.h: (Dito.)
|
||||
* usbasp.h: (Dito.)
|
||||
* lists.h: (Dito.)
|
||||
* stk500v2.h: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* fileio.h: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.h: (Dito.)
|
||||
* update.h: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* Makefile.am: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2012-11-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #35186 inverting pins with "~" doesn't work for pin lists (i.e. vcc)
|
||||
bug #37727 Add support for LM3S811 dev board as a programmer
|
||||
* lexer.l,config_gram.y: accepting inverted pins at pin lists
|
||||
syntax: ~num or ~(num,num,...)
|
||||
* par.c: par_set_many_bits is now usable with inverted pins
|
||||
* avrftdi.c: fixed wrong index in ftdi_pin_name
|
||||
* avrdude.conf.in: added programmer lm3s811
|
||||
|
||||
2012-11-04 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* lexer.l,config_gram.y,config.[hc]: changed reading of numbers to integers
|
||||
except of default_bitclock which is the only real number.
|
||||
No signs are allowed as negative values do not make sense for current
|
||||
config values.
|
||||
* buspirate.c: include own header file buspirate.h
|
||||
* doc/.cvsignore: add programmers.texi to ignore list
|
||||
|
||||
2012-09-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/Makefile.am: add EXTRA_DIST, replace $(srcdir) by
|
||||
$(builddir) for generated files, so "make distcheck"
|
||||
works again
|
||||
|
||||
2012-09-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* doc/Makefile.am: add $(srcdir) to name of generated files, so BSD make
|
||||
find the files ( GNU make sees no difference if the
|
||||
file is called version.texi or ./version.texi )
|
||||
|
||||
2012-08-15 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7184 Support for PICKit2 programmer
|
||||
* Makefile.am: add pickit2 files
|
||||
* pickit2.[ch]: new programmer implementation
|
||||
* pgm_type.c: add pickit to list
|
||||
* avrdude.1: documentation for pickit2
|
||||
* doc/avrdude.texi: documentation for pickit2
|
||||
* avrdude.conf.in: add pickit2 programmer entry
|
||||
|
||||
2012-08-15 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support, see comment #30
|
||||
* ft245r.c: added semaphore workaround for MacOS X,
|
||||
added pthread_testcancel in reader thread
|
||||
|
||||
* configure.ac: added check for TYPE_232H in libftdi (not in libftdi < 0.20)
|
||||
* avrftdi.c: do not use TYPE_232H if not declared
|
||||
|
||||
2012-08-13 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi.c: fixes pin_limit for different FTDI devices (there was a mixup
|
||||
between 2232C and 2232H)
|
||||
|
||||
2012-07-29 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi.c: bugfixes (synchronisation) and maintenance (paged programming,
|
||||
nicer output, separation of parameter checking and actual code)
|
||||
|
||||
2012-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_memtype): return MTYPE_FLASH rather than
|
||||
MTYPE_SPM for non-Xmega flash regions
|
||||
|
||||
2012-07-20 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrpart.c, avrpart.h: adds avr_pin_name()
|
||||
|
||||
2012-07-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: check for libelf.h also in libelf/
|
||||
* fileio.c: include <libelf/libelf.h> if configure found this
|
||||
to be the case
|
||||
|
||||
2012-06-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: Check for presence of <pthread.h>
|
||||
* ft245r.c: Depend on HAVE_PTHREAD_H
|
||||
* Makefile.am: Add -lpthread if needed.
|
||||
|
||||
2012-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbtiny.c (usbtiny_paged_load, usbtiny_paged_write):
|
||||
fix breakage introduced by the recent page handling reorg;
|
||||
it used to cause an infinite loop
|
||||
|
||||
2012-05-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Xmega page erase implementation for XPROG (AVRISPmkII, STK600)
|
||||
* stk500v2.c (stk600_xprog_page_erase): New function.
|
||||
|
||||
2012-05-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Xmega page erase implementation for JTAGICEmkII
|
||||
* jtagmkII.c: Handle flash pages sizes > 256 bytes, implement
|
||||
page_erase() method
|
||||
* avrdude.conf.in: Change flash pagesize for all Xmega devices
|
||||
to 512 bytes
|
||||
* avr.c: Implement auto_erase, using page_erase if available
|
||||
* avr.h: Remove unused parameters from avr_read(), replace
|
||||
unused parameter in avr_write)() by auto_erase
|
||||
* stk500v2.c: Handle flash page sizes > 256 bytes
|
||||
* update.c (do_op): Handle new updateflags parameter
|
||||
* main.c: Implement auto_erase as page_erase if possible
|
||||
* update.h (enum updateflags): New enum
|
||||
* pgm.h (struct programmer_t): Add page_erase method
|
||||
|
||||
2012-04-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_paged_load, jtagmkII_paged_write): fix bug
|
||||
in memory type calculation for Xmega "boot" memory region.
|
||||
|
||||
2012-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* update.c (parse_op): do not assume default memtype here
|
||||
* main.c: after locating the part information, determine default
|
||||
memtype for all update options that didn't have a memtype
|
||||
specified; this is "application" for Xmega parts, and "flash" for
|
||||
everything else.
|
||||
|
||||
2012-04-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c: Rework the way ELF file sections are considered: while
|
||||
scanning the program header table, the offsets from a program
|
||||
header entry must never be used directly when checking the bounds
|
||||
of the current AVR memory region. Instead, they must always be
|
||||
checked based on the corresponding section's entry. That way,
|
||||
Xmega devices now properly take into account whether the segment
|
||||
fits into any of the application/apptable/boot memory region.
|
||||
|
||||
2012-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30756: When setting SUT to 64ms on XMEGA, avrdude doesn't
|
||||
read device signature
|
||||
* main.c: When reading the signature yields 0x000000 or 0xffffff,
|
||||
retry (up to twice) after some progressive delay.
|
||||
|
||||
2012-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATxmega16D4, ATxmega32D4, ATxmega64D4,
|
||||
ATxmega128D4): New devices. As Xmega D doesn't feature a fuse0
|
||||
memory cell, move that one out from the generic .xmega part into
|
||||
the individual Xmega A parts.
|
||||
|
||||
2012-04-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29019: pagel/bs2 warning when uploading using stk500 to xmega
|
||||
* stk500.c (stk500_initialize): Insert dummy values for PAGEL and
|
||||
BS2 if they are not present in the config file, in order to be able
|
||||
to proceed with the stk500_set_extended_parms() anyway.
|
||||
|
||||
2012-04-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2_private.h (struct pdata): add boot_start
|
||||
* stk500v2.c: For the "flash" pseudo-memory of Xmega devices,
|
||||
distinguish addresses between "application" and "boot" area.
|
||||
|
||||
2012-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf2b): When checking the bounds of the current
|
||||
program header segment, subtract `low' from ph[n].p_paddr in order
|
||||
to correct the magic section offsets for the AVR's non-flash
|
||||
memory regions.
|
||||
|
||||
2012-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf_get_scn): Rather than trying to just match whether
|
||||
any given section maps straight to a program header segment, use a
|
||||
more sophisticated decision that matches any section as long as it
|
||||
fits into the segment. This is needed for situations where the
|
||||
program header segment spans a larger area than the section data
|
||||
provided. (This can e.g. happen in an ELF file that contains no
|
||||
data at address 0, like a bootloader only.)
|
||||
|
||||
2012-04-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28744: Can't load bootloader to xmega128a1 (part 2, fix for
|
||||
firmware >= V7.x)
|
||||
* jtagmkII.c: Add firmware-version dependent handling of Xmega parameters.
|
||||
V7.x firmware expects the NVM offsets being specified through the Xmega
|
||||
parameters command, but left out as part of the memory address itself.
|
||||
* jtagmkII_private.h: Add CMND_SET_XMEGA_PARAMS, and struct xmega_device_desc.
|
||||
* config_gram.y: Add mcu_base keyword.
|
||||
* avrpart.h: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in (.xmega): add mcu_base, and data memory segment.
|
||||
|
||||
2012-03-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28744: Can't load bootloader to xmega128a1 (part 1, fix for
|
||||
firmware < V7.x)
|
||||
* jtagmkII.c: When going to write to the boot section of flash,
|
||||
use MTYPE_BOOT_FLASH rather than MTYPE_FLASH
|
||||
* jtagmkII_private.h: add MTYPE_BOOT_FLASH constant
|
||||
|
||||
2012-03-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII_private.h: Sort commands, response codes and events
|
||||
into numerical order.
|
||||
|
||||
2012-03-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30451: Accessing some Xmega memory sections gives not
|
||||
supported error
|
||||
* stk500v2.c: Handle all Xmega memory sections (except
|
||||
"prodsig" which is not documented in AVR079)
|
||||
* fileio.c: Treat the "boot", "application", and "apptable"
|
||||
regions (which are actually subregions of "flash") all as
|
||||
being flash, i.e. suppress trailing 0xFF bytes when reading
|
||||
them
|
||||
* avr.c: (Dito.)
|
||||
|
||||
2012-03-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_close): The GO command before signing off
|
||||
turned out to be not required for normal megaAVR devices, and to
|
||||
cause the exact opposite (i.e. the target stopping) on Xmega
|
||||
devices being programmed to JTAG. However, programming Xmega
|
||||
devcies through PDI *does* need the GO command.
|
||||
|
||||
2012-03-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Print a configuration summary at the end of the
|
||||
configure run
|
||||
|
||||
2012-02-11 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7718: Merge global data of avrftdi in a private data structure
|
||||
* avrftdi.[ch]: moved global data into private data structure, moved
|
||||
private defines from header file into source file
|
||||
|
||||
2012-02-06 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7720 Bug in EEPROM write
|
||||
* avrftdi.c: fixed wrong buffer address initialization in paged_write
|
||||
* fileio.c: added #include <stdint.h>
|
||||
|
||||
2012-02-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support
|
||||
* ft245r.c: cancel reader thread before exiting program
|
||||
|
||||
2012-02-04 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7717 avrftdi_flash_write is broken
|
||||
* avrftdi.c: fixed wrong buffer address initialization in paged_write
|
||||
bug #35296 Extraneous newlines in output.
|
||||
* main.c: fixed output of newlines at 100% progress
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7715 FT4232H support
|
||||
* avrdude.conf.in: added programmer 4232h
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the programmers lists)
|
||||
* doc/avrdude.texi: Add include of generated table of programmers
|
||||
* doc/Makefile.am: Add generating of table of programmers in programmers.texi
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34768 Proposition: Change the name of the AVR32 devices
|
||||
* avrdude.conf.in: renamed ucr2 to uc3a0512
|
||||
* avrpart.c: added cast to avoid compiler warning
|
||||
|
||||
2012-02-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (fileio_elf): Fix a copy'n-paste-o.
|
||||
|
||||
2012-02-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* par.c (par_desc): Move to end of file, outside the #if
|
||||
HAVE_PARPORT
|
||||
|
||||
2012-02-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Implement ELF file reading (finally). Requires libelf(3) to be
|
||||
present on the host system.
|
||||
* configure.ac (HAVE_LIBELF): Add logic to detect presence of
|
||||
libelf(3)
|
||||
* Makefile.am (avrdude_LDADD): Add @LIBELF@
|
||||
* fileio.h (FILEFMT): add FMT_ELF
|
||||
* fileio.c: Implement ELF file reader.
|
||||
* update.c (parse_op): add 'e' format specifier
|
||||
* avrdude.1: Document the ELF file reading capability
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2012-02-01 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support
|
||||
* ft245r.[ch]: new programmer type implementation
|
||||
* configure.ac: add pthread as link library
|
||||
* avrdude.conf.in: added some new programmers
|
||||
* Makefile.am: added new source files to compile
|
||||
* pindefs.h: change PIN_MASK, PIN_INVERSE to highest bit of unsigned int
|
||||
* pgm.[ch]: added generic function to print pin assignments (taken from par.c)
|
||||
* par.c: moved pin assigment print function to pgm.c
|
||||
|
||||
2012-02-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Sort keyword tokens into alphabetic order.
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y, lexer.l: removed unused ID/TKN_ID definitions
|
||||
* config.[hc]: removed unused function id(), use value.type to select
|
||||
values
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7437 modifications to Bus Pirate module
|
||||
patch #7686 Updating buspirate ascii mode to current firmware, use AUX
|
||||
as clock generator, and setting of serial receive timeout
|
||||
* buspirate.c: added paged_write, changed binary mode setup/detection,
|
||||
added clock output on AUX pin
|
||||
* avrdude.1: updated documentation
|
||||
* doc/avrdude.texi: updated documentation
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Parser does not need to know all programmer types now, new programmers
|
||||
will update only the table in pgm_type.c.
|
||||
* config_gram.y, lexer.l: removed programmer type keywords,
|
||||
use now locate_programmer_type() function
|
||||
* pgm_type.[ch]: added new files for table of programmer types
|
||||
* main.c: allow list of programmer types by -c ?type
|
||||
* avrdude.conf.in: changed all type keywords to quoted strings
|
||||
* doc/avrdude.texi: changed description of type definition, list
|
||||
of valid types is now included from generated file
|
||||
* doc/Makefile.am: generate list of programmer types for doc
|
||||
* all programmers [hc]: add xxx_desc string for description of programmer
|
||||
|
||||
2012-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: fixed detection of yylex_destroy availability
|
||||
by checking the version number of flex; bump required autoconf
|
||||
version to 2.60 (for AC_PROG_SED)
|
||||
|
||||
2012-01-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Replace the old, now-defunct #define YY_NO_UNPUT by
|
||||
the new %option nounput. This gets rid of a compiler warning.
|
||||
|
||||
2012-01-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Add a connection_type attribute to each programmer, rather than
|
||||
trying to hard-code the default port name in main.c.
|
||||
* pgm.h: Add conntype to struct pgm.
|
||||
* lexer.l: Extend grammar for connection_type.
|
||||
* config_gram.y: (Dito.)
|
||||
* config.h: Add DEFAULT_USB, for symmetry with default_parallel
|
||||
and default_serial.
|
||||
* main.c: Replace old default portname hack by avrdude.conf-based
|
||||
knowledge.
|
||||
* usbtiny.c: Drop an old hack that's no longer necessary.
|
||||
* avrdude.conf.in: Add connection_type to each programmer
|
||||
definition.
|
||||
|
||||
2012-01-27 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: used parent parts for some other parts, added
|
||||
abstract .xmega part as parent for xmegas
|
||||
* main.c: hide parts starting with '.' from parts list
|
||||
|
||||
2012-01-22 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7688: Implement parent programmers feature
|
||||
* avrdude.conf.in: updated documentation comment and some programmers
|
||||
have now parents
|
||||
* config_gram.y: initpgm will now called at first use of programmer
|
||||
in main. parser sets only the function pointer in the pgm structure.
|
||||
Pin and pin lists definitions can now be empty to remove the parents
|
||||
setting.
|
||||
* doc/avrdude.texi: updated documentation
|
||||
* main.c: added call to pgm->initpgm after locate_programmer
|
||||
* pgm.[hc]: added field initpgm in structure, added function pgm_dup
|
||||
|
||||
2012-01-21 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #21797: AT90PWM316: New part description
|
||||
* avrdude.conf.in: added pwm316 with parent pwm3b but 16KB flash
|
||||
|
||||
2012-01-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Check for presence of lusb_usb.h as an alternative
|
||||
to usb.h; libusb-win32 switched to this name in version 1.2.5.0.
|
||||
* avrftdi.c: Decide whether to include <usb.h>, or <lusb0_usb.h>.
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2012-01-19 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avr.c: Unsigned variable was used for return code of paged_write/load
|
||||
functions. So a negative return code led never to a fallback to byte
|
||||
functions.
|
||||
|
||||
2012-01-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34302: Feature request : device configuration with parent classes
|
||||
* config_gram.y: if memory section is overwritten old entry is removed
|
||||
|
||||
(not in original patch)
|
||||
* config_gram.y: if programmer or part is defined twice, a warning is
|
||||
output and the first instance is removed
|
||||
|
||||
General cleanup and free functions, so valgrind does not report any lost
|
||||
blocks at program end.
|
||||
* avrpart.[hc]: added avr_free_(opcode|mem|part) functions
|
||||
* pgm.[hc]: added pgm_free function
|
||||
* update.[hc]: added free_update functions
|
||||
* config.[hc]: added cleanup_config function, use yylex_destroy to reset
|
||||
the lexer after usage. (So it can be reused.)
|
||||
* main.c: add cleanup_main function which is called by atexit() (This
|
||||
frees all lists so that at program exit only really lost memory is
|
||||
reported by valgrind.)
|
||||
* usbasp.c: added libusb_free_device_list() and libusb_exit() calls to
|
||||
avoid lost memory
|
||||
* buspirate.c: moved memory allocation from initpgm to setup and added
|
||||
free in teardown
|
||||
* configure.ac: add definition of HAVE_YYLEX_DESTROY if $LEX is flex.
|
||||
* Makefile.am: added . in front of SUBDIRS to build avrdude before trying
|
||||
to use it for creating the part list for the docs.
|
||||
|
||||
2012-01-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* usbasp.c: USB vid/pid/vendor/product from config file are used, for
|
||||
id "usbasp" nibobee and old usbasp are tried as they were currently
|
||||
implemented within usbasp
|
||||
* avrdude.conf.in: added usb params to "usbasp", added new entry "nibobee"
|
||||
with params which were hardcoded in usbasp.c, and added an entry
|
||||
"usbasb-clone" which only checks vid/pid.
|
||||
|
||||
2012-01-10 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #35261 avrftdi uses wrong interface in avrftdi_paged_(write|load)
|
||||
* avrftdi.c: Fixed interface and implementation of avrftdi_paged_(write|load)
|
||||
patch #7672 adding support for O-Link (FTDI based JTAG) as programmer
|
||||
* avrdude.conf.in: added o-link entry
|
||||
|
||||
2012-01-10 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7699 Read additional config files
|
||||
* main.c: Added reading of additional config files
|
||||
* avrdude.1: updated man page
|
||||
* doc/avrdude.texi: updated documentation
|
||||
|
||||
2012-01-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Bob Frazier:
|
||||
bug #35208: avrdude 5.11 on freebsd 8.2-STABLE does not reset
|
||||
Arduino Uno properly
|
||||
* arduino.c (arduino_open): Bump the timeout between pulling
|
||||
the DTR and RTS lines low and high.
|
||||
|
||||
2012-01-08 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Fixed following findings reported by cppcheck
|
||||
* avr910.c:625 (error) Possible null pointer dereference: cmd - otherwise it is redundant to check if cmd is null at line 624
|
||||
* avr910.c:626 (error) Possible null pointer dereference: cmd - otherwise it is redundant to check if cmd is null at line 624
|
||||
* avr910.c:168 (information) The scope of the variable 'devtype_1st' can be reduced
|
||||
* avr910.c:169 (information) The scope of the variable 'dev_supported' can be reduced
|
||||
* avrftdi.c:647 (error) Using sizeof for array given as function argument returns the size of pointer.
|
||||
* stk500v2.c:3347 (error) Memory leak: b
|
||||
* stk500v2.c:3452 (error) Memory leak: b
|
||||
* usbasp.c:554 (error) Using sizeof for array given as function argument returns the size of pointer.
|
||||
* usbasp.c:485 (information) The scope of the variable 'dly' can be reduced
|
||||
|
||||
2012-01-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Reported by Jason Kotzin:
|
||||
* usbasp.c (usbasp_spi_paged_load, usbasp_spi_paged_write):
|
||||
Fix buffer address calculation.
|
||||
|
||||
2012-01-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7629 add support for atmega48p
|
||||
* avrdude.conf.in: Added m48p with parent m48 + different signature
|
||||
|
||||
* avrdude.conf.in: made part parents (m88p = m88 + different signature,
|
||||
m168p = m168 + different signature)
|
||||
|
||||
2012-01-02 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #21663 AT90PWM efuse incorrect
|
||||
bug #30438 efuse bits written as 0 on at90pwmxx parts
|
||||
* avrdude.conf.in: (pwm2, pwm2b, pwm3, pwm3b) <efuse.write>: Write
|
||||
eight bits
|
||||
|
||||
* avrdude.conf.in: made part parents (pwm3 = pwm2, pwm3b = pwm2b,
|
||||
pwm2b = pwm2 + different signature)
|
||||
|
||||
* ChangeLog-2011: New file, rotate ChangeLog for new year.
|
||||
@@ -1,618 +0,0 @@
|
||||
2013-12-15 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* pgm.c/pgm.h: fixed syntax error in const pointer to const
|
||||
|
||||
2013-12-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: bump version to 6.1-svn-20131205
|
||||
|
||||
2013-12-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #40817: Elf file support (possibly) not working on 6.0.1 windows build
|
||||
* fileio.c (fileio): open file in binary mode also for FMT_ELF
|
||||
|
||||
2013-12-04 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Rework of bitbanging functions setpin, getpin, highpulsepin to make simplier use
|
||||
of new pindefs data in pgm structure
|
||||
* linuxgpio.c, bitbang.c, buspirate.c, par.c, pgm.h, term.c, serbb_*.c: changed
|
||||
interface of setpin, getpin, highpulsepin to take pin function as parameter
|
||||
(not the real number, which can be found by pgm->pinno[function])
|
||||
|
||||
2013-11-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #40748 linuxgpio doesn't work on Raspberry PI rev. 2.
|
||||
* linuxgpio.c: fixed check for unused pins to ignore the inverse flag
|
||||
* pindefs.c: fixed fill_old_pinlist to not create an empty mask with inverse flag set
|
||||
|
||||
2013-10-18 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* avrdude.conf.in (atmega1284): ATmega1284 variant added (same as ATmega1284p but with different signature)
|
||||
|
||||
2013-09-25 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
First part of patch #7720:
|
||||
* avrdude.conf.in: Add UM232H and C232H programmers
|
||||
|
||||
2013-09-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Daniel Rozsnyo:
|
||||
bug #40085: Typo fix in fuses report (for 6.1-svn-20130917)
|
||||
* main.c: Fix a typo.
|
||||
|
||||
2013-09-19 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
task #12798: Please cleanup #ifdef notyet entries in avrftdi.c
|
||||
* avrftdi.c: ditto.
|
||||
avrftdi.c: Remove DRYRUN-option.
|
||||
|
||||
2013-09-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #40055: AVRDUDE segfaults when writing eeprom
|
||||
* main.c: Always clear the UF_AUTO_ERASE flag if either a
|
||||
non-Xmega device was found, or the programmer does not offer a
|
||||
page_erase method.
|
||||
|
||||
2013-09-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to post-6.0.
|
||||
|
||||
2013-09-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to 6.0.
|
||||
|
||||
2013-09-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_initialize): Fix a buffer overflow by limiting
|
||||
the flash page cache size to at most "readsize". For Xmegas with
|
||||
a page size of 512 bytes, the maximum USB packet size was
|
||||
overflowed, and subsequently, a memmove copied beyond the end of
|
||||
the allocated buffer.
|
||||
* jtag3.c (jtag3_read_byte): Add the correct offset also for the
|
||||
various flash regions, so reading the apptable or boot regions
|
||||
yields the correct data.
|
||||
|
||||
2013-09-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Joakim Lubeck:
|
||||
bug #40040: Support for ATtiny20 and ATtiny40
|
||||
* avrdude.conf.in: Restructure the reduced-core tiny devices
|
||||
to use a common entry .reduced_core_tiny; add ATtiny20 and
|
||||
ATtiny40
|
||||
|
||||
2013-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Joakim Lubeck:
|
||||
bug #40033: Support for the XMegaE5 family
|
||||
* avrdude.conf.in (ATxmega8E5, ATxmega16E5, ATxmega32E5): New
|
||||
entries.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_set_sck_period): Revamp this to match the
|
||||
description/pseudo-code in appnote AVR068.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Stephen Roe:
|
||||
patch #7710: usb_libusb: Check VID/PID before opening device
|
||||
* usb_libusb.c (usbdev_open): Swap the sequence of verifying the
|
||||
VID:PID, and opening the device.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8176: butterfly.c (AVR109 protocol implementation) clean-up and bug-fixing
|
||||
* butterfly.c (butterfly_page_erase): Add dummy function to avoid
|
||||
segfault when writing to EEPROM.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #35474 Feature request: print fuse values in safemode output
|
||||
* config_gram.y: New configuration token "default_safemode".
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* config.h: Add variable default_safemode.
|
||||
* config.c: (Dito.)
|
||||
* main.c: Handle default_safemode, including -u option.
|
||||
* avrdude.1: Document all this.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by HubertB:
|
||||
patch #7657 Add ATmega406 support for avrdude using DRAGON + JTAG
|
||||
* avrdude.conf.in (ATmega406): New entry.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Marc de Hoop:
|
||||
patch #7606 ATtiny43u support
|
||||
* avrdude.conf.in (ATtiny43U): New entry.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #5708 avrdude should make 10 synchronization attempts instead of just one
|
||||
* stk500.c (stk500_getsync): Loop 10 times trying to get in
|
||||
sync with the programmer.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Ricardo Martins:
|
||||
bug #36384 ATxmega32A4 usersig size
|
||||
* avrdude.conf.in: Revamp all the ATxmega* entries. Add new
|
||||
entries for ATxmega128A1U, ATxmega128A3U, ATxmega128A4U,
|
||||
ATxmega128B1, ATxmega128B3, ATxmega128C3, ATxmega128D3,
|
||||
ATxmega16A4U, ATxmega16C4, ATxmega192A3U, ATxmega192C3,
|
||||
ATxmega192D3, ATxmega256A3BU, ATxmega256A3U, ATxmega256C3,
|
||||
ATxmega256D3, ATxmega32A4U, ATxmega32C4, ATxmega384C3,
|
||||
ATxmega384D3, ATxmega64A1U, ATxmega64A3U, ATxmega64A4U,
|
||||
ATxmega64B1, ATxmega64B3, ATxmega64C3, ATxmega64D3
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #35456 The progress bar for STK500V2 programmer is "wrong".
|
||||
* avr.c (avr_read, avr_write): Change the progress reporting for
|
||||
paged read/write from per-address to per-considered-page. This
|
||||
ought to give a realistic estimation about the time still to be
|
||||
spent.
|
||||
|
||||
2013-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34277: avrdude reads wrong byte order if using avr911 (aka butterfly)
|
||||
* butterfly.c (butterfly_read_byte_flash): Swap bytes received.
|
||||
|
||||
2013-09-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37768 Poll usbtiny 100 times at init time to handle low-clock devices
|
||||
* doc/avrdude.texi: Add a FAQ entry about how to connect to a
|
||||
target where the firmware has reduced the internal clock speed.
|
||||
|
||||
2013-09-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28344 chip_erase_delay too short for ATmega324P, 644, 644P, and 1284P
|
||||
* avrdude.conf: Bump the chip_erase_delay for all ATmega*4 devices
|
||||
to 55 ms. While the datasheet still claims 9 ms, all the XML files
|
||||
tell either 45 or 55 ms, depending on STK600 or not.
|
||||
|
||||
2013-09-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (fileio): Don't exit(1) if something goes wrong; return
|
||||
-1 instead. Don't refer to obsolete option -f to specify the file
|
||||
format.
|
||||
|
||||
2013-09-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Matthias Trute:
|
||||
bug #36901 flashing Atmega32U4 EEPROM produces garbage on chip
|
||||
* avrdude.conf.in (ATmega32U4): Fix EEPROM pagesize to 4, the
|
||||
datasheet is wrong here.
|
||||
|
||||
2013-09-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: check for ar and ranlib in the target tool
|
||||
namespace, rather than on the host.
|
||||
|
||||
2013-09-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix byte-wise EEPROM and flash writes on Xmega
|
||||
* jtagmkII_private.h (MTYPE_EEPROM_XMEGA): New memory type.
|
||||
* jtagmkII.c (jtagmkII_write_byte): For Xmega EEPROM, use
|
||||
memory type MTYPE_EEPROM_XMEGA; for flash writes, always
|
||||
write 2 bytes starting on an even address.
|
||||
|
||||
2013-09-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* term.c: Implement the "verbose" terminal mode command.
|
||||
* avrdude.1: Document this.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2013-09-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_write_byte): Do not attempt to start the paged
|
||||
algorithm for EEPROM when being connected through debugWIRE.
|
||||
|
||||
2013-09-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Extend the single-byte algorithm to all devices, both flash and
|
||||
EEPROM. (Flash cells must have been erased before though.)
|
||||
* jtag3.c (jtag3_initialize): OCDEN no longer needs to be
|
||||
considered; a session with "programming" purpose is sufficient
|
||||
* jtag3.c (jtag3_write_byte): Use the paged algorithm for all
|
||||
flash and EEPROM areas, not just Xmega.
|
||||
|
||||
2013-09-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix single-byte EEPROM updates on Xmega:
|
||||
* jtag3_private.h (MTYPE_EEPROM_XMEGA): New define.
|
||||
* jtag3.c (jtag3_write_byte): When updating flash or
|
||||
EEPROM on Xmega devices, resort to jtag3_paged_write()
|
||||
after filling and modifying the page cache.
|
||||
* jtag3.c (jtag3_paged_write): use MTYPE_EEPROM_XMEGA
|
||||
where appropriate.
|
||||
* jtag3.c (jtag3_initialize): Open with debugging intent
|
||||
for Xmega devices, so single-byte EEPROM updates will
|
||||
work.
|
||||
|
||||
2013-09-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Matthias Neeracher:
|
||||
bug #38732: Support for ATtiny1634
|
||||
* avrdude.conf.in (ATtiny1634): New entry.
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Brane Ždralo:
|
||||
patch #7769: Write flash fails for AVR910 programmers
|
||||
* avr910.c (avr910_paged_write): Fix flash addresses in
|
||||
'A' command.
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Fred (magister):
|
||||
bug #38951: AVR109 use byte offset instead of word offset
|
||||
patch #8045: AVR109 butterfly failing
|
||||
* butterfly.c (butterfly_paged_load, butterfly_paged_write):
|
||||
fix calculation of 'A' address when operating on flash memory.
|
||||
It must be given in terms of 16-bit words rather than bytes.
|
||||
|
||||
2013-09-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrftdi.c, avrftdi_private.h: added tx buffer size, and use
|
||||
smaller block sizes as larger sometimes hang
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.h: Remove the erase cycle counter (options -y / -Y).
|
||||
* avr.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* avrdude.1: Undocument -y / -Y.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #39691 Buffer overrun when reading EEPROM byte with JTAGICE3
|
||||
* jtag3.c (jtag3_initialize): initialize the eeprom_pagesize
|
||||
private attribute so the page cache will actually be usable
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #38580 Current svn head, xmega and fuses, all fuses tied to fuse0
|
||||
* jtag3.c (jtag3_read_byte, jtag3_write_byte): Correctly apply the
|
||||
relevant part of mem->offset as the address to operate on.
|
||||
|
||||
2013-09-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c: Fix "unused variable" warnings.
|
||||
* avr.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Travis Griggs:
|
||||
bug #38307: Can't write usersig of an xmega256a3
|
||||
* stk500v2.c (stk600_xprog_page_erase): allow erasing the usersig space.
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Robert Niemi:
|
||||
bug #35800: Compilation error on certain systems if parport is disabled
|
||||
* linux_ppdev.h: Conditionalize inclusion of <linux/parport.h> and
|
||||
<linux/ppdev.h> on HAVE_PARPORT
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #39794: warnings when building avrdude 6.0rc1 under CentOS 6.4
|
||||
* pickit.c (usb_open_device): Use %p rather than %X to print "handle"
|
||||
which is a pointer
|
||||
* jtag3.c (jtag3_initialize): Initialize "flashsize" to be sure it
|
||||
proceeds with a valid value.
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #39794: warnings when building avrdude 6.0rc1 under CentOS 6.4
|
||||
* buspirate.c: Turn the "cmd" argument of the various methods into
|
||||
a "const unsigned char *"; while doing this, declare all arrays being
|
||||
passed as arguments to be pointers rather than arrays, as the latter
|
||||
obfuscates the way arrays are being passed to a callee in C.
|
||||
* avrftdi.c: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* bitbang.h: (Dito.)
|
||||
* avrftdi_tpi.c: (Dito.)
|
||||
* avrftdi_tpi.h: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #38023: avrdude doesn't return an error code when attempting
|
||||
to upload an invalid Intel HEX file
|
||||
* fileio.c (ihex2b): Turn the "No end of file record found" warning
|
||||
into an error if no valid record was found at all.
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Claus-Justus Heine:
|
||||
bug #38713: Compilation of the documentation breaks with texinfo-5
|
||||
* doc/avrdude.texi: Turn @itemx into @item, add @headitem to STK600
|
||||
Routing/Socket card table
|
||||
|
||||
2013-09-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c: Add trace output for -vvv to non-TPI functions, too.
|
||||
|
||||
2013-09-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c (usbasp_tpi_paged_load): Calculate correct
|
||||
buffer address.
|
||||
* usbasp.c (usbasp_tpi_paged_write): Calculate correct
|
||||
buffer address; don't issue a SECTION_ERASE command for
|
||||
each page (a CHIP_ERASE has been done before anyway);
|
||||
remove the code that attempted to handle partial page
|
||||
writes, as all writes are now done with a full page.
|
||||
|
||||
2013-09-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c: Add more trace output, by now only for the TPI
|
||||
functions.
|
||||
|
||||
2013-08-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c (usbasp_transmit): Add -vvvv trace output.
|
||||
|
||||
2013-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #39893: Verification failure with AVRISPmkII and Xmega
|
||||
* stk500v2.c (stk600_xprog_page_erase): Fix argument that is
|
||||
passed to stk600_xprog_memtype()
|
||||
|
||||
2013-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf2b): replace elf_getshstrndx() by
|
||||
elf_getshdrstrndx() as the former one is deprecated
|
||||
|
||||
2013-06-19 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
use bitbanging on ftdi mpsse when wrong pins are used
|
||||
* avrftdi.c, avrftdi_private.h: added additional pin check
|
||||
and bitbanging fallback
|
||||
* pindefs.[ch]: added a flag to enable/disable output
|
||||
* ft245r.c: changes because of added flag above
|
||||
|
||||
2013-05-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by "Malte" and John McCorquodale:
|
||||
patch #7876 JTAGICE mkII fails to connect to attiny if debugwire
|
||||
is enabled AND target has a very slow clock
|
||||
* jtagmkII.c (jtagmkII_getsync): When leaving debugWIRE mode
|
||||
temporarily, immediately retry with ISP, rather than leaving.
|
||||
* stk500v2 (stk500v2_program_enable): Implemented similar logic
|
||||
for the JTAGICE3.
|
||||
|
||||
2013-05-16 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: reactivate check for TYPE_232H, which does not
|
||||
exist in libftdi < 0.20
|
||||
* avrftdi*.*: changed include check for libftdi/libusb, deactivate
|
||||
232H if not available
|
||||
* ft245r.c: changed include check for libftdi/libusb
|
||||
|
||||
2013-05-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c (main): Add option -l logfile.
|
||||
* avrdude.1: Document -l option.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2013-05-15 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: if both found libftdi and libftdi1 use only libftdi1
|
||||
* avrdude.conf.in: fixed buff pins of avrftdi programmers (low
|
||||
active buffer need now inverted numbers)
|
||||
* avrftdi*.*: accept also old libftdi (0.20 still works with it),
|
||||
added powerup to initialize
|
||||
* ft245r.c: accept libftdi1, code cleanup and make it more similar
|
||||
to avrfdti (os they might be merged someday)
|
||||
|
||||
2013-05-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to 6.0rc1.
|
||||
|
||||
2013-05-07 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi_private.h: Change size of pin_checklist to N_PINS (from N_PINS-1)
|
||||
* avrftdi.c: Adapt code to new size of pin_checklist. Remove pins_check()
|
||||
from set_pin().
|
||||
Add pgm->power[up|down] functions as well as fill pgm->enable|disable with
|
||||
proper content as suggested by Rene Liebscher.
|
||||
|
||||
2013-05-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* pindefs.h: use unsigned int if stdint.h is not available and UINT_MAX is 0xffffffff
|
||||
otherwise use unsinged long
|
||||
* ft245r.c: added support for more pin functions led, vcc, buff
|
||||
|
||||
2013-05-06 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi_tpi.c: instead of private set_pin() function pointer use the one
|
||||
declared in struct PROGRAMMER.
|
||||
* avrftdi_private.h: remove set_pin function pointer. Add pin_checklist_t
|
||||
member to check pgm->setpin calls during runtime.
|
||||
* avrftdi.c: remove set_pin function pointer init, add pgm->setpin init.
|
||||
Convert avrftdi to new 0-based pindefs infrastructure.
|
||||
* avrdude.conf.in: Change all avrftdi-based programmers' pin definitions to
|
||||
0-based.
|
||||
|
||||
2013-05-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* pindefs.h: Include "ac_cfg.h" before testing for HAVE_* macros.
|
||||
|
||||
2013-05-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* main.c: revert to rev 1159 (doing pgm_display after pgm_open)
|
||||
* avrpart.[ch]: moved avr_pin_name to pindefs.[ch]
|
||||
* pgm.c: moved pins_to_str to pindefs.[ch], added initialization of
|
||||
new pin definitions in pgm_new()
|
||||
* pindefs.[ch]: added moved functions from other files, added a lot of
|
||||
documentation, reformatted files using astyle to have consistent spacing,
|
||||
added a new generic check function for pins
|
||||
* ft245r.c: used new generic pin check function
|
||||
|
||||
2013-05-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Create new pin definition data structures to support 0-based pin numbers,
|
||||
and mixed inverse/non-inverse pin lists.
|
||||
* avrftdi.c,buspirate.c,linuxgpio.c,par.c,serbb_*.c: added function call
|
||||
to fill old pinno entries from new pin definitions.
|
||||
* pindefs.[hc]: added data struct and helper functions for new pin definitions
|
||||
* avrdude.conf.in: pins in entries using ftdi_syncbb are now 0-based
|
||||
* config_gram.y: allow combinations of inverted and non-inverted pins in pin lists
|
||||
* ft245r.c: reworked to work directly with the new pin definitions,
|
||||
pins are now 0-based, inverse pins are supported, buff is supported
|
||||
* pgm.[ch]: added new pin definitions field to programmer structure,
|
||||
adapted pin display functions
|
||||
|
||||
2013-05-03 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi_private.h: Remove update forward declaration from avrftdi_print to
|
||||
avrftdi_log.
|
||||
* avrftdi_tpi.c: Do all I/O in terms of pgm->cmd_tpi()-calls instead of
|
||||
avrftdi_tpi_[read,write]_byte().
|
||||
Remove unnecessary set_pin call to set MOSI high, speeds up I/O.
|
||||
Removes SKEY array, moves it to tpi.h.
|
||||
Integrate new avr_tpi_[program_enable,chip_erase]() and functions into
|
||||
avrftdi_tpi.
|
||||
* avrftdi_tpi.h: Remove avrftdi_tpi_[program_enable,chip_erase] forward
|
||||
declarations.
|
||||
* avr.c: Adds avr_tpi_chip_erase() generic TPI chip erase function.
|
||||
Adds avr_tpi_program_enable() - generic TPI external programming enable
|
||||
function. Sets guard time, reads identification register, sends SKEY command
|
||||
and key, checks NVMEN bit. The required guard time has to be passed as
|
||||
parameter.
|
||||
* tpi.h: Adds SKEY array including CMD_SKEY in "correct" order.
|
||||
|
||||
2013-05-02 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi_private.h: Add libusb-1.0 include to fix include order in windows.
|
||||
* NEWS: Add notice avrftdi supporting TPI
|
||||
* avr.c: Fix avr_tpi_poll_nvmbsy() - poll read data instead of return code
|
||||
* avrftdi_private.h, avrftdi.c: move logging #defines to from avrftdi.c to
|
||||
avrftdi_private.h, so that they are available for avrftdi_tpi, too.
|
||||
|
||||
2013-04-30 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* tpi.h: Add definition for TPI Identification Code
|
||||
* avrftdi_tpi.c: Add TPI-support for FTDI-based programmers
|
||||
* avrftdi_private.h: Add common include file for FTDI-based programmers
|
||||
|
||||
2013-04-28 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdic: Rework of textual output. Messages are divided by severity and
|
||||
printed accordingly to the verbosity, as specified by the user. The provided
|
||||
severity level are (ERROR, WARN, INFO, DEBUG, TRACE). Where "ERROR" messages
|
||||
are always printed. Shortcut-macros including function, from which the
|
||||
output was generated, and line number were also added.
|
||||
Some log messages were updated and other code warnings removed.
|
||||
|
||||
2013-04-27 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* configure.ac: Add libftdi1 library check, remove TYPE_232H DECL check
|
||||
* Makefile.am: Add @LIBFTDI1@ to avrdude_LDADD
|
||||
* avrftdi.c: Update from libftdi0 to libftdi1. Use libftdi1's function to
|
||||
find a device by vid/pid/serial instead of doing it ourself and add/update
|
||||
error messages. avrftdi_print is changed so that a message is printed when
|
||||
the verbosity level is greater or equal the message level, to have always-on
|
||||
messages.
|
||||
Fix a bug where the RX fifo of the FTDI chip is full, resulting in STALL/NAK
|
||||
of the ongoing OUT request and subsequently timeout, because an IN request
|
||||
cannot be issued due to the synchronous part of libftdi. This should fix
|
||||
#38831 and #38659.
|
||||
|
||||
2013-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac(AC_CONFIG_HEADERS): Replace the old AM_CONFIG_HEADER
|
||||
by this; automake 1.13+ barfs.
|
||||
|
||||
2013-03-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega2564RFR2, ATmega1284RFR2, ATmega644RFR2):
|
||||
New devices
|
||||
|
||||
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7724 Add TPI support for Bus Pirate using bitbang mode
|
||||
* buspirate.[ch]: added support for BusPirate Bitbanging
|
||||
* pgm_type.c: added entry for buspirate_bb
|
||||
* avrdude.conf.in: added entry for buspirate_bb
|
||||
|
||||
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7936 Patch to support BusPirate AVR Extended Commands mode
|
||||
* buspirate.c: added support for BusPirate AVR Extended Commands mode
|
||||
* avrdude.1: added doc for nopagedread parameter
|
||||
* doc/avrdude.texi: added doc for nopagedread parameter
|
||||
|
||||
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7723 Bus Pirate “raw-wire” mode which can run down to 5 kHz
|
||||
* buspirate.c: added raw wire mode
|
||||
* avrdude.1: added doc for rawfreq parameter
|
||||
* doc/avrdude.texi: added doc for rawfreq parameter
|
||||
|
||||
2013-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #37977 Support for Openmoko Debug Board
|
||||
* avrdude.conf.in: added openmoko entry
|
||||
|
||||
2013-01-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7932 Read USBtiny VID and PID from avrdude.conf if provided.
|
||||
* avrdude.conf.in: added usbpid, usbvid to usbtiny
|
||||
* usbtiny.[ch]: use usbpid, usbpid if provided in config file
|
||||
|
||||
2013-01-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #38172: avrftdi: Incorrect information in avrdude.conf
|
||||
* avrdude.conf.in (avrftdi): fix comments about ACBUS vs. ADBUS;
|
||||
add a comment that the MPSSE signals are fixed by the FTDI
|
||||
hardware and cannot be changed
|
||||
|
||||
2013-01-09 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7165 Add support for bitbanging GPIO lines using the Linux sysf GPIO interface
|
||||
* doc/avrdude.texi,avrdude.1: added doc for linuxgpio
|
||||
* avrdude.conf.in: added template for linuxgpio programmer
|
||||
* config_gram.y: pin numbers restricted to [PIN_MIN, PIN_MAX]
|
||||
* pindefs.h: added PIN_MIN, PIN_MAX, removed unused LED_ON/OFF
|
||||
* configure.ac: configure option enable-linuxgpio, print of enabled options
|
||||
* linuxgpio.[ch]: new source for linuxgpio programmer
|
||||
* Makefile.am: added linuxgpio to sources list
|
||||
* pgm_type.c: added linuxgpio to programmer types list
|
||||
|
||||
2013-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkI.c (jtagmkI_prmsg): replace a putchar() by putc(...stderr)
|
||||
* jtagmkII.c (jtagmkII_prmsg): (Dito.)
|
||||
* jtag3.c (jtag3_prevent, jtag3_prmsg): (Dito.)
|
||||
|
||||
2013-01-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_open): Downgrade the max transfer size for
|
||||
the main data endpoints when being forced so by the USB; this can
|
||||
happen when attaching the JTAGICE3 to a USB 1.1 connection
|
||||
* jtag3.c (jtag3_initialize): When detecting a downgraded max
|
||||
transfer size on the JTAGICE3 (presumably, due to being connected
|
||||
to USB 1.1 only), bail out as its firmware cannot properly handle
|
||||
this (by now)
|
||||
|
||||
2013-01-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ChangeLog: annual ChangeLog rotation time
|
||||
@@ -1,697 +0,0 @@
|
||||
2014-11-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ser_win32.c (net_send): Properly declare argument 2 as being a
|
||||
pointer to const data.
|
||||
|
||||
2014-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
* ser_posix.c: Add a hack to allow for arbitrary baud rates on
|
||||
Linux
|
||||
|
||||
2014-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||
* configure.ac: Check for ws2_32 library
|
||||
* ser_win32.c: Add hooks for forwarding serial data over
|
||||
TCP connections
|
||||
* avrdude.1: Drop previous restriction of -P net:
|
||||
* doc/avrdude.conf: (Dito.)
|
||||
|
||||
2014-11-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #42908: no external reset at JTAGICE3
|
||||
* jtag3.c (jtag3_initialize): Retry with external reset applied if
|
||||
the first sign-on attempt fails.
|
||||
|
||||
2014-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Allow the -B option argument to be suffixed with Hz,
|
||||
kHz, or MHz, in order to specify a bitclock frequency rather than
|
||||
period.
|
||||
* avrdude.1: Document the -B option changes.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2014-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #40870: config nitpick: ATtiny25/45/85 have 1 calibration byte not 2
|
||||
* avrdude.conf.in (ATtiny25, ATtiny45, ATtiny85): Fix size of
|
||||
"calibration" memory area
|
||||
|
||||
2014-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #43137: Writing and reading incorrect pages when using jtagicemkI
|
||||
* jtagmkI.c (jtagmkI_paged_write, jtagmkI_paged_load): correctly
|
||||
calculate the size of a partial (non-pagesize) buffer
|
||||
|
||||
2014-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #43078: AVRDUDE crashes after sucessfully reading/writing eeprom
|
||||
* jtag3.c (jtag3_edbg_recv_frame): Return correct length as
|
||||
reported in the response packet, rather than full 512 byte which
|
||||
are always reported by the CMSIS-DAP layer. Miscalculations
|
||||
based on the wrongly reported length caused heap corruption
|
||||
elsewhere, so this is presumably also a fix for bug #43078.
|
||||
|
||||
2014-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #41561: AVRDUDE 6.0.1/USBasp doesn't write first bytes of
|
||||
flash page
|
||||
* usbasp.c (usbasp_spi_paged_write): Remove USBASP_BLOCKFLAG_LAST.
|
||||
It is no longer needed, as we always write full pages now in paged
|
||||
write mode.
|
||||
|
||||
2014-11-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #43626: Inconsistent timeouts in stk500v2
|
||||
* stk500v2.c (stk500v2_recv): Add a reference to the bug report
|
||||
but don't change anything, lest to break it somehow
|
||||
|
||||
2014-11-14 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8529 2 more ftdi_syncbb devices
|
||||
* avrdude.conf.in: added 2 new programmers
|
||||
|
||||
2014-11-14 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #40142 Floating point exception on Ubuntu 10.04
|
||||
* avr.c: avoid division by zero in report_progress(), eg. when
|
||||
writing an empty eeprom file were total becomes 0
|
||||
|
||||
2014-11-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8504 buspirate: Also support "cpufreq" extended parameter
|
||||
in binary mode
|
||||
* buspirate.c: applied patch + switch off at disable (even when
|
||||
a reset follows) + some general whitespace/tab cleanup
|
||||
|
||||
2014-10-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37441: lockbits in ATxmega + avrdude = problem
|
||||
* fileio.c: replace strmcp(..., "lock") by strncmp(..., "lock", 4)
|
||||
where applicable
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
|
||||
2014-10-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #42267: jtag3isp fails to read lock and fuse bytes directly
|
||||
after changing lock byte
|
||||
* stk500v2.c (stk500isp_write_byte): As a workaround for broken
|
||||
tool firmware, add 10 ms of delay before returning from any
|
||||
single-byte write operation.
|
||||
|
||||
2014-10-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Use stk500isp_read_byte/stk500isp_write_byte for
|
||||
every byte-wide access (rather than JTAGICE3 only). This finally
|
||||
obsoletes the use of the prehistoric SPI_MULTI command where
|
||||
AVRDUDE used to assemble all the low-level ISP stuff by itself.
|
||||
|
||||
2014-10-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22248: Read efuse error
|
||||
* avrdude.conf.in (m168, m328, m48, m88, t1634, t26, t261, t461,
|
||||
t861, t88): In efuse (or hfuse for t26) read operation, turn all
|
||||
bits in byte 3 from "x" to "o" (output); this is a first step
|
||||
towards fixing the symptoms mentioned in the bug, by unifying the
|
||||
behaviour between different AVRs. Not touched are the historic
|
||||
devices where the fuses are not documented to form a full byte
|
||||
each (2333, 4433, 4434, 8535, m103, m161, m163).
|
||||
|
||||
2014-09-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #43268: usb_drain() call causes LUFA AVR-ISP MKII Code to Fail
|
||||
* usb_libusb.c (usbdev_drain): Make this a dummy function only.
|
||||
|
||||
2014-08-19 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7694 Add support for the atmega32m1
|
||||
* avrdude.conf.in: added ATmega32M1
|
||||
|
||||
2014-08-18 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8440 Print part id after signature
|
||||
When printing the part signature also print the part id.
|
||||
* avrpart.c (locate_part_by_signature): New function.
|
||||
* libavrdude.h (locate_part_by_signature): New function.
|
||||
* main.c (main): Use the new function to find the part and print its id.
|
||||
|
||||
2014-08-18 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8511 Fix reset on FT245R
|
||||
* ft245r.c: applied patch
|
||||
|
||||
2014-08-18 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #43002 usbasp debug output typo
|
||||
* usbasp.c: fixed typos
|
||||
|
||||
2014-07-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #42662 clang warnings under FreeBSD 10.x
|
||||
* avrftdi.h: Fix header guard macro name.
|
||||
* pgm_type.c (programmers_types): Remove duplicate "const".
|
||||
|
||||
2014-07-16 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42662 clang warnings under FreeBSD 10.x
|
||||
* avrftdi.c: remove warnings
|
||||
* buspirate.c: (Dito.)
|
||||
* dfu.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* libavrdude.h: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
|
||||
* config_gram.y: fix problem when using parent part with usbpid lists
|
||||
(existing list was extended not overwritten)
|
||||
|
||||
2014-07-11 Axel Wachtler <axel@uracoli.de>
|
||||
|
||||
* avrftdi.c: rollback to vfprintf, fixed error from -r1305, (patch #8463)
|
||||
|
||||
2014-06-23 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* linux_ppdev.h: added missing msg level for avrdude_message
|
||||
in ppi_claim/ppi_release macros
|
||||
* avrftdi.c: added break at end of default
|
||||
|
||||
2014-06-21 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #8419 fix ftdi_syncbb hang with libftdi 1
|
||||
* ft245r.c: set pthread cancel type to asynchronous, reorder ftdi_usb_close/deinit
|
||||
|
||||
2014-06-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrftdi_private.h: added missing msg level for avrdude_message
|
||||
in E/E_VOID macros
|
||||
|
||||
2014-06-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Removing exit calls from config parser
|
||||
* config.h: cleanup, left only internally needed definitions
|
||||
* config.c: removed exit calls, use yyerror and yywarning
|
||||
* config_gram.y: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* libavrdude.h: removed internal definitions of config parser
|
||||
* main.c: removed yyerror, it is now in config.c
|
||||
* jtagmkII.c: added missing free in error case
|
||||
* pgm.c: replaced exits by returns
|
||||
* pickit2.c: add missing return
|
||||
|
||||
2014-06-13 Axel Wachtler <axel@uracoli.de>
|
||||
|
||||
start removing global "verbose" variable, for avrdude library.
|
||||
* arduino.c: added verbose level in avrdude_message()
|
||||
* avr910.c: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* avrdude.h: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* dfu.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* flip1.c: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* libavrdude.h: (Dito.)
|
||||
* linuxgpio.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* pindefs.c: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
|
||||
2014-06-11 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42516 spelling-error-in-binary
|
||||
* stk500v2.c, avrftdi.c, usbasp.c: fixed spelling errors
|
||||
|
||||
2014-06-01 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42337 avrdude.conf updates for UM232H/CM232H
|
||||
* avrdude.conf.in: fixed entries as proposed
|
||||
|
||||
2014-05-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #41854: avrdude 6.1 does not compile on systems without libUSB
|
||||
Submitted by Didrik Madheden:
|
||||
* flip1.c: Provide dummy functions for the #ifndef HAVE_LIBUSB case
|
||||
* flip2.c: (Dito.)
|
||||
|
||||
2014-05-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* libavrdude.h: Join the former "public" header files (avr.h avrpart.h pindefs.h
|
||||
serial.h fileio.h safemode.h update.h pgm_type.h config.h confwin.h lists.h) into
|
||||
a single header that can be included by anyone wanting to link against the
|
||||
library
|
||||
* avr.h: Remove file.
|
||||
* avrpart.h: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* fileio.h: (Dito.)
|
||||
* safemode.h: (Dito.)
|
||||
* update.h: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* pgm_type.h: (Dito.)
|
||||
* config.h: (Dito.)
|
||||
* confwin.h: (Dito.)
|
||||
* lists.h: (Dito.)
|
||||
* Makefile.am: Adapt for new include file constellation; install shared lib
|
||||
* configure.ac: Bump version date
|
||||
* arduino.c: #include <libavrdude.h> rather than a bunch of different headers
|
||||
* avr910.c: (Dito.)
|
||||
* avr910.h: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* avrftdi_private.h: (Dito.)
|
||||
* avrftdi_tpi.c: (Dito.)
|
||||
* avrftdi_tpi.h: (Dito.)
|
||||
* avr.h: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* config.h: (Dito.)
|
||||
* confwin.c: (Dito.)
|
||||
* confwin.h: (Dito.)
|
||||
* dfu.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* fileio.h: (Dito.)
|
||||
* flip1.c: (Dito.)
|
||||
* flip1.h: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* flip2.h: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* ft245r.h: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* libavrdude.h: (Dito.)
|
||||
* linuxgpio.c: (Dito.)
|
||||
* lists.c: (Dito.)
|
||||
* lists.h: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* pgm_type.c: (Dito.)
|
||||
* pgm_type.h: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* pickit2.h: (Dito.)
|
||||
* pindefs.c: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* safemode.h: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* stk500v2_private.h: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* term.h: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* update.h: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usbasp.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
* usbtiny.h: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
|
||||
2014-05-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Cleanup unused include files.
|
||||
|
||||
2014-05-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* linux_ppdev.h: Caught two more instances of exit()
|
||||
* configure.ac: Add AC_CONFIG_MACRO_DIR as suggested by libtoolize
|
||||
* Makefile.am: add -I m4 to ACLOCAL_AMFLAGS as suggested by libtoolize
|
||||
|
||||
2014-05-16 Axel Wachtler <axel@uracoli.de>
|
||||
|
||||
* arduino.c: Replacing all occurences of fprintf(stderr,...) with avrdude_message(...)
|
||||
in potential library functions.
|
||||
* avr910.c: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* avrdude.h: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* avrftdi_private.h: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* dfu.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* flip1.c: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* linuxgpio.c: (Dito.)
|
||||
* linux_ppdev.h: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* pindefs.c: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
|
||||
2014-05-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version, add libtool hooks
|
||||
* Makefile.am: First attempt to define building a shared library
|
||||
(not to be installed by now)
|
||||
|
||||
2014-05-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* dfu.c (dfu_open, dfu_init): Fix signature of the dummy functions
|
||||
(in the !HAVE_LIBUSB case) to match prototypes.
|
||||
|
||||
2014-05-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Replace all occurences of exit() in potential library
|
||||
functions by appropriate return values
|
||||
* avrftdi.c: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* bitbang.h: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* linuxgpio.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* pindefs.c: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
|
||||
2014-05-07 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42310: New part description for AT90PWM216
|
||||
* avrdude.conf.in: added pwm216 entry
|
||||
|
||||
2014-05-07 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42158: Linux GPIO - Source Typo
|
||||
* pindefs.h: fixed typo
|
||||
|
||||
2014-04-14 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #42056: double free or corruption triggered at exit
|
||||
* pgm.c: copy usbpid list in pgm_dup
|
||||
|
||||
2014-04-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Remove the note that users might edit the system-wide
|
||||
config file. This file will be overwritten by the next
|
||||
installation, so it's not a good idea to manually modify it.
|
||||
Using the -C +file option is a much better way for user
|
||||
modifications.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
* avrdude.conf.in: Add a warning to not modify the file manually.
|
||||
|
||||
2014-03-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-6.1.
|
||||
|
||||
2014-03-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to 6.1.
|
||||
|
||||
2014-03-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* pgm.c (pgm_free): Cleanup police: destroy the p->usbpid
|
||||
list when freeing the programmer struct.
|
||||
|
||||
2014-03-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #40782: Verify errors for object size > 16 k on x32e5 due
|
||||
to typo in avrdude.conf
|
||||
* avrdude.conf.in (ATmega8E5, ATmega32E5): fix boot location
|
||||
|
||||
2014-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (atmelice, atmelice_pdi, atmelice_dw, atmelice_isp):
|
||||
New entries.
|
||||
* avrdude.1: Document the Atmel-ICE addition.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
* usbdevs.c (USB_DEVICE_ATMEL_ICE): New entry.
|
||||
|
||||
2014-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Bump copyright year.
|
||||
|
||||
2014-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_recv): avoid memmov'ing more data than available
|
||||
|
||||
2014-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Documentation update for EDBG.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2014-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: For EDBG protocol, always use 512-byte block I/O. The
|
||||
lower layers will split this according to the EP's maxsize. This
|
||||
makes it work over USB 1.1 connections (albeit very slowly, due to
|
||||
the interrupt transfers used).
|
||||
|
||||
2014-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Turn the usbpid parameter of the programmer into
|
||||
a list of PIDs. Make the JTAGICE3 programmer handle a list of
|
||||
PIDs, by trying each of them in sequence. Use a single, central
|
||||
jtag3_open_common() function to handle the common code of all
|
||||
jtag3_open_* functions. Centralize all USB VID/PID definitions in
|
||||
usbdevs.h.
|
||||
* flip1.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtag3.h: (Dito.)
|
||||
* flip2.c: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* usbtiny.h: (Dito.)
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* usbasp.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2014-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_open): Replace all calls to exit(1) by
|
||||
return -1
|
||||
|
||||
2014-02-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3_private.h: Add EDBG/CMSIS-DAP specific constants.
|
||||
* jtag3.c: Add EDBG/CMSIS-DAP protocol implementation.
|
||||
* serial.h: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* configure.ac: (Dito.)
|
||||
* avrdude.conf.in: Add JTAGICE3 and XplainedPro entries using
|
||||
EDBG.
|
||||
* configure.ac: Bump version date.
|
||||
|
||||
2014-02-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_recv_frame): Fix a bug where a new recv
|
||||
request was issued even though all desired data had aldready
|
||||
been received.
|
||||
|
||||
2014-02-21 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* serial.h: Change the second parameter of the ser_open method
|
||||
from "baud" into a "union pinfo", so the USB parameters can be
|
||||
passed without hacks.
|
||||
* arduino.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* buspirate.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* jtag3.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
|
||||
2014-01-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
[bug #41402] dfu.c missing include <stdint.h>
|
||||
* dfu.c: include <stdint.h> where uint16_t is defined
|
||||
|
||||
2014-01-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega256RFR2 et al.): Fix EEPROM size.
|
||||
|
||||
2014-01-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
[bug #41357] OS X: Avrdude messes with the usb stack?
|
||||
* usb_libusb.c (usbdev_close): Only issue the usb_reset() for
|
||||
Linux systems, as these are the only ones that seem to require
|
||||
it under some circumstances.
|
||||
|
||||
2014-01-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (libelf): check against elf_getshdrstrndx() rather
|
||||
than just elf_begin() only, so it is clear we found a sufficiently
|
||||
recent libelf to work with.
|
||||
|
||||
2014-01-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Alan Horstmann:
|
||||
bug #40897: AT Mega2560 not correctly programmed with stk500(v1) ISP (solution patch)
|
||||
* stk500.c: Implement extended address byte handling.
|
||||
* avrdude.conf.in (ATmega2560): enable stk500_devcode so
|
||||
STK500v1 protocol actually starts at all.
|
||||
|
||||
2014-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip1.c: Implement the meat of FLIP version 1 protocol.
|
||||
* avrdude.1: Document the new protocol.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2014-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip2.c (flip2_page_erase): Remove unimplemented function.
|
||||
* dfu.h: Correctly conditionalize <usb.h> vs. <lusb0_usb.h>;
|
||||
add adjustable timeout (struct dfu_dev); add dfu_abort()
|
||||
* dfu.c (dfu_abort): New function; implement adjustable timeout.
|
||||
|
||||
2014-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (libhid): Turn from AC_TRY_RUN into
|
||||
AC_TRY_COMPILE, so it also works for cross-compilation
|
||||
setups.
|
||||
|
||||
2014-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* dfu.c (dfu_init): Move the descriptor checks up into the
|
||||
FLIP protocol implementation.
|
||||
* flip2.c (flip2_initialize): (Dito.)
|
||||
* flip1.c (flip1_initialize): (Dito.)
|
||||
|
||||
2014-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip2.c: Rename from flip.c
|
||||
* flip2.h: Rename from flip.h
|
||||
* Makefile.am: Reflect the renaming.
|
||||
* dfu.c: Update information how to get GPL.
|
||||
* dfu.h: (Dito.)
|
||||
|
||||
2014-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip.c (flip2_initialize): Check user is running on an Xmega
|
||||
device.
|
||||
|
||||
2014-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* flip.c: Added some verbose-level messages (-vv)
|
||||
* dfu.c: Added some verbose-level messages (-vvvv)
|
||||
|
||||
2014-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Kirill Levchenko:
|
||||
patch #7896: DFU FLIPv2 programming support
|
||||
* pgm_type.c: Add the flip2 programmer type.
|
||||
* config_gram.y: Allow for the usbid keyword in a device definition.
|
||||
* avrdude.conf.in: Add usbpid values to those Xmega devices where
|
||||
applicable.
|
||||
* avrpart.h: Add usbpid device field.
|
||||
* dfu.c: (New file.)
|
||||
* dfu.h: (New file.)
|
||||
* flip.c: (New file.)
|
||||
* flip.h: (New file.)
|
||||
* Makefile.am: Add new files.
|
||||
* doc/avrdude.texi: Document the changes.
|
||||
* avrdude.1: (Dito.)
|
||||
|
||||
2014-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ChangeLog-2013: Annual changelog rotation.
|
||||
@@ -1,54 +0,0 @@
|
||||
2015-12-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1 (-C): Do not suggest users might change the
|
||||
default config file. It will be overwritten by updates.
|
||||
|
||||
2015-12-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #46610: Floating point exception (core dumped) arch linux rpi2
|
||||
bug #46483: version 6.2. ser_open(): can't set attributes for device
|
||||
* ser_posix.c: Back out change from patch #8380
|
||||
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-release 6.2.
|
||||
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 6.2.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martino Facchin:
|
||||
bug #45727: Wrong atmega8u2 flash parameters
|
||||
* avrdude.conf.in (ATmega8U2): correct page and block size
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46020: Add TIAO TUMPA to the conf file.
|
||||
* avrdude.conf.in (tumpa): New entry.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46021: Please add read in the memory lock section of ATtiny85
|
||||
* avrdude.conf.in (ATtiny25/45/85): add read pattern for lock bits
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (libavrdude_a_SOURCES): reflect recent changes
|
||||
(pgm.h is gone, config.h is new).
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #44717: avrdude creates empty flash dump
|
||||
* update.c (do_op): When about to write an empty flash dump file,
|
||||
warn about this to avoid surprises.
|
||||
* avrdude.1: Document the truncation of trailing 0xFF bytes for
|
||||
flash memory areas.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Annual ChangeLog rotation.
|
||||
@@ -1,206 +0,0 @@
|
||||
#
|
||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
||||
# Copyright (C) 2003, 2004 Theodore A. Roth <troth@openavr.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
EXTRA_DIST = \
|
||||
ChangeLog \
|
||||
ChangeLog-2001 \
|
||||
ChangeLog-2002 \
|
||||
ChangeLog-2003 \
|
||||
ChangeLog-2004-2006 \
|
||||
ChangeLog-2007 \
|
||||
ChangeLog-2008 \
|
||||
ChangeLog-2009 \
|
||||
ChangeLog-2010 \
|
||||
ChangeLog-2011 \
|
||||
ChangeLog-2012 \
|
||||
ChangeLog-2013 \
|
||||
avrdude.1 \
|
||||
avrdude.spec \
|
||||
bootstrap
|
||||
|
||||
CLEANFILES = \
|
||||
config_gram.c \
|
||||
config_gram.h \
|
||||
lexer.c
|
||||
|
||||
BUILT_SOURCES = $(CLEANFILES)
|
||||
|
||||
#SUBDIRS = doc @WINDOWS_DIRS@
|
||||
#DIST_SUBDIRS = doc windows
|
||||
|
||||
# . lets build this directory before the following in SUBDIRS
|
||||
SUBDIRS = .
|
||||
# doc comes here, and we want to use the built avrdude to generate the parts list
|
||||
SUBDIRS += @SUBDIRS_AC@
|
||||
SUBDIRS += @WINDOWS_DIRS@
|
||||
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
|
||||
|
||||
AM_YFLAGS = -d
|
||||
|
||||
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
libavrdude_a_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
libavrdude_la_CPPFLAGS = $(libavrdude_a_CPPFLAGS)
|
||||
|
||||
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
|
||||
libavrdude_la_CFLAGS = $(libavrdude_a_CFLAGS)
|
||||
|
||||
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB_1_0@ @LIBHIDAPI@ @LIBUSB@ @LIBFTDI1@ @LIBFTDI@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ -lm
|
||||
|
||||
bin_PROGRAMS = avrdude
|
||||
|
||||
noinst_LIBRARIES = libavrdude.a
|
||||
lib_LTLIBRARIES = libavrdude.la
|
||||
|
||||
# automake thinks these generated files should be in the distribution,
|
||||
# but this might cause trouble for some users, so we rather don't want
|
||||
# to have them there.
|
||||
#
|
||||
# See
|
||||
#
|
||||
# https://savannah.nongnu.org/bugs/index.php?func=detailitem&item_id=15536
|
||||
#
|
||||
# for why we don't want to have them.
|
||||
dist-hook:
|
||||
rm -f \
|
||||
$(distdir)/lexer.c \
|
||||
$(distdir)/config_gram.c \
|
||||
$(distdir)/config_gram.h
|
||||
|
||||
libavrdude_a_SOURCES = \
|
||||
config_gram.y \
|
||||
lexer.l \
|
||||
arduino.h \
|
||||
arduino.c \
|
||||
avr.c \
|
||||
avr910.c \
|
||||
avr910.h \
|
||||
avrdude.h \
|
||||
avrftdi.c \
|
||||
avrftdi.h \
|
||||
avrftdi_private.h \
|
||||
avrftdi_tpi.c \
|
||||
avrftdi_tpi.h \
|
||||
avrpart.c \
|
||||
bitbang.c \
|
||||
bitbang.h \
|
||||
buspirate.c \
|
||||
buspirate.h \
|
||||
butterfly.c \
|
||||
butterfly.h \
|
||||
config.c \
|
||||
config.h \
|
||||
confwin.c \
|
||||
crc16.c \
|
||||
crc16.h \
|
||||
dfu.c \
|
||||
dfu.h \
|
||||
fileio.c \
|
||||
flip1.c \
|
||||
flip1.h \
|
||||
flip2.c \
|
||||
flip2.h \
|
||||
freebsd_ppi.h \
|
||||
ft245r.c \
|
||||
ft245r.h \
|
||||
jtagmkI.c \
|
||||
jtagmkI.h \
|
||||
jtagmkI_private.h \
|
||||
jtagmkII.c \
|
||||
jtagmkII.h \
|
||||
jtagmkII_private.h \
|
||||
jtag3.c \
|
||||
jtag3.h \
|
||||
jtag3_private.h \
|
||||
libavrdude.h \
|
||||
linuxgpio.c \
|
||||
linuxgpio.h \
|
||||
linux_ppdev.h \
|
||||
lists.c \
|
||||
my_ddk_hidsdi.h \
|
||||
par.c \
|
||||
par.h \
|
||||
pgm.c \
|
||||
pgm_type.c \
|
||||
pickit2.c \
|
||||
pickit2.h \
|
||||
pindefs.c \
|
||||
ppi.c \
|
||||
ppi.h \
|
||||
ppiwin.c \
|
||||
safemode.c \
|
||||
serbb.h \
|
||||
serbb_posix.c \
|
||||
serbb_win32.c \
|
||||
ser_avrdoper.c \
|
||||
ser_posix.c \
|
||||
ser_win32.c \
|
||||
solaris_ecpp.h \
|
||||
stk500.c \
|
||||
stk500.h \
|
||||
stk500_private.h \
|
||||
stk500v2.c \
|
||||
stk500v2.h \
|
||||
stk500v2_private.h \
|
||||
stk500generic.c \
|
||||
stk500generic.h \
|
||||
tpi.h \
|
||||
usbasp.c \
|
||||
usbasp.h \
|
||||
usbdevs.h \
|
||||
usb_hidapi.c \
|
||||
usb_libusb.c \
|
||||
usbtiny.h \
|
||||
usbtiny.c \
|
||||
update.c \
|
||||
wiring.h \
|
||||
wiring.c
|
||||
libavrdude_la_SOURCES = $(libavrdude_a_SOURCES)
|
||||
libavrdude_la_LDFLAGS = -version-info 1:0
|
||||
|
||||
include_HEADERS = libavrdude.h
|
||||
|
||||
avrdude_SOURCES = \
|
||||
main.c \
|
||||
term.c \
|
||||
term.h
|
||||
|
||||
man_MANS = avrdude.1
|
||||
|
||||
sysconf_DATA = avrdude.conf
|
||||
|
||||
install-exec-local: backup-avrdude-conf
|
||||
|
||||
distclean-local:
|
||||
rm -f avrdude.conf
|
||||
|
||||
# This will get run before the config file is installed.
|
||||
backup-avrdude-conf:
|
||||
@echo "Backing up avrdude.conf in ${DESTDIR}${sysconfdir}"
|
||||
@if test -e ${DESTDIR}${sysconfdir}/avrdude.conf; then \
|
||||
cp -pR ${DESTDIR}${sysconfdir}/avrdude.conf \
|
||||
${DESTDIR}${sysconfdir}/avrdude.conf.bak; \
|
||||
fi
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
@@ -1,54 +0,0 @@
|
||||
|
||||
TARGET = avrdude-slic3r
|
||||
|
||||
SOURCES = \
|
||||
arduino.c \
|
||||
avr.c \
|
||||
avrpart.c \
|
||||
avr910.c \
|
||||
bitbang.c \
|
||||
buspirate.c \
|
||||
butterfly.c \
|
||||
config.c \
|
||||
config_gram.c \
|
||||
crc16.c \
|
||||
fileio.c \
|
||||
lexer.c \
|
||||
linuxgpio.c \
|
||||
lists.c \
|
||||
pgm.c \
|
||||
pgm_type.c \
|
||||
pickit2.c \
|
||||
pindefs.c \
|
||||
safemode.c \
|
||||
ser_avrdoper.c \
|
||||
serbb_posix.c \
|
||||
serbb_win32.c \
|
||||
ser_posix.c \
|
||||
ser_win32.c \
|
||||
stk500.c \
|
||||
stk500generic.c \
|
||||
stk500v2.c \
|
||||
term.c \
|
||||
update.c \
|
||||
wiring.c \
|
||||
main.c \
|
||||
main-standalone.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
CFLAGS = -std=c99 -Wall -D_BSD_SOURCE -D_DEFAULT_SOURCE -O3 -DNDEBUG -fPIC
|
||||
LDFLAGS = -lm
|
||||
|
||||
CC = gcc
|
||||
RM = rm
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) -o ./$@ $(OBJECTS) $(LDFLAGS)
|
||||
|
||||
$(OBJECTS): %.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
clean:
|
||||
$(RM) -f $(OBJECTS) $(TARGET)
|
||||
@@ -1,913 +0,0 @@
|
||||
$Id$
|
||||
|
||||
Approximate change log for AVRDUDE by version.
|
||||
|
||||
(For more detailed changes, see the ChangeLog file.)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Current:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- libhidapi support (part of patch #8717)
|
||||
- use libhidapi as (optional) transport for CMSIS-DAP compliant
|
||||
debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG)
|
||||
|
||||
* New devices supported:
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- ehajo-isp (commercial version of USBtiny)
|
||||
|
||||
* Bugfixes:
|
||||
bug #47550: Linux GPIO broken
|
||||
|
||||
* Internals:
|
||||
|
||||
|
||||
Version 6.3:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- Backout of
|
||||
patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
It broke the functionality in too many situations
|
||||
(bug #46610/46483)
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATmega48PB, ATmega88PB, ATmega168PB
|
||||
- ATtiny28 (HVPP-only device)
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- Atmel mEDBG: xplainedmini, xplainedmini_dw
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- bug #46610: Floating point exception (core dumped) arch linux rpi2
|
||||
- bug #46483: version 6.2. ser_open(): can't set attributes for device
|
||||
- patch #8435: Implementing mEDBG CMSIS-DAP protocol
|
||||
- patch #8735: ATtiny28 support in avrdude.conf
|
||||
- patch #8896: Silence cppcheck warnings in 6.2 code
|
||||
- patch #8895: Spelling in 6.2 code
|
||||
|
||||
|
||||
Version 6.2:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- The stk500v2 implementation now uses its own higher-level
|
||||
command implementation for byte-wide access, rather than the
|
||||
historic SPI_MULTI command where all the low-level ISP
|
||||
implementation had to be assembled manually inside AVRDUDE. In
|
||||
addition to the traditional STK500, this implementation is also
|
||||
used by all the more modern Atmel tools (AVRISPmkII, JTAGICEmkII
|
||||
in ISP mode, STK600 in ISP mode).
|
||||
|
||||
- The -B option can be suffixed with "Hz", "kHz", or "MHz", in
|
||||
order to specify a bitclock frequency rather than period.
|
||||
|
||||
- Print part id after signature (patch #8440 )
|
||||
|
||||
- buspirate: Also support "cpufreq" extended parameter
|
||||
in binary mode (patch #8504 )
|
||||
|
||||
- The "-P net:" syntax (forwarding of serial data over TCP) is now
|
||||
also implemented for Win32 systems.
|
||||
|
||||
- Allow for arbitrary serial baudrates under Linux (OSX and *BSD
|
||||
could already handle it).
|
||||
|
||||
|
||||
* New devices supported:
|
||||
- AT90PWM216 (bug #42310: New part description for AT90PWM216)
|
||||
- ATmega32M1 (patch #7694 Add support for the atmega32m1)
|
||||
|
||||
* New programmers supported:
|
||||
- ftdi_syncbb
|
||||
+ uncompatino, ttl232r (FTDI TTL232R-5V with ICSP adapter)
|
||||
(patch #8529 2 more ftdi_syncbb devices)
|
||||
|
||||
* Bugfixes
|
||||
- bug #45727: Wrong atmega8u2 flash parameters
|
||||
- bug #46020: Add TIAO TUMPA to the conf file.
|
||||
- bug #46021: Please add read in the memory lock section of ATtiny85
|
||||
- bug #42337 avrdude.conf updates for UM232H/CM232H
|
||||
- bug #42056: double free or corruption triggered at exit
|
||||
- bug #42158: Linux GPIO - Source Typo
|
||||
- bug #42516 spelling-error-in-binary
|
||||
- patch #8419 fix ftdi_syncbb hang with libftdi 1
|
||||
- bug #43002 usbasp debug output typo
|
||||
- patch #8511 Fix reset on FT245R
|
||||
- bug #40142 Floating point exception on Ubuntu 10.04
|
||||
- bug #22248: Read efuse error (partial fix)
|
||||
- bug #42267: jtag3isp fails to read lock and fuse bytes directly
|
||||
after changing lock byte
|
||||
- bug #41561: AVRDUDE 6.0.1/USBasp doesn't write first bytes of
|
||||
flash page
|
||||
- bug #43078: AVRDUDE crashes after sucessfully reading/writing eeprom
|
||||
- bug #43137: Writing and reading incorrect pages when using jtagicemkI
|
||||
- bug #40870: config nitpick: ATtiny25/45/85 have 1 calibration byte not 2
|
||||
- bug #42908: no external reset at JTAGICE3
|
||||
- patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||
- bug #44717: avrdude creates empty flash dump
|
||||
|
||||
* Internals:
|
||||
- Removing exit calls from config parser
|
||||
- bug #42662 clang warnings under FreeBSD 10.x
|
||||
|
||||
Version 6.1:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
- Atmel EDBG protocol support added (JTAGICE3, XplainedPro, Atmel-ICE)
|
||||
|
||||
* New programmers supported:
|
||||
- Atmel DFU, using FLIP protocol version 1 (AT90USB and ATmega*U* devices),
|
||||
or version 2 (Xmega devices)
|
||||
- Atmel-ICE (ARM/AVR), JTAG, PDI, debugWIRE, ISP modi
|
||||
|
||||
* Bugfixes
|
||||
- bug #40055: AVRDUDE segfaults when writing eeprom
|
||||
- bug #40085: Typo fix in fuses report (for 6.1-svn-20130917)
|
||||
- bug #40782: Verify errors for object size > 16 k on x32e5 due
|
||||
to typo in avrdude.conf
|
||||
- bug #40817: Elf file support (possibly) not working on 6.0.1 windows build
|
||||
- bug #40897: AT Mega2560 not correctly programmed with stk500(v1)
|
||||
ISP (solution patch)
|
||||
- bug #41357: OS X: Avrdude messes with the usb stack?
|
||||
- bug #41402: dfu.c missing include <stdint.h>
|
||||
- patch #7896: DFU FLIPv2 programming support
|
||||
- patch #XXXX: xxx
|
||||
|
||||
* Internals:
|
||||
- (Some) programmers can take a list of USB PIDs now.
|
||||
|
||||
|
||||
Version 6.0:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- Programmer types in configuration file are no longer keywords but
|
||||
specified as string.
|
||||
|
||||
So you need to change 'type = XYZ;' to 'type = "XYZ";' in own
|
||||
config files. (internal: The parser does not need to know all
|
||||
programmer types now, new programmers will update only the table
|
||||
in pgm_type.c.)
|
||||
|
||||
- The erase cycle counter (formerly options -y / -Y) has been
|
||||
removed.
|
||||
|
||||
- Specifying a -U option without a memory type (short form of
|
||||
option argument list) now defaults to "application" memory for
|
||||
Xmega devices, and "flash" for everything else. This ensures
|
||||
the Xmega bootloader is not accidentally touched.
|
||||
|
||||
- For programmers that support it, the default erase method is a
|
||||
page erase now, rather than a chip erase (Xmega only).
|
||||
|
||||
- Keep track of input file contents
|
||||
|
||||
Memory segments are being tracked to remember whether they've
|
||||
been actually read from a file. Only segments that came from a
|
||||
file are being programmed into the device, or considered for
|
||||
verification. This drastically improves handling speed for
|
||||
sparse files (e.g. files that have a second bootloader segment),
|
||||
and it ensures the device contents is actually compared for
|
||||
everything mentioned in the file (even in case the file has
|
||||
large 0xFF blocks).
|
||||
|
||||
- The -U option now accepts ELF files as input files, and extracts
|
||||
the appropriate section contents that matches the requested memory
|
||||
region. To enable this feature, the host system used for the
|
||||
compilation must have a libelf around, including the respective
|
||||
header files (i.e., package "libelf-devel" on many Linux systems).
|
||||
|
||||
- Programmers and parts lists
|
||||
|
||||
They are now sorted at output with '-c ?'/'-p ?'. (patch #7671:
|
||||
Sorting programmers and parts lists for console output)
|
||||
|
||||
Programmers and parts lists in documentation generated from lists
|
||||
mentioned above. (patch #7687: Autogenerating programmers and
|
||||
parts lists for docs)
|
||||
|
||||
Output list of programmer types with '-c ?type', add list to
|
||||
documentation
|
||||
|
||||
- Configuration files now accepts parent parts/programmers, parts
|
||||
starting with '.' (eg. .xmega) are not included in output parts
|
||||
list and can be used as abstract parents
|
||||
|
||||
(bug #34302: Feature request : device configuration with parent classes)
|
||||
(patch #7688: Implement parent programmers feature)
|
||||
|
||||
- Additional config files which are read after default can be
|
||||
specified on command line using '-C +filename'
|
||||
|
||||
(patch #7699 Read additional config files)
|
||||
|
||||
- "Safemode" can now be turned off by default from within a
|
||||
configuration file (like ~/.avrduderc).
|
||||
|
||||
- The new option -l logfile allows to redirect diagnostic messages
|
||||
to a logfile rather than stderr. Useful to record debugging
|
||||
traces, in particular in environments which do not offer
|
||||
shell-style redirection functionality for standard streams.
|
||||
|
||||
- When leaving debugWIRE mode, immediately retry with ISP rather
|
||||
than bailing out completely.
|
||||
|
||||
- The USBasp programmer implementation now supports detailed traces
|
||||
with -vvv, and device communication traces with -vvvv.
|
||||
|
||||
- The "verbose" terminal mode command allows to query or modify the
|
||||
verbosity level.
|
||||
|
||||
* New devices supported:
|
||||
- ATmega48P (patch #7629 add support for atmega48p)
|
||||
- AT90PWM316 (bug #21797: AT90PWM316: New part description)
|
||||
- ATxmega16D4, ATxmega32D4, ATxmega64D4, ATxmega128D4
|
||||
- ATmega256RFR2, ATmega128RFR2, ATmega64RFR2, ATmega2564RFR2,
|
||||
ATmega1284RFR2, ATmega644RFR2
|
||||
- ATtiny1634
|
||||
- ATxmega128A1U, ATxmega128A3U, ATxmega128A4U, ATxmega128B1,
|
||||
ATxmega128B3, ATxmega128C3, ATxmega128D3, ATxmega16A4U,
|
||||
ATxmega16C4, ATxmega192A3U, ATxmega192C3, ATxmega192D3,
|
||||
ATxmega256A3BU, ATxmega256A3U, ATxmega256C3, ATxmega256D3,
|
||||
ATxmega32A4U, ATxmega32C4, ATxmega384C3, ATxmega384D3,
|
||||
ATxmega64A1U, ATxmega64A3U, ATxmega64A4U, ATxmega64B1,
|
||||
ATxmega64B3, ATxmega64C3, ATxmega64D3
|
||||
- ATtiny43U
|
||||
- ATmega406
|
||||
- ATxmega8E5, ATxmega16E5, ATxmega32E5
|
||||
- ATtiny20, ATtiny40
|
||||
|
||||
|
||||
* New programmers supported:
|
||||
- linuxgpio
|
||||
+ any (embedded) Linux system with 4 GPIOs available can be used
|
||||
as a programmer with little or no additional hardware.
|
||||
|
||||
- avrftdi
|
||||
+ o-link (patch #7672 adding support for O-Link (FTDI based
|
||||
JTAG) as programmer)
|
||||
+ 4232h (patch #7715 FT4232H support)
|
||||
- TPI support
|
||||
+ openmoko (bug #37977 Support for Openmoko Debug Board)
|
||||
|
||||
- usbasp
|
||||
+ nibobee (previously specified as '-c usbasp -P nibobee)
|
||||
+ usbasp-clone (same as usbasp but ignores vendor and product
|
||||
string, checks only vid/pid)
|
||||
|
||||
- ftdi_syncbb (new type for synchronous bitbanging with ft232r/ft245r)
|
||||
+ ft245r (FT245R Synchronous BitBang, miso = D1, sck = D0, mosi
|
||||
= D2, reset = D4)
|
||||
+ ft232r (FT232R Synchronous BitBang, miso = RxD, sck = RTS,
|
||||
mosi = TxD, reset = DTR)
|
||||
+ bwmega (BitWizard ftdi_atmega builtin programmer, miso = DSR,
|
||||
sck = DCD, mosi = CTS, reset = RI)
|
||||
+ arduino-ft232r (Arduino: FT232R connected to ISP, miso = CTS
|
||||
X3(1), sck = DSR X3(2), mosi = DCD X3(3), reset = RI X3(4))
|
||||
+ diecimila (alias for arduino-ft232r)
|
||||
|
||||
- pickit2
|
||||
|
||||
- Atmel JTAGICE3
|
||||
|
||||
- buspirate_bb (TPI programming using the BusPirate in bitbang mode)
|
||||
|
||||
* Bugfixes
|
||||
- bug #34027: avrdude AT90S1200 Problem
|
||||
- bug #34518: loading intel hex files > 64k using record-type 4
|
||||
- patch #7667: Minor memory handling fixes
|
||||
- patch #7680: Fixing timeout problem in ser_recv in ser_win32.c
|
||||
- patch #7693: Fix config file atmel URLs (+ URLs in
|
||||
avrdude.texi and avrpart.h)
|
||||
- bug #21663: AT90PWM efuse incorrect, bug #30438: efuse bits
|
||||
written as 0 on at90pwmxx parts
|
||||
- bug #35261: avrftdi uses wrong interface in avrftdi_paged_(write|load)
|
||||
- patch #7437 modifications to Bus Pirate module
|
||||
- patch #7686 Updating buspirate ascii mode to current firmware,
|
||||
use AUX as clock generator, and setting of serial receive
|
||||
timeout
|
||||
- bug #34768 Proposition: Change the name of the AVR32 devices
|
||||
- patch #7718: Merge global data of avrftdi in a private data
|
||||
structure
|
||||
- bug #35208: avrdude 5.11 on freebsd 8.2-STABLE does not reset
|
||||
Arduino Uno properly
|
||||
- bug #34518: loading intel hex files > 64k using record-type 4
|
||||
(Extended Linear Address Record)
|
||||
- bug #34027: avrdude AT90S1200 Problem
|
||||
- bug #30451: Accessing some Xmega memory sections gives not
|
||||
supported error
|
||||
- bug #28744: Can't load bootloader to xmega128a1
|
||||
- bug #29019: pagel/bs2 warning when uploading using stk500 to xmega
|
||||
- bug #30756: When setting SUT to 64ms on XMEGA, avrdude doesn't
|
||||
read device signature
|
||||
- bug #37265: wrong page sizes for XMega64xx in avrdude.conf
|
||||
- bug #37942: Latest SVN can't program in dragon_jtag mode
|
||||
- patch #7876 JTAGICE mkII fails to connect to attiny if debugwire
|
||||
is enabled AND target has a very slow clock
|
||||
- bug #39893: Verification failure with AVRISPmkII and Xmega
|
||||
- bug #38713: Compilation of the documentation breaks with texinfo-5
|
||||
- bug #38023: avrdude doesn't return an error code when attempting
|
||||
to upload an invalid Intel HEX file
|
||||
- bug #39794: warnings when building avrdude 6.0rc1 under CentOS 6.4
|
||||
- bug #35800: Compilation error on certain systems if parport is disabled
|
||||
- bug #38307: Can't write usersig of an xmega256a3
|
||||
- bug #38580: Current svn head, xmega and fuses, all fuses tied to fuse0
|
||||
- bug #39691: Buffer overrun when reading EEPROM byte with JTAGICE3
|
||||
- bug #38951: AVR109 use byte offset instead of word offset
|
||||
- patch #7769: Write flash fails for AVR910 programmers
|
||||
- bug #38732: Support for ATtiny1634
|
||||
- bug #36901: flashing Atmega32U4 EEPROM produces garbage on chip
|
||||
- bug #28344: chip_erase_delay too short for ATmega324P, 644, 644P, and 1284P
|
||||
- bug #34277: avrdude reads wrong byte order if using avr911 (aka butterfly)
|
||||
- bug #35456: The progress bar for STK500V2 programmer is "wrong".
|
||||
- patch #5708: avrdude should make 10 synchronization attempts instead of just one
|
||||
- patch #7606: ATtiny43u support
|
||||
- patch #7657: Add ATmega406 support for avrdude using DRAGON + JTAG
|
||||
- bug #35474: Feature request: print fuse values in safemode output.
|
||||
- patch #7710: usb_libusb: Check VID/PID before opening device
|
||||
- [no-id]: Fix SCK period adjustment for STK500v2
|
||||
- bug #40040: Support for ATtiny20 and ATtiny40
|
||||
|
||||
* Internals:
|
||||
|
||||
- Restructuring and compacting programmer definition part of
|
||||
grammar for config file.
|
||||
- Cleanup of parser code, removing unused definitions/
|
||||
functions. Using yylex_destroy if available.
|
||||
- Fixed some more memory leaks, added cleanup code at program exit
|
||||
(to minimize the number of non-freed memory blocks reported by
|
||||
valgrind)
|
||||
- Fixed some findings reported by cppcheck.
|
||||
|
||||
Version 5.11:
|
||||
|
||||
* New devices supported:
|
||||
- ATmega88P/168P
|
||||
- ATmega8U2/16U2/32U2
|
||||
- ATtiny4313
|
||||
|
||||
* New programmers supported:
|
||||
- TPI programming through bitbang programmers (both, serial
|
||||
and parallel ones)
|
||||
- FT2232 (and relatives) based programmers (MPSSE bitbang mode)
|
||||
- Wiring environment (http://wiring.org.co/)
|
||||
- butterfly-style bootloader of the Mikrokopter.de device
|
||||
|
||||
* Bugfixes
|
||||
|
||||
|
||||
Version 5.10:
|
||||
|
||||
* Bugfixes
|
||||
- bug #28660: Problem with loading intel hex rom files that exceed
|
||||
0x10000 bytes
|
||||
- see ChangeLog for further details
|
||||
|
||||
* New Features
|
||||
- (JTAG ICE / AVR Dragon) apply external reset if JTAG ID could
|
||||
not be read
|
||||
|
||||
Version 5.9:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AVR32A0512 (JTAGMKII only)
|
||||
- ATmega32U4
|
||||
- ATtiny4
|
||||
- ATtiny5
|
||||
- ATtiny9
|
||||
- ATtiny10
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- BusPirate
|
||||
- Arduino
|
||||
- JTAGICEmkII and AVR Dragon in PDI mode (ATxmega devices)
|
||||
- STK600 and AVRISP mkII in TPI mode (ATtiny4/5/9/10)
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- see ChangeLog and ChangeLog-2009 for details
|
||||
|
||||
Version 5.8:
|
||||
|
||||
* Bugfixes; most importantly, fix a serious memory corruption for
|
||||
that JTAG ICE mkII and AVR Dragon in ISP/HVSP/PP mode.
|
||||
|
||||
Version 5.7:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATXMEGA64A1
|
||||
- ATXMEGA192A1
|
||||
- ATXMEGA256A1
|
||||
- ATXMEGA64A3
|
||||
- ATXMEGA128A3
|
||||
- ATXMEGA192A3
|
||||
- ATXMEGA256A3
|
||||
- ATXMEGA256A3B
|
||||
- ATXMEGA16A4
|
||||
- ATXMEGA32A4
|
||||
- ATXMEGA64A4
|
||||
- ATXMEGA128A4
|
||||
|
||||
* Major Xmega fixes for the JTAG ICE mkII (patch #6825)
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.6:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90USB82
|
||||
- AT90USB162
|
||||
- ATtiny88
|
||||
- ATmega328P
|
||||
- ATmega1284P
|
||||
- ATmega128RFA1
|
||||
- ATxmega128A1 rev D
|
||||
- ATxmega128A1
|
||||
- ATxmega256A3
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- AT89ISP cable (patch #6069)
|
||||
- Arduino
|
||||
|
||||
* Add support for the -x option to pass extended parameters to the
|
||||
programmer backend.
|
||||
|
||||
* Add support for JTAG daisy-chains, using the -x daisychain=
|
||||
option.
|
||||
|
||||
* Add support for the Atmel STK600 for "classic" AVRs (AT90, ATtiny,
|
||||
ATmega), using either ISP or high-voltage programming modes.
|
||||
|
||||
* Add support for the -x devcode extended parameter to the avr910
|
||||
programmer, to allow overriding the device code sent to the
|
||||
programmer.
|
||||
|
||||
* Add support for the Crossbow MIB510 programmer (patch #6074, #6542).
|
||||
|
||||
* Add support to bootstrap with GNU autoconf 2.61, and automake 1.10,
|
||||
respectively.
|
||||
|
||||
* Add support for ATxmega128A1 (including the revision D engineering
|
||||
samples) for STK600 and AVRISPmkII tools using PDI
|
||||
|
||||
* The option combination -tF now enters terminal mode even if the
|
||||
device initialization failed, so the user can modify programmer
|
||||
parameters (like Vtarget).
|
||||
|
||||
* Add preliminary support for ATxmega128A1 for the JTAG ICE mkII using
|
||||
JTAG.
|
||||
|
||||
* Add support for direct SPI transfers (bug #25156).
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.5:
|
||||
|
||||
* Add support for the USBtinyISP programmer (patch #6233)
|
||||
|
||||
* Add support for the C2N232I serial bitbang programmer (patch #6121)
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.4:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90PWM2B/AT90PWM3B
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
* Source code rearranged so that the functionality is now built
|
||||
into a libavrdude.a library where main.c is currently the only
|
||||
existing frontend.
|
||||
|
||||
* Implement ATmega256x support for butterfly/avr109.
|
||||
|
||||
Version 5.3.1:
|
||||
|
||||
* Add support for the AVR Dragon (all modes: ISP, JTAG, HVSP, PP,
|
||||
debugWire).
|
||||
|
||||
* Add support for debugWire (both, JTAG ICE mkII, and AVR Dragon).
|
||||
|
||||
* Add support for the AVR Doper USB HID-class programmer.
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.2:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90USB646/647/1286/1287
|
||||
- ATmega2560/2561
|
||||
- ATmega325/3250/645/6450
|
||||
- ATtiny11 (HVSP only device)
|
||||
- ATtiny261/461/861
|
||||
|
||||
* Fixed paged flash write operations for AT90PWMx devices
|
||||
(error in datasheet).
|
||||
|
||||
* Add signature verification.
|
||||
|
||||
* Add high-voltage mode programming for the STK500 (both,
|
||||
parallel, and high-voltage serial programming).
|
||||
|
||||
* Add support for using the JTAG ICE mkII as a generic ISP
|
||||
programmer.
|
||||
|
||||
* Allow for specifying the ISP clock delay as an option for
|
||||
bit-bang programming adapters.
|
||||
|
||||
* Add support for Thomas Fischl's USBasp low-cost USB-attached
|
||||
programmer.
|
||||
|
||||
* The "stk500" programmer type is now implemented as a stub
|
||||
that tries to probe for either "stk500v1" or "stk500v2".
|
||||
|
||||
* Many bugfixes.
|
||||
|
||||
Version 5.1:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATmega640/1280/1281
|
||||
- ATtiny24/44/84
|
||||
|
||||
* JTAG mkII support now works with libusb-win32, too
|
||||
|
||||
* JTAG ICE mkI support has been added
|
||||
|
||||
* Solaris support has been added (including ecpp(7D) parallel-port
|
||||
bit-bang mode)
|
||||
|
||||
|
||||
Version 5.0:
|
||||
|
||||
* Support for JTAGICE MkII device
|
||||
|
||||
* Support for STK500 Version 2 Protocol
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90CAN128
|
||||
- ATmega329x/649x
|
||||
- ATmega164/324/644
|
||||
- AT90PWM2/3,
|
||||
- ATmega164/324/644
|
||||
- ATmega329x/649x
|
||||
- ATtiny25/45/85
|
||||
|
||||
* Support for serial bit-bang adapters: Ponyprog serial, UISP DASA,
|
||||
UISP DASA3.
|
||||
|
||||
* DAPA programmer pinout supported
|
||||
|
||||
* New "safemode" feature where fuse bits are verified before exit
|
||||
and if possible recovered if they have changed. This is intended
|
||||
to protect against changed fuses which were not requested which is
|
||||
reported to sometimes happen due to improper power supply or other
|
||||
reasons.
|
||||
|
||||
* Various fixes for avr910 and butterfly programmers
|
||||
|
||||
* Full support for AVR109 boot loaders (butterfly)
|
||||
|
||||
* Adding -q -q suppresses most terminal output
|
||||
|
||||
|
||||
Version 4.4.0:
|
||||
|
||||
* Native Win32 support: The windows build doesn't need Cygwin
|
||||
anymore. Additionally, the delay timing on windows should be
|
||||
more accurate now.
|
||||
Contributed by Martin Thomas
|
||||
|
||||
* Add support for
|
||||
- ATmega48, ATmega88 (contributed by Galen Seitz)
|
||||
- ATtiny2313 (contributed by Bob Paddock)
|
||||
- ATtiny13 (contributed by Pawel Moll)
|
||||
|
||||
* Added command to change the SCK of STK500-programmers. Now it
|
||||
is possible to program uC with slow oscillator.
|
||||
Contributed by Galen Seitz
|
||||
|
||||
* Baudrate for serial programmers (STK500 and AVR910) is
|
||||
configurable in the config or at the command-line.
|
||||
This way some more tweaked bootloaders and programmers can be used.
|
||||
|
||||
* Deprecated options have been removed.
|
||||
Now the "-U" option must be used.
|
||||
|
||||
* MacOS X now supported by default.
|
||||
|
||||
Version 4.3.0:
|
||||
|
||||
* Added support for "Butterfly" evaluation board.
|
||||
|
||||
* Make cycle-count work with AVR910-programmers.
|
||||
|
||||
* Added "Troubleshooting"-Appendix to the manual.
|
||||
|
||||
* Add ATmega8515 support.
|
||||
Contributed by: Matthias Wei<65>er <matthias@matwei.de>
|
||||
|
||||
* Add ATmega64 support.
|
||||
Contributed by: Erik Christiansen <erik@dd.nec.com.au>
|
||||
|
||||
* Improved polling algorithm to speed up
|
||||
programming of byte oriented parallel programmers.
|
||||
Contributed by: Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>
|
||||
|
||||
* Add "fuse" and "lock" definitions for the AT90S8535.
|
||||
|
||||
* STK500 skips empty pages in paged write resulting in faster downloads
|
||||
when there are empty blocks in between code (such as files that contain
|
||||
application code and bootloader code).
|
||||
|
||||
Version 4.2.0:
|
||||
|
||||
* Add basic support for reading and writing fuses via SPI with avr910
|
||||
programmers. Submitted by
|
||||
Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>.
|
||||
|
||||
* Perform an auto erase before programming if the flash memory is
|
||||
anywhere specified to be written by any of the -U requests. Old
|
||||
style memory specification options (-f, -i, -I, -m, and -o) are
|
||||
deprecated in favor of the new -U options. Auto erase is disabled
|
||||
if any of the old-style options (specifically -i and -o) are
|
||||
specified.
|
||||
|
||||
* Add new -U option for specifying programming operations - allows
|
||||
multiple memory operations on a single command line.
|
||||
|
||||
* New progress reporting, looks nicer and is nicer to wrapper
|
||||
environments such as emacs.
|
||||
|
||||
* Fix long-standing timing (verify) problems on Windows platform.
|
||||
Submitted by Alex Shepherd <ashepherd@wave.co.nz>.
|
||||
|
||||
* Add new file format option - 'm' for "immediate mode." In this
|
||||
case, the filename argument of the -o, -i, or -U options is
|
||||
treated as the data for uploading - useful for specifying fuse
|
||||
bits without having to create a single-byte file for uploading.
|
||||
|
||||
* Add support for displaying and setting the various STK500 operational
|
||||
parameters (Vtarget, Varef, Master clock).
|
||||
|
||||
* Add 'picoweb' programming cable programmer.
|
||||
Contributed by Rune Christensen <rune.christensen@adslhome.dk>.
|
||||
|
||||
* Add support for the sp12 programmer. Submitted by
|
||||
Larry Barello <larryba@barrello.net>.
|
||||
|
||||
|
||||
Version 4.1.0
|
||||
|
||||
* Add support for the Bascom SAMPLE programmer. Submitted by
|
||||
Larry Barello <larryba@barrello.net>.
|
||||
|
||||
* Add support for avr910 type programmers (mcu00100, pavr avr910, etc).
|
||||
|
||||
* Support new devices: ATmega8535, ATtiny26
|
||||
|
||||
|
||||
Version 4.0.0
|
||||
|
||||
* Now support Linux - added by "Theodore A. Roth" <troth@openavr.org>.
|
||||
|
||||
* Now support Windows - added by "Eric B. Weddington" <eric@ecentral.com>.
|
||||
|
||||
* Use 'configure' scripts to tailor the code to the system avrdude
|
||||
is getting ready to be compiled on - added by "Theodore A. Roth"
|
||||
<troth@openavr.org>.
|
||||
|
||||
* Motorola S-Record support - submitted by "Alexey V.Levdikov "
|
||||
<tsar@kemford.com>.
|
||||
|
||||
* Support parallel programming on the STK500. Introduce 'pagel' and
|
||||
'bs2' keywords to the config file for this purpose.
|
||||
|
||||
* Add support for the AT90S2343
|
||||
|
||||
* Add support for the ATmega169
|
||||
|
||||
* Add ability to specify system defaults within the config file
|
||||
(default parallel port, default serial port).
|
||||
|
||||
* Specify the default programmer seperately from the programmer
|
||||
definition. This is now done in the config file using the
|
||||
'default_programmer' keyword.
|
||||
|
||||
* Support a per-user config file (~/.avrduderc) so that one can
|
||||
override system wide defaults if desired.
|
||||
|
||||
* Follow the datasheet more closely for several parts in the "retry"
|
||||
code when entering programming mode fails initially. Introduce
|
||||
'retry_pulse' to the config file for this purpose.
|
||||
|
||||
|
||||
|
||||
Version 3.1.0
|
||||
|
||||
* This change represents a name change only. There is currently an
|
||||
effort to port AVRPROG to other platforms including Linux and
|
||||
Windows. Since Atmel's programmer binary that's included within
|
||||
their AVR Studio software is named AVRPROG.EXE on the Windows OS,
|
||||
there is the chance for confusion if we keep calling this program
|
||||
AVRPROG as well. Up until now the name hasn't really been a
|
||||
problem since there was no chance to confuse 'avrprog' on Unix
|
||||
with Atmel's AVRPROG because Atmel's tools only run on Windows.
|
||||
But with the Unix 'avrprog' possibly being ported to Windows, I
|
||||
felt a name change was the best way to avoid problems.
|
||||
|
||||
So - from this point forward, my FreeBSD Unix program formerly
|
||||
known as AVRPROG will subsequently be known as AVRDUDE (AVR
|
||||
Downloader/UploaDEr).
|
||||
|
||||
This change also represents a time when the AVRDUDE sources move
|
||||
from my own private repository to a public repository. This will
|
||||
give other developers a chance to port AVRDUDE to other platforms
|
||||
and extend its functionality to support additional programming
|
||||
hardware, etc.
|
||||
|
||||
So goodbye AVRPROG, welcome AVRDUDE!
|
||||
|
||||
Version 3.0.0
|
||||
|
||||
* Rewrite parts of the code to make it easy to support other types
|
||||
of programmers besides the directly connected parallel port
|
||||
programmer (PPI).
|
||||
|
||||
* Add support for Atmel's STK500 programmer/development board. The
|
||||
STK500's "paged mode" read/write is supported which makes this
|
||||
programmer very fast. This is sorely needed on parts with large
|
||||
memories such as the ATmega128. My 12K test program burns in
|
||||
about 5 seconds, add another 5 to read it back out for
|
||||
verification.
|
||||
|
||||
|
||||
Version 2.1.5:
|
||||
|
||||
* When getting ready to initiate communications with the AVR device,
|
||||
first pull /RESET low for a short period of time before enabling
|
||||
the buffer chip. This sequence allows the AVR to be reset before
|
||||
the buffer is enabled to avoid a short period of time where the
|
||||
AVR may be driving the programming lines at the same time the
|
||||
programmer tries to. Of course, if a buffer is being used, then
|
||||
the /RESET line from the programmer needs to be directly connected
|
||||
to the AVR /RESET line and not via the buffer chip.
|
||||
|
||||
Feature contributed by Rick C. Petty <rick@KIWI-Computer.com>.
|
||||
|
||||
* When in interactive terminal mode and dumping memory using the
|
||||
'dump <memtype>' command without any address information, and the
|
||||
end of memory is reached, wrap back around to zero on the next
|
||||
invocation.
|
||||
|
||||
|
||||
Version 2.1.4:
|
||||
|
||||
* Fix -Y option.
|
||||
|
||||
|
||||
Version 2.1.3:
|
||||
|
||||
* Be backward compatible when reading 2-byte rewrite cycle counters
|
||||
as written by avrprog version 2.1.0. Version 2.1.1 changed over
|
||||
to a 4-byte counter, which caused avrprog versions 2.1.1 and 2.1.2
|
||||
to report a negative count for parts that were initialized using
|
||||
version 2.1.0. Thanks to Joerg Wunsch for noticing this.
|
||||
|
||||
|
||||
Version 2.1.2:
|
||||
|
||||
* Add '-V' option to disable automatic verify check with uploading
|
||||
data.
|
||||
|
||||
|
||||
Version 2.1.1:
|
||||
|
||||
* Fix ATmega128 instruction sequences for reading fuse bits -
|
||||
contributed by Joerg Wunsch.
|
||||
|
||||
* Modify erase-rewrite cycle counter code to use a 4 byte counter
|
||||
instead of a two byte counter.
|
||||
|
||||
|
||||
Version 2.1.0:
|
||||
|
||||
* Implement a per-part erase-rewrite cycle counter; requires the use
|
||||
of two bytes of EEPROM memory.
|
||||
|
||||
|
||||
Version 2.0.5:
|
||||
|
||||
* Support for ATtiny15 - contributed by Asher Hoskins
|
||||
|
||||
|
||||
Version 2.0.4:
|
||||
|
||||
* Config file fixes for various parts.
|
||||
|
||||
|
||||
Version 2.0.3:
|
||||
|
||||
* Work around problem programming fuse bits on parts like the
|
||||
at90s4433 as described in the following errata:
|
||||
|
||||
http://www.atmel.com/atmel/acrobat/doc1280.pdf
|
||||
|
||||
* Add part definition for at90s4414, at90s4433.
|
||||
|
||||
* Add fuse/lock bit memory instructions for the at90s1200,
|
||||
at90s2333, at90s4433 and at90s8515.
|
||||
|
||||
* Fix setting of programmer status LEDs under certain write-fail
|
||||
conditions.
|
||||
|
||||
|
||||
Version 2.0.2 :
|
||||
|
||||
* Fix writing to read-only memories such as the lock bits of the
|
||||
AT90S2313.
|
||||
|
||||
* Copyright updates.
|
||||
|
||||
|
||||
Version 2.0.1 :
|
||||
|
||||
* Use correct parallel port pins for VCC.
|
||||
|
||||
* Add programmer definition for Atmel's STK200.
|
||||
|
||||
* Add programmer definition for the AVR3 board.
|
||||
|
||||
* Fix address bit encoding for many parts.
|
||||
|
||||
* Allow the ``BUFF'' signal to be asserted by multiple pins of the
|
||||
parallel port (like VCC) instead of just one. The STK200 appears
|
||||
to need this feature.
|
||||
|
||||
|
||||
Version 2.0.0 :
|
||||
|
||||
* Add support for programming fuse and lock bits if supported by the
|
||||
part.
|
||||
|
||||
* Move instruction encoding into the config file. Now any part can
|
||||
be supported as long as it uses the same basic serial programming
|
||||
instruction format.
|
||||
|
||||
* Add part definitions for the ATMega163 and ATMega8 devices.
|
||||
|
||||
|
||||
Version 1.4.3 :
|
||||
|
||||
* Mostly internal code cleanup.
|
||||
|
||||
|
||||
Version 1.4.2 :
|
||||
|
||||
* Fixes for ATMega paged memory support.
|
||||
|
||||
* Support for ATMega16 device.
|
||||
|
||||
|
||||
Version 1.4.1 :
|
||||
|
||||
* No functional changes, update to Copyrights only.
|
||||
|
||||
|
||||
Version 1.4.0 :
|
||||
|
||||
* Add part definitions to the config file.
|
||||
|
||||
* Add initial support for Atmel's ATMega paged memory parts.
|
||||
|
||||
* Config file documentation added.
|
||||
|
||||
* Add a definition for the Dontronics DT006 programmer.
|
||||
|
||||
* Fix Intel Hex support for addresses larger than 64k.
|
||||
|
||||
|
||||
Version 1.3.0 :
|
||||
|
||||
* Make programmer pin assignments configurable.
|
||||
|
||||
|
||||
Version 1.2.2 :
|
||||
|
||||
* Initial public release.
|
||||
@@ -1,64 +0,0 @@
|
||||
THIS IS A QIDI3D BRANCH, WORKING AROUND A SPECIFIC PROBLEM
|
||||
IN THE EARLY I3 MK2 USB COMMUNICATION CHIPS.
|
||||
|
||||
Some of the early QIDI3D i3 MK2 printers were shipped with a buggy
|
||||
USB communication controller firmware. This fork of avrdude contains
|
||||
a workaround inside the stk500v2 protocol implementation.
|
||||
|
||||
The workaround depends on a specific behavior of the Arduino AVR 2560
|
||||
bootloader, which is installed on the i3 MK2 printers:
|
||||
|
||||
https://github.com/arduino/Arduino-stk500v2-bootloader
|
||||
|
||||
The avrdude binary modified by QIDI3D could replace the avrdude bianary
|
||||
of arduino to program the RAMBo board. In that case the modified binary
|
||||
is identified by a "-qidi3d" suffix to the version information.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
See the documentation file for the details.
|
||||
|
||||
The latest version of AVRDUDE is always available here:
|
||||
|
||||
http://savannah.nongnu.org/projects/avrdude
|
||||
|
||||
|
||||
Important environment variables for ./configure:
|
||||
================================================
|
||||
|
||||
CPPFLAGS: C preprocessor flags (*not* "C++")
|
||||
|
||||
This is the place to put additional (non-standard) -I options into.
|
||||
For example, if your Windows system has LibUSB-Win32 installed into
|
||||
\\WINDOWS\ProgramFiles\LibUSB-Win32, use
|
||||
|
||||
CPPFLAGS=-I/WINDOWS/ProgramFiles/LibUSB-Win32/include
|
||||
|
||||
to tell configure where to search for the header files. (The use of
|
||||
forward slashes rather than backslashes can often simplify things.
|
||||
Note that the Windows system services internally treat both the same.
|
||||
It's only cmd.exe which requires backslashes as the directory
|
||||
separator.)
|
||||
|
||||
LDFLAGS: Linker options
|
||||
|
||||
This is the place to make additional library locations known to the
|
||||
linker. To continue the above example, use
|
||||
|
||||
LDFLAGS=-L/WINDOWS/ProgramFiles/LibUSB-Win32/lib/gcc
|
||||
|
||||
to make the linker search for "libusb.a" in that directory.
|
||||
|
||||
|
||||
Linux users: make sure the header files are installed
|
||||
=====================================================
|
||||
|
||||
While many Linux distributions install the libraries needed by AVRDUDE
|
||||
(libusb, libelf) by default, they leave out the corresponding header
|
||||
files. Consequently, the configure script won't find them, so these
|
||||
libraries could not be used.
|
||||
|
||||
Usually, the packages with the header files (and static libraries) are
|
||||
derived from the regular package name by appending "-devel". Thus,
|
||||
make sure you have "libusb-devel" and "libelf-devel" installed before
|
||||
running the configure script. (Same goes for libftdi.)
|
||||
@@ -1,206 +0,0 @@
|
||||
/* ac_cfg.h. Generated from ac_cfg.h.in by configure. */
|
||||
/* ac_cfg.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
|
||||
// Edited by hand for usage with Slic3r PE
|
||||
|
||||
#define CONFIG_DIR "CONFIG_DIR"
|
||||
|
||||
|
||||
/* Define to 1 if you have the <ddk/hidsdi.h> header file. */
|
||||
/* #undef HAVE_DDK_HIDSDI_H */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#if defined (WIN32NATIVE)
|
||||
/* #undef HAVE_GETTIMEOFDAY */
|
||||
// We have a gettimeofday() replacement in unistd.cpp (there is also one in ppiwin.c, but that file is written for Cygwin/MinGW)
|
||||
#else
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <hidapi/hidapi.h> header file. */
|
||||
/* #undef HAVE_HIDAPI_HIDAPI_H */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define if ELF support is enabled via libelf */
|
||||
// #define HAVE_LIBELF 1
|
||||
|
||||
/* Define to 1 if you have the <libelf.h> header file. */
|
||||
// #define HAVE_LIBELF_H 1
|
||||
|
||||
/* Define to 1 if you have the <libelf/libelf.h> header file. */
|
||||
/* #undef HAVE_LIBELF_LIBELF_H */
|
||||
|
||||
/* Define if FTDI support is enabled via libftdi */
|
||||
/* #undef HAVE_LIBFTDI */
|
||||
|
||||
/* Define if FTDI support is enabled via libftdi1 */
|
||||
// #define HAVE_LIBFTDI1 1
|
||||
|
||||
/* Define if libftdi supports FT232H, libftdi version >= 0.20 */
|
||||
/* #undef HAVE_LIBFTDI_TYPE_232H */
|
||||
|
||||
/* Define if HID support is enabled via the Win32 DDK */
|
||||
/* #undef HAVE_LIBHID */
|
||||
|
||||
/* Define if HID support is enabled via libhidapi */
|
||||
/* #undef HAVE_LIBHIDAPI */
|
||||
|
||||
/* Define to 1 if you have the `ncurses' library (-lncurses). */
|
||||
// #define HAVE_LIBNCURSES 1
|
||||
|
||||
/* Define to 1 if you have the `readline' library (-lreadline). */
|
||||
// #define HAVE_LIBREADLINE 1
|
||||
|
||||
/* Define to 1 if you have the `termcap' library (-ltermcap). */
|
||||
/* #undef HAVE_LIBTERMCAP */
|
||||
|
||||
/* Define if USB support is enabled via libusb */
|
||||
// #define HAVE_LIBUSB 1
|
||||
|
||||
/* Define if USB support is enabled via a libusb-1.0 compatible libusb */
|
||||
// #define HAVE_LIBUSB_1_0 1
|
||||
|
||||
/* Define to 1 if you have the <libusb-1.0/libusb.h> header file. */
|
||||
// #define HAVE_LIBUSB_1_0_LIBUSB_H 1
|
||||
|
||||
/* Define to 1 if you have the <libusb.h> header file. */
|
||||
/* #undef HAVE_LIBUSB_H */
|
||||
|
||||
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
|
||||
/* #undef HAVE_LIBWS2_32 */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Linux sysfs GPIO support enabled */
|
||||
/* #undef HAVE_LINUXGPIO */
|
||||
|
||||
/* Define to 1 if you have the <lusb0_usb.h> header file. */
|
||||
/* #undef HAVE_LUSB0_USB_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* parallel port access enabled */
|
||||
// #define HAVE_PARPORT 1
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
// #define HAVE_PTHREAD_H 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#define HAVE_STRTOUL 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint_t'. */
|
||||
/* #undef HAVE_UINT_T */
|
||||
|
||||
/* Define to 1 if the system has the type `ulong_t'. */
|
||||
/* #undef HAVE_ULONG_T */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the <usb.h> header file. */
|
||||
#define HAVE_USB_H 1
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#define HAVE_USLEEP 1
|
||||
|
||||
/* Define if lex/flex has yylex_destroy */
|
||||
#define HAVE_YYLEX_DESTROY 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "avrdude-slic3r"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "https://github.com/QIDITECH/QIDISlicer/issues"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "avrdude-slic3r"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "avrdude 6.3-20160220"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "avrdude-slic3r"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "https://github.com/QIDITECH/QIDISlicer"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "6.3-20160220"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "6.3-20160220"
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#define YYTEXT_POINTER 1
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
@@ -1,194 +0,0 @@
|
||||
/* ac_cfg.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <ddk/hidsdi.h> header file. */
|
||||
#undef HAVE_DDK_HIDSDI_H
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define to 1 if you have the <hidapi/hidapi.h> header file. */
|
||||
#undef HAVE_HIDAPI_HIDAPI_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define if ELF support is enabled via libelf */
|
||||
#undef HAVE_LIBELF
|
||||
|
||||
/* Define to 1 if you have the <libelf.h> header file. */
|
||||
#undef HAVE_LIBELF_H
|
||||
|
||||
/* Define to 1 if you have the <libelf/libelf.h> header file. */
|
||||
#undef HAVE_LIBELF_LIBELF_H
|
||||
|
||||
/* Define if FTDI support is enabled via libftdi */
|
||||
#undef HAVE_LIBFTDI
|
||||
|
||||
/* Define if FTDI support is enabled via libftdi1 */
|
||||
#undef HAVE_LIBFTDI1
|
||||
|
||||
/* Define if libftdi supports FT232H, libftdi version >= 0.20 */
|
||||
#undef HAVE_LIBFTDI_TYPE_232H
|
||||
|
||||
/* Define if HID support is enabled via the Win32 DDK */
|
||||
#undef HAVE_LIBHID
|
||||
|
||||
/* Define if HID support is enabled via libhidapi */
|
||||
#undef HAVE_LIBHIDAPI
|
||||
|
||||
/* Define to 1 if you have the `ncurses' library (-lncurses). */
|
||||
#undef HAVE_LIBNCURSES
|
||||
|
||||
/* Define to 1 if you have the `readline' library (-lreadline). */
|
||||
#undef HAVE_LIBREADLINE
|
||||
|
||||
/* Define to 1 if you have the `termcap' library (-ltermcap). */
|
||||
#undef HAVE_LIBTERMCAP
|
||||
|
||||
/* Define if USB support is enabled via libusb */
|
||||
#undef HAVE_LIBUSB
|
||||
|
||||
/* Define if USB support is enabled via a libusb-1.0 compatible libusb */
|
||||
#undef HAVE_LIBUSB_1_0
|
||||
|
||||
/* Define to 1 if you have the <libusb-1.0/libusb.h> header file. */
|
||||
#undef HAVE_LIBUSB_1_0_LIBUSB_H
|
||||
|
||||
/* Define to 1 if you have the <libusb.h> header file. */
|
||||
#undef HAVE_LIBUSB_H
|
||||
|
||||
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
|
||||
#undef HAVE_LIBWS2_32
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Linux sysfs GPIO support enabled */
|
||||
#undef HAVE_LINUXGPIO
|
||||
|
||||
/* Define to 1 if you have the <lusb0_usb.h> header file. */
|
||||
#undef HAVE_LUSB0_USB_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#undef HAVE_MEMSET
|
||||
|
||||
/* parallel port access enabled */
|
||||
#undef HAVE_PARPORT
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#undef HAVE_PTHREAD_H
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#undef HAVE_SELECT
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#undef HAVE_STRNCASECMP
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#undef HAVE_STRTOL
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#undef HAVE_STRTOUL
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#undef HAVE_TERMIOS_H
|
||||
|
||||
/* Define to 1 if the system has the type `uint_t'. */
|
||||
#undef HAVE_UINT_T
|
||||
|
||||
/* Define to 1 if the system has the type `ulong_t'. */
|
||||
#undef HAVE_ULONG_T
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the <usb.h> header file. */
|
||||
#undef HAVE_USB_H
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#undef HAVE_USLEEP
|
||||
|
||||
/* Define if lex/flex has yylex_destroy */
|
||||
#undef HAVE_YYLEX_DESTROY
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2009 Lars Immisch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for Arduino programmer
|
||||
*
|
||||
* The Arduino programmer is mostly a STK500v1, just the signature bytes
|
||||
* are read differently.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
#include "stk500_private.h"
|
||||
#include "stk500.h"
|
||||
#include "arduino.h"
|
||||
|
||||
/* read signature bytes - arduino version */
|
||||
static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
(void)p;
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
|
||||
if (m->size < 3) {
|
||||
avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = Cmnd_STK_READ_SIGN;
|
||||
buf[1] = Sync_CRC_EOP;
|
||||
|
||||
serial_send(&pgm->fd, buf, 2);
|
||||
|
||||
if (serial_recv(&pgm->fd, buf, 5) < 0)
|
||||
return -1;
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
avrdude_message(MSG_INFO, "%s: stk500_cmd(): programmer is out of sync\n",
|
||||
progname);
|
||||
return -1;
|
||||
} else if (buf[0] != Resp_STK_INSYNC) {
|
||||
avrdude_message(MSG_INFO, "\n%s: arduino_read_sig_bytes(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_INSYNC, buf[0]);
|
||||
return -2;
|
||||
}
|
||||
if (buf[4] != Resp_STK_OK) {
|
||||
avrdude_message(MSG_INFO, "\n%s: arduino_read_sig_bytes(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_OK, buf[4]);
|
||||
return -3;
|
||||
}
|
||||
|
||||
m->buf[0] = buf[1];
|
||||
m->buf[1] = buf[2];
|
||||
m->buf[2] = buf[3];
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int qidi_init_external_flash(PROGRAMMER * pgm)
|
||||
{
|
||||
// Note: send/receive as in _the firmare_ send & receives
|
||||
const char entry_magic_send[] = "start\n";
|
||||
const unsigned char entry_magic_receive[] = "w25x20cl_enter\n";
|
||||
const char entry_magic_cfm[] = "w25x20cl_cfm\n";
|
||||
const size_t buffer_len = 32; // Should be large enough for the above messages
|
||||
|
||||
int res;
|
||||
size_t recv_size;
|
||||
char *buffer = alloca(buffer_len);
|
||||
|
||||
// 1. receive the "start" command
|
||||
recv_size = sizeof(entry_magic_send) - 1;
|
||||
res = serial_recv(&pgm->fd, (unsigned char *)buffer, recv_size);
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: qidi_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
|
||||
return -1;
|
||||
} else if (strncmp(buffer, entry_magic_send, recv_size) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: qidi_init_external_flash(): MK3 printer emitted incorrect start code: `%*s`\n", progname, recv_size, buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. Send the external flash programmer enter command
|
||||
if (serial_send(&pgm->fd, entry_magic_receive, sizeof(entry_magic_receive) - 1) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: qidi_init_external_flash(): Failed to send command to the printer\n",progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 3. Receive the entry confirmation command
|
||||
recv_size = sizeof(entry_magic_cfm) - 1;
|
||||
res = serial_recv(&pgm->fd, (unsigned char *)buffer, recv_size);
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: qidi_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
|
||||
return -1;
|
||||
} else if (strncmp(buffer, entry_magic_cfm, recv_size) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: qidi_init_external_flash(): MK3 printer emitted incorrect cfm code: `%*s`\n", progname, recv_size, buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arduino_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
union pinfo pinfo;
|
||||
strcpy(pgm->port, port);
|
||||
pinfo.baud = pgm->baudrate? pgm->baudrate: 115200;
|
||||
if (serial_open(port, pinfo, &pgm->fd)==-1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clear DTR and RTS to unload the RESET capacitor
|
||||
* (for example in Arduino) */
|
||||
serial_set_dtr_rts(&pgm->fd, 0);
|
||||
usleep(250*1000);
|
||||
/* Set DTR and RTS back to high */
|
||||
serial_set_dtr_rts(&pgm->fd, 1);
|
||||
usleep(50*1000);
|
||||
|
||||
// Sometimes there may be line noise generating input on the printer's USB-to-serial IC
|
||||
// Here we try to clean its input buffer with a sequence of newlines (a minimum of 9 is needed):
|
||||
const unsigned char cleanup_newlines[] = "\n\n\n\n\n\n\n\n\n\n";
|
||||
if (serial_send(&pgm->fd, cleanup_newlines, sizeof(cleanup_newlines) - 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
stk500_drain(pgm, 0);
|
||||
|
||||
// Initialization sequence for programming the external FLASH on the QIDI MK3
|
||||
if (qidi_init_external_flash(pgm) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: arduino_open(): Failed to initialize MK3 external flash programming mode\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stk500_getsync(pgm) < 0) {
|
||||
serial_close(&pgm->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void arduino_close(PROGRAMMER * pgm)
|
||||
{
|
||||
serial_set_dtr_rts(&pgm->fd, 0);
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
}
|
||||
|
||||
const char arduino_desc[] = "Arduino programmer";
|
||||
|
||||
void arduino_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
/* This is mostly a STK500; just the signature is read
|
||||
differently than on real STK500v1
|
||||
and the DTR signal is set when opening the serial port
|
||||
for the Auto-Reset feature */
|
||||
stk500_initpgm(pgm);
|
||||
|
||||
strcpy(pgm->type, "Arduino");
|
||||
pgm->read_sig_bytes = arduino_read_sig_bytes;
|
||||
pgm->open = arduino_open;
|
||||
pgm->close = arduino_close;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2009 Lars Immisch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef arduino_h__
|
||||
#define arduino_h__
|
||||
|
||||
extern const char arduino_desc[];
|
||||
void arduino_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
var BrowserDetect = {
|
||||
init: function () {
|
||||
this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
|
||||
this.version = this.searchVersion(navigator.userAgent)
|
||||
|| this.searchVersion(navigator.appVersion)
|
||||
|| "an unknown version";
|
||||
this.OS = this.searchString(this.dataOS) || "an unknown OS";
|
||||
},
|
||||
searchString: function (data) {
|
||||
for (var i=0;i<data.length;i++) {
|
||||
var dataString = data[i].string;
|
||||
var dataProp = data[i].prop;
|
||||
this.versionSearchString = data[i].versionSearch || data[i].identity;
|
||||
if (dataString) {
|
||||
if (dataString.indexOf(data[i].subString) != -1)
|
||||
return data[i].identity;
|
||||
}
|
||||
else if (dataProp)
|
||||
return data[i].identity;
|
||||
}
|
||||
},
|
||||
searchVersion: function (dataString) {
|
||||
var index = dataString.indexOf(this.versionSearchString);
|
||||
if (index == -1) return;
|
||||
return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
|
||||
},
|
||||
dataBrowser: [
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "Chrome",
|
||||
identity: "Chrome"
|
||||
},
|
||||
{ string: navigator.userAgent,
|
||||
subString: "OmniWeb",
|
||||
versionSearch: "OmniWeb/",
|
||||
identity: "OmniWeb"
|
||||
},
|
||||
{
|
||||
string: navigator.vendor,
|
||||
subString: "Apple",
|
||||
identity: "Safari",
|
||||
versionSearch: "Version"
|
||||
},
|
||||
{
|
||||
prop: window.opera,
|
||||
identity: "Opera"
|
||||
},
|
||||
{
|
||||
string: navigator.vendor,
|
||||
subString: "iCab",
|
||||
identity: "iCab"
|
||||
},
|
||||
{
|
||||
string: navigator.vendor,
|
||||
subString: "KDE",
|
||||
identity: "Konqueror"
|
||||
},
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "Firefox",
|
||||
identity: "Firefox"
|
||||
},
|
||||
{
|
||||
string: navigator.vendor,
|
||||
subString: "Camino",
|
||||
identity: "Camino"
|
||||
},
|
||||
{ // for newer Netscapes (6+)
|
||||
string: navigator.userAgent,
|
||||
subString: "Netscape",
|
||||
identity: "Netscape"
|
||||
},
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "MSIE",
|
||||
identity: "Explorer",
|
||||
versionSearch: "MSIE"
|
||||
},
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "Gecko",
|
||||
identity: "Mozilla",
|
||||
versionSearch: "rv"
|
||||
},
|
||||
{ // for older Netscapes (4-)
|
||||
string: navigator.userAgent,
|
||||
subString: "Mozilla",
|
||||
identity: "Netscape",
|
||||
versionSearch: "Mozilla"
|
||||
}
|
||||
],
|
||||
dataOS : [
|
||||
{
|
||||
string: navigator.platform,
|
||||
subString: "Win",
|
||||
identity: "Windows"
|
||||
},
|
||||
{
|
||||
string: navigator.platform,
|
||||
subString: "Mac",
|
||||
identity: "Mac"
|
||||
},
|
||||
{
|
||||
string: navigator.userAgent,
|
||||
subString: "iPhone",
|
||||
identity: "iPhone/iPod"
|
||||
},
|
||||
{
|
||||
string: navigator.platform,
|
||||
subString: "Linux",
|
||||
identity: "Linux"
|
||||
}
|
||||
]
|
||||
|
||||
};
|
||||
BrowserDetect.init();
|
||||
@@ -1,227 +0,0 @@
|
||||
|
||||
/* RESETS */
|
||||
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, tt, var,b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { /* */
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
body { font: 12px Verdana, Geneva, sans-serif; }
|
||||
|
||||
@font-face {
|
||||
font-family: DroidSansMono;
|
||||
src: url("../fonts/DroidSansMono.eot") /* EOT file for IE */
|
||||
}
|
||||
@font-face {
|
||||
font-family: DroidSansMono;
|
||||
src: url("../fonts/DroidSansMono.ttf") /* TTF file for CSS3 browsers */
|
||||
}
|
||||
|
||||
p, ul, ol, li { font: 10pt Verdana, Geneva, sans-serif; }
|
||||
h1 { font: bold 15pt IntervalLight, sans-serif; }
|
||||
h2 { font: bold 14pt IntervalLight, sans-serif; }
|
||||
|
||||
h1, h2, h3 { color: #444;}
|
||||
h4, h5, h6 { color: #444;}
|
||||
h3, h4, h5, h6 {padding:10px 0px 2px 4px;}
|
||||
|
||||
.book h1, .chapter h2, .section h2 {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 18px;
|
||||
margin-bottom: 6px;
|
||||
border-bottom: 1px #CCC solid;
|
||||
}
|
||||
|
||||
|
||||
p {
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
color: #444;
|
||||
/*width: 100%; Removing width so it's not fixed or floated */
|
||||
padding: 0px 10px 10px 5px; /* changed padding-right from 5 to 10 and padding-left from 10px to 5px */
|
||||
*padding: 5px 5px 10px 0px; /* IE7 hack */
|
||||
}
|
||||
|
||||
/* Page layout */
|
||||
div#content
|
||||
{
|
||||
padding: 1em 2em 1em 2em;
|
||||
}
|
||||
|
||||
.navfooter
|
||||
{
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.navfooter table td
|
||||
{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.mediaobject img
|
||||
{
|
||||
margin: 0.5em 0.5em 0.5em 0.5em;
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.mediaobject img[align="left"]
|
||||
{
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
.informalfigure { margin: 6px; }
|
||||
|
||||
/* "Layout" tables should not have borders */
|
||||
#content table, #content table td { border: none; }
|
||||
|
||||
/* Generic tables */
|
||||
#content .table table th, #content .informaltable table th { background-color: #585858 }
|
||||
#content .table table, #content .informaltable table
|
||||
{
|
||||
border-collapse:collapse;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#content .table tr:nth-child(odd), #content .informaltable tr:nth-child(odd)
|
||||
{
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
#content .table tr:nth-child(even), #content .informaltable tr:nth-child(even)
|
||||
{
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
|
||||
#content .table table td, #content .informaltable table td,
|
||||
#content .table table th, #content .informaltable table th
|
||||
{
|
||||
border: 1px solid #A7A9AB;
|
||||
}
|
||||
|
||||
#content .footnotes tr td
|
||||
{
|
||||
background-color:white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
/* Admonitions */
|
||||
div.note, div.caution, div.important, div.tip, div.warning
|
||||
{
|
||||
border: solid 1px #AAA;
|
||||
background: #ededed;
|
||||
padding: 0.5em 1em 0.5em 1em;
|
||||
margin: 1em 0em 1em 0em;
|
||||
}
|
||||
|
||||
div.note *, div.caution *, div.important *, div.tip *, div.warning * {
|
||||
background: inherit !important;
|
||||
color: inherit !important;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
/* Program listing */
|
||||
.programlisting
|
||||
{
|
||||
/*width: auto;*/
|
||||
border: solid 1px #AAA;
|
||||
background: #ededed;
|
||||
padding: 1em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
overflow:hidden;
|
||||
font-family: DroidSansMono, Consolas
|
||||
}
|
||||
|
||||
|
||||
/* Lists */
|
||||
ul
|
||||
{
|
||||
list-style: square outside;
|
||||
margin: 0 0 0 1em;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
ul.square
|
||||
{
|
||||
list-style: square outside;
|
||||
margin: 0 0 0 1em;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
ul.circle, ul[type=disk]
|
||||
{
|
||||
list-style: disc outside;
|
||||
margin: 0 0 0 1em;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
ol
|
||||
{
|
||||
list-style-type: decimal;
|
||||
list-style: decimal;
|
||||
margin: 0 0 0 2.8em;
|
||||
padding: 0 0 1em 0;
|
||||
}
|
||||
li
|
||||
{
|
||||
padding-bottom: .3em;
|
||||
/*list-style: square;*/
|
||||
}
|
||||
li p
|
||||
{
|
||||
margin: 0 0 .25em 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
ul ul.circle
|
||||
{
|
||||
margin-top: .3em;
|
||||
}
|
||||
ul ul.square
|
||||
{
|
||||
margin-top: .3em;
|
||||
}
|
||||
|
||||
ul, ol { margin-left: 3em; }
|
||||
/*
|
||||
dl dt { padding: 0px 10px 0px 5px;}
|
||||
*/
|
||||
div.orderedlist-collapsed
|
||||
{
|
||||
margin: 1em 0 0 1em;
|
||||
padding: 0 0 1em 0;
|
||||
font-size:smaller;
|
||||
}
|
||||
|
||||
div.orderedlist-collapsed span.listitem
|
||||
{
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.variablelist dt
|
||||
{
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
dl.toc
|
||||
{
|
||||
margin-left: 2em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.guibutton, .guimenu, .guimenuitem, .guisubmenu
|
||||
{
|
||||
font-family: Arial, Verdana, Geneva, sans-serif;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.disclaimer
|
||||
{
|
||||
font-size: 6pt;
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
Variable Grid System (Fluid Version).
|
||||
Learn more ~ http://www.spry-soft.com/grids/
|
||||
Based on 960 Grid System - http://960.gs/ & 960 Fluid - http://www.designinfluences.com/
|
||||
|
||||
Licensed under GPL and MIT.
|
||||
*/
|
||||
|
||||
|
||||
/* Containers
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
.container_3 {
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
}
|
||||
|
||||
/* Grid >> Global
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.grid_1,
|
||||
.grid_2,
|
||||
.grid_3 {
|
||||
display:inline;
|
||||
float: left;
|
||||
position: relative;
|
||||
margin-left: 1%;
|
||||
margin-right: 1%;
|
||||
}
|
||||
|
||||
/* Grid >> Children (Alpha ~ First, Omega ~ Last)
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.alpha {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.omega {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
/* Grid >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .grid_1 {
|
||||
width:31.333%;
|
||||
}
|
||||
|
||||
.container_3 .grid_2 {
|
||||
width:64.667%;
|
||||
}
|
||||
|
||||
.container_3 .grid_3 {
|
||||
width:98.0%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Prefix Extra Space >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .prefix_1 {
|
||||
padding-left:33.333%;
|
||||
}
|
||||
|
||||
.container_3 .prefix_2 {
|
||||
padding-left:66.667%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Suffix Extra Space >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .suffix_1 {
|
||||
padding-right:33.333%;
|
||||
}
|
||||
|
||||
.container_3 .suffix_2 {
|
||||
padding-right:66.667%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Push Space >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .push_1 {
|
||||
left:33.333%;
|
||||
}
|
||||
|
||||
.container_3 .push_2 {
|
||||
left:66.667%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Pull Space >> 3 Columns
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
.container_3 .pull_1 {
|
||||
left:-33.333%;
|
||||
}
|
||||
|
||||
.container_3 .pull_2 {
|
||||
left:-66.667%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Clear Floated Elements
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* http://sonspring.com/journal/clearing-floats */
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* http://perishablepress.com/press/2008/02/05/lessons-learned-concerning-the-clearfix-css-hack */
|
||||
|
||||
.clearfix:after {
|
||||
clear: both;
|
||||
content: ' ';
|
||||
display: block;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
* html .clearfix {
|
||||
height: 1%;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
display: block;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
body {
|
||||
font-size: 12px;
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
}
|
||||
|
||||
.a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 31px 0 0 0;
|
||||
}
|
||||
|
||||
.group
|
||||
{
|
||||
/*background-color: pink;*/
|
||||
width:966px;
|
||||
}
|
||||
|
||||
.group_header {
|
||||
color: #0066CB;
|
||||
font: bold 14pt IntervalLight, sans-serif;
|
||||
text-decoration: none;
|
||||
padding: 8px;
|
||||
background-color: #EEEEEE;
|
||||
margin-top: 24px;
|
||||
/*margin-bottom: 8px;*/
|
||||
}
|
||||
|
||||
.products
|
||||
{
|
||||
float:left;
|
||||
/*background:#FFF8F8;*/
|
||||
}
|
||||
|
||||
.product {
|
||||
/*background: url("../images/panelbg.png") 0 0 no-repeat;*/
|
||||
width: 300px;
|
||||
height: 130px;
|
||||
/*margin-left: 20px;*/
|
||||
padding: 10px;
|
||||
border: 1px solid #EEEEEE;
|
||||
display:block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.product span {
|
||||
font-size: 16px;
|
||||
color: #0066CB;
|
||||
margin-bottom: 8px;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.product img
|
||||
{
|
||||
margin-right:12px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
@@ -1,493 +0,0 @@
|
||||
tr th .added { color: #E6E6FA; }
|
||||
tr th .changed {color: #99ff99; }
|
||||
div.added tr, div.added { background-color: #E6E6FA; }
|
||||
div.deleted tr, div.deleted { text-decoration: line-through;
|
||||
background-color: #FF7F7F; }
|
||||
div.changed tr, div.changed { background-color: #99ff99; }
|
||||
div.off { }
|
||||
|
||||
span.added { background-color: #E6E6FA; }
|
||||
span.deleted { text-decoration: line-through;
|
||||
background-color: #FF7F7F; }
|
||||
span.changed { background-color: #99ff99; }
|
||||
span.off { }
|
||||
|
||||
|
||||
body { font: 12px Verdana, Geneva, sans-serif; }
|
||||
p, ul, ol, li { font: 10pt Verdana, Geneva, sans-serif; }
|
||||
h1 { font: 15pt Arial, Helvetica, geneva;
|
||||
color: black!important;
|
||||
}
|
||||
h2 { font: normal 12pt Arial, Helvetica, geneva; }
|
||||
|
||||
#header {
|
||||
background: white;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 99px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: auto;
|
||||
left: 0;
|
||||
border-bottom: 1px solid #bbc4c5;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin-left: 310px;
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: -15px;
|
||||
color: #404040 !important;
|
||||
}
|
||||
|
||||
|
||||
#header h1 {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
|
||||
p.breadcrumbs {
|
||||
margin-top: 30px;
|
||||
margin-left: 310px;
|
||||
}
|
||||
|
||||
#header img {
|
||||
float: left;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
#header p.breadcrumbs a {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
#leftnavigation {
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
height: auto;
|
||||
top:100px;
|
||||
/*right:10px;*/
|
||||
/*left:10px;*/
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width:inherit;
|
||||
z-index: 1500;
|
||||
border-right:2px solid #bbc4c5;
|
||||
padding:1px;
|
||||
background-color: #ededed!important;
|
||||
}
|
||||
|
||||
#treeDiv {
|
||||
overflow: auto;
|
||||
/* position: fixed;*/
|
||||
height: auto;
|
||||
top: 136px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
/* width: 18%;*/
|
||||
z-index: 1500;
|
||||
/* border-right:2px solid #CCCCCC;
|
||||
background-color: #f0f0f0!important;*/
|
||||
}
|
||||
|
||||
/*#searchDiv {
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
height: auto;
|
||||
top: 138px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 243px;
|
||||
z-index: 1500;
|
||||
border-right:2px solid #CCCCCC;
|
||||
background-color: #f0f0f0!important;
|
||||
}*/
|
||||
|
||||
#content {
|
||||
position: relative;
|
||||
top: 90px; /*left: 240px;*/
|
||||
right: auto; bottom: 20px;
|
||||
/*margin: 0px 0px 0px 280px;*/
|
||||
width: auto;
|
||||
height: inherit;
|
||||
padding-left: 5px;
|
||||
padding-right: 30px;
|
||||
border-left: 1px solid #cccccc;
|
||||
overflow :scroll;
|
||||
overflow-x:auto;
|
||||
z-index: 1000;
|
||||
|
||||
}
|
||||
|
||||
#navheader {
|
||||
position: fixed;
|
||||
background: #DCDCDC;
|
||||
padding-left: 10px;
|
||||
right: 0px;
|
||||
top: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#content h1, #content h2 {
|
||||
color: #404040 !important;
|
||||
font-size: 170%;
|
||||
font-weight: normal;
|
||||
}
|
||||
.navfooter { bottom: 2%; }
|
||||
.highlight { background-color: #c5d3c3; }
|
||||
.highlightButton{ font-size: 0; }
|
||||
|
||||
/* Show Hide TOC tree */
|
||||
.pointLeft {
|
||||
padding-right: 15px;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pointRight {
|
||||
padding-right: 15px;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Search results Styling */
|
||||
.searchExpression {
|
||||
color: #0050A0;
|
||||
background-color: #EBEFF8;
|
||||
font-size: 12pt;
|
||||
}
|
||||
.searchresult li a {
|
||||
text-decoration: none;
|
||||
color: #0050A0;
|
||||
}
|
||||
.searchresult li { color: #0050A0; }
|
||||
.shortdesclink { color: gray; font-size: 9pt; }
|
||||
.searchText { float:left;width:150px; }
|
||||
.searchButton {
|
||||
padding: 2px 12px 2px 12px;
|
||||
background-color:#bbb;
|
||||
border:#bbb solid 1pt;
|
||||
font-weight: bold;
|
||||
font-size: 10pt
|
||||
}
|
||||
.searchButton:hover{
|
||||
background-color: #cccccc;
|
||||
}
|
||||
.searchFieldSet {}
|
||||
|
||||
.title, div.toc>p{ font-weight: bold; }
|
||||
|
||||
p.breadcrumbs {
|
||||
display: inline;
|
||||
margin-bottom: 0px;
|
||||
margin-top: 33px;
|
||||
}
|
||||
|
||||
p.breadcrumbs a {
|
||||
padding-right: 12px;
|
||||
margin-right: 5px;
|
||||
text-decoration: none;
|
||||
color: #575757;
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
p.breadcrumbs a:first-child {background: url(../images/breadcrumb-arrow-white.png) no-repeat right center;}
|
||||
|
||||
p.breadcrumbs a:hover {text-decoration: underline;}
|
||||
|
||||
#star ul.star {
|
||||
LIST-STYLE: none;
|
||||
MARGIN: 0;
|
||||
PADDING: 0;
|
||||
WIDTH: 85px;
|
||||
/* was 100 */
|
||||
HEIGHT: 20px;
|
||||
LEFT: 1px;
|
||||
TOP: -5px;
|
||||
POSITION: relative;
|
||||
FLOAT: right;
|
||||
BACKGROUND: url('../images/starsSmall.png') repeat-x 0 -25px;
|
||||
}
|
||||
#star li {
|
||||
PADDING: 0;
|
||||
MARGIN: 0;
|
||||
FLOAT: right;
|
||||
DISPLAY: block;
|
||||
WIDTH: 85px;
|
||||
/* was 100 */
|
||||
HEIGHT: 20px;
|
||||
TEXT-DECORATION: none;
|
||||
text-indent: -9000px;
|
||||
Z-INDEX: 20;
|
||||
POSITION: absolute;
|
||||
PADDING: 0;
|
||||
}
|
||||
#star li.curr {
|
||||
BACKGROUND: url('../images/starsSmall.png') left 25px;
|
||||
FONT-SIZE: 1px;
|
||||
}
|
||||
|
||||
table.navLinks {margin-right: 20px;}
|
||||
|
||||
table.navLinks td a {
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
color: black;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
a.navLinkPrevious {
|
||||
padding-left: 12px;
|
||||
background: url(../images/previous-arrow.png) no-repeat left center;
|
||||
}
|
||||
|
||||
a.navLinkNext {
|
||||
padding-right: 12px;
|
||||
background: url(../images/next-arrow.png) no-repeat right center;
|
||||
}
|
||||
|
||||
a#showHideButton {
|
||||
padding-left: 20px;
|
||||
background: url(../images/sidebar.png) no-repeat left center;
|
||||
}
|
||||
|
||||
|
||||
.filetree li span a { color: #777; }
|
||||
|
||||
#treediv { -webkit-box-shadow: #CCC 0px 1px 2px 0px inset; }
|
||||
|
||||
.legal, .legal *{
|
||||
color: #555;
|
||||
text-align: center;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.internal { color : #0000CC;}
|
||||
|
||||
.writeronly {color : red;}
|
||||
|
||||
.remark, .remark .added, .remark .changed, .remark .deleted{ background: yellow;}
|
||||
|
||||
tr th, tr th .internal, tr th .added, tr th .changed {
|
||||
background: #00589E;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.statustext{
|
||||
position:fixed;
|
||||
top:105px;
|
||||
width: 0%;
|
||||
height: 0%;
|
||||
opacity: .3;
|
||||
-webkit-transform: rotate(90deg);
|
||||
-moz-transform: rotate(90deg);
|
||||
-o-transform: rotate(90deg);
|
||||
white-space: nowrap;
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
font-size: 2em;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
#toolbar {
|
||||
width: 100%;
|
||||
height: 33px;
|
||||
position: fixed;
|
||||
top: 93px;
|
||||
z-index: 99;
|
||||
left: 280px;
|
||||
color: #333;
|
||||
line-height: 28px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#toolbar-left {
|
||||
position: relative;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
body p.breadcrumbs {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
/*body #content {
|
||||
position: static;
|
||||
margin-top: 126px;
|
||||
top: 0px;
|
||||
}*/
|
||||
|
||||
body.sidebar #toolbar{left: 0px;}
|
||||
|
||||
body.sidebar #toolbar-left{left: 0px;}
|
||||
|
||||
div#toolbar-left img {vertical-align: text-top;}
|
||||
|
||||
div.note *, div.caution *, div.important *, div.tip *, div.warning * {
|
||||
background: inherit !important;
|
||||
color: inherit !important;
|
||||
border: inherit /*!important*/;
|
||||
}
|
||||
|
||||
#content table thead, #content table th, #content table th p{
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#content table caption{font-weight: bold;}
|
||||
|
||||
#content table td, #content table {border: 1px solid black;}
|
||||
|
||||
#content table td, #content table th { padding: 5px;}
|
||||
|
||||
#content table {margin-bottom: 20px;}
|
||||
|
||||
*[align = 'center']{ text-align: center;}
|
||||
|
||||
#content .qandaset>table, #content .qandaset>table td, #content .calloutlist table, #content .calloutlist table td, #content .navfooter table, #content .navfooter table td {
|
||||
border: 0px solid;
|
||||
}
|
||||
|
||||
#sidebar
|
||||
{
|
||||
position: fixed;
|
||||
margin: 0px;
|
||||
left: 0px;
|
||||
right: auto;
|
||||
top: 99px;
|
||||
bottom: 0px;
|
||||
height: 543px;
|
||||
z-index: 0;
|
||||
display: block;
|
||||
visibility: visible;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
body * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#content, #content * {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#sidebar, .navfooter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#expanders {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
#expanders dt {
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 2px solid #cccccc;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
background: url(../images/plus.png) 0px 7px no-repeat;
|
||||
/*background: pink;*/
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#expanders dt h2 {
|
||||
font: bold 14pt IntervalLight, sans-serif;
|
||||
text-decoration: none;
|
||||
color: #0066CB;
|
||||
/*background-position: -16px 0;*/
|
||||
padding-left: 13px;
|
||||
}
|
||||
|
||||
#expanders dt.plus {
|
||||
background: url(../images/plus.png) 0px 7px no-repeat;
|
||||
}
|
||||
|
||||
#expanders dt.minus {
|
||||
background: url(../images/minus.png) 0px 7px no-repeat;
|
||||
}
|
||||
|
||||
|
||||
#expanders dd {
|
||||
display: none;
|
||||
margin-bottom: 3em;
|
||||
/*background: yellow;*/
|
||||
}
|
||||
|
||||
#expanders .hitarea {
|
||||
background: url(../images/ui-icons_217bc0_256x240.png) 0 -208px no-repeat;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
/* fix for IE6 */
|
||||
/** html .hitarea {
|
||||
display: inline;
|
||||
float:none;
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
#expanders .prod
|
||||
{
|
||||
width: 300px;
|
||||
border: #DDD solid 1px;
|
||||
float: left;
|
||||
margin: 1px;
|
||||
height: 160px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
#expanders .prodimg
|
||||
{
|
||||
/*border: #DDD solid 1px;*/
|
||||
float: left;
|
||||
}
|
||||
|
||||
.prodimg img {
|
||||
display: block;
|
||||
margin-left: 3px;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
width: 100px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#expanders .prodtext
|
||||
{
|
||||
/*background: #F8F8F8;*/
|
||||
width: 165px;
|
||||
float: left;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
#expanders .prod p {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#expanders ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
#expanders li {
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
a.external {
|
||||
background: url("../images/external_link.gif") no-repeat scroll right top transparent;
|
||||
padding: 0 13px 0 0;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
body {
|
||||
color : #000000 !important;
|
||||
background : #ffffff !important;
|
||||
font-family : "Times New Roman", Times, serif !important;
|
||||
font-size : 12pt !important;
|
||||
}
|
||||
|
||||
#sidebar, #sidebar-resizer, #header-resizer, #header { display: none !important;}
|
||||
|
||||
#content {
|
||||
position: absolute !important;
|
||||
margin: 0px !important;
|
||||
left: 0px !important;
|
||||
right: auto !important;
|
||||
top: 0px !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
overflow-x: visible !important;
|
||||
border-left: 0px solid #000000 !important;
|
||||
}
|
||||
|
||||
.ui-layout-container {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.mediaobject {
|
||||
text-align: left !important;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,dialog,div,dl,dt,em,embed,fieldset,figcaption,figure,font,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,html,i,iframe,img,ins,kbd,label,legend,li,main,mark,menu,meter,nav,object,ol,output,p,pre,progress,q,rp,rt,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video,xmp{border:0;margin:0;padding:0;font-size:100%}html,body{height:100%}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section{display:block}b,strong{font-weight:bold}img{color:transparent;font-size:0;vertical-align:middle;-ms-interpolation-mode:bicubic}ol,ul{list-style:none}li{display:list-item}table{border-collapse:collapse;border-spacing:0}th,td,caption{font-weight:normal;vertical-align:top;text-align:left}q{quotes:none}q:before,q:after{content:'';content:none}sub,sup,small{font-size:75%}sub,sup{line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}svg{overflow:hidden}
|
||||
@@ -1 +0,0 @@
|
||||
body{font:13px/1.5 'Helvetica Neue',Arial,'Liberation Sans',FreeSans,sans-serif}pre,code{font-family:'DejaVu Sans Mono',Menlo,Consolas,monospace}hr{border:0 solid #ccc;border-top-width:1px;clear:both;height:0}h1{font-size:25px}h2{font-size:23px}h3{font-size:21px}h4{font-size:19px}h5{font-size:17px}h6{font-size:15px}ol{list-style:decimal}ul{list-style:disc}li{margin-left:30px}p,dl,hr,h1,h2,h3,h4,h5,h6,ol,ul,pre,table,address,fieldset,figure{margin-bottom:20px}
|
||||
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 703 B |
|
Before Width: | Height: | Size: 583 B |
|
Before Width: | Height: | Size: 798 B |
|
Before Width: | Height: | Size: 98 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 156 B |
|
Before Width: | Height: | Size: 199 B |
|
Before Width: | Height: | Size: 164 B |