VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "clsWApath"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

' CLASS PURPOSE & GOALS
' -------------------------------
' 1. Wrap many common GDI+ path-related methods/routines
' 2. Handle complicated calculations & path-related matrix operations
' 3. Provide patches/workarounds for GDI+ path-related buggy code (warping, XOR drawing)
' 4. Provide flexible rendering routines & clone routines
' 5. Re-usable and expandable

' IMPORTANT:  ARRAY POINTER USAGE
' --------------------------------
' Since this is a class and passing UDTs to it isn't allowed unless the UDTs are delcared public in a bas module.
' Some of the functions ask for array pointers. This has some benefits and only one drawback.
' The benfits are that you can use various storage items: Singles(), POINTF(), Bytes()

' First, GDI+ uses POINTF structures quite often. This is simply an X,Y structure where X,Y are Singles & not Longs.
' Since the structure are Singles, you can either declare and use an array of POINTF structures in your project or
' use an array of Singles instead.  Always declare your arrays like the following:
'       -- array of Singles: Dim mySingleArray(0 To 1, 0 To numberPoints-1) << 0 & 1 are X,Y coords respectively
'       -- array of POINTF:  Dim myPOINTFarray(0 To numberPoints-1)
' Now when you need to pass pointers to the class, simply pass it using VB's VarPtr function:
'       -- array of Singles:  VarPtr(mySingleArray(0, 0))
'       -- array of POINTF:   VarPtr(myPOINTFarray(0))
' The drawback, crashes if you pass invalid pointers or do not size your array appropriately
' All functions that expect pointers have a PTR suffix in their function name.
' ALWAYS ENSURE THE ARRAY IS SIZED BEFORE ATTEMPTING TO PASS ARRAY POINTERS

' ABOUT RENDERING, SCALING, OFFSETS
' ---------------------------------
' The path is never scaled, rotated or moved/repositioned once it is created.
' The class tracks the scale desired, angle desired, position desired, etc.
' When rendering occurs, a matrix is created to be used to place the path
' using set Angle, Scale, Offsets and then rendered to the DC via the matrix.
' This actually has several benefites and one or two drawbacks.

' The benefits? Original path is never altered, this promotes better quality
'   renderings. Since path is never physically modified, gradient/path brushes
'   do not need to be destroyed/modifiied/recreated when a path is resized or moved.
'   Rendering speed is improved in many scenarios, but not all
'   Paths can be cloned "as rendered" via the Clone function

' The drawbacks? Only major one I can think of :: hit testing a path on a DC if the project
'   requires the ability to see if mouse is over a path. Since the path handle in this
'   class is not the same dimensions/rotation as the rendered path, hit testing will fail.
'   To resolve this, recommend creating a second class and calling this class' Clone
'   method to get the path in rendered form.  When/If the rendered path changes scale,
'   rotation or position, then replace the path with another call to the Clone method.
'   -- Another drawback is that repainting via a matrix is slower than if the path
'      was created at specific angle/size/position. However, this drawback only occurs
'      when a DC's AutoRedraw=False otherwise, rendering generally only occurs when
'      path properties change which is less common overall. Animating via matrix is faster
'      overall than continually recreating a path to match the animated position/scale/rotation.
' -------------------------------------------------------------------------------------

' ---=====| NON-GDI+ APIS |====---

Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
' following used for XOR rendering of path
Private Declare Function CreatePen Lib "gdi32.dll" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function LineTo Lib "gdi32.dll" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function MoveToEx Lib "gdi32.dll" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByRef lpPoint As Any) As Long
Private Declare Function PolyBezierTo Lib "gdi32.dll" (ByVal hDC As Long, ByRef lppt As Any, ByVal cCount As Long) As Long
Private Declare Function SetROP2 Lib "gdi32.dll" (ByVal hDC As Long, ByVal nDrawMode As Long) As Long
' following used to saving path as an image
Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpszProgID As Long, pCLSID As Any) As Long
Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hDC As Long) As Long
Private Declare Function GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
Private Declare Function InflateRect Lib "user32.dll" (ByRef lpRect As RECT, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hDC As Long) As Long
Private Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal hDC As Long, ByRef pBitmapInfo As BITMAPINFO, ByVal un As Long, ByRef lplpVoid As Long, ByVal handle As Long, ByVal dw As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal psString As Any) As Long
Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hDC As Long) As Long
Private Declare Function FillRect Lib "user32.dll" (ByVal hDC As Long, ByRef lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As Long, ppstm As Any) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GetHGlobalFromStream Lib "ole32" (ByVal ppstm As Long, hGlobal As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal crColor As Long) As Long
Private Declare Function OffsetRect Lib "user32.dll" (ByRef lpRect As RECT, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function UnionRect Lib "user32.dll" (ByRef lpDestRect As RECT, ByRef lpSrc1Rect As RECT, ByRef lpSrc2Rect As RECT) As Long

' ---=====| GDI+ TEXT RELEATED APIS |====---
Private Declare Function GdipCreateFontFamilyFromName Lib "gdiplus" (ByVal name As Long, ByVal fontCollection As Long, fontFamily As Long) As Long
Private Declare Function GdipDeleteFontFamily Lib "gdiplus" (ByVal fontFamily As Long) As Long
Private Declare Function GdipAddur ao