]> git.cworth.org Git - apitrace/commitdiff
Merge branch 'master' into d2d
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 21 Jan 2012 00:06:19 +0000 (00:06 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 21 Jan 2012 00:12:31 +0000 (00:12 +0000)
Conflicts:
compat.h
trace.py

12 files changed:
1  2 
.gitignore
CMakeLists.txt
compat.h
d2d1trace.py
d3d9trace.py
dwritetrace.py
specs/d2d1.py
specs/dwrite.py
specs/scripts/cdecl.py
specs/stdapi.py
specs/winapi.py
trace.py

diff --combined .gitignore
index 455b6aff1e3271968b40f899a53919a2b73a866e,e16a1f7a6f7100e4fc505e0123596d9c0c5fd352..89057b768b83236cf841158e9a38bd57888c211e
@@@ -28,15 -28,16 +28,18 @@@ _CPack_Package
  CMakeCache.txt
  CMakeFiles
  Makefile
+ apitrace
  build
  cgltrace.cpp
 +d2d1trace.cpp
  d3d10trace.cpp
  d3d8trace.cpp
  d3d9trace.cpp
  ddrawtrace.cpp
 +dwritetrace.cpp
  dxsdk
+ egltrace.cpp
+ eglretrace
  glproc.hpp
  glretrace
  glretrace_gl.cpp
@@@ -44,6 -45,5 +47,5 @@@ glstate_params.cp
  glxtrace.cpp
  install_manifest.txt
  qapitrace
- tracedump
  traces
  wgltrace.cpp
diff --combined CMakeLists.txt
index 0cb0acec21e69952a6ef4b8e61fb488936af8b2f,24e2afc06bcdeb5e52a6e8ccb7ce9f3e1a2851de..e65c529f322a39b6047c3e406eb82fbd90fadb66
@@@ -17,10 -17,14 +17,14 @@@ endif (
  # prescribed in http://www.gentoo.org/proj/en/qa/automagic.xml
  set (ENABLE_GUI "AUTO" CACHE STRING "Enable Qt GUI.")
  
+ set (ENABLE_EGL "AUTO" CACHE STRING "Enable EGL support.")
  
  ##############################################################################
  # Find dependencies
  
+ include (FindPkgConfig)
  set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
  
  set (CMAKE_USE_PYTHON_VERSION 2.7 2.6)
@@@ -36,34 -40,32 +40,32 @@@ if (ENABLE_GUI
      find_package (QJSON ${REQUIRE_GUI})
  endif ()
  
- if (NOT WIN32)
-     find_package (X11 REQUIRED)
-     # On Mac OS X, GLX is provided as a separate OpenGL implementation, different
-     # from the standard OpenGL framework which provides support for native Mac OS X
-     # applications.
-     if (APPLE)
-         find_path (X11_GL_INCLUDE_PATH GL/glx.h ${X11_INC_SEARCH_PATH})
-         if (NOT X11_GL_INCLUDE_PATH)
-             message (SEND_ERROR "Could not find GL/glx.h")
-         endif (NOT X11_GL_INCLUDE_PATH)
-         set (X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_GL_INCLUDE_PATH})
-         find_library (X11_GL_LIB GL ${X11_LIB_SEARCH_PATH})
-         if (NOT X11_GL_LIB)
-             message (SEND_ERROR "Could not find libGL.dylib")
-         endif (NOT X11_GL_LIB)
-     else ()
-         set (X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR})
-         set (X11_GL_LIB ${OPENGL_gl_LIBRARY})
-     endif ()
-     include_directories (${X11_INCLUDE_DIR})
- endif (NOT WIN32)
+ include_directories (${OPENGL_INCLUDE_DIR})
  
  if (WIN32)
      find_package (DirectX)
- endif (WIN32)
+ elseif (APPLE)
+ else ()
+     find_package (X11)
+     if (X11_FOUND)
+         include_directories (${X11_INCLUDE_DIR})
+         add_definitions (-DHAVE_X11)
+     endif ()
+     if (ENABLE_EGL)
+         if (NOT ENABLE_EGL STREQUAL "AUTO")
+             set (REQUIRE_EGL REQUIRED)
+         endif ()
+         pkg_check_modules (EGL egl glesv1_cm glesv2 ${REQUIRE_EGL})
+         if (EGL_FOUND)
+             include_directories (${EGL_INCLUDE_DIR})
+             add_definitions (-DHAVE_EGL)
+         endif ()
+     else ()
+         set (EGL_FOUND 0)
+     endif ()
+ endif ()
  
  
  ##############################################################################
@@@ -123,6 -125,22 +125,22 @@@ else (
      add_definitions (-Wno-sign-compare) # comparison between signed and unsigned integer expressions
  endif ()
  
+ if (MINGW)
+     # Avoid depending on MinGW runtime DLLs
+     check_cxx_compiler_flag (-static-libgcc HAVE_STATIC_LIBGCC_FLAG)
+     if (HAVE_STATIC_LIBGCC_FLAG)
+         set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc")
+         set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc")
+         set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -static-libgcc")
+     endif ()
+     check_cxx_compiler_flag (-static-libstdc++ HAVE_STATIC_LIBSTDCXX_FLAG)
+     if (HAVE_STATIC_LIBSTDCXX_FLAG)
+         set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++")
+         set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++")
+         set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -static-libstdc++")
+     endif ()
+ endif ()
  
  # Put all executables into the same top level build directory, regardless of
  # which subdirectory they are declared
@@@ -171,20 -189,60 +189,60 @@@ link_libraries (${PNG_LIBRARIES}
  # AUTO.
  if (QT4_FOUND AND NOT QJSON_FOUND AND (ENABLE_GUI STREQUAL "AUTO"))
      add_subdirectory (thirdparty/qjson EXCLUDE_FROM_ALL)
-     set (QJSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/qjson)
+     set (QJSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty)
      set (QJSON_LIBRARY_DIRS)
      set (QJSON_LIBRARIES qjson_bundled)
      set (QJSON_FOUND TRUE)
  endif ()
  
- # For glext headers
- include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty)
+ # For glext headers.  Needs to be before system includes as often system's GL
+ # headers bundle and include glext.h and glxext.h
+ include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/glext)
+ # For EGL headers
+ include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/khr)
+ ##############################################################################
+ # Installation directories
+ if (WIN32 OR APPLE)
+     # On Windows/MacOSX, applications are usually installed on a directory of
+     # their own
+     set (DOC_INSTALL_DIR doc)
+ else ()
+     set (DOC_INSTALL_DIR share/doc/${CMAKE_PROJECT_NAME})
+ endif ()
+ set (LIB_INSTALL_DIR lib/apitrace)
+ if (APPLE)
+     # MacOSX uses fat binaries, so no need to have per-architecture wrapper
+     # directories
+     set (LIB_ARCH_INSTALL_DIR ${LIB_INSTALL_DIR})
+ else ()
+     set (LIB_ARCH_INSTALL_DIR ${LIB_INSTALL_DIR}/${CMAKE_SYSTEM_PROCESSOR})
+ endif ()
+ set(SCRIPTS_INSTALL_DIR ${LIB_INSTALL_DIR}/scripts)
+ set(WRAPPER_INSTALL_DIR ${LIB_ARCH_INSTALL_DIR}/wrappers)
+ # Expose the binary/install directories to source
+ #
+ # TODO: Use the same directory layout, for both build and install directories,
+ # so that binaries can find each other using just relative paths.
+ #
+ add_definitions(
+     -DAPITRACE_BINARY_DIR="${CMAKE_BINARY_DIR}"
+     -DAPITRACE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"
+     -DAPITRACE_WRAPPER_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${WRAPPER_INSTALL_DIR}"
+ )
  
  
  ##############################################################################
  # Common libraries / utilities
  
  include_directories (
+     ${CMAKE_CURRENT_BINARY_DIR}
      ${CMAKE_CURRENT_SOURCE_DIR}
      ${CMAKE_CURRENT_SOURCE_DIR}/common
  )
  add_custom_command (
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
      COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glproc.py > ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
-     DEPENDS glproc.py dispatch.py specs/wglapi.py specs/glxapi.py specs/cglapi.py specs/glapi.py specs/gltypes.py specs/stdapi.py
+     DEPENDS glproc.py dispatch.py specs/wglapi.py specs/glxapi.py specs/cglapi.py specs/eglapi.py specs/glesapi.py specs/glapi.py specs/gltypes.py specs/stdapi.py
  )
  
+ # Wrap glproc.hpp as a target to prevent the command from being executed
+ # multiple times simulatenously, when the targets that depend on it are built
+ # in parallel.
+ add_custom_target (glproc DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp)
  if (WIN32)
      set (os os_win32.cpp)
      set (glws_os glws_wgl.cpp)
- else (WIN32)
+ else ()
      set (os os_posix.cpp)
-     set (glws_os glws_glx.cpp)
- endif (WIN32)
+     if (APPLE)
+         set (glws_os glws_cocoa.mm)
+     else ()
+         set (glws_os glws_glx.cpp)
+     endif ()
+ endif ()
  
  add_library (common STATIC
+     common/trace_dump.cpp
      common/trace_file.cpp
-     common/trace_snappyfile.cpp
+     common/trace_file_read.cpp
+     common/trace_file_write.cpp
+     common/trace_file_zlib.cpp
+     common/trace_file_snappy.cpp
      common/trace_model.cpp
      common/trace_parser.cpp
+     common/trace_parser_flags.cpp
      common/trace_writer.cpp
-     common/trace_local_writer.cpp
-     common/trace_model_writer.cpp
+     common/trace_writer_local.cpp
+     common/trace_writer_model.cpp
      common/trace_loader.cpp
+     common/trace_resource.cpp
+     common/trace_tools_trace.cpp
      common/image.cpp
      common/image_bmp.cpp
      common/image_pnm.cpp
  )
  
  set_target_properties (common PROPERTIES
+     COMPILE_DEFINITIONS APITRACE_SOURCE_DIR="${CMAKE_SOURCE_DIR}"
      # Ensure it can be statically linked in shared libraries
      COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}"
  )
  
  link_libraries (common)
  
- add_executable (tracedump tracedump.cpp)
- install (TARGETS tracedump RUNTIME DESTINATION bin) 
  
  ##############################################################################
  # API tracers
@@@ -253,7 -325,7 +325,7 @@@ if (WIN32
              RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
              LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
          )
-         install (TARGETS ddraw LIBRARY DESTINATION wrappers)
+         install (TARGETS ddraw LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
      endif (DirectX_D3D_INCLUDE_DIR)
  
      # d3d8.dll
              RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
              LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
          )
-         install (TARGETS d3d8 LIBRARY DESTINATION wrappers)
+         install (TARGETS d3d8 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
      endif (DirectX_D3D8_INCLUDE_DIR AND DirectX_D3DX9_INCLUDE_DIR)
  
      # d3d9.dll
              RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
              LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
          )
-         install (TARGETS d3d9 LIBRARY DESTINATION wrappers)
+         install (TARGETS d3d9 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
      endif (DirectX_D3DX9_INCLUDE_DIR)
  
      # d3d10.dll
              RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
              LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
          )
-         install (TARGETS d3d10 LIBRARY DESTINATION wrappers)
+         install (TARGETS d3d10 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
      endif (DirectX_D3D10_INCLUDE_DIR)
  
 +    # d2d1.dll, dwrite.dll
 +    if (DirectX_D2D1_INCLUDE_DIR)
 +        include_directories (SYSTEM ${DirectX_D2D1_INCLUDE_DIR})
 +
 +        add_custom_command (
 +            OUTPUT d2d1trace.cpp
 +            COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d2d1trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d2d1trace.cpp
 +            DEPENDS d2d1trace.py trace.py specs/d2d1.py specs/d2d1.py specs/d2dbasetypes.py specs/d2derr.py specs/dwrite.py specs/dcommon.py specs/dxgi.py specs/dxgitype.py specs/dxgiformat.py specs/winapi.py specs/stdapi.py
 +        )
 +        add_library (d2d1 MODULE specs/d2d1.def d2d1trace.cpp)
 +        set_target_properties (d2d1
 +            PROPERTIES PREFIX ""
 +            RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
 +            LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
 +        )
 +        install (TARGETS d2d1 LIBRARY DESTINATION wrappers)
 +
 +        add_custom_command (
 +            OUTPUT dwritetrace.cpp
 +            COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/dwritetrace.py > ${CMAKE_CURRENT_BINARY_DIR}/dwritetrace.cpp
 +            DEPENDS dwritetrace.py trace.py specs/d2d1.py specs/d2d1.py specs/d2dbasetypes.py specs/d2derr.py specs/dwrite.py specs/dcommon.py specs/dxgi.py specs/dxgitype.py specs/dxgiformat.py specs/winapi.py specs/stdapi.py
 +        )
 +        add_library (dwrite MODULE specs/dwrite.def dwritetrace.cpp)
 +        set_target_properties (dwrite
 +            PROPERTIES PREFIX ""
 +            RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
 +            LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
 +        )
 +        install (TARGETS dwrite LIBRARY DESTINATION wrappers)
 +    endif (DirectX_D2D1_INCLUDE_DIR)
 +
      # opengl32.dll
      add_custom_command (
          OUTPUT wgltrace.cpp
      add_library (wgltrace MODULE specs/opengl32.def
          wgltrace.cpp
          glcaps.cpp
-         ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
+         glproc_gl.cpp
      )
+     add_dependencies (wgltrace glproc)
      set_target_properties (wgltrace PROPERTIES
          PREFIX ""
          OUTPUT_NAME opengl32
          RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
          LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
      )
-     install (TARGETS wgltrace LIBRARY DESTINATION wrappers)
+     install (TARGETS wgltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
  
  elseif (APPLE)
      # OpenGL framework
      add_library (cgltrace SHARED
          cgltrace.cpp
          glcaps.cpp
-         ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
+         glproc_gl.cpp
      )
  
+     add_dependencies (cgltrace glproc)
      set_target_properties (cgltrace PROPERTIES
          # OpenGL framework name
          PREFIX "" OUTPUT_NAME "OpenGL" SUFFIX ""
          LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
      )
  
-     target_link_libraries (cgltrace dl)
+     target_link_libraries (cgltrace
+         pthread
+         dl
+     )
  
-     install (TARGETS cgltrace LIBRARY DESTINATION wrappers)
- else ()
+     install (TARGETS cgltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+ elseif (X11_FOUND)
      # libGL.so
      add_custom_command (
          OUTPUT glxtrace.cpp
      )
  
      add_library (glxtrace SHARED
-         ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
          glxtrace.cpp
          glcaps.cpp
-         glsnapshot.cpp
+         glproc_gl.cpp
      )
  
+     add_dependencies (glxtrace glproc)
      set_target_properties (glxtrace PROPERTIES
          # avoid the default "lib" prefix
          PREFIX ""
+         # Prevent symbol relocations internal to our wrapper library to be
+         # overwritten by the application.
+         LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
+         RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
+         LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
      )
  
-     # Prevent symbol relocations internal to our wrapper library to be
-     # overwritten by the application.
-     set_target_properties (glxtrace PROPERTIES
+     target_link_libraries (glxtrace
+         ${X11_X11_LIB}
+         pthread
+         dl
+     )
+     install (TARGETS glxtrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+ endif ()
+ if (EGL_FOUND)
+     # libEGL.so/libGL.so
+     add_custom_command (
+         OUTPUT egltrace.cpp
+         COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/egltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/egltrace.cpp
+         DEPENDS egltrace.py gltrace.py trace.py specs/eglapi.py specs/glesapi.py specs/glapi.py specs/glparams.py specs/gltypes.py specs/stdapi.py
+     )
+     add_library (egltrace SHARED
+         egltrace.cpp
+         glcaps.cpp
+         glproc_egl.cpp
+     )
+     add_dependencies (egltrace glproc)
+     set_property (
+         TARGET egltrace
+         APPEND
+         PROPERTY COMPILE_DEFINITIONS "TRACE_EGL"
+     )
+     set_target_properties (egltrace PROPERTIES
+         # avoid the default "lib" prefix
+         PREFIX ""
          LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
+         # Prevent symbol relocations internal to our wrapper library to be
+         # overwritten by the application.
+         RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
+         LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
      )
  
-     target_link_libraries (glxtrace dl ${X11_X11_LIB})
+     target_link_libraries (egltrace
+         pthread
+         dl
+     )
  
-     install (TARGETS glxtrace LIBRARY DESTINATION lib)
+     install (TARGETS egltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
  endif ()
  
  ##############################################################################
  # API retracers
  
@@@ -430,51 -521,113 +552,113 @@@ add_custom_command 
      DEPENDS glstate.py specs/glparams.py specs/gltypes.py specs/stdapi.py
  )
  
- include_directories (
-     ${CMAKE_CURRENT_BINARY_DIR}
-     ${OPENGL_INCLUDE_PATH}
- )
- add_executable (glretrace
+ set (retrace_sources
      glretrace_gl.cpp
      glretrace_cgl.cpp
      glretrace_glx.cpp
      glretrace_wgl.cpp
+     glretrace_egl.cpp
      glretrace_main.cpp
      glstate.cpp
      glstate_params.cpp
      retrace.cpp
+     retrace_stdc.cpp
      glws.cpp
-     ${glws_os}
-     ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
  )
  
- set_property (
-     TARGET glretrace
-     APPEND
-     PROPERTY COMPILE_DEFINITIONS "RETRACE"
- )
+ if (WIN32 OR APPLE OR X11_FOUND)
+     add_executable (glretrace
+         ${retrace_sources}
+         ${glws_os}
+         glproc_gl.cpp
+     )
  
- target_link_libraries (glretrace
-     common
- )
+     add_dependencies (glretrace glproc)
+     set_property (
+         TARGET glretrace
+         APPEND
+         PROPERTY COMPILE_DEFINITIONS "RETRACE"
+     )
  
- if (WIN32)
-     target_link_libraries (glretrace ${OPENGL_gl_LIBRARY})
- elseif (APPLE)
-     # XXX: We use GLX on MacOSX, which is in a separate library.
      target_link_libraries (glretrace
-         ${X11_GL_LIB}
+         common
+     )
+     if (WIN32)
+     else ()
+         if (APPLE)
+             target_link_libraries (glretrace
+                 "-framework Cocoa"
+                 "-framework ApplicationServices" # CGS*
+                 ${OPENGL_gl_LIBRARY} # CGL*
+             )
+         else ()
+             target_link_libraries (glretrace ${X11_X11_LIB})
+         endif ()
+         target_link_libraries (glretrace
+             # gdb doesn't like when pthreads is loaded through dlopen (which happens
+             # when dlopen'ing libGL), so link pthreads to avoid this issue.  See also
+             # http://stackoverflow.com/questions/2702628/gdb-cannot-find-new-threads-generic-error
+             pthread
+             dl
+         )
+         if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+             target_link_libraries (glretrace rt)
+         endif ()
+     endif ()
+     install (TARGETS glretrace RUNTIME DESTINATION bin) 
+ endif ()
+ if (EGL_FOUND AND X11_FOUND AND NOT WIN32 AND NOT APPLE)
+     add_executable (eglretrace
+         ${retrace_sources}
+         glws_egl_xlib.cpp
+         glproc_egl.cpp
+     )
+     add_dependencies (eglretrace glproc)
+     set_property (
+         TARGET eglretrace
+         APPEND
+         PROPERTY COMPILE_DEFINITIONS "RETRACE"
+         PROPERTY COMPILE_DEFINITIONS "TRACE_EGL"
+     )
+     target_link_libraries (eglretrace
+         common
          ${X11_X11_LIB}
-         "-framework ApplicationServices" # CGS*
-         ${OPENGL_gl_LIBRARY} # CGL*
+         pthread
+         dl
      )
- else ()
-     target_link_libraries (glretrace ${OPENGL_gl_LIBRARY} ${X11_X11_LIB})
+     if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+         target_link_libraries (eglretrace rt)
+     endif ()
+     install (TARGETS eglretrace RUNTIME DESTINATION bin) 
  endif ()
  
- install (TARGETS glretrace RUNTIME DESTINATION bin) 
+ ##############################################################################
+ # CLI
  
+ add_subdirectory(cli)
+ ##############################################################################
+ # Scripts (to support the CLI)
+ install (
+     PROGRAMS
+         ${CMAKE_CURRENT_SOURCE_DIR}/scripts/tracediff.sh
+         ${CMAKE_CURRENT_SOURCE_DIR}/scripts/jsondiff.py
+         ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snapdiff.py
+     DESTINATION ${SCRIPTS_INSTALL_DIR}
+ )
  
  ##############################################################################
  # GUI
@@@ -494,7 -647,8 +678,8 @@@ install 
          NEWS.markdown
          README.markdown
          TODO.markdown
-     DESTINATION doc)
+     DESTINATION ${DOC_INSTALL_DIR}
+ )
  
  set (CPACK_PACKAGE_VERSION_MAJOR "2")
  set (CPACK_PACKAGE_VERSION_MINOR "0")
diff --combined compat.h
index 4573b97794daeb39f2f4daea55cb2bec01785b11,74b45c3c211535955f25ef69f6c880e4627466aa..b74bfd47d69155ce092bc6e2566cd729b37e1ee3
+++ b/compat.h
  #define __field_bcount(x) /**/
  #define __field_ecount(x) /**/
  #define __field_ecount_full(x) /**/
- #define __inline __inline__
+ #define __inline static __inline__
 +#define __deref_out /**/
 +#define __deref_out_opt /**/
 +#define __deref_out_bcount(x)
 +#define __maybenull
 +#define __in_z
 +#define __in_z_opt
 +#define __out_z
 +#define __out_ecount_z(x)
 +#define __nullterminated
 +#define __notnull
  
  #ifndef DECLSPEC_DEPRECATED
  #define DECLSPEC_DEPRECATED /**/
  #endif
  
- #include <stdint.h>
- #define INT8 int8_t
- #define UINT8 uint8_t
- #define INT16 int16_t
- #define UINT16 uint16_t
 +#ifndef DECLSPEC_NOVTABLE
 +#define DECLSPEC_NOVTABLE
 +#endif
 +
+ #ifndef __MINGW64_VERSION_MAJOR
++#define INT8 signed char
+ #define UINT8 unsigned char
++#define INT16 signed short
++#define UINT16 unsigned short
+ #endif
  
  #endif /* __MINGW32__ */
  
diff --combined d2d1trace.py
index 37cd53e0fc207fdca46359ea5e5ec4fb1864e42b,0000000000000000000000000000000000000000..a99abdaf8e2dc49f51ed16cbc435e41c33d860c1
mode 100644,000000..100644
--- /dev/null
@@@ -1,62 -1,0 +1,62 @@@
- from trace import DllTracer
 +##########################################################################
 +#
 +# Copyright 2008-2009 VMware, Inc.
 +# All Rights Reserved.
 +#
 +# Permission is hereby granted, free of charge, to any person obtaining a copy
 +# of this software and associated documentation files (the "Software"), to deal
 +# in the Software without restriction, including without limitation the rights
 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 +# copies of the Software, and to permit persons to whom the Software is
 +# furnished to do so, subject to the following conditions:
 +#
 +# The above copyright notice and this permission notice shall be included in
 +# all copies or substantial portions of the Software.
 +#
 +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 +# THE SOFTWARE.
 +#
 +##########################################################################/
 +
 +
-     def wrap_arg(self, function, arg):
++from dlltrace import DllTracer
 +from specs.d2d1 import d2d1
 +
 +
 +class D2D1Tracer(DllTracer):
 +
-         DllTracer.wrap_arg(self, function, arg)
++    def wrapArg(self, function, arg):
 +        if function.name == 'D2D1CreateFactory' and arg.output:
 +            print '    if (*%s) {' % arg.name
 +            for iface in d2d1.interfaces:
 +                print '        if (riid == IID_%s) {' % iface.name
 +                print '            *%s = (LPVOID) new Wrap%s((%s *)*%s);' % (arg.name, iface.name, iface.name, arg.name)
 +                print '        }'
 +            print '    }'
 +
-     print '#include "trace_writer.hpp"'
++        DllTracer.wrapArg(self, function, arg)
 +
 +
 +if __name__ == '__main__':
 +    print '#define INITGUID'
 +    print
++    print '#include "trace_writer_local.hpp"'
 +    print '#include "os.hpp"'
 +    print
 +    print '#include <windows.h>'
 +    print
 +    print '#include "compat.h"'
 +    print
 +    print '#include <d2d1.h>'
 +    print '#include <dwrite.h>'
 +    print
 +    print 'DEFINE_GUID(IID_ID2D1Factory,0x06152247,0x6f50,0x465a,0x92,0x45,0x11,0x8b,0xfd,0x3b,0x60,0x07);'
 +    print
 +
 +    tracer = D2D1Tracer('d2d1.dll')
 +    tracer.trace_api(d2d1)
diff --combined d3d9trace.py
index c489be6a6f53a2221533acb12e2898d63db82231,d2ff7d5fccf60ec1ae4fdc63a52629480f77085c..a40ae7f5f1eed1bcb189a3ea78ed848ec0e1d88f
  ##########################################################################/
  
  
- from trace import DllTracer
+ from dlltrace import DllTracer
  from specs.d3d9 import d3d9
  
  
  class D3D9Tracer(DllTracer):
  
-     def dump_arg_instance(self, function, arg):
+     def serializeArgValue(self, function, arg):
          # Dump shaders as strings
          if function.name in ('CreateVertexShader', 'CreatePixelShader') and arg.name == 'pFunction':
-             print '    DumpShader(Trace::localWriter, %s);' % (arg.name)
+             print '    DumpShader(trace::localWriter, %s);' % (arg.name)
              return
  
-         DllTracer.dump_arg_instance(self, function, arg)
+         DllTracer.serializeArgValue(self, function, arg)
+     def declareWrapperInterfaceVariables(self, interface):
+         DllTracer.declareWrapperInterfaceVariables(self, interface)
+         
+         if interface.name == 'IDirect3DVertexBuffer9':
+             print '    UINT m_OffsetToLock;'
+             print '    UINT m_SizeToLock;'
+             print '    VOID *m_pbData;'
 -    def implementWrapperInterfaceMethodBody(self, interface, method):
++    def implementWrapperInterfaceMethodBody(self, interface, base, method):
+         if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Unlock':
+             print '    if (m_pbData) {'
+             print '        if (!m_SizeToLock) {'
+             print '            D3DVERTEXBUFFER_DESC Desc;'
+             print '            m_pInstance->GetDesc(&Desc);'
+             print '            m_SizeToLock = Desc.Size;'
+             print '        }'
+             self.emit_memcpy('(LPBYTE)m_pbData + m_OffsetToLock', '(LPBYTE)m_pbData + m_OffsetToLock', 'm_SizeToLock')
+             print '    }'
 -        DllTracer.implementWrapperInterfaceMethodBody(self, interface, method)
++        DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method)
+         if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Lock':
+             print '    if (__result == D3D_OK && !(Flags & D3DLOCK_READONLY)) {'
+             print '        m_OffsetToLock = OffsetToLock;'
+             print '        m_SizeToLock = SizeToLock;'
+             print '        m_pbData = *ppbData;'
+             print '    } else {'
+             print '        m_pbData = NULL;'
+             print '    }'
  
  
  if __name__ == '__main__':
-     print '#include "trace_writer.hpp"'
+     print '#include "trace_writer_local.hpp"'
      print '#include "os.hpp"'
      print
      print '#include "d3d9imports.hpp"'
      print '#include "d3dshader.hpp"'
      print
+     print '''
+ static inline size_t
+ _declCount(const D3DVERTEXELEMENT9 *pVertexElements) {
+     size_t count = 0;
+     if (pVertexElements) {
+         while (pVertexElements[count++].Stream != 0xff)
+             ;
+     }
+     return count;
+ }
+ '''
      tracer = D3D9Tracer('d3d9.dll')
      tracer.trace_api(d3d9)
  
diff --combined dwritetrace.py
index 94f1fbfb36de60e3ea020532fb92424eabd30329,0000000000000000000000000000000000000000..4fc380d4b5d57c1dd8e21cc4ab8202b2f8c2e161
mode 100644,000000..100644
--- /dev/null
@@@ -1,65 -1,0 +1,65 @@@
- from trace import DllTracer
 +##########################################################################
 +#
 +# Copyright 2008-2009 VMware, Inc.
 +# All Rights Reserved.
 +#
 +# Permission is hereby granted, free of charge, to any person obtaining a copy
 +# of this software and associated documentation files (the "Software"), to deal
 +# in the Software without restriction, including without limitation the rights
 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 +# copies of the Software, and to permit persons to whom the Software is
 +# furnished to do so, subject to the following conditions:
 +#
 +# The above copyright notice and this permission notice shall be included in
 +# all copies or substantial portions of the Software.
 +#
 +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 +# THE SOFTWARE.
 +#
 +##########################################################################/
 +
 +
-     def wrap_arg(self, function, arg):
++from dlltrace import DllTracer
 +from specs.dwrite import dwrite
 +from specs.d2d1 import d2d1 # cyclic dependency
 +
 +
 +class D2D1Tracer(DllTracer):
 +
-         DllTracer.wrap_arg(self, function, arg)
++    def wrapArg(self, function, arg):
 +        if function.name == 'D2D1CreateFactory' and arg.output:
 +            print '    if (*%s) {' % arg.name
 +            for iface in d2d1.interfaces:
 +                print '        if (riid == IID_%s) {' % iface.name
 +                print '            *%s = (%s) new Wrap%s((%s *)*%s);' % (arg.name, arg.type, iface.name, iface.name, arg.name)
 +                print '        }'
 +            print '    }'
 +
-     print '#include "trace_writer.hpp"'
++        DllTracer.wrapArg(self, function, arg)
 +
 +
 +if __name__ == '__main__':
 +    print '#define INITGUID'
 +    print
++    print '#include "trace_writer_local.hpp"'
 +    print '#include "os.hpp"'
 +    print
 +    print '#include <windows.h>'
 +    print
 +    print '#include "compat.h"'
 +    print
 +    print '#define DWRITE_EXPORT WINAPI'
 +    print
 +    print '#include <d2d1.h>'
 +    print '#include <dwrite.h>'
 +    print
 +    print 'DEFINE_GUID(IID_IDWriteFactory,0xb859ee5a,0xd838,0x4b5b,0xa2,0xe8,0x1a,0xdc,0x7d,0x93,0xdb,0x48);'
 +    print
 +
 +    tracer = D2D1Tracer('dwrite.dll')
 +    tracer.trace_api(dwrite)
diff --combined specs/d2d1.py
index eed4d6f01de8471e8a56a60e9e230fd30f2b4258,0000000000000000000000000000000000000000..e7ac8df308556420628744ffe813042f86b3f26a
mode 100644,000000..100644
--- /dev/null
@@@ -1,633 -1,0 +1,633 @@@
- d2d1.add_interface(ID2D1Factory)
- d2d1.add_functions([
 +##########################################################################
 +#
 +# Copyright 2011 Jose Fonseca
 +# All Rights Reserved.
 +#
 +# Permission is hereby granted, free of charge, to any person obtaining a copy
 +# of this software and associated documentation files (the "Software"), to deal
 +# in the Software without restriction, including without limitation the rights
 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 +# copies of the Software, and to permit persons to whom the Software is
 +# furnished to do so, subject to the following conditions:
 +#
 +# The above copyright notice and this permission notice shall be included in
 +# all copies or substantial portions of the Software.
 +#
 +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 +# THE SOFTWARE.
 +#
 +##########################################################################/
 +
 +
 +from winapi import *
 +from dxgiformat import DXGI_FORMAT
 +from dxgi import IDXGISurface
 +from d2derr import *
 +from d2dbasetypes import *
 +from dwrite import *
 +
 +
 +ID2D1Resource = Interface("ID2D1Resource", IUnknown)
 +ID2D1Bitmap = Interface("ID2D1Bitmap", ID2D1Resource)
 +ID2D1GradientStopCollection = Interface("ID2D1GradientStopCollection", ID2D1Resource)
 +ID2D1Brush = Interface("ID2D1Brush", ID2D1Resource)
 +ID2D1BitmapBrush = Interface("ID2D1BitmapBrush", ID2D1Brush)
 +ID2D1SolidColorBrush = Interface("ID2D1SolidColorBrush", ID2D1Brush)
 +ID2D1LinearGradientBrush = Interface("ID2D1LinearGradientBrush", ID2D1Brush)
 +ID2D1RadialGradientBrush = Interface("ID2D1RadialGradientBrush", ID2D1Brush)
 +ID2D1StrokeStyle = Interface("ID2D1StrokeStyle", ID2D1Resource)
 +ID2D1Geometry = Interface("ID2D1Geometry", ID2D1Resource)
 +ID2D1RectangleGeometry = Interface("ID2D1RectangleGeometry", ID2D1Geometry)
 +ID2D1RoundedRectangleGeometry = Interface("ID2D1RoundedRectangleGeometry", ID2D1Geometry)
 +ID2D1EllipseGeometry = Interface("ID2D1EllipseGeometry", ID2D1Geometry)
 +ID2D1GeometryGroup = Interface("ID2D1GeometryGroup", ID2D1Geometry)
 +ID2D1TransformedGeometry = Interface("ID2D1TransformedGeometry", ID2D1Geometry)
 +ID2D1GeometrySink = Interface("ID2D1GeometrySink", ID2D1SimplifiedGeometrySink)
 +ID2D1TessellationSink = Interface("ID2D1TessellationSink", IUnknown)
 +ID2D1PathGeometry = Interface("ID2D1PathGeometry", ID2D1Geometry)
 +ID2D1Mesh = Interface("ID2D1Mesh", ID2D1Resource)
 +ID2D1Layer = Interface("ID2D1Layer", ID2D1Resource)
 +ID2D1DrawingStateBlock = Interface("ID2D1DrawingStateBlock", ID2D1Resource)
 +ID2D1RenderTarget = Interface("ID2D1RenderTarget", ID2D1Resource)
 +ID2D1BitmapRenderTarget = Interface("ID2D1BitmapRenderTarget", ID2D1RenderTarget)
 +ID2D1HwndRenderTarget = Interface("ID2D1HwndRenderTarget", ID2D1RenderTarget)
 +ID2D1GdiInteropRenderTarget = Interface("ID2D1GdiInteropRenderTarget", IUnknown)
 +ID2D1DCRenderTarget = Interface("ID2D1DCRenderTarget", ID2D1RenderTarget)
 +ID2D1Factory = Interface("ID2D1Factory", IUnknown)
 +
 +
 +D2D1_ALPHA_MODE = Enum("D2D1_ALPHA_MODE", [
 +    "D2D1_ALPHA_MODE_UNKNOWN",
 +    "D2D1_ALPHA_MODE_PREMULTIPLIED",
 +    "D2D1_ALPHA_MODE_STRAIGHT",
 +    "D2D1_ALPHA_MODE_IGNORE",
 +])
 +
 +D2D1_GAMMA = Enum("D2D1_GAMMA", [
 +    "D2D1_GAMMA_2_2",
 +    "D2D1_GAMMA_1_0",
 +])
 +
 +D2D1_OPACITY_MASK_CONTENT = Enum("D2D1_OPACITY_MASK_CONTENT", [
 +    "D2D1_OPACITY_MASK_CONTENT_GRAPHICS",
 +    "D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL",
 +    "D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE",
 +])
 +
 +D2D1_EXTEND_MODE = Enum("D2D1_EXTEND_MODE", [
 +    "D2D1_EXTEND_MODE_CLAMP",
 +    "D2D1_EXTEND_MODE_WRAP",
 +    "D2D1_EXTEND_MODE_MIRROR",
 +])
 +
 +D2D1_ANTIALIAS_MODE = Enum("D2D1_ANTIALIAS_MODE", [
 +    "D2D1_ANTIALIAS_MODE_PER_PRIMITIVE",
 +    "D2D1_ANTIALIAS_MODE_ALIASED",
 +])
 +
 +D2D1_TEXT_ANTIALIAS_MODE = Enum("D2D1_TEXT_ANTIALIAS_MODE", [
 +    "D2D1_TEXT_ANTIALIAS_MODE_DEFAULT",
 +    "D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE",
 +    "D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE",
 +    "D2D1_TEXT_ANTIALIAS_MODE_ALIASED",
 +])
 +
 +D2D1_BITMAP_INTERPOLATION_MODE = Enum("D2D1_BITMAP_INTERPOLATION_MODE", [
 +    "D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR",
 +    "D2D1_BITMAP_INTERPOLATION_MODE_LINEAR",
 +])
 +
 +D2D1_DRAW_TEXT_OPTIONS = EnumFlag("D2D1_DRAW_TEXT_OPTIONS", [
 +    "D2D1_DRAW_TEXT_OPTIONS_NONE",
 +    "D2D1_DRAW_TEXT_OPTIONS_NO_SNAP",
 +    "D2D1_DRAW_TEXT_OPTIONS_CLIP",
 +])
 +
 +D2D1_PIXEL_FORMAT = Struct("D2D1_PIXEL_FORMAT", [
 +    (DXGI_FORMAT, "format"),
 +    (D2D1_ALPHA_MODE, "alphaMode"),
 +])
 +
 +D2D1_POINT_2U = Alias("D2D1_POINT_2U", D2D_POINT_2U)
 +D2D1_POINT_2F = Alias("D2D1_POINT_2F", D2D_POINT_2F)
 +D2D1_RECT_F = Alias("D2D1_RECT_F", D2D_RECT_F)
 +D2D1_RECT_U = Alias("D2D1_RECT_U", D2D_RECT_U)
 +D2D1_SIZE_F = Alias("D2D1_SIZE_F", D2D_SIZE_F)
 +D2D1_SIZE_U = Alias("D2D1_SIZE_U", D2D_SIZE_U)
 +D2D1_COLOR_F = Alias("D2D1_COLOR_F", D2D_COLOR_F)
 +D2D1_MATRIX_3X2_F = Alias("D2D1_MATRIX_3X2_F", D2D_MATRIX_3X2_F)
 +D2D1_TAG = Alias("D2D1_TAG", UINT64)
 +D2D1_BITMAP_PROPERTIES = Struct("D2D1_BITMAP_PROPERTIES", [
 +    (D2D1_PIXEL_FORMAT, "pixelFormat"),
 +    (FLOAT, "dpiX"),
 +    (FLOAT, "dpiY"),
 +])
 +
 +D2D1_GRADIENT_STOP = Struct("D2D1_GRADIENT_STOP", [
 +    (FLOAT, "position"),
 +    (D2D1_COLOR_F, "color"),
 +])
 +
 +D2D1_BRUSH_PROPERTIES = Struct("D2D1_BRUSH_PROPERTIES", [
 +    (FLOAT, "opacity"),
 +    (D2D1_MATRIX_3X2_F, "transform"),
 +])
 +
 +D2D1_BITMAP_BRUSH_PROPERTIES = Struct("D2D1_BITMAP_BRUSH_PROPERTIES", [
 +    (D2D1_EXTEND_MODE, "extendModeX"),
 +    (D2D1_EXTEND_MODE, "extendModeY"),
 +    (D2D1_BITMAP_INTERPOLATION_MODE, "interpolationMode"),
 +])
 +
 +D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES = Struct("D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES", [
 +    (D2D1_POINT_2F, "startPoint"),
 +    (D2D1_POINT_2F, "endPoint"),
 +])
 +
 +D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES = Struct("D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES", [
 +    (D2D1_POINT_2F, "center"),
 +    (D2D1_POINT_2F, "gradientOriginOffset"),
 +    (FLOAT, "radiusX"),
 +    (FLOAT, "radiusY"),
 +])
 +
 +D2D1_ARC_SIZE = Enum("D2D1_ARC_SIZE", [
 +    "D2D1_ARC_SIZE_SMALL",
 +    "D2D1_ARC_SIZE_LARGE",
 +])
 +
 +D2D1_CAP_STYLE = Enum("D2D1_CAP_STYLE", [
 +    "D2D1_CAP_STYLE_FLAT",
 +    "D2D1_CAP_STYLE_SQUARE",
 +    "D2D1_CAP_STYLE_ROUND",
 +    "D2D1_CAP_STYLE_TRIANGLE",
 +])
 +
 +D2D1_DASH_STYLE = Enum("D2D1_DASH_STYLE", [
 +    "D2D1_DASH_STYLE_SOLID",
 +    "D2D1_DASH_STYLE_DASH",
 +    "D2D1_DASH_STYLE_DOT",
 +    "D2D1_DASH_STYLE_DASH_DOT",
 +    "D2D1_DASH_STYLE_DASH_DOT_DOT",
 +    "D2D1_DASH_STYLE_CUSTOM",
 +])
 +
 +D2D1_LINE_JOIN = Enum("D2D1_LINE_JOIN", [
 +    "D2D1_LINE_JOIN_MITER",
 +    "D2D1_LINE_JOIN_BEVEL",
 +    "D2D1_LINE_JOIN_ROUND",
 +    "D2D1_LINE_JOIN_MITER_OR_BEVEL",
 +])
 +
 +D2D1_COMBINE_MODE = Enum("D2D1_COMBINE_MODE", [
 +    "D2D1_COMBINE_MODE_UNION",
 +    "D2D1_COMBINE_MODE_INTERSECT",
 +    "D2D1_COMBINE_MODE_XOR",
 +    "D2D1_COMBINE_MODE_EXCLUDE",
 +])
 +
 +D2D1_GEOMETRY_RELATION = Enum("D2D1_GEOMETRY_RELATION", [
 +    "D2D1_GEOMETRY_RELATION_UNKNOWN",
 +    "D2D1_GEOMETRY_RELATION_DISJOINT",
 +    "D2D1_GEOMETRY_RELATION_IS_CONTAINED",
 +    "D2D1_GEOMETRY_RELATION_CONTAINS",
 +    "D2D1_GEOMETRY_RELATION_OVERLAP",
 +])
 +
 +D2D1_GEOMETRY_SIMPLIFICATION_OPTION = Enum("D2D1_GEOMETRY_SIMPLIFICATION_OPTION", [
 +    "D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES",
 +    "D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES",
 +])
 +
 +D2D1_FIGURE_BEGIN = Enum("D2D1_FIGURE_BEGIN", [
 +    "D2D1_FIGURE_BEGIN_FILLED",
 +    "D2D1_FIGURE_BEGIN_HOLLOW",
 +])
 +
 +D2D1_FIGURE_END = Enum("D2D1_FIGURE_END", [
 +    "D2D1_FIGURE_END_OPEN",
 +    "D2D1_FIGURE_END_CLOSED",
 +])
 +
 +D2D1_BEZIER_SEGMENT = Struct("D2D1_BEZIER_SEGMENT", [
 +    (D2D1_POINT_2F, "point1"),
 +    (D2D1_POINT_2F, "point2"),
 +    (D2D1_POINT_2F, "point3"),
 +])
 +
 +D2D1_TRIANGLE = Struct("D2D1_TRIANGLE", [
 +    (D2D1_POINT_2F, "point1"),
 +    (D2D1_POINT_2F, "point2"),
 +    (D2D1_POINT_2F, "point3"),
 +])
 +
 +D2D1_PATH_SEGMENT = EnumFlag("D2D1_PATH_SEGMENT", [
 +    "D2D1_PATH_SEGMENT_NONE",
 +    "D2D1_PATH_SEGMENT_FORCE_UNSTROKED",
 +    "D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN",
 +])
 +
 +D2D1_SWEEP_DIRECTION = Enum("D2D1_SWEEP_DIRECTION", [
 +    "D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE",
 +    "D2D1_SWEEP_DIRECTION_CLOCKWISE",
 +])
 +
 +D2D1_FILL_MODE = Enum("D2D1_FILL_MODE", [
 +    "D2D1_FILL_MODE_ALTERNATE",
 +    "D2D1_FILL_MODE_WINDING",
 +])
 +
 +D2D1_ARC_SEGMENT = Struct("D2D1_ARC_SEGMENT", [
 +    (D2D1_POINT_2F, "point"),
 +    (D2D1_SIZE_F, "size"),
 +    (FLOAT, "rotationAngle"),
 +    (D2D1_SWEEP_DIRECTION, "sweepDirection"),
 +    (D2D1_ARC_SIZE, "arcSize"),
 +])
 +
 +D2D1_QUADRATIC_BEZIER_SEGMENT = Struct("D2D1_QUADRATIC_BEZIER_SEGMENT", [
 +    (D2D1_POINT_2F, "point1"),
 +    (D2D1_POINT_2F, "point2"),
 +])
 +
 +D2D1_ELLIPSE = Struct("D2D1_ELLIPSE", [
 +    (D2D1_POINT_2F, "point"),
 +    (FLOAT, "radiusX"),
 +    (FLOAT, "radiusY"),
 +])
 +
 +D2D1_ROUNDED_RECT = Struct("D2D1_ROUNDED_RECT", [
 +    (D2D1_RECT_F, "rect"),
 +    (FLOAT, "radiusX"),
 +    (FLOAT, "radiusY"),
 +])
 +
 +D2D1_STROKE_STYLE_PROPERTIES = Struct("D2D1_STROKE_STYLE_PROPERTIES", [
 +    (D2D1_CAP_STYLE, "startCap"),
 +    (D2D1_CAP_STYLE, "endCap"),
 +    (D2D1_CAP_STYLE, "dashCap"),
 +    (D2D1_LINE_JOIN, "lineJoin"),
 +    (FLOAT, "miterLimit"),
 +    (D2D1_DASH_STYLE, "dashStyle"),
 +    (FLOAT, "dashOffset"),
 +])
 +
 +D2D1_LAYER_OPTIONS = EnumFlag("D2D1_LAYER_OPTIONS", [
 +    "D2D1_LAYER_OPTIONS_NONE",
 +    "D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE",
 +])
 +
 +D2D1_LAYER_PARAMETERS = Struct("D2D1_LAYER_PARAMETERS", [
 +    (D2D1_RECT_F, "contentBounds"),
 +    (Pointer(ID2D1Geometry), "geometricMask"),
 +    (D2D1_ANTIALIAS_MODE, "maskAntialiasMode"),
 +    (D2D1_MATRIX_3X2_F, "maskTransform"),
 +    (FLOAT, "opacity"),
 +    (Pointer(ID2D1Brush), "opacityBrush"),
 +    (D2D1_LAYER_OPTIONS, "layerOptions"),
 +])
 +
 +D2D1_WINDOW_STATE = EnumFlag("D2D1_WINDOW_STATE", [
 +    "D2D1_WINDOW_STATE_NONE",
 +    "D2D1_WINDOW_STATE_OCCLUDED",
 +])
 +
 +D2D1_RENDER_TARGET_TYPE = Enum("D2D1_RENDER_TARGET_TYPE", [
 +    "D2D1_RENDER_TARGET_TYPE_DEFAULT",
 +    "D2D1_RENDER_TARGET_TYPE_SOFTWARE",
 +    "D2D1_RENDER_TARGET_TYPE_HARDWARE",
 +])
 +
 +D2D1_FEATURE_LEVEL = Enum("D2D1_FEATURE_LEVEL", [
 +    "D2D1_FEATURE_LEVEL_DEFAULT",
 +    "D2D1_FEATURE_LEVEL_9",
 +    "D2D1_FEATURE_LEVEL_10",
 +])
 +
 +D2D1_RENDER_TARGET_USAGE = EnumFlag("D2D1_RENDER_TARGET_USAGE", [
 +    "D2D1_RENDER_TARGET_USAGE_NONE",
 +    "D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING",
 +    "D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE",
 +])
 +
 +D2D1_PRESENT_OPTIONS = EnumFlag("D2D1_PRESENT_OPTIONS", [
 +    "D2D1_PRESENT_OPTIONS_NONE",
 +    "D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS",
 +    "D2D1_PRESENT_OPTIONS_IMMEDIATELY",
 +])
 +
 +D2D1_RENDER_TARGET_PROPERTIES = Struct("D2D1_RENDER_TARGET_PROPERTIES", [
 +    (D2D1_RENDER_TARGET_TYPE, "type"),
 +    (D2D1_PIXEL_FORMAT, "pixelFormat"),
 +    (FLOAT, "dpiX"),
 +    (FLOAT, "dpiY"),
 +    (D2D1_RENDER_TARGET_USAGE, "usage"),
 +    (D2D1_FEATURE_LEVEL, "minLevel"),
 +])
 +
 +D2D1_HWND_RENDER_TARGET_PROPERTIES = Struct("D2D1_HWND_RENDER_TARGET_PROPERTIES", [
 +    (HWND, "hwnd"),
 +    (D2D1_SIZE_U, "pixelSize"),
 +    (D2D1_PRESENT_OPTIONS, "presentOptions"),
 +])
 +
 +D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS = EnumFlag("D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS", [
 +    "D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE",
 +    "D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE",
 +])
 +
 +D2D1_DRAWING_STATE_DESCRIPTION = Struct("D2D1_DRAWING_STATE_DESCRIPTION", [
 +    (D2D1_ANTIALIAS_MODE, "antialiasMode"),
 +    (D2D1_TEXT_ANTIALIAS_MODE, "textAntialiasMode"),
 +    (D2D1_TAG, "tag1"),
 +    (D2D1_TAG, "tag2"),
 +    (D2D1_MATRIX_3X2_F, "transform"),
 +])
 +
 +D2D1_DC_INITIALIZE_MODE = Enum("D2D1_DC_INITIALIZE_MODE", [
 +    "D2D1_DC_INITIALIZE_MODE_COPY",
 +    "D2D1_DC_INITIALIZE_MODE_CLEAR",
 +])
 +
 +D2D1_DEBUG_LEVEL = Enum("D2D1_DEBUG_LEVEL", [
 +    "D2D1_DEBUG_LEVEL_NONE",
 +    "D2D1_DEBUG_LEVEL_ERROR",
 +    "D2D1_DEBUG_LEVEL_WARNING",
 +    "D2D1_DEBUG_LEVEL_INFORMATION",
 +])
 +
 +D2D1_FACTORY_TYPE = Enum("D2D1_FACTORY_TYPE", [
 +    "D2D1_FACTORY_TYPE_SINGLE_THREADED",
 +    "D2D1_FACTORY_TYPE_MULTI_THREADED",
 +])
 +
 +D2D1_FACTORY_OPTIONS = Struct("D2D1_FACTORY_OPTIONS", [
 +    (D2D1_DEBUG_LEVEL, "debugLevel"),
 +])
 +
 +ID2D1Resource.methods += [
 +    Method(Void, "GetFactory", [Out(Pointer(Pointer(ID2D1Factory)), "factory")], const=True),
 +]
 +
 +ID2D1Bitmap.methods += [
 +    Method(D2D1_SIZE_F, "GetSize", [], const=True),
 +    Method(D2D1_SIZE_U, "GetPixelSize", [], const=True),
 +    Method(D2D1_PIXEL_FORMAT, "GetPixelFormat", [], const=True),
 +    Method(Void, "GetDpi", [Out(Pointer(FLOAT), "dpiX"), Out(Pointer(FLOAT), "dpiY")], const=True),
 +    Method(HRESULT, "CopyFromBitmap", [(Pointer(Const(D2D1_POINT_2U)), "destPoint"), (Pointer(ID2D1Bitmap), "bitmap"), (Pointer(Const(D2D1_RECT_U)), "srcRect")]),
 +    Method(HRESULT, "CopyFromRenderTarget", [(Pointer(Const(D2D1_POINT_2U)), "destPoint"), (Pointer(ID2D1RenderTarget), "renderTarget"), (Pointer(Const(D2D1_RECT_U)), "srcRect")]),
 +    Method(HRESULT, "CopyFromMemory", [(Pointer(Const(D2D1_RECT_U)), "dstRect"), (OpaquePointer(Const(Void)), "srcData"), (UINT32, "pitch")]),
 +]
 +
 +ID2D1GradientStopCollection.methods += [
 +    Method(UINT32, "GetGradientStopCount", [], const=True),
 +    Method(Void, "GetGradientStops", [Out(Pointer(D2D1_GRADIENT_STOP), "gradientStops"), (UINT, "gradientStopsCount")], const=True),
 +    Method(D2D1_GAMMA, "GetColorInterpolationGamma", [], const=True),
 +    Method(D2D1_EXTEND_MODE, "GetExtendMode", [], const=True),
 +]
 +
 +ID2D1Brush.methods += [
 +    Method(Void, "SetOpacity", [(FLOAT, "opacity")]),
 +    Method(Void, "SetTransform", [(Pointer(Const(D2D1_MATRIX_3X2_F)), "transform")]),
 +    Method(FLOAT, "GetOpacity", [], const=True),
 +    Method(Void, "GetTransform", [Out(Pointer(D2D1_MATRIX_3X2_F), "transform")], const=True),
 +]
 +
 +ID2D1BitmapBrush.methods += [
 +    Method(Void, "SetExtendModeX", [(D2D1_EXTEND_MODE, "extendModeX")]),
 +    Method(Void, "SetExtendModeY", [(D2D1_EXTEND_MODE, "extendModeY")]),
 +    Method(Void, "SetInterpolationMode", [(D2D1_BITMAP_INTERPOLATION_MODE, "interpolationMode")]),
 +    Method(Void, "SetBitmap", [(Pointer(ID2D1Bitmap), "bitmap")]),
 +    Method(D2D1_EXTEND_MODE, "GetExtendModeX", [], const=True),
 +    Method(D2D1_EXTEND_MODE, "GetExtendModeY", [], const=True),
 +    Method(D2D1_BITMAP_INTERPOLATION_MODE, "GetInterpolationMode", [], const=True),
 +    Method(Void, "GetBitmap", [Out(Pointer(Pointer(ID2D1Bitmap)), "bitmap")], const=True),
 +]
 +
 +ID2D1SolidColorBrush.methods += [
 +    Method(Void, "SetColor", [(Pointer(Const(D2D1_COLOR_F)), "color")]),
 +    Method(D2D1_COLOR_F, "GetColor", [], const=True),
 +]
 +
 +ID2D1LinearGradientBrush.methods += [
 +    Method(Void, "SetStartPoint", [(D2D1_POINT_2F, "startPoint")]),
 +    Method(Void, "SetEndPoint", [(D2D1_POINT_2F, "endPoint")]),
 +    Method(D2D1_POINT_2F, "GetStartPoint", [], const=True),
 +    Method(D2D1_POINT_2F, "GetEndPoint", [], const=True),
 +    Method(Void, "GetGradientStopCollection", [Out(Pointer(Pointer(ID2D1GradientStopCollection)), "gradientStopCollection")], const=True),
 +]
 +
 +ID2D1RadialGradientBrush.methods += [
 +    Method(Void, "SetCenter", [(D2D1_POINT_2F, "center")]),
 +    Method(Void, "SetGradientOriginOffset", [(D2D1_POINT_2F, "gradientOriginOffset")]),
 +    Method(Void, "SetRadiusX", [(FLOAT, "radiusX")]),
 +    Method(Void, "SetRadiusY", [(FLOAT, "radiusY")]),
 +    Method(D2D1_POINT_2F, "GetCenter", [], const=True),
 +    Method(D2D1_POINT_2F, "GetGradientOriginOffset", [], const=True),
 +    Method(FLOAT, "GetRadiusX", [], const=True),
 +    Method(FLOAT, "GetRadiusY", [], const=True),
 +    Method(Void, "GetGradientStopCollection", [Out(Pointer(Pointer(ID2D1GradientStopCollection)), "gradientStopCollection")], const=True),
 +]
 +
 +ID2D1StrokeStyle.methods += [
 +    Method(D2D1_CAP_STYLE, "GetStartCap", [], const=True),
 +    Method(D2D1_CAP_STYLE, "GetEndCap", [], const=True),
 +    Method(D2D1_CAP_STYLE, "GetDashCap", [], const=True),
 +    Method(FLOAT, "GetMiterLimit", [], const=True),
 +    Method(D2D1_LINE_JOIN, "GetLineJoin", [], const=True),
 +    Method(FLOAT, "GetDashOffset", [], const=True),
 +    Method(D2D1_DASH_STYLE, "GetDashStyle", [], const=True),
 +    Method(UINT32, "GetDashesCount", [], const=True),
 +    Method(Void, "GetDashes", [Out(Array(FLOAT, "dashesCount"), "dashes"), (UINT, "dashesCount")], const=True),
 +]
 +
 +ID2D1Geometry.methods += [
 +    Method(HRESULT, "GetBounds", [(Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), Out(Pointer(D2D1_RECT_F), "bounds")], const=True),
 +    Method(HRESULT, "GetWidenedBounds", [(FLOAT, "strokeWidth"), (Pointer(ID2D1StrokeStyle), "strokeStyle"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(Pointer(D2D1_RECT_F), "bounds")], const=True),
 +    Method(HRESULT, "StrokeContainsPoint", [(D2D1_POINT_2F, "point"), (FLOAT, "strokeWidth"), (Pointer(ID2D1StrokeStyle), "strokeStyle"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(Pointer(BOOL), "contains")], const=True),
 +    Method(HRESULT, "FillContainsPoint", [(D2D1_POINT_2F, "point"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(Pointer(BOOL), "contains")], const=True),
 +    Method(HRESULT, "CompareWithGeometry", [(Pointer(ID2D1Geometry), "inputGeometry"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "inputGeometryTransform"), (FLOAT, "flatteningTolerance"), Out(Pointer(D2D1_GEOMETRY_RELATION), "relation")], const=True),
 +    Method(HRESULT, "Simplify", [(D2D1_GEOMETRY_SIMPLIFICATION_OPTION, "simplificationOption"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), (Pointer(ID2D1SimplifiedGeometrySink), "geometrySink")], const=True),
 +    Method(HRESULT, "Tessellate", [(Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), (Pointer(ID2D1TessellationSink), "tessellationSink")], const=True),
 +    Method(HRESULT, "CombineWithGeometry", [(Pointer(ID2D1Geometry), "inputGeometry"), (D2D1_COMBINE_MODE, "combineMode"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "inputGeometryTransform"), (FLOAT, "flatteningTolerance"), (Pointer(ID2D1SimplifiedGeometrySink), "geometrySink")], const=True),
 +    Method(HRESULT, "Outline", [(Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), (Pointer(ID2D1SimplifiedGeometrySink), "geometrySink")], const=True),
 +    Method(HRESULT, "ComputeArea", [(Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(Pointer(FLOAT), "area")], const=True),
 +    Method(HRESULT, "ComputeLength", [(Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(Pointer(FLOAT), "length")], const=True),
 +    Method(HRESULT, "ComputePointAtLength", [(FLOAT, "length"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), Out(Pointer(D2D1_POINT_2F), "point"), Out(Pointer(D2D1_POINT_2F), "unitTangentVector")], const=True),
 +    Method(HRESULT, "Widen", [(FLOAT, "strokeWidth"), (Pointer(ID2D1StrokeStyle), "strokeStyle"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "worldTransform"), (FLOAT, "flatteningTolerance"), (Pointer(ID2D1SimplifiedGeometrySink), "geometrySink")], const=True),
 +]
 +
 +ID2D1RectangleGeometry.methods += [
 +    Method(Void, "GetRect", [Out(Pointer(D2D1_RECT_F), "rect")], const=True),
 +]
 +
 +ID2D1RoundedRectangleGeometry.methods += [
 +    Method(Void, "GetRoundedRect", [Out(Pointer(D2D1_ROUNDED_RECT), "roundedRect")], const=True),
 +]
 +
 +ID2D1EllipseGeometry.methods += [
 +    Method(Void, "GetEllipse", [Out(Pointer(D2D1_ELLIPSE), "ellipse")], const=True),
 +]
 +
 +ID2D1GeometryGroup.methods += [
 +    Method(D2D1_FILL_MODE, "GetFillMode", [], const=True),
 +    Method(UINT32, "GetSourceGeometryCount", [], const=True),
 +    Method(Void, "GetSourceGeometries", [Out(Array(Pointer(ID2D1Geometry), "geometriesCount"), "geometries"), (UINT, "geometriesCount")], const=True),
 +]
 +
 +ID2D1TransformedGeometry.methods += [
 +    Method(Void, "GetSourceGeometry", [Out(Pointer(Pointer(ID2D1Geometry)), "sourceGeometry")], const=True),
 +    Method(Void, "GetTransform", [Out(Pointer(D2D1_MATRIX_3X2_F), "transform")], const=True),
 +]
 +
 +ID2D1SimplifiedGeometrySink.methods += [
 +    Method(Void, "SetFillMode", [(D2D1_FILL_MODE, "fillMode")]),
 +    Method(Void, "SetSegmentFlags", [(D2D1_PATH_SEGMENT, "vertexFlags")]),
 +    Method(Void, "BeginFigure", [(D2D1_POINT_2F, "startPoint"), (D2D1_FIGURE_BEGIN, "figureBegin")]),
 +    Method(Void, "AddLines", [(Array(Const(D2D1_POINT_2F), "pointsCount"), "points"), (UINT, "pointsCount")]),
 +    Method(Void, "AddBeziers", [(Array(Const(D2D1_BEZIER_SEGMENT), "beziersCount"), "beziers"), (UINT, "beziersCount")]),
 +    Method(Void, "EndFigure", [(D2D1_FIGURE_END, "figureEnd")]),
 +    Method(HRESULT, "Close", []),
 +]
 +
 +ID2D1GeometrySink.methods += [
 +    Method(Void, "AddLine", [(D2D1_POINT_2F, "point")]),
 +    Method(Void, "AddBezier", [(Pointer(Const(D2D1_BEZIER_SEGMENT)), "bezier")]),
 +    Method(Void, "AddQuadraticBezier", [(Pointer(Const(D2D1_QUADRATIC_BEZIER_SEGMENT)), "bezier")]),
 +    Method(Void, "AddQuadraticBeziers", [(Array(Const(D2D1_QUADRATIC_BEZIER_SEGMENT), "beziersCount"), "beziers"), (UINT, "beziersCount")]),
 +    Method(Void, "AddArc", [(Pointer(Const(D2D1_ARC_SEGMENT)), "arc")]),
 +]
 +
 +ID2D1TessellationSink.methods += [
 +    Method(Void, "AddTriangles", [(Array(Const(D2D1_TRIANGLE), "trianglesCount"), "triangles"), (UINT, "trianglesCount")]),
 +    Method(HRESULT, "Close", []),
 +]
 +
 +ID2D1PathGeometry.methods += [
 +    Method(HRESULT, "Open", [Out(Pointer(Pointer(ID2D1GeometrySink)), "geometrySink")]),
 +    Method(HRESULT, "Stream", [(Pointer(ID2D1GeometrySink), "geometrySink")], const=True),
 +    Method(HRESULT, "GetSegmentCount", [Out(Pointer(UINT32), "count")], const=True),
 +    Method(HRESULT, "GetFigureCount", [Out(Pointer(UINT32), "count")], const=True),
 +]
 +
 +ID2D1Mesh.methods += [
 +    Method(HRESULT, "Open", [Out(Pointer(Pointer(ID2D1TessellationSink)), "tessellationSink")]),
 +]
 +
 +ID2D1Layer.methods += [
 +    Method(D2D1_SIZE_F, "GetSize", [], const=True),
 +]
 +
 +ID2D1DrawingStateBlock.methods += [
 +    Method(Void, "GetDescription", [Out(Pointer(D2D1_DRAWING_STATE_DESCRIPTION), "stateDescription")], const=True),
 +    Method(Void, "SetDescription", [(Pointer(Const(D2D1_DRAWING_STATE_DESCRIPTION)), "stateDescription")]),
 +    Method(Void, "SetTextRenderingParams", [(Pointer(IDWriteRenderingParams), "textRenderingParams")]),
 +    Method(Void, "GetTextRenderingParams", [Out(Pointer(Pointer(IDWriteRenderingParams)), "textRenderingParams")], const=True),
 +]
 +
 +ID2D1RenderTarget.methods += [
 +    Method(HRESULT, "CreateBitmap", [(D2D1_SIZE_U, "size"), (OpaquePointer(Const(Void)), "srcData"), (UINT32, "pitch"), (Pointer(Const(D2D1_BITMAP_PROPERTIES)), "bitmapProperties"), Out(Pointer(Pointer(ID2D1Bitmap)), "bitmap")]),
 +    Method(HRESULT, "CreateBitmapFromWicBitmap", [(Opaque("IWICBitmapSource *"), "wicBitmapSource"), (Pointer(Const(D2D1_BITMAP_PROPERTIES)), "bitmapProperties"), Out(Pointer(Pointer(ID2D1Bitmap)), "bitmap")]),
 +    Method(HRESULT, "CreateSharedBitmap", [(REFIID, "riid"), Out(OpaquePointer(Void), "data"), (Pointer(Const(D2D1_BITMAP_PROPERTIES)), "bitmapProperties"), Out(Pointer(Pointer(ID2D1Bitmap)), "bitmap")]),
 +    Method(HRESULT, "CreateBitmapBrush", [(Pointer(ID2D1Bitmap), "bitmap"), (Pointer(Const(D2D1_BITMAP_BRUSH_PROPERTIES)), "bitmapBrushProperties"), (Pointer(Const(D2D1_BRUSH_PROPERTIES)), "brushProperties"), Out(Pointer(Pointer(ID2D1BitmapBrush)), "bitmapBrush")]),
 +    Method(HRESULT, "CreateSolidColorBrush", [(Pointer(Const(D2D1_COLOR_F)), "color"), (Pointer(Const(D2D1_BRUSH_PROPERTIES)), "brushProperties"), Out(Pointer(Pointer(ID2D1SolidColorBrush)), "solidColorBrush")]),
 +    Method(HRESULT, "CreateGradientStopCollection", [(Array(Const(D2D1_GRADIENT_STOP), "gradientStopsCount"), "gradientStops"), (UINT, "gradientStopsCount"), (D2D1_GAMMA, "colorInterpolationGamma"), (D2D1_EXTEND_MODE, "extendMode"), Out(Pointer(Pointer(ID2D1GradientStopCollection)), "gradientStopCollection")]),
 +    Method(HRESULT, "CreateLinearGradientBrush", [(Pointer(Const(D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES)), "linearGradientBrushProperties"), (Pointer(Const(D2D1_BRUSH_PROPERTIES)), "brushProperties"), (Pointer(ID2D1GradientStopCollection), "gradientStopCollection"), Out(Pointer(Pointer(ID2D1LinearGradientBrush)), "linearGradientBrush")]),
 +    Method(HRESULT, "CreateRadialGradientBrush", [(Pointer(Const(D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES)), "radialGradientBrushProperties"), (Pointer(Const(D2D1_BRUSH_PROPERTIES)), "brushProperties"), (Pointer(ID2D1GradientStopCollection), "gradientStopCollection"), Out(Pointer(Pointer(ID2D1RadialGradientBrush)), "radialGradientBrush")]),
 +    Method(HRESULT, "CreateCompatibleRenderTarget", [(Pointer(Const(D2D1_SIZE_F)), "desiredSize"), (Pointer(Const(D2D1_SIZE_U)), "desiredPixelSize"), (Pointer(Const(D2D1_PIXEL_FORMAT)), "desiredFormat"), (D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS, "options"), Out(Pointer(Pointer(ID2D1BitmapRenderTarget)), "bitmapRenderTarget")]),
 +    Method(HRESULT, "CreateLayer", [(Pointer(Const(D2D1_SIZE_F)), "size"), Out(Pointer(Pointer(ID2D1Layer)), "layer")]),
 +    Method(HRESULT, "CreateMesh", [Out(Pointer(Pointer(ID2D1Mesh)), "mesh")]),
 +    Method(Void, "DrawLine", [(D2D1_POINT_2F, "point0"), (D2D1_POINT_2F, "point1"), (Pointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (Pointer(ID2D1StrokeStyle), "strokeStyle")]),
 +    Method(Void, "DrawRectangle", [(Pointer(Const(D2D1_RECT_F)), "rect"), (Pointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (Pointer(ID2D1StrokeStyle), "strokeStyle")]),
 +    Method(Void, "FillRectangle", [(Pointer(Const(D2D1_RECT_F)), "rect"), (Pointer(ID2D1Brush), "brush")]),
 +    Method(Void, "DrawRoundedRectangle", [(Pointer(Const(D2D1_ROUNDED_RECT)), "roundedRect"), (Pointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (Pointer(ID2D1StrokeStyle), "strokeStyle")]),
 +    Method(Void, "FillRoundedRectangle", [(Pointer(Const(D2D1_ROUNDED_RECT)), "roundedRect"), (Pointer(ID2D1Brush), "brush")]),
 +    Method(Void, "DrawEllipse", [(Pointer(Const(D2D1_ELLIPSE)), "ellipse"), (Pointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (Pointer(ID2D1StrokeStyle), "strokeStyle")]),
 +    Method(Void, "FillEllipse", [(Pointer(Const(D2D1_ELLIPSE)), "ellipse"), (Pointer(ID2D1Brush), "brush")]),
 +    Method(Void, "DrawGeometry", [(Pointer(ID2D1Geometry), "geometry"), (Pointer(ID2D1Brush), "brush"), (FLOAT, "strokeWidth"), (Pointer(ID2D1StrokeStyle), "strokeStyle")]),
 +    Method(Void, "FillGeometry", [(Pointer(ID2D1Geometry), "geometry"), (Pointer(ID2D1Brush), "brush"), (Pointer(ID2D1Brush), "opacityBrush")]),
 +    Method(Void, "FillMesh", [(Pointer(ID2D1Mesh), "mesh"), (Pointer(ID2D1Brush), "brush")]),
 +    Method(Void, "FillOpacityMask", [(Pointer(ID2D1Bitmap), "opacityMask"), (Pointer(ID2D1Brush), "brush"), (D2D1_OPACITY_MASK_CONTENT, "content"), (Pointer(Const(D2D1_RECT_F)), "destinationRectangle"), (Pointer(Const(D2D1_RECT_F)), "sourceRectangle")]),
 +    Method(Void, "DrawBitmap", [(Pointer(ID2D1Bitmap), "bitmap"), (Pointer(Const(D2D1_RECT_F)), "destinationRectangle"), (FLOAT, "opacity"), (D2D1_BITMAP_INTERPOLATION_MODE, "interpolationMode"), (Pointer(Const(D2D1_RECT_F)), "sourceRectangle")]),
 +    Method(Void, "DrawText", [(Pointer(Const(WCHAR)), "string"), (UINT, "stringLength"), (Pointer(IDWriteTextFormat), "textFormat"), (Pointer(Const(D2D1_RECT_F)), "layoutRect"), (Pointer(ID2D1Brush), "defaultForegroundBrush"), (D2D1_DRAW_TEXT_OPTIONS, "options"), (DWRITE_MEASURING_MODE, "measuringMode")]),
 +    Method(Void, "DrawTextLayout", [(D2D1_POINT_2F, "origin"), (Pointer(IDWriteTextLayout), "textLayout"), (Pointer(ID2D1Brush), "defaultForegroundBrush"), (D2D1_DRAW_TEXT_OPTIONS, "options")]),
 +    Method(Void, "DrawGlyphRun", [(D2D1_POINT_2F, "baselineOrigin"), (Pointer(Const(DWRITE_GLYPH_RUN)), "glyphRun"), (Pointer(ID2D1Brush), "foregroundBrush"), (DWRITE_MEASURING_MODE, "measuringMode")]),
 +    Method(Void, "SetTransform", [(Pointer(Const(D2D1_MATRIX_3X2_F)), "transform")]),
 +    Method(Void, "GetTransform", [Out(Pointer(D2D1_MATRIX_3X2_F), "transform")], const=True),
 +    Method(Void, "SetAntialiasMode", [(D2D1_ANTIALIAS_MODE, "antialiasMode")]),
 +    Method(D2D1_ANTIALIAS_MODE, "GetAntialiasMode", [], const=True),
 +    Method(Void, "SetTextAntialiasMode", [(D2D1_TEXT_ANTIALIAS_MODE, "textAntialiasMode")]),
 +    Method(D2D1_TEXT_ANTIALIAS_MODE, "GetTextAntialiasMode", [], const=True),
 +    Method(Void, "SetTextRenderingParams", [(Pointer(IDWriteRenderingParams), "textRenderingParams")]),
 +    Method(Void, "GetTextRenderingParams", [Out(Pointer(Pointer(IDWriteRenderingParams)), "textRenderingParams")], const=True),
 +    Method(Void, "SetTags", [(D2D1_TAG, "tag1"), (D2D1_TAG, "tag2")]),
 +    Method(Void, "GetTags", [Out(Pointer(D2D1_TAG), "tag1"), Out(Pointer(D2D1_TAG), "tag2")], const=True),
 +    Method(Void, "PushLayer", [(Pointer(Const(D2D1_LAYER_PARAMETERS)), "layerParameters"), (Pointer(ID2D1Layer), "layer")]),
 +    Method(Void, "PopLayer", []),
 +    Method(HRESULT, "Flush", [Out(Pointer(D2D1_TAG), "tag1"), Out(Pointer(D2D1_TAG), "tag2")]),
 +    Method(Void, "SaveDrawingState", [Out(Pointer(ID2D1DrawingStateBlock), "drawingStateBlock")], const=True),
 +    Method(Void, "RestoreDrawingState", [(Pointer(ID2D1DrawingStateBlock), "drawingStateBlock")]),
 +    Method(Void, "PushAxisAlignedClip", [(Pointer(Const(D2D1_RECT_F)), "clipRect"), (D2D1_ANTIALIAS_MODE, "antialiasMode")]),
 +    Method(Void, "PopAxisAlignedClip", []),
 +    Method(Void, "Clear", [(Pointer(Const(D2D1_COLOR_F)), "clearColor")]),
 +    Method(Void, "BeginDraw", []),
 +    Method(HRESULT, "EndDraw", [Out(Pointer(D2D1_TAG), "tag1"), Out(Pointer(D2D1_TAG), "tag2")]),
 +    Method(D2D1_PIXEL_FORMAT, "GetPixelFormat", [], const=True),
 +    Method(Void, "SetDpi", [(FLOAT, "dpiX"), (FLOAT, "dpiY")]),
 +    Method(Void, "GetDpi", [Out(Pointer(FLOAT), "dpiX"), Out(Pointer(FLOAT), "dpiY")], const=True),
 +    Method(D2D1_SIZE_F, "GetSize", [], const=True),
 +    Method(D2D1_SIZE_U, "GetPixelSize", [], const=True),
 +    Method(UINT32, "GetMaximumBitmapSize", [], const=True),
 +    Method(BOOL, "IsSupported", [(Pointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties")], const=True),
 +]
 +
 +ID2D1BitmapRenderTarget.methods += [
 +    Method(HRESULT, "GetBitmap", [Out(Pointer(Pointer(ID2D1Bitmap)), "bitmap")]),
 +]
 +
 +ID2D1HwndRenderTarget.methods += [
 +    Method(D2D1_WINDOW_STATE, "CheckWindowState", []),
 +    Method(HRESULT, "Resize", [(Pointer(Const(D2D1_SIZE_U)), "pixelSize")]),
 +    Method(HWND, "GetHwnd", [], const=True),
 +]
 +
 +ID2D1GdiInteropRenderTarget.methods += [
 +    Method(HRESULT, "GetDC", [(D2D1_DC_INITIALIZE_MODE, "mode"), Out(Pointer(HDC), "hdc")]),
 +    Method(HRESULT, "ReleaseDC", [(Pointer(Const(RECT)), "update")]),
 +]
 +
 +ID2D1DCRenderTarget.methods += [
 +    Method(HRESULT, "BindDC", [(Const(HDC), "hDC"), (Pointer(Const(RECT)), "pSubRect")]),
 +]
 +
 +ID2D1Factory.methods += [
 +    Method(HRESULT, "ReloadSystemMetrics", []),
 +    Method(Void, "GetDesktopDpi", [Out(Pointer(FLOAT), "dpiX"), Out(Pointer(FLOAT), "dpiY")]),
 +    Method(HRESULT, "CreateRectangleGeometry", [(Pointer(Const(D2D1_RECT_F)), "rectangle"), Out(Pointer(Pointer(ID2D1RectangleGeometry)), "rectangleGeometry")]),
 +    Method(HRESULT, "CreateRoundedRectangleGeometry", [(Pointer(Const(D2D1_ROUNDED_RECT)), "roundedRectangle"), Out(Pointer(Pointer(ID2D1RoundedRectangleGeometry)), "roundedRectangleGeometry")]),
 +    Method(HRESULT, "CreateEllipseGeometry", [(Pointer(Const(D2D1_ELLIPSE)), "ellipse"), Out(Pointer(Pointer(ID2D1EllipseGeometry)), "ellipseGeometry")]),
 +    Method(HRESULT, "CreateGeometryGroup", [(D2D1_FILL_MODE, "fillMode"), (Pointer(Pointer(ID2D1Geometry)), "geometries"), (UINT, "geometriesCount"), Out(Pointer(Pointer(ID2D1GeometryGroup)), "geometryGroup")]),
 +    Method(HRESULT, "CreateTransformedGeometry", [(Pointer(ID2D1Geometry), "sourceGeometry"), (Pointer(Const(D2D1_MATRIX_3X2_F)), "transform"), Out(Pointer(Pointer(ID2D1TransformedGeometry)), "transformedGeometry")]),
 +    Method(HRESULT, "CreatePathGeometry", [Out(Pointer(Pointer(ID2D1PathGeometry)), "pathGeometry")]),
 +    Method(HRESULT, "CreateStrokeStyle", [(Pointer(Const(D2D1_STROKE_STYLE_PROPERTIES)), "strokeStyleProperties"), (Pointer(Const(FLOAT)), "dashes"), (UINT, "dashesCount"), Out(Pointer(Pointer(ID2D1StrokeStyle)), "strokeStyle")]),
 +    Method(HRESULT, "CreateDrawingStateBlock", [(Pointer(Const(D2D1_DRAWING_STATE_DESCRIPTION)), "drawingStateDescription"), (Pointer(IDWriteRenderingParams), "textRenderingParams"), Out(Pointer(Pointer(ID2D1DrawingStateBlock)), "drawingStateBlock")]),
 +    Method(HRESULT, "CreateWicBitmapRenderTarget", [(Opaque("IWICBitmap *"), "target"), (Pointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties"), Out(Pointer(Pointer(ID2D1RenderTarget)), "renderTarget")]),
 +    Method(HRESULT, "CreateHwndRenderTarget", [(Pointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties"), (Pointer(Const(D2D1_HWND_RENDER_TARGET_PROPERTIES)), "hwndRenderTargetProperties"), Out(Pointer(Pointer(ID2D1HwndRenderTarget)), "hwndRenderTarget")]),
 +    Method(HRESULT, "CreateDxgiSurfaceRenderTarget", [(Pointer(IDXGISurface), "dxgiSurface"), (Pointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties"), Out(Pointer(Pointer(ID2D1RenderTarget)), "renderTarget")]),
 +    Method(HRESULT, "CreateDCRenderTarget", [(Pointer(Const(D2D1_RENDER_TARGET_PROPERTIES)), "renderTargetProperties"), Out(Pointer(Pointer(ID2D1DCRenderTarget)), "dcRenderTarget")]),
 +]
 +
 +d2d1 = API("d2d1")
++d2d1.addInterface(ID2D1Factory)
++d2d1.addFunctions([
 +    StdFunction(HRESULT, "D2D1CreateFactory", [(D2D1_FACTORY_TYPE, "factoryType"), (REFIID, "riid"), (Pointer(Const(D2D1_FACTORY_OPTIONS)), "pFactoryOptions"), Out(Pointer(OpaquePointer(Void)), "ppIFactory")]),
 +    StdFunction(Void, "D2D1MakeRotateMatrix", [(FLOAT, "angle"), (D2D1_POINT_2F, "center"), Out(Pointer(D2D1_MATRIX_3X2_F), "matrix")]),
 +    StdFunction(Void, "D2D1MakeSkewMatrix", [(FLOAT, "angleX"), (FLOAT, "angleY"), (D2D1_POINT_2F, "center"), Out(Pointer(D2D1_MATRIX_3X2_F), "matrix")]),
 +    StdFunction(BOOL, "D2D1IsMatrixInvertible", [(Pointer(Const(D2D1_MATRIX_3X2_F)), "matrix")]),
 +    StdFunction(BOOL, "D2D1InvertMatrix", [Out(Pointer(D2D1_MATRIX_3X2_F), "matrix")]),
 +])
diff --combined specs/dwrite.py
index dd9286255a3cdc07da6b35f9e60382a37485374a,0000000000000000000000000000000000000000..dac621100456750a83004be400184ae810d07618
mode 100644,000000..100644
--- /dev/null
@@@ -1,776 -1,0 +1,776 @@@
- dwrite.add_interface(IDWriteFactory)
- dwrite.add_functions([
 +##########################################################################
 +#
 +# Copyright 2011 Jose Fonseca
 +# All Rights Reserved.
 +#
 +# Permission is hereby granted, free of charge, to any person obtaining a copy
 +# of this software and associated documentation files (the "Software"), to deal
 +# in the Software without restriction, including without limitation the rights
 +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 +# copies of the Software, and to permit persons to whom the Software is
 +# furnished to do so, subject to the following conditions:
 +#
 +# The above copyright notice and this permission notice shall be included in
 +# all copies or substantial portions of the Software.
 +#
 +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 +# THE SOFTWARE.
 +#
 +##########################################################################/
 +
 +
 +from winapi import *
 +from dcommon import *
 +
 +
 +ID2D1SimplifiedGeometrySink = Interface("ID2D1SimplifiedGeometrySink", IUnknown)
 +IDWriteGeometrySink = Alias("IDWriteGeometrySink", ID2D1SimplifiedGeometrySink)
 +
 +IDWriteFontFileLoader = Interface("IDWriteFontFileLoader", IUnknown)
 +IDWriteLocalFontFileLoader = Interface("IDWriteLocalFontFileLoader", IDWriteFontFileLoader)
 +IDWriteFontFileStream = Interface("IDWriteFontFileStream", IUnknown)
 +IDWriteFontFile = Interface("IDWriteFontFile", IUnknown)
 +IDWriteRenderingParams = Interface("IDWriteRenderingParams", IUnknown)
 +IDWriteFontFace = Interface("IDWriteFontFace", IUnknown)
 +IDWriteFontCollectionLoader = Interface("IDWriteFontCollectionLoader", IUnknown)
 +IDWriteFontFileEnumerator = Interface("IDWriteFontFileEnumerator", IUnknown)
 +IDWriteLocalizedStrings = Interface("IDWriteLocalizedStrings", IUnknown)
 +IDWriteFontCollection = Interface("IDWriteFontCollection", IUnknown)
 +IDWriteFontList = Interface("IDWriteFontList", IUnknown)
 +IDWriteFontFamily = Interface("IDWriteFontFamily", IDWriteFontList)
 +IDWriteFont = Interface("IDWriteFont", IUnknown)
 +IDWriteTextFormat = Interface("IDWriteTextFormat", IUnknown)
 +IDWriteTypography = Interface("IDWriteTypography", IUnknown)
 +IDWriteNumberSubstitution = Interface("IDWriteNumberSubstitution", IUnknown)
 +IDWriteTextAnalysisSource = Interface("IDWriteTextAnalysisSource", IUnknown)
 +IDWriteTextAnalysisSink = Interface("IDWriteTextAnalysisSink", IUnknown)
 +IDWriteTextAnalyzer = Interface("IDWriteTextAnalyzer", IUnknown)
 +IDWriteInlineObject = Interface("IDWriteInlineObject", IUnknown)
 +IDWritePixelSnapping = Interface("IDWritePixelSnapping", IUnknown)
 +IDWriteTextRenderer = Interface("IDWriteTextRenderer", IDWritePixelSnapping)
 +IDWriteTextLayout = Interface("IDWriteTextLayout", IDWriteTextFormat)
 +IDWriteBitmapRenderTarget = Interface("IDWriteBitmapRenderTarget", IUnknown)
 +IDWriteGdiInterop = Interface("IDWriteGdiInterop", IUnknown)
 +IDWriteGlyphRunAnalysis = Interface("IDWriteGlyphRunAnalysis", IUnknown)
 +IDWriteFactory = Interface("IDWriteFactory", IUnknown)
 +
 +
 +def EnumFlag(expr, values):
 +    return Flags(Alias(expr, DWORD), values)
 +
 +
 +DWRITE_FONT_FILE_TYPE = Enum("DWRITE_FONT_FILE_TYPE", [
 +    "DWRITE_FONT_FILE_TYPE_UNKNOWN",
 +    "DWRITE_FONT_FILE_TYPE_CFF",
 +    "DWRITE_FONT_FILE_TYPE_TRUETYPE",
 +    "DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION",
 +    "DWRITE_FONT_FILE_TYPE_TYPE1_PFM",
 +    "DWRITE_FONT_FILE_TYPE_TYPE1_PFB",
 +    "DWRITE_FONT_FILE_TYPE_VECTOR",
 +    "DWRITE_FONT_FILE_TYPE_BITMAP",
 +])
 +
 +DWRITE_FONT_FACE_TYPE = Enum("DWRITE_FONT_FACE_TYPE", [
 +    "DWRITE_FONT_FACE_TYPE_CFF",
 +    "DWRITE_FONT_FACE_TYPE_TRUETYPE",
 +    "DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION",
 +    "DWRITE_FONT_FACE_TYPE_TYPE1",
 +    "DWRITE_FONT_FACE_TYPE_VECTOR",
 +    "DWRITE_FONT_FACE_TYPE_BITMAP",
 +    "DWRITE_FONT_FACE_TYPE_UNKNOWN",
 +])
 +
 +DWRITE_FONT_SIMULATIONS = EnumFlag("DWRITE_FONT_SIMULATIONS", [
 +    "DWRITE_FONT_SIMULATIONS_NONE",
 +    "DWRITE_FONT_SIMULATIONS_BOLD",
 +    "DWRITE_FONT_SIMULATIONS_OBLIQUE",
 +])
 +
 +DWRITE_FONT_WEIGHT = Enum("DWRITE_FONT_WEIGHT", [
 +    "DWRITE_FONT_WEIGHT_THIN",
 +    "DWRITE_FONT_WEIGHT_EXTRA_LIGHT",
 +    #"DWRITE_FONT_WEIGHT_ULTRA_LIGHT",
 +    "DWRITE_FONT_WEIGHT_LIGHT",
 +    "DWRITE_FONT_WEIGHT_NORMAL",
 +    #"DWRITE_FONT_WEIGHT_REGULAR",
 +    "DWRITE_FONT_WEIGHT_MEDIUM",
 +    "DWRITE_FONT_WEIGHT_DEMI_BOLD",
 +    #"DWRITE_FONT_WEIGHT_SEMI_BOLD",
 +    "DWRITE_FONT_WEIGHT_BOLD",
 +    "DWRITE_FONT_WEIGHT_EXTRA_BOLD",
 +    #"DWRITE_FONT_WEIGHT_ULTRA_BOLD",
 +    "DWRITE_FONT_WEIGHT_BLACK",
 +    #"DWRITE_FONT_WEIGHT_HEAVY",
 +    "DWRITE_FONT_WEIGHT_EXTRA_BLACK",
 +    #"DWRITE_FONT_WEIGHT_ULTRA_BLACK",
 +])
 +
 +DWRITE_FONT_STRETCH = Enum("DWRITE_FONT_STRETCH", [
 +    "DWRITE_FONT_STRETCH_UNDEFINED",
 +    "DWRITE_FONT_STRETCH_ULTRA_CONDENSED",
 +    "DWRITE_FONT_STRETCH_EXTRA_CONDENSED",
 +    "DWRITE_FONT_STRETCH_CONDENSED",
 +    "DWRITE_FONT_STRETCH_SEMI_CONDENSED",
 +    "DWRITE_FONT_STRETCH_NORMAL",
 +    #"DWRITE_FONT_STRETCH_MEDIUM",
 +    "DWRITE_FONT_STRETCH_SEMI_EXPANDED",
 +    "DWRITE_FONT_STRETCH_EXPANDED",
 +    "DWRITE_FONT_STRETCH_EXTRA_EXPANDED",
 +    "DWRITE_FONT_STRETCH_ULTRA_EXPANDED",
 +])
 +
 +DWRITE_FONT_STYLE = Enum("DWRITE_FONT_STYLE", [
 +    "DWRITE_FONT_STYLE_NORMAL",
 +    "DWRITE_FONT_STYLE_OBLIQUE",
 +    "DWRITE_FONT_STYLE_ITALIC",
 +])
 +
 +DWRITE_INFORMATIONAL_STRING_ID = Enum("DWRITE_INFORMATIONAL_STRING_ID", [
 +    "DWRITE_INFORMATIONAL_STRING_NONE",
 +    "DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE",
 +    "DWRITE_INFORMATIONAL_STRING_VERSION_STRINGS",
 +    "DWRITE_INFORMATIONAL_STRING_TRADEMARK",
 +    "DWRITE_INFORMATIONAL_STRING_MANUFACTURER",
 +    "DWRITE_INFORMATIONAL_STRING_DESIGNER",
 +    "DWRITE_INFORMATIONAL_STRING_DESIGNER_URL",
 +    "DWRITE_INFORMATIONAL_STRING_DESCRIPTION",
 +    "DWRITE_INFORMATIONAL_STRING_FONT_VENDOR_URL",
 +    "DWRITE_INFORMATIONAL_STRING_LICENSE_DESCRIPTION",
 +    "DWRITE_INFORMATIONAL_STRING_LICENSE_INFO_URL",
 +    "DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES",
 +    "DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES",
 +    "DWRITE_INFORMATIONAL_STRING_PREFERRED_FAMILY_NAMES",
 +    "DWRITE_INFORMATIONAL_STRING_PREFERRED_SUBFAMILY_NAMES",
 +    "DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT",
 +])
 +
 +DWRITE_FONT_METRICS = Struct("DWRITE_FONT_METRICS", [
 +    (UINT16, "designUnitsPerEm"),
 +    (UINT16, "ascent"),
 +    (UINT16, "descent"),
 +    (INT16, "lineGap"),
 +    (UINT16, "capHeight"),
 +    (UINT16, "xHeight"),
 +    (INT16, "underlinePosition"),
 +    (UINT16, "underlineThickness"),
 +    (INT16, "strikethroughPosition"),
 +    (UINT16, "strikethroughThickness"),
 +])
 +
 +DWRITE_GLYPH_METRICS = Struct("DWRITE_GLYPH_METRICS", [
 +    (INT32, "leftSideBearing"),
 +    (UINT32, "advanceWidth"),
 +    (INT32, "rightSideBearing"),
 +    (INT32, "topSideBearing"),
 +    (UINT32, "advanceHeight"),
 +    (INT32, "bottomSideBearing"),
 +    (INT32, "verticalOriginY"),
 +])
 +
 +DWRITE_GLYPH_OFFSET = Struct("DWRITE_GLYPH_OFFSET", [
 +    (FLOAT, "advanceOffset"),
 +    (FLOAT, "ascenderOffset"),
 +])
 +
 +DWRITE_FACTORY_TYPE = Enum("DWRITE_FACTORY_TYPE", [
 +    "DWRITE_FACTORY_TYPE_SHARED",
 +    "DWRITE_FACTORY_TYPE_ISOLATED",
 +])
 +
 +IDWriteFontFileLoader.methods += [
 +    Method(HRESULT, "CreateStreamFromKey", [(OpaquePointer(Const(Void)), "fontFileReferenceKey"), (UINT32, "fontFileReferenceKeySize"), Out(Pointer(Pointer(IDWriteFontFileStream)), "fontFileStream")]),
 +]
 +
 +IDWriteLocalFontFileLoader.methods += [
 +    Method(HRESULT, "GetFilePathLengthFromKey", [(OpaquePointer(Const(Void)), "fontFileReferenceKey"), (UINT32, "fontFileReferenceKeySize"), Out(Pointer(UINT32), "filePathLength")]),
 +    Method(HRESULT, "GetFilePathFromKey", [(OpaquePointer(Const(Void)), "fontFileReferenceKey"), (UINT32, "fontFileReferenceKeySize"), Out(Pointer(WCHAR), "filePath"), (UINT32, "filePathSize")]),
 +    Method(HRESULT, "GetLastWriteTimeFromKey", [(OpaquePointer(Const(Void)), "fontFileReferenceKey"), (UINT32, "fontFileReferenceKeySize"), Out(Pointer(FILETIME), "lastWriteTime")]),
 +]
 +
 +IDWriteFontFileStream.methods += [
 +    Method(HRESULT, "ReadFileFragment", [Out(Pointer(OpaquePointer(Const(Void))), "fragmentStart"), (UINT64, "fileOffset"), (UINT64, "fragmentSize"), Out(Pointer(OpaquePointer(Void)), "fragmentContext")]),
 +    Method(Void, "ReleaseFileFragment", [(OpaquePointer(Void), "fragmentContext")]),
 +    Method(HRESULT, "GetFileSize", [Out(Pointer(UINT64), "fileSize")]),
 +    Method(HRESULT, "GetLastWriteTime", [Out(Pointer(UINT64), "lastWriteTime")]),
 +]
 +
 +IDWriteFontFile.methods += [
 +    Method(HRESULT, "GetReferenceKey", [Out(Pointer(OpaquePointer(Const(Void))), "fontFileReferenceKey"), Out(Pointer(UINT32), "fontFileReferenceKeySize")]),
 +    Method(HRESULT, "GetLoader", [Out(Pointer(Pointer(IDWriteFontFileLoader)), "fontFileLoader")]),
 +    Method(HRESULT, "Analyze", [Out(Pointer(BOOL), "isSupportedFontType"), Out(Pointer(DWRITE_FONT_FILE_TYPE), "fontFileType"), Out(Pointer(DWRITE_FONT_FACE_TYPE), "fontFaceType"), Out(Pointer(UINT32), "numberOfFaces")]),
 +]
 +
 +DWRITE_PIXEL_GEOMETRY = Enum("DWRITE_PIXEL_GEOMETRY", [
 +    "DWRITE_PIXEL_GEOMETRY_FLAT",
 +    "DWRITE_PIXEL_GEOMETRY_RGB",
 +    "DWRITE_PIXEL_GEOMETRY_BGR",
 +])
 +
 +DWRITE_RENDERING_MODE = Enum("DWRITE_RENDERING_MODE", [
 +    "DWRITE_RENDERING_MODE_DEFAULT",
 +    "DWRITE_RENDERING_MODE_ALIASED",
 +    "DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC",
 +    "DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL",
 +    "DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL",
 +    "DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC",
 +    "DWRITE_RENDERING_MODE_OUTLINE",
 +])
 +
 +DWRITE_MATRIX = Struct("DWRITE_MATRIX", [
 +    (FLOAT, "m11"),
 +    (FLOAT, "m12"),
 +    (FLOAT, "m21"),
 +    (FLOAT, "m22"),
 +    (FLOAT, "dx"),
 +    (FLOAT, "dy"),
 +])
 +
 +IDWriteRenderingParams.methods += [
 +    Method(FLOAT, "GetGamma", []),
 +    Method(FLOAT, "GetEnhancedContrast", []),
 +    Method(FLOAT, "GetClearTypeLevel", []),
 +    Method(DWRITE_PIXEL_GEOMETRY, "GetPixelGeometry", []),
 +    Method(DWRITE_RENDERING_MODE, "GetRenderingMode", []),
 +]
 +
 +IDWriteFontFace.methods += [
 +    Method(DWRITE_FONT_FACE_TYPE, "GetType", []),
 +    Method(HRESULT, "GetFiles", [(OpaquePointer(UINT32), "numberOfFiles"), Out(Pointer(Pointer(IDWriteFontFile)), "fontFiles")]),
 +    Method(UINT32, "GetIndex", []),
 +    Method(DWRITE_FONT_SIMULATIONS, "GetSimulations", []),
 +    Method(BOOL, "IsSymbolFont", []),
 +    Method(Void, "GetMetrics", [Out(Pointer(DWRITE_FONT_METRICS), "fontFaceMetrics")]),
 +    Method(UINT16, "GetGlyphCount", []),
 +    Method(HRESULT, "GetDesignGlyphMetrics", [(Pointer(Const(UINT16)), "glyphIndices"), (UINT32, "glyphCount"), Out(Pointer(DWRITE_GLYPH_METRICS), "glyphMetrics"), (BOOL, "isSideways")]),
 +    Method(HRESULT, "GetGlyphIndices", [(Pointer(Const(UINT32)), "codePoints"), (UINT32, "codePointCount"), Out(Pointer(UINT16), "glyphIndices")]),
 +    Method(HRESULT, "TryGetFontTable", [(UINT32, "openTypeTableTag"), Out(Pointer(OpaquePointer(Const(Void))), "tableData"), Out(Pointer(UINT32), "tableSize"), Out(Pointer(OpaquePointer(Void)), "tableContext"), Out(Pointer(BOOL), "exists")]),
 +    Method(Void, "ReleaseFontTable", [(OpaquePointer(Void), "tableContext")]),
 +    Method(HRESULT, "GetGlyphRunOutline", [(FLOAT, "emSize"), (Pointer(Const(UINT16)), "glyphIndices"), (Pointer(Const(FLOAT)), "glyphAdvances"), (Pointer(Const(DWRITE_GLYPH_OFFSET)), "glyphOffsets"), (UINT32, "glyphCount"), (BOOL, "isSideways"), (BOOL, "isRightToLeft"), (Pointer(IDWriteGeometrySink), "geometrySink")]),
 +    Method(HRESULT, "GetRecommendedRenderingMode", [(FLOAT, "emSize"), (FLOAT, "pixelsPerDip"), (DWRITE_MEASURING_MODE, "measuringMode"), (Pointer(IDWriteRenderingParams), "renderingParams"), Out(Pointer(DWRITE_RENDERING_MODE), "renderingMode")]),
 +    Method(HRESULT, "GetGdiCompatibleMetrics", [(FLOAT, "emSize"), (FLOAT, "pixelsPerDip"), (Pointer(Const(DWRITE_MATRIX)), "transform"), Out(Pointer(DWRITE_FONT_METRICS), "fontFaceMetrics")]),
 +    Method(HRESULT, "GetGdiCompatibleGlyphMetrics", [(FLOAT, "emSize"), (FLOAT, "pixelsPerDip"), (Pointer(Const(DWRITE_MATRIX)), "transform"), (BOOL, "useGdiNatural"), (Array(Const(UINT16), "glyphCount"), "glyphIndices"), (UINT32, "glyphCount"), Out(Array(DWRITE_GLYPH_METRICS, "glyphCount"), "glyphMetrics"), (BOOL, "isSideways")]),
 +]
 +
 +IDWriteFontCollectionLoader.methods += [
 +    Method(HRESULT, "CreateEnumeratorFromKey", [(Pointer(IDWriteFactory), "factory"), (OpaquePointer(Const(Void)), "collectionKey"), (UINT32, "collectionKeySize"), Out(Pointer(Pointer(IDWriteFontFileEnumerator)), "fontFileEnumerator")]),
 +]
 +
 +IDWriteFontFileEnumerator.methods += [
 +    Method(HRESULT, "MoveNext", [Out(Pointer(BOOL), "hasCurrentFile")]),
 +    Method(HRESULT, "GetCurrentFontFile", [Out(Pointer(Pointer(IDWriteFontFile)), "fontFile")]),
 +]
 +
 +IDWriteLocalizedStrings.methods += [
 +    Method(UINT32, "GetCount", []),
 +    Method(HRESULT, "FindLocaleName", [(Pointer(Const(WCHAR)), "localeName"), Out(Pointer(UINT32), "index"), Out(Pointer(BOOL), "exists")]),
 +    Method(HRESULT, "GetLocaleNameLength", [(UINT32, "index"), Out(Pointer(UINT32), "length")]),
 +    Method(HRESULT, "GetLocaleName", [(UINT32, "index"), Out(Pointer(WCHAR), "localeName"), (UINT32, "size")]),
 +    Method(HRESULT, "GetStringLength", [(UINT32, "index"), Out(Pointer(UINT32), "length")]),
 +    Method(HRESULT, "GetString", [(UINT32, "index"), Out(Pointer(WCHAR), "stringBuffer"), (UINT32, "size")]),
 +]
 +
 +IDWriteFontCollection.methods += [
 +    Method(UINT32, "GetFontFamilyCount", []),
 +    Method(HRESULT, "GetFontFamily", [(UINT32, "index"), Out(Pointer(Pointer(IDWriteFontFamily)), "fontFamily")]),
 +    Method(HRESULT, "FindFamilyName", [(Pointer(Const(WCHAR)), "familyName"), Out(Pointer(UINT32), "index"), Out(Pointer(BOOL), "exists")]),
 +    Method(HRESULT, "GetFontFromFontFace", [(Pointer(IDWriteFontFace), "fontFace"), Out(Pointer(Pointer(IDWriteFont)), "font")]),
 +]
 +
 +IDWriteFontList.methods += [
 +    Method(HRESULT, "GetFontCollection", [Out(Pointer(Pointer(IDWriteFontCollection)), "fontCollection")]),
 +    Method(UINT32, "GetFontCount", []),
 +    Method(HRESULT, "GetFont", [(UINT32, "index"), Out(Pointer(Pointer(IDWriteFont)), "font")]),
 +]
 +
 +IDWriteFontFamily.methods += [
 +    Method(HRESULT, "GetFamilyNames", [Out(Pointer(Pointer(IDWriteLocalizedStrings)), "names")]),
 +    Method(HRESULT, "GetFirstMatchingFont", [(DWRITE_FONT_WEIGHT, "weight"), (DWRITE_FONT_STRETCH, "stretch"), (DWRITE_FONT_STYLE, "style"), Out(Pointer(Pointer(IDWriteFont)), "matchingFont")]),
 +    Method(HRESULT, "GetMatchingFonts", [(DWRITE_FONT_WEIGHT, "weight"), (DWRITE_FONT_STRETCH, "stretch"), (DWRITE_FONT_STYLE, "style"), Out(Pointer(Pointer(IDWriteFontList)), "matchingFonts")]),
 +]
 +
 +IDWriteFont.methods += [
 +    Method(HRESULT, "GetFontFamily", [Out(Pointer(Pointer(IDWriteFontFamily)), "fontFamily")]),
 +    Method(DWRITE_FONT_WEIGHT, "GetWeight", []),
 +    Method(DWRITE_FONT_STRETCH, "GetStretch", []),
 +    Method(DWRITE_FONT_STYLE, "GetStyle", []),
 +    Method(BOOL, "IsSymbolFont", []),
 +    Method(HRESULT, "GetFaceNames", [Out(Pointer(Pointer(IDWriteLocalizedStrings)), "names")]),
 +    Method(HRESULT, "GetInformationalStrings", [(DWRITE_INFORMATIONAL_STRING_ID, "informationalStringID"), Out(Pointer(Pointer(IDWriteLocalizedStrings)), "informationalStrings"), Out(Pointer(BOOL), "exists")]),
 +    Method(DWRITE_FONT_SIMULATIONS, "GetSimulations", []),
 +    Method(Void, "GetMetrics", [Out(Pointer(DWRITE_FONT_METRICS), "fontMetrics")]),
 +    Method(HRESULT, "HasCharacter", [(UINT32, "unicodeValue"), Out(Pointer(BOOL), "exists")]),
 +    Method(HRESULT, "CreateFontFace", [Out(Pointer(Pointer(IDWriteFontFace)), "fontFace")]),
 +]
 +
 +DWRITE_READING_DIRECTION = Enum("DWRITE_READING_DIRECTION", [
 +    "DWRITE_READING_DIRECTION_LEFT_TO_RIGHT",
 +    "DWRITE_READING_DIRECTION_RIGHT_TO_LEFT",
 +])
 +
 +DWRITE_FLOW_DIRECTION = Enum("DWRITE_FLOW_DIRECTION", [
 +    "DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM",
 +])
 +
 +DWRITE_TEXT_ALIGNMENT = Enum("DWRITE_TEXT_ALIGNMENT", [
 +    "DWRITE_TEXT_ALIGNMENT_LEADING",
 +    "DWRITE_TEXT_ALIGNMENT_TRAILING",
 +    "DWRITE_TEXT_ALIGNMENT_CENTER",
 +])
 +
 +DWRITE_PARAGRAPH_ALIGNMENT = Enum("DWRITE_PARAGRAPH_ALIGNMENT", [
 +    "DWRITE_PARAGRAPH_ALIGNMENT_NEAR",
 +    "DWRITE_PARAGRAPH_ALIGNMENT_FAR",
 +    "DWRITE_PARAGRAPH_ALIGNMENT_CENTER",
 +])
 +
 +DWRITE_WORD_WRAPPING = Enum("DWRITE_WORD_WRAPPING", [
 +    "DWRITE_WORD_WRAPPING_WRAP",
 +    "DWRITE_WORD_WRAPPING_NO_WRAP",
 +])
 +
 +DWRITE_LINE_SPACING_METHOD = Enum("DWRITE_LINE_SPACING_METHOD", [
 +    "DWRITE_LINE_SPACING_METHOD_DEFAULT",
 +    "DWRITE_LINE_SPACING_METHOD_UNIFORM",
 +])
 +
 +DWRITE_TRIMMING_GRANULARITY = Enum("DWRITE_TRIMMING_GRANULARITY", [
 +    "DWRITE_TRIMMING_GRANULARITY_NONE",
 +    "DWRITE_TRIMMING_GRANULARITY_CHARACTER",
 +    "DWRITE_TRIMMING_GRANULARITY_WORD",
 +])
 +
 +DWRITE_FONT_FEATURE_TAG = Enum("DWRITE_FONT_FEATURE_TAG", [
 +    "DWRITE_FONT_FEATURE_TAG_ALTERNATIVE_FRACTIONS",
 +    "DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS_FROM_CAPITALS",
 +    "DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS_FROM_CAPITALS",
 +    "DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_ALTERNATES",
 +    "DWRITE_FONT_FEATURE_TAG_CASE_SENSITIVE_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_GLYPH_COMPOSITION_DECOMPOSITION",
 +    "DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_LIGATURES",
 +    "DWRITE_FONT_FEATURE_TAG_CAPITAL_SPACING",
 +    "DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_SWASH",
 +    "DWRITE_FONT_FEATURE_TAG_CURSIVE_POSITIONING",
 +    "DWRITE_FONT_FEATURE_TAG_DEFAULT",
 +    "DWRITE_FONT_FEATURE_TAG_DISCRETIONARY_LIGATURES",
 +    "DWRITE_FONT_FEATURE_TAG_EXPERT_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_FRACTIONS",
 +    "DWRITE_FONT_FEATURE_TAG_FULL_WIDTH",
 +    "DWRITE_FONT_FEATURE_TAG_HALF_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_HALANT_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_ALTERNATE_HALF_WIDTH",
 +    "DWRITE_FONT_FEATURE_TAG_HISTORICAL_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_HORIZONTAL_KANA_ALTERNATES",
 +    "DWRITE_FONT_FEATURE_TAG_HISTORICAL_LIGATURES",
 +    "DWRITE_FONT_FEATURE_TAG_HALF_WIDTH",
 +    "DWRITE_FONT_FEATURE_TAG_HOJO_KANJI_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_JIS04_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_JIS78_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_JIS83_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_JIS90_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_KERNING",
 +    "DWRITE_FONT_FEATURE_TAG_STANDARD_LIGATURES",
 +    "DWRITE_FONT_FEATURE_TAG_LINING_FIGURES",
 +    "DWRITE_FONT_FEATURE_TAG_LOCALIZED_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_MARK_POSITIONING",
 +    "DWRITE_FONT_FEATURE_TAG_MATHEMATICAL_GREEK",
 +    "DWRITE_FONT_FEATURE_TAG_MARK_TO_MARK_POSITIONING",
 +    "DWRITE_FONT_FEATURE_TAG_ALTERNATE_ANNOTATION_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_NLC_KANJI_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_OLD_STYLE_FIGURES",
 +    "DWRITE_FONT_FEATURE_TAG_ORDINALS",
 +    "DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_ALTERNATE_WIDTH",
 +    "DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS",
 +    "DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_FIGURES",
 +    "DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_WIDTHS",
 +    "DWRITE_FONT_FEATURE_TAG_QUARTER_WIDTHS",
 +    "DWRITE_FONT_FEATURE_TAG_REQUIRED_LIGATURES",
 +    "DWRITE_FONT_FEATURE_TAG_RUBY_NOTATION_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_ALTERNATES",
 +    "DWRITE_FONT_FEATURE_TAG_SCIENTIFIC_INFERIORS",
 +    "DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS",
 +    "DWRITE_FONT_FEATURE_TAG_SIMPLIFIED_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_1",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_2",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_3",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_4",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_5",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_6",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_8",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_9",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_10",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_11",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_12",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_13",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_14",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_15",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_16",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_17",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_18",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_19",
 +    "DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_20",
 +    "DWRITE_FONT_FEATURE_TAG_SUBSCRIPT",
 +    "DWRITE_FONT_FEATURE_TAG_SUPERSCRIPT",
 +    "DWRITE_FONT_FEATURE_TAG_SWASH",
 +    "DWRITE_FONT_FEATURE_TAG_TITLING",
 +    "DWRITE_FONT_FEATURE_TAG_TRADITIONAL_NAME_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_TABULAR_FIGURES",
 +    "DWRITE_FONT_FEATURE_TAG_TRADITIONAL_FORMS",
 +    "DWRITE_FONT_FEATURE_TAG_THIRD_WIDTHS",
 +    "DWRITE_FONT_FEATURE_TAG_UNICASE",
 +    "DWRITE_FONT_FEATURE_TAG_SLASHED_ZERO",
 +])
 +
 +DWRITE_TEXT_RANGE = Struct("DWRITE_TEXT_RANGE", [
 +    (UINT32, "startPosition"),
 +    (UINT32, "length"),
 +])
 +
 +DWRITE_FONT_FEATURE = Struct("DWRITE_FONT_FEATURE", [
 +    (DWRITE_FONT_FEATURE_TAG, "nameTag"),
 +    (UINT32, "parameter"),
 +])
 +
 +DWRITE_TYPOGRAPHIC_FEATURES = Struct("DWRITE_TYPOGRAPHIC_FEATURES", [
 +    (OpaquePointer(DWRITE_FONT_FEATURE), "features"),
 +    (UINT32, "featureCount"),
 +])
 +
 +DWRITE_TRIMMING = Struct("DWRITE_TRIMMING", [
 +    (DWRITE_TRIMMING_GRANULARITY, "granularity"),
 +    (UINT32, "delimiter"),
 +    (UINT32, "delimiterCount"),
 +])
 +
 +IDWriteTextFormat.methods += [
 +    Method(HRESULT, "SetTextAlignment", [(DWRITE_TEXT_ALIGNMENT, "textAlignment")]),
 +    Method(HRESULT, "SetParagraphAlignment", [(DWRITE_PARAGRAPH_ALIGNMENT, "paragraphAlignment")]),
 +    Method(HRESULT, "SetWordWrapping", [(DWRITE_WORD_WRAPPING, "wordWrapping")]),
 +    Method(HRESULT, "SetReadingDirection", [(DWRITE_READING_DIRECTION, "readingDirection")]),
 +    Method(HRESULT, "SetFlowDirection", [(DWRITE_FLOW_DIRECTION, "flowDirection")]),
 +    Method(HRESULT, "SetIncrementalTabStop", [(FLOAT, "incrementalTabStop")]),
 +    Method(HRESULT, "SetTrimming", [(Pointer(Const(DWRITE_TRIMMING)), "trimmingOptions"), (Pointer(IDWriteInlineObject), "trimmingSign")]),
 +    Method(HRESULT, "SetLineSpacing", [(DWRITE_LINE_SPACING_METHOD, "lineSpacingMethod"), (FLOAT, "lineSpacing"), (FLOAT, "baseline")]),
 +    Method(DWRITE_TEXT_ALIGNMENT, "GetTextAlignment", []),
 +    Method(DWRITE_PARAGRAPH_ALIGNMENT, "GetParagraphAlignment", []),
 +    Method(DWRITE_WORD_WRAPPING, "GetWordWrapping", []),
 +    Method(DWRITE_READING_DIRECTION, "GetReadingDirection", []),
 +    Method(DWRITE_FLOW_DIRECTION, "GetFlowDirection", []),
 +    Method(FLOAT, "GetIncrementalTabStop", []),
 +    Method(HRESULT, "GetTrimming", [Out(Pointer(DWRITE_TRIMMING), "trimmingOptions"), Out(Pointer(Pointer(IDWriteInlineObject)), "trimmingSign")]),
 +    Method(HRESULT, "GetLineSpacing", [Out(Pointer(DWRITE_LINE_SPACING_METHOD), "lineSpacingMethod"), Out(Pointer(FLOAT), "lineSpacing"), Out(Pointer(FLOAT), "baseline")]),
 +    Method(HRESULT, "GetFontCollection", [Out(Pointer(Pointer(IDWriteFontCollection)), "fontCollection")]),
 +    Method(UINT32, "GetFontFamilyNameLength", []),
 +    Method(HRESULT, "GetFontFamilyName", [Out(Pointer(WCHAR), "fontFamilyName"), (UINT32, "nameSize")]),
 +    Method(DWRITE_FONT_WEIGHT, "GetFontWeight", []),
 +    Method(DWRITE_FONT_STYLE, "GetFontStyle", []),
 +    Method(DWRITE_FONT_STRETCH, "GetFontStretch", []),
 +    Method(FLOAT, "GetFontSize", []),
 +    Method(UINT32, "GetLocaleNameLength", []),
 +    Method(HRESULT, "GetLocaleName", [Out(Pointer(WCHAR), "localeName"), (UINT32, "nameSize")]),
 +]
 +
 +IDWriteTypography.methods += [
 +    Method(HRESULT, "AddFontFeature", [(DWRITE_FONT_FEATURE, "fontFeature")]),
 +    Method(UINT32, "GetFontFeatureCount", []),
 +    Method(HRESULT, "GetFontFeature", [(UINT32, "fontFeatureIndex"), Out(Pointer(DWRITE_FONT_FEATURE), "fontFeature")]),
 +]
 +
 +DWRITE_SCRIPT_SHAPES = EnumFlag("DWRITE_SCRIPT_SHAPES", [
 +    "DWRITE_SCRIPT_SHAPES_DEFAULT",
 +    "DWRITE_SCRIPT_SHAPES_NO_VISUAL",
 +])
 +
 +DWRITE_SCRIPT_ANALYSIS = Struct("DWRITE_SCRIPT_ANALYSIS", [
 +    (UINT16, "script"),
 +    (DWRITE_SCRIPT_SHAPES, "shapes"),
 +])
 +
 +DWRITE_BREAK_CONDITION = Enum("DWRITE_BREAK_CONDITION", [
 +    "DWRITE_BREAK_CONDITION_NEUTRAL",
 +    "DWRITE_BREAK_CONDITION_CAN_BREAK",
 +    "DWRITE_BREAK_CONDITION_MAY_NOT_BREAK",
 +    "DWRITE_BREAK_CONDITION_MUST_BREAK",
 +])
 +
 +DWRITE_LINE_BREAKPOINT = Struct("DWRITE_LINE_BREAKPOINT", [
 +    (UINT8, "breakConditionBefore"),
 +    (UINT8, "breakConditionAfter"),
 +    (UINT8, "isWhitespace"),
 +    (UINT8, "isSoftHyphen"),
 +    (UINT8, "padding"),
 +])
 +
 +DWRITE_NUMBER_SUBSTITUTION_METHOD = Enum("DWRITE_NUMBER_SUBSTITUTION_METHOD", [
 +    "DWRITE_NUMBER_SUBSTITUTION_METHOD_FROM_CULTURE",
 +    "DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL",
 +    "DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE",
 +    "DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL",
 +    "DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL",
 +])
 +
 +IDWriteNumberSubstitution.methods += [
 +]
 +
 +DWRITE_SHAPING_TEXT_PROPERTIES = Struct("DWRITE_SHAPING_TEXT_PROPERTIES", [
 +    (UINT16, "isShapedAlone"),
 +    (UINT16, "reserved"),
 +])
 +
 +DWRITE_SHAPING_GLYPH_PROPERTIES = Struct("DWRITE_SHAPING_GLYPH_PROPERTIES", [
 +    (UINT16, "justification"),
 +    (UINT16, "isClusterStart"),
 +    (UINT16, "isDiacritic"),
 +    (UINT16, "isZeroWidthSpace"),
 +    (UINT16, "reserved"),
 +])
 +
 +IDWriteTextAnalysisSource.methods += [
 +    Method(HRESULT, "GetTextAtPosition", [(UINT32, "textPosition"), Out(Pointer(Pointer(Const(WCHAR))), "textString"), Out(Pointer(UINT32), "textLength")]),
 +    Method(HRESULT, "GetTextBeforePosition", [(UINT32, "textPosition"), Out(Pointer(Pointer(Const(WCHAR))), "textString"), Out(Pointer(UINT32), "textLength")]),
 +    Method(DWRITE_READING_DIRECTION, "GetParagraphReadingDirection", []),
 +    Method(HRESULT, "GetLocaleName", [(UINT32, "textPosition"), Out(Pointer(UINT32), "textLength"), Out(Pointer(Pointer(Const(WCHAR))), "localeName")]),
 +    Method(HRESULT, "GetNumberSubstitution", [(UINT32, "textPosition"), Out(Pointer(UINT32), "textLength"), Out(Pointer(Pointer(IDWriteNumberSubstitution)), "numberSubstitution")]),
 +]
 +
 +IDWriteTextAnalysisSink.methods += [
 +    Method(HRESULT, "SetScriptAnalysis", [(UINT32, "textPosition"), (UINT32, "textLength"), (Pointer(Const(DWRITE_SCRIPT_ANALYSIS)), "scriptAnalysis")]),
 +    Method(HRESULT, "SetLineBreakpoints", [(UINT32, "textPosition"), (UINT32, "textLength"), (Pointer(Const(DWRITE_LINE_BREAKPOINT)), "lineBreakpoints")]),
 +    Method(HRESULT, "SetBidiLevel", [(UINT32, "textPosition"), (UINT32, "textLength"), (UINT8, "explicitLevel"), (UINT8, "resolvedLevel")]),
 +    Method(HRESULT, "SetNumberSubstitution", [(UINT32, "textPosition"), (UINT32, "textLength"), (Pointer(IDWriteNumberSubstitution), "numberSubstitution")]),
 +]
 +
 +IDWriteTextAnalyzer.methods += [
 +    Method(HRESULT, "AnalyzeScript", [(Pointer(IDWriteTextAnalysisSource), "analysisSource"), (UINT32, "textPosition"), (UINT32, "textLength"), (Pointer(IDWriteTextAnalysisSink), "analysisSink")]),
 +    Method(HRESULT, "AnalyzeBidi", [(Pointer(IDWriteTextAnalysisSource), "analysisSource"), (UINT32, "textPosition"), (UINT32, "textLength"), (Pointer(IDWriteTextAnalysisSink), "analysisSink")]),
 +    Method(HRESULT, "AnalyzeNumberSubstitution", [(Pointer(IDWriteTextAnalysisSource), "analysisSource"), (UINT32, "textPosition"), (UINT32, "textLength"), (Pointer(IDWriteTextAnalysisSink), "analysisSink")]),
 +    Method(HRESULT, "AnalyzeLineBreakpoints", [(Pointer(IDWriteTextAnalysisSource), "analysisSource"), (UINT32, "textPosition"), (UINT32, "textLength"), (Pointer(IDWriteTextAnalysisSink), "analysisSink")]),
 +    Method(HRESULT, "GetGlyphs", [(Pointer(Const(WCHAR)), "textString"), (UINT32, "textLength"), (Pointer(IDWriteFontFace), "fontFace"), (BOOL, "isSideways"), (BOOL, "isRightToLeft"), (Pointer(Const(DWRITE_SCRIPT_ANALYSIS)), "scriptAnalysis"), (Pointer(Const(WCHAR)), "localeName"), (Pointer(IDWriteNumberSubstitution), "numberSubstitution"), (OpaquePointer(Pointer(Const(DWRITE_TYPOGRAPHIC_FEATURES))), "features"), (Pointer(Const(UINT32)), "featureRangeLengths"), (UINT32, "featureRanges"), (UINT32, "maxGlyphCount"), Out(Pointer(UINT16), "clusterMap"), Out(Pointer(DWRITE_SHAPING_TEXT_PROPERTIES), "textProps"), Out(Pointer(UINT16), "glyphIndices"), Out(Pointer(DWRITE_SHAPING_GLYPH_PROPERTIES), "glyphProps"), Out(Pointer(UINT32), "actualGlyphCount")]),
 +    Method(HRESULT, "GetGlyphPlacements", [(Array(Const(WCHAR), "textLength"), "textString"), (Array(Const(UINT16), "textLength"), "clusterMap"), (Array(DWRITE_SHAPING_TEXT_PROPERTIES, "textLength"), "textProps"), (UINT32, "textLength"), (Array(Const(UINT16), "glyphCount"), "glyphIndices"), (Array(Const(DWRITE_SHAPING_GLYPH_PROPERTIES), "glyphCount"), "glyphProps"), (UINT32, "glyphCount"), (Pointer(IDWriteFontFace), "fontFace"), (FLOAT, "fontEmSize"), (BOOL, "isSideways"), (BOOL, "isRightToLeft"), (Pointer(Const(DWRITE_SCRIPT_ANALYSIS)), "scriptAnalysis"), (LPCWSTR, "localeName"), (Array(Pointer(Const(DWRITE_TYPOGRAPHIC_FEATURES)), "featureRanges"), "features"), (Array(Const(UINT32), "featureRanges"), "featureRangeLengths"), (UINT32, "featureRanges"), Out(Array(FLOAT, "glyphCount"), "glyphAdvances"), Out(Array(DWRITE_GLYPH_OFFSET, "glyphCount"), "glyphOffsets")]), 
 +    Method(HRESULT, "GetGdiCompatibleGlyphPlacements", [(Array(Const(WCHAR), "textLength"), "textString"), (Array(Const(UINT16), "textLength"), "clusterMap"), (Array(DWRITE_SHAPING_TEXT_PROPERTIES, "textLength"), "textProps"), (UINT32, "textLength"), (Array(Const(UINT16), "glyphCount"), "glyphIndices"), (Array(Const(DWRITE_SHAPING_GLYPH_PROPERTIES), "glyphCount"), "glyphProps"), (UINT32, "glyphCount"), (Pointer(IDWriteFontFace), "fontFace"), (FLOAT, "fontEmSize"), (FLOAT, "pixelsPerDip"), (Pointer(Const(DWRITE_MATRIX)), "transform"), (BOOL, "useGdiNatural"), (BOOL, "isSideways"), (BOOL, "isRightToLeft"), (Pointer(Const(DWRITE_SCRIPT_ANALYSIS)), "scriptAnalysis"), (LPCWSTR, "localeName"), (Array(Pointer(Const(DWRITE_TYPOGRAPHIC_FEATURES)), "featureRanges"), "features"), (Array(Const(UINT32), "featureRanges"), "featureRangeLengths"), (UINT32, "featureRanges"), Out(Array(FLOAT, "glyphCount"), "glyphAdvances"), Out(Array(DWRITE_GLYPH_OFFSET, "glyphCount"), "glyphOffsets")]),
 +]
 +
 +DWRITE_GLYPH_RUN = Struct("DWRITE_GLYPH_RUN", [
 +    (Pointer(IDWriteFontFace), "fontFace"),
 +    (FLOAT, "fontEmSize"),
 +    (UINT32, "glyphCount"),
 +    (Pointer(Const(UINT16)), "glyphIndices"),
 +    (Pointer(Const(FLOAT)), "glyphAdvances"),
 +    (Pointer(Const(DWRITE_GLYPH_OFFSET)), "glyphOffsets"),
 +    (BOOL, "isSideways"),
 +    (UINT32, "bidiLevel"),
 +])
 +
 +DWRITE_GLYPH_RUN_DESCRIPTION = Struct("DWRITE_GLYPH_RUN_DESCRIPTION", [
 +    (Pointer(Const(WCHAR)), "localeName"),
 +    (Pointer(Const(WCHAR)), "string"),
 +    (UINT32, "stringLength"),
 +    (Pointer(Const(UINT16)), "clusterMap"),
 +    (UINT32, "textPosition"),
 +])
 +
 +DWRITE_UNDERLINE = Struct("DWRITE_UNDERLINE", [
 +    (FLOAT, "width"),
 +    (FLOAT, "thickness"),
 +    (FLOAT, "offset"),
 +    (FLOAT, "runHeight"),
 +    (DWRITE_READING_DIRECTION, "readingDirection"),
 +    (DWRITE_FLOW_DIRECTION, "flowDirection"),
 +    (Pointer(Const(WCHAR)), "localeName"),
 +    (DWRITE_MEASURING_MODE, "measuringMode"),
 +])
 +
 +DWRITE_STRIKETHROUGH = Struct("DWRITE_STRIKETHROUGH", [
 +    (FLOAT, "width"),
 +    (FLOAT, "thickness"),
 +    (FLOAT, "offset"),
 +    (DWRITE_READING_DIRECTION, "readingDirection"),
 +    (DWRITE_FLOW_DIRECTION, "flowDirection"),
 +    (Pointer(Const(WCHAR)), "localeName"),
 +    (DWRITE_MEASURING_MODE, "measuringMode"),
 +])
 +
 +DWRITE_LINE_METRICS = Struct("DWRITE_LINE_METRICS", [
 +    (UINT32, "length"),
 +    (UINT32, "trailingWhitespaceLength"),
 +    (UINT32, "newlineLength"),
 +    (FLOAT, "height"),
 +    (FLOAT, "baseline"),
 +    (BOOL, "isTrimmed"),
 +])
 +
 +DWRITE_CLUSTER_METRICS = Struct("DWRITE_CLUSTER_METRICS", [
 +    (FLOAT, "width"),
 +    (UINT16, "length"),
 +    (UINT16, "canWrapLineAfter"),
 +    (UINT16, "isWhitespace"),
 +    (UINT16, "isNewline"),
 +    (UINT16, "isSoftHyphen"),
 +    (UINT16, "isRightToLeft"),
 +    (UINT16, "padding"),
 +])
 +
 +DWRITE_TEXT_METRICS = Struct("DWRITE_TEXT_METRICS", [
 +    (FLOAT, "left"),
 +    (FLOAT, "top"),
 +    (FLOAT, "width"),
 +    (FLOAT, "widthIncludingTrailingWhitespace"),
 +    (FLOAT, "height"),
 +    (FLOAT, "layoutWidth"),
 +    (FLOAT, "layoutHeight"),
 +    (UINT32, "maxBidiReorderingDepth"),
 +    (UINT32, "lineCount"),
 +])
 +
 +DWRITE_INLINE_OBJECT_METRICS = Struct("DWRITE_INLINE_OBJECT_METRICS", [
 +    (FLOAT, "width"),
 +    (FLOAT, "height"),
 +    (FLOAT, "baseline"),
 +    (BOOL, "supportsSideways"),
 +])
 +
 +DWRITE_OVERHANG_METRICS = Struct("DWRITE_OVERHANG_METRICS", [
 +    (FLOAT, "left"),
 +    (FLOAT, "top"),
 +    (FLOAT, "right"),
 +    (FLOAT, "bottom"),
 +])
 +
 +DWRITE_HIT_TEST_METRICS = Struct("DWRITE_HIT_TEST_METRICS", [
 +    (UINT32, "textPosition"),
 +    (UINT32, "length"),
 +    (FLOAT, "left"),
 +    (FLOAT, "top"),
 +    (FLOAT, "width"),
 +    (FLOAT, "height"),
 +    (UINT32, "bidiLevel"),
 +    (BOOL, "isText"),
 +    (BOOL, "isTrimmed"),
 +])
 +
 +IDWriteInlineObject.methods += [
 +    Method(HRESULT, "Draw", [(OpaquePointer(Void), "clientDrawingContext"), (Pointer(IDWriteTextRenderer), "renderer"), (FLOAT, "originX"), (FLOAT, "originY"), (BOOL, "isSideways"), (BOOL, "isRightToLeft"), (Pointer(IUnknown), "clientDrawingEffect")]),
 +    Method(HRESULT, "GetMetrics", [Out(Pointer(DWRITE_INLINE_OBJECT_METRICS), "metrics")]),
 +    Method(HRESULT, "GetOverhangMetrics", [Out(Pointer(DWRITE_OVERHANG_METRICS), "overhangs")]),
 +    Method(HRESULT, "GetBreakConditions", [Out(Pointer(DWRITE_BREAK_CONDITION), "breakConditionBefore"), Out(Pointer(DWRITE_BREAK_CONDITION), "breakConditionAfter")]),
 +]
 +
 +IDWritePixelSnapping.methods += [
 +    Method(HRESULT, "IsPixelSnappingDisabled", [(OpaquePointer(Void), "clientDrawingContext"), Out(Pointer(BOOL), "isDisabled")]),
 +    Method(HRESULT, "GetCurrentTransform", [(OpaquePointer(Void), "clientDrawingContext"), Out(Pointer(DWRITE_MATRIX), "transform")]),
 +    Method(HRESULT, "GetPixelsPerDip", [(OpaquePointer(Void), "clientDrawingContext"), Out(Pointer(FLOAT), "pixelsPerDip")]),
 +]
 +
 +IDWriteTextRenderer.methods += [
 +    Method(HRESULT, "DrawGlyphRun", [(OpaquePointer(Void), "clientDrawingContext"), (FLOAT, "baselineOriginX"), (FLOAT, "baselineOriginY"), (DWRITE_MEASURING_MODE, "measuringMode"), (Pointer(Const(DWRITE_GLYPH_RUN)), "glyphRun"), (Pointer(Const(DWRITE_GLYPH_RUN_DESCRIPTION)), "glyphRunDescription"), (Pointer(IUnknown), "clientDrawingEffect")]),
 +    Method(HRESULT, "DrawUnderline", [(OpaquePointer(Void), "clientDrawingContext"), (FLOAT, "baselineOriginX"), (FLOAT, "baselineOriginY"), (Pointer(Const(DWRITE_UNDERLINE)), "underline"), (Pointer(IUnknown), "clientDrawingEffect")]),
 +    Method(HRESULT, "DrawStrikethrough", [(OpaquePointer(Void), "clientDrawingContext"), (FLOAT, "baselineOriginX"), (FLOAT, "baselineOriginY"), (Pointer(Const(DWRITE_STRIKETHROUGH)), "strikethrough"), (Pointer(IUnknown), "clientDrawingEffect")]),
 +    Method(HRESULT, "DrawInlineObject", [(OpaquePointer(Void), "clientDrawingContext"), (FLOAT, "originX"), (FLOAT, "originY"), (Pointer(IDWriteInlineObject), "inlineObject"), (BOOL, "isSideways"), (BOOL, "isRightToLeft"), (Pointer(IUnknown), "clientDrawingEffect")]),
 +]
 +
 +IDWriteTextLayout.methods += [
 +    Method(HRESULT, "SetMaxWidth", [(FLOAT, "maxWidth")]),
 +    Method(HRESULT, "SetMaxHeight", [(FLOAT, "maxHeight")]),
 +    Method(HRESULT, "SetFontCollection", [(Pointer(IDWriteFontCollection), "fontCollection"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetFontFamilyName", [(Pointer(Const(WCHAR)), "fontFamilyName"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetFontWeight", [(DWRITE_FONT_WEIGHT, "fontWeight"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetFontStyle", [(DWRITE_FONT_STYLE, "fontStyle"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetFontStretch", [(DWRITE_FONT_STRETCH, "fontStretch"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetFontSize", [(FLOAT, "fontSize"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetUnderline", [(BOOL, "hasUnderline"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetStrikethrough", [(BOOL, "hasStrikethrough"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetDrawingEffect", [(Pointer(IUnknown), "drawingEffect"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetInlineObject", [(Pointer(IDWriteInlineObject), "inlineObject"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetTypography", [(Pointer(IDWriteTypography), "typography"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(HRESULT, "SetLocaleName", [(Pointer(Const(WCHAR)), "localeName"), (DWRITE_TEXT_RANGE, "textRange")]),
 +    Method(FLOAT, "GetMaxWidth", []),
 +    Method(FLOAT, "GetMaxHeight", []),
 +    Method(HRESULT, "GetFontCollection", [(UINT32, "currentPosition"), Out(Pointer(Pointer(IDWriteFontCollection)), "fontCollection"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetFontFamilyNameLength", [(UINT32, "currentPosition"), Out(Pointer(UINT32), "nameLength"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetFontFamilyName", [(UINT32, "currentPosition"), Out(Pointer(WCHAR), "fontFamilyName"), (UINT32, "nameSize"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetFontWeight", [(UINT32, "currentPosition"), Out(Pointer(DWRITE_FONT_WEIGHT), "fontWeight"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetFontStyle", [(UINT32, "currentPosition"), Out(Pointer(DWRITE_FONT_STYLE), "fontStyle"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetFontStretch", [(UINT32, "currentPosition"), Out(Pointer(DWRITE_FONT_STRETCH), "fontStretch"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetFontSize", [(UINT32, "currentPosition"), Out(Pointer(FLOAT), "fontSize"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetUnderline", [(UINT32, "currentPosition"), Out(Pointer(BOOL), "hasUnderline"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetStrikethrough", [(UINT32, "currentPosition"), Out(Pointer(BOOL), "hasStrikethrough"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetDrawingEffect", [(UINT32, "currentPosition"), Out(Pointer(Pointer(IUnknown)), "drawingEffect"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetInlineObject", [(UINT32, "currentPosition"), Out(Pointer(Pointer(IDWriteInlineObject)), "inlineObject"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetTypography", [(UINT32, "currentPosition"), Out(Pointer(Pointer(IDWriteTypography)), "typography"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetLocaleNameLength", [(UINT32, "currentPosition"), Out(Pointer(UINT32), "nameLength"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "GetLocaleName", [(UINT32, "currentPosition"), Out(Pointer(WCHAR), "localeName"), (UINT32, "nameSize"), Out(Pointer(DWRITE_TEXT_RANGE), "textRange")]),
 +    Method(HRESULT, "Draw", [(OpaquePointer(Void), "clientDrawingContext"), (Pointer(IDWriteTextRenderer), "renderer"), (FLOAT, "originX"), (FLOAT, "originY")]),
 +    Method(HRESULT, "GetLineMetrics", [Out(Pointer(DWRITE_LINE_METRICS), "lineMetrics"), (UINT32, "maxLineCount"), Out(Pointer(UINT32), "actualLineCount")]),
 +    Method(HRESULT, "GetMetrics", [Out(Pointer(DWRITE_TEXT_METRICS), "textMetrics")]),
 +    Method(HRESULT, "GetOverhangMetrics", [Out(Pointer(DWRITE_OVERHANG_METRICS), "overhangs")]),
 +    Method(HRESULT, "GetClusterMetrics", [Out(Pointer(DWRITE_CLUSTER_METRICS), "clusterMetrics"), (UINT32, "maxClusterCount"), Out(Pointer(UINT32), "actualClusterCount")]),
 +    Method(HRESULT, "DetermineMinWidth", [Out(Pointer(FLOAT), "minWidth")]),
 +    Method(HRESULT, "HitTestPoint", [(FLOAT, "pointX"), (FLOAT, "pointY"), Out(Pointer(BOOL), "isTrailingHit"), Out(Pointer(BOOL), "isInside"), Out(Pointer(DWRITE_HIT_TEST_METRICS), "hitTestMetrics")]),
 +    Method(HRESULT, "HitTestTextPosition", [(UINT32, "textPosition"), (BOOL, "isTrailingHit"), Out(Pointer(FLOAT), "pointX"), Out(Pointer(FLOAT), "pointY"), Out(Pointer(DWRITE_HIT_TEST_METRICS), "hitTestMetrics")]),
 +    Method(HRESULT, "HitTestTextRange", [(UINT32, "textPosition"), (UINT32, "textLength"), (FLOAT, "originX"), (FLOAT, "originY"), Out(Pointer(DWRITE_HIT_TEST_METRICS), "hitTestMetrics"), (UINT32, "maxHitTestMetricsCount"), Out(Pointer(UINT32), "actualHitTestMetricsCount")]),
 +]
 +
 +IDWriteBitmapRenderTarget.methods += [
 +    Method(HRESULT, "DrawGlyphRun", [(FLOAT, "baselineOriginX"), (FLOAT, "baselineOriginY"), (DWRITE_MEASURING_MODE, "measuringMode"), (Pointer(Const(DWRITE_GLYPH_RUN)), "glyphRun"), (Pointer(IDWriteRenderingParams), "renderingParams"), (COLORREF, "textColor"), Out(Pointer(RECT), "blackBoxRect")]),
 +    Method(HDC, "GetMemoryDC", []),
 +    Method(FLOAT, "GetPixelsPerDip", []),
 +    Method(HRESULT, "SetPixelsPerDip", [(FLOAT, "pixelsPerDip")]),
 +    Method(HRESULT, "GetCurrentTransform", [Out(Pointer(DWRITE_MATRIX), "transform")]),
 +    Method(HRESULT, "SetCurrentTransform", [(Pointer(Const(DWRITE_MATRIX)), "transform")]),
 +    Method(HRESULT, "GetSize", [Out(Pointer(SIZE), "size")]),
 +    Method(HRESULT, "Resize", [(UINT32, "width"), (UINT32, "height")]),
 +]
 +
 +IDWriteGdiInterop.methods += [
 +    Method(HRESULT, "CreateFontFromLOGFONT", [(Pointer(Const(LOGFONTW)), "logFont"), Out(Pointer(Pointer(IDWriteFont)), "font")]),
 +    Method(HRESULT, "ConvertFontToLOGFONT", [(Pointer(IDWriteFont), "font"), Out(Pointer(LOGFONTW), "logFont"), Out(Pointer(BOOL), "isSystemFont")]),
 +    Method(HRESULT, "ConvertFontFaceToLOGFONT", [(Pointer(IDWriteFontFace), "font"), Out(Pointer(LOGFONTW), "logFont")]),
 +    Method(HRESULT, "CreateFontFaceFromHdc", [(HDC, "hdc"), Out(Pointer(Pointer(IDWriteFontFace)), "fontFace")]),
 +    Method(HRESULT, "CreateBitmapRenderTarget", [(HDC, "hdc"), (UINT32, "width"), (UINT32, "height"), Out(Pointer(Pointer(IDWriteBitmapRenderTarget)), "renderTarget")]),
 +]
 +
 +DWRITE_TEXTURE_TYPE = Enum("DWRITE_TEXTURE_TYPE", [
 +    "DWRITE_TEXTURE_ALIASED_1x1",
 +    "DWRITE_TEXTURE_CLEARTYPE_3x1",
 +])
 +
 +IDWriteGlyphRunAnalysis.methods += [
 +    Method(HRESULT, "GetAlphaTextureBounds", [(DWRITE_TEXTURE_TYPE, "textureType"), Out(Pointer(RECT), "textureBounds")]),
 +    Method(HRESULT, "CreateAlphaTexture", [(DWRITE_TEXTURE_TYPE, "textureType"), (Pointer(Const(RECT)), "textureBounds"), Out(Pointer(BYTE), "alphaValues"), (UINT32, "bufferSize")]),
 +    Method(HRESULT, "GetAlphaBlendParams", [(Pointer(IDWriteRenderingParams), "renderingParams"), Out(Pointer(FLOAT), "blendGamma"), Out(Pointer(FLOAT), "blendEnhancedContrast"), Out(Pointer(FLOAT), "blendClearTypeLevel")]),
 +]
 +
 +IDWriteFactory.methods += [
 +    Method(HRESULT, "GetSystemFontCollection", [Out(Pointer(Pointer(IDWriteFontCollection)), "fontCollection"), (BOOL, "checkForUpdates")]),
 +    Method(HRESULT, "CreateCustomFontCollection", [(Pointer(IDWriteFontCollectionLoader), "collectionLoader"), (OpaquePointer(Const(Void)), "collectionKey"), (UINT32, "collectionKeySize"), Out(Pointer(Pointer(IDWriteFontCollection)), "fontCollection")]),
 +    Method(HRESULT, "RegisterFontCollectionLoader", [(Pointer(IDWriteFontCollectionLoader), "fontCollectionLoader")]),
 +    Method(HRESULT, "UnregisterFontCollectionLoader", [(Pointer(IDWriteFontCollectionLoader), "fontCollectionLoader")]),
 +    Method(HRESULT, "CreateFontFileReference", [(Pointer(Const(WCHAR)), "filePath"), (Pointer(Const(FILETIME)), "lastWriteTime"), Out(Pointer(Pointer(IDWriteFontFile)), "fontFile")]),
 +    Method(HRESULT, "CreateCustomFontFileReference", [(OpaquePointer(Const(Void)), "fontFileReferenceKey"), (UINT32, "fontFileReferenceKeySize"), (Pointer(IDWriteFontFileLoader), "fontFileLoader"), Out(Pointer(Pointer(IDWriteFontFile)), "fontFile")]),
 +    Method(HRESULT, "CreateFontFace", [(DWRITE_FONT_FACE_TYPE, "fontFaceType"), (UINT32, "numberOfFiles"), (Pointer(Const(Pointer(IDWriteFontFile))), "fontFiles"), (UINT32, "faceIndex"), (DWRITE_FONT_SIMULATIONS, "fontFaceSimulationFlags"), Out(Pointer(Pointer(IDWriteFontFace)), "fontFace")]),
 +    Method(HRESULT, "CreateRenderingParams", [Out(Pointer(Pointer(IDWriteRenderingParams)), "renderingParams")]),
 +    Method(HRESULT, "CreateMonitorRenderingParams", [(HMONITOR, "monitor"), Out(Pointer(Pointer(IDWriteRenderingParams)), "renderingParams")]),
 +    Method(HRESULT, "CreateCustomRenderingParams", [(FLOAT, "gamma"), (FLOAT, "enhancedContrast"), (FLOAT, "clearTypeLevel"), (DWRITE_PIXEL_GEOMETRY, "pixelGeometry"), (DWRITE_RENDERING_MODE, "renderingMode"), Out(Pointer(Pointer(IDWriteRenderingParams)), "renderingParams")]),
 +    Method(HRESULT, "RegisterFontFileLoader", [(Pointer(IDWriteFontFileLoader), "fontFileLoader")]),
 +    Method(HRESULT, "UnregisterFontFileLoader", [(Pointer(IDWriteFontFileLoader), "fontFileLoader")]),
 +    Method(HRESULT, "CreateTextFormat", [(Pointer(Const(WCHAR)), "fontFamilyName"), (Pointer(IDWriteFontCollection), "fontCollection"), (DWRITE_FONT_WEIGHT, "fontWeight"), (DWRITE_FONT_STYLE, "fontStyle"), (DWRITE_FONT_STRETCH, "fontStretch"), (FLOAT, "fontSize"), (Pointer(Const(WCHAR)), "localeName"), Out(Pointer(Pointer(IDWriteTextFormat)), "textFormat")]),
 +    Method(HRESULT, "CreateTypography", [Out(Pointer(Pointer(IDWriteTypography)), "typography")]),
 +    Method(HRESULT, "GetGdiInterop", [Out(Pointer(Pointer(IDWriteGdiInterop)), "gdiInterop")]),
 +    Method(HRESULT, "CreateTextLayout", [(Pointer(Const(WCHAR)), "string"), (UINT32, "stringLength"), (Pointer(IDWriteTextFormat), "textFormat"), (FLOAT, "maxWidth"), (FLOAT, "maxHeight"), Out(Pointer(Pointer(IDWriteTextLayout)), "textLayout")]),
 +    Method(HRESULT, "CreateGdiCompatibleTextLayout", [(Pointer(Const(WCHAR)), "string"), (UINT32, "stringLength"), (Pointer(IDWriteTextFormat), "textFormat"), (FLOAT, "layoutWidth"), (FLOAT, "layoutHeight"), (FLOAT, "pixelsPerDip"), (Pointer(Const(DWRITE_MATRIX)), "transform"), (BOOL, "useGdiNatural"), Out(Pointer(Pointer(IDWriteTextLayout)), "textLayout")]),
 +    Method(HRESULT, "CreateEllipsisTrimmingSign", [(Pointer(IDWriteTextFormat), "textFormat"), Out(Pointer(Pointer(IDWriteInlineObject)), "trimmingSign")]),
 +    Method(HRESULT, "CreateTextAnalyzer", [Out(Pointer(Pointer(IDWriteTextAnalyzer)), "textAnalyzer")]),
 +    Method(HRESULT, "CreateNumberSubstitution", [(DWRITE_NUMBER_SUBSTITUTION_METHOD, "substitutionMethod"), (Pointer(Const(WCHAR)), "localeName"), (BOOL, "ignoreUserOverride"), Out(Pointer(Pointer(IDWriteNumberSubstitution)), "numberSubstitution")]),
 +    Method(HRESULT, "CreateGlyphRunAnalysis", [(Pointer(Const(DWRITE_GLYPH_RUN)), "glyphRun"), (FLOAT, "pixelsPerDip"), (Pointer(Const(DWRITE_MATRIX)), "transform"), (DWRITE_RENDERING_MODE, "renderingMode"), (DWRITE_MEASURING_MODE, "measuringMode"), (FLOAT, "baselineOriginX"), (FLOAT, "baselineOriginY"), Out(Pointer(Pointer(IDWriteGlyphRunAnalysis)), "glyphRunAnalysis")]),
 +]
 +
 +dwrite = API("dwrite")
++dwrite.addInterface(IDWriteFactory)
++dwrite.addFunctions([
 +    StdFunction(HRESULT, "DWriteCreateFactory", [(DWRITE_FACTORY_TYPE, "factoryType"), (REFIID, "iid"), Out(Pointer(Pointer(IUnknown)), "factory")]),
 +])
diff --combined specs/scripts/cdecl.py
index 3ef4a0110352be11db08680343f09d7f5f98c402,d6ee05850df2159ff0e7b2246ed9be3e650c8220..940ce4424a6c948390be1f8647c704a923dba461
@@@ -34,7 -34,7 +34,7 @@@ import r
  import optparse
  
  
- class Parser:
+ class DeclParser:
  
      token_re = re.compile(r'(\d[x0-9a-fA-F.UL]*|\w+|\s+|.)')
  
          value = 0
          while self.lookahead() != '}':
              type, name = self.parse_named_type()
 +
 +            if self.match(':'):
 +                self.consume()
 +                self.consume()
 +
              if self.match(','):
                  self.consume(',')
              self.consume(';')
          if self.match(';'):
              return
          self.consume(':')
 +        if self.lookahead() in ('public', 'protected'):
 +            self.consume()
          base = self.consume()
          self.consume('{')
  
  
          ret = self.parse_type()
  
 -        if self.match('__stdcall'):
 +        if self.match('__stdcall', 'WINAPI'):
              self.consume()
              creator = 'StdFunction'
  
              args.append(arg)
              if self.match(','):
                  self.consume()
 -        self.consume() == ')'
 +        self.consume(')')
 +        if self.lookahead() == 'const':
 +            self.consume()
 +            extra = ', const=True' + extra
          
          print '    %s(%s, "%s", [%s]%s),' % (creator, ret, name, ', '.join(args), extra)
  
          arg = '(%s, "%s")' % (type, name)
          if 'out' in tags:
              arg = 'Out' + arg
 +
 +        if self.match('='):
 +            self.consume()
 +            while not self.match(',', ')'):
 +                self.consume()
 +
          return arg
  
      def parse_tags(self):
              self.consume()
              length = self.consume()
              self.consume(']')
-             type = 'Array(%s, "%s")' % (type, length)
+             try:
+                 int(length)
+             except ValueError:
+                 length = "%s" % length
+             type = 'Array(%s, %s)' % (type, length)
          return type, name
  
      int_tokens = ('unsigned', 'signed', 'int', 'long', 'short', 'char')
          return type
  
  
-         
  def main():
-     parser = Parser()
-     for arg in sys.argv[1:]:
-         parser.parse(open(arg, 'rt').read())
+     args = sys.argv[1:]
+     parser = DeclParser()
+     if args:
+         for arg in args:
+             parser.parse(open(arg, 'rt').read())
+     else:
+         parser.parse(sys.stdin.read())
      
  
  if __name__ == '__main__':
diff --combined specs/stdapi.py
index c4fc14af7ee2ffd7f3b68d535103605abbe8066c,44d4680a7e53467a8a464bddac2a2c63b2050416..b6bab8f542e2744ee642b3a7ffafa4663e05d9f1
@@@ -30,28 -30,36 +30,36 @@@ import debu
  
  
  class Type:
+     """Base class for all types."""
  
-     __all = {}
-     __seq = 0
+     __tags = set()
  
-     def __init__(self, expr, id = ''):
+     def __init__(self, expr, tag = None):
          self.expr = expr
-         
-         for char in id:
-             assert char.isalnum() or char in '_ '
  
-         id = id.replace(' ', '_')
-         
-         if id in Type.__all:
-             Type.__seq += 1
-             id += str(Type.__seq)
-         
-         assert id not in Type.__all
-         Type.__all[id] = self
+         # Generate a default tag, used when naming functions that will operate
+         # on this type, so it should preferrably be something representative of
+         # the type.
+         if tag is None:
+             tag = ''.join([c for c in expr if c.isalnum() or c in '_'])
+         else:
+             for c in tag:
+                 assert c.isalnum() or c in '_'
+         # Ensure it is unique.
+         if tag in Type.__tags:
+             suffix = 1
+             while tag + str(suffix) in Type.__tags:
+                 suffix += 1
+             tag += str(suffix)
  
-         self.id = id
+         assert tag not in Type.__tags
+         Type.__tags.add(tag)
+         self.tag = tag
  
      def __str__(self):
+         """Return the C/C++ type expression for this type."""
          return self.expr
  
      def visit(self, visitor, *args, **kwargs):
  
  
  class _Void(Type):
+     """Singleton void type."""
  
      def __init__(self):
          Type.__init__(self, "void")
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_void(self, *args, **kwargs)
+         return visitor.visitVoid(self, *args, **kwargs)
  
  Void = _Void()
  
  
  class Literal(Type):
+     """Class to describe literal types.
+     Types which are not defined in terms of other types, such as integers and
+     floats."""
  
-     def __init__(self, expr, format, base=10):
+     def __init__(self, expr, kind):
          Type.__init__(self, expr)
-         self.format = format
+         self.kind = kind
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_literal(self, *args, **kwargs)
+         return visitor.visitLiteral(self, *args, **kwargs)
  
  
  class Const(Type):
              # The most legible
              expr = "const " + type.expr
  
-         Type.__init__(self, expr, 'C' + type.id)
+         Type.__init__(self, expr, 'C' + type.tag)
  
          self.type = type
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_const(self, *args, **kwargs)
+         return visitor.visitConst(self, *args, **kwargs)
  
  
  class Pointer(Type):
  
      def __init__(self, type):
-         Type.__init__(self, type.expr + " *", 'P' + type.id)
+         Type.__init__(self, type.expr + " *", 'P' + type.tag)
          self.type = type
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_pointer(self, *args, **kwargs)
+         return visitor.visitPointer(self, *args, **kwargs)
+ class IntPointer(Type):
+     '''Integer encoded as a pointer.'''
+     def visit(self, visitor, *args, **kwargs):
+         return visitor.visitIntPointer(self, *args, **kwargs)
+ class LinearPointer(Type):
+     '''Integer encoded as a pointer.'''
+     def __init__(self, type, size = None):
+         Type.__init__(self, type.expr + " *", 'P' + type.tag)
+         self.type = type
+         self.size = size
+     def visit(self, visitor, *args, **kwargs):
+         return visitor.visitLinearPointer(self, *args, **kwargs)
  
  
  class Handle(Type):
  
      def __init__(self, name, type, range=None, key=None):
-         Type.__init__(self, type.expr, 'P' + type.id)
+         Type.__init__(self, type.expr, 'P' + type.tag)
          self.name = name
          self.type = type
          self.range = range
          self.key = key
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_handle(self, *args, **kwargs)
+         return visitor.visitHandle(self, *args, **kwargs)
  
  
  def ConstPointer(type):
  
  class Enum(Type):
  
+     __id = 0
      def __init__(self, name, values):
          Type.__init__(self, name)
+         self.id = Enum.__id
+         Enum.__id += 1
          self.values = list(values)
-     
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_enum(self, *args, **kwargs)
+         return visitor.visitEnum(self, *args, **kwargs)
  
  
  def FakeEnum(type, values):
  
  class Bitmask(Type):
  
+     __id = 0
      def __init__(self, type, values):
          Type.__init__(self, type.expr)
+         self.id = Bitmask.__id
+         Bitmask.__id += 1
          self.type = type
          self.values = values
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_bitmask(self, *args, **kwargs)
+         return visitor.visitBitmask(self, *args, **kwargs)
  
  Flags = Bitmask
  
@@@ -166,7 -210,7 +210,7 @@@ class Array(Type)
          self.length = length
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_array(self, *args, **kwargs)
+         return visitor.visitArray(self, *args, **kwargs)
  
  
  class Blob(Type):
          self.size = size
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_blob(self, *args, **kwargs)
+         return visitor.visitBlob(self, *args, **kwargs)
  
  
  class Struct(Type):
  
+     __id = 0
      def __init__(self, name, members):
          Type.__init__(self, name)
+         self.id = Struct.__id
+         Struct.__id += 1
          self.name = name
          self.members = members
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_struct(self, *args, **kwargs)
+         return visitor.visitStruct(self, *args, **kwargs)
  
  
  class Alias(Type):
          self.type = type
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_alias(self, *args, **kwargs)
+         return visitor.visitAlias(self, *args, **kwargs)
  
  
  def Out(type, name):
@@@ -220,7 -270,8 +270,8 @@@ class Arg
  
  class Function:
  
-     __id = 0
+     # 0-3 are reserved to memcpy, malloc, free, and realloc
+     __id = 4
  
      def __init__(self, type, name, args, call = '', fail = None, sideeffects=True):
          self.id = Function.__id
          s += ")"
          return s
  
+     def argNames(self):
+         return [arg.name for arg in self.args]
  
  def StdFunction(*args, **kwargs):
      kwargs.setdefault('call', '__stdcall')
@@@ -286,38 -340,23 +340,38 @@@ class Interface(Type)
          self.methods = []
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_interface(self, *args, **kwargs)
+         return visitor.visitInterface(self, *args, **kwargs)
  
-     def itermethods(self):
+     def iterMethods(self):
          if self.base is not None:
-             for method in self.base.itermethods():
+             for method in self.base.iterMethods():
                  yield method
          for method in self.methods:
              yield method
          raise StopIteration
-     def itermethods2(self):
 +    
-             for iface, method in self.base.itermethods2():
++    def iterBaseMethods(self):
 +        if self.base is not None:
++            for iface, method in self.base.iterBaseMethods():
 +                yield iface, method
 +        for method in self.methods:
 +            yield self, method
 +        raise StopIteration
  
  
  class Method(Function):
  
 -    def __init__(self, type, name, args):
 +    def __init__(self, type, name, args, const=False):
          Function.__init__(self, type, name, args, call = '__stdcall')
          for index in range(len(self.args)):
              self.args[index].index = index + 1
 +        self.const = const
 +
 +    def prototype(self, name=None):
 +        s = Function.prototype(self, name)
 +        if self.const:
 +            s += ' const'
 +        return s
  
  
  class String(Type):
          self.length = length
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_string(self, *args, **kwargs)
+         return visitor.visitString(self, *args, **kwargs)
  
  # C string (i.e., zero terminated)
  CString = String()
@@@ -340,7 -379,7 +394,7 @@@ class Opaque(Type)
          Type.__init__(self, expr)
  
      def visit(self, visitor, *args, **kwargs):
-         return visitor.visit_opaque(self, *args, **kwargs)
+         return visitor.visitOpaque(self, *args, **kwargs)
  
  
  def OpaquePointer(type, *args):
@@@ -353,55 -392,95 +407,95 @@@ def OpaqueBlob(type, size)
      return Opaque(type.expr + ' *')
  
  
+ class Polymorphic(Type):
+     def __init__(self, defaultType, switchExpr, switchTypes):
+         Type.__init__(self, defaultType.expr)
+         self.defaultType = defaultType
+         self.switchExpr = switchExpr
+         self.switchTypes = switchTypes
+     def visit(self, visitor, *args, **kwargs):
+         return visitor.visitPolymorphic(self, *args, **kwargs)
+     def iterSwitch(self):
+         cases = [['default']]
+         types = [self.defaultType]
+         for expr, type in self.switchTypes:
+             case = 'case %s' % expr
+             try:
+                 i = types.index(type)
+             except ValueError:
+                 cases.append([case])
+                 types.append(type)
+             else:
+                 cases[i].append(case)
+         return zip(cases, types)
  class Visitor:
+     '''Abstract visitor for the type hierarchy.'''
  
      def visit(self, type, *args, **kwargs):
          return type.visit(self, *args, **kwargs)
  
-     def visit_void(self, void, *args, **kwargs):
+     def visitVoid(self, void, *args, **kwargs):
+         raise NotImplementedError
+     def visitLiteral(self, literal, *args, **kwargs):
+         raise NotImplementedError
+     def visitString(self, string, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_literal(self, literal, *args, **kwargs):
+     def visitConst(self, const, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_string(self, string, *args, **kwargs):
+     def visitStruct(self, struct, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_const(self, const, *args, **kwargs):
+     def visitArray(self, array, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_struct(self, struct, *args, **kwargs):
+     def visitBlob(self, blob, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_array(self, array, *args, **kwargs):
+     def visitEnum(self, enum, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_blob(self, blob, *args, **kwargs):
+     def visitBitmask(self, bitmask, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_enum(self, enum, *args, **kwargs):
+     def visitPointer(self, pointer, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_bitmask(self, bitmask, *args, **kwargs):
+     def visitIntPointer(self, pointer, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_pointer(self, pointer, *args, **kwargs):
+     def visitLinearPointer(self, pointer, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_handle(self, handle, *args, **kwargs):
+     def visitHandle(self, handle, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_alias(self, alias, *args, **kwargs):
+     def visitAlias(self, alias, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_opaque(self, opaque, *args, **kwargs):
+     def visitOpaque(self, opaque, *args, **kwargs):
          raise NotImplementedError
  
-     def visit_interface(self, interface, *args, **kwargs):
+     def visitInterface(self, interface, *args, **kwargs):
          raise NotImplementedError
  
+     def visitPolymorphic(self, polymorphic, *args, **kwargs):
+         raise NotImplementedError
+         #return self.visit(polymorphic.defaultType, *args, **kwargs)
  
  class OnceVisitor(Visitor):
+     '''Visitor that guarantees that each type is visited only once.'''
  
      def __init__(self):
          self.__visited = set()
  
  
  class Rebuilder(Visitor):
+     '''Visitor which rebuild types as it visits them.
  
-     def visit_void(self, void):
+     By itself it is a no-op -- it is intended to be overwritten.
+     '''
+     def visitVoid(self, void):
          return void
  
-     def visit_literal(self, literal):
+     def visitLiteral(self, literal):
          return literal
  
-     def visit_string(self, string):
+     def visitString(self, string):
          return string
  
-     def visit_const(self, const):
+     def visitConst(self, const):
          return Const(const.type)
  
-     def visit_struct(self, struct):
+     def visitStruct(self, struct):
          members = [(self.visit(type), name) for type, name in struct.members]
          return Struct(struct.name, members)
  
-     def visit_array(self, array):
+     def visitArray(self, array):
          type = self.visit(array.type)
          return Array(type, array.length)
  
-     def visit_blob(self, blob):
+     def visitBlob(self, blob):
          type = self.visit(blob.type)
          return Blob(type, blob.size)
  
-     def visit_enum(self, enum):
+     def visitEnum(self, enum):
          return enum
  
-     def visit_bitmask(self, bitmask):
+     def visitBitmask(self, bitmask):
          type = self.visit(bitmask.type)
          return Bitmask(type, bitmask.values)
  
-     def visit_pointer(self, pointer):
+     def visitPointer(self, pointer):
          type = self.visit(pointer.type)
          return Pointer(type)
  
-     def visit_handle(self, handle):
+     def visitIntPointer(self, pointer):
+         return pointer
+     def visitLinearPointer(self, pointer):
+         type = self.visit(pointer.type)
+         return LinearPointer(type, pointer.size)
+     def visitHandle(self, handle):
          type = self.visit(handle.type)
          return Handle(handle.name, type, range=handle.range, key=handle.key)
  
-     def visit_alias(self, alias):
+     def visitAlias(self, alias):
          type = self.visit(alias.type)
          return Alias(alias.expr, type)
  
-     def visit_opaque(self, opaque):
+     def visitOpaque(self, opaque):
          return opaque
  
+     def visitPolymorphic(self, polymorphic):
+         defaultType = self.visit(polymorphic.defaultType)
+         switchExpr = polymorphic.switchExpr
+         switchTypes = [(expr, self.visit(type)) for expr, type in polymorphic.switchTypes]
+         return Polymorphic(defaultType, switchExpr, switchTypes)
  
  class Collector(Visitor):
-     '''Collect.'''
+     '''Visitor which collects all unique types as it traverses them.'''
  
      def __init__(self):
          self.__visited = set()
          Visitor.visit(self, type)
          self.types.append(type)
  
-     def visit_void(self, literal):
+     def visitVoid(self, literal):
          pass
  
-     def visit_literal(self, literal):
+     def visitLiteral(self, literal):
          pass
  
-     def visit_string(self, string):
+     def visitString(self, string):
          pass
  
-     def visit_const(self, const):
+     def visitConst(self, const):
          self.visit(const.type)
  
-     def visit_struct(self, struct):
+     def visitStruct(self, struct):
          for type, name in struct.members:
              self.visit(type)
  
-     def visit_array(self, array):
+     def visitArray(self, array):
          self.visit(array.type)
  
-     def visit_blob(self, array):
+     def visitBlob(self, array):
          pass
  
-     def visit_enum(self, enum):
+     def visitEnum(self, enum):
          pass
  
-     def visit_bitmask(self, bitmask):
+     def visitBitmask(self, bitmask):
          self.visit(bitmask.type)
  
-     def visit_pointer(self, pointer):
+     def visitPointer(self, pointer):
          self.visit(pointer.type)
  
-     def visit_handle(self, handle):
+     def visitIntPointer(self, pointer):
+         pass
+     def visitLinearPointer(self, pointer):
+         self.visit(pointer.type)
+     def visitHandle(self, handle):
          self.visit(handle.type)
  
-     def visit_alias(self, alias):
+     def visitAlias(self, alias):
          self.visit(alias.type)
  
-     def visit_opaque(self, opaque):
+     def visitOpaque(self, opaque):
          pass
  
-     def visit_interface(self, interface):
+     def visitInterface(self, interface):
          if interface.base is not None:
              self.visit(interface.base)
-         for method in interface.itermethods():
+         for method in interface.iterMethods():
              for arg in method.args:
                  self.visit(arg.type)
              self.visit(method.type)
  
+     def visitPolymorphic(self, polymorphic):
+         self.visit(polymorphic.defaultType)
+         for expr, type in polymorphic.switchTypes:
+             self.visit(type)
  
  class API:
+     '''API abstraction.
+     Essentially, a collection of types, functions, and interfaces.
+     '''
  
      def __init__(self, name = None):
          self.name = name
              collector.visit(function.type)
          for interface in self.interfaces:
              collector.visit(interface)
-             for method in interface.itermethods():
+             for method in interface.iterMethods():
                  for arg in method.args:
                      collector.visit(arg.type)
                  collector.visit(method.type)
          return collector.types
  
-     def add_function(self, function):
+     def addFunction(self, function):
          self.functions.append(function)
  
-     def add_functions(self, functions):
+     def addFunctions(self, functions):
          for function in functions:
-             self.add_function(function)
+             self.addFunction(function)
  
-     def add_interface(self, interface):
+     def addInterface(self, interface):
          self.interfaces.append(interface)
  
-     def add_interfaces(self, interfaces):
+     def addInterfaces(self, interfaces):
          self.interfaces.extend(interfaces)
  
-     def add_api(self, api):
+     def addApi(self, api):
          self.headers.extend(api.headers)
-         self.add_functions(api.functions)
-         self.add_interfaces(api.interfaces)
+         self.addFunctions(api.functions)
+         self.addInterfaces(api.interfaces)
  
      def get_function_by_name(self, name):
          for function in self.functions:
diff --combined specs/winapi.py
index 94764362bda51708fa85b4d4bca6fb977b64b1a7,6e3c60932123ab070213d888ae690f478057148d..017cf5f0e527dab0094998a44326c6404e638f1e
@@@ -45,11 -45,11 +45,11 @@@ UINT32 = Alias("UINT32", UInt32
  INT64 = Alias("INT64", Int64)
  UINT64 = Alias("UINT64", UInt64)
  
- BYTE = Literal("BYTE", "UInt", base=16)
- WORD = Literal("WORD", "UInt", base=16)
- DWORD = Literal("DWORD", "UInt", base=16)
+ BYTE = Alias("BYTE", UInt8)
+ WORD = Alias("WORD", UInt16)
+ DWORD = Alias("DWORD", UInt32)
  
- WCHAR = Literal("WCHAR", "SInt")
+ WCHAR = Alias("WCHAR", Short)
  
  BOOL = Alias("BOOL", Bool)
  
@@@ -83,7 -83,7 +83,7 @@@ GUID = Struct("GUID", 
      (DWORD, "Data1"),
      (WORD, "Data2"),
      (WORD, "Data3"),
-     (Array(BYTE, "8"), "Data4"),
+     (Array(BYTE, 8), "Data4"),
  ])
  LPGUID = Pointer(GUID)
  
@@@ -150,30 -150,6 +150,30 @@@ HMODULE = Opaque("HMODULE"
  
  IUnknown = Interface("IUnknown")
  
 +FILETIME = Struct("FILETIME", [
 +    (DWORD, "dwLowDateTime"),
 +    (DWORD, "dwHighDateTime"),
 +])
 +
 +COLORREF = Alias("COLORREF", DWORD)
 +
 +LOGFONTW = Struct("LOGFONTW", [
 +    (LONG, "lfHeight"),
 +    (LONG, "lfWidth"),
 +    (LONG, "lfEscapement"),
 +    (LONG, "lfOrientation"),
 +    (LONG, "lfWeight"),
 +    (BYTE, "lfItalic"),
 +    (BYTE, "lfUnderline"),
 +    (BYTE, "lfStrikeOut"),
 +    (BYTE, "lfCharSet"),
 +    (BYTE, "lfOutPrecision"),
 +    (BYTE, "lfClipPrecision"),
 +    (BYTE, "lfQuality"),
 +    (BYTE, "lfPitchAndFamily"),
 +    (WString, "lfFaceName"),
 +])
 +
  HRESULT_com = FakeEnum(HRESULT, [
      "S_OK",
      "E_NOINTERFACE",
diff --combined trace.py
index 53045f260f892c9d17e624bd4f23b9e73fbcd493,4d2f055794c4974646dcb0f27e2ee480e5d88236..38005008941efeb4e3744cbecf1ac3a9a5a01a66
+++ b/trace.py
  
  
  import specs.stdapi as stdapi
- from dispatch import Dispatcher
  
  
- def interface_wrap_name(interface):
+ def getWrapperInterfaceName(interface):
      return "Wrap" + interface.expr
  
  
- class DumpDeclarator(stdapi.OnceVisitor):
-     '''Declare helper functions to dump complex types.'''
+ class ComplexValueSerializer(stdapi.OnceVisitor):
+     '''Type visitors which generates serialization functions for
+     complex types.
+     
+     Simple types are serialized inline.
+     '''
+     def __init__(self, serializer):
+         stdapi.OnceVisitor.__init__(self)
+         self.serializer = serializer
  
-     def visit_void(self, literal):
+     def visitVoid(self, literal):
          pass
  
-     def visit_literal(self, literal):
+     def visitLiteral(self, literal):
          pass
  
-     def visit_string(self, string):
+     def visitString(self, string):
          pass
  
-     def visit_const(self, const):
+     def visitConst(self, const):
          self.visit(const.type)
  
-     def visit_struct(self, struct):
+     def visitStruct(self, struct):
          for type, name in struct.members:
              self.visit(type)
-         print 'static void __traceStruct%s(const %s &value) {' % (struct.id, struct.expr)
+         print 'static void _write__%s(const %s &value) {' % (struct.tag, struct.expr)
          print '    static const char * members[%u] = {' % (len(struct.members),)
          for type, name,  in struct.members:
              print '        "%s",' % (name,)
          print '    };'
-         print '    static const Trace::StructSig sig = {'
-         print '       %u, "%s", %u, members' % (int(struct.id), struct.name, len(struct.members))
+         print '    static const trace::StructSig sig = {'
+         print '       %u, "%s", %u, members' % (struct.id, struct.name, len(struct.members))
          print '    };'
-         print '    Trace::localWriter.beginStruct(&sig);'
+         print '    trace::localWriter.beginStruct(&sig);'
          for type, name in struct.members:
-             dump_instance(type, 'value.%s' % (name,))
-         print '    Trace::localWriter.endStruct();'
+             self.serializer.visit(type, 'value.%s' % (name,))
+         print '    trace::localWriter.endStruct();'
          print '}'
          print
  
-     def visit_array(self, array):
+     def visitArray(self, array):
          self.visit(array.type)
  
-     def visit_blob(self, array):
+     def visitBlob(self, array):
          pass
  
-     __enum_id = 0
-     def visit_enum(self, enum):
-         print 'static void __traceEnum%s(const %s value) {' % (enum.id, enum.expr)
-         n = len(enum.values)
-         for i in range(n):
-             value = enum.values[i]
-             print '    static const Trace::EnumSig sig%u = {%u, "%s", %s};' % (i, DumpDeclarator.__enum_id, value, value)
-             DumpDeclarator.__enum_id += 1
-         print '    const Trace::EnumSig *sig;'
-         print '    switch(value) {'
-         for i in range(n):
-             value = enum.values[i]
-             print '    case %s:' % value
-             print '        sig = &sig%u;' % i
-             print '        break;'
-         print '    default:'
-         print '        Trace::localWriter.writeSInt(value);'
-         print '        return;'
-         print '    }'
-         print '    Trace::localWriter.writeEnum(sig);'
-         print '}'
+     def visitEnum(self, enum):
+         print 'static const trace::EnumValue __enum%s_values[] = {' % (enum.tag)
+         for value in enum.values:
+             print '   {"%s", %s},' % (value, value)
+         print '};'
+         print
+         print 'static const trace::EnumSig __enum%s_sig = {' % (enum.tag)
+         print '   %u, %u, __enum%s_values' % (enum.id, len(enum.values), enum.tag)
+         print '};'
          print
  
-     def visit_bitmask(self, bitmask):
-         print 'static const Trace::BitmaskFlag __bitmask%s_flags[] = {' % (bitmask.id)
+     def visitBitmask(self, bitmask):
+         print 'static const trace::BitmaskFlag __bitmask%s_flags[] = {' % (bitmask.tag)
          for value in bitmask.values:
              print '   {"%s", %s},' % (value, value)
          print '};'
          print
-         print 'static const Trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.id)
-         print '   %u, %u, __bitmask%s_flags' % (int(bitmask.id), len(bitmask.values), bitmask.id)
+         print 'static const trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.tag)
+         print '   %u, %u, __bitmask%s_flags' % (bitmask.id, len(bitmask.values), bitmask.tag)
          print '};'
          print
  
-     def visit_pointer(self, pointer):
+     def visitPointer(self, pointer):
+         self.visit(pointer.type)
+     def visitIntPointer(self, pointer):
+         pass
+     def visitLinearPointer(self, pointer):
          self.visit(pointer.type)
  
-     def visit_handle(self, handle):
+     def visitHandle(self, handle):
          self.visit(handle.type)
  
-     def visit_alias(self, alias):
+     def visitAlias(self, alias):
          self.visit(alias.type)
  
-     def visit_opaque(self, opaque):
+     def visitOpaque(self, opaque):
          pass
  
-     def visit_interface(self, interface):
-         print "class %s : public %s " % (interface_wrap_name(interface), interface.name)
-         print "{"
-         print "public:"
-         print "    %s(%s * pInstance);" % (interface_wrap_name(interface), interface.name)
-         print "    virtual ~%s();" % interface_wrap_name(interface)
-         print
-         for method in interface.itermethods():
-             print "    " + method.prototype() + ";"
-         print
-         #print "private:"
-         print "    %s * m_pInstance;" % (interface.name,)
-         print "};"
+     def visitInterface(self, interface):
+         pass
+     def visitPolymorphic(self, polymorphic):
+         print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
+         print '    switch (selector) {'
+         for cases, type in polymorphic.iterSwitch():
+             for case in cases:
+                 print '    %s:' % case
+             self.serializer.visit(type, 'static_cast<%s>(value)' % (type,))
+             print '        break;'
+         print '    }'
+         print '}'
          print
  
  
- class DumpImplementer(stdapi.Visitor):
-     '''Dump an instance.'''
+ class ValueSerializer(stdapi.Visitor):
+     '''Visitor which generates code to serialize any type.
+     
+     Simple types are serialized inline here, whereas the serialization of
+     complex types is dispatched to the serialization functions generated by
+     ComplexValueSerializer visitor above.
+     '''
  
-     def visit_literal(self, literal, instance):
-         print '    Trace::localWriter.write%s(%s);' % (literal.format, instance)
+     def visitLiteral(self, literal, instance):
+         print '    trace::localWriter.write%s(%s);' % (literal.kind, instance)
  
-     def visit_string(self, string, instance):
+     def visitString(self, string, instance):
          if string.length is not None:
-             print '    Trace::localWriter.writeString((const char *)%s, %s);' % (instance, string.length)
+             print '    trace::localWriter.writeString((const char *)%s, %s);' % (instance, string.length)
          else:
-             print '    Trace::localWriter.writeString((const char *)%s);' % instance
+             print '    trace::localWriter.writeString((const char *)%s);' % instance
  
-     def visit_const(self, const, instance):
+     def visitConst(self, const, instance):
          self.visit(const.type, instance)
  
-     def visit_struct(self, struct, instance):
-         print '    __traceStruct%s(%s);' % (struct.id, instance)
+     def visitStruct(self, struct, instance):
+         print '    _write__%s(%s);' % (struct.tag, instance)
  
-     def visit_array(self, array, instance):
-         length = '__c' + array.type.id
-         index = '__i' + array.type.id
+     def visitArray(self, array, instance):
+         length = '__c' + array.type.tag
+         index = '__i' + array.type.tag
          print '    if (%s) {' % instance
          print '        size_t %s = %s;' % (length, array.length)
-         print '        Trace::localWriter.beginArray(%s);' % length
+         print '        trace::localWriter.beginArray(%s);' % length
          print '        for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
-         print '            Trace::localWriter.beginElement();'
+         print '            trace::localWriter.beginElement();'
          self.visit(array.type, '(%s)[%s]' % (instance, index))
-         print '            Trace::localWriter.endElement();'
+         print '            trace::localWriter.endElement();'
          print '        }'
-         print '        Trace::localWriter.endArray();'
+         print '        trace::localWriter.endArray();'
          print '    } else {'
-         print '        Trace::localWriter.writeNull();'
+         print '        trace::localWriter.writeNull();'
          print '    }'
  
-     def visit_blob(self, blob, instance):
-         print '    Trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
+     def visitBlob(self, blob, instance):
+         print '    trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
  
-     def visit_enum(self, enum, instance):
-         print '    __traceEnum%s(%s);' % (enum.id, instance)
+     def visitEnum(self, enum, instance):
+         print '    trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
  
-     def visit_bitmask(self, bitmask, instance):
-         print '    Trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.id, instance)
+     def visitBitmask(self, bitmask, instance):
+         print '    trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
  
-     def visit_pointer(self, pointer, instance):
+     def visitPointer(self, pointer, instance):
          print '    if (%s) {' % instance
-         print '        Trace::localWriter.beginArray(1);'
-         print '        Trace::localWriter.beginElement();'
-         dump_instance(pointer.type, "*" + instance)
-         print '        Trace::localWriter.endElement();'
-         print '        Trace::localWriter.endArray();'
+         print '        trace::localWriter.beginArray(1);'
+         print '        trace::localWriter.beginElement();'
+         self.visit(pointer.type, "*" + instance)
+         print '        trace::localWriter.endElement();'
+         print '        trace::localWriter.endArray();'
          print '    } else {'
-         print '        Trace::localWriter.writeNull();'
+         print '        trace::localWriter.writeNull();'
          print '    }'
  
-     def visit_handle(self, handle, instance):
-         self.visit(handle.type, instance)
+     def visitIntPointer(self, pointer, instance):
+         print '    trace::localWriter.writeOpaque((const void *)%s);' % instance
  
-     def visit_alias(self, alias, instance):
-         self.visit(alias.type, instance)
+     def visitLinearPointer(self, pointer, instance):
+         print '    trace::localWriter.writeOpaque((const void *)%s);' % instance
  
-     def visit_opaque(self, opaque, instance):
-         print '    Trace::localWriter.writeOpaque((const void *)%s);' % instance
+     def visitHandle(self, handle, instance):
+         self.visit(handle.type, instance)
  
-     def visit_interface(self, interface, instance):
-         print '    Trace::localWriter.writeOpaque((const void *)&%s);' % instance
+     def visitAlias(self, alias, instance):
+         self.visit(alias.type, instance)
  
+     def visitOpaque(self, opaque, instance):
+         print '    trace::localWriter.writeOpaque((const void *)%s);' % instance
  
- dump_instance = DumpImplementer().visit
+     def visitInterface(self, interface, instance):
+         print '    trace::localWriter.writeOpaque((const void *)&%s);' % instance
  
+     def visitPolymorphic(self, polymorphic, instance):
+         print '    _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
  
  
- class Wrapper(stdapi.Visitor):
-     '''Wrap an instance.'''
+ class ValueWrapper(stdapi.Visitor):
+     '''Type visitor which will generate the code to wrap an instance.
+     
+     Wrapping is necessary mostly for interfaces, however interface pointers can
+     appear anywhere inside complex types.
+     '''
  
-     def visit_void(self, type, instance):
+     def visitVoid(self, type, instance):
          raise NotImplementedError
  
-     def visit_literal(self, type, instance):
+     def visitLiteral(self, type, instance):
          pass
  
-     def visit_string(self, type, instance):
+     def visitString(self, type, instance):
          pass
  
-     def visit_const(self, type, instance):
+     def visitConst(self, type, instance):
          pass
  
-     def visit_struct(self, struct, instance):
+     def visitStruct(self, struct, instance):
          for type, name in struct.members:
              self.visit(type, "(%s).%s" % (instance, name))
  
-     def visit_array(self, array, instance):
+     def visitArray(self, array, instance):
          # XXX: actually it is possible to return an array of pointers
          pass
  
-     def visit_blob(self, blob, instance):
+     def visitBlob(self, blob, instance):
          pass
  
-     def visit_enum(self, enum, instance):
+     def visitEnum(self, enum, instance):
          pass
  
-     def visit_bitmask(self, bitmask, instance):
+     def visitBitmask(self, bitmask, instance):
          pass
  
-     def visit_pointer(self, pointer, instance):
+     def visitPointer(self, pointer, instance):
          print "    if (%s) {" % instance
          self.visit(pointer.type, "*" + instance)
          print "    }"
+     
+     def visitIntPointer(self, pointer, instance):
+         pass
+     def visitLinearPointer(self, pointer, instance):
+         pass
  
-     def visit_handle(self, handle, instance):
+     def visitHandle(self, handle, instance):
          self.visit(handle.type, instance)
  
-     def visit_alias(self, alias, instance):
+     def visitAlias(self, alias, instance):
          self.visit(alias.type, instance)
  
-     def visit_opaque(self, opaque, instance):
+     def visitOpaque(self, opaque, instance):
          pass
      
-     def visit_interface(self, interface, instance):
+     def visitInterface(self, interface, instance):
          assert instance.startswith('*')
          instance = instance[1:]
          print "    if (%s) {" % instance
-         print "        %s = new %s(%s);" % (instance, interface_wrap_name(interface), instance)
+         print "        %s = new %s(%s);" % (instance, getWrapperInterfaceName(interface), instance)
          print "    }"
+     
+     def visitPolymorphic(self, type, instance):
+         # XXX: There might be polymorphic values that need wrapping in the future
+         pass
  
  
- class Unwrapper(Wrapper):
+ class ValueUnwrapper(ValueWrapper):
+     '''Reverse of ValueWrapper.'''
  
-     def visit_interface(self, interface, instance):
+     def visitInterface(self, interface, instance):
          assert instance.startswith('*')
          instance = instance[1:]
          print "    if (%s) {" % instance
-         print "        %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, interface_wrap_name(interface), instance)
+         print "        %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, getWrapperInterfaceName(interface), instance)
          print "    }"
  
  
- wrap_instance = Wrapper().visit
- unwrap_instance = Unwrapper().visit
  class Tracer:
+     '''Base class to orchestrate the code generation of API tracing.'''
  
      def __init__(self):
          self.api = None
  
+     def serializerFactory(self):
+         '''Create a serializer.
+         
+         Can be overriden by derived classes to inject their own serialzer.
+         '''
+         return ValueSerializer()
      def trace_api(self, api):
          self.api = api
  
              print header
          print
  
-         # Type dumpers
+         # Generate the serializer functions
          types = api.all_types()
-         visitor = DumpDeclarator()
+         visitor = ComplexValueSerializer(self.serializerFactory())
          map(visitor.visit, types)
          print
  
          # Interfaces wrapers
          interfaces = [type for type in types if isinstance(type, stdapi.Interface)]
-         map(self.interface_wrap_impl, interfaces)
+         map(self.declareWrapperInterface, interfaces)
+         map(self.implementWrapperInterface, interfaces)
          print
  
          # Function wrappers
-         map(self.trace_function_decl, api.functions)
-         map(self.trace_function_impl, api.functions)
+         map(self.traceFunctionDecl, api.functions)
+         map(self.traceFunctionImpl, api.functions)
          print
  
          self.footer(api)
      def footer(self, api):
          pass
  
-     def trace_function_decl(self, function):
+     def traceFunctionDecl(self, function):
          # Per-function declarations
  
          if function.args:
              print 'static const char * __%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args]))
          else:
              print 'static const char ** __%s_args = NULL;' % (function.name,)
-         print 'static const Trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, int(function.id), function.name, len(function.args), function.name)
+         print 'static const trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, function.id, function.name, len(function.args), function.name)
          print
  
-     def is_public_function(self, function):
+     def isFunctionPublic(self, function):
          return True
  
-     def trace_function_impl(self, function):
-         if self.is_public_function(function):
+     def traceFunctionImpl(self, function):
+         if self.isFunctionPublic(function):
              print 'extern "C" PUBLIC'
          else:
              print 'extern "C" PRIVATE'
          print function.prototype() + ' {'
          if function.type is not stdapi.Void:
              print '    %s __result;' % function.type
-         self.trace_function_impl_body(function)
+         self.traceFunctionImplBody(function)
          if function.type is not stdapi.Void:
-             self.wrap_ret(function, "__result")
+             self.wrapRet(function, "__result")
              print '    return __result;'
          print '}'
          print
  
-     def trace_function_impl_body(self, function):
-         print '    unsigned __call = Trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
+     def traceFunctionImplBody(self, function):
+         print '    unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
          for arg in function.args:
              if not arg.output:
-                 self.unwrap_arg(function, arg)
-                 self.dump_arg(function, arg)
-         print '    Trace::localWriter.endEnter();'
-         self.dispatch_function(function)
-         print '    Trace::localWriter.beginLeave(__call);'
+                 self.unwrapArg(function, arg)
+                 self.serializeArg(function, arg)
+         print '    trace::localWriter.endEnter();'
+         self.invokeFunction(function)
+         print '    trace::localWriter.beginLeave(__call);'
          for arg in function.args:
              if arg.output:
-                 self.dump_arg(function, arg)
-                 self.wrap_arg(function, arg)
+                 self.serializeArg(function, arg)
+                 self.wrapArg(function, arg)
          if function.type is not stdapi.Void:
-             self.dump_ret(function, "__result")
-         print '    Trace::localWriter.endLeave();'
+             self.serializeRet(function, "__result")
+         print '    trace::localWriter.endLeave();'
  
-     def dispatch_function(self, function, prefix='__', suffix=''):
+     def invokeFunction(self, function, prefix='__', suffix=''):
          if function.type is stdapi.Void:
              result = ''
          else:
          dispatch = prefix + function.name + suffix
          print '    %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
  
-     def dump_arg(self, function, arg):
-         print '    Trace::localWriter.beginArg(%u);' % (arg.index,)
-         self.dump_arg_instance(function, arg)
-         print '    Trace::localWriter.endArg();'
+     def serializeArg(self, function, arg):
+         print '    trace::localWriter.beginArg(%u);' % (arg.index,)
+         self.serializeArgValue(function, arg)
+         print '    trace::localWriter.endArg();'
+     def serializeArgValue(self, function, arg):
+         self.serializeValue(arg.type, arg.name)
  
-     def dump_arg_instance(self, function, arg):
-         dump_instance(arg.type, arg.name)
+     def wrapArg(self, function, arg):
+         self.wrapValue(arg.type, arg.name)
  
-     def wrap_arg(self, function, arg):
-         wrap_instance(arg.type, arg.name)
+     def unwrapArg(self, function, arg):
+         self.unwrapValue(arg.type, arg.name)
  
-     def unwrap_arg(self, function, arg):
-         unwrap_instance(arg.type, arg.name)
+     def serializeRet(self, function, instance):
+         print '    trace::localWriter.beginReturn();'
+         self.serializeValue(function.type, instance)
+         print '    trace::localWriter.endReturn();'
  
-     def dump_ret(self, function, instance):
-         print '    Trace::localWriter.beginReturn();'
-         dump_instance(function.type, instance)
-         print '    Trace::localWriter.endReturn();'
+     def serializeValue(self, type, instance):
+         serializer = self.serializerFactory()
+         serializer.visit(type, instance)
  
-     def wrap_ret(self, function, instance):
-         wrap_instance(function.type, instance)
+     def wrapRet(self, function, instance):
+         self.wrapValue(function.type, instance)
  
-     def unwrap_ret(self, function, instance):
-         unwrap_instance(function.type, instance)
+     def unwrapRet(self, function, instance):
+         self.unwrapValue(function.type, instance)
  
-     def interface_wrap_impl(self, interface):
-         print '%s::%s(%s * pInstance) {' % (interface_wrap_name(interface), interface_wrap_name(interface), interface.name)
+     def wrapValue(self, type, instance):
+         visitor = ValueWrapper()
+         visitor.visit(type, instance)
+     def unwrapValue(self, type, instance):
+         visitor = ValueUnwrapper()
+         visitor.visit(type, instance)
+     def declareWrapperInterface(self, interface):
+         print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
+         print "{"
+         print "public:"
+         print "    %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
+         print "    virtual ~%s();" % getWrapperInterfaceName(interface)
+         print
+         for method in interface.iterMethods():
+             print "    " + method.prototype() + ";"
+         print
+         self.declareWrapperInterfaceVariables(interface)
+         print "};"
+         print
+     def declareWrapperInterfaceVariables(self, interface):
+         #print "private:"
+         print "    %s * m_pInstance;" % (interface.name,)
+     def implementWrapperInterface(self, interface):
+         print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
          print '    m_pInstance = pInstance;'
          print '}'
          print
-         print '%s::~%s() {' % (interface_wrap_name(interface), interface_wrap_name(interface))
+         print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
          print '}'
          print
-         for base, method in interface.itermethods2():
-             self.trace_method(interface, base, method)
 -        for method in interface.iterMethods():
 -            self.implementWrapperInterfaceMethod(interface, method)
++        for base, method in interface.iterBaseMethods():
++            self.implementWrapperInterfaceMethod(interface, base, method)
+         print
 -    def implementWrapperInterfaceMethod(self, interface, method):
++    def implementWrapperInterfaceMethod(self, interface, base, method):
+         print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
+         if method.type is not stdapi.Void:
+             print '    %s __result;' % method.type
+     
 -        self.implementWrapperInterfaceMethodBody(interface, method)
++        self.implementWrapperInterfaceMethodBody(interface, base, method)
+     
+         if method.type is not stdapi.Void:
+             print '    return __result;'
+         print '}'
          print
  
-     def trace_method(self, interface, base, method):
-         print method.prototype(interface_wrap_name(interface) + '::' + method.name) + ' {'
 -    def implementWrapperInterfaceMethodBody(self, interface, method):
++    def implementWrapperInterfaceMethodBody(self, interface, base, method):
          print '    static const char * __args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
-         print '    static const Trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (int(method.id), interface.name + '::' + method.name, len(method.args) + 1)
-         print '    unsigned __call = Trace::localWriter.beginEnter(&__sig);'
-         print '    Trace::localWriter.beginArg(0);'
-         print '    Trace::localWriter.writeOpaque((const void *)m_pInstance);'
-         print '    Trace::localWriter.endArg();'
+         print '    static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
+         print '    unsigned __call = trace::localWriter.beginEnter(&__sig);'
+         print '    trace::localWriter.beginArg(0);'
+         print '    trace::localWriter.writeOpaque((const void *)m_pInstance);'
+         print '    trace::localWriter.endArg();'
          for arg in method.args:
              if not arg.output:
-                 self.unwrap_arg(method, arg)
-                 self.dump_arg(method, arg)
-         if method.type is stdapi.Void:
-             result = ''
-         else:
-             print '    %s __result;' % method.type
-             result = '__result = '
-         print '    Trace::localWriter.endEnter();'
-         print '    %sstatic_cast<%s *>(m_pInstance)->%s(%s);' % (result, base, method.name, ', '.join([str(arg.name) for arg in method.args]))
-         print '    Trace::localWriter.beginLeave(__call);'
+                 self.unwrapArg(method, arg)
+                 self.serializeArg(method, arg)
+         print '    trace::localWriter.endEnter();'
+         
 -        self.invokeMethod(interface, method)
++        self.invokeMethod(interface, base, method)
+         print '    trace::localWriter.beginLeave(__call);'
          for arg in method.args:
              if arg.output:
-                 self.dump_arg(method, arg)
-                 self.wrap_arg(method, arg)
+                 self.serializeArg(method, arg)
+                 self.wrapArg(method, arg)
          if method.type is not stdapi.Void:
-             print '    Trace::localWriter.beginReturn();'
-             dump_instance(method.type, "__result")
-             print '    Trace::localWriter.endReturn();'
-             wrap_instance(method.type, '__result')
-         print '    Trace::localWriter.endLeave();'
+             print '    trace::localWriter.beginReturn();'
+             self.serializeValue(method.type, "__result")
+             print '    trace::localWriter.endReturn();'
+             self.wrapValue(method.type, '__result')
+         print '    trace::localWriter.endLeave();'
          if method.name == 'QueryInterface':
              print '    if (ppvObj && *ppvObj) {'
              print '        if (*ppvObj == m_pInstance) {'
              print '            *ppvObj = this;'
              print '        }'
              for iface in self.api.interfaces:
-                 print '        else if (riid == IID_%s) {' % iface.name
-                 print '            *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
-                 print '        }'
+                 print r'        else if (riid == IID_%s) {' % iface.name
+                 print r'            *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
+                 print r'        }'
+             print r'        else {'
+             print r'            os::log("apitrace: warning: unknown REFIID {0x%08lX,0x%04X,0x%04X,{0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X}}\n",'
+             print r'                    riid.Data1, riid.Data2, riid.Data3,'
+             print r'                    riid.Data4[0],'
+             print r'                    riid.Data4[1],'
+             print r'                    riid.Data4[2],'
+             print r'                    riid.Data4[3],'
+             print r'                    riid.Data4[4],'
+             print r'                    riid.Data4[5],'
+             print r'                    riid.Data4[6],'
+             print r'                    riid.Data4[7]);'
+             print r'        }'
              print '    }'
          if method.name == 'Release':
              assert method.type is not stdapi.Void
              print '    if (!__result)'
              print '        delete this;'
-         if method.type is not stdapi.Void:
-             print '    return __result;'
-         print '}'
-         print
- class DllTracer(Tracer):
  
-     def __init__(self, dllname):
-         self.dllname = dllname
 -    def invokeMethod(self, interface, method):
++    def invokeMethod(self, interface, base, method):
+         if method.type is stdapi.Void:
+             result = ''
+         else:
+             result = '__result = '
 -        print '    %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
++        print '    %sstatic_cast<%s *>(m_pInstance)->%s(%s);' % (result, base, method.name, ', '.join([str(arg.name) for arg in method.args]))
      
-     def header(self, api):
-         print '''
- static HINSTANCE g_hDll = NULL;
- static PROC
- __getPublicProcAddress(LPCSTR lpProcName)
- {
-     if (!g_hDll) {
-         char szDll[MAX_PATH] = {0};
-         
-         if (!GetSystemDirectoryA(szDll, MAX_PATH)) {
-             return NULL;
-         }
-         
-         strcat(szDll, "\\\\%s");
-         
-         g_hDll = LoadLibraryA(szDll);
-         if (!g_hDll) {
-             return NULL;
-         }
-     }
-         
-     return GetProcAddress(g_hDll, lpProcName);
- }
- ''' % self.dllname
-         dispatcher = Dispatcher()
-         dispatcher.dispatch_api(api)
-         Tracer.header(self, api)
+     def emit_memcpy(self, dest, src, length):
+         print '        unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
+         print '        trace::localWriter.beginArg(0);'
+         print '        trace::localWriter.writeOpaque(%s);' % dest
+         print '        trace::localWriter.endArg();'
+         print '        trace::localWriter.beginArg(1);'
+         print '        trace::localWriter.writeBlob(%s, %s);' % (src, length)
+         print '        trace::localWriter.endArg();'
+         print '        trace::localWriter.beginArg(2);'
+         print '        trace::localWriter.writeUInt(%s);' % length
+         print '        trace::localWriter.endArg();'
+         print '        trace::localWriter.endEnter();'
+         print '        trace::localWriter.beginLeave(__call);'
+         print '        trace::localWriter.endLeave();'
+