]> O.S.I.I.S - jp/vkvg.git/commitdiff
clang format
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 27 Oct 2024 20:03:31 +0000 (20:03 +0000)
committerj-p <jp_bruyere@hotmail.com>
Mon, 24 Mar 2025 18:12:00 +0000 (19:12 +0100)
85 files changed:
.clang-format [new file with mode: 0644]
include/vkvg-svg.h
include/vkvg.h
src/cross_os.c
src/cross_os.h
src/deps/tinycthread.c
src/deps/tinycthread.h
src/nsvg/nanosvg.h
src/nsvg/vkvg_nsvg.c
src/recording/vkvg_record.c
src/recording/vkvg_record_internal.c
src/recording/vkvg_record_internal.h
src/shaders.h
src/stb_image.h
src/stb_image_write.h
src/stb_truetype.h
src/vectors.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h
src/vkvg_device.c
src/vkvg_device_internal.c
src/vkvg_device_internal.h
src/vkvg_experimental.c
src/vkvg_fonts.c
src/vkvg_fonts.h
src/vkvg_internal.h
src/vkvg_matrix.c
src/vkvg_matrix.h
src/vkvg_pattern.c
src/vkvg_pattern.h
src/vkvg_surface.c
src/vkvg_surface_internal.c
src/vkvg_surface_internal.h
template.c
tests/arcs.c
tests/bezier.c
tests/circles.c
tests/clip.c
tests/colinear.c
tests/common/nanosvg.h
tests/common/rnd.c
tests/common/test.c
tests/common/test.h
tests/common/tinycthread.c
tests/common/tinycthread.h
tests/common/vkengine.c
tests/common/vkengine.h
tests/compositing.c
tests/context.c
tests/curve.c
tests/dashes.c
tests/fill.c
tests/fill_and_stroke.c
tests/fill_non_zero.c
tests/gradient.c
tests/gradient2.c
tests/img_surf.c
tests/inverse_colinear.c
tests/line_caps.c
tests/line_join.c
tests/lines.c
tests/multithreading/multithreaded.c
tests/multithreading/multithreaded2.c
tests/multithreading/threaded_create_surf.c
tests/multithreading/threaded_text.c
tests/offscreen.c
tests/paint_surf.c
tests/path_extents.c
tests/pattern_transforms.c
tests/perfs/random_rects.c
tests/perfs/randoms.c
tests/radial_gradient.c
tests/recording.c
tests/rect_fill.c
tests/save_restore.c
tests/simple_paint.c
tests/stroke.c
tests/surface.c
tests/svg.c
tests/test1.c
tests/text.c
tests/tmp/getarcstep.c
tests/transform.c
tests/vkvg-svg/svg-viewer.c

diff --git a/.clang-format b/.clang-format
new file mode 100644 (file)
index 0000000..cf8cd36
--- /dev/null
@@ -0,0 +1,225 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignArrayOfStructures: None
+AlignConsecutiveAssignments:
+  Enabled:         true
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  PadOperators:    true
+AlignConsecutiveBitFields:
+  Enabled:         true
+  AcrossEmptyLines: true
+  AcrossComments:  false
+  AlignCompound:   false
+  PadOperators:    false
+AlignConsecutiveDeclarations:
+  Enabled:         true
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  PadOperators:    false
+AlignConsecutiveMacros:
+  Enabled:         true
+  AcrossEmptyLines: true
+  AcrossComments:  false
+  AlignCompound:   false
+  PadOperators:    false
+AlignEscapedNewlines: Right
+AlignOperands:   Align
+AlignTrailingComments:
+  Kind:            Always
+  OverEmptyLines:  0
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: All
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+AttributeMacros:
+  - __capability
+BinPackArguments: true
+BinPackParameters: true
+BitFieldColonSpacing: Both
+BraceWrapping:
+  AfterCaseLabel:  false
+  AfterClass:      false
+  AfterControlStatement: Never
+  AfterEnum:       false
+  AfterExternBlock: false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakAfterAttributes: Never
+BreakAfterJavaFieldAnnotations: false
+BreakArrays:     true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: Always
+BreakBeforeBraces: Attach
+BreakBeforeInlineASMColon: OnlyMultiline
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: true
+ColumnLimit:     120
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IfMacros:
+  - KJ_IF_MAYBE
+IncludeBlocks:   Preserve
+IncludeCategories:
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '.*'
+    Priority:        1
+    SortPriority:    0
+    CaseSensitive:   false
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseBlocks: false
+IndentCaseLabels: false
+IndentExternBlock: AfterExternBlock
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentRequiresClause: true
+IndentWidth:     4
+IndentWrappedFunctionNames: false
+InsertBraces:    false
+InsertNewlineAtEOF: false
+InsertTrailingCommas: None
+IntegerLiteralSeparator:
+  Binary:          0
+  BinaryMinDigits: 0
+  Decimal:         0
+  DecimalMinDigits: 0
+  Hex:             0
+  HexMinDigits:    0
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+LambdaBodyIndentation: Signature
+LineEnding:      DeriveLF
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PackConstructorInitializers: BinPack
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyIndentedWhitespace: 0
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+PPIndentWidth:   -1
+QualifierAlignment: Leave
+ReferenceAlignment: Pointer
+ReflowComments:  true
+RemoveBracesLLVM: false
+RemoveSemicolon: false
+RequiresClausePosition: OwnLine
+RequiresExpressionIndentation: OuterScope
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SortIncludes: false 
+SortJavaStaticImport: Before
+SortUsingDeclarations: LexicographicNumeric
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeParensOptions:
+  AfterControlStatements: true
+  AfterForeachMacros: true
+  AfterFunctionDefinitionName: false
+  AfterFunctionDeclarationName: false
+  AfterIfMacros:   true
+  AfterOverloadedOperator: false
+  AfterRequiresInClause: false
+  AfterRequiresInExpression: false
+  BeforeNonEmptyParentheses: false
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  Never
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInLineCommentPrefix:
+  Minimum:         1
+  Maximum:         -1
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Latest
+StatementAttributeLikeMacros:
+  - Q_EMIT
+StatementMacros:
+  - Q_UNUSED
+  - QT_REQUIRE_VERSION
+TabWidth:        4
+UseTab:          Never
+WhitespaceSensitiveMacros:
+  - BOOST_PP_STRINGIZE
+  - CF_SWIFT_NAME
+  - NS_SWIFT_NAME
+  - PP_STRINGIZE
+  - STRINGIZE
+...
+
index 61b916c5a511bcb2a0f9590c4339eec57abcf746..4df57ce9f06766381e10554d699912472485cabf 100644 (file)
@@ -27,9 +27,9 @@ extern "C" {
 #endif
 
 #ifdef VKVG_SVG
-typedef struct _vkvg_svg_tVkvgSvg;
+typedef struct _vkvg_svg_t *VkvgSvg;
 #else
-typedef struct NSVGimageVkvgSvg;
+typedef struct NSVGimage *VkvgSvg;
 #endif
 /**
  * @brief load svg file into @ref surface
@@ -41,8 +41,8 @@ typedef struct NSVGimage* VkvgSvg;
  * @param height force the rendering height, if 0 autosize from svg.
  * @return The new vkvg surface with the loaded SVG drawing as content, or null if an error occured.
  */
-vkvg_public
-VkvgSurface vkvg_surface_create_from_svg(VkvgDevice dev, uint32_t width, uint32_t height, const char* svgFilePath);
+vkvg_public VkvgSurface vkvg_surface_create_from_svg(VkvgDevice dev, uint32_t width, uint32_t height,
+                                                     const char *svgFilePath);
 /**
  * @brief create surface from svg fragment
  *
@@ -53,8 +53,8 @@ VkvgSurface vkvg_surface_create_from_svg(VkvgDevice dev, uint32_t width, uint32_
  * @param svgFragment The SVG fragment to parse.
  * @return The new vkvg surface with the parsed SVG fragment as content, or null if an error occured.
  */
-vkvg_public
-VkvgSurface vkvg_surface_create_from_svg_fragment(VkvgDevice dev, uint32_t width, uint32_t height, char* svgFragment);
+vkvg_public VkvgSurface vkvg_surface_create_from_svg_fragment(VkvgDevice dev, uint32_t width, uint32_t height,
+                                                              char *svgFragment);
 /**
  * @brief get svg dimensions.
  *
@@ -63,8 +63,7 @@ VkvgSurface vkvg_surface_create_from_svg_fragment(VkvgDevice dev, uint32_t width
  * @param width pointer to a valid integer to receive the svg width.
  * @param height pointer to a valid integer to receive the svg height.
  */
-vkvg_public
-void vkvg_svg_get_dimensions (VkvgSvg svg, uint32_t* width, uint32_t* height);
+vkvg_public void vkvg_svg_get_dimensions(VkvgSvg svg, uint32_t *width, uint32_t *height);
 
 /**
  * @brief Load svg file in memory.
@@ -73,16 +72,14 @@ void vkvg_svg_get_dimensions (VkvgSvg svg, uint32_t* width, uint32_t* height);
  * @param svgFilePath a valid file path to the svg to load.
  * @return a VkvgSvg pointer.
  */
-vkvg_public
-VkvgSvg vkvg_svg_load (const char* svgFilePath);
+vkvg_public VkvgSvg vkvg_svg_load(const char *svgFilePath);
 
 /**
  * @brief Load svg from an svg source fragment.
  * @param svgFragment A valid svg code fragment.
  * @return a VkvgSvg pointer.
  */
-vkvg_public
-VkvgSvg vkvg_svg_load_fragment (char* svgFragment);
+vkvg_public VkvgSvg vkvg_svg_load_fragment(char *svgFragment);
 
 /**
  * @brief render svg on a context.
@@ -90,15 +87,13 @@ VkvgSvg vkvg_svg_load_fragment (char* svgFragment);
  * @param ctx a valid vkvg context.
  * @param id an optional id to limit rendering to specific `<g>` elemnt.
  */
-vkvg_public
-void vkvg_svg_render (VkvgSvg svg, VkvgContext ctx, const char* id);
+vkvg_public void vkvg_svg_render(VkvgSvg svg, VkvgContext ctx, const char *id);
 
 /**
  * @brief release VkvgSvg pointer resources.
  * @param svg a valid VkvgSvg handle to free.
  */
-vkvg_public
-void vkvg_svg_destroy (VkvgSvg svg);
+vkvg_public void vkvg_svg_destroy(VkvgSvg svg);
 
 #ifdef __cplusplus
 }
index 2ac2c31c50a2e70a2e03edb567aba46f3ef1a6ad..132aabac90b67bebab1a9ceef3729a6495be1076 100644 (file)
@@ -28,11 +28,13 @@ extern "C" {
 
 /** @mainpage Documentation
  *
- * VKVG is an open source 2d vector drawing library written in @b c and using [vulkan](https://www.khronos.org/vulkan/) for hardware acceleration.
+ * VKVG is an open source 2d vector drawing library written in @b c and using [vulkan](https://www.khronos.org/vulkan/)
+ * for hardware acceleration.
  *
  * @image html screenshot3.png
  *
- * Its api is modeled on the [cairo graphic library](https://www.cairographics.org/) with the following software components:
+ * Its api is modeled on the [cairo graphic library](https://www.cairographics.org/) with the following software
+ * components:
  *
  * - @ref surface
  * - @ref context
@@ -67,47 +69,46 @@ extern "C" {
 #include <stdbool.h>
 
 #ifndef vkvg_public
-       #ifdef VKVG_SHARED_BUILD
-               #if (defined(_WIN32) || defined(_WIN64))
-                       #define vkvg_public __declspec(dllexport)
-               #else
-                       #define vkvg_public __attribute__((visibility("default")))
-               #endif
-       #elif (defined(VKVG_SHARED_LINKING) && (defined(_WIN32) || defined(_WIN64)))
-               #define vkvg_public __declspec(dllimport)
-       #else
-               #define vkvg_public 
-       #endif
+#ifdef VKVG_SHARED_BUILD
+#if (defined(_WIN32) || defined(_WIN64))
+#define vkvg_public __declspec(dllexport)
+#else
+#define vkvg_public __attribute__((visibility("default")))
+#endif
+#elif (defined(VKVG_SHARED_LINKING) && (defined(_WIN32) || defined(_WIN64)))
+#define vkvg_public __declspec(dllimport)
+#else
+#define vkvg_public
+#endif
 #endif
 
+#define VKVG_LOG_ERR        0x00000001
+#define VKVG_LOG_DEBUG      0x00000002
 
-#define VKVG_LOG_ERR           0x00000001
-#define VKVG_LOG_DEBUG         0x00000002
-
-#define VKVG_LOG_INFO_PTS      0x00000004
-#define VKVG_LOG_INFO_PATH     0x00000008
-#define VKVG_LOG_INFO_CMD      0x00000010
-#define VKVG_LOG_INFO_VBO      0x00000020
-#define VKVG_LOG_INFO_IBO      0x00000040
-#define VKVG_LOG_INFO_VAO      (VKVG_LOG_INFO_VBO|VKVG_LOG_INFO_IBO)
-#define VKVG_LOG_THREAD                0x00000080
-#define VKVG_LOG_DBG_ARRAYS    0x00001000
-#define VKVG_LOG_STROKE                0x00010000
-#define VKVG_LOG_FULL          0xffffffff
+#define VKVG_LOG_INFO_PTS   0x00000004
+#define VKVG_LOG_INFO_PATH  0x00000008
+#define VKVG_LOG_INFO_CMD   0x00000010
+#define VKVG_LOG_INFO_VBO   0x00000020
+#define VKVG_LOG_INFO_IBO   0x00000040
+#define VKVG_LOG_INFO_VAO   (VKVG_LOG_INFO_VBO | VKVG_LOG_INFO_IBO)
+#define VKVG_LOG_THREAD     0x00000080
+#define VKVG_LOG_DBG_ARRAYS 0x00001000
+#define VKVG_LOG_STROKE     0x00010000
+#define VKVG_LOG_FULL       0xffffffff
 
-#define VKVG_LOG_INFO          0x00008000//(VKVG_LOG_INFO_PTS|VKVG_LOG_INFO_PATH|VKVG_LOG_INFO_CMD|VKVG_LOG_INFO_VAO)
+#define VKVG_LOG_INFO       0x00008000 //(VKVG_LOG_INFO_PTS|VKVG_LOG_INFO_PATH|VKVG_LOG_INFO_CMD|VKVG_LOG_INFO_VAO)
 #ifdef DEBUG
-       extern uint32_t vkvg_log_level;
-       #ifdef VKVG_WIRED_DEBUG
-               typedef enum {
-                       vkvg_wired_debug_mode_normal    = 0x01,
-                       vkvg_wired_debug_mode_points    = 0x02,
-                       vkvg_wired_debug_mode_lines             = 0x04,
-                       vkvg_wired_debug_mode_both              = vkvg_wired_debug_mode_points|vkvg_wired_debug_mode_lines,
-                       vkvg_wired_debug_mode_all               = 0xFFFFFFFF
-               }vkvg_wired_debug_mode;
-               extern vkvg_wired_debug_mode vkvg_wired_debug;
-       #endif
+extern uint32_t vkvg_log_level;
+#ifdef VKVG_WIRED_DEBUG
+typedef enum {
+    vkvg_wired_debug_mode_normal = 0x01,
+    vkvg_wired_debug_mode_points = 0x02,
+    vkvg_wired_debug_mode_lines  = 0x04,
+    vkvg_wired_debug_mode_both   = vkvg_wired_debug_mode_points | vkvg_wired_debug_mode_lines,
+    vkvg_wired_debug_mode_all    = 0xFFFFFFFF
+vkvg_wired_debug_mode;
+extern vkvg_wired_debug_mode vkvg_wired_debug;
+#endif
 #endif
 
 /**
@@ -120,40 +121,32 @@ extern "C" {
  * As soon as a status is not success, further operations will be canceled.
  */
 typedef enum {
-       VKVG_STATUS_SUCCESS = 0,                        /*!< no error occurred.*/
-       VKVG_STATUS_NO_MEMORY,                          /*!< out of memory*/
-       VKVG_STATUS_INVALID_RESTORE,            /*!< call to #vkvg_restore without matching call to #vkvg_save*/
-       VKVG_STATUS_NO_CURRENT_POINT,           /*!< path command expecting a current point to be defined failed*/
-       VKVG_STATUS_INVALID_MATRIX,                     /*!< invalid matrix (not invertible)*/
-       VKVG_STATUS_INVALID_STATUS,                     /*!< */
-       VKVG_STATUS_INVALID_INDEX,                      /*!< */
-       VKVG_STATUS_NULL_POINTER,                       /*!< NULL pointer*/
-       VKVG_STATUS_WRITE_ERROR,                        /*!< */
-       VKVG_STATUS_PATTERN_TYPE_MISMATCH,      /*!< */
-       VKVG_STATUS_PATTERN_INVALID_GRADIENT,/*!< occurs when stops count is zero */
-       VKVG_STATUS_INVALID_FORMAT,                     /*!< */
-       VKVG_STATUS_FILE_NOT_FOUND,                     /*!< */
-       VKVG_STATUS_INVALID_DASH,                       /*!< invalid value for a dash setting */
-       VKVG_STATUS_INVALID_RECT,                       /*!< rectangle with height or width equal to 0. */
-       VKVG_STATUS_TIMEOUT,                            /*!< waiting for a vulkan operation to finish resulted in a fence timeout (5 seconds)*/
-       VKVG_STATUS_DEVICE_ERROR,                       /*!< vkvg device initialization error */
-       VKVG_STATUS_INVALID_IMAGE,                      /*!< */
-       VKVG_STATUS_INVALID_SURFACE,            /*!< */
-       VKVG_STATUS_INVALID_FONT,                       /*!< Unresolved font name*/
-       VKVG_STATUS_ENUM_MAX = 0x7FFFFFFF
-}vkvg_status_t;
+    VKVG_STATUS_SUCCESS = 0,              /*!< no error occurred.*/
+    VKVG_STATUS_NO_MEMORY,                /*!< out of memory*/
+    VKVG_STATUS_INVALID_RESTORE,          /*!< call to #vkvg_restore without matching call to #vkvg_save*/
+    VKVG_STATUS_NO_CURRENT_POINT,         /*!< path command expecting a current point to be defined failed*/
+    VKVG_STATUS_INVALID_MATRIX,           /*!< invalid matrix (not invertible)*/
+    VKVG_STATUS_INVALID_STATUS,           /*!< */
+    VKVG_STATUS_INVALID_INDEX,            /*!< */
+    VKVG_STATUS_NULL_POINTER,             /*!< NULL pointer*/
+    VKVG_STATUS_WRITE_ERROR,              /*!< */
+    VKVG_STATUS_PATTERN_TYPE_MISMATCH,    /*!< */
+    VKVG_STATUS_PATTERN_INVALID_GRADIENT, /*!< occurs when stops count is zero */
+    VKVG_STATUS_INVALID_FORMAT,           /*!< */
+    VKVG_STATUS_FILE_NOT_FOUND,           /*!< */
+    VKVG_STATUS_INVALID_DASH,             /*!< invalid value for a dash setting */
+    VKVG_STATUS_INVALID_RECT,             /*!< rectangle with height or width equal to 0. */
+    VKVG_STATUS_TIMEOUT,         /*!< waiting for a vulkan operation to finish resulted in a fence timeout (5 seconds)*/
+    VKVG_STATUS_DEVICE_ERROR,    /*!< vkvg device initialization error */
+    VKVG_STATUS_INVALID_IMAGE,   /*!< */
+    VKVG_STATUS_INVALID_SURFACE, /*!< */
+    VKVG_STATUS_INVALID_FONT,    /*!< Unresolved font name*/
+    VKVG_STATUS_ENUM_MAX = 0x7FFFFFFF
+} vkvg_status_t;
 
-typedef enum {
-       VKVG_HORIZONTAL = 0,
-       VKVG_VERTICAL   = 1
-}vkvg_direction_t;
+typedef enum { VKVG_HORIZONTAL = 0, VKVG_VERTICAL = 1 } vkvg_direction_t;
 
-typedef enum {
-       VKVG_FORMAT_ARGB32,
-       VKVG_FORMAT_RGB24,
-       VKVG_FORMAT_A8,
-       VKVG_FORMAT_A1
-} vkvg_format_t;
+typedef enum { VKVG_FORMAT_ARGB32, VKVG_FORMAT_RGB24, VKVG_FORMAT_A8, VKVG_FORMAT_A1 } vkvg_format_t;
 /**
  * @brief pattern border policy
  *
@@ -161,20 +154,19 @@ typedef enum {
  * the extend defines how the pattern will be rendered outside its original bounds.
  */
 typedef enum {
-       VKVG_EXTEND_NONE,                       /*!< nothing will be outputed outside the pattern original bounds */
-       VKVG_EXTEND_REPEAT,                     /*!< pattern will be repeated to fill all the target bounds */
-       VKVG_EXTEND_REFLECT,            /*!< pattern will be repeated but mirrored on each repeat */
-       VKVG_EXTEND_PAD                         /*!< the last pixels making the borders of the pattern will be extended to the whole target */
+    VKVG_EXTEND_NONE,    /*!< nothing will be outputed outside the pattern original bounds */
+    VKVG_EXTEND_REPEAT,  /*!< pattern will be repeated to fill all the target bounds */
+    VKVG_EXTEND_REFLECT, /*!< pattern will be repeated but mirrored on each repeat */
+    VKVG_EXTEND_PAD      /*!< the last pixels making the borders of the pattern will be extended to the whole target */
 } vkvg_extend_t;
 
-
 typedef enum {
-       VKVG_FILTER_FAST,
-       VKVG_FILTER_GOOD,
-       VKVG_FILTER_BEST,
-       VKVG_FILTER_NEAREST,
-       VKVG_FILTER_BILINEAR,
-       VKVG_FILTER_GAUSSIAN,
+    VKVG_FILTER_FAST,
+    VKVG_FILTER_GOOD,
+    VKVG_FILTER_BEST,
+    VKVG_FILTER_NEAREST,
+    VKVG_FILTER_BILINEAR,
+    VKVG_FILTER_GAUSSIAN,
 } vkvg_filter_t;
 
 /**
@@ -183,12 +175,12 @@ typedef enum {
  *
  */
 typedef enum {
-       VKVG_PATTERN_TYPE_SOLID,                        /*!< single color pattern */
-       VKVG_PATTERN_TYPE_SURFACE,                      /*!< vkvg surface pattern */
-       VKVG_PATTERN_TYPE_LINEAR,                       /*!< linear gradient pattern */
-       VKVG_PATTERN_TYPE_RADIAL,                       /*!< radial gradient pattern */
-       VKVG_PATTERN_TYPE_MESH,                         /*!< not implemented */
-       VKVG_PATTERN_TYPE_RASTER_SOURCE,        /*!< not implemented */
+    VKVG_PATTERN_TYPE_SOLID,         /*!< single color pattern */
+    VKVG_PATTERN_TYPE_SURFACE,       /*!< vkvg surface pattern */
+    VKVG_PATTERN_TYPE_LINEAR,        /*!< linear gradient pattern */
+    VKVG_PATTERN_TYPE_RADIAL,        /*!< radial gradient pattern */
+    VKVG_PATTERN_TYPE_MESH,          /*!< not implemented */
+    VKVG_PATTERN_TYPE_RASTER_SOURCE, /*!< not implemented */
 } vkvg_pattern_type_t;
 
 /**
@@ -198,9 +190,9 @@ typedef enum {
  * configuration which may be accessed with #vkvg_set_line_cap and #vkvg_get_line_cap
  */
 typedef enum {
-       VKVG_LINE_CAP_BUTT,             /*!< normal line endings, this is the default. */
-       VKVG_LINE_CAP_ROUND,    /*!< rounded line caps */
-       VKVG_LINE_CAP_SQUARE    /*!< extend the caps with squared terminations having border equal to current line width. */
+    VKVG_LINE_CAP_BUTT,  /*!< normal line endings, this is the default. */
+    VKVG_LINE_CAP_ROUND, /*!< rounded line caps */
+    VKVG_LINE_CAP_SQUARE /*!< extend the caps with squared terminations having border equal to current line width. */
 } vkvg_line_cap_t;
 /**
  * @brief lines articulations
@@ -209,9 +201,9 @@ typedef enum {
  * in the context and may be accessed with #vkvg_set_line_join and #vkvg_get_line_join.
  */
 typedef enum {
-       VKVG_LINE_JOIN_MITER,   /*!< normal joins with sharp angles, this is the default. */
-       VKVG_LINE_JOIN_ROUND,   /*!< joins are rounded on the exterior border of the line. */
-       VKVG_LINE_JOIN_BEVEL    /*!< beveled line joins. */
+    VKVG_LINE_JOIN_MITER, /*!< normal joins with sharp angles, this is the default. */
+    VKVG_LINE_JOIN_ROUND, /*!< joins are rounded on the exterior border of the line. */
+    VKVG_LINE_JOIN_BEVEL  /*!< beveled line joins. */
 } vkvg_line_join_t;
 
 /**
@@ -223,58 +215,63 @@ typedef enum {
  * All further drawing and clipping operations are affected by this setting.
  */
 typedef enum {
-       VKVG_FILL_RULE_EVEN_ODD,        /*!< even-odd fill rule */
-       VKVG_FILL_RULE_NON_ZERO         /*!< non zero fill rule */
+    VKVG_FILL_RULE_EVEN_ODD, /*!< even-odd fill rule */
+    VKVG_FILL_RULE_NON_ZERO  /*!< non zero fill rule */
 } vkvg_fill_rule_t;
 
 typedef struct {
-       float r;                                        /*!< the red component */
-       float g;                                        /*!< the green component */
-       float b;                                        /*!< the blue component */
-       float a;                                        /*!< the alpha component */
+    float r; /*!< the red component */
+    float g; /*!< the green component */
+    float b; /*!< the blue component */
+    float a; /*!< the alpha component */
 } vkvg_color_t;
 
 /**
 * @brief font metrics
 *
 * structure defining global font metrics for a particular font. It can be retrieve by calling @ref vkvg_font_extents
 * on a valid context.
 */
+ * @brief font metrics
+ *
+ * structure defining global font metrics for a particular font. It can be retrieve by calling @ref vkvg_font_extents
+ * on a valid context.
+ */
 typedef struct {
-       float ascent;                   /*!< the distance that the font extends above the baseline. */
-       float descent;                  /*!< the distance that the font extends below the baseline.*/
-       float height;                   /*!< the recommended vertical distance between baselines. */
-       float max_x_advance;    /*!< the maximum distance in the X direction that the origin is advanced for any glyph in the font.*/
-       float max_y_advance;    /*!< the maximum distance in the Y direction that the origin is advanced for any glyph in the font. This will be zero for normal fonts used for horizontal writing.*/
+    float ascent;        /*!< the distance that the font extends above the baseline. */
+    float descent;       /*!< the distance that the font extends below the baseline.*/
+    float height;        /*!< the recommended vertical distance between baselines. */
+    float max_x_advance; /*!< the maximum distance in the X direction that the origin is advanced for any glyph in the
+                            font.*/
+    float max_y_advance; /*!< the maximum distance in the Y direction that the origin is advanced for any glyph in the
+                            font. This will be zero for normal fonts used for horizontal writing.*/
 } vkvg_font_extents_t;
 /**
 * @brief text metrics
 *
 * structure defining metrics for a single or a string of glyphs. To measure text, call @ref vkvg_text_extents
 * on a valid context.
 */
+ * @brief text metrics
+ *
+ * structure defining metrics for a single or a string of glyphs. To measure text, call @ref vkvg_text_extents
+ * on a valid context.
+ */
 typedef struct {
-       float x_bearing;                /*!< the horizontal distance from the origin to the leftmost part of the glyphs as drawn. Positive if the glyphs lie entirely to the right of the origin. */
-       float y_bearing;                /*!< the vertical distance from the origin to the topmost part of the glyphs as drawn. Positive only if the glyphs lie completely below the origin; will usually be negative.*/
-       float width;                    /*!< width of the glyphs as drawn*/
-       float height;                   /*!< height of the glyphs as drawn*/
-       float x_advance;                /*!< distance to advance in the X direction after drawing these glyphs*/
-       float y_advance;                /*!< distance to advance in the Y direction after drawing these glyphs. Will typically be zero except for vertical text layout as found in East-Asian languages.*/
+    float x_bearing; /*!< the horizontal distance from the origin to the leftmost part of the glyphs as drawn. Positive
+                        if the glyphs lie entirely to the right of the origin. */
+    float y_bearing; /*!< the vertical distance from the origin to the topmost part of the glyphs as drawn. Positive
+                        only if the glyphs lie completely below the origin; will usually be negative.*/
+    float width;     /*!< width of the glyphs as drawn*/
+    float height;    /*!< height of the glyphs as drawn*/
+    float x_advance; /*!< distance to advance in the X direction after drawing these glyphs*/
+    float y_advance; /*!< distance to advance in the Y direction after drawing these glyphs. Will typically be zero
+                        except for vertical text layout as found in East-Asian languages.*/
 } vkvg_text_extents_t;
 
 /**
 * @brief glyphs position in a @ref VkvgText
 *
 * structure defining glyph position as computed for rendering a text run.
 * the codepoint field is for internal use only.
 */
+ * @brief glyphs position in a @ref VkvgText
+ *
+ * structure defining glyph position as computed for rendering a text run.
+ * the codepoint field is for internal use only.
+ */
 typedef struct _glyph_info_t {
-       int32_t  x_advance;
-       int32_t  y_advance;
-       int32_t  x_offset;
-       int32_t  y_offset;
-       /* private */
-       uint32_t codepoint;//should be named glyphIndex, but for harfbuzz compatibility...
+    int32_t x_advance;
+    int32_t y_advance;
+    int32_t x_offset;
+    int32_t y_offset;
+    /* private */
+    uint32_t codepoint; // should be named glyphIndex, but for harfbuzz compatibility...
 } vkvg_glyph_info_t;
 
 /**
@@ -289,7 +286,7 @@ typedef struct _glyph_info_t {
  * Drawing text with @ref vkvg_show_text() implicitly create such intermediate structure
  * that is destroyed imediatly after the function call.
  */
-typedef struct _vkvg_text_run_tVkvgText;
+typedef struct _vkvg_text_run_t *VkvgText;
 
 /**
  * @brief The Vkvg drawing Context.
@@ -297,7 +294,7 @@ typedef struct _vkvg_text_run_t* VkvgText;
  *
  * A #VkvgContext is the central object for drawing operations.
  */
-typedef struct _vkvg_context_tVkvgContext;
+typedef struct _vkvg_context_t *VkvgContext;
 /**
  * @brief Opaque pointer on a Vkvg Surface structure.
  * @ingroup surface
@@ -309,14 +306,14 @@ typedef struct _vkvg_context_t* VkvgContext;
  * with the surface as the target, using #vkvg_create().
  *
  */
-typedef struct _vkvg_surface_tVkvgSurface;
+typedef struct _vkvg_surface_t *VkvgSurface;
 /**
  * @brief Opaque pointer on a Vkvg device structure.
  * @ingroup device
  *
  * A #VkvgDevice is required for creating new surfaces.
  */
-typedef struct _vkvg_device_tVkvgDevice;
+typedef struct _vkvg_device_t *VkvgDevice;
 /**
  * @brief Opaque pointer on a Vkvg pattern structure.
  * @ingroup pattern
@@ -324,28 +321,27 @@ typedef struct _vkvg_device_t*    VkvgDevice;
  * Patterns are images to be drawn on surface with several
  * configurable parameters such as the wrap mode, the filtering, etc...
  */
-typedef struct _vkvg_pattern_tVkvgPattern;
+typedef struct _vkvg_pattern_t *VkvgPattern;
 
 #if VKVG_DBG_STATS
 /**
  * @brief vkvg memory and vulkan statistiques.
- * 
+ *
  * @ingroup device
  */
 typedef struct {
-       uint32_t        sizePoints;             /**< maximum point array size                                   */
-       uint32_t        sizePathes;             /**< maximum path array size                                    */
-       uint32_t        sizeVertices;   /**< maximum size of host vertice cache                 */
-       uint32_t        sizeIndices;    /**< maximum size of host index cache                   */
-       uint32_t        sizeVBO;                /**< maximum size of vulkan vertex buffer               */
-       uint32_t        sizeIBO;                /**< maximum size of vulkan index buffer                */
+    uint32_t sizePoints;   /**< maximum point array size                                       */
+    uint32_t sizePathes;   /**< maximum path array size                                        */
+    uint32_t sizeVertices; /**< maximum size of host vertice cache                     */
+    uint32_t sizeIndices;  /**< maximum size of host index cache                       */
+    uint32_t sizeVBO;      /**< maximum size of vulkan vertex buffer           */
+    uint32_t sizeIBO;      /**< maximum size of vulkan index buffer            */
 } vkvg_debug_stats_t;
 
-vkvg_debug_stats_t vkvg_device_get_stats (VkvgDevice dev);
-vkvg_debug_stats_t vkvg_device_reset_stats (VkvgDevice dev);
+vkvg_debug_stats_t vkvg_device_get_stats(VkvgDevice dev);
+vkvg_debug_stats_t vkvg_device_reset_stats(VkvgDevice dev);
 #endif
 
-
 /**
  * @defgroup matrix Matrices
  * @brief Generic matrix operations
@@ -353,7 +349,8 @@ vkvg_debug_stats_t vkvg_device_reset_stats (VkvgDevice dev);
  * This is the reference documentation for handling matrices to use as transformation in drawing operations.
  * Matrix computations in vkvg are taken from the cairo library.
  * @{ */
-#define VKVG_IDENTITY_MATRIX (vkvg_matrix_t){1,0,0,1,0,0}/*!< The identity matrix*/
+#define VKVG_IDENTITY_MATRIX                                                                                           \
+    (vkvg_matrix_t) { 1, 0, 0, 1, 0, 0 } /*!< The identity matrix*/
 /**
  * @brief vkvg matrix structure
  *
@@ -372,9 +369,12 @@ vkvg_debug_stats_t vkvg_device_reset_stats (VkvgDevice dev);
  * @y0: Y translation component of the affine transformation
  */
 typedef struct {
-       float xx; float yx;
-       float xy; float yy;
-       float x0; float y0;
+    float xx;
+    float yx;
+    float xy;
+    float yy;
+    float x0;
+    float y0;
 } vkvg_matrix_t;
 /**
  * @brief Set matrix to identity
@@ -382,8 +382,7 @@ typedef struct {
  * Initialize members of the supplied #vkvg_matrix_t to make an identity matrix of it.
  * @param matrix a valid #vkvg_matrix_t pointer.
  */
-vkvg_public
-void vkvg_matrix_init_identity (vkvg_matrix_t *matrix);
+vkvg_public void vkvg_matrix_init_identity(vkvg_matrix_t *matrix);
 /**
  * @brief Matrix initialization.
  *
@@ -397,11 +396,7 @@ void vkvg_matrix_init_identity (vkvg_matrix_t *matrix);
  * @param x0 X translation component of the affine transformation
  * @param y0 Y translation component of the affine transformation
  */
-vkvg_public
-void vkvg_matrix_init (vkvg_matrix_t *matrix,
-                  float xx, float yx,
-                  float xy, float yy,
-                  float x0, float y0);
+vkvg_public void vkvg_matrix_init(vkvg_matrix_t *matrix, float xx, float yx, float xy, float yy, float x0, float y0);
 /**
  * @brief Rotation matrix initialization
  *
@@ -410,8 +405,7 @@ void vkvg_matrix_init (vkvg_matrix_t *matrix,
  * @param tx translation in the X direction
  * @param ty translation in the Y direction
  */
-vkvg_public
-void vkvg_matrix_init_translate (vkvg_matrix_t *matrix, float tx, float ty);
+vkvg_public void vkvg_matrix_init_translate(vkvg_matrix_t *matrix, float tx, float ty);
 /**
  * @brief scaling matrix initialization
  *
@@ -420,8 +414,7 @@ void vkvg_matrix_init_translate (vkvg_matrix_t *matrix, float tx, float ty);
  * @param sx scale in the x direction
  * @param sy Scale in the y direction
  */
-vkvg_public
-void vkvg_matrix_init_scale (vkvg_matrix_t *matrix, float sx, float sy);
+vkvg_public void vkvg_matrix_init_scale(vkvg_matrix_t *matrix, float sx, float sy);
 /**
  * @brief rotation matrix initialization
  *
@@ -433,8 +426,7 @@ void vkvg_matrix_init_scale (vkvg_matrix_t *matrix, float sx, float sy);
  * axis orientation of vkvg, positive angles rotate in a clockwise
  * direction.
  */
-vkvg_public
-void vkvg_matrix_init_rotate (vkvg_matrix_t *matrix, float radians);
+vkvg_public void vkvg_matrix_init_rotate(vkvg_matrix_t *matrix, float radians);
 /**
  * @brief apply translation on matrix
  *
@@ -445,8 +437,7 @@ void vkvg_matrix_init_rotate (vkvg_matrix_t *matrix, float radians);
  * @param tx translation in the x direction
  * @param ty translation in the y direction
  */
-vkvg_public
-void vkvg_matrix_translate (vkvg_matrix_t *matrix, float tx, float ty);
+vkvg_public void vkvg_matrix_translate(vkvg_matrix_t *matrix, float tx, float ty);
 /**
  * @brief apply scale on matrix
  *
@@ -457,8 +448,7 @@ void vkvg_matrix_translate (vkvg_matrix_t *matrix, float tx, float ty);
  * @param sx scale in the x direction
  * @param sy scale in the y direction
  */
-vkvg_public
-void vkvg_matrix_scale (vkvg_matrix_t *matrix, float sx, float sy);
+vkvg_public void vkvg_matrix_scale(vkvg_matrix_t *matrix, float sx, float sy);
 /**
  * @brief apply rotation on matrix
  *
@@ -470,8 +460,7 @@ void vkvg_matrix_scale (vkvg_matrix_t *matrix, float sx, float sy);
  * rotate in the direction from the positive X axis toward the positive Y axis.
  * With the default axis orientation of cairo, positive angles rotate in a clockwise direction.
  */
-vkvg_public
-void vkvg_matrix_rotate (vkvg_matrix_t *matrix, float radians);
+vkvg_public void vkvg_matrix_rotate(vkvg_matrix_t *matrix, float radians);
 /**
  * @brief matrices multiplication
  *
@@ -480,25 +469,23 @@ void vkvg_matrix_rotate (vkvg_matrix_t *matrix, float radians);
  * @param a first operand of the multiplication
  * @param b second operand of the multiplication
  */
-vkvg_public
-void vkvg_matrix_multiply (vkvg_matrix_t *result, const vkvg_matrix_t *a, const vkvg_matrix_t *b);
+vkvg_public void vkvg_matrix_multiply(vkvg_matrix_t *result, const vkvg_matrix_t *a, const vkvg_matrix_t *b);
 /**
  * @brief transform distances
  *
- * Transforms the distance vector (dx ,dy ) by matrix . This is similar to #cairo_matrix_transform_point() except that the translation
- * components of the transformation are ignored. The calculation of the returned vector is as follows:
+ * Transforms the distance vector (dx ,dy ) by matrix . This is similar to #cairo_matrix_transform_point() except that
+ * the translation components of the transformation are ignored. The calculation of the returned vector is as follows:
  * @code
  * dx2 = dx1 * a + dy1 * c;
  * dy2 = dx1 * b + dy1 * d;
  * @endcode
- * Affine transformations are position invariant, so the same vector always transforms to the same vector. If (x1 ,y1 ) transforms to (x2 ,y2 )
- * then (x1 +dx1 ,y1 +dy1 ) will transform to (x1 +dx2 ,y1 +dy2 ) for all values of x1 and x2 .
+ * Affine transformations are position invariant, so the same vector always transforms to the same vector. If (x1 ,y1 )
+ * transforms to (x2 ,y2 ) then (x1 +dx1 ,y1 +dy1 ) will transform to (x1 +dx2 ,y1 +dy2 ) for all values of x1 and x2 .
  * @param matrix a valid #vkvg_matrix_t to use to transform distance
  * @param dx X component of a distance vector. An in/out parameter
  * @param dy Y component of a distance vector. An in/out parameter
  */
-vkvg_public
-void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, float *dx, float *dy);
+vkvg_public void vkvg_matrix_transform_distance(const vkvg_matrix_t *matrix, float *dx, float *dy);
 /**
  * @brief transform point
  *
@@ -507,8 +494,7 @@ void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, float *dx, flo
  * @param x X position. An in/out parameter
  * @param y Y position. An in/out parameter
  */
-vkvg_public
-void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, float *x, float *y);
+vkvg_public void vkvg_matrix_transform_point(const vkvg_matrix_t *matrix, float *x, float *y);
 /**
  * @brief invert matrix
  *
@@ -518,10 +504,8 @@ void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, float *x, float *
  * @return If matrix has an inverse, modifies matrix to be the inverse matrix and returns VKVG_STATUS_SUCCESS.
  * Otherwise, returns VKVG_STATUS_INVALID_MATRIX.
  */
-vkvg_public
-vkvg_status_t vkvg_matrix_invert (vkvg_matrix_t *matrix);
-vkvg_public
-void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy);
+vkvg_public vkvg_status_t vkvg_matrix_invert(vkvg_matrix_t *matrix);
+vkvg_public void          vkvg_matrix_get_scale(const vkvg_matrix_t *matrix, float *sx, float *sy);
 /** @}*/
 
 /*!
@@ -564,38 +548,38 @@ void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy);
  */
 typedef struct {
     VkSampleCountFlags samples;
-    bool deferredResolve;
-    VkInstance inst;
-       VkPhysicalDevice phy;
-       VkDevice vkdev;
-       uint32_t qFamIdx;
-    uint32_t qIndex;
-}vkvg_device_create_info_t;
+    bool               deferredResolve;
+    VkInstance         inst;
+    VkPhysicalDevice   phy;
+    VkDevice           vkdev;
+    uint32_t           qFamIdx;
+    uint32_t           qIndex;
+} vkvg_device_create_info_t;
 /**
  * @brief Set device ready for multithreading.
  *
  * If thread aware mode is set to true,
  *
- * This method should be called only once on device creation. If this method is called while some surfaces or patterns are
- * in use, this could have unexpected results.
+ * This method should be called only once on device creation. If this method is called while some surfaces or patterns
+ * are in use, this could have unexpected results.
  *
  *
  * @param dev
  * @param thread_awayre
  */
+vkvg_public void vkvg_device_set_thread_aware(VkvgDevice dev, uint32_t thread_awayre);
 vkvg_public
-void vkvg_device_set_thread_aware (VkvgDevice dev, uint32_t thread_awayre);
-vkvg_public
-/**
- * @brief Set maximum cached context count.
- *
- * The context cache stored destroyed contexts per thread to speed-up new context creation.
- * To disable context cache, call this method with maxCount=0.
- *
- * @param dev A valid vkvg device pointer.
- * @param maxCount The maximum count of saved contexts for fast context instanciation.
- */
-void vkvg_device_set_context_cache_size (VkvgDevice dev, uint32_t maxCount);
+    /**
+     * @brief Set maximum cached context count.
+     *
+     * The context cache stored destroyed contexts per thread to speed-up new context creation.
+     * To disable context cache, call this method with maxCount=0.
+     *
+     * @param dev A valid vkvg device pointer.
+     * @param maxCount The maximum count of saved contexts for fast context instanciation.
+     */
+    void
+    vkvg_device_set_context_cache_size(VkvgDevice dev, uint32_t maxCount);
 /**
  * @brief Create a new vkvg device.
  *
@@ -608,11 +592,10 @@ void vkvg_device_set_context_cache_size (VkvgDevice dev, uint32_t maxCount);
  * - VKVG_STATUS_NULL_POINTER: vulkan function pointer fetching failed.
  *
  * @param samples The sample count that will be setup for the surfaces created by this device.
- * @param deferredResolve If true, the final simple sampled image of the surface will only be resolved on demand with a call
- * to #vkvg_surface_resolve() or
+ * @param deferredResolve If true, the final simple sampled image of the surface will only be resolved on demand with a
+ * call to #vkvg_surface_resolve() or
  */
-vkvg_public
-VkvgDevice vkvg_device_create (vkvg_device_create_info_t* info);
+vkvg_public VkvgDevice vkvg_device_create(vkvg_device_create_info_t *info);
 /**
  * @brief Create a new vkvg device from an existing vulkan logical device.
  *
@@ -658,8 +641,7 @@ VkvgDevice vkvg_device_create (vkvg_device_create_info_t* info);
  * Vkvg Devices has to stay active as long as surfaces created by it are used.
  * @param dev The vkvg device to destroy.
  */
-vkvg_public
-void vkvg_device_destroy (VkvgDevice dev);
+vkvg_public void vkvg_device_destroy(VkvgDevice dev);
 /**
  * @brief Get the current status of the device.
  *
@@ -667,8 +649,7 @@ void vkvg_device_destroy (VkvgDevice dev);
  * @param dev a valid vkvg device pointer.
  * @return current state.
  */
-vkvg_public
-vkvg_status_t vkvg_device_status (VkvgDevice dev);
+vkvg_public vkvg_status_t vkvg_device_status(VkvgDevice dev);
 /**
  * @brief Increment the reference count on this device.
  *
@@ -676,8 +657,7 @@ vkvg_status_t vkvg_device_status (VkvgDevice dev);
  * @param The vkvg device pointer to increment the reference count for.
  * @return
  */
-vkvg_public
-VkvgDevice vkvg_device_reference (VkvgDevice dev);
+vkvg_public VkvgDevice vkvg_device_reference(VkvgDevice dev);
 /**
  * @brief Query the reference count of the device.
  *
@@ -685,8 +665,7 @@ VkvgDevice vkvg_device_reference (VkvgDevice dev);
  * @param dev The vkvg device to get the reference count for.
  * @return The reference count on this device.
  */
-vkvg_public
-uint32_t vkvg_device_get_reference_count (VkvgDevice dev);
+vkvg_public uint32_t vkvg_device_get_reference_count(VkvgDevice dev);
 /**
  * @brief Set the screen dot per inch for this device.
  *
@@ -695,8 +674,7 @@ uint32_t vkvg_device_get_reference_count (VkvgDevice dev);
  * @param hdpy Horizontal dot per inch.
  * @param vdpy Vertical dot per inch.
  */
-vkvg_public
-void vkvg_device_set_dpy (VkvgDevice dev, int hdpy, int vdpy);
+vkvg_public void vkvg_device_set_dpy(VkvgDevice dev, int hdpy, int vdpy);
 /**
  * @brief Get the current dpy values.
  *
@@ -706,8 +684,7 @@ void vkvg_device_set_dpy (VkvgDevice dev, int hdpy, int vdpy);
  * @param hdpy The current horizontal dot per inch.
  * @param vdpy The current vertical dot per inch.
  */
-vkvg_public
-void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdpy);
+vkvg_public void vkvg_device_get_dpy(VkvgDevice dev, int *hdpy, int *vdpy);
 
 /**
  * @brief query required instance extensions for vkvg.
@@ -716,8 +693,7 @@ void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdpy);
  * by calling this method with pExtension being a NULL pointer.
  * @param pExtCount a valid pointer to an integer that will be fill with the required extension count.
  */
-vkvg_public
-void vkvg_get_required_instance_extensions (const char** pExtensions, uint32_t* pExtCount);
+vkvg_public void vkvg_get_required_instance_extensions(const char **pExtensions, uint32_t *pExtCount);
 /**
  * @brief query required device extensions for vkvg.
  * @param phy the vulkan physical device that will be used to create the @ref VkvgDevice.
@@ -725,9 +701,9 @@ void vkvg_get_required_instance_extensions (const char** pExtensions, uint32_t*
  * by calling this method with pExtension being a NULL pointer.
  * @param pExtCount a valid pointer to an integer that will be fill with the required extension count.
  * @return #VKVG_STATUS_SUCCESS or #VKVG_STATUS_DEVICE_ERROR if a fatal error occured.
-*/
-vkvg_public
-vkvg_status_t vkvg_get_required_device_extensions(VkPhysicalDevice phy, const char** pExtensions, uint32_t* pExtCount);
+ */
+vkvg_public vkvg_status_t vkvg_get_required_device_extensions(VkPhysicalDevice phy, const char **pExtensions,
+                                                              uint32_t *pExtCount);
 /**
  * @brief get vulkan device creation requirement to fit vkvg needs.
  *
@@ -735,8 +711,7 @@ vkvg_status_t vkvg_get_required_device_extensions(VkPhysicalDevice phy, const ch
  * @return the required pNext chain for the vulkan device creation. The first structure is guarantied to
  * be VkPhysicalDeviceVulkan12Features if vulkan version is >= 1.2
  */
-vkvg_public
-const void* vkvg_get_device_requirements (VkPhysicalDeviceFeatures* pEnabledFeatures);
+vkvg_public const void *vkvg_get_device_requirements(VkPhysicalDeviceFeatures *pEnabledFeatures);
 /** @}*/
 
 /** @addtogroup surface
@@ -751,8 +726,7 @@ const void* vkvg_get_device_requirements (VkPhysicalDeviceFeatures* pEnabledFeat
  * @param height Height in pixel of the surface to create.
  * @return The new vkvg surface pointer, or null if an error occured.
  */
-vkvg_public
-VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height);
+vkvg_public VkvgSurface vkvg_surface_create(VkvgDevice dev, uint32_t width, uint32_t height);
 /**
  * @brief Create a new vkvg surface by loading an image file.
  * The resulting surface will have the same dimension as the supplied image.
@@ -762,8 +736,7 @@ VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height
  * @param filePath The path of the image to load for creating the surface.
  * @return The new vkvg surface with the loaded image as content, or null if an error occured.
  */
-vkvg_public
-VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath);
+vkvg_public VkvgSurface vkvg_surface_create_from_image(VkvgDevice dev, const char *filePath);
 /**
  * @brief Create a new vkvg surface using an existing vulkan texture as backend.
  * This method will always return a valid pointer.
@@ -771,8 +744,7 @@ VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath
  * @param vkhImg The VkhImage to use as the backend texture for drawing operations.
  * @return A new surface, or null if an error occured.
  */
-vkvg_public
-VkvgSurface vkvg_surface_create_for_VkhImage (VkvgDevice dev, void* vkhImg);
+vkvg_public VkvgSurface vkvg_surface_create_for_VkhImage(VkvgDevice dev, void *vkhImg);
 /**
  * @brief Create a new vkvg surface from an in memory rgba bitmap
  * @param dev The vkvg device used for creating the surface.
@@ -781,35 +753,31 @@ VkvgSurface vkvg_surface_create_for_VkhImage (VkvgDevice dev, void* vkhImg);
  * @param height the height of the provided bitmap.
  * @return
  */
-vkvg_public
-VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, uint32_t width, uint32_t height);
+vkvg_public VkvgSurface vkvg_surface_create_from_bitmap(VkvgDevice dev, unsigned char *img, uint32_t width,
+                                                        uint32_t height);
 /**
  * @brief Increment reference count on the surface by one.
  * @param The vkvg surface to increment the reference count for.
  * @return ?
  */
-vkvg_public
-VkvgSurface vkvg_surface_reference (VkvgSurface surf);
+vkvg_public VkvgSurface vkvg_surface_reference(VkvgSurface surf);
 /**
  * @brief Get the current reference count on this surface.
  * @param The vkvg surface to get the reference count for.
  * @return The reference count on the surface.
  */
-vkvg_public
-uint32_t vkvg_surface_get_reference_count (VkvgSurface surf);
+vkvg_public uint32_t vkvg_surface_get_reference_count(VkvgSurface surf);
 /**
  * @brief Decrement the reference count on the surface by one. Destroy it if count reach 0.
  * @param The vkvg surface to destroy.
  */
-vkvg_public
-void vkvg_surface_destroy (VkvgSurface surf);
+vkvg_public void vkvg_surface_destroy(VkvgSurface surf);
 /**
  * @brief Query the current status of the surface.
  * @param The vkvg surface to query the status for.
  * @return The current surface status.
  */
-vkvg_public
-vkvg_status_t vkvg_surface_status (VkvgSurface surf);
+vkvg_public vkvg_status_t vkvg_surface_status(VkvgSurface surf);
 /**
  * @brief Clear surface's content.
  *
@@ -820,68 +788,60 @@ vkvg_status_t vkvg_surface_status (VkvgSurface surf);
  * function of the context that will try to use the render pass load operations when possible.
  * @param The surface to clear.
  */
-vkvg_public
-void vkvg_surface_clear (VkvgSurface surf);
+vkvg_public void vkvg_surface_clear(VkvgSurface surf);
 /**
  * @brief Get the final single sampled vulkan image of this surface.
  * @param The vkvg surface to get the vulkan texture of.
  * @return The VkImage object containing the result of the drawing operations on the surface.
  */
-vkvg_public
-VkImage        vkvg_surface_get_vk_image (VkvgSurface surf);
+vkvg_public VkImage vkvg_surface_get_vk_image(VkvgSurface surf);
 /**
  * @brief Get the vulkan format of the vulkan texture used as backend for this surface.
  * @param The surface to get the format for.
  * @return The VkFormat.
  */
-vkvg_public
-VkFormat vkvg_surface_get_vk_format (VkvgSurface surf);
+vkvg_public VkFormat vkvg_surface_get_vk_format(VkvgSurface surf);
 /**
  * @brief Get the actual surface width.
  * @param The vkvg surface to get the width for.
  * @return The width in pixel of the surface.
  */
-vkvg_public
-uint32_t vkvg_surface_get_width (VkvgSurface surf);
+vkvg_public uint32_t vkvg_surface_get_width(VkvgSurface surf);
 /**
  * @brief Get the actual surface height.
  * @param The vkvg surface to get the height for.
  * @return The height in pixel of the surface.
  */
-vkvg_public
-uint32_t vkvg_surface_get_height (VkvgSurface surf);
+vkvg_public uint32_t vkvg_surface_get_height(VkvgSurface surf);
 /**
  * @brief Write surface content to a png file on disk.
  * @param The surface to save on disk.
  * @param The png file path.
  * @return SUCCESS or not.
  */
-vkvg_public
-vkvg_status_t vkvg_surface_write_to_png (VkvgSurface surf, const char* path);
+vkvg_public vkvg_status_t vkvg_surface_write_to_png(VkvgSurface surf, const char *path);
 /**
  * @brief Save surface to memory
  * @param The surface to save
  * @param A valid pointer on cpu memory large enough to contain surface pixels (stride * height)
  * @return SUCCESS or not.
  */
-vkvg_public
-vkvg_status_t vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap);
+vkvg_public vkvg_status_t vkvg_surface_write_to_memory(VkvgSurface surf, unsigned char *const bitmap);
 /**
  * @brief Explicitly resolve a multisampled surface.
  *
  * Multisampled surfaces are backed internally by 2 vulkan textures, one multisampled for internal use only, and one
  * single sampled texture onto which the multisampled one is resolved.
  * If #VkvgDevice is created with `deferredResolve` set to `false`, multisampled image is automatically resolved on each
- * draw call. If `deferredResolve` is set to `true`, multisampled image will be resolved only with a call to #vkvg_surface_resolve() or
- * by a call to #vkvg_surface_get_vk_image().
+ * draw call. If `deferredResolve` is set to `true`, multisampled image will be resolved only with a call to
+ * #vkvg_surface_resolve() or by a call to #vkvg_surface_get_vk_image().
  *
  * @param surf The multisampled surface to resolve.
  */
-vkvg_public
-void vkvg_surface_resolve (VkvgSurface surf);
+vkvg_public void vkvg_surface_resolve(VkvgSurface surf);
 /** @}*/
 
-//mimic from cairo, to facilitate usage of vkvg as cairo vulkan backend
+// mimic from cairo, to facilitate usage of vkvg as cairo vulkan backend
 
 /**
  * @brief compositing operators
@@ -889,40 +849,41 @@ void vkvg_surface_resolve (VkvgSurface surf);
  * define the operation used to draw
  */
 typedef enum _vkvg_operator {
-       VKVG_OPERATOR_CLEAR,
+    VKVG_OPERATOR_CLEAR,
 
-       VKVG_OPERATOR_SOURCE,
-       VKVG_OPERATOR_OVER,
-/*     VKVG_OPERATOR_IN,
-       VKVG_OPERATOR_OUT,
-       VKVG_OPERATOR_ATOP,
+    VKVG_OPERATOR_SOURCE,
+    VKVG_OPERATOR_OVER,
+    /* VKVG_OPERATOR_IN,
+        VKVG_OPERATOR_OUT,
+        VKVG_OPERATOR_ATOP,
 
-       VKVG_OPERATOR_DEST,
-       VKVG_OPERATOR_DEST_OVER,
-       VKVG_OPERATOR_DEST_IN,
-       VKVG_OPERATOR_DEST_OUT,
-       VKVG_OPERATOR_DEST_ATOP,
+        VKVG_OPERATOR_DEST,
+        VKVG_OPERATOR_DEST_OVER,
+        VKVG_OPERATOR_DEST_IN,
+        VKVG_OPERATOR_DEST_OUT,
+        VKVG_OPERATOR_DEST_ATOP,
 
-       VKVG_OPERATOR_XOR,
-       VKVG_OPERATOR_ADD,
-       VKVG_OPERATOR_SATURATE,
+        VKVG_OPERATOR_XOR,
+        VKVG_OPERATOR_ADD,
+        VKVG_OPERATOR_SATURATE,
 
-       VKVG_OPERATOR_MULTIPLY,
-       VKVG_OPERATOR_SCREEN,
-       VKVG_OPERATOR_OVERLAY,
-       VKVG_OPERATOR_DARKEN,
-       VKVG_OPERATOR_LIGHTEN,
-       VKVG_OPERATOR_COLOR_DODGE,
-       VKVG_OPERATOR_COLOR_BURN,
-       VKVG_OPERATOR_HARD_LIGHT,
-       VKVG_OPERATOR_SOFT_LIGHT,
-       */VKVG_OPERATOR_DIFFERENCE,/*
-       VKVG_OPERATOR_EXCLUSION,
-       VKVG_OPERATOR_HSL_HUE,
-       VKVG_OPERATOR_HSL_SATURATION,
-       VKVG_OPERATOR_HSL_COLOR,
-       VKVG_OPERATOR_HSL_LUMINOSITY,*/
-       VKVG_OPERATOR_MAX,
+        VKVG_OPERATOR_MULTIPLY,
+        VKVG_OPERATOR_SCREEN,
+        VKVG_OPERATOR_OVERLAY,
+        VKVG_OPERATOR_DARKEN,
+        VKVG_OPERATOR_LIGHTEN,
+        VKVG_OPERATOR_COLOR_DODGE,
+        VKVG_OPERATOR_COLOR_BURN,
+        VKVG_OPERATOR_HARD_LIGHT,
+        VKVG_OPERATOR_SOFT_LIGHT,
+        */
+    VKVG_OPERATOR_DIFFERENCE, /*
+   VKVG_OPERATOR_EXCLUSION,
+   VKVG_OPERATOR_HSL_HUE,
+   VKVG_OPERATOR_HSL_SATURATION,
+   VKVG_OPERATOR_HSL_COLOR,
+   VKVG_OPERATOR_HSL_LUMINOSITY,*/
+    VKVG_OPERATOR_MAX,
 } vkvg_operator_t;
 
 /** @addtogroup context
@@ -931,22 +892,21 @@ typedef enum _vkvg_operator {
 /**
  * @brief Create a new vkvg context used for drawing on surfaces.
  *
- * Creates a new #VkvgContext with all graphics state parameters set to default values and with surf as a target surface.
- * This method will always return a valid pointer even if memory allocation failed.
- * @remark This function references surf, so you can immediately call #vkvg_surface_destroy() on it if you don't need to maintain a separate reference to it.
+ * Creates a new #VkvgContext with all graphics state parameters set to default values and with surf as a target
+ * surface. This method will always return a valid pointer even if memory allocation failed.
+ * @remark This function references surf, so you can immediately call #vkvg_surface_destroy() on it if you don't need to
+ * maintain a separate reference to it.
  * @param surf The target surface of the drawing operations.
  * @return A new #VkvgContext or null if an error occured.
  */
-vkvg_public
-VkvgContext vkvg_create (VkvgSurface surf);
+vkvg_public VkvgContext vkvg_create(VkvgSurface surf);
 /**
  * @brief Destroy vkvg context.
  *
  * Decrement the reference count on the context by one. Destroy it if count reach 0.
  * @param ctx The vkvg context to destroy.
  */
-vkvg_public
-void vkvg_destroy (VkvgContext ctx);
+vkvg_public void vkvg_destroy(VkvgContext ctx);
 /**
  * @brief Get context status.
  *
@@ -954,8 +914,7 @@ void vkvg_destroy (VkvgContext ctx);
  *
  * @param ctx The vkvg context to query the status for.
  */
-vkvg_public
-vkvg_status_t vkvg_status (VkvgContext ctx);
+vkvg_public vkvg_status_t vkvg_status(VkvgContext ctx);
 /**
  * vkvg_status_to_string:
  * @status: a vkvg status
@@ -964,22 +923,19 @@ vkvg_status_t vkvg_status (VkvgContext ctx);
  *
  * Returns: a string representation of the status
  **/
-vkvg_public
-const char* vkvg_status_to_string (vkvg_status_t status);
+vkvg_public const char *vkvg_status_to_string(vkvg_status_t status);
 /**
  * @brief Increment by one the reference count on this context.
  * @param ctx The context to increment the reference count for.
  * @return
  */
-vkvg_public
-VkvgContext vkvg_reference (VkvgContext ctx);
+vkvg_public VkvgContext vkvg_reference(VkvgContext ctx);
 /**
  * @brief Get the current reference count of this context.
  * @param The vkvg context to query.
  * @return The current reference count for this context.
  */
-vkvg_public
-uint32_t vkvg_get_reference_count (VkvgContext ctx);
+vkvg_public uint32_t vkvg_get_reference_count(VkvgContext ctx);
 /**
  * @brief Perform all the pending drawing operations on a context.
  *
@@ -989,8 +945,7 @@ uint32_t vkvg_get_reference_count (VkvgContext ctx);
  * The context is automatically flushed on destruction.
  * @param ctx The vkvg context to flush.
  */
-vkvg_public
-void vkvg_flush (VkvgContext ctx);
+vkvg_public void vkvg_flush(VkvgContext ctx);
 /**
  * @brief Start a new empty path.
  *
@@ -999,8 +954,7 @@ void vkvg_flush (VkvgContext ctx);
  * The current position is reseted to (0,0).
  * @param ctx The vkvg context pointer.
  */
-vkvg_public
-void vkvg_new_path (VkvgContext ctx);
+vkvg_public void vkvg_new_path(VkvgContext ctx);
 /**
  * @brief Close the current path.
  *
@@ -1009,8 +963,7 @@ void vkvg_new_path (VkvgContext ctx);
  * than 2.
  * @param ctx The vkvg context pointer.
  */
-vkvg_public
-void vkvg_close_path (VkvgContext ctx);
+vkvg_public void vkvg_close_path(VkvgContext ctx);
 /**
  * @brief Start a new sub path.
  *
@@ -1020,8 +973,7 @@ void vkvg_close_path (VkvgContext ctx);
  * In many cases, this call is not needed since new sub-paths are frequently started with #vkvg_move_to().
  * @param ctx The vkvg context pointer.
  */
-vkvg_public
-void vkvg_new_sub_path (VkvgContext ctx);
+vkvg_public void vkvg_new_sub_path(VkvgContext ctx);
 /**
  * @brief vkvg_path_extents
  * @param ctx a valid @ref context
@@ -1030,8 +982,7 @@ void vkvg_new_sub_path (VkvgContext ctx);
  * @param x2 right of the resulting extents
  * @param y2 bottom of the resulting extents
  */
-vkvg_public
-void vkvg_path_extents (VkvgContext ctx, float *x1, float *y1, float *x2, float *y2);
+vkvg_public void vkvg_path_extents(VkvgContext ctx, float *x1, float *y1, float *x2, float *y2);
 /**
  * @brief Get the current point.
  *
@@ -1040,8 +991,7 @@ void vkvg_path_extents (VkvgContext ctx, float *x1, float *y1, float *x2, float
  * @param x A valid float pointer to receive the x coordinate of the current point.
  * @param y A valid float pointer to receive the y coordinate of the current point.
  */
-vkvg_public
-void vkvg_get_current_point (VkvgContext ctx, float* x, float* y);
+vkvg_public void vkvg_get_current_point(VkvgContext ctx, float *x, float *y);
 /**
  * @brief Add a line to the current path from the current point to the coordinate given in arguments.
  *
@@ -1052,8 +1002,7 @@ void vkvg_get_current_point (VkvgContext ctx, float* x, float* y);
  * @param x absolute x coordinate of second point
  * @param y aboslute y coordinate of second point
  */
-vkvg_public
-void vkvg_line_to (VkvgContext ctx, float x, float y);
+vkvg_public void vkvg_line_to(VkvgContext ctx, float x, float y);
 /**
  * @brief Add a line to the current path from the current point to the coordinate relative to it.
  *
@@ -1064,8 +1013,7 @@ void vkvg_line_to (VkvgContext ctx, float x, float y);
  * @param dx delta x
  * @param dy delta y
  */
-vkvg_public
-void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy);
+vkvg_public void vkvg_rel_line_to(VkvgContext ctx, float dx, float dy);
 /**
  * @brief Move the context pen to the position given in argument.
  *
@@ -1078,8 +1026,7 @@ void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy);
  * @param x new x position of the pen
  * @param y new y position of the pen
  */
-vkvg_public
-void vkvg_move_to (VkvgContext ctx, float x, float y);
+vkvg_public void vkvg_move_to(VkvgContext ctx, float x, float y);
 /**
  * @brief Move the context pen relative to the current point.
  *
@@ -1091,22 +1038,23 @@ void vkvg_move_to (VkvgContext ctx, float x, float y);
  * @param x delta in the horizontal direction.
  * @param y delta in the vertical direction.
  */
-vkvg_public
-void vkvg_rel_move_to (VkvgContext ctx, float x, float y);
+vkvg_public void vkvg_rel_move_to(VkvgContext ctx, float x, float y);
 /**
  * @brief Adds a circular arc of the given radius to the current path.
  *
- * Adds a circular arc in clockwise order of the given radius to the current path following angles of a trigonometric circle.
- * After this call the current point will be the last computed point of the arc.
- * The arc is centered at (xc , yc ), begins at angle a1 and proceeds in the direction of increasing angles to end at angle a2.
- * If a2 is less than a1, it will be progressively increased by 2*PI until it is greater than a1.
+ * Adds a circular arc in clockwise order of the given radius to the current path following angles of a trigonometric
+ * circle. After this call the current point will be the last computed point of the arc. The arc is centered at (xc , yc
+ * ), begins at angle a1 and proceeds in the direction of increasing angles to end at angle a2. If a2 is less than a1,
+ * it will be progressively increased by 2*PI until it is greater than a1.
  *
- * If there is a current point, an initial line segment will be added to the path to connect the current point to the beginning of the arc.
- * If this initial line is undesired, it can be avoided by calling vkvg_new_sub_path() before calling vkvg_arc().
+ * If there is a current point, an initial line segment will be added to the path to connect the current point to the
+ * beginning of the arc. If this initial line is undesired, it can be avoided by calling vkvg_new_sub_path() before
+ * calling vkvg_arc().
  *
  * Angles are measured in radians. An angle of 0.0 is in the direction of the positive X axis.
  * An angle of PI/2 radians (90 degrees) is in the direction of the positive Y axis. Angles increase in the direction
- * from the positive X axis toward the positive Y axis. So with the default transformation matrix, angles increase in a clockwise direction.
+ * from the positive X axis toward the positive Y axis. So with the default transformation matrix, angles increase in a
+ * clockwise direction.
  *
  * @remark To convert from degrees to radians, use degrees * (PI/180).
  * @param ctx The vkvg context pointer.
@@ -1116,14 +1064,13 @@ void vkvg_rel_move_to (VkvgContext ctx, float x, float y);
  * @param a1 start angle in radians of the arc as if on a trigonometric circle.
  * @param a2 end angle in radians of the arc to draw.
  */
-vkvg_public
-void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2);
+vkvg_public void vkvg_arc(VkvgContext ctx, float xc, float yc, float radius, float a1, float a2);
 /**
  * @brief Add a circular arc in counter clockwise order to the current path.
  *
- * Adds a circular arc in counter clockwise order of the given radius to the current path following angles of a trigonometric circle.
- * After this call the current point will be the last computed point of the arc.
- * The arc is centered at `(xc,yc)`, begins at angle `a1` and proceeds in the direction of decreasing angles to end at angle `a2`.
+ * Adds a circular arc in counter clockwise order of the given radius to the current path following angles of a
+ * trigonometric circle. After this call the current point will be the last computed point of the arc. The arc is
+ * centered at `(xc,yc)`, begins at angle `a1` and proceeds in the direction of decreasing angles to end at angle `a2`.
  * If `a2` is greater than `a1`, it will be progressively decreased by `2*PI` until it is less than `a1`.
  *
  *
@@ -1135,15 +1082,15 @@ void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, floa
  * @param a1 start angle in radians of the arc as if on a trigonometric circle.
  * @param a2 end angle in radians of the arc to draw.
  */
-vkvg_public
-void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2);
+vkvg_public void vkvg_arc_negative(VkvgContext ctx, float xc, float yc, float radius, float a1, float a2);
 /**
  * @brief Adds a cubic Bézier spline to the current path.
  *
- * Adds a cubic Bezier spline to the path from the current point to position (x3, y3), using (x1, y1) and (x2, y2) as the control points.
- * After this call the current point will be (x3, y3).
+ * Adds a cubic Bezier spline to the path from the current point to position (x3, y3), using (x1, y1) and (x2, y2) as
+ * the control points. After this call the current point will be (x3, y3).
  *
- * If there is no current point before the call to vkvg_curve_to() this function will behave as if preceded by a call to vkvg_move_to(ctx, x1, y1).
+ * If there is no current point before the call to vkvg_curve_to() this function will behave as if preceded by a call to
+ * vkvg_move_to(ctx, x1, y1).
  * @param ctx The vkvg context pointer.
  * @param x1 The X coordinate of the first control point.
  * @param y1 The Y coordinate of the first control point.
@@ -1152,14 +1099,13 @@ void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float
  * @param x3 The X coordinate of the end of the curve.
  * @param y3 The Y coordinate of the end of the curve.
  */
-vkvg_public
-void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3);
+vkvg_public void vkvg_curve_to(VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3);
 /**
  * @brief Adds a cubic Bézier spline to the current path relative to the current point.
  *
- * Adds a cubic Bézier spline to the path from the current point to position (x3, y3) in relative coordinate to the current point,
- * using (x1, y1) and (x2, y2) as the control points relative to the current point.
- * After this call the current point will be (x3, y3).
+ * Adds a cubic Bézier spline to the path from the current point to position (x3, y3) in relative coordinate to the
+ * current point, using (x1, y1) and (x2, y2) as the control points relative to the current point. After this call the
+ * current point will be (x3, y3).
  *
  * If there is no current point before the call to vkvg_rel_curve_to() => error:VKVG_STATUS_NO_CURRENT_POINT.
  * @param ctx The vkvg context pointer.
@@ -1170,20 +1116,19 @@ void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, flo
  * @param x3 The X coordinate of the end of the curve.
  * @param y3 The Y coordinate of the end of the curve.
  */
-vkvg_public
-void vkvg_rel_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3);
+vkvg_public void vkvg_rel_curve_to(VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3);
 /**
  * @brief Add a quadratic Bezizer curve to the current path
  *
- * If there is no current point before the call to vkvg_quadratic_to() this function will behave as if preceded by a call to vkvg_move_to(ctx, x1, y1).
+ * If there is no current point before the call to vkvg_quadratic_to() this function will behave as if preceded by a
+ * call to vkvg_move_to(ctx, x1, y1).
  * @param ctx The vkvg context pointer.
  * @param x1 The X coordinate of the control point.
  * @param y1 The Y coordinate of the control point.
  * @param x2 The X coordinate of the end point of the curve.
  * @param y2 The Y coordinate of the end point of the curve.
  */
-vkvg_public
-void vkvg_quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2);
+vkvg_public void vkvg_quadratic_to(VkvgContext ctx, float x1, float y1, float x2, float y2);
 /**
  * @brief Add a quadratic Bezizer curve to the current path relative to the current point
  *
@@ -1193,8 +1138,7 @@ void vkvg_quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2)
  * @param x2 The X coordinate of the end point of the curve relative to the current point.
  * @param y2 The Y coordinate of the end point of the curve relative to the current point.
  */
-vkvg_public
-void vkvg_rel_quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2);
+vkvg_public void vkvg_rel_quadratic_to(VkvgContext ctx, float x1, float y1, float x2, float y2);
 /**
  * @brief Add an axis aligned rectangle subpath to the current path.
  *
@@ -1206,37 +1150,34 @@ void vkvg_rel_quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float
  * @param h The height in pixel of the rectangle to draw.
  * @return VKVG_STATUS_SUCCESS or VKVG_STATUS_INVALID_RECT if width or height is equal to 0.
  */
-vkvg_public
-vkvg_status_t vkvg_rectangle(VkvgContext ctx, float x, float y, float w, float h);
-/**
-* @brief Add an axis aligned rectangle with rounded corners to the current path.
-*
-* Adds a closed sub-path rectangle of the given size to the current path at position (x, y).
-* @param ctx The vkvg context pointer.
-* @param x The x coordinate of the top left corner of the rectangle to emit.
-* @param y The y coordinate of the top left corner of the rectangle to emit.
-* @param w The width in pixel of the rectangle to draw.
-* @param h The height in pixel of the rectangle to draw.
-* @param radius The radius of the corners.
-* @return VKVG_STATUS_SUCCESS or VKVG_STATUS_INVALID_RECT if width or height is equal to 0.
-*/
-vkvg_public
-vkvg_status_t vkvg_rounded_rectangle (VkvgContext ctx, float x, float y, float w, float h, float radius);
-/**
-* @brief Add an axis aligned rectangle with rounded corners defined in both axis to the current path.
-*
-* Adds a closed sub-path rectangle of the given size to the current path at position (x, y).
-* @param ctx The vkvg context pointer.
-* @param x The x coordinate of the top left corner of the rectangle to emit.
-* @param y The y coordinate of the top left corner of the rectangle to emit.
-* @param w The width in pixel of the rectangle to draw.
-* @param h The height in pixel of the rectangle to draw.
-* @param rx The horizontal radius of the corners.
-* @param ry The vertical radius of the corners.
-* @return VKVG_STATUS_SUCCESS or VKVG_STATUS_INVALID_RECT if width or height is equal to 0.
-*/
-vkvg_public
-void vkvg_rounded_rectangle2 (VkvgContext ctx, float x, float y, float w, float h, float rx, float ry);
+vkvg_public vkvg_status_t vkvg_rectangle(VkvgContext ctx, float x, float y, float w, float h);
+/**
+ * @brief Add an axis aligned rectangle with rounded corners to the current path.
+ *
+ * Adds a closed sub-path rectangle of the given size to the current path at position (x, y).
+ * @param ctx The vkvg context pointer.
+ * @param x The x coordinate of the top left corner of the rectangle to emit.
+ * @param y The y coordinate of the top left corner of the rectangle to emit.
+ * @param w The width in pixel of the rectangle to draw.
+ * @param h The height in pixel of the rectangle to draw.
+ * @param radius The radius of the corners.
+ * @return VKVG_STATUS_SUCCESS or VKVG_STATUS_INVALID_RECT if width or height is equal to 0.
+ */
+vkvg_public vkvg_status_t vkvg_rounded_rectangle(VkvgContext ctx, float x, float y, float w, float h, float radius);
+/**
+ * @brief Add an axis aligned rectangle with rounded corners defined in both axis to the current path.
+ *
+ * Adds a closed sub-path rectangle of the given size to the current path at position (x, y).
+ * @param ctx The vkvg context pointer.
+ * @param x The x coordinate of the top left corner of the rectangle to emit.
+ * @param y The y coordinate of the top left corner of the rectangle to emit.
+ * @param w The width in pixel of the rectangle to draw.
+ * @param h The height in pixel of the rectangle to draw.
+ * @param rx The horizontal radius of the corners.
+ * @param ry The vertical radius of the corners.
+ * @return VKVG_STATUS_SUCCESS or VKVG_STATUS_INVALID_RECT if width or height is equal to 0.
+ */
+vkvg_public void vkvg_rounded_rectangle2(VkvgContext ctx, float x, float y, float w, float h, float rx, float ry);
 
 /**
  * @brief Add a closed ellipse to the current path.
@@ -1250,16 +1191,15 @@ void vkvg_rounded_rectangle2 (VkvgContext ctx, float x, float y, float w, float
  * @param y Ellipse's center y coordinate.
  * @param rotationAngle A clockwise rotation angle in radian.
  */
-vkvg_public
-void vkvg_ellipse (VkvgContext ctx, float radiusX, float radiusY, float x, float y, float rotationAngle);
+vkvg_public void vkvg_ellipse(VkvgContext ctx, float radiusX, float radiusY, float x, float y, float rotationAngle);
 /**
  * @brief Add an elliptical arc to the current path.
  *
- * Draws an elliptical arc from the current point to (x, y). The size and orientation of the ellipse are defined by two radii (rx, ry)
- * and an x-axis-rotation, which indicates how the ellipse as a whole is rotated relative to the current coordinate system.
- * The center (cx, cy) of the ellipse is calculated automatically to satisfy the constraints imposed by the other parameters.
- * For a given radii pair, there are two ellipses that could connect two random points. large-arc-flag and sweep-flag contribute
- * to the automatic calculations and help determine how the arc is drawn.
+ * Draws an elliptical arc from the current point to (x, y). The size and orientation of the ellipse are defined by two
+ * radii (rx, ry) and an x-axis-rotation, which indicates how the ellipse as a whole is rotated relative to the current
+ * coordinate system. The center (cx, cy) of the ellipse is calculated automatically to satisfy the constraints imposed
+ * by the other parameters. For a given radii pair, there are two ellipses that could connect two random points.
+ * large-arc-flag and sweep-flag contribute to the automatic calculations and help determine how the arc is drawn.
  *
  * @image html elliptical-arc-options.svg
  *
@@ -1272,12 +1212,13 @@ void vkvg_ellipse (VkvgContext ctx, float radiusX, float radiusY, float x, float
  * @param ry The y radius of the ellipse.
  * @param phi Clockwise rotation of the arc in radian.
  */
-vkvg_public
-void vkvg_elliptic_arc_to (VkvgContext ctx, float x, float y, bool large_arc_flag, bool sweep_flag, float rx, float ry, float phi);
+vkvg_public void vkvg_elliptic_arc_to(VkvgContext ctx, float x, float y, bool large_arc_flag, bool sweep_flag, float rx,
+                                      float ry, float phi);
 /**
  * @brief Add an elliptical arc to the current path.
  *
- * This method has the same effect as a call to #vkvg_elliptic_arc_to except that the coordinate are expressed relative to the current point.
+ * This method has the same effect as a call to #vkvg_elliptic_arc_to except that the coordinate are expressed relative
+ * to the current point.
  * @param ctx A valid context handle.
  * @param x the arc end point x coordinate relative to the current point.
  * @param y the arc end point y coordinate relative to the current point.
@@ -1287,19 +1228,18 @@ void vkvg_elliptic_arc_to (VkvgContext ctx, float x, float y, bool large_arc_fla
  * @param ry The y radius of the ellipse.
  * @param phi Clockwise rotation of the arc in radian.
  */
-vkvg_public
-void vkvg_rel_elliptic_arc_to (VkvgContext ctx, float x, float y, bool large_arc_flag, bool sweep_flag, float rx, float ry, float phi);
+vkvg_public void vkvg_rel_elliptic_arc_to(VkvgContext ctx, float x, float y, bool large_arc_flag, bool sweep_flag,
+                                          float rx, float ry, float phi);
 /**
  * @brief Stroke command
  *
- * A drawing operator that strokes the current path according to the current line width, line join, line cap, and dash settings.
- * After vkvg_stroke(), the current path will be cleared from the vkvg context. See #vkvg_set_line_width(), #vkvg_set_line_join(),
- * #vkvg_set_line_cap(), #vkvg_set_dash(), and #vkvg_stroke_preserve().
+ * A drawing operator that strokes the current path according to the current line width, line join, line cap, and dash
+ * settings. After vkvg_stroke(), the current path will be cleared from the vkvg context. See #vkvg_set_line_width(),
+ * #vkvg_set_line_join(), #vkvg_set_line_cap(), #vkvg_set_dash(), and #vkvg_stroke_preserve().
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_stroke (VkvgContext ctx);
+vkvg_public void vkvg_stroke(VkvgContext ctx);
 /**
  * @brief Stroke command that preserve current path.
  *
@@ -1307,8 +1247,7 @@ void vkvg_stroke (VkvgContext ctx);
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_stroke_preserve (VkvgContext ctx);
+vkvg_public void vkvg_stroke_preserve(VkvgContext ctx);
 /**
  * @brief Fill command
  *
@@ -1317,8 +1256,7 @@ void vkvg_stroke_preserve (VkvgContext ctx);
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_fill (VkvgContext ctx);
+vkvg_public void vkvg_fill(VkvgContext ctx);
 /**
  * @brief Fill command that preserve current path.
  *
@@ -1326,8 +1264,7 @@ void vkvg_fill (VkvgContext ctx);
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_fill_preserve (VkvgContext ctx);
+vkvg_public void vkvg_fill_preserve(VkvgContext ctx);
 /**
  * @brief Paint command.
  *
@@ -1336,8 +1273,7 @@ void vkvg_fill_preserve (VkvgContext ctx);
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_paint (VkvgContext ctx);
+vkvg_public void vkvg_paint(VkvgContext ctx);
 /**
  * @brief Clear surface.
  *
@@ -1348,8 +1284,7 @@ void vkvg_paint (VkvgContext ctx);
  * @remark To clear a surface not bound to a context, call #vkvg_surface_clear().
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_clear (VkvgContext ctx);//use vkClearAttachment to speed up clearing surf
+vkvg_public void vkvg_clear(VkvgContext ctx); // use vkClearAttachment to speed up clearing surf
 /**
  * @brief Reset the current clip region.
  *
@@ -1357,25 +1292,25 @@ void vkvg_clear (VkvgContext ctx);//use vkClearAttachment to speed up clearing s
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_reset_clip (VkvgContext ctx);
+vkvg_public void vkvg_reset_clip(VkvgContext ctx);
 /**
  * @brief Establishes a new clip region.
  *
- * Establishes a new clip region by intersecting the current clip region with the current path as it would be filled by @ref vkvg_fill() and
- * according to the current fill rule (@ref vkvg_set_fill_rule()).
+ * Establishes a new clip region by intersecting the current clip region with the current path as it would be filled by
+ * @ref vkvg_fill() and according to the current fill rule (@ref vkvg_set_fill_rule()).
  *
- * The current clip region affects all drawing operations by effectively masking out any changes to the surface that are outside the current clip region.
+ * The current clip region affects all drawing operations by effectively masking out any changes to the surface that are
+ * outside the current clip region.
  *
  * After vkvg_clip(), the current path will be cleared from the context.
  *
- * Calling vkvg_clip() can only make the clip region smaller, never larger. But the current clip is part of the graphics state,
- * so a temporary restriction of the clip region can be achieved by calling @ref vkvg_clip() within a @ref vkvg_save()/@ref vkvg_restore() pair.
- * The only other means of increasing the size of the clip region is @ref vkvg_reset_clip().
+ * Calling vkvg_clip() can only make the clip region smaller, never larger. But the current clip is part of the graphics
+ * state, so a temporary restriction of the clip region can be achieved by calling @ref vkvg_clip() within a @ref
+ * vkvg_save()/@ref vkvg_restore() pair. The only other means of increasing the size of the clip region is @ref
+ * vkvg_reset_clip().
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_clip (VkvgContext ctx);
+vkvg_public void vkvg_clip(VkvgContext ctx);
 /**
  * @brief Establishes a new clip region preserving the current path.
  *
@@ -1383,8 +1318,7 @@ void vkvg_clip (VkvgContext ctx);
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_clip_preserve (VkvgContext ctx);
+vkvg_public void vkvg_clip_preserve(VkvgContext ctx);
 /**
  * @brief Set global opacity for drawing operations.
  *
@@ -1393,24 +1327,23 @@ void vkvg_clip_preserve (VkvgContext ctx);
  * @param ctx a valid context handle.
  * @param opacity global opacity value between 0..1.
  */
+vkvg_public void vkvg_set_opacity(VkvgContext ctx, float opacity);
 vkvg_public
-void vkvg_set_opacity (VkvgContext ctx, float opacity);
-vkvg_public
-/**
- * @brief Get current opacity.
- *
- * Retrieve the current opacity for the supplied context as set by a call to #vkvg_set_opacity().
- * @param ctx a valid context handle.
- * @return the current opacity of the supplied context.
- */
-float vkvg_get_opacity (VkvgContext ctx);
+    /**
+     * @brief Get current opacity.
+     *
+     * Retrieve the current opacity for the supplied context as set by a call to #vkvg_set_opacity().
+     * @param ctx a valid context handle.
+     * @return the current opacity of the supplied context.
+     */
+    float
+    vkvg_get_opacity(VkvgContext ctx);
 /**
  * @brief Set current source for drawing to the solid color defined by the supplied 32bit integer.
  * @param ctx a valid vkvg @ref context
  * @param rgba color coded in 32bit integer.
  */
-vkvg_public
-void vkvg_set_source_color (VkvgContext ctx, uint32_t c);
+vkvg_public void vkvg_set_source_color(VkvgContext ctx, uint32_t c);
 /**
  * @brief set color with alpha.
  *
@@ -1421,8 +1354,7 @@ void vkvg_set_source_color (VkvgContext ctx, uint32_t c);
  * @param b the blue component of the color.
  * @param a the alpha component holding the transparency for the current color.
  */
-vkvg_public
-void vkvg_set_source_rgba (VkvgContext ctx, float r, float g, float b, float a);
+vkvg_public void vkvg_set_source_rgba(VkvgContext ctx, float r, float g, float b, float a);
 /**
  * @brief set opaque color as new source.
  *
@@ -1437,8 +1369,7 @@ void vkvg_set_source_rgba (VkvgContext ctx, float r, float g, float b, float a);
  * @param b the blue component of the color.
  * @param a the alpha component holding the transparency for the current color.
  */
-vkvg_public
-void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b);
+vkvg_public void vkvg_set_source_rgb(VkvgContext ctx, float r, float g, float b);
 /**
  * @brief set line width for the next draw command.
  *
@@ -1448,24 +1379,24 @@ void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b);
  * @param ctx a valid vkvg @ref context
  * @param width new current line width for the context.
  */
-vkvg_public
-void vkvg_set_line_width (VkvgContext ctx, float width);
+vkvg_public void vkvg_set_line_width(VkvgContext ctx, float width);
 /**
  * @brief set line join miter size limit.
  *
- * If the current line join style is set to VKVG_LINE_JOIN_MITER (see vkvg_set_line_join()), the miter limit is used to determine whether the lines should be
- * joined with a bevel instead of a miter. Vkvg divides the length of the miter by the line width. If the result is greater than the miter limit, the style is converted to a bevel.
+ * If the current line join style is set to VKVG_LINE_JOIN_MITER (see vkvg_set_line_join()), the miter limit is used to
+ * determine whether the lines should be joined with a bevel instead of a miter. Vkvg divides the length of the miter by
+ * the line width. If the result is greater than the miter limit, the style is converted to a bevel.
  *
- * The default miter limit value is 10.0, which will convert joins with interior angles less than 11 degrees to bevels instead of miters.
- * For reference, a miter limit of 2.0 makes the miter cutoff at 60 degrees, and a miter limit of 1.414 makes the cutoff at 90 degrees.
+ * The default miter limit value is 10.0, which will convert joins with interior angles less than 11 degrees to bevels
+ * instead of miters. For reference, a miter limit of 2.0 makes the miter cutoff at 60 degrees, and a miter limit
+ * of 1.414 makes the cutoff at 90 degrees.
  *
  * A miter limit for a desired angle can be computed as: miter limit = 1/sin(angle/2)
  *
  * @param ctx a valid vkvg @ref context
  * @param limit new current miter limit value for the context.
  */
-vkvg_public
-void vkvg_set_miter_limit (VkvgContext ctx, float limit);
+vkvg_public void vkvg_set_miter_limit(VkvgContext ctx, float limit);
 /**
  * @brief Gets the current miter limit.
  *
@@ -1474,8 +1405,7 @@ void vkvg_set_miter_limit (VkvgContext ctx, float limit);
  * @param ctx a valid vkvg @ref context
  * @return the current miter limit for the context.
  */
-vkvg_public
-float vkvg_get_miter_limit (VkvgContext ctx);
+vkvg_public float vkvg_get_miter_limit(VkvgContext ctx);
 /**
  * @brief set line terminations for the next draw command.
  *
@@ -1483,8 +1413,7 @@ float vkvg_get_miter_limit (VkvgContext ctx);
  * @param ctx a valid vkvg @ref context
  * @param cap new line termination, may be one of the value of #vkvg_line_cap_t.
  */
-vkvg_public
-void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap);
+vkvg_public void vkvg_set_line_cap(VkvgContext ctx, vkvg_line_cap_t cap);
 /**
  * @brief set line joins for the next draw command.
  *
@@ -1492,8 +1421,7 @@ void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap);
  * @param ctx a valid vkvg @ref context
  * @param join new line join as defined in #vkvg_line_joint_t.
  */
-vkvg_public
-void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join);
+vkvg_public void vkvg_set_line_join(VkvgContext ctx, vkvg_line_join_t join);
 /**
  * @brief use supplied surface as current pattern.
  *
@@ -1503,8 +1431,7 @@ void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join);
  * @param x an x offset to apply for drawing operations using this surface.
  * @param y an y offset to apply for drawing operations using this surface.
  */
-vkvg_public
-void vkvg_set_source_surface (VkvgContext ctx, VkvgSurface surf, float x, float y);
+vkvg_public void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y);
 /**
  * @brief set supplied pattern as current source.
  *
@@ -1512,24 +1439,21 @@ void vkvg_set_source_surface (VkvgContext ctx, VkvgSurface surf, float x, float
  * @param ctx a valid vkvg @ref context
  * @param pat the new pattern to use as source for further drawing operations.
  */
-vkvg_public
-void vkvg_set_source (VkvgContext ctx, VkvgPattern pat);
+vkvg_public void vkvg_set_source(VkvgContext ctx, VkvgPattern pat);
 /**
  * @brief
  *
  * @param ctx a valid vkvg @ref context
  * @param op
  */
-vkvg_public
-void vkvg_set_operator (VkvgContext ctx, vkvg_operator_t op);
+vkvg_public void vkvg_set_operator(VkvgContext ctx, vkvg_operator_t op);
 /**
  * @brief
  *
  * @param ctx a valid vkvg @ref context
  * @param fr
  */
-vkvg_public
-void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr);
+vkvg_public void vkvg_set_fill_rule(VkvgContext ctx, vkvg_fill_rule_t fr);
 /**
  * @brief set the dash configuration for strokes
  *
@@ -1542,8 +1466,7 @@ void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr);
  * @param num_dashes the length of the dash array.
  * @param offset an offset into the dash pattern at which the stroke should start.
  */
-vkvg_public
-void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset);
+vkvg_public void vkvg_set_dash(VkvgContext ctx, const float *dashes, uint32_t num_dashes, float offset);
 /**
  * @brief get current dash settings.
  *
@@ -1555,8 +1478,7 @@ void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, f
  * @param num_dashes[out] return length of dash array or 0 if dash is not set.
  * @param offset[out] return value for the current dash offset
  */
-vkvg_public
-void vkvg_get_dash (VkvgContext ctx, const float *dashes, uint32_t* num_dashes, float* offset);
+vkvg_public void vkvg_get_dash(VkvgContext ctx, const float *dashes, uint32_t *num_dashes, float *offset);
 
 /**
  * @brief get current line width
@@ -1565,32 +1487,28 @@ void vkvg_get_dash (VkvgContext ctx, const float *dashes, uint32_t* num_dashes,
  * @param ctx a valid vkvg @ref context
  * @return current line width.
  */
-vkvg_public
-float vkvg_get_line_width (VkvgContext ctx);
+vkvg_public float vkvg_get_line_width(VkvgContext ctx);
 /**
  * @brief
  *
  * @param ctx a valid vkvg @ref context
  * @return vkvg_line_cap_t
  */
-vkvg_public
-vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx);
+vkvg_public vkvg_line_cap_t vkvg_get_line_cap(VkvgContext ctx);
 /**
  * @brief
  *
  * @param ctx a valid vkvg @ref context
  * @return vkvg_line_join_t
  */
-vkvg_public
-vkvg_line_join_t vkvg_get_line_join (VkvgContext ctx);
+vkvg_public vkvg_line_join_t vkvg_get_line_join(VkvgContext ctx);
 /**
  * @brief
  *
  * @param ctx a valid vkvg @ref context
  * @return vkvg_operator_t
  */
-vkvg_public
-vkvg_operator_t vkvg_get_operator (VkvgContext ctx);
+vkvg_public vkvg_operator_t vkvg_get_operator(VkvgContext ctx);
 /**
  * @brief Get current fill rule.
  *
@@ -1602,8 +1520,7 @@ vkvg_operator_t vkvg_get_operator (VkvgContext ctx);
  * @param ctx a valid vkvg @ref context
  * @return vkvg_fill_rule_t The current fill rule of the context.
  */
-vkvg_public
-vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx);
+vkvg_public vkvg_fill_rule_t vkvg_get_fill_rule(VkvgContext ctx);
 /**
  * @brief Get the current source of the context.
  *
@@ -1612,8 +1529,7 @@ vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx);
  * @param ctx a valid vkvg @ref context
  * @return VkvgPattern The current context's source.
  */
-vkvg_public
-VkvgPattern vkvg_get_source (VkvgContext ctx);
+vkvg_public VkvgPattern vkvg_get_source(VkvgContext ctx);
 
 /**
  * @brief Get the current target of the context.
@@ -1622,8 +1538,7 @@ VkvgPattern vkvg_get_source (VkvgContext ctx);
  * @param ctx a valid vkvg @ref context
  * @return The currently bound target surface.
  */
-vkvg_public
-VkvgSurface vkvg_get_target (VkvgContext ctx);
+vkvg_public VkvgSurface vkvg_get_target(VkvgContext ctx);
 /**
  * @brief Check if context has a current point defined.
  *
@@ -1633,8 +1548,7 @@ VkvgSurface vkvg_get_target (VkvgContext ctx);
  * @param ctx a valig vkvg @ref context
  * @return bool `true`if  a current point is defined, `false` otherwise.
  **/
-vkvg_public
-bool vkvg_has_current_point (VkvgContext ctx);
+vkvg_public bool vkvg_has_current_point(VkvgContext ctx);
 
 /**
  * @brief Save context's graphic states.
@@ -1644,8 +1558,7 @@ bool vkvg_has_current_point (VkvgContext ctx);
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_save (VkvgContext ctx);
+vkvg_public void vkvg_save(VkvgContext ctx);
 /**
  * @brief Restore context's graphic states.
  *
@@ -1654,28 +1567,27 @@ void vkvg_save (VkvgContext ctx);
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_restore (VkvgContext ctx);
+vkvg_public void vkvg_restore(VkvgContext ctx);
 /**
  * @brief Add a translation to the current transformation matrix.
  *
- * Modifies the current transformation matrix by applying an additional translation transformation by (dx,dy) in user space coordinate.
+ * Modifies the current transformation matrix by applying an additional translation transformation by (dx,dy) in user
+ * space coordinate.
  * @param ctx a valid vkvg @ref context
  * @param dx the x translation
  * @param dy the y translation
  */
-vkvg_public
-void vkvg_translate (VkvgContext ctx, float dx, float dy);
+vkvg_public void vkvg_translate(VkvgContext ctx, float dx, float dy);
 /**
  * @brief Add a scaling transform to the current transformation matrix.
  *
- * Modifies the current transformation matrix by applying an additional scaling transformation by (sx,sy) in user space coordinate.
+ * Modifies the current transformation matrix by applying an additional scaling transformation by (sx,sy) in user space
+ * coordinate.
  * @param ctx a valid vkvg @ref context
  * @param sx scale in the x direction.
  * @param sy scale in the y direction.
  */
-vkvg_public
-void vkvg_scale (VkvgContext ctx, float sx, float sy);
+vkvg_public void vkvg_scale(VkvgContext ctx, float sx, float sy);
 /**
  * @brief Add a rotation to the current transformation matrix.
  *
@@ -1683,8 +1595,7 @@ void vkvg_scale (VkvgContext ctx, float sx, float sy);
  * @param ctx a valid vkvg @ref context
  * @param radians rotation angle in radian.
  */
-vkvg_public
-void vkvg_rotate (VkvgContext ctx, float radians);
+vkvg_public void vkvg_rotate(VkvgContext ctx, float radians);
 /**
  * @brief Add an additional transformation to the current matrix.
  *
@@ -1693,8 +1604,7 @@ void vkvg_rotate (VkvgContext ctx, float radians);
  * @param ctx a valid vkvg @ref context
  * @param matrix
  */
-vkvg_public
-void vkvg_transform (VkvgContext ctx, const vkvg_matrix_t* matrix);
+vkvg_public void vkvg_transform(VkvgContext ctx, const vkvg_matrix_t *matrix);
 /**
  * @brief Set the current matrix.
  *
@@ -1703,8 +1613,7 @@ void vkvg_transform (VkvgContext ctx, const vkvg_matrix_t* matrix);
  * @param ctx a valid vkvg @ref context
  * @param matrix
  */
-vkvg_public
-void vkvg_set_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix);
+vkvg_public void vkvg_set_matrix(VkvgContext ctx, const vkvg_matrix_t *matrix);
 /**
  * @brief Get the current matrix.
  *
@@ -1713,8 +1622,7 @@ void vkvg_set_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix);
  * @param ctx a valid vkvg @ref context
  * @param matrix a valid #vkvg_matrix_t pointer to receive the current context's transform.
  */
-vkvg_public
-void vkvg_get_matrix (VkvgContext ctx, vkvg_matrix_t * const matrix);
+vkvg_public void vkvg_get_matrix(VkvgContext ctx, vkvg_matrix_t *const matrix);
 /**
  * @brief Set the current matrix to identity.
  *
@@ -1722,8 +1630,7 @@ void vkvg_get_matrix (VkvgContext ctx, vkvg_matrix_t * const matrix);
  *
  * @param ctx a valid vkvg @ref context
  */
-vkvg_public
-void vkvg_identity_matrix (VkvgContext ctx);
+vkvg_public void vkvg_identity_matrix(VkvgContext ctx);
 
 /**
  * @brief Try find font with the specified name using the FontConfig library.
@@ -1731,8 +1638,7 @@ void vkvg_identity_matrix (VkvgContext ctx);
  * @param ctx a valid vkvg @ref context
  * @param name A name to be recognized by the FontConfig library
  */
-vkvg_public
-void vkvg_select_font_face (VkvgContext ctx, const char* name);
+vkvg_public void vkvg_select_font_face(VkvgContext ctx, const char *name);
 /**
  * @brief Select a new font by providing its file path.
  *
@@ -1740,8 +1646,7 @@ void vkvg_select_font_face (VkvgContext ctx, const char* name);
  * @param path A valid font file path.
  * @param name A short name to select this font afteward
  */
-vkvg_public
-void vkvg_load_font_from_path (VkvgContext ctx, const char* path, const char *name);
+vkvg_public void vkvg_load_font_from_path(VkvgContext ctx, const char *path, const char *name);
 /**
  * @brief Select a new font by providing a pointer on the font file loaded in memory and its size in byte.
  *
@@ -1750,16 +1655,15 @@ void vkvg_load_font_from_path (VkvgContext ctx, const char* path, const char *na
  * @param fontBufferByteSize the size of the font buffer in bytes.
  * @param name A short name to select this font afteward
  */
-vkvg_public
-void vkvg_load_font_from_memory (VkvgContext ctx, unsigned char* fontBuffer, long fontBufferByteSize, const char* name);
+vkvg_public void vkvg_load_font_from_memory(VkvgContext ctx, unsigned char *fontBuffer, long fontBufferByteSize,
+                                            const char *name);
 /**
  * @brief
  *
  * @param ctx a valid vkvg @ref context
  * @param size
  */
-vkvg_public
-void vkvg_set_font_size (VkvgContext ctx, uint32_t size);
+vkvg_public void vkvg_set_font_size(VkvgContext ctx, uint32_t size);
 /**
  * @brief Show a string of text.
  *
@@ -1769,8 +1673,7 @@ void vkvg_set_font_size (VkvgContext ctx, uint32_t size);
  * @param ctx a valid vkvg @ref context
  * @param utf8 A null-terminated utf8 encoded string of text.
  */
-vkvg_public
-void vkvg_show_text (VkvgContext ctx, const char* utf8);
+vkvg_public void vkvg_show_text(VkvgContext ctx, const char *utf8);
 /**
  * @brief Gets the extents for a string of text.
  *
@@ -1778,18 +1681,16 @@ void vkvg_show_text (VkvgContext ctx, const char* utf8);
  * @param utf8 A null-terminated utf8 encoded string of text.
  * @param extents
  */
-vkvg_public
-void vkvg_text_extents (VkvgContext ctx, const char* utf8, vkvg_text_extents_t* extents);
+vkvg_public void vkvg_text_extents(VkvgContext ctx, const char *utf8, vkvg_text_extents_t *extents);
 /**
  * @brief Gets the font extents for the currently selected font.
  *
  * @param ctx a valid vkvg @ref context
  * @param extents A valid #vkvg_font_extents_t handle to be filled with current font extents.
  */
-vkvg_public
-void vkvg_font_extents (VkvgContext ctx, vkvg_font_extents_t* extents);
+vkvg_public void vkvg_font_extents(VkvgContext ctx, vkvg_font_extents_t *extents);
 
-//text run holds harfbuz datas, and prevent recreating them multiple times for the same line of text.
+// text run holds harfbuz datas, and prevent recreating them multiple times for the same line of text.
 /**
  * @brief Create a new text run.
  *
@@ -1797,8 +1698,7 @@ void vkvg_font_extents (VkvgContext ctx, vkvg_font_extents_t* extents);
  * @param text Null terminated utf8 string.
  * @return VkvgText
  */
-vkvg_public
-VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text);
+vkvg_public VkvgText vkvg_text_run_create(VkvgContext ctx, const char *text);
 /**
  * @brief Create a new text run for a non null terminated string.
  *
@@ -1807,46 +1707,38 @@ VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text);
  * @param length glyphs count, not to be confused with byte length.
  * @return VkvgText
  */
-vkvg_public
-VkvgText vkvg_text_run_create_with_length (VkvgContext ctx, const char* text, uint32_t length);
+vkvg_public VkvgText vkvg_text_run_create_with_length(VkvgContext ctx, const char *text, uint32_t length);
 /**
  * @brief Release resources holded by the text run.
  *
  * @param VkvgtextRun A valid VkvgText pointer.
  */
-vkvg_public
-void vkvg_text_run_destroy (VkvgText textRun);
+vkvg_public void vkvg_text_run_destroy(VkvgText textRun);
 /**
  * @brief
  *
  * @param ctx a valid vkvg @ref context
  * @param textRun
  */
-vkvg_public
-void vkvg_show_text_run (VkvgContext ctx, VkvgText textRun);
+vkvg_public void vkvg_show_text_run(VkvgContext ctx, VkvgText textRun);
 /**
  * @brief
  *
  * @param textRun
  * @param extents
  */
-vkvg_public
-void vkvg_text_run_get_extents (VkvgText textRun, vkvg_text_extents_t* extents);
+vkvg_public void vkvg_text_run_get_extents(VkvgText textRun, vkvg_text_extents_t *extents);
 /**
  * @brief Get glyph count of text run.
  *
  * @return glyph count
  */
-vkvg_public
-uint32_t vkvg_text_run_get_glyph_count (VkvgText textRun);
+vkvg_public uint32_t vkvg_text_run_get_glyph_count(VkvgText textRun);
 /**
  * @brief retrieve glyph positions.
  *
  */
-vkvg_public
-void vkvg_text_run_get_glyph_position (VkvgText textRun,
-                                                                          uint32_t index,
-                                                                          vkvg_glyph_info_t* pGlyphInfo);
+vkvg_public void vkvg_text_run_get_glyph_position(VkvgText textRun, uint32_t index, vkvg_glyph_info_t *pGlyphInfo);
 /** @}*/
 
 /**
@@ -1864,8 +1756,7 @@ void vkvg_text_run_get_glyph_position (VkvgText textRun,
  * @param pat A valid pattern handle.
  * @return The current status of the pattern.
  */
-vkvg_public
-vkvg_status_t vkvg_pattern_status (VkvgPattern pat);
+vkvg_public vkvg_status_t vkvg_pattern_status(VkvgPattern pat);
 /**
  * @brief add reference
  *
@@ -1873,8 +1764,7 @@ vkvg_status_t vkvg_pattern_status (VkvgPattern pat);
  * @param pat a valid #VkvgPattern pointer
  * @return VkvgPattern
  */
-vkvg_public
-VkvgPattern vkvg_pattern_reference (VkvgPattern pat);
+vkvg_public VkvgPattern vkvg_pattern_reference(VkvgPattern pat);
 /**
  * @brief get reference count
  *
@@ -1882,8 +1772,7 @@ VkvgPattern vkvg_pattern_reference (VkvgPattern pat);
  * @param pat a valid #VkvgPattern to query for its reference count
  * @return uint32_t the current reference count for this instance.
  */
-vkvg_public
-uint32_t vkvg_pattern_get_reference_count (VkvgPattern pat);
+vkvg_public uint32_t vkvg_pattern_get_reference_count(VkvgPattern pat);
 /**
  * @brief create a surface pattern
  *
@@ -1894,8 +1783,7 @@ uint32_t vkvg_pattern_get_reference_count (VkvgPattern pat);
  * @param surf a valid #VkvgSurface to use for pattern
  * @return VkvgPattern a newly created pattern
  */
-vkvg_public
-VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf);
+vkvg_public VkvgPattern vkvg_pattern_create_for_surface(VkvgSurface surf);
 /**
  * @brief create a new linear gradient.
  *
@@ -1908,8 +1796,7 @@ VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf);
  * @param y1 y coordinate of the end point
  * @return VkvgPattern the newly created pattern, call @ref vkvg_pattern_destroy when finished with it.
  */
-vkvg_public
-VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1);
+vkvg_public VkvgPattern vkvg_pattern_create_linear(float x0, float y0, float x1, float y1);
 /**
  * @brief edit an existing linear gradient.
  *
@@ -1921,8 +1808,7 @@ VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1);
  * @param y1 y coordinate of the end point
  * @return VKVG_STATUS_SUCCESS, or VKVG_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a linear gradient.
  */
-vkvg_public
-vkvg_status_t vkvg_pattern_edit_linear(VkvgPattern pat, float x0, float y0, float x1, float y1);
+vkvg_public vkvg_status_t vkvg_pattern_edit_linear(VkvgPattern pat, float x0, float y0, float x1, float y1);
 /**
  * @brief get the gradient end points for a linear gradient
  *
@@ -1934,11 +1820,10 @@ vkvg_status_t vkvg_pattern_edit_linear(VkvgPattern pat, float x0, float y0, floa
  * @param y1 y coordinate of the end point
  * @return VKVG_STATUS_SUCCESS, or VKVG_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a linear gradient.
  */
-vkvg_public
-vkvg_status_t vkvg_pattern_get_linear_points(VkvgPattern pat, float* x0, float* y0, float* x1, float* y1);
+vkvg_public vkvg_status_t vkvg_pattern_get_linear_points(VkvgPattern pat, float *x0, float *y0, float *x1, float *y1);
 /**
  * @brief create a new radial gradient.
- * 
+ *
  * Creates a new radial gradient between the two circles defined by (cx0, cy0, radius0) and (cx1, cy1, radius1).
  * Before using the gradient pattern, a number of color stops should be defined using vkvg_pattern_add_color_stop.
  *
@@ -1950,9 +1835,8 @@ vkvg_status_t vkvg_pattern_get_linear_points(VkvgPattern pat, float* x0, float*
  * @param radius1 radius for the center of the end circle, the outer circle.
  * @return VkvgPattern the newly created pattern to be disposed when finished by calling @ref vkvg_pattern_destroy.
  */
-vkvg_public
-VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0,
-                                                                               float cx1, float cy1, float radius1);
+vkvg_public VkvgPattern vkvg_pattern_create_radial(float cx0, float cy0, float radius0, float cx1, float cy1,
+                                                   float radius1);
 /**
  * @brief edit an existing radial gradient.
  *
@@ -1967,10 +1851,8 @@ VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0,
  * @param radius1 radius for the center of the end circle, the outer circle.
  * @return VKVG_STATUS_SUCCESS, or VKVG_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a radial gradient.
  */
-vkvg_public
-vkvg_status_t vkvg_pattern_edit_radial(VkvgPattern pat,
-                                                               float cx0, float cy0, float radius0,
-                                                               float cx1, float cy1, float radius1);
+vkvg_public vkvg_status_t vkvg_pattern_edit_radial(VkvgPattern pat, float cx0, float cy0, float radius0, float cx1,
+                                                   float cy1, float radius1);
 /**
  * @brief get color stop count.
  *
@@ -1980,13 +1862,12 @@ vkvg_status_t vkvg_pattern_edit_radial(VkvgPattern pat,
  * @param count a valid integer pointer to old the current stop count returned.
  * @return VKVG_STATUS_SUCCESS, or VKVG_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a gradient.
  */
-vkvg_public
-vkvg_status_t vkvg_pattern_get_color_stop_count (VkvgPattern pat, uint32_t* count);
+vkvg_public vkvg_status_t vkvg_pattern_get_color_stop_count(VkvgPattern pat, uint32_t *count);
 /**
  * @brief get color stop.
  *
- * Gets the color and offset information at the given index for a gradient pattern. Values of index range from 0 to n-1 where n is the number
- * returned by @ref vkvg_pattern_get_color_stop_count().
+ * Gets the color and offset information at the given index for a gradient pattern. Values of index range from 0 to n-1
+ * where n is the number returned by @ref vkvg_pattern_get_color_stop_count().
  *
  * @param pat a valid pattern pointer.
  * @param index index of the stop to return data for.
@@ -1995,24 +1876,23 @@ vkvg_status_t vkvg_pattern_get_color_stop_count (VkvgPattern pat, uint32_t* coun
  * @param g a valid float pointer to old the green component.
  * @param b a valid float pointer to old the blue component.
  * @param a a valid float pointer to old the alpha component.
- * @return VKVG_STATUS_SUCCESS, VKVG_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a gradient, VKVG_STATUS_INVALID_INDEX if index is out of bounds.
+ * @return VKVG_STATUS_SUCCESS, VKVG_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a gradient,
+ * VKVG_STATUS_INVALID_INDEX if index is out of bounds.
  */
-vkvg_public
-vkvg_status_t vkvg_pattern_get_color_stop_rgba (VkvgPattern pat, uint32_t index,
-                                                                                               float* offset, float* r, float* g, float* b, float* a);
+vkvg_public vkvg_status_t vkvg_pattern_get_color_stop_rgba(VkvgPattern pat, uint32_t index, float *offset, float *r,
+                                                           float *g, float *b, float *a);
 
 /**
  * @brief dispose pattern.
- * 
+ *
  * When you have finished using a pattern, free its resources by calling this method.
  *
  * @param pat the pattern to destroy.
  */
-vkvg_public
-void vkvg_pattern_destroy (VkvgPattern pat);
+vkvg_public void vkvg_pattern_destroy(VkvgPattern pat);
 /**
  * @brief add colors to gradients
- * 
+ *
  * for each color step in the gradient, call this method and provide an absolute position between 0 and 1
  * and a color.
  *
@@ -2023,43 +1903,39 @@ void vkvg_pattern_destroy (VkvgPattern pat);
  * @param b the blue component of the color stop
  * @param a the alpha chanel of the color stop
  */
-vkvg_public
-vkvg_status_t vkvg_pattern_add_color_stop(VkvgPattern pat, float offset, float r, float g, float b, float a);
+vkvg_public vkvg_status_t vkvg_pattern_add_color_stop(VkvgPattern pat, float offset, float r, float g, float b,
+                                                      float a);
 /**
  * @brief control the extend of the pattern
- * 
+ *
  * control whether the pattern has to be repeated or extended when painted on a surface.
  *
  * @param pat the pattern to set extend for.
  * @param extend one value of the @ref vkvg_extend_t enumeration.
  * @return VKVG_STATUS_SUCCESS, or VKVG_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a gradient.
  */
-vkvg_public
-void vkvg_pattern_set_extend (VkvgPattern pat, vkvg_extend_t extend);
+vkvg_public void vkvg_pattern_set_extend(VkvgPattern pat, vkvg_extend_t extend);
 /**
  * @brief control the filtering when using this pattern on a surface.
  *
  * @param pat pat the pattern to set filter for.
  * @param filter one value of the @ref vkvg_filter_t enumeration.
  */
-vkvg_public
-void vkvg_pattern_set_filter (VkvgPattern pat, vkvg_filter_t filter);
+vkvg_public void vkvg_pattern_set_filter(VkvgPattern pat, vkvg_filter_t filter);
 /**
  * @brief query the current extend value for a pa
  *
  * @param pat
  * @return vkvg_extend_t
  */
-vkvg_public
-vkvg_extend_t vkvg_pattern_get_extend (VkvgPattern pat);
+vkvg_public vkvg_extend_t vkvg_pattern_get_extend(VkvgPattern pat);
 /**
  * @brief
  *
  * @param pat
  * @return vkvg_filter_t
  */
-vkvg_public
-vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat);
+vkvg_public vkvg_filter_t vkvg_pattern_get_filter(VkvgPattern pat);
 /**
  * @brief get pattern type
  *
@@ -2068,38 +1944,26 @@ vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat);
  * @param pat the pattern to query
  * @return vkvg_pattern_type_t
  */
-vkvg_public
-vkvg_pattern_type_t vkvg_pattern_get_type (VkvgPattern pat);
-vkvg_public
-void vkvg_pattern_set_matrix (VkvgPattern pat, const vkvg_matrix_t* matrix);
-vkvg_public
-void vkvg_pattern_get_matrix (VkvgPattern pat, vkvg_matrix_t* matrix);
+vkvg_public vkvg_pattern_type_t vkvg_pattern_get_type(VkvgPattern pat);
+vkvg_public void                vkvg_pattern_set_matrix(VkvgPattern pat, const vkvg_matrix_t *matrix);
+vkvg_public void                vkvg_pattern_get_matrix(VkvgPattern pat, vkvg_matrix_t *matrix);
 
 /** @}*/
 
 /********* EXPERIMENTAL **************/
-vkvg_public
-void vkvg_set_source_color_name (VkvgContext ctx, const char* color);
+vkvg_public void vkvg_set_source_color_name(VkvgContext ctx, const char *color);
 
 #ifdef VKVG_RECORDING
-typedef struct _vkvg_recording_tVkvgRecording;
+typedef struct _vkvg_recording_t *VkvgRecording;
 
-vkvg_public
-void                   vkvg_start_recording    (VkvgContext ctx);
-vkvg_public
-VkvgRecording  vkvg_stop_recording             (VkvgContext ctx);
-vkvg_public
-void                   vkvg_replay                             (VkvgContext ctx, VkvgRecording rec);
-vkvg_public
-void                   vkvg_replay_command             (VkvgContext ctx, VkvgRecording rec, uint32_t cmdIndex);
-vkvg_public
-void                   vkvg_recording_get_command (VkvgRecording rec, uint32_t cmdIndex, uint32_t* cmd, void** dataOffset);
-vkvg_public
-uint32_t               vkvg_recording_get_count(VkvgRecording rec);
-vkvg_public
-void*                  vkvg_recording_get_data (VkvgRecording rec);
-vkvg_public
-void                   vkvg_recording_destroy  (VkvgRecording rec);
+vkvg_public void          vkvg_start_recording(VkvgContext ctx);
+vkvg_public VkvgRecording vkvg_stop_recording(VkvgContext ctx);
+vkvg_public void          vkvg_replay(VkvgContext ctx, VkvgRecording rec);
+vkvg_public void          vkvg_replay_command(VkvgContext ctx, VkvgRecording rec, uint32_t cmdIndex);
+vkvg_public void     vkvg_recording_get_command(VkvgRecording rec, uint32_t cmdIndex, uint32_t *cmd, void **dataOffset);
+vkvg_public uint32_t vkvg_recording_get_count(VkvgRecording rec);
+vkvg_public void    *vkvg_recording_get_data(VkvgRecording rec);
+vkvg_public void     vkvg_recording_destroy(VkvgRecording rec);
 /*************************************/
 #endif
 
index 41ec036e3fceb8f76adc701b9d0a711484c9d070..e7c1a0c31b4d99e064d0242734c9b925bedd2b26 100644 (file)
 
 #define _CRT_SECURE_NO_WARNINGS
 
-int directoryExists (const char* path) {
+int directoryExists(const char *path) {
 #if defined(_WIN32) || defined(_WIN64)
 #elif __APPLE__
 #elif __unix__
-       struct stat st = {0};
-       return stat(path, &st)+1;
+    struct stat st = {0};
+    return stat(path, &st) + 1;
 #else
-       return -1;
+    return -1;
 #endif
 }
-const char* getUserDir () {
+const char *getUserDir() {
 #if defined(_WIN32) || defined(_WIN64)
-       return getenv("HOME");
+    return getenv("HOME");
 #elif __APPLE__
 #elif __unix__
-       struct passwd *pw = getpwuid(getuid());
-       return pw->pw_dir;
+    struct passwd *pw = getpwuid(getuid());
+    return pw->pw_dir;
 #endif
 }
 
@@ -53,20 +53,20 @@ const char* getUserDir () {
 #include <unistd.h>
 
 void handler(int sig) {
-  void *array[100];
-  size_t size;
+    void  *array[100];
+    size_t size;
 
-  // get void*'s for all entries on the stack
-  size = backtrace(array, 100);
+    // get void*'s for all entries on the stack
+    size = backtrace(array, 100);
 
-  // print out all the frames to stderr
-  fprintf(stderr, "Error: signal %d:\n", sig);
-  backtrace_symbols_fd(array, size, STDERR_FILENO);
-  exit(1);
+    // print out all the frames to stderr
+    fprintf(stderr, "Error: signal %d:\n", sig);
+    backtrace_symbols_fd(array, size, STDERR_FILENO);
+    exit(1);
 }
 
-void _linux_register_error_handler () {
-       signal(SIGSEGV, handler);   // install our handler
-       signal(SIGABRT, handler);   // install our handler
+void _linux_register_error_handler() {
+    signal(SIGSEGV, handler); // install our handler
+    signal(SIGABRT, handler); // install our handler
 }
 #endif
index e2d4350af48a6fd944c3f13798672afef78a3aca..e047ba8d6ed4c5de1ed34e75864555d47d55219f 100644 (file)
 #ifndef CROSS_OS_H
 #define CROSS_OS_H
 
-//cross platform os helpers
+// cross platform os helpers
 #if defined(_WIN32) || defined(_WIN64)
-       //disable warning on iostream functions on windows
-       #define _CRT_SECURE_NO_WARNINGS
-       #include "windows.h"
-       #if defined(_WIN64)
-               #ifndef isnan
-                       #define isnan _isnanf
-               #endif
-       #endif
-       #define vkvg_inline __forceinline
-       #define disable_warning (warn)
-       #define reset_warning (warn)
+// disable warning on iostream functions on windows
+#define _CRT_SECURE_NO_WARNINGS
+#include "windows.h"
+#if defined(_WIN64)
+#ifndef isnan
+#define isnan _isnanf
+#endif
+#endif
+#define vkvg_inline     __forceinline
+#define disable_warning (warn)
+#define reset_warning   (warn)
 #elif __APPLE__
-       #include <math.h>
-       #define vkvg_inline static
-       #define disable_warning (warn)
-       #define reset_warning (warn)
+#include <math.h>
+#define vkvg_inline     static
+#define disable_warning (warn)
+#define reset_warning   (warn)
 #elif __unix__
-       #include <unistd.h>
-       #include <sys/types.h>
-       #include <pwd.h>
-       #define vkvg_inline static inline __attribute((always_inline))
-       #define disable_warning (warn) #pragma GCC diagnostic ignored "-W"#warn
-       #define reset_warning (warn) #pragma GCC diagnostic warning "-W"#warn
-       #if __linux__
-               void _linux_register_error_handler ();
-       #endif
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#define vkvg_inline     static inline __attribute((always_inline))
+#define disable_warning (warn) #pragma GCC diagnostic ignored "-W" #warn
+#define reset_warning   (warn) #pragma GCC diagnostic warning "-W" #warn
+#if __linux__
+void _linux_register_error_handler();
+#endif
 #endif
 
-const char* getUserDir ();
+const char *getUserDir();
 
 #endif // CROSS_OS_H
index f9cea2ed8c8587b442bffb1167c672af62826dc4..5dcf01fd1a9ae5c422387a8a0084d95fc5eb405f 100644 (file)
@@ -32,103 +32,96 @@ freely, subject to the following restrictions:
 
 /* Platform specific includes */
 #if defined(_TTHREAD_POSIX_)
-  #include <signal.h>
-  #include <sched.h>
-  #include <unistd.h>
-  #include <sys/time.h>
-  #include <errno.h>
+#include <signal.h>
+#include <sched.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <errno.h>
 #elif defined(_TTHREAD_WIN32_)
-  #include <process.h>
-  #include <sys/timeb.h>
+#include <process.h>
+#include <sys/timeb.h>
 #endif
 
 /* Standard, good-to-have defines */
 #ifndef NULL
-  #define NULL (void*)0
+#define NULL (void *)0
 #endif
 #ifndef TRUE
-  #define TRUE 1
+#define TRUE 1
 #endif
 #ifndef FALSE
-  #define FALSE 0
+#define FALSE 0
 #endif
 
-int mtx_init(mtx_t *mtx, int type)
-{
+int mtx_init(mtx_t *mtx, int type) {
 #if defined(_TTHREAD_WIN32_)
-  mtx->mAlreadyLocked = FALSE;
-  mtx->mRecursive = type & mtx_recursive;
-  InitializeCriticalSection(&mtx->mHandle);
-  return thrd_success;
+    mtx->mAlreadyLocked = FALSE;
+    mtx->mRecursive     = type & mtx_recursive;
+    InitializeCriticalSection(&mtx->mHandle);
+    return thrd_success;
 #else
-  int ret;
-  pthread_mutexattr_t attr;
-  pthread_mutexattr_init(&attr);
-  if (type & mtx_recursive)
-  {
-    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-  }
-  ret = pthread_mutex_init(mtx, &attr);
-  pthread_mutexattr_destroy(&attr);
-  return ret == 0 ? thrd_success : thrd_error;
+    int                 ret;
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    if (type & mtx_recursive) {
+        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    }
+    ret = pthread_mutex_init(mtx, &attr);
+    pthread_mutexattr_destroy(&attr);
+    return ret == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-void mtx_destroy(mtx_t *mtx)
-{
+void mtx_destroy(mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  DeleteCriticalSection(&mtx->mHandle);
+    DeleteCriticalSection(&mtx->mHandle);
 #else
-  pthread_mutex_destroy(mtx);
+    pthread_mutex_destroy(mtx);
 #endif
 }
 
-int mtx_lock(mtx_t *mtx)
-{
+int mtx_lock(mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  EnterCriticalSection(&mtx->mHandle);
-  if (!mtx->mRecursive)
-  {
-    while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */
-    mtx->mAlreadyLocked = TRUE;
-  }
-  return thrd_success;
+    EnterCriticalSection(&mtx->mHandle);
+    if (!mtx->mRecursive) {
+        while (mtx->mAlreadyLocked)
+            Sleep(1000); /* Simulate deadlock... */
+        mtx->mAlreadyLocked = TRUE;
+    }
+    return thrd_success;
 #else
-  return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
+    return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
-{
-  /* FIXME! */
-  (void)mtx;
-  (void)ts;
-  return thrd_error;
+int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) {
+    /* FIXME! */
+    (void)mtx;
+    (void)ts;
+    return thrd_error;
 }
 
-int mtx_trylock(mtx_t *mtx)
-{
+int mtx_trylock(mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy;
-  if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked)
-  {
-    LeaveCriticalSection(&mtx->mHandle);
-    ret = thrd_busy;
-  }
-  return ret;
+    int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy;
+    if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked) {
+        LeaveCriticalSection(&mtx->mHandle);
+        ret = thrd_busy;
+    }
+    return ret;
 #else
-  return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
+    return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
 #endif
 }
 
-int mtx_unlock(mtx_t *mtx)
-{
+int mtx_unlock(mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  mtx->mAlreadyLocked = FALSE;
-  LeaveCriticalSection(&mtx->mHandle);
-  return thrd_success;
+    mtx->mAlreadyLocked = FALSE;
+    LeaveCriticalSection(&mtx->mHandle);
+    return thrd_success;
 #else
-  return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
+    return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;
+    ;
 #endif
 }
 
@@ -137,458 +130,397 @@ int mtx_unlock(mtx_t *mtx)
 #define _CONDITION_EVENT_ALL 1
 #endif
 
-int cnd_init(cnd_t *cond)
-{
+int cnd_init(cnd_t *cond) {
 #if defined(_TTHREAD_WIN32_)
-  cond->mWaitersCount = 0;
+    cond->mWaitersCount = 0;
 
-  /* Init critical section */
-  InitializeCriticalSection(&cond->mWaitersCountLock);
+    /* Init critical section */
+    InitializeCriticalSection(&cond->mWaitersCountLock);
 
-  /* Init events */
-  cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
-  if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL)
-  {
-    cond->mEvents[_CONDITION_EVENT_ALL] = NULL;
-    return thrd_error;
-  }
-  cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
-  if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
-    cond->mEvents[_CONDITION_EVENT_ONE] = NULL;
-    return thrd_error;
-  }
+    /* Init events */
+    cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL) {
+        cond->mEvents[_CONDITION_EVENT_ALL] = NULL;
+        return thrd_error;
+    }
+    cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
+    if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL) {
+        CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
+        cond->mEvents[_CONDITION_EVENT_ONE] = NULL;
+        return thrd_error;
+    }
 
-  return thrd_success;
+    return thrd_success;
 #else
-  return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
+    return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-void cnd_destroy(cnd_t *cond)
-{
+void cnd_destroy(cnd_t *cond) {
 #if defined(_TTHREAD_WIN32_)
-  if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
-  }
-  if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
-  }
-  DeleteCriticalSection(&cond->mWaitersCountLock);
+    if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL) {
+        CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
+    }
+    if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL) {
+        CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
+    }
+    DeleteCriticalSection(&cond->mWaitersCountLock);
 #else
-  pthread_cond_destroy(cond);
+    pthread_cond_destroy(cond);
 #endif
 }
 
-int cnd_signal(cnd_t *cond)
-{
+int cnd_signal(cnd_t *cond) {
 #if defined(_TTHREAD_WIN32_)
-  int haveWaiters;
-
-  /* Are there any waiters? */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  haveWaiters = (cond->mWaitersCount > 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we have any waiting threads, send them a signal */
-  if(haveWaiters)
-  {
-    if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0)
-    {
-      return thrd_error;
+    int haveWaiters;
+
+    /* Are there any waiters? */
+    EnterCriticalSection(&cond->mWaitersCountLock);
+    haveWaiters = (cond->mWaitersCount > 0);
+    LeaveCriticalSection(&cond->mWaitersCountLock);
+
+    /* If we have any waiting threads, send them a signal */
+    if (haveWaiters) {
+        if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0) {
+            return thrd_error;
+        }
     }
-  }
 
-  return thrd_success;
+    return thrd_success;
 #else
-  return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
+    return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-int cnd_broadcast(cnd_t *cond)
-{
+int cnd_broadcast(cnd_t *cond) {
 #if defined(_TTHREAD_WIN32_)
-  int haveWaiters;
-
-  /* Are there any waiters? */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  haveWaiters = (cond->mWaitersCount > 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we have any waiting threads, send them a signal */
-  if(haveWaiters)
-  {
-    if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
-    {
-      return thrd_error;
+    int haveWaiters;
+
+    /* Are there any waiters? */
+    EnterCriticalSection(&cond->mWaitersCountLock);
+    haveWaiters = (cond->mWaitersCount > 0);
+    LeaveCriticalSection(&cond->mWaitersCountLock);
+
+    /* If we have any waiting threads, send them a signal */
+    if (haveWaiters) {
+        if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) {
+            return thrd_error;
+        }
     }
-  }
 
-  return thrd_success;
+    return thrd_success;
 #else
-  return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
+    return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
 #if defined(_TTHREAD_WIN32_)
-static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout)
-{
-  int result, lastWaiter;
-
-  /* Increment number of waiters */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  ++ cond->mWaitersCount;
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* Release the mutex while waiting for the condition (will decrease
-     the number of waiters when done)... */
-  mtx_unlock(mtx);
-
-  /* Wait for either event to become signaled due to cnd_signal() or
-     cnd_broadcast() being called */
-  result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout);
-  if (result == WAIT_TIMEOUT)
-  {
-    return thrd_timeout;
-  }
-  else if (result == (int)WAIT_FAILED)
-  {
-    return thrd_error;
-  }
-
-  /* Check if we are the last waiter */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  -- cond->mWaitersCount;
-  lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
-               (cond->mWaitersCount == 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we are the last waiter to be notified to stop waiting, reset the event */
-  if (lastWaiter)
-  {
-    if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
-    {
-      return thrd_error;
+static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout) {
+    int result, lastWaiter;
+
+    /* Increment number of waiters */
+    EnterCriticalSection(&cond->mWaitersCountLock);
+    ++cond->mWaitersCount;
+    LeaveCriticalSection(&cond->mWaitersCountLock);
+
+    /* Release the mutex while waiting for the condition (will decrease
+       the number of waiters when done)... */
+    mtx_unlock(mtx);
+
+    /* Wait for either event to become signaled due to cnd_signal() or
+       cnd_broadcast() being called */
+    result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout);
+    if (result == WAIT_TIMEOUT) {
+        return thrd_timeout;
+    } else if (result == (int)WAIT_FAILED) {
+        return thrd_error;
+    }
+
+    /* Check if we are the last waiter */
+    EnterCriticalSection(&cond->mWaitersCountLock);
+    --cond->mWaitersCount;
+    lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && (cond->mWaitersCount == 0);
+    LeaveCriticalSection(&cond->mWaitersCountLock);
+
+    /* If we are the last waiter to be notified to stop waiting, reset the event */
+    if (lastWaiter) {
+        if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) {
+            return thrd_error;
+        }
     }
-  }
 
-  /* Re-acquire the mutex */
-  mtx_lock(mtx);
+    /* Re-acquire the mutex */
+    mtx_lock(mtx);
 
-  return thrd_success;
+    return thrd_success;
 }
 #endif
 
-int cnd_wait(cnd_t *cond, mtx_t *mtx)
-{
+int cnd_wait(cnd_t *cond, mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  return _cnd_timedwait_win32(cond, mtx, INFINITE);
+    return _cnd_timedwait_win32(cond, mtx, INFINITE);
 #else
-  return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
+    return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
-{
+int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts) {
 #if defined(_TTHREAD_WIN32_)
-  struct timespec now;
-  if (clock_gettime(CLOCK_REALTIME, &now) == 0)
-  {
-    DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 +
-                           (ts->tv_nsec - now.tv_nsec + 500000) / 1000000);
-    return _cnd_timedwait_win32(cond, mtx, delta);
-  }
-  else
-    return thrd_error;
+    struct timespec now;
+    if (clock_gettime(CLOCK_REALTIME, &now) == 0) {
+        DWORD delta = (DWORD)((ts->tv_sec - now.tv_sec) * 1000 + (ts->tv_nsec - now.tv_nsec + 500000) / 1000000);
+        return _cnd_timedwait_win32(cond, mtx, delta);
+    } else
+        return thrd_error;
 #else
-  int ret;
-  ret = pthread_cond_timedwait(cond, mtx, ts);
-  if (ret == ETIMEDOUT)
-  {
-    return thrd_timeout;
-  }
-  return ret == 0 ? thrd_success : thrd_error;
+    int ret;
+    ret = pthread_cond_timedwait(cond, mtx, ts);
+    if (ret == ETIMEDOUT) {
+        return thrd_timeout;
+    }
+    return ret == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-
 /** Information to pass to the new thread (what to run). */
 typedef struct {
-  thrd_start_t mFunction; /**< Pointer to the function to be executed. */
-  void * mArg;            /**< Function argument for the thread function. */
+    thrd_start_t mFunction; /**< Pointer to the function to be executed. */
+    void        *mArg;      /**< Function argument for the thread function. */
 } _thread_start_info;
 
 /* Thread wrapper function. */
 #if defined(_TTHREAD_WIN32_)
-static unsigned WINAPI _thrd_wrapper_function(void * aArg)
+static unsigned WINAPI _thrd_wrapper_function(void *aArg)
 #elif defined(_TTHREAD_POSIX_)
-static void * _thrd_wrapper_function(void * aArg)
+static void *_thrd_wrapper_function(void *aArg)
 #endif
 {
-  thrd_start_t fun;
-  void *arg;
-  int  res;
+    thrd_start_t fun;
+    void        *arg;
+    int          res;
 #if defined(_TTHREAD_POSIX_)
-  void *pres;
+    void *pres;
 #endif
 
-  /* Get thread startup information */
-  _thread_start_info *ti = (_thread_start_info *) aArg;
-  fun = ti->mFunction;
-  arg = ti->mArg;
+    /* Get thread startup information */
+    _thread_start_info *ti = (_thread_start_info *)aArg;
+    fun                    = ti->mFunction;
+    arg                    = ti->mArg;
 
-  /* The thread is responsible for freeing the startup information */
-  free((void *)ti);
+    /* The thread is responsible for freeing the startup information */
+    free((void *)ti);
 
-  /* Call the actual client thread function */
-  res = fun(arg);
+    /* Call the actual client thread function */
+    res = fun(arg);
 
 #if defined(_TTHREAD_WIN32_)
-  return res;
+    return res;
 #else
-  pres = malloc(sizeof(int));
-  if (pres != NULL)
-  {
-    *(int*)pres = res;
-  }
-  return pres;
+    pres = malloc(sizeof(int));
+    if (pres != NULL) {
+        *(int *)pres = res;
+    }
+    return pres;
 #endif
 }
 
-int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
-{
-  /* Fill out the thread startup information (passed to the thread wrapper,
-     which will eventually free it) */
-  _thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info));
-  if (ti == NULL)
-  {
-    return thrd_nomem;
-  }
-  ti->mFunction = func;
-  ti->mArg = arg;
-
-  /* Create the thread */
+int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) {
+    /* Fill out the thread startup information (passed to the thread wrapper,
+       which will eventually free it) */
+    _thread_start_info *ti = (_thread_start_info *)malloc(sizeof(_thread_start_info));
+    if (ti == NULL) {
+        return thrd_nomem;
+    }
+    ti->mFunction = func;
+    ti->mArg      = arg;
+
+    /* Create the thread */
 #if defined(_TTHREAD_WIN32_)
-  *thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL);
+    *thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL);
 #elif defined(_TTHREAD_POSIX_)
-  if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0)
-  {
-    *thr = 0;
-  }
+    if (pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0) {
+        *thr = 0;
+    }
 #endif
 
-  /* Did we fail to create the thread? */
-  if(!*thr)
-  {
-    free(ti);
-    return thrd_error;
-  }
+    /* Did we fail to create the thread? */
+    if (!*thr) {
+        free(ti);
+        return thrd_error;
+    }
 
-  return thrd_success;
+    return thrd_success;
 }
 
-thrd_t thrd_current(void)
-{
+thrd_t thrd_current(void) {
 #if defined(_TTHREAD_WIN32_)
-  return GetCurrentThread();
+    return GetCurrentThread();
 #else
-  return pthread_self();
+    return pthread_self();
 #endif
 }
 
-int thrd_detach(thrd_t thr)
-{
-  /* FIXME! */
-  (void)thr;
-  return thrd_error;
+int thrd_detach(thrd_t thr) {
+    /* FIXME! */
+    (void)thr;
+    return thrd_error;
 }
 
-int thrd_equal(thrd_t thr0, thrd_t thr1)
-{
+int thrd_equal(thrd_t thr0, thrd_t thr1) {
 #if defined(_TTHREAD_WIN32_)
-  return thr0 == thr1;
+    return thr0 == thr1;
 #else
-  return pthread_equal(thr0, thr1);
+    return pthread_equal(thr0, thr1);
 #endif
 }
 
-void thrd_exit(int res)
-{
+void thrd_exit(int res) {
 #if defined(_TTHREAD_WIN32_)
-  ExitThread(res);
+    ExitThread(res);
 #else
-  void *pres = malloc(sizeof(int));
-  if (pres != NULL)
-  {
-    *(int*)pres = res;
-  }
-  pthread_exit(pres);
+    void *pres = malloc(sizeof(int));
+    if (pres != NULL) {
+        *(int *)pres = res;
+    }
+    pthread_exit(pres);
 #endif
 }
 
-int thrd_join(thrd_t thr, int *res)
-{
+int thrd_join(thrd_t thr, int *res) {
 #if defined(_TTHREAD_WIN32_)
-  if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED)
-  {
-    return thrd_error;
-  }
-  if (res != NULL)
-  {
-    DWORD dwRes;
-    GetExitCodeThread(thr, &dwRes);
-    *res = dwRes;
-  }
+    if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED) {
+        return thrd_error;
+    }
+    if (res != NULL) {
+        DWORD dwRes;
+        GetExitCodeThread(thr, &dwRes);
+        *res = dwRes;
+    }
 #elif defined(_TTHREAD_POSIX_)
-  void *pres;
-  int ires = 0;
-  if (pthread_join(thr, &pres) != 0)
-  {
-    return thrd_error;
-  }
-  if (pres != NULL)
-  {
-    ires = *(int*)pres;
-    free(pres);
-  }
-  if (res != NULL)
-  {
-    *res = ires;
-  }
-#endif
-  return thrd_success;
+    void *pres;
+    int   ires = 0;
+    if (pthread_join(thr, &pres) != 0) {
+        return thrd_error;
+    }
+    if (pres != NULL) {
+        ires = *(int *)pres;
+        free(pres);
+    }
+    if (res != NULL) {
+        *res = ires;
+    }
+#endif
+    return thrd_success;
 }
 
-int thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
-{
-  struct timespec now;
+int thrd_sleep(const struct timespec *time_point, struct timespec *remaining) {
+    struct timespec now;
 #if defined(_TTHREAD_WIN32_)
-  DWORD delta;
+    DWORD delta;
 #else
-  long delta;
+    long delta;
 #endif
 
-  /* Get the current time */
-  if (clock_gettime(CLOCK_REALTIME, &now) != 0)
-    return -2;  // FIXME: Some specific error code?
+    /* Get the current time */
+    if (clock_gettime(CLOCK_REALTIME, &now) != 0)
+        return -2; // FIXME: Some specific error code?
 
 #if defined(_TTHREAD_WIN32_)
-  /* Delta in milliseconds */
-  delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 +
-                   (time_point->tv_nsec - now.tv_nsec + 500000) / 1000000);
-  if (delta > 0)
-  {
-    Sleep(delta);
-  }
+    /* Delta in milliseconds */
+    delta = (DWORD)((time_point->tv_sec - now.tv_sec) * 1000 + (time_point->tv_nsec - now.tv_nsec + 500000) / 1000000);
+    if (delta > 0) {
+        Sleep(delta);
+    }
 #else
-  /* Delta in microseconds */
-  delta = (time_point->tv_sec - now.tv_sec) * 1000000L +
-          (time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
-
-  /* On some systems, the usleep argument must be < 1000000 */
-  while (delta > 999999L)
-  {
-    usleep(999999);
-    delta -= 999999L;
-  }
-  if (delta > 0L)
-  {
-    usleep((useconds_t)delta);
-  }
-#endif
-
-  /* We don't support waking up prematurely (yet) */
-  if (remaining)
-  {
-    remaining->tv_sec = 0;
-    remaining->tv_nsec = 0;
-  }
-  return 0;
+    /* Delta in microseconds */
+    delta = (time_point->tv_sec - now.tv_sec) * 1000000L + (time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
+
+    /* On some systems, the usleep argument must be < 1000000 */
+    while (delta > 999999L) {
+        usleep(999999);
+        delta -= 999999L;
+    }
+    if (delta > 0L) {
+        usleep((useconds_t)delta);
+    }
+#endif
+
+    /* We don't support waking up prematurely (yet) */
+    if (remaining) {
+        remaining->tv_sec  = 0;
+        remaining->tv_nsec = 0;
+    }
+    return 0;
 }
 
-void thrd_yield(void)
-{
+void thrd_yield(void) {
 #if defined(_TTHREAD_WIN32_)
-  Sleep(0);
+    Sleep(0);
 #else
-  sched_yield();
+    sched_yield();
 #endif
 }
 
-int tss_create(tss_t *key, tss_dtor_t dtor)
-{
+int tss_create(tss_t *key, tss_dtor_t dtor) {
 #if defined(_TTHREAD_WIN32_)
-  /* FIXME: The destructor function is not supported yet... */
-  if (dtor != NULL)
-  {
-    return thrd_error;
-  }
-  *key = TlsAlloc();
-  if (*key == TLS_OUT_OF_INDEXES)
-  {
-    return thrd_error;
-  }
+    /* FIXME: The destructor function is not supported yet... */
+    if (dtor != NULL) {
+        return thrd_error;
+    }
+    *key = TlsAlloc();
+    if (*key == TLS_OUT_OF_INDEXES) {
+        return thrd_error;
+    }
 #else
-  if (pthread_key_create(key, dtor) != 0)
-  {
-    return thrd_error;
-  }
+    if (pthread_key_create(key, dtor) != 0) {
+        return thrd_error;
+    }
 #endif
-  return thrd_success;
+    return thrd_success;
 }
 
-void tss_delete(tss_t key)
-{
+void tss_delete(tss_t key) {
 #if defined(_TTHREAD_WIN32_)
-  TlsFree(key);
+    TlsFree(key);
 #else
-  pthread_key_delete(key);
+    pthread_key_delete(key);
 #endif
 }
 
-void *tss_get(tss_t key)
-{
+void *tss_get(tss_t key) {
 #if defined(_TTHREAD_WIN32_)
-  return TlsGetValue(key);
+    return TlsGetValue(key);
 #else
-  return pthread_getspecific(key);
+    return pthread_getspecific(key);
 #endif
 }
 
-int tss_set(tss_t key, void *val)
-{
+int tss_set(tss_t key, void *val) {
 #if defined(_TTHREAD_WIN32_)
-  if (TlsSetValue(key, val) == 0)
-  {
-    return thrd_error;
-  }
+    if (TlsSetValue(key, val) == 0) {
+        return thrd_error;
+    }
 #else
-  if (pthread_setspecific(key, val) != 0)
-  {
-    return thrd_error;
-  }
+    if (pthread_setspecific(key, val) != 0) {
+        return thrd_error;
+    }
 #endif
-  return thrd_success;
+    return thrd_success;
 }
 
 #if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_)
-int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts)
-{
+int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts) {
 #if defined(_TTHREAD_WIN32_)
-  struct _timeb tb;
-  _ftime(&tb);
-  ts->tv_sec = (time_t)tb.time;
-  ts->tv_nsec = 1000000L * (long)tb.millitm;
+    struct _timeb tb;
+    _ftime(&tb);
+    ts->tv_sec  = (time_t)tb.time;
+    ts->tv_nsec = 1000000L * (long)tb.millitm;
 #else
-  struct timeval tv;
-  gettimeofday(&tv, NULL);
-  ts->tv_sec = (time_t)tv.tv_sec;
-  ts->tv_nsec = 1000L * (long)tv.tv_usec;
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    ts->tv_sec  = (time_t)tv.tv_sec;
+    ts->tv_nsec = 1000L * (long)tv.tv_usec;
 #endif
-  return 0;
+    return 0;
 }
 #endif // _TTHREAD_EMULATE_CLOCK_GETTIME_
-
index 42958c393e86ec8bc55ee10e150a02f243f71041..eaacfbe38683f7122380368dc16f2fa0ec0c2c35 100644 (file)
@@ -25,52 +25,52 @@ freely, subject to the following restrictions:
 #define _TINYCTHREAD_H_
 
 /**
-* @file
-* @mainpage TinyCThread API Reference
-*
-* @section intro_sec Introduction
-* TinyCThread is a minimal, portable implementation of basic threading
-* classes for C.
-*
-* They closely mimic the functionality and naming of the C11 standard, and
-* should be easily replaceable with the corresponding standard variants.
-*
-* @section port_sec Portability
-* The Win32 variant uses the native Win32 API for implementing the thread
-* classes, while for other systems, the POSIX threads API (pthread) is used.
-*
-* @section misc_sec Miscellaneous
-* The following special keywords are available: #_Thread_local.
-*
-* For more detailed information, browse the different sections of this
-* documentation. A good place to start is:
-* tinycthread.h.
-*/
+ * @file
+ * @mainpage TinyCThread API Reference
+ *
+ * @section intro_sec Introduction
+ * TinyCThread is a minimal, portable implementation of basic threading
+ * classes for C.
+ *
+ * They closely mimic the functionality and naming of the C11 standard, and
+ * should be easily replaceable with the corresponding standard variants.
+ *
+ * @section port_sec Portability
+ * The Win32 variant uses the native Win32 API for implementing the thread
+ * classes, while for other systems, the POSIX threads API (pthread) is used.
+ *
+ * @section misc_sec Miscellaneous
+ * The following special keywords are available: #_Thread_local.
+ *
+ * For more detailed information, browse the different sections of this
+ * documentation. A good place to start is:
+ * tinycthread.h.
+ */
 
 /* Which platform are we on? */
 #if !defined(_TTHREAD_PLATFORM_DEFINED_)
-  #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
-    #define _TTHREAD_WIN32_
-  #else
-    #define _TTHREAD_POSIX_
-  #endif
-  #define _TTHREAD_PLATFORM_DEFINED_
+#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
+#define _TTHREAD_WIN32_
+#else
+#define _TTHREAD_POSIX_
+#endif
+#define _TTHREAD_PLATFORM_DEFINED_
 #endif
 
 /* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */
 #if defined(_TTHREAD_POSIX_)
-  #undef _FEATURES_H
-  #if !defined(_GNU_SOURCE)
-    #define _GNU_SOURCE
-  #endif
-  #if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
-    #undef _POSIX_C_SOURCE
-    #define _POSIX_C_SOURCE 199309L
-  #endif
-  #if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
-    #undef _XOPEN_SOURCE
-    #define _XOPEN_SOURCE 500
-  #endif
+#undef _FEATURES_H
+#if !defined(_GNU_SOURCE)
+#define _GNU_SOURCE
+#endif
+#if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 199309L
+#endif
+#if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
+#undef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
 #endif
 
 /* Generic includes */
@@ -78,18 +78,18 @@ freely, subject to the following restrictions:
 
 /* Platform specific includes */
 #if defined(_TTHREAD_POSIX_)
-  #include <sys/time.h>
-  #include <pthread.h>
+#include <sys/time.h>
+#include <pthread.h>
 #elif defined(_TTHREAD_WIN32_)
-  #ifndef WIN32_LEAN_AND_MEAN
-    #define WIN32_LEAN_AND_MEAN
-    #define __UNDEF_LEAN_AND_MEAN
-  #endif
-  #include <windows.h>
-  #ifdef __UNDEF_LEAN_AND_MEAN
-    #undef WIN32_LEAN_AND_MEAN
-    #undef __UNDEF_LEAN_AND_MEAN
-  #endif
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#define __UNDEF_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#ifdef __UNDEF_LEAN_AND_MEAN
+#undef WIN32_LEAN_AND_MEAN
+#undef __UNDEF_LEAN_AND_MEAN
+#endif
 #endif
 
 /* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC,
@@ -97,11 +97,11 @@ freely, subject to the following restrictions:
    the only other supported time specifier: CLOCK_REALTIME (and if that fails,
    we're probably emulating clock_gettime anyway, so anything goes). */
 #ifndef TIME_UTC
-  #ifdef CLOCK_REALTIME
-    #define TIME_UTC CLOCK_REALTIME
-  #else
-    #define TIME_UTC 0
-  #endif
+#ifdef CLOCK_REALTIME
+#define TIME_UTC CLOCK_REALTIME
+#else
+#define TIME_UTC 0
+#endif
 #endif
 
 /* Workaround for missing clock_gettime (most Windows compilers, afaik) */
@@ -110,8 +110,8 @@ freely, subject to the following restrictions:
 /* Emulate struct timespec */
 #if defined(_TTHREAD_WIN32_)
 struct _ttherad_timespec {
-  time_t tv_sec;
-  long   tv_nsec;
+    time_t tv_sec;
+    long   tv_nsec;
 };
 #define timespec _ttherad_timespec
 #endif
@@ -124,11 +124,10 @@ typedef int _tthread_clockid_t;
 int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
 #define clock_gettime _tthread_clock_gettime
 #ifndef CLOCK_REALTIME
-  #define CLOCK_REALTIME 0
+#define CLOCK_REALTIME 0
 #endif
 #endif
 
-
 /** TinyCThread version (major number). */
 #define TINYCTHREAD_VERSION_MAJOR 1
 /** TinyCThread version (minor number). */
@@ -137,42 +136,44 @@ int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
 #define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
 
 /**
-* @def _Thread_local
-* Thread local storage keyword.
-* A variable that is declared with the @c _Thread_local keyword makes the
-* value of the variable local to each thread (known as thread-local storage,
-* or TLS). Example usage:
-* @code
-* // This variable is local to each thread.
-* _Thread_local int variable;
-* @endcode
-* @note The @c _Thread_local keyword is a macro that maps to the corresponding
-* compiler directive (e.g. @c __declspec(thread)).
-* @note This directive is currently not supported on Mac OS X (it will give
-* a compiler error), since compile-time TLS is not supported in the Mac OS X
-* executable format. Also, some older versions of MinGW (before GCC 4.x) do
-* not support this directive.
-* @hideinitializer
-*/
+ * @def _Thread_local
+ * Thread local storage keyword.
+ * A variable that is declared with the @c _Thread_local keyword makes the
+ * value of the variable local to each thread (known as thread-local storage,
+ * or TLS). Example usage:
+ * @code
+ * // This variable is local to each thread.
+ * _Thread_local int variable;
+ * @endcode
+ * @note The @c _Thread_local keyword is a macro that maps to the corresponding
+ * compiler directive (e.g. @c __declspec(thread)).
+ * @note This directive is currently not supported on Mac OS X (it will give
+ * a compiler error), since compile-time TLS is not supported in the Mac OS X
+ * executable format. Also, some older versions of MinGW (before GCC 4.x) do
+ * not support this directive.
+ * @hideinitializer
+ */
 
 /* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */
 #if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
- #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-  #define _Thread_local __thread
- #else
-  #define _Thread_local __declspec(thread)
- #endif
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
+#define _Thread_local __thread
+#else
+#define _Thread_local __declspec(thread)
+#endif
 #endif
 
 /* Macros */
 #define TSS_DTOR_ITERATIONS 0
 
 /* Function return values */
-#define thrd_error    0 /**< The requested operation failed */
-#define thrd_success  1 /**< The requested operation succeeded */
-#define thrd_timeout  2 /**< The time specified in the call was reached without acquiring the requested resource */
-#define thrd_busy     3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */
-#define thrd_nomem    4 /**< The requested operation failed because it was unable to allocate memory */
+#define thrd_error   0 /**< The requested operation failed */
+#define thrd_success 1 /**< The requested operation succeeded */
+#define thrd_timeout 2 /**< The time specified in the call was reached without acquiring the requested resource */
+#define thrd_busy                                                                                                      \
+    3 /**< The requested operation failed because a tesource requested by a test and return function is already in use \
+       */
+#define thrd_nomem 4 /**< The requested operation failed because it was unable to allocate memory */
 
 /* Mutex types */
 #define mtx_plain     1
@@ -183,261 +184,259 @@ int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
 /* Mutex */
 #if defined(_TTHREAD_WIN32_)
 typedef struct {
-  CRITICAL_SECTION mHandle;   /* Critical section handle */
-  int mAlreadyLocked;         /* TRUE if the mutex is already locked */
-  int mRecursive;             /* TRUE if the mutex is recursive */
+    CRITICAL_SECTION mHandle;        /* Critical section handle */
+    int              mAlreadyLocked; /* TRUE if the mutex is already locked */
+    int              mRecursive;     /* TRUE if the mutex is recursive */
 } mtx_t;
 #else
 typedef pthread_mutex_t mtx_t;
 #endif
 
 /** Create a mutex object.
-* @param mtx A mutex object.
-* @param type Bit-mask that must have one of the following six values:
-*   @li @c mtx_plain for a simple non-recursive mutex
-*   @li @c mtx_timed for a non-recursive mutex that supports timeout
-*   @li @c mtx_try for a non-recursive mutex that supports test and return
-*   @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive)
-*   @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive)
-*   @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive)
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * @param mtx A mutex object.
+ * @param type Bit-mask that must have one of the following six values:
+ *   @li @c mtx_plain for a simple non-recursive mutex
+ *   @li @c mtx_timed for a non-recursive mutex that supports timeout
+ *   @li @c mtx_try for a non-recursive mutex that supports test and return
+ *   @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive)
+ *   @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive)
+ *   @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive)
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int mtx_init(mtx_t *mtx, int type);
 
 /** Release any resources used by the given mutex.
-* @param mtx A mutex object.
-*/
+ * @param mtx A mutex object.
+ */
 void mtx_destroy(mtx_t *mtx);
 
 /** Lock the given mutex.
-* Blocks until the given mutex can be locked. If the mutex is non-recursive, and
-* the calling thread already has a lock on the mutex, this call will block
-* forever.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * Blocks until the given mutex can be locked. If the mutex is non-recursive, and
+ * the calling thread already has a lock on the mutex, this call will block
+ * forever.
+ * @param mtx A mutex object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int mtx_lock(mtx_t *mtx);
 
 /** NOT YET IMPLEMENTED.
-*/
+ */
 int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
 
 /** Try to lock the given mutex.
-* The specified mutex shall support either test and return or timeout. If the
-* mutex is already locked, the function returns without blocking.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_busy if the resource
-* requested is already in use, or @ref thrd_error if the request could not be
-* honored.
-*/
+ * The specified mutex shall support either test and return or timeout. If the
+ * mutex is already locked, the function returns without blocking.
+ * @param mtx A mutex object.
+ * @return @ref thrd_success on success, or @ref thrd_busy if the resource
+ * requested is already in use, or @ref thrd_error if the request could not be
+ * honored.
+ */
 int mtx_trylock(mtx_t *mtx);
 
 /** Unlock the given mutex.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * @param mtx A mutex object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int mtx_unlock(mtx_t *mtx);
 
 /* Condition variable */
 #if defined(_TTHREAD_WIN32_)
 typedef struct {
-  HANDLE mEvents[2];                  /* Signal and broadcast event HANDLEs. */
-  unsigned int mWaitersCount;         /* Count of the number of waiters. */
-  CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
+    HANDLE           mEvents[2];        /* Signal and broadcast event HANDLEs. */
+    unsigned int     mWaitersCount;     /* Count of the number of waiters. */
+    CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
 } cnd_t;
 #else
-typedef pthread_cond_t cnd_t;
+typedef pthread_cond_t  cnd_t;
 #endif
 
 /** Create a condition variable object.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * @param cond A condition variable object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int cnd_init(cnd_t *cond);
 
 /** Release any resources used by the given condition variable.
-* @param cond A condition variable object.
-*/
+ * @param cond A condition variable object.
+ */
 void cnd_destroy(cnd_t *cond);
 
 /** Signal a condition variable.
-* Unblocks one of the threads that are blocked on the given condition variable
-* at the time of the call. If no threads are blocked on the condition variable
-* at the time of the call, the function does nothing and return success.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * Unblocks one of the threads that are blocked on the given condition variable
+ * at the time of the call. If no threads are blocked on the condition variable
+ * at the time of the call, the function does nothing and return success.
+ * @param cond A condition variable object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int cnd_signal(cnd_t *cond);
 
 /** Broadcast a condition variable.
-* Unblocks all of the threads that are blocked on the given condition variable
-* at the time of the call. If no threads are blocked on the condition variable
-* at the time of the call, the function does nothing and return success.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * Unblocks all of the threads that are blocked on the given condition variable
+ * at the time of the call. If no threads are blocked on the condition variable
+ * at the time of the call, the function does nothing and return success.
+ * @param cond A condition variable object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int cnd_broadcast(cnd_t *cond);
 
 /** Wait for a condition variable to become signaled.
-* The function atomically unlocks the given mutex and endeavors to block until
-* the given condition variable is signaled by a call to cnd_signal or to
-* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex
-* before it returns.
-* @param cond A condition variable object.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * The function atomically unlocks the given mutex and endeavors to block until
+ * the given condition variable is signaled by a call to cnd_signal or to
+ * cnd_broadcast. When the calling thread becomes unblocked it locks the mutex
+ * before it returns.
+ * @param cond A condition variable object.
+ * @param mtx A mutex object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int cnd_wait(cnd_t *cond, mtx_t *mtx);
 
 /** Wait for a condition variable to become signaled.
-* The function atomically unlocks the given mutex and endeavors to block until
-* the given condition variable is signaled by a call to cnd_signal or to
-* cnd_broadcast, or until after the specified time. When the calling thread
-* becomes unblocked it locks the mutex before it returns.
-* @param cond A condition variable object.
-* @param mtx A mutex object.
-* @param xt A point in time at which the request will time out (absolute time).
-* @return @ref thrd_success upon success, or @ref thrd_timeout if the time
-* specified in the call was reached without acquiring the requested resource, or
-* @ref thrd_error if the request could not be honored.
-*/
+ * The function atomically unlocks the given mutex and endeavors to block until
+ * the given condition variable is signaled by a call to cnd_signal or to
+ * cnd_broadcast, or until after the specified time. When the calling thread
+ * becomes unblocked it locks the mutex before it returns.
+ * @param cond A condition variable object.
+ * @param mtx A mutex object.
+ * @param xt A point in time at which the request will time out (absolute time).
+ * @return @ref thrd_success upon success, or @ref thrd_timeout if the time
+ * specified in the call was reached without acquiring the requested resource, or
+ * @ref thrd_error if the request could not be honored.
+ */
 int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
 
 /* Thread */
 #if defined(_TTHREAD_WIN32_)
 typedef HANDLE thrd_t;
 #else
-typedef pthread_t thrd_t;
+typedef pthread_t       thrd_t;
 #endif
 
 /** Thread start function.
-* Any thread that is started with the @ref thrd_create() function must be
-* started through a function of this type.
-* @param arg The thread argument (the @c arg argument of the corresponding
-*        @ref thrd_create() call).
-* @return The thread return value, which can be obtained by another thread
-* by using the @ref thrd_join() function.
-*/
+ * Any thread that is started with the @ref thrd_create() function must be
+ * started through a function of this type.
+ * @param arg The thread argument (the @c arg argument of the corresponding
+ *        @ref thrd_create() call).
+ * @return The thread return value, which can be obtained by another thread
+ * by using the @ref thrd_join() function.
+ */
 typedef int (*thrd_start_t)(void *arg);
 
 /** Create a new thread.
-* @param thr Identifier of the newly created thread.
-* @param func A function pointer to the function that will be executed in
-*        the new thread.
-* @param arg An argument to the thread function.
-* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could
-* be allocated for the thread requested, or @ref thrd_error if the request
-* could not be honored.
-* @note A thread’s identifier may be reused for a different thread once the
-* original thread has exited and either been detached or joined to another
-* thread.
-*/
+ * @param thr Identifier of the newly created thread.
+ * @param func A function pointer to the function that will be executed in
+ *        the new thread.
+ * @param arg An argument to the thread function.
+ * @return @ref thrd_success on success, or @ref thrd_nomem if no memory could
+ * be allocated for the thread requested, or @ref thrd_error if the request
+ * could not be honored.
+ * @note A thread’s identifier may be reused for a different thread once the
+ * original thread has exited and either been detached or joined to another
+ * thread.
+ */
 int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
 
 /** Identify the calling thread.
-* @return The identifier of the calling thread.
-*/
+ * @return The identifier of the calling thread.
+ */
 thrd_t thrd_current(void);
 
 /** NOT YET IMPLEMENTED.
-*/
+ */
 int thrd_detach(thrd_t thr);
 
 /** Compare two thread identifiers.
-* The function determines if two thread identifiers refer to the same thread.
-* @return Zero if the two thread identifiers refer to different threads.
-* Otherwise a nonzero value is returned.
-*/
+ * The function determines if two thread identifiers refer to the same thread.
+ * @return Zero if the two thread identifiers refer to different threads.
+ * Otherwise a nonzero value is returned.
+ */
 int thrd_equal(thrd_t thr0, thrd_t thr1);
 
 /** Terminate execution of the calling thread.
-* @param res Result code of the calling thread.
-*/
+ * @param res Result code of the calling thread.
+ */
 void thrd_exit(int res);
 
 /** Wait for a thread to terminate.
-* The function joins the given thread with the current thread by blocking
-* until the other thread has terminated.
-* @param thr The thread to join with.
-* @param res If this pointer is not NULL, the function will store the result
-*        code of the given thread in the integer pointed to by @c res.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * The function joins the given thread with the current thread by blocking
+ * until the other thread has terminated.
+ * @param thr The thread to join with.
+ * @param res If this pointer is not NULL, the function will store the result
+ *        code of the given thread in the integer pointed to by @c res.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int thrd_join(thrd_t thr, int *res);
 
 /** Put the calling thread to sleep.
-* Suspend execution of the calling thread.
-* @param time_point A point in time at which the thread will resume (absolute time).
-* @param remaining If non-NULL, this parameter will hold the remaining time until
-*                  time_point upon return. This will typically be zero, but if
-*                  the thread was woken up by a signal that is not ignored before
-*                  time_point was reached @c remaining will hold a positive
-*                  time.
-* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
-*/
+ * Suspend execution of the calling thread.
+ * @param time_point A point in time at which the thread will resume (absolute time).
+ * @param remaining If non-NULL, this parameter will hold the remaining time until
+ *                  time_point upon return. This will typically be zero, but if
+ *                  the thread was woken up by a signal that is not ignored before
+ *                  time_point was reached @c remaining will hold a positive
+ *                  time.
+ * @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
+ */
 int thrd_sleep(const struct timespec *time_point, struct timespec *remaining);
 
 /** Yield execution to another thread.
-* Permit other threads to run, even if the current thread would ordinarily
-* continue to run.
-*/
+ * Permit other threads to run, even if the current thread would ordinarily
+ * continue to run.
+ */
 void thrd_yield(void);
 
 /* Thread local storage */
 #if defined(_TTHREAD_WIN32_)
 typedef DWORD tss_t;
 #else
-typedef pthread_key_t tss_t;
+typedef pthread_key_t   tss_t;
 #endif
 
 /** Destructor function for a thread-specific storage.
-* @param val The value of the destructed thread-specific storage.
-*/
+ * @param val The value of the destructed thread-specific storage.
+ */
 typedef void (*tss_dtor_t)(void *val);
 
 /** Create a thread-specific storage.
-* @param key The unique key identifier that will be set if the function is
-*        successful.
-* @param dtor Destructor function. This can be NULL.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-* @note The destructor function is not supported under Windows. If @c dtor is
-* not NULL when calling this function under Windows, the function will fail
-* and return @ref thrd_error.
-*/
+ * @param key The unique key identifier that will be set if the function is
+ *        successful.
+ * @param dtor Destructor function. This can be NULL.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ * @note The destructor function is not supported under Windows. If @c dtor is
+ * not NULL when calling this function under Windows, the function will fail
+ * and return @ref thrd_error.
+ */
 int tss_create(tss_t *key, tss_dtor_t dtor);
 
 /** Delete a thread-specific storage.
-* The function releases any resources used by the given thread-specific
-* storage.
-* @param key The key that shall be deleted.
-*/
+ * The function releases any resources used by the given thread-specific
+ * storage.
+ * @param key The key that shall be deleted.
+ */
 void tss_delete(tss_t key);
 
 /** Get the value for a thread-specific storage.
-* @param key The thread-specific storage identifier.
-* @return The value for the current thread held in the given thread-specific
-* storage.
-*/
+ * @param key The thread-specific storage identifier.
+ * @return The value for the current thread held in the given thread-specific
+ * storage.
+ */
 void *tss_get(tss_t key);
 
 /** Set the value for a thread-specific storage.
-* @param key The thread-specific storage identifier.
-* @param val The value of the thread-specific storage to set for the current
-*        thread.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * @param key The thread-specific storage identifier.
+ * @param val The value of the thread-specific storage to set for the current
+ *        thread.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int tss_set(tss_t key, void *val);
 
-
 #endif /* _TINYTHREAD_H_ */
-
index 809bc87bff15cee8fc074088fc8b51172ef6c48b..5f6951bf7fd9cb102f02c8e48847f8f12eb93c23 100644 (file)
@@ -27,7 +27,6 @@
  *
  */
 
-
 #ifndef NANOSVG_H
 #define NANOSVG_H
 
@@ -54,128 +53,107 @@ extern "C" {
 //
 // If you don't know or care about the units stuff, "px" and 96 should get you going.
 
-
 /* Example Usage:
-       // Load SVG
-       NSVGimage* image;
-       image = nsvgParseFromFile("test.svg", "px", 96);
-       printf("size: %f x %f\n", image->width, image->height);
-       // Use...
-       for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
-               for (NSVGpath *path = shape->paths; path != NULL; path = path->next) {
-                       for (int i = 0; i < path->npts-1; i += 3) {
-                               float* p = &path->pts[i*2];
-                               drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]);
-                       }
-               }
-       }
-       // Delete
-       nsvgDelete(image);
+    // Load SVG
+    NSVGimage* image;
+    image = nsvgParseFromFile("test.svg", "px", 96);
+    printf("size: %f x %f\n", image->width, image->height);
+    // Use...
+    for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
+        for (NSVGpath *path = shape->paths; path != NULL; path = path->next) {
+            for (int i = 0; i < path->npts-1; i += 3) {
+                float* p = &path->pts[i*2];
+                drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]);
+            }
+        }
+    }
+    // Delete
+    nsvgDelete(image);
 */
 
 enum NSVGpaintType {
-       NSVG_PAINT_NONE = 0,
-       NSVG_PAINT_COLOR = 1,
-       NSVG_PAINT_LINEAR_GRADIENT = 2,
-       NSVG_PAINT_RADIAL_GRADIENT = 3
+    NSVG_PAINT_NONE            = 0,
+    NSVG_PAINT_COLOR           = 1,
+    NSVG_PAINT_LINEAR_GRADIENT = 2,
+    NSVG_PAINT_RADIAL_GRADIENT = 3
 };
 
-enum NSVGspreadType {
-       NSVG_SPREAD_PAD = 0,
-       NSVG_SPREAD_REFLECT = 1,
-       NSVG_SPREAD_REPEAT = 2
-};
+enum NSVGspreadType { NSVG_SPREAD_PAD = 0, NSVG_SPREAD_REFLECT = 1, NSVG_SPREAD_REPEAT = 2 };
 
-enum NSVGlineJoin {
-       NSVG_JOIN_MITER = 0,
-       NSVG_JOIN_ROUND = 1,
-       NSVG_JOIN_BEVEL = 2
-};
+enum NSVGlineJoin { NSVG_JOIN_MITER = 0, NSVG_JOIN_ROUND = 1, NSVG_JOIN_BEVEL = 2 };
 
-enum NSVGlineCap {
-       NSVG_CAP_BUTT = 0,
-       NSVG_CAP_ROUND = 1,
-       NSVG_CAP_SQUARE = 2
-};
+enum NSVGlineCap { NSVG_CAP_BUTT = 0, NSVG_CAP_ROUND = 1, NSVG_CAP_SQUARE = 2 };
 
-enum NSVGfillRule {
-       NSVG_FILLRULE_NONZERO = 0,
-       NSVG_FILLRULE_EVENODD = 1
-};
+enum NSVGfillRule { NSVG_FILLRULE_NONZERO = 0, NSVG_FILLRULE_EVENODD = 1 };
 
-enum NSVGflags {
-       NSVG_FLAGS_VISIBLE = 0x01
-};
+enum NSVGflags { NSVG_FLAGS_VISIBLE = 0x01 };
 
 typedef struct NSVGgradientStop {
-       unsigned int color;
-       float offset;
+    unsigned int color;
+    float        offset;
 } NSVGgradientStop;
 
 typedef struct NSVGgradient {
-       float xform[6];
-       char spread;
-       float fx, fy;
-       int nstops;
-       NSVGgradientStop stops[1];
+    float            xform[6];
+    char             spread;
+    float            fx, fy;
+    int              nstops;
+    NSVGgradientStop stops[1];
 } NSVGgradient;
 
 typedef struct NSVGpaint {
-       char type;
-       union {
-               unsigned int color;
-               NSVGgradient* gradient;
-       };
+    char type;
+    union {
+        unsigned int  color;
+        NSVGgradient *gradient;
+    };
 } NSVGpaint;
 
-typedef struct NSVGpath
-{
-       float* pts;                                     // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ...
-       int npts;                                       // Total number of bezier points.
-       char closed;                            // Flag indicating if shapes should be treated as closed.
-       float bounds[4];                        // Tight bounding box of the shape [minx,miny,maxx,maxy].
-       struct NSVGpath* next;          // Pointer to next path, or NULL if last element.
+typedef struct NSVGpath {
+    float           *pts;       // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ...
+    int              npts;      // Total number of bezier points.
+    char             closed;    // Flag indicating if shapes should be treated as closed.
+    float            bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy].
+    struct NSVGpath *next;      // Pointer to next path, or NULL if last element.
 } NSVGpath;
 
-typedef struct NSVGshape
-{
-       char id[64];                            // Optional 'id' attr of the shape or its group
-       NSVGpaint fill;                         // Fill paint
-       NSVGpaint stroke;                       // Stroke paint
-       float opacity;                          // Opacity of the shape.
-       float strokeWidth;                      // Stroke width (scaled).
-       float strokeDashOffset;         // Stroke dash offset (scaled).
-       float strokeDashArray[8];                       // Stroke dash array (scaled).
-       char strokeDashCount;                           // Number of dash values in dash array.
-       char strokeLineJoin;            // Stroke join type.
-       char strokeLineCap;                     // Stroke cap type.
-       float miterLimit;                       // Miter limit
-       char fillRule;                          // Fill rule, see NSVGfillRule.
-       unsigned char flags;            // Logical or of NSVG_FLAGS_* flags
-       float bounds[4];                        // Tight bounding box of the shape [minx,miny,maxx,maxy].
-       NSVGpath* paths;                        // Linked list of paths in the image.
-       struct NSVGshape* next;         // Pointer to next shape, or NULL if last element.
+typedef struct NSVGshape {
+    char              id[64];             // Optional 'id' attr of the shape or its group
+    NSVGpaint         fill;               // Fill paint
+    NSVGpaint         stroke;             // Stroke paint
+    float             opacity;            // Opacity of the shape.
+    float             strokeWidth;        // Stroke width (scaled).
+    float             strokeDashOffset;   // Stroke dash offset (scaled).
+    float             strokeDashArray[8]; // Stroke dash array (scaled).
+    char              strokeDashCount;    // Number of dash values in dash array.
+    char              strokeLineJoin;     // Stroke join type.
+    char              strokeLineCap;      // Stroke cap type.
+    float             miterLimit;         // Miter limit
+    char              fillRule;           // Fill rule, see NSVGfillRule.
+    unsigned char     flags;              // Logical or of NSVG_FLAGS_* flags
+    float             bounds[4];          // Tight bounding box of the shape [minx,miny,maxx,maxy].
+    NSVGpath         *paths;              // Linked list of paths in the image.
+    struct NSVGshape *next;               // Pointer to next shape, or NULL if last element.
 } NSVGshape;
 
-typedef struct NSVGimage
-{
-       float width;                            // Width of the image.
-       float height;                           // Height of the image.
-       NSVGshape* shapes;                      // Linked list of shapes in the image.
+typedef struct NSVGimage {
+    float      width;  // Width of the image.
+    float      height; // Height of the image.
+    NSVGshape *shapes; // Linked list of shapes in the image.
 } NSVGimage;
 
 // Parses SVG file from a file, returns SVG image as paths.
-NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi);
+NSVGimage *nsvgParseFromFile(const char *filename, const char *units, float dpi);
 
 // Parses SVG file from a null terminated string, returns SVG image as paths.
 // Important note: changes the string.
-NSVGimage* nsvgParse(char* input, const char* units, float dpi);
+NSVGimage *nsvgParse(char *input, const char *units, float dpi);
 
 // Duplicates a path.
-NSVGpath* nsvgDuplicatePath(NSVGpath* p);
+NSVGpath *nsvgDuplicatePath(NSVGpath *p);
 
 // Deletes an image.
-void nsvgDelete(NSVGimageimage);
+void nsvgDelete(NSVGimage *image);
 
 #ifndef NANOSVG_CPLUSPLUS
 #ifdef __cplusplus
@@ -191,2817 +169,2827 @@ void nsvgDelete(NSVGimage* image);
 #include <stdlib.h>
 #include <math.h>
 
-#define NSVG_PI (3.14159265358979323846264338327f)
-#define NSVG_KAPPA90 (0.5522847493f)   // Length proportional to radius of a cubic bezier handle for 90deg arcs.
+#define NSVG_PI          (3.14159265358979323846264338327f)
+#define NSVG_KAPPA90     (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs.
 
-#define NSVG_ALIGN_MIN 0
-#define NSVG_ALIGN_MID 1
-#define NSVG_ALIGN_MAX 2
-#define NSVG_ALIGN_NONE 0
-#define NSVG_ALIGN_MEET 1
+#define NSVG_ALIGN_MIN   0
+#define NSVG_ALIGN_MID   1
+#define NSVG_ALIGN_MAX   2
+#define NSVG_ALIGN_NONE  0
+#define NSVG_ALIGN_MEET  1
 #define NSVG_ALIGN_SLICE 2
 
-#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
+#define NSVG_NOTUSED(v)                                                                                                \
+    do {                                                                                                               \
+        (void)(1 ? (void)0 : ((void)(v)));                                                                             \
+    } while (0)
 #define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))
 
 #ifdef _MSC_VER
-       #pragma warning (disable: 4996) // Switch off security warnings
-       #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
-       #ifdef __cplusplus
-       #define NSVG_INLINE inline
-       #else
-       #define NSVG_INLINE
-       #endif
+#pragma warning(disable : 4996) // Switch off security warnings
+#pragma warning(disable : 4100) // Switch off unreferenced formal parameter warnings
+#ifdef __cplusplus
+#define NSVG_INLINE inline
+#else
+#define NSVG_INLINE
+#endif
 #else
-       #define NSVG_INLINE inline
+#define NSVG_INLINE inline
 #endif
 
 #ifndef NANOSVG_DEBUG
 #define NANOSVG_DEBUG(...)
-//#define NANOSVG_DEBUG printf
+// #define NANOSVG_DEBUG printf
 #endif
 
-static int nsvg__isspace(char c)
-{
-       return strchr(" \t\n\v\f\r", c) != 0;
-}
+static int nsvg__isspace(char c) { return strchr(" \t\n\v\f\r", c) != 0; }
 
-static int nsvg__isdigit(char c)
-{
-       return c >= '0' && c <= '9';
-}
+static int nsvg__isdigit(char c) { return c >= '0' && c <= '9'; }
 
-static int nsvg__isnum(char c)
-{
-       return strchr("0123456789+-.eE", c) != 0;
-}
+static int nsvg__isnum(char c) { return strchr("0123456789+-.eE", c) != 0; }
 
 static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
 static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }
 
-
 // Simple XML parser
 
-#define NSVG_XML_TAG 1
-#define NSVG_XML_CONTENT 2
+#define NSVG_XML_TAG         1
+#define NSVG_XML_CONTENT     2
 #define NSVG_XML_MAX_ATTRIBS 256
 
-static void nsvg__parseContent(char* s,
-                                                          void (*contentCb)(void* ud, const char* s),
-                                                          void* ud)
-{
-       // Trim start white spaces
-       while (nsvg__isspace(*s)) s++;
-       if (!*s) return;
-
-       if (contentCb)
-               (*contentCb)(ud, s);
-}
-
-static void nsvg__parseElement(char* s,
-                                                          void (*startelCb)(void* ud, const char* el, const char** attr),
-                                                          void (*endelCb)(void* ud, const char* el),
-                                                          void* ud)
-{
-       const char* attr[NSVG_XML_MAX_ATTRIBS];
-       int nattr = 0;
-       char* name;
-       int start = 0;
-       int end = 0;
-       char quote;
-
-       // Skip white space after the '<'
-       while (nsvg__isspace(*s)) s++;
-
-       // Check if the tag is end tag
-       if (*s == '/') {
-               s++;
-               end = 1;
-       } else {
-               start = 1;
-       }
-
-       // Skip comments, data and preprocessor stuff.
-       if (!*s || *s == '?' || *s == '!')
-               return;
-
-       // Get tag name
-       name = s;
-       while (*s && !nsvg__isspace(*s)) s++;
-       if (*s) { *s++ = '\0'; }
-
-       // Get attribs
-       while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) {
-               char* name = NULL;
-               char* value = NULL;
-
-               // Skip white space before the attrib name
-               while (nsvg__isspace(*s)) s++;
-               if (!*s) break;
-               if (*s == '/') {
-                       end = 1;
-                       break;
-               }
-               name = s;
-               // Find end of the attrib name.
-               while (*s && !nsvg__isspace(*s) && *s != '=') s++;
-               if (*s) { *s++ = '\0'; }
-               // Skip until the beginning of the value.
-               while (*s && *s != '\"' && *s != '\'') s++;
-               if (!*s) break;
-               quote = *s;
-               s++;
-               // Store value and find the end of it.
-               value = s;
-               while (*s && *s != quote) s++;
-               if (*s) { *s++ = '\0'; }
-
-               // Store only well formed attributes
-               if (name && value) {
-                       attr[nattr++] = name;
-                       attr[nattr++] = value;
-               }
-       }
-
-       // List terminator
-       attr[nattr++] = 0;
-       attr[nattr++] = 0;
-
-       // Call callbacks.
-       if (start && startelCb)
-               (*startelCb)(ud, name, attr);
-       if (end && endelCb)
-               (*endelCb)(ud, name);
-}
-
-int nsvg__parseXML(char* input,
-                                  void (*startelCb)(void* ud, const char* el, const char** attr),
-                                  void (*endelCb)(void* ud, const char* el),
-                                  void (*contentCb)(void* ud, const char* s),
-                                  void* ud)
-{
-       char* s = input;
-       char* mark = s;
-       int state = NSVG_XML_CONTENT;
-       while (*s) {
-               if (*s == '<' && state == NSVG_XML_CONTENT) {
-                       // Start of a tag
-                       *s++ = '\0';
-                       nsvg__parseContent(mark, contentCb, ud);
-                       mark = s;
-                       state = NSVG_XML_TAG;
-               } else if (*s == '>' && state == NSVG_XML_TAG) {
-                       // Start of a content or new tag.
-                       *s++ = '\0';
-                       nsvg__parseElement(mark, startelCb, endelCb, ud);
-                       mark = s;
-                       state = NSVG_XML_CONTENT;
-               } else {
-                       s++;
-               }
-       }
-
-       return 1;
+static void nsvg__parseContent(char *s, void (*contentCb)(void *ud, const char *s), void *ud) {
+    // Trim start white spaces
+    while (nsvg__isspace(*s))
+        s++;
+    if (!*s)
+        return;
+
+    if (contentCb)
+        (*contentCb)(ud, s);
+}
+
+static void nsvg__parseElement(char *s, void (*startelCb)(void *ud, const char *el, const char **attr),
+                               void (*endelCb)(void *ud, const char *el), void *ud) {
+    const char *attr[NSVG_XML_MAX_ATTRIBS];
+    int         nattr = 0;
+    char       *name;
+    int         start = 0;
+    int         end   = 0;
+    char        quote;
+
+    // Skip white space after the '<'
+    while (nsvg__isspace(*s))
+        s++;
+
+    // Check if the tag is end tag
+    if (*s == '/') {
+        s++;
+        end = 1;
+    } else {
+        start = 1;
+    }
+
+    // Skip comments, data and preprocessor stuff.
+    if (!*s || *s == '?' || *s == '!')
+        return;
+
+    // Get tag name
+    name = s;
+    while (*s && !nsvg__isspace(*s))
+        s++;
+    if (*s) {
+        *s++ = '\0';
+    }
+
+    // Get attribs
+    while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS - 3) {
+        char *name  = NULL;
+        char *value = NULL;
+
+        // Skip white space before the attrib name
+        while (nsvg__isspace(*s))
+            s++;
+        if (!*s)
+            break;
+        if (*s == '/') {
+            end = 1;
+            break;
+        }
+        name = s;
+        // Find end of the attrib name.
+        while (*s && !nsvg__isspace(*s) && *s != '=')
+            s++;
+        if (*s) {
+            *s++ = '\0';
+        }
+        // Skip until the beginning of the value.
+        while (*s && *s != '\"' && *s != '\'')
+            s++;
+        if (!*s)
+            break;
+        quote = *s;
+        s++;
+        // Store value and find the end of it.
+        value = s;
+        while (*s && *s != quote)
+            s++;
+        if (*s) {
+            *s++ = '\0';
+        }
+
+        // Store only well formed attributes
+        if (name && value) {
+            attr[nattr++] = name;
+            attr[nattr++] = value;
+        }
+    }
+
+    // List terminator
+    attr[nattr++] = 0;
+    attr[nattr++] = 0;
+
+    // Call callbacks.
+    if (start && startelCb)
+        (*startelCb)(ud, name, attr);
+    if (end && endelCb)
+        (*endelCb)(ud, name);
+}
+
+int nsvg__parseXML(char *input, void (*startelCb)(void *ud, const char *el, const char **attr),
+                   void (*endelCb)(void *ud, const char *el), void (*contentCb)(void *ud, const char *s), void *ud) {
+    char *s     = input;
+    char *mark  = s;
+    int   state = NSVG_XML_CONTENT;
+    while (*s) {
+        if (*s == '<' && state == NSVG_XML_CONTENT) {
+            // Start of a tag
+            *s++ = '\0';
+            nsvg__parseContent(mark, contentCb, ud);
+            mark  = s;
+            state = NSVG_XML_TAG;
+        } else if (*s == '>' && state == NSVG_XML_TAG) {
+            // Start of a content or new tag.
+            *s++ = '\0';
+            nsvg__parseElement(mark, startelCb, endelCb, ud);
+            mark  = s;
+            state = NSVG_XML_CONTENT;
+        } else {
+            s++;
+        }
+    }
+
+    return 1;
 }
 
-
 /* Simple SVG parser. */
 
 #define NSVG_MAX_ATTR 128
 
-enum NSVGgradientUnits {
-       NSVG_USER_SPACE = 0,
-       NSVG_OBJECT_SPACE = 1
-};
+enum NSVGgradientUnits { NSVG_USER_SPACE = 0, NSVG_OBJECT_SPACE = 1 };
 
 #define NSVG_MAX_DASHES 8
 
 enum NSVGunits {
-       NSVG_UNITS_USER,
-       NSVG_UNITS_PX,
-       NSVG_UNITS_PT,
-       NSVG_UNITS_PC,
-       NSVG_UNITS_MM,
-       NSVG_UNITS_CM,
-       NSVG_UNITS_IN,
-       NSVG_UNITS_PERCENT,
-       NSVG_UNITS_EM,
-       NSVG_UNITS_EX
+    NSVG_UNITS_USER,
+    NSVG_UNITS_PX,
+    NSVG_UNITS_PT,
+    NSVG_UNITS_PC,
+    NSVG_UNITS_MM,
+    NSVG_UNITS_CM,
+    NSVG_UNITS_IN,
+    NSVG_UNITS_PERCENT,
+    NSVG_UNITS_EM,
+    NSVG_UNITS_EX
 };
 
 typedef struct NSVGcoordinate {
-       float value;
-       int units;
+    float value;
+    int   units;
 } NSVGcoordinate;
 
 typedef struct NSVGlinearData {
-       NSVGcoordinate x1, y1, x2, y2;
+    NSVGcoordinate x1, y1, x2, y2;
 } NSVGlinearData;
 
 typedef struct NSVGradialData {
-       NSVGcoordinate cx, cy, r, fx, fy;
+    NSVGcoordinate cx, cy, r, fx, fy;
 } NSVGradialData;
 
-typedef struct NSVGgradientData
-{
-       char id[64];
-       char ref[64];
-       char type;
-       union {
-               NSVGlinearData linear;
-               NSVGradialData radial;
-       };
-       char spread;
-       char units;
-       float xform[6];
-       int nstops;
-       NSVGgradientStop* stops;
-       struct NSVGgradientData* next;
+typedef struct NSVGgradientData {
+    char id[64];
+    char ref[64];
+    char type;
+    union {
+        NSVGlinearData linear;
+        NSVGradialData radial;
+    };
+    char                     spread;
+    char                     units;
+    float                    xform[6];
+    int                      nstops;
+    NSVGgradientStop        *stops;
+    struct NSVGgradientData *next;
 } NSVGgradientData;
 
-typedef struct NSVGattrib
-{
-       char id[64];
-       float xform[6];
-       unsigned int fillColor;
-       unsigned int strokeColor;
-       float opacity;
-       float fillOpacity;
-       float strokeOpacity;
-       char fillGradient[64];
-       char strokeGradient[64];
-       float strokeWidth;
-       float strokeDashOffset;
-       float strokeDashArray[NSVG_MAX_DASHES];
-       int strokeDashCount;
-       char strokeLineJoin;
-       char strokeLineCap;
-       float miterLimit;
-       char fillRule;
-       float fontSize;
-       unsigned int stopColor;
-       float stopOpacity;
-       float stopOffset;
-       char hasFill;
-       char hasStroke;
-       char visible;
+typedef struct NSVGattrib {
+    char         id[64];
+    float        xform[6];
+    unsigned int fillColor;
+    unsigned int strokeColor;
+    float        opacity;
+    float        fillOpacity;
+    float        strokeOpacity;
+    char         fillGradient[64];
+    char         strokeGradient[64];
+    float        strokeWidth;
+    float        strokeDashOffset;
+    float        strokeDashArray[NSVG_MAX_DASHES];
+    int          strokeDashCount;
+    char         strokeLineJoin;
+    char         strokeLineCap;
+    float        miterLimit;
+    char         fillRule;
+    float        fontSize;
+    unsigned int stopColor;
+    float        stopOpacity;
+    float        stopOffset;
+    char         hasFill;
+    char         hasStroke;
+    char         visible;
 } NSVGattrib;
 
-typedef struct NSVGparser
-{
-       NSVGattrib attr[NSVG_MAX_ATTR];
-       int attrHead;
-       float* pts;
-       int npts;
-       int cpts;
-       NSVGpath* plist;
-       NSVGimage* image;
-       NSVGgradientData* gradients;
-       NSVGshape* shapesTail;
-       float viewMinx, viewMiny, viewWidth, viewHeight;
-       int alignX, alignY, alignType;
-       float dpi;
-       char pathFlag;
-       char defsFlag;
+typedef struct NSVGparser {
+    NSVGattrib        attr[NSVG_MAX_ATTR];
+    int               attrHead;
+    float            *pts;
+    int               npts;
+    int               cpts;
+    NSVGpath         *plist;
+    NSVGimage        *image;
+    NSVGgradientData *gradients;
+    NSVGshape        *shapesTail;
+    float             viewMinx, viewMiny, viewWidth, viewHeight;
+    int               alignX, alignY, alignType;
+    float             dpi;
+    char              pathFlag;
+    char              defsFlag;
 } NSVGparser;
 
-static void nsvg__xformIdentity(float* t)
-{
-       t[0] = 1.0f; t[1] = 0.0f;
-       t[2] = 0.0f; t[3] = 1.0f;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformSetTranslation(float* t, float tx, float ty)
-{
-       t[0] = 1.0f; t[1] = 0.0f;
-       t[2] = 0.0f; t[3] = 1.0f;
-       t[4] = tx; t[5] = ty;
-}
-
-static void nsvg__xformSetScale(float* t, float sx, float sy)
-{
-       t[0] = sx; t[1] = 0.0f;
-       t[2] = 0.0f; t[3] = sy;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformSetSkewX(float* t, float a)
-{
-       t[0] = 1.0f; t[1] = 0.0f;
-       t[2] = tanf(a); t[3] = 1.0f;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformSetSkewY(float* t, float a)
-{
-       t[0] = 1.0f; t[1] = tanf(a);
-       t[2] = 0.0f; t[3] = 1.0f;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformSetRotation(float* t, float a)
-{
-       float cs = cosf(a), sn = sinf(a);
-       t[0] = cs; t[1] = sn;
-       t[2] = -sn; t[3] = cs;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformMultiply(float* t, float* s)
-{
-       float t0 = t[0] * s[0] + t[1] * s[2];
-       float t2 = t[2] * s[0] + t[3] * s[2];
-       float t4 = t[4] * s[0] + t[5] * s[2] + s[4];
-       t[1] = t[0] * s[1] + t[1] * s[3];
-       t[3] = t[2] * s[1] + t[3] * s[3];
-       t[5] = t[4] * s[1] + t[5] * s[3] + s[5];
-       t[0] = t0;
-       t[2] = t2;
-       t[4] = t4;
-}
-
-static void nsvg__xformInverse(float* inv, float* t)
-{
-       double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1];
-       if (det > -1e-6 && det < 1e-6) {
-               nsvg__xformIdentity(t);
-               return;
-       }
-       invdet = 1.0 / det;
-       inv[0] = (float)(t[3] * invdet);
-       inv[2] = (float)(-t[2] * invdet);
-       inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet);
-       inv[1] = (float)(-t[1] * invdet);
-       inv[3] = (float)(t[0] * invdet);
-       inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet);
-}
-
-static void nsvg__xformPremultiply(float* t, float* s)
-{
-       float s2[6];
-       memcpy(s2, s, sizeof(float)*6);
-       nsvg__xformMultiply(s2, t);
-       memcpy(t, s2, sizeof(float)*6);
-}
-
-static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t)
-{
-       *dx = x*t[0] + y*t[2] + t[4];
-       *dy = x*t[1] + y*t[3] + t[5];
-}
-
-static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t)
-{
-       *dx = x*t[0] + y*t[2];
-       *dy = x*t[1] + y*t[3];
+static void nsvg__xformIdentity(float *t) {
+    t[0] = 1.0f;
+    t[1] = 0.0f;
+    t[2] = 0.0f;
+    t[3] = 1.0f;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformSetTranslation(float *t, float tx, float ty) {
+    t[0] = 1.0f;
+    t[1] = 0.0f;
+    t[2] = 0.0f;
+    t[3] = 1.0f;
+    t[4] = tx;
+    t[5] = ty;
+}
+
+static void nsvg__xformSetScale(float *t, float sx, float sy) {
+    t[0] = sx;
+    t[1] = 0.0f;
+    t[2] = 0.0f;
+    t[3] = sy;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformSetSkewX(float *t, float a) {
+    t[0] = 1.0f;
+    t[1] = 0.0f;
+    t[2] = tanf(a);
+    t[3] = 1.0f;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformSetSkewY(float *t, float a) {
+    t[0] = 1.0f;
+    t[1] = tanf(a);
+    t[2] = 0.0f;
+    t[3] = 1.0f;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformSetRotation(float *t, float a) {
+    float cs = cosf(a), sn = sinf(a);
+    t[0] = cs;
+    t[1] = sn;
+    t[2] = -sn;
+    t[3] = cs;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformMultiply(float *t, float *s) {
+    float t0 = t[0] * s[0] + t[1] * s[2];
+    float t2 = t[2] * s[0] + t[3] * s[2];
+    float t4 = t[4] * s[0] + t[5] * s[2] + s[4];
+    t[1]     = t[0] * s[1] + t[1] * s[3];
+    t[3]     = t[2] * s[1] + t[3] * s[3];
+    t[5]     = t[4] * s[1] + t[5] * s[3] + s[5];
+    t[0]     = t0;
+    t[2]     = t2;
+    t[4]     = t4;
+}
+
+static void nsvg__xformInverse(float *inv, float *t) {
+    double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1];
+    if (det > -1e-6 && det < 1e-6) {
+        nsvg__xformIdentity(t);
+        return;
+    }
+    invdet = 1.0 / det;
+    inv[0] = (float)(t[3] * invdet);
+    inv[2] = (float)(-t[2] * invdet);
+    inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet);
+    inv[1] = (float)(-t[1] * invdet);
+    inv[3] = (float)(t[0] * invdet);
+    inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet);
+}
+
+static void nsvg__xformPremultiply(float *t, float *s) {
+    float s2[6];
+    memcpy(s2, s, sizeof(float) * 6);
+    nsvg__xformMultiply(s2, t);
+    memcpy(t, s2, sizeof(float) * 6);
+}
+
+static void nsvg__xformPoint(float *dx, float *dy, float x, float y, float *t) {
+    *dx = x * t[0] + y * t[2] + t[4];
+    *dy = x * t[1] + y * t[3] + t[5];
+}
+
+static void nsvg__xformVec(float *dx, float *dy, float x, float y, float *t) {
+    *dx = x * t[0] + y * t[2];
+    *dy = x * t[1] + y * t[3];
 }
 
 #define NSVG_EPSILON (1e-12)
 
-static int nsvg__ptInBounds(float* pt, float* bounds)
-{
-       return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3];
-}
-
-
-static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3)
-{
-       double it = 1.0-t;
-       return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3;
-}
-
-static void nsvg__curveBounds(float* bounds, float* curve)
-{
-       int i, j, count;
-       double roots[2], a, b, c, b2ac, t, v;
-       float* v0 = &curve[0];
-       float* v1 = &curve[2];
-       float* v2 = &curve[4];
-       float* v3 = &curve[6];
-
-       // Start the bounding box by end points
-       bounds[0] = nsvg__minf(v0[0], v3[0]);
-       bounds[1] = nsvg__minf(v0[1], v3[1]);
-       bounds[2] = nsvg__maxf(v0[0], v3[0]);
-       bounds[3] = nsvg__maxf(v0[1], v3[1]);
-
-       // Bezier curve fits inside the convex hull of it's control points.
-       // If control points are inside the bounds, we're done.
-       if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
-               return;
-
-       // Add bezier curve inflection points in X and Y.
-       for (i = 0; i < 2; i++) {
-               a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
-               b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
-               c = 3.0 * v1[i] - 3.0 * v0[i];
-               count = 0;
-               if (fabs(a) < NSVG_EPSILON) {
-                       if (fabs(b) > NSVG_EPSILON) {
-                               t = -c / b;
-                               if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
-                                       roots[count++] = t;
-                       }
-               } else {
-                       b2ac = b*b - 4.0*c*a;
-                       if (b2ac > NSVG_EPSILON) {
-                               t = (-b + sqrt(b2ac)) / (2.0 * a);
-                               if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
-                                       roots[count++] = t;
-                               t = (-b - sqrt(b2ac)) / (2.0 * a);
-                               if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
-                                       roots[count++] = t;
-                       }
-               }
-               for (j = 0; j < count; j++) {
-                       v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]);
-                       bounds[0+i] = nsvg__minf(bounds[0+i], (float)v);
-                       bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v);
-               }
-       }
-}
-
-static NSVGparser* nsvg__createParser()
-{
-       NSVGparser* p;
-       p = (NSVGparser*)malloc(sizeof(NSVGparser));
-       if (p == NULL) goto error;
-       memset(p, 0, sizeof(NSVGparser));
-
-       p->image = (NSVGimage*)malloc(sizeof(NSVGimage));
-       if (p->image == NULL) goto error;
-       memset(p->image, 0, sizeof(NSVGimage));
-
-       // Init style
-       nsvg__xformIdentity(p->attr[0].xform);
-       memset(p->attr[0].id, 0, sizeof p->attr[0].id);
-       p->attr[0].fillColor = NSVG_RGB(0,0,0);
-       p->attr[0].strokeColor = NSVG_RGB(0,0,0);
-       p->attr[0].opacity = 1;
-       p->attr[0].fillOpacity = 1;
-       p->attr[0].strokeOpacity = 1;
-       p->attr[0].stopOpacity = 1;
-       p->attr[0].strokeWidth = 1;
-       p->attr[0].strokeLineJoin = NSVG_JOIN_MITER;
-       p->attr[0].strokeLineCap = NSVG_CAP_BUTT;
-       p->attr[0].miterLimit = 4;
-       p->attr[0].fillRule = NSVG_FILLRULE_NONZERO;
-       p->attr[0].hasFill = 1;
-       p->attr[0].visible = 1;
-
-       return p;
+static int nsvg__ptInBounds(float *pt, float *bounds) {
+    return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3];
+}
+
+static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3) {
+    double it = 1.0 - t;
+    return it * it * it * p0 + 3.0 * it * it * t * p1 + 3.0 * it * t * t * p2 + t * t * t * p3;
+}
+
+static void nsvg__curveBounds(float *bounds, float *curve) {
+    int    i, j, count;
+    double roots[2], a, b, c, b2ac, t, v;
+    float *v0 = &curve[0];
+    float *v1 = &curve[2];
+    float *v2 = &curve[4];
+    float *v3 = &curve[6];
+
+    // Start the bounding box by end points
+    bounds[0] = nsvg__minf(v0[0], v3[0]);
+    bounds[1] = nsvg__minf(v0[1], v3[1]);
+    bounds[2] = nsvg__maxf(v0[0], v3[0]);
+    bounds[3] = nsvg__maxf(v0[1], v3[1]);
+
+    // Bezier curve fits inside the convex hull of it's control points.
+    // If control points are inside the bounds, we're done.
+    if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
+        return;
+
+    // Add bezier curve inflection points in X and Y.
+    for (i = 0; i < 2; i++) {
+        a     = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
+        b     = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
+        c     = 3.0 * v1[i] - 3.0 * v0[i];
+        count = 0;
+        if (fabs(a) < NSVG_EPSILON) {
+            if (fabs(b) > NSVG_EPSILON) {
+                t = -c / b;
+                if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON)
+                    roots[count++] = t;
+            }
+        } else {
+            b2ac = b * b - 4.0 * c * a;
+            if (b2ac > NSVG_EPSILON) {
+                t = (-b + sqrt(b2ac)) / (2.0 * a);
+                if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON)
+                    roots[count++] = t;
+                t = (-b - sqrt(b2ac)) / (2.0 * a);
+                if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON)
+                    roots[count++] = t;
+            }
+        }
+        for (j = 0; j < count; j++) {
+            v             = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]);
+            bounds[0 + i] = nsvg__minf(bounds[0 + i], (float)v);
+            bounds[2 + i] = nsvg__maxf(bounds[2 + i], (float)v);
+        }
+    }
+}
+
+static NSVGparser *nsvg__createParser() {
+    NSVGparser *p;
+    p = (NSVGparser *)malloc(sizeof(NSVGparser));
+    if (p == NULL)
+        goto error;
+    memset(p, 0, sizeof(NSVGparser));
+
+    p->image = (NSVGimage *)malloc(sizeof(NSVGimage));
+    if (p->image == NULL)
+        goto error;
+    memset(p->image, 0, sizeof(NSVGimage));
+
+    // Init style
+    nsvg__xformIdentity(p->attr[0].xform);
+    memset(p->attr[0].id, 0, sizeof p->attr[0].id);
+    p->attr[0].fillColor      = NSVG_RGB(0, 0, 0);
+    p->attr[0].strokeColor    = NSVG_RGB(0, 0, 0);
+    p->attr[0].opacity        = 1;
+    p->attr[0].fillOpacity    = 1;
+    p->attr[0].strokeOpacity  = 1;
+    p->attr[0].stopOpacity    = 1;
+    p->attr[0].strokeWidth    = 1;
+    p->attr[0].strokeLineJoin = NSVG_JOIN_MITER;
+    p->attr[0].strokeLineCap  = NSVG_CAP_BUTT;
+    p->attr[0].miterLimit     = 4;
+    p->attr[0].fillRule       = NSVG_FILLRULE_NONZERO;
+    p->attr[0].hasFill        = 1;
+    p->attr[0].visible        = 1;
+
+    return p;
 
 error:
-       if (p) {
-               if (p->image) free(p->image);
-               free(p);
-       }
-       return NULL;
-}
-
-static void nsvg__deletePaths(NSVGpath* path)
-{
-       while (path) {
-               NSVGpath *next = path->next;
-               if (path->pts != NULL)
-                       free(path->pts);
-               free(path);
-               path = next;
-       }
-}
-
-static void nsvg__deletePaint(NSVGpaint* paint)
-{
-       if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT)
-               free(paint->gradient);
+    if (p) {
+        if (p->image)
+            free(p->image);
+        free(p);
+    }
+    return NULL;
 }
-
-static void nsvg__deleteGradientData(NSVGgradientData* grad)
-{
-       NSVGgradientData* next;
-       while (grad != NULL) {
-               next = grad->next;
-               free(grad->stops);
-               free(grad);
-               grad = next;
-       }
+
+static void nsvg__deletePaths(NSVGpath *path) {
+    while (path) {
+        NSVGpath *next = path->next;
+        if (path->pts != NULL)
+            free(path->pts);
+        free(path);
+        path = next;
+    }
 }
 
-static void nsvg__deleteParser(NSVGparser* p)
-{
-       if (p != NULL) {
-               nsvg__deletePaths(p->plist);
-               nsvg__deleteGradientData(p->gradients);
-               nsvgDelete(p->image);
-               free(p->pts);
-               free(p);
-       }
+static void nsvg__deletePaint(NSVGpaint *paint) {
+    if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT)
+        free(paint->gradient);
 }
 
-static void nsvg__resetPath(NSVGparser* p)
-{
-       p->npts = 0;
-}
-
-static void nsvg__addPoint(NSVGparser* p, float x, float y)
-{
-       if (p->npts+1 > p->cpts) {
-               p->cpts = p->cpts ? p->cpts*2 : 8;
-               p->pts = (float*)realloc(p->pts, p->cpts*2*sizeof(float));
-               if (!p->pts) return;
-       }
-       p->pts[p->npts*2+0] = x;
-       p->pts[p->npts*2+1] = y;
-       p->npts++;
-}
-
-static void nsvg__moveTo(NSVGparser* p, float x, float y)
-{
-       if (p->npts > 0) {
-               p->pts[(p->npts-1)*2+0] = x;
-               p->pts[(p->npts-1)*2+1] = y;
-       } else {
-               nsvg__addPoint(p, x, y);
-       }
-}
-
-static void nsvg__lineTo(NSVGparser* p, float x, float y)
-{
-       float px,py, dx,dy;
-       if (p->npts > 0) {
-               px = p->pts[(p->npts-1)*2+0];
-               py = p->pts[(p->npts-1)*2+1];
-               dx = x - px;
-               dy = y - py;
-               nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f);
-               nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f);
-               nsvg__addPoint(p, x, y);
-       }
-}
-
-static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
-{
-       nsvg__addPoint(p, cpx1, cpy1);
-       nsvg__addPoint(p, cpx2, cpy2);
-       nsvg__addPoint(p, x, y);
-}
-
-static NSVGattrib* nsvg__getAttr(NSVGparser* p)
-{
-       return &p->attr[p->attrHead];
-}
-
-static void nsvg__pushAttr(NSVGparser* p)
-{
-       if (p->attrHead < NSVG_MAX_ATTR-1) {
-               p->attrHead++;
-               memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib));
-       }
-}
-
-static void nsvg__popAttr(NSVGparser* p)
-{
-       if (p->attrHead > 0)
-               p->attrHead--;
-}
-
-static float nsvg__actualOrigX(NSVGparser* p)
-{
-       return p->viewMinx;
-}
-
-static float nsvg__actualOrigY(NSVGparser* p)
-{
-       return p->viewMiny;
-}
-
-static float nsvg__actualWidth(NSVGparser* p)
-{
-       return p->viewWidth;
-}
-
-static float nsvg__actualHeight(NSVGparser* p)
-{
-       return p->viewHeight;
-}
-
-static float nsvg__actualLength(NSVGparser* p)
-{
-       float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p);
-       return sqrtf(w*w + h*h) / sqrtf(2.0f);
-}
-
-static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length)
-{
-       NSVGattrib* attr = nsvg__getAttr(p);
-       switch (c.units) {
-               case NSVG_UNITS_USER:           return c.value;
-               case NSVG_UNITS_PX:                     return c.value;
-               case NSVG_UNITS_PT:                     return c.value / 72.0f * p->dpi;
-               case NSVG_UNITS_PC:                     return c.value / 6.0f * p->dpi;
-               case NSVG_UNITS_MM:                     return c.value / 25.4f * p->dpi;
-               case NSVG_UNITS_CM:                     return c.value / 2.54f * p->dpi;
-               case NSVG_UNITS_IN:                     return c.value * p->dpi;
-               case NSVG_UNITS_EM:                     return c.value * attr->fontSize;
-               case NSVG_UNITS_EX:                     return c.value * attr->fontSize * 0.52f; // x-height of Helvetica.
-               case NSVG_UNITS_PERCENT:        return orig + c.value / 100.0f * length;
-               default:                                        return c.value;
-       }
-       return c.value;
-}
-
-static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
-{
-       NSVGgradientData* grad = p->gradients;
-       while (grad) {
-               if (strcmp(grad->id, id) == 0)
-                       return grad;
-               grad = grad->next;
-       }
-       return NULL;
-}
-
-static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType)
-{
-       NSVGattrib* attr = nsvg__getAttr(p);
-       NSVGgradientData* data = NULL;
-       NSVGgradientData* ref = NULL;
-       NSVGgradientStop* stops = NULL;
-       NSVGgradient* grad;
-       float ox, oy, sw, sh, sl;
-       int nstops = 0;
-
-       data = nsvg__findGradientData(p, id);
-       if (data == NULL) return NULL;
-
-       // TODO: use ref to fill in all unset values too.
-       ref = data;
-       while (ref != NULL) {
-               if (stops == NULL && ref->stops != NULL) {
-                       stops = ref->stops;
-                       nstops = ref->nstops;
-                       break;
-               }
-               ref = nsvg__findGradientData(p, ref->ref);
-       }
-       if (stops == NULL) return NULL;
-
-       grad = (NSVGgradient*)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1));
-       if (grad == NULL) return NULL;
-
-       // The shape width and height.
-       if (data->units == NSVG_OBJECT_SPACE) {
-               ox = localBounds[0];
-               oy = localBounds[1];
-               sw = localBounds[2] - localBounds[0];
-               sh = localBounds[3] - localBounds[1];
-       } else {
-               ox = nsvg__actualOrigX(p);
-               oy = nsvg__actualOrigY(p);
-               sw = nsvg__actualWidth(p);
-               sh = nsvg__actualHeight(p);
-       }
-       sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f);
-
-       if (data->type == NSVG_PAINT_LINEAR_GRADIENT) {
-               float x1, y1, x2, y2, dx, dy;
-               x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw);
-               y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh);
-               x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw);
-               y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh);
-               // Calculate transform aligned to the line
-               dx = x2 - x1;
-               dy = y2 - y1;
-               grad->xform[0] = dy; grad->xform[1] = -dx;
-               grad->xform[2] = dx; grad->xform[3] = dy;
-               grad->xform[4] = x1; grad->xform[5] = y1;
-       } else {
-               float cx, cy, fx, fy, r;
-               cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw);
-               cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh);
-               fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw);
-               fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh);
-               r = nsvg__convertToPixels(p, data->radial.r, 0, sl);
-               // Calculate transform aligned to the circle
-               grad->xform[0] = r; grad->xform[1] = 0;
-               grad->xform[2] = 0; grad->xform[3] = r;
-               grad->xform[4] = cx; grad->xform[5] = cy;
-               grad->fx = fx / r;
-               grad->fy = fy / r;
-       }
-
-       nsvg__xformMultiply(grad->xform, data->xform);
-       nsvg__xformMultiply(grad->xform, attr->xform);
-
-       grad->spread = data->spread;
-       memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop));
-       grad->nstops = nstops;
-
-       *paintType = data->type;
-
-       return grad;
-}
-
-static float nsvg__getAverageScale(float* t)
-{
-       float sx = sqrtf(t[0]*t[0] + t[2]*t[2]);
-       float sy = sqrtf(t[1]*t[1] + t[3]*t[3]);
-       return (sx + sy) * 0.5f;
-}
-
-static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform)
-{
-       NSVGpath* path;
-       float curve[4*2], curveBounds[4];
-       int i, first = 1;
-       for (path = shape->paths; path != NULL; path = path->next) {
-               nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform);
-               for (i = 0; i < path->npts-1; i += 3) {
-                       nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform);
-                       nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform);
-                       nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform);
-                       nsvg__curveBounds(curveBounds, curve);
-                       if (first) {
-                               bounds[0] = curveBounds[0];
-                               bounds[1] = curveBounds[1];
-                               bounds[2] = curveBounds[2];
-                               bounds[3] = curveBounds[3];
-                               first = 0;
-                       } else {
-                               bounds[0] = nsvg__minf(bounds[0], curveBounds[0]);
-                               bounds[1] = nsvg__minf(bounds[1], curveBounds[1]);
-                               bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]);
-                               bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]);
-                       }
-                       curve[0] = curve[6];
-                       curve[1] = curve[7];
-               }
-       }
-}
-
-static void nsvg__addShape(NSVGparser* p)
-{
-       NSVGattrib* attr = nsvg__getAttr(p);
-       float scale = 1.0f;
-       NSVGshape* shape;
-       NSVGpath* path;
-       int i;
-
-       if (p->plist == NULL)
-               return;
-
-       shape = (NSVGshape*)malloc(sizeof(NSVGshape));
-       if (shape == NULL) goto error;
-       memset(shape, 0, sizeof(NSVGshape));
-
-       memcpy(shape->id, attr->id, sizeof shape->id);
-       scale = nsvg__getAverageScale(attr->xform);
-       shape->strokeWidth = attr->strokeWidth * scale;
-       shape->strokeDashOffset = attr->strokeDashOffset * scale;
-       shape->strokeDashCount = (char)attr->strokeDashCount;
-       for (i = 0; i < attr->strokeDashCount; i++)
-               shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale;
-       shape->strokeLineJoin = attr->strokeLineJoin;
-       shape->strokeLineCap = attr->strokeLineCap;
-       shape->miterLimit = attr->miterLimit;
-       shape->fillRule = attr->fillRule;
-       shape->opacity = attr->opacity;
-
-       shape->paths = p->plist;
-       p->plist = NULL;
-
-       // Calculate shape bounds
-       shape->bounds[0] = shape->paths->bounds[0];
-       shape->bounds[1] = shape->paths->bounds[1];
-       shape->bounds[2] = shape->paths->bounds[2];
-       shape->bounds[3] = shape->paths->bounds[3];
-       for (path = shape->paths->next; path != NULL; path = path->next) {
-               shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]);
-               shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]);
-               shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]);
-               shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]);
-       }
-
-       // Set fill
-       if (attr->hasFill == 0) {
-               shape->fill.type = NSVG_PAINT_NONE;
-       } else if (attr->hasFill == 1) {
-               shape->fill.type = NSVG_PAINT_COLOR;
-               shape->fill.color = attr->fillColor;
-               shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24;
-       } else if (attr->hasFill == 2) {
-               float inv[6], localBounds[4];
-               nsvg__xformInverse(inv, attr->xform);
-               nsvg__getLocalBounds(localBounds, shape, inv);
-               shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type);
-               if (shape->fill.gradient == NULL) {
-                       shape->fill.type = NSVG_PAINT_NONE;
-               }
-       }
-
-       // Set stroke
-       if (attr->hasStroke == 0) {
-               shape->stroke.type = NSVG_PAINT_NONE;
-       } else if (attr->hasStroke == 1) {
-               shape->stroke.type = NSVG_PAINT_COLOR;
-               shape->stroke.color = attr->strokeColor;
-               shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24;
-       } else if (attr->hasStroke == 2) {
-               float inv[6], localBounds[4];
-               nsvg__xformInverse(inv, attr->xform);
-               nsvg__getLocalBounds(localBounds, shape, inv);
-               shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type);
-               if (shape->stroke.gradient == NULL)
-                       shape->stroke.type = NSVG_PAINT_NONE;
-       }
-
-       // Set flags
-       shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00);
-
-       // Add to tail
-       if (p->image->shapes == NULL)
-               p->image->shapes = shape;
-       else
-               p->shapesTail->next = shape;
-       p->shapesTail = shape;
-
-       return;
+static void nsvg__deleteGradientData(NSVGgradientData *grad) {
+    NSVGgradientData *next;
+    while (grad != NULL) {
+        next = grad->next;
+        free(grad->stops);
+        free(grad);
+        grad = next;
+    }
+}
+
+static void nsvg__deleteParser(NSVGparser *p) {
+    if (p != NULL) {
+        nsvg__deletePaths(p->plist);
+        nsvg__deleteGradientData(p->gradients);
+        nsvgDelete(p->image);
+        free(p->pts);
+        free(p);
+    }
+}
+
+static void nsvg__resetPath(NSVGparser *p) { p->npts = 0; }
+
+static void nsvg__addPoint(NSVGparser *p, float x, float y) {
+    if (p->npts + 1 > p->cpts) {
+        p->cpts = p->cpts ? p->cpts * 2 : 8;
+        p->pts  = (float *)realloc(p->pts, p->cpts * 2 * sizeof(float));
+        if (!p->pts)
+            return;
+    }
+    p->pts[p->npts * 2 + 0] = x;
+    p->pts[p->npts * 2 + 1] = y;
+    p->npts++;
+}
+
+static void nsvg__moveTo(NSVGparser *p, float x, float y) {
+    if (p->npts > 0) {
+        p->pts[(p->npts - 1) * 2 + 0] = x;
+        p->pts[(p->npts - 1) * 2 + 1] = y;
+    } else {
+        nsvg__addPoint(p, x, y);
+    }
+}
+
+static void nsvg__lineTo(NSVGparser *p, float x, float y) {
+    float px, py, dx, dy;
+    if (p->npts > 0) {
+        px = p->pts[(p->npts - 1) * 2 + 0];
+        py = p->pts[(p->npts - 1) * 2 + 1];
+        dx = x - px;
+        dy = y - py;
+        nsvg__addPoint(p, px + dx / 3.0f, py + dy / 3.0f);
+        nsvg__addPoint(p, x - dx / 3.0f, y - dy / 3.0f);
+        nsvg__addPoint(p, x, y);
+    }
+}
+
+static void nsvg__cubicBezTo(NSVGparser *p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) {
+    nsvg__addPoint(p, cpx1, cpy1);
+    nsvg__addPoint(p, cpx2, cpy2);
+    nsvg__addPoint(p, x, y);
+}
+
+static NSVGattrib *nsvg__getAttr(NSVGparser *p) { return &p->attr[p->attrHead]; }
+
+static void nsvg__pushAttr(NSVGparser *p) {
+    if (p->attrHead < NSVG_MAX_ATTR - 1) {
+        p->attrHead++;
+        memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead - 1], sizeof(NSVGattrib));
+    }
+}
+
+static void nsvg__popAttr(NSVGparser *p) {
+    if (p->attrHead > 0)
+        p->attrHead--;
+}
+
+static float nsvg__actualOrigX(NSVGparser *p) { return p->viewMinx; }
+
+static float nsvg__actualOrigY(NSVGparser *p) { return p->viewMiny; }
+
+static float nsvg__actualWidth(NSVGparser *p) { return p->viewWidth; }
+
+static float nsvg__actualHeight(NSVGparser *p) { return p->viewHeight; }
+
+static float nsvg__actualLength(NSVGparser *p) {
+    float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p);
+    return sqrtf(w * w + h * h) / sqrtf(2.0f);
+}
+
+static float nsvg__convertToPixels(NSVGparser *p, NSVGcoordinate c, float orig, float length) {
+    NSVGattrib *attr = nsvg__getAttr(p);
+    switch (c.units) {
+    case NSVG_UNITS_USER:
+        return c.value;
+    case NSVG_UNITS_PX:
+        return c.value;
+    case NSVG_UNITS_PT:
+        return c.value / 72.0f * p->dpi;
+    case NSVG_UNITS_PC:
+        return c.value / 6.0f * p->dpi;
+    case NSVG_UNITS_MM:
+        return c.value / 25.4f * p->dpi;
+    case NSVG_UNITS_CM:
+        return c.value / 2.54f * p->dpi;
+    case NSVG_UNITS_IN:
+        return c.value * p->dpi;
+    case NSVG_UNITS_EM:
+        return c.value * attr->fontSize;
+    case NSVG_UNITS_EX:
+        return c.value * attr->fontSize * 0.52f; // x-height of Helvetica.
+    case NSVG_UNITS_PERCENT:
+        return orig + c.value / 100.0f * length;
+    default:
+        return c.value;
+    }
+    return c.value;
+}
+
+static NSVGgradientData *nsvg__findGradientData(NSVGparser *p, const char *id) {
+    NSVGgradientData *grad = p->gradients;
+    while (grad) {
+        if (strcmp(grad->id, id) == 0)
+            return grad;
+        grad = grad->next;
+    }
+    return NULL;
+}
+
+static NSVGgradient *nsvg__createGradient(NSVGparser *p, const char *id, const float *localBounds, char *paintType) {
+    NSVGattrib       *attr  = nsvg__getAttr(p);
+    NSVGgradientData *data  = NULL;
+    NSVGgradientData *ref   = NULL;
+    NSVGgradientStop *stops = NULL;
+    NSVGgradient     *grad;
+    float             ox, oy, sw, sh, sl;
+    int               nstops = 0;
+
+    data = nsvg__findGradientData(p, id);
+    if (data == NULL)
+        return NULL;
+
+    // TODO: use ref to fill in all unset values too.
+    ref = data;
+    while (ref != NULL) {
+        if (stops == NULL && ref->stops != NULL) {
+            stops  = ref->stops;
+            nstops = ref->nstops;
+            break;
+        }
+        ref = nsvg__findGradientData(p, ref->ref);
+    }
+    if (stops == NULL)
+        return NULL;
+
+    grad = (NSVGgradient *)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop) * (nstops - 1));
+    if (grad == NULL)
+        return NULL;
+
+    // The shape width and height.
+    if (data->units == NSVG_OBJECT_SPACE) {
+        ox = localBounds[0];
+        oy = localBounds[1];
+        sw = localBounds[2] - localBounds[0];
+        sh = localBounds[3] - localBounds[1];
+    } else {
+        ox = nsvg__actualOrigX(p);
+        oy = nsvg__actualOrigY(p);
+        sw = nsvg__actualWidth(p);
+        sh = nsvg__actualHeight(p);
+    }
+    sl = sqrtf(sw * sw + sh * sh) / sqrtf(2.0f);
+
+    if (data->type == NSVG_PAINT_LINEAR_GRADIENT) {
+        float x1, y1, x2, y2, dx, dy;
+        x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw);
+        y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh);
+        x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw);
+        y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh);
+        // Calculate transform aligned to the line
+        dx             = x2 - x1;
+        dy             = y2 - y1;
+        grad->xform[0] = dy;
+        grad->xform[1] = -dx;
+        grad->xform[2] = dx;
+        grad->xform[3] = dy;
+        grad->xform[4] = x1;
+        grad->xform[5] = y1;
+    } else {
+        float cx, cy, fx, fy, r;
+        cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw);
+        cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh);
+        fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw);
+        fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh);
+        r  = nsvg__convertToPixels(p, data->radial.r, 0, sl);
+        // Calculate transform aligned to the circle
+        grad->xform[0] = r;
+        grad->xform[1] = 0;
+        grad->xform[2] = 0;
+        grad->xform[3] = r;
+        grad->xform[4] = cx;
+        grad->xform[5] = cy;
+        grad->fx       = fx / r;
+        grad->fy       = fy / r;
+    }
+
+    nsvg__xformMultiply(grad->xform, data->xform);
+    nsvg__xformMultiply(grad->xform, attr->xform);
+
+    grad->spread = data->spread;
+    memcpy(grad->stops, stops, nstops * sizeof(NSVGgradientStop));
+    grad->nstops = nstops;
+
+    *paintType = data->type;
+
+    return grad;
+}
+
+static float nsvg__getAverageScale(float *t) {
+    float sx = sqrtf(t[0] * t[0] + t[2] * t[2]);
+    float sy = sqrtf(t[1] * t[1] + t[3] * t[3]);
+    return (sx + sy) * 0.5f;
+}
+
+static void nsvg__getLocalBounds(float *bounds, NSVGshape *shape, float *xform) {
+    NSVGpath *path;
+    float     curve[4 * 2], curveBounds[4];
+    int       i, first = 1;
+    for (path = shape->paths; path != NULL; path = path->next) {
+        nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform);
+        for (i = 0; i < path->npts - 1; i += 3) {
+            nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i + 1) * 2], path->pts[(i + 1) * 2 + 1], xform);
+            nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i + 2) * 2], path->pts[(i + 2) * 2 + 1], xform);
+            nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i + 3) * 2], path->pts[(i + 3) * 2 + 1], xform);
+            nsvg__curveBounds(curveBounds, curve);
+            if (first) {
+                bounds[0] = curveBounds[0];
+                bounds[1] = curveBounds[1];
+                bounds[2] = curveBounds[2];
+                bounds[3] = curveBounds[3];
+                first     = 0;
+            } else {
+                bounds[0] = nsvg__minf(bounds[0], curveBounds[0]);
+                bounds[1] = nsvg__minf(bounds[1], curveBounds[1]);
+                bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]);
+                bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]);
+            }
+            curve[0] = curve[6];
+            curve[1] = curve[7];
+        }
+    }
+}
+
+static void nsvg__addShape(NSVGparser *p) {
+    NSVGattrib *attr  = nsvg__getAttr(p);
+    float       scale = 1.0f;
+    NSVGshape  *shape;
+    NSVGpath   *path;
+    int         i;
+
+    if (p->plist == NULL)
+        return;
+
+    shape = (NSVGshape *)malloc(sizeof(NSVGshape));
+    if (shape == NULL)
+        goto error;
+    memset(shape, 0, sizeof(NSVGshape));
+
+    memcpy(shape->id, attr->id, sizeof shape->id);
+    scale                   = nsvg__getAverageScale(attr->xform);
+    shape->strokeWidth      = attr->strokeWidth * scale;
+    shape->strokeDashOffset = attr->strokeDashOffset * scale;
+    shape->strokeDashCount  = (char)attr->strokeDashCount;
+    for (i = 0; i < attr->strokeDashCount; i++)
+        shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale;
+    shape->strokeLineJoin = attr->strokeLineJoin;
+    shape->strokeLineCap  = attr->strokeLineCap;
+    shape->miterLimit     = attr->miterLimit;
+    shape->fillRule       = attr->fillRule;
+    shape->opacity        = attr->opacity;
+
+    shape->paths = p->plist;
+    p->plist     = NULL;
+
+    // Calculate shape bounds
+    shape->bounds[0] = shape->paths->bounds[0];
+    shape->bounds[1] = shape->paths->bounds[1];
+    shape->bounds[2] = shape->paths->bounds[2];
+    shape->bounds[3] = shape->paths->bounds[3];
+    for (path = shape->paths->next; path != NULL; path = path->next) {
+        shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]);
+        shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]);
+        shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]);
+        shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]);
+    }
+
+    // Set fill
+    if (attr->hasFill == 0) {
+        shape->fill.type = NSVG_PAINT_NONE;
+    } else if (attr->hasFill == 1) {
+        shape->fill.type  = NSVG_PAINT_COLOR;
+        shape->fill.color = attr->fillColor;
+        shape->fill.color |= (unsigned int)(attr->fillOpacity * 255) << 24;
+    } else if (attr->hasFill == 2) {
+        float inv[6], localBounds[4];
+        nsvg__xformInverse(inv, attr->xform);
+        nsvg__getLocalBounds(localBounds, shape, inv);
+        shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type);
+        if (shape->fill.gradient == NULL) {
+            shape->fill.type = NSVG_PAINT_NONE;
+        }
+    }
+
+    // Set stroke
+    if (attr->hasStroke == 0) {
+        shape->stroke.type = NSVG_PAINT_NONE;
+    } else if (attr->hasStroke == 1) {
+        shape->stroke.type  = NSVG_PAINT_COLOR;
+        shape->stroke.color = attr->strokeColor;
+        shape->stroke.color |= (unsigned int)(attr->strokeOpacity * 255) << 24;
+    } else if (attr->hasStroke == 2) {
+        float inv[6], localBounds[4];
+        nsvg__xformInverse(inv, attr->xform);
+        nsvg__getLocalBounds(localBounds, shape, inv);
+        shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type);
+        if (shape->stroke.gradient == NULL)
+            shape->stroke.type = NSVG_PAINT_NONE;
+    }
+
+    // Set flags
+    shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00);
+
+    // Add to tail
+    if (p->image->shapes == NULL)
+        p->image->shapes = shape;
+    else
+        p->shapesTail->next = shape;
+    p->shapesTail = shape;
+
+    return;
 
 error:
-       if (shape) free(shape);
-}
-
-static void nsvg__addPath(NSVGparser* p, char closed)
-{
-       NSVGattrib* attr = nsvg__getAttr(p);
-       NSVGpath* path = NULL;
-       float bounds[4];
-       float* curve;
-       int i;
-
-       if (p->npts < 4)
-               return;
-
-       if (closed)
-               nsvg__lineTo(p, p->pts[0], p->pts[1]);
-
-       path = (NSVGpath*)malloc(sizeof(NSVGpath));
-       if (path == NULL) goto error;
-       memset(path, 0, sizeof(NSVGpath));
-
-       path->pts = (float*)malloc(p->npts*2*sizeof(float));
-       if (path->pts == NULL) goto error;
-       path->closed = closed;
-       path->npts = p->npts;
-
-       // Transform path.
-       for (i = 0; i < p->npts; ++i)
-               nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform);
-
-       // Find bounds
-       for (i = 0; i < path->npts-1; i += 3) {
-               curve = &path->pts[i*2];
-               nsvg__curveBounds(bounds, curve);
-               if (i == 0) {
-                       path->bounds[0] = bounds[0];
-                       path->bounds[1] = bounds[1];
-                       path->bounds[2] = bounds[2];
-                       path->bounds[3] = bounds[3];
-               } else {
-                       path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]);
-                       path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]);
-                       path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]);
-                       path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]);
-               }
-       }
-
-       path->next = p->plist;
-       p->plist = path;
-
-       return;
+    if (shape)
+        free(shape);
+}
+
+static void nsvg__addPath(NSVGparser *p, char closed) {
+    NSVGattrib *attr = nsvg__getAttr(p);
+    NSVGpath   *path = NULL;
+    float       bounds[4];
+    float      *curve;
+    int         i;
+
+    if (p->npts < 4)
+        return;
+
+    if (closed)
+        nsvg__lineTo(p, p->pts[0], p->pts[1]);
+
+    path = (NSVGpath *)malloc(sizeof(NSVGpath));
+    if (path == NULL)
+        goto error;
+    memset(path, 0, sizeof(NSVGpath));
+
+    path->pts = (float *)malloc(p->npts * 2 * sizeof(float));
+    if (path->pts == NULL)
+        goto error;
+    path->closed = closed;
+    path->npts   = p->npts;
+
+    // Transform path.
+    for (i = 0; i < p->npts; ++i)
+        nsvg__xformPoint(&path->pts[i * 2], &path->pts[i * 2 + 1], p->pts[i * 2], p->pts[i * 2 + 1], attr->xform);
+
+    // Find bounds
+    for (i = 0; i < path->npts - 1; i += 3) {
+        curve = &path->pts[i * 2];
+        nsvg__curveBounds(bounds, curve);
+        if (i == 0) {
+            path->bounds[0] = bounds[0];
+            path->bounds[1] = bounds[1];
+            path->bounds[2] = bounds[2];
+            path->bounds[3] = bounds[3];
+        } else {
+            path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]);
+            path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]);
+            path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]);
+            path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]);
+        }
+    }
+
+    path->next = p->plist;
+    p->plist   = path;
+
+    return;
 
 error:
-       if (path != NULL) {
-               if (path->pts != NULL) free(path->pts);
-               free(path);
-       }
+    if (path != NULL) {
+        if (path->pts != NULL)
+            free(path->pts);
+        free(path);
+    }
 }
 
 // We roll our own string to float because the std library one uses locale and messes things up.
-static double nsvg__atof(const char* s)
-{
-       char* cur = (char*)s;
-       char* end = NULL;
-       double res = 0.0, sign = 1.0;
-       long long intPart = 0, fracPart = 0;
-       char hasIntPart = 0, hasFracPart = 0;
-
-       // Parse optional sign
-       if (*cur == '+') {
-               cur++;
-       } else if (*cur == '-') {
-               sign = -1;
-               cur++;
-       }
-
-       // Parse integer part
-       if (nsvg__isdigit(*cur)) {
-               // Parse digit sequence
-               intPart = (double)strtoll(cur, &end, 10);
-               if (cur != end) {
-                       res = (double)intPart;
-                       hasIntPart = 1;
-                       cur = end;
-               }
-       }
-
-       // Parse fractional part.
-       if (*cur == '.') {
-               cur++; // Skip '.'
-               if (nsvg__isdigit(*cur)) {
-                       // Parse digit sequence
-                       fracPart = strtoll(cur, &end, 10);
-                       if (cur != end) {
-                               res += (double)fracPart / pow(10.0, (double)(end - cur));
-                               hasFracPart = 1;
-                               cur = end;
-                       }
-               }
-       }
-
-       // A valid number should have integer or fractional part.
-       if (!hasIntPart && !hasFracPart)
-               return 0.0;
-
-       // Parse optional exponent
-       if (*cur == 'e' || *cur == 'E') {
-               long expPart = 0;
-               cur++; // skip 'E'
-               expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
-               if (cur != end) {
-                       res *= pow(10.0, (double)expPart);
-               }
-       }
-
-       return res * sign;
-}
-
-
-static const char* nsvg__parseNumber(const char* s, char* it, const int size)
-{
-       const int last = size-1;
-       int i = 0;
-
-       // sign
-       if (*s == '-' || *s == '+') {
-               if (i < last) it[i++] = *s;
-               s++;
-       }
-       // integer part
-       // leading zero
-       if (*s == '0') {
-               if (i < last) it[i++] = *s;
-               s++;
-       }
-       else
-               while (nsvg__isdigit(*s)) {
-                       if (i < last) it[i++] = *s;
-                       s++;
-               }
-       if (*s == '.') {
-               // decimal point
-               if (i < last) it[i++] = *s;
-               s++;
-               // fraction part
-               while (nsvg__isdigit(*s)) {
-                       if (i < last) it[i++] = *s;
-                       s++;
-               }
-       }
-       // exponent
-       if ((*s == 'e' || *s == 'E') && (s[1] != 'm' && s[1] != 'x')) {
-               if (i < last) it[i++] = *s;
-               s++;
-               if (*s == '-' || *s == '+') {
-                       if (i < last) it[i++] = *s;
-                       s++;
-               }
-               while (nsvg__isdigit(*s)) {
-                       if (i < last) it[i++] = *s;
-                       s++;
-               }
-       }
-       it[i] = '\0';
-
-       return s;
-}
-
-static const char* nsvg__getNextPathItemWhenArcFlag(const char* s, char* it)
-{
-       it[0] = '\0';
-       while (nsvg__isspace(*s) || *s == ',') s++;
-       if (*s == '0' || *s == '1') {
-               it[0] = *s++;
-               it[1] = '\0';
-               return s;
-       }
-       return s;
-}
-
-static const char* nsvg__getNextPathItem(const char* s, char* it)
-{
-       it[0] = '\0';
-       // Skip white spaces and commas
-       while (nsvg__isspace(*s) || *s == ',') s++;
-       if (!*s) return s;
-       if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
-               s = nsvg__parseNumber(s, it, 64);
-       } else {
-               // Parse command
-               it[0] = *s++;
-               it[1] = '\0';
-               return s;
-       }
-
-       return s;
-}
-
-static unsigned int nsvg__parseColorHex(const char* str)
-{
-       unsigned int c = 0, r = 0, g = 0, b = 0;
-       int n = 0;
-       str++; // skip #
-       // Calculate number of characters.
-       while(str[n] && !nsvg__isspace(str[n]))
-               n++;
-       if (n == 6) {
-               sscanf(str, "%x", &c);
-       } else if (n == 3) {
-               sscanf(str, "%x", &c);
-               c = (c&0xf) | ((c&0xf0) << 4) | ((c&0xf00) << 8);
-               c |= c<<4;
-       }
-       r = (c >> 16) & 0xff;
-       g = (c >> 8) & 0xff;
-       b = c & 0xff;
-       return NSVG_RGB(r,g,b);
-}
-
-static unsigned int nsvg__parseColorRGB(const char* str)
-{
-       int r = -1, g = -1, b = -1;
-       char s1[32]="", s2[32]="";
-       sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);
-       if (strchr(s1, '%')) {
-               return NSVG_RGB((r*255)/100,(g*255)/100,(b*255)/100);
-       } else {
-               return NSVG_RGB(r,g,b);
-       }
+static double nsvg__atof(const char *s) {
+    char     *cur = (char *)s;
+    char     *end = NULL;
+    double    res = 0.0, sign = 1.0;
+    long long intPart = 0, fracPart = 0;
+    char      hasIntPart = 0, hasFracPart = 0;
+
+    // Parse optional sign
+    if (*cur == '+') {
+        cur++;
+    } else if (*cur == '-') {
+        sign = -1;
+        cur++;
+    }
+
+    // Parse integer part
+    if (nsvg__isdigit(*cur)) {
+        // Parse digit sequence
+        intPart = (double)strtoll(cur, &end, 10);
+        if (cur != end) {
+            res        = (double)intPart;
+            hasIntPart = 1;
+            cur        = end;
+        }
+    }
+
+    // Parse fractional part.
+    if (*cur == '.') {
+        cur++; // Skip '.'
+        if (nsvg__isdigit(*cur)) {
+            // Parse digit sequence
+            fracPart = strtoll(cur, &end, 10);
+            if (cur != end) {
+                res += (double)fracPart / pow(10.0, (double)(end - cur));
+                hasFracPart = 1;
+                cur         = end;
+            }
+        }
+    }
+
+    // A valid number should have integer or fractional part.
+    if (!hasIntPart && !hasFracPart)
+        return 0.0;
+
+    // Parse optional exponent
+    if (*cur == 'e' || *cur == 'E') {
+        long expPart = 0;
+        cur++;                           // skip 'E'
+        expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
+        if (cur != end) {
+            res *= pow(10.0, (double)expPart);
+        }
+    }
+
+    return res * sign;
+}
+
+static const char *nsvg__parseNumber(const char *s, char *it, const int size) {
+    const int last = size - 1;
+    int       i    = 0;
+
+    // sign
+    if (*s == '-' || *s == '+') {
+        if (i < last)
+            it[i++] = *s;
+        s++;
+    }
+    // integer part
+    // leading zero
+    if (*s == '0') {
+        if (i < last)
+            it[i++] = *s;
+        s++;
+    } else
+        while (nsvg__isdigit(*s)) {
+            if (i < last)
+                it[i++] = *s;
+            s++;
+        }
+    if (*s == '.') {
+        // decimal point
+        if (i < last)
+            it[i++] = *s;
+        s++;
+        // fraction part
+        while (nsvg__isdigit(*s)) {
+            if (i < last)
+                it[i++] = *s;
+            s++;
+        }
+    }
+    // exponent
+    if ((*s == 'e' || *s == 'E') && (s[1] != 'm' && s[1] != 'x')) {
+        if (i < last)
+            it[i++] = *s;
+        s++;
+        if (*s == '-' || *s == '+') {
+            if (i < last)
+                it[i++] = *s;
+            s++;
+        }
+        while (nsvg__isdigit(*s)) {
+            if (i < last)
+                it[i++] = *s;
+            s++;
+        }
+    }
+    it[i] = '\0';
+
+    return s;
+}
+
+static const char *nsvg__getNextPathItemWhenArcFlag(const char *s, char *it) {
+    it[0] = '\0';
+    while (nsvg__isspace(*s) || *s == ',')
+        s++;
+    if (*s == '0' || *s == '1') {
+        it[0] = *s++;
+        it[1] = '\0';
+        return s;
+    }
+    return s;
+}
+
+static const char *nsvg__getNextPathItem(const char *s, char *it) {
+    it[0] = '\0';
+    // Skip white spaces and commas
+    while (nsvg__isspace(*s) || *s == ',')
+        s++;
+    if (!*s)
+        return s;
+    if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
+        s = nsvg__parseNumber(s, it, 64);
+    } else {
+        // Parse command
+        it[0] = *s++;
+        it[1] = '\0';
+        return s;
+    }
+
+    return s;
+}
+
+static unsigned int nsvg__parseColorHex(const char *str) {
+    unsigned int c = 0, r = 0, g = 0, b = 0;
+    int          n = 0;
+    str++; // skip #
+    // Calculate number of characters.
+    while (str[n] && !nsvg__isspace(str[n]))
+        n++;
+    if (n == 6) {
+        sscanf(str, "%x", &c);
+    } else if (n == 3) {
+        sscanf(str, "%x", &c);
+        c = (c & 0xf) | ((c & 0xf0) << 4) | ((c & 0xf00) << 8);
+        c |= c << 4;
+    }
+    r = (c >> 16) & 0xff;
+    g = (c >> 8) & 0xff;
+    b = c & 0xff;
+    return NSVG_RGB(r, g, b);
+}
+
+static unsigned int nsvg__parseColorRGB(const char *str) {
+    int  r = -1, g = -1, b = -1;
+    char s1[32] = "", s2[32] = "";
+    sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);
+    if (strchr(s1, '%')) {
+        return NSVG_RGB((r * 255) / 100, (g * 255) / 100, (b * 255) / 100);
+    } else {
+        return NSVG_RGB(r, g, b);
+    }
 }
 
 typedef struct NSVGNamedColor {
-       const char* name;
-       unsigned int color;
+    const char  *name;
+    unsigned int color;
 } NSVGNamedColor;
 
 NSVGNamedColor nsvg__colors[] = {
 
-       { "red", NSVG_RGB(255, 0, 0) },
-       { "green", NSVG_RGB( 0, 128, 0) },
-       { "blue", NSVG_RGB( 0, 0, 255) },
-       { "yellow", NSVG_RGB(255, 255, 0) },
-       { "cyan", NSVG_RGB( 0, 255, 255) },
-       { "magenta", NSVG_RGB(255, 0, 255) },
-       { "black", NSVG_RGB( 0, 0, 0) },
-       { "grey", NSVG_RGB(128, 128, 128) },
-       { "gray", NSVG_RGB(128, 128, 128) },
-       { "white", NSVG_RGB(255, 255, 255) },
+    {"red", NSVG_RGB(255, 0, 0)},
+    {"green", NSVG_RGB(0, 128, 0)},
+    {"blue", NSVG_RGB(0, 0, 255)},
+    {"yellow", NSVG_RGB(255, 255, 0)},
+    {"cyan", NSVG_RGB(0, 255, 255)},
+    {"magenta", NSVG_RGB(255, 0, 255)},
+    {"black", NSVG_RGB(0, 0, 0)},
+    {"grey", NSVG_RGB(128, 128, 128)},
+    {"gray", NSVG_RGB(128, 128, 128)},
+    {"white", NSVG_RGB(255, 255, 255)},
 
 #ifdef NANOSVG_ALL_COLOR_KEYWORDS
-       { "aliceblue", NSVG_RGB(240, 248, 255) },
-       { "antiquewhite", NSVG_RGB(250, 235, 215) },
-       { "aqua", NSVG_RGB( 0, 255, 255) },
-       { "aquamarine", NSVG_RGB(127, 255, 212) },
-       { "azure", NSVG_RGB(240, 255, 255) },
-       { "beige", NSVG_RGB(245, 245, 220) },
-       { "bisque", NSVG_RGB(255, 228, 196) },
-       { "blanchedalmond", NSVG_RGB(255, 235, 205) },
-       { "blueviolet", NSVG_RGB(138, 43, 226) },
-       { "brown", NSVG_RGB(165, 42, 42) },
-       { "burlywood", NSVG_RGB(222, 184, 135) },
-       { "cadetblue", NSVG_RGB( 95, 158, 160) },
-       { "chartreuse", NSVG_RGB(127, 255, 0) },
-       { "chocolate", NSVG_RGB(210, 105, 30) },
-       { "coral", NSVG_RGB(255, 127, 80) },
-       { "cornflowerblue", NSVG_RGB(100, 149, 237) },
-       { "cornsilk", NSVG_RGB(255, 248, 220) },
-       { "crimson", NSVG_RGB(220, 20, 60) },
-       { "darkblue", NSVG_RGB( 0, 0, 139) },
-       { "darkcyan", NSVG_RGB( 0, 139, 139) },
-       { "darkgoldenrod", NSVG_RGB(184, 134, 11) },
-       { "darkgray", NSVG_RGB(169, 169, 169) },
-       { "darkgreen", NSVG_RGB( 0, 100, 0) },
-       { "darkgrey", NSVG_RGB(169, 169, 169) },
-       { "darkkhaki", NSVG_RGB(189, 183, 107) },
-       { "darkmagenta", NSVG_RGB(139, 0, 139) },
-       { "darkolivegreen", NSVG_RGB( 85, 107, 47) },
-       { "darkorange", NSVG_RGB(255, 140, 0) },
-       { "darkorchid", NSVG_RGB(153, 50, 204) },
-       { "darkred", NSVG_RGB(139, 0, 0) },
-       { "darksalmon", NSVG_RGB(233, 150, 122) },
-       { "darkseagreen", NSVG_RGB(143, 188, 143) },
-       { "darkslateblue", NSVG_RGB( 72, 61, 139) },
-       { "darkslategray", NSVG_RGB( 47, 79, 79) },
-       { "darkslategrey", NSVG_RGB( 47, 79, 79) },
-       { "darkturquoise", NSVG_RGB( 0, 206, 209) },
-       { "darkviolet", NSVG_RGB(148, 0, 211) },
-       { "deeppink", NSVG_RGB(255, 20, 147) },
-       { "deepskyblue", NSVG_RGB( 0, 191, 255) },
-       { "dimgray", NSVG_RGB(105, 105, 105) },
-       { "dimgrey", NSVG_RGB(105, 105, 105) },
-       { "dodgerblue", NSVG_RGB( 30, 144, 255) },
-       { "firebrick", NSVG_RGB(178, 34, 34) },
-       { "floralwhite", NSVG_RGB(255, 250, 240) },
-       { "forestgreen", NSVG_RGB( 34, 139, 34) },
-       { "fuchsia", NSVG_RGB(255, 0, 255) },
-       { "gainsboro", NSVG_RGB(220, 220, 220) },
-       { "ghostwhite", NSVG_RGB(248, 248, 255) },
-       { "gold", NSVG_RGB(255, 215, 0) },
-       { "goldenrod", NSVG_RGB(218, 165, 32) },
-       { "greenyellow", NSVG_RGB(173, 255, 47) },
-       { "honeydew", NSVG_RGB(240, 255, 240) },
-       { "hotpink", NSVG_RGB(255, 105, 180) },
-       { "indianred", NSVG_RGB(205, 92, 92) },
-       { "indigo", NSVG_RGB( 75, 0, 130) },
-       { "ivory", NSVG_RGB(255, 255, 240) },
-       { "khaki", NSVG_RGB(240, 230, 140) },
-       { "lavender", NSVG_RGB(230, 230, 250) },
-       { "lavenderblush", NSVG_RGB(255, 240, 245) },
-       { "lawngreen", NSVG_RGB(124, 252, 0) },
-       { "lemonchiffon", NSVG_RGB(255, 250, 205) },
-       { "lightblue", NSVG_RGB(173, 216, 230) },
-       { "lightcoral", NSVG_RGB(240, 128, 128) },
-       { "lightcyan", NSVG_RGB(224, 255, 255) },
-       { "lightgoldenrodyellow", NSVG_RGB(250, 250, 210) },
-       { "lightgray", NSVG_RGB(211, 211, 211) },
-       { "lightgreen", NSVG_RGB(144, 238, 144) },
-       { "lightgrey", NSVG_RGB(211, 211, 211) },
-       { "lightpink", NSVG_RGB(255, 182, 193) },
-       { "lightsalmon", NSVG_RGB(255, 160, 122) },
-       { "lightseagreen", NSVG_RGB( 32, 178, 170) },
-       { "lightskyblue", NSVG_RGB(135, 206, 250) },
-       { "lightslategray", NSVG_RGB(119, 136, 153) },
-       { "lightslategrey", NSVG_RGB(119, 136, 153) },
-       { "lightsteelblue", NSVG_RGB(176, 196, 222) },
-       { "lightyellow", NSVG_RGB(255, 255, 224) },
-       { "lime", NSVG_RGB( 0, 255, 0) },
-       { "limegreen", NSVG_RGB( 50, 205, 50) },
-       { "linen", NSVG_RGB(250, 240, 230) },
-       { "maroon", NSVG_RGB(128, 0, 0) },
-       { "mediumaquamarine", NSVG_RGB(102, 205, 170) },
-       { "mediumblue", NSVG_RGB( 0, 0, 205) },
-       { "mediumorchid", NSVG_RGB(186, 85, 211) },
-       { "mediumpurple", NSVG_RGB(147, 112, 219) },
-       { "mediumseagreen", NSVG_RGB( 60, 179, 113) },
-       { "mediumslateblue", NSVG_RGB(123, 104, 238) },
-       { "mediumspringgreen", NSVG_RGB( 0, 250, 154) },
-       { "mediumturquoise", NSVG_RGB( 72, 209, 204) },
-       { "mediumvioletred", NSVG_RGB(199, 21, 133) },
-       { "midnightblue", NSVG_RGB( 25, 25, 112) },
-       { "mintcream", NSVG_RGB(245, 255, 250) },
-       { "mistyrose", NSVG_RGB(255, 228, 225) },
-       { "moccasin", NSVG_RGB(255, 228, 181) },
-       { "navajowhite", NSVG_RGB(255, 222, 173) },
-       { "navy", NSVG_RGB( 0, 0, 128) },
-       { "oldlace", NSVG_RGB(253, 245, 230) },
-       { "olive", NSVG_RGB(128, 128, 0) },
-       { "olivedrab", NSVG_RGB(107, 142, 35) },
-       { "orange", NSVG_RGB(255, 165, 0) },
-       { "orangered", NSVG_RGB(255, 69, 0) },
-       { "orchid", NSVG_RGB(218, 112, 214) },
-       { "palegoldenrod", NSVG_RGB(238, 232, 170) },
-       { "palegreen", NSVG_RGB(152, 251, 152) },
-       { "paleturquoise", NSVG_RGB(175, 238, 238) },
-       { "palevioletred", NSVG_RGB(219, 112, 147) },
-       { "papayawhip", NSVG_RGB(255, 239, 213) },
-       { "peachpuff", NSVG_RGB(255, 218, 185) },
-       { "peru", NSVG_RGB(205, 133, 63) },
-       { "pink", NSVG_RGB(255, 192, 203) },
-       { "plum", NSVG_RGB(221, 160, 221) },
-       { "powderblue", NSVG_RGB(176, 224, 230) },
-       { "purple", NSVG_RGB(128, 0, 128) },
-       { "rosybrown", NSVG_RGB(188, 143, 143) },
-       { "royalblue", NSVG_RGB( 65, 105, 225) },
-       { "saddlebrown", NSVG_RGB(139, 69, 19) },
-       { "salmon", NSVG_RGB(250, 128, 114) },
-       { "sandybrown", NSVG_RGB(244, 164, 96) },
-       { "seagreen", NSVG_RGB( 46, 139, 87) },
-       { "seashell", NSVG_RGB(255, 245, 238) },
-       { "sienna", NSVG_RGB(160, 82, 45) },
-       { "silver", NSVG_RGB(192, 192, 192) },
-       { "skyblue", NSVG_RGB(135, 206, 235) },
-       { "slateblue", NSVG_RGB(106, 90, 205) },
-       { "slategray", NSVG_RGB(112, 128, 144) },
-       { "slategrey", NSVG_RGB(112, 128, 144) },
-       { "snow", NSVG_RGB(255, 250, 250) },
-       { "springgreen", NSVG_RGB( 0, 255, 127) },
-       { "steelblue", NSVG_RGB( 70, 130, 180) },
-       { "tan", NSVG_RGB(210, 180, 140) },
-       { "teal", NSVG_RGB( 0, 128, 128) },
-       { "thistle", NSVG_RGB(216, 191, 216) },
-       { "tomato", NSVG_RGB(255, 99, 71) },
-       { "turquoise", NSVG_RGB( 64, 224, 208) },
-       { "violet", NSVG_RGB(238, 130, 238) },
-       { "wheat", NSVG_RGB(245, 222, 179) },
-       { "whitesmoke", NSVG_RGB(245, 245, 245) },
-       { "yellowgreen", NSVG_RGB(154, 205, 50) },
+    {"aliceblue", NSVG_RGB(240, 248, 255)},
+    {"antiquewhite", NSVG_RGB(250, 235, 215)},
+    {"aqua", NSVG_RGB(0, 255, 255)},
+    {"aquamarine", NSVG_RGB(127, 255, 212)},
+    {"azure", NSVG_RGB(240, 255, 255)},
+    {"beige", NSVG_RGB(245, 245, 220)},
+    {"bisque", NSVG_RGB(255, 228, 196)},
+    {"blanchedalmond", NSVG_RGB(255, 235, 205)},
+    {"blueviolet", NSVG_RGB(138, 43, 226)},
+    {"brown", NSVG_RGB(165, 42, 42)},
+    {"burlywood", NSVG_RGB(222, 184, 135)},
+    {"cadetblue", NSVG_RGB(95, 158, 160)},
+    {"chartreuse", NSVG_RGB(127, 255, 0)},
+    {"chocolate", NSVG_RGB(210, 105, 30)},
+    {"coral", NSVG_RGB(255, 127, 80)},
+    {"cornflowerblue", NSVG_RGB(100, 149, 237)},
+    {"cornsilk", NSVG_RGB(255, 248, 220)},
+    {"crimson", NSVG_RGB(220, 20, 60)},
+    {"darkblue", NSVG_RGB(0, 0, 139)},
+    {"darkcyan", NSVG_RGB(0, 139, 139)},
+    {"darkgoldenrod", NSVG_RGB(184, 134, 11)},
+    {"darkgray", NSVG_RGB(169, 169, 169)},
+    {"darkgreen", NSVG_RGB(0, 100, 0)},
+    {"darkgrey", NSVG_RGB(169, 169, 169)},
+    {"darkkhaki", NSVG_RGB(189, 183, 107)},
+    {"darkmagenta", NSVG_RGB(139, 0, 139)},
+    {"darkolivegreen", NSVG_RGB(85, 107, 47)},
+    {"darkorange", NSVG_RGB(255, 140, 0)},
+    {"darkorchid", NSVG_RGB(153, 50, 204)},
+    {"darkred", NSVG_RGB(139, 0, 0)},
+    {"darksalmon", NSVG_RGB(233, 150, 122)},
+    {"darkseagreen", NSVG_RGB(143, 188, 143)},
+    {"darkslateblue", NSVG_RGB(72, 61, 139)},
+    {"darkslategray", NSVG_RGB(47, 79, 79)},
+    {"darkslategrey", NSVG_RGB(47, 79, 79)},
+    {"darkturquoise", NSVG_RGB(0, 206, 209)},
+    {"darkviolet", NSVG_RGB(148, 0, 211)},
+    {"deeppink", NSVG_RGB(255, 20, 147)},
+    {"deepskyblue", NSVG_RGB(0, 191, 255)},
+    {"dimgray", NSVG_RGB(105, 105, 105)},
+    {"dimgrey", NSVG_RGB(105, 105, 105)},
+    {"dodgerblue", NSVG_RGB(30, 144, 255)},
+    {"firebrick", NSVG_RGB(178, 34, 34)},
+    {"floralwhite", NSVG_RGB(255, 250, 240)},
+    {"forestgreen", NSVG_RGB(34, 139, 34)},
+    {"fuchsia", NSVG_RGB(255, 0, 255)},
+    {"gainsboro", NSVG_RGB(220, 220, 220)},
+    {"ghostwhite", NSVG_RGB(248, 248, 255)},
+    {"gold", NSVG_RGB(255, 215, 0)},
+    {"goldenrod", NSVG_RGB(218, 165, 32)},
+    {"greenyellow", NSVG_RGB(173, 255, 47)},
+    {"honeydew", NSVG_RGB(240, 255, 240)},
+    {"hotpink", NSVG_RGB(255, 105, 180)},
+    {"indianred", NSVG_RGB(205, 92, 92)},
+    {"indigo", NSVG_RGB(75, 0, 130)},
+    {"ivory", NSVG_RGB(255, 255, 240)},
+    {"khaki", NSVG_RGB(240, 230, 140)},
+    {"lavender", NSVG_RGB(230, 230, 250)},
+    {"lavenderblush", NSVG_RGB(255, 240, 245)},
+    {"lawngreen", NSVG_RGB(124, 252, 0)},
+    {"lemonchiffon", NSVG_RGB(255, 250, 205)},
+    {"lightblue", NSVG_RGB(173, 216, 230)},
+    {"lightcoral", NSVG_RGB(240, 128, 128)},
+    {"lightcyan", NSVG_RGB(224, 255, 255)},
+    {"lightgoldenrodyellow", NSVG_RGB(250, 250, 210)},
+    {"lightgray", NSVG_RGB(211, 211, 211)},
+    {"lightgreen", NSVG_RGB(144, 238, 144)},
+    {"lightgrey", NSVG_RGB(211, 211, 211)},
+    {"lightpink", NSVG_RGB(255, 182, 193)},
+    {"lightsalmon", NSVG_RGB(255, 160, 122)},
+    {"lightseagreen", NSVG_RGB(32, 178, 170)},
+    {"lightskyblue", NSVG_RGB(135, 206, 250)},
+    {"lightslategray", NSVG_RGB(119, 136, 153)},
+    {"lightslategrey", NSVG_RGB(119, 136, 153)},
+    {"lightsteelblue", NSVG_RGB(176, 196, 222)},
+    {"lightyellow", NSVG_RGB(255, 255, 224)},
+    {"lime", NSVG_RGB(0, 255, 0)},
+    {"limegreen", NSVG_RGB(50, 205, 50)},
+    {"linen", NSVG_RGB(250, 240, 230)},
+    {"maroon", NSVG_RGB(128, 0, 0)},
+    {"mediumaquamarine", NSVG_RGB(102, 205, 170)},
+    {"mediumblue", NSVG_RGB(0, 0, 205)},
+    {"mediumorchid", NSVG_RGB(186, 85, 211)},
+    {"mediumpurple", NSVG_RGB(147, 112, 219)},
+    {"mediumseagreen", NSVG_RGB(60, 179, 113)},
+    {"mediumslateblue", NSVG_RGB(123, 104, 238)},
+    {"mediumspringgreen", NSVG_RGB(0, 250, 154)},
+    {"mediumturquoise", NSVG_RGB(72, 209, 204)},
+    {"mediumvioletred", NSVG_RGB(199, 21, 133)},
+    {"midnightblue", NSVG_RGB(25, 25, 112)},
+    {"mintcream", NSVG_RGB(245, 255, 250)},
+    {"mistyrose", NSVG_RGB(255, 228, 225)},
+    {"moccasin", NSVG_RGB(255, 228, 181)},
+    {"navajowhite", NSVG_RGB(255, 222, 173)},
+    {"navy", NSVG_RGB(0, 0, 128)},
+    {"oldlace", NSVG_RGB(253, 245, 230)},
+    {"olive", NSVG_RGB(128, 128, 0)},
+    {"olivedrab", NSVG_RGB(107, 142, 35)},
+    {"orange", NSVG_RGB(255, 165, 0)},
+    {"orangered", NSVG_RGB(255, 69, 0)},
+    {"orchid", NSVG_RGB(218, 112, 214)},
+    {"palegoldenrod", NSVG_RGB(238, 232, 170)},
+    {"palegreen", NSVG_RGB(152, 251, 152)},
+    {"paleturquoise", NSVG_RGB(175, 238, 238)},
+    {"palevioletred", NSVG_RGB(219, 112, 147)},
+    {"papayawhip", NSVG_RGB(255, 239, 213)},
+    {"peachpuff", NSVG_RGB(255, 218, 185)},
+    {"peru", NSVG_RGB(205, 133, 63)},
+    {"pink", NSVG_RGB(255, 192, 203)},
+    {"plum", NSVG_RGB(221, 160, 221)},
+    {"powderblue", NSVG_RGB(176, 224, 230)},
+    {"purple", NSVG_RGB(128, 0, 128)},
+    {"rosybrown", NSVG_RGB(188, 143, 143)},
+    {"royalblue", NSVG_RGB(65, 105, 225)},
+    {"saddlebrown", NSVG_RGB(139, 69, 19)},
+    {"salmon", NSVG_RGB(250, 128, 114)},
+    {"sandybrown", NSVG_RGB(244, 164, 96)},
+    {"seagreen", NSVG_RGB(46, 139, 87)},
+    {"seashell", NSVG_RGB(255, 245, 238)},
+    {"sienna", NSVG_RGB(160, 82, 45)},
+    {"silver", NSVG_RGB(192, 192, 192)},
+    {"skyblue", NSVG_RGB(135, 206, 235)},
+    {"slateblue", NSVG_RGB(106, 90, 205)},
+    {"slategray", NSVG_RGB(112, 128, 144)},
+    {"slategrey", NSVG_RGB(112, 128, 144)},
+    {"snow", NSVG_RGB(255, 250, 250)},
+    {"springgreen", NSVG_RGB(0, 255, 127)},
+    {"steelblue", NSVG_RGB(70, 130, 180)},
+    {"tan", NSVG_RGB(210, 180, 140)},
+    {"teal", NSVG_RGB(0, 128, 128)},
+    {"thistle", NSVG_RGB(216, 191, 216)},
+    {"tomato", NSVG_RGB(255, 99, 71)},
+    {"turquoise", NSVG_RGB(64, 224, 208)},
+    {"violet", NSVG_RGB(238, 130, 238)},
+    {"wheat", NSVG_RGB(245, 222, 179)},
+    {"whitesmoke", NSVG_RGB(245, 245, 245)},
+    {"yellowgreen", NSVG_RGB(154, 205, 50)},
 #endif
 };
 
-static unsigned int nsvg__parseColorName(const char* str)
-{
-       int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor);
-
-       for (i = 0; i < ncolors; i++) {
-               if (strcmp(nsvg__colors[i].name, str) == 0) {
-                       return nsvg__colors[i].color;
-               }
-       }
-
-       return NSVG_RGB(128, 128, 128);
-}
-
-static unsigned int nsvg__parseColor(const char* str)
-{
-       size_t len = 0;
-       while(*str == ' ') ++str;
-       len = strlen(str);
-       if (len >= 1 && *str == '#')
-               return nsvg__parseColorHex(str);
-       else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(')
-               return nsvg__parseColorRGB(str);
-       return nsvg__parseColorName(str);
-}
-
-static float nsvg__parseOpacity(const char* str)
-{
-       float val = nsvg__atof(str);
-       if (val < 0.0f) val = 0.0f;
-       if (val > 1.0f) val = 1.0f;
-       return val;
-}
-
-static float nsvg__parseMiterLimit(const char* str)
-{
-       float val = nsvg__atof(str);
-       if (val < 0.0f) val = 0.0f;
-       return val;
-}
-
-static int nsvg__parseUnits(const char* units)
-{
-       if (units[0] == 'p' && units[1] == 'x')
-               return NSVG_UNITS_PX;
-       else if (units[0] == 'p' && units[1] == 't')
-               return NSVG_UNITS_PT;
-       else if (units[0] == 'p' && units[1] == 'c')
-               return NSVG_UNITS_PC;
-       else if (units[0] == 'm' && units[1] == 'm')
-               return NSVG_UNITS_MM;
-       else if (units[0] == 'c' && units[1] == 'm')
-               return NSVG_UNITS_CM;
-       else if (units[0] == 'i' && units[1] == 'n')
-               return NSVG_UNITS_IN;
-       else if (units[0] == '%')
-               return NSVG_UNITS_PERCENT;
-       else if (units[0] == 'e' && units[1] == 'm')
-               return NSVG_UNITS_EM;
-       else if (units[0] == 'e' && units[1] == 'x')
-               return NSVG_UNITS_EX;
-       return NSVG_UNITS_USER;
-}
-
-static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
-{
-       NSVGcoordinate coord = {0, NSVG_UNITS_USER};
-       char buf[64];
-       coord.units = nsvg__parseUnits(nsvg__parseNumber(str, buf, 64));
-       coord.value = nsvg__atof(buf);
-       return coord;
-}
-
-static NSVGcoordinate nsvg__coord(float v, int units)
-{
-       NSVGcoordinate coord = {v, units};
-       return coord;
-}
-
-static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length)
-{
-       NSVGcoordinate coord = nsvg__parseCoordinateRaw(str);
-       return nsvg__convertToPixels(p, coord, orig, length);
-}
-
-static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int* na)
-{
-       const char* end;
-       const char* ptr;
-       char it[64];
-
-       *na = 0;
-       ptr = str;
-       while (*ptr && *ptr != '(') ++ptr;
-       if (*ptr == 0)
-               return 1;
-       end = ptr;
-       while (*end && *end != ')') ++end;
-       if (*end == 0)
-               return 1;
-
-       while (ptr < end) {
-               if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) {
-                       if (*na >= maxNa) return 0;
-                       ptr = nsvg__parseNumber(ptr, it, 64);
-                       args[(*na)++] = (float)nsvg__atof(it);
-               } else {
-                       ++ptr;
-               }
-       }
-       return (int)(end - str);
-}
-
-
-static int nsvg__parseMatrix(float* xform, const char* str)
-{
-       float t[6];
-       int na = 0;
-       int len = nsvg__parseTransformArgs(str, t, 6, &na);
-       if (na != 6) return len;
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseTranslate(float* xform, const char* str)
-{
-       float args[2];
-       float t[6];
-       int na = 0;
-       int len = nsvg__parseTransformArgs(str, args, 2, &na);
-       if (na == 1) args[1] = 0.0;
-
-       nsvg__xformSetTranslation(t, args[0], args[1]);
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseScale(float* xform, const char* str)
-{
-       float args[2];
-       int na = 0;
-       float t[6];
-       int len = nsvg__parseTransformArgs(str, args, 2, &na);
-       if (na == 1) args[1] = args[0];
-       nsvg__xformSetScale(t, args[0], args[1]);
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseSkewX(float* xform, const char* str)
-{
-       float args[1];
-       int na = 0;
-       float t[6];
-       int len = nsvg__parseTransformArgs(str, args, 1, &na);
-       nsvg__xformSetSkewX(t, args[0]/180.0f*NSVG_PI);
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseSkewY(float* xform, const char* str)
-{
-       float args[1];
-       int na = 0;
-       float t[6];
-       int len = nsvg__parseTransformArgs(str, args, 1, &na);
-       nsvg__xformSetSkewY(t, args[0]/180.0f*NSVG_PI);
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseRotate(float* xform, const char* str)
-{
-       float args[3];
-       int na = 0;
-       float m[6];
-       float t[6];
-       int len = nsvg__parseTransformArgs(str, args, 3, &na);
-       if (na == 1)
-               args[1] = args[2] = 0.0f;
-       nsvg__xformIdentity(m);
-
-       if (na > 1) {
-               nsvg__xformSetTranslation(t, -args[1], -args[2]);
-               nsvg__xformMultiply(m, t);
-       }
-
-       nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI);
-       nsvg__xformMultiply(m, t);
-
-       if (na > 1) {
-               nsvg__xformSetTranslation(t, args[1], args[2]);
-               nsvg__xformMultiply(m, t);
-       }
-
-       memcpy(xform, m, sizeof(float)*6);
-
-       return len;
-}
-
-static void nsvg__parseTransform(float* xform, const char* str)
-{
-       float t[6];
-       nsvg__xformIdentity(xform);
-       while (*str)
-       {
-               if (strncmp(str, "matrix", 6) == 0)
-                       str += nsvg__parseMatrix(t, str);
-               else if (strncmp(str, "translate", 9) == 0)
-                       str += nsvg__parseTranslate(t, str);
-               else if (strncmp(str, "scale", 5) == 0)
-                       str += nsvg__parseScale(t, str);
-               else if (strncmp(str, "rotate", 6) == 0)
-                       str += nsvg__parseRotate(t, str);
-               else if (strncmp(str, "skewX", 5) == 0)
-                       str += nsvg__parseSkewX(t, str);
-               else if (strncmp(str, "skewY", 5) == 0)
-                       str += nsvg__parseSkewY(t, str);
-               else{
-                       ++str;
-                       continue;
-               }
-
-               nsvg__xformPremultiply(xform, t);
-       }
-}
-
-static void nsvg__parseUrl(char* id, const char* str)
-{
-       int i = 0;
-       str += 4; // "url(";
-       if (*str == '#')
-               str++;
-       while (i < 63 && *str != ')') {
-               id[i] = *str++;
-               i++;
-       }
-       id[i] = '\0';
-}
-
-static char nsvg__parseLineCap(const char* str)
-{
-       if (strcmp(str, "butt") == 0)
-               return NSVG_CAP_BUTT;
-       else if (strcmp(str, "round") == 0)
-               return NSVG_CAP_ROUND;
-       else if (strcmp(str, "square") == 0)
-               return NSVG_CAP_SQUARE;
-       // TODO: handle inherit.
-       return NSVG_CAP_BUTT;
-}
-
-static char nsvg__parseLineJoin(const char* str)
-{
-       if (strcmp(str, "miter") == 0)
-               return NSVG_JOIN_MITER;
-       else if (strcmp(str, "round") == 0)
-               return NSVG_JOIN_ROUND;
-       else if (strcmp(str, "bevel") == 0)
-               return NSVG_JOIN_BEVEL;
-       // TODO: handle inherit.
-       return NSVG_JOIN_MITER;
-}
-
-static char nsvg__parseFillRule(const char* str)
-{
-       if (strcmp(str, "nonzero") == 0)
-               return NSVG_FILLRULE_NONZERO;
-       else if (strcmp(str, "evenodd") == 0)
-               return NSVG_FILLRULE_EVENODD;
-       // TODO: handle inherit.
-       return NSVG_FILLRULE_NONZERO;
-}
-
-static const char* nsvg__getNextDashItem(const char* s, char* it)
-{
-       int n = 0;
-       it[0] = '\0';
-       // Skip white spaces and commas
-       while (nsvg__isspace(*s) || *s == ',') s++;
-       // Advance until whitespace, comma or end.
-       while (*s && (!nsvg__isspace(*s) && *s != ',')) {
-               if (n < 63)
-                       it[n++] = *s;
-               s++;
-       }
-       it[n++] = '\0';
-       return s;
-}
-
-static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray)
-{
-       char item[64];
-       int count = 0, i;
-       float sum = 0.0f;
-
-       // Handle "none"
-       if (str[0] == 'n')
-               return 0;
-
-       // Parse dashes
-       while (*str) {
-               str = nsvg__getNextDashItem(str, item);
-               if (!*item) break;
-               if (count < NSVG_MAX_DASHES)
-                       strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
-       }
-
-       for (i = 0; i < count; i++)
-               sum += strokeDashArray[i];
-       if (sum <= 1e-6f)
-               count = 0;
-
-       return count;
-}
-
-static void nsvg__parseStyle(NSVGparser* p, const char* str);
-
-static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
-{
-       float xform[6];
-       NSVGattrib* attr = nsvg__getAttr(p);
-       if (!attr) return 0;
-
-       if (strcmp(name, "style") == 0) {
-               nsvg__parseStyle(p, value);
-       } else if (strcmp(name, "display") == 0) {
-               if (strcmp(value, "none") == 0)
-                       attr->visible = 0;
-               // Don't reset ->visible on display:inline, one display:none hides the whole subtree
-
-       } else if (strcmp(name, "fill") == 0) {
-               if (strcmp(value, "none") == 0) {
-                       attr->hasFill = 0;
-               } else if (strncmp(value, "url(", 4) == 0) {
-                       attr->hasFill = 2;
-                       nsvg__parseUrl(attr->fillGradient, value);
-               } else {
-                       attr->hasFill = 1;
-                       attr->fillColor = nsvg__parseColor(value);
-               }
-       } else if (strcmp(name, "opacity") == 0) {
-               attr->opacity = nsvg__parseOpacity(value);
-       } else if (strcmp(name, "fill-opacity") == 0) {
-               attr->fillOpacity = nsvg__parseOpacity(value);
-       } else if (strcmp(name, "stroke") == 0) {
-               if (strcmp(value, "none") == 0) {
-                       attr->hasStroke = 0;
-               } else if (strncmp(value, "url(", 4) == 0) {
-                       attr->hasStroke = 2;
-                       nsvg__parseUrl(attr->strokeGradient, value);
-               } else {
-                       attr->hasStroke = 1;
-                       attr->strokeColor = nsvg__parseColor(value);
-               }
-       } else if (strcmp(name, "stroke-width") == 0) {
-               attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
-       } else if (strcmp(name, "stroke-dasharray") == 0) {
-               attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray);
-       } else if (strcmp(name, "stroke-dashoffset") == 0) {
-               attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
-       } else if (strcmp(name, "stroke-opacity") == 0) {
-               attr->strokeOpacity = nsvg__parseOpacity(value);
-       } else if (strcmp(name, "stroke-linecap") == 0) {
-               attr->strokeLineCap = nsvg__parseLineCap(value);
-       } else if (strcmp(name, "stroke-linejoin") == 0) {
-               attr->strokeLineJoin = nsvg__parseLineJoin(value);
-       } else if (strcmp(name, "stroke-miterlimit") == 0) {
-               attr->miterLimit = nsvg__parseMiterLimit(value);
-       } else if (strcmp(name, "fill-rule") == 0) {
-               attr->fillRule = nsvg__parseFillRule(value);
-       } else if (strcmp(name, "font-size") == 0) {
-               attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
-       } else if (strcmp(name, "transform") == 0) {
-               nsvg__parseTransform(xform, value);
-               nsvg__xformPremultiply(attr->xform, xform);
-       } else if (strcmp(name, "stop-color") == 0) {
-               attr->stopColor = nsvg__parseColor(value);
-       } else if (strcmp(name, "stop-opacity") == 0) {
-               attr->stopOpacity = nsvg__parseOpacity(value);
-       } else if (strcmp(name, "offset") == 0) {
-               attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f);
-       } else if (strcmp(name, "id") == 0) {
-               strncpy(attr->id, value, 63);
-               attr->id[63] = '\0';
-       } else {
-               return 0;
-       }
-       return 1;
-}
-
-static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end)
-{
-       const char* str;
-       const char* val;
-       char name[512];
-       char value[512];
-       int n;
-
-       str = start;
-       while (str < end && *str != ':') ++str;
-
-       val = str;
-
-       // Right Trim
-       while (str > start &&  (*str == ':' || nsvg__isspace(*str))) --str;
-       ++str;
-
-       n = (int)(str - start);
-       if (n > 511) n = 511;
-       if (n) memcpy(name, start, n);
-       name[n] = 0;
-
-       while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val;
-
-       n = (int)(end - val);
-       if (n > 511) n = 511;
-       if (n) memcpy(value, val, n);
-       value[n] = 0;
-
-       return nsvg__parseAttr(p, name, value);
-}
-
-static void nsvg__parseStyle(NSVGparser* p, const char* str)
-{
-       const char* start;
-       const char* end;
-
-       while (*str) {
-               // Left Trim
-               while(nsvg__isspace(*str)) ++str;
-               start = str;
-               while(*str && *str != ';') ++str;
-               end = str;
-
-               // Right Trim
-               while (end > start &&  (*end == ';' || nsvg__isspace(*end))) --end;
-               ++end;
-
-               nsvg__parseNameValue(p, start, end);
-               if (*str) ++str;
-       }
-}
-
-static void nsvg__parseAttribs(NSVGparser* p, const char** attr)
-{
-       int i;
-       for (i = 0; attr[i]; i += 2)
-       {
-               if (strcmp(attr[i], "style") == 0)
-                       nsvg__parseStyle(p, attr[i + 1]);
-               else
-                       nsvg__parseAttr(p, attr[i], attr[i + 1]);
-       }
-}
-
-static int nsvg__getArgsPerElement(char cmd)
-{
-       switch (cmd) {
-               case 'v':
-               case 'V':
-               case 'h':
-               case 'H':
-                       return 1;
-               case 'm':
-               case 'M':
-               case 'l':
-               case 'L':
-               case 't':
-               case 'T':
-                       return 2;
-               case 'q':
-               case 'Q':
-               case 's':
-               case 'S':
-                       return 4;
-               case 'c':
-               case 'C':
-                       return 6;
-               case 'a':
-               case 'A':
-                       return 7;
-       }
-       return 0;
-}
-
-static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       if (rel) {
-               *cpx += args[0];
-               *cpy += args[1];
-       } else {
-               *cpx = args[0];
-               *cpy = args[1];
-       }
-       nsvg__moveTo(p, *cpx, *cpy);
-}
-
-static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       if (rel) {
-               *cpx += args[0];
-               *cpy += args[1];
-       } else {
-               *cpx = args[0];
-               *cpy = args[1];
-       }
-       nsvg__lineTo(p, *cpx, *cpy);
-}
-
-static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       if (rel)
-               *cpx += args[0];
-       else
-               *cpx = args[0];
-       nsvg__lineTo(p, *cpx, *cpy);
-}
-
-static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       if (rel)
-               *cpy += args[0];
-       else
-               *cpy = args[0];
-       nsvg__lineTo(p, *cpx, *cpy);
-}
-
-static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy,
-                                                                float* cpx2, float* cpy2, float* args, int rel)
-{
-       float x2, y2, cx1, cy1, cx2, cy2;
-
-       if (rel) {
-               cx1 = *cpx + args[0];
-               cy1 = *cpy + args[1];
-               cx2 = *cpx + args[2];
-               cy2 = *cpy + args[3];
-               x2 = *cpx + args[4];
-               y2 = *cpy + args[5];
-       } else {
-               cx1 = args[0];
-               cy1 = args[1];
-               cx2 = args[2];
-               cy2 = args[3];
-               x2 = args[4];
-               y2 = args[5];
-       }
-
-       nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);
-
-       *cpx2 = cx2;
-       *cpy2 = cy2;
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy,
-                                                                         float* cpx2, float* cpy2, float* args, int rel)
-{
-       float x1, y1, x2, y2, cx1, cy1, cx2, cy2;
-
-       x1 = *cpx;
-       y1 = *cpy;
-       if (rel) {
-               cx2 = *cpx + args[0];
-               cy2 = *cpy + args[1];
-               x2 = *cpx + args[2];
-               y2 = *cpy + args[3];
-       } else {
-               cx2 = args[0];
-               cy2 = args[1];
-               x2 = args[2];
-               y2 = args[3];
-       }
-
-       cx1 = 2*x1 - *cpx2;
-       cy1 = 2*y1 - *cpy2;
-
-       nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);
-
-       *cpx2 = cx2;
-       *cpy2 = cy2;
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy,
-                                                               float* cpx2, float* cpy2, float* args, int rel)
-{
-       float x1, y1, x2, y2, cx, cy;
-       float cx1, cy1, cx2, cy2;
-
-       x1 = *cpx;
-       y1 = *cpy;
-       if (rel) {
-               cx = *cpx + args[0];
-               cy = *cpy + args[1];
-               x2 = *cpx + args[2];
-               y2 = *cpy + args[3];
-       } else {
-               cx = args[0];
-               cy = args[1];
-               x2 = args[2];
-               y2 = args[3];
-       }
-
-       // Convert to cubic bezier
-       cx1 = x1 + 2.0f/3.0f*(cx - x1);
-       cy1 = y1 + 2.0f/3.0f*(cy - y1);
-       cx2 = x2 + 2.0f/3.0f*(cx - x2);
-       cy2 = y2 + 2.0f/3.0f*(cy - y2);
-
-       nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);
-
-       *cpx2 = cx;
-       *cpy2 = cy;
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy,
-                                                                        float* cpx2, float* cpy2, float* args, int rel)
-{
-       float x1, y1, x2, y2, cx, cy;
-       float cx1, cy1, cx2, cy2;
-
-       x1 = *cpx;
-       y1 = *cpy;
-       if (rel) {
-               x2 = *cpx + args[0];
-               y2 = *cpy + args[1];
-       } else {
-               x2 = args[0];
-               y2 = args[1];
-       }
-
-       cx = 2*x1 - *cpx2;
-       cy = 2*y1 - *cpy2;
-
-       // Convert to cubix bezier
-       cx1 = x1 + 2.0f/3.0f*(cx - x1);
-       cy1 = y1 + 2.0f/3.0f*(cy - y1);
-       cx2 = x2 + 2.0f/3.0f*(cx - x2);
-       cy2 = y2 + 2.0f/3.0f*(cy - y2);
-
-       nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);
-
-       *cpx2 = cx;
-       *cpy2 = cy;
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static float nsvg__sqr(float x) { return x*x; }
-static float nsvg__vmag(float x, float y) { return sqrtf(x*x + y*y); }
-
-static float nsvg__vecrat(float ux, float uy, float vx, float vy)
-{
-       return (ux*vx + uy*vy) / (nsvg__vmag(ux,uy) * nsvg__vmag(vx,vy));
-}
-
-static float nsvg__vecang(float ux, float uy, float vx, float vy)
-{
-       float r = nsvg__vecrat(ux,uy, vx,vy);
-       if (r < -1.0f) r = -1.0f;
-       if (r > 1.0f) r = 1.0f;
-       return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r);
-}
-
-static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       // Ported from canvg (https://code.google.com/p/canvg/)
-       float rx, ry, rotx;
-       float x1, y1, x2, y2, cx, cy, dx, dy, d;
-       float x1p, y1p, cxp, cyp, s, sa, sb;
-       float ux, uy, vx, vy, a1, da;
-       float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6];
-       float sinrx, cosrx;
-       int fa, fs;
-       int i, ndivs;
-       float hda, kappa;
-
-       rx = fabsf(args[0]);                            // y radius
-       ry = fabsf(args[1]);                            // x radius
-       rotx = args[2] / 180.0f * NSVG_PI;              // x rotation angle
-       fa = fabsf(args[3]) > 1e-6 ? 1 : 0;     // Large arc
-       fs = fabsf(args[4]) > 1e-6 ? 1 : 0;     // Sweep direction
-       x1 = *cpx;                                                      // start point
-       y1 = *cpy;
-       if (rel) {                                                      // end point
-               x2 = *cpx + args[5];
-               y2 = *cpy + args[6];
-       } else {
-               x2 = args[5];
-               y2 = args[6];
-       }
-
-       dx = x1 - x2;
-       dy = y1 - y2;
-       d = sqrtf(dx*dx + dy*dy);
-       if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
-               // The arc degenerates to a line
-               nsvg__lineTo(p, x2, y2);
-               *cpx = x2;
-               *cpy = y2;
-               return;
-       }
-
-       sinrx = sinf(rotx);
-       cosrx = cosf(rotx);
-
-       // Convert to center point parameterization.
-       // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
-       // 1) Compute x1', y1'
-       x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
-       y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
-       d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry);
-       if (d > 1) {
-               d = sqrtf(d);
-               rx *= d;
-               ry *= d;
-       }
-       // 2) Compute cx', cy'
-       s = 0.0f;
-       sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p);
-       sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p);
-       if (sa < 0.0f) sa = 0.0f;
-       if (sb > 0.0f)
-               s = sqrtf(sa / sb);
-       if (fa == fs)
-               s = -s;
-       cxp = s * rx * y1p / ry;
-       cyp = s * -ry * x1p / rx;
-
-       // 3) Compute cx,cy from cx',cy'
-       cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp;
-       cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp;
-
-       // 4) Calculate theta1, and delta theta.
-       ux = (x1p - cxp) / rx;
-       uy = (y1p - cyp) / ry;
-       vx = (-x1p - cxp) / rx;
-       vy = (-y1p - cyp) / ry;
-       a1 = nsvg__vecang(1.0f,0.0f, ux,uy);    // Initial angle
-       da = nsvg__vecang(ux,uy, vx,vy);                // Delta angle
-
-//     if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
-//     if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;
-
-       if (fs == 0 && da > 0)
-               da -= 2 * NSVG_PI;
-       else if (fs == 1 && da < 0)
-               da += 2 * NSVG_PI;
-
-       // Approximate the arc using cubic spline segments.
-       t[0] = cosrx; t[1] = sinrx;
-       t[2] = -sinrx; t[3] = cosrx;
-       t[4] = cx; t[5] = cy;
-
-       // Split arc into max 90 degree segments.
-       // The loop assumes an iteration per end point (including start and end), this +1.
-       ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f);
-       hda = (da / (float)ndivs) / 2.0f;
-       kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
-       if (da < 0.0f)
-               kappa = -kappa;
-
-       for (i = 0; i <= ndivs; i++) {
-               a = a1 + da * ((float)i/(float)ndivs);
-               dx = cosf(a);
-               dy = sinf(a);
-               nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position
-               nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent
-               if (i > 0)
-                       nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y);
-               px = x;
-               py = y;
-               ptanx = tanx;
-               ptany = tany;
-       }
-
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static void nsvg__parsePath(NSVGparser* p, const char** attr)
-{
-       const char* s = NULL;
-       char cmd = '\0';
-       float args[10];
-       int nargs;
-       int rargs = 0;
-       float cpx, cpy, cpx2, cpy2;
-       const char* tmp[4];
-       char closedFlag;
-       int i;
-       char item[64];
-
-       for (i = 0; attr[i]; i += 2) {
-               if (strcmp(attr[i], "d") == 0) {
-                       s = attr[i + 1];
-               } else {
-                       tmp[0] = attr[i];
-                       tmp[1] = attr[i + 1];
-                       tmp[2] = 0;
-                       tmp[3] = 0;
-                       nsvg__parseAttribs(p, tmp);
-               }
-       }
-
-       if (s) {
-               nsvg__resetPath(p);
-               cpx = 0; cpy = 0;
-               cpx2 = 0; cpy2 = 0;
-               closedFlag = 0;
-               nargs = 0;
-
-               while (*s) {
-                       item[0] = '\0';
-                       if ((cmd == 'A' || cmd == 'a') && (nargs == 3 || nargs == 4))
-                               s = nsvg__getNextPathItemWhenArcFlag(s, item);
-                       if (!*item)
-                               s = nsvg__getNextPathItem(s, item);
-                       if (!*item) break;
-                       if (nsvg__isnum(item[0])) {
-                               if (nargs < 10)
-                                       args[nargs++] = (float)nsvg__atof(item);
-                               if (nargs >= rargs) {
-                                       switch (cmd) {
-                                               case 'm':
-                                               case 'M':
-                                                       nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0);
-                                                       // Moveto can be followed by multiple coordinate pairs,
-                                                       // which should be treated as linetos.
-                                                       cmd = (cmd == 'm') ? 'l' : 'L';
-                                                       rargs = nsvg__getArgsPerElement(cmd);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               case 'l':
-                                               case 'L':
-                                                       nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               case 'H':
-                                               case 'h':
-                                                       nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               case 'V':
-                                               case 'v':
-                                                       nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               case 'C':
-                                               case 'c':
-                                                       nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0);
-                                                       break;
-                                               case 'S':
-                                               case 's':
-                                                       nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0);
-                                                       break;
-                                               case 'Q':
-                                               case 'q':
-                                                       nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0);
-                                                       break;
-                                               case 'T':
-                                               case 't':
-                                                       nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0);
-                                                       break;
-                                               case 'A':
-                                               case 'a':
-                                                       nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               default:
-                                                       if (nargs >= 2) {
-                                                               cpx = args[nargs-2];
-                                                               cpy = args[nargs-1];
-                                                               cpx2 = cpx; cpy2 = cpy;
-                                                       }
-                                                       break;
-                                       }
-                                       nargs = 0;
-                               }
-                       } else {
-                               // New command
-                               if (nargs) {
-                                       NANOSVG_DEBUG("unfinished command '%c' %d/%d args\n", cmd, nargs, rargs);
-                               }
-                               cmd = item[0];
-                               rargs = nsvg__getArgsPerElement(cmd);
-                               if (cmd == 'M' || cmd == 'm') {
-                                       // Commit path.
-                                       if (p->npts > 0)
-                                               nsvg__addPath(p, closedFlag);
-                                       // Start new subpath.
-                                       nsvg__resetPath(p);
-                                       closedFlag = 0;
-                                       nargs = 0;
-                               } else if (cmd == 'Z' || cmd == 'z') {
-                                       closedFlag = 1;
-                                       // Commit path.
-                                       if (p->npts > 0) {
-                                               // Move current point to first point
-                                               cpx = p->pts[0];
-                                               cpy = p->pts[1];
-                                               cpx2 = cpx; cpy2 = cpy;
-                                               nsvg__addPath(p, closedFlag);
-                                       }
-                                       // Start new subpath.
-                                       nsvg__resetPath(p);
-                                       nsvg__moveTo(p, cpx, cpy);
-                                       closedFlag = 0;
-                                       nargs = 0;
-                               }
-                       }
-               }
-               // Commit path.
-               if (p->npts)
-                       nsvg__addPath(p, closedFlag);
-       }
-
-       nsvg__addShape(p);
-}
-
-static void nsvg__parseRect(NSVGparser* p, const char** attr)
-{
-       float x = 0.0f;
-       float y = 0.0f;
-       float w = 0.0f;
-       float h = 0.0f;
-       float rx = -1.0f; // marks not set
-       float ry = -1.0f;
-       int i;
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)));
-                       if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)));
-               }
-       }
-
-       if (rx < 0.0f && ry > 0.0f) rx = ry;
-       if (ry < 0.0f && rx > 0.0f) ry = rx;
-       if (rx < 0.0f) rx = 0.0f;
-       if (ry < 0.0f) ry = 0.0f;
-       if (rx > w/2.0f) rx = w/2.0f;
-       if (ry > h/2.0f) ry = h/2.0f;
-
-       if (w != 0.0f && h != 0.0f) {
-               nsvg__resetPath(p);
-
-               if (rx < 0.00001f || ry < 0.0001f) {
-                       nsvg__moveTo(p, x, y);
-                       nsvg__lineTo(p, x+w, y);
-                       nsvg__lineTo(p, x+w, y+h);
-                       nsvg__lineTo(p, x, y+h);
-               } else {
-                       // Rounded rectangle
-                       nsvg__moveTo(p, x+rx, y);
-                       nsvg__lineTo(p, x+w-rx, y);
-                       nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry);
-                       nsvg__lineTo(p, x+w, y+h-ry);
-                       nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h);
-                       nsvg__lineTo(p, x+rx, y+h);
-                       nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry);
-                       nsvg__lineTo(p, x, y+ry);
-                       nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y);
-               }
-
-               nsvg__addPath(p, 1);
-
-               nsvg__addShape(p);
-       }
-}
-
-static void nsvg__parseCircle(NSVGparser* p, const char** attr)
-{
-       float cx = 0.0f;
-       float cy = 0.0f;
-       float r = 0.0f;
-       int i;
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p)));
-               }
-       }
-
-       if (r > 0.0f) {
-               nsvg__resetPath(p);
-
-               nsvg__moveTo(p, cx+r, cy);
-               nsvg__cubicBezTo(p, cx+r, cy+r*NSVG_KAPPA90, cx+r*NSVG_KAPPA90, cy+r, cx, cy+r);
-               nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy);
-               nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r);
-               nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy);
-
-               nsvg__addPath(p, 1);
-
-               nsvg__addShape(p);
-       }
-}
-
-static void nsvg__parseEllipse(NSVGparser* p, const char** attr)
-{
-       float cx = 0.0f;
-       float cy = 0.0f;
-       float rx = 0.0f;
-       float ry = 0.0f;
-       int i;
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)));
-                       if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)));
-               }
-       }
-
-       if (rx > 0.0f && ry > 0.0f) {
-
-               nsvg__resetPath(p);
-
-               nsvg__moveTo(p, cx+rx, cy);
-               nsvg__cubicBezTo(p, cx+rx, cy+ry*NSVG_KAPPA90, cx+rx*NSVG_KAPPA90, cy+ry, cx, cy+ry);
-               nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy);
-               nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry);
-               nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy);
-
-               nsvg__addPath(p, 1);
-
-               nsvg__addShape(p);
-       }
-}
-
-static void nsvg__parseLine(NSVGparser* p, const char** attr)
-{
-       float x1 = 0.0;
-       float y1 = 0.0;
-       float x2 = 0.0;
-       float y2 = 0.0;
-       int i;
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-               }
-       }
-
-       nsvg__resetPath(p);
-
-       nsvg__moveTo(p, x1, y1);
-       nsvg__lineTo(p, x2, y2);
-
-       nsvg__addPath(p, 0);
-
-       nsvg__addShape(p);
-}
-
-static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag)
-{
-       int i;
-       const char* s;
-       float args[2];
-       int nargs, npts = 0;
-       char item[64];
-
-       nsvg__resetPath(p);
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "points") == 0) {
-                               s = attr[i + 1];
-                               nargs = 0;
-                               while (*s) {
-                                       s = nsvg__getNextPathItem(s, item);
-                                       args[nargs++] = (float)nsvg__atof(item);
-                                       if (nargs >= 2) {
-                                               if (npts == 0)
-                                                       nsvg__moveTo(p, args[0], args[1]);
-                                               else
-                                                       nsvg__lineTo(p, args[0], args[1]);
-                                               nargs = 0;
-                                               npts++;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       nsvg__addPath(p, (char)closeFlag);
-
-       nsvg__addShape(p);
-}
-
-static void nsvg__parseSVG(NSVGparser* p, const char** attr)
-{
-       int i;
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "width") == 0) {
-                               p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
-                       } else if (strcmp(attr[i], "height") == 0) {
-                               p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
-                       } else if (strcmp(attr[i], "viewBox") == 0) {
-                               const char *s = attr[i + 1];
-                               char buf[64];
-                               s = nsvg__parseNumber(s, buf, 64);
-                               p->viewMinx = nsvg__atof(buf);
-                               while (nsvg__isspace(*s) || *s == '%' || *s == ',') s++;
-                               if (!*s) return;
-                               s = nsvg__parseNumber(s, buf, 64);
-                               p->viewMiny = nsvg__atof(buf);
-                               while (nsvg__isspace(*s) || *s == '%' || *s == ',') s++;
-                               if (!*s) return;
-                               s = nsvg__parseNumber(s, buf, 64);
-                               p->viewWidth = nsvg__atof(buf);
-                               while (nsvg__isspace(*s) || *s == '%' || *s == ',') s++;
-                               if (!*s) return;
-                               s = nsvg__parseNumber(s, buf, 64);
-                               p->viewHeight = nsvg__atof(buf);
-                       } else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
-                               if (strstr(attr[i + 1], "none") != 0) {
-                                       // No uniform scaling
-                                       p->alignType = NSVG_ALIGN_NONE;
-                               } else {
-                                       // Parse X align
-                                       if (strstr(attr[i + 1], "xMin") != 0)
-                                               p->alignX = NSVG_ALIGN_MIN;
-                                       else if (strstr(attr[i + 1], "xMid") != 0)
-                                               p->alignX = NSVG_ALIGN_MID;
-                                       else if (strstr(attr[i + 1], "xMax") != 0)
-                                               p->alignX = NSVG_ALIGN_MAX;
-                                       // Parse X align
-                                       if (strstr(attr[i + 1], "yMin") != 0)
-                                               p->alignY = NSVG_ALIGN_MIN;
-                                       else if (strstr(attr[i + 1], "yMid") != 0)
-                                               p->alignY = NSVG_ALIGN_MID;
-                                       else if (strstr(attr[i + 1], "yMax") != 0)
-                                               p->alignY = NSVG_ALIGN_MAX;
-                                       // Parse meet/slice
-                                       p->alignType = NSVG_ALIGN_MEET;
-                                       if (strstr(attr[i + 1], "slice") != 0)
-                                               p->alignType = NSVG_ALIGN_SLICE;
-                               }
-                       }
-               }
-       }
-}
-
-static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type)
-{
-       int i;
-       NSVGgradientData* grad = (NSVGgradientData*)malloc(sizeof(NSVGgradientData));
-       if (grad == NULL) return;
-       memset(grad, 0, sizeof(NSVGgradientData));
-       grad->units = NSVG_OBJECT_SPACE;
-       grad->type = type;
-       if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) {
-               grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
-               grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
-               grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT);
-               grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
-       } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) {
-               grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
-               grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
-               grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
-       }
-
-       nsvg__xformIdentity(grad->xform);
-
-       for (i = 0; attr[i]; i += 2) {
-               if (strcmp(attr[i], "id") == 0) {
-                       strncpy(grad->id, attr[i+1], 63);
-                       grad->id[63] = '\0';
-               } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "gradientUnits") == 0) {
-                               if (strcmp(attr[i+1], "objectBoundingBox") == 0)
-                                       grad->units = NSVG_OBJECT_SPACE;
-                               else
-                                       grad->units = NSVG_USER_SPACE;
-                       } else if (strcmp(attr[i], "gradientTransform") == 0) {
-                               nsvg__parseTransform(grad->xform, attr[i + 1]);
-                       } else if (strcmp(attr[i], "cx") == 0) {
-                               grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "cy") == 0) {
-                               grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "r") == 0) {
-                               grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "fx") == 0) {
-                               grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "fy") == 0) {
-                               grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "x1") == 0) {
-                               grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "y1") == 0) {
-                               grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "x2") == 0) {
-                               grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "y2") == 0) {
-                               grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "spreadMethod") == 0) {
-                               if (strcmp(attr[i+1], "pad") == 0)
-                                       grad->spread = NSVG_SPREAD_PAD;
-                               else if (strcmp(attr[i+1], "reflect") == 0)
-                                       grad->spread = NSVG_SPREAD_REFLECT;
-                               else if (strcmp(attr[i+1], "repeat") == 0)
-                                       grad->spread = NSVG_SPREAD_REPEAT;
-                       } else if (strcmp(attr[i], "xlink:href") == 0) {
-                               const char *href = attr[i+1];
-                               strncpy(grad->ref, href+1, 62);
-                               grad->ref[62] = '\0';
-                       }
-               }
-       }
-
-       grad->next = p->gradients;
-       p->gradients = grad;
-}
-
-static void nsvg__parseGradientStop(NSVGparser* p, const char** attr)
-{
-       NSVGattrib* curAttr = nsvg__getAttr(p);
-       NSVGgradientData* grad;
-       NSVGgradientStop* stop;
-       int i, idx;
-
-       curAttr->stopOffset = 0;
-       curAttr->stopColor = 0;
-       curAttr->stopOpacity = 1.0f;
-
-       for (i = 0; attr[i]; i += 2) {
-               nsvg__parseAttr(p, attr[i], attr[i + 1]);
-       }
-
-       // Add stop to the last gradient.
-       grad = p->gradients;
-       if (grad == NULL) return;
-
-       grad->nstops++;
-       grad->stops = (NSVGgradientStop*)realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops);
-       if (grad->stops == NULL) return;
-
-       // Insert
-       idx = grad->nstops-1;
-       for (i = 0; i < grad->nstops-1; i++) {
-               if (curAttr->stopOffset < grad->stops[i].offset) {
-                       idx = i;
-                       break;
-               }
-       }
-       if (idx != grad->nstops-1) {
-               for (i = grad->nstops-1; i > idx; i--)
-                       grad->stops[i] = grad->stops[i-1];
-       }
-
-       stop = &grad->stops[idx];
-       stop->color = curAttr->stopColor;
-       stop->color |= (unsigned int)(curAttr->stopOpacity*255) << 24;
-       stop->offset = curAttr->stopOffset;
-}
-
-static void nsvg__startElement(void* ud, const char* el, const char** attr)
-{
-       NSVGparser* p = (NSVGparser*)ud;
-
-       if (p->defsFlag) {
-               // Skip everything but gradients in defs
-               if (strcmp(el, "linearGradient") == 0) {
-                       nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
-               } else if (strcmp(el, "radialGradient") == 0) {
-                       nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
-               } else if (strcmp(el, "stop") == 0) {
-                       nsvg__parseGradientStop(p, attr);
-               }
-               return;
-       }
-
-       if (strcmp(el, "g") == 0) {
-               nsvg__pushAttr(p);
-               nsvg__parseAttribs(p, attr);
-       } else if (strcmp(el, "path") == 0) {
-               if (p->pathFlag)        // Do not allow nested paths.
-                       return;
-               nsvg__pushAttr(p);
-               nsvg__parsePath(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "rect") == 0) {
-               nsvg__pushAttr(p);
-               nsvg__parseRect(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "circle") == 0) {
-               nsvg__pushAttr(p);
-               nsvg__parseCircle(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "ellipse") == 0) {
-               nsvg__pushAttr(p);
-               nsvg__parseEllipse(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "line") == 0)      {
-               nsvg__pushAttr(p);
-               nsvg__parseLine(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "polyline") == 0)  {
-               nsvg__pushAttr(p);
-               nsvg__parsePoly(p, attr, 0);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "polygon") == 0)  {
-               nsvg__pushAttr(p);
-               nsvg__parsePoly(p, attr, 1);
-               nsvg__popAttr(p);
-       } else  if (strcmp(el, "linearGradient") == 0) {
-               nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
-       } else if (strcmp(el, "radialGradient") == 0) {
-               nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
-       } else if (strcmp(el, "stop") == 0) {
-               nsvg__parseGradientStop(p, attr);
-       } else if (strcmp(el, "defs") == 0) {
-               p->defsFlag = 1;
-       } else if (strcmp(el, "svg") == 0) {
-               nsvg__parseSVG(p, attr);
-       }
-}
-
-static void nsvg__endElement(void* ud, const char* el)
-{
-       NSVGparser* p = (NSVGparser*)ud;
-
-       if (strcmp(el, "g") == 0) {
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "path") == 0) {
-               p->pathFlag = 0;
-       } else if (strcmp(el, "defs") == 0) {
-               p->defsFlag = 0;
-       }
-}
-
-static void nsvg__content(void* ud, const char* s)
-{
-       NSVG_NOTUSED(ud);
-       NSVG_NOTUSED(s);
-       // empty
-}
-
-static void nsvg__imageBounds(NSVGparser* p, float* bounds)
-{
-       NSVGshape* shape;
-       shape = p->image->shapes;
-       if (shape == NULL) {
-               bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0;
-               return;
-       }
-       bounds[0] = shape->bounds[0];
-       bounds[1] = shape->bounds[1];
-       bounds[2] = shape->bounds[2];
-       bounds[3] = shape->bounds[3];
-       for (shape = shape->next; shape != NULL; shape = shape->next) {
-               bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]);
-               bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]);
-               bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]);
-               bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]);
-       }
-}
-
-static float nsvg__viewAlign(float content, float container, int type)
-{
-       if (type == NSVG_ALIGN_MIN)
-               return 0;
-       else if (type == NSVG_ALIGN_MAX)
-               return container - content;
-       // mid
-       return (container - content) * 0.5f;
-}
-
-static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy)
-{
-       float t[6];
-       nsvg__xformSetTranslation(t, tx, ty);
-       nsvg__xformMultiply (grad->xform, t);
-
-       nsvg__xformSetScale(t, sx, sy);
-       nsvg__xformMultiply (grad->xform, t);
-}
-
-static void nsvg__scaleToViewbox(NSVGparser* p, const char* units)
-{
-       NSVGshape* shape;
-       NSVGpath* path;
-       float tx, ty, sx, sy, us, bounds[4], t[6], avgs;
-       int i;
-       float* pt;
-
-       // Guess image size if not set completely.
-       nsvg__imageBounds(p, bounds);
-
-       if (p->viewWidth == 0) {
-               if (p->image->width > 0) {
-                       p->viewWidth = p->image->width;
-               } else {
-                       p->viewMinx = bounds[0];
-                       p->viewWidth = bounds[2] - bounds[0];
-               }
-       }
-       if (p->viewHeight == 0) {
-               if (p->image->height > 0) {
-                       p->viewHeight = p->image->height;
-               } else {
-                       p->viewMiny = bounds[1];
-                       p->viewHeight = bounds[3] - bounds[1];
-               }
-       }
-       if (p->image->width == 0)
-               p->image->width = p->viewWidth;
-       if (p->image->height == 0)
-               p->image->height = p->viewHeight;
-
-       tx = -p->viewMinx;
-       ty = -p->viewMiny;
-       sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
-       sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
-       // Unit scaling
-       us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);
-
-       // Fix aspect ratio
-       if (p->alignType == NSVG_ALIGN_MEET) {
-               // fit whole image into viewbox
-               sx = sy = nsvg__minf(sx, sy);
-               tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
-               ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
-       } else if (p->alignType == NSVG_ALIGN_SLICE) {
-               // fill whole viewbox with image
-               sx = sy = nsvg__maxf(sx, sy);
-               tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
-               ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
-       }
-
-       // Transform
-       sx *= us;
-       sy *= us;
-       avgs = (sx+sy) / 2.0f;
-       for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
-               shape->bounds[0] = (shape->bounds[0] + tx) * sx;
-               shape->bounds[1] = (shape->bounds[1] + ty) * sy;
-               shape->bounds[2] = (shape->bounds[2] + tx) * sx;
-               shape->bounds[3] = (shape->bounds[3] + ty) * sy;
-               for (path = shape->paths; path != NULL; path = path->next) {
-                       path->bounds[0] = (path->bounds[0] + tx) * sx;
-                       path->bounds[1] = (path->bounds[1] + ty) * sy;
-                       path->bounds[2] = (path->bounds[2] + tx) * sx;
-                       path->bounds[3] = (path->bounds[3] + ty) * sy;
-                       for (i =0; i < path->npts; i++) {
-                               pt = &path->pts[i*2];
-                               pt[0] = (pt[0] + tx) * sx;
-                               pt[1] = (pt[1] + ty) * sy;
-                       }
-               }
-
-               if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) {
-                       nsvg__scaleGradient(shape->fill.gradient, tx,ty, sx,sy);
-                       memcpy(t, shape->fill.gradient->xform, sizeof(float)*6);
-                       nsvg__xformInverse(shape->fill.gradient->xform, t);
-               }
-               if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) {
-                       nsvg__scaleGradient(shape->stroke.gradient, tx,ty, sx,sy);
-                       memcpy(t, shape->stroke.gradient->xform, sizeof(float)*6);
-                       nsvg__xformInverse(shape->stroke.gradient->xform, t);
-               }
-
-               shape->strokeWidth *= avgs;
-               shape->strokeDashOffset *= avgs;
-               for (i = 0; i < shape->strokeDashCount; i++)
-                       shape->strokeDashArray[i] *= avgs;
-       }
-}
-
-NSVGimage* nsvgParse(char* input, const char* units, float dpi)
-{
-       NSVGparser* p;
-       NSVGimage* ret = 0;
-
-       p = nsvg__createParser();
-       if (p == NULL) {
-               return NULL;
-       }
-       p->dpi = dpi;
-
-       nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p);
-
-       // Scale to viewBox
-       nsvg__scaleToViewbox(p, units);
-
-       ret = p->image;
-       p->image = NULL;
-
-       nsvg__deleteParser(p);
-
-       return ret;
-}
-
-NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi)
-{
-       FILE* fp = NULL;
-       size_t size;
-       char* data = NULL;
-       NSVGimage* image = NULL;
-
-       fp = fopen(filename, "rb");
-       if (!fp) goto error;
-       fseek(fp, 0, SEEK_END);
-       size = ftell(fp);
-       fseek(fp, 0, SEEK_SET);
-       data = (char*)malloc(size+1);
-       if (data == NULL) goto error;
-       if (fread(data, 1, size, fp) != size) goto error;
-       data[size] = '\0';      // Must be null terminated.
-       fclose(fp);
-       image = nsvgParse(data, units, dpi);
-       free(data);
-
-       return image;
+static unsigned int nsvg__parseColorName(const char *str) {
+    int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor);
+
+    for (i = 0; i < ncolors; i++) {
+        if (strcmp(nsvg__colors[i].name, str) == 0) {
+            return nsvg__colors[i].color;
+        }
+    }
+
+    return NSVG_RGB(128, 128, 128);
+}
+
+static unsigned int nsvg__parseColor(const char *str) {
+    size_t len = 0;
+    while (*str == ' ')
+        ++str;
+    len = strlen(str);
+    if (len >= 1 && *str == '#')
+        return nsvg__parseColorHex(str);
+    else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(')
+        return nsvg__parseColorRGB(str);
+    return nsvg__parseColorName(str);
+}
+
+static float nsvg__parseOpacity(const char *str) {
+    float val = nsvg__atof(str);
+    if (val < 0.0f)
+        val = 0.0f;
+    if (val > 1.0f)
+        val = 1.0f;
+    return val;
+}
+
+static float nsvg__parseMiterLimit(const char *str) {
+    float val = nsvg__atof(str);
+    if (val < 0.0f)
+        val = 0.0f;
+    return val;
+}
+
+static int nsvg__parseUnits(const char *units) {
+    if (units[0] == 'p' && units[1] == 'x')
+        return NSVG_UNITS_PX;
+    else if (units[0] == 'p' && units[1] == 't')
+        return NSVG_UNITS_PT;
+    else if (units[0] == 'p' && units[1] == 'c')
+        return NSVG_UNITS_PC;
+    else if (units[0] == 'm' && units[1] == 'm')
+        return NSVG_UNITS_MM;
+    else if (units[0] == 'c' && units[1] == 'm')
+        return NSVG_UNITS_CM;
+    else if (units[0] == 'i' && units[1] == 'n')
+        return NSVG_UNITS_IN;
+    else if (units[0] == '%')
+        return NSVG_UNITS_PERCENT;
+    else if (units[0] == 'e' && units[1] == 'm')
+        return NSVG_UNITS_EM;
+    else if (units[0] == 'e' && units[1] == 'x')
+        return NSVG_UNITS_EX;
+    return NSVG_UNITS_USER;
+}
+
+static NSVGcoordinate nsvg__parseCoordinateRaw(const char *str) {
+    NSVGcoordinate coord = {0, NSVG_UNITS_USER};
+    char           buf[64];
+    coord.units = nsvg__parseUnits(nsvg__parseNumber(str, buf, 64));
+    coord.value = nsvg__atof(buf);
+    return coord;
+}
+
+static NSVGcoordinate nsvg__coord(float v, int units) {
+    NSVGcoordinate coord = {v, units};
+    return coord;
+}
+
+static float nsvg__parseCoordinate(NSVGparser *p, const char *str, float orig, float length) {
+    NSVGcoordinate coord = nsvg__parseCoordinateRaw(str);
+    return nsvg__convertToPixels(p, coord, orig, length);
+}
+
+static int nsvg__parseTransformArgs(const char *str, float *args, int maxNa, int *na) {
+    const char *end;
+    const char *ptr;
+    char        it[64];
+
+    *na = 0;
+    ptr = str;
+    while (*ptr && *ptr != '(')
+        ++ptr;
+    if (*ptr == 0)
+        return 1;
+    end = ptr;
+    while (*end && *end != ')')
+        ++end;
+    if (*end == 0)
+        return 1;
+
+    while (ptr < end) {
+        if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) {
+            if (*na >= maxNa)
+                return 0;
+            ptr           = nsvg__parseNumber(ptr, it, 64);
+            args[(*na)++] = (float)nsvg__atof(it);
+        } else {
+            ++ptr;
+        }
+    }
+    return (int)(end - str);
+}
+
+static int nsvg__parseMatrix(float *xform, const char *str) {
+    float t[6];
+    int   na  = 0;
+    int   len = nsvg__parseTransformArgs(str, t, 6, &na);
+    if (na != 6)
+        return len;
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseTranslate(float *xform, const char *str) {
+    float args[2];
+    float t[6];
+    int   na  = 0;
+    int   len = nsvg__parseTransformArgs(str, args, 2, &na);
+    if (na == 1)
+        args[1] = 0.0;
+
+    nsvg__xformSetTranslation(t, args[0], args[1]);
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseScale(float *xform, const char *str) {
+    float args[2];
+    int   na = 0;
+    float t[6];
+    int   len = nsvg__parseTransformArgs(str, args, 2, &na);
+    if (na == 1)
+        args[1] = args[0];
+    nsvg__xformSetScale(t, args[0], args[1]);
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseSkewX(float *xform, const char *str) {
+    float args[1];
+    int   na = 0;
+    float t[6];
+    int   len = nsvg__parseTransformArgs(str, args, 1, &na);
+    nsvg__xformSetSkewX(t, args[0] / 180.0f * NSVG_PI);
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseSkewY(float *xform, const char *str) {
+    float args[1];
+    int   na = 0;
+    float t[6];
+    int   len = nsvg__parseTransformArgs(str, args, 1, &na);
+    nsvg__xformSetSkewY(t, args[0] / 180.0f * NSVG_PI);
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseRotate(float *xform, const char *str) {
+    float args[3];
+    int   na = 0;
+    float m[6];
+    float t[6];
+    int   len = nsvg__parseTransformArgs(str, args, 3, &na);
+    if (na == 1)
+        args[1] = args[2] = 0.0f;
+    nsvg__xformIdentity(m);
+
+    if (na > 1) {
+        nsvg__xformSetTranslation(t, -args[1], -args[2]);
+        nsvg__xformMultiply(m, t);
+    }
+
+    nsvg__xformSetRotation(t, args[0] / 180.0f * NSVG_PI);
+    nsvg__xformMultiply(m, t);
+
+    if (na > 1) {
+        nsvg__xformSetTranslation(t, args[1], args[2]);
+        nsvg__xformMultiply(m, t);
+    }
+
+    memcpy(xform, m, sizeof(float) * 6);
+
+    return len;
+}
+
+static void nsvg__parseTransform(float *xform, const char *str) {
+    float t[6];
+    nsvg__xformIdentity(xform);
+    while (*str) {
+        if (strncmp(str, "matrix", 6) == 0)
+            str += nsvg__parseMatrix(t, str);
+        else if (strncmp(str, "translate", 9) == 0)
+            str += nsvg__parseTranslate(t, str);
+        else if (strncmp(str, "scale", 5) == 0)
+            str += nsvg__parseScale(t, str);
+        else if (strncmp(str, "rotate", 6) == 0)
+            str += nsvg__parseRotate(t, str);
+        else if (strncmp(str, "skewX", 5) == 0)
+            str += nsvg__parseSkewX(t, str);
+        else if (strncmp(str, "skewY", 5) == 0)
+            str += nsvg__parseSkewY(t, str);
+        else {
+            ++str;
+            continue;
+        }
+
+        nsvg__xformPremultiply(xform, t);
+    }
+}
+
+static void nsvg__parseUrl(char *id, const char *str) {
+    int i = 0;
+    str += 4; // "url(";
+    if (*str == '#')
+        str++;
+    while (i < 63 && *str != ')') {
+        id[i] = *str++;
+        i++;
+    }
+    id[i] = '\0';
+}
+
+static char nsvg__parseLineCap(const char *str) {
+    if (strcmp(str, "butt") == 0)
+        return NSVG_CAP_BUTT;
+    else if (strcmp(str, "round") == 0)
+        return NSVG_CAP_ROUND;
+    else if (strcmp(str, "square") == 0)
+        return NSVG_CAP_SQUARE;
+    // TODO: handle inherit.
+    return NSVG_CAP_BUTT;
+}
+
+static char nsvg__parseLineJoin(const char *str) {
+    if (strcmp(str, "miter") == 0)
+        return NSVG_JOIN_MITER;
+    else if (strcmp(str, "round") == 0)
+        return NSVG_JOIN_ROUND;
+    else if (strcmp(str, "bevel") == 0)
+        return NSVG_JOIN_BEVEL;
+    // TODO: handle inherit.
+    return NSVG_JOIN_MITER;
+}
+
+static char nsvg__parseFillRule(const char *str) {
+    if (strcmp(str, "nonzero") == 0)
+        return NSVG_FILLRULE_NONZERO;
+    else if (strcmp(str, "evenodd") == 0)
+        return NSVG_FILLRULE_EVENODD;
+    // TODO: handle inherit.
+    return NSVG_FILLRULE_NONZERO;
+}
+
+static const char *nsvg__getNextDashItem(const char *s, char *it) {
+    int n = 0;
+    it[0] = '\0';
+    // Skip white spaces and commas
+    while (nsvg__isspace(*s) || *s == ',')
+        s++;
+    // Advance until whitespace, comma or end.
+    while (*s && (!nsvg__isspace(*s) && *s != ',')) {
+        if (n < 63)
+            it[n++] = *s;
+        s++;
+    }
+    it[n++] = '\0';
+    return s;
+}
+
+static int nsvg__parseStrokeDashArray(NSVGparser *p, const char *str, float *strokeDashArray) {
+    char  item[64];
+    int   count = 0, i;
+    float sum   = 0.0f;
+
+    // Handle "none"
+    if (str[0] == 'n')
+        return 0;
+
+    // Parse dashes
+    while (*str) {
+        str = nsvg__getNextDashItem(str, item);
+        if (!*item)
+            break;
+        if (count < NSVG_MAX_DASHES)
+            strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
+    }
+
+    for (i = 0; i < count; i++)
+        sum += strokeDashArray[i];
+    if (sum <= 1e-6f)
+        count = 0;
+
+    return count;
+}
+
+static void nsvg__parseStyle(NSVGparser *p, const char *str);
+
+static int nsvg__parseAttr(NSVGparser *p, const char *name, const char *value) {
+    float       xform[6];
+    NSVGattrib *attr = nsvg__getAttr(p);
+    if (!attr)
+        return 0;
+
+    if (strcmp(name, "style") == 0) {
+        nsvg__parseStyle(p, value);
+    } else if (strcmp(name, "display") == 0) {
+        if (strcmp(value, "none") == 0)
+            attr->visible = 0;
+        // Don't reset ->visible on display:inline, one display:none hides the whole subtree
+
+    } else if (strcmp(name, "fill") == 0) {
+        if (strcmp(value, "none") == 0) {
+            attr->hasFill = 0;
+        } else if (strncmp(value, "url(", 4) == 0) {
+            attr->hasFill = 2;
+            nsvg__parseUrl(attr->fillGradient, value);
+        } else {
+            attr->hasFill   = 1;
+            attr->fillColor = nsvg__parseColor(value);
+        }
+    } else if (strcmp(name, "opacity") == 0) {
+        attr->opacity = nsvg__parseOpacity(value);
+    } else if (strcmp(name, "fill-opacity") == 0) {
+        attr->fillOpacity = nsvg__parseOpacity(value);
+    } else if (strcmp(name, "stroke") == 0) {
+        if (strcmp(value, "none") == 0) {
+            attr->hasStroke = 0;
+        } else if (strncmp(value, "url(", 4) == 0) {
+            attr->hasStroke = 2;
+            nsvg__parseUrl(attr->strokeGradient, value);
+        } else {
+            attr->hasStroke   = 1;
+            attr->strokeColor = nsvg__parseColor(value);
+        }
+    } else if (strcmp(name, "stroke-width") == 0) {
+        attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
+    } else if (strcmp(name, "stroke-dasharray") == 0) {
+        attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray);
+    } else if (strcmp(name, "stroke-dashoffset") == 0) {
+        attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
+    } else if (strcmp(name, "stroke-opacity") == 0) {
+        attr->strokeOpacity = nsvg__parseOpacity(value);
+    } else if (strcmp(name, "stroke-linecap") == 0) {
+        attr->strokeLineCap = nsvg__parseLineCap(value);
+    } else if (strcmp(name, "stroke-linejoin") == 0) {
+        attr->strokeLineJoin = nsvg__parseLineJoin(value);
+    } else if (strcmp(name, "stroke-miterlimit") == 0) {
+        attr->miterLimit = nsvg__parseMiterLimit(value);
+    } else if (strcmp(name, "fill-rule") == 0) {
+        attr->fillRule = nsvg__parseFillRule(value);
+    } else if (strcmp(name, "font-size") == 0) {
+        attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
+    } else if (strcmp(name, "transform") == 0) {
+        nsvg__parseTransform(xform, value);
+        nsvg__xformPremultiply(attr->xform, xform);
+    } else if (strcmp(name, "stop-color") == 0) {
+        attr->stopColor = nsvg__parseColor(value);
+    } else if (strcmp(name, "stop-opacity") == 0) {
+        attr->stopOpacity = nsvg__parseOpacity(value);
+    } else if (strcmp(name, "offset") == 0) {
+        attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f);
+    } else if (strcmp(name, "id") == 0) {
+        strncpy(attr->id, value, 63);
+        attr->id[63] = '\0';
+    } else {
+        return 0;
+    }
+    return 1;
+}
+
+static int nsvg__parseNameValue(NSVGparser *p, const char *start, const char *end) {
+    const char *str;
+    const char *val;
+    char        name[512];
+    char        value[512];
+    int         n;
+
+    str = start;
+    while (str < end && *str != ':')
+        ++str;
+
+    val = str;
+
+    // Right Trim
+    while (str > start && (*str == ':' || nsvg__isspace(*str)))
+        --str;
+    ++str;
+
+    n = (int)(str - start);
+    if (n > 511)
+        n = 511;
+    if (n)
+        memcpy(name, start, n);
+    name[n] = 0;
+
+    while (val < end && (*val == ':' || nsvg__isspace(*val)))
+        ++val;
+
+    n = (int)(end - val);
+    if (n > 511)
+        n = 511;
+    if (n)
+        memcpy(value, val, n);
+    value[n] = 0;
+
+    return nsvg__parseAttr(p, name, value);
+}
+
+static void nsvg__parseStyle(NSVGparser *p, const char *str) {
+    const char *start;
+    const char *end;
+
+    while (*str) {
+        // Left Trim
+        while (nsvg__isspace(*str))
+            ++str;
+        start = str;
+        while (*str && *str != ';')
+            ++str;
+        end = str;
+
+        // Right Trim
+        while (end > start && (*end == ';' || nsvg__isspace(*end)))
+            --end;
+        ++end;
+
+        nsvg__parseNameValue(p, start, end);
+        if (*str)
+            ++str;
+    }
+}
+
+static void nsvg__parseAttribs(NSVGparser *p, const char **attr) {
+    int i;
+    for (i = 0; attr[i]; i += 2) {
+        if (strcmp(attr[i], "style") == 0)
+            nsvg__parseStyle(p, attr[i + 1]);
+        else
+            nsvg__parseAttr(p, attr[i], attr[i + 1]);
+    }
+}
+
+static int nsvg__getArgsPerElement(char cmd) {
+    switch (cmd) {
+    case 'v':
+    case 'V':
+    case 'h':
+    case 'H':
+        return 1;
+    case 'm':
+    case 'M':
+    case 'l':
+    case 'L':
+    case 't':
+    case 'T':
+        return 2;
+    case 'q':
+    case 'Q':
+    case 's':
+    case 'S':
+        return 4;
+    case 'c':
+    case 'C':
+        return 6;
+    case 'a':
+    case 'A':
+        return 7;
+    }
+    return 0;
+}
+
+static void nsvg__pathMoveTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    if (rel) {
+        *cpx += args[0];
+        *cpy += args[1];
+    } else {
+        *cpx = args[0];
+        *cpy = args[1];
+    }
+    nsvg__moveTo(p, *cpx, *cpy);
+}
+
+static void nsvg__pathLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    if (rel) {
+        *cpx += args[0];
+        *cpy += args[1];
+    } else {
+        *cpx = args[0];
+        *cpy = args[1];
+    }
+    nsvg__lineTo(p, *cpx, *cpy);
+}
+
+static void nsvg__pathHLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    if (rel)
+        *cpx += args[0];
+    else
+        *cpx = args[0];
+    nsvg__lineTo(p, *cpx, *cpy);
+}
+
+static void nsvg__pathVLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    if (rel)
+        *cpy += args[0];
+    else
+        *cpy = args[0];
+    nsvg__lineTo(p, *cpx, *cpy);
+}
+
+static void nsvg__pathCubicBezTo(NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args,
+                                 int rel) {
+    float x2, y2, cx1, cy1, cx2, cy2;
+
+    if (rel) {
+        cx1 = *cpx + args[0];
+        cy1 = *cpy + args[1];
+        cx2 = *cpx + args[2];
+        cy2 = *cpy + args[3];
+        x2  = *cpx + args[4];
+        y2  = *cpy + args[5];
+    } else {
+        cx1 = args[0];
+        cy1 = args[1];
+        cx2 = args[2];
+        cy2 = args[3];
+        x2  = args[4];
+        y2  = args[5];
+    }
+
+    nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2);
+
+    *cpx2 = cx2;
+    *cpy2 = cy2;
+    *cpx  = x2;
+    *cpy  = y2;
+}
+
+static void nsvg__pathCubicBezShortTo(NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args,
+                                      int rel) {
+    float x1, y1, x2, y2, cx1, cy1, cx2, cy2;
+
+    x1 = *cpx;
+    y1 = *cpy;
+    if (rel) {
+        cx2 = *cpx + args[0];
+        cy2 = *cpy + args[1];
+        x2  = *cpx + args[2];
+        y2  = *cpy + args[3];
+    } else {
+        cx2 = args[0];
+        cy2 = args[1];
+        x2  = args[2];
+        y2  = args[3];
+    }
+
+    cx1 = 2 * x1 - *cpx2;
+    cy1 = 2 * y1 - *cpy2;
+
+    nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2);
+
+    *cpx2 = cx2;
+    *cpy2 = cy2;
+    *cpx  = x2;
+    *cpy  = y2;
+}
+
+static void nsvg__pathQuadBezTo(NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args, int rel) {
+    float x1, y1, x2, y2, cx, cy;
+    float cx1, cy1, cx2, cy2;
+
+    x1 = *cpx;
+    y1 = *cpy;
+    if (rel) {
+        cx = *cpx + args[0];
+        cy = *cpy + args[1];
+        x2 = *cpx + args[2];
+        y2 = *cpy + args[3];
+    } else {
+        cx = args[0];
+        cy = args[1];
+        x2 = args[2];
+        y2 = args[3];
+    }
+
+    // Convert to cubic bezier
+    cx1 = x1 + 2.0f / 3.0f * (cx - x1);
+    cy1 = y1 + 2.0f / 3.0f * (cy - y1);
+    cx2 = x2 + 2.0f / 3.0f * (cx - x2);
+    cy2 = y2 + 2.0f / 3.0f * (cy - y2);
+
+    nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2);
+
+    *cpx2 = cx;
+    *cpy2 = cy;
+    *cpx  = x2;
+    *cpy  = y2;
+}
+
+static void nsvg__pathQuadBezShortTo(NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args,
+                                     int rel) {
+    float x1, y1, x2, y2, cx, cy;
+    float cx1, cy1, cx2, cy2;
+
+    x1 = *cpx;
+    y1 = *cpy;
+    if (rel) {
+        x2 = *cpx + args[0];
+        y2 = *cpy + args[1];
+    } else {
+        x2 = args[0];
+        y2 = args[1];
+    }
+
+    cx = 2 * x1 - *cpx2;
+    cy = 2 * y1 - *cpy2;
+
+    // Convert to cubix bezier
+    cx1 = x1 + 2.0f / 3.0f * (cx - x1);
+    cy1 = y1 + 2.0f / 3.0f * (cy - y1);
+    cx2 = x2 + 2.0f / 3.0f * (cx - x2);
+    cy2 = y2 + 2.0f / 3.0f * (cy - y2);
+
+    nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2);
+
+    *cpx2 = cx;
+    *cpy2 = cy;
+    *cpx  = x2;
+    *cpy  = y2;
+}
+
+static float nsvg__sqr(float x) { return x * x; }
+static float nsvg__vmag(float x, float y) { return sqrtf(x * x + y * y); }
+
+static float nsvg__vecrat(float ux, float uy, float vx, float vy) {
+    return (ux * vx + uy * vy) / (nsvg__vmag(ux, uy) * nsvg__vmag(vx, vy));
+}
+
+static float nsvg__vecang(float ux, float uy, float vx, float vy) {
+    float r = nsvg__vecrat(ux, uy, vx, vy);
+    if (r < -1.0f)
+        r = -1.0f;
+    if (r > 1.0f)
+        r = 1.0f;
+    return ((ux * vy < uy * vx) ? -1.0f : 1.0f) * acosf(r);
+}
+
+static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    // Ported from canvg (https://code.google.com/p/canvg/)
+    float rx, ry, rotx;
+    float x1, y1, x2, y2, cx, cy, dx, dy, d;
+    float x1p, y1p, cxp, cyp, s, sa, sb;
+    float ux, uy, vx, vy, a1, da;
+    float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6];
+    float sinrx, cosrx;
+    int   fa, fs;
+    int   i, ndivs;
+    float hda, kappa;
+
+    rx   = fabsf(args[0]);                // y radius
+    ry   = fabsf(args[1]);                // x radius
+    rotx = args[2] / 180.0f * NSVG_PI;    // x rotation angle
+    fa   = fabsf(args[3]) > 1e-6 ? 1 : 0; // Large arc
+    fs   = fabsf(args[4]) > 1e-6 ? 1 : 0; // Sweep direction
+    x1   = *cpx;                          // start point
+    y1   = *cpy;
+    if (rel) { // end point
+        x2 = *cpx + args[5];
+        y2 = *cpy + args[6];
+    } else {
+        x2 = args[5];
+        y2 = args[6];
+    }
+
+    dx = x1 - x2;
+    dy = y1 - y2;
+    d  = sqrtf(dx * dx + dy * dy);
+    if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
+        // The arc degenerates to a line
+        nsvg__lineTo(p, x2, y2);
+        *cpx = x2;
+        *cpy = y2;
+        return;
+    }
+
+    sinrx = sinf(rotx);
+    cosrx = cosf(rotx);
+
+    // Convert to center point parameterization.
+    // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
+    // 1) Compute x1', y1'
+    x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
+    y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
+    d   = nsvg__sqr(x1p) / nsvg__sqr(rx) + nsvg__sqr(y1p) / nsvg__sqr(ry);
+    if (d > 1) {
+        d = sqrtf(d);
+        rx *= d;
+        ry *= d;
+    }
+    // 2) Compute cx', cy'
+    s  = 0.0f;
+    sa = nsvg__sqr(rx) * nsvg__sqr(ry) - nsvg__sqr(rx) * nsvg__sqr(y1p) - nsvg__sqr(ry) * nsvg__sqr(x1p);
+    sb = nsvg__sqr(rx) * nsvg__sqr(y1p) + nsvg__sqr(ry) * nsvg__sqr(x1p);
+    if (sa < 0.0f)
+        sa = 0.0f;
+    if (sb > 0.0f)
+        s = sqrtf(sa / sb);
+    if (fa == fs)
+        s = -s;
+    cxp = s * rx * y1p / ry;
+    cyp = s * -ry * x1p / rx;
+
+    // 3) Compute cx,cy from cx',cy'
+    cx = (x1 + x2) / 2.0f + cosrx * cxp - sinrx * cyp;
+    cy = (y1 + y2) / 2.0f + sinrx * cxp + cosrx * cyp;
+
+    // 4) Calculate theta1, and delta theta.
+    ux = (x1p - cxp) / rx;
+    uy = (y1p - cyp) / ry;
+    vx = (-x1p - cxp) / rx;
+    vy = (-y1p - cyp) / ry;
+    a1 = nsvg__vecang(1.0f, 0.0f, ux, uy); // Initial angle
+    da = nsvg__vecang(ux, uy, vx, vy);     // Delta angle
+
+    // if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
+    // if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;
+
+    if (fs == 0 && da > 0)
+        da -= 2 * NSVG_PI;
+    else if (fs == 1 && da < 0)
+        da += 2 * NSVG_PI;
+
+    // Approximate the arc using cubic spline segments.
+    t[0] = cosrx;
+    t[1] = sinrx;
+    t[2] = -sinrx;
+    t[3] = cosrx;
+    t[4] = cx;
+    t[5] = cy;
+
+    // Split arc into max 90 degree segments.
+    // The loop assumes an iteration per end point (including start and end), this +1.
+    ndivs = (int)(fabsf(da) / (NSVG_PI * 0.5f) + 1.0f);
+    hda   = (da / (float)ndivs) / 2.0f;
+    kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
+    if (da < 0.0f)
+        kappa = -kappa;
+
+    for (i = 0; i <= ndivs; i++) {
+        a  = a1 + da * ((float)i / (float)ndivs);
+        dx = cosf(a);
+        dy = sinf(a);
+        nsvg__xformPoint(&x, &y, dx * rx, dy * ry, t);                      // position
+        nsvg__xformVec(&tanx, &tany, -dy * rx * kappa, dx * ry * kappa, t); // tangent
+        if (i > 0)
+            nsvg__cubicBezTo(p, px + ptanx, py + ptany, x - tanx, y - tany, x, y);
+        px    = x;
+        py    = y;
+        ptanx = tanx;
+        ptany = tany;
+    }
+
+    *cpx = x2;
+    *cpy = y2;
+}
+
+static void nsvg__parsePath(NSVGparser *p, const char **attr) {
+    const char *s   = NULL;
+    char        cmd = '\0';
+    float       args[10];
+    int         nargs;
+    int         rargs = 0;
+    float       cpx, cpy, cpx2, cpy2;
+    const char *tmp[4];
+    char        closedFlag;
+    int         i;
+    char        item[64];
+
+    for (i = 0; attr[i]; i += 2) {
+        if (strcmp(attr[i], "d") == 0) {
+            s = attr[i + 1];
+        } else {
+            tmp[0] = attr[i];
+            tmp[1] = attr[i + 1];
+            tmp[2] = 0;
+            tmp[3] = 0;
+            nsvg__parseAttribs(p, tmp);
+        }
+    }
+
+    if (s) {
+        nsvg__resetPath(p);
+        cpx        = 0;
+        cpy        = 0;
+        cpx2       = 0;
+        cpy2       = 0;
+        closedFlag = 0;
+        nargs      = 0;
+
+        while (*s) {
+            item[0] = '\0';
+            if ((cmd == 'A' || cmd == 'a') && (nargs == 3 || nargs == 4))
+                s = nsvg__getNextPathItemWhenArcFlag(s, item);
+            if (!*item)
+                s = nsvg__getNextPathItem(s, item);
+            if (!*item)
+                break;
+            if (nsvg__isnum(item[0])) {
+                if (nargs < 10)
+                    args[nargs++] = (float)nsvg__atof(item);
+                if (nargs >= rargs) {
+                    switch (cmd) {
+                    case 'm':
+                    case 'M':
+                        nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0);
+                        // Moveto can be followed by multiple coordinate pairs,
+                        // which should be treated as linetos.
+                        cmd   = (cmd == 'm') ? 'l' : 'L';
+                        rargs = nsvg__getArgsPerElement(cmd);
+                        cpx2  = cpx;
+                        cpy2  = cpy;
+                        break;
+                    case 'l':
+                    case 'L':
+                        nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0);
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        break;
+                    case 'H':
+                    case 'h':
+                        nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0);
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        break;
+                    case 'V':
+                    case 'v':
+                        nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0);
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        break;
+                    case 'C':
+                    case 'c':
+                        nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0);
+                        break;
+                    case 'S':
+                    case 's':
+                        nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0);
+                        break;
+                    case 'Q':
+                    case 'q':
+                        nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0);
+                        break;
+                    case 'T':
+                    case 't':
+                        nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0);
+                        break;
+                    case 'A':
+                    case 'a':
+                        nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0);
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        break;
+                    default:
+                        if (nargs >= 2) {
+                            cpx  = args[nargs - 2];
+                            cpy  = args[nargs - 1];
+                            cpx2 = cpx;
+                            cpy2 = cpy;
+                        }
+                        break;
+                    }
+                    nargs = 0;
+                }
+            } else {
+                // New command
+                if (nargs) {
+                    NANOSVG_DEBUG("unfinished command '%c' %d/%d args\n", cmd, nargs, rargs);
+                }
+                cmd   = item[0];
+                rargs = nsvg__getArgsPerElement(cmd);
+                if (cmd == 'M' || cmd == 'm') {
+                    // Commit path.
+                    if (p->npts > 0)
+                        nsvg__addPath(p, closedFlag);
+                    // Start new subpath.
+                    nsvg__resetPath(p);
+                    closedFlag = 0;
+                    nargs      = 0;
+                } else if (cmd == 'Z' || cmd == 'z') {
+                    closedFlag = 1;
+                    // Commit path.
+                    if (p->npts > 0) {
+                        // Move current point to first point
+                        cpx  = p->pts[0];
+                        cpy  = p->pts[1];
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        nsvg__addPath(p, closedFlag);
+                    }
+                    // Start new subpath.
+                    nsvg__resetPath(p);
+                    nsvg__moveTo(p, cpx, cpy);
+                    closedFlag = 0;
+                    nargs      = 0;
+                }
+            }
+        }
+        // Commit path.
+        if (p->npts)
+            nsvg__addPath(p, closedFlag);
+    }
+
+    nsvg__addShape(p);
+}
+
+static void nsvg__parseRect(NSVGparser *p, const char **attr) {
+    float x  = 0.0f;
+    float y  = 0.0f;
+    float w  = 0.0f;
+    float h  = 0.0f;
+    float rx = -1.0f; // marks not set
+    float ry = -1.0f;
+    int   i;
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "x") == 0)
+                x = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "y") == 0)
+                y = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+            if (strcmp(attr[i], "width") == 0)
+                w = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p));
+            if (strcmp(attr[i], "height") == 0)
+                h = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p));
+            if (strcmp(attr[i], "rx") == 0)
+                rx = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p)));
+            if (strcmp(attr[i], "ry") == 0)
+                ry = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p)));
+        }
+    }
+
+    if (rx < 0.0f && ry > 0.0f)
+        rx = ry;
+    if (ry < 0.0f && rx > 0.0f)
+        ry = rx;
+    if (rx < 0.0f)
+        rx = 0.0f;
+    if (ry < 0.0f)
+        ry = 0.0f;
+    if (rx > w / 2.0f)
+        rx = w / 2.0f;
+    if (ry > h / 2.0f)
+        ry = h / 2.0f;
+
+    if (w != 0.0f && h != 0.0f) {
+        nsvg__resetPath(p);
+
+        if (rx < 0.00001f || ry < 0.0001f) {
+            nsvg__moveTo(p, x, y);
+            nsvg__lineTo(p, x + w, y);
+            nsvg__lineTo(p, x + w, y + h);
+            nsvg__lineTo(p, x, y + h);
+        } else {
+            // Rounded rectangle
+            nsvg__moveTo(p, x + rx, y);
+            nsvg__lineTo(p, x + w - rx, y);
+            nsvg__cubicBezTo(p, x + w - rx * (1 - NSVG_KAPPA90), y, x + w, y + ry * (1 - NSVG_KAPPA90), x + w, y + ry);
+            nsvg__lineTo(p, x + w, y + h - ry);
+            nsvg__cubicBezTo(p, x + w, y + h - ry * (1 - NSVG_KAPPA90), x + w - rx * (1 - NSVG_KAPPA90), y + h,
+                             x + w - rx, y + h);
+            nsvg__lineTo(p, x + rx, y + h);
+            nsvg__cubicBezTo(p, x + rx * (1 - NSVG_KAPPA90), y + h, x, y + h - ry * (1 - NSVG_KAPPA90), x, y + h - ry);
+            nsvg__lineTo(p, x, y + ry);
+            nsvg__cubicBezTo(p, x, y + ry * (1 - NSVG_KAPPA90), x + rx * (1 - NSVG_KAPPA90), y, x + rx, y);
+        }
+
+        nsvg__addPath(p, 1);
+
+        nsvg__addShape(p);
+    }
+}
+
+static void nsvg__parseCircle(NSVGparser *p, const char **attr) {
+    float cx = 0.0f;
+    float cy = 0.0f;
+    float r  = 0.0f;
+    int   i;
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "cx") == 0)
+                cx = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "cy") == 0)
+                cy = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+            if (strcmp(attr[i], "r") == 0)
+                r = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualLength(p)));
+        }
+    }
+
+    if (r > 0.0f) {
+        nsvg__resetPath(p);
+
+        nsvg__moveTo(p, cx + r, cy);
+        nsvg__cubicBezTo(p, cx + r, cy + r * NSVG_KAPPA90, cx + r * NSVG_KAPPA90, cy + r, cx, cy + r);
+        nsvg__cubicBezTo(p, cx - r * NSVG_KAPPA90, cy + r, cx - r, cy + r * NSVG_KAPPA90, cx - r, cy);
+        nsvg__cubicBezTo(p, cx - r, cy - r * NSVG_KAPPA90, cx - r * NSVG_KAPPA90, cy - r, cx, cy - r);
+        nsvg__cubicBezTo(p, cx + r * NSVG_KAPPA90, cy - r, cx + r, cy - r * NSVG_KAPPA90, cx + r, cy);
+
+        nsvg__addPath(p, 1);
+
+        nsvg__addShape(p);
+    }
+}
+
+static void nsvg__parseEllipse(NSVGparser *p, const char **attr) {
+    float cx = 0.0f;
+    float cy = 0.0f;
+    float rx = 0.0f;
+    float ry = 0.0f;
+    int   i;
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "cx") == 0)
+                cx = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "cy") == 0)
+                cy = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+            if (strcmp(attr[i], "rx") == 0)
+                rx = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p)));
+            if (strcmp(attr[i], "ry") == 0)
+                ry = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p)));
+        }
+    }
+
+    if (rx > 0.0f && ry > 0.0f) {
+
+        nsvg__resetPath(p);
+
+        nsvg__moveTo(p, cx + rx, cy);
+        nsvg__cubicBezTo(p, cx + rx, cy + ry * NSVG_KAPPA90, cx + rx * NSVG_KAPPA90, cy + ry, cx, cy + ry);
+        nsvg__cubicBezTo(p, cx - rx * NSVG_KAPPA90, cy + ry, cx - rx, cy + ry * NSVG_KAPPA90, cx - rx, cy);
+        nsvg__cubicBezTo(p, cx - rx, cy - ry * NSVG_KAPPA90, cx - rx * NSVG_KAPPA90, cy - ry, cx, cy - ry);
+        nsvg__cubicBezTo(p, cx + rx * NSVG_KAPPA90, cy - ry, cx + rx, cy - ry * NSVG_KAPPA90, cx + rx, cy);
+
+        nsvg__addPath(p, 1);
+
+        nsvg__addShape(p);
+    }
+}
+
+static void nsvg__parseLine(NSVGparser *p, const char **attr) {
+    float x1 = 0.0;
+    float y1 = 0.0;
+    float x2 = 0.0;
+    float y2 = 0.0;
+    int   i;
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "x1") == 0)
+                x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "y1") == 0)
+                y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+            if (strcmp(attr[i], "x2") == 0)
+                x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "y2") == 0)
+                y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+        }
+    }
+
+    nsvg__resetPath(p);
+
+    nsvg__moveTo(p, x1, y1);
+    nsvg__lineTo(p, x2, y2);
+
+    nsvg__addPath(p, 0);
+
+    nsvg__addShape(p);
+}
+
+static void nsvg__parsePoly(NSVGparser *p, const char **attr, int closeFlag) {
+    int         i;
+    const char *s;
+    float       args[2];
+    int         nargs, npts = 0;
+    char        item[64];
+
+    nsvg__resetPath(p);
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "points") == 0) {
+                s     = attr[i + 1];
+                nargs = 0;
+                while (*s) {
+                    s             = nsvg__getNextPathItem(s, item);
+                    args[nargs++] = (float)nsvg__atof(item);
+                    if (nargs >= 2) {
+                        if (npts == 0)
+                            nsvg__moveTo(p, args[0], args[1]);
+                        else
+                            nsvg__lineTo(p, args[0], args[1]);
+                        nargs = 0;
+                        npts++;
+                    }
+                }
+            }
+        }
+    }
+
+    nsvg__addPath(p, (char)closeFlag);
+
+    nsvg__addShape(p);
+}
+
+static void nsvg__parseSVG(NSVGparser *p, const char **attr) {
+    int i;
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "width") == 0) {
+                p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
+            } else if (strcmp(attr[i], "height") == 0) {
+                p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
+            } else if (strcmp(attr[i], "viewBox") == 0) {
+                const char *s = attr[i + 1];
+                char        buf[64];
+                s           = nsvg__parseNumber(s, buf, 64);
+                p->viewMinx = nsvg__atof(buf);
+                while (nsvg__isspace(*s) || *s == '%' || *s == ',')
+                    s++;
+                if (!*s)
+                    return;
+                s           = nsvg__parseNumber(s, buf, 64);
+                p->viewMiny = nsvg__atof(buf);
+                while (nsvg__isspace(*s) || *s == '%' || *s == ',')
+                    s++;
+                if (!*s)
+                    return;
+                s            = nsvg__parseNumber(s, buf, 64);
+                p->viewWidth = nsvg__atof(buf);
+                while (nsvg__isspace(*s) || *s == '%' || *s == ',')
+                    s++;
+                if (!*s)
+                    return;
+                s             = nsvg__parseNumber(s, buf, 64);
+                p->viewHeight = nsvg__atof(buf);
+            } else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
+                if (strstr(attr[i + 1], "none") != 0) {
+                    // No uniform scaling
+                    p->alignType = NSVG_ALIGN_NONE;
+                } else {
+                    // Parse X align
+                    if (strstr(attr[i + 1], "xMin") != 0)
+                        p->alignX = NSVG_ALIGN_MIN;
+                    else if (strstr(attr[i + 1], "xMid") != 0)
+                        p->alignX = NSVG_ALIGN_MID;
+                    else if (strstr(attr[i + 1], "xMax") != 0)
+                        p->alignX = NSVG_ALIGN_MAX;
+                    // Parse X align
+                    if (strstr(attr[i + 1], "yMin") != 0)
+                        p->alignY = NSVG_ALIGN_MIN;
+                    else if (strstr(attr[i + 1], "yMid") != 0)
+                        p->alignY = NSVG_ALIGN_MID;
+                    else if (strstr(attr[i + 1], "yMax") != 0)
+                        p->alignY = NSVG_ALIGN_MAX;
+                    // Parse meet/slice
+                    p->alignType = NSVG_ALIGN_MEET;
+                    if (strstr(attr[i + 1], "slice") != 0)
+                        p->alignType = NSVG_ALIGN_SLICE;
+                }
+            }
+        }
+    }
+}
+
+static void nsvg__parseGradient(NSVGparser *p, const char **attr, char type) {
+    int               i;
+    NSVGgradientData *grad = (NSVGgradientData *)malloc(sizeof(NSVGgradientData));
+    if (grad == NULL)
+        return;
+    memset(grad, 0, sizeof(NSVGgradientData));
+    grad->units = NSVG_OBJECT_SPACE;
+    grad->type  = type;
+    if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) {
+        grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
+        grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
+        grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT);
+        grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
+    } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) {
+        grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
+        grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
+        grad->radial.r  = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
+    }
+
+    nsvg__xformIdentity(grad->xform);
+
+    for (i = 0; attr[i]; i += 2) {
+        if (strcmp(attr[i], "id") == 0) {
+            strncpy(grad->id, attr[i + 1], 63);
+            grad->id[63] = '\0';
+        } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "gradientUnits") == 0) {
+                if (strcmp(attr[i + 1], "objectBoundingBox") == 0)
+                    grad->units = NSVG_OBJECT_SPACE;
+                else
+                    grad->units = NSVG_USER_SPACE;
+            } else if (strcmp(attr[i], "gradientTransform") == 0) {
+                nsvg__parseTransform(grad->xform, attr[i + 1]);
+            } else if (strcmp(attr[i], "cx") == 0) {
+                grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "cy") == 0) {
+                grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "r") == 0) {
+                grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "fx") == 0) {
+                grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "fy") == 0) {
+                grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "x1") == 0) {
+                grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "y1") == 0) {
+                grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "x2") == 0) {
+                grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "y2") == 0) {
+                grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "spreadMethod") == 0) {
+                if (strcmp(attr[i + 1], "pad") == 0)
+                    grad->spread = NSVG_SPREAD_PAD;
+                else if (strcmp(attr[i + 1], "reflect") == 0)
+                    grad->spread = NSVG_SPREAD_REFLECT;
+                else if (strcmp(attr[i + 1], "repeat") == 0)
+                    grad->spread = NSVG_SPREAD_REPEAT;
+            } else if (strcmp(attr[i], "xlink:href") == 0) {
+                const char *href = attr[i + 1];
+                strncpy(grad->ref, href + 1, 62);
+                grad->ref[62] = '\0';
+            }
+        }
+    }
+
+    grad->next   = p->gradients;
+    p->gradients = grad;
+}
+
+static void nsvg__parseGradientStop(NSVGparser *p, const char **attr) {
+    NSVGattrib       *curAttr = nsvg__getAttr(p);
+    NSVGgradientData *grad;
+    NSVGgradientStop *stop;
+    int               i, idx;
+
+    curAttr->stopOffset  = 0;
+    curAttr->stopColor   = 0;
+    curAttr->stopOpacity = 1.0f;
+
+    for (i = 0; attr[i]; i += 2) {
+        nsvg__parseAttr(p, attr[i], attr[i + 1]);
+    }
+
+    // Add stop to the last gradient.
+    grad = p->gradients;
+    if (grad == NULL)
+        return;
+
+    grad->nstops++;
+    grad->stops = (NSVGgradientStop *)realloc(grad->stops, sizeof(NSVGgradientStop) * grad->nstops);
+    if (grad->stops == NULL)
+        return;
+
+    // Insert
+    idx = grad->nstops - 1;
+    for (i = 0; i < grad->nstops - 1; i++) {
+        if (curAttr->stopOffset < grad->stops[i].offset) {
+            idx = i;
+            break;
+        }
+    }
+    if (idx != grad->nstops - 1) {
+        for (i = grad->nstops - 1; i > idx; i--)
+            grad->stops[i] = grad->stops[i - 1];
+    }
+
+    stop        = &grad->stops[idx];
+    stop->color = curAttr->stopColor;
+    stop->color |= (unsigned int)(curAttr->stopOpacity * 255) << 24;
+    stop->offset = curAttr->stopOffset;
+}
+
+static void nsvg__startElement(void *ud, const char *el, const char **attr) {
+    NSVGparser *p = (NSVGparser *)ud;
+
+    if (p->defsFlag) {
+        // Skip everything but gradients in defs
+        if (strcmp(el, "linearGradient") == 0) {
+            nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
+        } else if (strcmp(el, "radialGradient") == 0) {
+            nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
+        } else if (strcmp(el, "stop") == 0) {
+            nsvg__parseGradientStop(p, attr);
+        }
+        return;
+    }
+
+    if (strcmp(el, "g") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseAttribs(p, attr);
+    } else if (strcmp(el, "path") == 0) {
+        if (p->pathFlag) // Do not allow nested paths.
+            return;
+        nsvg__pushAttr(p);
+        nsvg__parsePath(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "rect") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseRect(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "circle") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseCircle(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "ellipse") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseEllipse(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "line") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseLine(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "polyline") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parsePoly(p, attr, 0);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "polygon") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parsePoly(p, attr, 1);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "linearGradient") == 0) {
+        nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
+    } else if (strcmp(el, "radialGradient") == 0) {
+        nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
+    } else if (strcmp(el, "stop") == 0) {
+        nsvg__parseGradientStop(p, attr);
+    } else if (strcmp(el, "defs") == 0) {
+        p->defsFlag = 1;
+    } else if (strcmp(el, "svg") == 0) {
+        nsvg__parseSVG(p, attr);
+    }
+}
+
+static void nsvg__endElement(void *ud, const char *el) {
+    NSVGparser *p = (NSVGparser *)ud;
+
+    if (strcmp(el, "g") == 0) {
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "path") == 0) {
+        p->pathFlag = 0;
+    } else if (strcmp(el, "defs") == 0) {
+        p->defsFlag = 0;
+    }
+}
+
+static void nsvg__content(void *ud, const char *s) {
+    NSVG_NOTUSED(ud);
+    NSVG_NOTUSED(s);
+    // empty
+}
+
+static void nsvg__imageBounds(NSVGparser *p, float *bounds) {
+    NSVGshape *shape;
+    shape = p->image->shapes;
+    if (shape == NULL) {
+        bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0;
+        return;
+    }
+    bounds[0] = shape->bounds[0];
+    bounds[1] = shape->bounds[1];
+    bounds[2] = shape->bounds[2];
+    bounds[3] = shape->bounds[3];
+    for (shape = shape->next; shape != NULL; shape = shape->next) {
+        bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]);
+        bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]);
+        bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]);
+        bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]);
+    }
+}
+
+static float nsvg__viewAlign(float content, float container, int type) {
+    if (type == NSVG_ALIGN_MIN)
+        return 0;
+    else if (type == NSVG_ALIGN_MAX)
+        return container - content;
+    // mid
+    return (container - content) * 0.5f;
+}
+
+static void nsvg__scaleGradient(NSVGgradient *grad, float tx, float ty, float sx, float sy) {
+    float t[6];
+    nsvg__xformSetTranslation(t, tx, ty);
+    nsvg__xformMultiply(grad->xform, t);
+
+    nsvg__xformSetScale(t, sx, sy);
+    nsvg__xformMultiply(grad->xform, t);
+}
+
+static void nsvg__scaleToViewbox(NSVGparser *p, const char *units) {
+    NSVGshape *shape;
+    NSVGpath  *path;
+    float      tx, ty, sx, sy, us, bounds[4], t[6], avgs;
+    int        i;
+    float     *pt;
+
+    // Guess image size if not set completely.
+    nsvg__imageBounds(p, bounds);
+
+    if (p->viewWidth == 0) {
+        if (p->image->width > 0) {
+            p->viewWidth = p->image->width;
+        } else {
+            p->viewMinx  = bounds[0];
+            p->viewWidth = bounds[2] - bounds[0];
+        }
+    }
+    if (p->viewHeight == 0) {
+        if (p->image->height > 0) {
+            p->viewHeight = p->image->height;
+        } else {
+            p->viewMiny   = bounds[1];
+            p->viewHeight = bounds[3] - bounds[1];
+        }
+    }
+    if (p->image->width == 0)
+        p->image->width = p->viewWidth;
+    if (p->image->height == 0)
+        p->image->height = p->viewHeight;
+
+    tx = -p->viewMinx;
+    ty = -p->viewMiny;
+    sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
+    sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
+    // Unit scaling
+    us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);
+
+    // Fix aspect ratio
+    if (p->alignType == NSVG_ALIGN_MEET) {
+        // fit whole image into viewbox
+        sx = sy = nsvg__minf(sx, sy);
+        tx += nsvg__viewAlign(p->viewWidth * sx, p->image->width, p->alignX) / sx;
+        ty += nsvg__viewAlign(p->viewHeight * sy, p->image->height, p->alignY) / sy;
+    } else if (p->alignType == NSVG_ALIGN_SLICE) {
+        // fill whole viewbox with image
+        sx = sy = nsvg__maxf(sx, sy);
+        tx += nsvg__viewAlign(p->viewWidth * sx, p->image->width, p->alignX) / sx;
+        ty += nsvg__viewAlign(p->viewHeight * sy, p->image->height, p->alignY) / sy;
+    }
+
+    // Transform
+    sx *= us;
+    sy *= us;
+    avgs = (sx + sy) / 2.0f;
+    for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
+        shape->bounds[0] = (shape->bounds[0] + tx) * sx;
+        shape->bounds[1] = (shape->bounds[1] + ty) * sy;
+        shape->bounds[2] = (shape->bounds[2] + tx) * sx;
+        shape->bounds[3] = (shape->bounds[3] + ty) * sy;
+        for (path = shape->paths; path != NULL; path = path->next) {
+            path->bounds[0] = (path->bounds[0] + tx) * sx;
+            path->bounds[1] = (path->bounds[1] + ty) * sy;
+            path->bounds[2] = (path->bounds[2] + tx) * sx;
+            path->bounds[3] = (path->bounds[3] + ty) * sy;
+            for (i = 0; i < path->npts; i++) {
+                pt    = &path->pts[i * 2];
+                pt[0] = (pt[0] + tx) * sx;
+                pt[1] = (pt[1] + ty) * sy;
+            }
+        }
+
+        if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) {
+            nsvg__scaleGradient(shape->fill.gradient, tx, ty, sx, sy);
+            memcpy(t, shape->fill.gradient->xform, sizeof(float) * 6);
+            nsvg__xformInverse(shape->fill.gradient->xform, t);
+        }
+        if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) {
+            nsvg__scaleGradient(shape->stroke.gradient, tx, ty, sx, sy);
+            memcpy(t, shape->stroke.gradient->xform, sizeof(float) * 6);
+            nsvg__xformInverse(shape->stroke.gradient->xform, t);
+        }
+
+        shape->strokeWidth *= avgs;
+        shape->strokeDashOffset *= avgs;
+        for (i = 0; i < shape->strokeDashCount; i++)
+            shape->strokeDashArray[i] *= avgs;
+    }
+}
+
+NSVGimage *nsvgParse(char *input, const char *units, float dpi) {
+    NSVGparser *p;
+    NSVGimage  *ret = 0;
+
+    p = nsvg__createParser();
+    if (p == NULL) {
+        return NULL;
+    }
+    p->dpi = dpi;
+
+    nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p);
+
+    // Scale to viewBox
+    nsvg__scaleToViewbox(p, units);
+
+    ret      = p->image;
+    p->image = NULL;
+
+    nsvg__deleteParser(p);
+
+    return ret;
+}
+
+NSVGimage *nsvgParseFromFile(const char *filename, const char *units, float dpi) {
+    FILE      *fp = NULL;
+    size_t     size;
+    char      *data  = NULL;
+    NSVGimage *image = NULL;
+
+    fp = fopen(filename, "rb");
+    if (!fp)
+        goto error;
+    fseek(fp, 0, SEEK_END);
+    size = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    data = (char *)malloc(size + 1);
+    if (data == NULL)
+        goto error;
+    if (fread(data, 1, size, fp) != size)
+        goto error;
+    data[size] = '\0'; // Must be null terminated.
+    fclose(fp);
+    image = nsvgParse(data, units, dpi);
+    free(data);
+
+    return image;
 
 error:
-       if (fp) fclose(fp);
-       if (data) free(data);
-       if (image) nsvgDelete(image);
-       return NULL;
+    if (fp)
+        fclose(fp);
+    if (data)
+        free(data);
+    if (image)
+        nsvgDelete(image);
+    return NULL;
 }
 
-NSVGpath* nsvgDuplicatePath(NSVGpath* p)
-{
-       NSVGpath* res = NULL;
+NSVGpath *nsvgDuplicatePath(NSVGpath *p) {
+    NSVGpath *res = NULL;
 
-       if (p == NULL)
-               return NULL;
+    if (p == NULL)
+        return NULL;
 
-       res = (NSVGpath*)malloc(sizeof(NSVGpath));
-       if (res == NULL) goto error;
-       memset(res, 0, sizeof(NSVGpath));
+    res = (NSVGpath *)malloc(sizeof(NSVGpath));
+    if (res == NULL)
+        goto error;
+    memset(res, 0, sizeof(NSVGpath));
 
-       res->pts = (float*)malloc(p->npts*2*sizeof(float));
-       if (res->pts == NULL) goto error;
-       memcpy(res->pts, p->pts, p->npts * sizeof(float) * 2);
-       res->npts = p->npts;
+    res->pts = (float *)malloc(p->npts * 2 * sizeof(float));
+    if (res->pts == NULL)
+        goto error;
+    memcpy(res->pts, p->pts, p->npts * sizeof(float) * 2);
+    res->npts = p->npts;
 
-       memcpy(res->bounds, p->bounds, sizeof(p->bounds));
+    memcpy(res->bounds, p->bounds, sizeof(p->bounds));
 
-       res->closed = p->closed;
+    res->closed = p->closed;
 
-       return res;
+    return res;
 
 error:
-       if (res != NULL) {
-               free(res->pts);
-               free(res);
-       }
-       return NULL;
-}
-
-void nsvgDelete(NSVGimage* image)
-{
-       NSVGshape *snext, *shape;
-       if (image == NULL) return;
-       shape = image->shapes;
-       while (shape != NULL) {
-               snext = shape->next;
-               nsvg__deletePaths(shape->paths);
-               nsvg__deletePaint(&shape->fill);
-               nsvg__deletePaint(&shape->stroke);
-               free(shape);
-               shape = snext;
-       }
-       free(image);
+    if (res != NULL) {
+        free(res->pts);
+        free(res);
+    }
+    return NULL;
+}
+
+void nsvgDelete(NSVGimage *image) {
+    NSVGshape *snext, *shape;
+    if (image == NULL)
+        return;
+    shape = image->shapes;
+    while (shape != NULL) {
+        snext = shape->next;
+        nsvg__deletePaths(shape->paths);
+        nsvg__deletePaint(&shape->fill);
+        nsvg__deletePaint(&shape->stroke);
+        free(shape);
+        shape = snext;
+    }
+    free(image);
 }
 
 #endif
index 681471ad946541651dfceb9ffb95d2f4967aedb5..1e37caaca2de54772ed2a66558a48d603822fb08 100644 (file)
 #include "vkvg_device_internal.h"
 #include "vkvg_context_internal.h"
 
-#define NANOSVG_IMPLEMENTATION // Expands implementation
+#define NANOSVG_IMPLEMENTATION // Expands implementation
 #include "nanosvg.h"
 #include "vkvg-svg.h"
 
-void _svg_set_color (VkvgContext ctx, uint32_t c, float alpha) {
-       float a = (c >> 24 & 255) / 255.f;
-       float b = (c >> 16 & 255) / 255.f;
-       float g = (c >> 8 & 255) / 255.f;
-       float r = (c & 255) / 255.f;
-       vkvg_set_source_rgba(ctx,r,g,b,a*alpha);
+void _svg_set_color(VkvgContext ctx, uint32_t c, float alpha) {
+    float a = (c >> 24 & 255) / 255.f;
+    float b = (c >> 16 & 255) / 255.f;
+    float g = (c >> 8 & 255) / 255.f;
+    float r = (c & 255) / 255.f;
+    vkvg_set_source_rgba(ctx, r, g, b, a * alpha);
 }
 
-VkvgSurface _svg_load (VkvgDevice dev, NSVGimage* svg) {
-       if (svg == NULL) {
-               LOG(VKVG_LOG_ERR, "nsvg error");
-               return NULL;
-       }
-       VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
-       if (!surf)
-               return NULL;
+VkvgSurface _svg_load(VkvgDevice dev, NSVGimage *svg) {
+    if (svg == NULL) {
+        LOG(VKVG_LOG_ERR, "nsvg error");
+        return NULL;
+    }
+    VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
+    if (!surf)
+        return NULL;
 
-       surf->width = (uint32_t)svg->width;
-       surf->height = (uint32_t)svg->height;
-       surf->newSurf = true;
+    surf->width   = (uint32_t)svg->width;
+    surf->height  = (uint32_t)svg->height;
+    surf->newSurf = true;
 
-       _create_surface_images (surf);
+    _create_surface_images(surf);
 
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_svg_render(svg, ctx, NULL);
-       vkvg_destroy(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_svg_render(svg, ctx, NULL);
+    vkvg_destroy(ctx);
 
-       nsvgDelete(svg);
+    nsvgDelete(svg);
 
-       surf->references = 1;
-       vkvg_device_reference (surf->dev);
+    surf->references = 1;
+    vkvg_device_reference(surf->dev);
 
-       return surf;
+    return surf;
 }
 
-VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, uint32_t width, uint32_t height, const char* filePath) {
-       return _svg_load(dev, nsvgParseFromFile(filePath, "px", (float)dev->hdpi));
+VkvgSurface vkvg_surface_create_from_svg(VkvgDevice dev, uint32_t width, uint32_t height, const char *filePath) {
+    return _svg_load(dev, nsvgParseFromFile(filePath, "px", (float)dev->hdpi));
 }
-VkvgSurface vkvg_surface_create_from_svg_fragment (VkvgDevice dev, uint32_t width, uint32_t height, char* svgFragment) {
-       return _svg_load(dev, nsvgParse(svgFragment, "px", (float)dev->hdpi));
+VkvgSurface vkvg_surface_create_from_svg_fragment(VkvgDevice dev, uint32_t width, uint32_t height, char *svgFragment) {
+    return _svg_load(dev, nsvgParse(svgFragment, "px", (float)dev->hdpi));
 }
-VkvgSvg vkvg_svg_load (const char* svgFilePath) {
-       return nsvgParseFromFile(svgFilePath, "px", 96.0f);
-}
-VkvgSvg vkvg_svg_load_fragment (char* svgFragment) {
-       return nsvgParse (svgFragment, "px", 96.0f);
-}
-void vkvg_svg_destroy (VkvgSvg svg) {
-       nsvgDelete(svg);
-}
-void vkvg_svg_get_dimensions (VkvgSvg svg, uint32_t* width, uint32_t* height) {
-       *width = (uint32_t)svg->width;
-       *height = (uint32_t)svg->height;
+VkvgSvg vkvg_svg_load(const char *svgFilePath) { return nsvgParseFromFile(svgFilePath, "px", 96.0f); }
+VkvgSvg vkvg_svg_load_fragment(char *svgFragment) { return nsvgParse(svgFragment, "px", 96.0f); }
+void    vkvg_svg_destroy(VkvgSvg svg) { nsvgDelete(svg); }
+void    vkvg_svg_get_dimensions(VkvgSvg svg, uint32_t *width, uint32_t *height) {
+    *width  = (uint32_t)svg->width;
+    *height = (uint32_t)svg->height;
 }
 
-void vkvg_svg_render (VkvgSvg svg, VkvgContext ctx, const char* subId){
-       NSVGshape* shape;
-       NSVGpath* path;
-       vkvg_save (ctx);
-
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-
-       vkvg_set_source_rgba(ctx,0.0,0.0,0.0,1);
-
-       for (shape = svg->shapes; shape != NULL; shape = shape->next) {
-               if (subId != NULL) {
-                       if (strcmp(shape->id, subId)!=0)
-                               continue;
-               }
-
-               vkvg_new_path(ctx);
-
-               float o = shape->opacity;
-
-               vkvg_set_line_width(ctx, shape->strokeWidth);
-
-               for (path = shape->paths; path != NULL; path = path->next) {
-                       float* p = path->pts;
-                       vkvg_move_to(ctx, p[0],p[1]);
-                       for (int i = 1; i < path->npts; i += 3) {
-                               p = &path->pts[i*2];
-                               vkvg_curve_to(ctx, p[0],p[1], p[2],p[3], p[4],p[5]);
-                       }
-                       if (path->closed)
-                               vkvg_close_path(ctx);
-               }
-
-               if (shape->fill.type == NSVG_PAINT_COLOR)
-                       _svg_set_color(ctx, shape->fill.color, o);
-               else if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT){
-                       NSVGgradient* g = shape->fill.gradient;
-                       _svg_set_color(ctx, g->stops[0].color, o);
-               }
-
-               if (shape->fill.type != NSVG_PAINT_NONE){
-                       if (shape->stroke.type == NSVG_PAINT_NONE){
-                               vkvg_fill(ctx);
-                               continue;
-                       }
-                       vkvg_fill_preserve (ctx);
-               }
-
-               if (shape->stroke.type == NSVG_PAINT_COLOR)
-                       _svg_set_color(ctx, shape->stroke.color, o);
-               else if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT){
-                       NSVGgradient* g = shape->stroke.gradient;
-                       _svg_set_color(ctx, g->stops[0].color, o);
-               }
-
-               vkvg_stroke(ctx);
-       }
-       vkvg_restore (ctx);
+void vkvg_svg_render(VkvgSvg svg, VkvgContext ctx, const char *subId) {
+    NSVGshape *shape;
+    NSVGpath  *path;
+    vkvg_save(ctx);
+
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+
+    vkvg_set_source_rgba(ctx, 0.0, 0.0, 0.0, 1);
+
+    for (shape = svg->shapes; shape != NULL; shape = shape->next) {
+        if (subId != NULL) {
+            if (strcmp(shape->id, subId) != 0)
+                continue;
+        }
+
+        vkvg_new_path(ctx);
+
+        float o = shape->opacity;
+
+        vkvg_set_line_width(ctx, shape->strokeWidth);
+
+        for (path = shape->paths; path != NULL; path = path->next) {
+            float *p = path->pts;
+            vkvg_move_to(ctx, p[0], p[1]);
+            for (int i = 1; i < path->npts; i += 3) {
+                p = &path->pts[i * 2];
+                vkvg_curve_to(ctx, p[0], p[1], p[2], p[3], p[4], p[5]);
+            }
+            if (path->closed)
+                vkvg_close_path(ctx);
+        }
+
+        if (shape->fill.type == NSVG_PAINT_COLOR)
+            _svg_set_color(ctx, shape->fill.color, o);
+        else if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT) {
+            NSVGgradient *g = shape->fill.gradient;
+            _svg_set_color(ctx, g->stops[0].color, o);
+        }
+
+        if (shape->fill.type != NSVG_PAINT_NONE) {
+            if (shape->stroke.type == NSVG_PAINT_NONE) {
+                vkvg_fill(ctx);
+                continue;
+            }
+            vkvg_fill_preserve(ctx);
+        }
+
+        if (shape->stroke.type == NSVG_PAINT_COLOR)
+            _svg_set_color(ctx, shape->stroke.color, o);
+        else if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT) {
+            NSVGgradient *g = shape->stroke.gradient;
+            _svg_set_color(ctx, g->stops[0].color, o);
+        }
+
+        vkvg_stroke(ctx);
+    }
+    vkvg_restore(ctx);
 }
index a70ee183f7b9a70e0ccb6ca02f27e4558a93fa2f..9184b5f7a1436e70890ed543ee18b1a146e9fdc6 100644 (file)
 #include "vkvg_record_internal.h"
 
 #ifdef VKVG_RECORDING
-void vkvg_start_recording (VkvgContext ctx) {
-       if (ctx->status)
-               return;
-       _start_recording(ctx);
+void vkvg_start_recording(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    _start_recording(ctx);
 }
-VkvgRecording vkvg_stop_recording (VkvgContext ctx) {
-       if (ctx->status)
-               return NULL;
-       return _stop_recording (ctx);
+VkvgRecording vkvg_stop_recording(VkvgContext ctx) {
+    if (ctx->status)
+        return NULL;
+    return _stop_recording(ctx);
 }
-uint32_t vkvg_recording_get_count (VkvgRecording rec) {
-       if (!rec)
-               return 0;
-       return rec->commandsCount;
+uint32_t vkvg_recording_get_count(VkvgRecording rec) {
+    if (!rec)
+        return 0;
+    return rec->commandsCount;
 }
-void* vkvg_recording_get_data (VkvgRecording rec) {
-       if (!rec)
-               return 0;
-       return rec->buffer;
+void *vkvg_recording_get_data(VkvgRecording rec) {
+    if (!rec)
+        return 0;
+    return rec->buffer;
 }
-void vkvg_recording_get_command (VkvgRecording rec, uint32_t cmdIndex, uint32_t* cmd, void** dataOffset) {
-       if (!rec)
-               return;
-       if (cmdIndex < rec->commandsCount) {
-               *cmd = rec->commands[cmdIndex].cmd;
-               *dataOffset = (void*)rec->commands[cmdIndex].dataOffset;
-       } else {
-               *cmd = 0;
-               *dataOffset = NULL;
-       }
-
+void vkvg_recording_get_command(VkvgRecording rec, uint32_t cmdIndex, uint32_t *cmd, void **dataOffset) {
+    if (!rec)
+        return;
+    if (cmdIndex < rec->commandsCount) {
+        *cmd        = rec->commands[cmdIndex].cmd;
+        *dataOffset = (void *)rec->commands[cmdIndex].dataOffset;
+    } else {
+        *cmd        = 0;
+        *dataOffset = NULL;
+    }
 }
-void vkvg_replay (VkvgContext ctx, VkvgRecording rec) {
-       if (!rec)
-               return;
-       for (uint32_t i=0; i<rec->commandsCount; i++)
-               _replay_command(ctx, rec, i);
+void vkvg_replay(VkvgContext ctx, VkvgRecording rec) {
+    if (!rec)
+        return;
+    for (uint32_t i = 0; i < rec->commandsCount; i++)
+        _replay_command(ctx, rec, i);
 }
-void vkvg_replay_command (VkvgContext ctx, VkvgRecording rec, uint32_t cmdIndex) {
-       if (!rec)
-               return;
-       if (cmdIndex < rec->commandsCount)
-               _replay_command(ctx, rec, cmdIndex);
+void vkvg_replay_command(VkvgContext ctx, VkvgRecording rec, uint32_t cmdIndex) {
+    if (!rec)
+        return;
+    if (cmdIndex < rec->commandsCount)
+        _replay_command(ctx, rec, cmdIndex);
 }
-void vkvg_recording_destroy (VkvgRecording rec) {
-       if (!rec)
-               return;
-       _destroy_recording(rec);
+void vkvg_recording_destroy(VkvgRecording rec) {
+    if (!rec)
+        return;
+    _destroy_recording(rec);
 }
 #endif
index 29c91c9e51bed665b1fa47b59240424a46bd9b15..e30363c0cb5ad0176cc07e07e97ac1cdd94587cf 100644 (file)
 #include "vkvg_record_internal.h"
 #include "vkvg_context_internal.h"
 
-#define VKVG_RECORDING_INIT_BUFFER_SIZE_TRESHOLD       64
-#define VKVG_RECORDING_INIT_BUFFER_SIZE                                1024
-#define VKVG_RECORDING_INIT_COMMANDS_COUNT                     64
+#define VKVG_RECORDING_INIT_BUFFER_SIZE_TRESHOLD 64
+#define VKVG_RECORDING_INIT_BUFFER_SIZE          1024
+#define VKVG_RECORDING_INIT_COMMANDS_COUNT       64
 
-vkvg_recording_t* _new_recording () {
+vkvg_recording_t *_new_recording() {
 
-       vkvg_recording_t* rec = (vkvg_recording_t*)calloc(1,sizeof (vkvg_recording_t));
+    vkvg_recording_t *rec = (vkvg_recording_t *)calloc(1, sizeof(vkvg_recording_t));
 
-       rec->commandsReservedCount      = VKVG_RECORDING_INIT_COMMANDS_COUNT;
-       rec->bufferReservedSize         = VKVG_RECORDING_INIT_BUFFER_SIZE;
-       rec->commands = (vkvg_record_t*)malloc(rec->commandsReservedCount * sizeof (vkvg_record_t));
-       rec->buffer = malloc (rec->bufferReservedSize);
+    rec->commandsReservedCount = VKVG_RECORDING_INIT_COMMANDS_COUNT;
+    rec->bufferReservedSize    = VKVG_RECORDING_INIT_BUFFER_SIZE;
+    rec->commands              = (vkvg_record_t *)malloc(rec->commandsReservedCount * sizeof(vkvg_record_t));
+    rec->buffer                = malloc(rec->bufferReservedSize);
 
-       return rec;
+    return rec;
 }
-void _destroy_recording (vkvg_recording_t* rec) {
-       if (!rec)
-               return;
-       for (uint32_t i=0; i<rec->commandsCount; i++) {
-               if (rec->commands[i].cmd == VKVG_CMD_SET_SOURCE)
-                       vkvg_pattern_destroy((VkvgPattern)(rec->buffer + rec->commands[i].dataOffset));
-               else if (rec->commands[i].cmd == VKVG_CMD_SET_SOURCE_SURFACE)
-                       vkvg_surface_destroy ((VkvgSurface)(rec->buffer + rec->commands[i].dataOffset + 2 * sizeof(float)));
-       }
-       free(rec->commands);
-       free(rec->buffer);
-       free(rec);
+void _destroy_recording(vkvg_recording_t *rec) {
+    if (!rec)
+        return;
+    for (uint32_t i = 0; i < rec->commandsCount; i++) {
+        if (rec->commands[i].cmd == VKVG_CMD_SET_SOURCE)
+            vkvg_pattern_destroy((VkvgPattern)(rec->buffer + rec->commands[i].dataOffset));
+        else if (rec->commands[i].cmd == VKVG_CMD_SET_SOURCE_SURFACE)
+            vkvg_surface_destroy((VkvgSurface)(rec->buffer + rec->commands[i].dataOffset + 2 * sizeof(float)));
+    }
+    free(rec->commands);
+    free(rec->buffer);
+    free(rec);
 }
-void _start_recording (VkvgContext ctx) {
-       if (ctx->recording)
-               _destroy_recording(ctx->recording);
-       ctx->recording = _new_recording();
+void _start_recording(VkvgContext ctx) {
+    if (ctx->recording)
+        _destroy_recording(ctx->recording);
+    ctx->recording = _new_recording();
 }
-vkvg_recording_t* _stop_recording (VkvgContext ctx) {
-       vkvg_recording_t* rec = ctx->recording;
-       if (!rec)
-               return NULL;
-       if (!rec->commandsCount) {
-               _destroy_recording(rec);
-               ctx->recording = NULL;
-               return NULL;
-       }
-       /*rec->buffer = realloc(rec->buffer, rec->bufferSize);
-       rec->commands = (vkvg_record_t*)realloc(rec->commands, rec->commandsCount * sizeof (vkvg_record_t));*/
-       ctx->recording = NULL;
-       return rec;
+vkvg_recording_t *_stop_recording(VkvgContext ctx) {
+    vkvg_recording_t *rec = ctx->recording;
+    if (!rec)
+        return NULL;
+    if (!rec->commandsCount) {
+        _destroy_recording(rec);
+        ctx->recording = NULL;
+        return NULL;
+    }
+    /*rec->buffer = realloc(rec->buffer, rec->bufferSize);
+    rec->commands = (vkvg_record_t*)realloc(rec->commands, rec->commandsCount * sizeof (vkvg_record_t));*/
+    ctx->recording = NULL;
+    return rec;
 }
-void* _ensure_recording_buffer (vkvg_recording_t* rec, size_t size) {
-       if (rec->bufferReservedSize >= rec->bufferSize - VKVG_RECORDING_INIT_BUFFER_SIZE_TRESHOLD - size) {
-               rec->bufferReservedSize += VKVG_RECORDING_INIT_BUFFER_SIZE;
-               rec->buffer = realloc(rec->buffer, rec->bufferReservedSize);
-       }
-       return rec->buffer + rec->bufferSize;
+void *_ensure_recording_buffer(vkvg_recording_t *rec, size_t size) {
+    if (rec->bufferReservedSize >= rec->bufferSize - VKVG_RECORDING_INIT_BUFFER_SIZE_TRESHOLD - size) {
+        rec->bufferReservedSize += VKVG_RECORDING_INIT_BUFFER_SIZE;
+        rec->buffer = realloc(rec->buffer, rec->bufferReservedSize);
+    }
+    return rec->buffer + rec->bufferSize;
 }
-void* _advance_recording_buffer_unchecked (vkvg_recording_t* rec, size_t size) {
-       rec->bufferSize += size;
-       return rec->buffer + rec->bufferSize;
+void *_advance_recording_buffer_unchecked(vkvg_recording_t *rec, size_t size) {
+    rec->bufferSize += size;
+    return rec->buffer + rec->bufferSize;
 }
 
-#define STORE_FLOATS(floatcount)                                                                               \
-       for (i=0; i<floatcount; i++) {                                                                          \
-               buff = _ensure_recording_buffer (rec, sizeof(float));                   \
-               *(float*)buff = (float)va_arg(args, double);                                    \
-               buff = _advance_recording_buffer_unchecked (rec, sizeof(float));\
-       }
-#define STORE_BOOLS(count)                                                                                             \
-       for (i=0; i<count; i++) {                                                                                       \
-               buff = _ensure_recording_buffer (rec, sizeof(bool));                    \
-               *(bool*)buff = (bool)va_arg(args, int);                                                 \
-               _advance_recording_buffer_unchecked (rec, sizeof(bool));                \
-       }
-#define STORE_UINT32(count)                                                                                            \
-       for (i=0; i<count; i++) {                                                                                       \
-               buff = _ensure_recording_buffer (rec, sizeof(uint32_t));                \
-               *(uint32_t*)buff = (uint32_t)va_arg(args, uint32_t);                            \
-               buff = _advance_recording_buffer_unchecked (rec, sizeof(uint32_t));     \
-       }
+#define STORE_FLOATS(floatcount)                                                                                       \
+    for (i = 0; i < floatcount; i++) {                                                                                 \
+        buff           = _ensure_recording_buffer(rec, sizeof(float));                                                 \
+        *(float *)buff = (float)va_arg(args, double);                                                                  \
+        buff           = _advance_recording_buffer_unchecked(rec, sizeof(float));                                      \
+    }
+#define STORE_BOOLS(count)                                                                                             \
+    for (i = 0; i < count; i++) {                                                                                      \
+        buff          = _ensure_recording_buffer(rec, sizeof(bool));                                                   \
+        *(bool *)buff = (bool)va_arg(args, int);                                                                       \
+        _advance_recording_buffer_unchecked(rec, sizeof(bool));                                                        \
+    }
+#define STORE_UINT32(count)                                                                                            \
+    for (i = 0; i < count; i++) {                                                                                      \
+        buff              = _ensure_recording_buffer(rec, sizeof(uint32_t));                                           \
+        *(uint32_t *)buff = (uint32_t)va_arg(args, uint32_t);                                                          \
+        buff              = _advance_recording_buffer_unchecked(rec, sizeof(uint32_t));                                \
+    }
 
-void _record (vkvg_recording_t* rec,...) {
-       va_list args;
-       va_start(args, rec);
+void _record(vkvg_recording_t *rec, ...) {
+    va_list args;
+    va_start(args, rec);
 
-       uint32_t cmd = va_arg(args, uint32_t);
+    uint32_t cmd = va_arg(args, uint32_t);
 
-       if (rec->commandsCount == rec->commandsReservedCount) {
-               rec->commandsReservedCount += VKVG_RECORDING_INIT_COMMANDS_COUNT;
-               rec->commands = (vkvg_record_t*)realloc(rec->commands, rec->commandsReservedCount * sizeof (vkvg_record_t));
-       }
-       vkvg_record_t* r = &rec->commands[rec->commandsCount++];
-       r->cmd = cmd;
-       r->dataOffset = rec->bufferSize;
+    if (rec->commandsCount == rec->commandsReservedCount) {
+        rec->commandsReservedCount += VKVG_RECORDING_INIT_COMMANDS_COUNT;
+        rec->commands = (vkvg_record_t *)realloc(rec->commands, rec->commandsReservedCount * sizeof(vkvg_record_t));
+    }
+    vkvg_record_t *r = &rec->commands[rec->commandsCount++];
+    r->cmd           = cmd;
+    r->dataOffset    = rec->bufferSize;
 
-       char* buff;
-       int i = 0;
+    char *buff;
+    int   i = 0;
 
-       if (cmd & VKVG_CMD_PATH_COMMANDS) {
-               if ((cmd & VKVG_CMD_PATHPROPS_COMMANDS) == VKVG_CMD_PATHPROPS_COMMANDS) {
-                       switch (r->cmd) {
-                       case VKVG_CMD_SET_LINE_WIDTH:
-                       case VKVG_CMD_SET_MITER_LIMIT:
-                               STORE_FLOATS(1);
-                               break;
-                       case VKVG_CMD_SET_LINE_JOIN:
-                               STORE_UINT32(1);
-                               break;
-                       case VKVG_CMD_SET_LINE_CAP:
-                               STORE_UINT32(1);
-                               break;
-                       case VKVG_CMD_SET_OPERATOR:
-                               STORE_UINT32(1);
-                               break;
-                       case VKVG_CMD_SET_FILL_RULE:
-                               STORE_UINT32(1);
-                               break;
-                       case VKVG_CMD_SET_DASH:
-                               break;
-                       }
-               } else {
-                       switch (cmd) {
-                       case VKVG_CMD_MOVE_TO:
-                       case VKVG_CMD_LINE_TO:
-                       case VKVG_CMD_REL_MOVE_TO:
-                       case VKVG_CMD_REL_LINE_TO:
-                               STORE_FLOATS(2);
-                               break;
-                       case VKVG_CMD_RECTANGLE:
-                       case VKVG_CMD_QUADRATIC_TO:
-                       case VKVG_CMD_REL_QUADRATIC_TO:
-                               STORE_FLOATS(4);
-                               break;
-                       case VKVG_CMD_ARC:
-                       case VKVG_CMD_ARC_NEG:
-                               STORE_FLOATS(5);
-                               break;
-                       case VKVG_CMD_CURVE_TO:
-                       case VKVG_CMD_REL_CURVE_TO:
-                               STORE_FLOATS(6);
-                               break;
-                       case VKVG_CMD_ELLIPTICAL_ARC_TO:
-                       case VKVG_CMD_REL_ELLIPTICAL_ARC_TO:
-                               STORE_FLOATS(5);
-                               STORE_BOOLS(2);
-                               break;
-                       case VKVG_CMD_NEW_PATH:
-                       case VKVG_CMD_NEW_SUB_PATH:
-                       case VKVG_CMD_CLOSE_PATH:
-                               break;
-                       }
-               }
-       } else if (!(r->cmd & VKVG_CMD_DRAW_COMMANDS)) {
-               if (r->cmd & VKVG_CMD_TRANSFORM_COMMANDS) {
-                       switch (r->cmd) {
-                       case VKVG_CMD_TRANSLATE:
-                       case VKVG_CMD_SCALE:
-                               STORE_FLOATS(2);
-                               break;
-                       case VKVG_CMD_ROTATE:
-                               STORE_FLOATS(1);
-                               break;
-                       case VKVG_CMD_IDENTITY_MATRIX:
-                               break;
-                       case VKVG_CMD_SET_MATRIX:
-                       case VKVG_CMD_TRANSFORM:
-                               {
-                                       buff = _ensure_recording_buffer (rec, sizeof(vkvg_matrix_t));
-                                       vkvg_matrix_t* mat = (vkvg_matrix_t*)va_arg(args, vkvg_matrix_t*);
-                                       memcpy(buff, mat, sizeof(vkvg_matrix_t));
-                                       buff = _advance_recording_buffer_unchecked (rec, sizeof(vkvg_matrix_t));
+    if (cmd & VKVG_CMD_PATH_COMMANDS) {
+        if ((cmd & VKVG_CMD_PATHPROPS_COMMANDS) == VKVG_CMD_PATHPROPS_COMMANDS) {
+            switch (r->cmd) {
+            case VKVG_CMD_SET_LINE_WIDTH:
+            case VKVG_CMD_SET_MITER_LIMIT:
+                STORE_FLOATS(1);
+                break;
+            case VKVG_CMD_SET_LINE_JOIN:
+                STORE_UINT32(1);
+                break;
+            case VKVG_CMD_SET_LINE_CAP:
+                STORE_UINT32(1);
+                break;
+            case VKVG_CMD_SET_OPERATOR:
+                STORE_UINT32(1);
+                break;
+            case VKVG_CMD_SET_FILL_RULE:
+                STORE_UINT32(1);
+                break;
+            case VKVG_CMD_SET_DASH:
+                break;
+            }
+        } else {
+            switch (cmd) {
+            case VKVG_CMD_MOVE_TO:
+            case VKVG_CMD_LINE_TO:
+            case VKVG_CMD_REL_MOVE_TO:
+            case VKVG_CMD_REL_LINE_TO:
+                STORE_FLOATS(2);
+                break;
+            case VKVG_CMD_RECTANGLE:
+            case VKVG_CMD_QUADRATIC_TO:
+            case VKVG_CMD_REL_QUADRATIC_TO:
+                STORE_FLOATS(4);
+                break;
+            case VKVG_CMD_ARC:
+            case VKVG_CMD_ARC_NEG:
+                STORE_FLOATS(5);
+                break;
+            case VKVG_CMD_CURVE_TO:
+            case VKVG_CMD_REL_CURVE_TO:
+                STORE_FLOATS(6);
+                break;
+            case VKVG_CMD_ELLIPTICAL_ARC_TO:
+            case VKVG_CMD_REL_ELLIPTICAL_ARC_TO:
+                STORE_FLOATS(5);
+                STORE_BOOLS(2);
+                break;
+            case VKVG_CMD_NEW_PATH:
+            case VKVG_CMD_NEW_SUB_PATH:
+            case VKVG_CMD_CLOSE_PATH:
+                break;
+            }
+        }
+    } else if (!(r->cmd & VKVG_CMD_DRAW_COMMANDS)) {
+        if (r->cmd & VKVG_CMD_TRANSFORM_COMMANDS) {
+            switch (r->cmd) {
+            case VKVG_CMD_TRANSLATE:
+            case VKVG_CMD_SCALE:
+                STORE_FLOATS(2);
+                break;
+            case VKVG_CMD_ROTATE:
+                STORE_FLOATS(1);
+                break;
+            case VKVG_CMD_IDENTITY_MATRIX:
+                break;
+            case VKVG_CMD_SET_MATRIX:
+            case VKVG_CMD_TRANSFORM: {
+                buff               = _ensure_recording_buffer(rec, sizeof(vkvg_matrix_t));
+                vkvg_matrix_t *mat = (vkvg_matrix_t *)va_arg(args, vkvg_matrix_t *);
+                memcpy(buff, mat, sizeof(vkvg_matrix_t));
+                buff = _advance_recording_buffer_unchecked(rec, sizeof(vkvg_matrix_t));
 
-                               }
-                               break;
-                       }
-               } else if (r->cmd & VKVG_CMD_PATTERN_COMMANDS) {
-                       switch (r->cmd) {
-                       case VKVG_CMD_SET_SOURCE_RGBA:
-                               STORE_FLOATS(4);
-                               break;
-                       case VKVG_CMD_SET_SOURCE_RGB:
-                               STORE_FLOATS(3);
-                               break;
-                       case VKVG_CMD_SET_SOURCE_COLOR:
-                               STORE_UINT32(1);
-                               break;
-                       case VKVG_CMD_SET_SOURCE:
-                               {
-                                       buff = _ensure_recording_buffer (rec, sizeof(VkvgPattern));
-                                       VkvgPattern pat = (VkvgPattern)va_arg(args, VkvgPattern);
-                                       vkvg_pattern_reference(pat);
-                                       VkvgPattern* pPat = (VkvgPattern*)buff;
-                                       *pPat = pat;
-                                       _advance_recording_buffer_unchecked (rec, sizeof(VkvgPattern));
-                               }
-                               break;
-                       case VKVG_CMD_SET_SOURCE_SURFACE:
-                               STORE_FLOATS(2);
-                               {
-                                       buff = _ensure_recording_buffer (rec, sizeof(VkvgSurface));
-                                       VkvgSurface surf = (VkvgSurface)va_arg(args, VkvgSurface);
-                                       vkvg_surface_reference(surf);
-                                       *(VkvgSurface*)buff = surf;
-                                       _advance_recording_buffer_unchecked (rec, sizeof(VkvgSurface));
-                               }
-                               break;
-                       }
-               } else if (r->cmd & VKVG_CMD_TEXT_COMMANDS) {
-                       char* txt;
-                       int txtLen;
-                       switch (r->cmd) {
-                       case VKVG_CMD_SET_FONT_SIZE:
-                               STORE_UINT32(1);
-                               break;
-                       case VKVG_CMD_SHOW_TEXT:
-                       case VKVG_CMD_SET_FONT_FACE:
-                               txt = (char*)va_arg(args, char*);
-                               txtLen = strlen(txt);
-                               buff = _ensure_recording_buffer (rec, txtLen * sizeof(char));
-                               strcpy(buff, txt);
-                               _advance_recording_buffer_unchecked (rec, txtLen * sizeof(char));
-                               break;
-                       case VKVG_CMD_SET_FONT_PATH:
-                               break;
-                       }
-               }
-       }
-       va_end(args);
+            } break;
+            }
+        } else if (r->cmd & VKVG_CMD_PATTERN_COMMANDS) {
+            switch (r->cmd) {
+            case VKVG_CMD_SET_SOURCE_RGBA:
+                STORE_FLOATS(4);
+                break;
+            case VKVG_CMD_SET_SOURCE_RGB:
+                STORE_FLOATS(3);
+                break;
+            case VKVG_CMD_SET_SOURCE_COLOR:
+                STORE_UINT32(1);
+                break;
+            case VKVG_CMD_SET_SOURCE: {
+                buff            = _ensure_recording_buffer(rec, sizeof(VkvgPattern));
+                VkvgPattern pat = (VkvgPattern)va_arg(args, VkvgPattern);
+                vkvg_pattern_reference(pat);
+                VkvgPattern *pPat = (VkvgPattern *)buff;
+                *pPat             = pat;
+                _advance_recording_buffer_unchecked(rec, sizeof(VkvgPattern));
+            } break;
+            case VKVG_CMD_SET_SOURCE_SURFACE:
+                STORE_FLOATS(2);
+                {
+                    buff             = _ensure_recording_buffer(rec, sizeof(VkvgSurface));
+                    VkvgSurface surf = (VkvgSurface)va_arg(args, VkvgSurface);
+                    vkvg_surface_reference(surf);
+                    *(VkvgSurface *)buff = surf;
+                    _advance_recording_buffer_unchecked(rec, sizeof(VkvgSurface));
+                }
+                break;
+            }
+        } else if (r->cmd & VKVG_CMD_TEXT_COMMANDS) {
+            char *txt;
+            int   txtLen;
+            switch (r->cmd) {
+            case VKVG_CMD_SET_FONT_SIZE:
+                STORE_UINT32(1);
+                break;
+            case VKVG_CMD_SHOW_TEXT:
+            case VKVG_CMD_SET_FONT_FACE:
+                txt    = (char *)va_arg(args, char *);
+                txtLen = strlen(txt);
+                buff   = _ensure_recording_buffer(rec, txtLen * sizeof(char));
+                strcpy(buff, txt);
+                _advance_recording_buffer_unchecked(rec, txtLen * sizeof(char));
+                break;
+            case VKVG_CMD_SET_FONT_PATH:
+                break;
+            }
+        }
+    }
+    va_end(args);
 }
-void _replay_command (VkvgContext ctx, VkvgRecording rec, uint32_t index) {
-       vkvg_record_t* r = &rec->commands[index];
-       float* floats = (float*)(rec->buffer + r->dataOffset);
-       uint32_t* uints = (uint32_t*)floats;
-       if (r->cmd&VKVG_CMD_PATH_COMMANDS) {
-               if ((r->cmd&VKVG_CMD_RELATIVE_COMMANDS)==VKVG_CMD_RELATIVE_COMMANDS) {
-                       switch (r->cmd) {
-                       case VKVG_CMD_REL_MOVE_TO:
-                               vkvg_rel_move_to(ctx, floats[0], floats[1]);
-                               return;
-                       case VKVG_CMD_REL_LINE_TO:
-                               vkvg_rel_line_to(ctx, floats[0], floats[1]);
-                               return;
-                       case VKVG_CMD_REL_CURVE_TO:
-                               vkvg_rel_curve_to (ctx, floats[0], floats[1], floats[2], floats[3], floats[4], floats[5]);
-                               return;
-                       case VKVG_CMD_REL_QUADRATIC_TO:
-                               vkvg_rel_quadratic_to (ctx, floats[0], floats[1], floats[2], floats[3]);
-                               return;
-                       case VKVG_CMD_REL_ELLIPTICAL_ARC_TO:
-                               {
-                                       bool* flags = (bool*)&floats[5];
-                                       vkvg_rel_elliptic_arc_to (ctx, floats[0], floats[1], flags[0], flags[1], floats[2], floats[3], floats[4]);
-                               }
-                               return;
-                       }
-               }else if ((r->cmd&VKVG_CMD_PATHPROPS_COMMANDS)==VKVG_CMD_PATHPROPS_COMMANDS) {
-                       switch (r->cmd) {
-                       case VKVG_CMD_SET_LINE_WIDTH:
-                               vkvg_set_line_width (ctx, floats[0]);
-                               return;
-                       case VKVG_CMD_SET_MITER_LIMIT:
-                               vkvg_set_miter_limit (ctx, floats[0]);
-                               return;
-                       case VKVG_CMD_SET_LINE_JOIN:
-                               vkvg_set_line_join (ctx, (vkvg_line_join_t)uints[0]);
-                               return;
-                       case VKVG_CMD_SET_LINE_CAP:
-                               vkvg_set_line_cap (ctx, (vkvg_line_cap_t)uints[0]);
-                               return;
-                       case VKVG_CMD_SET_OPERATOR:
-                               vkvg_set_operator (ctx, (vkvg_operator_t)uints[0]);
-                               return;
-                       case VKVG_CMD_SET_FILL_RULE:
-                               vkvg_set_fill_rule (ctx, (vkvg_fill_rule_t)uints[0]);
-                               return;
-                       case VKVG_CMD_SET_DASH:
-                               vkvg_set_dash(ctx, &floats[2],  uints[0], floats[1]);
-                               return;
-                       }
-               } else {
-                       switch (r->cmd) {
-                       case VKVG_CMD_NEW_PATH:
-                               vkvg_new_path (ctx);
-                               return;
-                       case VKVG_CMD_NEW_SUB_PATH:
-                               vkvg_new_sub_path (ctx);
-                               return;
-                       case VKVG_CMD_CLOSE_PATH:
-                               vkvg_close_path (ctx);
-                               return;
-                       case VKVG_CMD_RECTANGLE:
-                               vkvg_rectangle (ctx, floats[0], floats[1], floats[2], floats[3]);
-                               return;
-                       case VKVG_CMD_ARC:
-                               vkvg_arc (ctx, floats[0], floats[1], floats[2], floats[3], floats[4]);
-                               return;
-                       case VKVG_CMD_ARC_NEG:
-                               vkvg_arc (ctx, floats[0], floats[1], floats[2], floats[3], floats[4]);
-                               return;
-                       /*case VKVG_CMD_ELLIPSE:
-                               vkvg_ellipse (ctx, floats[0], floats[1], floats[2], floats[3], floats[4]);
-                               break;*/
-                       case VKVG_CMD_MOVE_TO:
-                               vkvg_move_to(ctx, floats[0], floats[1]);
-                               return;
-                       case VKVG_CMD_LINE_TO:
-                               vkvg_line_to(ctx, floats[0], floats[1]);
-                               return;
-                       case VKVG_CMD_CURVE_TO:
-                               vkvg_curve_to (ctx, floats[0], floats[1], floats[2], floats[3], floats[4], floats[5]);
-                               return;
-                       case VKVG_CMD_ELLIPTICAL_ARC_TO:
-                               {
-                                       bool* flags = (bool*)&floats[5];
-                                       vkvg_elliptic_arc_to (ctx, floats[0], floats[1], flags[0], flags[1], floats[2], floats[3], floats[4]);
-                               }
-                               return;
-                       case VKVG_CMD_QUADRATIC_TO:
-                               vkvg_quadratic_to (ctx, floats[0], floats[1], floats[2], floats[3]);
-                               return;
-                       }
-               }
-       } else if (r->cmd & VKVG_CMD_DRAW_COMMANDS) {
-               switch (r->cmd) {
-               case VKVG_CMD_PAINT:
-                       vkvg_paint (ctx);
-                       return;
-               case VKVG_CMD_FILL:
-                       vkvg_fill (ctx);
-                       return;
-               case VKVG_CMD_STROKE:
-                       vkvg_stroke (ctx);
-                       return;
-               case VKVG_CMD_CLIP:
-                       vkvg_clip (ctx);
-                       return;
-               case VKVG_CMD_CLEAR:
-                       vkvg_clear (ctx);
-                       return;
-               case VKVG_CMD_FILL_PRESERVE:
-                       vkvg_fill_preserve (ctx);
-                       return;
-               case VKVG_CMD_STROKE_PRESERVE:
-                       vkvg_stroke_preserve (ctx);
-                       return;
-               case VKVG_CMD_CLIP_PRESERVE:
-                       vkvg_clip_preserve (ctx);
-                       return;
-               }
-       } else if (r->cmd & VKVG_CMD_TRANSFORM_COMMANDS) {
-               switch (r->cmd) {
-               case VKVG_CMD_TRANSLATE:
-                       vkvg_translate (ctx, floats[0], floats[1]);
-                       return;
-               case VKVG_CMD_SCALE:
-                       vkvg_scale (ctx, floats[0], floats[1]);
-                       return;
-               case VKVG_CMD_ROTATE:
-                       vkvg_rotate (ctx, floats[0]);
-                       return;
-               case VKVG_CMD_IDENTITY_MATRIX:
-                       vkvg_identity_matrix (ctx);
-                       return;
-               case VKVG_CMD_TRANSFORM:
-                       {
-                               vkvg_matrix_t* mat = (vkvg_matrix_t*)&floats[0];
-                               vkvg_transform (ctx, mat);
-                       }
-                       return;
-               case VKVG_CMD_SET_MATRIX:
-                       {
-                               vkvg_matrix_t* mat = (vkvg_matrix_t*)&floats[0];
-                               vkvg_set_matrix (ctx, mat);
-                       }
-                       return;
-               }
-       } else if (r->cmd & VKVG_CMD_PATTERN_COMMANDS) {
-               switch (r->cmd) {
-               case VKVG_CMD_SET_SOURCE_RGB:
-                       vkvg_set_source_rgb (ctx, floats[0], floats[1], floats[2]);
-                       return;
-               case VKVG_CMD_SET_SOURCE_RGBA:
-                       vkvg_set_source_rgba (ctx, floats[0], floats[1], floats[2], floats[3]);
-                       return;
-               case VKVG_CMD_SET_SOURCE_COLOR:
-                       vkvg_set_source_color (ctx, uints[0]);
-                       return;
-               case VKVG_CMD_SET_SOURCE:
-                       {
-                               VkvgPattern pat = *((VkvgPattern*)(rec->buffer + r->dataOffset));
-                               vkvg_set_source (ctx, pat);
-                       }
-                       return;
-               case VKVG_CMD_SET_SOURCE_SURFACE:
-                       {
-                               VkvgSurface surf = *((VkvgSurface*)&floats[2]);
-                               vkvg_set_source_surface (ctx, surf, floats[0], floats[1]);
-                       }
-                       return;
-               }
-       } else if (r->cmd & VKVG_CMD_TEXT_COMMANDS) {
-               char* txt = (char*)floats;
-               switch (r->cmd) {
-               case VKVG_CMD_SET_FONT_SIZE:
-                       vkvg_set_font_size (ctx, uints[0]);
-                       return;
-               case VKVG_CMD_SET_FONT_FACE:
-                       vkvg_select_font_face (ctx, txt);
-                       return;
-               /*case VKVG_CMD_SET_FONT_PATH:
-                       vkvg_load_font_from_path (ctx, txt);
-                       return; */
-               case VKVG_CMD_SHOW_TEXT:
-                       vkvg_show_text (ctx, txt);
-                       return;
-               }
-       } else {
-               switch (r->cmd) {
-               case VKVG_CMD_SAVE:
-                       vkvg_save (ctx);
-                       return;
-               case VKVG_CMD_RESTORE:
-                       vkvg_restore (ctx);
-                       return;
-               }
-       }
-       LOG(VKVG_LOG_ERR, "[REPLAY] unimplemented command: %.4x\n", r->cmd);
+void _replay_command(VkvgContext ctx, VkvgRecording rec, uint32_t index) {
+    vkvg_record_t *r      = &rec->commands[index];
+    float         *floats = (float *)(rec->buffer + r->dataOffset);
+    uint32_t      *uints  = (uint32_t *)floats;
+    if (r->cmd & VKVG_CMD_PATH_COMMANDS) {
+        if ((r->cmd & VKVG_CMD_RELATIVE_COMMANDS) == VKVG_CMD_RELATIVE_COMMANDS) {
+            switch (r->cmd) {
+            case VKVG_CMD_REL_MOVE_TO:
+                vkvg_rel_move_to(ctx, floats[0], floats[1]);
+                return;
+            case VKVG_CMD_REL_LINE_TO:
+                vkvg_rel_line_to(ctx, floats[0], floats[1]);
+                return;
+            case VKVG_CMD_REL_CURVE_TO:
+                vkvg_rel_curve_to(ctx, floats[0], floats[1], floats[2], floats[3], floats[4], floats[5]);
+                return;
+            case VKVG_CMD_REL_QUADRATIC_TO:
+                vkvg_rel_quadratic_to(ctx, floats[0], floats[1], floats[2], floats[3]);
+                return;
+            case VKVG_CMD_REL_ELLIPTICAL_ARC_TO: {
+                bool *flags = (bool *)&floats[5];
+                vkvg_rel_elliptic_arc_to(ctx, floats[0], floats[1], flags[0], flags[1], floats[2], floats[3],
+                                         floats[4]);
+            }
+                return;
+            }
+        } else if ((r->cmd & VKVG_CMD_PATHPROPS_COMMANDS) == VKVG_CMD_PATHPROPS_COMMANDS) {
+            switch (r->cmd) {
+            case VKVG_CMD_SET_LINE_WIDTH:
+                vkvg_set_line_width(ctx, floats[0]);
+                return;
+            case VKVG_CMD_SET_MITER_LIMIT:
+                vkvg_set_miter_limit(ctx, floats[0]);
+                return;
+            case VKVG_CMD_SET_LINE_JOIN:
+                vkvg_set_line_join(ctx, (vkvg_line_join_t)uints[0]);
+                return;
+            case VKVG_CMD_SET_LINE_CAP:
+                vkvg_set_line_cap(ctx, (vkvg_line_cap_t)uints[0]);
+                return;
+            case VKVG_CMD_SET_OPERATOR:
+                vkvg_set_operator(ctx, (vkvg_operator_t)uints[0]);
+                return;
+            case VKVG_CMD_SET_FILL_RULE:
+                vkvg_set_fill_rule(ctx, (vkvg_fill_rule_t)uints[0]);
+                return;
+            case VKVG_CMD_SET_DASH:
+                vkvg_set_dash(ctx, &floats[2], uints[0], floats[1]);
+                return;
+            }
+        } else {
+            switch (r->cmd) {
+            case VKVG_CMD_NEW_PATH:
+                vkvg_new_path(ctx);
+                return;
+            case VKVG_CMD_NEW_SUB_PATH:
+                vkvg_new_sub_path(ctx);
+                return;
+            case VKVG_CMD_CLOSE_PATH:
+                vkvg_close_path(ctx);
+                return;
+            case VKVG_CMD_RECTANGLE:
+                vkvg_rectangle(ctx, floats[0], floats[1], floats[2], floats[3]);
+                return;
+            case VKVG_CMD_ARC:
+                vkvg_arc(ctx, floats[0], floats[1], floats[2], floats[3], floats[4]);
+                return;
+            case VKVG_CMD_ARC_NEG:
+                vkvg_arc(ctx, floats[0], floats[1], floats[2], floats[3], floats[4]);
+                return;
+            /*case VKVG_CMD_ELLIPSE:
+                vkvg_ellipse (ctx, floats[0], floats[1], floats[2], floats[3], floats[4]);
+                break;*/
+            case VKVG_CMD_MOVE_TO:
+                vkvg_move_to(ctx, floats[0], floats[1]);
+                return;
+            case VKVG_CMD_LINE_TO:
+                vkvg_line_to(ctx, floats[0], floats[1]);
+                return;
+            case VKVG_CMD_CURVE_TO:
+                vkvg_curve_to(ctx, floats[0], floats[1], floats[2], floats[3], floats[4], floats[5]);
+                return;
+            case VKVG_CMD_ELLIPTICAL_ARC_TO: {
+                bool *flags = (bool *)&floats[5];
+                vkvg_elliptic_arc_to(ctx, floats[0], floats[1], flags[0], flags[1], floats[2], floats[3], floats[4]);
+            }
+                return;
+            case VKVG_CMD_QUADRATIC_TO:
+                vkvg_quadratic_to(ctx, floats[0], floats[1], floats[2], floats[3]);
+                return;
+            }
+        }
+    } else if (r->cmd & VKVG_CMD_DRAW_COMMANDS) {
+        switch (r->cmd) {
+        case VKVG_CMD_PAINT:
+            vkvg_paint(ctx);
+            return;
+        case VKVG_CMD_FILL:
+            vkvg_fill(ctx);
+            return;
+        case VKVG_CMD_STROKE:
+            vkvg_stroke(ctx);
+            return;
+        case VKVG_CMD_CLIP:
+            vkvg_clip(ctx);
+            return;
+        case VKVG_CMD_CLEAR:
+            vkvg_clear(ctx);
+            return;
+        case VKVG_CMD_FILL_PRESERVE:
+            vkvg_fill_preserve(ctx);
+            return;
+        case VKVG_CMD_STROKE_PRESERVE:
+            vkvg_stroke_preserve(ctx);
+            return;
+        case VKVG_CMD_CLIP_PRESERVE:
+            vkvg_clip_preserve(ctx);
+            return;
+        }
+    } else if (r->cmd & VKVG_CMD_TRANSFORM_COMMANDS) {
+        switch (r->cmd) {
+        case VKVG_CMD_TRANSLATE:
+            vkvg_translate(ctx, floats[0], floats[1]);
+            return;
+        case VKVG_CMD_SCALE:
+            vkvg_scale(ctx, floats[0], floats[1]);
+            return;
+        case VKVG_CMD_ROTATE:
+            vkvg_rotate(ctx, floats[0]);
+            return;
+        case VKVG_CMD_IDENTITY_MATRIX:
+            vkvg_identity_matrix(ctx);
+            return;
+        case VKVG_CMD_TRANSFORM: {
+            vkvg_matrix_t *mat = (vkvg_matrix_t *)&floats[0];
+            vkvg_transform(ctx, mat);
+        }
+            return;
+        case VKVG_CMD_SET_MATRIX: {
+            vkvg_matrix_t *mat = (vkvg_matrix_t *)&floats[0];
+            vkvg_set_matrix(ctx, mat);
+        }
+            return;
+        }
+    } else if (r->cmd & VKVG_CMD_PATTERN_COMMANDS) {
+        switch (r->cmd) {
+        case VKVG_CMD_SET_SOURCE_RGB:
+            vkvg_set_source_rgb(ctx, floats[0], floats[1], floats[2]);
+            return;
+        case VKVG_CMD_SET_SOURCE_RGBA:
+            vkvg_set_source_rgba(ctx, floats[0], floats[1], floats[2], floats[3]);
+            return;
+        case VKVG_CMD_SET_SOURCE_COLOR:
+            vkvg_set_source_color(ctx, uints[0]);
+            return;
+        case VKVG_CMD_SET_SOURCE: {
+            VkvgPattern pat = *((VkvgPattern *)(rec->buffer + r->dataOffset));
+            vkvg_set_source(ctx, pat);
+        }
+            return;
+        case VKVG_CMD_SET_SOURCE_SURFACE: {
+            VkvgSurface surf = *((VkvgSurface *)&floats[2]);
+            vkvg_set_source_surface(ctx, surf, floats[0], floats[1]);
+        }
+            return;
+        }
+    } else if (r->cmd & VKVG_CMD_TEXT_COMMANDS) {
+        char *txt = (char *)floats;
+        switch (r->cmd) {
+        case VKVG_CMD_SET_FONT_SIZE:
+            vkvg_set_font_size(ctx, uints[0]);
+            return;
+        case VKVG_CMD_SET_FONT_FACE:
+            vkvg_select_font_face(ctx, txt);
+            return;
+        /*case VKVG_CMD_SET_FONT_PATH:
+            vkvg_load_font_from_path (ctx, txt);
+            return;    */
+        case VKVG_CMD_SHOW_TEXT:
+            vkvg_show_text(ctx, txt);
+            return;
+        }
+    } else {
+        switch (r->cmd) {
+        case VKVG_CMD_SAVE:
+            vkvg_save(ctx);
+            return;
+        case VKVG_CMD_RESTORE:
+            vkvg_restore(ctx);
+            return;
+        }
+    }
+    LOG(VKVG_LOG_ERR, "[REPLAY] unimplemented command: %.4x\n", r->cmd);
 }
-
index c18801ac7eb9925e90e8b24d6cb15588a709803b..fcc905f283a917ead5e31e83832c62db5bb063d0 100644 (file)
 #include "vkvg.h"
 #include "vkvg_internal.h"
 
-#define VKVG_CMD_SAVE                          0x0001
-#define VKVG_CMD_RESTORE                       0x0002
-
-#define VKVG_CMD_PATH_COMMANDS         0x0100
-#define VKVG_CMD_DRAW_COMMANDS         0x0200
-#define VKVG_CMD_RELATIVE_COMMANDS     (0x0400|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_PATHPROPS_COMMANDS    (0x1000|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_PRESERVE_COMMANDS     (0x0400|VKVG_CMD_DRAW_COMMANDS)
-#define VKVG_CMD_PATTERN_COMMANDS      0x0800
-#define VKVG_CMD_TRANSFORM_COMMANDS    0x2000
-#define VKVG_CMD_TEXT_COMMANDS         0x4000
-
-#define VKVG_CMD_NEW_PATH                      (0x0001|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_NEW_SUB_PATH          (0x0002|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_CLOSE_PATH                    (0x0003|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_MOVE_TO                       (0x0004|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_LINE_TO                       (0x0005|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_RECTANGLE                     (0x0006|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_ARC                           (0x0007|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_ARC_NEG                       (0x0008|VKVG_CMD_PATH_COMMANDS)
-//#define VKVG_CMD_ELLIPSE                     (0x0009|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_CURVE_TO                      (0x000A|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_QUADRATIC_TO          (0x000B|VKVG_CMD_PATH_COMMANDS)
-#define VKVG_CMD_ELLIPTICAL_ARC_TO     (0x000C|VKVG_CMD_PATH_COMMANDS)
-
-#define VKVG_CMD_SET_LINE_WIDTH                (0x0001|VKVG_CMD_PATHPROPS_COMMANDS)
-#define VKVG_CMD_SET_MITER_LIMIT       (0x0002|VKVG_CMD_PATHPROPS_COMMANDS)
-#define VKVG_CMD_SET_LINE_JOIN         (0x0003|VKVG_CMD_PATHPROPS_COMMANDS)
-#define VKVG_CMD_SET_LINE_CAP          (0x0004|VKVG_CMD_PATHPROPS_COMMANDS)
-#define VKVG_CMD_SET_OPERATOR          (0x0005|VKVG_CMD_PATHPROPS_COMMANDS)
-#define VKVG_CMD_SET_FILL_RULE         (0x0006|VKVG_CMD_PATHPROPS_COMMANDS)
-#define VKVG_CMD_SET_DASH                      (0x0007|VKVG_CMD_PATHPROPS_COMMANDS)
-
-#define VKVG_CMD_TRANSLATE                     (0x0001|VKVG_CMD_TRANSFORM_COMMANDS)
-#define VKVG_CMD_ROTATE                                (0x0002|VKVG_CMD_TRANSFORM_COMMANDS)
-#define VKVG_CMD_SCALE                         (0x0003|VKVG_CMD_TRANSFORM_COMMANDS)
-#define VKVG_CMD_TRANSFORM                     (0x0004|VKVG_CMD_TRANSFORM_COMMANDS)
-#define VKVG_CMD_IDENTITY_MATRIX       (0x0005|VKVG_CMD_TRANSFORM_COMMANDS)
-
-#define VKVG_CMD_SET_MATRIX                    (0x0006|VKVG_CMD_TRANSFORM_COMMANDS)
-
-#define VKVG_CMD_SET_FONT_SIZE         (0x0001|VKVG_CMD_TEXT_COMMANDS)
-#define VKVG_CMD_SET_FONT_FACE         (0x0002|VKVG_CMD_TEXT_COMMANDS)
-#define VKVG_CMD_SET_FONT_PATH         (0x0003|VKVG_CMD_TEXT_COMMANDS)
-#define VKVG_CMD_SHOW_TEXT                     (0x0004|VKVG_CMD_TEXT_COMMANDS)
-
-#define VKVG_CMD_REL_MOVE_TO                   (VKVG_CMD_MOVE_TO                       |VKVG_CMD_RELATIVE_COMMANDS)
-#define VKVG_CMD_REL_LINE_TO                   (VKVG_CMD_LINE_TO                       |VKVG_CMD_RELATIVE_COMMANDS)
-#define VKVG_CMD_REL_CURVE_TO                  (VKVG_CMD_CURVE_TO                      |VKVG_CMD_RELATIVE_COMMANDS)
-#define VKVG_CMD_REL_QUADRATIC_TO              (VKVG_CMD_QUADRATIC_TO          |VKVG_CMD_RELATIVE_COMMANDS)
-#define VKVG_CMD_REL_ELLIPTICAL_ARC_TO (VKVG_CMD_ELLIPTICAL_ARC_TO     |VKVG_CMD_RELATIVE_COMMANDS)
-
-#define VKVG_CMD_PAINT                         (0x0001|VKVG_CMD_DRAW_COMMANDS)
-#define VKVG_CMD_FILL                          (0x0002|VKVG_CMD_DRAW_COMMANDS)
-#define VKVG_CMD_STROKE                                (0x0003|VKVG_CMD_DRAW_COMMANDS)
-#define VKVG_CMD_CLIP                          (0x0004|VKVG_CMD_DRAW_COMMANDS)
-#define VKVG_CMD_RESET_CLIP                    (0x0005|VKVG_CMD_DRAW_COMMANDS)
-#define VKVG_CMD_CLEAR                         (0x0006|VKVG_CMD_DRAW_COMMANDS)
-
-#define VKVG_CMD_FILL_PRESERVE         (VKVG_CMD_FILL  |VKVG_CMD_PRESERVE_COMMANDS)
-#define VKVG_CMD_STROKE_PRESERVE       (VKVG_CMD_STROKE        |VKVG_CMD_PRESERVE_COMMANDS)
-#define VKVG_CMD_CLIP_PRESERVE         (VKVG_CMD_CLIP  |VKVG_CMD_PRESERVE_COMMANDS)
-
-#define VKVG_CMD_SET_SOURCE_RGB                (0x0001|VKVG_CMD_PATTERN_COMMANDS)
-#define VKVG_CMD_SET_SOURCE_RGBA       (0x0002|VKVG_CMD_PATTERN_COMMANDS)
-#define VKVG_CMD_SET_SOURCE_COLOR      (0x0003|VKVG_CMD_PATTERN_COMMANDS)
-#define VKVG_CMD_SET_SOURCE                    (0x0004|VKVG_CMD_PATTERN_COMMANDS)
-#define VKVG_CMD_SET_SOURCE_SURFACE    (0x0005|VKVG_CMD_PATTERN_COMMANDS)
-
-
-
-typedef struct _vkvg_record_t{
-       uint16_t        cmd;
-       size_t          dataOffset;
-}vkvg_record_t;
-
-typedef struct _vkvg_recording_t{
-       vkvg_record_t*  commands;
-       uint32_t                commandsCount;
-       uint32_t                commandsReservedCount;
-       size_t                  bufferSize;
-       size_t                  bufferReservedSize;
-       char*                   buffer;
-}vkvg_recording_t;
-
-
-void                           _start_recording        (VkvgContext ctx);
-vkvg_recording_t*      _stop_recording         (VkvgContext ctx);
-void                           _destroy_recording      (vkvg_recording_t* rec);
-void                           _replay_command         (VkvgContext ctx, VkvgRecording rec, uint32_t index);
-void                           _record                         (vkvg_recording_t* rec,...);
-
-#define RECORD(ctx,...) {\
-       if (ctx->recording)     {\
-               _record (ctx->recording,__VA_ARGS__);\
-               return;\
-       }\
-}
-#define RECORD2(ctx,...) {\
-       if (ctx->recording)     {\
-               _record (ctx->recording,__VA_ARGS__);\
-               return 0;\
-       }\
-}
-
+#define VKVG_CMD_SAVE               0x0001
+#define VKVG_CMD_RESTORE            0x0002
+
+#define VKVG_CMD_PATH_COMMANDS      0x0100
+#define VKVG_CMD_DRAW_COMMANDS      0x0200
+#define VKVG_CMD_RELATIVE_COMMANDS  (0x0400 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_PATHPROPS_COMMANDS (0x1000 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_PRESERVE_COMMANDS  (0x0400 | VKVG_CMD_DRAW_COMMANDS)
+#define VKVG_CMD_PATTERN_COMMANDS   0x0800
+#define VKVG_CMD_TRANSFORM_COMMANDS 0x2000
+#define VKVG_CMD_TEXT_COMMANDS      0x4000
+
+#define VKVG_CMD_NEW_PATH           (0x0001 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_NEW_SUB_PATH       (0x0002 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_CLOSE_PATH         (0x0003 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_MOVE_TO            (0x0004 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_LINE_TO            (0x0005 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_RECTANGLE          (0x0006 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_ARC                (0x0007 | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_ARC_NEG            (0x0008 | VKVG_CMD_PATH_COMMANDS)
+// #define VKVG_CMD_ELLIPSE                    (0x0009|VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_CURVE_TO              (0x000A | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_QUADRATIC_TO          (0x000B | VKVG_CMD_PATH_COMMANDS)
+#define VKVG_CMD_ELLIPTICAL_ARC_TO     (0x000C | VKVG_CMD_PATH_COMMANDS)
+
+#define VKVG_CMD_SET_LINE_WIDTH        (0x0001 | VKVG_CMD_PATHPROPS_COMMANDS)
+#define VKVG_CMD_SET_MITER_LIMIT       (0x0002 | VKVG_CMD_PATHPROPS_COMMANDS)
+#define VKVG_CMD_SET_LINE_JOIN         (0x0003 | VKVG_CMD_PATHPROPS_COMMANDS)
+#define VKVG_CMD_SET_LINE_CAP          (0x0004 | VKVG_CMD_PATHPROPS_COMMANDS)
+#define VKVG_CMD_SET_OPERATOR          (0x0005 | VKVG_CMD_PATHPROPS_COMMANDS)
+#define VKVG_CMD_SET_FILL_RULE         (0x0006 | VKVG_CMD_PATHPROPS_COMMANDS)
+#define VKVG_CMD_SET_DASH              (0x0007 | VKVG_CMD_PATHPROPS_COMMANDS)
+
+#define VKVG_CMD_TRANSLATE             (0x0001 | VKVG_CMD_TRANSFORM_COMMANDS)
+#define VKVG_CMD_ROTATE                (0x0002 | VKVG_CMD_TRANSFORM_COMMANDS)
+#define VKVG_CMD_SCALE                 (0x0003 | VKVG_CMD_TRANSFORM_COMMANDS)
+#define VKVG_CMD_TRANSFORM             (0x0004 | VKVG_CMD_TRANSFORM_COMMANDS)
+#define VKVG_CMD_IDENTITY_MATRIX       (0x0005 | VKVG_CMD_TRANSFORM_COMMANDS)
+
+#define VKVG_CMD_SET_MATRIX            (0x0006 | VKVG_CMD_TRANSFORM_COMMANDS)
+
+#define VKVG_CMD_SET_FONT_SIZE         (0x0001 | VKVG_CMD_TEXT_COMMANDS)
+#define VKVG_CMD_SET_FONT_FACE         (0x0002 | VKVG_CMD_TEXT_COMMANDS)
+#define VKVG_CMD_SET_FONT_PATH         (0x0003 | VKVG_CMD_TEXT_COMMANDS)
+#define VKVG_CMD_SHOW_TEXT             (0x0004 | VKVG_CMD_TEXT_COMMANDS)
+
+#define VKVG_CMD_REL_MOVE_TO           (VKVG_CMD_MOVE_TO | VKVG_CMD_RELATIVE_COMMANDS)
+#define VKVG_CMD_REL_LINE_TO           (VKVG_CMD_LINE_TO | VKVG_CMD_RELATIVE_COMMANDS)
+#define VKVG_CMD_REL_CURVE_TO          (VKVG_CMD_CURVE_TO | VKVG_CMD_RELATIVE_COMMANDS)
+#define VKVG_CMD_REL_QUADRATIC_TO      (VKVG_CMD_QUADRATIC_TO | VKVG_CMD_RELATIVE_COMMANDS)
+#define VKVG_CMD_REL_ELLIPTICAL_ARC_TO (VKVG_CMD_ELLIPTICAL_ARC_TO | VKVG_CMD_RELATIVE_COMMANDS)
+
+#define VKVG_CMD_PAINT                 (0x0001 | VKVG_CMD_DRAW_COMMANDS)
+#define VKVG_CMD_FILL                  (0x0002 | VKVG_CMD_DRAW_COMMANDS)
+#define VKVG_CMD_STROKE                (0x0003 | VKVG_CMD_DRAW_COMMANDS)
+#define VKVG_CMD_CLIP                  (0x0004 | VKVG_CMD_DRAW_COMMANDS)
+#define VKVG_CMD_RESET_CLIP            (0x0005 | VKVG_CMD_DRAW_COMMANDS)
+#define VKVG_CMD_CLEAR                 (0x0006 | VKVG_CMD_DRAW_COMMANDS)
+
+#define VKVG_CMD_FILL_PRESERVE         (VKVG_CMD_FILL | VKVG_CMD_PRESERVE_COMMANDS)
+#define VKVG_CMD_STROKE_PRESERVE       (VKVG_CMD_STROKE | VKVG_CMD_PRESERVE_COMMANDS)
+#define VKVG_CMD_CLIP_PRESERVE         (VKVG_CMD_CLIP | VKVG_CMD_PRESERVE_COMMANDS)
+
+#define VKVG_CMD_SET_SOURCE_RGB        (0x0001 | VKVG_CMD_PATTERN_COMMANDS)
+#define VKVG_CMD_SET_SOURCE_RGBA       (0x0002 | VKVG_CMD_PATTERN_COMMANDS)
+#define VKVG_CMD_SET_SOURCE_COLOR      (0x0003 | VKVG_CMD_PATTERN_COMMANDS)
+#define VKVG_CMD_SET_SOURCE            (0x0004 | VKVG_CMD_PATTERN_COMMANDS)
+#define VKVG_CMD_SET_SOURCE_SURFACE    (0x0005 | VKVG_CMD_PATTERN_COMMANDS)
+
+typedef struct _vkvg_record_t {
+    uint16_t cmd;
+    size_t   dataOffset;
+} vkvg_record_t;
+
+typedef struct _vkvg_recording_t {
+    vkvg_record_t *commands;
+    uint32_t       commandsCount;
+    uint32_t       commandsReservedCount;
+    size_t         bufferSize;
+    size_t         bufferReservedSize;
+    char          *buffer;
+} vkvg_recording_t;
+
+void              _start_recording(VkvgContext ctx);
+vkvg_recording_t *_stop_recording(VkvgContext ctx);
+void              _destroy_recording(vkvg_recording_t *rec);
+void              _replay_command(VkvgContext ctx, VkvgRecording rec, uint32_t index);
+void              _record(vkvg_recording_t *rec, ...);
+
+#define RECORD(ctx, ...)                                                                                               \
+    {                                                                                                                  \
+        if (ctx->recording) {                                                                                          \
+            _record(ctx->recording, __VA_ARGS__);                                                                      \
+            return;                                                                                                    \
+        }                                                                                                              \
+    }
+#define RECORD2(ctx, ...)                                                                                              \
+    {                                                                                                                  \
+        if (ctx->recording) {                                                                                          \
+            _record(ctx->recording, __VA_ARGS__);                                                                      \
+            return 0;                                                                                                  \
+        }                                                                                                              \
+    }
 
 #endif
index b4a8c8e9656b8891a1d93d4ae25e137892c68642..9e4836544e5a9ebf095a0bf7f0a0e82081d227e2 100644 (file)
 unsigned char shader_comp_spv[] = {
-  0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00,
-  0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
-  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0xc2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41,
-  0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f,
-  0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63,
-  0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47,
-  0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74,
-  0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72,
-  0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
-  0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e,
-  0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
-  0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x47, 0x6c, 0x6f, 0x62, 0x61,
-  0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49,
-  0x44, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, 0x00,
-  0x78, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x2d, 0x00, 0x00, 0x00,
-  0x75, 0x76, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x6e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00,
-  0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x3d, 0x00, 0x00, 0x00,
-  0x7a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00,
-  0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x6d, 0x00, 0x00, 0x00,
-  0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x73, 0x00, 0x00, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x76, 0x00, 0x00, 0x00,
-  0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00,
-  0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x00, 0x00,
-  0x67, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x84, 0x00, 0x00, 0x00,
-  0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x97, 0x00, 0x00, 0x00, 0x62, 0x75, 0x66, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
-  0x97, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0xa0, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x80, 0x0c, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x60, 0x09, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x45,
-  0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x16, 0x45, 0x17, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xe3, 0xbe, 0x2c, 0x00, 0x05, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x2b, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x8f, 0xc2, 0x15, 0x40,
-  0x2c, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
-  0x3f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00,
-  0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x3f, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x40, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00,
-  0x3f, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x43, 0x17, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x72, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
-  0x9a, 0x99, 0x99, 0x3e, 0x2c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x75, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x77, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0xbe, 0x2b, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x9a, 0x99, 0x99, 0xbe,
-  0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0xbf, 0x2c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x7a, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
-  0x79, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x7c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x06, 0x40, 0x2b, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
-  0x2c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
-  0x7c, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-  0xcd, 0xcc, 0xcc, 0x3d, 0x2c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x82, 0x00, 0x00, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x83, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00,
-  0xd0, 0x0f, 0xc9, 0x40, 0x19, 0x00, 0x09, 0x00, 0x95, 0x00, 0x00, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x96, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x96, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0x99, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00,
-  0x3f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
-  0x9f, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00, 0x00,
-  0x76, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x72, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x83, 0x00, 0x00, 0x00,
-  0x84, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00,
-  0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
-  0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x16, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x07, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xfa, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x1b, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0xfd, 0x00, 0x01, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x2a, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x2d, 0x00, 0x00, 0x00,
-  0x30, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x36, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x39, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
-  0x8e, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
-  0x39, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00,
-  0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3d, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00,
-  0x42, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
-  0x45, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xf9, 0x00, 0x02, 0x00, 0x47, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x47, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
-  0x49, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00,
-  0x44, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x44, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x4b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
-  0x4b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x4d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00,
-  0x4d, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x51, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
-  0x54, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x57, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
-  0x57, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3d, 0x00, 0x00, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x60, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00,
-  0x94, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
-  0x60, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0xba, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x65, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x63, 0x00, 0x00, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
-  0x67, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x31, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x46, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x3f, 0x00, 0x00, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
-  0xf9, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x45, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x6e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
-  0x6f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x6d, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x73, 0x00, 0x00, 0x00,
-  0x75, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x76, 0x00, 0x00, 0x00,
-  0x7a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00,
-  0x7e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x71, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
-  0x7b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x89, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00,
-  0x71, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
-  0x89, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x8b, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x71, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00,
-  0x8b, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x8d, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x71, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00,
-  0x86, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x71, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00,
-  0x8f, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x91, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x51, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00,
-  0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x82, 0x00, 0x00, 0x00,
-  0x94, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00,
-  0x93, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x84, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x95, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x99, 0x00, 0x00, 0x00,
-  0x9b, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00,
-  0x9c, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x82, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
-  0x84, 0x00, 0x00, 0x00, 0x63, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00,
-  0x9d, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00,
-  0x38, 0x00, 0x01, 0x00
-};
-unsigned int shader_comp_spv_len = 3580;
-unsigned char shader2_comp_spv[] = {
-  0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
-  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0xc2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41,
-  0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f,
-  0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63,
-  0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47,
-  0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74,
-  0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72,
-  0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
-  0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e,
-  0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
-  0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00,
-  0x10, 0x00, 0x00, 0x00, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x46,
-  0x72, 0x61, 0x6d, 0x65, 0x28, 0x76, 0x66, 0x32, 0x3b, 0x76, 0x66, 0x32,
-  0x3b, 0x76, 0x66, 0x32, 0x3b, 0x66, 0x31, 0x3b, 0x66, 0x31, 0x3b, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x75, 0x76, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x73, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x73, 0x69, 0x7a, 0x65,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x74, 0x68, 0x69, 0x63, 0x6b, 0x6e, 0x65, 0x73,
-  0x73, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x12, 0x00, 0x00, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x67, 0x6c, 0x5f, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x76,
-  0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x73, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61,
-  0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x53, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x54, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61,
-  0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x55, 0x00, 0x00, 0x00,
-  0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x61, 0x00, 0x00, 0x00, 0x62, 0x75, 0x66, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x61, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x61, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x03, 0x00, 0x61, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x19, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x33, 0x33, 0x73, 0x3f,
-  0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
-  0xcd, 0xcc, 0x4c, 0x3d, 0x14, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0x15, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-  0x80, 0x0c, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x60, 0x09, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x48, 0x45, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x45, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x9a, 0x99, 0x19, 0x3f,
-  0x2c, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
-  0x4b, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0xcc, 0x3d,
-  0x2c, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00,
-  0x4d, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x6f, 0x12, 0x03, 0x3b,
-  0x17, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x60, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x63, 0x00, 0x00, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
-  0x66, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0x67, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x6a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00,
-  0x29, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00,
-  0x6a, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x4a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x53, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
-  0x30, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x2d, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
-  0x38, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x34, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x34, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x07, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x03, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xfa, 0x00, 0x04, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
-  0x3c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x3b, 0x00, 0x00, 0x00,
-  0xfd, 0x00, 0x01, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
-  0x40, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x43, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00,
-  0x45, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00,
-  0x50, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
-  0x43, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x3e, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x52, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x53, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x55, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
-  0x39, 0x00, 0x09, 0x00, 0x06, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
-  0x10, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0x53, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x5b, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0x4a, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x57, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x63, 0x00, 0x00, 0x00,
-  0x65, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00,
-  0x67, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x63, 0x00, 0x04, 0x00, 0x62, 0x00, 0x00, 0x00,
-  0x68, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00,
-  0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
-  0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x1a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x12, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0xfe, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00
-};
-unsigned int shader2_comp_spv_len = 2604;
+    0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c,
+    0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
+    0x00, 0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52,
+    0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f,
+    0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47,
+    0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64,
+    0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f,
+    0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+    0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49,
+    0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1f,
+    0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00,
+    0x05, 0x00, 0x03, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x75, 0x76, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x31, 0x00, 0x00,
+    0x00, 0x6e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x05, 0x00,
+    0x03, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x69,
+    0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
+    0x73, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x76, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00,
+    0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x84, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
+    0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x97, 0x00, 0x00, 0x00, 0x62, 0x75, 0x66, 0x00, 0x47, 0x00, 0x04, 0x00,
+    0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00,
+    0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x21, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x97, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x47,
+    0x00, 0x04, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00,
+    0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x80,
+    0x0c, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x60, 0x09, 0x00, 0x00, 0x16, 0x00, 0x03,
+    0x00, 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x48, 0x45, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x45,
+    0x17, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04,
+    0x00, 0x2c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00,
+    0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x34,
+    0x00, 0x00, 0x00, 0x0a, 0xd7, 0xe3, 0xbe, 0x2c, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
+    0x34, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x3f, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x8f, 0xc2,
+    0x15, 0x40, 0x2c, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32,
+    0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x20, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04,
+    0x00, 0x3f, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x3f, 0x00,
+    0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x56,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x17, 0x00,
+    0x04, 0x00, 0x71, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x72,
+    0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
+    0x74, 0x00, 0x00, 0x00, 0x9a, 0x99, 0x99, 0x3e, 0x2c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00,
+    0x00, 0x74, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00,
+    0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0xbe, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x78,
+    0x00, 0x00, 0x00, 0x9a, 0x99, 0x99, 0xbe, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xbf, 0x2c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00,
+    0x00, 0x78, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x7c, 0x00,
+    0x00, 0x00, 0x66, 0x66, 0x06, 0x40, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x40, 0x40, 0x2c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
+    0x56, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0xcd, 0xcc, 0xcc, 0x3d, 0x2c, 0x00, 0x06, 0x00, 0x71, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x32, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x82, 0x00, 0x00, 0x00, 0x1d,
+    0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x83, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x82, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0xd0, 0x0f, 0xc9,
+    0x40, 0x19, 0x00, 0x09, 0x00, 0x95, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x04, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x96, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x99, 0x00, 0x00,
+    0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x3f, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00,
+    0x9f, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00,
+    0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1e,
+    0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00,
+    0x2d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00,
+    0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b,
+    0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x1e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00,
+    0x00, 0x73, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00, 0x00, 0x76, 0x00,
+    0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x3b, 0x00, 0x04, 0x00, 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05,
+    0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00,
+    0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15,
+    0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x16, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+    0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf8, 0x00,
+    0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00,
+    0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00,
+    0x00, 0x1b, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0xf8, 0x00,
+    0x02, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0a,
+    0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+    0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00,
+    0x00, 0x88, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00,
+    0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0c,
+    0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x70, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00,
+    0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x2a, 0x00,
+    0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00, 0x2a,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05,
+    0x00, 0x2b, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
+    0x50, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00,
+    0x00, 0x83, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00,
+    0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3a,
+    0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
+    0x3b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03,
+    0x00, 0x3d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, 0x00,
+    0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf6,
+    0x00, 0x04, 0x00, 0x45, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
+    0x47, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x47, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00,
+    0x00, 0x48, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4a, 0x00,
+    0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x44,
+    0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
+    0x1e, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x1d, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00,
+    0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d,
+    0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00,
+    0x4f, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00,
+    0x00, 0x50, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00,
+    0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x52,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
+    0x53, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00,
+    0x00, 0x51, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x55, 0x00,
+    0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x57,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
+    0x58, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00,
+    0x00, 0x56, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x5a, 0x00,
+    0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x5b,
+    0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
+    0x59, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00,
+    0x00, 0x55, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x5e, 0x00,
+    0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x5d,
+    0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x2b, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x94, 0x00, 0x05, 0x00, 0x1d, 0x00,
+    0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0xba, 0x00, 0x05, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00,
+    0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x63, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
+    0x00, 0x65, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x64, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x45, 0x00,
+    0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x67,
+    0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
+    0x67, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x31, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00,
+    0x00, 0xf9, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x3f,
+    0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
+    0x41, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02,
+    0x00, 0x45, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x31, 0x00,
+    0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x6f,
+    0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
+    0x73, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x76, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00,
+    0x00, 0x3e, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7f, 0x00,
+    0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x73,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x1d, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, 0x71, 0x00,
+    0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x71,
+    0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x71, 0x00, 0x00, 0x00,
+    0x8c, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, 0x71, 0x00, 0x00,
+    0x00, 0x8d, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x71, 0x00,
+    0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x85,
+    0x00, 0x05, 0x00, 0x71, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
+    0x81, 0x00, 0x05, 0x00, 0x71, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00,
+    0x00, 0x51, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x82, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00,
+    0x00, 0x92, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x84, 0x00,
+    0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x95, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x97,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
+    0x4f, 0x00, 0x07, 0x00, 0x99, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x9d, 0x00,
+    0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x82, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x84,
+    0x00, 0x00, 0x00, 0x63, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
+    0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00};
+unsigned int  shader_comp_spv_len = 3580;
+unsigned char shader2_comp_spv[]  = {
+    0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c,
+    0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
+    0x00, 0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52,
+    0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f,
+    0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47,
+    0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64,
+    0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f,
+    0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+    0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x46, 0x72, 0x61,
+    0x6d, 0x65, 0x28, 0x76, 0x66, 0x32, 0x3b, 0x76, 0x66, 0x32, 0x3b, 0x76, 0x66, 0x32, 0x3b, 0x66, 0x31, 0x3b, 0x66,
+    0x31, 0x3b, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x75, 0x76, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
+    0x0c, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x73, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x73, 0x69, 0x7a,
+    0x65, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73,
+    0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x74, 0x68, 0x69, 0x63, 0x6b, 0x6e, 0x65, 0x73, 0x73,
+    0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x12, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00,
+    0x2b, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x70, 0x6f,
+    0x73, 0x00, 0x05, 0x00, 0x03, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x50,
+    0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x52, 0x00, 0x00, 0x00,
+    0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x53, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72,
+    0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x54, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00,
+    0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x55, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05,
+    0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
+    0x61, 0x00, 0x00, 0x00, 0x62, 0x75, 0x66, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
+    0x00, 0x1c, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x61, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x61, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+    0x00, 0x03, 0x00, 0x61, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x6b, 0x00, 0x00, 0x00,
+    0x0b, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03,
+    0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
+    0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x21, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00,
+    0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x33,
+    0x33, 0x73, 0x3f, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3d,
+    0x14, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x3b,
+    0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
+    0x28, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x30, 0x00,
+    0x00, 0x00, 0x80, 0x0c, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x60, 0x09, 0x00, 0x00,
+    0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x45, 0x2b, 0x00, 0x04,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x45, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00,
+    0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x9a, 0x99, 0x19, 0x3f, 0x2c, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4c,
+    0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x4d, 0x00, 0x00, 0x00, 0xcd, 0xcc, 0xcc, 0x3d, 0x2c, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00,
+    0x00, 0x4d, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4f, 0x00,
+    0x00, 0x00, 0x6f, 0x12, 0x03, 0x3b, 0x17, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
+    0x19, 0x00, 0x09, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x04, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x60,
+    0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x63, 0x00, 0x00, 0x00,
+    0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x66, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x67, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2c,
+    0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00,
+    0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a,
+    0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+    0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00,
+    0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x09,
+    0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
+    0x59, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00,
+    0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2f, 0x00,
+    0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2f,
+    0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
+    0x31, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04,
+    0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x33, 0x00,
+    0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x35,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
+    0xae, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00,
+    0x00, 0xf9, 0x00, 0x02, 0x00, 0x34, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x34, 0x00, 0x00, 0x00, 0xf5, 0x00,
+    0x07, 0x00, 0x27, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x39,
+    0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xfa, 0x00, 0x04, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02,
+    0x00, 0x3b, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x41, 0x00,
+    0x05, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x70, 0x00, 0x04, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x43, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2d, 0x00,
+    0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x28,
+    0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x70, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x46, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00,
+    0x00, 0x46, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x49, 0x00,
+    0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x49,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
+    0x3e, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x52, 0x00, 0x00,
+    0x00, 0x4c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x53, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0x54, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x55, 0x00, 0x00, 0x00, 0x4f,
+    0x00, 0x00, 0x00, 0x39, 0x00, 0x09, 0x00, 0x06, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x50, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00,
+    0x00, 0x3e, 0x00, 0x03, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00,
+    0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5b,
+    0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
+    0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
+    0x00, 0x50, 0x00, 0x07, 0x00, 0x57, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5b, 0x00,
+    0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x59, 0x00, 0x00, 0x00, 0x5e,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07,
+    0x00, 0x63, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x67, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x65,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
+    0x63, 0x00, 0x04, 0x00, 0x62, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01,
+    0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x37,
+    0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x0d, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03,
+    0x00, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3b, 0x00,
+    0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00,
+    0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, 0x16, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x83, 0x00,
+    0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0c,
+    0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
+    0x1a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
+    0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00,
+    0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x21, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x23, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
+    0x1f, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01,
+    0x00};
+unsigned int  shader2_comp_spv_len = 2604;
 unsigned char vkvg_main_frag_spv[] = {
-  0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00,
-  0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
-  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x00,
-  0x94, 0x01, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0xc2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41,
-  0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f,
-  0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63,
-  0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41,
-  0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c,
-  0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70,
-  0x61, 0x63, 0x6b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x45,
-  0x58, 0x54, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f, 0x62, 0x6c,
-  0x6f, 0x63, 0x6b, 0x5f, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x00, 0x00,
-  0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c,
-  0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f,
-  0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
-  0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47,
-  0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
-  0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x69, 0x6e, 0x53, 0x72, 0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x50, 0x61, 0x74, 0x54, 0x79, 0x70,
-  0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00,
-  0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x75, 0x76, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x69, 0x6e, 0x4d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x4a, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x52, 0x00, 0x00, 0x00, 0x64, 0x69, 0x73, 0x74,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x70, 0x30, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x5f, 0x75, 0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00,
-  0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x74, 0x6f, 0x70,
-  0x73, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x63, 0x70, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00,
-  0x5a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x75, 0x6e,
-  0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x75, 0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x70, 0x31, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x75, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x97, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x9e, 0x00, 0x00, 0x00, 0x62, 0x62, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0xcc, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0xf2, 0x00, 0x00, 0x00, 0x63, 0x30, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0xf9, 0x00, 0x00, 0x00, 0x63, 0x31, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x00, 0x01, 0x00, 0x00, 0x72, 0x30, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x06, 0x01, 0x00, 0x00, 0x72, 0x31, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0x0c, 0x01, 0x00, 0x00, 0x67, 0x72, 0x61, 0x64, 0x4c, 0x65, 0x6e, 0x67,
-  0x74, 0x68, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0d, 0x01, 0x00, 0x00,
-  0x64, 0x69, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x11, 0x01, 0x00, 0x00, 0x72, 0x61, 0x79, 0x44, 0x69, 0x72, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x16, 0x01, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x20, 0x01, 0x00, 0x00, 0x63, 0x63, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x28, 0x01, 0x00, 0x00, 0x64, 0x69, 0x73, 0x63,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x36, 0x01, 0x00, 0x00,
-  0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x40, 0x01, 0x00, 0x00,
-  0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x4b, 0x01, 0x00, 0x00, 0x67, 0x72, 0x61, 0x64,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x5f, 0x01, 0x00, 0x00,
-  0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x7f, 0x01, 0x00, 0x00,
-  0x69, 0x6e, 0x46, 0x6f, 0x6e, 0x74, 0x55, 0x56, 0x00, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x88, 0x01, 0x00, 0x00, 0x66, 0x6f, 0x6e, 0x74,
-  0x4d, 0x61, 0x70, 0x00, 0x05, 0x00, 0x05, 0x00, 0x8f, 0x01, 0x00, 0x00,
-  0x69, 0x6e, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x06, 0x00, 0x94, 0x01, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x46,
-  0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x05, 0x00, 0x96, 0x01, 0x00, 0x00, 0x4e, 0x55, 0x4d, 0x5f,
-  0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x53, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
-  0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-  0x48, 0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
-  0x5a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x60, 0x01, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x7f, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x88, 0x01, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x88, 0x01, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x03, 0x00, 0x8f, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x8f, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x94, 0x01, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x96, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x15, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x18, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00,
-  0x47, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00,
-  0x48, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x49, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x55, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x58, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x5b, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x5b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
-  0x7d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xc2, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0xcb, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xd5, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-  0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
-  0x00, 0x00, 0x80, 0x40, 0x17, 0x00, 0x04, 0x00, 0x7d, 0x01, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x7e, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7d, 0x01, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x7e, 0x01, 0x00, 0x00, 0x7f, 0x01, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x85, 0x01, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x86, 0x01, 0x00, 0x00,
-  0x85, 0x01, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x87, 0x01, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x86, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x87, 0x01, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x93, 0x01, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x93, 0x01, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x96, 0x01, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x97, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0xf2, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x16, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x06, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x11, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1a, 0x01, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x20, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x40, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x4b, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xfb, 0x00, 0x09, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x1b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
-  0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x83, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x25, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
-  0x2e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x35, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x36, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
-  0x36, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x38, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x39, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x40, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x40, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x42, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
-  0x43, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x45, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
-  0x50, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x48, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x4d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
-  0x4d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
-  0x4c, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x50, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x52, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x5d, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x61, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00,
-  0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00,
-  0x60, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x54, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x5d, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00,
-  0x66, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x68, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
-  0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00,
-  0x67, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
-  0x6b, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x6d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00,
-  0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00,
-  0x54, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x73, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x70, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x77, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00,
-  0x77, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
-  0x78, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x75, 0x00, 0x00, 0x00,
-  0x79, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x7a, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00,
-  0x7a, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00,
-  0x7e, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xfa, 0x00, 0x04, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-  0x96, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00,
-  0x75, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00,
-  0xb8, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00,
-  0x82, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00,
-  0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
-  0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x84, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x87, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x89, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00,
-  0x89, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x8b, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
-  0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00,
-  0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x52, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x85, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x8e, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00,
-  0x54, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00,
-  0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00,
-  0x90, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
-  0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00,
-  0x93, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x52, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x85, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x85, 0x00, 0x00, 0x00,
-  0xf9, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x96, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x98, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00,
-  0x98, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x9a, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x9c, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00,
-  0x9c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x97, 0x00, 0x00, 0x00,
-  0x9d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x9f, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
-  0x9f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xa1, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xa3, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00,
-  0xa3, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xa5, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x9e, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00,
-  0x97, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0xa9, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
-  0xa9, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xab, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
-  0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
-  0xa7, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
-  0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00,
-  0xac, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00,
-  0x97, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xb1, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00,
-  0x53, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00,
-  0xb3, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xb5, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
-  0xb5, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0xb6, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0xb7, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00,
-  0xb7, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00,
-  0xb9, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x03, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xfa, 0x00, 0x04, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00,
-  0xbb, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xba, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00,
-  0x52, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xbd, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x52, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0xbb, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xbb, 0x00, 0x00, 0x00,
-  0xf9, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x80, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0xbe, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0xbf, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x5d, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00,
-  0xc3, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00,
-  0xc5, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xc6, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00,
-  0xc6, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
-  0xc8, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00,
-  0xc1, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0xcc, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0xcd, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xcd, 0x00, 0x00, 0x00,
-  0xf6, 0x00, 0x04, 0x00, 0xcf, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xd1, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00,
-  0x7c, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00,
-  0xd2, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0xd5, 0x00, 0x00, 0x00,
-  0xd6, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00,
-  0xd6, 0x00, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0xd8, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
-  0xb0, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00,
-  0xd3, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
-  0xd9, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0xce, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00,
-  0xcc, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0xdc, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00,
-  0xdd, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0xdf, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0xc2, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00,
-  0xcc, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0xe3, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00,
-  0xe4, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xe6, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x31, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00,
-  0xe6, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0xe8, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00,
-  0xe7, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2e, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00,
-  0xe8, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0xe9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00,
-  0x80, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00,
-  0xea, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0xcc, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0xcd, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xcf, 0x00, 0x00, 0x00,
-  0xf9, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x13, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0xed, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00,
-  0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0xf0, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00,
-  0xf0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0xf1, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0xf3, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0xf4, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00,
-  0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xf2, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0xfa, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0xfb, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00,
-  0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0xfe, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-  0xfe, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xf9, 0x00, 0x00, 0x00,
-  0xff, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0xc2, 0x00, 0x00, 0x00,
-  0x01, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00,
-  0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00,
-  0x02, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x00, 0x01, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00,
-  0xc2, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00,
-  0x07, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x09, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00,
-  0x09, 0x01, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x0b, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x06, 0x01, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x00, 0x00,
-  0xf2, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x0f, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x0e, 0x01, 0x00, 0x00,
-  0x0f, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x0d, 0x01, 0x00, 0x00,
-  0x10, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x12, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00,
-  0x83, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00,
-  0x12, 0x01, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x45, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x11, 0x01, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00,
-  0x11, 0x01, 0x00, 0x00, 0x94, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x19, 0x01, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x16, 0x01, 0x00, 0x00, 0x19, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00,
-  0x11, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x1d, 0x01, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x94, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00,
-  0x1d, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x1f, 0x01, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x1e, 0x01, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x1f, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00,
-  0x0d, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x22, 0x01, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x94, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00,
-  0x22, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x24, 0x01, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00,
-  0x24, 0x01, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00,
-  0x26, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x20, 0x01, 0x00, 0x00,
-  0x27, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x29, 0x01, 0x00, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x1a, 0x01, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00,
-  0x29, 0x01, 0x00, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x2d, 0x01, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x01, 0x00, 0x00,
-  0x2c, 0x01, 0x00, 0x00, 0x2d, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x2f, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00,
-  0x2e, 0x01, 0x00, 0x00, 0x2f, 0x01, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x31, 0x01, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00,
-  0x30, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x28, 0x01, 0x00, 0x00,
-  0x31, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x32, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0xbe, 0x00, 0x05, 0x00,
-  0x7d, 0x00, 0x00, 0x00, 0x33, 0x01, 0x00, 0x00, 0x32, 0x01, 0x00, 0x00,
-  0x7c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x35, 0x01, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x33, 0x01, 0x00, 0x00,
-  0x34, 0x01, 0x00, 0x00, 0x35, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x34, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x37, 0x01, 0x00, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x37, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x39, 0x01, 0x00, 0x00,
-  0x28, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x3a, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x39, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x3b, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
-  0x3a, 0x01, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x3c, 0x01, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3d, 0x01, 0x00, 0x00,
-  0x16, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x3e, 0x01, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x3d, 0x01, 0x00, 0x00,
-  0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00,
-  0x3c, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x36, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x41, 0x01, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00,
-  0x11, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x43, 0x01, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00,
-  0x43, 0x01, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x45, 0x01, 0x00, 0x00, 0x41, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x40, 0x01, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00,
-  0x40, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x47, 0x01, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x43, 0x00, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00, 0x47, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x49, 0x01, 0x00, 0x00,
-  0x00, 0x01, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x4a, 0x01, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x49, 0x01, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x00, 0x00,
-  0xf9, 0x00, 0x02, 0x00, 0x35, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x35, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x4c, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x4d, 0x01, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00,
-  0x4d, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x4f, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00,
-  0x4f, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x51, 0x01, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x52, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00,
-  0x51, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4b, 0x01, 0x00, 0x00,
-  0x52, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0x53, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x54, 0x01, 0x00, 0x00, 0x53, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x5d, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x57, 0x01, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00,
-  0x57, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00,
-  0x59, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x5a, 0x01, 0x00, 0x00, 0x59, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x5b, 0x01, 0x00, 0x00, 0x4b, 0x01, 0x00, 0x00,
-  0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00,
-  0x5a, 0x01, 0x00, 0x00, 0x5b, 0x01, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00,
-  0x5c, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00,
-  0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00,
-  0x56, 0x01, 0x00, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x5f, 0x01, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x60, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x60, 0x01, 0x00, 0x00,
-  0xf6, 0x00, 0x04, 0x00, 0x62, 0x01, 0x00, 0x00, 0x63, 0x01, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x64, 0x01, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x64, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00,
-  0x7c, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x66, 0x01, 0x00, 0x00,
-  0x65, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0xd5, 0x00, 0x00, 0x00,
-  0x67, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00,
-  0x67, 0x01, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00,
-  0x69, 0x01, 0x00, 0x00, 0x66, 0x01, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00,
-  0xfa, 0x00, 0x04, 0x00, 0x69, 0x01, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00,
-  0x62, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x61, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6a, 0x01, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x6b, 0x01, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x5d, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x6b, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x6d, 0x01, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x6e, 0x01, 0x00, 0x00,
-  0x5f, 0x01, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x6f, 0x01, 0x00, 0x00, 0x6e, 0x01, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x6f, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x71, 0x01, 0x00, 0x00,
-  0x70, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x72, 0x01, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0xc2, 0x00, 0x00, 0x00, 0x73, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x72, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x73, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x75, 0x01, 0x00, 0x00,
-  0x4b, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x76, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x71, 0x01, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x75, 0x01, 0x00, 0x00,
-  0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x77, 0x01, 0x00, 0x00,
-  0x76, 0x01, 0x00, 0x00, 0x76, 0x01, 0x00, 0x00, 0x76, 0x01, 0x00, 0x00,
-  0x76, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x78, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
-  0x6a, 0x01, 0x00, 0x00, 0x6d, 0x01, 0x00, 0x00, 0x77, 0x01, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00,
-  0xf9, 0x00, 0x02, 0x00, 0x63, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x63, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x79, 0x01, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x7a, 0x01, 0x00, 0x00, 0x79, 0x01, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x5f, 0x01, 0x00, 0x00,
-  0x7a, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x60, 0x01, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x62, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
-  0x7f, 0x01, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
-  0xbe, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00,
-  0x81, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00,
-  0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
-  0x82, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x83, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x86, 0x01, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x7d, 0x01, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x00,
-  0x7f, 0x01, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x8b, 0x01, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x00,
-  0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x00,
-  0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x8e, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00,
-  0x8d, 0x01, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x84, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x84, 0x01, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
-  0x8f, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x91, 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x92, 0x01, 0x00, 0x00, 0x91, 0x01, 0x00, 0x00,
-  0x90, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x92, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x95, 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x94, 0x01, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00,
-  0x38, 0x00, 0x01, 0x00
-};
-unsigned int vkvg_main_frag_spv_len = 9532;
-unsigned char vkvg_main_vert_spv[] = {
-  0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00,
-  0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
-  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-  0x42, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00,
-  0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73,
-  0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64,
-  0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00,
-  0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73,
-  0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75,
-  0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00,
-  0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c,
-  0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f,
-  0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
-  0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47,
-  0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
-  0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x6f, 0x75, 0x74, 0x50, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00,
-  0x05, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x50, 0x75, 0x73, 0x68,
-  0x43, 0x6f, 0x6e, 0x73, 0x74, 0x73, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x72,
-  0x63, 0x65, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x66, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x51, 0x75,
-  0x61, 0x64, 0x5f, 0x73, 0x72, 0x63, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00,
-  0x06, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x06, 0x00, 0x04, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x74, 0x00,
-  0x06, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
-  0x6d, 0x61, 0x74, 0x49, 0x6e, 0x76, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x70, 0x63, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x4d, 0x61, 0x74, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x53,
-  0x72, 0x63, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0x69, 0x6e, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x4f, 0x70, 0x61, 0x63, 0x69,
-  0x74, 0x79, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
-  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74,
-  0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74,
-  0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00,
-  0x3e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43,
-  0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00,
-  0x06, 0x00, 0x07, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x67, 0x6c, 0x5f, 0x43, 0x75, 0x6c, 0x6c, 0x44, 0x69, 0x73, 0x74, 0x61,
-  0x6e, 0x63, 0x65, 0x00, 0x05, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x42, 0x00, 0x00, 0x00,
-  0x69, 0x6e, 0x50, 0x6f, 0x73, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x4c, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x55, 0x56, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x51, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x55, 0x56,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x05, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
-  0x3e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x05, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
-  0x3e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x42, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x51, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x18, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x14, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x19, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x14, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x2a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x15, 0x00, 0x04, 0x00,
-  0x3b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x3d, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00,
-  0x3e, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x3f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x41, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x17, 0x00, 0x04, 0x00,
-  0x4a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x4a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x4b, 0x00, 0x00, 0x00,
-  0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf,
-  0x2c, 0x00, 0x06, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00,
-  0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x4a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x50, 0x00, 0x00, 0x00,
-  0x51, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x53, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x3b, 0x00, 0x00, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2c, 0x00, 0x05, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
-  0x77, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x7a, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x05, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
-  0x45, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x53, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00,
-  0x12, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
-  0x12, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xfa, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
-  0x29, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x25, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x2d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
-  0x32, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x2f, 0x00, 0x00, 0x00,
-  0x33, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
-  0xaa, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00,
-  0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
-  0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
-  0x51, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00,
-  0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00,
-  0x44, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x49, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
-  0x4e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x3a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00,
-  0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x4c, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00,
-  0x31, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
-  0x55, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
-  0x57, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x59, 0x00, 0x00, 0x00,
-  0x5a, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
-  0x5a, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x07, 0x00, 0x31, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
-  0x3c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x61, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00,
-  0x61, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x63, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x07, 0x00, 0x31, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x65, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00,
-  0x65, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x67, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x59, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
-  0x42, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00,
-  0x68, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00,
-  0x31, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
-  0x55, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x59, 0x00, 0x00, 0x00,
-  0x6e, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00,
-  0x6e, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00,
-  0x6b, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00,
-  0x31, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
-  0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
-  0x72, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x74, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
-  0x50, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00,
-  0x66, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x54, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00,
-  0x76, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x7a, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
-  0x5d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x7c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00,
-  0x7c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x7f, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
-  0x51, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-  0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x82, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00,
-  0x44, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x83, 0x00, 0x00, 0x00,
-  0x82, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2e, 0x00, 0x00, 0x00,
-  0x84, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x84, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
-  0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
-};
-unsigned int vkvg_main_vert_spv_len = 3704;
+    0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c,
+    0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+    0x00, 0x21, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00, 0x10, 0x00,
+    0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2,
+    0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72,
+    0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00,
+    0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, 0x6e, 0x67,
+    0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00, 0x04,
+    0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x45, 0x58, 0x54, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f, 0x62, 0x6c,
+    0x6f, 0x63, 0x6b, 0x5f, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f,
+    0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69,
+    0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47,
+    0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69,
+    0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69,
+    0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x05, 0x00,
+    0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x53, 0x72, 0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0f,
+    0x00, 0x00, 0x00, 0x69, 0x6e, 0x50, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
+    0x17, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f,
+    0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1e, 0x00,
+    0x00, 0x00, 0x75, 0x76, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x4d, 0x61, 0x74,
+    0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x00,
+    0x05, 0x00, 0x04, 0x00, 0x52, 0x00, 0x00, 0x00, 0x64, 0x69, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03,
+    0x00, 0x54, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5f, 0x75,
+    0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x5a, 0x00, 0x00,
+    0x00, 0x02, 0x00, 0x00, 0x00, 0x63, 0x70, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x75,
+    0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00, 0x05, 0x00, 0x03, 0x00, 0x64, 0x00, 0x00, 0x00, 0x70, 0x31, 0x00, 0x00,
+    0x05, 0x00, 0x03, 0x00, 0x70, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x75, 0x00, 0x00,
+    0x00, 0x75, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x97, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00,
+    0x03, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x62, 0x62, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x69,
+    0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x63, 0x30, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00,
+    0xf9, 0x00, 0x00, 0x00, 0x63, 0x31, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x72, 0x30, 0x00,
+    0x00, 0x05, 0x00, 0x03, 0x00, 0x06, 0x01, 0x00, 0x00, 0x72, 0x31, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0c, 0x01,
+    0x00, 0x00, 0x67, 0x72, 0x61, 0x64, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0d,
+    0x01, 0x00, 0x00, 0x64, 0x69, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x11, 0x01, 0x00, 0x00,
+    0x72, 0x61, 0x79, 0x44, 0x69, 0x72, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x16, 0x01, 0x00, 0x00, 0x61, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x03, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x20, 0x01,
+    0x00, 0x00, 0x63, 0x63, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x28, 0x01, 0x00, 0x00, 0x64, 0x69, 0x73, 0x63, 0x00,
+    0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x36, 0x01, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
+    0x40, 0x01, 0x00, 0x00, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x05, 0x00, 0x04,
+    0x00, 0x4b, 0x01, 0x00, 0x00, 0x67, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x5f, 0x01,
+    0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x7f, 0x01, 0x00, 0x00, 0x69, 0x6e, 0x46, 0x6f, 0x6e,
+    0x74, 0x55, 0x56, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x88, 0x01, 0x00, 0x00, 0x66, 0x6f, 0x6e, 0x74,
+    0x4d, 0x61, 0x70, 0x00, 0x05, 0x00, 0x05, 0x00, 0x8f, 0x01, 0x00, 0x00, 0x69, 0x6e, 0x4f, 0x70, 0x61, 0x63, 0x69,
+    0x74, 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x94, 0x01, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x46, 0x72, 0x61,
+    0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x96, 0x01, 0x00, 0x00, 0x4e,
+    0x55, 0x4d, 0x5f, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x53, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
+    0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
+    0x00, 0x47, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00,
+    0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x21,
+    0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00,
+    0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00,
+    0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47,
+    0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
+    0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05,
+    0x00, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x48, 0x00,
+    0x05, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x48,
+    0x00, 0x05, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00,
+    0x47, 0x00, 0x03, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x5c, 0x00, 0x00,
+    0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x21, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x7f, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x88, 0x01, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x47, 0x00, 0x04, 0x00, 0x88, 0x01, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03,
+    0x00, 0x8f, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x8f, 0x01, 0x00, 0x00, 0x1e, 0x00,
+    0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x94, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x96, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+    0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x15, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e,
+    0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+    0x00, 0x15, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00,
+    0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x20, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04,
+    0x00, 0x0d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x23, 0x00,
+    0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x34,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x47, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x48, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x04, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x49,
+    0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00,
+    0x00, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x55, 0x00,
+    0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x2b,
+    0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00,
+    0x59, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, 0x5a, 0x00, 0x00,
+    0x00, 0x56, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x04, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x5b,
+    0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x5d, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xc2, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xd5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00,
+    0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2b, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x17, 0x00, 0x04, 0x00, 0x7d,
+    0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x7e, 0x01, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x7d, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x7e, 0x01, 0x00, 0x00, 0x7f, 0x01, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x85, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x86, 0x01, 0x00, 0x00, 0x85, 0x01, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
+    0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x87, 0x01, 0x00,
+    0x00, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x8f, 0x01,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x93, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x93, 0x01, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x32, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x96, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05,
+    0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00,
+    0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04,
+    0x00, 0x28, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00,
+    0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x64,
+    0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+    0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00,
+    0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xcb,
+    0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
+    0xf2, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+    0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b,
+    0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x16, 0x00, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00,
+    0x00, 0x11, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x16, 0x01,
+    0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04,
+    0x00, 0x28, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00,
+    0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x4b,
+    0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
+    0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00,
+    0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xfb, 0x00, 0x09, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00,
+    0x00, 0xf8, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x19, 0x00,
+    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x19,
+    0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00,
+    0x00, 0x1c, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1c,
+    0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
+    0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x41, 0x00,
+    0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06,
+    0x00, 0x25, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x24, 0x00,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x41,
+    0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x81, 0x00,
+    0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x41,
+    0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+    0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00,
+    0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x36, 0x00,
+    0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22,
+    0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
+    0x38, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00,
+    0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3a, 0x00,
+    0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3b,
+    0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+    0x2c, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x17, 0x00,
+    0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3f,
+    0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
+    0x40, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
+    0x00, 0x41, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x21, 0x00,
+    0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44,
+    0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
+    0x42, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00,
+    0x00, 0x37, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x46, 0x00,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x48, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00,
+    0x00, 0x4e, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4e,
+    0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00,
+    0x4f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02,
+    0x00, 0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x52, 0x00,
+    0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x5c,
+    0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x5f, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
+    0x00, 0x5f, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15,
+    0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
+    0x00, 0x62, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x41, 0x00,
+    0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x22,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
+    0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
+    0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x68, 0x00,
+    0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x68,
+    0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00,
+    0x15, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03,
+    0x00, 0x64, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6b, 0x00,
+    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6b,
+    0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00,
+    0x00, 0x6e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6e,
+    0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x15, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00,
+    0x00, 0x72, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x73, 0x00,
+    0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x74,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
+    0x70, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00,
+    0x00, 0x64, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x54, 0x00,
+    0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x77,
+    0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x45, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x75, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00,
+    0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x2f, 0x00,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xb4,
+    0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
+    0xf7, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x7e, 0x00, 0x00,
+    0x00, 0x7f, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x41, 0x00,
+    0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x05, 0x00,
+    0x7d, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03,
+    0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x83, 0x00, 0x00, 0x00, 0x84, 0x00,
+    0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x84, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28,
+    0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00,
+    0x00, 0x88, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00,
+    0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8a,
+    0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x8b, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00,
+    0x00, 0x70, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x8b, 0x00,
+    0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x52, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0xf9,
+    0x00, 0x02, 0x00, 0x85, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
+    0x28, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00,
+    0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x93, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x94, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x95, 0x00,
+    0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x52, 0x00, 0x00, 0x00, 0x95,
+    0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x85, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x85, 0x00, 0x00, 0x00,
+    0xf9, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x96, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05,
+    0x00, 0x28, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00,
+    0x9b, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x9c, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9d, 0x00,
+    0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x97, 0x00, 0x00, 0x00, 0x9d,
+    0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
+    0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x41, 0x00,
+    0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0x9e, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0xa6,
+    0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0xa7, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00,
+    0x00, 0x97, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x17, 0x00,
+    0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xa9,
+    0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00,
+    0xaa, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00,
+    0x00, 0xab, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x9e, 0x00,
+    0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xad,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x81, 0x00,
+    0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x0c,
+    0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+    0xb2, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00,
+    0x00, 0xb3, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x70, 0x00,
+    0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0xb5,
+    0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x52, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
+    0x28, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x05, 0x00, 0x7d, 0x00,
+    0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xbb,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00,
+    0xbb, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xba, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0xbc, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xbd, 0x00,
+    0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x52, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0xf9,
+    0x00, 0x02, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00,
+    0x00, 0xbe, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d,
+    0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06,
+    0x00, 0xc2, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x22, 0x00,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x41,
+    0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
+    0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x0c, 0x00,
+    0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xc4,
+    0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0xc9, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00,
+    0x00, 0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00,
+    0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09,
+    0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
+    0xf9, 0x00, 0x02, 0x00, 0xcd, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xcd, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04,
+    0x00, 0xcf, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xd1, 0x00,
+    0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xd2,
+    0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00,
+    0xd2, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0xd5, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
+    0x00, 0xd4, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0xd6, 0x00,
+    0x00, 0x00, 0x82, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x2f,
+    0x00, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00,
+    0xd8, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00,
+    0x00, 0xf8, 0x00, 0x02, 0x00, 0xce, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xda, 0x00,
+    0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0xcc,
+    0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00,
+    0x2c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
+    0x00, 0x22, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xde, 0x00,
+    0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xcc,
+    0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
+    0x2c, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00,
+    0x00, 0xe0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0xcc, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x2c,
+    0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
+    0x2c, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00,
+    0x00, 0xe4, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x52, 0x00,
+    0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31,
+    0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00,
+    0x00, 0xe7, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x3e,
+    0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x00, 0x00,
+    0xf8, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00,
+    0x00, 0xcc, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0xea, 0x00,
+    0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0xf9,
+    0x00, 0x02, 0x00, 0xcd, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xcf, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
+    0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00,
+    0x00, 0xed, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0xee, 0x00,
+    0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00,
+    0x15, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xee, 0x00,
+    0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x41,
+    0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+    0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00,
+    0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xf4, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf6,
+    0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00,
+    0xf6, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05,
+    0x00, 0x15, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0xf2, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0xfa,
+    0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00,
+    0x00, 0xfc, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x4f,
+    0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+    0x00, 0xfc, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xff, 0x00,
+    0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x34,
+    0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x02, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00,
+    0x00, 0x0b, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x01,
+    0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x02,
+    0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00,
+    0x41, 0x00, 0x07, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00,
+    0x00, 0x2c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x01,
+    0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x0b,
+    0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00,
+    0x09, 0x01, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00,
+    0x00, 0x0a, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x06, 0x01, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0e,
+    0x01, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00,
+    0xf9, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x0e, 0x01, 0x00,
+    0x00, 0x0f, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15,
+    0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
+    0x14, 0x01, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
+    0x00, 0x15, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0x11, 0x01, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x17,
+    0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00,
+    0x11, 0x01, 0x00, 0x00, 0x94, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00, 0x00, 0x17, 0x01, 0x00,
+    0x00, 0x18, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x16, 0x01, 0x00, 0x00, 0x19, 0x01, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15,
+    0x00, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x94, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x1e, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x1f, 0x01, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x1e, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1a, 0x01,
+    0x00, 0x00, 0x1f, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00, 0x0d,
+    0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x22, 0x01, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00,
+    0x94, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00, 0x22, 0x01, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03,
+    0x00, 0x20, 0x01, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x29, 0x01,
+    0x00, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x1a,
+    0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00, 0x29, 0x01, 0x00, 0x00,
+    0x2a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2d, 0x01, 0x00, 0x00, 0x16, 0x01, 0x00,
+    0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x2d, 0x01,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2f, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x85,
+    0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x2e, 0x01, 0x00, 0x00, 0x2f, 0x01, 0x00, 0x00,
+    0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x31, 0x01, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00, 0x30, 0x01, 0x00,
+    0x00, 0x3e, 0x00, 0x03, 0x00, 0x28, 0x01, 0x00, 0x00, 0x31, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00,
+    0x00, 0x00, 0x32, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0xbe, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x33,
+    0x01, 0x00, 0x00, 0x32, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x35, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x33, 0x01, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, 0x35, 0x01, 0x00,
+    0x00, 0xf8, 0x00, 0x02, 0x00, 0x34, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x37, 0x01,
+    0x00, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x37,
+    0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x39, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
+    0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+    0x00, 0x39, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3c,
+    0x01, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x3d, 0x01, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3e, 0x01, 0x00,
+    0x00, 0x1b, 0x01, 0x00, 0x00, 0x3d, 0x01, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3f, 0x01,
+    0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x36, 0x01, 0x00, 0x00, 0x3f,
+    0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x41, 0x01, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, 0x15, 0x00,
+    0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x15,
+    0x00, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, 0x41, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
+    0x40, 0x01, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x46, 0x01, 0x00,
+    0x00, 0x40, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0xf2, 0x00,
+    0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x43,
+    0x00, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x49, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4a, 0x01, 0x00,
+    0x00, 0x48, 0x01, 0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x4a, 0x01,
+    0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x35, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x35, 0x01, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x15, 0x00, 0x00, 0x00, 0x4d, 0x01, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x4e, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x4d, 0x01,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4f, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x83,
+    0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00, 0x4f, 0x01, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x51, 0x01, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x88, 0x00, 0x05,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x52, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x51, 0x01, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0x4b, 0x01, 0x00, 0x00, 0x52, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x53,
+    0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0x53, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00,
+    0x00, 0x55, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xc2,
+    0x00, 0x00, 0x00, 0x57, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00, 0x57, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06,
+    0x00, 0xc2, 0x00, 0x00, 0x00, 0x59, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2c, 0x00,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x59, 0x01, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5b, 0x01, 0x00, 0x00, 0x4b, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x58, 0x01, 0x00,
+    0x00, 0x5a, 0x01, 0x00, 0x00, 0x5b, 0x01, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5d, 0x01,
+    0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x0c,
+    0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
+    0x54, 0x01, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00,
+    0x00, 0x5e, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xf9, 0x00,
+    0x02, 0x00, 0x60, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x60, 0x01, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x62,
+    0x01, 0x00, 0x00, 0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x64, 0x01, 0x00, 0x00,
+    0xf8, 0x00, 0x02, 0x00, 0x64, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x65, 0x01, 0x00,
+    0x00, 0x5f, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x66, 0x01, 0x00, 0x00, 0x65, 0x01,
+    0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0xd5, 0x00, 0x00, 0x00, 0x67, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0xd4,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x67, 0x01, 0x00, 0x00,
+    0xb0, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x69, 0x01, 0x00, 0x00, 0x66, 0x01, 0x00, 0x00, 0x68, 0x01, 0x00,
+    0x00, 0xfa, 0x00, 0x04, 0x00, 0x69, 0x01, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, 0xf8, 0x00,
+    0x02, 0x00, 0x61, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6a, 0x01, 0x00, 0x00, 0x09,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x6b, 0x01, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00,
+    0x41, 0x00, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
+    0x00, 0x6b, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x6d, 0x01, 0x00, 0x00, 0x6c, 0x01,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x6e, 0x01, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x82,
+    0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x6f, 0x01, 0x00, 0x00, 0x6e, 0x01, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
+    0x41, 0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00,
+    0x00, 0x6f, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x71, 0x01, 0x00, 0x00, 0x70, 0x01,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x72, 0x01, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x41,
+    0x00, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x73, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
+    0x72, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x73, 0x01, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x75, 0x01, 0x00, 0x00, 0x4b, 0x01, 0x00, 0x00, 0x0c, 0x00,
+    0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x71,
+    0x01, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x75, 0x01, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x77, 0x01, 0x00, 0x00, 0x76, 0x01, 0x00, 0x00, 0x76, 0x01, 0x00, 0x00, 0x76, 0x01, 0x00, 0x00, 0x76, 0x01, 0x00,
+    0x00, 0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00,
+    0x00, 0x00, 0x6a, 0x01, 0x00, 0x00, 0x6d, 0x01, 0x00, 0x00, 0x77, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09,
+    0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x63, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
+    0x63, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00, 0x00, 0x5f, 0x01, 0x00,
+    0x00, 0x80, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x7a, 0x01, 0x00, 0x00, 0x79, 0x01, 0x00, 0x00, 0x2c, 0x00,
+    0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x7a, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x60,
+    0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x62, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00,
+    0xf8, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+    0x00, 0x7f, 0x01, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x81, 0x01,
+    0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xbe, 0x00, 0x05, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0x81,
+    0x01, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xfa, 0x00, 0x04, 0x00, 0x82, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02,
+    0x00, 0x83, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x86, 0x01, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x88, 0x01,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x7d, 0x01, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x00, 0x7f, 0x01, 0x00, 0x00, 0x57,
+    0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x8b, 0x01, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x00,
+    0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x8e, 0x00,
+    0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x3e,
+    0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x84, 0x01, 0x00, 0x00,
+    0xf8, 0x00, 0x02, 0x00, 0x84, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00,
+    0x00, 0x8f, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x91, 0x01, 0x00, 0x00, 0x09, 0x00,
+    0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x92, 0x01, 0x00, 0x00, 0x91, 0x01, 0x00, 0x00, 0x90,
+    0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x92, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x94, 0x01, 0x00,
+    0x00, 0x95, 0x01, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00};
+unsigned int  vkvg_main_frag_spv_len = 9532;
+unsigned char vkvg_main_vert_spv[]   = {
+    0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c,
+    0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00,
+    0x00, 0x27, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x4c, 0x00,
+    0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0x04,
+    0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f,
+    0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x09,
+    0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e,
+    0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47,
+    0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f,
+    0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08,
+    0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f,
+    0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d,
+    0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x50,
+    0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x50, 0x75, 0x73,
+    0x68, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x73, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x66, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x51, 0x75, 0x61, 0x64, 0x5f,
+    0x73, 0x72, 0x63, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x6d, 0x61, 0x74, 0x00, 0x06, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x6d, 0x61, 0x74, 0x49, 0x6e, 0x76, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x70, 0x63, 0x00,
+    0x00, 0x05, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x4d, 0x61, 0x74, 0x00, 0x00, 0x05, 0x00,
+    0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x53, 0x72, 0x63, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x27,
+    0x00, 0x00, 0x00, 0x69, 0x6e, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x05, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x00, 0x00,
+    0x6f, 0x75, 0x74, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x00,
+    0x00, 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+    0x06, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69,
+    0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50,
+    0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0x3e, 0x00, 0x00,
+    0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43, 0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63,
+    0x65, 0x00, 0x06, 0x00, 0x07, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43, 0x75,
+    0x6c, 0x6c, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, 0x05, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x42, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x50, 0x6f, 0x73, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x55, 0x56, 0x00, 0x00, 0x00, 0x05, 0x00,
+    0x04, 0x00, 0x51, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x55, 0x56, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x54,
+    0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+    0x47, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05,
+    0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00,
+    0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48,
+    0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+    0x48, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,
+    0x00, 0x48, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00,
+    0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x48,
+    0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x48, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05,
+    0x00, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x48, 0x00,
+    0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x47,
+    0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00,
+    0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2f,
+    0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x3e, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x3e, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x3e, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x3e,
+    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
+    0x3e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x42, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x51, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
+    0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x15, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04,
+    0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x17, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04,
+    0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x08, 0x00, 0x0d, 0x00,
+    0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c,
+    0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
+    0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
+    0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00,
+    0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00,
+    0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x26,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00,
+    0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
+    0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00,
+    0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b,
+    0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
+    0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x15, 0x00, 0x04, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
+    0x1e, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, 0x00,
+    0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x04, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00,
+    0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x45, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x17, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
+    0x3b, 0x00, 0x04, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04,
+    0x00, 0x09, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x2c, 0x00, 0x06, 0x00, 0x4a, 0x00,
+    0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x04, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x50, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x53, 0x00, 0x00,
+    0x00, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 0x00,
+    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
+    0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04,
+    0x00, 0x09, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2c, 0x00, 0x05, 0x00, 0x0b, 0x00,
+    0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x7a,
+    0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00,
+    0x7e, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00,
+    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00,
+    0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b,
+    0x00, 0x04, 0x00, 0x53, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
+    0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x06, 0x00,
+    0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
+    0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00,
+    0x00, 0x1a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x05, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00,
+    0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
+    0x00, 0x29, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00,
+    0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x23, 0x00, 0x00, 0x00, 0x28,
+    0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00, 0x00,
+    0x41, 0x00, 0x05, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0xf8,
+    0x00, 0x02, 0x00, 0x25, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
+    0x23, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05,
+    0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x2f,
+    0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+    0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00,
+    0x00, 0x34, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x35, 0x00,
+    0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x37,
+    0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xfa, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02,
+    0x00, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x42, 0x00,
+    0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00,
+    0x00, 0x47, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1c, 0x00,
+    0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x49,
+    0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00,
+    0xfd, 0x00, 0x01, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x00,
+    0x00, 0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x52, 0x00,
+    0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x31, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x55,
+    0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
+    0x58, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x59, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00,
+    0x00, 0x42, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x00,
+    0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x58,
+    0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x31, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
+    0x0f, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x09, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x59, 0x00,
+    0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09,
+    0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00,
+    0x62, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00,
+    0x00, 0x63, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x31, 0x00,
+    0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x56,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+    0x81, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00,
+    0x00, 0x41, 0x00, 0x07, 0x00, 0x31, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x55, 0x00,
+    0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x68,
+    0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x59, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
+    0x42, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00,
+    0x00, 0x69, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x68, 0x00,
+    0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x31, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0f,
+    0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x09, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x59, 0x00, 0x00,
+    0x00, 0x6e, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00,
+    0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x70,
+    0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00,
+    0x71, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x31, 0x00, 0x00,
+    0x00, 0x72, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3c, 0x00,
+    0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x81,
+    0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
+    0x50, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00,
+    0x00, 0x3e, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0b, 0x00,
+    0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x79,
+    0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x7a, 0x00, 0x00, 0x00,
+    0x7b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00,
+    0x00, 0x7c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x7d, 0x00,
+    0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x7f,
+    0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00,
+    0x00, 0x81, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x0a, 0x00,
+    0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x45,
+    0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+    0x1f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x83, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05,
+    0x00, 0x2e, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0x84, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00};
+unsigned int  vkvg_main_vert_spv_len   = 3704;
 unsigned char vkvg_main_lcd_frag_spv[] = {
-  0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00,
-  0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
-  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
-  0x25, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00,
-  0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00,
-  0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73,
-  0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64,
-  0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00,
-  0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73,
-  0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75,
-  0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00,
-  0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x45, 0x58, 0x54, 0x5f, 0x73,
-  0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
-  0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00,
-  0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70,
-  0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65,
-  0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00,
-  0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c,
-  0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69,
-  0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x50, 0x61,
-  0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x16, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x53, 0x72, 0x63, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x46,
-  0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x22, 0x00, 0x00, 0x00, 0x75, 0x76, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x4d, 0x61,
-  0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x4e, 0x00, 0x00, 0x00,
-  0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5f, 0x75, 0x62, 0x6f,
-  0x47, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f,
-  0x72, 0x73, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x04, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x63, 0x70, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x75, 0x62, 0x6f, 0x47,
-  0x72, 0x61, 0x64, 0x00, 0x05, 0x00, 0x09, 0x00, 0x6c, 0x00, 0x00, 0x00,
-  0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x72,
-  0x74, 0x50, 0x6f, 0x73, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x58,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x78, 0x00, 0x00, 0x00,
-  0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x64, 0x50,
-  0x6f, 0x73, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x58, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x84, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x88, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x03, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x05, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x78, 0x4c, 0x6f, 0x63,
-  0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x00, 0x05, 0x00, 0x03, 0x00,
-  0xae, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0xdc, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x46, 0x6f, 0x6e, 0x74, 0x55, 0x56,
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xe5, 0x00, 0x00, 0x00,
-  0x66, 0x6f, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x00, 0x05, 0x00, 0x06, 0x00,
-  0xec, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x46, 0x72, 0x61, 0x67, 0x43,
-  0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0xee, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x4d, 0x5f, 0x53, 0x41, 0x4d, 0x50,
-  0x4c, 0x45, 0x53, 0x00, 0x47, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x16, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x4e, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x00, 0x02, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00,
-  0x47, 0x00, 0x03, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x5e, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0xdc, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xe5, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0xec, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0xee, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x2c, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x18, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0x38, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00,
-  0x4b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00,
-  0x4c, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0x57, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00,
-  0x58, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x57, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0x5a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00,
-  0x5b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x06, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
-  0x59, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x5c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x5d, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xad, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0xbb, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0xda, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xdb, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0xdb, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x19, 0x00, 0x09, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x1b, 0x00, 0x03, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xe3, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xe4, 0x00, 0x00, 0x00,
-  0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0xeb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0xeb, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x32, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0xee, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x1b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x1a, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x88, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xad, 0x00, 0x00, 0x00,
-  0xae, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0xf7, 0x00, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0xfb, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x07, 0x00, 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
-  0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
-  0x2a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x2d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
-  0x2d, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
-  0x25, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
-  0x31, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
-  0x34, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x36, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
-  0x2f, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x29, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x38, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
-  0x37, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x29, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x26, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x1b, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x29, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
-  0x1b, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
-  0x42, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-  0x45, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
-  0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x4a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x22, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
-  0x4e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x50, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x07, 0x00, 0x19, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0x51, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x53, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
-  0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
-  0x4f, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-  0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x61, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
-  0x64, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00,
-  0x66, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
-  0x30, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x69, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00,
-  0x69, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x6b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
-  0x65, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
-  0x38, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
-  0x6d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x6f, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
-  0x70, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00,
-  0x72, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
-  0x26, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x76, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00,
-  0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
-  0x71, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
-  0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00,
-  0x79, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x7b, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00,
-  0x7c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00,
-  0x7e, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
-  0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-  0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x80, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x82, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00,
-  0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00,
-  0x7d, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x78, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x87, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x84, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x88, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00,
-  0x8b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x90, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00,
-  0x91, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x93, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00,
-  0x93, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00,
-  0x96, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x8e, 0x00, 0x00, 0x00,
-  0x97, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x98, 0x00, 0x00, 0x00,
-  0x99, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x26, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x9a, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x98, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
-  0x26, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5f, 0x00, 0x00, 0x00,
-  0x9e, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-  0x26, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x9f, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00,
-  0x9f, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00,
-  0xa1, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xa3, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
-  0x5f, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
-  0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00,
-  0x84, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xa7, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00,
-  0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00,
-  0xa3, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00,
-  0xa8, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
-  0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
-  0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00,
-  0x9c, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0xae, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0xaf, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xaf, 0x00, 0x00, 0x00,
-  0xf6, 0x00, 0x04, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xb3, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00,
-  0x7c, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00,
-  0xb4, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0xb7, 0x00, 0x00, 0x00,
-  0xb8, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00,
-  0xb8, 0x00, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00,
-  0xba, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
-  0xb0, 0x00, 0x05, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00,
-  0xb5, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
-  0xbc, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00,
-  0xae, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0xbf, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0x98, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
-  0xc0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xc2, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00,
-  0x41, 0x00, 0x06, 0x00, 0x5f, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00,
-  0x5e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00,
-  0xc4, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xc6, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00,
-  0xc6, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xc8, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00,
-  0x6c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,
-  0xca, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00,
-  0x30, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5f, 0x00, 0x00, 0x00,
-  0xcc, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-  0xcb, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xcd, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00,
-  0xcd, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00,
-  0xcf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xd1, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x31, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00,
-  0xd1, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0xd3, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00,
-  0xd2, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x2e, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
-  0xd3, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0xd4, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0xd5, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00,
-  0x80, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00,
-  0xd5, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0xae, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0xaf, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb1, 0x00, 0x00, 0x00,
-  0xf9, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0x13, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0xf8, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
-  0x29, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00,
-  0x5a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0xde, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x05, 0x00,
-  0xbb, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xe1, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xdf, 0x00, 0x00, 0x00,
-  0xe0, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
-  0xe0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xe3, 0x00, 0x00, 0x00,
-  0xe6, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0xda, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00,
-  0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,
-  0xe6, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
-  0x07, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00,
-  0xe9, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00,
-  0xe1, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xe1, 0x00, 0x00, 0x00,
-  0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xec, 0x00, 0x00, 0x00,
-  0xed, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
-};
-unsigned int vkvg_main_lcd_frag_spv_len = 5784;
-unsigned char wired_frag_spv[] = {
-  0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00,
-  0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
-  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
-  0x09, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
-  0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00,
-  0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73,
-  0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64,
-  0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00,
-  0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73,
-  0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75,
-  0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00,
-  0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x45, 0x58, 0x54, 0x5f, 0x73,
-  0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
-  0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00,
-  0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70,
-  0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65,
-  0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00,
-  0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c,
-  0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69,
-  0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x46,
-  0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x6e, 0x74,
-  0x4d, 0x61, 0x70, 0x00, 0x05, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00,
-  0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0x1a, 0x00, 0x00, 0x00, 0x5f, 0x75, 0x62, 0x6f, 0x47, 0x72, 0x61, 0x64,
-  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x00, 0x00,
-  0x06, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x73, 0x74, 0x6f, 0x70, 0x73, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00,
-  0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x63, 0x70, 0x00, 0x00,
-  0x06, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x75, 0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00,
-  0x05, 0x00, 0x05, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x46, 0x6f,
-  0x6e, 0x74, 0x55, 0x56, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x53, 0x72, 0x63, 0x00, 0x00, 0x00,
-  0x05, 0x00, 0x05, 0x00, 0x24, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x50, 0x61,
-  0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0x26, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74,
-  0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00,
-  0x69, 0x6e, 0x4d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x4d, 0x5f, 0x53, 0x41, 0x4d, 0x50,
-  0x4c, 0x45, 0x53, 0x00, 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x0f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00,
-  0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x19, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
-  0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
-  0x00, 0x01, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
-  0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
-  0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x03, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
-  0x2a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-  0x47, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x80, 0x3f, 0x2c, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x0b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
-  0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00,
-  0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00,
-  0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x10, 0x00, 0x00, 0x00,
-  0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x11, 0x00, 0x00, 0x00,
-  0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x15, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00,
-  0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x15, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00,
-  0x19, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
-  0x1e, 0x00, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x1a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00,
-  0x1c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x1d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
-  0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-  0x17, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x27, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
-  0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
-  0x3b, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
-  0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00,
-  0x2b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
-  0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
-  0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-  0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
-};
+    0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c,
+    0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,
+    0x00, 0x25, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0x04,
+    0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f,
+    0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x09,
+    0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e,
+    0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47,
+    0x4c, 0x5f, 0x45, 0x58, 0x54, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
+    0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47,
+    0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64,
+    0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f,
+    0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+    0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0e, 0x00,
+    0x00, 0x00, 0x69, 0x6e, 0x50, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x16,
+    0x00, 0x00, 0x00, 0x69, 0x6e, 0x53, 0x72, 0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x00, 0x00,
+    0x70, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67,
+    0x43, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x22, 0x00, 0x00, 0x00, 0x75, 0x76,
+    0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x05,
+    0x00, 0x04, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
+    0x56, 0x00, 0x00, 0x00, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00,
+    0x00, 0x5f, 0x75, 0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5c, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5c,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x74, 0x6f, 0x70, 0x73, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00,
+    0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x63, 0x70, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00,
+    0x00, 0x03, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x5e, 0x00,
+    0x00, 0x00, 0x75, 0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00, 0x05, 0x00, 0x09, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x67,
+    0x72, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x73, 0x52, 0x6f, 0x74, 0x61,
+    0x74, 0x65, 0x64, 0x58, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x78, 0x00, 0x00, 0x00, 0x67, 0x72, 0x61,
+    0x64, 0x69, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x64, 0x50, 0x6f, 0x73, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x58,
+    0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x84, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x88,
+    0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
+    0x05, 0x00, 0x05, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x78, 0x4c, 0x6f, 0x63, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64,
+    0x00, 0x05, 0x00, 0x03, 0x00, 0xae, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0xdc, 0x00,
+    0x00, 0x00, 0x69, 0x6e, 0x46, 0x6f, 0x6e, 0x74, 0x55, 0x56, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xe5,
+    0x00, 0x00, 0x00, 0x66, 0x6f, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x00, 0x05, 0x00, 0x06, 0x00, 0xec, 0x00, 0x00, 0x00,
+    0x6f, 0x75, 0x74, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05,
+    0x00, 0xee, 0x00, 0x00, 0x00, 0x4e, 0x55, 0x4d, 0x5f, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x53, 0x00, 0x47, 0x00,
+    0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1e,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00,
+    0x00, 0x47, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00,
+    0x04, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x4e,
+    0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00,
+    0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00,
+    0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47,
+    0x00, 0x04, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
+    0x5e, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xdc, 0x00, 0x00,
+    0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x22, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xec, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x47, 0x00, 0x04, 0x00, 0xee, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02,
+    0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00,
+    0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x2c, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00,
+    0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x0c, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00,
+    0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x19,
+    0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x3b,
+    0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
+    0x0c, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04,
+    0x00, 0x27, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00,
+    0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x04, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x3b, 0x00,
+    0x04, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x27,
+    0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x57, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x1e,
+    0x00, 0x06, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00,
+    0x27, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
+    0x00, 0x3b, 0x00, 0x04, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x04, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x98,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xad, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00,
+    0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x27, 0x00,
+    0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0xda, 0x00, 0x00, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0xda, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xdb, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x19, 0x00, 0x09, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+    0x00, 0x03, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xe4, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xe4, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xeb, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32,
+    0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02,
+    0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b,
+    0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+    0x2c, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00,
+    0x00, 0x6c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x78, 0x00,
+    0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x3b, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04,
+    0x00, 0x2c, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xad, 0x00,
+    0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+    0xf7, 0x00, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00,
+    0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf8,
+    0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
+    0x16, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02,
+    0x00, 0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1e,
+    0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07,
+    0x00, 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1e,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+    0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00,
+    0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2a, 0x00,
+    0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x28,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
+    0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00,
+    0x00, 0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x30, 0x00,
+    0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x31,
+    0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
+    0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00,
+    0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x35, 0x00,
+    0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x36,
+    0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+    0x38, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00,
+    0x00, 0x39, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x37, 0x00,
+    0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x25,
+    0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
+    0x00, 0x1b, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3f, 0x00,
+    0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3d,
+    0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
+    0x25, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x42, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x43, 0x00,
+    0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44,
+    0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
+    0x42, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00,
+    0x00, 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x47, 0x00,
+    0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x49, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00,
+    0x00, 0x4a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x22, 0x00,
+    0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x4e,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07,
+    0x00, 0x19, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x50,
+    0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
+    0x4f, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00,
+    0x00, 0xf9, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, 0x41, 0x00,
+    0x07, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30,
+    0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00,
+    0x60, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00,
+    0x00, 0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00,
+    0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
+    0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
+    0x62, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
+    0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x5f,
+    0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
+    0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00,
+    0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x69, 0x00,
+    0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19,
+    0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x56, 0x00, 0x00, 0x00,
+    0x6b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00,
+    0x00, 0x38, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00,
+    0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6f,
+    0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x71, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x5f, 0x00,
+    0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x33,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x74, 0x00,
+    0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x75,
+    0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00,
+    0x76, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07,
+    0x00, 0x5f, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00,
+    0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x79,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
+    0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
+    0x00, 0x7b, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x7a, 0x00,
+    0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x5e,
+    0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x81, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03,
+    0x00, 0x78, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x85, 0x00,
+    0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x6c,
+    0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00,
+    0x86, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x84, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05,
+    0x00, 0x29, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x88,
+    0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
+    0x1c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00,
+    0x00, 0x8c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x91, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x83, 0x00,
+    0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x3e,
+    0x00, 0x03, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x98, 0x00, 0x00, 0x00,
+    0x99, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x07, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x98, 0x00,
+    0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3d,
+    0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5f, 0x00, 0x00,
+    0x00, 0x9e, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3d, 0x00,
+    0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06,
+    0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0xa1, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0xa2, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00,
+    0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5f, 0x00, 0x00, 0x00, 0xa4,
+    0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0xa6, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa7, 0x00,
+    0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa8,
+    0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0xa9, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa9, 0x00,
+    0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa,
+    0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0xac, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00,
+    0x00, 0xab, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x3e, 0x00,
+    0x03, 0x00, 0xae, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xf8,
+    0x00, 0x02, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb3, 0x00, 0x00,
+    0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x7c, 0x00,
+    0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0xb7,
+    0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x27, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00,
+    0x00, 0xba, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, 0xbb, 0x00,
+    0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xbc,
+    0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x0c, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0c, 0x00,
+    0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x98,
+    0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00,
+    0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04,
+    0x00, 0x06, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00,
+    0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5f, 0x00, 0x00, 0x00, 0xc4,
+    0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0xc6, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc7, 0x00,
+    0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xc8,
+    0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0xc9, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00,
+    0x00, 0xae, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xca, 0x00,
+    0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x5f, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x5e,
+    0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0xcd, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00,
+    0x00, 0x84, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0xcd, 0x00,
+    0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xc9,
+    0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00,
+    0x8e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x31, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x50, 0x00,
+    0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0xd2,
+    0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00,
+    0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xb2, 0x00,
+    0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xd5,
+    0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00,
+    0xd5, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xae, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00,
+    0x00, 0xf9, 0x00, 0x02, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xf9, 0x00,
+    0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x14,
+    0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00,
+    0xdd, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0xde, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x05, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xdf, 0x00,
+    0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00,
+    0xf8, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00,
+    0x00, 0xe5, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xda, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0xdc, 0x00,
+    0x00, 0x00, 0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0xe7,
+    0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
+    0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00,
+    0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xe1, 0x00,
+    0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xed,
+    0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xec, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00,
+    0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00};
+unsigned int  vkvg_main_lcd_frag_spv_len = 5784;
+unsigned char wired_frag_spv[]           = {
+    0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c,
+    0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00,
+    0x00, 0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, 0x04,
+    0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f,
+    0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x09,
+    0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e,
+    0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47,
+    0x4c, 0x5f, 0x45, 0x58, 0x54, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
+    0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47,
+    0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64,
+    0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f,
+    0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
+    0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c,
+    0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x6e, 0x74, 0x4d,
+    0x61, 0x70, 0x00, 0x05, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x00,
+    0x05, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x5f, 0x75, 0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00,
+    0x00, 0x06, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73,
+    0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x74, 0x6f, 0x70, 0x73,
+    0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x63, 0x70, 0x00, 0x00,
+    0x06, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x75, 0x62, 0x6f, 0x47, 0x72, 0x61, 0x64, 0x00, 0x05, 0x00,
+    0x05, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x46, 0x6f, 0x6e, 0x74, 0x55, 0x56, 0x00, 0x00, 0x00, 0x00, 0x05,
+    0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x53, 0x72, 0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
+    0x24, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x50, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05,
+    0x00, 0x26, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x05, 0x00,
+    0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x2b,
+    0x00, 0x00, 0x00, 0x4e, 0x55, 0x4d, 0x5f, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x53, 0x00, 0x47, 0x00, 0x04, 0x00,
+    0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00,
+    0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x21, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x47, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04,
+    0x00, 0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x19, 0x00,
+    0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00,
+    0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00,
+    0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x1a,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x47, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00,
+    0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x24,
+    0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x26, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04,
+    0x00, 0x26, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2a, 0x00,
+    0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x2c, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
+    0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x19, 0x00,
+    0x09, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00,
+    0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x1b, 0x00, 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x1c, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04,
+    0x00, 0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x14, 0x00,
+    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x07,
+    0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
+    0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00,
+    0x00, 0x02, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
+    0x3b, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04,
+    0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x20, 0x00,
+    0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x22, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00,
+    0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x27,
+    0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
+    0x27, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x28, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x32, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x36,
+    0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
+    0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00};
 unsigned int wired_frag_spv_len = 1700;
index 8b4af4dd5915cadbaefcedfd1ede0f44a3363aab..b79dd5079c7c37f6bd212a5398139a017d9829e9 100644 (file)
@@ -1,8 +1,8 @@
 /* stb_image - v2.19 - public domain image loader - http://nothings.org/stb
-                                                                 no warranty implied; use at your own risk
+                                  no warranty implied; use at your own risk
 
    Do this:
-         #define STB_IMAGE_IMPLEMENTATION
+      #define STB_IMAGE_IMPLEMENTATION
    before you include this file in *one* C or C++ file to create the implementation.
 
    // i.e. it should look like this:
 
 
    QUICK NOTES:
-         Primarily of interest to game developers and other people who can
-                 avoid problematic images and only need the trivial interface
+      Primarily of interest to game developers and other people who can
+          avoid problematic images and only need the trivial interface
 
-         JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
-         PNG 1/2/4/8/16-bit-per-channel
+      JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
+      PNG 1/2/4/8/16-bit-per-channel
 
-         TGA (not sure what subset, if a subset)
-         BMP non-1bpp, non-RLE
-         PSD (composited view only, no extra channels, 8/16 bit-per-channel)
+      TGA (not sure what subset, if a subset)
+      BMP non-1bpp, non-RLE
+      PSD (composited view only, no extra channels, 8/16 bit-per-channel)
 
-         GIF (*comp always reports as 4-channel)
-         HDR (radiance rgbE format)
-         PIC (Softimage PIC)
-         PNM (PPM and PGM binary only)
+      GIF (*comp always reports as 4-channel)
+      HDR (radiance rgbE format)
+      PIC (Softimage PIC)
+      PNM (PPM and PGM binary only)
 
-         Animated GIF still needs a proper API, but here's one way to do it:
-                 http://gist.github.com/urraka/685d9a6340b26b830d49
+      Animated GIF still needs a proper API, but here's one way to do it:
+          http://gist.github.com/urraka/685d9a6340b26b830d49
 
-         - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
-         - decode from arbitrary I/O callbacks
-         - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
+      - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
+      - decode from arbitrary I/O callbacks
+      - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
 
    Full documentation under "DOCUMENTATION" below.
 
@@ -48,20 +48,20 @@ LICENSE
 
 RECENT REVISION HISTORY:
 
-         2.19  (2018-02-11) fix warning
-         2.18  (2018-01-30) fix warnings
-         2.17  (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
-         2.16  (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
-         2.15  (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
-         2.14  (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
-         2.13  (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
-         2.12  (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
-         2.11  (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
-                                                RGB-format JPEG; remove white matting in PSD;
-                                                allocate large structures on the stack;
-                                                correct channel count for PNG & BMP
-         2.10  (2016-01-22) avoid warning introduced in 2.09
-         2.09  (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
+      2.19     (2018-02-11) fix warning
+      2.18     (2018-01-30) fix warnings
+      2.17     (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
+      2.16     (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
+      2.15     (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
+      2.14     (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
+      2.13     (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
+      2.12     (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
+      2.11     (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
+                         RGB-format JPEG; remove white matting in PSD;
+                         allocate large structures on the stack;
+                         correct channel count for PNG & BMP
+      2.10     (2016-01-22) avoid warning introduced in 2.09
+      2.09     (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
 
    See end of file for full revision history.
 
@@ -69,38 +69,38 @@ RECENT REVISION HISTORY:
  ============================   Contributors    =========================
 
  Image formats                                                 Extensions, features
-       Sean Barrett (jpeg, png, bmp)              Jetro Lauha (stbi_info)
-       Nicolas Schulz (hdr, psd)                          Martin "SpartanJ" Golini (stbi_info)
-       Jonathan Dummer (tga)                              James "moose2000" Brown (iPhone PNG)
-       Jean-Marc Lienher (gif)                            Ben "Disch" Wenger (io callbacks)
-       Tom Seddon (pic)                                           Omar Cornut (1/2/4-bit PNG)
-       Thatcher Ulrich (psd)                              Nicolas Guillemot (vertical flip)
-       Ken Miller (pgm, ppm)                              Richard Mitton (16-bit PSD)
-       github:urraka (animated gif)               Junggon Kim (PNM comments)
-       Christopher Forseth (animated gif)         Daniel Gibson (16-bit TGA)
-                                                                                  socks-the-fox (16-bit PNG)
-                                                                                  Jeremy Sawicki (handle all ImageNet JPGs)
+    Sean Barrett (jpeg, png, bmp)                 Jetro Lauha (stbi_info)
+    Nicolas Schulz (hdr, psd)                     Martin "SpartanJ" Golini (stbi_info)
+    Jonathan Dummer (tga)                                 James "moose2000" Brown (iPhone PNG)
+    Jean-Marc Lienher (gif)                               Ben "Disch" Wenger (io callbacks)
+    Tom Seddon (pic)                                      Omar Cornut (1/2/4-bit PNG)
+    Thatcher Ulrich (psd)                                 Nicolas Guillemot (vertical flip)
+    Ken Miller (pgm, ppm)                                 Richard Mitton (16-bit PSD)
+    github:urraka (animated gif)                  Junggon Kim (PNM comments)
+    Christopher Forseth (animated gif)    Daniel Gibson (16-bit TGA)
+                                           socks-the-fox (16-bit PNG)
+                                           Jeremy Sawicki (handle all ImageNet JPGs)
  Optimizations & bugfixes                                 Mikhail Morozov (1-bit BMP)
-       Fabian "ryg" Giesen                                        Anael Seghezzi (is-16-bit query)
-       Arseny Kapoulkine
-       John-Mark Allen
+    Fabian "ryg" Giesen                                           Anael Seghezzi (is-16-bit query)
+    Arseny Kapoulkine
+    John-Mark Allen
 
  Bug & warning fixes
-       Marc LeBlanc                    David Woo                  Guillaume George       Martins Mozeiko
-       Christpher Lloyd                Jerry Jansson      Joseph Thomson         Phil Jordan
-       Dave Moore                              Roy Eltham                 Hayaki Saito           Nathan Reed
-       Won Chun                                Luke Graham                Johan Duparc           Nick Verigakis
-       the Horde3D community   Thomas Ruf                 Ronny Chevalier        github:rlyeh
-       Janez Zemva                             John Bartholomew   Michal Cichon          github:romigrou
-       Jonathan Blow                   Ken Hamada                 Tero Hanninen          github:svdijk
-       Laurent Gomila                  Cort Stratton      Sergio Gonzalez        github:snagar
-       Aruelien Pocheville             Thibault Reuille   Cass Everitt           github:Zelex
-       Ryamond Barbiero                Paul Du Bois       Engin Manap            github:grim210
-       Aldo Culquicondor               Philipp Wiesemann  Dale Weiler            github:sammyhw
-       Oriol Ferrer Mesia              Josh Tobin                 Matthew Gregan         github:phprus
-       Julian Raschke                  Gregory Mullen     Baldur Karlsson        github:poppolopoppo
-       Christian Floisand              Kevin Schmidt                                             github:darealshinji
-       Blazej Dariusz Roszkowski                                                                         github:Michaelangel007
+    Marc LeBlanc                       David Woo                  Guillaume George       Martins Mozeiko
+    Christpher Lloyd           Jerry Jansson      Joseph Thomson         Phil Jordan
+    Dave Moore                         Roy Eltham                 Hayaki Saito           Nathan Reed
+    Won Chun                           Luke Graham                Johan Duparc           Nick Verigakis
+    the Horde3D community      Thomas Ruf                 Ronny Chevalier        github:rlyeh
+    Janez Zemva                                John Bartholomew   Michal Cichon          github:romigrou
+    Jonathan Blow                      Ken Hamada                 Tero Hanninen          github:svdijk
+    Laurent Gomila                     Cort Stratton      Sergio Gonzalez        github:snagar
+    Aruelien Pocheville                Thibault Reuille   Cass Everitt           github:Zelex
+    Ryamond Barbiero           Paul Du Bois       Engin Manap            github:grim210
+    Aldo Culquicondor          Philipp Wiesemann  Dale Weiler            github:sammyhw
+    Oriol Ferrer Mesia         Josh Tobin                 Matthew Gregan         github:phprus
+    Julian Raschke                     Gregory Mullen     Baldur Karlsson        github:poppolopoppo
+    Christian Floisand         Kevin Schmidt                                             github:darealshinji
+    Blazej Dariusz Roszkowski                                                                    github:Michaelangel007
 */
 
 #ifndef STBI_INCLUDE_STB_IMAGE_H
@@ -302,24 +302,22 @@ RECENT REVISION HISTORY:
 //        want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
 //
 
-
 #ifndef STBI_NO_STDIO
 #include <stdio.h>
 #endif // STBI_NO_STDIO
 
 #define STBI_VERSION 1
 
-enum
-{
-   STBI_default = 0, // only used for desired_channels
+enum {
+    STBI_default = 0, // only used for desired_channels
 
-   STBI_grey      = 1,
-   STBI_grey_alpha = 2,
-   STBI_rgb               = 3,
-   STBI_rgb_alpha  = 4
+    STBI_grey       = 1,
+    STBI_grey_alpha = 2,
+    STBI_rgb        = 3,
+    STBI_rgb_alpha  = 4
 };
 
-typedef unsigned char stbi_uc;
+typedef unsigned char  stbi_uc;
 typedef unsigned short stbi_us;
 
 #ifdef __cplusplus
@@ -341,11 +339,11 @@ extern "C" {
 // load image by filename, open file, or memory buffer
 //
 
-typedef struct
-{
-   int         (*read)  (void *user,char *data,int size);       // fill 'data' with 'size' bytes.      return number of bytes actually read
-   void                (*skip)  (void *user,int n);                             // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
-   int         (*eof)   (void *user);                                           // returns nonzero if we are at end of file/data
+typedef struct {
+    int (*read)(void *user, char *data,
+                int size);           // fill 'data' with 'size' bytes. return number of bytes actually read
+    void (*skip)(void *user, int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
+    int (*eof)(void *user);          // returns nonzero if we are at end of file/data
 } stbi_io_callbacks;
 
 ////////////////////////////////////
@@ -353,16 +351,18 @@ typedef struct
 // 8-bits-per-channel interface
 //
 
-STBIDEF stbi_uc *stbi_load_from_memory  (stbi_uc                       const *buffer, int len   , int *x, int *y, int *channels_in_file, int desired_channels);
-STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk         , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file,
+                                       int desired_channels);
+STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y,
+                                          int *channels_in_file, int desired_channels);
 #ifndef STBI_NO_GIF
-STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
+STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z,
+                                           int *comp, int req_comp);
 #endif
 
-
 #ifndef STBI_NO_STDIO
-STBIDEF stbi_uc *stbi_load                       (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
-STBIDEF stbi_uc *stbi_load_from_file  (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
 // for stbi_load_from_file, file pointer is left pointing immediately after image
 #endif
 
@@ -371,11 +371,13 @@ STBIDEF stbi_uc *stbi_load_from_file  (FILE *f, int *x, int *y, int *channels_in
 // 16-bits-per-channel interface
 //
 
-STBIDEF stbi_us *stbi_load_16_from_memory      (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
-STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file,
+                                          int desired_channels);
+STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y,
+                                             int *channels_in_file, int desired_channels);
 
 #ifndef STBI_NO_STDIO
-STBIDEF stbi_us *stbi_load_16             (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
 STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
 #endif
 
@@ -384,56 +386,55 @@ STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_i
 // float-per-channel interface
 //
 #ifndef STBI_NO_LINEAR
-   STBIDEF float *stbi_loadf_from_memory        (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
-   STBIDEF float *stbi_loadf_from_callbacks     (stbi_io_callbacks const *clbk, void *user, int *x, int *y,  int *channels_in_file, int desired_channels);
+STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file,
+                                      int desired_channels);
+STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y,
+                                         int *channels_in_file, int desired_channels);
 
-   #ifndef STBI_NO_STDIO
-   STBIDEF float *stbi_loadf                   (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
-   STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
-   #endif
+#ifndef STBI_NO_STDIO
+STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
+#endif
 #endif
 
 #ifndef STBI_NO_HDR
-   STBIDEF void          stbi_hdr_to_ldr_gamma(float gamma);
-   STBIDEF void          stbi_hdr_to_ldr_scale(float scale);
+STBIDEF void stbi_hdr_to_ldr_gamma(float gamma);
+STBIDEF void stbi_hdr_to_ldr_scale(float scale);
 #endif // STBI_NO_HDR
 
 #ifndef STBI_NO_LINEAR
-   STBIDEF void          stbi_ldr_to_hdr_gamma(float gamma);
-   STBIDEF void          stbi_ldr_to_hdr_scale(float scale);
+STBIDEF void stbi_ldr_to_hdr_gamma(float gamma);
+STBIDEF void stbi_ldr_to_hdr_scale(float scale);
 #endif // STBI_NO_LINEAR
 
 // stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
-STBIDEF int       stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
-STBIDEF int       stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
+STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
+STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
 #ifndef STBI_NO_STDIO
-STBIDEF int             stbi_is_hdr              (char const *filename);
-STBIDEF int             stbi_is_hdr_from_file(FILE *f);
+STBIDEF int stbi_is_hdr(char const *filename);
+STBIDEF int stbi_is_hdr_from_file(FILE *f);
 #endif // STBI_NO_STDIO
 
-
 // get a VERY brief reason for failure
 // NOT THREADSAFE
-STBIDEF const char *stbi_failure_reason         (void);
+STBIDEF const char *stbi_failure_reason(void);
 
 // free the loaded image -- this is just free()
-STBIDEF void    stbi_image_free          (void *retval_from_stbi_load);
+STBIDEF void stbi_image_free(void *retval_from_stbi_load);
 
 // get image dimensions & components without fully decoding
-STBIDEF int             stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
-STBIDEF int             stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
-STBIDEF int             stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len);
-STBIDEF int             stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user);
+STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
+STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len);
+STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user);
 
 #ifndef STBI_NO_STDIO
-STBIDEF int             stbi_info                               (char const *filename,         int *x, int *y, int *comp);
-STBIDEF int             stbi_info_from_file     (FILE *f,                                      int *x, int *y, int *comp);
-STBIDEF int             stbi_is_16_bit                  (char const *filename);
-STBIDEF int             stbi_is_16_bit_from_file(FILE *f);
+STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp);
+STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp);
+STBIDEF int stbi_is_16_bit(char const *filename);
+STBIDEF int stbi_is_16_bit_from_file(FILE *f);
 #endif
 
-
-
 // for image formats that explicitly notate that they have premultiplied alpha,
 // we just return the colors as stored in the file. set this flag to force
 // unpremultiplication. results are undefined if the unpremultiply overflow.
@@ -449,13 +450,13 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
 // ZLIB client - used by PNG, available for other purposes
 
 STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
-STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header);
+STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen,
+                                                           int parse_header);
 STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
-STBIDEF int      stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
+STBIDEF int   stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
 
 STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
-STBIDEF int      stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
-
+STBIDEF int   stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
 
 #ifdef __cplusplus
 }
@@ -468,44 +469,42 @@ STBIDEF int         stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
 
 #ifdef STB_IMAGE_IMPLEMENTATION
 
-#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \
-  || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \
-  || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \
-  || defined(STBI_ONLY_ZLIB)
-   #ifndef STBI_ONLY_JPEG
-   #define STBI_NO_JPEG
-   #endif
-   #ifndef STBI_ONLY_PNG
-   #define STBI_NO_PNG
-   #endif
-   #ifndef STBI_ONLY_BMP
-   #define STBI_NO_BMP
-   #endif
-   #ifndef STBI_ONLY_PSD
-   #define STBI_NO_PSD
-   #endif
-   #ifndef STBI_ONLY_TGA
-   #define STBI_NO_TGA
-   #endif
-   #ifndef STBI_ONLY_GIF
-   #define STBI_NO_GIF
-   #endif
-   #ifndef STBI_ONLY_HDR
-   #define STBI_NO_HDR
-   #endif
-   #ifndef STBI_ONLY_PIC
-   #define STBI_NO_PIC
-   #endif
-   #ifndef STBI_ONLY_PNM
-   #define STBI_NO_PNM
-   #endif
+#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) || defined(STBI_ONLY_TGA) ||           \
+    defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) ||            \
+    defined(STBI_ONLY_PNM) || defined(STBI_ONLY_ZLIB)
+#ifndef STBI_ONLY_JPEG
+#define STBI_NO_JPEG
+#endif
+#ifndef STBI_ONLY_PNG
+#define STBI_NO_PNG
+#endif
+#ifndef STBI_ONLY_BMP
+#define STBI_NO_BMP
+#endif
+#ifndef STBI_ONLY_PSD
+#define STBI_NO_PSD
+#endif
+#ifndef STBI_ONLY_TGA
+#define STBI_NO_TGA
+#endif
+#ifndef STBI_ONLY_GIF
+#define STBI_NO_GIF
+#endif
+#ifndef STBI_ONLY_HDR
+#define STBI_NO_HDR
+#endif
+#ifndef STBI_ONLY_PIC
+#define STBI_NO_PIC
+#endif
+#ifndef STBI_ONLY_PNM
+#define STBI_NO_PNM
+#endif
 #endif
 
 #if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB)
 #define STBI_NO_ZLIB
 #endif
 
-
 #include <stdarg.h>
 #include <stddef.h> // ptrdiff_t on osx
 #include <stdlib.h>
@@ -513,7 +512,7 @@ STBIDEF int   stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
 #include <limits.h>
 
 #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
-#include <math.h>  // ldexp, pow
+#include <math.h> // ldexp, pow
 #endif
 
 #ifndef STBI_NO_STDIO
@@ -525,38 +524,36 @@ STBIDEF int         stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
 #define STBI_ASSERT(x) assert(x)
 #endif
 
-
 #ifndef _MSC_VER
-   #ifdef __cplusplus
-   #define stbi_inline inline
-   #else
-   #define stbi_inline
-   #endif
+#ifdef __cplusplus
+#define stbi_inline inline
 #else
-   #define stbi_inline __forceinline
+#define stbi_inline
+#endif
+#else
+#define stbi_inline __forceinline
 #endif
-
 
 #ifdef _MSC_VER
 typedef unsigned short stbi__uint16;
-typedef          signed short stbi__int16;
+typedef signed short   stbi__int16;
 typedef unsigned int   stbi__uint32;
-typedef          signed int   stbi__int32;
+typedef signed int     stbi__int32;
 #else
 #include <stdint.h>
 typedef uint16_t stbi__uint16;
-typedef int16_t         stbi__int16;
+typedef int16_t  stbi__int16;
 typedef uint32_t stbi__uint32;
-typedef int32_t         stbi__int32;
+typedef int32_t  stbi__int32;
 #endif
 
 // should produce compiler error if size is wrong
-typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
+typedef unsigned char validate_uint32[sizeof(stbi__uint32) == 4 ? 1 : -1];
 
 #ifdef _MSC_VER
-#define STBI_NOTUSED(v)         (void)(v)
+#define STBI_NOTUSED(v) (void)(v)
 #else
-#define STBI_NOTUSED(v)         (void)sizeof(v)
+#define STBI_NOTUSED(v) (void)sizeof(v)
 #endif
 
 #ifdef _MSC_VER
@@ -564,9 +561,9 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 #endif
 
 #ifdef STBI_HAS_LROTL
-   #define stbi_lrot(x,y)  _lrotl(x,y)
+#define stbi_lrot(x, y) _lrotl(x, y)
 #else
-   #define stbi_lrot(x,y)  (((x) << (y)) | ((x) >> (32 - (y))))
+#define stbi_lrot(x, y) (((x) << (y)) | ((x) >> (32 - (y))))
 #endif
 
 #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
@@ -578,13 +575,13 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 #endif
 
 #ifndef STBI_MALLOC
-#define STBI_MALLOC(sz)                          malloc(sz)
-#define STBI_REALLOC(p,newsz)    realloc(p,newsz)
-#define STBI_FREE(p)                     free(p)
+#define STBI_MALLOC(sz)        malloc(sz)
+#define STBI_REALLOC(p, newsz) realloc(p, newsz)
+#define STBI_FREE(p)           free(p)
 #endif
 
 #ifndef STBI_REALLOC_SIZED
-#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
+#define STBI_REALLOC_SIZED(p, oldsz, newsz) STBI_REALLOC(p, newsz)
 #endif
 
 // x86/x64 detection
@@ -626,43 +623,39 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 
 #ifdef _MSC_VER
 
-#if _MSC_VER >= 1400  // not VC6
-#include <intrin.h> // __cpuid
-static int stbi__cpuid3(void)
-{
-   int info[4];
-   __cpuid(info,1);
-   return info[3];
+#if _MSC_VER >= 1400 // not VC6
+#include <intrin.h>  // __cpuid
+static int stbi__cpuid3(void) {
+    int info[4];
+    __cpuid(info, 1);
+    return info[3];
 }
 #else
-static int stbi__cpuid3(void)
-{
-   int res;
-   __asm {
+static int stbi__cpuid3(void) {
+    int res;
+    __asm {
          mov  eax,1
          cpuid
          mov  res,edx
-   }
-   return res;
+    }
+    return res;
 }
 #endif
 
 #define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
 
-static int stbi__sse2_available(void)
-{
-   int info3 = stbi__cpuid3();
-   return ((info3 >> 26) & 1) != 0;
+static int stbi__sse2_available(void) {
+    int info3 = stbi__cpuid3();
+    return ((info3 >> 26) & 1) != 0;
 }
 #else // assume GCC-style if not VC++
 #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
 
-static int stbi__sse2_available(void)
-{
-   // If we're even attempting to compile this on GCC/Clang, that means
-   // -msse2 is on, which means the compiler is allowed to use SSE2
-   // instructions at will, and so are we.
-   return 1;
+static int stbi__sse2_available(void) {
+    // If we're even attempting to compile this on GCC/Clang, that means
+    // -msse2 is on, which means the compiler is allowed to use SSE2
+    // instructions at will, and so are we.
+    return 1;
 }
 #endif
 #endif
@@ -688,176 +681,146 @@ static int stbi__sse2_available(void)
 
 // stbi__context structure is our basic context used by all images, so it
 // contains all the IO context, plus some basic image information
-typedef struct
-{
-   stbi__uint32 img_x, img_y;
-   int img_n, img_out_n;
+typedef struct {
+    stbi__uint32 img_x, img_y;
+    int          img_n, img_out_n;
 
-   stbi_io_callbacks io;
-   void *io_user_data;
+    stbi_io_callbacks io;
+    void             *io_user_data;
 
-   int read_from_callbacks;
-   int buflen;
-   stbi_uc buffer_start[128];
+    int     read_from_callbacks;
+    int     buflen;
+    stbi_uc buffer_start[128];
 
-   stbi_uc *img_buffer, *img_buffer_end;
-   stbi_uc *img_buffer_original, *img_buffer_original_end;
+    stbi_uc *img_buffer, *img_buffer_end;
+    stbi_uc *img_buffer_original, *img_buffer_original_end;
 } stbi__context;
 
-
 static void stbi__refill_buffer(stbi__context *s);
 
 // initialize a memory-decode context
-static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
-{
-   s->io.read = NULL;
-   s->read_from_callbacks = 0;
-   s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
-   s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
+static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) {
+    s->io.read             = NULL;
+    s->read_from_callbacks = 0;
+    s->img_buffer = s->img_buffer_original = (stbi_uc *)buffer;
+    s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *)buffer + len;
 }
 
 // initialize a callback-based context
-static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user)
-{
-   s->io = *c;
-   s->io_user_data = user;
-   s->buflen = sizeof(s->buffer_start);
-   s->read_from_callbacks = 1;
-   s->img_buffer_original = s->buffer_start;
-   stbi__refill_buffer(s);
-   s->img_buffer_original_end = s->img_buffer_end;
+static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) {
+    s->io                  = *c;
+    s->io_user_data        = user;
+    s->buflen              = sizeof(s->buffer_start);
+    s->read_from_callbacks = 1;
+    s->img_buffer_original = s->buffer_start;
+    stbi__refill_buffer(s);
+    s->img_buffer_original_end = s->img_buffer_end;
 }
 
 #ifndef STBI_NO_STDIO
 
-static int stbi__stdio_read(void *user, char *data, int size)
-{
-   return (int) fread(data,1,size,(FILE*) user);
-}
+static int stbi__stdio_read(void *user, char *data, int size) { return (int)fread(data, 1, size, (FILE *)user); }
 
-static void stbi__stdio_skip(void *user, int n)
-{
-   fseek((FILE*) user, n, SEEK_CUR);
-}
+static void stbi__stdio_skip(void *user, int n) { fseek((FILE *)user, n, SEEK_CUR); }
 
-static int stbi__stdio_eof(void *user)
-{
-   return feof((FILE*) user);
-}
+static int stbi__stdio_eof(void *user) { return feof((FILE *)user); }
 
-static stbi_io_callbacks stbi__stdio_callbacks =
-{
-   stbi__stdio_read,
-   stbi__stdio_skip,
-   stbi__stdio_eof,
+static stbi_io_callbacks stbi__stdio_callbacks = {
+    stbi__stdio_read,
+    stbi__stdio_skip,
+    stbi__stdio_eof,
 };
 
-static void stbi__start_file(stbi__context *s, FILE *f)
-{
-   stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f);
-}
+static void stbi__start_file(stbi__context *s, FILE *f) { stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *)f); }
 
-//static void stop_file(stbi__context *s) { }
+// static void stop_file(stbi__context *s) { }
 
 #endif // !STBI_NO_STDIO
 
-static void stbi__rewind(stbi__context *s)
-{
-   // conceptually rewind SHOULD rewind to the beginning of the stream,
-   // but we just rewind to the beginning of the initial buffer, because
-   // we only use it after doing 'test', which only ever looks at at most 92 bytes
-   s->img_buffer = s->img_buffer_original;
-   s->img_buffer_end = s->img_buffer_original_end;
+static void stbi__rewind(stbi__context *s) {
+    // conceptually rewind SHOULD rewind to the beginning of the stream,
+    // but we just rewind to the beginning of the initial buffer, because
+    // we only use it after doing 'test', which only ever looks at at most 92 bytes
+    s->img_buffer     = s->img_buffer_original;
+    s->img_buffer_end = s->img_buffer_original_end;
 }
 
-enum
-{
-   STBI_ORDER_RGB,
-   STBI_ORDER_BGR
-};
+enum { STBI_ORDER_RGB, STBI_ORDER_BGR };
 
-typedef struct
-{
-   int bits_per_channel;
-   int num_channels;
-   int channel_order;
+typedef struct {
+    int bits_per_channel;
+    int num_channels;
+    int channel_order;
 } stbi__result_info;
 
 #ifndef STBI_NO_JPEG
-static int             stbi__jpeg_test(stbi__context *s);
-static void       *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int             stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp);
+static int   stbi__jpeg_test(stbi__context *s);
+static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int   stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp);
 #endif
 
 #ifndef STBI_NO_PNG
-static int             stbi__png_test(stbi__context *s);
-static void       *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int             stbi__png_info(stbi__context *s, int *x, int *y, int *comp);
-static int             stbi__png_is16(stbi__context *s);
+static int   stbi__png_test(stbi__context *s);
+static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int   stbi__png_info(stbi__context *s, int *x, int *y, int *comp);
+static int   stbi__png_is16(stbi__context *s);
 #endif
 
 #ifndef STBI_NO_BMP
-static int             stbi__bmp_test(stbi__context *s);
-static void       *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int             stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp);
+static int   stbi__bmp_test(stbi__context *s);
+static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int   stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp);
 #endif
 
 #ifndef STBI_NO_TGA
-static int             stbi__tga_test(stbi__context *s);
-static void       *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int             stbi__tga_info(stbi__context *s, int *x, int *y, int *comp);
+static int   stbi__tga_test(stbi__context *s);
+static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int   stbi__tga_info(stbi__context *s, int *x, int *y, int *comp);
 #endif
 
 #ifndef STBI_NO_PSD
-static int             stbi__psd_test(stbi__context *s);
-static void       *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc);
-static int             stbi__psd_info(stbi__context *s, int *x, int *y, int *comp);
-static int             stbi__psd_is16(stbi__context *s);
+static int   stbi__psd_test(stbi__context *s);
+static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc);
+static int   stbi__psd_info(stbi__context *s, int *x, int *y, int *comp);
+static int   stbi__psd_is16(stbi__context *s);
 #endif
 
 #ifndef STBI_NO_HDR
-static int             stbi__hdr_test(stbi__context *s);
-static float   *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int             stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp);
+static int    stbi__hdr_test(stbi__context *s);
+static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int    stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp);
 #endif
 
 #ifndef STBI_NO_PIC
-static int             stbi__pic_test(stbi__context *s);
-static void       *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int             stbi__pic_info(stbi__context *s, int *x, int *y, int *comp);
+static int   stbi__pic_test(stbi__context *s);
+static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int   stbi__pic_info(stbi__context *s, int *x, int *y, int *comp);
 #endif
 
 #ifndef STBI_NO_GIF
-static int             stbi__gif_test(stbi__context *s);
-static void       *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static void       *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
-static int             stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
+static int   stbi__gif_test(stbi__context *s);
+static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
+static int   stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
 #endif
 
 #ifndef STBI_NO_PNM
-static int             stbi__pnm_test(stbi__context *s);
-static void       *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
-static int             stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
+static int   stbi__pnm_test(stbi__context *s);
+static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int   stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
 #endif
 
 // this is not threadsafe
 static const char *stbi__g_failure_reason;
 
-STBIDEF const char *stbi_failure_reason(void)
-{
-   return stbi__g_failure_reason;
-}
+STBIDEF const char *stbi_failure_reason(void) { return stbi__g_failure_reason; }
 
-static int stbi__err(const char *str)
-{
-   stbi__g_failure_reason = str;
-   return 0;
+static int stbi__err(const char *str) {
+    stbi__g_failure_reason = str;
+    return 0;
 }
 
-static void *stbi__malloc(size_t size)
-{
-       return STBI_MALLOC(size);
-}
+static void *stbi__malloc(size_t size) { return STBI_MALLOC(size); }
 
 // stb_image uses ints pervasively, including for offset calculations.
 // therefore the largest decoded image size we can support with the
@@ -871,66 +834,63 @@ static void *stbi__malloc(size_t size)
 
 // return 1 if the sum is valid, 0 on overflow.
 // negative terms are considered invalid.
-static int stbi__addsizes_valid(int a, int b)
-{
-   if (b < 0) return 0;
-   // now 0 <= b <= INT_MAX, hence also
-   // 0 <= INT_MAX - b <= INTMAX.
-   // And "a + b <= INT_MAX" (which might overflow) is the
-   // same as a <= INT_MAX - b (no overflow)
-   return a <= INT_MAX - b;
+static int stbi__addsizes_valid(int a, int b) {
+    if (b < 0)
+        return 0;
+    // now 0 <= b <= INT_MAX, hence also
+    // 0 <= INT_MAX - b <= INTMAX.
+    // And "a + b <= INT_MAX" (which might overflow) is the
+    // same as a <= INT_MAX - b (no overflow)
+    return a <= INT_MAX - b;
 }
 
 // returns 1 if the product is valid, 0 on overflow.
 // negative factors are considered invalid.
-static int stbi__mul2sizes_valid(int a, int b)
-{
-   if (a < 0 || b < 0) return 0;
-   if (b == 0) return 1; // mul-by-0 is always safe
-   // portable way to check for no overflows in a*b
-   return a <= INT_MAX/b;
+static int stbi__mul2sizes_valid(int a, int b) {
+    if (a < 0 || b < 0)
+        return 0;
+    if (b == 0)
+        return 1; // mul-by-0 is always safe
+    // portable way to check for no overflows in a*b
+    return a <= INT_MAX / b;
 }
 
 // returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow
-static int stbi__mad2sizes_valid(int a, int b, int add)
-{
-   return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add);
+static int stbi__mad2sizes_valid(int a, int b, int add) {
+    return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add);
 }
 
 // returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow
-static int stbi__mad3sizes_valid(int a, int b, int c, int add)
-{
-   return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
-         stbi__addsizes_valid(a*b*c, add);
+static int stbi__mad3sizes_valid(int a, int b, int c, int add) {
+    return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && stbi__addsizes_valid(a * b * c, add);
 }
 
 // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
 #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
-static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
-{
-   return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
-         stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add);
+static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) {
+    return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && stbi__mul2sizes_valid(a * b * c, d) &&
+           stbi__addsizes_valid(a * b * c * d, add);
 }
 #endif
 
 // mallocs with size overflow checking
-static void *stbi__malloc_mad2(int a, int b, int add)
-{
-   if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
-   return stbi__malloc(a*b + add);
+static void *stbi__malloc_mad2(int a, int b, int add) {
+    if (!stbi__mad2sizes_valid(a, b, add))
+        return NULL;
+    return stbi__malloc(a * b + add);
 }
 
-static void *stbi__malloc_mad3(int a, int b, int c, int add)
-{
-   if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL;
-   return stbi__malloc(a*b*c + add);
+static void *stbi__malloc_mad3(int a, int b, int c, int add) {
+    if (!stbi__mad3sizes_valid(a, b, c, add))
+        return NULL;
+    return stbi__malloc(a * b * c + add);
 }
 
 #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
-static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
-{
-   if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL;
-   return stbi__malloc(a*b*c*d + add);
+static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) {
+    if (!stbi__mad4sizes_valid(a, b, c, d, add))
+        return NULL;
+    return stbi__malloc(a * b * c * d + add);
 }
 #endif
 
@@ -939,365 +899,356 @@ static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
 // stbi__errpuc - error returning pointer to unsigned char
 
 #ifdef STBI_NO_FAILURE_STRINGS
-   #define stbi__err(x,y)  0
+#define stbi__err(x, y) 0
 #elif defined(STBI_FAILURE_USERMSG)
-   #define stbi__err(x,y)  stbi__err(y)
+#define stbi__err(x, y) stbi__err(y)
 #else
-   #define stbi__err(x,y)  stbi__err(x)
+#define stbi__err(x, y) stbi__err(x)
 #endif
 
-#define stbi__errpf(x,y)   ((float *)(size_t) (stbi__err(x,y)?NULL:NULL))
-#define stbi__errpuc(x,y)  ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL))
+#define stbi__errpf(x, y)  ((float *)(size_t)(stbi__err(x, y) ? NULL : NULL))
+#define stbi__errpuc(x, y) ((unsigned char *)(size_t)(stbi__err(x, y) ? NULL : NULL))
 
-STBIDEF void stbi_image_free(void *retval_from_stbi_load)
-{
-   STBI_FREE(retval_from_stbi_load);
-}
+STBIDEF void stbi_image_free(void *retval_from_stbi_load) { STBI_FREE(retval_from_stbi_load); }
 
 #ifndef STBI_NO_LINEAR
-static float   *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
+static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
 #endif
 
 #ifndef STBI_NO_HDR
-static stbi_uc *stbi__hdr_to_ldr(float  *data, int x, int y, int comp);
+static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp);
 #endif
 
 static int stbi__vertically_flip_on_load = 0;
 
-STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
-{
-       stbi__vertically_flip_on_load = flag_true_if_should_flip;
+STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) {
+    stbi__vertically_flip_on_load = flag_true_if_should_flip;
 }
 
-static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
-{
-   memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
-   ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed
-   ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
-   ri->num_channels = 0;
-
-   #ifndef STBI_NO_JPEG
-   if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_PNG
-   if (stbi__png_test(s))  return stbi__png_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_BMP
-   if (stbi__bmp_test(s))  return stbi__bmp_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_GIF
-   if (stbi__gif_test(s))  return stbi__gif_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_PSD
-   if (stbi__psd_test(s))  return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
-   #endif
-   #ifndef STBI_NO_PIC
-   if (stbi__pic_test(s))  return stbi__pic_load(s,x,y,comp,req_comp, ri);
-   #endif
-   #ifndef STBI_NO_PNM
-   if (stbi__pnm_test(s))  return stbi__pnm_load(s,x,y,comp,req_comp, ri);
-   #endif
-
-   #ifndef STBI_NO_HDR
-   if (stbi__hdr_test(s)) {
-         float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri);
-         return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
-   }
-   #endif
-
-   #ifndef STBI_NO_TGA
-   // test tga last because it's a crappy test!
-   if (stbi__tga_test(s))
-         return stbi__tga_load(s,x,y,comp,req_comp, ri);
-   #endif
-
-   return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
-}
-
-static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels)
-{
-   int i;
-   int img_len = w * h * channels;
-   stbi_uc *reduced;
+static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri,
+                             int bpc) {
+    memset(ri, 0, sizeof(*ri));         // make sure it's initialized if we add new fields
+    ri->bits_per_channel = 8;           // default is 8 so most paths don't have to be changed
+    ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
+    ri->num_channels  = 0;
 
-   reduced = (stbi_uc *) stbi__malloc(img_len);
-   if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory");
+#ifndef STBI_NO_JPEG
+    if (stbi__jpeg_test(s))
+        return stbi__jpeg_load(s, x, y, comp, req_comp, ri);
+#endif
+#ifndef STBI_NO_PNG
+    if (stbi__png_test(s))
+        return stbi__png_load(s, x, y, comp, req_comp, ri);
+#endif
+#ifndef STBI_NO_BMP
+    if (stbi__bmp_test(s))
+        return stbi__bmp_load(s, x, y, comp, req_comp, ri);
+#endif
+#ifndef STBI_NO_GIF
+    if (stbi__gif_test(s))
+        return stbi__gif_load(s, x, y, comp, req_comp, ri);
+#endif
+#ifndef STBI_NO_PSD
+    if (stbi__psd_test(s))
+        return stbi__psd_load(s, x, y, comp, req_comp, ri, bpc);
+#endif
+#ifndef STBI_NO_PIC
+    if (stbi__pic_test(s))
+        return stbi__pic_load(s, x, y, comp, req_comp, ri);
+#endif
+#ifndef STBI_NO_PNM
+    if (stbi__pnm_test(s))
+        return stbi__pnm_load(s, x, y, comp, req_comp, ri);
+#endif
+
+#ifndef STBI_NO_HDR
+    if (stbi__hdr_test(s)) {
+        float *hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri);
+        return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
+    }
+#endif
 
-   for (i = 0; i < img_len; ++i)
-         reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling
+#ifndef STBI_NO_TGA
+    // test tga last because it's a crappy test!
+    if (stbi__tga_test(s))
+        return stbi__tga_load(s, x, y, comp, req_comp, ri);
+#endif
 
-   STBI_FREE(orig);
-   return reduced;
+    return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
 }
 
-static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels)
-{
-   int i;
-   int img_len = w * h * channels;
-   stbi__uint16 *enlarged;
+static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) {
+    int      i;
+    int      img_len = w * h * channels;
+    stbi_uc *reduced;
 
-   enlarged = (stbi__uint16 *) stbi__malloc(img_len*2);
-   if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
+    reduced = (stbi_uc *)stbi__malloc(img_len);
+    if (reduced == NULL)
+        return stbi__errpuc("outofmem", "Out of memory");
 
-   for (i = 0; i < img_len; ++i)
-         enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
+    for (i = 0; i < img_len; ++i)
+        reduced[i] =
+            (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling
 
-   STBI_FREE(orig);
-   return enlarged;
+    STBI_FREE(orig);
+    return reduced;
 }
 
-static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
-{
-   int row;
-   size_t bytes_per_row = (size_t)w * bytes_per_pixel;
-   stbi_uc temp[2048];
-   stbi_uc *bytes = (stbi_uc *)image;
-
-   for (row = 0; row < (h>>1); row++) {
-         stbi_uc *row0 = bytes + row*bytes_per_row;
-         stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row;
-         // swap row0 with row1
-         size_t bytes_left = bytes_per_row;
-         while (bytes_left) {
-                size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
-                memcpy(temp, row0, bytes_copy);
-                memcpy(row0, row1, bytes_copy);
-                memcpy(row1, temp, bytes_copy);
-                row0 += bytes_copy;
-                row1 += bytes_copy;
-                bytes_left -= bytes_copy;
-         }
-   }
-}
-
-static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
-{
-   int slice;
-   int slice_size = w * h * bytes_per_pixel;
+static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) {
+    int           i;
+    int           img_len = w * h * channels;
+    stbi__uint16 *enlarged;
+
+    enlarged = (stbi__uint16 *)stbi__malloc(img_len * 2);
+    if (enlarged == NULL)
+        return (stbi__uint16 *)stbi__errpuc("outofmem", "Out of memory");
 
-   stbi_uc *bytes = (stbi_uc *)image;
-   for (slice = 0; slice < z; ++slice) {
-         stbi__vertical_flip(bytes, w, h, bytes_per_pixel); 
-         bytes += slice_size; 
-   }
+    for (i = 0; i < img_len; ++i)
+        enlarged[i] =
+            (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
+
+    STBI_FREE(orig);
+    return enlarged;
 }
 
-static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__result_info ri;
-   void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8);
+static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) {
+    int      row;
+    size_t   bytes_per_row = (size_t)w * bytes_per_pixel;
+    stbi_uc  temp[2048];
+    stbi_uc *bytes = (stbi_uc *)image;
+
+    for (row = 0; row < (h >> 1); row++) {
+        stbi_uc *row0 = bytes + row * bytes_per_row;
+        stbi_uc *row1 = bytes + (h - row - 1) * bytes_per_row;
+        // swap row0 with row1
+        size_t bytes_left = bytes_per_row;
+        while (bytes_left) {
+            size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
+            memcpy(temp, row0, bytes_copy);
+            memcpy(row0, row1, bytes_copy);
+            memcpy(row1, temp, bytes_copy);
+            row0 += bytes_copy;
+            row1 += bytes_copy;
+            bytes_left -= bytes_copy;
+        }
+    }
+}
+
+static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) {
+    int slice;
+    int slice_size = w * h * bytes_per_pixel;
+
+    stbi_uc *bytes = (stbi_uc *)image;
+    for (slice = 0; slice < z; ++slice) {
+        stbi__vertical_flip(bytes, w, h, bytes_per_pixel);
+        bytes += slice_size;
+    }
+}
+
+static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) {
+    stbi__result_info ri;
+    void             *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8);
 
-   if (result == NULL)
-         return NULL;
+    if (result == NULL)
+        return NULL;
 
-   if (ri.bits_per_channel != 8) {
-         STBI_ASSERT(ri.bits_per_channel == 16);
-         result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
-         ri.bits_per_channel = 8;
-   }
+    if (ri.bits_per_channel != 8) {
+        STBI_ASSERT(ri.bits_per_channel == 16);
+        result              = stbi__convert_16_to_8((stbi__uint16 *)result, *x, *y, req_comp == 0 ? *comp : req_comp);
+        ri.bits_per_channel = 8;
+    }
 
-   // @TODO: move stbi__convert_format to here
+    // @TODO: move stbi__convert_format to here
 
-   if (stbi__vertically_flip_on_load) {
-         int channels = req_comp ? req_comp : *comp;
-         stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
-   }
+    if (stbi__vertically_flip_on_load) {
+        int channels = req_comp ? req_comp : *comp;
+        stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
+    }
 
-   return (unsigned char *) result;
+    return (unsigned char *)result;
 }
 
-static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__result_info ri;
-   void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16);
+static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) {
+    stbi__result_info ri;
+    void             *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16);
 
-   if (result == NULL)
-         return NULL;
+    if (result == NULL)
+        return NULL;
 
-   if (ri.bits_per_channel != 16) {
-         STBI_ASSERT(ri.bits_per_channel == 8);
-         result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
-         ri.bits_per_channel = 16;
-   }
+    if (ri.bits_per_channel != 16) {
+        STBI_ASSERT(ri.bits_per_channel == 8);
+        result              = stbi__convert_8_to_16((stbi_uc *)result, *x, *y, req_comp == 0 ? *comp : req_comp);
+        ri.bits_per_channel = 16;
+    }
 
-   // @TODO: move stbi__convert_format16 to here
-   // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision
+    // @TODO: move stbi__convert_format16 to here
+    // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision
 
-   if (stbi__vertically_flip_on_load) {
-         int channels = req_comp ? req_comp : *comp;
-         stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16));
-   }
+    if (stbi__vertically_flip_on_load) {
+        int channels = req_comp ? req_comp : *comp;
+        stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16));
+    }
 
-   return (stbi__uint16 *) result;
+    return (stbi__uint16 *)result;
 }
 
 #if !defined(STBI_NO_HDR) || !defined(STBI_NO_LINEAR)
-static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
-{
-   if (stbi__vertically_flip_on_load && result != NULL) {
-         int channels = req_comp ? req_comp : *comp;
-         stbi__vertical_flip(result, *x, *y, channels * sizeof(float));
-   }
+static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) {
+    if (stbi__vertically_flip_on_load && result != NULL) {
+        int channels = req_comp ? req_comp : *comp;
+        stbi__vertical_flip(result, *x, *y, channels * sizeof(float));
+    }
 }
 #endif
 
 #ifndef STBI_NO_STDIO
 
-static FILE *stbi__fopen(char const *filename, char const *mode)
-{
-   FILE *f;
+static FILE *stbi__fopen(char const *filename, char const *mode) {
+    FILE *f;
 #if defined(_MSC_VER) && _MSC_VER >= 1400
-   if (0 != fopen_s(&f, filename, mode))
-         f=0;
+    if (0 != fopen_s(&f, filename, mode))
+        f = 0;
 #else
-   f = fopen(filename, mode);
+    f = fopen(filename, mode);
 #endif
-   return f;
+    return f;
 }
 
+STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) {
+    FILE          *f = stbi__fopen(filename, "rb");
+    unsigned char *result;
+    if (!f)
+        return stbi__errpuc("can't fopen", "Unable to open file");
+    result = stbi_load_from_file(f, x, y, comp, req_comp);
+    fclose(f);
+    return result;
+}
 
-STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
-{
-   FILE *f = stbi__fopen(filename, "rb");
-   unsigned char *result;
-   if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
-   result = stbi_load_from_file(f,x,y,comp,req_comp);
-   fclose(f);
-   return result;
+STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) {
+    unsigned char *result;
+    stbi__context  s;
+    stbi__start_file(&s, f);
+    result = stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp);
+    if (result) {
+        // need to 'unget' all the characters in the IO buffer
+        fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR);
+    }
+    return result;
 }
 
-STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
-{
-   unsigned char *result;
-   stbi__context s;
-   stbi__start_file(&s,f);
-   result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
-   if (result) {
-         // need to 'unget' all the characters in the IO buffer
-         fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
-   }
-   return result;
-}
-
-STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__uint16 *result;
-   stbi__context s;
-   stbi__start_file(&s,f);
-   result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
-   if (result) {
-         // need to 'unget' all the characters in the IO buffer
-         fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
-   }
-   return result;
-}
-
-STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp)
-{
-   FILE *f = stbi__fopen(filename, "rb");
-   stbi__uint16 *result;
-   if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file");
-   result = stbi_load_from_file_16(f,x,y,comp,req_comp);
-   fclose(f);
-   return result;
+STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) {
+    stbi__uint16 *result;
+    stbi__context s;
+    stbi__start_file(&s, f);
+    result = stbi__load_and_postprocess_16bit(&s, x, y, comp, req_comp);
+    if (result) {
+        // need to 'unget' all the characters in the IO buffer
+        fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR);
+    }
+    return result;
 }
 
+STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) {
+    FILE         *f = stbi__fopen(filename, "rb");
+    stbi__uint16 *result;
+    if (!f)
+        return (stbi_us *)stbi__errpuc("can't fopen", "Unable to open file");
+    result = stbi_load_from_file_16(f, x, y, comp, req_comp);
+    fclose(f);
+    return result;
+}
 
-#endif //!STBI_NO_STDIO
+#endif //! STBI_NO_STDIO
 
-STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
+STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file,
+                                          int desired_channels) {
+    stbi__context s;
+    stbi__start_mem(&s, buffer, len);
+    return stbi__load_and_postprocess_16bit(&s, x, y, channels_in_file, desired_channels);
 }
 
-STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
-   return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
+STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y,
+                                             int *channels_in_file, int desired_channels) {
+    stbi__context s;
+    stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
+    return stbi__load_and_postprocess_16bit(&s, x, y, channels_in_file, desired_channels);
 }
 
-STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
+STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) {
+    stbi__context s;
+    stbi__start_mem(&s, buffer, len);
+    return stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp);
 }
 
-STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
-   return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
+STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp,
+                                          int req_comp) {
+    stbi__context s;
+    stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
+    return stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp);
 }
 
 #ifndef STBI_NO_GIF
-STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
-{
-   unsigned char *result;
-   stbi__context s; 
-   stbi__start_mem(&s,buffer,len); 
-   
-   result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
-   if (stbi__vertically_flip_on_load) {
-         stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); 
-   }
+STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z,
+                                           int *comp, int req_comp) {
+    unsigned char *result;
+    stbi__context  s;
+    stbi__start_mem(&s, buffer, len);
 
-   return result; 
+    result = (unsigned char *)stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
+    if (stbi__vertically_flip_on_load) {
+        stbi__vertical_flip_slices(result, *x, *y, *z, *comp);
+    }
+
+    return result;
 }
 #endif
 
 #ifndef STBI_NO_LINEAR
-static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
-{
-   unsigned char *data;
-   #ifndef STBI_NO_HDR
-   if (stbi__hdr_test(s)) {
-         stbi__result_info ri;
-         float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri);
-         if (hdr_data)
-                stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
-         return hdr_data;
-   }
-   #endif
-   data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp);
-   if (data)
-         return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
-   return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
-}
-
-STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__loadf_main(&s,x,y,comp,req_comp);
+static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) {
+    unsigned char *data;
+#ifndef STBI_NO_HDR
+    if (stbi__hdr_test(s)) {
+        stbi__result_info ri;
+        float            *hdr_data = stbi__hdr_load(s, x, y, comp, req_comp, &ri);
+        if (hdr_data)
+            stbi__float_postprocess(hdr_data, x, y, comp, req_comp);
+        return hdr_data;
+    }
+#endif
+    data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp);
+    if (data)
+        return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
+    return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
 }
 
-STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
-   return stbi__loadf_main(&s,x,y,comp,req_comp);
+STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) {
+    stbi__context s;
+    stbi__start_mem(&s, buffer, len);
+    return stbi__loadf_main(&s, x, y, comp, req_comp);
+}
+
+STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp,
+                                         int req_comp) {
+    stbi__context s;
+    stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
+    return stbi__loadf_main(&s, x, y, comp, req_comp);
 }
 
 #ifndef STBI_NO_STDIO
-STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp)
-{
-   float *result;
-   FILE *f = stbi__fopen(filename, "rb");
-   if (!f) return stbi__errpf("can't fopen", "Unable to open file");
-   result = stbi_loadf_from_file(f,x,y,comp,req_comp);
-   fclose(f);
-   return result;
+STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) {
+    float *result;
+    FILE  *f = stbi__fopen(filename, "rb");
+    if (!f)
+        return stbi__errpf("can't fopen", "Unable to open file");
+    result = stbi_loadf_from_file(f, x, y, comp, req_comp);
+    fclose(f);
+    return result;
 }
 
-STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
-{
-   stbi__context s;
-   stbi__start_file(&s,f);
-   return stbi__loadf_main(&s,x,y,comp,req_comp);
+STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) {
+    stbi__context s;
+    stbi__start_file(&s, f);
+    return stbi__loadf_main(&s, x, y, comp, req_comp);
 }
 #endif // !STBI_NO_STDIO
 
@@ -1307,198 +1258,180 @@ STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_
 // defined, for API simplicity; if STBI_NO_LINEAR is defined, it always
 // reports false!
 
-STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
-{
-   #ifndef STBI_NO_HDR
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__hdr_test(&s);
-   #else
-   STBI_NOTUSED(buffer);
-   STBI_NOTUSED(len);
-   return 0;
-   #endif
+STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) {
+#ifndef STBI_NO_HDR
+    stbi__context s;
+    stbi__start_mem(&s, buffer, len);
+    return stbi__hdr_test(&s);
+#else
+    STBI_NOTUSED(buffer);
+    STBI_NOTUSED(len);
+    return 0;
+#endif
 }
 
 #ifndef STBI_NO_STDIO
-STBIDEF int             stbi_is_hdr              (char const *filename)
-{
-   FILE *f = stbi__fopen(filename, "rb");
-   int result=0;
-   if (f) {
-         result = stbi_is_hdr_from_file(f);
-         fclose(f);
-   }
-   return result;
+STBIDEF int stbi_is_hdr(char const *filename) {
+    FILE *f      = stbi__fopen(filename, "rb");
+    int   result = 0;
+    if (f) {
+        result = stbi_is_hdr_from_file(f);
+        fclose(f);
+    }
+    return result;
 }
 
-STBIDEF int stbi_is_hdr_from_file(FILE *f)
-{
-   #ifndef STBI_NO_HDR
-   long pos = ftell(f);
-   int res;
-   stbi__context s;
-   stbi__start_file(&s,f);
-   res = stbi__hdr_test(&s);
-   fseek(f, pos, SEEK_SET);
-   return res;
-   #else
-   STBI_NOTUSED(f);
-   return 0;
-   #endif
+STBIDEF int stbi_is_hdr_from_file(FILE *f) {
+#ifndef STBI_NO_HDR
+    long          pos = ftell(f);
+    int           res;
+    stbi__context s;
+    stbi__start_file(&s, f);
+    res = stbi__hdr_test(&s);
+    fseek(f, pos, SEEK_SET);
+    return res;
+#else
+    STBI_NOTUSED(f);
+    return 0;
+#endif
 }
 #endif // !STBI_NO_STDIO
 
-STBIDEF int             stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user)
-{
-   #ifndef STBI_NO_HDR
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
-   return stbi__hdr_test(&s);
-   #else
-   STBI_NOTUSED(clbk);
-   STBI_NOTUSED(user);
-   return 0;
-   #endif
+STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) {
+#ifndef STBI_NO_HDR
+    stbi__context s;
+    stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
+    return stbi__hdr_test(&s);
+#else
+    STBI_NOTUSED(clbk);
+    STBI_NOTUSED(user);
+    return 0;
+#endif
 }
 
 #ifndef STBI_NO_LINEAR
-static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f;
+static float stbi__l2h_gamma = 2.2f, stbi__l2h_scale = 1.0f;
 
-STBIDEF void   stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
-STBIDEF void   stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
+STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
+STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
 #endif
 
-static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
-
-STBIDEF void   stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
-STBIDEF void   stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
+static float stbi__h2l_gamma_i = 1.0f / 2.2f, stbi__h2l_scale_i = 1.0f;
 
+STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1 / gamma; }
+STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1 / scale; }
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // Common code used by all image loaders
 //
 
-enum
-{
-   STBI__SCAN_load=0,
-   STBI__SCAN_type,
-   STBI__SCAN_header
-};
-
-static void stbi__refill_buffer(stbi__context *s)
-{
-   int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
-   if (n == 0) {
-         // at end of file, treat same as if from memory, but need to handle case
-         // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
-         s->read_from_callbacks = 0;
-         s->img_buffer = s->buffer_start;
-         s->img_buffer_end = s->buffer_start+1;
-         *s->img_buffer = 0;
-   } else {
-         s->img_buffer = s->buffer_start;
-         s->img_buffer_end = s->buffer_start + n;
-   }
-}
-
-stbi_inline static stbi_uc stbi__get8(stbi__context *s)
-{
-   if (s->img_buffer < s->img_buffer_end)
-         return *s->img_buffer++;
-   if (s->read_from_callbacks) {
-         stbi__refill_buffer(s);
-         return *s->img_buffer++;
-   }
-   return 0;
-}
-
-stbi_inline static int stbi__at_eof(stbi__context *s)
-{
-   if (s->io.read) {
-         if (!(s->io.eof)(s->io_user_data)) return 0;
-         // if feof() is true, check if buffer = end
-         // special case: we've only got the special 0 character at the end
-         if (s->read_from_callbacks == 0) return 1;
-   }
-
-   return s->img_buffer >= s->img_buffer_end;
-}
-
-static void stbi__skip(stbi__context *s, int n)
-{
-   if (n < 0) {
-         s->img_buffer = s->img_buffer_end;
-         return;
-   }
-   if (s->io.read) {
-         int blen = (int) (s->img_buffer_end - s->img_buffer);
-         if (blen < n) {
-                s->img_buffer = s->img_buffer_end;
-                (s->io.skip)(s->io_user_data, n - blen);
-                return;
-         }
-   }
-   s->img_buffer += n;
-}
-
-static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
-{
-   if (s->io.read) {
-         int blen = (int) (s->img_buffer_end - s->img_buffer);
-         if (blen < n) {
-                int res, count;
-
-                memcpy(buffer, s->img_buffer, blen);
-
-                count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen);
-                res = (count == (n-blen));
-                s->img_buffer = s->img_buffer_end;
-                return res;
-         }
-   }
-
-   if (s->img_buffer+n <= s->img_buffer_end) {
-         memcpy(buffer, s->img_buffer, n);
-         s->img_buffer += n;
-         return 1;
-   } else
-         return 0;
-}
-
-static int stbi__get16be(stbi__context *s)
-{
-   int z = stbi__get8(s);
-   return (z << 8) + stbi__get8(s);
-}
-
-static stbi__uint32 stbi__get32be(stbi__context *s)
-{
-   stbi__uint32 z = stbi__get16be(s);
-   return (z << 16) + stbi__get16be(s);
+enum { STBI__SCAN_load = 0, STBI__SCAN_type, STBI__SCAN_header };
+
+static void stbi__refill_buffer(stbi__context *s) {
+    int n = (s->io.read)(s->io_user_data, (char *)s->buffer_start, s->buflen);
+    if (n == 0) {
+        // at end of file, treat same as if from memory, but need to handle case
+        // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
+        s->read_from_callbacks = 0;
+        s->img_buffer          = s->buffer_start;
+        s->img_buffer_end      = s->buffer_start + 1;
+        *s->img_buffer         = 0;
+    } else {
+        s->img_buffer     = s->buffer_start;
+        s->img_buffer_end = s->buffer_start + n;
+    }
+}
+
+stbi_inline static stbi_uc stbi__get8(stbi__context *s) {
+    if (s->img_buffer < s->img_buffer_end)
+        return *s->img_buffer++;
+    if (s->read_from_callbacks) {
+        stbi__refill_buffer(s);
+        return *s->img_buffer++;
+    }
+    return 0;
+}
+
+stbi_inline static int stbi__at_eof(stbi__context *s) {
+    if (s->io.read) {
+        if (!(s->io.eof)(s->io_user_data))
+            return 0;
+        // if feof() is true, check if buffer = end
+        // special case: we've only got the special 0 character at the end
+        if (s->read_from_callbacks == 0)
+            return 1;
+    }
+
+    return s->img_buffer >= s->img_buffer_end;
+}
+
+static void stbi__skip(stbi__context *s, int n) {
+    if (n < 0) {
+        s->img_buffer = s->img_buffer_end;
+        return;
+    }
+    if (s->io.read) {
+        int blen = (int)(s->img_buffer_end - s->img_buffer);
+        if (blen < n) {
+            s->img_buffer = s->img_buffer_end;
+            (s->io.skip)(s->io_user_data, n - blen);
+            return;
+        }
+    }
+    s->img_buffer += n;
+}
+
+static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) {
+    if (s->io.read) {
+        int blen = (int)(s->img_buffer_end - s->img_buffer);
+        if (blen < n) {
+            int res, count;
+
+            memcpy(buffer, s->img_buffer, blen);
+
+            count         = (s->io.read)(s->io_user_data, (char *)buffer + blen, n - blen);
+            res           = (count == (n - blen));
+            s->img_buffer = s->img_buffer_end;
+            return res;
+        }
+    }
+
+    if (s->img_buffer + n <= s->img_buffer_end) {
+        memcpy(buffer, s->img_buffer, n);
+        s->img_buffer += n;
+        return 1;
+    } else
+        return 0;
+}
+
+static int stbi__get16be(stbi__context *s) {
+    int z = stbi__get8(s);
+    return (z << 8) + stbi__get8(s);
+}
+
+static stbi__uint32 stbi__get32be(stbi__context *s) {
+    stbi__uint32 z = stbi__get16be(s);
+    return (z << 16) + stbi__get16be(s);
 }
 
 #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
 // nothing
 #else
-static int stbi__get16le(stbi__context *s)
-{
-   int z = stbi__get8(s);
-   return z + (stbi__get8(s) << 8);
+static int stbi__get16le(stbi__context *s) {
+    int z = stbi__get8(s);
+    return z + (stbi__get8(s) << 8);
 }
 #endif
 
 #ifndef STBI_NO_BMP
-static stbi__uint32 stbi__get32le(stbi__context *s)
-{
-   stbi__uint32 z = stbi__get16le(s);
-   return z + (stbi__get16le(s) << 16);
+static stbi__uint32 stbi__get32le(stbi__context *s) {
+    stbi__uint32 z = stbi__get16le(s);
+    return z + (stbi__get16le(s) << 16);
 }
 #endif
 
-#define STBI__BYTECAST(x)  ((stbi_uc) ((x) & 255))     // truncate int to byte without warnings
-
+#define STBI__BYTECAST(x) ((stbi_uc)((x)&255)) // truncate int to byte without warnings
 
 //////////////////////////////////////////////////////////////////////////////
 //
@@ -1511,152 +1444,197 @@ static stbi__uint32 stbi__get32le(stbi__context *s)
 //     assume data buffer is malloced, so malloc a new one and free that one
 //     only failure mode is malloc failing
 
-static stbi_uc stbi__compute_y(int r, int g, int b)
-{
-   return (stbi_uc) (((r*77) + (g*150) +  (29*b)) >> 8);
-}
-
-static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y)
-{
-   int i,j;
-   unsigned char *good;
-
-   if (req_comp == img_n) return data;
-   STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
-
-   good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0);
-   if (good == NULL) {
-         STBI_FREE(data);
-         return stbi__errpuc("outofmem", "Out of memory");
-   }
-
-   for (j=0; j < (int) y; ++j) {
-         unsigned char *src  = data + j * x * img_n   ;
-         unsigned char *dest = good + j * x * req_comp;
-
-         #define STBI__COMBO(a,b)      ((a)*8+(b))
-         #define STBI__CASE(a,b)       case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
-         // convert source image with img_n components to one with req_comp components;
-         // avoid switch per pixel, so use switch per scanline and massive macros
-         switch (STBI__COMBO(img_n, req_comp)) {
-                STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255;                                                                         } break;
-                STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0];                                                                      } break;
-                STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255;                                         } break;
-                STBI__CASE(2,1) { dest[0]=src[0];                                                                                                      } break;
-                STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0];                                                                      } break;
-                STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1];                                      } break;
-                STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255;            } break;
-                STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]);                                       } break;
-                STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255;        } break;
-                STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]);                                       } break;
-                STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break;
-                STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2];                                        } break;
-                default: STBI_ASSERT(0);
-         }
-         #undef STBI__CASE
-   }
-
-   STBI_FREE(data);
-   return good;
-}
-
-static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
-{
-   return (stbi__uint16) (((r*77) + (g*150) +  (29*b)) >> 8);
-}
-
-static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
-{
-   int i,j;
-   stbi__uint16 *good;
-
-   if (req_comp == img_n) return data;
-   STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
-
-   good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2);
-   if (good == NULL) {
-         STBI_FREE(data);
-         return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
-   }
-
-   for (j=0; j < (int) y; ++j) {
-         stbi__uint16 *src      = data + j * x * img_n   ;
-         stbi__uint16 *dest = good + j * x * req_comp;
-
-         #define STBI__COMBO(a,b)      ((a)*8+(b))
-         #define STBI__CASE(a,b)       case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
-         // convert source image with img_n components to one with req_comp components;
-         // avoid switch per pixel, so use switch per scanline and massive macros
-         switch (STBI__COMBO(img_n, req_comp)) {
-                STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff;                                                                         } break;
-                STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0];                                                                         } break;
-                STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff;                                         } break;
-                STBI__CASE(2,1) { dest[0]=src[0];                                                                                                         } break;
-                STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0];                                                                         } break;
-                STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1];                                         } break;
-                STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff;            } break;
-                STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]);                               } break;
-                STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break;
-                STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]);                               } break;
-                STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break;
-                STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2];                                           } break;
-                default: STBI_ASSERT(0);
-         }
-         #undef STBI__CASE
-   }
-
-   STBI_FREE(data);
-   return good;
+static stbi_uc stbi__compute_y(int r, int g, int b) { return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); }
+
+static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x,
+                                           unsigned int y) {
+    int            i, j;
+    unsigned char *good;
+
+    if (req_comp == img_n)
+        return data;
+    STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
+
+    good = (unsigned char *)stbi__malloc_mad3(req_comp, x, y, 0);
+    if (good == NULL) {
+        STBI_FREE(data);
+        return stbi__errpuc("outofmem", "Out of memory");
+    }
+
+    for (j = 0; j < (int)y; ++j) {
+        unsigned char *src  = data + j * x * img_n;
+        unsigned char *dest = good + j * x * req_comp;
+
+#define STBI__COMBO(a, b) ((a)*8 + (b))
+#define STBI__CASE(a, b)                                                                                               \
+    case STBI__COMBO(a, b):                                                                                            \
+        for (i = x - 1; i >= 0; --i, src += a, dest += b)
+        // convert source image with img_n components to one with req_comp components;
+        // avoid switch per pixel, so use switch per scanline and massive macros
+        switch (STBI__COMBO(img_n, req_comp)) {
+            STBI__CASE(1, 2) { dest[0] = src[0], dest[1] = 255; }
+            break;
+            STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; }
+            break;
+            STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0], dest[3] = 255; }
+            break;
+            STBI__CASE(2, 1) { dest[0] = src[0]; }
+            break;
+            STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; }
+            break;
+            STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0], dest[3] = src[1]; }
+            break;
+            STBI__CASE(3, 4) { dest[0] = src[0], dest[1] = src[1], dest[2] = src[2], dest[3] = 255; }
+            break;
+            STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); }
+            break;
+            STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]), dest[1] = 255; }
+            break;
+            STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); }
+            break;
+            STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]), dest[1] = src[3]; }
+            break;
+            STBI__CASE(4, 3) { dest[0] = src[0], dest[1] = src[1], dest[2] = src[2]; }
+            break;
+        default:
+            STBI_ASSERT(0);
+        }
+#undef STBI__CASE
+    }
+
+    STBI_FREE(data);
+    return good;
+}
+
+static stbi__uint16 stbi__compute_y_16(int r, int g, int b) {
+    return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8);
+}
+
+static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x,
+                                            unsigned int y) {
+    int           i, j;
+    stbi__uint16 *good;
+
+    if (req_comp == img_n)
+        return data;
+    STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
+
+    good = (stbi__uint16 *)stbi__malloc(req_comp * x * y * 2);
+    if (good == NULL) {
+        STBI_FREE(data);
+        return (stbi__uint16 *)stbi__errpuc("outofmem", "Out of memory");
+    }
+
+    for (j = 0; j < (int)y; ++j) {
+        stbi__uint16 *src  = data + j * x * img_n;
+        stbi__uint16 *dest = good + j * x * req_comp;
+
+#define STBI__COMBO(a, b) ((a)*8 + (b))
+#define STBI__CASE(a, b)                                                                                               \
+    case STBI__COMBO(a, b):                                                                                            \
+        for (i = x - 1; i >= 0; --i, src += a, dest += b)
+        // convert source image with img_n components to one with req_comp components;
+        // avoid switch per pixel, so use switch per scanline and massive macros
+        switch (STBI__COMBO(img_n, req_comp)) {
+            STBI__CASE(1, 2) { dest[0] = src[0], dest[1] = 0xffff; }
+            break;
+            STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; }
+            break;
+            STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0], dest[3] = 0xffff; }
+            break;
+            STBI__CASE(2, 1) { dest[0] = src[0]; }
+            break;
+            STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; }
+            break;
+            STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0], dest[3] = src[1]; }
+            break;
+            STBI__CASE(3, 4) { dest[0] = src[0], dest[1] = src[1], dest[2] = src[2], dest[3] = 0xffff; }
+            break;
+            STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); }
+            break;
+            STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]), dest[1] = 0xffff; }
+            break;
+            STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); }
+            break;
+            STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]), dest[1] = src[3]; }
+            break;
+            STBI__CASE(4, 3) { dest[0] = src[0], dest[1] = src[1], dest[2] = src[2]; }
+            break;
+        default:
+            STBI_ASSERT(0);
+        }
+#undef STBI__CASE
+    }
+
+    STBI_FREE(data);
+    return good;
 }
 
 #ifndef STBI_NO_LINEAR
-static float   *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
-{
-   int i,k,n;
-   float *output;
-   if (!data) return NULL;
-   output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0);
-   if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); }
-   // compute number of non-alpha components
-   if (comp & 1) n = comp; else n = comp-1;
-   for (i=0; i < x*y; ++i) {
-         for (k=0; k < n; ++k) {
-                output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
-         }
-         if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f;
-   }
-   STBI_FREE(data);
-   return output;
+static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) {
+    int    i, k, n;
+    float *output;
+    if (!data)
+        return NULL;
+    output = (float *)stbi__malloc_mad4(x, y, comp, sizeof(float), 0);
+    if (output == NULL) {
+        STBI_FREE(data);
+        return stbi__errpf("outofmem", "Out of memory");
+    }
+    // compute number of non-alpha components
+    if (comp & 1)
+        n = comp;
+    else
+        n = comp - 1;
+    for (i = 0; i < x * y; ++i) {
+        for (k = 0; k < n; ++k) {
+            output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
+        }
+        if (k < comp)
+            output[i * comp + k] = data[i * comp + k] / 255.0f;
+    }
+    STBI_FREE(data);
+    return output;
 }
 #endif
 
 #ifndef STBI_NO_HDR
-#define stbi__float2int(x)      ((int) (x))
-static stbi_uc *stbi__hdr_to_ldr(float  *data, int x, int y, int comp)
-{
-   int i,k,n;
-   stbi_uc *output;
-   if (!data) return NULL;
-   output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0);
-   if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); }
-   // compute number of non-alpha components
-   if (comp & 1) n = comp; else n = comp-1;
-   for (i=0; i < x*y; ++i) {
-         for (k=0; k < n; ++k) {
-                float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f;
-                if (z < 0) z = 0;
-                if (z > 255) z = 255;
-                output[i*comp + k] = (stbi_uc) stbi__float2int(z);
-         }
-         if (k < comp) {
-                float z = data[i*comp+k] * 255 + 0.5f;
-                if (z < 0) z = 0;
-                if (z > 255) z = 255;
-                output[i*comp + k] = (stbi_uc) stbi__float2int(z);
-         }
-   }
-   STBI_FREE(data);
-   return output;
+#define stbi__float2int(x) ((int)(x))
+static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) {
+    int      i, k, n;
+    stbi_uc *output;
+    if (!data)
+        return NULL;
+    output = (stbi_uc *)stbi__malloc_mad3(x, y, comp, 0);
+    if (output == NULL) {
+        STBI_FREE(data);
+        return stbi__errpuc("outofmem", "Out of memory");
+    }
+    // compute number of non-alpha components
+    if (comp & 1)
+        n = comp;
+    else
+        n = comp - 1;
+    for (i = 0; i < x * y; ++i) {
+        for (k = 0; k < n; ++k) {
+            float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f;
+            if (z < 0)
+                z = 0;
+            if (z > 255)
+                z = 255;
+            output[i * comp + k] = (stbi_uc)stbi__float2int(z);
+        }
+        if (k < comp) {
+            float z = data[i * comp + k] * 255 + 0.5f;
+            if (z < 0)
+                z = 0;
+            if (z > 255)
+                z = 255;
+            output[i * comp + k] = (stbi_uc)stbi__float2int(z);
+        }
+    }
+    STBI_FREE(data);
+    return output;
 }
 #endif
 
@@ -1684,749 +1662,760 @@ static stbi_uc *stbi__hdr_to_ldr(float         *data, int x, int y, int comp)
 #ifndef STBI_NO_JPEG
 
 // huffman decoding acceleration
-#define FAST_BITS      9  // larger handles more cases; smaller stomps less cache
-
-typedef struct
-{
-   stbi_uc     fast[1 << FAST_BITS];
-   // weirdly, repacking this into AoS is a 10% speed loss, instead of a win
-   stbi__uint16 code[256];
-   stbi_uc     values[256];
-   stbi_uc     size[257];
-   unsigned int maxcode[18];
-   int   delta[17];   // old 'firstsymbol' - old 'firstcode'
+#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache
+
+typedef struct {
+    stbi_uc fast[1 << FAST_BITS];
+    // weirdly, repacking this into AoS is a 10% speed loss, instead of a win
+    stbi__uint16 code[256];
+    stbi_uc      values[256];
+    stbi_uc      size[257];
+    unsigned int maxcode[18];
+    int          delta[17]; // old 'firstsymbol' - old 'firstcode'
 } stbi__huffman;
 
-typedef struct
-{
-   stbi__context *s;
-   stbi__huffman huff_dc[4];
-   stbi__huffman huff_ac[4];
-   stbi__uint16 dequant[4][64];
-   stbi__int16 fast_ac[4][1 << FAST_BITS];
-
-// sizes for components, interleaved MCUs
-   int img_h_max, img_v_max;
-   int img_mcu_x, img_mcu_y;
-   int img_mcu_w, img_mcu_h;
-
-// definition of jpeg image component
-   struct
-   {
-         int id;
-         int h,v;
-         int tq;
-         int hd,ha;
-         int dc_pred;
-
-         int x,y,w2,h2;
-         stbi_uc *data;
-         void *raw_data, *raw_coeff;
-         stbi_uc *linebuf;
-         short   *coeff;       // progressive only
-         int      coeff_w, coeff_h; // number of 8x8 coefficient blocks
-   } img_comp[4];
-
-   stbi__uint32          code_buffer; // jpeg entropy-coded buffer
-   int                   code_bits;   // number of valid bits
-   unsigned char  marker;         // marker seen while filling entropy buffer
-   int                   nomore;          // flag if we saw a marker so must stop
-
-   int                   progressive;
-   int                   spec_start;
-   int                   spec_end;
-   int                   succ_high;
-   int                   succ_low;
-   int                   eob_run;
-   int                   jfif;
-   int                   app14_color_transform; // Adobe APP14 tag
-   int                   rgb;
-
-   int scan_n, order[4];
-   int restart_interval, todo;
-
-// kernels
-   void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]);
-   void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step);
-   stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs);
+typedef struct {
+    stbi__context *s;
+    stbi__huffman  huff_dc[4];
+    stbi__huffman  huff_ac[4];
+    stbi__uint16   dequant[4][64];
+    stbi__int16    fast_ac[4][1 << FAST_BITS];
+
+    // sizes for components, interleaved MCUs
+    int img_h_max, img_v_max;
+    int img_mcu_x, img_mcu_y;
+    int img_mcu_w, img_mcu_h;
+
+    // definition of jpeg image component
+    struct {
+        int id;
+        int h, v;
+        int tq;
+        int hd, ha;
+        int dc_pred;
+
+        int      x, y, w2, h2;
+        stbi_uc *data;
+        void    *raw_data, *raw_coeff;
+        stbi_uc *linebuf;
+        short   *coeff;            // progressive only
+        int      coeff_w, coeff_h; // number of 8x8 coefficient blocks
+    } img_comp[4];
+
+    stbi__uint32  code_buffer; // jpeg entropy-coded buffer
+    int           code_bits;   // number of valid bits
+    unsigned char marker;      // marker seen while filling entropy buffer
+    int           nomore;      // flag if we saw a marker so must stop
+
+    int progressive;
+    int spec_start;
+    int spec_end;
+    int succ_high;
+    int succ_low;
+    int eob_run;
+    int jfif;
+    int app14_color_transform; // Adobe APP14 tag
+    int rgb;
+
+    int scan_n, order[4];
+    int restart_interval, todo;
+
+    // kernels
+    void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]);
+    void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count,
+                                int step);
+    stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs);
 } stbi__jpeg;
 
-static int stbi__build_huffman(stbi__huffman *h, int *count)
-{
-   int i,j,k=0;
-   unsigned int code;
-   // build size list for each symbol (from JPEG spec)
-   for (i=0; i < 16; ++i)
-         for (j=0; j < count[i]; ++j)
-                h->size[k++] = (stbi_uc) (i+1);
-   h->size[k] = 0;
-
-   // compute actual symbols (from jpeg spec)
-   code = 0;
-   k = 0;
-   for(j=1; j <= 16; ++j) {
-         // compute delta to add to code to compute symbol id
-         h->delta[j] = k - code;
-         if (h->size[k] == j) {
-                while (h->size[k] == j)
-                       h->code[k++] = (stbi__uint16) (code++);
-                if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG");
-         }
-         // compute largest code + 1 for this size, preshifted as needed later
-         h->maxcode[j] = code << (16-j);
-         code <<= 1;
-   }
-   h->maxcode[j] = 0xffffffff;
-
-   // build non-spec acceleration table; 255 is flag for not-accelerated
-   memset(h->fast, 255, 1 << FAST_BITS);
-   for (i=0; i < k; ++i) {
-         int s = h->size[i];
-         if (s <= FAST_BITS) {
-                int c = h->code[i] << (FAST_BITS-s);
-                int m = 1 << (FAST_BITS-s);
-                for (j=0; j < m; ++j) {
-                       h->fast[c+j] = (stbi_uc) i;
-                }
-         }
-   }
-   return 1;
+static int stbi__build_huffman(stbi__huffman *h, int *count) {
+    int          i, j, k = 0;
+    unsigned int code;
+    // build size list for each symbol (from JPEG spec)
+    for (i = 0; i < 16; ++i)
+        for (j = 0; j < count[i]; ++j)
+            h->size[k++] = (stbi_uc)(i + 1);
+    h->size[k] = 0;
+
+    // compute actual symbols (from jpeg spec)
+    code = 0;
+    k    = 0;
+    for (j = 1; j <= 16; ++j) {
+        // compute delta to add to code to compute symbol id
+        h->delta[j] = k - code;
+        if (h->size[k] == j) {
+            while (h->size[k] == j)
+                h->code[k++] = (stbi__uint16)(code++);
+            if (code - 1 >= (1u << j))
+                return stbi__err("bad code lengths", "Corrupt JPEG");
+        }
+        // compute largest code + 1 for this size, preshifted as needed later
+        h->maxcode[j] = code << (16 - j);
+        code <<= 1;
+    }
+    h->maxcode[j] = 0xffffffff;
+
+    // build non-spec acceleration table; 255 is flag for not-accelerated
+    memset(h->fast, 255, 1 << FAST_BITS);
+    for (i = 0; i < k; ++i) {
+        int s = h->size[i];
+        if (s <= FAST_BITS) {
+            int c = h->code[i] << (FAST_BITS - s);
+            int m = 1 << (FAST_BITS - s);
+            for (j = 0; j < m; ++j) {
+                h->fast[c + j] = (stbi_uc)i;
+            }
+        }
+    }
+    return 1;
 }
 
 // build a table that decodes both magnitude and value of small ACs in
 // one go.
-static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
-{
-   int i;
-   for (i=0; i < (1 << FAST_BITS); ++i) {
-         stbi_uc fast = h->fast[i];
-         fast_ac[i] = 0;
-         if (fast < 255) {
-                int rs = h->values[fast];
-                int run = (rs >> 4) & 15;
-                int magbits = rs & 15;
-                int len = h->size[fast];
-
-                if (magbits && len + magbits <= FAST_BITS) {
-                       // magnitude code followed by receive_extend code
-                       int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
-                       int m = 1 << (magbits - 1);
-                       if (k < m) k += (~0U << magbits) + 1;
-                       // if the result is small enough, we can fit it in fast_ac table
-                       if (k >= -128 && k <= 127)
-                          fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits));
-                }
-         }
-   }
-}
-
-static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
-{
-   do {
-         unsigned int b = j->nomore ? 0 : stbi__get8(j->s);
-         if (b == 0xff) {
-                int c = stbi__get8(j->s);
-                while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes
-                if (c != 0) {
-                       j->marker = (unsigned char) c;
-                       j->nomore = 1;
-                       return;
-                }
-         }
-         j->code_buffer |= b << (24 - j->code_bits);
-         j->code_bits += 8;
-   } while (j->code_bits <= 24);
+static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) {
+    int i;
+    for (i = 0; i < (1 << FAST_BITS); ++i) {
+        stbi_uc fast = h->fast[i];
+        fast_ac[i]   = 0;
+        if (fast < 255) {
+            int rs      = h->values[fast];
+            int run     = (rs >> 4) & 15;
+            int magbits = rs & 15;
+            int len     = h->size[fast];
+
+            if (magbits && len + magbits <= FAST_BITS) {
+                // magnitude code followed by receive_extend code
+                int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
+                int m = 1 << (magbits - 1);
+                if (k < m)
+                    k += (~0U << magbits) + 1;
+                // if the result is small enough, we can fit it in fast_ac table
+                if (k >= -128 && k <= 127)
+                    fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits));
+            }
+        }
+    }
+}
+
+static void stbi__grow_buffer_unsafe(stbi__jpeg *j) {
+    do {
+        unsigned int b = j->nomore ? 0 : stbi__get8(j->s);
+        if (b == 0xff) {
+            int c = stbi__get8(j->s);
+            while (c == 0xff)
+                c = stbi__get8(j->s); // consume fill bytes
+            if (c != 0) {
+                j->marker = (unsigned char)c;
+                j->nomore = 1;
+                return;
+            }
+        }
+        j->code_buffer |= b << (24 - j->code_bits);
+        j->code_bits += 8;
+    } while (j->code_bits <= 24);
 }
 
 // (1 << n) - 1
-static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
+static const stbi__uint32 stbi__bmask[17] = {0,   1,    3,    7,    15,   31,    63,    127,  255,
+                                             511, 1023, 2047, 4095, 8191, 16383, 32767, 65535};
 
 // decode a jpeg huffman value from the bitstream
-stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
-{
-   unsigned int temp;
-   int c,k;
-
-   if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-
-   // look at the top FAST_BITS and determine what symbol ID it is,
-   // if the code is <= FAST_BITS
-   c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
-   k = h->fast[c];
-   if (k < 255) {
-         int s = h->size[k];
-         if (s > j->code_bits)
-                return -1;
-         j->code_buffer <<= s;
-         j->code_bits -= s;
-         return h->values[k];
-   }
-
-   // naive test is to shift the code_buffer down so k bits are
-   // valid, then test against maxcode. To speed this up, we've
-   // preshifted maxcode left so that it has (16-k) 0s at the
-   // end; in other words, regardless of the number of bits, it
-   // wants to be compared against something shifted to have 16;
-   // that way we don't need to shift inside the loop.
-   temp = j->code_buffer >> 16;
-   for (k=FAST_BITS+1 ; ; ++k)
-         if (temp < h->maxcode[k])
-                break;
-   if (k == 17) {
-         // error! code not found
-         j->code_bits -= 16;
-         return -1;
-   }
-
-   if (k > j->code_bits)
-         return -1;
-
-   // convert the huffman code to the symbol id
-   c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
-   STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
-
-   // convert the id to a symbol
-   j->code_bits -= k;
-   j->code_buffer <<= k;
-   return h->values[c];
+stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) {
+    unsigned int temp;
+    int          c, k;
+
+    if (j->code_bits < 16)
+        stbi__grow_buffer_unsafe(j);
+
+    // look at the top FAST_BITS and determine what symbol ID it is,
+    // if the code is <= FAST_BITS
+    c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1);
+    k = h->fast[c];
+    if (k < 255) {
+        int s = h->size[k];
+        if (s > j->code_bits)
+            return -1;
+        j->code_buffer <<= s;
+        j->code_bits -= s;
+        return h->values[k];
+    }
+
+    // naive test is to shift the code_buffer down so k bits are
+    // valid, then test against maxcode. To speed this up, we've
+    // preshifted maxcode left so that it has (16-k) 0s at the
+    // end; in other words, regardless of the number of bits, it
+    // wants to be compared against something shifted to have 16;
+    // that way we don't need to shift inside the loop.
+    temp = j->code_buffer >> 16;
+    for (k = FAST_BITS + 1;; ++k)
+        if (temp < h->maxcode[k])
+            break;
+    if (k == 17) {
+        // error! code not found
+        j->code_bits -= 16;
+        return -1;
+    }
+
+    if (k > j->code_bits)
+        return -1;
+
+    // convert the huffman code to the symbol id
+    c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
+    STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
+
+    // convert the id to a symbol
+    j->code_bits -= k;
+    j->code_buffer <<= k;
+    return h->values[c];
 }
 
 // bias[n] = (-1<<n) + 1
-static const int stbi__jbias[16] = {0,-1,-3,-7,-15,-31,-63,-127,-255,-511,-1023,-2047,-4095,-8191,-16383,-32767};
+static const int stbi__jbias[16] = {0,    -1,   -3,    -7,    -15,   -31,   -63,    -127,
+                                    -255, -511, -1023, -2047, -4095, -8191, -16383, -32767};
 
 // combined JPEG 'receive' and JPEG 'extend', since baseline
 // always extends everything it receives.
-stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
-{
-   unsigned int k;
-   int sgn;
-   if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
+stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n) {
+    unsigned int k;
+    int          sgn;
+    if (j->code_bits < n)
+        stbi__grow_buffer_unsafe(j);
 
-   sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
-   k = stbi_lrot(j->code_buffer, n);
-   STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
-   j->code_buffer = k & ~stbi__bmask[n];
-   k &= stbi__bmask[n];
-   j->code_bits -= n;
-   return k + (stbi__jbias[n] & ~sgn);
+    sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
+    k   = stbi_lrot(j->code_buffer, n);
+    STBI_ASSERT(n >= 0 && n < (int)(sizeof(stbi__bmask) / sizeof(*stbi__bmask)));
+    j->code_buffer = k & ~stbi__bmask[n];
+    k &= stbi__bmask[n];
+    j->code_bits -= n;
+    return k + (stbi__jbias[n] & ~sgn);
 }
 
 // get some unsigned bits
-stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n)
-{
-   unsigned int k;
-   if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
-   k = stbi_lrot(j->code_buffer, n);
-   j->code_buffer = k & ~stbi__bmask[n];
-   k &= stbi__bmask[n];
-   j->code_bits -= n;
-   return k;
-}
-
-stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
-{
-   unsigned int k;
-   if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
-   k = j->code_buffer;
-   j->code_buffer <<= 1;
-   --j->code_bits;
-   return k & 0x80000000;
+stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) {
+    unsigned int k;
+    if (j->code_bits < n)
+        stbi__grow_buffer_unsafe(j);
+    k              = stbi_lrot(j->code_buffer, n);
+    j->code_buffer = k & ~stbi__bmask[n];
+    k &= stbi__bmask[n];
+    j->code_bits -= n;
+    return k;
+}
+
+stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) {
+    unsigned int k;
+    if (j->code_bits < 1)
+        stbi__grow_buffer_unsafe(j);
+    k = j->code_buffer;
+    j->code_buffer <<= 1;
+    --j->code_bits;
+    return k & 0x80000000;
 }
 
 // given a value that's at position X in the zigzag stream,
 // where does it appear in the 8x8 matrix coded as row-major?
-static const stbi_uc stbi__jpeg_dezigzag[64+15] =
-{
-       0,      1,      8, 16,  9,      2,      3, 10,
-   17, 24, 32, 25, 18, 11,     4,      5,
-   12, 19, 26, 33, 40, 48, 41, 34,
-   27, 20, 13, 6,      7, 14, 21, 28,
-   35, 42, 49, 56, 57, 50, 43, 36,
-   29, 22, 15, 23, 30, 37, 44, 51,
-   58, 59, 52, 45, 38, 31, 39, 46,
-   53, 60, 61, 54, 47, 55, 62, 63,
-   // let corrupt input sample past end
-   63, 63, 63, 63, 63, 63, 63, 63,
-   63, 63, 63, 63, 63, 63, 63
-};
+static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = {0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26,
+                                                     33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56,
+                                                     57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38,
+                                                     31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63,
+                                                     // let corrupt input sample past end
+                                                     63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63};
 
 // decode one 64-entry block--
-static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant)
-{
-   int diff,dc,k;
-   int t;
-
-   if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-   t = stbi__jpeg_huff_decode(j, hdc);
-   if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG");
-
-   // 0 all the ac values now so we can do it 32-bits at a time
-   memset(data,0,64*sizeof(data[0]));
-
-   diff = t ? stbi__extend_receive(j, t) : 0;
-   dc = j->img_comp[b].dc_pred + diff;
-   j->img_comp[b].dc_pred = dc;
-   data[0] = (short) (dc * dequant[0]);
-
-   // decode AC components, see JPEG spec
-   k = 1;
-   do {
-         unsigned int zig;
-         int c,r,s;
-         if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-         c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
-         r = fac[c];
-         if (r) { // fast-AC path
-                k += (r >> 4) & 15; // run
-                s = r & 15; // combined length
-                j->code_buffer <<= s;
-                j->code_bits -= s;
-                // decode into unzigzag'd location
-                zig = stbi__jpeg_dezigzag[k++];
-                data[zig] = (short) ((r >> 8) * dequant[zig]);
-         } else {
-                int rs = stbi__jpeg_huff_decode(j, hac);
-                if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
-                s = rs & 15;
-                r = rs >> 4;
-                if (s == 0) {
-                       if (rs != 0xf0) break; // end block
-                       k += 16;
-                } else {
-                       k += r;
-                       // decode into unzigzag'd location
-                       zig = stbi__jpeg_dezigzag[k++];
-                       data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]);
-                }
-         }
-   } while (k < 64);
-   return 1;
-}
-
-static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b)
-{
-   int diff,dc;
-   int t;
-   if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
-
-   if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-
-   if (j->succ_high == 0) {
-         // first scan for DC coefficient, must be first
-         memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
-         t = stbi__jpeg_huff_decode(j, hdc);
-         diff = t ? stbi__extend_receive(j, t) : 0;
-
-         dc = j->img_comp[b].dc_pred + diff;
-         j->img_comp[b].dc_pred = dc;
-         data[0] = (short) (dc << j->succ_low);
-   } else {
-         // refinement scan for DC coefficient
-         if (stbi__jpeg_get_bit(j))
-                data[0] += (short) (1 << j->succ_low);
-   }
-   return 1;
+static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac,
+                                   stbi__int16 *fac, int b, stbi__uint16 *dequant) {
+    int diff, dc, k;
+    int t;
+
+    if (j->code_bits < 16)
+        stbi__grow_buffer_unsafe(j);
+    t = stbi__jpeg_huff_decode(j, hdc);
+    if (t < 0)
+        return stbi__err("bad huffman code", "Corrupt JPEG");
+
+    // 0 all the ac values now so we can do it 32-bits at a time
+    memset(data, 0, 64 * sizeof(data[0]));
+
+    diff                   = t ? stbi__extend_receive(j, t) : 0;
+    dc                     = j->img_comp[b].dc_pred + diff;
+    j->img_comp[b].dc_pred = dc;
+    data[0]                = (short)(dc * dequant[0]);
+
+    // decode AC components, see JPEG spec
+    k = 1;
+    do {
+        unsigned int zig;
+        int          c, r, s;
+        if (j->code_bits < 16)
+            stbi__grow_buffer_unsafe(j);
+        c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1);
+        r = fac[c];
+        if (r) {                // fast-AC path
+            k += (r >> 4) & 15; // run
+            s = r & 15;         // combined length
+            j->code_buffer <<= s;
+            j->code_bits -= s;
+            // decode into unzigzag'd location
+            zig       = stbi__jpeg_dezigzag[k++];
+            data[zig] = (short)((r >> 8) * dequant[zig]);
+        } else {
+            int rs = stbi__jpeg_huff_decode(j, hac);
+            if (rs < 0)
+                return stbi__err("bad huffman code", "Corrupt JPEG");
+            s = rs & 15;
+            r = rs >> 4;
+            if (s == 0) {
+                if (rs != 0xf0)
+                    break; // end block
+                k += 16;
+            } else {
+                k += r;
+                // decode into unzigzag'd location
+                zig       = stbi__jpeg_dezigzag[k++];
+                data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]);
+            }
+        }
+    } while (k < 64);
+    return 1;
+}
+
+static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) {
+    int diff, dc;
+    int t;
+    if (j->spec_end != 0)
+        return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+
+    if (j->code_bits < 16)
+        stbi__grow_buffer_unsafe(j);
+
+    if (j->succ_high == 0) {
+        // first scan for DC coefficient, must be first
+        memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now
+        t    = stbi__jpeg_huff_decode(j, hdc);
+        diff = t ? stbi__extend_receive(j, t) : 0;
+
+        dc                     = j->img_comp[b].dc_pred + diff;
+        j->img_comp[b].dc_pred = dc;
+        data[0]                = (short)(dc << j->succ_low);
+    } else {
+        // refinement scan for DC coefficient
+        if (stbi__jpeg_get_bit(j))
+            data[0] += (short)(1 << j->succ_low);
+    }
+    return 1;
 }
 
 // @OPTIMIZE: store non-zigzagged during the decode passes,
 // and only de-zigzag when dequantizing
-static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac)
-{
-   int k;
-   if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
-
-   if (j->succ_high == 0) {
-         int shift = j->succ_low;
-
-         if (j->eob_run) {
-                --j->eob_run;
-                return 1;
-         }
-
-         k = j->spec_start;
-         do {
-                unsigned int zig;
-                int c,r,s;
-                if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
-                c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
-                r = fac[c];
-                if (r) { // fast-AC path
-                       k += (r >> 4) & 15; // run
-                       s = r & 15; // combined length
-                       j->code_buffer <<= s;
-                       j->code_bits -= s;
-                       zig = stbi__jpeg_dezigzag[k++];
-                       data[zig] = (short) ((r >> 8) << shift);
-                } else {
-                       int rs = stbi__jpeg_huff_decode(j, hac);
-                       if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
-                       s = rs & 15;
-                       r = rs >> 4;
-                       if (s == 0) {
-                          if (r < 15) {
-                                 j->eob_run = (1 << r);
-                                 if (r)
-                                        j->eob_run += stbi__jpeg_get_bits(j, r);
-                                 --j->eob_run;
-                                 break;
-                          }
-                          k += 16;
-                       } else {
-                          k += r;
-                          zig = stbi__jpeg_dezigzag[k++];
-                          data[zig] = (short) (stbi__extend_receive(j,s) << shift);
-                       }
-                }
-         } while (k <= j->spec_end);
-   } else {
-         // refinement scan for these AC coefficients
-
-         short bit = (short) (1 << j->succ_low);
-
-         if (j->eob_run) {
-                --j->eob_run;
-                for (k = j->spec_start; k <= j->spec_end; ++k) {
-                       short *p = &data[stbi__jpeg_dezigzag[k]];
-                       if (*p != 0)
-                          if (stbi__jpeg_get_bit(j))
-                                 if ((*p & bit)==0) {
-                                        if (*p > 0)
-                                               *p += bit;
-                                        else
-                                               *p -= bit;
-                                 }
-                }
-         } else {
-                k = j->spec_start;
-                do {
-                       int r,s;
-                       int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh
-                       if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
-                       s = rs & 15;
-                       r = rs >> 4;
-                       if (s == 0) {
-                          if (r < 15) {
-                                 j->eob_run = (1 << r) - 1;
-                                 if (r)
-                                        j->eob_run += stbi__jpeg_get_bits(j, r);
-                                 r = 64; // force end of block
-                          } else {
-                                 // r=15 s=0 should write 16 0s, so we just do
-                                 // a run of 15 0s and then write s (which is 0),
-                                 // so we don't have to do anything special here
-                          }
-                       } else {
-                          if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG");
-                          // sign bit
-                          if (stbi__jpeg_get_bit(j))
-                                 s = bit;
-                          else
-                                 s = -bit;
-                       }
-
-                       // advance by r
-                       while (k <= j->spec_end) {
-                          short *p = &data[stbi__jpeg_dezigzag[k++]];
-                          if (*p != 0) {
-                                 if (stbi__jpeg_get_bit(j))
-                                        if ((*p & bit)==0) {
-                                               if (*p > 0)
-                                                  *p += bit;
-                                               else
-                                                  *p -= bit;
-                                        }
-                          } else {
-                                 if (r == 0) {
-                                        *p = (short) s;
-                                        break;
-                                 }
-                                 --r;
-                          }
-                       }
-                } while (k <= j->spec_end);
-         }
-   }
-   return 1;
+static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) {
+    int k;
+    if (j->spec_start == 0)
+        return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+
+    if (j->succ_high == 0) {
+        int shift = j->succ_low;
+
+        if (j->eob_run) {
+            --j->eob_run;
+            return 1;
+        }
+
+        k = j->spec_start;
+        do {
+            unsigned int zig;
+            int          c, r, s;
+            if (j->code_bits < 16)
+                stbi__grow_buffer_unsafe(j);
+            c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1);
+            r = fac[c];
+            if (r) {                // fast-AC path
+                k += (r >> 4) & 15; // run
+                s = r & 15;         // combined length
+                j->code_buffer <<= s;
+                j->code_bits -= s;
+                zig       = stbi__jpeg_dezigzag[k++];
+                data[zig] = (short)((r >> 8) << shift);
+            } else {
+                int rs = stbi__jpeg_huff_decode(j, hac);
+                if (rs < 0)
+                    return stbi__err("bad huffman code", "Corrupt JPEG");
+                s = rs & 15;
+                r = rs >> 4;
+                if (s == 0) {
+                    if (r < 15) {
+                        j->eob_run = (1 << r);
+                        if (r)
+                            j->eob_run += stbi__jpeg_get_bits(j, r);
+                        --j->eob_run;
+                        break;
+                    }
+                    k += 16;
+                } else {
+                    k += r;
+                    zig       = stbi__jpeg_dezigzag[k++];
+                    data[zig] = (short)(stbi__extend_receive(j, s) << shift);
+                }
+            }
+        } while (k <= j->spec_end);
+    } else {
+        // refinement scan for these AC coefficients
+
+        short bit = (short)(1 << j->succ_low);
+
+        if (j->eob_run) {
+            --j->eob_run;
+            for (k = j->spec_start; k <= j->spec_end; ++k) {
+                short *p = &data[stbi__jpeg_dezigzag[k]];
+                if (*p != 0)
+                    if (stbi__jpeg_get_bit(j))
+                        if ((*p & bit) == 0) {
+                            if (*p > 0)
+                                *p += bit;
+                            else
+                                *p -= bit;
+                        }
+            }
+        } else {
+            k = j->spec_start;
+            do {
+                int r, s;
+                int rs = stbi__jpeg_huff_decode(
+                    j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh
+                if (rs < 0)
+                    return stbi__err("bad huffman code", "Corrupt JPEG");
+                s = rs & 15;
+                r = rs >> 4;
+                if (s == 0) {
+                    if (r < 15) {
+                        j->eob_run = (1 << r) - 1;
+                        if (r)
+                            j->eob_run += stbi__jpeg_get_bits(j, r);
+                        r = 64; // force end of block
+                    } else {
+                        // r=15 s=0 should write 16 0s, so we just do
+                        // a run of 15 0s and then write s (which is 0),
+                        // so we don't have to do anything special here
+                    }
+                } else {
+                    if (s != 1)
+                        return stbi__err("bad huffman code", "Corrupt JPEG");
+                    // sign bit
+                    if (stbi__jpeg_get_bit(j))
+                        s = bit;
+                    else
+                        s = -bit;
+                }
+
+                // advance by r
+                while (k <= j->spec_end) {
+                    short *p = &data[stbi__jpeg_dezigzag[k++]];
+                    if (*p != 0) {
+                        if (stbi__jpeg_get_bit(j))
+                            if ((*p & bit) == 0) {
+                                if (*p > 0)
+                                    *p += bit;
+                                else
+                                    *p -= bit;
+                            }
+                    } else {
+                        if (r == 0) {
+                            *p = (short)s;
+                            break;
+                        }
+                        --r;
+                    }
+                }
+            } while (k <= j->spec_end);
+        }
+    }
+    return 1;
 }
 
 // take a -128..127 value and stbi__clamp it and convert to 0..255
-stbi_inline static stbi_uc stbi__clamp(int x)
-{
-   // trick to use a single test to catch both cases
-   if ((unsigned int) x > 255) {
-         if (x < 0) return 0;
-         if (x > 255) return 255;
-   }
-   return (stbi_uc) x;
+stbi_inline static stbi_uc stbi__clamp(int x) {
+    // trick to use a single test to catch both cases
+    if ((unsigned int)x > 255) {
+        if (x < 0)
+            return 0;
+        if (x > 255)
+            return 255;
+    }
+    return (stbi_uc)x;
 }
 
-#define stbi__f2f(x)  ((int) (((x) * 4096 + 0.5)))
-#define stbi__fsh(x)  ((x) * 4096)
+#define stbi__f2f(x) ((int)(((x)*4096 + 0.5)))
+#define stbi__fsh(x) ((x)*4096)
 
 // derived from jidctint -- DCT_ISLOW
-#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \
-   int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \
-   p2 = s2;                                                                       \
-   p3 = s6;                                                                       \
-   p1 = (p2+p3) * stbi__f2f(0.5411961f);          \
-   t2 = p1 + p3*stbi__f2f(-1.847759065f);         \
-   t3 = p1 + p2*stbi__f2f( 0.765366865f);         \
-   p2 = s0;                                                                       \
-   p3 = s4;                                                                       \
-   t0 = stbi__fsh(p2+p3);                                         \
-   t1 = stbi__fsh(p2-p3);                                         \
-   x0 = t0+t3;                                                            \
-   x3 = t0-t3;                                                            \
-   x1 = t1+t2;                                                            \
-   x2 = t1-t2;                                                            \
-   t0 = s7;                                                                       \
-   t1 = s5;                                                                       \
-   t2 = s3;                                                                       \
-   t3 = s1;                                                                       \
-   p3 = t0+t2;                                                            \
-   p4 = t1+t3;                                                            \
-   p1 = t0+t3;                                                            \
-   p2 = t1+t2;                                                            \
-   p5 = (p3+p4)*stbi__f2f( 1.175875602f);         \
-   t0 = t0*stbi__f2f( 0.298631336f);              \
-   t1 = t1*stbi__f2f( 2.053119869f);              \
-   t2 = t2*stbi__f2f( 3.072711026f);              \
-   t3 = t3*stbi__f2f( 1.501321110f);              \
-   p1 = p5 + p1*stbi__f2f(-0.899976223f);         \
-   p2 = p5 + p2*stbi__f2f(-2.562915447f);         \
-   p3 = p3*stbi__f2f(-1.961570560f);              \
-   p4 = p4*stbi__f2f(-0.390180644f);              \
-   t3 += p1+p4;                                                                   \
-   t2 += p2+p3;                                                                   \
-   t1 += p2+p4;                                                                   \
-   t0 += p1+p3;
-
-static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64])
-{
-   int i,val[64],*v=val;
-   stbi_uc *o;
-   short *d = data;
-
-   // columns
-   for (i=0; i < 8; ++i,++d, ++v) {
-         // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing
-         if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0
-                  && d[40]==0 && d[48]==0 && d[56]==0) {
-                //        no shortcut                             0     seconds
-                //        (1|2|3|4|5|6|7)==0              0     seconds
-                //        all separate                           -0.047 seconds
-                //        1 && 2|3 && 4|5 && 6|7:        -0.047 seconds
-                int dcterm = d[0]*4;
-                v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm;
-         } else {
-                STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56])
-                // constants scaled things up by 1<<12; let's bring them back
-                // down, but keep 2 extra bits of precision
-                x0 += 512; x1 += 512; x2 += 512; x3 += 512;
-                v[ 0] = (x0+t3) >> 10;
-                v[56] = (x0-t3) >> 10;
-                v[ 8] = (x1+t2) >> 10;
-                v[48] = (x1-t2) >> 10;
-                v[16] = (x2+t1) >> 10;
-                v[40] = (x2-t1) >> 10;
-                v[24] = (x3+t0) >> 10;
-                v[32] = (x3-t0) >> 10;
-         }
-   }
-
-   for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) {
-         // no fast case since the first 1D IDCT spread components out
-         STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])
-         // constants scaled things up by 1<<12, plus we had 1<<2 from first
-         // loop, plus horizontal and vertical each scale by sqrt(8) so together
-         // we've got an extra 1<<3, so 1<<17 total we need to remove.
-         // so we want to round that, which means adding 0.5 * 1<<17,
-         // aka 65536. Also, we'll end up with -128 to 127 that we want
-         // to encode as 0..255 by adding 128, so we'll add that before the shift
-         x0 += 65536 + (128<<17);
-         x1 += 65536 + (128<<17);
-         x2 += 65536 + (128<<17);
-         x3 += 65536 + (128<<17);
-         // tried computing the shifts into temps, or'ing the temps to see
-         // if any were out of range, but that was slower
-         o[0] = stbi__clamp((x0+t3) >> 17);
-         o[7] = stbi__clamp((x0-t3) >> 17);
-         o[1] = stbi__clamp((x1+t2) >> 17);
-         o[6] = stbi__clamp((x1-t2) >> 17);
-         o[2] = stbi__clamp((x2+t1) >> 17);
-         o[5] = stbi__clamp((x2-t1) >> 17);
-         o[3] = stbi__clamp((x3+t0) >> 17);
-         o[4] = stbi__clamp((x3-t0) >> 17);
-   }
+#define STBI__IDCT_1D(s0, s1, s2, s3, s4, s5, s6, s7)                                                                  \
+    int t0, t1, t2, t3, p1, p2, p3, p4, p5, x0, x1, x2, x3;                                                            \
+    p2 = s2;                                                                                                           \
+    p3 = s6;                                                                                                           \
+    p1 = (p2 + p3) * stbi__f2f(0.5411961f);                                                                            \
+    t2 = p1 + p3 * stbi__f2f(-1.847759065f);                                                                           \
+    t3 = p1 + p2 * stbi__f2f(0.765366865f);                                                                            \
+    p2 = s0;                                                                                                           \
+    p3 = s4;                                                                                                           \
+    t0 = stbi__fsh(p2 + p3);                                                                                           \
+    t1 = stbi__fsh(p2 - p3);                                                                                           \
+    x0 = t0 + t3;                                                                                                      \
+    x3 = t0 - t3;                                                                                                      \
+    x1 = t1 + t2;                                                                                                      \
+    x2 = t1 - t2;                                                                                                      \
+    t0 = s7;                                                                                                           \
+    t1 = s5;                                                                                                           \
+    t2 = s3;                                                                                                           \
+    t3 = s1;                                                                                                           \
+    p3 = t0 + t2;                                                                                                      \
+    p4 = t1 + t3;                                                                                                      \
+    p1 = t0 + t3;                                                                                                      \
+    p2 = t1 + t2;                                                                                                      \
+    p5 = (p3 + p4) * stbi__f2f(1.175875602f);                                                                          \
+    t0 = t0 * stbi__f2f(0.298631336f);                                                                                 \
+    t1 = t1 * stbi__f2f(2.053119869f);                                                                                 \
+    t2 = t2 * stbi__f2f(3.072711026f);                                                                                 \
+    t3 = t3 * stbi__f2f(1.501321110f);                                                                                 \
+    p1 = p5 + p1 * stbi__f2f(-0.899976223f);                                                                           \
+    p2 = p5 + p2 * stbi__f2f(-2.562915447f);                                                                           \
+    p3 = p3 * stbi__f2f(-1.961570560f);                                                                                \
+    p4 = p4 * stbi__f2f(-0.390180644f);                                                                                \
+    t3 += p1 + p4;                                                                                                     \
+    t2 += p2 + p3;                                                                                                     \
+    t1 += p2 + p4;                                                                                                     \
+    t0 += p1 + p3;
+
+static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) {
+    int      i, val[64], *v = val;
+    stbi_uc *o;
+    short   *d = data;
+
+    // columns
+    for (i = 0; i < 8; ++i, ++d, ++v) {
+        // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing
+        if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 && d[40] == 0 && d[48] == 0 && d[56] == 0) {
+            //    no shortcut                             0     seconds
+            //    (1|2|3|4|5|6|7)==0              0     seconds
+            //    all separate                           -0.047 seconds
+            //    1 && 2|3 && 4|5 && 6|7:        -0.047 seconds
+            int dcterm = d[0] * 4;
+            v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm;
+        } else {
+            STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56])
+            // constants scaled things up by 1<<12; let's bring them back
+            // down, but keep 2 extra bits of precision
+            x0 += 512;
+            x1 += 512;
+            x2 += 512;
+            x3 += 512;
+            v[0]  = (x0 + t3) >> 10;
+            v[56] = (x0 - t3) >> 10;
+            v[8]  = (x1 + t2) >> 10;
+            v[48] = (x1 - t2) >> 10;
+            v[16] = (x2 + t1) >> 10;
+            v[40] = (x2 - t1) >> 10;
+            v[24] = (x3 + t0) >> 10;
+            v[32] = (x3 - t0) >> 10;
+        }
+    }
+
+    for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) {
+        // no fast case since the first 1D IDCT spread components out
+        STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7])
+        // constants scaled things up by 1<<12, plus we had 1<<2 from first
+        // loop, plus horizontal and vertical each scale by sqrt(8) so together
+        // we've got an extra 1<<3, so 1<<17 total we need to remove.
+        // so we want to round that, which means adding 0.5 * 1<<17,
+        // aka 65536. Also, we'll end up with -128 to 127 that we want
+        // to encode as 0..255 by adding 128, so we'll add that before the shift
+        x0 += 65536 + (128 << 17);
+        x1 += 65536 + (128 << 17);
+        x2 += 65536 + (128 << 17);
+        x3 += 65536 + (128 << 17);
+        // tried computing the shifts into temps, or'ing the temps to see
+        // if any were out of range, but that was slower
+        o[0] = stbi__clamp((x0 + t3) >> 17);
+        o[7] = stbi__clamp((x0 - t3) >> 17);
+        o[1] = stbi__clamp((x1 + t2) >> 17);
+        o[6] = stbi__clamp((x1 - t2) >> 17);
+        o[2] = stbi__clamp((x2 + t1) >> 17);
+        o[5] = stbi__clamp((x2 - t1) >> 17);
+        o[3] = stbi__clamp((x3 + t0) >> 17);
+        o[4] = stbi__clamp((x3 - t0) >> 17);
+    }
 }
 
 #ifdef STBI_SSE2
 // sse2 integer IDCT. not the fastest possible implementation but it
 // produces bit-identical results to the generic C version so it's
 // fully "transparent".
-static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
-{
-   // This is constructed to match our regular (generic) integer IDCT exactly.
-   __m128i row0, row1, row2, row3, row4, row5, row6, row7;
-   __m128i tmp;
-
-   // dot product constant: even elems=x, odd elems=y
-   #define dct_const(x,y)  _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y))
-
-   // out(0) = c0[even]*x + c0[odd]*y  (c0, x, y 16-bit, out 32-bit)
-   // out(1) = c1[even]*x + c1[odd]*y
-   #define dct_rot(out0,out1, x,y,c0,c1) \
-         __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \
-         __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \
-         __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \
-         __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \
-         __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \
-         __m128i out1##_h = _mm_madd_epi16(c0##hi, c1)
-
-   // out = in << 12  (in 16-bit, out 32-bit)
-   #define dct_widen(out, in) \
-         __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \
-         __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4)
-
-   // wide add
-   #define dct_wadd(out, a, b) \
-         __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \
-         __m128i out##_h = _mm_add_epi32(a##_h, b##_h)
-
-   // wide sub
-   #define dct_wsub(out, a, b) \
-         __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \
-         __m128i out##_h = _mm_sub_epi32(a##_h, b##_h)
-
-   // butterfly a/b, add bias, then shift by "s" and pack
-   #define dct_bfly32o(out0, out1, a,b,bias,s) \
-         { \
-                __m128i abiased_l = _mm_add_epi32(a##_l, bias); \
-                __m128i abiased_h = _mm_add_epi32(a##_h, bias); \
-                dct_wadd(sum, abiased, b); \
-                dct_wsub(dif, abiased, b); \
-                out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \
-                out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \
-         }
-
-   // 8-bit interleave step (for transposes)
-   #define dct_interleave8(a, b) \
-         tmp = a; \
-         a = _mm_unpacklo_epi8(a, b); \
-         b = _mm_unpackhi_epi8(tmp, b)
-
-   // 16-bit interleave step (for transposes)
-   #define dct_interleave16(a, b) \
-         tmp = a; \
-         a = _mm_unpacklo_epi16(a, b); \
-         b = _mm_unpackhi_epi16(tmp, b)
-
-   #define dct_pass(bias,shift) \
-         { \
-                /* even part */ \
-                dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \
-                __m128i sum04 = _mm_add_epi16(row0, row4); \
-                __m128i dif04 = _mm_sub_epi16(row0, row4); \
-                dct_widen(t0e, sum04); \
-                dct_widen(t1e, dif04); \
-                dct_wadd(x0, t0e, t3e); \
-                dct_wsub(x3, t0e, t3e); \
-                dct_wadd(x1, t1e, t2e); \
-                dct_wsub(x2, t1e, t2e); \
-                /* odd part */ \
-                dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \
-                dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \
-                __m128i sum17 = _mm_add_epi16(row1, row7); \
-                __m128i sum35 = _mm_add_epi16(row3, row5); \
-                dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \
-                dct_wadd(x4, y0o, y4o); \
-                dct_wadd(x5, y1o, y5o); \
-                dct_wadd(x6, y2o, y5o); \
-                dct_wadd(x7, y3o, y4o); \
-                dct_bfly32o(row0,row7, x0,x7,bias,shift); \
-                dct_bfly32o(row1,row6, x1,x6,bias,shift); \
-                dct_bfly32o(row2,row5, x2,x5,bias,shift); \
-                dct_bfly32o(row3,row4, x3,x4,bias,shift); \
-         }
-
-   __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f));
-   __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f));
-   __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f));
-   __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f));
-   __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f));
-   __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f));
-   __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f));
-   __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f));
-
-   // rounding biases in column/row passes, see stbi__idct_block for explanation.
-   __m128i bias_0 = _mm_set1_epi32(512);
-   __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17));
-
-   // load
-   row0 = _mm_load_si128((const __m128i *) (data + 0*8));
-   row1 = _mm_load_si128((const __m128i *) (data + 1*8));
-   row2 = _mm_load_si128((const __m128i *) (data + 2*8));
-   row3 = _mm_load_si128((const __m128i *) (data + 3*8));
-   row4 = _mm_load_si128((const __m128i *) (data + 4*8));
-   row5 = _mm_load_si128((const __m128i *) (data + 5*8));
-   row6 = _mm_load_si128((const __m128i *) (data + 6*8));
-   row7 = _mm_load_si128((const __m128i *) (data + 7*8));
-
-   // column pass
-   dct_pass(bias_0, 10);
-
-   {
-         // 16bit 8x8 transpose pass 1
-         dct_interleave16(row0, row4);
-         dct_interleave16(row1, row5);
-         dct_interleave16(row2, row6);
-         dct_interleave16(row3, row7);
-
-         // transpose pass 2
-         dct_interleave16(row0, row2);
-         dct_interleave16(row1, row3);
-         dct_interleave16(row4, row6);
-         dct_interleave16(row5, row7);
-
-         // transpose pass 3
-         dct_interleave16(row0, row1);
-         dct_interleave16(row2, row3);
-         dct_interleave16(row4, row5);
-         dct_interleave16(row6, row7);
-   }
-
-   // row pass
-   dct_pass(bias_1, 17);
-
-   {
-         // pack
-         __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7
-         __m128i p1 = _mm_packus_epi16(row2, row3);
-         __m128i p2 = _mm_packus_epi16(row4, row5);
-         __m128i p3 = _mm_packus_epi16(row6, row7);
-
-         // 8bit 8x8 transpose pass 1
-         dct_interleave8(p0, p2); // a0e0a1e1...
-         dct_interleave8(p1, p3); // c0g0c1g1...
-
-         // transpose pass 2
-         dct_interleave8(p0, p1); // a0c0e0g0...
-         dct_interleave8(p2, p3); // b0d0f0h0...
-
-         // transpose pass 3
-         dct_interleave8(p0, p2); // a0b0c0d0...
-         dct_interleave8(p1, p3); // a4b4c4d4...
-
-         // store
-         _mm_storel_epi64((__m128i *) out, p0); out += out_stride;
-         _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride;
-         _mm_storel_epi64((__m128i *) out, p2); out += out_stride;
-         _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride;
-         _mm_storel_epi64((__m128i *) out, p1); out += out_stride;
-         _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride;
-         _mm_storel_epi64((__m128i *) out, p3); out += out_stride;
-         _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e));
-   }
+static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) {
+    // This is constructed to match our regular (generic) integer IDCT exactly.
+    __m128i row0, row1, row2, row3, row4, row5, row6, row7;
+    __m128i tmp;
+
+// dot product constant: even elems=x, odd elems=y
+#define dct_const(x, y) _mm_setr_epi16((x), (y), (x), (y), (x), (y), (x), (y))
+
+// out(0) = c0[even]*x + c0[odd]*y     (c0, x, y 16-bit, out 32-bit)
+// out(1) = c1[even]*x + c1[odd]*y
+#define dct_rot(out0, out1, x, y, c0, c1)                                                                              \
+    __m128i c0##lo   = _mm_unpacklo_epi16((x), (y));                                                                   \
+    __m128i c0##hi   = _mm_unpackhi_epi16((x), (y));                                                                   \
+    __m128i out0##_l = _mm_madd_epi16(c0##lo, c0);                                                                     \
+    __m128i out0##_h = _mm_madd_epi16(c0##hi, c0);                                                                     \
+    __m128i out1##_l = _mm_madd_epi16(c0##lo, c1);                                                                     \
+    __m128i out1##_h = _mm_madd_epi16(c0##hi, c1)
+
+// out = in << 12  (in 16-bit, out 32-bit)
+#define dct_widen(out, in)                                                                                             \
+    __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4);                                \
+    __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4)
+
+// wide add
+#define dct_wadd(out, a, b)                                                                                            \
+    __m128i out##_l = _mm_add_epi32(a##_l, b##_l);                                                                     \
+    __m128i out##_h = _mm_add_epi32(a##_h, b##_h)
+
+// wide sub
+#define dct_wsub(out, a, b)                                                                                            \
+    __m128i out##_l = _mm_sub_epi32(a##_l, b##_l);                                                                     \
+    __m128i out##_h = _mm_sub_epi32(a##_h, b##_h)
+
+// butterfly a/b, add bias, then shift by "s" and pack
+#define dct_bfly32o(out0, out1, a, b, bias, s)                                                                         \
+    {                                                                                                                  \
+        __m128i abiased_l = _mm_add_epi32(a##_l, bias);                                                                \
+        __m128i abiased_h = _mm_add_epi32(a##_h, bias);                                                                \
+        dct_wadd(sum, abiased, b);                                                                                     \
+        dct_wsub(dif, abiased, b);                                                                                     \
+        out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s));                                    \
+        out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s));                                    \
+    }
+
+// 8-bit interleave step (for transposes)
+#define dct_interleave8(a, b)                                                                                          \
+    tmp = a;                                                                                                           \
+    a   = _mm_unpacklo_epi8(a, b);                                                                                     \
+    b   = _mm_unpackhi_epi8(tmp, b)
+
+// 16-bit interleave step (for transposes)
+#define dct_interleave16(a, b)                                                                                         \
+    tmp = a;                                                                                                           \
+    a   = _mm_unpacklo_epi16(a, b);                                                                                    \
+    b   = _mm_unpackhi_epi16(tmp, b)
+
+#define dct_pass(bias, shift)                                                                                          \
+    {                                                                                                                  \
+        /* even part */                                                                                                \
+        dct_rot(t2e, t3e, row2, row6, rot0_0, rot0_1);                                                                 \
+        __m128i sum04 = _mm_add_epi16(row0, row4);                                                                     \
+        __m128i dif04 = _mm_sub_epi16(row0, row4);                                                                     \
+        dct_widen(t0e, sum04);                                                                                         \
+        dct_widen(t1e, dif04);                                                                                         \
+        dct_wadd(x0, t0e, t3e);                                                                                        \
+        dct_wsub(x3, t0e, t3e);                                                                                        \
+        dct_wadd(x1, t1e, t2e);                                                                                        \
+        dct_wsub(x2, t1e, t2e);                                                                                        \
+        /* odd part */                                                                                                 \
+        dct_rot(y0o, y2o, row7, row3, rot2_0, rot2_1);                                                                 \
+        dct_rot(y1o, y3o, row5, row1, rot3_0, rot3_1);                                                                 \
+        __m128i sum17 = _mm_add_epi16(row1, row7);                                                                     \
+        __m128i sum35 = _mm_add_epi16(row3, row5);                                                                     \
+        dct_rot(y4o, y5o, sum17, sum35, rot1_0, rot1_1);                                                               \
+        dct_wadd(x4, y0o, y4o);                                                                                        \
+        dct_wadd(x5, y1o, y5o);                                                                                        \
+        dct_wadd(x6, y2o, y5o);                                                                                        \
+        dct_wadd(x7, y3o, y4o);                                                                                        \
+        dct_bfly32o(row0, row7, x0, x7, bias, shift);                                                                  \
+        dct_bfly32o(row1, row6, x1, x6, bias, shift);                                                                  \
+        dct_bfly32o(row2, row5, x2, x5, bias, shift);                                                                  \
+        dct_bfly32o(row3, row4, x3, x4, bias, shift);                                                                  \
+    }
+
+    __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f));
+    __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f));
+    __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f));
+    __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f));
+    __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f));
+    __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f));
+    __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f));
+    __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f));
+
+    // rounding biases in column/row passes, see stbi__idct_block for explanation.
+    __m128i bias_0 = _mm_set1_epi32(512);
+    __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17));
+
+    // load
+    row0 = _mm_load_si128((const __m128i *)(data + 0 * 8));
+    row1 = _mm_load_si128((const __m128i *)(data + 1 * 8));
+    row2 = _mm_load_si128((const __m128i *)(data + 2 * 8));
+    row3 = _mm_load_si128((const __m128i *)(data + 3 * 8));
+    row4 = _mm_load_si128((const __m128i *)(data + 4 * 8));
+    row5 = _mm_load_si128((const __m128i *)(data + 5 * 8));
+    row6 = _mm_load_si128((const __m128i *)(data + 6 * 8));
+    row7 = _mm_load_si128((const __m128i *)(data + 7 * 8));
+
+    // column pass
+    dct_pass(bias_0, 10);
+
+    {
+        // 16bit 8x8 transpose pass 1
+        dct_interleave16(row0, row4);
+        dct_interleave16(row1, row5);
+        dct_interleave16(row2, row6);
+        dct_interleave16(row3, row7);
+
+        // transpose pass 2
+        dct_interleave16(row0, row2);
+        dct_interleave16(row1, row3);
+        dct_interleave16(row4, row6);
+        dct_interleave16(row5, row7);
+
+        // transpose pass 3
+        dct_interleave16(row0, row1);
+        dct_interleave16(row2, row3);
+        dct_interleave16(row4, row5);
+        dct_interleave16(row6, row7);
+    }
+
+    // row pass
+    dct_pass(bias_1, 17);
+
+    {
+        // pack
+        __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7
+        __m128i p1 = _mm_packus_epi16(row2, row3);
+        __m128i p2 = _mm_packus_epi16(row4, row5);
+        __m128i p3 = _mm_packus_epi16(row6, row7);
+
+        // 8bit 8x8 transpose pass 1
+        dct_interleave8(p0, p2); // a0e0a1e1...
+        dct_interleave8(p1, p3); // c0g0c1g1...
+
+        // transpose pass 2
+        dct_interleave8(p0, p1); // a0c0e0g0...
+        dct_interleave8(p2, p3); // b0d0f0h0...
+
+        // transpose pass 3
+        dct_interleave8(p0, p2); // a0b0c0d0...
+        dct_interleave8(p1, p3); // a4b4c4d4...
+
+        // store
+        _mm_storel_epi64((__m128i *)out, p0);
+        out += out_stride;
+        _mm_storel_epi64((__m128i *)out, _mm_shuffle_epi32(p0, 0x4e));
+        out += out_stride;
+        _mm_storel_epi64((__m128i *)out, p2);
+        out += out_stride;
+        _mm_storel_epi64((__m128i *)out, _mm_shuffle_epi32(p2, 0x4e));
+        out += out_stride;
+        _mm_storel_epi64((__m128i *)out, p1);
+        out += out_stride;
+        _mm_storel_epi64((__m128i *)out, _mm_shuffle_epi32(p1, 0x4e));
+        out += out_stride;
+        _mm_storel_epi64((__m128i *)out, p3);
+        out += out_stride;
+        _mm_storel_epi64((__m128i *)out, _mm_shuffle_epi32(p3, 0x4e));
+    }
 
 #undef dct_const
 #undef dct_rot
@@ -2445,198 +2434,235 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
 
 // NEON integer IDCT. should produce bit-identical
 // results to the generic C version.
-static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
-{
-   int16x8_t row0, row1, row2, row3, row4, row5, row6, row7;
-
-   int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f));
-   int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f));
-   int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f));
-   int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f));
-   int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f));
-   int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f));
-   int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f));
-   int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f));
-   int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f));
-   int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f));
-   int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f));
-   int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f));
-
-#define dct_long_mul(out, inq, coeff) \
-   int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \
-   int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff)
-
-#define dct_long_mac(out, acc, inq, coeff) \
-   int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \
-   int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff)
-
-#define dct_widen(out, inq) \
-   int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \
-   int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12)
+static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) {
+    int16x8_t row0, row1, row2, row3, row4, row5, row6, row7;
+
+    int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f));
+    int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f));
+    int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f));
+    int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f));
+    int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f));
+    int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f));
+    int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f));
+    int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f));
+    int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f));
+    int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f));
+    int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f));
+    int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f));
+
+#define dct_long_mul(out, inq, coeff)                                                                                  \
+    int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff);                                                           \
+    int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff)
+
+#define dct_long_mac(out, acc, inq, coeff)                                                                             \
+    int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff);                                                  \
+    int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff)
+
+#define dct_widen(out, inq)                                                                                            \
+    int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12);                                                            \
+    int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12)
 
 // wide add
-#define dct_wadd(out, a, b) \
-   int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \
-   int32x4_t out##_h = vaddq_s32(a##_h, b##_h)
+#define dct_wadd(out, a, b)                                                                                            \
+    int32x4_t out##_l = vaddq_s32(a##_l, b##_l);                                                                       \
+    int32x4_t out##_h = vaddq_s32(a##_h, b##_h)
 
 // wide sub
-#define dct_wsub(out, a, b) \
-   int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \
-   int32x4_t out##_h = vsubq_s32(a##_h, b##_h)
+#define dct_wsub(out, a, b)                                                                                            \
+    int32x4_t out##_l = vsubq_s32(a##_l, b##_l);                                                                       \
+    int32x4_t out##_h = vsubq_s32(a##_h, b##_h)
 
 // butterfly a/b, then shift using "shiftop" by "s" and pack
-#define dct_bfly32o(out0,out1, a,b,shiftop,s) \
-   { \
-         dct_wadd(sum, a, b); \
-         dct_wsub(dif, a, b); \
-         out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \
-         out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \
-   }
-
-#define dct_pass(shiftop, shift) \
-   { \
-         /* even part */ \
-         int16x8_t sum26 = vaddq_s16(row2, row6); \
-         dct_long_mul(p1e, sum26, rot0_0); \
-         dct_long_mac(t2e, p1e, row6, rot0_1); \
-         dct_long_mac(t3e, p1e, row2, rot0_2); \
-         int16x8_t sum04 = vaddq_s16(row0, row4); \
-         int16x8_t dif04 = vsubq_s16(row0, row4); \
-         dct_widen(t0e, sum04); \
-         dct_widen(t1e, dif04); \
-         dct_wadd(x0, t0e, t3e); \
-         dct_wsub(x3, t0e, t3e); \
-         dct_wadd(x1, t1e, t2e); \
-         dct_wsub(x2, t1e, t2e); \
-         /* odd part */ \
-         int16x8_t sum15 = vaddq_s16(row1, row5); \
-         int16x8_t sum17 = vaddq_s16(row1, row7); \
-         int16x8_t sum35 = vaddq_s16(row3, row5); \
-         int16x8_t sum37 = vaddq_s16(row3, row7); \
-         int16x8_t sumodd = vaddq_s16(sum17, sum35); \
-         dct_long_mul(p5o, sumodd, rot1_0); \
-         dct_long_mac(p1o, p5o, sum17, rot1_1); \
-         dct_long_mac(p2o, p5o, sum35, rot1_2); \
-         dct_long_mul(p3o, sum37, rot2_0); \
-         dct_long_mul(p4o, sum15, rot2_1); \
-         dct_wadd(sump13o, p1o, p3o); \
-         dct_wadd(sump24o, p2o, p4o); \
-         dct_wadd(sump23o, p2o, p3o); \
-         dct_wadd(sump14o, p1o, p4o); \
-         dct_long_mac(x4, sump13o, row7, rot3_0); \
-         dct_long_mac(x5, sump24o, row5, rot3_1); \
-         dct_long_mac(x6, sump23o, row3, rot3_2); \
-         dct_long_mac(x7, sump14o, row1, rot3_3); \
-         dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \
-         dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \
-         dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \
-         dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \
-   }
-
-   // load
-   row0 = vld1q_s16(data + 0*8);
-   row1 = vld1q_s16(data + 1*8);
-   row2 = vld1q_s16(data + 2*8);
-   row3 = vld1q_s16(data + 3*8);
-   row4 = vld1q_s16(data + 4*8);
-   row5 = vld1q_s16(data + 5*8);
-   row6 = vld1q_s16(data + 6*8);
-   row7 = vld1q_s16(data + 7*8);
-
-   // add DC bias
-   row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0));
-
-   // column pass
-   dct_pass(vrshrn_n_s32, 10);
-
-   // 16bit 8x8 transpose
-   {
+#define dct_bfly32o(out0, out1, a, b, shiftop, s)                                                                      \
+    {                                                                                                                  \
+        dct_wadd(sum, a, b);                                                                                           \
+        dct_wsub(dif, a, b);                                                                                           \
+        out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s));                                                     \
+        out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s));                                                     \
+    }
+
+#define dct_pass(shiftop, shift)                                                                                       \
+    {                                                                                                                  \
+        /* even part */                                                                                                \
+        int16x8_t sum26 = vaddq_s16(row2, row6);                                                                       \
+        dct_long_mul(p1e, sum26, rot0_0);                                                                              \
+        dct_long_mac(t2e, p1e, row6, rot0_1);                                                                          \
+        dct_long_mac(t3e, p1e, row2, rot0_2);                                                                          \
+        int16x8_t sum04 = vaddq_s16(row0, row4);                                                                       \
+        int16x8_t dif04 = vsubq_s16(row0, row4);                                                                       \
+        dct_widen(t0e, sum04);                                                                                         \
+        dct_widen(t1e, dif04);                                                                                         \
+        dct_wadd(x0, t0e, t3e);                                                                                        \
+        dct_wsub(x3, t0e, t3e);                                                                                        \
+        dct_wadd(x1, t1e, t2e);                                                                                        \
+        dct_wsub(x2, t1e, t2e);                                                                                        \
+        /* odd part */                                                                                                 \
+        int16x8_t sum15  = vaddq_s16(row1, row5);                                                                      \
+        int16x8_t sum17  = vaddq_s16(row1, row7);                                                                      \
+        int16x8_t sum35  = vaddq_s16(row3, row5);                                                                      \
+        int16x8_t sum37  = vaddq_s16(row3, row7);                                                                      \
+        int16x8_t sumodd = vaddq_s16(sum17, sum35);                                                                    \
+        dct_long_mul(p5o, sumodd, rot1_0);                                                                             \
+        dct_long_mac(p1o, p5o, sum17, rot1_1);                                                                         \
+        dct_long_mac(p2o, p5o, sum35, rot1_2);                                                                         \
+        dct_long_mul(p3o, sum37, rot2_0);                                                                              \
+        dct_long_mul(p4o, sum15, rot2_1);                                                                              \
+        dct_wadd(sump13o, p1o, p3o);                                                                                   \
+        dct_wadd(sump24o, p2o, p4o);                                                                                   \
+        dct_wadd(sump23o, p2o, p3o);                                                                                   \
+        dct_wadd(sump14o, p1o, p4o);                                                                                   \
+        dct_long_mac(x4, sump13o, row7, rot3_0);                                                                       \
+        dct_long_mac(x5, sump24o, row5, rot3_1);                                                                       \
+        dct_long_mac(x6, sump23o, row3, rot3_2);                                                                       \
+        dct_long_mac(x7, sump14o, row1, rot3_3);                                                                       \
+        dct_bfly32o(row0, row7, x0, x7, shiftop, shift);                                                               \
+        dct_bfly32o(row1, row6, x1, x6, shiftop, shift);                                                               \
+        dct_bfly32o(row2, row5, x2, x5, shiftop, shift);                                                               \
+        dct_bfly32o(row3, row4, x3, x4, shiftop, shift);                                                               \
+    }
+
+    // load
+    row0 = vld1q_s16(data + 0 * 8);
+    row1 = vld1q_s16(data + 1 * 8);
+    row2 = vld1q_s16(data + 2 * 8);
+    row3 = vld1q_s16(data + 3 * 8);
+    row4 = vld1q_s16(data + 4 * 8);
+    row5 = vld1q_s16(data + 5 * 8);
+    row6 = vld1q_s16(data + 6 * 8);
+    row7 = vld1q_s16(data + 7 * 8);
+
+    // add DC bias
+    row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0));
+
+    // column pass
+    dct_pass(vrshrn_n_s32, 10);
+
+    // 16bit 8x8 transpose
+    {
 // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively.
 // whether compilers actually get this is another story, sadly.
-#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; }
-#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); }
-#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); }
-
-         // pass 1
-         dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6
-         dct_trn16(row2, row3);
-         dct_trn16(row4, row5);
-         dct_trn16(row6, row7);
-
-         // pass 2
-         dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4
-         dct_trn32(row1, row3);
-         dct_trn32(row4, row6);
-         dct_trn32(row5, row7);
-
-         // pass 3
-         dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0
-         dct_trn64(row1, row5);
-         dct_trn64(row2, row6);
-         dct_trn64(row3, row7);
+#define dct_trn16(x, y)                                                                                                \
+    {                                                                                                                  \
+        int16x8x2_t t = vtrnq_s16(x, y);                                                                               \
+        x             = t.val[0];                                                                                      \
+        y             = t.val[1];                                                                                      \
+    }
+#define dct_trn32(x, y)                                                                                                \
+    {                                                                                                                  \
+        int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y));                                 \
+        x             = vreinterpretq_s16_s32(t.val[0]);                                                               \
+        y             = vreinterpretq_s16_s32(t.val[1]);                                                               \
+    }
+#define dct_trn64(x, y)                                                                                                \
+    {                                                                                                                  \
+        int16x8_t x0 = x;                                                                                              \
+        int16x8_t y0 = y;                                                                                              \
+        x            = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0));                                               \
+        y            = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0));                                             \
+    }
+
+        // pass 1
+        dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6
+        dct_trn16(row2, row3);
+        dct_trn16(row4, row5);
+        dct_trn16(row6, row7);
+
+        // pass 2
+        dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4
+        dct_trn32(row1, row3);
+        dct_trn32(row4, row6);
+        dct_trn32(row5, row7);
+
+        // pass 3
+        dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0
+        dct_trn64(row1, row5);
+        dct_trn64(row2, row6);
+        dct_trn64(row3, row7);
 
 #undef dct_trn16
 #undef dct_trn32
 #undef dct_trn64
-   }
-
-   // row pass
-   // vrshrn_n_s32 only supports shifts up to 16, we need
-   // 17. so do a non-rounding shift of 16 first then follow
-   // up with a rounding shift by 1.
-   dct_pass(vshrn_n_s32, 16);
-
-   {
-         // pack and round
-         uint8x8_t p0 = vqrshrun_n_s16(row0, 1);
-         uint8x8_t p1 = vqrshrun_n_s16(row1, 1);
-         uint8x8_t p2 = vqrshrun_n_s16(row2, 1);
-         uint8x8_t p3 = vqrshrun_n_s16(row3, 1);
-         uint8x8_t p4 = vqrshrun_n_s16(row4, 1);
-         uint8x8_t p5 = vqrshrun_n_s16(row5, 1);
-         uint8x8_t p6 = vqrshrun_n_s16(row6, 1);
-         uint8x8_t p7 = vqrshrun_n_s16(row7, 1);
-
-         // again, these can translate into one instruction, but often don't.
-#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; }
-#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); }
-#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); }
-
-         // sadly can't use interleaved stores here since we only write
-         // 8 bytes to each scan line!
-
-         // 8x8 8-bit transpose pass 1
-         dct_trn8_8(p0, p1);
-         dct_trn8_8(p2, p3);
-         dct_trn8_8(p4, p5);
-         dct_trn8_8(p6, p7);
-
-         // pass 2
-         dct_trn8_16(p0, p2);
-         dct_trn8_16(p1, p3);
-         dct_trn8_16(p4, p6);
-         dct_trn8_16(p5, p7);
-
-         // pass 3
-         dct_trn8_32(p0, p4);
-         dct_trn8_32(p1, p5);
-         dct_trn8_32(p2, p6);
-         dct_trn8_32(p3, p7);
-
-         // store
-         vst1_u8(out, p0); out += out_stride;
-         vst1_u8(out, p1); out += out_stride;
-         vst1_u8(out, p2); out += out_stride;
-         vst1_u8(out, p3); out += out_stride;
-         vst1_u8(out, p4); out += out_stride;
-         vst1_u8(out, p5); out += out_stride;
-         vst1_u8(out, p6); out += out_stride;
-         vst1_u8(out, p7);
+    }
+
+    // row pass
+    // vrshrn_n_s32 only supports shifts up to 16, we need
+    // 17. so do a non-rounding shift of 16 first then follow
+    // up with a rounding shift by 1.
+    dct_pass(vshrn_n_s32, 16);
+
+    {
+        // pack and round
+        uint8x8_t p0 = vqrshrun_n_s16(row0, 1);
+        uint8x8_t p1 = vqrshrun_n_s16(row1, 1);
+        uint8x8_t p2 = vqrshrun_n_s16(row2, 1);
+        uint8x8_t p3 = vqrshrun_n_s16(row3, 1);
+        uint8x8_t p4 = vqrshrun_n_s16(row4, 1);
+        uint8x8_t p5 = vqrshrun_n_s16(row5, 1);
+        uint8x8_t p6 = vqrshrun_n_s16(row6, 1);
+        uint8x8_t p7 = vqrshrun_n_s16(row7, 1);
+
+        // again, these can translate into one instruction, but often don't.
+#define dct_trn8_8(x, y)                                                                                               \
+    {                                                                                                                  \
+        uint8x8x2_t t = vtrn_u8(x, y);                                                                                 \
+        x             = t.val[0];                                                                                      \
+        y             = t.val[1];                                                                                      \
+    }
+#define dct_trn8_16(x, y)                                                                                              \
+    {                                                                                                                  \
+        uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y));                                     \
+        x              = vreinterpret_u8_u16(t.val[0]);                                                                \
+        y              = vreinterpret_u8_u16(t.val[1]);                                                                \
+    }
+#define dct_trn8_32(x, y)                                                                                              \
+    {                                                                                                                  \
+        uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y));                                     \
+        x              = vreinterpret_u8_u32(t.val[0]);                                                                \
+        y              = vreinterpret_u8_u32(t.val[1]);                                                                \
+    }
+
+        // sadly can't use interleaved stores here since we only write
+        // 8 bytes to each scan line!
+
+        // 8x8 8-bit transpose pass 1
+        dct_trn8_8(p0, p1);
+        dct_trn8_8(p2, p3);
+        dct_trn8_8(p4, p5);
+        dct_trn8_8(p6, p7);
+
+        // pass 2
+        dct_trn8_16(p0, p2);
+        dct_trn8_16(p1, p3);
+        dct_trn8_16(p4, p6);
+        dct_trn8_16(p5, p7);
+
+        // pass 3
+        dct_trn8_32(p0, p4);
+        dct_trn8_32(p1, p5);
+        dct_trn8_32(p2, p6);
+        dct_trn8_32(p3, p7);
+
+        // store
+        vst1_u8(out, p0);
+        out += out_stride;
+        vst1_u8(out, p1);
+        out += out_stride;
+        vst1_u8(out, p2);
+        out += out_stride;
+        vst1_u8(out, p3);
+        out += out_stride;
+        vst1_u8(out, p4);
+        out += out_stride;
+        vst1_u8(out, p5);
+        out += out_stride;
+        vst1_u8(out, p6);
+        out += out_stride;
+        vst1_u8(out, p7);
 
 #undef dct_trn8_8
 #undef dct_trn8_16
 #undef dct_trn8_32
-   }
+    }
 
 #undef dct_long_mul
 #undef dct_long_mac
@@ -2649,1130 +2675,1221 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
 
 #endif // STBI_NEON
 
-#define STBI__MARKER_none  0xff
+#define STBI__MARKER_none 0xff
 // if there's a pending marker from the entropy stream, return that
 // otherwise, fetch from the stream and get a marker. if there's no
 // marker, return 0xff, which is never a valid marker value
-static stbi_uc stbi__get_marker(stbi__jpeg *j)
-{
-   stbi_uc x;
-   if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; }
-   x = stbi__get8(j->s);
-   if (x != 0xff) return STBI__MARKER_none;
-   while (x == 0xff)
-         x = stbi__get8(j->s); // consume repeated 0xff fill bytes
-   return x;
+static stbi_uc stbi__get_marker(stbi__jpeg *j) {
+    stbi_uc x;
+    if (j->marker != STBI__MARKER_none) {
+        x         = j->marker;
+        j->marker = STBI__MARKER_none;
+        return x;
+    }
+    x = stbi__get8(j->s);
+    if (x != 0xff)
+        return STBI__MARKER_none;
+    while (x == 0xff)
+        x = stbi__get8(j->s); // consume repeated 0xff fill bytes
+    return x;
 }
 
 // in each scan, we'll have scan_n components, and the order
 // of the components is specified by order[]
-#define STBI__RESTART(x)        ((x) >= 0xd0 && (x) <= 0xd7)
+#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7)
 
 // after a restart interval, stbi__jpeg_reset the entropy decoder and
 // the dc prediction
-static void stbi__jpeg_reset(stbi__jpeg *j)
-{
-   j->code_bits = 0;
-   j->code_buffer = 0;
-   j->nomore = 0;
-   j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0;
-   j->marker = STBI__MARKER_none;
-   j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
-   j->eob_run = 0;
-   // no more than 1<<31 MCUs if no restart_interal? that's plenty safe,
-   // since we don't even allow 1<<30 pixels
-}
-
-static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
-{
-   stbi__jpeg_reset(z);
-   if (!z->progressive) {
-         if (z->scan_n == 1) {
-                int i,j;
-                STBI_SIMD_ALIGN(short, data[64]);
-                int n = z->order[0];
-                // non-interleaved data, we just need to process one block at a time,
-                // in trivial scanline order
-                // number of blocks to do just depends on how many actual "pixels" this
-                // component has, independent of interleaved MCU blocking and such
-                int w = (z->img_comp[n].x+7) >> 3;
-                int h = (z->img_comp[n].y+7) >> 3;
-                for (j=0; j < h; ++j) {
-                       for (i=0; i < w; ++i) {
-                          int ha = z->img_comp[n].ha;
-                          if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
-                          z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
-                          // every data block is an MCU, so countdown the restart interval
-                          if (--z->todo <= 0) {
-                                 if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
-                                 // if it's NOT a restart, then just bail, so we get corrupt data
-                                 // rather than no data
-                                 if (!STBI__RESTART(z->marker)) return 1;
-                                 stbi__jpeg_reset(z);
-                          }
-                       }
-                }
-                return 1;
-         } else { // interleaved
-                int i,j,k,x,y;
-                STBI_SIMD_ALIGN(short, data[64]);
-                for (j=0; j < z->img_mcu_y; ++j) {
-                       for (i=0; i < z->img_mcu_x; ++i) {
-                          // scan an interleaved mcu... process scan_n components in order
-                          for (k=0; k < z->scan_n; ++k) {
-                                 int n = z->order[k];
-                                 // scan out an mcu's worth of this component; that's just determined
-                                 // by the basic H and V specified for the component
-                                 for (y=0; y < z->img_comp[n].v; ++y) {
-                                        for (x=0; x < z->img_comp[n].h; ++x) {
-                                               int x2 = (i*z->img_comp[n].h + x)*8;
-                                               int y2 = (j*z->img_comp[n].v + y)*8;
-                                               int ha = z->img_comp[n].ha;
-                                               if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
-                                               z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data);
-                                        }
-                                 }
-                          }
-                          // after all interleaved components, that's an interleaved MCU,
-                          // so now count down the restart interval
-                          if (--z->todo <= 0) {
-                                 if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
-                                 if (!STBI__RESTART(z->marker)) return 1;
-                                 stbi__jpeg_reset(z);
-                          }
-                       }
-                }
-                return 1;
-         }
-   } else {
-         if (z->scan_n == 1) {
-                int i,j;
-                int n = z->order[0];
-                // non-interleaved data, we just need to process one block at a time,
-                // in trivial scanline order
-                // number of blocks to do just depends on how many actual "pixels" this
-                // component has, independent of interleaved MCU blocking and such
-                int w = (z->img_comp[n].x+7) >> 3;
-                int h = (z->img_comp[n].y+7) >> 3;
-                for (j=0; j < h; ++j) {
-                       for (i=0; i < w; ++i) {
-                          short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
-                          if (z->spec_start == 0) {
-                                 if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
-                                        return 0;
-                          } else {
-                                 int ha = z->img_comp[n].ha;
-                                 if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha]))
-                                        return 0;
-                          }
-                          // every data block is an MCU, so countdown the restart interval
-                          if (--z->todo <= 0) {
-                                 if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
-                                 if (!STBI__RESTART(z->marker)) return 1;
-                                 stbi__jpeg_reset(z);
-                          }
-                       }
-                }
-                return 1;
-         } else { // interleaved
-                int i,j,k,x,y;
-                for (j=0; j < z->img_mcu_y; ++j) {
-                       for (i=0; i < z->img_mcu_x; ++i) {
-                          // scan an interleaved mcu... process scan_n components in order
-                          for (k=0; k < z->scan_n; ++k) {
-                                 int n = z->order[k];
-                                 // scan out an mcu's worth of this component; that's just determined
-                                 // by the basic H and V specified for the component
-                                 for (y=0; y < z->img_comp[n].v; ++y) {
-                                        for (x=0; x < z->img_comp[n].h; ++x) {
-                                               int x2 = (i*z->img_comp[n].h + x);
-                                               int y2 = (j*z->img_comp[n].v + y);
-                                               short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w);
-                                               if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
-                                                  return 0;
-                                        }
-                                 }
-                          }
-                          // after all interleaved components, that's an interleaved MCU,
-                          // so now count down the restart interval
-                          if (--z->todo <= 0) {
-                                 if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
-                                 if (!STBI__RESTART(z->marker)) return 1;
-                                 stbi__jpeg_reset(z);
-                          }
-                       }
-                }
-                return 1;
-         }
-   }
-}
-
-static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant)
-{
-   int i;
-   for (i=0; i < 64; ++i)
-         data[i] *= dequant[i];
-}
-
-static void stbi__jpeg_finish(stbi__jpeg *z)
-{
-   if (z->progressive) {
-         // dequantize and idct the data
-         int i,j,n;
-         for (n=0; n < z->s->img_n; ++n) {
-                int w = (z->img_comp[n].x+7) >> 3;
-                int h = (z->img_comp[n].y+7) >> 3;
-                for (j=0; j < h; ++j) {
-                       for (i=0; i < w; ++i) {
-                          short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
-                          stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]);
-                          z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
-                       }
-                }
-         }
-   }
-}
-
-static int stbi__process_marker(stbi__jpeg *z, int m)
-{
-   int L;
-   switch (m) {
-         case STBI__MARKER_none: // no marker found
-                return stbi__err("expected marker","Corrupt JPEG");
-
-         case 0xDD: // DRI - specify restart interval
-                if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG");
-                z->restart_interval = stbi__get16be(z->s);
-                return 1;
-
-         case 0xDB: // DQT - define quantization table
-                L = stbi__get16be(z->s)-2;
-                while (L > 0) {
-                       int q = stbi__get8(z->s);
-                       int p = q >> 4, sixteen = (p != 0);
-                       int t = q & 15,i;
-                       if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG");
-                       if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG");
-
-                       for (i=0; i < 64; ++i)
-                          z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s));
-                       L -= (sixteen ? 129 : 65);
-                }
-                return L==0;
-
-         case 0xC4: // DHT - define huffman table
-                L = stbi__get16be(z->s)-2;
-                while (L > 0) {
-                       stbi_uc *v;
-                       int sizes[16],i,n=0;
-                       int q = stbi__get8(z->s);
-                       int tc = q >> 4;
-                       int th = q & 15;
-                       if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG");
-                       for (i=0; i < 16; ++i) {
-                          sizes[i] = stbi__get8(z->s);
-                          n += sizes[i];
-                       }
-                       L -= 17;
-                       if (tc == 0) {
-                          if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
-                          v = z->huff_dc[th].values;
-                       } else {
-                          if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0;
-                          v = z->huff_ac[th].values;
-                       }
-                       for (i=0; i < n; ++i)
-                          v[i] = stbi__get8(z->s);
-                       if (tc != 0)
-                          stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th);
-                       L -= n;
-                }
-                return L==0;
-   }
-
-   // check for comment block or APP blocks
-   if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
-         L = stbi__get16be(z->s);
-         if (L < 2) {
-                if (m == 0xFE)
-                       return stbi__err("bad COM len","Corrupt JPEG");
-                else
-                       return stbi__err("bad APP len","Corrupt JPEG");
-         }
-         L -= 2;
-
-         if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
-                static const unsigned char tag[5] = {'J','F','I','F','\0'};
-                int ok = 1;
-                int i;
-                for (i=0; i < 5; ++i)
-                       if (stbi__get8(z->s) != tag[i])
-                          ok = 0;
-                L -= 5;
-                if (ok)
-                       z->jfif = 1;
-         } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
-                static const unsigned char tag[6] = {'A','d','o','b','e','\0'};
-                int ok = 1;
-                int i;
-                for (i=0; i < 6; ++i)
-                       if (stbi__get8(z->s) != tag[i])
-                          ok = 0;
-                L -= 6;
-                if (ok) {
-                       stbi__get8(z->s); // version
-                       stbi__get16be(z->s); // flags0
-                       stbi__get16be(z->s); // flags1
-                       z->app14_color_transform = stbi__get8(z->s); // color transform
-                       L -= 6;
-                }
-         }
-
-         stbi__skip(z->s, L);
-         return 1;
-   }
-
-   return stbi__err("unknown marker","Corrupt JPEG");
+static void stbi__jpeg_reset(stbi__jpeg *j) {
+    j->code_bits           = 0;
+    j->code_buffer         = 0;
+    j->nomore              = 0;
+    j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0;
+    j->marker  = STBI__MARKER_none;
+    j->todo    = j->restart_interval ? j->restart_interval : 0x7fffffff;
+    j->eob_run = 0;
+    // no more than 1<<31 MCUs if no restart_interal? that's plenty safe,
+    // since we don't even allow 1<<30 pixels
+}
+
+static int stbi__parse_entropy_coded_data(stbi__jpeg *z) {
+    stbi__jpeg_reset(z);
+    if (!z->progressive) {
+        if (z->scan_n == 1) {
+            int i, j;
+            STBI_SIMD_ALIGN(short, data[64]);
+            int n = z->order[0];
+            // non-interleaved data, we just need to process one block at a time,
+            // in trivial scanline order
+            // number of blocks to do just depends on how many actual "pixels" this
+            // component has, independent of interleaved MCU blocking and such
+            int w = (z->img_comp[n].x + 7) >> 3;
+            int h = (z->img_comp[n].y + 7) >> 3;
+            for (j = 0; j < h; ++j) {
+                for (i = 0; i < w; ++i) {
+                    int ha = z->img_comp[n].ha;
+                    if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha,
+                                                 z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq]))
+                        return 0;
+                    z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2,
+                                         data);
+                    // every data block is an MCU, so countdown the restart interval
+                    if (--z->todo <= 0) {
+                        if (z->code_bits < 24)
+                            stbi__grow_buffer_unsafe(z);
+                        // if it's NOT a restart, then just bail, so we get corrupt data
+                        // rather than no data
+                        if (!STBI__RESTART(z->marker))
+                            return 1;
+                        stbi__jpeg_reset(z);
+                    }
+                }
+            }
+            return 1;
+        } else { // interleaved
+            int i, j, k, x, y;
+            STBI_SIMD_ALIGN(short, data[64]);
+            for (j = 0; j < z->img_mcu_y; ++j) {
+                for (i = 0; i < z->img_mcu_x; ++i) {
+                    // scan an interleaved mcu... process scan_n components in order
+                    for (k = 0; k < z->scan_n; ++k) {
+                        int n = z->order[k];
+                        // scan out an mcu's worth of this component; that's just determined
+                        // by the basic H and V specified for the component
+                        for (y = 0; y < z->img_comp[n].v; ++y) {
+                            for (x = 0; x < z->img_comp[n].h; ++x) {
+                                int x2 = (i * z->img_comp[n].h + x) * 8;
+                                int y2 = (j * z->img_comp[n].v + y) * 8;
+                                int ha = z->img_comp[n].ha;
+                                if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha,
+                                                             z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq]))
+                                    return 0;
+                                z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2,
+                                                     z->img_comp[n].w2, data);
+                            }
+                        }
+                    }
+                    // after all interleaved components, that's an interleaved MCU,
+                    // so now count down the restart interval
+                    if (--z->todo <= 0) {
+                        if (z->code_bits < 24)
+                            stbi__grow_buffer_unsafe(z);
+                        if (!STBI__RESTART(z->marker))
+                            return 1;
+                        stbi__jpeg_reset(z);
+                    }
+                }
+            }
+            return 1;
+        }
+    } else {
+        if (z->scan_n == 1) {
+            int i, j;
+            int n = z->order[0];
+            // non-interleaved data, we just need to process one block at a time,
+            // in trivial scanline order
+            // number of blocks to do just depends on how many actual "pixels" this
+            // component has, independent of interleaved MCU blocking and such
+            int w = (z->img_comp[n].x + 7) >> 3;
+            int h = (z->img_comp[n].y + 7) >> 3;
+            for (j = 0; j < h; ++j) {
+                for (i = 0; i < w; ++i) {
+                    short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
+                    if (z->spec_start == 0) {
+                        if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
+                            return 0;
+                    } else {
+                        int ha = z->img_comp[n].ha;
+                        if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha]))
+                            return 0;
+                    }
+                    // every data block is an MCU, so countdown the restart interval
+                    if (--z->todo <= 0) {
+                        if (z->code_bits < 24)
+                            stbi__grow_buffer_unsafe(z);
+                        if (!STBI__RESTART(z->marker))
+                            return 1;
+                        stbi__jpeg_reset(z);
+                    }
+                }
+            }
+            return 1;
+        } else { // interleaved
+            int i, j, k, x, y;
+            for (j = 0; j < z->img_mcu_y; ++j) {
+                for (i = 0; i < z->img_mcu_x; ++i) {
+                    // scan an interleaved mcu... process scan_n components in order
+                    for (k = 0; k < z->scan_n; ++k) {
+                        int n = z->order[k];
+                        // scan out an mcu's worth of this component; that's just determined
+                        // by the basic H and V specified for the component
+                        for (y = 0; y < z->img_comp[n].v; ++y) {
+                            for (x = 0; x < z->img_comp[n].h; ++x) {
+                                int    x2   = (i * z->img_comp[n].h + x);
+                                int    y2   = (j * z->img_comp[n].v + y);
+                                short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w);
+                                if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
+                                    return 0;
+                            }
+                        }
+                    }
+                    // after all interleaved components, that's an interleaved MCU,
+                    // so now count down the restart interval
+                    if (--z->todo <= 0) {
+                        if (z->code_bits < 24)
+                            stbi__grow_buffer_unsafe(z);
+                        if (!STBI__RESTART(z->marker))
+                            return 1;
+                        stbi__jpeg_reset(z);
+                    }
+                }
+            }
+            return 1;
+        }
+    }
+}
+
+static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) {
+    int i;
+    for (i = 0; i < 64; ++i)
+        data[i] *= dequant[i];
+}
+
+static void stbi__jpeg_finish(stbi__jpeg *z) {
+    if (z->progressive) {
+        // dequantize and idct the data
+        int i, j, n;
+        for (n = 0; n < z->s->img_n; ++n) {
+            int w = (z->img_comp[n].x + 7) >> 3;
+            int h = (z->img_comp[n].y + 7) >> 3;
+            for (j = 0; j < h; ++j) {
+                for (i = 0; i < w; ++i) {
+                    short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
+                    stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]);
+                    z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2,
+                                         data);
+                }
+            }
+        }
+    }
+}
+
+static int stbi__process_marker(stbi__jpeg *z, int m) {
+    int L;
+    switch (m) {
+    case STBI__MARKER_none: // no marker found
+        return stbi__err("expected marker", "Corrupt JPEG");
+
+    case 0xDD: // DRI - specify restart interval
+        if (stbi__get16be(z->s) != 4)
+            return stbi__err("bad DRI len", "Corrupt JPEG");
+        z->restart_interval = stbi__get16be(z->s);
+        return 1;
+
+    case 0xDB: // DQT - define quantization table
+        L = stbi__get16be(z->s) - 2;
+        while (L > 0) {
+            int q = stbi__get8(z->s);
+            int p = q >> 4, sixteen = (p != 0);
+            int t = q & 15, i;
+            if (p != 0 && p != 1)
+                return stbi__err("bad DQT type", "Corrupt JPEG");
+            if (t > 3)
+                return stbi__err("bad DQT table", "Corrupt JPEG");
+
+            for (i = 0; i < 64; ++i)
+                z->dequant[t][stbi__jpeg_dezigzag[i]] =
+                    (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s));
+            L -= (sixteen ? 129 : 65);
+        }
+        return L == 0;
+
+    case 0xC4: // DHT - define huffman table
+        L = stbi__get16be(z->s) - 2;
+        while (L > 0) {
+            stbi_uc *v;
+            int      sizes[16], i, n = 0;
+            int      q  = stbi__get8(z->s);
+            int      tc = q >> 4;
+            int      th = q & 15;
+            if (tc > 1 || th > 3)
+                return stbi__err("bad DHT header", "Corrupt JPEG");
+            for (i = 0; i < 16; ++i) {
+                sizes[i] = stbi__get8(z->s);
+                n += sizes[i];
+            }
+            L -= 17;
+            if (tc == 0) {
+                if (!stbi__build_huffman(z->huff_dc + th, sizes))
+                    return 0;
+                v = z->huff_dc[th].values;
+            } else {
+                if (!stbi__build_huffman(z->huff_ac + th, sizes))
+                    return 0;
+                v = z->huff_ac[th].values;
+            }
+            for (i = 0; i < n; ++i)
+                v[i] = stbi__get8(z->s);
+            if (tc != 0)
+                stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th);
+            L -= n;
+        }
+        return L == 0;
+    }
+
+    // check for comment block or APP blocks
+    if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
+        L = stbi__get16be(z->s);
+        if (L < 2) {
+            if (m == 0xFE)
+                return stbi__err("bad COM len", "Corrupt JPEG");
+            else
+                return stbi__err("bad APP len", "Corrupt JPEG");
+        }
+        L -= 2;
+
+        if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
+            static const unsigned char tag[5] = {'J', 'F', 'I', 'F', '\0'};
+            int                        ok     = 1;
+            int                        i;
+            for (i = 0; i < 5; ++i)
+                if (stbi__get8(z->s) != tag[i])
+                    ok = 0;
+            L -= 5;
+            if (ok)
+                z->jfif = 1;
+        } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
+            static const unsigned char tag[6] = {'A', 'd', 'o', 'b', 'e', '\0'};
+            int                        ok     = 1;
+            int                        i;
+            for (i = 0; i < 6; ++i)
+                if (stbi__get8(z->s) != tag[i])
+                    ok = 0;
+            L -= 6;
+            if (ok) {
+                stbi__get8(z->s);                            // version
+                stbi__get16be(z->s);                         // flags0
+                stbi__get16be(z->s);                         // flags1
+                z->app14_color_transform = stbi__get8(z->s); // color transform
+                L -= 6;
+            }
+        }
+
+        stbi__skip(z->s, L);
+        return 1;
+    }
+
+    return stbi__err("unknown marker", "Corrupt JPEG");
 }
 
 // after we see SOS
-static int stbi__process_scan_header(stbi__jpeg *z)
-{
-   int i;
-   int Ls = stbi__get16be(z->s);
-   z->scan_n = stbi__get8(z->s);
-   if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG");
-   if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG");
-   for (i=0; i < z->scan_n; ++i) {
-         int id = stbi__get8(z->s), which;
-         int q = stbi__get8(z->s);
-         for (which = 0; which < z->s->img_n; ++which)
-                if (z->img_comp[which].id == id)
-                       break;
-         if (which == z->s->img_n) return 0; // no match
-         z->img_comp[which].hd = q >> 4;       if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG");
-         z->img_comp[which].ha = q & 15;       if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG");
-         z->order[i] = which;
-   }
-
-   {
-         int aa;
-         z->spec_start = stbi__get8(z->s);
-         z->spec_end   = stbi__get8(z->s); // should be 63, but might be 0
-         aa = stbi__get8(z->s);
-         z->succ_high = (aa >> 4);
-         z->succ_low  = (aa & 15);
-         if (z->progressive) {
-                if (z->spec_start > 63 || z->spec_end > 63      || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13)
-                       return stbi__err("bad SOS", "Corrupt JPEG");
-         } else {
-                if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG");
-                if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG");
-                z->spec_end = 63;
-         }
-   }
-
-   return 1;
-}
-
-static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why)
-{
-   int i;
-   for (i=0; i < ncomp; ++i) {
-         if (z->img_comp[i].raw_data) {
-                STBI_FREE(z->img_comp[i].raw_data);
-                z->img_comp[i].raw_data = NULL;
-                z->img_comp[i].data = NULL;
-         }
-         if (z->img_comp[i].raw_coeff) {
-                STBI_FREE(z->img_comp[i].raw_coeff);
-                z->img_comp[i].raw_coeff = 0;
-                z->img_comp[i].coeff = 0;
-         }
-         if (z->img_comp[i].linebuf) {
-                STBI_FREE(z->img_comp[i].linebuf);
-                z->img_comp[i].linebuf = NULL;
-         }
-   }
-   return why;
-}
-
-static int stbi__process_frame_header(stbi__jpeg *z, int scan)
-{
-   stbi__context *s = z->s;
-   int Lf,p,i,q, h_max=1,v_max=1,c;
-   Lf = stbi__get16be(s);                if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG
-   p  = stbi__get8(s);                   if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
-   s->img_y = stbi__get16be(s);          if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
-   s->img_x = stbi__get16be(s);          if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
-   c = stbi__get8(s);
-   if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
-   s->img_n = c;
-   for (i=0; i < c; ++i) {
-         z->img_comp[i].data = NULL;
-         z->img_comp[i].linebuf = NULL;
-   }
-
-   if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG");
-
-   z->rgb = 0;
-   for (i=0; i < s->img_n; ++i) {
-         static const unsigned char rgb[3] = { 'R', 'G', 'B' };
-         z->img_comp[i].id = stbi__get8(s);
-         if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
-                ++z->rgb;
-         q = stbi__get8(s);
-         z->img_comp[i].h = (q >> 4);  if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
-         z->img_comp[i].v = q & 15;    if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
-         z->img_comp[i].tq = stbi__get8(s);  if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG");
-   }
-
-   if (scan != STBI__SCAN_load) return 1;
-
-   if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode");
-
-   for (i=0; i < s->img_n; ++i) {
-         if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h;
-         if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v;
-   }
-
-   // compute interleaved mcu info
-   z->img_h_max = h_max;
-   z->img_v_max = v_max;
-   z->img_mcu_w = h_max * 8;
-   z->img_mcu_h = v_max * 8;
-   // these sizes can't be more than 17 bits
-   z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w;
-   z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h;
-
-   for (i=0; i < s->img_n; ++i) {
-         // number of effective pixels (e.g. for non-interleaved MCU)
-         z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max;
-         z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max;
-         // to simplify generation, we'll allocate enough memory to decode
-         // the bogus oversized data from using interleaved MCUs and their
-         // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
-         // discard the extra data until colorspace conversion
-         //
-         // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier)
-         // so these muls can't overflow with 32-bit ints (which we require)
-         z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8;
-         z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8;
-         z->img_comp[i].coeff = 0;
-         z->img_comp[i].raw_coeff = 0;
-         z->img_comp[i].linebuf = NULL;
-         z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15);
-         if (z->img_comp[i].raw_data == NULL)
-                return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
-         // align blocks for idct using mmx/sse
-         z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15);
-         if (z->progressive) {
-                // w2, h2 are multiples of 8 (see above)
-                z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8;
-                z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8;
-                z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15);
-                if (z->img_comp[i].raw_coeff == NULL)
-                       return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
-                z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15);
-         }
-   }
-
-   return 1;
+static int stbi__process_scan_header(stbi__jpeg *z) {
+    int i;
+    int Ls    = stbi__get16be(z->s);
+    z->scan_n = stbi__get8(z->s);
+    if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n)
+        return stbi__err("bad SOS component count", "Corrupt JPEG");
+    if (Ls != 6 + 2 * z->scan_n)
+        return stbi__err("bad SOS len", "Corrupt JPEG");
+    for (i = 0; i < z->scan_n; ++i) {
+        int id = stbi__get8(z->s), which;
+        int q  = stbi__get8(z->s);
+        for (which = 0; which < z->s->img_n; ++which)
+            if (z->img_comp[which].id == id)
+                break;
+        if (which == z->s->img_n)
+            return 0; // no match
+        z->img_comp[which].hd = q >> 4;
+        if (z->img_comp[which].hd > 3)
+            return stbi__err("bad DC huff", "Corrupt JPEG");
+        z->img_comp[which].ha = q & 15;
+        if (z->img_comp[which].ha > 3)
+            return stbi__err("bad AC huff", "Corrupt JPEG");
+        z->order[i] = which;
+    }
+
+    {
+        int aa;
+        z->spec_start = stbi__get8(z->s);
+        z->spec_end   = stbi__get8(z->s); // should be 63, but might be 0
+        aa            = stbi__get8(z->s);
+        z->succ_high  = (aa >> 4);
+        z->succ_low   = (aa & 15);
+        if (z->progressive) {
+            if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 ||
+                z->succ_low > 13)
+                return stbi__err("bad SOS", "Corrupt JPEG");
+        } else {
+            if (z->spec_start != 0)
+                return stbi__err("bad SOS", "Corrupt JPEG");
+            if (z->succ_high != 0 || z->succ_low != 0)
+                return stbi__err("bad SOS", "Corrupt JPEG");
+            z->spec_end = 63;
+        }
+    }
+
+    return 1;
+}
+
+static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) {
+    int i;
+    for (i = 0; i < ncomp; ++i) {
+        if (z->img_comp[i].raw_data) {
+            STBI_FREE(z->img_comp[i].raw_data);
+            z->img_comp[i].raw_data = NULL;
+            z->img_comp[i].data     = NULL;
+        }
+        if (z->img_comp[i].raw_coeff) {
+            STBI_FREE(z->img_comp[i].raw_coeff);
+            z->img_comp[i].raw_coeff = 0;
+            z->img_comp[i].coeff     = 0;
+        }
+        if (z->img_comp[i].linebuf) {
+            STBI_FREE(z->img_comp[i].linebuf);
+            z->img_comp[i].linebuf = NULL;
+        }
+    }
+    return why;
+}
+
+static int stbi__process_frame_header(stbi__jpeg *z, int scan) {
+    stbi__context *s = z->s;
+    int            Lf, p, i, q, h_max = 1, v_max = 1, c;
+    Lf = stbi__get16be(s);
+    if (Lf < 11)
+        return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG
+    p = stbi__get8(s);
+    if (p != 8)
+        return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline
+    s->img_y = stbi__get16be(s);
+    if (s->img_y == 0)
+        return stbi__err(
+            "no header height",
+            "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
+    s->img_x = stbi__get16be(s);
+    if (s->img_x == 0)
+        return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires
+    c = stbi__get8(s);
+    if (c != 3 && c != 1 && c != 4)
+        return stbi__err("bad component count", "Corrupt JPEG");
+    s->img_n = c;
+    for (i = 0; i < c; ++i) {
+        z->img_comp[i].data    = NULL;
+        z->img_comp[i].linebuf = NULL;
+    }
+
+    if (Lf != 8 + 3 * s->img_n)
+        return stbi__err("bad SOF len", "Corrupt JPEG");
+
+    z->rgb = 0;
+    for (i = 0; i < s->img_n; ++i) {
+        static const unsigned char rgb[3] = {'R', 'G', 'B'};
+        z->img_comp[i].id                 = stbi__get8(s);
+        if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
+            ++z->rgb;
+        q                = stbi__get8(s);
+        z->img_comp[i].h = (q >> 4);
+        if (!z->img_comp[i].h || z->img_comp[i].h > 4)
+            return stbi__err("bad H", "Corrupt JPEG");
+        z->img_comp[i].v = q & 15;
+        if (!z->img_comp[i].v || z->img_comp[i].v > 4)
+            return stbi__err("bad V", "Corrupt JPEG");
+        z->img_comp[i].tq = stbi__get8(s);
+        if (z->img_comp[i].tq > 3)
+            return stbi__err("bad TQ", "Corrupt JPEG");
+    }
+
+    if (scan != STBI__SCAN_load)
+        return 1;
+
+    if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0))
+        return stbi__err("too large", "Image too large to decode");
+
+    for (i = 0; i < s->img_n; ++i) {
+        if (z->img_comp[i].h > h_max)
+            h_max = z->img_comp[i].h;
+        if (z->img_comp[i].v > v_max)
+            v_max = z->img_comp[i].v;
+    }
+
+    // compute interleaved mcu info
+    z->img_h_max = h_max;
+    z->img_v_max = v_max;
+    z->img_mcu_w = h_max * 8;
+    z->img_mcu_h = v_max * 8;
+    // these sizes can't be more than 17 bits
+    z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w;
+    z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h;
+
+    for (i = 0; i < s->img_n; ++i) {
+        // number of effective pixels (e.g. for non-interleaved MCU)
+        z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max;
+        z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max;
+        // to simplify generation, we'll allocate enough memory to decode
+        // the bogus oversized data from using interleaved MCUs and their
+        // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
+        // discard the extra data until colorspace conversion
+        //
+        // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier)
+        // so these muls can't overflow with 32-bit ints (which we require)
+        z->img_comp[i].w2        = z->img_mcu_x * z->img_comp[i].h * 8;
+        z->img_comp[i].h2        = z->img_mcu_y * z->img_comp[i].v * 8;
+        z->img_comp[i].coeff     = 0;
+        z->img_comp[i].raw_coeff = 0;
+        z->img_comp[i].linebuf   = NULL;
+        z->img_comp[i].raw_data  = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15);
+        if (z->img_comp[i].raw_data == NULL)
+            return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory"));
+        // align blocks for idct using mmx/sse
+        z->img_comp[i].data = (stbi_uc *)(((size_t)z->img_comp[i].raw_data + 15) & ~15);
+        if (z->progressive) {
+            // w2, h2 are multiples of 8 (see above)
+            z->img_comp[i].coeff_w   = z->img_comp[i].w2 / 8;
+            z->img_comp[i].coeff_h   = z->img_comp[i].h2 / 8;
+            z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15);
+            if (z->img_comp[i].raw_coeff == NULL)
+                return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory"));
+            z->img_comp[i].coeff = (short *)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15);
+        }
+    }
+
+    return 1;
 }
 
 // use comparisons since in some cases we handle more than one case (e.g. SOF)
-#define stbi__DNL(x)            ((x) == 0xdc)
-#define stbi__SOI(x)            ((x) == 0xd8)
-#define stbi__EOI(x)            ((x) == 0xd9)
-#define stbi__SOF(x)            ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2)
-#define stbi__SOS(x)            ((x) == 0xda)
-
-#define stbi__SOF_progressive(x)   ((x) == 0xc2)
-
-static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
-{
-   int m;
-   z->jfif = 0;
-   z->app14_color_transform = -1; // valid values are 0,1,2
-   z->marker = STBI__MARKER_none; // initialize cached marker to empty
-   m = stbi__get_marker(z);
-   if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
-   if (scan == STBI__SCAN_type) return 1;
-   m = stbi__get_marker(z);
-   while (!stbi__SOF(m)) {
-         if (!stbi__process_marker(z,m)) return 0;
-         m = stbi__get_marker(z);
-         while (m == STBI__MARKER_none) {
-                // some files have extra padding after their blocks, so ok, we'll scan
-                if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG");
-                m = stbi__get_marker(z);
-         }
-   }
-   z->progressive = stbi__SOF_progressive(m);
-   if (!stbi__process_frame_header(z, scan)) return 0;
-   return 1;
+#define stbi__DNL(x)             ((x) == 0xdc)
+#define stbi__SOI(x)             ((x) == 0xd8)
+#define stbi__EOI(x)             ((x) == 0xd9)
+#define stbi__SOF(x)             ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2)
+#define stbi__SOS(x)             ((x) == 0xda)
+
+#define stbi__SOF_progressive(x) ((x) == 0xc2)
+
+static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) {
+    int m;
+    z->jfif                  = 0;
+    z->app14_color_transform = -1;                // valid values are 0,1,2
+    z->marker                = STBI__MARKER_none; // initialize cached marker to empty
+    m                        = stbi__get_marker(z);
+    if (!stbi__SOI(m))
+        return stbi__err("no SOI", "Corrupt JPEG");
+    if (scan == STBI__SCAN_type)
+        return 1;
+    m = stbi__get_marker(z);
+    while (!stbi__SOF(m)) {
+        if (!stbi__process_marker(z, m))
+            return 0;
+        m = stbi__get_marker(z);
+        while (m == STBI__MARKER_none) {
+            // some files have extra padding after their blocks, so ok, we'll scan
+            if (stbi__at_eof(z->s))
+                return stbi__err("no SOF", "Corrupt JPEG");
+            m = stbi__get_marker(z);
+        }
+    }
+    z->progressive = stbi__SOF_progressive(m);
+    if (!stbi__process_frame_header(z, scan))
+        return 0;
+    return 1;
 }
 
 // decode image to YCbCr format
-static int stbi__decode_jpeg_image(stbi__jpeg *j)
-{
-   int m;
-   for (m = 0; m < 4; m++) {
-         j->img_comp[m].raw_data = NULL;
-         j->img_comp[m].raw_coeff = NULL;
-   }
-   j->restart_interval = 0;
-   if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0;
-   m = stbi__get_marker(j);
-   while (!stbi__EOI(m)) {
-         if (stbi__SOS(m)) {
-                if (!stbi__process_scan_header(j)) return 0;
-                if (!stbi__parse_entropy_coded_data(j)) return 0;
-                if (j->marker == STBI__MARKER_none ) {
-                       // handle 0s at the end of image data from IP Kamera 9060
-                       while (!stbi__at_eof(j->s)) {
-                          int x = stbi__get8(j->s);
-                          if (x == 255) {
-                                 j->marker = stbi__get8(j->s);
-                                 break;
-                          }
-                       }
-                       // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
-                }
-         } else if (stbi__DNL(m)) {
-                int Ld = stbi__get16be(j->s);
-                stbi__uint32 NL = stbi__get16be(j->s);
-                if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
-                if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
-         } else {
-                if (!stbi__process_marker(j, m)) return 0;
-         }
-         m = stbi__get_marker(j);
-   }
-   if (j->progressive)
-         stbi__jpeg_finish(j);
-   return 1;
+static int stbi__decode_jpeg_image(stbi__jpeg *j) {
+    int m;
+    for (m = 0; m < 4; m++) {
+        j->img_comp[m].raw_data  = NULL;
+        j->img_comp[m].raw_coeff = NULL;
+    }
+    j->restart_interval = 0;
+    if (!stbi__decode_jpeg_header(j, STBI__SCAN_load))
+        return 0;
+    m = stbi__get_marker(j);
+    while (!stbi__EOI(m)) {
+        if (stbi__SOS(m)) {
+            if (!stbi__process_scan_header(j))
+                return 0;
+            if (!stbi__parse_entropy_coded_data(j))
+                return 0;
+            if (j->marker == STBI__MARKER_none) {
+                // handle 0s at the end of image data from IP Kamera 9060
+                while (!stbi__at_eof(j->s)) {
+                    int x = stbi__get8(j->s);
+                    if (x == 255) {
+                        j->marker = stbi__get8(j->s);
+                        break;
+                    }
+                }
+                // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually
+                // return 0
+            }
+        } else if (stbi__DNL(m)) {
+            int          Ld = stbi__get16be(j->s);
+            stbi__uint32 NL = stbi__get16be(j->s);
+            if (Ld != 4)
+                return stbi__err("bad DNL len", "Corrupt JPEG");
+            if (NL != j->s->img_y)
+                return stbi__err("bad DNL height", "Corrupt JPEG");
+        } else {
+            if (!stbi__process_marker(j, m))
+                return 0;
+        }
+        m = stbi__get_marker(j);
+    }
+    if (j->progressive)
+        stbi__jpeg_finish(j);
+    return 1;
 }
 
 // static jfif-centered resampling (across block boundaries)
 
-typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1,
-                                                                       int w, int hs);
+typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, int w, int hs);
 
-#define stbi__div4(x) ((stbi_uc) ((x) >> 2))
+#define stbi__div4(x) ((stbi_uc)((x) >> 2))
 
-static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   STBI_NOTUSED(out);
-   STBI_NOTUSED(in_far);
-   STBI_NOTUSED(w);
-   STBI_NOTUSED(hs);
-   return in_near;
+static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) {
+    STBI_NOTUSED(out);
+    STBI_NOTUSED(in_far);
+    STBI_NOTUSED(w);
+    STBI_NOTUSED(hs);
+    return in_near;
 }
 
-static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   // need to generate two samples vertically for every one in input
-   int i;
-   STBI_NOTUSED(hs);
-   for (i=0; i < w; ++i)
-         out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2);
-   return out;
+static stbi_uc *stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) {
+    // need to generate two samples vertically for every one in input
+    int i;
+    STBI_NOTUSED(hs);
+    for (i = 0; i < w; ++i)
+        out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2);
+    return out;
 }
 
-static stbi_uc*         stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   // need to generate two samples horizontally for every one in input
-   int i;
-   stbi_uc *input = in_near;
+static stbi_uc *stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) {
+    // need to generate two samples horizontally for every one in input
+    int      i;
+    stbi_uc *input = in_near;
 
-   if (w == 1) {
-         // if only one sample, can't do any interpolation
-         out[0] = out[1] = input[0];
-         return out;
-   }
+    if (w == 1) {
+        // if only one sample, can't do any interpolation
+        out[0] = out[1] = input[0];
+        return out;
+    }
 
-   out[0] = input[0];
-   out[1] = stbi__div4(input[0]*3 + input[1] + 2);
-   for (i=1; i < w-1; ++i) {
-         int n = 3*input[i]+2;
-         out[i*2+0] = stbi__div4(n+input[i-1]);
-         out[i*2+1] = stbi__div4(n+input[i+1]);
-   }
-   out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2);
-   out[i*2+1] = input[w-1];
+    out[0] = input[0];
+    out[1] = stbi__div4(input[0] * 3 + input[1] + 2);
+    for (i = 1; i < w - 1; ++i) {
+        int n          = 3 * input[i] + 2;
+        out[i * 2 + 0] = stbi__div4(n + input[i - 1]);
+        out[i * 2 + 1] = stbi__div4(n + input[i + 1]);
+    }
+    out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2);
+    out[i * 2 + 1] = input[w - 1];
 
-   STBI_NOTUSED(in_far);
-   STBI_NOTUSED(hs);
+    STBI_NOTUSED(in_far);
+    STBI_NOTUSED(hs);
 
-   return out;
+    return out;
 }
 
-#define stbi__div16(x) ((stbi_uc) ((x) >> 4))
+#define stbi__div16(x) ((stbi_uc)((x) >> 4))
 
-static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   // need to generate 2x2 samples for every one in input
-   int i,t0,t1;
-   if (w == 1) {
-         out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2);
-         return out;
-   }
+static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) {
+    // need to generate 2x2 samples for every one in input
+    int i, t0, t1;
+    if (w == 1) {
+        out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2);
+        return out;
+    }
 
-   t1 = 3*in_near[0] + in_far[0];
-   out[0] = stbi__div4(t1+2);
-   for (i=1; i < w; ++i) {
-         t0 = t1;
-         t1 = 3*in_near[i]+in_far[i];
-         out[i*2-1] = stbi__div16(3*t0 + t1 + 8);
-         out[i*2  ] = stbi__div16(3*t1 + t0 + 8);
-   }
-   out[w*2-1] = stbi__div4(t1+2);
+    t1     = 3 * in_near[0] + in_far[0];
+    out[0] = stbi__div4(t1 + 2);
+    for (i = 1; i < w; ++i) {
+        t0             = t1;
+        t1             = 3 * in_near[i] + in_far[i];
+        out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8);
+        out[i * 2]     = stbi__div16(3 * t1 + t0 + 8);
+    }
+    out[w * 2 - 1] = stbi__div4(t1 + 2);
 
-   STBI_NOTUSED(hs);
+    STBI_NOTUSED(hs);
 
-   return out;
+    return out;
 }
 
 #if defined(STBI_SSE2) || defined(STBI_NEON)
-static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   // need to generate 2x2 samples for every one in input
-   int i=0,t0,t1;
-
-   if (w == 1) {
-         out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2);
-         return out;
-   }
-
-   t1 = 3*in_near[0] + in_far[0];
-   // process groups of 8 pixels for as long as we can.
-   // note we can't handle the last pixel in a row in this loop
-   // because we need to handle the filter boundary conditions.
-   for (; i < ((w-1) & ~7); i += 8) {
+static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) {
+    // need to generate 2x2 samples for every one in input
+    int i = 0, t0, t1;
+
+    if (w == 1) {
+        out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2);
+        return out;
+    }
+
+    t1 = 3 * in_near[0] + in_far[0];
+    // process groups of 8 pixels for as long as we can.
+    // note we can't handle the last pixel in a row in this loop
+    // because we need to handle the filter boundary conditions.
+    for (; i < ((w - 1) & ~7); i += 8) {
 #if defined(STBI_SSE2)
-         // load and perform the vertical filtering pass
-         // this uses 3*x + y = 4*x + (y - x)
-         __m128i zero  = _mm_setzero_si128();
-         __m128i farb  = _mm_loadl_epi64((__m128i *) (in_far + i));
-         __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i));
-         __m128i farw  = _mm_unpacklo_epi8(farb, zero);
-         __m128i nearw = _mm_unpacklo_epi8(nearb, zero);
-         __m128i diff  = _mm_sub_epi16(farw, nearw);
-         __m128i nears = _mm_slli_epi16(nearw, 2);
-         __m128i curr  = _mm_add_epi16(nears, diff); // current row
-
-         // horizontal filter works the same based on shifted vers of current
-         // row. "prev" is current row shifted right by 1 pixel; we need to
-         // insert the previous pixel value (from t1).
-         // "next" is current row shifted left by 1 pixel, with first pixel
-         // of next block of 8 pixels added in.
-         __m128i prv0 = _mm_slli_si128(curr, 2);
-         __m128i nxt0 = _mm_srli_si128(curr, 2);
-         __m128i prev = _mm_insert_epi16(prv0, t1, 0);
-         __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7);
-
-         // horizontal filter, polyphase implementation since it's convenient:
-         // even pixels = 3*cur + prev = cur*4 + (prev - cur)
-         // odd  pixels = 3*cur + next = cur*4 + (next - cur)
-         // note the shared term.
-         __m128i bias  = _mm_set1_epi16(8);
-         __m128i curs = _mm_slli_epi16(curr, 2);
-         __m128i prvd = _mm_sub_epi16(prev, curr);
-         __m128i nxtd = _mm_sub_epi16(next, curr);
-         __m128i curb = _mm_add_epi16(curs, bias);
-         __m128i even = _mm_add_epi16(prvd, curb);
-         __m128i odd  = _mm_add_epi16(nxtd, curb);
-
-         // interleave even and odd pixels, then undo scaling.
-         __m128i int0 = _mm_unpacklo_epi16(even, odd);
-         __m128i int1 = _mm_unpackhi_epi16(even, odd);
-         __m128i de0  = _mm_srli_epi16(int0, 4);
-         __m128i de1  = _mm_srli_epi16(int1, 4);
-
-         // pack and write output
-         __m128i outv = _mm_packus_epi16(de0, de1);
-         _mm_storeu_si128((__m128i *) (out + i*2), outv);
+        // load and perform the vertical filtering pass
+        // this uses 3*x + y = 4*x + (y - x)
+        __m128i zero  = _mm_setzero_si128();
+        __m128i farb  = _mm_loadl_epi64((__m128i *)(in_far + i));
+        __m128i nearb = _mm_loadl_epi64((__m128i *)(in_near + i));
+        __m128i farw  = _mm_unpacklo_epi8(farb, zero);
+        __m128i nearw = _mm_unpacklo_epi8(nearb, zero);
+        __m128i diff  = _mm_sub_epi16(farw, nearw);
+        __m128i nears = _mm_slli_epi16(nearw, 2);
+        __m128i curr  = _mm_add_epi16(nears, diff); // current row
+
+        // horizontal filter works the same based on shifted vers of current
+        // row. "prev" is current row shifted right by 1 pixel; we need to
+        // insert the previous pixel value (from t1).
+        // "next" is current row shifted left by 1 pixel, with first pixel
+        // of next block of 8 pixels added in.
+        __m128i prv0 = _mm_slli_si128(curr, 2);
+        __m128i nxt0 = _mm_srli_si128(curr, 2);
+        __m128i prev = _mm_insert_epi16(prv0, t1, 0);
+        __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7);
+
+        // horizontal filter, polyphase implementation since it's convenient:
+        // even pixels = 3*cur + prev = cur*4 + (prev - cur)
+        // odd  pixels = 3*cur + next = cur*4 + (next - cur)
+        // note the shared term.
+        __m128i bias = _mm_set1_epi16(8);
+        __m128i curs = _mm_slli_epi16(curr, 2);
+        __m128i prvd = _mm_sub_epi16(prev, curr);
+        __m128i nxtd = _mm_sub_epi16(next, curr);
+        __m128i curb = _mm_add_epi16(curs, bias);
+        __m128i even = _mm_add_epi16(prvd, curb);
+        __m128i odd  = _mm_add_epi16(nxtd, curb);
+
+        // interleave even and odd pixels, then undo scaling.
+        __m128i int0 = _mm_unpacklo_epi16(even, odd);
+        __m128i int1 = _mm_unpackhi_epi16(even, odd);
+        __m128i de0  = _mm_srli_epi16(int0, 4);
+        __m128i de1  = _mm_srli_epi16(int1, 4);
+
+        // pack and write output
+        __m128i outv = _mm_packus_epi16(de0, de1);
+        _mm_storeu_si128((__m128i *)(out + i * 2), outv);
 #elif defined(STBI_NEON)
-         // load and perform the vertical filtering pass
-         // this uses 3*x + y = 4*x + (y - x)
-         uint8x8_t farb  = vld1_u8(in_far + i);
-         uint8x8_t nearb = vld1_u8(in_near + i);
-         int16x8_t diff  = vreinterpretq_s16_u16(vsubl_u8(farb, nearb));
-         int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2));
-         int16x8_t curr  = vaddq_s16(nears, diff); // current row
-
-         // horizontal filter works the same based on shifted vers of current
-         // row. "prev" is current row shifted right by 1 pixel; we need to
-         // insert the previous pixel value (from t1).
-         // "next" is current row shifted left by 1 pixel, with first pixel
-         // of next block of 8 pixels added in.
-         int16x8_t prv0 = vextq_s16(curr, curr, 7);
-         int16x8_t nxt0 = vextq_s16(curr, curr, 1);
-         int16x8_t prev = vsetq_lane_s16(t1, prv0, 0);
-         int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7);
-
-         // horizontal filter, polyphase implementation since it's convenient:
-         // even pixels = 3*cur + prev = cur*4 + (prev - cur)
-         // odd  pixels = 3*cur + next = cur*4 + (next - cur)
-         // note the shared term.
-         int16x8_t curs = vshlq_n_s16(curr, 2);
-         int16x8_t prvd = vsubq_s16(prev, curr);
-         int16x8_t nxtd = vsubq_s16(next, curr);
-         int16x8_t even = vaddq_s16(curs, prvd);
-         int16x8_t odd  = vaddq_s16(curs, nxtd);
-
-         // undo scaling and round, then store with even/odd phases interleaved
-         uint8x8x2_t o;
-         o.val[0] = vqrshrun_n_s16(even, 4);
-         o.val[1] = vqrshrun_n_s16(odd,  4);
-         vst2_u8(out + i*2, o);
+        // load and perform the vertical filtering pass
+        // this uses 3*x + y = 4*x + (y - x)
+        uint8x8_t farb  = vld1_u8(in_far + i);
+        uint8x8_t nearb = vld1_u8(in_near + i);
+        int16x8_t diff  = vreinterpretq_s16_u16(vsubl_u8(farb, nearb));
+        int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2));
+        int16x8_t curr  = vaddq_s16(nears, diff); // current row
+
+        // horizontal filter works the same based on shifted vers of current
+        // row. "prev" is current row shifted right by 1 pixel; we need to
+        // insert the previous pixel value (from t1).
+        // "next" is current row shifted left by 1 pixel, with first pixel
+        // of next block of 8 pixels added in.
+        int16x8_t prv0 = vextq_s16(curr, curr, 7);
+        int16x8_t nxt0 = vextq_s16(curr, curr, 1);
+        int16x8_t prev = vsetq_lane_s16(t1, prv0, 0);
+        int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7);
+
+        // horizontal filter, polyphase implementation since it's convenient:
+        // even pixels = 3*cur + prev = cur*4 + (prev - cur)
+        // odd  pixels = 3*cur + next = cur*4 + (next - cur)
+        // note the shared term.
+        int16x8_t curs = vshlq_n_s16(curr, 2);
+        int16x8_t prvd = vsubq_s16(prev, curr);
+        int16x8_t nxtd = vsubq_s16(next, curr);
+        int16x8_t even = vaddq_s16(curs, prvd);
+        int16x8_t odd  = vaddq_s16(curs, nxtd);
+
+        // undo scaling and round, then store with even/odd phases interleaved
+        uint8x8x2_t o;
+        o.val[0] = vqrshrun_n_s16(even, 4);
+        o.val[1] = vqrshrun_n_s16(odd, 4);
+        vst2_u8(out + i * 2, o);
 #endif
 
-         // "previous" value for next iter
-         t1 = 3*in_near[i+7] + in_far[i+7];
-   }
+        // "previous" value for next iter
+        t1 = 3 * in_near[i + 7] + in_far[i + 7];
+    }
 
-   t0 = t1;
-   t1 = 3*in_near[i] + in_far[i];
-   out[i*2] = stbi__div16(3*t1 + t0 + 8);
+    t0         = t1;
+    t1         = 3 * in_near[i] + in_far[i];
+    out[i * 2] = stbi__div16(3 * t1 + t0 + 8);
 
-   for (++i; i < w; ++i) {
-         t0 = t1;
-         t1 = 3*in_near[i]+in_far[i];
-         out[i*2-1] = stbi__div16(3*t0 + t1 + 8);
-         out[i*2  ] = stbi__div16(3*t1 + t0 + 8);
-   }
-   out[w*2-1] = stbi__div4(t1+2);
+    for (++i; i < w; ++i) {
+        t0             = t1;
+        t1             = 3 * in_near[i] + in_far[i];
+        out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8);
+        out[i * 2]     = stbi__div16(3 * t1 + t0 + 8);
+    }
+    out[w * 2 - 1] = stbi__div4(t1 + 2);
 
-   STBI_NOTUSED(hs);
+    STBI_NOTUSED(hs);
 
-   return out;
+    return out;
 }
 #endif
 
-static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
-{
-   // resample with nearest-neighbor
-   int i,j;
-   STBI_NOTUSED(in_far);
-   for (i=0; i < w; ++i)
-         for (j=0; j < hs; ++j)
-                out[i*hs+j] = in_near[i];
-   return out;
+static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) {
+    // resample with nearest-neighbor
+    int i, j;
+    STBI_NOTUSED(in_far);
+    for (i = 0; i < w; ++i)
+        for (j = 0; j < hs; ++j)
+            out[i * hs + j] = in_near[i];
+    return out;
 }
 
 // this is a reduced-precision calculation of YCbCr-to-RGB introduced
 // to make sure the code produces the same results in both SIMD and scalar
-#define stbi__float2fixed(x)  (((int) ((x) * 4096.0f + 0.5f)) << 8)
-static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
-{
-   int i;
-   for (i=0; i < count; ++i) {
-         int y_fixed = (y[i] << 20) + (1<<19); // rounding
-         int r,g,b;
-         int cr = pcr[i] - 128;
-         int cb = pcb[i] - 128;
-         r = y_fixed +  cr* stbi__float2fixed(1.40200f);
-         g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
-         b = y_fixed                                                                     +       cb* stbi__float2fixed(1.77200f);
-         r >>= 20;
-         g >>= 20;
-         b >>= 20;
-         if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
-         if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
-         if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
-         out[0] = (stbi_uc)r;
-         out[1] = (stbi_uc)g;
-         out[2] = (stbi_uc)b;
-         out[3] = 255;
-         out += step;
-   }
+#define stbi__float2fixed(x) (((int)((x)*4096.0f + 0.5f)) << 8)
+static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count,
+                                   int step) {
+    int i;
+    for (i = 0; i < count; ++i) {
+        int y_fixed = (y[i] << 20) + (1 << 19); // rounding
+        int r, g, b;
+        int cr = pcr[i] - 128;
+        int cb = pcb[i] - 128;
+        r      = y_fixed + cr * stbi__float2fixed(1.40200f);
+        g      = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000);
+        b      = y_fixed + cb * stbi__float2fixed(1.77200f);
+        r >>= 20;
+        g >>= 20;
+        b >>= 20;
+        if ((unsigned)r > 255) {
+            if (r < 0)
+                r = 0;
+            else
+                r = 255;
+        }
+        if ((unsigned)g > 255) {
+            if (g < 0)
+                g = 0;
+            else
+                g = 255;
+        }
+        if ((unsigned)b > 255) {
+            if (b < 0)
+                b = 0;
+            else
+                b = 255;
+        }
+        out[0] = (stbi_uc)r;
+        out[1] = (stbi_uc)g;
+        out[2] = (stbi_uc)b;
+        out[3] = 255;
+        out += step;
+    }
 }
 
 #if defined(STBI_SSE2) || defined(STBI_NEON)
-static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step)
-{
-   int i = 0;
+static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count,
+                                    int step) {
+    int i = 0;
 
 #ifdef STBI_SSE2
-   // step == 3 is pretty ugly on the final interleave, and i'm not convinced
-   // it's useful in practice (you wouldn't use it for textures, for example).
-   // so just accelerate step == 4 case.
-   if (step == 4) {
-         // this is a fairly straightforward implementation and not super-optimized.
-         __m128i signflip      = _mm_set1_epi8(-0x80);
-         __m128i cr_const0 = _mm_set1_epi16(   (short) ( 1.40200f*4096.0f+0.5f));
-         __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f));
-         __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f));
-         __m128i cb_const1 = _mm_set1_epi16(   (short) ( 1.77200f*4096.0f+0.5f));
-         __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128);
-         __m128i xw = _mm_set1_epi16(255); // alpha channel
-
-         for (; i+7 < count; i += 8) {
-                // load
-                __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i));
-                __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i));
-                __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i));
-                __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128
-                __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128
-
-                // unpack to short (and left-shift cr, cb by 8)
-                __m128i yw      = _mm_unpacklo_epi8(y_bias, y_bytes);
-                __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased);
-                __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased);
-
-                // color transform
-                __m128i yws = _mm_srli_epi16(yw, 4);
-                __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw);
-                __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw);
-                __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1);
-                __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1);
-                __m128i rws = _mm_add_epi16(cr0, yws);
-                __m128i gwt = _mm_add_epi16(cb0, yws);
-                __m128i bws = _mm_add_epi16(yws, cb1);
-                __m128i gws = _mm_add_epi16(gwt, cr1);
-
-                // descale
-                __m128i rw = _mm_srai_epi16(rws, 4);
-                __m128i bw = _mm_srai_epi16(bws, 4);
-                __m128i gw = _mm_srai_epi16(gws, 4);
-
-                // back to byte, set up for transpose
-                __m128i brb = _mm_packus_epi16(rw, bw);
-                __m128i gxb = _mm_packus_epi16(gw, xw);
-
-                // transpose to interleave channels
-                __m128i t0 = _mm_unpacklo_epi8(brb, gxb);
-                __m128i t1 = _mm_unpackhi_epi8(brb, gxb);
-                __m128i o0 = _mm_unpacklo_epi16(t0, t1);
-                __m128i o1 = _mm_unpackhi_epi16(t0, t1);
-
-                // store
-                _mm_storeu_si128((__m128i *) (out + 0), o0);
-                _mm_storeu_si128((__m128i *) (out + 16), o1);
-                out += 32;
-         }
-   }
+    // step == 3 is pretty ugly on the final interleave, and i'm not convinced
+    // it's useful in practice (you wouldn't use it for textures, for example).
+    // so just accelerate step == 4 case.
+    if (step == 4) {
+        // this is a fairly straightforward implementation and not super-optimized.
+        __m128i signflip  = _mm_set1_epi8(-0x80);
+        __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f));
+        __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f));
+        __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f));
+        __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f));
+        __m128i y_bias    = _mm_set1_epi8((char)(unsigned char)128);
+        __m128i xw        = _mm_set1_epi16(255); // alpha channel
+
+        for (; i + 7 < count; i += 8) {
+            // load
+            __m128i y_bytes   = _mm_loadl_epi64((__m128i *)(y + i));
+            __m128i cr_bytes  = _mm_loadl_epi64((__m128i *)(pcr + i));
+            __m128i cb_bytes  = _mm_loadl_epi64((__m128i *)(pcb + i));
+            __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128
+            __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128
+
+            // unpack to short (and left-shift cr, cb by 8)
+            __m128i yw  = _mm_unpacklo_epi8(y_bias, y_bytes);
+            __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased);
+            __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased);
+
+            // color transform
+            __m128i yws = _mm_srli_epi16(yw, 4);
+            __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw);
+            __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw);
+            __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1);
+            __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1);
+            __m128i rws = _mm_add_epi16(cr0, yws);
+            __m128i gwt = _mm_add_epi16(cb0, yws);
+            __m128i bws = _mm_add_epi16(yws, cb1);
+            __m128i gws = _mm_add_epi16(gwt, cr1);
+
+            // descale
+            __m128i rw = _mm_srai_epi16(rws, 4);
+            __m128i bw = _mm_srai_epi16(bws, 4);
+            __m128i gw = _mm_srai_epi16(gws, 4);
+
+            // back to byte, set up for transpose
+            __m128i brb = _mm_packus_epi16(rw, bw);
+            __m128i gxb = _mm_packus_epi16(gw, xw);
+
+            // transpose to interleave channels
+            __m128i t0 = _mm_unpacklo_epi8(brb, gxb);
+            __m128i t1 = _mm_unpackhi_epi8(brb, gxb);
+            __m128i o0 = _mm_unpacklo_epi16(t0, t1);
+            __m128i o1 = _mm_unpackhi_epi16(t0, t1);
+
+            // store
+            _mm_storeu_si128((__m128i *)(out + 0), o0);
+            _mm_storeu_si128((__m128i *)(out + 16), o1);
+            out += 32;
+        }
+    }
 #endif
 
 #ifdef STBI_NEON
-   // in this version, step=3 support would be easy to add. but is there demand?
-   if (step == 4) {
-         // this is a fairly straightforward implementation and not super-optimized.
-         uint8x8_t signflip = vdup_n_u8(0x80);
-         int16x8_t cr_const0 = vdupq_n_s16(   (short) ( 1.40200f*4096.0f+0.5f));
-         int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f));
-         int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f));
-         int16x8_t cb_const1 = vdupq_n_s16(   (short) ( 1.77200f*4096.0f+0.5f));
-
-         for (; i+7 < count; i += 8) {
-                // load
-                uint8x8_t y_bytes      = vld1_u8(y + i);
-                uint8x8_t cr_bytes = vld1_u8(pcr + i);
-                uint8x8_t cb_bytes = vld1_u8(pcb + i);
-                int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip));
-                int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip));
-
-                // expand to s16
-                int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4));
-                int16x8_t crw = vshll_n_s8(cr_biased, 7);
-                int16x8_t cbw = vshll_n_s8(cb_biased, 7);
-
-                // color transform
-                int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0);
-                int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0);
-                int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1);
-                int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1);
-                int16x8_t rws = vaddq_s16(yws, cr0);
-                int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1);
-                int16x8_t bws = vaddq_s16(yws, cb1);
-
-                // undo scaling, round, convert to byte
-                uint8x8x4_t o;
-                o.val[0] = vqrshrun_n_s16(rws, 4);
-                o.val[1] = vqrshrun_n_s16(gws, 4);
-                o.val[2] = vqrshrun_n_s16(bws, 4);
-                o.val[3] = vdup_n_u8(255);
-
-                // store, interleaving r/g/b/a
-                vst4_u8(out, o);
-                out += 8*4;
-         }
-   }
+    // in this version, step=3 support would be easy to add. but is there demand?
+    if (step == 4) {
+        // this is a fairly straightforward implementation and not super-optimized.
+        uint8x8_t signflip  = vdup_n_u8(0x80);
+        int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f));
+        int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f));
+        int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f));
+        int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f));
+
+        for (; i + 7 < count; i += 8) {
+            // load
+            uint8x8_t y_bytes   = vld1_u8(y + i);
+            uint8x8_t cr_bytes  = vld1_u8(pcr + i);
+            uint8x8_t cb_bytes  = vld1_u8(pcb + i);
+            int8x8_t  cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip));
+            int8x8_t  cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip));
+
+            // expand to s16
+            int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4));
+            int16x8_t crw = vshll_n_s8(cr_biased, 7);
+            int16x8_t cbw = vshll_n_s8(cb_biased, 7);
+
+            // color transform
+            int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0);
+            int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0);
+            int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1);
+            int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1);
+            int16x8_t rws = vaddq_s16(yws, cr0);
+            int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1);
+            int16x8_t bws = vaddq_s16(yws, cb1);
+
+            // undo scaling, round, convert to byte
+            uint8x8x4_t o;
+            o.val[0] = vqrshrun_n_s16(rws, 4);
+            o.val[1] = vqrshrun_n_s16(gws, 4);
+            o.val[2] = vqrshrun_n_s16(bws, 4);
+            o.val[3] = vdup_n_u8(255);
+
+            // store, interleaving r/g/b/a
+            vst4_u8(out, o);
+            out += 8 * 4;
+        }
+    }
 #endif
 
-   for (; i < count; ++i) {
-         int y_fixed = (y[i] << 20) + (1<<19); // rounding
-         int r,g,b;
-         int cr = pcr[i] - 128;
-         int cb = pcb[i] - 128;
-         r = y_fixed + cr* stbi__float2fixed(1.40200f);
-         g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
-         b = y_fixed                                                                   +       cb* stbi__float2fixed(1.77200f);
-         r >>= 20;
-         g >>= 20;
-         b >>= 20;
-         if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
-         if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
-         if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
-         out[0] = (stbi_uc)r;
-         out[1] = (stbi_uc)g;
-         out[2] = (stbi_uc)b;
-         out[3] = 255;
-         out += step;
-   }
+    for (; i < count; ++i) {
+        int y_fixed = (y[i] << 20) + (1 << 19); // rounding
+        int r, g, b;
+        int cr = pcr[i] - 128;
+        int cb = pcb[i] - 128;
+        r      = y_fixed + cr * stbi__float2fixed(1.40200f);
+        g      = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000);
+        b      = y_fixed + cb * stbi__float2fixed(1.77200f);
+        r >>= 20;
+        g >>= 20;
+        b >>= 20;
+        if ((unsigned)r > 255) {
+            if (r < 0)
+                r = 0;
+            else
+                r = 255;
+        }
+        if ((unsigned)g > 255) {
+            if (g < 0)
+                g = 0;
+            else
+                g = 255;
+        }
+        if ((unsigned)b > 255) {
+            if (b < 0)
+                b = 0;
+            else
+                b = 255;
+        }
+        out[0] = (stbi_uc)r;
+        out[1] = (stbi_uc)g;
+        out[2] = (stbi_uc)b;
+        out[3] = 255;
+        out += step;
+    }
 }
 #endif
 
 // set up the kernels
-static void stbi__setup_jpeg(stbi__jpeg *j)
-{
-   j->idct_block_kernel = stbi__idct_block;
-   j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row;
-   j->resample_row_hv_2_kernel = stbi__resample_row_hv_2;
+static void stbi__setup_jpeg(stbi__jpeg *j) {
+    j->idct_block_kernel        = stbi__idct_block;
+    j->YCbCr_to_RGB_kernel      = stbi__YCbCr_to_RGB_row;
+    j->resample_row_hv_2_kernel = stbi__resample_row_hv_2;
 
 #ifdef STBI_SSE2
-   if (stbi__sse2_available()) {
-         j->idct_block_kernel = stbi__idct_simd;
-         j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
-         j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
-   }
+    if (stbi__sse2_available()) {
+        j->idct_block_kernel        = stbi__idct_simd;
+        j->YCbCr_to_RGB_kernel      = stbi__YCbCr_to_RGB_simd;
+        j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
+    }
 #endif
 
 #ifdef STBI_NEON
-   j->idct_block_kernel = stbi__idct_simd;
-   j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
-   j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
+    j->idct_block_kernel        = stbi__idct_simd;
+    j->YCbCr_to_RGB_kernel      = stbi__YCbCr_to_RGB_simd;
+    j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
 #endif
 }
 
 // clean up the temporary component buffers
-static void stbi__cleanup_jpeg(stbi__jpeg *j)
-{
-   stbi__free_jpeg_components(j, j->s->img_n, 0);
-}
-
-typedef struct
-{
-   resample_row_func resample;
-   stbi_uc *line0,*line1;
-   int hs,vs;  // expansion factor in each axis
-   int w_lores; // horizontal pixels pre-expansion
-   int ystep;  // how far through vertical expansion we are
-   int ypos;   // which pre-expansion row we're on
+static void stbi__cleanup_jpeg(stbi__jpeg *j) { stbi__free_jpeg_components(j, j->s->img_n, 0); }
+
+typedef struct {
+    resample_row_func resample;
+    stbi_uc          *line0, *line1;
+    int               hs, vs;  // expansion factor in each axis
+    int               w_lores; // horizontal pixels pre-expansion
+    int               ystep;   // how far through vertical expansion we are
+    int               ypos;    // which pre-expansion row we're on
 } stbi__resample;
 
 // fast 0..255 * 0..255 => 0..255 rounded multiplication
-static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y)
-{
-   unsigned int t = x*y + 128;
-   return (stbi_uc) ((t + (t >>8)) >> 8);
-}
-
-static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
-{
-   int n, decode_n, is_rgb;
-   z->s->img_n = 0; // make stbi__cleanup_jpeg safe
-
-   // validate req_comp
-   if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
-
-   // load a jpeg image from whichever source, but leave in YCbCr format
-   if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
-
-   // determine actual number of components to generate
-   n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
-
-   is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
-
-   if (z->s->img_n == 3 && n < 3 && !is_rgb)
-         decode_n = 1;
-   else
-         decode_n = z->s->img_n;
-
-   // resample and color-convert
-   {
-         int k;
-         unsigned int i,j;
-         stbi_uc *output;
-         stbi_uc *coutput[4];
-
-         stbi__resample res_comp[4];
-
-         for (k=0; k < decode_n; ++k) {
-                stbi__resample *r = &res_comp[k];
-
-                // allocate line buffer big enough for upsampling off the edges
-                // with upsample factor of 4
-                z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3);
-                if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
-
-                r->hs          = z->img_h_max / z->img_comp[k].h;
-                r->vs          = z->img_v_max / z->img_comp[k].v;
-                r->ystep       = r->vs >> 1;
-                r->w_lores = (z->s->img_x + r->hs-1) / r->hs;
-                r->ypos        = 0;
-                r->line0       = r->line1 = z->img_comp[k].data;
-
-                if              (r->hs == 1 && r->vs == 1) r->resample = resample_row_1;
-                else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2;
-                else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2;
-                else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel;
-                else                                                           r->resample = stbi__resample_row_generic;
-         }
-
-         // can't error after this so, this is safe
-         output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1);
-         if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
-
-         // now go ahead and resample
-         for (j=0; j < z->s->img_y; ++j) {
-                stbi_uc *out = output + n * z->s->img_x * j;
-                for (k=0; k < decode_n; ++k) {
-                       stbi__resample *r = &res_comp[k];
-                       int y_bot = r->ystep >= (r->vs >> 1);
-                       coutput[k] = r->resample(z->img_comp[k].linebuf,
-                                                                        y_bot ? r->line1 : r->line0,
-                                                                        y_bot ? r->line0 : r->line1,
-                                                                        r->w_lores, r->hs);
-                       if (++r->ystep >= r->vs) {
-                          r->ystep = 0;
-                          r->line0 = r->line1;
-                          if (++r->ypos < z->img_comp[k].y)
-                                 r->line1 += z->img_comp[k].w2;
-                       }
-                }
-                if (n >= 3) {
-                       stbi_uc *y = coutput[0];
-                       if (z->s->img_n == 3) {
-                          if (is_rgb) {
-                                 for (i=0; i < z->s->img_x; ++i) {
-                                        out[0] = y[i];
-                                        out[1] = coutput[1][i];
-                                        out[2] = coutput[2][i];
-                                        out[3] = 255;
-                                        out += n;
-                                 }
-                          } else {
-                                 z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
-                          }
-                       } else if (z->s->img_n == 4) {
-                          if (z->app14_color_transform == 0) { // CMYK
-                                 for (i=0; i < z->s->img_x; ++i) {
-                                        stbi_uc m = coutput[3][i];
-                                        out[0] = stbi__blinn_8x8(coutput[0][i], m);
-                                        out[1] = stbi__blinn_8x8(coutput[1][i], m);
-                                        out[2] = stbi__blinn_8x8(coutput[2][i], m);
-                                        out[3] = 255;
-                                        out += n;
-                                 }
-                          } else if (z->app14_color_transform == 2) { // YCCK
-                                 z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
-                                 for (i=0; i < z->s->img_x; ++i) {
-                                        stbi_uc m = coutput[3][i];
-                                        out[0] = stbi__blinn_8x8(255 - out[0], m);
-                                        out[1] = stbi__blinn_8x8(255 - out[1], m);
-                                        out[2] = stbi__blinn_8x8(255 - out[2], m);
-                                        out += n;
-                                 }
-                          } else { // YCbCr + alpha?  Ignore the fourth channel for now
-                                 z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
-                          }
-                       } else
-                          for (i=0; i < z->s->img_x; ++i) {
-                                 out[0] = out[1] = out[2] = y[i];
-                                 out[3] = 255; // not used if n==3
-                                 out += n;
-                          }
-                } else {
-                       if (is_rgb) {
-                          if (n == 1)
-                                 for (i=0; i < z->s->img_x; ++i)
-                                        *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
-                          else {
-                                 for (i=0; i < z->s->img_x; ++i, out += 2) {
-                                        out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
-                                        out[1] = 255;
-                                 }
-                          }
-                       } else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
-                          for (i=0; i < z->s->img_x; ++i) {
-                                 stbi_uc m = coutput[3][i];
-                                 stbi_uc r = stbi__blinn_8x8(coutput[0][i], m);
-                                 stbi_uc g = stbi__blinn_8x8(coutput[1][i], m);
-                                 stbi_uc b = stbi__blinn_8x8(coutput[2][i], m);
-                                 out[0] = stbi__compute_y(r, g, b);
-                                 out[1] = 255;
-                                 out += n;
-                          }
-                       } else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
-                          for (i=0; i < z->s->img_x; ++i) {
-                                 out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
-                                 out[1] = 255;
-                                 out += n;
-                          }
-                       } else {
-                          stbi_uc *y = coutput[0];
-                          if (n == 1)
-                                 for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
-                          else
-                                 for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
-                       }
-                }
-         }
-         stbi__cleanup_jpeg(z);
-         *out_x = z->s->img_x;
-         *out_y = z->s->img_y;
-         if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
-         return output;
-   }
-}
-
-static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   unsigned char* result;
-   stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
-   STBI_NOTUSED(ri);
-   j->s = s;
-   stbi__setup_jpeg(j);
-   result = load_jpeg_image(j, x,y,comp,req_comp);
-   STBI_FREE(j);
-   return result;
-}
-
-static int stbi__jpeg_test(stbi__context *s)
-{
-   int r;
-   stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
-   j->s = s;
-   stbi__setup_jpeg(j);
-   r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
-   stbi__rewind(s);
-   STBI_FREE(j);
-   return r;
-}
-
-static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
-{
-   if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) {
-         stbi__rewind( j->s );
-         return 0;
-   }
-   if (x) *x = j->s->img_x;
-   if (y) *y = j->s->img_y;
-   if (comp) *comp = j->s->img_n >= 3 ? 3 : 1;
-   return 1;
-}
-
-static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   int result;
-   stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
-   j->s = s;
-   result = stbi__jpeg_info_raw(j, x, y, comp);
-   STBI_FREE(j);
-   return result;
+static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) {
+    unsigned int t = x * y + 128;
+    return (stbi_uc)((t + (t >> 8)) >> 8);
+}
+
+static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) {
+    int n, decode_n, is_rgb;
+    z->s->img_n = 0; // make stbi__cleanup_jpeg safe
+
+    // validate req_comp
+    if (req_comp < 0 || req_comp > 4)
+        return stbi__errpuc("bad req_comp", "Internal error");
+
+    // load a jpeg image from whichever source, but leave in YCbCr format
+    if (!stbi__decode_jpeg_image(z)) {
+        stbi__cleanup_jpeg(z);
+        return NULL;
+    }
+
+    // determine actual number of components to generate
+    n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
+
+    is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
+
+    if (z->s->img_n == 3 && n < 3 && !is_rgb)
+        decode_n = 1;
+    else
+        decode_n = z->s->img_n;
+
+    // resample and color-convert
+    {
+        int          k;
+        unsigned int i, j;
+        stbi_uc     *output;
+        stbi_uc     *coutput[4];
+
+        stbi__resample res_comp[4];
+
+        for (k = 0; k < decode_n; ++k) {
+            stbi__resample *r = &res_comp[k];
+
+            // allocate line buffer big enough for upsampling off the edges
+            // with upsample factor of 4
+            z->img_comp[k].linebuf = (stbi_uc *)stbi__malloc(z->s->img_x + 3);
+            if (!z->img_comp[k].linebuf) {
+                stbi__cleanup_jpeg(z);
+                return stbi__errpuc("outofmem", "Out of memory");
+            }
+
+            r->hs      = z->img_h_max / z->img_comp[k].h;
+            r->vs      = z->img_v_max / z->img_comp[k].v;
+            r->ystep   = r->vs >> 1;
+            r->w_lores = (z->s->img_x + r->hs - 1) / r->hs;
+            r->ypos    = 0;
+            r->line0 = r->line1 = z->img_comp[k].data;
+
+            if (r->hs == 1 && r->vs == 1)
+                r->resample = resample_row_1;
+            else if (r->hs == 1 && r->vs == 2)
+                r->resample = stbi__resample_row_v_2;
+            else if (r->hs == 2 && r->vs == 1)
+                r->resample = stbi__resample_row_h_2;
+            else if (r->hs == 2 && r->vs == 2)
+                r->resample = z->resample_row_hv_2_kernel;
+            else
+                r->resample = stbi__resample_row_generic;
+        }
+
+        // can't error after this so, this is safe
+        output = (stbi_uc *)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1);
+        if (!output) {
+            stbi__cleanup_jpeg(z);
+            return stbi__errpuc("outofmem", "Out of memory");
+        }
+
+        // now go ahead and resample
+        for (j = 0; j < z->s->img_y; ++j) {
+            stbi_uc *out = output + n * z->s->img_x * j;
+            for (k = 0; k < decode_n; ++k) {
+                stbi__resample *r     = &res_comp[k];
+                int             y_bot = r->ystep >= (r->vs >> 1);
+                coutput[k]            = r->resample(z->img_comp[k].linebuf, y_bot ? r->line1 : r->line0,
+                                         y_bot ? r->line0 : r->line1, r->w_lores, r->hs);
+                if (++r->ystep >= r->vs) {
+                    r->ystep = 0;
+                    r->line0 = r->line1;
+                    if (++r->ypos < z->img_comp[k].y)
+                        r->line1 += z->img_comp[k].w2;
+                }
+            }
+            if (n >= 3) {
+                stbi_uc *y = coutput[0];
+                if (z->s->img_n == 3) {
+                    if (is_rgb) {
+                        for (i = 0; i < z->s->img_x; ++i) {
+                            out[0] = y[i];
+                            out[1] = coutput[1][i];
+                            out[2] = coutput[2][i];
+                            out[3] = 255;
+                            out += n;
+                        }
+                    } else {
+                        z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+                    }
+                } else if (z->s->img_n == 4) {
+                    if (z->app14_color_transform == 0) { // CMYK
+                        for (i = 0; i < z->s->img_x; ++i) {
+                            stbi_uc m = coutput[3][i];
+                            out[0]    = stbi__blinn_8x8(coutput[0][i], m);
+                            out[1]    = stbi__blinn_8x8(coutput[1][i], m);
+                            out[2]    = stbi__blinn_8x8(coutput[2][i], m);
+                            out[3]    = 255;
+                            out += n;
+                        }
+                    } else if (z->app14_color_transform == 2) { // YCCK
+                        z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+                        for (i = 0; i < z->s->img_x; ++i) {
+                            stbi_uc m = coutput[3][i];
+                            out[0]    = stbi__blinn_8x8(255 - out[0], m);
+                            out[1]    = stbi__blinn_8x8(255 - out[1], m);
+                            out[2]    = stbi__blinn_8x8(255 - out[2], m);
+                            out += n;
+                        }
+                    } else { // YCbCr + alpha?  Ignore the fourth channel for now
+                        z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+                    }
+                } else
+                    for (i = 0; i < z->s->img_x; ++i) {
+                        out[0] = out[1] = out[2] = y[i];
+                        out[3]                   = 255; // not used if n==3
+                        out += n;
+                    }
+            } else {
+                if (is_rgb) {
+                    if (n == 1)
+                        for (i = 0; i < z->s->img_x; ++i)
+                            *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
+                    else {
+                        for (i = 0; i < z->s->img_x; ++i, out += 2) {
+                            out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
+                            out[1] = 255;
+                        }
+                    }
+                } else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
+                    for (i = 0; i < z->s->img_x; ++i) {
+                        stbi_uc m = coutput[3][i];
+                        stbi_uc r = stbi__blinn_8x8(coutput[0][i], m);
+                        stbi_uc g = stbi__blinn_8x8(coutput[1][i], m);
+                        stbi_uc b = stbi__blinn_8x8(coutput[2][i], m);
+                        out[0]    = stbi__compute_y(r, g, b);
+                        out[1]    = 255;
+                        out += n;
+                    }
+                } else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
+                    for (i = 0; i < z->s->img_x; ++i) {
+                        out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
+                        out[1] = 255;
+                        out += n;
+                    }
+                } else {
+                    stbi_uc *y = coutput[0];
+                    if (n == 1)
+                        for (i = 0; i < z->s->img_x; ++i)
+                            out[i] = y[i];
+                    else
+                        for (i = 0; i < z->s->img_x; ++i)
+                            *out++ = y[i], *out++ = 255;
+                }
+            }
+        }
+        stbi__cleanup_jpeg(z);
+        *out_x = z->s->img_x;
+        *out_y = z->s->img_y;
+        if (comp)
+            *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
+        return output;
+    }
+}
+
+static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) {
+    unsigned char *result;
+    stbi__jpeg    *j = (stbi__jpeg *)stbi__malloc(sizeof(stbi__jpeg));
+    STBI_NOTUSED(ri);
+    j->s = s;
+    stbi__setup_jpeg(j);
+    result = load_jpeg_image(j, x, y, comp, req_comp);
+    STBI_FREE(j);
+    return result;
+}
+
+static int stbi__jpeg_test(stbi__context *s) {
+    int         r;
+    stbi__jpeg *j = (stbi__jpeg *)stbi__malloc(sizeof(stbi__jpeg));
+    j->s          = s;
+    stbi__setup_jpeg(j);
+    r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
+    stbi__rewind(s);
+    STBI_FREE(j);
+    return r;
+}
+
+static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) {
+    if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) {
+        stbi__rewind(j->s);
+        return 0;
+    }
+    if (x)
+        *x = j->s->img_x;
+    if (y)
+        *y = j->s->img_y;
+    if (comp)
+        *comp = j->s->img_n >= 3 ? 3 : 1;
+    return 1;
+}
+
+static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) {
+    int         result;
+    stbi__jpeg *j = (stbi__jpeg *)(stbi__malloc(sizeof(stbi__jpeg)));
+    j->s          = s;
+    result        = stbi__jpeg_info_raw(j, x, y, comp);
+    STBI_FREE(j);
+    return result;
 }
 #endif
 
@@ -3786,83 +3903,80 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
 #ifndef STBI_NO_ZLIB
 
 // fast-way is faster to check than jpeg huffman, but slow way is slower
-#define STBI__ZFAST_BITS  9 // accelerate all cases in default tables
-#define STBI__ZFAST_MASK  ((1 << STBI__ZFAST_BITS) - 1)
+#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables
+#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1)
 
 // zlib-style huffman encoding
 // (jpegs packs from left, zlib from right, so can't share code)
-typedef struct
-{
-   stbi__uint16 fast[1 << STBI__ZFAST_BITS];
-   stbi__uint16 firstcode[16];
-   int maxcode[17];
-   stbi__uint16 firstsymbol[16];
-   stbi_uc     size[288];
-   stbi__uint16 value[288];
+typedef struct {
+    stbi__uint16 fast[1 << STBI__ZFAST_BITS];
+    stbi__uint16 firstcode[16];
+    int          maxcode[17];
+    stbi__uint16 firstsymbol[16];
+    stbi_uc      size[288];
+    stbi__uint16 value[288];
 } stbi__zhuffman;
 
-stbi_inline static int stbi__bitreverse16(int n)
-{
-  n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1);
-  n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2);
-  n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4);
-  n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8);
-  return n;
-}
-
-stbi_inline static int stbi__bit_reverse(int v, int bits)
-{
-   STBI_ASSERT(bits <= 16);
-   // to bit reverse n bits, reverse 16 and shift
-   // e.g. 11 bits, bit reverse and shift away 5
-   return stbi__bitreverse16(v) >> (16-bits);
-}
-
-static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num)
-{
-   int i,k=0;
-   int code, next_code[16], sizes[17];
-
-   // DEFLATE spec for generating codes
-   memset(sizes, 0, sizeof(sizes));
-   memset(z->fast, 0, sizeof(z->fast));
-   for (i=0; i < num; ++i)
-         ++sizes[sizelist[i]];
-   sizes[0] = 0;
-   for (i=1; i < 16; ++i)
-         if (sizes[i] > (1 << i))
-                return stbi__err("bad sizes", "Corrupt PNG");
-   code = 0;
-   for (i=1; i < 16; ++i) {
-         next_code[i] = code;
-         z->firstcode[i] = (stbi__uint16) code;
-         z->firstsymbol[i] = (stbi__uint16) k;
-         code = (code + sizes[i]);
-         if (sizes[i])
-                if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG");
-         z->maxcode[i] = code << (16-i); // preshift for inner loop
-         code <<= 1;
-         k += sizes[i];
-   }
-   z->maxcode[16] = 0x10000; // sentinel
-   for (i=0; i < num; ++i) {
-         int s = sizelist[i];
-         if (s) {
-                int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s];
-                stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i);
-                z->size [c] = (stbi_uc         ) s;
-                z->value[c] = (stbi__uint16) i;
-                if (s <= STBI__ZFAST_BITS) {
-                       int j = stbi__bit_reverse(next_code[s],s);
-                       while (j < (1 << STBI__ZFAST_BITS)) {
-                          z->fast[j] = fastv;
-                          j += (1 << s);
-                       }
-                }
-                ++next_code[s];
-         }
-   }
-   return 1;
+stbi_inline static int stbi__bitreverse16(int n) {
+    n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1);
+    n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2);
+    n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4);
+    n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8);
+    return n;
+}
+
+stbi_inline static int stbi__bit_reverse(int v, int bits) {
+    STBI_ASSERT(bits <= 16);
+    // to bit reverse n bits, reverse 16 and shift
+    // e.g. 11 bits, bit reverse and shift away 5
+    return stbi__bitreverse16(v) >> (16 - bits);
+}
+
+static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) {
+    int i, k = 0;
+    int code, next_code[16], sizes[17];
+
+    // DEFLATE spec for generating codes
+    memset(sizes, 0, sizeof(sizes));
+    memset(z->fast, 0, sizeof(z->fast));
+    for (i = 0; i < num; ++i)
+        ++sizes[sizelist[i]];
+    sizes[0] = 0;
+    for (i = 1; i < 16; ++i)
+        if (sizes[i] > (1 << i))
+            return stbi__err("bad sizes", "Corrupt PNG");
+    code = 0;
+    for (i = 1; i < 16; ++i) {
+        next_code[i]      = code;
+        z->firstcode[i]   = (stbi__uint16)code;
+        z->firstsymbol[i] = (stbi__uint16)k;
+        code              = (code + sizes[i]);
+        if (sizes[i])
+            if (code - 1 >= (1 << i))
+                return stbi__err("bad codelengths", "Corrupt PNG");
+        z->maxcode[i] = code << (16 - i); // preshift for inner loop
+        code <<= 1;
+        k += sizes[i];
+    }
+    z->maxcode[16] = 0x10000; // sentinel
+    for (i = 0; i < num; ++i) {
+        int s = sizelist[i];
+        if (s) {
+            int          c     = next_code[s] - z->firstcode[s] + z->firstsymbol[s];
+            stbi__uint16 fastv = (stbi__uint16)((s << 9) | i);
+            z->size[c]         = (stbi_uc)s;
+            z->value[c]        = (stbi__uint16)i;
+            if (s <= STBI__ZFAST_BITS) {
+                int j = stbi__bit_reverse(next_code[s], s);
+                while (j < (1 << STBI__ZFAST_BITS)) {
+                    z->fast[j] = fastv;
+                    j += (1 << s);
+                }
+            }
+            ++next_code[s];
+        }
+    }
+    return 1;
 }
 
 // zlib-from-memory implementation for PNG reading
@@ -3871,259 +3985,277 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int
 //       we require PNG read all the IDATs and combine them into a single
 //       memory buffer
 
-typedef struct
-{
-   stbi_uc *zbuffer, *zbuffer_end;
-   int num_bits;
-   stbi__uint32 code_buffer;
+typedef struct {
+    stbi_uc     *zbuffer, *zbuffer_end;
+    int          num_bits;
+    stbi__uint32 code_buffer;
 
-   char *zout;
-   char *zout_start;
-   char *zout_end;
-   int  z_expandable;
+    char *zout;
+    char *zout_start;
+    char *zout_end;
+    int   z_expandable;
 
-   stbi__zhuffman z_length, z_distance;
+    stbi__zhuffman z_length, z_distance;
 } stbi__zbuf;
 
-stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
-{
-   if (z->zbuffer >= z->zbuffer_end) return 0;
-   return *z->zbuffer++;
-}
-
-static void stbi__fill_bits(stbi__zbuf *z)
-{
-   do {
-         STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
-         z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
-         z->num_bits += 8;
-   } while (z->num_bits <= 24);
-}
-
-stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n)
-{
-   unsigned int k;
-   if (z->num_bits < n) stbi__fill_bits(z);
-   k = z->code_buffer & ((1 << n) - 1);
-   z->code_buffer >>= n;
-   z->num_bits -= n;
-   return k;
-}
-
-static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
-{
-   int b,s,k;
-   // not resolved by fast table, so compute it the slow way
-   // use jpeg approach, which requires MSbits at top
-   k = stbi__bit_reverse(a->code_buffer, 16);
-   for (s=STBI__ZFAST_BITS+1; ; ++s)
-         if (k < z->maxcode[s])
-                break;
-   if (s == 16) return -1; // invalid code!
-   // code size is s, so:
-   b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
-   STBI_ASSERT(z->size[b] == s);
-   a->code_buffer >>= s;
-   a->num_bits -= s;
-   return z->value[b];
-}
-
-stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
-{
-   int b,s;
-   if (a->num_bits < 16) stbi__fill_bits(a);
-   b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
-   if (b) {
-         s = b >> 9;
-         a->code_buffer >>= s;
-         a->num_bits -= s;
-         return b & 511;
-   }
-   return stbi__zhuffman_decode_slowpath(a, z);
-}
-
-static int stbi__zexpand(stbi__zbuf *z, char *zout, int n)     // need to make room for n bytes
-{
-   char *q;
-   int cur, limit, old_limit;
-   z->zout = zout;
-   if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
-   cur  = (int) (z->zout         - z->zout_start);
-   limit = old_limit = (int) (z->zout_end - z->zout_start);
-   while (cur + n > limit)
-         limit *= 2;
-   q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
-   STBI_NOTUSED(old_limit);
-   if (q == NULL) return stbi__err("outofmem", "Out of memory");
-   z->zout_start = q;
-   z->zout              = q + cur;
-   z->zout_end  = q + limit;
-   return 1;
-}
-
-static const int stbi__zlength_base[31] = {
-   3,4,5,6,7,8,9,10,11,13,
-   15,17,19,23,27,31,35,43,51,59,
-   67,83,99,115,131,163,195,227,258,0,0 };
-
-static const int stbi__zlength_extra[31]=
-{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
-
-static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
-257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
-
-static const int stbi__zdist_extra[32] =
-{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-static int stbi__parse_huffman_block(stbi__zbuf *a)
-{
-   char *zout = a->zout;
-   for(;;) {
-         int z = stbi__zhuffman_decode(a, &a->z_length);
-         if (z < 256) {
-                if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes
-                if (zout >= a->zout_end) {
-                       if (!stbi__zexpand(a, zout, 1)) return 0;
-                       zout = a->zout;
-                }
-                *zout++ = (char) z;
-         } else {
-                stbi_uc *p;
-                int len,dist;
-                if (z == 256) {
-                       a->zout = zout;
-                       return 1;
-                }
-                z -= 257;
-                len = stbi__zlength_base[z];
-                if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]);
-                z = stbi__zhuffman_decode(a, &a->z_distance);
-                if (z < 0) return stbi__err("bad huffman code","Corrupt PNG");
-                dist = stbi__zdist_base[z];
-                if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
-                if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
-                if (zout + len > a->zout_end) {
-                       if (!stbi__zexpand(a, zout, len)) return 0;
-                       zout = a->zout;
-                }
-                p = (stbi_uc *) (zout - dist);
-                if (dist == 1) { // run of one byte; common in images.
-                       stbi_uc v = *p;
-                       if (len) { do *zout++ = v; while (--len); }
-                } else {
-                       if (len) { do *zout++ = *p++; while (--len); }
-                }
-         }
-   }
-}
-
-static int stbi__compute_huffman_codes(stbi__zbuf *a)
-{
-   static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
-   stbi__zhuffman z_codelength;
-   stbi_uc lencodes[286+32+137];//padding for maximum single op
-   stbi_uc codelength_sizes[19];
-   int i,n;
-
-   int hlit     = stbi__zreceive(a,5) + 257;
-   int hdist = stbi__zreceive(a,5) + 1;
-   int hclen = stbi__zreceive(a,4) + 4;
-   int ntot     = hlit + hdist;
-
-   memset(codelength_sizes, 0, sizeof(codelength_sizes));
-   for (i=0; i < hclen; ++i) {
-         int s = stbi__zreceive(a,3);
-         codelength_sizes[length_dezigzag[i]] = (stbi_uc) s;
-   }
-   if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0;
-
-   n = 0;
-   while (n < ntot) {
-         int c = stbi__zhuffman_decode(a, &z_codelength);
-         if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG");
-         if (c < 16)
-                lencodes[n++] = (stbi_uc) c;
-         else {
-                stbi_uc fill = 0;
-                if (c == 16) {
-                       c = stbi__zreceive(a,2)+3;
-                       if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
-                       fill = lencodes[n-1];
-                } else if (c == 17)
-                       c = stbi__zreceive(a,3)+3;
-                else {
-                       STBI_ASSERT(c == 18);
-                       c = stbi__zreceive(a,7)+11;
-                }
-                if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
-                memset(lencodes+n, fill, c);
-                n += c;
-         }
-   }
-   if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG");
-   if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0;
-   if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0;
-   return 1;
-}
-
-static int stbi__parse_uncompressed_block(stbi__zbuf *a)
-{
-   stbi_uc header[4];
-   int len,nlen,k;
-   if (a->num_bits & 7)
-         stbi__zreceive(a, a->num_bits & 7); // discard
-   // drain the bit-packed data into header
-   k = 0;
-   while (a->num_bits > 0) {
-         header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check
-         a->code_buffer >>= 8;
-         a->num_bits -= 8;
-   }
-   STBI_ASSERT(a->num_bits == 0);
-   // now fill header the normal way
-   while (k < 4)
-         header[k++] = stbi__zget8(a);
-   len = header[1] * 256 + header[0];
-   nlen = header[3] * 256 + header[2];
-   if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG");
-   if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG");
-   if (a->zout + len > a->zout_end)
-         if (!stbi__zexpand(a, a->zout, len)) return 0;
-   memcpy(a->zout, a->zbuffer, len);
-   a->zbuffer += len;
-   a->zout += len;
-   return 1;
-}
-
-static int stbi__parse_zlib_header(stbi__zbuf *a)
-{
-   int cmf      = stbi__zget8(a);
-   int cm       = cmf & 15;
-   /* int cinfo = cmf >> 4; */
-   int flg      = stbi__zget8(a);
-   if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
-   if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
-   if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
-   // window = 1 << (8 + cinfo)... but who cares, we fully buffer output
-   return 1;
-}
-
-static const stbi_uc stbi__zdefault_length[288] =
-{
-   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8
-};
-static const stbi_uc stbi__zdefault_distance[32] =
-{
-   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
-};
+stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) {
+    if (z->zbuffer >= z->zbuffer_end)
+        return 0;
+    return *z->zbuffer++;
+}
+
+static void stbi__fill_bits(stbi__zbuf *z) {
+    do {
+        STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
+        z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits;
+        z->num_bits += 8;
+    } while (z->num_bits <= 24);
+}
+
+stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) {
+    unsigned int k;
+    if (z->num_bits < n)
+        stbi__fill_bits(z);
+    k = z->code_buffer & ((1 << n) - 1);
+    z->code_buffer >>= n;
+    z->num_bits -= n;
+    return k;
+}
+
+static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) {
+    int b, s, k;
+    // not resolved by fast table, so compute it the slow way
+    // use jpeg approach, which requires MSbits at top
+    k = stbi__bit_reverse(a->code_buffer, 16);
+    for (s = STBI__ZFAST_BITS + 1;; ++s)
+        if (k < z->maxcode[s])
+            break;
+    if (s == 16)
+        return -1; // invalid code!
+    // code size is s, so:
+    b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s];
+    STBI_ASSERT(z->size[b] == s);
+    a->code_buffer >>= s;
+    a->num_bits -= s;
+    return z->value[b];
+}
+
+stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) {
+    int b, s;
+    if (a->num_bits < 16)
+        stbi__fill_bits(a);
+    b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
+    if (b) {
+        s = b >> 9;
+        a->code_buffer >>= s;
+        a->num_bits -= s;
+        return b & 511;
+    }
+    return stbi__zhuffman_decode_slowpath(a, z);
+}
+
+static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
+{
+    char *q;
+    int   cur, limit, old_limit;
+    z->zout = zout;
+    if (!z->z_expandable)
+        return stbi__err("output buffer limit", "Corrupt PNG");
+    cur   = (int)(z->zout - z->zout_start);
+    limit = old_limit = (int)(z->zout_end - z->zout_start);
+    while (cur + n > limit)
+        limit *= 2;
+    q = (char *)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
+    STBI_NOTUSED(old_limit);
+    if (q == NULL)
+        return stbi__err("outofmem", "Out of memory");
+    z->zout_start = q;
+    z->zout       = q + cur;
+    z->zout_end   = q + limit;
+    return 1;
+}
+
+static const int stbi__zlength_base[31] = {3,  4,  5,  6,  7,  8,  9,  10,  11,  13,  15,  17,  19,  23, 27, 31,
+                                           35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0,  0};
+
+static const int stbi__zlength_extra[31] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+                                            3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0};
+
+static const int stbi__zdist_base[32] = {1,    2,    3,    4,    5,    7,     9,     13,    17,  25,   33,
+                                         49,   65,   97,   129,  193,  257,   385,   513,   769, 1025, 1537,
+                                         2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0,   0};
+
+static const int stbi__zdist_extra[32] = {0, 0, 0, 0, 1, 1, 2, 2,  3,  3,  4,  4,  5,  5,  6,
+                                          6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
+
+static int stbi__parse_huffman_block(stbi__zbuf *a) {
+    char *zout = a->zout;
+    for (;;) {
+        int z = stbi__zhuffman_decode(a, &a->z_length);
+        if (z < 256) {
+            if (z < 0)
+                return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes
+            if (zout >= a->zout_end) {
+                if (!stbi__zexpand(a, zout, 1))
+                    return 0;
+                zout = a->zout;
+            }
+            *zout++ = (char)z;
+        } else {
+            stbi_uc *p;
+            int      len, dist;
+            if (z == 256) {
+                a->zout = zout;
+                return 1;
+            }
+            z -= 257;
+            len = stbi__zlength_base[z];
+            if (stbi__zlength_extra[z])
+                len += stbi__zreceive(a, stbi__zlength_extra[z]);
+            z = stbi__zhuffman_decode(a, &a->z_distance);
+            if (z < 0)
+                return stbi__err("bad huffman code", "Corrupt PNG");
+            dist = stbi__zdist_base[z];
+            if (stbi__zdist_extra[z])
+                dist += stbi__zreceive(a, stbi__zdist_extra[z]);
+            if (zout - a->zout_start < dist)
+                return stbi__err("bad dist", "Corrupt PNG");
+            if (zout + len > a->zout_end) {
+                if (!stbi__zexpand(a, zout, len))
+                    return 0;
+                zout = a->zout;
+            }
+            p = (stbi_uc *)(zout - dist);
+            if (dist == 1) { // run of one byte; common in images.
+                stbi_uc v = *p;
+                if (len) {
+                    do
+                        *zout++ = v;
+                    while (--len);
+                }
+            } else {
+                if (len) {
+                    do
+                        *zout++ = *p++;
+                    while (--len);
+                }
+            }
+        }
+    }
+}
+
+static int stbi__compute_huffman_codes(stbi__zbuf *a) {
+    static const stbi_uc length_dezigzag[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+    stbi__zhuffman       z_codelength;
+    stbi_uc              lencodes[286 + 32 + 137]; // padding for maximum single op
+    stbi_uc              codelength_sizes[19];
+    int                  i, n;
+
+    int hlit  = stbi__zreceive(a, 5) + 257;
+    int hdist = stbi__zreceive(a, 5) + 1;
+    int hclen = stbi__zreceive(a, 4) + 4;
+    int ntot  = hlit + hdist;
+
+    memset(codelength_sizes, 0, sizeof(codelength_sizes));
+    for (i = 0; i < hclen; ++i) {
+        int s                                = stbi__zreceive(a, 3);
+        codelength_sizes[length_dezigzag[i]] = (stbi_uc)s;
+    }
+    if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19))
+        return 0;
+
+    n = 0;
+    while (n < ntot) {
+        int c = stbi__zhuffman_decode(a, &z_codelength);
+        if (c < 0 || c >= 19)
+            return stbi__err("bad codelengths", "Corrupt PNG");
+        if (c < 16)
+            lencodes[n++] = (stbi_uc)c;
+        else {
+            stbi_uc fill = 0;
+            if (c == 16) {
+                c = stbi__zreceive(a, 2) + 3;
+                if (n == 0)
+                    return stbi__err("bad codelengths", "Corrupt PNG");
+                fill = lencodes[n - 1];
+            } else if (c == 17)
+                c = stbi__zreceive(a, 3) + 3;
+            else {
+                STBI_ASSERT(c == 18);
+                c = stbi__zreceive(a, 7) + 11;
+            }
+            if (ntot - n < c)
+                return stbi__err("bad codelengths", "Corrupt PNG");
+            memset(lencodes + n, fill, c);
+            n += c;
+        }
+    }
+    if (n != ntot)
+        return stbi__err("bad codelengths", "Corrupt PNG");
+    if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit))
+        return 0;
+    if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist))
+        return 0;
+    return 1;
+}
+
+static int stbi__parse_uncompressed_block(stbi__zbuf *a) {
+    stbi_uc header[4];
+    int     len, nlen, k;
+    if (a->num_bits & 7)
+        stbi__zreceive(a, a->num_bits & 7); // discard
+    // drain the bit-packed data into header
+    k = 0;
+    while (a->num_bits > 0) {
+        header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check
+        a->code_buffer >>= 8;
+        a->num_bits -= 8;
+    }
+    STBI_ASSERT(a->num_bits == 0);
+    // now fill header the normal way
+    while (k < 4)
+        header[k++] = stbi__zget8(a);
+    len  = header[1] * 256 + header[0];
+    nlen = header[3] * 256 + header[2];
+    if (nlen != (len ^ 0xffff))
+        return stbi__err("zlib corrupt", "Corrupt PNG");
+    if (a->zbuffer + len > a->zbuffer_end)
+        return stbi__err("read past buffer", "Corrupt PNG");
+    if (a->zout + len > a->zout_end)
+        if (!stbi__zexpand(a, a->zout, len))
+            return 0;
+    memcpy(a->zout, a->zbuffer, len);
+    a->zbuffer += len;
+    a->zout += len;
+    return 1;
+}
+
+static int stbi__parse_zlib_header(stbi__zbuf *a) {
+    int cmf = stbi__zget8(a);
+    int cm  = cmf & 15;
+    /* int cinfo = cmf >> 4; */
+    int flg = stbi__zget8(a);
+    if ((cmf * 256 + flg) % 31 != 0)
+        return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec
+    if (flg & 32)
+        return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png
+    if (cm != 8)
+        return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png
+    // window = 1 << (8 + cinfo)... but who cares, we fully buffer output
+    return 1;
+}
+
+static const stbi_uc stbi__zdefault_length[288] = {
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8};
+static const stbi_uc stbi__zdefault_distance[32] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+                                                    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
 /*
 Init algorithm:
 {
@@ -4137,117 +4269,122 @@ Init algorithm:
 }
 */
 
-static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
-{
-   int final, type;
-   if (parse_header)
-         if (!stbi__parse_zlib_header(a)) return 0;
-   a->num_bits = 0;
-   a->code_buffer = 0;
-   do {
-         final = stbi__zreceive(a,1);
-         type = stbi__zreceive(a,2);
-         if (type == 0) {
-                if (!stbi__parse_uncompressed_block(a)) return 0;
-         } else if (type == 3) {
-                return 0;
-         } else {
-                if (type == 1) {
-                       // use fixed code lengths
-                       if (!stbi__zbuild_huffman(&a->z_length  , stbi__zdefault_length  , 288)) return 0;
-                       if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance,      32)) return 0;
-                } else {
-                       if (!stbi__compute_huffman_codes(a)) return 0;
-                }
-                if (!stbi__parse_huffman_block(a)) return 0;
-         }
-   } while (!final);
-   return 1;
-}
-
-static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header)
-{
-   a->zout_start = obuf;
-   a->zout              = obuf;
-   a->zout_end  = obuf + olen;
-   a->z_expandable = exp;
-
-   return stbi__parse_zlib(a, parse_header);
-}
-
-STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen)
-{
-   stbi__zbuf a;
-   char *p = (char *) stbi__malloc(initial_size);
-   if (p == NULL) return NULL;
-   a.zbuffer = (stbi_uc *) buffer;
-   a.zbuffer_end = (stbi_uc *) buffer + len;
-   if (stbi__do_zlib(&a, p, initial_size, 1, 1)) {
-         if (outlen) *outlen = (int) (a.zout - a.zout_start);
-         return a.zout_start;
-   } else {
-         STBI_FREE(a.zout_start);
-         return NULL;
-   }
-}
-
-STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen)
-{
-   return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen);
-}
-
-STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header)
-{
-   stbi__zbuf a;
-   char *p = (char *) stbi__malloc(initial_size);
-   if (p == NULL) return NULL;
-   a.zbuffer = (stbi_uc *) buffer;
-   a.zbuffer_end = (stbi_uc *) buffer + len;
-   if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) {
-         if (outlen) *outlen = (int) (a.zout - a.zout_start);
-         return a.zout_start;
-   } else {
-         STBI_FREE(a.zout_start);
-         return NULL;
-   }
-}
-
-STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen)
-{
-   stbi__zbuf a;
-   a.zbuffer = (stbi_uc *) ibuffer;
-   a.zbuffer_end = (stbi_uc *) ibuffer + ilen;
-   if (stbi__do_zlib(&a, obuffer, olen, 0, 1))
-         return (int) (a.zout - a.zout_start);
-   else
-         return -1;
-}
-
-STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen)
-{
-   stbi__zbuf a;
-   char *p = (char *) stbi__malloc(16384);
-   if (p == NULL) return NULL;
-   a.zbuffer = (stbi_uc *) buffer;
-   a.zbuffer_end = (stbi_uc *) buffer+len;
-   if (stbi__do_zlib(&a, p, 16384, 1, 0)) {
-         if (outlen) *outlen = (int) (a.zout - a.zout_start);
-         return a.zout_start;
-   } else {
-         STBI_FREE(a.zout_start);
-         return NULL;
-   }
-}
-
-STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen)
-{
-   stbi__zbuf a;
-   a.zbuffer = (stbi_uc *) ibuffer;
-   a.zbuffer_end = (stbi_uc *) ibuffer + ilen;
-   if (stbi__do_zlib(&a, obuffer, olen, 0, 0))
-         return (int) (a.zout - a.zout_start);
-   else
-         return -1;
+static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) {
+    int final, type;
+    if (parse_header)
+        if (!stbi__parse_zlib_header(a))
+            return 0;
+    a->num_bits    = 0;
+    a->code_buffer = 0;
+    do {
+        final = stbi__zreceive(a, 1);
+        type  = stbi__zreceive(a, 2);
+        if (type == 0) {
+            if (!stbi__parse_uncompressed_block(a))
+                return 0;
+        } else if (type == 3) {
+            return 0;
+        } else {
+            if (type == 1) {
+                // use fixed code lengths
+                if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, 288))
+                    return 0;
+                if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32))
+                    return 0;
+            } else {
+                if (!stbi__compute_huffman_codes(a))
+                    return 0;
+            }
+            if (!stbi__parse_huffman_block(a))
+                return 0;
+        }
+    } while (!final);
+    return 1;
+}
+
+static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) {
+    a->zout_start   = obuf;
+    a->zout         = obuf;
+    a->zout_end     = obuf + olen;
+    a->z_expandable = exp;
+
+    return stbi__parse_zlib(a, parse_header);
+}
+
+STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) {
+    stbi__zbuf a;
+    char      *p = (char *)stbi__malloc(initial_size);
+    if (p == NULL)
+        return NULL;
+    a.zbuffer     = (stbi_uc *)buffer;
+    a.zbuffer_end = (stbi_uc *)buffer + len;
+    if (stbi__do_zlib(&a, p, initial_size, 1, 1)) {
+        if (outlen)
+            *outlen = (int)(a.zout - a.zout_start);
+        return a.zout_start;
+    } else {
+        STBI_FREE(a.zout_start);
+        return NULL;
+    }
+}
+
+STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) {
+    return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen);
+}
+
+STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen,
+                                                           int parse_header) {
+    stbi__zbuf a;
+    char      *p = (char *)stbi__malloc(initial_size);
+    if (p == NULL)
+        return NULL;
+    a.zbuffer     = (stbi_uc *)buffer;
+    a.zbuffer_end = (stbi_uc *)buffer + len;
+    if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) {
+        if (outlen)
+            *outlen = (int)(a.zout - a.zout_start);
+        return a.zout_start;
+    } else {
+        STBI_FREE(a.zout_start);
+        return NULL;
+    }
+}
+
+STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) {
+    stbi__zbuf a;
+    a.zbuffer     = (stbi_uc *)ibuffer;
+    a.zbuffer_end = (stbi_uc *)ibuffer + ilen;
+    if (stbi__do_zlib(&a, obuffer, olen, 0, 1))
+        return (int)(a.zout - a.zout_start);
+    else
+        return -1;
+}
+
+STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) {
+    stbi__zbuf a;
+    char      *p = (char *)stbi__malloc(16384);
+    if (p == NULL)
+        return NULL;
+    a.zbuffer     = (stbi_uc *)buffer;
+    a.zbuffer_end = (stbi_uc *)buffer + len;
+    if (stbi__do_zlib(&a, p, 16384, 1, 0)) {
+        if (outlen)
+            *outlen = (int)(a.zout - a.zout_start);
+        return a.zout_start;
+    } else {
+        STBI_FREE(a.zout_start);
+        return NULL;
+    }
+}
+
+STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) {
+    stbi__zbuf a;
+    a.zbuffer     = (stbi_uc *)ibuffer;
+    a.zbuffer_end = (stbi_uc *)ibuffer + ilen;
+    if (stbi__do_zlib(&a, obuffer, olen, 0, 0))
+        return (int)(a.zout - a.zout_start);
+    else
+        return -1;
 }
 #endif
 
@@ -4262,1057 +4399,1203 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char
 //             - uses stb_zlib, a PD zlib implementation with fast huffman decoding
 
 #ifndef STBI_NO_PNG
-typedef struct
-{
-   stbi__uint32 length;
-   stbi__uint32 type;
+typedef struct {
+    stbi__uint32 length;
+    stbi__uint32 type;
 } stbi__pngchunk;
 
-static stbi__pngchunk stbi__get_chunk_header(stbi__context *s)
-{
-   stbi__pngchunk c;
-   c.length = stbi__get32be(s);
-   c.type      = stbi__get32be(s);
-   return c;
+static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) {
+    stbi__pngchunk c;
+    c.length = stbi__get32be(s);
+    c.type   = stbi__get32be(s);
+    return c;
 }
 
-static int stbi__check_png_header(stbi__context *s)
-{
-   static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 };
-   int i;
-   for (i=0; i < 8; ++i)
-         if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG");
-   return 1;
+static int stbi__check_png_header(stbi__context *s) {
+    static const stbi_uc png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+    int                  i;
+    for (i = 0; i < 8; ++i)
+        if (stbi__get8(s) != png_sig[i])
+            return stbi__err("bad png sig", "Not a PNG");
+    return 1;
 }
 
-typedef struct
-{
-   stbi__context *s;
-   stbi_uc *idata, *expanded, *out;
-   int depth;
+typedef struct {
+    stbi__context *s;
+    stbi_uc       *idata, *expanded, *out;
+    int            depth;
 } stbi__png;
 
-
 enum {
-   STBI__F_none=0,
-   STBI__F_sub=1,
-   STBI__F_up=2,
-   STBI__F_avg=3,
-   STBI__F_paeth=4,
-   // synthetic filters used for first scanline to avoid needing a dummy row of 0s
-   STBI__F_avg_first,
-   STBI__F_paeth_first
+    STBI__F_none  = 0,
+    STBI__F_sub   = 1,
+    STBI__F_up    = 2,
+    STBI__F_avg   = 3,
+    STBI__F_paeth = 4,
+    // synthetic filters used for first scanline to avoid needing a dummy row of 0s
+    STBI__F_avg_first,
+    STBI__F_paeth_first
 };
 
-static stbi_uc first_row_filter[5] =
-{
-   STBI__F_none,
-   STBI__F_sub,
-   STBI__F_none,
-   STBI__F_avg_first,
-   STBI__F_paeth_first
-};
+static stbi_uc first_row_filter[5] = {STBI__F_none, STBI__F_sub, STBI__F_none, STBI__F_avg_first, STBI__F_paeth_first};
 
-static int stbi__paeth(int a, int b, int c)
-{
-   int p = a + b - c;
-   int pa = abs(p-a);
-   int pb = abs(p-b);
-   int pc = abs(p-c);
-   if (pa <= pb && pa <= pc) return a;
-   if (pb <= pc) return b;
-   return c;
+static int stbi__paeth(int a, int b, int c) {
+    int p  = a + b - c;
+    int pa = abs(p - a);
+    int pb = abs(p - b);
+    int pc = abs(p - c);
+    if (pa <= pb && pa <= pc)
+        return a;
+    if (pb <= pc)
+        return b;
+    return c;
 }
 
-static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
+static const stbi_uc stbi__depth_scale_table[9] = {0, 0xff, 0x55, 0, 0x11, 0, 0, 0, 0x01};
 
 // create the png data from post-deflated data
-static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
-{
-   int bytes = (depth == 16? 2 : 1);
-   stbi__context *s = a->s;
-   stbi__uint32 i,j,stride = x*out_n*bytes;
-   stbi__uint32 img_len, img_width_bytes;
-   int k;
-   int img_n = s->img_n; // copy it into a local for later
-
-   int output_bytes = out_n*bytes;
-   int filter_bytes = img_n*bytes;
-   int width = x;
-
-   STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
-   a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
-   if (!a->out) return stbi__err("outofmem", "Out of memory");
-
-   if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
-   img_width_bytes = (((img_n * x * depth) + 7) >> 3);
-   img_len = (img_width_bytes + 1) * y;
-
-   // we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
-   // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros),
-   // so just check for raw_len < img_len always.
-   if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
-
-   for (j=0; j < y; ++j) {
-         stbi_uc *cur = a->out + stride*j;
-         stbi_uc *prior;
-         int filter = *raw++;
-
-         if (filter > 4)
-                return stbi__err("invalid filter","Corrupt PNG");
-
-         if (depth < 8) {
-                STBI_ASSERT(img_width_bytes <= x);
-                cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
-                filter_bytes = 1;
-                width = img_width_bytes;
-         }
-         prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
-
-         // if first row, use special filter that doesn't sample previous row
-         if (j == 0) filter = first_row_filter[filter];
-
-         // handle first byte explicitly
-         for (k=0; k < filter_bytes; ++k) {
-                switch (filter) {
-                       case STBI__F_none               : cur[k] = raw[k]; break;
-                       case STBI__F_sub                : cur[k] = raw[k]; break;
-                       case STBI__F_up                 : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
-                       case STBI__F_avg                : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break;
-                       case STBI__F_paeth              : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break;
-                       case STBI__F_avg_first  : cur[k] = raw[k]; break;
-                       case STBI__F_paeth_first: cur[k] = raw[k]; break;
-                }
-         }
-
-         if (depth == 8) {
-                if (img_n != out_n)
-                       cur[img_n] = 255; // first pixel
-                raw += img_n;
-                cur += out_n;
-                prior += out_n;
-         } else if (depth == 16) {
-                if (img_n != out_n) {
-                       cur[filter_bytes]       = 255; // first pixel top byte
-                       cur[filter_bytes+1] = 255; // first pixel bottom byte
-                }
-                raw += filter_bytes;
-                cur += output_bytes;
-                prior += output_bytes;
-         } else {
-                raw += 1;
-                cur += 1;
-                prior += 1;
-         }
-
-         // this is a little gross, so that we don't switch per-pixel or per-component
-         if (depth < 8 || img_n == out_n) {
-                int nk = (width - 1)*filter_bytes;
-                #define STBI__CASE(f) \
-                        case f:         \
-                               for (k=0; k < nk; ++k)
-                switch (filter) {
-                       // "none" filter turns into a memcpy here; make that explicit.
-                       case STBI__F_none:                 memcpy(cur, raw, nk); break;
-                       STBI__CASE(STBI__F_sub)                  { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
-                       STBI__CASE(STBI__F_up)                   { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
-                       STBI__CASE(STBI__F_avg)                  { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
-                       STBI__CASE(STBI__F_paeth)                { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
-                       STBI__CASE(STBI__F_avg_first)    { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
-                       STBI__CASE(STBI__F_paeth_first)  { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
-                }
-                #undef STBI__CASE
-                raw += nk;
-         } else {
-                STBI_ASSERT(img_n+1 == out_n);
-                #define STBI__CASE(f) \
-                        case f:         \
-                               for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
-                                  for (k=0; k < filter_bytes; ++k)
-                switch (filter) {
-                       STBI__CASE(STBI__F_none)                 { cur[k] = raw[k]; } break;
-                       STBI__CASE(STBI__F_sub)                  { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
-                       STBI__CASE(STBI__F_up)                   { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
-                       STBI__CASE(STBI__F_avg)                  { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
-                       STBI__CASE(STBI__F_paeth)                { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
-                       STBI__CASE(STBI__F_avg_first)    { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
-                       STBI__CASE(STBI__F_paeth_first)  { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
-                }
-                #undef STBI__CASE
-
-                // the loop above sets the high byte of the pixels' alpha, but for
-                // 16 bit png files we also need the low byte set. we'll do that here.
-                if (depth == 16) {
-                       cur = a->out + stride*j; // start at the beginning of the row again
-                       for (i=0; i < x; ++i,cur+=output_bytes) {
-                          cur[filter_bytes+1] = 255;
-                       }
-                }
-         }
-   }
-
-   // we make a separate pass to expand bits to pixels; for performance,
-   // this could run two scanlines behind the above code, so it won't
-   // intefere with filtering but will still be in the cache.
-   if (depth < 8) {
-         for (j=0; j < y; ++j) {
-                stbi_uc *cur = a->out + stride*j;
-                stbi_uc *in  = a->out + stride*j + x*out_n - img_width_bytes;
-                // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
-                // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
-                stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
-
-                // note that the final byte might overshoot and write more data than desired.
-                // we can allocate enough data that this never writes out of memory, but it
-                // could also overwrite the next scanline. can it overwrite non-empty data
-                // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
-                // so we need to explicitly clamp the final ones
-
-                if (depth == 4) {
-                       for (k=x*img_n; k >= 2; k-=2, ++in) {
-                          *cur++ = scale * ((*in >> 4)           );
-                          *cur++ = scale * ((*in         ) & 0x0f);
-                       }
-                       if (k > 0) *cur++ = scale * ((*in >> 4)           );
-                } else if (depth == 2) {
-                       for (k=x*img_n; k >= 4; k-=4, ++in) {
-                          *cur++ = scale * ((*in >> 6)           );
-                          *cur++ = scale * ((*in >> 4) & 0x03);
-                          *cur++ = scale * ((*in >> 2) & 0x03);
-                          *cur++ = scale * ((*in         ) & 0x03);
-                       }
-                       if (k > 0) *cur++ = scale * ((*in >> 6)           );
-                       if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03);
-                       if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03);
-                } else if (depth == 1) {
-                       for (k=x*img_n; k >= 8; k-=8, ++in) {
-                          *cur++ = scale * ((*in >> 7)           );
-                          *cur++ = scale * ((*in >> 6) & 0x01);
-                          *cur++ = scale * ((*in >> 5) & 0x01);
-                          *cur++ = scale * ((*in >> 4) & 0x01);
-                          *cur++ = scale * ((*in >> 3) & 0x01);
-                          *cur++ = scale * ((*in >> 2) & 0x01);
-                          *cur++ = scale * ((*in >> 1) & 0x01);
-                          *cur++ = scale * ((*in         ) & 0x01);
-                       }
-                       if (k > 0) *cur++ = scale * ((*in >> 7)           );
-                       if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01);
-                       if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01);
-                       if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01);
-                       if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01);
-                       if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01);
-                       if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
-                }
-                if (img_n != out_n) {
-                       int q;
-                       // insert alpha = 255
-                       cur = a->out + stride*j;
-                       if (img_n == 1) {
-                          for (q=x-1; q >= 0; --q) {
-                                 cur[q*2+1] = 255;
-                                 cur[q*2+0] = cur[q];
-                          }
-                       } else {
-                          STBI_ASSERT(img_n == 3);
-                          for (q=x-1; q >= 0; --q) {
-                                 cur[q*4+3] = 255;
-                                 cur[q*4+2] = cur[q*3+2];
-                                 cur[q*4+1] = cur[q*3+1];
-                                 cur[q*4+0] = cur[q*3+0];
-                          }
-                       }
-                }
-         }
-   } else if (depth == 16) {
-         // force the image data from big-endian to platform-native.
-         // this is done in a separate pass due to the decoding relying
-         // on the data being untouched, but could probably be done
-         // per-line during decode if care is taken.
-         stbi_uc *cur = a->out;
-         stbi__uint16 *cur16 = (stbi__uint16*)cur;
-
-         for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
-                *cur16 = (cur[0] << 8) | cur[1];
-         }
-   }
-
-   return 1;
-}
-
-static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced)
-{
-   int bytes = (depth == 16 ? 2 : 1);
-   int out_bytes = out_n * bytes;
-   stbi_uc *final;
-   int p;
-   if (!interlaced)
-         return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color);
-
-   // de-interlacing
-   final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
-   for (p=0; p < 7; ++p) {
-         int xorig[] = { 0,4,0,2,0,1,0 };
-         int yorig[] = { 0,0,4,0,2,0,1 };
-         int xspc[]  = { 8,8,4,4,2,2,1 };
-         int yspc[]  = { 8,8,8,4,4,2,2 };
-         int i,j,x,y;
-         // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1
-         x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p];
-         y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p];
-         if (x && y) {
-                stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y;
-                if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) {
-                       STBI_FREE(final);
-                       return 0;
-                }
-                for (j=0; j < y; ++j) {
-                       for (i=0; i < x; ++i) {
-                          int out_y = j*yspc[p]+yorig[p];
-                          int out_x = i*xspc[p]+xorig[p];
-                          memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes,
-                                         a->out + (j*x+i)*out_bytes, out_bytes);
-                       }
-                }
-                STBI_FREE(a->out);
-                image_data += img_len;
-                image_data_len -= img_len;
-         }
-   }
-   a->out = final;
-
-   return 1;
-}
-
-static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
-{
-   stbi__context *s = z->s;
-   stbi__uint32 i, pixel_count = s->img_x * s->img_y;
-   stbi_uc *p = z->out;
-
-   // compute color-based transparency, assuming we've
-   // already got 255 as the alpha value in the output
-   STBI_ASSERT(out_n == 2 || out_n == 4);
-
-   if (out_n == 2) {
-         for (i=0; i < pixel_count; ++i) {
-                p[1] = (p[0] == tc[0] ? 0 : 255);
-                p += 2;
-         }
-   } else {
-         for (i=0; i < pixel_count; ++i) {
-                if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
-                       p[3] = 0;
-                p += 4;
-         }
-   }
-   return 1;
-}
-
-static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n)
-{
-   stbi__context *s = z->s;
-   stbi__uint32 i, pixel_count = s->img_x * s->img_y;
-   stbi__uint16 *p = (stbi__uint16*) z->out;
-
-   // compute color-based transparency, assuming we've
-   // already got 65535 as the alpha value in the output
-   STBI_ASSERT(out_n == 2 || out_n == 4);
-
-   if (out_n == 2) {
-         for (i = 0; i < pixel_count; ++i) {
-                p[1] = (p[0] == tc[0] ? 0 : 65535);
-                p += 2;
-         }
-   } else {
-         for (i = 0; i < pixel_count; ++i) {
-                if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
-                       p[3] = 0;
-                p += 4;
-         }
-   }
-   return 1;
-}
-
-static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n)
-{
-   stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
-   stbi_uc *p, *temp_out, *orig = a->out;
-
-   p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0);
-   if (p == NULL) return stbi__err("outofmem", "Out of memory");
-
-   // between here and free(out) below, exitting would leak
-   temp_out = p;
-
-   if (pal_img_n == 3) {
-         for (i=0; i < pixel_count; ++i) {
-                int n = orig[i]*4;
-                p[0] = palette[n  ];
-                p[1] = palette[n+1];
-                p[2] = palette[n+2];
-                p += 3;
-         }
-   } else {
-         for (i=0; i < pixel_count; ++i) {
-                int n = orig[i]*4;
-                p[0] = palette[n  ];
-                p[1] = palette[n+1];
-                p[2] = palette[n+2];
-                p[3] = palette[n+3];
-                p += 4;
-         }
-   }
-   STBI_FREE(a->out);
-   a->out = temp_out;
-
-   STBI_NOTUSED(len);
-
-   return 1;
+static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x,
+                                      stbi__uint32 y, int depth, int color) {
+    int            bytes = (depth == 16 ? 2 : 1);
+    stbi__context *s     = a->s;
+    stbi__uint32   i, j, stride = x * out_n * bytes;
+    stbi__uint32   img_len, img_width_bytes;
+    int            k;
+    int            img_n = s->img_n; // copy it into a local for later
+
+    int output_bytes = out_n * bytes;
+    int filter_bytes = img_n * bytes;
+    int width        = x;
+
+    STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1);
+    a->out = (stbi_uc *)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
+    if (!a->out)
+        return stbi__err("outofmem", "Out of memory");
+
+    if (!stbi__mad3sizes_valid(img_n, x, depth, 7))
+        return stbi__err("too large", "Corrupt PNG");
+    img_width_bytes = (((img_n * x * depth) + 7) >> 3);
+    img_len         = (img_width_bytes + 1) * y;
+
+    // we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
+    // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros),
+    // so just check for raw_len < img_len always.
+    if (raw_len < img_len)
+        return stbi__err("not enough pixels", "Corrupt PNG");
+
+    for (j = 0; j < y; ++j) {
+        stbi_uc *cur = a->out + stride * j;
+        stbi_uc *prior;
+        int      filter = *raw++;
+
+        if (filter > 4)
+            return stbi__err("invalid filter", "Corrupt PNG");
+
+        if (depth < 8) {
+            STBI_ASSERT(img_width_bytes <= x);
+            cur +=
+                x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
+            filter_bytes = 1;
+            width        = img_width_bytes;
+        }
+        prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
+
+        // if first row, use special filter that doesn't sample previous row
+        if (j == 0)
+            filter = first_row_filter[filter];
+
+        // handle first byte explicitly
+        for (k = 0; k < filter_bytes; ++k) {
+            switch (filter) {
+            case STBI__F_none:
+                cur[k] = raw[k];
+                break;
+            case STBI__F_sub:
+                cur[k] = raw[k];
+                break;
+            case STBI__F_up:
+                cur[k] = STBI__BYTECAST(raw[k] + prior[k]);
+                break;
+            case STBI__F_avg:
+                cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1));
+                break;
+            case STBI__F_paeth:
+                cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0));
+                break;
+            case STBI__F_avg_first:
+                cur[k] = raw[k];
+                break;
+            case STBI__F_paeth_first:
+                cur[k] = raw[k];
+                break;
+            }
+        }
+
+        if (depth == 8) {
+            if (img_n != out_n)
+                cur[img_n] = 255; // first pixel
+            raw += img_n;
+            cur += out_n;
+            prior += out_n;
+        } else if (depth == 16) {
+            if (img_n != out_n) {
+                cur[filter_bytes]     = 255; // first pixel top byte
+                cur[filter_bytes + 1] = 255; // first pixel bottom byte
+            }
+            raw += filter_bytes;
+            cur += output_bytes;
+            prior += output_bytes;
+        } else {
+            raw += 1;
+            cur += 1;
+            prior += 1;
+        }
+
+        // this is a little gross, so that we don't switch per-pixel or per-component
+        if (depth < 8 || img_n == out_n) {
+            int nk = (width - 1) * filter_bytes;
+#define STBI__CASE(f)                                                                                                  \
+    case f:                                                                                                            \
+        for (k = 0; k < nk; ++k)
+            switch (filter) {
+            // "none" filter turns into a memcpy here; make that explicit.
+            case STBI__F_none:
+                memcpy(cur, raw, nk);
+                break;
+                STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); }
+                break;
+                STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); }
+                break;
+                STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); }
+                break;
+                STBI__CASE(STBI__F_paeth) {
+                    cur[k] =
+                        STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes]));
+                }
+                break;
+                STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); }
+                break;
+                STBI__CASE(STBI__F_paeth_first) {
+                    cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0));
+                }
+                break;
+            }
+#undef STBI__CASE
+            raw += nk;
+        } else {
+            STBI_ASSERT(img_n + 1 == out_n);
+#define STBI__CASE(f)                                                                                                  \
+    case f:                                                                                                            \
+        for (i = x - 1; i >= 1;                                                                                        \
+             --i, cur[filter_bytes] = 255, raw += filter_bytes, cur += output_bytes, prior += output_bytes)            \
+            for (k = 0; k < filter_bytes; ++k)
+            switch (filter) {
+                STBI__CASE(STBI__F_none) { cur[k] = raw[k]; }
+                break;
+                STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); }
+                break;
+                STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); }
+                break;
+                STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); }
+                break;
+                STBI__CASE(STBI__F_paeth) {
+                    cur[k] =
+                        STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes]));
+                }
+                break;
+                STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); }
+                break;
+                STBI__CASE(STBI__F_paeth_first) {
+                    cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0));
+                }
+                break;
+            }
+#undef STBI__CASE
+
+            // the loop above sets the high byte of the pixels' alpha, but for
+            // 16 bit png files we also need the low byte set. we'll do that here.
+            if (depth == 16) {
+                cur = a->out + stride * j; // start at the beginning of the row again
+                for (i = 0; i < x; ++i, cur += output_bytes) {
+                    cur[filter_bytes + 1] = 255;
+                }
+            }
+        }
+    }
+
+    // we make a separate pass to expand bits to pixels; for performance,
+    // this could run two scanlines behind the above code, so it won't
+    // intefere with filtering but will still be in the cache.
+    if (depth < 8) {
+        for (j = 0; j < y; ++j) {
+            stbi_uc *cur = a->out + stride * j;
+            stbi_uc *in  = a->out + stride * j + x * out_n - img_width_bytes;
+            // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for
+            // 1/2/4-bit png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data
+            // that will be skipped in the later loop
+            stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
+
+            // note that the final byte might overshoot and write more data than desired.
+            // we can allocate enough data that this never writes out of memory, but it
+            // could also overwrite the next scanline. can it overwrite non-empty data
+            // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
+            // so we need to explicitly clamp the final ones
+
+            if (depth == 4) {
+                for (k = x * img_n; k >= 2; k -= 2, ++in) {
+                    *cur++ = scale * ((*in >> 4));
+                    *cur++ = scale * ((*in) & 0x0f);
+                }
+                if (k > 0)
+                    *cur++ = scale * ((*in >> 4));
+            } else if (depth == 2) {
+                for (k = x * img_n; k >= 4; k -= 4, ++in) {
+                    *cur++ = scale * ((*in >> 6));
+                    *cur++ = scale * ((*in >> 4) & 0x03);
+                    *cur++ = scale * ((*in >> 2) & 0x03);
+                    *cur++ = scale * ((*in) & 0x03);
+                }
+                if (k > 0)
+                    *cur++ = scale * ((*in >> 6));
+                if (k > 1)
+                    *cur++ = scale * ((*in >> 4) & 0x03);
+                if (k > 2)
+                    *cur++ = scale * ((*in >> 2) & 0x03);
+            } else if (depth == 1) {
+                for (k = x * img_n; k >= 8; k -= 8, ++in) {
+                    *cur++ = scale * ((*in >> 7));
+                    *cur++ = scale * ((*in >> 6) & 0x01);
+                    *cur++ = scale * ((*in >> 5) & 0x01);
+                    *cur++ = scale * ((*in >> 4) & 0x01);
+                    *cur++ = scale * ((*in >> 3) & 0x01);
+                    *cur++ = scale * ((*in >> 2) & 0x01);
+                    *cur++ = scale * ((*in >> 1) & 0x01);
+                    *cur++ = scale * ((*in) & 0x01);
+                }
+                if (k > 0)
+                    *cur++ = scale * ((*in >> 7));
+                if (k > 1)
+                    *cur++ = scale * ((*in >> 6) & 0x01);
+                if (k > 2)
+                    *cur++ = scale * ((*in >> 5) & 0x01);
+                if (k > 3)
+                    *cur++ = scale * ((*in >> 4) & 0x01);
+                if (k > 4)
+                    *cur++ = scale * ((*in >> 3) & 0x01);
+                if (k > 5)
+                    *cur++ = scale * ((*in >> 2) & 0x01);
+                if (k > 6)
+                    *cur++ = scale * ((*in >> 1) & 0x01);
+            }
+            if (img_n != out_n) {
+                int q;
+                // insert alpha = 255
+                cur = a->out + stride * j;
+                if (img_n == 1) {
+                    for (q = x - 1; q >= 0; --q) {
+                        cur[q * 2 + 1] = 255;
+                        cur[q * 2 + 0] = cur[q];
+                    }
+                } else {
+                    STBI_ASSERT(img_n == 3);
+                    for (q = x - 1; q >= 0; --q) {
+                        cur[q * 4 + 3] = 255;
+                        cur[q * 4 + 2] = cur[q * 3 + 2];
+                        cur[q * 4 + 1] = cur[q * 3 + 1];
+                        cur[q * 4 + 0] = cur[q * 3 + 0];
+                    }
+                }
+            }
+        }
+    } else if (depth == 16) {
+        // force the image data from big-endian to platform-native.
+        // this is done in a separate pass due to the decoding relying
+        // on the data being untouched, but could probably be done
+        // per-line during decode if care is taken.
+        stbi_uc      *cur   = a->out;
+        stbi__uint16 *cur16 = (stbi__uint16 *)cur;
+
+        for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) {
+            *cur16 = (cur[0] << 8) | cur[1];
+        }
+    }
+
+    return 1;
+}
+
+static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth,
+                                  int color, int interlaced) {
+    int      bytes     = (depth == 16 ? 2 : 1);
+    int      out_bytes = out_n * bytes;
+    stbi_uc *final;
+    int      p;
+    if (!interlaced)
+        return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color);
+
+    // de-interlacing
+    final = (stbi_uc *)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
+    for (p = 0; p < 7; ++p) {
+        int xorig[] = {0, 4, 0, 2, 0, 1, 0};
+        int yorig[] = {0, 0, 4, 0, 2, 0, 1};
+        int xspc[]  = {8, 8, 4, 4, 2, 2, 1};
+        int yspc[]  = {8, 8, 8, 4, 4, 2, 2};
+        int i, j, x, y;
+        // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1
+        x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p];
+        y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p];
+        if (x && y) {
+            stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y;
+            if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) {
+                STBI_FREE(final);
+                return 0;
+            }
+            for (j = 0; j < y; ++j) {
+                for (i = 0; i < x; ++i) {
+                    int out_y = j * yspc[p] + yorig[p];
+                    int out_x = i * xspc[p] + xorig[p];
+                    memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes,
+                           a->out + (j * x + i) * out_bytes, out_bytes);
+                }
+            }
+            STBI_FREE(a->out);
+            image_data += img_len;
+            image_data_len -= img_len;
+        }
+    }
+    a->out = final;
+
+    return 1;
+}
+
+static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) {
+    stbi__context *s = z->s;
+    stbi__uint32   i, pixel_count = s->img_x * s->img_y;
+    stbi_uc       *p = z->out;
+
+    // compute color-based transparency, assuming we've
+    // already got 255 as the alpha value in the output
+    STBI_ASSERT(out_n == 2 || out_n == 4);
+
+    if (out_n == 2) {
+        for (i = 0; i < pixel_count; ++i) {
+            p[1] = (p[0] == tc[0] ? 0 : 255);
+            p += 2;
+        }
+    } else {
+        for (i = 0; i < pixel_count; ++i) {
+            if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
+                p[3] = 0;
+            p += 4;
+        }
+    }
+    return 1;
+}
+
+static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) {
+    stbi__context *s = z->s;
+    stbi__uint32   i, pixel_count = s->img_x * s->img_y;
+    stbi__uint16  *p = (stbi__uint16 *)z->out;
+
+    // compute color-based transparency, assuming we've
+    // already got 65535 as the alpha value in the output
+    STBI_ASSERT(out_n == 2 || out_n == 4);
+
+    if (out_n == 2) {
+        for (i = 0; i < pixel_count; ++i) {
+            p[1] = (p[0] == tc[0] ? 0 : 65535);
+            p += 2;
+        }
+    } else {
+        for (i = 0; i < pixel_count; ++i) {
+            if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
+                p[3] = 0;
+            p += 4;
+        }
+    }
+    return 1;
+}
+
+static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) {
+    stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
+    stbi_uc     *p, *temp_out, *orig = a->out;
+
+    p = (stbi_uc *)stbi__malloc_mad2(pixel_count, pal_img_n, 0);
+    if (p == NULL)
+        return stbi__err("outofmem", "Out of memory");
+
+    // between here and free(out) below, exitting would leak
+    temp_out = p;
+
+    if (pal_img_n == 3) {
+        for (i = 0; i < pixel_count; ++i) {
+            int n = orig[i] * 4;
+            p[0]  = palette[n];
+            p[1]  = palette[n + 1];
+            p[2]  = palette[n + 2];
+            p += 3;
+        }
+    } else {
+        for (i = 0; i < pixel_count; ++i) {
+            int n = orig[i] * 4;
+            p[0]  = palette[n];
+            p[1]  = palette[n + 1];
+            p[2]  = palette[n + 2];
+            p[3]  = palette[n + 3];
+            p += 4;
+        }
+    }
+    STBI_FREE(a->out);
+    a->out = temp_out;
+
+    STBI_NOTUSED(len);
+
+    return 1;
 }
 
 static int stbi__unpremultiply_on_load = 0;
-static int stbi__de_iphone_flag = 0;
-
-STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
-{
-   stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply;
-}
-
-STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
-{
-   stbi__de_iphone_flag = flag_true_if_should_convert;
-}
-
-static void stbi__de_iphone(stbi__png *z)
-{
-   stbi__context *s = z->s;
-   stbi__uint32 i, pixel_count = s->img_x * s->img_y;
-   stbi_uc *p = z->out;
-
-   if (s->img_out_n == 3) {     // convert bgr to rgb
-         for (i=0; i < pixel_count; ++i) {
-                stbi_uc t = p[0];
-                p[0] = p[2];
-                p[2] = t;
-                p += 3;
-         }
-   } else {
-         STBI_ASSERT(s->img_out_n == 4);
-         if (stbi__unpremultiply_on_load) {
-                // convert bgr to rgb and unpremultiply
-                for (i=0; i < pixel_count; ++i) {
-                       stbi_uc a = p[3];
-                       stbi_uc t = p[0];
-                       if (a) {
-                          stbi_uc half = a / 2;
-                          p[0] = (p[2] * 255 + half) / a;
-                          p[1] = (p[1] * 255 + half) / a;
-                          p[2] = ( t   * 255 + half) / a;
-                       } else {
-                          p[0] = p[2];
-                          p[2] = t;
-                       }
-                       p += 4;
-                }
-         } else {
-                // convert bgr to rgb
-                for (i=0; i < pixel_count; ++i) {
-                       stbi_uc t = p[0];
-                       p[0] = p[2];
-                       p[2] = t;
-                       p += 4;
-                }
-         }
-   }
-}
-
-#define STBI__PNG_TYPE(a,b,c,d)         (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d))
-
-static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
-{
-   stbi_uc palette[1024], pal_img_n=0;
-   stbi_uc has_trans=0, tc[3];
-   stbi__uint16 tc16[3];
-   stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
-   int first=1,k,interlace=0, color=0, is_iphone=0;
-   stbi__context *s = z->s;
-
-   z->expanded = NULL;
-   z->idata = NULL;
-   z->out = NULL;
-
-   if (!stbi__check_png_header(s)) return 0;
-
-   if (scan == STBI__SCAN_type) return 1;
-
-   for (;;) {
-         stbi__pngchunk c = stbi__get_chunk_header(s);
-         switch (c.type) {
-                case STBI__PNG_TYPE('C','g','B','I'):
-                       is_iphone = 1;
-                       stbi__skip(s, c.length);
-                       break;
-                case STBI__PNG_TYPE('I','H','D','R'): {
-                       int comp,filter;
-                       if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
-                       first = 0;
-                       if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
-                       s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
-                       s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
-                       z->depth = stbi__get8(s);  if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16)      return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
-                       color = stbi__get8(s);  if (color > 6)             return stbi__err("bad ctype","Corrupt PNG");
-                       if (color == 3 && z->depth == 16)                                  return stbi__err("bad ctype","Corrupt PNG");
-                       if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
-                       comp  = stbi__get8(s);  if (comp) return stbi__err("bad comp method","Corrupt PNG");
-                       filter= stbi__get8(s);  if (filter) return stbi__err("bad filter method","Corrupt PNG");
-                       interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG");
-                       if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG");
-                       if (!pal_img_n) {
-                          s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
-                          if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode");
-                          if (scan == STBI__SCAN_header) return 1;
-                       } else {
-                          // if paletted, then pal_n is our final components, and
-                          // img_n is # components to decompress/filter.
-                          s->img_n = 1;
-                          if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG");
-                          // if SCAN_header, have to scan to see if we have a tRNS
-                       }
-                       break;
-                }
-
-                case STBI__PNG_TYPE('P','L','T','E'):  {
-                       if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-                       if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG");
-                       pal_len = c.length / 3;
-                       if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG");
-                       for (i=0; i < pal_len; ++i) {
-                          palette[i*4+0] = stbi__get8(s);
-                          palette[i*4+1] = stbi__get8(s);
-                          palette[i*4+2] = stbi__get8(s);
-                          palette[i*4+3] = 255;
-                       }
-                       break;
-                }
-
-                case STBI__PNG_TYPE('t','R','N','S'): {
-                       if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-                       if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG");
-                       if (pal_img_n) {
-                          if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; }
-                          if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG");
-                          if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG");
-                          pal_img_n = 4;
-                          for (i=0; i < c.length; ++i)
-                                 palette[i*4+3] = stbi__get8(s);
-                       } else {
-                          if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
-                          if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
-                          has_trans = 1;
-                          if (z->depth == 16) {
-                                 for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
-                          } else {
-                                 for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
-                          }
-                       }
-                       break;
-                }
-
-                case STBI__PNG_TYPE('I','D','A','T'): {
-                       if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-                       if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
-                       if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
-                       if ((int)(ioff + c.length) < (int)ioff) return 0;
-                       if (ioff + c.length > idata_limit) {
-                          stbi__uint32 idata_limit_old = idata_limit;
-                          stbi_uc *p;
-                          if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
-                          while (ioff + c.length > idata_limit)
-                                 idata_limit *= 2;
-                          STBI_NOTUSED(idata_limit_old);
-                          p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
-                          z->idata = p;
-                       }
-                       if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG");
-                       ioff += c.length;
-                       break;
-                }
-
-                case STBI__PNG_TYPE('I','E','N','D'): {
-                       stbi__uint32 raw_len, bpl;
-                       if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-                       if (scan != STBI__SCAN_load) return 1;
-                       if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
-                       // initial guess for decoded data size to avoid unnecessary reallocs
-                       bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
-                       raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
-                       z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
-                       if (z->expanded == NULL) return 0; // zlib should set error
-                       STBI_FREE(z->idata); z->idata = NULL;
-                       if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans)
-                          s->img_out_n = s->img_n+1;
-                       else
-                          s->img_out_n = s->img_n;
-                       if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
-                       if (has_trans) {
-                          if (z->depth == 16) {
-                                 if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0;
-                          } else {
-                                 if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
-                          }
-                       }
-                       if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
-                          stbi__de_iphone(z);
-                       if (pal_img_n) {
-                          // pal_img_n == 3 or 4
-                          s->img_n = pal_img_n; // record the actual colors we had
-                          s->img_out_n = pal_img_n;
-                          if (req_comp >= 3) s->img_out_n = req_comp;
-                          if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n))
-                                 return 0;
-                       } else if (has_trans) {
-                          // non-paletted image with tRNS -> source image has (constant) alpha
-                          ++s->img_n;
-                       }
-                       STBI_FREE(z->expanded); z->expanded = NULL;
-                       return 1;
-                }
-
-                default:
-                       // if critical, fail
-                       if (first) return stbi__err("first not IHDR", "Corrupt PNG");
-                       if ((c.type & (1 << 29)) == 0) {
-                          #ifndef STBI_NO_FAILURE_STRINGS
-                          // not threadsafe
-                          static char invalid_chunk[] = "XXXX PNG chunk not known";
-                          invalid_chunk[0] = STBI__BYTECAST(c.type >> 24);
-                          invalid_chunk[1] = STBI__BYTECAST(c.type >> 16);
-                          invalid_chunk[2] = STBI__BYTECAST(c.type >>  8);
-                          invalid_chunk[3] = STBI__BYTECAST(c.type >>  0);
-                          #endif
-                          return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type");
-                       }
-                       stbi__skip(s, c.length);
-                       break;
-         }
-         // end of PNG chunk, read and skip CRC
-         stbi__get32be(s);
-   }
-}
-
-static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri)
-{
-   void *result=NULL;
-   if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
-   if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
-         if (p->depth < 8)
-                ri->bits_per_channel = 8;
-         else
-                ri->bits_per_channel = p->depth;
-         result = p->out;
-         p->out = NULL;
-         if (req_comp && req_comp != p->s->img_out_n) {
-                if (ri->bits_per_channel == 8)
-                       result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
-                else
-                       result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
-                p->s->img_out_n = req_comp;
-                if (result == NULL) return result;
-         }
-         *x = p->s->img_x;
-         *y = p->s->img_y;
-         if (n) *n = p->s->img_n;
-   }
-   STBI_FREE(p->out);     p->out          = NULL;
-   STBI_FREE(p->expanded); p->expanded = NULL;
-   STBI_FREE(p->idata);           p->idata        = NULL;
-
-   return result;
-}
-
-static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   stbi__png p;
-   p.s = s;
-   return stbi__do_png(&p, x,y,comp,req_comp, ri);
-}
-
-static int stbi__png_test(stbi__context *s)
-{
-   int r;
-   r = stbi__check_png_header(s);
-   stbi__rewind(s);
-   return r;
-}
-
-static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp)
-{
-   if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) {
-         stbi__rewind( p->s );
-         return 0;
-   }
-   if (x) *x = p->s->img_x;
-   if (y) *y = p->s->img_y;
-   if (comp) *comp = p->s->img_n;
-   return 1;
-}
-
-static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   stbi__png p;
-   p.s = s;
-   return stbi__png_info_raw(&p, x, y, comp);
-}
-
-static int stbi__png_is16(stbi__context *s)
-{
-   stbi__png p;
-   p.s = s;
-   if (!stbi__png_info_raw(&p, NULL, NULL, NULL))
-          return 0;
-   if (p.depth != 16) {
-         stbi__rewind(p.s);
-         return 0;
-   }
-   return 1;
+static int stbi__de_iphone_flag        = 0;
+
+STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) {
+    stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply;
+}
+
+STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) {
+    stbi__de_iphone_flag = flag_true_if_should_convert;
+}
+
+static void stbi__de_iphone(stbi__png *z) {
+    stbi__context *s = z->s;
+    stbi__uint32   i, pixel_count = s->img_x * s->img_y;
+    stbi_uc       *p = z->out;
+
+    if (s->img_out_n == 3) { // convert bgr to rgb
+        for (i = 0; i < pixel_count; ++i) {
+            stbi_uc t = p[0];
+            p[0]      = p[2];
+            p[2]      = t;
+            p += 3;
+        }
+    } else {
+        STBI_ASSERT(s->img_out_n == 4);
+        if (stbi__unpremultiply_on_load) {
+            // convert bgr to rgb and unpremultiply
+            for (i = 0; i < pixel_count; ++i) {
+                stbi_uc a = p[3];
+                stbi_uc t = p[0];
+                if (a) {
+                    stbi_uc half = a / 2;
+                    p[0]         = (p[2] * 255 + half) / a;
+                    p[1]         = (p[1] * 255 + half) / a;
+                    p[2]         = (t * 255 + half) / a;
+                } else {
+                    p[0] = p[2];
+                    p[2] = t;
+                }
+                p += 4;
+            }
+        } else {
+            // convert bgr to rgb
+            for (i = 0; i < pixel_count; ++i) {
+                stbi_uc t = p[0];
+                p[0]      = p[2];
+                p[2]      = t;
+                p += 4;
+            }
+        }
+    }
+}
+
+#define STBI__PNG_TYPE(a, b, c, d)                                                                                     \
+    (((unsigned)(a) << 24) + ((unsigned)(b) << 16) + ((unsigned)(c) << 8) + (unsigned)(d))
+
+static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) {
+    stbi_uc        palette[1024], pal_img_n = 0;
+    stbi_uc        has_trans = 0, tc[3];
+    stbi__uint16   tc16[3];
+    stbi__uint32   ioff = 0, idata_limit = 0, i, pal_len = 0;
+    int            first = 1, k, interlace = 0, color = 0, is_iphone = 0;
+    stbi__context *s = z->s;
+
+    z->expanded = NULL;
+    z->idata    = NULL;
+    z->out      = NULL;
+
+    if (!stbi__check_png_header(s))
+        return 0;
+
+    if (scan == STBI__SCAN_type)
+        return 1;
+
+    for (;;) {
+        stbi__pngchunk c = stbi__get_chunk_header(s);
+        switch (c.type) {
+        case STBI__PNG_TYPE('C', 'g', 'B', 'I'):
+            is_iphone = 1;
+            stbi__skip(s, c.length);
+            break;
+        case STBI__PNG_TYPE('I', 'H', 'D', 'R'): {
+            int comp, filter;
+            if (!first)
+                return stbi__err("multiple IHDR", "Corrupt PNG");
+            first = 0;
+            if (c.length != 13)
+                return stbi__err("bad IHDR len", "Corrupt PNG");
+            s->img_x = stbi__get32be(s);
+            if (s->img_x > (1 << 24))
+                return stbi__err("too large", "Very large image (corrupt?)");
+            s->img_y = stbi__get32be(s);
+            if (s->img_y > (1 << 24))
+                return stbi__err("too large", "Very large image (corrupt?)");
+            z->depth = stbi__get8(s);
+            if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16)
+                return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only");
+            color = stbi__get8(s);
+            if (color > 6)
+                return stbi__err("bad ctype", "Corrupt PNG");
+            if (color == 3 && z->depth == 16)
+                return stbi__err("bad ctype", "Corrupt PNG");
+            if (color == 3)
+                pal_img_n = 3;
+            else if (color & 1)
+                return stbi__err("bad ctype", "Corrupt PNG");
+            comp = stbi__get8(s);
+            if (comp)
+                return stbi__err("bad comp method", "Corrupt PNG");
+            filter = stbi__get8(s);
+            if (filter)
+                return stbi__err("bad filter method", "Corrupt PNG");
+            interlace = stbi__get8(s);
+            if (interlace > 1)
+                return stbi__err("bad interlace method", "Corrupt PNG");
+            if (!s->img_x || !s->img_y)
+                return stbi__err("0-pixel image", "Corrupt PNG");
+            if (!pal_img_n) {
+                s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
+                if ((1 << 30) / s->img_x / s->img_n < s->img_y)
+                    return stbi__err("too large", "Image too large to decode");
+                if (scan == STBI__SCAN_header)
+                    return 1;
+            } else {
+                // if paletted, then pal_n is our final components, and
+                // img_n is # components to decompress/filter.
+                s->img_n = 1;
+                if ((1 << 30) / s->img_x / 4 < s->img_y)
+                    return stbi__err("too large", "Corrupt PNG");
+                // if SCAN_header, have to scan to see if we have a tRNS
+            }
+            break;
+        }
+
+        case STBI__PNG_TYPE('P', 'L', 'T', 'E'): {
+            if (first)
+                return stbi__err("first not IHDR", "Corrupt PNG");
+            if (c.length > 256 * 3)
+                return stbi__err("invalid PLTE", "Corrupt PNG");
+            pal_len = c.length / 3;
+            if (pal_len * 3 != c.length)
+                return stbi__err("invalid PLTE", "Corrupt PNG");
+            for (i = 0; i < pal_len; ++i) {
+                palette[i * 4 + 0] = stbi__get8(s);
+                palette[i * 4 + 1] = stbi__get8(s);
+                palette[i * 4 + 2] = stbi__get8(s);
+                palette[i * 4 + 3] = 255;
+            }
+            break;
+        }
+
+        case STBI__PNG_TYPE('t', 'R', 'N', 'S'): {
+            if (first)
+                return stbi__err("first not IHDR", "Corrupt PNG");
+            if (z->idata)
+                return stbi__err("tRNS after IDAT", "Corrupt PNG");
+            if (pal_img_n) {
+                if (scan == STBI__SCAN_header) {
+                    s->img_n = 4;
+                    return 1;
+                }
+                if (pal_len == 0)
+                    return stbi__err("tRNS before PLTE", "Corrupt PNG");
+                if (c.length > pal_len)
+                    return stbi__err("bad tRNS len", "Corrupt PNG");
+                pal_img_n = 4;
+                for (i = 0; i < c.length; ++i)
+                    palette[i * 4 + 3] = stbi__get8(s);
+            } else {
+                if (!(s->img_n & 1))
+                    return stbi__err("tRNS with alpha", "Corrupt PNG");
+                if (c.length != (stbi__uint32)s->img_n * 2)
+                    return stbi__err("bad tRNS len", "Corrupt PNG");
+                has_trans = 1;
+                if (z->depth == 16) {
+                    for (k = 0; k < s->img_n; ++k)
+                        tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
+                } else {
+                    for (k = 0; k < s->img_n; ++k)
+                        tc[k] = (stbi_uc)(stbi__get16be(s) & 255) *
+                                stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
+                }
+            }
+            break;
+        }
+
+        case STBI__PNG_TYPE('I', 'D', 'A', 'T'): {
+            if (first)
+                return stbi__err("first not IHDR", "Corrupt PNG");
+            if (pal_img_n && !pal_len)
+                return stbi__err("no PLTE", "Corrupt PNG");
+            if (scan == STBI__SCAN_header) {
+                s->img_n = pal_img_n;
+                return 1;
+            }
+            if ((int)(ioff + c.length) < (int)ioff)
+                return 0;
+            if (ioff + c.length > idata_limit) {
+                stbi__uint32 idata_limit_old = idata_limit;
+                stbi_uc     *p;
+                if (idata_limit == 0)
+                    idata_limit = c.length > 4096 ? c.length : 4096;
+                while (ioff + c.length > idata_limit)
+                    idata_limit *= 2;
+                STBI_NOTUSED(idata_limit_old);
+                p = (stbi_uc *)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit);
+                if (p == NULL)
+                    return stbi__err("outofmem", "Out of memory");
+                z->idata = p;
+            }
+            if (!stbi__getn(s, z->idata + ioff, c.length))
+                return stbi__err("outofdata", "Corrupt PNG");
+            ioff += c.length;
+            break;
+        }
+
+        case STBI__PNG_TYPE('I', 'E', 'N', 'D'): {
+            stbi__uint32 raw_len, bpl;
+            if (first)
+                return stbi__err("first not IHDR", "Corrupt PNG");
+            if (scan != STBI__SCAN_load)
+                return 1;
+            if (z->idata == NULL)
+                return stbi__err("no IDAT", "Corrupt PNG");
+            // initial guess for decoded data size to avoid unnecessary reallocs
+            bpl         = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
+            raw_len     = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
+            z->expanded = (stbi_uc *)stbi_zlib_decode_malloc_guesssize_headerflag((char *)z->idata, ioff, raw_len,
+                                                                                  (int *)&raw_len, !is_iphone);
+            if (z->expanded == NULL)
+                return 0; // zlib should set error
+            STBI_FREE(z->idata);
+            z->idata = NULL;
+            if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans)
+                s->img_out_n = s->img_n + 1;
+            else
+                s->img_out_n = s->img_n;
+            if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace))
+                return 0;
+            if (has_trans) {
+                if (z->depth == 16) {
+                    if (!stbi__compute_transparency16(z, tc16, s->img_out_n))
+                        return 0;
+                } else {
+                    if (!stbi__compute_transparency(z, tc, s->img_out_n))
+                        return 0;
+                }
+            }
+            if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
+                stbi__de_iphone(z);
+            if (pal_img_n) {
+                // pal_img_n == 3 or 4
+                s->img_n     = pal_img_n; // record the actual colors we had
+                s->img_out_n = pal_img_n;
+                if (req_comp >= 3)
+                    s->img_out_n = req_comp;
+                if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n))
+                    return 0;
+            } else if (has_trans) {
+                // non-paletted image with tRNS -> source image has (constant) alpha
+                ++s->img_n;
+            }
+            STBI_FREE(z->expanded);
+            z->expanded = NULL;
+            return 1;
+        }
+
+        default:
+            // if critical, fail
+            if (first)
+                return stbi__err("first not IHDR", "Corrupt PNG");
+            if ((c.type & (1 << 29)) == 0) {
+#ifndef STBI_NO_FAILURE_STRINGS
+                // not threadsafe
+                static char invalid_chunk[] = "XXXX PNG chunk not known";
+                invalid_chunk[0]            = STBI__BYTECAST(c.type >> 24);
+                invalid_chunk[1]            = STBI__BYTECAST(c.type >> 16);
+                invalid_chunk[2]            = STBI__BYTECAST(c.type >> 8);
+                invalid_chunk[3]            = STBI__BYTECAST(c.type >> 0);
+#endif
+                return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type");
+            }
+            stbi__skip(s, c.length);
+            break;
+        }
+        // end of PNG chunk, read and skip CRC
+        stbi__get32be(s);
+    }
+}
+
+static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) {
+    void *result = NULL;
+    if (req_comp < 0 || req_comp > 4)
+        return stbi__errpuc("bad req_comp", "Internal error");
+    if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
+        if (p->depth < 8)
+            ri->bits_per_channel = 8;
+        else
+            ri->bits_per_channel = p->depth;
+        result = p->out;
+        p->out = NULL;
+        if (req_comp && req_comp != p->s->img_out_n) {
+            if (ri->bits_per_channel == 8)
+                result =
+                    stbi__convert_format((unsigned char *)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
+            else
+                result =
+                    stbi__convert_format16((stbi__uint16 *)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
+            p->s->img_out_n = req_comp;
+            if (result == NULL)
+                return result;
+        }
+        *x = p->s->img_x;
+        *y = p->s->img_y;
+        if (n)
+            *n = p->s->img_n;
+    }
+    STBI_FREE(p->out);
+    p->out = NULL;
+    STBI_FREE(p->expanded);
+    p->expanded = NULL;
+    STBI_FREE(p->idata);
+    p->idata = NULL;
+
+    return result;
+}
+
+static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) {
+    stbi__png p;
+    p.s = s;
+    return stbi__do_png(&p, x, y, comp, req_comp, ri);
+}
+
+static int stbi__png_test(stbi__context *s) {
+    int r;
+    r = stbi__check_png_header(s);
+    stbi__rewind(s);
+    return r;
+}
+
+static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) {
+    if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) {
+        stbi__rewind(p->s);
+        return 0;
+    }
+    if (x)
+        *x = p->s->img_x;
+    if (y)
+        *y = p->s->img_y;
+    if (comp)
+        *comp = p->s->img_n;
+    return 1;
+}
+
+static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) {
+    stbi__png p;
+    p.s = s;
+    return stbi__png_info_raw(&p, x, y, comp);
+}
+
+static int stbi__png_is16(stbi__context *s) {
+    stbi__png p;
+    p.s = s;
+    if (!stbi__png_info_raw(&p, NULL, NULL, NULL))
+        return 0;
+    if (p.depth != 16) {
+        stbi__rewind(p.s);
+        return 0;
+    }
+    return 1;
 }
 #endif
 
 // Microsoft/Windows BMP image
 
 #ifndef STBI_NO_BMP
-static int stbi__bmp_test_raw(stbi__context *s)
-{
-   int r;
-   int sz;
-   if (stbi__get8(s) != 'B') return 0;
-   if (stbi__get8(s) != 'M') return 0;
-   stbi__get32le(s); // discard filesize
-   stbi__get16le(s); // discard reserved
-   stbi__get16le(s); // discard reserved
-   stbi__get32le(s); // discard data offset
-   sz = stbi__get32le(s);
-   r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124);
-   return r;
-}
-
-static int stbi__bmp_test(stbi__context *s)
-{
-   int r = stbi__bmp_test_raw(s);
-   stbi__rewind(s);
-   return r;
+static int stbi__bmp_test_raw(stbi__context *s) {
+    int r;
+    int sz;
+    if (stbi__get8(s) != 'B')
+        return 0;
+    if (stbi__get8(s) != 'M')
+        return 0;
+    stbi__get32le(s); // discard filesize
+    stbi__get16le(s); // discard reserved
+    stbi__get16le(s); // discard reserved
+    stbi__get32le(s); // discard data offset
+    sz = stbi__get32le(s);
+    r  = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124);
+    return r;
+}
+
+static int stbi__bmp_test(stbi__context *s) {
+    int r = stbi__bmp_test_raw(s);
+    stbi__rewind(s);
+    return r;
 }
 
-
 // returns 0..31 for the highest set bit
-static int stbi__high_bit(unsigned int z)
-{
-   int n=0;
-   if (z == 0) return -1;
-   if (z >= 0x10000) n += 16, z >>= 16;
-   if (z >= 0x00100) n +=  8, z >>=     8;
-   if (z >= 0x00010) n +=  4, z >>=     4;
-   if (z >= 0x00004) n +=  2, z >>=     2;
-   if (z >= 0x00002) n +=  1, z >>=     1;
-   return n;
-}
-
-static int stbi__bitcount(unsigned int a)
-{
-   a = (a & 0x55555555) + ((a >>  1) & 0x55555555); // max 2
-   a = (a & 0x33333333) + ((a >>  2) & 0x33333333); // max 4
-   a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits
-   a = (a + (a >> 8)); // max 16 per 8 bits
-   a = (a + (a >> 16)); // max 32 per 8 bits
-   return a & 0xff;
+static int stbi__high_bit(unsigned int z) {
+    int n = 0;
+    if (z == 0)
+        return -1;
+    if (z >= 0x10000)
+        n += 16, z >>= 16;
+    if (z >= 0x00100)
+        n += 8, z >>= 8;
+    if (z >= 0x00010)
+        n += 4, z >>= 4;
+    if (z >= 0x00004)
+        n += 2, z >>= 2;
+    if (z >= 0x00002)
+        n += 1, z >>= 1;
+    return n;
+}
+
+static int stbi__bitcount(unsigned int a) {
+    a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2
+    a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4
+    a = (a + (a >> 4)) & 0x0f0f0f0f;                // max 8 per 4, now 8 bits
+    a = (a + (a >> 8));                             // max 16 per 8 bits
+    a = (a + (a >> 16));                            // max 32 per 8 bits
+    return a & 0xff;
 }
 
 // extract an arbitrarily-aligned N-bit value (N=bits)
 // from v, and then make it 8-bits long and fractionally
 // extend it to full full range.
-static int stbi__shiftsigned(int v, int shift, int bits)
-{
-   static unsigned int mul_table[9] = {
-         0,
-         0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/,
-         0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/,
-   };
-   static unsigned int shift_table[9] = {
-         0, 0,0,1,0,2,4,6,0,
-   };
-   if (shift < 0)
-         v <<= -shift;
-   else
-         v >>= shift;
-   STBI_ASSERT(v >= 0 && v < 256);
-   v >>= (8-bits);
-   STBI_ASSERT(bits >= 0 && bits <= 8);
-   return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
-}
-
-typedef struct
-{
-   int bpp, offset, hsz;
-   unsigned int mr,mg,mb,ma, all_a;
+static int stbi__shiftsigned(int v, int shift, int bits) {
+    static unsigned int mul_table[9] = {
+        0,
+        0xff /*0b11111111*/,
+        0x55 /*0b01010101*/,
+        0x49 /*0b01001001*/,
+        0x11 /*0b00010001*/,
+        0x21 /*0b00100001*/,
+        0x41 /*0b01000001*/,
+        0x81 /*0b10000001*/,
+        0x01 /*0b00000001*/,
+    };
+    static unsigned int shift_table[9] = {
+        0, 0, 0, 1, 0, 2, 4, 6, 0,
+    };
+    if (shift < 0)
+        v <<= -shift;
+    else
+        v >>= shift;
+    STBI_ASSERT(v >= 0 && v < 256);
+    v >>= (8 - bits);
+    STBI_ASSERT(bits >= 0 && bits <= 8);
+    return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits];
+}
+
+typedef struct {
+    int          bpp, offset, hsz;
+    unsigned int mr, mg, mb, ma, all_a;
 } stbi__bmp_data;
 
-static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
-{
-   int hsz;
-   if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP");
-   stbi__get32le(s); // discard filesize
-   stbi__get16le(s); // discard reserved
-   stbi__get16le(s); // discard reserved
-   info->offset = stbi__get32le(s);
-   info->hsz = hsz = stbi__get32le(s);
-   info->mr = info->mg = info->mb = info->ma = 0;
-
-   if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
-   if (hsz == 12) {
-         s->img_x = stbi__get16le(s);
-         s->img_y = stbi__get16le(s);
-   } else {
-         s->img_x = stbi__get32le(s);
-         s->img_y = stbi__get32le(s);
-   }
-   if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP");
-   info->bpp = stbi__get16le(s);
-   if (hsz != 12) {
-         int compress = stbi__get32le(s);
-         if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
-         stbi__get32le(s); // discard sizeof
-         stbi__get32le(s); // discard hres
-         stbi__get32le(s); // discard vres
-         stbi__get32le(s); // discard colorsused
-         stbi__get32le(s); // discard max important
-         if (hsz == 40 || hsz == 56) {
-                if (hsz == 56) {
-                       stbi__get32le(s);
-                       stbi__get32le(s);
-                       stbi__get32le(s);
-                       stbi__get32le(s);
-                }
-                if (info->bpp == 16 || info->bpp == 32) {
-                       if (compress == 0) {
-                          if (info->bpp == 32) {
-                                 info->mr = 0xffu << 16;
-                                 info->mg = 0xffu <<  8;
-                                 info->mb = 0xffu <<  0;
-                                 info->ma = 0xffu << 24;
-                                 info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
-                          } else {
-                                 info->mr = 31u << 10;
-                                 info->mg = 31u <<      5;
-                                 info->mb = 31u <<      0;
-                          }
-                       } else if (compress == 3) {
-                          info->mr = stbi__get32le(s);
-                          info->mg = stbi__get32le(s);
-                          info->mb = stbi__get32le(s);
-                          // not documented, but generated by photoshop and handled by mspaint
-                          if (info->mr == info->mg && info->mg == info->mb) {
-                                 // ?!?!?
-                                 return stbi__errpuc("bad BMP", "bad BMP");
-                          }
-                       } else
-                          return stbi__errpuc("bad BMP", "bad BMP");
-                }
-         } else {
-                int i;
-                if (hsz != 108 && hsz != 124)
-                       return stbi__errpuc("bad BMP", "bad BMP");
-                info->mr = stbi__get32le(s);
-                info->mg = stbi__get32le(s);
-                info->mb = stbi__get32le(s);
-                info->ma = stbi__get32le(s);
-                stbi__get32le(s); // discard color space
-                for (i=0; i < 12; ++i)
-                       stbi__get32le(s); // discard color space parameters
-                if (hsz == 124) {
-                       stbi__get32le(s); // discard rendering intent
-                       stbi__get32le(s); // discard offset of profile data
-                       stbi__get32le(s); // discard size of profile data
-                       stbi__get32le(s); // discard reserved
-                }
-         }
-   }
-   return (void *) 1;
-}
-
-
-static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   stbi_uc *out;
-   unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
-   stbi_uc pal[256][4];
-   int psize=0,i,j,width;
-   int flip_vertically, pad, target;
-   stbi__bmp_data info;
-   STBI_NOTUSED(ri);
-
-   info.all_a = 255;
-   if (stbi__bmp_parse_header(s, &info) == NULL)
-         return NULL; // error code already set
-
-   flip_vertically = ((int) s->img_y) > 0;
-   s->img_y = abs((int) s->img_y);
-
-   mr = info.mr;
-   mg = info.mg;
-   mb = info.mb;
-   ma = info.ma;
-   all_a = info.all_a;
-
-   if (info.hsz == 12) {
-         if (info.bpp < 24)
-                psize = (info.offset - 14 - 24) / 3;
-   } else {
-         if (info.bpp < 16)
-                psize = (info.offset - 14 - info.hsz) >> 2;
-   }
-
-   s->img_n = ma ? 4 : 3;
-   if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
-         target = req_comp;
-   else
-         target = s->img_n; // if they want monochrome, we'll post-convert
-
-   // sanity-check size
-   if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0))
-         return stbi__errpuc("too large", "Corrupt BMP");
-
-   out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0);
-   if (!out) return stbi__errpuc("outofmem", "Out of memory");
-   if (info.bpp < 16) {
-         int z=0;
-         if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); }
-         for (i=0; i < psize; ++i) {
-                pal[i][2] = stbi__get8(s);
-                pal[i][1] = stbi__get8(s);
-                pal[i][0] = stbi__get8(s);
-                if (info.hsz != 12) stbi__get8(s);
-                pal[i][3] = 255;
-         }
-         stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
-         if (info.bpp == 1) width = (s->img_x + 7) >> 3;
-         else if (info.bpp == 4) width = (s->img_x + 1) >> 1;
-         else if (info.bpp == 8) width = s->img_x;
-         else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); }
-         pad = (-width)&3;
-         if (info.bpp == 1) {
-                for (j=0; j < (int) s->img_y; ++j) {
-                       int bit_offset = 7, v = stbi__get8(s);
-                       for (i=0; i < (int) s->img_x; ++i) {
-                          int color = (v>>bit_offset)&0x1;
-                          out[z++] = pal[color][0];
-                          out[z++] = pal[color][1];
-                          out[z++] = pal[color][2];
-                          if((--bit_offset) < 0) {
-                                 bit_offset = 7;
-                                 v = stbi__get8(s);
-                          }
-                       }
-                       stbi__skip(s, pad);
-                }
-         } else {
-                for (j=0; j < (int) s->img_y; ++j) {
-                       for (i=0; i < (int) s->img_x; i += 2) {
-                          int v=stbi__get8(s),v2=0;
-                          if (info.bpp == 4) {
-                                 v2 = v & 15;
-                                 v >>= 4;
-                          }
-                          out[z++] = pal[v][0];
-                          out[z++] = pal[v][1];
-                          out[z++] = pal[v][2];
-                          if (target == 4) out[z++] = 255;
-                          if (i+1 == (int) s->img_x) break;
-                          v = (info.bpp == 8) ? stbi__get8(s) : v2;
-                          out[z++] = pal[v][0];
-                          out[z++] = pal[v][1];
-                          out[z++] = pal[v][2];
-                          if (target == 4) out[z++] = 255;
-                       }
-                       stbi__skip(s, pad);
-                }
-         }
-   } else {
-         int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
-         int z = 0;
-         int easy=0;
-         stbi__skip(s, info.offset - 14 - info.hsz);
-         if (info.bpp == 24) width = 3 * s->img_x;
-         else if (info.bpp == 16) width = 2*s->img_x;
-         else /* bpp = 32 and pad = 0 */ width=0;
-         pad = (-width) & 3;
-         if (info.bpp == 24) {
-                easy = 1;
-         } else if (info.bpp == 32) {
-                if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
-                       easy = 2;
-         }
-         if (!easy) {
-                if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
-                // right shift amt to put high bit in position #7
-                rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr);
-                gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
-                bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
-                ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
-         }
-         for (j=0; j < (int) s->img_y; ++j) {
-                if (easy) {
-                       for (i=0; i < (int) s->img_x; ++i) {
-                          unsigned char a;
-                          out[z+2] = stbi__get8(s);
-                          out[z+1] = stbi__get8(s);
-                          out[z+0] = stbi__get8(s);
-                          z += 3;
-                          a = (easy == 2 ? stbi__get8(s) : 255);
-                          all_a |= a;
-                          if (target == 4) out[z++] = a;
-                       }
-                } else {
-                       int bpp = info.bpp;
-                       for (i=0; i < (int) s->img_x; ++i) {
-                          stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
-                          unsigned int a;
-                          out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
-                          out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
-                          out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount));
-                          a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255);
-                          all_a |= a;
-                          if (target == 4) out[z++] = STBI__BYTECAST(a);
-                       }
-                }
-                stbi__skip(s, pad);
-         }
-   }
-
-   // if alpha channel is all 0s, replace with all 255s
-   if (target == 4 && all_a == 0)
-         for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
-                out[i] = 255;
-
-   if (flip_vertically) {
-         stbi_uc t;
-         for (j=0; j < (int) s->img_y>>1; ++j) {
-                stbi_uc *p1 = out +      j             *s->img_x*target;
-                stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
-                for (i=0; i < (int) s->img_x*target; ++i) {
-                       t = p1[i], p1[i] = p2[i], p2[i] = t;
-                }
-         }
-   }
-
-   if (req_comp && req_comp != target) {
-         out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y);
-         if (out == NULL) return out; // stbi__convert_format frees input on failure
-   }
-
-   *x = s->img_x;
-   *y = s->img_y;
-   if (comp) *comp = s->img_n;
-   return out;
+static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) {
+    int hsz;
+    if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M')
+        return stbi__errpuc("not BMP", "Corrupt BMP");
+    stbi__get32le(s); // discard filesize
+    stbi__get16le(s); // discard reserved
+    stbi__get16le(s); // discard reserved
+    info->offset = stbi__get32le(s);
+    info->hsz = hsz = stbi__get32le(s);
+    info->mr = info->mg = info->mb = info->ma = 0;
+
+    if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124)
+        return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
+    if (hsz == 12) {
+        s->img_x = stbi__get16le(s);
+        s->img_y = stbi__get16le(s);
+    } else {
+        s->img_x = stbi__get32le(s);
+        s->img_y = stbi__get32le(s);
+    }
+    if (stbi__get16le(s) != 1)
+        return stbi__errpuc("bad BMP", "bad BMP");
+    info->bpp = stbi__get16le(s);
+    if (hsz != 12) {
+        int compress = stbi__get32le(s);
+        if (compress == 1 || compress == 2)
+            return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
+        stbi__get32le(s); // discard sizeof
+        stbi__get32le(s); // discard hres
+        stbi__get32le(s); // discard vres
+        stbi__get32le(s); // discard colorsused
+        stbi__get32le(s); // discard max important
+        if (hsz == 40 || hsz == 56) {
+            if (hsz == 56) {
+                stbi__get32le(s);
+                stbi__get32le(s);
+                stbi__get32le(s);
+                stbi__get32le(s);
+            }
+            if (info->bpp == 16 || info->bpp == 32) {
+                if (compress == 0) {
+                    if (info->bpp == 32) {
+                        info->mr    = 0xffu << 16;
+                        info->mg    = 0xffu << 8;
+                        info->mb    = 0xffu << 0;
+                        info->ma    = 0xffu << 24;
+                        info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
+                    } else {
+                        info->mr = 31u << 10;
+                        info->mg = 31u << 5;
+                        info->mb = 31u << 0;
+                    }
+                } else if (compress == 3) {
+                    info->mr = stbi__get32le(s);
+                    info->mg = stbi__get32le(s);
+                    info->mb = stbi__get32le(s);
+                    // not documented, but generated by photoshop and handled by mspaint
+                    if (info->mr == info->mg && info->mg == info->mb) {
+                        // ?!?!?
+                        return stbi__errpuc("bad BMP", "bad BMP");
+                    }
+                } else
+                    return stbi__errpuc("bad BMP", "bad BMP");
+            }
+        } else {
+            int i;
+            if (hsz != 108 && hsz != 124)
+                return stbi__errpuc("bad BMP", "bad BMP");
+            info->mr = stbi__get32le(s);
+            info->mg = stbi__get32le(s);
+            info->mb = stbi__get32le(s);
+            info->ma = stbi__get32le(s);
+            stbi__get32le(s); // discard color space
+            for (i = 0; i < 12; ++i)
+                stbi__get32le(s); // discard color space parameters
+            if (hsz == 124) {
+                stbi__get32le(s); // discard rendering intent
+                stbi__get32le(s); // discard offset of profile data
+                stbi__get32le(s); // discard size of profile data
+                stbi__get32le(s); // discard reserved
+            }
+        }
+    }
+    return (void *)1;
+}
+
+static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) {
+    stbi_uc       *out;
+    unsigned int   mr = 0, mg = 0, mb = 0, ma = 0, all_a;
+    stbi_uc        pal[256][4];
+    int            psize = 0, i, j, width;
+    int            flip_vertically, pad, target;
+    stbi__bmp_data info;
+    STBI_NOTUSED(ri);
+
+    info.all_a = 255;
+    if (stbi__bmp_parse_header(s, &info) == NULL)
+        return NULL; // error code already set
+
+    flip_vertically = ((int)s->img_y) > 0;
+    s->img_y        = abs((int)s->img_y);
+
+    mr    = info.mr;
+    mg    = info.mg;
+    mb    = info.mb;
+    ma    = info.ma;
+    all_a = info.all_a;
+
+    if (info.hsz == 12) {
+        if (info.bpp < 24)
+            psize = (info.offset - 14 - 24) / 3;
+    } else {
+        if (info.bpp < 16)
+            psize = (info.offset - 14 - info.hsz) >> 2;
+    }
+
+    s->img_n = ma ? 4 : 3;
+    if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
+        target = req_comp;
+    else
+        target = s->img_n; // if they want monochrome, we'll post-convert
+
+    // sanity-check size
+    if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0))
+        return stbi__errpuc("too large", "Corrupt BMP");
+
+    out = (stbi_uc *)stbi__malloc_mad3(target, s->img_x, s->img_y, 0);
+    if (!out)
+        return stbi__errpuc("outofmem", "Out of memory");
+    if (info.bpp < 16) {
+        int z = 0;
+        if (psize == 0 || psize > 256) {
+            STBI_FREE(out);
+            return stbi__errpuc("invalid", "Corrupt BMP");
+        }
+        for (i = 0; i < psize; ++i) {
+            pal[i][2] = stbi__get8(s);
+            pal[i][1] = stbi__get8(s);
+            pal[i][0] = stbi__get8(s);
+            if (info.hsz != 12)
+                stbi__get8(s);
+            pal[i][3] = 255;
+        }
+        stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
+        if (info.bpp == 1)
+            width = (s->img_x + 7) >> 3;
+        else if (info.bpp == 4)
+            width = (s->img_x + 1) >> 1;
+        else if (info.bpp == 8)
+            width = s->img_x;
+        else {
+            STBI_FREE(out);
+            return stbi__errpuc("bad bpp", "Corrupt BMP");
+        }
+        pad = (-width) & 3;
+        if (info.bpp == 1) {
+            for (j = 0; j < (int)s->img_y; ++j) {
+                int bit_offset = 7, v = stbi__get8(s);
+                for (i = 0; i < (int)s->img_x; ++i) {
+                    int color = (v >> bit_offset) & 0x1;
+                    out[z++]  = pal[color][0];
+                    out[z++]  = pal[color][1];
+                    out[z++]  = pal[color][2];
+                    if ((--bit_offset) < 0) {
+                        bit_offset = 7;
+                        v          = stbi__get8(s);
+                    }
+                }
+                stbi__skip(s, pad);
+            }
+        } else {
+            for (j = 0; j < (int)s->img_y; ++j) {
+                for (i = 0; i < (int)s->img_x; i += 2) {
+                    int v = stbi__get8(s), v2 = 0;
+                    if (info.bpp == 4) {
+                        v2 = v & 15;
+                        v >>= 4;
+                    }
+                    out[z++] = pal[v][0];
+                    out[z++] = pal[v][1];
+                    out[z++] = pal[v][2];
+                    if (target == 4)
+                        out[z++] = 255;
+                    if (i + 1 == (int)s->img_x)
+                        break;
+                    v        = (info.bpp == 8) ? stbi__get8(s) : v2;
+                    out[z++] = pal[v][0];
+                    out[z++] = pal[v][1];
+                    out[z++] = pal[v][2];
+                    if (target == 4)
+                        out[z++] = 255;
+                }
+                stbi__skip(s, pad);
+            }
+        }
+    } else {
+        int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0;
+        int z    = 0;
+        int easy = 0;
+        stbi__skip(s, info.offset - 14 - info.hsz);
+        if (info.bpp == 24)
+            width = 3 * s->img_x;
+        else if (info.bpp == 16)
+            width = 2 * s->img_x;
+        else /* bpp = 32 and pad = 0 */
+            width = 0;
+        pad = (-width) & 3;
+        if (info.bpp == 24) {
+            easy = 1;
+        } else if (info.bpp == 32) {
+            if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
+                easy = 2;
+        }
+        if (!easy) {
+            if (!mr || !mg || !mb) {
+                STBI_FREE(out);
+                return stbi__errpuc("bad masks", "Corrupt BMP");
+            }
+            // right shift amt to put high bit in position #7
+            rshift = stbi__high_bit(mr) - 7;
+            rcount = stbi__bitcount(mr);
+            gshift = stbi__high_bit(mg) - 7;
+            gcount = stbi__bitcount(mg);
+            bshift = stbi__high_bit(mb) - 7;
+            bcount = stbi__bitcount(mb);
+            ashift = stbi__high_bit(ma) - 7;
+            acount = stbi__bitcount(ma);
+        }
+        for (j = 0; j < (int)s->img_y; ++j) {
+            if (easy) {
+                for (i = 0; i < (int)s->img_x; ++i) {
+                    unsigned char a;
+                    out[z + 2] = stbi__get8(s);
+                    out[z + 1] = stbi__get8(s);
+                    out[z + 0] = stbi__get8(s);
+                    z += 3;
+                    a = (easy == 2 ? stbi__get8(s) : 255);
+                    all_a |= a;
+                    if (target == 4)
+                        out[z++] = a;
+                }
+            } else {
+                int bpp = info.bpp;
+                for (i = 0; i < (int)s->img_x; ++i) {
+                    stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s));
+                    unsigned int a;
+                    out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
+                    out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
+                    out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount));
+                    a        = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255);
+                    all_a |= a;
+                    if (target == 4)
+                        out[z++] = STBI__BYTECAST(a);
+                }
+            }
+            stbi__skip(s, pad);
+        }
+    }
+
+    // if alpha channel is all 0s, replace with all 255s
+    if (target == 4 && all_a == 0)
+        for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4)
+            out[i] = 255;
+
+    if (flip_vertically) {
+        stbi_uc t;
+        for (j = 0; j < (int)s->img_y >> 1; ++j) {
+            stbi_uc *p1 = out + j * s->img_x * target;
+            stbi_uc *p2 = out + (s->img_y - 1 - j) * s->img_x * target;
+            for (i = 0; i < (int)s->img_x * target; ++i) {
+                t = p1[i], p1[i] = p2[i], p2[i] = t;
+            }
+        }
+    }
+
+    if (req_comp && req_comp != target) {
+        out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y);
+        if (out == NULL)
+            return out; // stbi__convert_format frees input on failure
+    }
+
+    *x = s->img_x;
+    *y = s->img_y;
+    if (comp)
+        *comp = s->img_n;
+    return out;
 }
 #endif
 
@@ -5320,330 +5603,332 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
 // by Jonathan Dummer
 #ifndef STBI_NO_TGA
 // returns STBI_rgb or whatever, 0 on error
-static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
-{
-   // only RGB or RGBA (incl. 16bit) or grey allowed
-   if (is_rgb16) *is_rgb16 = 0;
-   switch(bits_per_pixel) {
-         case 8:  return STBI_grey;
-         case 16: if(is_grey) return STBI_grey_alpha;
-                          // fallthrough
-         case 15: if(is_rgb16) *is_rgb16 = 1;
-                          return STBI_rgb;
-         case 24: // fallthrough
-         case 32: return bits_per_pixel/8;
-         default: return 0;
-   }
-}
-
-static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
-{
-       int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
-       int sz, tga_colormap_type;
-       stbi__get8(s);                                   // discard Offset
-       tga_colormap_type = stbi__get8(s); // colormap type
-       if( tga_colormap_type > 1 ) {
-               stbi__rewind(s);
-               return 0;          // only RGB or indexed allowed
-       }
-       tga_image_type = stbi__get8(s); // image type
-       if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
-               if (tga_image_type != 1 && tga_image_type != 9) {
-                       stbi__rewind(s);
-                       return 0;
-               }
-               stbi__skip(s,4);           // skip index of first colormap entry and number of entries
-               sz = stbi__get8(s);        //   check bits per palette color entry
-               if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) {
-                       stbi__rewind(s);
-                       return 0;
-               }
-               stbi__skip(s,4);           // skip image x and y origin
-               tga_colormap_bpp = sz;
-       } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
-               if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) {
-                       stbi__rewind(s);
-                       return 0; // only RGB or grey allowed, +/- RLE
-               }
-               stbi__skip(s,9); // skip colormap specification and image x/y origin
-               tga_colormap_bpp = 0;
-       }
-       tga_w = stbi__get16le(s);
-       if( tga_w < 1 ) {
-               stbi__rewind(s);
-               return 0;       // test width
-       }
-       tga_h = stbi__get16le(s);
-       if( tga_h < 1 ) {
-               stbi__rewind(s);
-               return 0;       // test height
-       }
-       tga_bits_per_pixel = stbi__get8(s); // bits per pixel
-       stbi__get8(s); // ignore alpha bits
-       if (tga_colormap_bpp != 0) {
-               if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
-                       // when using a colormap, tga_bits_per_pixel is the size of the indexes
-                       // I don't think anything but 8 or 16bit indexes makes sense
-                       stbi__rewind(s);
-                       return 0;
-               }
-               tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
-       } else {
-               tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
-       }
-       if(!tga_comp) {
-         stbi__rewind(s);
-         return 0;
-       }
-       if (x) *x = tga_w;
-       if (y) *y = tga_h;
-       if (comp) *comp = tga_comp;
-       return 1;                                       // seems to have passed everything
-}
-
-static int stbi__tga_test(stbi__context *s)
-{
-   int res = 0;
-   int sz, tga_color_type;
-   stbi__get8(s);         //   discard Offset
-   tga_color_type = stbi__get8(s);      //       color type
-   if ( tga_color_type > 1 ) goto errorEnd;      //   only RGB or indexed allowed
-   sz = stbi__get8(s);  //       image type
-   if ( tga_color_type == 1 ) { // colormapped (paletted) image
-         if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
-         stbi__skip(s,4);               // skip index of first colormap entry and number of entries
-         sz = stbi__get8(s);    //       check bits per palette color entry
-         if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
-         stbi__skip(s,4);               // skip image x and y origin
-   } else { // "normal" image w/o colormap
-         if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE
-         stbi__skip(s,9); // skip colormap specification and image x/y origin
-   }
-   if ( stbi__get16le(s) < 1 ) goto errorEnd;     //   test width
-   if ( stbi__get16le(s) < 1 ) goto errorEnd;     //   test height
-   sz = stbi__get8(s);  //       bits per pixel
-   if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
-   if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
-
-   res = 1; // if we got this far, everything's good and we can return 1 instead of 0
+static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int *is_rgb16) {
+    // only RGB or RGBA (incl. 16bit) or grey allowed
+    if (is_rgb16)
+        *is_rgb16 = 0;
+    switch (bits_per_pixel) {
+    case 8:
+        return STBI_grey;
+    case 16:
+        if (is_grey)
+            return STBI_grey_alpha;
+        // fallthrough
+    case 15:
+        if (is_rgb16)
+            *is_rgb16 = 1;
+        return STBI_rgb;
+    case 24: // fallthrough
+    case 32:
+        return bits_per_pixel / 8;
+    default:
+        return 0;
+    }
+}
+
+static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) {
+    int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
+    int sz, tga_colormap_type;
+    stbi__get8(s);                     // discard Offset
+    tga_colormap_type = stbi__get8(s); // colormap type
+    if (tga_colormap_type > 1) {
+        stbi__rewind(s);
+        return 0; // only RGB or indexed allowed
+    }
+    tga_image_type = stbi__get8(s); // image type
+    if (tga_colormap_type == 1) {   // colormapped (paletted) image
+        if (tga_image_type != 1 && tga_image_type != 9) {
+            stbi__rewind(s);
+            return 0;
+        }
+        stbi__skip(s, 4);   // skip index of first colormap entry and number of entries
+        sz = stbi__get8(s); // check bits per palette color entry
+        if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) {
+            stbi__rewind(s);
+            return 0;
+        }
+        stbi__skip(s, 4); // skip image x and y origin
+        tga_colormap_bpp = sz;
+    } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
+        if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) {
+            stbi__rewind(s);
+            return 0; // only RGB or grey allowed, +/- RLE
+        }
+        stbi__skip(s, 9); // skip colormap specification and image x/y origin
+        tga_colormap_bpp = 0;
+    }
+    tga_w = stbi__get16le(s);
+    if (tga_w < 1) {
+        stbi__rewind(s);
+        return 0; // test width
+    }
+    tga_h = stbi__get16le(s);
+    if (tga_h < 1) {
+        stbi__rewind(s);
+        return 0; // test height
+    }
+    tga_bits_per_pixel = stbi__get8(s); // bits per pixel
+    stbi__get8(s);                      // ignore alpha bits
+    if (tga_colormap_bpp != 0) {
+        if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
+            // when using a colormap, tga_bits_per_pixel is the size of the indexes
+            // I don't think anything but 8 or 16bit indexes makes sense
+            stbi__rewind(s);
+            return 0;
+        }
+        tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
+    } else {
+        tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
+    }
+    if (!tga_comp) {
+        stbi__rewind(s);
+        return 0;
+    }
+    if (x)
+        *x = tga_w;
+    if (y)
+        *y = tga_h;
+    if (comp)
+        *comp = tga_comp;
+    return 1; // seems to have passed everything
+}
+
+static int stbi__tga_test(stbi__context *s) {
+    int res = 0;
+    int sz, tga_color_type;
+    stbi__get8(s);                  // discard Offset
+    tga_color_type = stbi__get8(s); //   color type
+    if (tga_color_type > 1)
+        goto errorEnd;         //   only RGB or indexed allowed
+    sz = stbi__get8(s);        //        image type
+    if (tga_color_type == 1) { // colormapped (paletted) image
+        if (sz != 1 && sz != 9)
+            goto errorEnd;  // colortype 1 demands image type 1 or 9
+        stbi__skip(s, 4);   // skip index of first colormap entry and number of entries
+        sz = stbi__get8(s); //   check bits per palette color entry
+        if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32))
+            goto errorEnd;
+        stbi__skip(s, 4); // skip image x and y origin
+    } else {              // "normal" image w/o colormap
+        if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11))
+            goto errorEnd; // only RGB or grey allowed, +/- RLE
+        stbi__skip(s, 9);  // skip colormap specification and image x/y origin
+    }
+    if (stbi__get16le(s) < 1)
+        goto errorEnd; //      test width
+    if (stbi__get16le(s) < 1)
+        goto errorEnd;  //     test height
+    sz = stbi__get8(s); //       bits per pixel
+    if ((tga_color_type == 1) && (sz != 8) && (sz != 16))
+        goto errorEnd; // for colormapped images, bpp is size of an index
+    if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32))
+        goto errorEnd;
+
+    res = 1; // if we got this far, everything's good and we can return 1 instead of 0
 
 errorEnd:
-   stbi__rewind(s);
-   return res;
+    stbi__rewind(s);
+    return res;
 }
 
 // read 16bit value and convert to 24bit RGB
-static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
-{
-   stbi__uint16 px = (stbi__uint16)stbi__get16le(s);
-   stbi__uint16 fiveBitMask = 31;
-   // we have 3 channels with 5bits each
-   int r = (px >> 10) & fiveBitMask;
-   int g = (px >> 5) & fiveBitMask;
-   int b = px & fiveBitMask;
-   // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
-   out[0] = (stbi_uc)((r * 255)/31);
-   out[1] = (stbi_uc)((g * 255)/31);
-   out[2] = (stbi_uc)((b * 255)/31);
-
-   // some people claim that the most significant bit might be used for alpha
-   // (possibly if an alpha-bit is set in the "image descriptor byte")
-   // but that only made 16bit test images completely translucent..
-   // so let's treat all 15 and 16bit TGAs as RGB with no alpha.
-}
-
-static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   //  read in the TGA header stuff
-   int tga_offset = stbi__get8(s);
-   int tga_indexed = stbi__get8(s);
-   int tga_image_type = stbi__get8(s);
-   int tga_is_RLE = 0;
-   int tga_palette_start = stbi__get16le(s);
-   int tga_palette_len = stbi__get16le(s);
-   int tga_palette_bits = stbi__get8(s);
-   int tga_x_origin = stbi__get16le(s);
-   int tga_y_origin = stbi__get16le(s);
-   int tga_width = stbi__get16le(s);
-   int tga_height = stbi__get16le(s);
-   int tga_bits_per_pixel = stbi__get8(s);
-   int tga_comp, tga_rgb16=0;
-   int tga_inverted = stbi__get8(s);
-   // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
-   //  image data
-   unsigned char *tga_data;
-   unsigned char *tga_palette = NULL;
-   int i, j;
-   unsigned char raw_data[4] = {0};
-   int RLE_count = 0;
-   int RLE_repeating = 0;
-   int read_next_pixel = 1;
-   STBI_NOTUSED(ri);
-
-   //  do a tiny bit of precessing
-   if ( tga_image_type >= 8 )
-   {
-         tga_image_type -= 8;
-         tga_is_RLE = 1;
-   }
-   tga_inverted = 1 - ((tga_inverted >> 5) & 1);
-
-   //  If I'm paletted, then I'll use the number of bits from the palette
-   if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
-   else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
-
-   if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
-         return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
-
-   //  tga info
-   *x = tga_width;
-   *y = tga_height;
-   if (comp) *comp = tga_comp;
-
-   if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0))
-         return stbi__errpuc("too large", "Corrupt TGA");
-
-   tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
-   if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
-
-   // skip to the data's starting position (offset usually = 0)
-   stbi__skip(s, tga_offset );
-
-   if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) {
-         for (i=0; i < tga_height; ++i) {
-                int row = tga_inverted ? tga_height -i - 1 : i;
-                stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
-                stbi__getn(s, tga_row, tga_width * tga_comp);
-         }
-   } else  {
-         //   do I need to load a palette?
-         if ( tga_indexed)
-         {
-                //       any data to skip? (offset usually = 0)
-                stbi__skip(s, tga_palette_start );
-                //       load the palette
-                tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);
-                if (!tga_palette) {
-                       STBI_FREE(tga_data);
-                       return stbi__errpuc("outofmem", "Out of memory");
-                }
-                if (tga_rgb16) {
-                       stbi_uc *pal_entry = tga_palette;
-                       STBI_ASSERT(tga_comp == STBI_rgb);
-                       for (i=0; i < tga_palette_len; ++i) {
-                          stbi__tga_read_rgb16(s, pal_entry);
-                          pal_entry += tga_comp;
-                       }
-                } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
-                          STBI_FREE(tga_data);
-                          STBI_FREE(tga_palette);
-                          return stbi__errpuc("bad palette", "Corrupt TGA");
-                }
-         }
-         //   load the data
-         for (i=0; i < tga_width * tga_height; ++i)
-         {
-                //       if I'm in RLE mode, do I need to get a RLE stbi__pngchunk?
-                if ( tga_is_RLE )
-                {
-                       if ( RLE_count == 0 )
-                       {
-                          //   yep, get the next byte as a RLE command
-                          int RLE_cmd = stbi__get8(s);
-                          RLE_count = 1 + (RLE_cmd & 127);
-                          RLE_repeating = RLE_cmd >> 7;
-                          read_next_pixel = 1;
-                       } else if ( !RLE_repeating )
-                       {
-                          read_next_pixel = 1;
-                       }
-                } else
-                {
-                       read_next_pixel = 1;
-                }
-                //       OK, if I need to read a pixel, do it now
-                if ( read_next_pixel )
-                {
-                       //       load however much data we did have
-                       if ( tga_indexed )
-                       {
-                          // read in index, then perform the lookup
-                          int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
-                          if ( pal_idx >= tga_palette_len ) {
-                                 // invalid index
-                                 pal_idx = 0;
-                          }
-                          pal_idx *= tga_comp;
-                          for (j = 0; j < tga_comp; ++j) {
-                                 raw_data[j] = tga_palette[pal_idx+j];
-                          }
-                       } else if(tga_rgb16) {
-                          STBI_ASSERT(tga_comp == STBI_rgb);
-                          stbi__tga_read_rgb16(s, raw_data);
-                       } else {
-                          //   read in the data raw
-                          for (j = 0; j < tga_comp; ++j) {
-                                 raw_data[j] = stbi__get8(s);
-                          }
-                       }
-                       //       clear the reading flag for the next pixel
-                       read_next_pixel = 0;
-                } // end of reading a pixel
-
-                // copy data
-                for (j = 0; j < tga_comp; ++j)
-                  tga_data[i*tga_comp+j] = raw_data[j];
-
-                //       in case we're in RLE mode, keep counting down
-                --RLE_count;
-         }
-         //   do I need to invert the image?
-         if ( tga_inverted )
-         {
-                for (j = 0; j*2 < tga_height; ++j)
-                {
-                       int index1 = j * tga_width * tga_comp;
-                       int index2 = (tga_height - 1 - j) * tga_width * tga_comp;
-                       for (i = tga_width * tga_comp; i > 0; --i)
-                       {
-                          unsigned char temp = tga_data[index1];
-                          tga_data[index1] = tga_data[index2];
-                          tga_data[index2] = temp;
-                          ++index1;
-                          ++index2;
-                       }
-                }
-         }
-         //   clear my palette, if I had one
-         if ( tga_palette != NULL )
-         {
-                STBI_FREE( tga_palette );
-         }
-   }
-
-   // swap RGB - if the source data was RGB16, it already is in the right order
-   if (tga_comp >= 3 && !tga_rgb16)
-   {
-         unsigned char* tga_pixel = tga_data;
-         for (i=0; i < tga_width * tga_height; ++i)
-         {
-                unsigned char temp = tga_pixel[0];
-                tga_pixel[0] = tga_pixel[2];
-                tga_pixel[2] = temp;
-                tga_pixel += tga_comp;
-         }
-   }
-
-   // convert to target component count
-   if (req_comp && req_comp != tga_comp)
-         tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height);
-
-   //  the things I do to get rid of an error message, and yet keep
-   //  Microsoft's C compilers happy... [8^(
-   tga_palette_start = tga_palette_len = tga_palette_bits =
-                tga_x_origin = tga_y_origin = 0;
-   //  OK, done
-   return tga_data;
+static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc *out) {
+    stbi__uint16 px          = (stbi__uint16)stbi__get16le(s);
+    stbi__uint16 fiveBitMask = 31;
+    // we have 3 channels with 5bits each
+    int r = (px >> 10) & fiveBitMask;
+    int g = (px >> 5) & fiveBitMask;
+    int b = px & fiveBitMask;
+    // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
+    out[0] = (stbi_uc)((r * 255) / 31);
+    out[1] = (stbi_uc)((g * 255) / 31);
+    out[2] = (stbi_uc)((b * 255) / 31);
+
+    // some people claim that the most significant bit might be used for alpha
+    // (possibly if an alpha-bit is set in the "image descriptor byte")
+    // but that only made 16bit test images completely translucent..
+    // so let's treat all 15 and 16bit TGAs as RGB with no alpha.
+}
+
+static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) {
+    // read in the TGA header stuff
+    int tga_offset         = stbi__get8(s);
+    int tga_indexed        = stbi__get8(s);
+    int tga_image_type     = stbi__get8(s);
+    int tga_is_RLE         = 0;
+    int tga_palette_start  = stbi__get16le(s);
+    int tga_palette_len    = stbi__get16le(s);
+    int tga_palette_bits   = stbi__get8(s);
+    int tga_x_origin       = stbi__get16le(s);
+    int tga_y_origin       = stbi__get16le(s);
+    int tga_width          = stbi__get16le(s);
+    int tga_height         = stbi__get16le(s);
+    int tga_bits_per_pixel = stbi__get8(s);
+    int tga_comp, tga_rgb16 = 0;
+    int tga_inverted = stbi__get8(s);
+    // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
+    // image data
+    unsigned char *tga_data;
+    unsigned char *tga_palette = NULL;
+    int            i, j;
+    unsigned char  raw_data[4]     = {0};
+    int            RLE_count       = 0;
+    int            RLE_repeating   = 0;
+    int            read_next_pixel = 1;
+    STBI_NOTUSED(ri);
+
+    // do a tiny bit of precessing
+    if (tga_image_type >= 8) {
+        tga_image_type -= 8;
+        tga_is_RLE = 1;
+    }
+    tga_inverted = 1 - ((tga_inverted >> 5) & 1);
+
+    // If I'm paletted, then I'll use the number of bits from the palette
+    if (tga_indexed)
+        tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
+    else
+        tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
+
+    if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
+        return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
+
+    // tga info
+    *x = tga_width;
+    *y = tga_height;
+    if (comp)
+        *comp = tga_comp;
+
+    if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0))
+        return stbi__errpuc("too large", "Corrupt TGA");
+
+    tga_data = (unsigned char *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
+    if (!tga_data)
+        return stbi__errpuc("outofmem", "Out of memory");
+
+    // skip to the data's starting position (offset usually = 0)
+    stbi__skip(s, tga_offset);
+
+    if (!tga_indexed && !tga_is_RLE && !tga_rgb16) {
+        for (i = 0; i < tga_height; ++i) {
+            int      row     = tga_inverted ? tga_height - i - 1 : i;
+            stbi_uc *tga_row = tga_data + row * tga_width * tga_comp;
+            stbi__getn(s, tga_row, tga_width * tga_comp);
+        }
+    } else {
+        //   do I need to load a palette?
+        if (tga_indexed) {
+            //   any data to skip? (offset usually = 0)
+            stbi__skip(s, tga_palette_start);
+            //   load the palette
+            tga_palette = (unsigned char *)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);
+            if (!tga_palette) {
+                STBI_FREE(tga_data);
+                return stbi__errpuc("outofmem", "Out of memory");
+            }
+            if (tga_rgb16) {
+                stbi_uc *pal_entry = tga_palette;
+                STBI_ASSERT(tga_comp == STBI_rgb);
+                for (i = 0; i < tga_palette_len; ++i) {
+                    stbi__tga_read_rgb16(s, pal_entry);
+                    pal_entry += tga_comp;
+                }
+            } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
+                STBI_FREE(tga_data);
+                STBI_FREE(tga_palette);
+                return stbi__errpuc("bad palette", "Corrupt TGA");
+            }
+        }
+        //   load the data
+        for (i = 0; i < tga_width * tga_height; ++i) {
+            //   if I'm in RLE mode, do I need to get a RLE stbi__pngchunk?
+            if (tga_is_RLE) {
+                if (RLE_count == 0) {
+                    // yep, get the next byte as a RLE command
+                    int RLE_cmd     = stbi__get8(s);
+                    RLE_count       = 1 + (RLE_cmd & 127);
+                    RLE_repeating   = RLE_cmd >> 7;
+                    read_next_pixel = 1;
+                } else if (!RLE_repeating) {
+                    read_next_pixel = 1;
+                }
+            } else {
+                read_next_pixel = 1;
+            }
+            //   OK, if I need to read a pixel, do it now
+            if (read_next_pixel) {
+                //      load however much data we did have
+                if (tga_indexed) {
+                    // read in index, then perform the lookup
+                    int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
+                    if (pal_idx >= tga_palette_len) {
+                        // invalid index
+                        pal_idx = 0;
+                    }
+                    pal_idx *= tga_comp;
+                    for (j = 0; j < tga_comp; ++j) {
+                        raw_data[j] = tga_palette[pal_idx + j];
+                    }
+                } else if (tga_rgb16) {
+                    STBI_ASSERT(tga_comp == STBI_rgb);
+                    stbi__tga_read_rgb16(s, raw_data);
+                } else {
+                    // read in the data raw
+                    for (j = 0; j < tga_comp; ++j) {
+                        raw_data[j] = stbi__get8(s);
+                    }
+                }
+                //      clear the reading flag for the next pixel
+                read_next_pixel = 0;
+            } // end of reading a pixel
+
+            // copy data
+            for (j = 0; j < tga_comp; ++j)
+                tga_data[i * tga_comp + j] = raw_data[j];
+
+            //   in case we're in RLE mode, keep counting down
+            --RLE_count;
+        }
+        //   do I need to invert the image?
+        if (tga_inverted) {
+            for (j = 0; j * 2 < tga_height; ++j) {
+                int index1 = j * tga_width * tga_comp;
+                int index2 = (tga_height - 1 - j) * tga_width * tga_comp;
+                for (i = tga_width * tga_comp; i > 0; --i) {
+                    unsigned char temp = tga_data[index1];
+                    tga_data[index1]   = tga_data[index2];
+                    tga_data[index2]   = temp;
+                    ++index1;
+                    ++index2;
+                }
+            }
+        }
+        //   clear my palette, if I had one
+        if (tga_palette != NULL) {
+            STBI_FREE(tga_palette);
+        }
+    }
+
+    // swap RGB - if the source data was RGB16, it already is in the right order
+    if (tga_comp >= 3 && !tga_rgb16) {
+        unsigned char *tga_pixel = tga_data;
+        for (i = 0; i < tga_width * tga_height; ++i) {
+            unsigned char temp = tga_pixel[0];
+            tga_pixel[0]       = tga_pixel[2];
+            tga_pixel[2]       = temp;
+            tga_pixel += tga_comp;
+        }
+    }
+
+    // convert to target component count
+    if (req_comp && req_comp != tga_comp)
+        tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height);
+
+    // the things I do to get rid of an error message, and yet keep
+    // Microsoft's C compilers happy... [8^(
+    tga_palette_start = tga_palette_len = tga_palette_bits = tga_x_origin = tga_y_origin = 0;
+    // OK, done
+    return tga_data;
 }
 #endif
 
@@ -5651,247 +5936,249 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
 // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB
 
 #ifndef STBI_NO_PSD
-static int stbi__psd_test(stbi__context *s)
-{
-   int r = (stbi__get32be(s) == 0x38425053);
-   stbi__rewind(s);
-   return r;
-}
-
-static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount)
-{
-   int count, nleft, len;
-
-   count = 0;
-   while ((nleft = pixelCount - count) > 0) {
-         len = stbi__get8(s);
-         if (len == 128) {
-                // No-op.
-         } else if (len < 128) {
-                // Copy next len+1 bytes literally.
-                len++;
-                if (len > nleft) return 0; // corrupt data
-                count += len;
-                while (len) {
-                       *p = stbi__get8(s);
-                       p += 4;
-                       len--;
-                }
-         } else if (len > 128) {
-                stbi_uc   val;
-                // Next -len+1 bytes in the dest are replicated from next source byte.
-                // (Interpret len as a negative 8-bit int.)
-                len = 257 - len;
-                if (len > nleft) return 0; // corrupt data
-                val = stbi__get8(s);
-                count += len;
-                while (len) {
-                       *p = val;
-                       p += 4;
-                       len--;
-                }
-         }
-   }
-
-   return 1;
-}
-
-static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
-{
-   int pixelCount;
-   int channelCount, compression;
-   int channel, i;
-   int bitdepth;
-   int w,h;
-   stbi_uc *out;
-   STBI_NOTUSED(ri);
-
-   // Check identifier
-   if (stbi__get32be(s) != 0x38425053)  // "8BPS"
-         return stbi__errpuc("not PSD", "Corrupt PSD image");
-
-   // Check file type version.
-   if (stbi__get16be(s) != 1)
-         return stbi__errpuc("wrong version", "Unsupported version of PSD image");
-
-   // Skip 6 reserved bytes.
-   stbi__skip(s, 6 );
-
-   // Read the number of channels (R, G, B, A, etc).
-   channelCount = stbi__get16be(s);
-   if (channelCount < 0 || channelCount > 16)
-         return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image");
-
-   // Read the rows and columns of the image.
-   h = stbi__get32be(s);
-   w = stbi__get32be(s);
-
-   // Make sure the depth is 8 bits.
-   bitdepth = stbi__get16be(s);
-   if (bitdepth != 8 && bitdepth != 16)
-         return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit");
-
-   // Make sure the color mode is RGB.
-   // Valid options are:
-   //  0: Bitmap
-   //  1: Grayscale
-   //  2: Indexed color
-   //  3: RGB color
-   //  4: CMYK color
-   //  7: Multichannel
-   //  8: Duotone
-   //  9: Lab color
-   if (stbi__get16be(s) != 3)
-         return stbi__errpuc("wrong color format", "PSD is not in RGB color format");
-
-   // Skip the Mode Data.  (It's the palette for indexed color; other info for other modes.)
-   stbi__skip(s,stbi__get32be(s) );
-
-   // Skip the image resources.         (resolution, pen tool paths, etc)
-   stbi__skip(s, stbi__get32be(s) );
-
-   // Skip the reserved data.
-   stbi__skip(s, stbi__get32be(s) );
-
-   // Find out if the data is compressed.
-   // Known values:
-   //  0: no compression
-   //  1: RLE compressed
-   compression = stbi__get16be(s);
-   if (compression > 1)
-         return stbi__errpuc("bad compression", "PSD has an unknown compression format");
-
-   // Check size
-   if (!stbi__mad3sizes_valid(4, w, h, 0))
-         return stbi__errpuc("too large", "Corrupt PSD");
-
-   // Create the destination image.
-
-   if (!compression && bitdepth == 16 && bpc == 16) {
-         out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0);
-         ri->bits_per_channel = 16;
-   } else
-         out = (stbi_uc *) stbi__malloc(4 * w*h);
-
-   if (!out) return stbi__errpuc("outofmem", "Out of memory");
-   pixelCount = w*h;
-
-   // Initialize the data to zero.
-   //memset( out, 0, pixelCount * 4 );
-
-   // Finally, the image data.
-   if (compression) {
-         // RLE as used by .PSD and .TIFF
-         // Loop until you get the number of unpacked bytes you are expecting:
-         //     Read the next source byte into n.
-         //     If n is between 0 and 127 inclusive, copy the next n+1 bytes literally.
-         //     Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times.
-         //     Else if n is 128, noop.
-         // Endloop
-
-         // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
-         // which we're going to just skip.
-         stbi__skip(s, h * channelCount * 2 );
-
-         // Read the RLE data by channel.
-         for (channel = 0; channel < 4; channel++) {
-                stbi_uc *p;
-
-                p = out+channel;
-                if (channel >= channelCount) {
-                       // Fill this channel with default data.
-                       for (i = 0; i < pixelCount; i++, p += 4)
-                          *p = (channel == 3 ? 255 : 0);
-                } else {
-                       // Read the RLE data.
-                       if (!stbi__psd_decode_rle(s, p, pixelCount)) {
-                          STBI_FREE(out);
-                          return stbi__errpuc("corrupt", "bad RLE data");
-                       }
-                }
-         }
-
-   } else {
-         // We're at the raw image data.  It's each channel in order (Red, Green, Blue, Alpha, ...)
-         // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image.
-
-         // Read the data by channel.
-         for (channel = 0; channel < 4; channel++) {
-                if (channel >= channelCount) {
-                       // Fill this channel with default data.
-                       if (bitdepth == 16 && bpc == 16) {
-                          stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
-                          stbi__uint16 val = channel == 3 ? 65535 : 0;
-                          for (i = 0; i < pixelCount; i++, q += 4)
-                                 *q = val;
-                       } else {
-                          stbi_uc *p = out+channel;
-                          stbi_uc val = channel == 3 ? 255 : 0;
-                          for (i = 0; i < pixelCount; i++, p += 4)
-                                 *p = val;
-                       }
-                } else {
-                       if (ri->bits_per_channel == 16) {        // output bpc
-                          stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
-                          for (i = 0; i < pixelCount; i++, q += 4)
-                                 *q = (stbi__uint16) stbi__get16be(s);
-                       } else {
-                          stbi_uc *p = out+channel;
-                          if (bitdepth == 16) {  // input bpc
-                                 for (i = 0; i < pixelCount; i++, p += 4)
-                                        *p = (stbi_uc) (stbi__get16be(s) >> 8);
-                          } else {
-                                 for (i = 0; i < pixelCount; i++, p += 4)
-                                        *p = stbi__get8(s);
-                          }
-                       }
-                }
-         }
-   }
-
-   // remove weird white matte from PSD
-   if (channelCount >= 4) {
-         if (ri->bits_per_channel == 16) {
-                for (i=0; i < w*h; ++i) {
-                       stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i;
-                       if (pixel[3] != 0 && pixel[3] != 65535) {
-                          float a = pixel[3] / 65535.0f;
-                          float ra = 1.0f / a;
-                          float inv_a = 65535.0f * (1 - ra);
-                          pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a);
-                          pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a);
-                          pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a);
-                       }
-                }
-         } else {
-                for (i=0; i < w*h; ++i) {
-                       unsigned char *pixel = out + 4*i;
-                       if (pixel[3] != 0 && pixel[3] != 255) {
-                          float a = pixel[3] / 255.0f;
-                          float ra = 1.0f / a;
-                          float inv_a = 255.0f * (1 - ra);
-                          pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
-                          pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
-                          pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
-                       }
-                }
-         }
-   }
-
-   // convert to desired output format
-   if (req_comp && req_comp != 4) {
-         if (ri->bits_per_channel == 16)
-                out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h);
-         else
-                out = stbi__convert_format(out, 4, req_comp, w, h);
-         if (out == NULL) return out; // stbi__convert_format frees input on failure
-   }
-
-   if (comp) *comp = 4;
-   *y = h;
-   *x = w;
-
-   return out;
+static int stbi__psd_test(stbi__context *s) {
+    int r = (stbi__get32be(s) == 0x38425053);
+    stbi__rewind(s);
+    return r;
+}
+
+static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) {
+    int count, nleft, len;
+
+    count = 0;
+    while ((nleft = pixelCount - count) > 0) {
+        len = stbi__get8(s);
+        if (len == 128) {
+            // No-op.
+        } else if (len < 128) {
+            // Copy next len+1 bytes literally.
+            len++;
+            if (len > nleft)
+                return 0; // corrupt data
+            count += len;
+            while (len) {
+                *p = stbi__get8(s);
+                p += 4;
+                len--;
+            }
+        } else if (len > 128) {
+            stbi_uc val;
+            // Next -len+1 bytes in the dest are replicated from next source byte.
+            // (Interpret len as a negative 8-bit int.)
+            len = 257 - len;
+            if (len > nleft)
+                return 0; // corrupt data
+            val = stbi__get8(s);
+            count += len;
+            while (len) {
+                *p = val;
+                p += 4;
+                len--;
+            }
+        }
+    }
+
+    return 1;
+}
+
+static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) {
+    int      pixelCount;
+    int      channelCount, compression;
+    int      channel, i;
+    int      bitdepth;
+    int      w, h;
+    stbi_uc *out;
+    STBI_NOTUSED(ri);
+
+    // Check identifier
+    if (stbi__get32be(s) != 0x38425053) // "8BPS"
+        return stbi__errpuc("not PSD", "Corrupt PSD image");
+
+    // Check file type version.
+    if (stbi__get16be(s) != 1)
+        return stbi__errpuc("wrong version", "Unsupported version of PSD image");
+
+    // Skip 6 reserved bytes.
+    stbi__skip(s, 6);
+
+    // Read the number of channels (R, G, B, A, etc).
+    channelCount = stbi__get16be(s);
+    if (channelCount < 0 || channelCount > 16)
+        return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image");
+
+    // Read the rows and columns of the image.
+    h = stbi__get32be(s);
+    w = stbi__get32be(s);
+
+    // Make sure the depth is 8 bits.
+    bitdepth = stbi__get16be(s);
+    if (bitdepth != 8 && bitdepth != 16)
+        return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit");
+
+    // Make sure the color mode is RGB.
+    // Valid options are:
+    // 0: Bitmap
+    // 1: Grayscale
+    // 2: Indexed color
+    // 3: RGB color
+    // 4: CMYK color
+    // 7: Multichannel
+    // 8: Duotone
+    // 9: Lab color
+    if (stbi__get16be(s) != 3)
+        return stbi__errpuc("wrong color format", "PSD is not in RGB color format");
+
+    // Skip the Mode Data.  (It's the palette for indexed color; other info for other modes.)
+    stbi__skip(s, stbi__get32be(s));
+
+    // Skip the image resources.        (resolution, pen tool paths, etc)
+    stbi__skip(s, stbi__get32be(s));
+
+    // Skip the reserved data.
+    stbi__skip(s, stbi__get32be(s));
+
+    // Find out if the data is compressed.
+    // Known values:
+    // 0: no compression
+    // 1: RLE compressed
+    compression = stbi__get16be(s);
+    if (compression > 1)
+        return stbi__errpuc("bad compression", "PSD has an unknown compression format");
+
+    // Check size
+    if (!stbi__mad3sizes_valid(4, w, h, 0))
+        return stbi__errpuc("too large", "Corrupt PSD");
+
+    // Create the destination image.
+
+    if (!compression && bitdepth == 16 && bpc == 16) {
+        out                  = (stbi_uc *)stbi__malloc_mad3(8, w, h, 0);
+        ri->bits_per_channel = 16;
+    } else
+        out = (stbi_uc *)stbi__malloc(4 * w * h);
+
+    if (!out)
+        return stbi__errpuc("outofmem", "Out of memory");
+    pixelCount = w * h;
+
+    // Initialize the data to zero.
+    // memset( out, 0, pixelCount * 4 );
+
+    // Finally, the image data.
+    if (compression) {
+        // RLE as used by .PSD and .TIFF
+        // Loop until you get the number of unpacked bytes you are expecting:
+        //      Read the next source byte into n.
+        //      If n is between 0 and 127 inclusive, copy the next n+1 bytes literally.
+        //      Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times.
+        //      Else if n is 128, noop.
+        // Endloop
+
+        // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
+        // which we're going to just skip.
+        stbi__skip(s, h * channelCount * 2);
+
+        // Read the RLE data by channel.
+        for (channel = 0; channel < 4; channel++) {
+            stbi_uc *p;
+
+            p = out + channel;
+            if (channel >= channelCount) {
+                // Fill this channel with default data.
+                for (i = 0; i < pixelCount; i++, p += 4)
+                    *p = (channel == 3 ? 255 : 0);
+            } else {
+                // Read the RLE data.
+                if (!stbi__psd_decode_rle(s, p, pixelCount)) {
+                    STBI_FREE(out);
+                    return stbi__errpuc("corrupt", "bad RLE data");
+                }
+            }
+        }
+
+    } else {
+        // We're at the raw image data.  It's each channel in order (Red, Green, Blue, Alpha, ...)
+        // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image.
+
+        // Read the data by channel.
+        for (channel = 0; channel < 4; channel++) {
+            if (channel >= channelCount) {
+                // Fill this channel with default data.
+                if (bitdepth == 16 && bpc == 16) {
+                    stbi__uint16 *q   = ((stbi__uint16 *)out) + channel;
+                    stbi__uint16  val = channel == 3 ? 65535 : 0;
+                    for (i = 0; i < pixelCount; i++, q += 4)
+                        *q = val;
+                } else {
+                    stbi_uc *p   = out + channel;
+                    stbi_uc  val = channel == 3 ? 255 : 0;
+                    for (i = 0; i < pixelCount; i++, p += 4)
+                        *p = val;
+                }
+            } else {
+                if (ri->bits_per_channel == 16) { // output bpc
+                    stbi__uint16 *q = ((stbi__uint16 *)out) + channel;
+                    for (i = 0; i < pixelCount; i++, q += 4)
+                        *q = (stbi__uint16)stbi__get16be(s);
+                } else {
+                    stbi_uc *p = out + channel;
+                    if (bitdepth == 16) { // input bpc
+                        for (i = 0; i < pixelCount; i++, p += 4)
+                            *p = (stbi_uc)(stbi__get16be(s) >> 8);
+                    } else {
+                        for (i = 0; i < pixelCount; i++, p += 4)
+                            *p = stbi__get8(s);
+                    }
+                }
+            }
+        }
+    }
+
+    // remove weird white matte from PSD
+    if (channelCount >= 4) {
+        if (ri->bits_per_channel == 16) {
+            for (i = 0; i < w * h; ++i) {
+                stbi__uint16 *pixel = (stbi__uint16 *)out + 4 * i;
+                if (pixel[3] != 0 && pixel[3] != 65535) {
+                    float a     = pixel[3] / 65535.0f;
+                    float ra    = 1.0f / a;
+                    float inv_a = 65535.0f * (1 - ra);
+                    pixel[0]    = (stbi__uint16)(pixel[0] * ra + inv_a);
+                    pixel[1]    = (stbi__uint16)(pixel[1] * ra + inv_a);
+                    pixel[2]    = (stbi__uint16)(pixel[2] * ra + inv_a);
+                }
+            }
+        } else {
+            for (i = 0; i < w * h; ++i) {
+                unsigned char *pixel = out + 4 * i;
+                if (pixel[3] != 0 && pixel[3] != 255) {
+                    float a     = pixel[3] / 255.0f;
+                    float ra    = 1.0f / a;
+                    float inv_a = 255.0f * (1 - ra);
+                    pixel[0]    = (unsigned char)(pixel[0] * ra + inv_a);
+                    pixel[1]    = (unsigned char)(pixel[1] * ra + inv_a);
+                    pixel[2]    = (unsigned char)(pixel[2] * ra + inv_a);
+                }
+            }
+        }
+    }
+
+    // convert to desired output format
+    if (req_comp && req_comp != 4) {
+        if (ri->bits_per_channel == 16)
+            out = (stbi_uc *)stbi__convert_format16((stbi__uint16 *)out, 4, req_comp, w, h);
+        else
+            out = stbi__convert_format(out, 4, req_comp, w, h);
+        if (out == NULL)
+            return out; // stbi__convert_format frees input on failure
+    }
+
+    if (comp)
+        *comp = 4;
+    *y = h;
+    *x = w;
+
+    return out;
 }
 #endif
 
@@ -5903,211 +6190,213 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
 // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/
 
 #ifndef STBI_NO_PIC
-static int stbi__pic_is4(stbi__context *s,const char *str)
-{
-   int i;
-   for (i=0; i<4; ++i)
-         if (stbi__get8(s) != (stbi_uc)str[i])
-                return 0;
+static int stbi__pic_is4(stbi__context *s, const char *str) {
+    int i;
+    for (i = 0; i < 4; ++i)
+        if (stbi__get8(s) != (stbi_uc)str[i])
+            return 0;
 
-   return 1;
+    return 1;
 }
 
-static int stbi__pic_test_core(stbi__context *s)
-{
-   int i;
+static int stbi__pic_test_core(stbi__context *s) {
+    int i;
 
-   if (!stbi__pic_is4(s,"\x53\x80\xF6\x34"))
-         return 0;
+    if (!stbi__pic_is4(s, "\x53\x80\xF6\x34"))
+        return 0;
 
-   for(i=0;i<84;++i)
-         stbi__get8(s);
+    for (i = 0; i < 84; ++i)
+        stbi__get8(s);
 
-   if (!stbi__pic_is4(s,"PICT"))
-         return 0;
+    if (!stbi__pic_is4(s, "PICT"))
+        return 0;
 
-   return 1;
+    return 1;
 }
 
-typedef struct
-{
-   stbi_uc size,type,channel;
+typedef struct {
+    stbi_uc size, type, channel;
 } stbi__pic_packet;
 
-static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest)
-{
-   int mask=0x80, i;
+static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) {
+    int mask = 0x80, i;
 
-   for (i=0; i<4; ++i, mask>>=1) {
-         if (channel & mask) {
-                if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short");
-                dest[i]=stbi__get8(s);
-         }
-   }
+    for (i = 0; i < 4; ++i, mask >>= 1) {
+        if (channel & mask) {
+            if (stbi__at_eof(s))
+                return stbi__errpuc("bad file", "PIC file too short");
+            dest[i] = stbi__get8(s);
+        }
+    }
 
-   return dest;
+    return dest;
 }
 
-static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src)
-{
-   int mask=0x80,i;
+static void stbi__copyval(int channel, stbi_uc *dest, const stbi_uc *src) {
+    int mask = 0x80, i;
 
-   for (i=0;i<4; ++i, mask>>=1)
-         if (channel&mask)
-                dest[i]=src[i];
+    for (i = 0; i < 4; ++i, mask >>= 1)
+        if (channel & mask)
+            dest[i] = src[i];
 }
 
-static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result)
-{
-   int act_comp=0,num_packets=0,y,chained;
-   stbi__pic_packet packets[10];
-
-   // this will (should...) cater for even some bizarre stuff like having data
-       // for the same channel in multiple packets.
-   do {
-         stbi__pic_packet *packet;
-
-         if (num_packets==sizeof(packets)/sizeof(packets[0]))
-                return stbi__errpuc("bad format","too many packets");
-
-         packet = &packets[num_packets++];
+static stbi_uc *stbi__pic_load_core(stbi__context *s, int width, int height, int *comp, stbi_uc *result) {
+    int              act_comp = 0, num_packets = 0, y, chained;
+    stbi__pic_packet packets[10];
 
-         chained = stbi__get8(s);
-         packet->size    = stbi__get8(s);
-         packet->type    = stbi__get8(s);
-         packet->channel = stbi__get8(s);
+    // this will (should...) cater for even some bizarre stuff like having data
+    // for the same channel in multiple packets.
+    do {
+        stbi__pic_packet *packet;
+
+        if (num_packets == sizeof(packets) / sizeof(packets[0]))
+            return stbi__errpuc("bad format", "too many packets");
 
-         act_comp |= packet->channel;
+        packet = &packets[num_packets++];
 
-         if (stbi__at_eof(s))                  return stbi__errpuc("bad file","file too short (reading packets)");
-         if (packet->size != 8)  return stbi__errpuc("bad format","packet isn't 8bpp");
-   } while (chained);
+        chained         = stbi__get8(s);
+        packet->size    = stbi__get8(s);
+        packet->type    = stbi__get8(s);
+        packet->channel = stbi__get8(s);
 
-   *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel?
+        act_comp |= packet->channel;
 
-   for(y=0; y<height; ++y) {
-         int packet_idx;
+        if (stbi__at_eof(s))
+            return stbi__errpuc("bad file", "file too short (reading packets)");
+        if (packet->size != 8)
+            return stbi__errpuc("bad format", "packet isn't 8bpp");
+    } while (chained);
 
-         for(packet_idx=0; packet_idx < num_packets; ++packet_idx) {
-                stbi__pic_packet *packet = &packets[packet_idx];
-                stbi_uc *dest = result+y*width*4;
+    *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel?
 
-                switch (packet->type) {
-                       default:
-                          return stbi__errpuc("bad format","packet has bad compression type");
+    for (y = 0; y < height; ++y) {
+        int packet_idx;
 
-                       case 0: {//uncompressed
-                          int x;
+        for (packet_idx = 0; packet_idx < num_packets; ++packet_idx) {
+            stbi__pic_packet *packet = &packets[packet_idx];
+            stbi_uc          *dest   = result + y * width * 4;
 
-                          for(x=0;x<width;++x, dest+=4)
-                                 if (!stbi__readval(s,packet->channel,dest))
-                                        return 0;
-                          break;
-                       }
+            switch (packet->type) {
+            default:
+                return stbi__errpuc("bad format", "packet has bad compression type");
 
-                       case 1://Pure RLE
-                          {
-                                 int left=width, i;
+            case 0: { // uncompressed
+                int x;
 
-                                 while (left>0) {
-                                        stbi_uc count,value[4];
+                for (x = 0; x < width; ++x, dest += 4)
+                    if (!stbi__readval(s, packet->channel, dest))
+                        return 0;
+                break;
+            }
+
+            case 1: // Pure RLE
+            {
+                int left = width, i;
 
-                                        count=stbi__get8(s);
-                                        if (stbi__at_eof(s))   return stbi__errpuc("bad file","file too short (pure read count)");
+                while (left > 0) {
+                    stbi_uc count, value[4];
 
-                                        if (count > left)
-                                               count = (stbi_uc) left;
+                    count = stbi__get8(s);
+                    if (stbi__at_eof(s))
+                        return stbi__errpuc("bad file", "file too short (pure read count)");
 
-                                        if (!stbi__readval(s,packet->channel,value))  return 0;
+                    if (count > left)
+                        count = (stbi_uc)left;
 
-                                        for(i=0; i<count; ++i,dest+=4)
-                                               stbi__copyval(packet->channel,dest,value);
-                                        left -= count;
-                                 }
-                          }
-                          break;
+                    if (!stbi__readval(s, packet->channel, value))
+                        return 0;
 
-                       case 2: {//Mixed RLE
-                          int left=width;
-                          while (left>0) {
-                                 int count = stbi__get8(s), i;
-                                 if (stbi__at_eof(s))  return stbi__errpuc("bad file","file too short (mixed read count)");
+                    for (i = 0; i < count; ++i, dest += 4)
+                        stbi__copyval(packet->channel, dest, value);
+                    left -= count;
+                }
+            } break;
 
-                                 if (count >= 128) { // Repeated
-                                        stbi_uc value[4];
+            case 2: { // Mixed RLE
+                int left = width;
+                while (left > 0) {
+                    int count = stbi__get8(s), i;
+                    if (stbi__at_eof(s))
+                        return stbi__errpuc("bad file", "file too short (mixed read count)");
+
+                    if (count >= 128) { // Repeated
+                        stbi_uc value[4];
+
+                        if (count == 128)
+                            count = stbi__get16be(s);
+                        else
+                            count -= 127;
+                        if (count > left)
+                            return stbi__errpuc("bad file", "scanline overrun");
 
-                                        if (count==128)
-                                               count = stbi__get16be(s);
-                                        else
-                                               count -= 127;
-                                        if (count > left)
-                                               return stbi__errpuc("bad file","scanline overrun");
+                        if (!stbi__readval(s, packet->channel, value))
+                            return 0;
 
-                                        if (!stbi__readval(s,packet->channel,value))
-                                               return 0;
-
-                                        for(i=0;i<count;++i, dest += 4)
-                                               stbi__copyval(packet->channel,dest,value);
-                                 } else { // Raw
-                                        ++count;
-                                        if (count>left) return stbi__errpuc("bad file","scanline overrun");
-
-                                        for(i=0;i<count;++i, dest+=4)
-                                               if (!stbi__readval(s,packet->channel,dest))
-                                                  return 0;
-                                 }
-                                 left-=count;
-                          }
-                          break;
-                       }
-                }
-         }
-   }
-
-   return result;
-}
-
-static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri)
-{
-   stbi_uc *result;
-   int i, x,y, internal_comp;
-   STBI_NOTUSED(ri);
-
-   if (!comp) comp = &internal_comp;
-
-   for (i=0; i<92; ++i)
-         stbi__get8(s);
-
-   x = stbi__get16be(s);
-   y = stbi__get16be(s);
-   if (stbi__at_eof(s))         return stbi__errpuc("bad file","file too short (pic header)");
-   if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
-
-   stbi__get32be(s); //skip `ratio'
-   stbi__get16be(s); //skip `fields'
-   stbi__get16be(s); //skip `pad'
-
-   // intermediate buffer is RGBA
-   result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0);
-   memset(result, 0xff, x*y*4);
-
-   if (!stbi__pic_load_core(s,x,y,comp, result)) {
-         STBI_FREE(result);
-         result=0;
-   }
-   *px = x;
-   *py = y;
-   if (req_comp == 0) req_comp = *comp;
-   result=stbi__convert_format(result,4,req_comp,x,y);
-
-   return result;
-}
-
-static int stbi__pic_test(stbi__context *s)
-{
-   int r = stbi__pic_test_core(s);
-   stbi__rewind(s);
-   return r;
+                        for (i = 0; i < count; ++i, dest += 4)
+                            stbi__copyval(packet->channel, dest, value);
+                    } else { // Raw
+                        ++count;
+                        if (count > left)
+                            return stbi__errpuc("bad file", "scanline overrun");
+
+                        for (i = 0; i < count; ++i, dest += 4)
+                            if (!stbi__readval(s, packet->channel, dest))
+                                return 0;
+                    }
+                    left -= count;
+                }
+                break;
+            }
+            }
+        }
+    }
+
+    return result;
+}
+
+static void *stbi__pic_load(stbi__context *s, int *px, int *py, int *comp, int req_comp, stbi__result_info *ri) {
+    stbi_uc *result;
+    int      i, x, y, internal_comp;
+    STBI_NOTUSED(ri);
+
+    if (!comp)
+        comp = &internal_comp;
+
+    for (i = 0; i < 92; ++i)
+        stbi__get8(s);
+
+    x = stbi__get16be(s);
+    y = stbi__get16be(s);
+    if (stbi__at_eof(s))
+        return stbi__errpuc("bad file", "file too short (pic header)");
+    if (!stbi__mad3sizes_valid(x, y, 4, 0))
+        return stbi__errpuc("too large", "PIC image too large to decode");
+
+    stbi__get32be(s); // skip `ratio'
+    stbi__get16be(s); // skip `fields'
+    stbi__get16be(s); // skip `pad'
+
+    // intermediate buffer is RGBA
+    result = (stbi_uc *)stbi__malloc_mad3(x, y, 4, 0);
+    memset(result, 0xff, x * y * 4);
+
+    if (!stbi__pic_load_core(s, x, y, comp, result)) {
+        STBI_FREE(result);
+        result = 0;
+    }
+    *px = x;
+    *py = y;
+    if (req_comp == 0)
+        req_comp = *comp;
+    result = stbi__convert_format(result, 4, req_comp, x, y);
+
+    return result;
+}
+
+static int stbi__pic_test(stbi__context *s) {
+    int r = stbi__pic_test_core(s);
+    stbi__rewind(s);
+    return r;
 }
 #endif
 
@@ -6115,868 +6404,901 @@ static int stbi__pic_test(stbi__context *s)
 // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
 
 #ifndef STBI_NO_GIF
-typedef struct
-{
-   stbi__int16 prefix;
-   stbi_uc first;
-   stbi_uc suffix;
+typedef struct {
+    stbi__int16 prefix;
+    stbi_uc     first;
+    stbi_uc     suffix;
 } stbi__gif_lzw;
 
-typedef struct
-{
-   int w,h;
-   stbi_uc *out;                                // output buffer (always 4 components)
-   stbi_uc *background;                         // The current "background" as far as a gif is concerned
-   stbi_uc *history; 
-   int flags, bgindex, ratio, transparent, eflags;
-   stbi_uc     pal[256][4];
-   stbi_uc lpal[256][4];
-   stbi__gif_lzw codes[8192];
-   stbi_uc *color_table;
-   int parse, step;
-   int lflags;
-   int start_x, start_y;
-   int max_x, max_y;
-   int cur_x, cur_y;
-   int line_size;
-   int delay;
+typedef struct {
+    int           w, h;
+    stbi_uc      *out;        // output buffer (always 4 components)
+    stbi_uc      *background; // The current "background" as far as a gif is concerned
+    stbi_uc      *history;
+    int           flags, bgindex, ratio, transparent, eflags;
+    stbi_uc       pal[256][4];
+    stbi_uc       lpal[256][4];
+    stbi__gif_lzw codes[8192];
+    stbi_uc      *color_table;
+    int           parse, step;
+    int           lflags;
+    int           start_x, start_y;
+    int           max_x, max_y;
+    int           cur_x, cur_y;
+    int           line_size;
+    int           delay;
 } stbi__gif;
 
-static int stbi__gif_test_raw(stbi__context *s)
-{
-   int sz;
-   if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0;
-   sz = stbi__get8(s);
-   if (sz != '9' && sz != '7') return 0;
-   if (stbi__get8(s) != 'a') return 0;
-   return 1;
-}
-
-static int stbi__gif_test(stbi__context *s)
-{
-   int r = stbi__gif_test_raw(s);
-   stbi__rewind(s);
-   return r;
-}
-
-static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp)
-{
-   int i;
-   for (i=0; i < num_entries; ++i) {
-         pal[i][2] = stbi__get8(s);
-         pal[i][1] = stbi__get8(s);
-         pal[i][0] = stbi__get8(s);
-         pal[i][3] = transp == i ? 0 : 255;
-   }
-}
-
-static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info)
-{
-   stbi_uc version;
-   if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8')
-         return stbi__err("not GIF", "Corrupt GIF");
-
-   version = stbi__get8(s);
-   if (version != '7' && version != '9')       return stbi__err("not GIF", "Corrupt GIF");
-   if (stbi__get8(s) != 'a')                           return stbi__err("not GIF", "Corrupt GIF");
-
-   stbi__g_failure_reason = "";
-   g->w = stbi__get16le(s);
-   g->h = stbi__get16le(s);
-   g->flags = stbi__get8(s);
-   g->bgindex = stbi__get8(s);
-   g->ratio = stbi__get8(s);
-   g->transparent = -1;
-
-   if (comp != 0) *comp = 4;  // can't actually tell whether it's 3 or 4 until we parse the comments
-
-   if (is_info) return 1;
-
-   if (g->flags & 0x80)
-         stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1);
-
-   return 1;
-}
-
-static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
-{
-   stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
-   if (!stbi__gif_header(s, g, comp, 1)) {
-         STBI_FREE(g);
-         stbi__rewind( s );
-         return 0;
-   }
-   if (x) *x = g->w;
-   if (y) *y = g->h;
-   STBI_FREE(g);
-   return 1;
-}
-
-static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
-{
-   stbi_uc *p, *c;
-   int idx; 
-
-   // recurse to decode the prefixes, since the linked-list is backwards,
-   // and working backwards through an interleaved image would be nasty
-   if (g->codes[code].prefix >= 0)
-         stbi__out_gif_code(g, g->codes[code].prefix);
-
-   if (g->cur_y >= g->max_y) return;
-
-   idx = g->cur_x + g->cur_y; 
-   p = &g->out[idx];
-   g->history[idx / 4] = 1;     
-
-   c = &g->color_table[g->codes[code].suffix * 4];
-   if (c[3] > 128) { // don't render transparent pixels; 
-         p[0] = c[2];
-         p[1] = c[1];
-         p[2] = c[0];
-         p[3] = c[3];
-   }
-   g->cur_x += 4;
-
-   if (g->cur_x >= g->max_x) {
-         g->cur_x = g->start_x;
-         g->cur_y += g->step;
-
-         while (g->cur_y >= g->max_y && g->parse > 0) {
-                g->step = (1 << g->parse) * g->line_size;
-                g->cur_y = g->start_y + (g->step >> 1);
-                --g->parse;
-         }
-   }
-}
-
-static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
-{
-   stbi_uc lzw_cs;
-   stbi__int32 len, init_code;
-   stbi__uint32 first;
-   stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear;
-   stbi__gif_lzw *p;
-
-   lzw_cs = stbi__get8(s);
-   if (lzw_cs > 12) return NULL;
-   clear = 1 << lzw_cs;
-   first = 1;
-   codesize = lzw_cs + 1;
-   codemask = (1 << codesize) - 1;
-   bits = 0;
-   valid_bits = 0;
-   for (init_code = 0; init_code < clear; init_code++) {
-         g->codes[init_code].prefix = -1;
-         g->codes[init_code].first = (stbi_uc) init_code;
-         g->codes[init_code].suffix = (stbi_uc) init_code;
-   }
-
-   // support no starting clear code
-   avail = clear+2;
-   oldcode = -1;
-
-   len = 0;
-   for(;;) {
-         if (valid_bits < codesize) {
-                if (len == 0) {
-                       len = stbi__get8(s); // start new block
-                       if (len == 0)
-                          return g->out;
-                }
-                --len;
-                bits |= (stbi__int32) stbi__get8(s) << valid_bits;
-                valid_bits += 8;
-         } else {
-                stbi__int32 code = bits & codemask;
-                bits >>= codesize;
-                valid_bits -= codesize;
-                // @OPTIMIZE: is there some way we can accelerate the non-clear path?
-                if (code == clear) {  // clear code
-                       codesize = lzw_cs + 1;
-                       codemask = (1 << codesize) - 1;
-                       avail = clear + 2;
-                       oldcode = -1;
-                       first = 0;
-                } else if (code == clear + 1) { // end of stream code
-                       stbi__skip(s, len);
-                       while ((len = stbi__get8(s)) > 0)
-                          stbi__skip(s,len);
-                       return g->out;
-                } else if (code <= avail) {
-                       if (first) {
-                          return stbi__errpuc("no clear code", "Corrupt GIF");
-                       }
-
-                       if (oldcode >= 0) {
-                          p = &g->codes[avail++];
-                          if (avail > 8192) {
-                                 return stbi__errpuc("too many codes", "Corrupt GIF");
-                          }
-
-                          p->prefix = (stbi__int16) oldcode;
-                          p->first = g->codes[oldcode].first;
-                          p->suffix = (code == avail) ? p->first : g->codes[code].first;
-                       } else if (code == avail)
-                          return stbi__errpuc("illegal code in raster", "Corrupt GIF");
-
-                       stbi__out_gif_code(g, (stbi__uint16) code);
-
-                       if ((avail & codemask) == 0 && avail <= 0x0FFF) {
-                          codesize++;
-                          codemask = (1 << codesize) - 1;
-                       }
-
-                       oldcode = code;
-                } else {
-                       return stbi__errpuc("illegal code in raster", "Corrupt GIF");
-                }
-         }
-   }
+static int stbi__gif_test_raw(stbi__context *s) {
+    int sz;
+    if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8')
+        return 0;
+    sz = stbi__get8(s);
+    if (sz != '9' && sz != '7')
+        return 0;
+    if (stbi__get8(s) != 'a')
+        return 0;
+    return 1;
+}
+
+static int stbi__gif_test(stbi__context *s) {
+    int r = stbi__gif_test_raw(s);
+    stbi__rewind(s);
+    return r;
+}
+
+static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) {
+    int i;
+    for (i = 0; i < num_entries; ++i) {
+        pal[i][2] = stbi__get8(s);
+        pal[i][1] = stbi__get8(s);
+        pal[i][0] = stbi__get8(s);
+        pal[i][3] = transp == i ? 0 : 255;
+    }
+}
+
+static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) {
+    stbi_uc version;
+    if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8')
+        return stbi__err("not GIF", "Corrupt GIF");
+
+    version = stbi__get8(s);
+    if (version != '7' && version != '9')
+        return stbi__err("not GIF", "Corrupt GIF");
+    if (stbi__get8(s) != 'a')
+        return stbi__err("not GIF", "Corrupt GIF");
+
+    stbi__g_failure_reason = "";
+    g->w                   = stbi__get16le(s);
+    g->h                   = stbi__get16le(s);
+    g->flags               = stbi__get8(s);
+    g->bgindex             = stbi__get8(s);
+    g->ratio               = stbi__get8(s);
+    g->transparent         = -1;
+
+    if (comp != 0)
+        *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
+
+    if (is_info)
+        return 1;
+
+    if (g->flags & 0x80)
+        stbi__gif_parse_colortable(s, g->pal, 2 << (g->flags & 7), -1);
+
+    return 1;
+}
+
+static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) {
+    stbi__gif *g = (stbi__gif *)stbi__malloc(sizeof(stbi__gif));
+    if (!stbi__gif_header(s, g, comp, 1)) {
+        STBI_FREE(g);
+        stbi__rewind(s);
+        return 0;
+    }
+    if (x)
+        *x = g->w;
+    if (y)
+        *y = g->h;
+    STBI_FREE(g);
+    return 1;
+}
+
+static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) {
+    stbi_uc *p, *c;
+    int      idx;
+
+    // recurse to decode the prefixes, since the linked-list is backwards,
+    // and working backwards through an interleaved image would be nasty
+    if (g->codes[code].prefix >= 0)
+        stbi__out_gif_code(g, g->codes[code].prefix);
+
+    if (g->cur_y >= g->max_y)
+        return;
+
+    idx                 = g->cur_x + g->cur_y;
+    p                   = &g->out[idx];
+    g->history[idx / 4] = 1;
+
+    c = &g->color_table[g->codes[code].suffix * 4];
+    if (c[3] > 128) { // don't render transparent pixels;
+        p[0] = c[2];
+        p[1] = c[1];
+        p[2] = c[0];
+        p[3] = c[3];
+    }
+    g->cur_x += 4;
+
+    if (g->cur_x >= g->max_x) {
+        g->cur_x = g->start_x;
+        g->cur_y += g->step;
+
+        while (g->cur_y >= g->max_y && g->parse > 0) {
+            g->step  = (1 << g->parse) * g->line_size;
+            g->cur_y = g->start_y + (g->step >> 1);
+            --g->parse;
+        }
+    }
+}
+
+static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) {
+    stbi_uc        lzw_cs;
+    stbi__int32    len, init_code;
+    stbi__uint32   first;
+    stbi__int32    codesize, codemask, avail, oldcode, bits, valid_bits, clear;
+    stbi__gif_lzw *p;
+
+    lzw_cs = stbi__get8(s);
+    if (lzw_cs > 12)
+        return NULL;
+    clear      = 1 << lzw_cs;
+    first      = 1;
+    codesize   = lzw_cs + 1;
+    codemask   = (1 << codesize) - 1;
+    bits       = 0;
+    valid_bits = 0;
+    for (init_code = 0; init_code < clear; init_code++) {
+        g->codes[init_code].prefix = -1;
+        g->codes[init_code].first  = (stbi_uc)init_code;
+        g->codes[init_code].suffix = (stbi_uc)init_code;
+    }
+
+    // support no starting clear code
+    avail   = clear + 2;
+    oldcode = -1;
+
+    len = 0;
+    for (;;) {
+        if (valid_bits < codesize) {
+            if (len == 0) {
+                len = stbi__get8(s); // start new block
+                if (len == 0)
+                    return g->out;
+            }
+            --len;
+            bits |= (stbi__int32)stbi__get8(s) << valid_bits;
+            valid_bits += 8;
+        } else {
+            stbi__int32 code = bits & codemask;
+            bits >>= codesize;
+            valid_bits -= codesize;
+            // @OPTIMIZE: is there some way we can accelerate the non-clear path?
+            if (code == clear) { // clear code
+                codesize = lzw_cs + 1;
+                codemask = (1 << codesize) - 1;
+                avail    = clear + 2;
+                oldcode  = -1;
+                first    = 0;
+            } else if (code == clear + 1) { // end of stream code
+                stbi__skip(s, len);
+                while ((len = stbi__get8(s)) > 0)
+                    stbi__skip(s, len);
+                return g->out;
+            } else if (code <= avail) {
+                if (first) {
+                    return stbi__errpuc("no clear code", "Corrupt GIF");
+                }
+
+                if (oldcode >= 0) {
+                    p = &g->codes[avail++];
+                    if (avail > 8192) {
+                        return stbi__errpuc("too many codes", "Corrupt GIF");
+                    }
+
+                    p->prefix = (stbi__int16)oldcode;
+                    p->first  = g->codes[oldcode].first;
+                    p->suffix = (code == avail) ? p->first : g->codes[code].first;
+                } else if (code == avail)
+                    return stbi__errpuc("illegal code in raster", "Corrupt GIF");
+
+                stbi__out_gif_code(g, (stbi__uint16)code);
+
+                if ((avail & codemask) == 0 && avail <= 0x0FFF) {
+                    codesize++;
+                    codemask = (1 << codesize) - 1;
+                }
+
+                oldcode = code;
+            } else {
+                return stbi__errpuc("illegal code in raster", "Corrupt GIF");
+            }
+        }
+    }
 }
 
 // this function is designed to support animated gifs, although stb_image doesn't support it
 // two back is the image from two frames ago, used for a very specific disposal format
-static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back)
-{
-   int dispose; 
-   int first_frame; 
-   int pi; 
-   int pcount; 
-
-   // on first frame, any non-written pixels get the background colour (non-transparent)
-   first_frame = 0; 
-   if (g->out == 0) {
-         if (!stbi__gif_header(s, g, comp,0))     return 0; // stbi__g_failure_reason set by stbi__gif_header
-         g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
-         g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h); 
-         g->history = (stbi_uc *) stbi__malloc(g->w * g->h); 
-         if (g->out == 0)                                              return stbi__errpuc("outofmem", "Out of memory");
-
-         // image is treated as "tranparent" at the start - ie, nothing overwrites the current background; 
-         // background colour is only used for pixels that are not rendered first frame, after that "background"
-         // color refers to teh color that was there the previous frame. 
-         memset( g->out, 0x00, 4 * g->w * g->h ); 
-         memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent)
-         memset( g->history, 0x00, g->w * g->h );                // pixels that were affected previous frame
-         first_frame = 1; 
-   } else {
-         // second frame - how do we dispoase of the previous one?
-         dispose = (g->eflags & 0x1C) >> 2; 
-         pcount = g->w * g->h; 
-
-         if ((dispose == 3) && (two_back == 0)) {
-                dispose = 2; // if I don't have an image to revert back to, default to the old background
-         }
-
-         if (dispose == 3) { // use previous graphic
-                for (pi = 0; pi < pcount; ++pi) {
-                       if (g->history[pi]) {
-                          memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); 
-                       }
-                }
-         } else if (dispose == 2) { 
-                // restore what was changed last frame to background before that frame; 
-                for (pi = 0; pi < pcount; ++pi) {
-                       if (g->history[pi]) {
-                          memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); 
-                       }
-                }
-         } else {
-                // This is a non-disposal case eithe way, so just 
-                // leave the pixels as is, and they will become the new background
-                // 1: do not dispose
-                // 0:  not specified.
-         }
-
-         // background is what out is after the undoing of the previou frame; 
-         memcpy( g->background, g->out, 4 * g->w * g->h ); 
-   }
-
-   // clear my history; 
-   memset( g->history, 0x00, g->w * g->h );               // pixels that were affected previous frame
-
-   for (;;) {
-         int tag = stbi__get8(s); 
-         switch (tag) {
-                case 0x2C: /* Image Descriptor */
-                {
-                       stbi__int32 x, y, w, h;
-                       stbi_uc *o;
-
-                       x = stbi__get16le(s);
-                       y = stbi__get16le(s);
-                       w = stbi__get16le(s);
-                       h = stbi__get16le(s);
-                       if (((x + w) > (g->w)) || ((y + h) > (g->h)))
-                          return stbi__errpuc("bad Image Descriptor", "Corrupt GIF");
-
-                       g->line_size = g->w * 4;
-                       g->start_x = x * 4;
-                       g->start_y = y * g->line_size;
-                       g->max_x   = g->start_x + w * 4;
-                       g->max_y   = g->start_y + h * g->line_size;
-                       g->cur_x   = g->start_x;
-                       g->cur_y   = g->start_y;
-
-                       g->lflags = stbi__get8(s);
-
-                       if (g->lflags & 0x40) {
-                          g->step = 8 * g->line_size; // first interlaced spacing
-                          g->parse = 3;
-                       } else {
-                          g->step = g->line_size;
-                          g->parse = 0;
-                       }
-
-                       if (g->lflags & 0x80) {
-                          stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1);
-                          g->color_table = (stbi_uc *) g->lpal;
-                       } else if (g->flags & 0x80) {
-                          g->color_table = (stbi_uc *) g->pal;
-                       } else
-                          return stbi__errpuc("missing color table", "Corrupt GIF");                    
-                       
-                       o = stbi__process_gif_raster(s, g);
-                       if (o == NULL) return NULL;
-
-                       // if this was the first frame, 
-                       pcount = g->w * g->h; 
-                       if (first_frame && (g->bgindex > 0)) {
-                          // if first frame, any pixel not drawn to gets the background color
-                          for (pi = 0; pi < pcount; ++pi) {
-                                 if (g->history[pi] == 0) {
-                                        g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; 
-                                        memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); 
-                                 }
-                          }
-                       }
-
-                       return o;
-                }
-
-                case 0x21: // Comment Extension.
-                {
-                       int len;
-                       int ext = stbi__get8(s); 
-                       if (ext == 0xF9) { // Graphic Control Extension.
-                          len = stbi__get8(s);
-                          if (len == 4) {
-                                 g->eflags = stbi__get8(s);
-                                 g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths.
-
-                                 // unset old transparent
-                                 if (g->transparent >= 0) {
-                                        g->pal[g->transparent][3] = 255; 
-                                 } 
-                                 if (g->eflags & 0x01) {
-                                        g->transparent = stbi__get8(s);
-                                        if (g->transparent >= 0) {
-                                               g->pal[g->transparent][3] = 0; 
-                                        }
-                                 } else {
-                                        // don't need transparent
-                                        stbi__skip(s, 1); 
-                                        g->transparent = -1; 
-                                 }
-                          } else {
-                                 stbi__skip(s, len);
-                                 break;
-                          }
-                       } 
-                       while ((len = stbi__get8(s)) != 0) {
-                          stbi__skip(s, len);
-                       }
-                       break;
-                }
-
-                case 0x3B: // gif stream termination code
-                       return (stbi_uc *) s; // using '1' causes warning on some compilers
-
-                default:
-                       return stbi__errpuc("unknown code", "Corrupt GIF");
-         }
-   }
-}
-
-static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
-{
-   if (stbi__gif_test(s)) {
-         int layers = 0; 
-         stbi_uc *u = 0;
-         stbi_uc *out = 0;
-         stbi_uc *two_back = 0; 
-         stbi__gif g;
-         int stride; 
-         memset(&g, 0, sizeof(g));
-         if (delays) {
-                *delays = 0; 
-         }
-
-         do {
-                u = stbi__gif_load_next(s, &g, comp, req_comp, two_back);
-                if (u == (stbi_uc *) s) u = 0;  // end of animated gif marker
-
-                if (u) {
-                       *x = g.w;
-                       *y = g.h;
-                       ++layers; 
-                       stride = g.w * g.h * 4; 
-                
-                       if (out) {
-                          out = (stbi_uc*) STBI_REALLOC( out, layers * stride ); 
-                          if (delays) {
-                                 *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers ); 
-                          }
-                       } else {
-                          out = (stbi_uc*)stbi__malloc( layers * stride ); 
-                          if (delays) {
-                                 *delays = (int*) stbi__malloc( layers * sizeof(int) ); 
-                          }
-                       }
-                       memcpy( out + ((layers - 1) * stride), u, stride ); 
-                       if (layers >= 2) {
-                          two_back = out - 2 * stride; 
-                       }
-
-                       if (delays) {
-                          (*delays)[layers - 1U] = g.delay; 
-                       }
-                }
-         } while (u != 0); 
-
-         // free temp buffer; 
-         STBI_FREE(g.out); 
-         STBI_FREE(g.history); 
-         STBI_FREE(g.background); 
-
-         // do the final conversion after loading everything; 
-         if (req_comp && req_comp != 4)
-                out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h);
-
-         *z = layers; 
-         return out;
-   } else {
-         return stbi__errpuc("not GIF", "Image was not as a gif type."); 
-   }
-}
-
-static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   stbi_uc *u = 0;
-   stbi__gif g;
-   memset(&g, 0, sizeof(g));
-
-   u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
-   if (u == (stbi_uc *) s) u = 0;  // end of animated gif marker
-   if (u) {
-         *x = g.w;
-         *y = g.h;
-
-         // moved conversion to after successful load so that the same
-         // can be done for multiple frames. 
-         if (req_comp && req_comp != 4)
-                u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
-   }
-
-   // free buffers needed for multiple frame loading; 
-   STBI_FREE(g.history);
-   STBI_FREE(g.background); 
-
-   return u;
-}
-
-static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   return stbi__gif_info_raw(s,x,y,comp);
-}
+static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) {
+    int dispose;
+    int first_frame;
+    int pi;
+    int pcount;
+
+    // on first frame, any non-written pixels get the background colour (non-transparent)
+    first_frame = 0;
+    if (g->out == 0) {
+        if (!stbi__gif_header(s, g, comp, 0))
+            return 0; // stbi__g_failure_reason set by stbi__gif_header
+        g->out        = (stbi_uc *)stbi__malloc(4 * g->w * g->h);
+        g->background = (stbi_uc *)stbi__malloc(4 * g->w * g->h);
+        g->history    = (stbi_uc *)stbi__malloc(g->w * g->h);
+        if (g->out == 0)
+            return stbi__errpuc("outofmem", "Out of memory");
+
+        // image is treated as "tranparent" at the start - ie, nothing overwrites the current background;
+        // background colour is only used for pixels that are not rendered first frame, after that "background"
+        // color refers to teh color that was there the previous frame.
+        memset(g->out, 0x00, 4 * g->w * g->h);
+        memset(g->background, 0x00, 4 * g->w * g->h); // state of the background (starts transparent)
+        memset(g->history, 0x00, g->w * g->h);        // pixels that were affected previous frame
+        first_frame = 1;
+    } else {
+        // second frame - how do we dispoase of the previous one?
+        dispose = (g->eflags & 0x1C) >> 2;
+        pcount  = g->w * g->h;
+
+        if ((dispose == 3) && (two_back == 0)) {
+            dispose = 2; // if I don't have an image to revert back to, default to the old background
+        }
+
+        if (dispose == 3) { // use previous graphic
+            for (pi = 0; pi < pcount; ++pi) {
+                if (g->history[pi]) {
+                    memcpy(&g->out[pi * 4], &two_back[pi * 4], 4);
+                }
+            }
+        } else if (dispose == 2) {
+            // restore what was changed last frame to background before that frame;
+            for (pi = 0; pi < pcount; ++pi) {
+                if (g->history[pi]) {
+                    memcpy(&g->out[pi * 4], &g->background[pi * 4], 4);
+                }
+            }
+        } else {
+            // This is a non-disposal case eithe way, so just
+            // leave the pixels as is, and they will become the new background
+            // 1: do not dispose
+            // 0:      not specified.
+        }
+
+        // background is what out is after the undoing of the previou frame;
+        memcpy(g->background, g->out, 4 * g->w * g->h);
+    }
+
+    // clear my history;
+    memset(g->history, 0x00, g->w * g->h); // pixels that were affected previous frame
+
+    for (;;) {
+        int tag = stbi__get8(s);
+        switch (tag) {
+        case 0x2C: /* Image Descriptor */
+        {
+            stbi__int32 x, y, w, h;
+            stbi_uc    *o;
+
+            x = stbi__get16le(s);
+            y = stbi__get16le(s);
+            w = stbi__get16le(s);
+            h = stbi__get16le(s);
+            if (((x + w) > (g->w)) || ((y + h) > (g->h)))
+                return stbi__errpuc("bad Image Descriptor", "Corrupt GIF");
+
+            g->line_size = g->w * 4;
+            g->start_x   = x * 4;
+            g->start_y   = y * g->line_size;
+            g->max_x     = g->start_x + w * 4;
+            g->max_y     = g->start_y + h * g->line_size;
+            g->cur_x     = g->start_x;
+            g->cur_y     = g->start_y;
+
+            g->lflags = stbi__get8(s);
+
+            if (g->lflags & 0x40) {
+                g->step  = 8 * g->line_size; // first interlaced spacing
+                g->parse = 3;
+            } else {
+                g->step  = g->line_size;
+                g->parse = 0;
+            }
+
+            if (g->lflags & 0x80) {
+                stbi__gif_parse_colortable(s, g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1);
+                g->color_table = (stbi_uc *)g->lpal;
+            } else if (g->flags & 0x80) {
+                g->color_table = (stbi_uc *)g->pal;
+            } else
+                return stbi__errpuc("missing color table", "Corrupt GIF");
+
+            o = stbi__process_gif_raster(s, g);
+            if (o == NULL)
+                return NULL;
+
+            // if this was the first frame,
+            pcount = g->w * g->h;
+            if (first_frame && (g->bgindex > 0)) {
+                // if first frame, any pixel not drawn to gets the background color
+                for (pi = 0; pi < pcount; ++pi) {
+                    if (g->history[pi] == 0) {
+                        g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be
+                                                     // reset next frame if need be;
+                        memcpy(&g->out[pi * 4], &g->pal[g->bgindex], 4);
+                    }
+                }
+            }
+
+            return o;
+        }
+
+        case 0x21: // Comment Extension.
+        {
+            int len;
+            int ext = stbi__get8(s);
+            if (ext == 0xF9) { // Graphic Control Extension.
+                len = stbi__get8(s);
+                if (len == 4) {
+                    g->eflags = stbi__get8(s);
+                    g->delay  = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths.
+
+                    // unset old transparent
+                    if (g->transparent >= 0) {
+                        g->pal[g->transparent][3] = 255;
+                    }
+                    if (g->eflags & 0x01) {
+                        g->transparent = stbi__get8(s);
+                        if (g->transparent >= 0) {
+                            g->pal[g->transparent][3] = 0;
+                        }
+                    } else {
+                        // don't need transparent
+                        stbi__skip(s, 1);
+                        g->transparent = -1;
+                    }
+                } else {
+                    stbi__skip(s, len);
+                    break;
+                }
+            }
+            while ((len = stbi__get8(s)) != 0) {
+                stbi__skip(s, len);
+            }
+            break;
+        }
+
+        case 0x3B:               // gif stream termination code
+            return (stbi_uc *)s; // using '1' causes warning on some compilers
+
+        default:
+            return stbi__errpuc("unknown code", "Corrupt GIF");
+        }
+    }
+}
+
+static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) {
+    if (stbi__gif_test(s)) {
+        int       layers   = 0;
+        stbi_uc  *u        = 0;
+        stbi_uc  *out      = 0;
+        stbi_uc  *two_back = 0;
+        stbi__gif g;
+        int       stride;
+        memset(&g, 0, sizeof(g));
+        if (delays) {
+            *delays = 0;
+        }
+
+        do {
+            u = stbi__gif_load_next(s, &g, comp, req_comp, two_back);
+            if (u == (stbi_uc *)s)
+                u = 0; // end of animated gif marker
+
+            if (u) {
+                *x = g.w;
+                *y = g.h;
+                ++layers;
+                stride = g.w * g.h * 4;
+
+                if (out) {
+                    out = (stbi_uc *)STBI_REALLOC(out, layers * stride);
+                    if (delays) {
+                        *delays = (int *)STBI_REALLOC(*delays, sizeof(int) * layers);
+                    }
+                } else {
+                    out = (stbi_uc *)stbi__malloc(layers * stride);
+                    if (delays) {
+                        *delays = (int *)stbi__malloc(layers * sizeof(int));
+                    }
+                }
+                memcpy(out + ((layers - 1) * stride), u, stride);
+                if (layers >= 2) {
+                    two_back = out - 2 * stride;
+                }
+
+                if (delays) {
+                    (*delays)[layers - 1U] = g.delay;
+                }
+            }
+        } while (u != 0);
+
+        // free temp buffer;
+        STBI_FREE(g.out);
+        STBI_FREE(g.history);
+        STBI_FREE(g.background);
+
+        // do the final conversion after loading everything;
+        if (req_comp && req_comp != 4)
+            out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h);
+
+        *z = layers;
+        return out;
+    } else {
+        return stbi__errpuc("not GIF", "Image was not as a gif type.");
+    }
+}
+
+static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) {
+    stbi_uc  *u = 0;
+    stbi__gif g;
+    memset(&g, 0, sizeof(g));
+
+    u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
+    if (u == (stbi_uc *)s)
+        u = 0; // end of animated gif marker
+    if (u) {
+        *x = g.w;
+        *y = g.h;
+
+        // moved conversion to after successful load so that the same
+        // can be done for multiple frames.
+        if (req_comp && req_comp != 4)
+            u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
+    }
+
+    // free buffers needed for multiple frame loading;
+    STBI_FREE(g.history);
+    STBI_FREE(g.background);
+
+    return u;
+}
+
+static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) { return stbi__gif_info_raw(s, x, y, comp); }
 #endif
 
 // *************************************************************************************************
 // Radiance RGBE HDR loader
 // originally by Nicolas Schulz
 #ifndef STBI_NO_HDR
-static int stbi__hdr_test_core(stbi__context *s, const char *signature)
-{
-   int i;
-   for (i=0; signature[i]; ++i)
-         if (stbi__get8(s) != signature[i])
-                 return 0;
-   stbi__rewind(s);
-   return 1;
-}
-
-static int stbi__hdr_test(stbi__context* s)
-{
-   int r = stbi__hdr_test_core(s, "#?RADIANCE\n");
-   stbi__rewind(s);
-   if(!r) {
-          r = stbi__hdr_test_core(s, "#?RGBE\n");
-          stbi__rewind(s);
-   }
-   return r;
-}
-
-#define STBI__HDR_BUFLEN  1024
-static char *stbi__hdr_gettoken(stbi__context *z, char *buffer)
-{
-   int len=0;
-   char c = '\0';
-
-   c = (char) stbi__get8(z);
-
-   while (!stbi__at_eof(z) && c != '\n') {
-         buffer[len++] = c;
-         if (len == STBI__HDR_BUFLEN-1) {
-                // flush to end of line
-                while (!stbi__at_eof(z) && stbi__get8(z) != '\n')
-                       ;
-                break;
-         }
-         c = (char) stbi__get8(z);
-   }
-
-   buffer[len] = 0;
-   return buffer;
-}
-
-static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp)
-{
-   if ( input[3] != 0 ) {
-         float f1;
-         // Exponent
-         f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8));
-         if (req_comp <= 2)
-                output[0] = (input[0] + input[1] + input[2]) * f1 / 3;
-         else {
-                output[0] = input[0] * f1;
-                output[1] = input[1] * f1;
-                output[2] = input[2] * f1;
-         }
-         if (req_comp == 2) output[1] = 1;
-         if (req_comp == 4) output[3] = 1;
-   } else {
-         switch (req_comp) {
-                case 4: output[3] = 1; /* fallthrough */
-                case 3: output[0] = output[1] = output[2] = 0;
-                                break;
-                case 2: output[1] = 1; /* fallthrough */
-                case 1: output[0] = 0;
-                                break;
-         }
-   }
-}
-
-static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   char buffer[STBI__HDR_BUFLEN];
-   char *token;
-   int valid = 0;
-   int width, height;
-   stbi_uc *scanline;
-   float *hdr_data;
-   int len;
-   unsigned char count, value;
-   int i, j, k, c1,c2, z;
-   const char *headerToken;
-   STBI_NOTUSED(ri);
-
-   // Check identifier
-   headerToken = stbi__hdr_gettoken(s,buffer);
-   if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0)
-         return stbi__errpf("not HDR", "Corrupt HDR image");
-
-   // Parse header
-   for(;;) {
-         token = stbi__hdr_gettoken(s,buffer);
-         if (token[0] == 0) break;
-         if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
-   }
-
-   if (!valid)   return stbi__errpf("unsupported format", "Unsupported HDR format");
-
-   // Parse width and height
-   // can't use sscanf() if we're not using stdio!
-   token = stbi__hdr_gettoken(s,buffer);
-   if (strncmp(token, "-Y ", 3))  return stbi__errpf("unsupported data layout", "Unsupported HDR format");
-   token += 3;
-   height = (int) strtol(token, &token, 10);
-   while (*token == ' ') ++token;
-   if (strncmp(token, "+X ", 3))  return stbi__errpf("unsupported data layout", "Unsupported HDR format");
-   token += 3;
-   width = (int) strtol(token, NULL, 10);
-
-   *x = width;
-   *y = height;
-
-   if (comp) *comp = 3;
-   if (req_comp == 0) req_comp = 3;
-
-   if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0))
-         return stbi__errpf("too large", "HDR image is too large");
-
-   // Read data
-   hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0);
-   if (!hdr_data)
-         return stbi__errpf("outofmem", "Out of memory");
-
-   // Load image data
-   // image data is stored as some number of sca
-   if ( width < 8 || width >= 32768) {
-         // Read flat data
-         for (j=0; j < height; ++j) {
-                for (i=0; i < width; ++i) {
-                       stbi_uc rgbe[4];
-                  main_decode_loop:
-                       stbi__getn(s, rgbe, 4);
-                       stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
-                }
-         }
-   } else {
-         // Read RLE-encoded data
-         scanline = NULL;
-
-         for (j = 0; j < height; ++j) {
-                c1 = stbi__get8(s);
-                c2 = stbi__get8(s);
-                len = stbi__get8(s);
-                if (c1 != 2 || c2 != 2 || (len & 0x80)) {
-                       // not run-length encoded, so we have to actually use THIS data as a decoded
-                       // pixel (note this can't be a valid pixel--one of RGB must be >= 128)
-                       stbi_uc rgbe[4];
-                       rgbe[0] = (stbi_uc) c1;
-                       rgbe[1] = (stbi_uc) c2;
-                       rgbe[2] = (stbi_uc) len;
-                       rgbe[3] = (stbi_uc) stbi__get8(s);
-                       stbi__hdr_convert(hdr_data, rgbe, req_comp);
-                       i = 1;
-                       j = 0;
-                       STBI_FREE(scanline);
-                       goto main_decode_loop; // yes, this makes no sense
-                }
-                len <<= 8;
-                len |= stbi__get8(s);
-                if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
-                if (scanline == NULL) {
-                       scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0);
-                       if (!scanline) {
-                          STBI_FREE(hdr_data);
-                          return stbi__errpf("outofmem", "Out of memory");
-                       }
-                }
-
-                for (k = 0; k < 4; ++k) {
-                       int nleft;
-                       i = 0;
-                       while ((nleft = width - i) > 0) {
-                          count = stbi__get8(s);
-                          if (count > 128) {
-                                 // Run
-                                 value = stbi__get8(s);
-                                 count -= 128;
-                                 if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
-                                 for (z = 0; z < count; ++z)
-                                        scanline[i++ * 4 + k] = value;
-                          } else {
-                                 // Dump
-                                 if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
-                                 for (z = 0; z < count; ++z)
-                                        scanline[i++ * 4 + k] = stbi__get8(s);
-                          }
-                       }
-                }
-                for (i=0; i < width; ++i)
-                       stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
-         }
-         if (scanline)
-                STBI_FREE(scanline);
-   }
-
-   return hdr_data;
-}
-
-static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   char buffer[STBI__HDR_BUFLEN];
-   char *token;
-   int valid = 0;
-   int dummy;
-
-   if (!x) x = &dummy;
-   if (!y) y = &dummy;
-   if (!comp) comp = &dummy;
-
-   if (stbi__hdr_test(s) == 0) {
-          stbi__rewind( s );
-          return 0;
-   }
-
-   for(;;) {
-         token = stbi__hdr_gettoken(s,buffer);
-         if (token[0] == 0) break;
-         if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
-   }
-
-   if (!valid) {
-          stbi__rewind( s );
-          return 0;
-   }
-   token = stbi__hdr_gettoken(s,buffer);
-   if (strncmp(token, "-Y ", 3)) {
-          stbi__rewind( s );
-          return 0;
-   }
-   token += 3;
-   *y = (int) strtol(token, &token, 10);
-   while (*token == ' ') ++token;
-   if (strncmp(token, "+X ", 3)) {
-          stbi__rewind( s );
-          return 0;
-   }
-   token += 3;
-   *x = (int) strtol(token, NULL, 10);
-   *comp = 3;
-   return 1;
+static int stbi__hdr_test_core(stbi__context *s, const char *signature) {
+    int i;
+    for (i = 0; signature[i]; ++i)
+        if (stbi__get8(s) != signature[i])
+            return 0;
+    stbi__rewind(s);
+    return 1;
+}
+
+static int stbi__hdr_test(stbi__context *s) {
+    int r = stbi__hdr_test_core(s, "#?RADIANCE\n");
+    stbi__rewind(s);
+    if (!r) {
+        r = stbi__hdr_test_core(s, "#?RGBE\n");
+        stbi__rewind(s);
+    }
+    return r;
+}
+
+#define STBI__HDR_BUFLEN 1024
+static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) {
+    int  len = 0;
+    char c   = '\0';
+
+    c = (char)stbi__get8(z);
+
+    while (!stbi__at_eof(z) && c != '\n') {
+        buffer[len++] = c;
+        if (len == STBI__HDR_BUFLEN - 1) {
+            // flush to end of line
+            while (!stbi__at_eof(z) && stbi__get8(z) != '\n')
+                ;
+            break;
+        }
+        c = (char)stbi__get8(z);
+    }
+
+    buffer[len] = 0;
+    return buffer;
+}
+
+static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) {
+    if (input[3] != 0) {
+        float f1;
+        // Exponent
+        f1 = (float)ldexp(1.0f, input[3] - (int)(128 + 8));
+        if (req_comp <= 2)
+            output[0] = (input[0] + input[1] + input[2]) * f1 / 3;
+        else {
+            output[0] = input[0] * f1;
+            output[1] = input[1] * f1;
+            output[2] = input[2] * f1;
+        }
+        if (req_comp == 2)
+            output[1] = 1;
+        if (req_comp == 4)
+            output[3] = 1;
+    } else {
+        switch (req_comp) {
+        case 4:
+            output[3] = 1; /* fallthrough */
+        case 3:
+            output[0] = output[1] = output[2] = 0;
+            break;
+        case 2:
+            output[1] = 1; /* fallthrough */
+        case 1:
+            output[0] = 0;
+            break;
+        }
+    }
+}
+
+static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) {
+    char          buffer[STBI__HDR_BUFLEN];
+    char         *token;
+    int           valid = 0;
+    int           width, height;
+    stbi_uc      *scanline;
+    float        *hdr_data;
+    int           len;
+    unsigned char count, value;
+    int           i, j, k, c1, c2, z;
+    const char   *headerToken;
+    STBI_NOTUSED(ri);
+
+    // Check identifier
+    headerToken = stbi__hdr_gettoken(s, buffer);
+    if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0)
+        return stbi__errpf("not HDR", "Corrupt HDR image");
+
+    // Parse header
+    for (;;) {
+        token = stbi__hdr_gettoken(s, buffer);
+        if (token[0] == 0)
+            break;
+        if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0)
+            valid = 1;
+    }
+
+    if (!valid)
+        return stbi__errpf("unsupported format", "Unsupported HDR format");
+
+    // Parse width and height
+    // can't use sscanf() if we're not using stdio!
+    token = stbi__hdr_gettoken(s, buffer);
+    if (strncmp(token, "-Y ", 3))
+        return stbi__errpf("unsupported data layout", "Unsupported HDR format");
+    token += 3;
+    height = (int)strtol(token, &token, 10);
+    while (*token == ' ')
+        ++token;
+    if (strncmp(token, "+X ", 3))
+        return stbi__errpf("unsupported data layout", "Unsupported HDR format");
+    token += 3;
+    width = (int)strtol(token, NULL, 10);
+
+    *x = width;
+    *y = height;
+
+    if (comp)
+        *comp = 3;
+    if (req_comp == 0)
+        req_comp = 3;
+
+    if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0))
+        return stbi__errpf("too large", "HDR image is too large");
+
+    // Read data
+    hdr_data = (float *)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0);
+    if (!hdr_data)
+        return stbi__errpf("outofmem", "Out of memory");
+
+    // Load image data
+    // image data is stored as some number of sca
+    if (width < 8 || width >= 32768) {
+        // Read flat data
+        for (j = 0; j < height; ++j) {
+            for (i = 0; i < width; ++i) {
+                stbi_uc rgbe[4];
+            main_decode_loop:
+                stbi__getn(s, rgbe, 4);
+                stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
+            }
+        }
+    } else {
+        // Read RLE-encoded data
+        scanline = NULL;
+
+        for (j = 0; j < height; ++j) {
+            c1  = stbi__get8(s);
+            c2  = stbi__get8(s);
+            len = stbi__get8(s);
+            if (c1 != 2 || c2 != 2 || (len & 0x80)) {
+                // not run-length encoded, so we have to actually use THIS data as a decoded
+                // pixel (note this can't be a valid pixel--one of RGB must be >= 128)
+                stbi_uc rgbe[4];
+                rgbe[0] = (stbi_uc)c1;
+                rgbe[1] = (stbi_uc)c2;
+                rgbe[2] = (stbi_uc)len;
+                rgbe[3] = (stbi_uc)stbi__get8(s);
+                stbi__hdr_convert(hdr_data, rgbe, req_comp);
+                i = 1;
+                j = 0;
+                STBI_FREE(scanline);
+                goto main_decode_loop; // yes, this makes no sense
+            }
+            len <<= 8;
+            len |= stbi__get8(s);
+            if (len != width) {
+                STBI_FREE(hdr_data);
+                STBI_FREE(scanline);
+                return stbi__errpf("invalid decoded scanline length", "corrupt HDR");
+            }
+            if (scanline == NULL) {
+                scanline = (stbi_uc *)stbi__malloc_mad2(width, 4, 0);
+                if (!scanline) {
+                    STBI_FREE(hdr_data);
+                    return stbi__errpf("outofmem", "Out of memory");
+                }
+            }
+
+            for (k = 0; k < 4; ++k) {
+                int nleft;
+                i = 0;
+                while ((nleft = width - i) > 0) {
+                    count = stbi__get8(s);
+                    if (count > 128) {
+                        // Run
+                        value = stbi__get8(s);
+                        count -= 128;
+                        if (count > nleft) {
+                            STBI_FREE(hdr_data);
+                            STBI_FREE(scanline);
+                            return stbi__errpf("corrupt", "bad RLE data in HDR");
+                        }
+                        for (z = 0; z < count; ++z)
+                            scanline[i++ * 4 + k] = value;
+                    } else {
+                        // Dump
+                        if (count > nleft) {
+                            STBI_FREE(hdr_data);
+                            STBI_FREE(scanline);
+                            return stbi__errpf("corrupt", "bad RLE data in HDR");
+                        }
+                        for (z = 0; z < count; ++z)
+                            scanline[i++ * 4 + k] = stbi__get8(s);
+                    }
+                }
+            }
+            for (i = 0; i < width; ++i)
+                stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp);
+        }
+        if (scanline)
+            STBI_FREE(scanline);
+    }
+
+    return hdr_data;
+}
+
+static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) {
+    char  buffer[STBI__HDR_BUFLEN];
+    char *token;
+    int   valid = 0;
+    int   dummy;
+
+    if (!x)
+        x = &dummy;
+    if (!y)
+        y = &dummy;
+    if (!comp)
+        comp = &dummy;
+
+    if (stbi__hdr_test(s) == 0) {
+        stbi__rewind(s);
+        return 0;
+    }
+
+    for (;;) {
+        token = stbi__hdr_gettoken(s, buffer);
+        if (token[0] == 0)
+            break;
+        if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0)
+            valid = 1;
+    }
+
+    if (!valid) {
+        stbi__rewind(s);
+        return 0;
+    }
+    token = stbi__hdr_gettoken(s, buffer);
+    if (strncmp(token, "-Y ", 3)) {
+        stbi__rewind(s);
+        return 0;
+    }
+    token += 3;
+    *y = (int)strtol(token, &token, 10);
+    while (*token == ' ')
+        ++token;
+    if (strncmp(token, "+X ", 3)) {
+        stbi__rewind(s);
+        return 0;
+    }
+    token += 3;
+    *x    = (int)strtol(token, NULL, 10);
+    *comp = 3;
+    return 1;
 }
 #endif // STBI_NO_HDR
 
 #ifndef STBI_NO_BMP
-static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   void *p;
-   stbi__bmp_data info;
-
-   info.all_a = 255;
-   p = stbi__bmp_parse_header(s, &info);
-   stbi__rewind( s );
-   if (p == NULL)
-         return 0;
-   if (x) *x = s->img_x;
-   if (y) *y = s->img_y;
-   if (comp) *comp = info.ma ? 4 : 3;
-   return 1;
+static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) {
+    void          *p;
+    stbi__bmp_data info;
+
+    info.all_a = 255;
+    p          = stbi__bmp_parse_header(s, &info);
+    stbi__rewind(s);
+    if (p == NULL)
+        return 0;
+    if (x)
+        *x = s->img_x;
+    if (y)
+        *y = s->img_y;
+    if (comp)
+        *comp = info.ma ? 4 : 3;
+    return 1;
 }
 #endif
 
 #ifndef STBI_NO_PSD
-static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   int channelCount, dummy, depth;
-   if (!x) x = &dummy;
-   if (!y) y = &dummy;
-   if (!comp) comp = &dummy;
-   if (stbi__get32be(s) != 0x38425053) {
-          stbi__rewind( s );
-          return 0;
-   }
-   if (stbi__get16be(s) != 1) {
-          stbi__rewind( s );
-          return 0;
-   }
-   stbi__skip(s, 6);
-   channelCount = stbi__get16be(s);
-   if (channelCount < 0 || channelCount > 16) {
-          stbi__rewind( s );
-          return 0;
-   }
-   *y = stbi__get32be(s);
-   *x = stbi__get32be(s);
-   depth = stbi__get16be(s);
-   if (depth != 8 && depth != 16) {
-          stbi__rewind( s );
-          return 0;
-   }
-   if (stbi__get16be(s) != 3) {
-          stbi__rewind( s );
-          return 0;
-   }
-   *comp = 4;
-   return 1;
-}
-
-static int stbi__psd_is16(stbi__context *s)
-{
-   int channelCount, depth;
-   if (stbi__get32be(s) != 0x38425053) {
-          stbi__rewind( s );
-          return 0;
-   }
-   if (stbi__get16be(s) != 1) {
-          stbi__rewind( s );
-          return 0;
-   }
-   stbi__skip(s, 6);
-   channelCount = stbi__get16be(s);
-   if (channelCount < 0 || channelCount > 16) {
-          stbi__rewind( s );
-          return 0;
-   }
-   (void) stbi__get32be(s);
-   (void) stbi__get32be(s);
-   depth = stbi__get16be(s);
-   if (depth != 16) {
-          stbi__rewind( s );
-          return 0;
-   }
-   return 1;
+static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) {
+    int channelCount, dummy, depth;
+    if (!x)
+        x = &dummy;
+    if (!y)
+        y = &dummy;
+    if (!comp)
+        comp = &dummy;
+    if (stbi__get32be(s) != 0x38425053) {
+        stbi__rewind(s);
+        return 0;
+    }
+    if (stbi__get16be(s) != 1) {
+        stbi__rewind(s);
+        return 0;
+    }
+    stbi__skip(s, 6);
+    channelCount = stbi__get16be(s);
+    if (channelCount < 0 || channelCount > 16) {
+        stbi__rewind(s);
+        return 0;
+    }
+    *y    = stbi__get32be(s);
+    *x    = stbi__get32be(s);
+    depth = stbi__get16be(s);
+    if (depth != 8 && depth != 16) {
+        stbi__rewind(s);
+        return 0;
+    }
+    if (stbi__get16be(s) != 3) {
+        stbi__rewind(s);
+        return 0;
+    }
+    *comp = 4;
+    return 1;
+}
+
+static int stbi__psd_is16(stbi__context *s) {
+    int channelCount, depth;
+    if (stbi__get32be(s) != 0x38425053) {
+        stbi__rewind(s);
+        return 0;
+    }
+    if (stbi__get16be(s) != 1) {
+        stbi__rewind(s);
+        return 0;
+    }
+    stbi__skip(s, 6);
+    channelCount = stbi__get16be(s);
+    if (channelCount < 0 || channelCount > 16) {
+        stbi__rewind(s);
+        return 0;
+    }
+    (void)stbi__get32be(s);
+    (void)stbi__get32be(s);
+    depth = stbi__get16be(s);
+    if (depth != 16) {
+        stbi__rewind(s);
+        return 0;
+    }
+    return 1;
 }
 #endif
 
 #ifndef STBI_NO_PIC
-static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   int act_comp=0,num_packets=0,chained,dummy;
-   stbi__pic_packet packets[10];
-
-   if (!x) x = &dummy;
-   if (!y) y = &dummy;
-   if (!comp) comp = &dummy;
-
-   if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
-         stbi__rewind(s);
-         return 0;
-   }
-
-   stbi__skip(s, 88);
-
-   *x = stbi__get16be(s);
-   *y = stbi__get16be(s);
-   if (stbi__at_eof(s)) {
-         stbi__rewind( s);
-         return 0;
-   }
-   if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) {
-         stbi__rewind( s );
-         return 0;
-   }
-
-   stbi__skip(s, 8);
-
-   do {
-         stbi__pic_packet *packet;
-
-         if (num_packets==sizeof(packets)/sizeof(packets[0]))
-                return 0;
-
-         packet = &packets[num_packets++];
-         chained = stbi__get8(s);
-         packet->size    = stbi__get8(s);
-         packet->type    = stbi__get8(s);
-         packet->channel = stbi__get8(s);
-         act_comp |= packet->channel;
-
-         if (stbi__at_eof(s)) {
-                 stbi__rewind( s );
-                 return 0;
-         }
-         if (packet->size != 8) {
-                 stbi__rewind( s );
-                 return 0;
-         }
-   } while (chained);
-
-   *comp = (act_comp & 0x10 ? 4 : 3);
-
-   return 1;
+static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) {
+    int              act_comp = 0, num_packets = 0, chained, dummy;
+    stbi__pic_packet packets[10];
+
+    if (!x)
+        x = &dummy;
+    if (!y)
+        y = &dummy;
+    if (!comp)
+        comp = &dummy;
+
+    if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) {
+        stbi__rewind(s);
+        return 0;
+    }
+
+    stbi__skip(s, 88);
+
+    *x = stbi__get16be(s);
+    *y = stbi__get16be(s);
+    if (stbi__at_eof(s)) {
+        stbi__rewind(s);
+        return 0;
+    }
+    if ((*x) != 0 && (1 << 28) / (*x) < (*y)) {
+        stbi__rewind(s);
+        return 0;
+    }
+
+    stbi__skip(s, 8);
+
+    do {
+        stbi__pic_packet *packet;
+
+        if (num_packets == sizeof(packets) / sizeof(packets[0]))
+            return 0;
+
+        packet          = &packets[num_packets++];
+        chained         = stbi__get8(s);
+        packet->size    = stbi__get8(s);
+        packet->type    = stbi__get8(s);
+        packet->channel = stbi__get8(s);
+        act_comp |= packet->channel;
+
+        if (stbi__at_eof(s)) {
+            stbi__rewind(s);
+            return 0;
+        }
+        if (packet->size != 8) {
+            stbi__rewind(s);
+            return 0;
+        }
+    } while (chained);
+
+    *comp = (act_comp & 0x10 ? 4 : 3);
+
+    return 1;
 }
 #endif
 
@@ -6994,431 +7316,426 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
 
 #ifndef STBI_NO_PNM
 
-static int             stbi__pnm_test(stbi__context *s)
-{
-   char p, t;
-   p = (char) stbi__get8(s);
-   t = (char) stbi__get8(s);
-   if (p != 'P' || (t != '5' && t != '6')) {
-          stbi__rewind( s );
-          return 0;
-   }
-   return 1;
+static int stbi__pnm_test(stbi__context *s) {
+    char p, t;
+    p = (char)stbi__get8(s);
+    t = (char)stbi__get8(s);
+    if (p != 'P' || (t != '5' && t != '6')) {
+        stbi__rewind(s);
+        return 0;
+    }
+    return 1;
 }
 
-static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
-{
-   stbi_uc *out;
-   STBI_NOTUSED(ri);
+static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) {
+    stbi_uc *out;
+    STBI_NOTUSED(ri);
 
-   if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
-         return 0;
+    if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
+        return 0;
 
-   *x = s->img_x;
-   *y = s->img_y;
-   if (comp) *comp = s->img_n;
+    *x = s->img_x;
+    *y = s->img_y;
+    if (comp)
+        *comp = s->img_n;
 
-   if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
-         return stbi__errpuc("too large", "PNM too large");
+    if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
+        return stbi__errpuc("too large", "PNM too large");
 
-   out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0);
-   if (!out) return stbi__errpuc("outofmem", "Out of memory");
-   stbi__getn(s, out, s->img_n * s->img_x * s->img_y);
+    out = (stbi_uc *)stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0);
+    if (!out)
+        return stbi__errpuc("outofmem", "Out of memory");
+    stbi__getn(s, out, s->img_n * s->img_x * s->img_y);
 
-   if (req_comp && req_comp != s->img_n) {
-         out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
-         if (out == NULL) return out; // stbi__convert_format frees input on failure
-   }
-   return out;
+    if (req_comp && req_comp != s->img_n) {
+        out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
+        if (out == NULL)
+            return out; // stbi__convert_format frees input on failure
+    }
+    return out;
 }
 
-static int             stbi__pnm_isspace(char c)
-{
-   return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
+static int stbi__pnm_isspace(char c) {
+    return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
 }
 
-static void            stbi__pnm_skip_whitespace(stbi__context *s, char *c)
-{
-   for (;;) {
-         while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
-                *c = (char) stbi__get8(s);
+static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) {
+    for (;;) {
+        while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
+            *c = (char)stbi__get8(s);
 
-         if (stbi__at_eof(s) || *c != '#')
-                break;
+        if (stbi__at_eof(s) || *c != '#')
+            break;
 
-         while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' )
-                *c = (char) stbi__get8(s);
-   }
+        while (!stbi__at_eof(s) && *c != '\n' && *c != '\r')
+            *c = (char)stbi__get8(s);
+    }
 }
 
-static int             stbi__pnm_isdigit(char c)
-{
-   return c >= '0' && c <= '9';
-}
+static int stbi__pnm_isdigit(char c) { return c >= '0' && c <= '9'; }
 
-static int             stbi__pnm_getinteger(stbi__context *s, char *c)
-{
-   int value = 0;
+static int stbi__pnm_getinteger(stbi__context *s, char *c) {
+    int value = 0;
 
-   while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
-         value = value*10 + (*c - '0');
-         *c = (char) stbi__get8(s);
-   }
+    while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
+        value = value * 10 + (*c - '0');
+        *c    = (char)stbi__get8(s);
+    }
 
-   return value;
+    return value;
 }
 
-static int             stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
-{
-   int maxv, dummy;
-   char c, p, t;
+static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) {
+    int  maxv, dummy;
+    char c, p, t;
 
-   if (!x) x = &dummy;
-   if (!y) y = &dummy;
-   if (!comp) comp = &dummy;
+    if (!x)
+        x = &dummy;
+    if (!y)
+        y = &dummy;
+    if (!comp)
+        comp = &dummy;
 
-   stbi__rewind(s);
+    stbi__rewind(s);
 
-   // Get identifier
-   p = (char) stbi__get8(s);
-   t = (char) stbi__get8(s);
-   if (p != 'P' || (t != '5' && t != '6')) {
-          stbi__rewind(s);
-          return 0;
-   }
+    // Get identifier
+    p = (char)stbi__get8(s);
+    t = (char)stbi__get8(s);
+    if (p != 'P' || (t != '5' && t != '6')) {
+        stbi__rewind(s);
+        return 0;
+    }
 
-   *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm
+    *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm
 
-   c = (char) stbi__get8(s);
-   stbi__pnm_skip_whitespace(s, &c);
+    c = (char)stbi__get8(s);
+    stbi__pnm_skip_whitespace(s, &c);
 
-   *x = stbi__pnm_getinteger(s, &c); // read width
-   stbi__pnm_skip_whitespace(s, &c);
+    *x = stbi__pnm_getinteger(s, &c); // read width
+    stbi__pnm_skip_whitespace(s, &c);
 
-   *y = stbi__pnm_getinteger(s, &c); // read height
-   stbi__pnm_skip_whitespace(s, &c);
+    *y = stbi__pnm_getinteger(s, &c); // read height
+    stbi__pnm_skip_whitespace(s, &c);
 
-   maxv = stbi__pnm_getinteger(s, &c); // read max value
+    maxv = stbi__pnm_getinteger(s, &c); // read max value
 
-   if (maxv > 255)
-         return stbi__err("max value > 255", "PPM image not 8-bit");
-   else
-         return 1;
+    if (maxv > 255)
+        return stbi__err("max value > 255", "PPM image not 8-bit");
+    else
+        return 1;
 }
 #endif
 
-static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
-{
-   #ifndef STBI_NO_JPEG
-   if (stbi__jpeg_info(s, x, y, comp)) return 1;
-   #endif
+static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) {
+#ifndef STBI_NO_JPEG
+    if (stbi__jpeg_info(s, x, y, comp))
+        return 1;
+#endif
 
-   #ifndef STBI_NO_PNG
-   if (stbi__png_info(s, x, y, comp))  return 1;
-   #endif
+#ifndef STBI_NO_PNG
+    if (stbi__png_info(s, x, y, comp))
+        return 1;
+#endif
 
-   #ifndef STBI_NO_GIF
-   if (stbi__gif_info(s, x, y, comp))  return 1;
-   #endif
+#ifndef STBI_NO_GIF
+    if (stbi__gif_info(s, x, y, comp))
+        return 1;
+#endif
 
-   #ifndef STBI_NO_BMP
-   if (stbi__bmp_info(s, x, y, comp))  return 1;
-   #endif
+#ifndef STBI_NO_BMP
+    if (stbi__bmp_info(s, x, y, comp))
+        return 1;
+#endif
 
-   #ifndef STBI_NO_PSD
-   if (stbi__psd_info(s, x, y, comp))  return 1;
-   #endif
+#ifndef STBI_NO_PSD
+    if (stbi__psd_info(s, x, y, comp))
+        return 1;
+#endif
 
-   #ifndef STBI_NO_PIC
-   if (stbi__pic_info(s, x, y, comp))  return 1;
-   #endif
+#ifndef STBI_NO_PIC
+    if (stbi__pic_info(s, x, y, comp))
+        return 1;
+#endif
 
-   #ifndef STBI_NO_PNM
-   if (stbi__pnm_info(s, x, y, comp))  return 1;
-   #endif
+#ifndef STBI_NO_PNM
+    if (stbi__pnm_info(s, x, y, comp))
+        return 1;
+#endif
 
-   #ifndef STBI_NO_HDR
-   if (stbi__hdr_info(s, x, y, comp))  return 1;
-   #endif
+#ifndef STBI_NO_HDR
+    if (stbi__hdr_info(s, x, y, comp))
+        return 1;
+#endif
 
-   // test tga last because it's a crappy test!
-   #ifndef STBI_NO_TGA
-   if (stbi__tga_info(s, x, y, comp))
-          return 1;
-   #endif
-   return stbi__err("unknown image type", "Image not of any known type, or corrupt");
+// test tga last because it's a crappy test!
+#ifndef STBI_NO_TGA
+    if (stbi__tga_info(s, x, y, comp))
+        return 1;
+#endif
+    return stbi__err("unknown image type", "Image not of any known type, or corrupt");
 }
 
-static int stbi__is_16_main(stbi__context *s)
-{
-   #ifndef STBI_NO_PNG
-   if (stbi__png_is16(s))  return 1;
-   #endif
+static int stbi__is_16_main(stbi__context *s) {
+#ifndef STBI_NO_PNG
+    if (stbi__png_is16(s))
+        return 1;
+#endif
 
-   #ifndef STBI_NO_PSD
-   if (stbi__psd_is16(s))  return 1;
-   #endif
+#ifndef STBI_NO_PSD
+    if (stbi__psd_is16(s))
+        return 1;
+#endif
 
-   return 0;
+    return 0;
 }
 
 #ifndef STBI_NO_STDIO
-STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp)
-{
-       FILE *f = stbi__fopen(filename, "rb");
-       int result;
-       if (!f) return stbi__err("can't fopen", "Unable to open file");
-       result = stbi_info_from_file(f, x, y, comp);
-       fclose(f);
-       return result;
-}
-
-STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
-{
-   int r;
-   stbi__context s;
-   long pos = ftell(f);
-   stbi__start_file(&s, f);
-   r = stbi__info_main(&s,x,y,comp);
-   fseek(f,pos,SEEK_SET);
-   return r;
-}
-
-STBIDEF int stbi_is_16_bit(char const *filename)
-{
-       FILE *f = stbi__fopen(filename, "rb");
-       int result;
-       if (!f) return stbi__err("can't fopen", "Unable to open file");
-       result = stbi_is_16_bit_from_file(f);
-       fclose(f);
-       return result;
-}
-
-STBIDEF int stbi_is_16_bit_from_file(FILE *f)
-{
-   int r;
-   stbi__context s;
-   long pos = ftell(f);
-   stbi__start_file(&s, f);
-   r = stbi__is_16_main(&s);
-   fseek(f,pos,SEEK_SET);
-   return r;
+STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) {
+    FILE *f = stbi__fopen(filename, "rb");
+    int   result;
+    if (!f)
+        return stbi__err("can't fopen", "Unable to open file");
+    result = stbi_info_from_file(f, x, y, comp);
+    fclose(f);
+    return result;
+}
+
+STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) {
+    int           r;
+    stbi__context s;
+    long          pos = ftell(f);
+    stbi__start_file(&s, f);
+    r = stbi__info_main(&s, x, y, comp);
+    fseek(f, pos, SEEK_SET);
+    return r;
+}
+
+STBIDEF int stbi_is_16_bit(char const *filename) {
+    FILE *f = stbi__fopen(filename, "rb");
+    int   result;
+    if (!f)
+        return stbi__err("can't fopen", "Unable to open file");
+    result = stbi_is_16_bit_from_file(f);
+    fclose(f);
+    return result;
+}
+
+STBIDEF int stbi_is_16_bit_from_file(FILE *f) {
+    int           r;
+    stbi__context s;
+    long          pos = ftell(f);
+    stbi__start_file(&s, f);
+    r = stbi__is_16_main(&s);
+    fseek(f, pos, SEEK_SET);
+    return r;
 }
 #endif // !STBI_NO_STDIO
 
-STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__info_main(&s,x,y,comp);
+STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) {
+    stbi__context s;
+    stbi__start_mem(&s, buffer, len);
+    return stbi__info_main(&s, x, y, comp);
 }
 
-STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
-   return stbi__info_main(&s,x,y,comp);
+STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) {
+    stbi__context s;
+    stbi__start_callbacks(&s, (stbi_io_callbacks *)c, user);
+    return stbi__info_main(&s, x, y, comp);
 }
 
-STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len)
-{
-   stbi__context s;
-   stbi__start_mem(&s,buffer,len);
-   return stbi__is_16_main(&s);
+STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) {
+    stbi__context s;
+    stbi__start_mem(&s, buffer, len);
+    return stbi__is_16_main(&s);
 }
 
-STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user)
-{
-   stbi__context s;
-   stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
-   return stbi__is_16_main(&s);
+STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) {
+    stbi__context s;
+    stbi__start_callbacks(&s, (stbi_io_callbacks *)c, user);
+    return stbi__is_16_main(&s);
 }
 
 #endif // STB_IMAGE_IMPLEMENTATION
 
 /*
    revision history:
-         2.19  (2018-02-11) fix warning
-         2.18  (2018-01-30) fix warnings
-         2.17  (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
-                                                1-bit BMP
-                                                *_is_16_bit api
-                                                avoid warnings
-         2.16  (2017-07-23) all functions have 16-bit variants;
-                                                STBI_NO_STDIO works again;
-                                                compilation fixes;
-                                                fix rounding in unpremultiply;
-                                                optimize vertical flip;
-                                                disable raw_len validation;
-                                                documentation fixes
-         2.15  (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
-                                                warning fixes; disable run-time SSE detection on gcc;
-                                                uniform handling of optional "return" values;
-                                                thread-safe initialization of zlib tables
-         2.14  (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
-         2.13  (2016-11-29) add 16-bit API, only supported for PNG right now
-         2.12  (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
-         2.11  (2016-04-02) allocate large structures on the stack
-                                                remove white matting for transparent PSD
-                                                fix reported channel count for PNG & BMP
-                                                re-enable SSE2 in non-gcc 64-bit
-                                                support RGB-formatted JPEG
-                                                read 16-bit PNGs (only as 8-bit)
-         2.10  (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
-         2.09  (2016-01-16) allow comments in PNM files
-                                                16-bit-per-pixel TGA (not bit-per-component)
-                                                info() for TGA could break due to .hdr handling
-                                                info() for BMP to shares code instead of sloppy parse
-                                                can use STBI_REALLOC_SIZED if allocator doesn't support realloc
-                                                code cleanup
-         2.08  (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
-         2.07  (2015-09-13) fix compiler warnings
-                                                partial animated GIF support
-                                                limited 16-bpc PSD support
-                                                #ifdef unused functions
-                                                bug with < 92 byte PIC,PNM,HDR,TGA
-         2.06  (2015-04-19) fix bug where PSD returns wrong '*comp' value
-         2.05  (2015-04-19) fix bug in progressive JPEG handling, fix warning
-         2.04  (2015-04-15) try to re-enable SIMD on MinGW 64-bit
-         2.03  (2015-04-12) extra corruption checking (mmozeiko)
-                                                stbi_set_flip_vertically_on_load (nguillemot)
-                                                fix NEON support; fix mingw support
-         2.02  (2015-01-19) fix incorrect assert, fix warning
-         2.01  (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2
-         2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
-         2.00  (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg)
-                                                progressive JPEG (stb)
-                                                PGM/PPM support (Ken Miller)
-                                                STBI_MALLOC,STBI_REALLOC,STBI_FREE
-                                                GIF bugfix -- seemingly never worked
-                                                STBI_NO_*, STBI_ONLY_*
-         1.48  (2014-12-14) fix incorrectly-named assert()
-         1.47  (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb)
-                                                optimize PNG (ryg)
-                                                fix bug in interlaced PNG with user-specified channel count (stb)
-         1.46  (2014-08-26)
-                         fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG
-         1.45  (2014-08-16)
-                         fix MSVC-ARM internal compiler error by wrapping malloc
-         1.44  (2014-08-07)
-                         various warning fixes from Ronny Chevalier
-         1.43  (2014-07-15)
-                         fix MSVC-only compiler problem in code changed in 1.42
-         1.42  (2014-07-09)
-                         don't define _CRT_SECURE_NO_WARNINGS (affects user code)
-                         fixes to stbi__cleanup_jpeg path
-                         added STBI_ASSERT to avoid requiring assert.h
-         1.41  (2014-06-25)
-                         fix search&replace from 1.36 that messed up comments/error messages
-         1.40  (2014-06-22)
-                         fix gcc struct-initialization warning
-         1.39  (2014-06-15)
-                         fix to TGA optimization when req_comp != number of components in TGA;
-                         fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite)
-                         add support for BMP version 5 (more ignored fields)
-         1.38  (2014-06-06)
-                         suppress MSVC warnings on integer casts truncating values
-                         fix accidental rename of 'skip' field of I/O
-         1.37  (2014-06-04)
-                         remove duplicate typedef
-         1.36  (2014-06-03)
-                         convert to header file single-file library
-                         if de-iphone isn't set, load iphone images color-swapped instead of returning NULL
-         1.35  (2014-05-27)
-                         various warnings
-                         fix broken STBI_SIMD path
-                         fix bug where stbi_load_from_file no longer left file pointer in correct place
-                         fix broken non-easy path for 32-bit BMP (possibly never used)
-                         TGA optimization by Arseny Kapoulkine
-         1.34  (unknown)
-                         use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case
-         1.33  (2011-07-14)
-                         make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements
-         1.32  (2011-07-13)
-                         support for "info" function for all supported filetypes (SpartanJ)
-         1.31  (2011-06-20)
-                         a few more leak fixes, bug in PNG handling (SpartanJ)
-         1.30  (2011-06-11)
-                         added ability to load files via callbacks to accomidate custom input streams (Ben Wenger)
-                         removed deprecated format-specific test/load functions
-                         removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway
-                         error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha)
-                         fix inefficiency in decoding 32-bit BMP (David Woo)
-         1.29  (2010-08-16)
-                         various warning fixes from Aurelien Pocheville
-         1.28  (2010-08-01)
-                         fix bug in GIF palette transparency (SpartanJ)
-         1.27  (2010-08-01)
-                         cast-to-stbi_uc to fix warnings
-         1.26  (2010-07-24)
-                         fix bug in file buffering for PNG reported by SpartanJ
-         1.25  (2010-07-17)
-                         refix trans_data warning (Won Chun)
-         1.24  (2010-07-12)
-                         perf improvements reading from files on platforms with lock-heavy fgetc()
-                         minor perf improvements for jpeg
-                         deprecated type-specific functions so we'll get feedback if they're needed
-                         attempt to fix trans_data warning (Won Chun)
-         1.23    fixed bug in iPhone support
-         1.22  (2010-07-10)
-                         removed image *writing* support
-                         stbi_info support from Jetro Lauha
-                         GIF support from Jean-Marc Lienher
-                         iPhone PNG-extensions from James Brown
-                         warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva)
-         1.21    fix use of 'stbi_uc' in header (reported by jon blow)
-         1.20    added support for Softimage PIC, by Tom Seddon
-         1.19    bug in interlaced PNG corruption check (found by ryg)
-         1.18  (2008-08-02)
-                         fix a threading bug (local mutable static)
-         1.17    support interlaced PNG
-         1.16    major bugfix - stbi__convert_format converted one too many pixels
-         1.15    initialize some fields for thread safety
-         1.14    fix threadsafe conversion bug
-                         header-file-only version (#define STBI_HEADER_FILE_ONLY before including)
-         1.13    threadsafe
-         1.12    const qualifiers in the API
-         1.11    Support installable IDCT, colorspace conversion routines
-         1.10    Fixes for 64-bit (don't use "unsigned long")
-                         optimized upsampling by Fabian "ryg" Giesen
-         1.09    Fix format-conversion for PSD code (bad global variables!)
-         1.08    Thatcher Ulrich's PSD code integrated by Nicolas Schulz
-         1.07    attempt to fix C++ warning/errors again
-         1.06    attempt to fix C++ warning/errors again
-         1.05    fix TGA loading to return correct *comp and use good luminance calc
-         1.04    default float alpha is 1, not 255; use 'void *' for stbi_image_free
-         1.03    bugfixes to STBI_NO_STDIO, STBI_NO_HDR
-         1.02    support for (subset of) HDR files, float interface for preferred access to them
-         1.01    fix bug: possible bug in handling right-side up bmps... not sure
-                         fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all
-         1.00    interface to zlib that skips zlib header
-         0.99    correct handling of alpha in palette
-         0.98    TGA loader by lonesock; dynamically add loaders (untested)
-         0.97    jpeg errors on too large a file; also catch another malloc failure
-         0.96    fix detection of invalid v value - particleman@mollyrocket forum
-         0.95    during header scan, seek to markers in case of padding
-         0.94    STBI_NO_STDIO to disable stdio usage; rename all #defines the same
-         0.93    handle jpegtran output; verbose errors
-         0.92    read 4,8,16,24,32-bit BMP files of several formats
-         0.91    output 24-bit Windows 3.0 BMP files
-         0.90    fix a few more warnings; bump version number to approach 1.0
-         0.61    bugfixes due to Marc LeBlanc, Christopher Lloyd
-         0.60    fix compiling as c++
-         0.59    fix warnings: merge Dave Moore's -Wall fixes
-         0.58    fix bug: zlib uncompressed mode len/nlen was wrong endian
-         0.57    fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available
-         0.56    fix bug: zlib uncompressed mode len vs. nlen
-         0.55    fix bug: restart_interval not initialized to 0
-         0.54    allow NULL for 'int *comp'
-         0.53    fix bug in png 3->4; speedup png decoding
-         0.52    png handles req_comp=3,4 directly; minor cleanup; jpeg comments
-         0.51    obey req_comp requests, 1-component jpegs return as 1-component,
-                         on 'test' only check type, not whether we support this variant
-         0.50  (2006-11-19)
-                         first released version
+      2.19     (2018-02-11) fix warning
+      2.18     (2018-01-30) fix warnings
+      2.17     (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
+                         1-bit BMP
+                         *_is_16_bit api
+                         avoid warnings
+      2.16     (2017-07-23) all functions have 16-bit variants;
+                         STBI_NO_STDIO works again;
+                         compilation fixes;
+                         fix rounding in unpremultiply;
+                         optimize vertical flip;
+                         disable raw_len validation;
+                         documentation fixes
+      2.15     (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
+                         warning fixes; disable run-time SSE detection on gcc;
+                         uniform handling of optional "return" values;
+                         thread-safe initialization of zlib tables
+      2.14     (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
+      2.13     (2016-11-29) add 16-bit API, only supported for PNG right now
+      2.12     (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
+      2.11     (2016-04-02) allocate large structures on the stack
+                         remove white matting for transparent PSD
+                         fix reported channel count for PNG & BMP
+                         re-enable SSE2 in non-gcc 64-bit
+                         support RGB-formatted JPEG
+                         read 16-bit PNGs (only as 8-bit)
+      2.10     (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
+      2.09     (2016-01-16) allow comments in PNM files
+                         16-bit-per-pixel TGA (not bit-per-component)
+                         info() for TGA could break due to .hdr handling
+                         info() for BMP to shares code instead of sloppy parse
+                         can use STBI_REALLOC_SIZED if allocator doesn't support realloc
+                         code cleanup
+      2.08     (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
+      2.07     (2015-09-13) fix compiler warnings
+                         partial animated GIF support
+                         limited 16-bpc PSD support
+                         #ifdef unused functions
+                         bug with < 92 byte PIC,PNM,HDR,TGA
+      2.06     (2015-04-19) fix bug where PSD returns wrong '*comp' value
+      2.05     (2015-04-19) fix bug in progressive JPEG handling, fix warning
+      2.04     (2015-04-15) try to re-enable SIMD on MinGW 64-bit
+      2.03     (2015-04-12) extra corruption checking (mmozeiko)
+                         stbi_set_flip_vertically_on_load (nguillemot)
+                         fix NEON support; fix mingw support
+      2.02     (2015-01-19) fix incorrect assert, fix warning
+      2.01     (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2
+      2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
+      2.00     (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg)
+                         progressive JPEG (stb)
+                         PGM/PPM support (Ken Miller)
+                         STBI_MALLOC,STBI_REALLOC,STBI_FREE
+                         GIF bugfix -- seemingly never worked
+                         STBI_NO_*, STBI_ONLY_*
+      1.48     (2014-12-14) fix incorrectly-named assert()
+      1.47     (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb)
+                         optimize PNG (ryg)
+                         fix bug in interlaced PNG with user-specified channel count (stb)
+      1.46     (2014-08-26)
+              fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG
+      1.45     (2014-08-16)
+              fix MSVC-ARM internal compiler error by wrapping malloc
+      1.44     (2014-08-07)
+              various warning fixes from Ronny Chevalier
+      1.43     (2014-07-15)
+              fix MSVC-only compiler problem in code changed in 1.42
+      1.42     (2014-07-09)
+              don't define _CRT_SECURE_NO_WARNINGS (affects user code)
+              fixes to stbi__cleanup_jpeg path
+              added STBI_ASSERT to avoid requiring assert.h
+      1.41     (2014-06-25)
+              fix search&replace from 1.36 that messed up comments/error messages
+      1.40     (2014-06-22)
+              fix gcc struct-initialization warning
+      1.39     (2014-06-15)
+              fix to TGA optimization when req_comp != number of components in TGA;
+              fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite)
+              add support for BMP version 5 (more ignored fields)
+      1.38     (2014-06-06)
+              suppress MSVC warnings on integer casts truncating values
+              fix accidental rename of 'skip' field of I/O
+      1.37     (2014-06-04)
+              remove duplicate typedef
+      1.36     (2014-06-03)
+              convert to header file single-file library
+              if de-iphone isn't set, load iphone images color-swapped instead of returning NULL
+      1.35     (2014-05-27)
+              various warnings
+              fix broken STBI_SIMD path
+              fix bug where stbi_load_from_file no longer left file pointer in correct place
+              fix broken non-easy path for 32-bit BMP (possibly never used)
+              TGA optimization by Arseny Kapoulkine
+      1.34     (unknown)
+              use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case
+      1.33     (2011-07-14)
+              make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements
+      1.32     (2011-07-13)
+              support for "info" function for all supported filetypes (SpartanJ)
+      1.31     (2011-06-20)
+              a few more leak fixes, bug in PNG handling (SpartanJ)
+      1.30     (2011-06-11)
+              added ability to load files via callbacks to accomidate custom input streams (Ben Wenger)
+              removed deprecated format-specific test/load functions
+              removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks
+   anyway error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) fix inefficiency in
+   decoding 32-bit BMP (David Woo) 1.29        (2010-08-16) various warning fixes from Aurelien Pocheville 1.28        (2010-08-01)
+              fix bug in GIF palette transparency (SpartanJ)
+      1.27     (2010-08-01)
+              cast-to-stbi_uc to fix warnings
+      1.26     (2010-07-24)
+              fix bug in file buffering for PNG reported by SpartanJ
+      1.25     (2010-07-17)
+              refix trans_data warning (Won Chun)
+      1.24     (2010-07-12)
+              perf improvements reading from files on platforms with lock-heavy fgetc()
+              minor perf improvements for jpeg
+              deprecated type-specific functions so we'll get feedback if they're needed
+              attempt to fix trans_data warning (Won Chun)
+      1.23       fixed bug in iPhone support
+      1.22     (2010-07-10)
+              removed image *writing* support
+              stbi_info support from Jetro Lauha
+              GIF support from Jean-Marc Lienher
+              iPhone PNG-extensions from James Brown
+              warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva)
+      1.21       fix use of 'stbi_uc' in header (reported by jon blow)
+      1.20       added support for Softimage PIC, by Tom Seddon
+      1.19       bug in interlaced PNG corruption check (found by ryg)
+      1.18     (2008-08-02)
+              fix a threading bug (local mutable static)
+      1.17       support interlaced PNG
+      1.16       major bugfix - stbi__convert_format converted one too many pixels
+      1.15       initialize some fields for thread safety
+      1.14       fix threadsafe conversion bug
+              header-file-only version (#define STBI_HEADER_FILE_ONLY before including)
+      1.13       threadsafe
+      1.12       const qualifiers in the API
+      1.11       Support installable IDCT, colorspace conversion routines
+      1.10       Fixes for 64-bit (don't use "unsigned long")
+              optimized upsampling by Fabian "ryg" Giesen
+      1.09       Fix format-conversion for PSD code (bad global variables!)
+      1.08       Thatcher Ulrich's PSD code integrated by Nicolas Schulz
+      1.07       attempt to fix C++ warning/errors again
+      1.06       attempt to fix C++ warning/errors again
+      1.05       fix TGA loading to return correct *comp and use good luminance calc
+      1.04       default float alpha is 1, not 255; use 'void *' for stbi_image_free
+      1.03       bugfixes to STBI_NO_STDIO, STBI_NO_HDR
+      1.02       support for (subset of) HDR files, float interface for preferred access to them
+      1.01       fix bug: possible bug in handling right-side up bmps... not sure
+              fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all
+      1.00       interface to zlib that skips zlib header
+      0.99       correct handling of alpha in palette
+      0.98       TGA loader by lonesock; dynamically add loaders (untested)
+      0.97       jpeg errors on too large a file; also catch another malloc failure
+      0.96       fix detection of invalid v value - particleman@mollyrocket forum
+      0.95       during header scan, seek to markers in case of padding
+      0.94       STBI_NO_STDIO to disable stdio usage; rename all #defines the same
+      0.93       handle jpegtran output; verbose errors
+      0.92       read 4,8,16,24,32-bit BMP files of several formats
+      0.91       output 24-bit Windows 3.0 BMP files
+      0.90       fix a few more warnings; bump version number to approach 1.0
+      0.61       bugfixes due to Marc LeBlanc, Christopher Lloyd
+      0.60       fix compiling as c++
+      0.59       fix warnings: merge Dave Moore's -Wall fixes
+      0.58       fix bug: zlib uncompressed mode len/nlen was wrong endian
+      0.57       fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available
+      0.56       fix bug: zlib uncompressed mode len vs. nlen
+      0.55       fix bug: restart_interval not initialized to 0
+      0.54       allow NULL for 'int *comp'
+      0.53       fix bug in png 3->4; speedup png decoding
+      0.52       png handles req_comp=3,4 directly; minor cleanup; jpeg comments
+      0.51       obey req_comp requests, 1-component jpegs return as 1-component,
+              on 'test' only check type, not whether we support this variant
+      0.50     (2006-11-19)
+              first released version
 */
 
-
 /*
 ------------------------------------------------------------------------------
 This software is available under 2 licenses -- choose whichever you prefer.
index 082eb69d5bcd7112b0506f2780817b0bbc7d6048..c61ec30b568e8ff3e0639638144eefd80084d449 100644 (file)
@@ -55,11 +55,11 @@ USAGE:
    There are also five equivalent functions that use an arbitrary write function. You are
    expected to open/close your file-equivalent before and after calling these:
 
-     int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data, int stride_in_bytes);
-     int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
-     int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
-     int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
-     int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality);
+     int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data, int
+stride_in_bytes); int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void
+*data); int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data); int
+stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); int
+stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality);
 
    where the callback is:
       void stbi_write_func(void *context, void *data, int size);
@@ -105,7 +105,7 @@ USAGE:
 
    TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
    data, set the global variable 'stbi_write_tga_with_rle' to 0.
-   
+
    JPEG does ignore alpha channels in input data; quality is between 1 and 100.
    Higher quality looks better but results in a bigger image.
    JPEG baseline (no JPEG progressive).
@@ -113,7 +113,7 @@ USAGE:
 CREDITS:
 
 
-   Sean Barrett           -    PNG/BMP/TGA 
+   Sean Barrett           -    PNG/BMP/TGA
    Baldur Karlsson        -    HDR
    Jean-Sebastien Guay    -    TGA monochrome
    Tim Kelsey             -    misc enhancements
@@ -155,55 +155,57 @@ LICENSE
 // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
 #ifndef STBIWDEF
 #ifdef STB_IMAGE_WRITE_STATIC
-#define STBIWDEF  static
+#define STBIWDEF static
 #else
 #ifdef __cplusplus
-#define STBIWDEF  extern "C"
+#define STBIWDEF extern "C"
 #else
-#define STBIWDEF  extern
+#define STBIWDEF extern
 #endif
 #endif
 #endif
 
-#ifndef STB_IMAGE_WRITE_STATIC  // C++ forbids static forward declarations
+#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
 extern int stbi_write_tga_with_rle;
 extern int stbi_write_png_compression_level;
 extern int stbi_write_force_png_filter;
 #endif
 
 #ifndef STBI_WRITE_NO_STDIO
-STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void  *data, int stride_in_bytes);
-STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void  *data);
-STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void  *data);
+STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
+STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
+STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
 STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
-STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void  *data, int quality);
+STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
 
 #ifdef STBI_WINDOWS_UTF8
-STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_tinput);
+STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t *input);
 #endif
 #endif
 
 typedef void stbi_write_func(void *context, void *data, int size);
 
-STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data, int stride_in_bytes);
-STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
-STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
+STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data,
+                                    int stride_in_bytes);
+STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
+STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
-STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void  *data, int quality);
+STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data,
+                                    int quality);
 
 STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
 
-#endif//INCLUDE_STB_IMAGE_WRITE_H
+#endif // INCLUDE_STB_IMAGE_WRITE_H
 
 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
 
 #ifdef _WIN32
-   #ifndef _CRT_SECURE_NO_WARNINGS
-   #define _CRT_SECURE_NO_WARNINGS
-   #endif
-   #ifndef _CRT_NONSTDC_NO_DEPRECATE
-   #define _CRT_NONSTDC_NO_DEPRECATE
-   #endif
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+#ifndef _CRT_NONSTDC_NO_DEPRECATE
+#define _CRT_NONSTDC_NO_DEPRECATE
+#endif
 #endif
 
 #ifndef STBI_WRITE_NO_STDIO
@@ -225,63 +227,53 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
 
 #ifndef STBIW_MALLOC
 #define STBIW_MALLOC(sz)        malloc(sz)
-#define STBIW_REALLOC(p,newsz)  realloc(p,newsz)
+#define STBIW_REALLOC(p, newsz) realloc(p, newsz)
 #define STBIW_FREE(p)           free(p)
 #endif
 
 #ifndef STBIW_REALLOC_SIZED
-#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
+#define STBIW_REALLOC_SIZED(p, oldsz, newsz) STBIW_REALLOC(p, newsz)
 #endif
 
-
 #ifndef STBIW_MEMMOVE
-#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
+#define STBIW_MEMMOVE(a, b, sz) memmove(a, b, sz)
 #endif
 
-
 #ifndef STBIW_ASSERT
 #include <assert.h>
 #define STBIW_ASSERT(x) assert(x)
 #endif
 
-#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
+#define STBIW_UCHAR(x) (unsigned char)((x)&0xff)
 
 #ifdef STB_IMAGE_WRITE_STATIC
-static int stbi__flip_vertically_on_write=0;
+static int stbi__flip_vertically_on_write   = 0;
 static int stbi_write_png_compression_level = 8;
-static int stbi_write_tga_with_rle = 1;
-static int stbi_write_force_png_filter = -1;
+static int stbi_write_tga_with_rle          = 1;
+static int stbi_write_force_png_filter      = -1;
 #else
 int stbi_write_png_compression_level = 8;
-int stbi__flip_vertically_on_write=0;
-int stbi_write_tga_with_rle = 1;
-int stbi_write_force_png_filter = -1;
+int stbi__flip_vertically_on_write   = 0;
+int stbi_write_tga_with_rle          = 1;
+int stbi_write_force_png_filter      = -1;
 #endif
 
-STBIWDEF void stbi_flip_vertically_on_write(int flag)
-{
-   stbi__flip_vertically_on_write = flag;
-}
+STBIWDEF void stbi_flip_vertically_on_write(int flag) { stbi__flip_vertically_on_write = flag; }
 
-typedef struct
-{
-   stbi_write_func *func;
-   void *context;
+typedef struct {
+    stbi_write_func *func;
+    void            *context;
 } stbi__write_context;
 
 // initialize a callback-based context
-static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context)
-{
-   s->func    = c;
-   s->context = context;
+static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) {
+    s->func    = c;
+    s->context = context;
 }
 
 #ifndef STBI_WRITE_NO_STDIO
 
-static void stbi__stdio_write(void *context, void *data, int size)
-{
-   fwrite(data,1,size,(FILE*) context);
-}
+static void stbi__stdio_write(void *context, void *data, int size) { fwrite(data, 1, size, (FILE *)context); }
 
 #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
 #ifdef __cplusplus
@@ -289,306 +281,305 @@ static void stbi__stdio_write(void *context, void *data, int size)
 #else
 #define STBIW_EXTERN extern
 #endif
-STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
-STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
-
-STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
-{
-       return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
+STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags,
+                                                                     const char *str, int cbmb, wchar_t *widestr,
+                                                                     int cchwide);
+STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags,
+                                                                     const wchar_t *widestr, int cchwide, char *str,
+                                                                     int cbmb, const char *defchar, int *used_default);
+
+STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t *input) {
+    return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int)bufferlen, NULL, NULL);
 }
 #endif
 
-static FILE *stbiw__fopen(char const *filename, char const *mode)
-{
-   FILE *f;
+static FILE *stbiw__fopen(char const *filename, char const *mode) {
+    FILE *f;
 #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
-   wchar_t wMode[64];
-   wchar_t wFilename[1024];
-       if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
-      return 0;
-       
-       if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
-      return 0;
+    wchar_t wMode[64];
+    wchar_t wFilename[1024];
+    if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
+        return 0;
+
+    if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
+        return 0;
 
 #if _MSC_VER >= 1400
-       if (0 != _wfopen_s(&f, wFilename, wMode))
-               f = 0;
+    if (0 != _wfopen_s(&f, wFilename, wMode))
+        f = 0;
 #else
-   f = _wfopen(wFilename, wMode);
+    f = _wfopen(wFilename, wMode);
 #endif
 
 #elif defined(_MSC_VER) && _MSC_VER >= 1400
-   if (0 != fopen_s(&f, filename, mode))
-      f=0;
+    if (0 != fopen_s(&f, filename, mode))
+        f = 0;
 #else
-   f = fopen(filename, mode);
+    f = fopen(filename, mode);
 #endif
-   return f;
+    return f;
 }
 
-static int stbi__start_write_file(stbi__write_context *s, const char *filename)
-{
-   FILE *f = stbiw__fopen(filename, "wb");
-   stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
-   return f != NULL;
+static int stbi__start_write_file(stbi__write_context *s, const char *filename) {
+    FILE *f = stbiw__fopen(filename, "wb");
+    stbi__start_write_callbacks(s, stbi__stdio_write, (void *)f);
+    return f != NULL;
 }
 
-static void stbi__end_write_file(stbi__write_context *s)
-{
-   fclose((FILE *)s->context);
-}
+static void stbi__end_write_file(stbi__write_context *s) { fclose((FILE *)s->context); }
 
 #endif // !STBI_WRITE_NO_STDIO
 
 typedef unsigned int stbiw_uint32;
-typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
-
-static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
-{
-   while (*fmt) {
-      switch (*fmt++) {
-         case ' ': break;
-         case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int));
-                     s->func(s->context,&x,1);
-                     break; }
-         case '2': { int x = va_arg(v,int);
-                     unsigned char b[2];
-                     b[0] = STBIW_UCHAR(x);
-                     b[1] = STBIW_UCHAR(x>>8);
-                     s->func(s->context,b,2);
-                     break; }
-         case '4': { stbiw_uint32 x = va_arg(v,int);
-                     unsigned char b[4];
-                     b[0]=STBIW_UCHAR(x);
-                     b[1]=STBIW_UCHAR(x>>8);
-                     b[2]=STBIW_UCHAR(x>>16);
-                     b[3]=STBIW_UCHAR(x>>24);
-                     s->func(s->context,b,4);
-                     break; }
-         default:
+typedef int          stb_image_write_test[sizeof(stbiw_uint32) == 4 ? 1 : -1];
+
+static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) {
+    while (*fmt) {
+        switch (*fmt++) {
+        case ' ':
+            break;
+        case '1': {
+            unsigned char x = STBIW_UCHAR(va_arg(v, int));
+            s->func(s->context, &x, 1);
+            break;
+        }
+        case '2': {
+            int           x = va_arg(v, int);
+            unsigned char b[2];
+            b[0] = STBIW_UCHAR(x);
+            b[1] = STBIW_UCHAR(x >> 8);
+            s->func(s->context, b, 2);
+            break;
+        }
+        case '4': {
+            stbiw_uint32  x = va_arg(v, int);
+            unsigned char b[4];
+            b[0] = STBIW_UCHAR(x);
+            b[1] = STBIW_UCHAR(x >> 8);
+            b[2] = STBIW_UCHAR(x >> 16);
+            b[3] = STBIW_UCHAR(x >> 24);
+            s->func(s->context, b, 4);
+            break;
+        }
+        default:
             STBIW_ASSERT(0);
             return;
-      }
-   }
+        }
+    }
 }
 
-static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
-{
-   va_list v;
-   va_start(v, fmt);
-   stbiw__writefv(s, fmt, v);
-   va_end(v);
+static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) {
+    va_list v;
+    va_start(v, fmt);
+    stbiw__writefv(s, fmt, v);
+    va_end(v);
 }
 
-static void stbiw__putc(stbi__write_context *s, unsigned char c)
-{
-   s->func(s->context, &c, 1);
-}
+static void stbiw__putc(stbi__write_context *s, unsigned char c) { s->func(s->context, &c, 1); }
 
-static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
-{
-   unsigned char arr[3];
-   arr[0] = a; arr[1] = b; arr[2] = c;
-   s->func(s->context, arr, 3);
+static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) {
+    unsigned char arr[3];
+    arr[0] = a;
+    arr[1] = b;
+    arr[2] = c;
+    s->func(s->context, arr, 3);
 }
 
-static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
-{
-   unsigned char bg[3] = { 255, 0, 255}, px[3];
-   int k;
+static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono,
+                               unsigned char *d) {
+    unsigned char bg[3] = {255, 0, 255}, px[3];
+    int           k;
 
-   if (write_alpha < 0)
-      s->func(s->context, &d[comp - 1], 1);
+    if (write_alpha < 0)
+        s->func(s->context, &d[comp - 1], 1);
 
-   switch (comp) {
-      case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
-      case 1:
-         if (expand_mono)
+    switch (comp) {
+    case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
+    case 1:
+        if (expand_mono)
             stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
-         else
-            s->func(s->context, d, 1);  // monochrome TGA
-         break;
-      case 4:
-         if (!write_alpha) {
+        else
+            s->func(s->context, d, 1); // monochrome TGA
+        break;
+    case 4:
+        if (!write_alpha) {
             // composite against pink background
             for (k = 0; k < 3; ++k)
-               px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
+                px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
             stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
             break;
-         }
-         /* FALLTHROUGH */
-      case 3:
-         stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
-         break;
-   }
-   if (write_alpha > 0)
-      s->func(s->context, &d[comp - 1], 1);
+        }
+        /* FALLTHROUGH */
+    case 3:
+        stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
+        break;
+    }
+    if (write_alpha > 0)
+        s->func(s->context, &d[comp - 1], 1);
 }
 
-static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
-{
-   stbiw_uint32 zero = 0;
-   int i,j, j_end;
-
-   if (y <= 0)
-      return;
-
-   if (stbi__flip_vertically_on_write)
-      vdir *= -1;
-
-   if (vdir < 0) {
-      j_end = -1; j = y-1;
-   } else {
-      j_end =  y; j = 0;
-   }
-
-   for (; j != j_end; j += vdir) {
-      for (i=0; i < x; ++i) {
-         unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
-         stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
-      }
-      s->func(s->context, &zero, scanline_pad);
-   }
+static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data,
+                                int write_alpha, int scanline_pad, int expand_mono) {
+    stbiw_uint32 zero = 0;
+    int          i, j, j_end;
+
+    if (y <= 0)
+        return;
+
+    if (stbi__flip_vertically_on_write)
+        vdir *= -1;
+
+    if (vdir < 0) {
+        j_end = -1;
+        j     = y - 1;
+    } else {
+        j_end = y;
+        j     = 0;
+    }
+
+    for (; j != j_end; j += vdir) {
+        for (i = 0; i < x; ++i) {
+            unsigned char *d = (unsigned char *)data + (j * x + i) * comp;
+            stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
+        }
+        s->func(s->context, &zero, scanline_pad);
+    }
 }
 
-static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...)
-{
-   if (y < 0 || x < 0) {
-      return 0;
-   } else {
-      va_list v;
-      va_start(v, fmt);
-      stbiw__writefv(s, fmt, v);
-      va_end(v);
-      stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono);
-      return 1;
-   }
+static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono,
+                          void *data, int alpha, int pad, const char *fmt, ...) {
+    if (y < 0 || x < 0) {
+        return 0;
+    } else {
+        va_list v;
+        va_start(v, fmt);
+        stbiw__writefv(s, fmt, v);
+        va_end(v);
+        stbiw__write_pixels(s, rgb_dir, vdir, x, y, comp, data, alpha, pad, expand_mono);
+        return 1;
+    }
 }
 
-static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
-{
-   int pad = (-x*3) & 3;
-   return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
-           "11 4 22 4" "4 44 22 444444",
-           'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40,  // file header
-            40, x,y, 1,24, 0,0,0,0,0,0);             // bitmap header
+static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) {
+    int pad = (-x * 3) & 3;
+    return stbiw__outfile(s, -1, -1, x, y, comp, 1, (void *)data, 0, pad,
+                          "11 4 22 4"
+                          "4 44 22 444444",
+                          'B', 'M', 14 + 40 + (x * 3 + pad) * y, 0, 0, 14 + 40, // file header
+                          40, x, y, 1, 24, 0, 0, 0, 0, 0, 0);                   // bitmap header
 }
 
-STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
-{
-   stbi__write_context s;
-   stbi__start_write_callbacks(&s, func, context);
-   return stbi_write_bmp_core(&s, x, y, comp, data);
+STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) {
+    stbi__write_context s;
+    stbi__start_write_callbacks(&s, func, context);
+    return stbi_write_bmp_core(&s, x, y, comp, data);
 }
 
 #ifndef STBI_WRITE_NO_STDIO
-STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
-{
-   stbi__write_context s;
-   if (stbi__start_write_file(&s,filename)) {
-      int r = stbi_write_bmp_core(&s, x, y, comp, data);
-      stbi__end_write_file(&s);
-      return r;
-   } else
-      return 0;
+STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) {
+    stbi__write_context s;
+    if (stbi__start_write_file(&s, filename)) {
+        int r = stbi_write_bmp_core(&s, x, y, comp, data);
+        stbi__end_write_file(&s);
+        return r;
+    } else
+        return 0;
 }
-#endif //!STBI_WRITE_NO_STDIO
-
-static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data)
-{
-   int has_alpha = (comp == 2 || comp == 4);
-   int colorbytes = has_alpha ? comp-1 : comp;
-   int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
-
-   if (y < 0 || x < 0)
-      return 0;
-
-   if (!stbi_write_tga_with_rle) {
-      return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0,
-         "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
-   } else {
-      int i,j,k;
-      int jend, jdir;
-
-      stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8);
-
-      if (stbi__flip_vertically_on_write) {
-         j = 0;
-         jend = y;
-         jdir = 1;
-      } else {
-         j = y-1;
-         jend = -1;
-         jdir = -1;
-      }
-      for (; j != jend; j += jdir) {
-         unsigned char *row = (unsigned char *) data + j * x * comp;
-         int len;
-
-         for (i = 0; i < x; i += len) {
-            unsigned char *begin = row + i * comp;
-            int diff = 1;
-            len = 1;
-
-            if (i < x - 1) {
-               ++len;
-               diff = memcmp(begin, row + (i + 1) * comp, comp);
-               if (diff) {
-                  const unsigned char *prev = begin;
-                  for (k = i + 2; k < x && len < 128; ++k) {
-                     if (memcmp(prev, row + k * comp, comp)) {
-                        prev += comp;
-                        ++len;
-                     } else {
-                        --len;
-                        break;
-                     }
-                  }
-               } else {
-                  for (k = i + 2; k < x && len < 128; ++k) {
-                     if (!memcmp(begin, row + k * comp, comp)) {
-                        ++len;
-                     } else {
-                        break;
-                     }
-                  }
-               }
-            }
-
-            if (diff) {
-               unsigned char header = STBIW_UCHAR(len - 1);
-               s->func(s->context, &header, 1);
-               for (k = 0; k < len; ++k) {
-                  stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
-               }
-            } else {
-               unsigned char header = STBIW_UCHAR(len - 129);
-               s->func(s->context, &header, 1);
-               stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
+#endif //! STBI_WRITE_NO_STDIO
+
+static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) {
+    int has_alpha  = (comp == 2 || comp == 4);
+    int colorbytes = has_alpha ? comp - 1 : comp;
+    int format     = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
+
+    if (y < 0 || x < 0)
+        return 0;
+
+    if (!stbi_write_tga_with_rle) {
+        return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *)data, has_alpha, 0, "111 221 2222 11", 0, 0, format, 0,
+                              0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
+    } else {
+        int i, j, k;
+        int jend, jdir;
+
+        stbiw__writef(s, "111 221 2222 11", 0, 0, format + 8, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8,
+                      has_alpha * 8);
+
+        if (stbi__flip_vertically_on_write) {
+            j    = 0;
+            jend = y;
+            jdir = 1;
+        } else {
+            j    = y - 1;
+            jend = -1;
+            jdir = -1;
+        }
+        for (; j != jend; j += jdir) {
+            unsigned char *row = (unsigned char *)data + j * x * comp;
+            int            len;
+
+            for (i = 0; i < x; i += len) {
+                unsigned char *begin = row + i * comp;
+                int            diff  = 1;
+                len                  = 1;
+
+                if (i < x - 1) {
+                    ++len;
+                    diff = memcmp(begin, row + (i + 1) * comp, comp);
+                    if (diff) {
+                        const unsigned char *prev = begin;
+                        for (k = i + 2; k < x && len < 128; ++k) {
+                            if (memcmp(prev, row + k * comp, comp)) {
+                                prev += comp;
+                                ++len;
+                            } else {
+                                --len;
+                                break;
+                            }
+                        }
+                    } else {
+                        for (k = i + 2; k < x && len < 128; ++k) {
+                            if (!memcmp(begin, row + k * comp, comp)) {
+                                ++len;
+                            } else {
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                if (diff) {
+                    unsigned char header = STBIW_UCHAR(len - 1);
+                    s->func(s->context, &header, 1);
+                    for (k = 0; k < len; ++k) {
+                        stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
+                    }
+                } else {
+                    unsigned char header = STBIW_UCHAR(len - 129);
+                    s->func(s->context, &header, 1);
+                    stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
+                }
             }
-         }
-      }
-   }
-   return 1;
+        }
+    }
+    return 1;
 }
 
-STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
-{
-   stbi__write_context s;
-   stbi__start_write_callbacks(&s, func, context);
-   return stbi_write_tga_core(&s, x, y, comp, (void *) data);
+STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) {
+    stbi__write_context s;
+    stbi__start_write_callbacks(&s, func, context);
+    return stbi_write_tga_core(&s, x, y, comp, (void *)data);
 }
 
 #ifndef STBI_WRITE_NO_STDIO
-STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
-{
-   stbi__write_context s;
-   if (stbi__start_write_file(&s,filename)) {
-      int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
-      stbi__end_write_file(&s);
-      return r;
-   } else
-      return 0;
+STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) {
+    stbi__write_context s;
+    if (stbi__start_write_file(&s, filename)) {
+        int r = stbi_write_tga_core(&s, x, y, comp, (void *)data);
+        stbi__end_write_file(&s);
+        return r;
+    } else
+        return 0;
 }
 #endif
 
@@ -596,177 +587,175 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
 // Radiance RGBE HDR writer
 // by Baldur Karlsson
 
-#define stbiw__max(a, b)  ((a) > (b) ? (a) : (b))
+#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
 
-static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
-{
-   int exponent;
-   float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
+static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) {
+    int   exponent;
+    float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
 
-   if (maxcomp < 1e-32f) {
-      rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
-   } else {
-      float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
+    if (maxcomp < 1e-32f) {
+        rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
+    } else {
+        float normalize = (float)frexp(maxcomp, &exponent) * 256.0f / maxcomp;
 
-      rgbe[0] = (unsigned char)(linear[0] * normalize);
-      rgbe[1] = (unsigned char)(linear[1] * normalize);
-      rgbe[2] = (unsigned char)(linear[2] * normalize);
-      rgbe[3] = (unsigned char)(exponent + 128);
-   }
+        rgbe[0] = (unsigned char)(linear[0] * normalize);
+        rgbe[1] = (unsigned char)(linear[1] * normalize);
+        rgbe[2] = (unsigned char)(linear[2] * normalize);
+        rgbe[3] = (unsigned char)(exponent + 128);
+    }
 }
 
-static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
-{
-   unsigned char lengthbyte = STBIW_UCHAR(length+128);
-   STBIW_ASSERT(length+128 <= 255);
-   s->func(s->context, &lengthbyte, 1);
-   s->func(s->context, &databyte, 1);
+static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) {
+    unsigned char lengthbyte = STBIW_UCHAR(length + 128);
+    STBIW_ASSERT(length + 128 <= 255);
+    s->func(s->context, &lengthbyte, 1);
+    s->func(s->context, &databyte, 1);
 }
 
-static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
-{
-   unsigned char lengthbyte = STBIW_UCHAR(length);
-   STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
-   s->func(s->context, &lengthbyte, 1);
-   s->func(s->context, data, length);
+static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) {
+    unsigned char lengthbyte = STBIW_UCHAR(length);
+    STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
+    s->func(s->context, &lengthbyte, 1);
+    s->func(s->context, data, length);
 }
 
-static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
-{
-   unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
-   unsigned char rgbe[4];
-   float linear[3];
-   int x;
+static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch,
+                                      float *scanline) {
+    unsigned char scanlineheader[4] = {2, 2, 0, 0};
+    unsigned char rgbe[4];
+    float         linear[3];
+    int           x;
 
-   scanlineheader[2] = (width&0xff00)>>8;
-   scanlineheader[3] = (width&0x00ff);
+    scanlineheader[2] = (width & 0xff00) >> 8;
+    scanlineheader[3] = (width & 0x00ff);
 
-   /* skip RLE for images too small or large */
-   if (width < 8 || width >= 32768) {
-      for (x=0; x < width; x++) {
-         switch (ncomp) {
+    /* skip RLE for images too small or large */
+    if (width < 8 || width >= 32768) {
+        for (x = 0; x < width; x++) {
+            switch (ncomp) {
             case 4: /* fallthrough */
-            case 3: linear[2] = scanline[x*ncomp + 2];
-                    linear[1] = scanline[x*ncomp + 1];
-                    linear[0] = scanline[x*ncomp + 0];
-                    break;
+            case 3:
+                linear[2] = scanline[x * ncomp + 2];
+                linear[1] = scanline[x * ncomp + 1];
+                linear[0] = scanline[x * ncomp + 0];
+                break;
             default:
-                    linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
-                    break;
-         }
-         stbiw__linear_to_rgbe(rgbe, linear);
-         s->func(s->context, rgbe, 4);
-      }
-   } else {
-      int c,r;
-      /* encode into scratch buffer */
-      for (x=0; x < width; x++) {
-         switch(ncomp) {
+                linear[0] = linear[1] = linear[2] = scanline[x * ncomp + 0];
+                break;
+            }
+            stbiw__linear_to_rgbe(rgbe, linear);
+            s->func(s->context, rgbe, 4);
+        }
+    } else {
+        int c, r;
+        /* encode into scratch buffer */
+        for (x = 0; x < width; x++) {
+            switch (ncomp) {
             case 4: /* fallthrough */
-            case 3: linear[2] = scanline[x*ncomp + 2];
-                    linear[1] = scanline[x*ncomp + 1];
-                    linear[0] = scanline[x*ncomp + 0];
-                    break;
+            case 3:
+                linear[2] = scanline[x * ncomp + 2];
+                linear[1] = scanline[x * ncomp + 1];
+                linear[0] = scanline[x * ncomp + 0];
+                break;
             default:
-                    linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
-                    break;
-         }
-         stbiw__linear_to_rgbe(rgbe, linear);
-         scratch[x + width*0] = rgbe[0];
-         scratch[x + width*1] = rgbe[1];
-         scratch[x + width*2] = rgbe[2];
-         scratch[x + width*3] = rgbe[3];
-      }
-
-      s->func(s->context, scanlineheader, 4);
-
-      /* RLE each component separately */
-      for (c=0; c < 4; c++) {
-         unsigned char *comp = &scratch[width*c];
-
-         x = 0;
-         while (x < width) {
-            // find first run
-            r = x;
-            while (r+2 < width) {
-               if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
-                  break;
-               ++r;
-            }
-            if (r+2 >= width)
-               r = width;
-            // dump up to first run
-            while (x < r) {
-               int len = r-x;
-               if (len > 128) len = 128;
-               stbiw__write_dump_data(s, len, &comp[x]);
-               x += len;
+                linear[0] = linear[1] = linear[2] = scanline[x * ncomp + 0];
+                break;
             }
-            // if there's a run, output it
-            if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd
-               // find next byte after run
-               while (r < width && comp[r] == comp[x])
-                  ++r;
-               // output run up to r
-               while (x < r) {
-                  int len = r-x;
-                  if (len > 127) len = 127;
-                  stbiw__write_run_data(s, len, comp[x]);
-                  x += len;
-               }
+            stbiw__linear_to_rgbe(rgbe, linear);
+            scratch[x + width * 0] = rgbe[0];
+            scratch[x + width * 1] = rgbe[1];
+            scratch[x + width * 2] = rgbe[2];
+            scratch[x + width * 3] = rgbe[3];
+        }
+
+        s->func(s->context, scanlineheader, 4);
+
+        /* RLE each component separately */
+        for (c = 0; c < 4; c++) {
+            unsigned char *comp = &scratch[width * c];
+
+            x = 0;
+            while (x < width) {
+                // find first run
+                r = x;
+                while (r + 2 < width) {
+                    if (comp[r] == comp[r + 1] && comp[r] == comp[r + 2])
+                        break;
+                    ++r;
+                }
+                if (r + 2 >= width)
+                    r = width;
+                // dump up to first run
+                while (x < r) {
+                    int len = r - x;
+                    if (len > 128)
+                        len = 128;
+                    stbiw__write_dump_data(s, len, &comp[x]);
+                    x += len;
+                }
+                // if there's a run, output it
+                if (r + 2 < width) { // same test as what we break out of in search loop, so only true if we break'd
+                    // find next byte after run
+                    while (r < width && comp[r] == comp[x])
+                        ++r;
+                    // output run up to r
+                    while (x < r) {
+                        int len = r - x;
+                        if (len > 127)
+                            len = 127;
+                        stbiw__write_run_data(s, len, comp[x]);
+                        x += len;
+                    }
+                }
             }
-         }
-      }
-   }
+        }
+    }
 }
 
-static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data)
-{
-   if (y <= 0 || x <= 0 || data == NULL)
-      return 0;
-   else {
-      // Each component is stored separately. Allocate scratch space for full output scanline.
-      unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
-      int i, len;
-      char buffer[128];
-      char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
-      s->func(s->context, header, sizeof(header)-1);
+static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) {
+    if (y <= 0 || x <= 0 || data == NULL)
+        return 0;
+    else {
+        // Each component is stored separately. Allocate scratch space for full output scanline.
+        unsigned char *scratch = (unsigned char *)STBIW_MALLOC(x * 4);
+        int            i, len;
+        char           buffer[128];
+        char           header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
+        s->func(s->context, header, sizeof(header) - 1);
 
 #ifdef __STDC_WANT_SECURE_LIB__
-      len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
+        len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
 #else
-      len = sprintf(buffer, "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
+        len = sprintf(buffer, "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
 #endif
-      s->func(s->context, buffer, len);
-
-      for(i=0; i < y; i++)
-         stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i));
-      STBIW_FREE(scratch);
-      return 1;
-   }
+        s->func(s->context, buffer, len);
+
+        for (i = 0; i < y; i++)
+            stbiw__write_hdr_scanline(s, x, comp, scratch,
+                                      data + comp * x * (stbi__flip_vertically_on_write ? y - 1 - i : i));
+        STBIW_FREE(scratch);
+        return 1;
+    }
 }
 
-STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
-{
-   stbi__write_context s;
-   stbi__start_write_callbacks(&s, func, context);
-   return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
+STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) {
+    stbi__write_context s;
+    stbi__start_write_callbacks(&s, func, context);
+    return stbi_write_hdr_core(&s, x, y, comp, (float *)data);
 }
 
 #ifndef STBI_WRITE_NO_STDIO
-STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
-{
-   stbi__write_context s;
-   if (stbi__start_write_file(&s,filename)) {
-      int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
-      stbi__end_write_file(&s);
-      return r;
-   } else
-      return 0;
+STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) {
+    stbi__write_context s;
+    if (stbi__start_write_file(&s, filename)) {
+        int r = stbi_write_hdr_core(&s, x, y, comp, (float *)data);
+        stbi__end_write_file(&s);
+        return r;
+    } else
+        return 0;
 }
 #endif // STBI_WRITE_NO_STDIO
 
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // PNG writer
@@ -774,417 +763,472 @@ STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const
 
 #ifndef STBIW_ZLIB_COMPRESS
 // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
-#define stbiw__sbraw(a) ((int *) (a) - 2)
-#define stbiw__sbm(a)   stbiw__sbraw(a)[0]
-#define stbiw__sbn(a)   stbiw__sbraw(a)[1]
+#define stbiw__sbraw(a)          ((int *)(a)-2)
+#define stbiw__sbm(a)            stbiw__sbraw(a)[0]
+#define stbiw__sbn(a)            stbiw__sbraw(a)[1]
 
-#define stbiw__sbneedgrow(a,n)  ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
-#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
-#define stbiw__sbgrow(a,n)  stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
+#define stbiw__sbneedgrow(a, n)  ((a) == 0 || stbiw__sbn(a) + n >= stbiw__sbm(a))
+#define stbiw__sbmaybegrow(a, n) (stbiw__sbneedgrow(a, (n)) ? stbiw__sbgrow(a, n) : 0)
+#define stbiw__sbgrow(a, n)      stbiw__sbgrowf((void **)&(a), (n), sizeof(*(a)))
 
-#define stbiw__sbpush(a, v)      (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
+#define stbiw__sbpush(a, v)      (stbiw__sbmaybegrow(a, 1), (a)[stbiw__sbn(a)++] = (v))
 #define stbiw__sbcount(a)        ((a) ? stbiw__sbn(a) : 0)
-#define stbiw__sbfree(a)         ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0)
-
-static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
-{
-   int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
-   void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2);
-   STBIW_ASSERT(p);
-   if (p) {
-      if (!*arr) ((int *) p)[1] = 0;
-      *arr = (void *) ((int *) p + 2);
-      stbiw__sbm(*arr) = m;
-   }
-   return *arr;
+#define stbiw__sbfree(a)         ((a) ? STBIW_FREE(stbiw__sbraw(a)), 0 : 0)
+
+static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) {
+    int   m = *arr ? 2 * stbiw__sbm(*arr) + increment : increment + 1;
+    void *p =
+        STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr) * itemsize + sizeof(int) * 2) : 0,
+                            itemsize * m + sizeof(int) * 2);
+    STBIW_ASSERT(p);
+    if (p) {
+        if (!*arr)
+            ((int *)p)[1] = 0;
+        *arr             = (void *)((int *)p + 2);
+        stbiw__sbm(*arr) = m;
+    }
+    return *arr;
 }
 
-static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
-{
-   while (*bitcount >= 8) {
-      stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
-      *bitbuffer >>= 8;
-      *bitcount -= 8;
-   }
-   return data;
+static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) {
+    while (*bitcount >= 8) {
+        stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
+        *bitbuffer >>= 8;
+        *bitcount -= 8;
+    }
+    return data;
 }
 
-static int stbiw__zlib_bitrev(int code, int codebits)
-{
-   int res=0;
-   while (codebits--) {
-      res = (res << 1) | (code & 1);
-      code >>= 1;
-   }
-   return res;
+static int stbiw__zlib_bitrev(int code, int codebits) {
+    int res = 0;
+    while (codebits--) {
+        res = (res << 1) | (code & 1);
+        code >>= 1;
+    }
+    return res;
 }
 
-static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
-{
-   int i;
-   for (i=0; i < limit && i < 258; ++i)
-      if (a[i] != b[i]) break;
-   return i;
+static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) {
+    int i;
+    for (i = 0; i < limit && i < 258; ++i)
+        if (a[i] != b[i])
+            break;
+    return i;
 }
 
-static unsigned int stbiw__zhash(unsigned char *data)
-{
-   stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
-   hash ^= hash << 3;
-   hash += hash >> 5;
-   hash ^= hash << 4;
-   hash += hash >> 17;
-   hash ^= hash << 25;
-   hash += hash >> 6;
-   return hash;
+static unsigned int stbiw__zhash(unsigned char *data) {
+    stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
+    hash ^= hash << 3;
+    hash += hash >> 5;
+    hash ^= hash << 4;
+    hash += hash >> 17;
+    hash ^= hash << 25;
+    hash += hash >> 6;
+    return hash;
 }
 
-#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
-#define stbiw__zlib_add(code,codebits) \
-      (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
-#define stbiw__zlib_huffa(b,c)  stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
+#define stbiw__zlib_flush()             (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
+#define stbiw__zlib_add(code, codebits) (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
+#define stbiw__zlib_huffa(b, c)         stbiw__zlib_add(stbiw__zlib_bitrev(b, c), c)
 // default huffman tables
-#define stbiw__zlib_huff1(n)  stbiw__zlib_huffa(0x30 + (n), 8)
-#define stbiw__zlib_huff2(n)  stbiw__zlib_huffa(0x190 + (n)-144, 9)
-#define stbiw__zlib_huff3(n)  stbiw__zlib_huffa(0 + (n)-256,7)
-#define stbiw__zlib_huff4(n)  stbiw__zlib_huffa(0xc0 + (n)-280,8)
-#define stbiw__zlib_huff(n)  ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n))
+#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
+#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
+#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256, 7)
+#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280, 8)
+#define stbiw__zlib_huff(n)                                                                                            \
+    ((n) <= 143   ? stbiw__zlib_huff1(n)                                                                               \
+     : (n) <= 255 ? stbiw__zlib_huff2(n)                                                                               \
+     : (n) <= 279 ? stbiw__zlib_huff3(n)                                                                               \
+                  : stbiw__zlib_huff4(n))
 #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
 
-#define stbiw__ZHASH   16384
+#define stbiw__ZHASH         16384
 
 #endif // STBIW_ZLIB_COMPRESS
 
-STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
-{
+STBIWDEF unsigned char *stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) {
 #ifdef STBIW_ZLIB_COMPRESS
-   // user provided a zlib compress implementation, use that
-   return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
-#else // use builtin
-   static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
-   static unsigned char  lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5,  0 };
-   static unsigned short distc[]   = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
-   static unsigned char  disteb[]  = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
-   unsigned int bitbuf=0;
-   int i,j, bitcount=0;
-   unsigned char *out = NULL;
-   unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
-   if (hash_table == NULL)
-      return NULL;
-   if (quality < 5) quality = 5;
-
-   stbiw__sbpush(out, 0x78);   // DEFLATE 32K window
-   stbiw__sbpush(out, 0x5e);   // FLEVEL = 1
-   stbiw__zlib_add(1,1);  // BFINAL = 1
-   stbiw__zlib_add(1,2);  // BTYPE = 1 -- fixed huffman
-
-   for (i=0; i < stbiw__ZHASH; ++i)
-      hash_table[i] = NULL;
-
-   i=0;
-   while (i < data_len-3) {
-      // hash next 3 bytes of data to be compressed
-      int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
-      unsigned char *bestloc = 0;
-      unsigned char **hlist = hash_table[h];
-      int n = stbiw__sbcount(hlist);
-      for (j=0; j < n; ++j) {
-         if (hlist[j]-data > i-32768) { // if entry lies within window
-            int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
-            if (d >= best) { best=d; bestloc=hlist[j]; }
-         }
-      }
-      // when hash table entry is too long, delete half the entries
-      if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
-         STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
-         stbiw__sbn(hash_table[h]) = quality;
-      }
-      stbiw__sbpush(hash_table[h],data+i);
-
-      if (bestloc) {
-         // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
-         h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
-         hlist = hash_table[h];
-         n = stbiw__sbcount(hlist);
-         for (j=0; j < n; ++j) {
-            if (hlist[j]-data > i-32767) {
-               int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
-               if (e > best) { // if next match is better, bail on current match
-                  bestloc = NULL;
-                  break;
-               }
+    // user provided a zlib compress implementation, use that
+    return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
+#else  // use builtin
+    static unsigned short lengthc[]  = {3,  4,  5,  6,  7,  8,  9,  10, 11,  13,  15,  17,  19,  23,  27,
+                                        31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 259};
+    static unsigned char  lengtheb[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
+                                        2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
+    static unsigned short distc[]    = {1,    2,    3,    4,    5,    7,     9,     13,    17,   25,   33,
+                                        49,   65,   97,   129,  193,  257,   385,   513,   769,  1025, 1537,
+                                        2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 32768};
+    static unsigned char  disteb[]   = {0, 0, 0, 0, 1, 1, 2, 2,  3,  3,  4,  4,  5,  5,  6,
+                                        6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
+    unsigned int          bitbuf     = 0;
+    int                   i, j, bitcount = 0;
+    unsigned char        *out        = NULL;
+    unsigned char      ***hash_table = (unsigned char ***)STBIW_MALLOC(stbiw__ZHASH * sizeof(char **));
+    if (hash_table == NULL)
+        return NULL;
+    if (quality < 5)
+        quality = 5;
+
+    stbiw__sbpush(out, 0x78); // DEFLATE 32K window
+    stbiw__sbpush(out, 0x5e); // FLEVEL = 1
+    stbiw__zlib_add(1, 1);    // BFINAL = 1
+    stbiw__zlib_add(1, 2);    // BTYPE = 1 -- fixed huffman
+
+    for (i = 0; i < stbiw__ZHASH; ++i)
+        hash_table[i] = NULL;
+
+    i = 0;
+    while (i < data_len - 3) {
+        // hash next 3 bytes of data to be compressed
+        int             h = stbiw__zhash(data + i) & (stbiw__ZHASH - 1), best = 3;
+        unsigned char  *bestloc = 0;
+        unsigned char **hlist   = hash_table[h];
+        int             n       = stbiw__sbcount(hlist);
+        for (j = 0; j < n; ++j) {
+            if (hlist[j] - data > i - 32768) { // if entry lies within window
+                int d = stbiw__zlib_countm(hlist[j], data + i, data_len - i);
+                if (d >= best) {
+                    best    = d;
+                    bestloc = hlist[j];
+                }
+            }
+        }
+        // when hash table entry is too long, delete half the entries
+        if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2 * quality) {
+            STBIW_MEMMOVE(hash_table[h], hash_table[h] + quality, sizeof(hash_table[h][0]) * quality);
+            stbiw__sbn(hash_table[h]) = quality;
+        }
+        stbiw__sbpush(hash_table[h], data + i);
+
+        if (bestloc) {
+            // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
+            h     = stbiw__zhash(data + i + 1) & (stbiw__ZHASH - 1);
+            hlist = hash_table[h];
+            n     = stbiw__sbcount(hlist);
+            for (j = 0; j < n; ++j) {
+                if (hlist[j] - data > i - 32767) {
+                    int e = stbiw__zlib_countm(hlist[j], data + i + 1, data_len - i - 1);
+                    if (e > best) { // if next match is better, bail on current match
+                        bestloc = NULL;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (bestloc) {
+            int d = (int)(data + i - bestloc); // distance back
+            STBIW_ASSERT(d <= 32767 && best <= 258);
+            for (j = 0; best > lengthc[j + 1] - 1; ++j)
+                ;
+            stbiw__zlib_huff(j + 257);
+            if (lengtheb[j])
+                stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
+            for (j = 0; d > distc[j + 1] - 1; ++j)
+                ;
+            stbiw__zlib_add(stbiw__zlib_bitrev(j, 5), 5);
+            if (disteb[j])
+                stbiw__zlib_add(d - distc[j], disteb[j]);
+            i += best;
+        } else {
+            stbiw__zlib_huffb(data[i]);
+            ++i;
+        }
+    }
+    // write out final bytes
+    for (; i < data_len; ++i)
+        stbiw__zlib_huffb(data[i]);
+    stbiw__zlib_huff(256); // end of block
+    // pad with 0 bits to byte boundary
+    while (bitcount)
+        stbiw__zlib_add(0, 1);
+
+    for (i = 0; i < stbiw__ZHASH; ++i)
+        (void)stbiw__sbfree(hash_table[i]);
+    STBIW_FREE(hash_table);
+
+    {
+        // compute adler32 on input
+        unsigned int s1 = 1, s2 = 0;
+        int          blocklen = (int)(data_len % 5552);
+        j                     = 0;
+        while (j < data_len) {
+            for (i = 0; i < blocklen; ++i) {
+                s1 += data[j + i];
+                s2 += s1;
             }
-         }
-      }
-
-      if (bestloc) {
-         int d = (int) (data+i - bestloc); // distance back
-         STBIW_ASSERT(d <= 32767 && best <= 258);
-         for (j=0; best > lengthc[j+1]-1; ++j);
-         stbiw__zlib_huff(j+257);
-         if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
-         for (j=0; d > distc[j+1]-1; ++j);
-         stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
-         if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
-         i += best;
-      } else {
-         stbiw__zlib_huffb(data[i]);
-         ++i;
-      }
-   }
-   // write out final bytes
-   for (;i < data_len; ++i)
-      stbiw__zlib_huffb(data[i]);
-   stbiw__zlib_huff(256); // end of block
-   // pad with 0 bits to byte boundary
-   while (bitcount)
-      stbiw__zlib_add(0,1);
-
-   for (i=0; i < stbiw__ZHASH; ++i)
-      (void) stbiw__sbfree(hash_table[i]);
-   STBIW_FREE(hash_table);
-
-   {
-      // compute adler32 on input
-      unsigned int s1=1, s2=0;
-      int blocklen = (int) (data_len % 5552);
-      j=0;
-      while (j < data_len) {
-         for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
-         s1 %= 65521; s2 %= 65521;
-         j += blocklen;
-         blocklen = 5552;
-      }
-      stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8));
-      stbiw__sbpush(out, STBIW_UCHAR(s2));
-      stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8));
-      stbiw__sbpush(out, STBIW_UCHAR(s1));
-   }
-   *out_len = stbiw__sbn(out);
-   // make returned pointer freeable
-   STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
-   return (unsigned char *) stbiw__sbraw(out);
+            s1 %= 65521;
+            s2 %= 65521;
+            j += blocklen;
+            blocklen = 5552;
+        }
+        stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8));
+        stbiw__sbpush(out, STBIW_UCHAR(s2));
+        stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8));
+        stbiw__sbpush(out, STBIW_UCHAR(s1));
+    }
+    *out_len = stbiw__sbn(out);
+    // make returned pointer freeable
+    STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
+    return (unsigned char *)stbiw__sbraw(out);
 #endif // STBIW_ZLIB_COMPRESS
 }
 
-static unsigned int stbiw__crc32(unsigned char *buffer, int len)
-{
+static unsigned int stbiw__crc32(unsigned char *buffer, int len) {
 #ifdef STBIW_CRC32
     return STBIW_CRC32(buffer, len);
 #else
-   static unsigned int crc_table[256] =
-   {
-      0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
-      0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
-      0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
-      0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
-      0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
-      0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
-      0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
-      0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
-      0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
-      0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
-      0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
-      0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
-      0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
-      0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
-      0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
-      0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
-      0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
-      0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
-      0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
-      0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
-      0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
-      0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
-      0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
-      0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
-      0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
-      0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
-      0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
-      0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
-      0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
-      0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
-      0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
-      0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
-   };
-
-   unsigned int crc = ~0u;
-   int i;
-   for (i=0; i < len; ++i)
-      crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
-   return ~crc;
+    static unsigned int crc_table[256] = {
+        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0eDB8832,
+        0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
+        0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A,
+        0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+        0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
+        0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
+        0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
+        0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+        0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4,
+        0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
+        0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074,
+        0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+        0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525,
+        0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
+        0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
+        0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+        0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76,
+        0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
+        0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6,
+        0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+        0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
+        0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
+        0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7,
+        0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+        0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
+        0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
+        0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330,
+        0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
+
+    unsigned int crc = ~0u;
+    int          i;
+    for (i = 0; i < len; ++i)
+        crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
+    return ~crc;
 #endif
 }
 
-#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4)
-#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
-#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
+#define stbiw__wpng4(o, a, b, c, d)                                                                                    \
+    ((o)[0] = STBIW_UCHAR(a), (o)[1] = STBIW_UCHAR(b), (o)[2] = STBIW_UCHAR(c), (o)[3] = STBIW_UCHAR(d), (o) += 4)
+#define stbiw__wp32(data, v)  stbiw__wpng4(data, (v) >> 24, (v) >> 16, (v) >> 8, (v));
+#define stbiw__wptag(data, s) stbiw__wpng4(data, s[0], s[1], s[2], s[3])
 
-static void stbiw__wpcrc(unsigned char **data, int len)
-{
-   unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
-   stbiw__wp32(*data, crc);
+static void stbiw__wpcrc(unsigned char **data, int len) {
+    unsigned int crc = stbiw__crc32(*data - len - 4, len + 4);
+    stbiw__wp32(*data, crc);
 }
 
-static unsigned char stbiw__paeth(int a, int b, int c)
-{
-   int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
-   if (pa <= pb && pa <= pc) return STBIW_UCHAR(a);
-   if (pb <= pc) return STBIW_UCHAR(b);
-   return STBIW_UCHAR(c);
+static unsigned char stbiw__paeth(int a, int b, int c) {
+    int p = a + b - c, pa = abs(p - a), pb = abs(p - b), pc = abs(p - c);
+    if (pa <= pb && pa <= pc)
+        return STBIW_UCHAR(a);
+    if (pb <= pc)
+        return STBIW_UCHAR(b);
+    return STBIW_UCHAR(c);
 }
 
 // @OPTIMIZE: provide an option that always forces left-predict or paeth predict
-static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer)
-{
-   static int mapping[] = { 0,1,2,3,4 };
-   static int firstmap[] = { 0,1,0,5,6 };
-   int *mymap = (y != 0) ? mapping : firstmap;
-   int i;
-   int type = mymap[filter_type];
-   unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
-   int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
-    
-   if (type==0) {
-      memcpy(line_buffer, z, width*n);
-      return;
-   }
-
-   // first loop isn't optimized since it's just one pixel    
-   for (i = 0; i < n; ++i) {
-      switch (type) {
-         case 1: line_buffer[i] = z[i]; break;
-         case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
-         case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
-         case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break;
-         case 5: line_buffer[i] = z[i]; break;
-         case 6: line_buffer[i] = z[i]; break;
-      }
-   }
-   switch (type) {
-      case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break;
-      case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break;
-      case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
-      case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break;
-      case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break;
-      case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
-   }
+static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n,
+                                   int filter_type, signed char *line_buffer) {
+    static int     mapping[]  = {0, 1, 2, 3, 4};
+    static int     firstmap[] = {0, 1, 0, 5, 6};
+    int           *mymap      = (y != 0) ? mapping : firstmap;
+    int            i;
+    int            type          = mymap[filter_type];
+    unsigned char *z             = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height - 1 - y : y);
+    int            signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
+
+    if (type == 0) {
+        memcpy(line_buffer, z, width * n);
+        return;
+    }
+
+    // first loop isn't optimized since it's just one pixel
+    for (i = 0; i < n; ++i) {
+        switch (type) {
+        case 1:
+            line_buffer[i] = z[i];
+            break;
+        case 2:
+            line_buffer[i] = z[i] - z[i - signed_stride];
+            break;
+        case 3:
+            line_buffer[i] = z[i] - (z[i - signed_stride] >> 1);
+            break;
+        case 4:
+            line_buffer[i] = (signed char)(z[i] - stbiw__paeth(0, z[i - signed_stride], 0));
+            break;
+        case 5:
+            line_buffer[i] = z[i];
+            break;
+        case 6:
+            line_buffer[i] = z[i];
+            break;
+        }
+    }
+    switch (type) {
+    case 1:
+        for (i = n; i < width * n; ++i)
+            line_buffer[i] = z[i] - z[i - n];
+        break;
+    case 2:
+        for (i = n; i < width * n; ++i)
+            line_buffer[i] = z[i] - z[i - signed_stride];
+        break;
+    case 3:
+        for (i = n; i < width * n; ++i)
+            line_buffer[i] = z[i] - ((z[i - n] + z[i - signed_stride]) >> 1);
+        break;
+    case 4:
+        for (i = n; i < width * n; ++i)
+            line_buffer[i] = z[i] - stbiw__paeth(z[i - n], z[i - signed_stride], z[i - signed_stride - n]);
+        break;
+    case 5:
+        for (i = n; i < width * n; ++i)
+            line_buffer[i] = z[i] - (z[i - n] >> 1);
+        break;
+    case 6:
+        for (i = n; i < width * n; ++i)
+            line_buffer[i] = z[i] - stbiw__paeth(z[i - n], 0, 0);
+        break;
+    }
 }
 
-STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
-{
-   int force_filter = stbi_write_force_png_filter;
-   int ctype[5] = { -1, 0, 4, 2, 6 };
-   unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
-   unsigned char *out,*o, *filt, *zlib;
-   signed char *line_buffer;
-   int j,zlen;
-
-   if (stride_bytes == 0)
-      stride_bytes = x * n;
-
-   if (force_filter >= 5) {
-      force_filter = -1;
-   }
-
-   filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
-   line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
-   for (j=0; j < y; ++j) {
-      int filter_type;
-      if (force_filter > -1) {
-         filter_type = force_filter;
-         stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
-      } else { // Estimate the best filter by running through all of them:
-         int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
-         for (filter_type = 0; filter_type < 5; filter_type++) {
-            stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
-
-            // Estimate the entropy of the line using this filter; the less, the better.
-            est = 0;
-            for (i = 0; i < x*n; ++i) {
-               est += abs((signed char) line_buffer[i]);
+STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n,
+                                              int *out_len) {
+    int            force_filter = stbi_write_force_png_filter;
+    int            ctype[5]     = {-1, 0, 4, 2, 6};
+    unsigned char  sig[8]       = {137, 80, 78, 71, 13, 10, 26, 10};
+    unsigned char *out, *o, *filt, *zlib;
+    signed char   *line_buffer;
+    int            j, zlen;
+
+    if (stride_bytes == 0)
+        stride_bytes = x * n;
+
+    if (force_filter >= 5) {
+        force_filter = -1;
+    }
+
+    filt = (unsigned char *)STBIW_MALLOC((x * n + 1) * y);
+    if (!filt)
+        return 0;
+    line_buffer = (signed char *)STBIW_MALLOC(x * n);
+    if (!line_buffer) {
+        STBIW_FREE(filt);
+        return 0;
+    }
+    for (j = 0; j < y; ++j) {
+        int filter_type;
+        if (force_filter > -1) {
+            filter_type = force_filter;
+            stbiw__encode_png_line((unsigned char *)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
+        } else { // Estimate the best filter by running through all of them:
+            int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
+            for (filter_type = 0; filter_type < 5; filter_type++) {
+                stbiw__encode_png_line((unsigned char *)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
+
+                // Estimate the entropy of the line using this filter; the less, the better.
+                est = 0;
+                for (i = 0; i < x * n; ++i) {
+                    est += abs((signed char)line_buffer[i]);
+                }
+                if (est < best_filter_val) {
+                    best_filter_val = est;
+                    best_filter     = filter_type;
+                }
             }
-            if (est < best_filter_val) {
-               best_filter_val = est;
-               best_filter = filter_type;
+            if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it
+                stbiw__encode_png_line((unsigned char *)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
+                filter_type = best_filter;
             }
-         }
-         if (filter_type != best_filter) {  // If the last iteration already got us the best filter, don't redo it
-            stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
-            filter_type = best_filter;
-         }
-      }
-      // when we get here, filter_type contains the filter type, and line_buffer contains the data
-      filt[j*(x*n+1)] = (unsigned char) filter_type;
-      STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
-   }
-   STBIW_FREE(line_buffer);
-   zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level);
-   STBIW_FREE(filt);
-   if (!zlib) return 0;
-
-   // each tag requires 12 bytes of overhead
-   out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
-   if (!out) return 0;
-   *out_len = 8 + 12+13 + 12+zlen + 12;
-
-   o=out;
-   STBIW_MEMMOVE(o,sig,8); o+= 8;
-   stbiw__wp32(o, 13); // header length
-   stbiw__wptag(o, "IHDR");
-   stbiw__wp32(o, x);
-   stbiw__wp32(o, y);
-   *o++ = 8;
-   *o++ = STBIW_UCHAR(ctype[n]);
-   *o++ = 0;
-   *o++ = 0;
-   *o++ = 0;
-   stbiw__wpcrc(&o,13);
-
-   stbiw__wp32(o, zlen);
-   stbiw__wptag(o, "IDAT");
-   STBIW_MEMMOVE(o, zlib, zlen);
-   o += zlen;
-   STBIW_FREE(zlib);
-   stbiw__wpcrc(&o, zlen);
-
-   stbiw__wp32(o,0);
-   stbiw__wptag(o, "IEND");
-   stbiw__wpcrc(&o,0);
-
-   STBIW_ASSERT(o == out + *out_len);
-
-   return out;
+        }
+        // when we get here, filter_type contains the filter type, and line_buffer contains the data
+        filt[j * (x * n + 1)] = (unsigned char)filter_type;
+        STBIW_MEMMOVE(filt + j * (x * n + 1) + 1, line_buffer, x * n);
+    }
+    STBIW_FREE(line_buffer);
+    zlib = stbi_zlib_compress(filt, y * (x * n + 1), &zlen, stbi_write_png_compression_level);
+    STBIW_FREE(filt);
+    if (!zlib)
+        return 0;
+
+    // each tag requires 12 bytes of overhead
+    out = (unsigned char *)STBIW_MALLOC(8 + 12 + 13 + 12 + zlen + 12);
+    if (!out)
+        return 0;
+    *out_len = 8 + 12 + 13 + 12 + zlen + 12;
+
+    o = out;
+    STBIW_MEMMOVE(o, sig, 8);
+    o += 8;
+    stbiw__wp32(o, 13); // header length
+    stbiw__wptag(o, "IHDR");
+    stbiw__wp32(o, x);
+    stbiw__wp32(o, y);
+    *o++ = 8;
+    *o++ = STBIW_UCHAR(ctype[n]);
+    *o++ = 0;
+    *o++ = 0;
+    *o++ = 0;
+    stbiw__wpcrc(&o, 13);
+
+    stbiw__wp32(o, zlen);
+    stbiw__wptag(o, "IDAT");
+    STBIW_MEMMOVE(o, zlib, zlen);
+    o += zlen;
+    STBIW_FREE(zlib);
+    stbiw__wpcrc(&o, zlen);
+
+    stbiw__wp32(o, 0);
+    stbiw__wptag(o, "IEND");
+    stbiw__wpcrc(&o, 0);
+
+    STBIW_ASSERT(o == out + *out_len);
+
+    return out;
 }
 
 #ifndef STBI_WRITE_NO_STDIO
-STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
-{
-   FILE *f;
-   int len;
-   unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
-   if (png == NULL) return 0;
-
-   f = stbiw__fopen(filename, "wb");
-   if (!f) { STBIW_FREE(png); return 0; }
-   fwrite(png, 1, len, f);
-   fclose(f);
-   STBIW_FREE(png);
-   return 1;
+STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) {
+    FILE          *f;
+    int            len;
+    unsigned char *png = stbi_write_png_to_mem((const unsigned char *)data, stride_bytes, x, y, comp, &len);
+    if (png == NULL)
+        return 0;
+
+    f = stbiw__fopen(filename, "wb");
+    if (!f) {
+        STBIW_FREE(png);
+        return 0;
+    }
+    fwrite(png, 1, len, f);
+    fclose(f);
+    STBIW_FREE(png);
+    return 1;
 }
 #endif
 
-STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes)
-{
-   int len;
-   unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
-   if (png == NULL) return 0;
-   func(context, png, len);
-   STBIW_FREE(png);
-   return 1;
+STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data,
+                                    int stride_bytes) {
+    int            len;
+    unsigned char *png = stbi_write_png_to_mem((const unsigned char *)data, stride_bytes, x, y, comp, &len);
+    if (png == NULL)
+        return 0;
+    func(context, png, len);
+    STBIW_FREE(png);
+    return 1;
 }
 
-
 /* ***************************************************************************
  *
  * JPEG writer
@@ -1193,337 +1237,406 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x,
  * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html
  */
 
-static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18,
-      24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 };
+static const unsigned char stbiw__jpg_ZigZag[] = {0,  1,  5,  6,  14, 15, 27, 28, 2,  4,  7,  13, 16, 26, 29, 42,
+                                                  3,  8,  12, 17, 25, 30, 41, 43, 9,  11, 18, 24, 31, 40, 44, 53,
+                                                  10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60,
+                                                  21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63};
 
 static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) {
-   int bitBuf = *bitBufP, bitCnt = *bitCntP;
-   bitCnt += bs[1];
-   bitBuf |= bs[0] << (24 - bitCnt);
-   while(bitCnt >= 8) {
-      unsigned char c = (bitBuf >> 16) & 255;
-      stbiw__putc(s, c);
-      if(c == 255) {
-         stbiw__putc(s, 0);
-      }
-      bitBuf <<= 8;
-      bitCnt -= 8;
-   }
-   *bitBufP = bitBuf;
-   *bitCntP = bitCnt;
+    int bitBuf = *bitBufP, bitCnt = *bitCntP;
+    bitCnt += bs[1];
+    bitBuf |= bs[0] << (24 - bitCnt);
+    while (bitCnt >= 8) {
+        unsigned char c = (bitBuf >> 16) & 255;
+        stbiw__putc(s, c);
+        if (c == 255) {
+            stbiw__putc(s, 0);
+        }
+        bitBuf <<= 8;
+        bitCnt -= 8;
+    }
+    *bitBufP = bitBuf;
+    *bitCntP = bitCnt;
 }
 
-static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) {
-   float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p;
-   float z1, z2, z3, z4, z5, z11, z13;
-
-   float tmp0 = d0 + d7;
-   float tmp7 = d0 - d7;
-   float tmp1 = d1 + d6;
-   float tmp6 = d1 - d6;
-   float tmp2 = d2 + d5;
-   float tmp5 = d2 - d5;
-   float tmp3 = d3 + d4;
-   float tmp4 = d3 - d4;
-
-   // Even part
-   float tmp10 = tmp0 + tmp3;   // phase 2
-   float tmp13 = tmp0 - tmp3;
-   float tmp11 = tmp1 + tmp2;
-   float tmp12 = tmp1 - tmp2;
-
-   d0 = tmp10 + tmp11;       // phase 3
-   d4 = tmp10 - tmp11;
-
-   z1 = (tmp12 + tmp13) * 0.707106781f; // c4
-   d2 = tmp13 + z1;       // phase 5
-   d6 = tmp13 - z1;
-
-   // Odd part
-   tmp10 = tmp4 + tmp5;       // phase 2
-   tmp11 = tmp5 + tmp6;
-   tmp12 = tmp6 + tmp7;
-
-   // The rotator is modified from fig 4-8 to avoid extra negations.
-   z5 = (tmp10 - tmp12) * 0.382683433f; // c6
-   z2 = tmp10 * 0.541196100f + z5; // c2-c6
-   z4 = tmp12 * 1.306562965f + z5; // c2+c6
-   z3 = tmp11 * 0.707106781f; // c4
-
-   z11 = tmp7 + z3;      // phase 5
-   z13 = tmp7 - z3;
-
-   *d5p = z13 + z2;         // phase 6
-   *d3p = z13 - z2;
-   *d1p = z11 + z4;
-   *d7p = z11 - z4;
-
-   *d0p = d0;  *d2p = d2;  *d4p = d4;  *d6p = d6;
+static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p,
+                           float *d7p) {
+    float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p;
+    float z1, z2, z3, z4, z5, z11, z13;
+
+    float tmp0 = d0 + d7;
+    float tmp7 = d0 - d7;
+    float tmp1 = d1 + d6;
+    float tmp6 = d1 - d6;
+    float tmp2 = d2 + d5;
+    float tmp5 = d2 - d5;
+    float tmp3 = d3 + d4;
+    float tmp4 = d3 - d4;
+
+    // Even part
+    float tmp10 = tmp0 + tmp3; // phase 2
+    float tmp13 = tmp0 - tmp3;
+    float tmp11 = tmp1 + tmp2;
+    float tmp12 = tmp1 - tmp2;
+
+    d0 = tmp10 + tmp11; // phase 3
+    d4 = tmp10 - tmp11;
+
+    z1 = (tmp12 + tmp13) * 0.707106781f; // c4
+    d2 = tmp13 + z1;                     // phase 5
+    d6 = tmp13 - z1;
+
+    // Odd part
+    tmp10 = tmp4 + tmp5; // phase 2
+    tmp11 = tmp5 + tmp6;
+    tmp12 = tmp6 + tmp7;
+
+    // The rotator is modified from fig 4-8 to avoid extra negations.
+    z5 = (tmp10 - tmp12) * 0.382683433f; // c6
+    z2 = tmp10 * 0.541196100f + z5;      // c2-c6
+    z4 = tmp12 * 1.306562965f + z5;      // c2+c6
+    z3 = tmp11 * 0.707106781f;           // c4
+
+    z11 = tmp7 + z3; // phase 5
+    z13 = tmp7 - z3;
+
+    *d5p = z13 + z2; // phase 6
+    *d3p = z13 - z2;
+    *d1p = z11 + z4;
+    *d7p = z11 - z4;
+
+    *d0p = d0;
+    *d2p = d2;
+    *d4p = d4;
+    *d6p = d6;
 }
 
 static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) {
-   int tmp1 = val < 0 ? -val : val;
-   val = val < 0 ? val-1 : val;
-   bits[1] = 1;
-   while(tmp1 >>= 1) {
-      ++bits[1];
-   }
-   bits[0] = val & ((1<<bits[1])-1);
+    int tmp1 = val < 0 ? -val : val;
+    val      = val < 0 ? val - 1 : val;
+    bits[1]  = 1;
+    while (tmp1 >>= 1) {
+        ++bits[1];
+    }
+    bits[0] = val & ((1 << bits[1]) - 1);
 }
 
-static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
-   const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
-   const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
-   int dataOff, i, diff, end0pos;
-   int DU[64];
-
-   // DCT rows
-   for(dataOff=0; dataOff<64; dataOff+=8) {
-      stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+1], &CDU[dataOff+2], &CDU[dataOff+3], &CDU[dataOff+4], &CDU[dataOff+5], &CDU[dataOff+6], &CDU[dataOff+7]);
-   }
-   // DCT columns
-   for(dataOff=0; dataOff<8; ++dataOff) {
-      stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+8], &CDU[dataOff+16], &CDU[dataOff+24], &CDU[dataOff+32], &CDU[dataOff+40], &CDU[dataOff+48], &CDU[dataOff+56]);
-   }
-   // Quantize/descale/zigzag the coefficients
-   for(i=0; i<64; ++i) {
-      float v = CDU[i]*fdtbl[i];
-      // DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
-      // ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
-      DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
-   }
-
-   // Encode DC
-   diff = DU[0] - DC;
-   if (diff == 0) {
-      stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[0]);
-   } else {
-      unsigned short bits[2];
-      stbiw__jpg_calcBits(diff, bits);
-      stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[bits[1]]);
-      stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
-   }
-   // Encode ACs
-   end0pos = 63;
-   for(; (end0pos>0)&&(DU[end0pos]==0); --end0pos) {
-   }
-   // end0pos = first element in reverse order !=0
-   if(end0pos == 0) {
-      stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
-      return DU[0];
-   }
-   for(i = 1; i <= end0pos; ++i) {
-      int startpos = i;
-      int nrzeroes;
-      unsigned short bits[2];
-      for (; DU[i]==0 && i<=end0pos; ++i) {
-      }
-      nrzeroes = i-startpos;
-      if ( nrzeroes >= 16 ) {
-         int lng = nrzeroes>>4;
-         int nrmarker;
-         for (nrmarker=1; nrmarker <= lng; ++nrmarker)
-            stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes);
-         nrzeroes &= 15;
-      }
-      stbiw__jpg_calcBits(DU[i], bits);
-      stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]);
-      stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
-   }
-   if(end0pos != 63) {
-      stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
-   }
-   return DU[0];
+static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, float *fdtbl, int DC,
+                                const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
+    const unsigned short EOB[2]       = {HTAC[0x00][0], HTAC[0x00][1]};
+    const unsigned short M16zeroes[2] = {HTAC[0xF0][0], HTAC[0xF0][1]};
+    int                  dataOff, i, diff, end0pos;
+    int                  DU[64];
+
+    // DCT rows
+    for (dataOff = 0; dataOff < 64; dataOff += 8) {
+        stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff + 1], &CDU[dataOff + 2], &CDU[dataOff + 3], &CDU[dataOff + 4],
+                       &CDU[dataOff + 5], &CDU[dataOff + 6], &CDU[dataOff + 7]);
+    }
+    // DCT columns
+    for (dataOff = 0; dataOff < 8; ++dataOff) {
+        stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff + 8], &CDU[dataOff + 16], &CDU[dataOff + 24], &CDU[dataOff + 32],
+                       &CDU[dataOff + 40], &CDU[dataOff + 48], &CDU[dataOff + 56]);
+    }
+    // Quantize/descale/zigzag the coefficients
+    for (i = 0; i < 64; ++i) {
+        float v = CDU[i] * fdtbl[i];
+        // DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
+        // ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
+        DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
+    }
+
+    // Encode DC
+    diff = DU[0] - DC;
+    if (diff == 0) {
+        stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[0]);
+    } else {
+        unsigned short bits[2];
+        stbiw__jpg_calcBits(diff, bits);
+        stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[bits[1]]);
+        stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
+    }
+    // Encode ACs
+    end0pos = 63;
+    for (; (end0pos > 0) && (DU[end0pos] == 0); --end0pos) {
+    }
+    // end0pos = first element in reverse order !=0
+    if (end0pos == 0) {
+        stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
+        return DU[0];
+    }
+    for (i = 1; i <= end0pos; ++i) {
+        int            startpos = i;
+        int            nrzeroes;
+        unsigned short bits[2];
+        for (; DU[i] == 0 && i <= end0pos; ++i) {
+        }
+        nrzeroes = i - startpos;
+        if (nrzeroes >= 16) {
+            int lng = nrzeroes >> 4;
+            int nrmarker;
+            for (nrmarker = 1; nrmarker <= lng; ++nrmarker)
+                stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes);
+            nrzeroes &= 15;
+        }
+        stbiw__jpg_calcBits(DU[i], bits);
+        stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes << 4) + bits[1]]);
+        stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
+    }
+    if (end0pos != 63) {
+        stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
+    }
+    return DU[0];
 }
 
-static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) {
-   // Constants that don't pollute global namespace
-   static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0};
-   static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
-   static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d};
-   static const unsigned char std_ac_luminance_values[] = {
-      0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
-      0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
-      0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
-      0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
-      0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
-      0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
-      0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
-   };
-   static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0};
-   static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
-   static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77};
-   static const unsigned char std_ac_chrominance_values[] = {
-      0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
-      0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
-      0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
-      0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
-      0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
-      0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
-      0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
-   };
-   // Huffman tables
-   static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}};
-   static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}};
-   static const unsigned short YAC_HT[256][2] = {
-      {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
-   };
-   static const unsigned short UVAC_HT[256][2] = {
-      {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0},
-      {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
-   };
-   static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,
-                             37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99};
-   static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,
-                              99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99};
-   static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, 
-                                 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
-
-   int row, col, i, k;
-   float fdtbl_Y[64], fdtbl_UV[64];
-   unsigned char YTable[64], UVTable[64];
-
-   if(!data || !width || !height || comp > 4 || comp < 1) {
-      return 0;
-   }
-
-   quality = quality ? quality : 90;
-   quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
-   quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
-
-   for(i = 0; i < 64; ++i) {
-      int uvti, yti = (YQT[i]*quality+50)/100;
-      YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti);
-      uvti = (UVQT[i]*quality+50)/100;
-      UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti);
-   }
-
-   for(row = 0, k = 0; row < 8; ++row) {
-      for(col = 0; col < 8; ++col, ++k) {
-         fdtbl_Y[k]  = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
-         fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
-      }
-   }
-
-   // Write Headers
-   {
-      static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
-      static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
-      const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width),
-                                      3,1,0x11,0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
-      s->func(s->context, (void*)head0, sizeof(head0));
-      s->func(s->context, (void*)YTable, sizeof(YTable));
-      stbiw__putc(s, 1);
-      s->func(s->context, UVTable, sizeof(UVTable));
-      s->func(s->context, (void*)head1, sizeof(head1));
-      s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1);
-      s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values));
-      stbiw__putc(s, 0x10); // HTYACinfo
-      s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1);
-      s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values));
-      stbiw__putc(s, 1); // HTUDCinfo
-      s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1);
-      s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values));
-      stbiw__putc(s, 0x11); // HTUACinfo
-      s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1);
-      s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values));
-      s->func(s->context, (void*)head2, sizeof(head2));
-   }
-
-   // Encode 8x8 macroblocks
-   {
-      static const unsigned short fillBits[] = {0x7F, 7};
-      const unsigned char *imageData = (const unsigned char *)data;
-      int DCY=0, DCU=0, DCV=0;
-      int bitBuf=0, bitCnt=0;
-      // comp == 2 is grey+alpha (alpha is ignored)
-      int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
-      int x, y, pos;
-      for(y = 0; y < height; y += 8) {
-         for(x = 0; x < width; x += 8) {
-            float YDU[64], UDU[64], VDU[64];
-            for(row = y, pos = 0; row < y+8; ++row) {
-               // row >= height => use last input row
-               int clamped_row = (row < height) ? row : height - 1;
-               int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
-               for(col = x; col < x+8; ++col, ++pos) {
-                  float r, g, b;
-                  // if col >= width => use pixel from last input column
-                  int p = base_p + ((col < width) ? col : (width-1))*comp;
-
-                  r = imageData[p+0];
-                  g = imageData[p+ofsG];
-                  b = imageData[p+ofsB];
-                  YDU[pos]=+0.29900f*r+0.58700f*g+0.11400f*b-128;
-                  UDU[pos]=-0.16874f*r-0.33126f*g+0.50000f*b;
-                  VDU[pos]=+0.50000f*r-0.41869f*g-0.08131f*b;
-               }
+static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void *data, int quality) {
+    // Constants that don't pollute global namespace
+    static const unsigned char std_dc_luminance_nrcodes[] = {0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0};
+    static const unsigned char std_dc_luminance_values[]  = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    static const unsigned char std_ac_luminance_nrcodes[] = {0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d};
+    static const unsigned char std_ac_luminance_values[]  = {
+        0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71,
+        0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
+        0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37,
+        0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+        0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
+        0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
+        0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+        0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+        0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
+    static const unsigned char std_dc_chrominance_nrcodes[] = {0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
+    static const unsigned char std_dc_chrominance_values[]  = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    static const unsigned char std_ac_chrominance_nrcodes[] = {0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77};
+    static const unsigned char std_ac_chrominance_values[]  = {
+        0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
+        0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
+        0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36,
+        0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+        0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
+        0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
+        0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
+        0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+        0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
+    // Huffman tables
+    static const unsigned short YDC_HT[256][2]  = {{0, 2},  {2, 3},  {3, 3},  {4, 3},   {5, 3},   {6, 3},
+                                                   {14, 4}, {30, 5}, {62, 6}, {126, 7}, {254, 8}, {510, 9}};
+    static const unsigned short UVDC_HT[256][2] = {{0, 2},  {1, 2},   {2, 2},   {6, 3},   {14, 4},    {30, 5},
+                                                   {62, 6}, {126, 7}, {254, 8}, {510, 9}, {1022, 10}, {2046, 11}};
+    static const unsigned short YAC_HT[256][2]  = {
+        {10, 4},     {0, 2},      {1, 2},      {4, 3},      {11, 4},     {26, 5},     {120, 7},    {248, 8},
+        {1014, 10},  {65410, 16}, {65411, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {12, 4},     {27, 5},     {121, 7},    {502, 9},    {2038, 11},  {65412, 16}, {65413, 16},
+        {65414, 16}, {65415, 16}, {65416, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {28, 5},     {249, 8},    {1015, 10},  {4084, 12},  {65417, 16}, {65418, 16}, {65419, 16},
+        {65420, 16}, {65421, 16}, {65422, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {58, 6},     {503, 9},    {4085, 12},  {65423, 16}, {65424, 16}, {65425, 16}, {65426, 16},
+        {65427, 16}, {65428, 16}, {65429, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {59, 6},     {1016, 10},  {65430, 16}, {65431, 16}, {65432, 16}, {65433, 16}, {65434, 16},
+        {65435, 16}, {65436, 16}, {65437, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {122, 7},    {2039, 11},  {65438, 16}, {65439, 16}, {65440, 16}, {65441, 16}, {65442, 16},
+        {65443, 16}, {65444, 16}, {65445, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {123, 7},    {4086, 12},  {65446, 16}, {65447, 16}, {65448, 16}, {65449, 16}, {65450, 16},
+        {65451, 16}, {65452, 16}, {65453, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {250, 8},    {4087, 12},  {65454, 16}, {65455, 16}, {65456, 16}, {65457, 16}, {65458, 16},
+        {65459, 16}, {65460, 16}, {65461, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {504, 9},    {32704, 15}, {65462, 16}, {65463, 16}, {65464, 16}, {65465, 16}, {65466, 16},
+        {65467, 16}, {65468, 16}, {65469, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {505, 9},    {65470, 16}, {65471, 16}, {65472, 16}, {65473, 16}, {65474, 16}, {65475, 16},
+        {65476, 16}, {65477, 16}, {65478, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {506, 9},    {65479, 16}, {65480, 16}, {65481, 16}, {65482, 16}, {65483, 16}, {65484, 16},
+        {65485, 16}, {65486, 16}, {65487, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {1017, 10},  {65488, 16}, {65489, 16}, {65490, 16}, {65491, 16}, {65492, 16}, {65493, 16},
+        {65494, 16}, {65495, 16}, {65496, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {1018, 10},  {65497, 16}, {65498, 16}, {65499, 16}, {65500, 16}, {65501, 16}, {65502, 16},
+        {65503, 16}, {65504, 16}, {65505, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {2040, 11},  {65506, 16}, {65507, 16}, {65508, 16}, {65509, 16}, {65510, 16}, {65511, 16},
+        {65512, 16}, {65513, 16}, {65514, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {65515, 16}, {65516, 16}, {65517, 16}, {65518, 16}, {65519, 16}, {65520, 16}, {65521, 16},
+        {65522, 16}, {65523, 16}, {65524, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {2041, 11},  {65525, 16}, {65526, 16}, {65527, 16}, {65528, 16}, {65529, 16}, {65530, 16}, {65531, 16},
+        {65532, 16}, {65533, 16}, {65534, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0}};
+    static const unsigned short UVAC_HT[256][2] = {
+        {0, 2},      {1, 2},      {4, 3},      {10, 4},     {24, 5},     {25, 5},     {56, 6},     {120, 7},
+        {500, 9},    {1014, 10},  {4084, 12},  {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {11, 4},     {57, 6},     {246, 8},    {501, 9},    {2038, 11},  {4085, 12},  {65416, 16},
+        {65417, 16}, {65418, 16}, {65419, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {26, 5},     {247, 8},    {1015, 10},  {4086, 12},  {32706, 15}, {65420, 16}, {65421, 16},
+        {65422, 16}, {65423, 16}, {65424, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {27, 5},     {248, 8},    {1016, 10},  {4087, 12},  {65425, 16}, {65426, 16}, {65427, 16},
+        {65428, 16}, {65429, 16}, {65430, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {58, 6},     {502, 9},    {65431, 16}, {65432, 16}, {65433, 16}, {65434, 16}, {65435, 16},
+        {65436, 16}, {65437, 16}, {65438, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {59, 6},     {1017, 10},  {65439, 16}, {65440, 16}, {65441, 16}, {65442, 16}, {65443, 16},
+        {65444, 16}, {65445, 16}, {65446, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {121, 7},    {2039, 11},  {65447, 16}, {65448, 16}, {65449, 16}, {65450, 16}, {65451, 16},
+        {65452, 16}, {65453, 16}, {65454, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {122, 7},    {2040, 11},  {65455, 16}, {65456, 16}, {65457, 16}, {65458, 16}, {65459, 16},
+        {65460, 16}, {65461, 16}, {65462, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {249, 8},    {65463, 16}, {65464, 16}, {65465, 16}, {65466, 16}, {65467, 16}, {65468, 16},
+        {65469, 16}, {65470, 16}, {65471, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {503, 9},    {65472, 16}, {65473, 16}, {65474, 16}, {65475, 16}, {65476, 16}, {65477, 16},
+        {65478, 16}, {65479, 16}, {65480, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {504, 9},    {65481, 16}, {65482, 16}, {65483, 16}, {65484, 16}, {65485, 16}, {65486, 16},
+        {65487, 16}, {65488, 16}, {65489, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {505, 9},    {65490, 16}, {65491, 16}, {65492, 16}, {65493, 16}, {65494, 16}, {65495, 16},
+        {65496, 16}, {65497, 16}, {65498, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {506, 9},    {65499, 16}, {65500, 16}, {65501, 16}, {65502, 16}, {65503, 16}, {65504, 16},
+        {65505, 16}, {65506, 16}, {65507, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {2041, 11},  {65508, 16}, {65509, 16}, {65510, 16}, {65511, 16}, {65512, 16}, {65513, 16},
+        {65514, 16}, {65515, 16}, {65516, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {0, 0},      {16352, 14}, {65517, 16}, {65518, 16}, {65519, 16}, {65520, 16}, {65521, 16}, {65522, 16},
+        {65523, 16}, {65524, 16}, {65525, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0},
+        {1018, 10},  {32707, 15}, {65526, 16}, {65527, 16}, {65528, 16}, {65529, 16}, {65530, 16}, {65531, 16},
+        {65532, 16}, {65533, 16}, {65534, 16}, {0, 0},      {0, 0},      {0, 0},      {0, 0},      {0, 0}};
+    static const int   YQT[]  = {16, 11, 10, 16, 24,  40,  51,  61,  12, 12, 14, 19, 26,  58,  60,  55,
+                                 14, 13, 16, 24, 40,  57,  69,  56,  14, 17, 22, 29, 51,  87,  80,  62,
+                                 18, 22, 37, 56, 68,  109, 103, 77,  24, 35, 55, 64, 81,  104, 113, 92,
+                                 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99};
+    static const int   UVQT[] = {17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99,
+                                 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+                                 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99};
+    static const float aasf[] = {1.0f * 2.828427125f,         1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f,
+                                 1.175875602f * 2.828427125f, 1.0f * 2.828427125f,         0.785694958f * 2.828427125f,
+                                 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f};
+
+    int           row, col, i, k;
+    float         fdtbl_Y[64], fdtbl_UV[64];
+    unsigned char YTable[64], UVTable[64];
+
+    if (!data || !width || !height || comp > 4 || comp < 1) {
+        return 0;
+    }
+
+    quality = quality ? quality : 90;
+    quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
+    quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
+
+    for (i = 0; i < 64; ++i) {
+        int uvti, yti = (YQT[i] * quality + 50) / 100;
+        YTable[stbiw__jpg_ZigZag[i]]  = (unsigned char)(yti < 1 ? 1 : yti > 255 ? 255 : yti);
+        uvti                          = (UVQT[i] * quality + 50) / 100;
+        UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char)(uvti < 1 ? 1 : uvti > 255 ? 255 : uvti);
+    }
+
+    for (row = 0, k = 0; row < 8; ++row) {
+        for (col = 0; col < 8; ++col, ++k) {
+            fdtbl_Y[k]  = 1 / (YTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
+            fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
+        }
+    }
+
+    // Write Headers
+    {
+        static const unsigned char head0[] = {0xFF, 0xD8, 0xFF, 0xE0, 0, 0x10, 'J', 'F',  'I',  'F', 0,    1, 1,
+                                              0,    0,    1,    0,    1, 0,    0,   0xFF, 0xDB, 0,   0x84, 0};
+        static const unsigned char head2[] = {0xFF, 0xDA, 0, 0xC, 3, 1, 0, 2, 0x11, 3, 0x11, 0, 0x3F, 0};
+        const unsigned char        head1[] = {0xFF,
+                                              0xC0,
+                                              0,
+                                              0x11,
+                                              8,
+                                              (unsigned char)(height >> 8),
+                                              STBIW_UCHAR(height),
+                                              (unsigned char)(width >> 8),
+                                              STBIW_UCHAR(width),
+                                              3,
+                                              1,
+                                              0x11,
+                                              0,
+                                              2,
+                                              0x11,
+                                              1,
+                                              3,
+                                              0x11,
+                                              1,
+                                              0xFF,
+                                              0xC4,
+                                              0x01,
+                                              0xA2,
+                                              0};
+        s->func(s->context, (void *)head0, sizeof(head0));
+        s->func(s->context, (void *)YTable, sizeof(YTable));
+        stbiw__putc(s, 1);
+        s->func(s->context, UVTable, sizeof(UVTable));
+        s->func(s->context, (void *)head1, sizeof(head1));
+        s->func(s->context, (void *)(std_dc_luminance_nrcodes + 1), sizeof(std_dc_luminance_nrcodes) - 1);
+        s->func(s->context, (void *)std_dc_luminance_values, sizeof(std_dc_luminance_values));
+        stbiw__putc(s, 0x10); // HTYACinfo
+        s->func(s->context, (void *)(std_ac_luminance_nrcodes + 1), sizeof(std_ac_luminance_nrcodes) - 1);
+        s->func(s->context, (void *)std_ac_luminance_values, sizeof(std_ac_luminance_values));
+        stbiw__putc(s, 1); // HTUDCinfo
+        s->func(s->context, (void *)(std_dc_chrominance_nrcodes + 1), sizeof(std_dc_chrominance_nrcodes) - 1);
+        s->func(s->context, (void *)std_dc_chrominance_values, sizeof(std_dc_chrominance_values));
+        stbiw__putc(s, 0x11); // HTUACinfo
+        s->func(s->context, (void *)(std_ac_chrominance_nrcodes + 1), sizeof(std_ac_chrominance_nrcodes) - 1);
+        s->func(s->context, (void *)std_ac_chrominance_values, sizeof(std_ac_chrominance_values));
+        s->func(s->context, (void *)head2, sizeof(head2));
+    }
+
+    // Encode 8x8 macroblocks
+    {
+        static const unsigned short fillBits[] = {0x7F, 7};
+        const unsigned char        *imageData  = (const unsigned char *)data;
+        int                         DCY = 0, DCU = 0, DCV = 0;
+        int                         bitBuf = 0, bitCnt = 0;
+        // comp == 2 is grey+alpha (alpha is ignored)
+        int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
+        int x, y, pos;
+        for (y = 0; y < height; y += 8) {
+            for (x = 0; x < width; x += 8) {
+                float YDU[64], UDU[64], VDU[64];
+                for (row = y, pos = 0; row < y + 8; ++row) {
+                    // row >= height => use last input row
+                    int clamped_row = (row < height) ? row : height - 1;
+                    int base_p =
+                        (stbi__flip_vertically_on_write ? (height - 1 - clamped_row) : clamped_row) * width * comp;
+                    for (col = x; col < x + 8; ++col, ++pos) {
+                        float r, g, b;
+                        // if col >= width => use pixel from last input column
+                        int p = base_p + ((col < width) ? col : (width - 1)) * comp;
+
+                        r        = imageData[p + 0];
+                        g        = imageData[p + ofsG];
+                        b        = imageData[p + ofsB];
+                        YDU[pos] = +0.29900f * r + 0.58700f * g + 0.11400f * b - 128;
+                        UDU[pos] = -0.16874f * r - 0.33126f * g + 0.50000f * b;
+                        VDU[pos] = +0.50000f * r - 0.41869f * g - 0.08131f * b;
+                    }
+                }
+
+                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
+                DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
+                DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
             }
+        }
 
-            DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
-            DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
-            DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
-         }
-      }
+        // Do the bit alignment of the EOI marker
+        stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits);
+    }
 
-      // Do the bit alignment of the EOI marker
-      stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits);
-   }
+    // EOI
+    stbiw__putc(s, 0xFF);
+    stbiw__putc(s, 0xD9);
 
-   // EOI
-   stbiw__putc(s, 0xFF);
-   stbiw__putc(s, 0xD9);
-
-   return 1;
+    return 1;
 }
 
-STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)
-{
-   stbi__write_context s;
-   stbi__start_write_callbacks(&s, func, context);
-   return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality);
+STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data,
+                                    int quality) {
+    stbi__write_context s;
+    stbi__start_write_callbacks(&s, func, context);
+    return stbi_write_jpg_core(&s, x, y, comp, (void *)data, quality);
 }
 
-
 #ifndef STBI_WRITE_NO_STDIO
-STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
-{
-   stbi__write_context s;
-   if (stbi__start_write_file(&s,filename)) {
-      int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
-      stbi__end_write_file(&s);
-      return r;
-   } else
-      return 0;
+STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) {
+    stbi__write_context s;
+    if (stbi__start_write_file(&s, filename)) {
+        int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
+        stbi__end_write_file(&s);
+        return r;
+    } else
+        return 0;
 }
 #endif
 
@@ -1531,7 +1644,7 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
 
 /* Revision history
       1.10  (2019-02-07)
-             support utf8 filenames in Windows; fix warnings and platform ifdefs 
+             support utf8 filenames in Windows; fix warnings and platform ifdefs
       1.09  (2018-02-11)
              fix typo in zlib quality API, improve STB_I_W_STATIC in C++
       1.08  (2018-01-29)
@@ -1562,7 +1675,7 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
              add HDR output
              fix monochrome BMP
       0.95 (2014-08-17)
-                      add monochrome TGA output
+               add monochrome TGA output
       0.94 (2014-05-31)
              rename private functions to avoid conflicts with stb_image.h
       0.93 (2014-05-27)
@@ -1580,38 +1693,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
 ------------------------------------------------------------------------------
 ALTERNATIVE A - MIT License
 Copyright (c) 2017 Sean Barrett
-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 
+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 
+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 
+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.
 ------------------------------------------------------------------------------
 ALTERNATIVE B - Public Domain (www.unlicense.org)
 This is free and unencumbered software released into the public domain.
-Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 
-software, either in source code form or as a compiled binary, for any purpose, 
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
 commercial or non-commercial, and by any means.
-In jurisdictions that recognize copyright laws, the author or authors of this 
-software dedicate any and all copyright interest in the software to the public 
-domain. We make this dedication for the benefit of the public at large and to 
-the detriment of our heirs and successors. We intend this dedication to be an 
-overt act of relinquishment in perpetuity of all present and future rights to 
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
 this software under copyright law.
-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 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 
+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 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.
 ------------------------------------------------------------------------------
 */
index bbf2284b164c2bc23f31d90439c416397fa02d71..622e4ef4d7f7659a0d7f3a600fd1e4bec92807a2 100644 (file)
 //  Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless.
 //  See "tests/truetype_demo_win32.c" for a complete version.
 #if 0
-#define STB_TRUETYPE_IMPLEMENTATION  // force following include to generate implementation
+#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
 #include "stb_truetype.h"
 
 unsigned char ttf_buffer[1<<20];
@@ -326,7 +326,7 @@ void my_stbtt_print(float x, float y, char *text)
 //
 #if 0
 #include <stdio.h>
-#define STB_TRUETYPE_IMPLEMENTATION  // force following include to generate implementation
+#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
 #include "stb_truetype.h"
 
 char ttf_buffer[1<<25];
@@ -412,7 +412,6 @@ int main(int arg, char **argv)
 }
 #endif
 
-
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 ////
@@ -423,70 +422,70 @@ int main(int arg, char **argv)
 ////   link with the C runtime library.
 
 #ifdef STB_TRUETYPE_IMPLEMENTATION
-   // #define your own (u)stbtt_int8/16/32 before including to override this
-   #ifndef stbtt_uint8
-   typedef unsigned char   stbtt_uint8;
-   typedef signed   char   stbtt_int8;
-   typedef unsigned short  stbtt_uint16;
-   typedef signed   short  stbtt_int16;
-   typedef unsigned int    stbtt_uint32;
-   typedef signed   int    stbtt_int32;
-   #endif
-
-   typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
-   typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
-
-   // e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
-   #ifndef STBTT_ifloor
-   #include <math.h>
-   #define STBTT_ifloor(x)   ((int) floor(x))
-   #define STBTT_iceil(x)    ((int) ceil(x))
-   #endif
-
-   #ifndef STBTT_sqrt
-   #include <math.h>
-   #define STBTT_sqrt(x)      sqrt(x)
-   #define STBTT_pow(x,y)     pow(x,y)
-   #endif
-
-   #ifndef STBTT_fmod
-   #include <math.h>
-   #define STBTT_fmod(x,y)    fmod(x,y)
-   #endif
-
-   #ifndef STBTT_cos
-   #include <math.h>
-   #define STBTT_cos(x)       cos(x)
-   #define STBTT_acos(x)      acos(x)
-   #endif
-
-   #ifndef STBTT_fabs
-   #include <math.h>
-   #define STBTT_fabs(x)      fabs(x)
-   #endif
-
-   // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
-   #ifndef STBTT_malloc
-   #include <stdlib.h>
-   #define STBTT_malloc(x,u)  ((void)(u),malloc(x))
-   #define STBTT_free(x,u)    ((void)(u),free(x))
-   #endif
-
-   #ifndef STBTT_assert
-   #include <assert.h>
-   #define STBTT_assert(x)    assert(x)
-   #endif
-
-   #ifndef STBTT_strlen
-   #include <string.h>
-   #define STBTT_strlen(x)    strlen(x)
-   #endif
-
-   #ifndef STBTT_memcpy
-   #include <string.h>
-   #define STBTT_memcpy       memcpy
-   #define STBTT_memset       memset
-   #endif
+// #define your own (u)stbtt_int8/16/32 before including to override this
+#ifndef stbtt_uint8
+typedef unsigned char  stbtt_uint8;
+typedef signed char    stbtt_int8;
+typedef unsigned short stbtt_uint16;
+typedef signed short   stbtt_int16;
+typedef unsigned int   stbtt_uint32;
+typedef signed int     stbtt_int32;
+#endif
+
+typedef char stbtt__check_size32[sizeof(stbtt_int32) == 4 ? 1 : -1];
+typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1];
+
+// e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
+#ifndef STBTT_ifloor
+#include <math.h>
+#define STBTT_ifloor(x) ((int)floor(x))
+#define STBTT_iceil(x)  ((int)ceil(x))
+#endif
+
+#ifndef STBTT_sqrt
+#include <math.h>
+#define STBTT_sqrt(x)   sqrt(x)
+#define STBTT_pow(x, y) pow(x, y)
+#endif
+
+#ifndef STBTT_fmod
+#include <math.h>
+#define STBTT_fmod(x, y) fmod(x, y)
+#endif
+
+#ifndef STBTT_cos
+#include <math.h>
+#define STBTT_cos(x)  cos(x)
+#define STBTT_acos(x) acos(x)
+#endif
+
+#ifndef STBTT_fabs
+#include <math.h>
+#define STBTT_fabs(x) fabs(x)
+#endif
+
+// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
+#ifndef STBTT_malloc
+#include <stdlib.h>
+#define STBTT_malloc(x, u) ((void)(u), malloc(x))
+#define STBTT_free(x, u)   ((void)(u), free(x))
+#endif
+
+#ifndef STBTT_assert
+#include <assert.h>
+#define STBTT_assert(x) assert(x)
+#endif
+
+#ifndef STBTT_strlen
+#include <string.h>
+#define STBTT_strlen(x) strlen(x)
+#endif
+
+#ifndef STBTT_memcpy
+#include <string.h>
+#define STBTT_memcpy memcpy
+#define STBTT_memset memset
+#endif
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -510,11 +509,10 @@ extern "C" {
 #endif
 
 // private structure
-typedef struct
-{
-   unsigned char *data;
-   int cursor;
-   int size;
+typedef struct {
+    unsigned char *data;
+    int            cursor;
+    int            size;
 } stbtt__buf;
 
 //////////////////////////////////////////////////////////////////////////////
@@ -524,33 +522,31 @@ typedef struct
 // If you use this API, you only have to call two functions ever.
 //
 
-typedef struct
-{
-   unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
-   float xoff,yoff,xadvance;
+typedef struct {
+    unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap
+    float          xoff, yoff, xadvance;
 } stbtt_bakedchar;
 
-STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset,  // font location (use offset=0 for plain .ttf)
-                                float pixel_height,                     // height of font in pixels
-                                unsigned char *pixels, int pw, int ph,  // bitmap to be filled in
-                                int first_char, int num_chars,          // characters to bake
-                                stbtt_bakedchar *chardata);             // you allocate this, it's num_chars long
+STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
+                                   float          pixel_height,           // height of font in pixels
+                                   unsigned char *pixels, int pw, int ph, // bitmap to be filled in
+                                   int first_char, int num_chars,         // characters to bake
+                                   stbtt_bakedchar *chardata);            // you allocate this, it's num_chars long
 // if return is positive, the first unused row of the bitmap
 // if return is negative, returns the negative of the number of characters that fit
 // if return is 0, no characters fit and no rows were used
 // This uses a very crappy packing.
 
-typedef struct
-{
-   float x0,y0,s0,t0; // top-left
-   float x1,y1,s1,t1; // bottom-right
+typedef struct {
+    float x0, y0, s0, t0; // top-left
+    float x1, y1, s1, t1; // bottom-right
 } stbtt_aligned_quad;
 
-STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph,  // same data as above
-                               int char_index,             // character to display
-                               float *xpos, float *ypos,   // pointers to current position in screen pixel space
-                               stbtt_aligned_quad *q,      // output: quad to draw
-                               int opengl_fillrule);       // true if opengl fill rule; false if DX9 or earlier
+STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above
+                                  int    char_index,                               // character to display
+                                  float *xpos, float *ypos, // pointers to current position in screen pixel space
+                                  stbtt_aligned_quad *q,    // output: quad to draw
+                                  int opengl_fillrule);     // true if opengl fill rule; false if DX9 or earlier
 // Call GetBakedQuad with char_index = 'character - first_char', and it
 // creates the quad you need to draw and advances the current position.
 //
@@ -561,10 +557,10 @@ STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int p
 //
 // It's inefficient; you might want to c&p it and optimize it.
 
-STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
+STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent,
+                                           float *descent, float *lineGap);
 // Query the font vertical metrics without having to create a font first.
 
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // NEW TEXTURE BAKING API
@@ -572,20 +568,20 @@ STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int in
 // This provides options for packing multiple fonts into one atlas, not
 // perfectly but better than nothing.
 
-typedef struct
-{
-   unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
-   float xoff,yoff,xadvance;
-   float xoff2,yoff2;
+typedef struct {
+    unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap
+    float          xoff, yoff, xadvance;
+    float          xoff2, yoff2;
 } stbtt_packedchar;
 
 typedef struct stbtt_pack_context stbtt_pack_context;
-typedef struct stbtt_fontinfo stbtt_fontinfo;
+typedef struct stbtt_fontinfo     stbtt_fontinfo;
 #ifndef STB_RECT_PACK_VERSION
 typedef struct stbrp_rect stbrp_rect;
 #endif
 
-STBTT_DEF int  stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context);
+STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height,
+                              int stride_in_bytes, int padding, void *alloc_context);
 // Initializes a packing context stored in the passed-in stbtt_pack_context.
 // Future calls using this context will pack characters into the bitmap passed
 // in here: a 1-channel bitmap that is width * height. stride_in_bytes is
@@ -596,13 +592,14 @@ STBTT_DEF int  stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, i
 //
 // Returns 0 on failure, 1 on success.
 
-STBTT_DEF void stbtt_PackEnd  (stbtt_pack_context *spc);
+STBTT_DEF void stbtt_PackEnd(stbtt_pack_context *spc);
 // Cleans up the packing context and frees all memory.
 
-#define STBTT_POINT_SIZE(x)   (-(x))
+#define STBTT_POINT_SIZE(x) (-(x))
 
-STBTT_DEF int  stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size,
-                                int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
+STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index,
+                                  float font_size, int first_unicode_char_in_range, int num_chars_in_range,
+                                  stbtt_packedchar *chardata_for_range);
 // Creates character bitmaps from the font_index'th font found in fontdata (use
 // font_index=0 if you don't know what that is). It creates num_chars_in_range
 // bitmaps for characters with unicode values starting at first_unicode_char_in_range
@@ -616,17 +613,17 @@ STBTT_DEF int  stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char
 //       ...,                  20 , ... // font max minus min y is 20 pixels tall
 //       ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
 
-typedef struct
-{
-   float font_size;
-   int first_unicode_codepoint_in_range;  // if non-zero, then the chars are continuous, and this is the first codepoint
-   int *array_of_unicode_codepoints;       // if non-zero, then this is an array of unicode codepoints
-   int num_chars;
-   stbtt_packedchar *chardata_for_range; // output
-   unsigned char h_oversample, v_oversample; // don't set these, they're used internally
+typedef struct {
+    float font_size;
+    int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint
+    int              *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints
+    int               num_chars;
+    stbtt_packedchar *chardata_for_range;         // output
+    unsigned char     h_oversample, v_oversample; // don't set these, they're used internally
 } stbtt_pack_range;
 
-STBTT_DEF int  stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
+STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index,
+                                   stbtt_pack_range *ranges, int num_ranges);
 // Creates character bitmaps from multiple ranges of characters stored in
 // ranges. This will usually create a better-packed bitmap than multiple
 // calls to stbtt_PackFontRange. Note that you can call this multiple
@@ -654,15 +651,17 @@ STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int s
 // codepoints without a glyph recived the font's "missing character" glyph,
 // typically an empty box by convention.
 
-STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph,  // same data as above
-                               int char_index,             // character to display
-                               float *xpos, float *ypos,   // pointers to current position in screen pixel space
-                               stbtt_aligned_quad *q,      // output: quad to draw
-                               int align_to_integer);
+STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
+                                   int    char_index,                                // character to display
+                                   float *xpos, float *ypos, // pointers to current position in screen pixel space
+                                   stbtt_aligned_quad *q,    // output: quad to draw
+                                   int                 align_to_integer);
 
-STBTT_DEF int  stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
+STBTT_DEF int  stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info,
+                                               stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
 STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects);
-STBTT_DEF int  stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
+STBTT_DEF int  stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info,
+                                                   stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
 // Calling these functions in sequence is roughly equivalent to calling
 // stbtt_PackFontRanges(). If you more control over the packing of multiple
 // fonts, or if you want to pack custom data into a font texture, take a look
@@ -676,16 +675,16 @@ STBTT_DEF int  stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, cons
 // this is an opaque structure that you shouldn't mess with which holds
 // all the context needed from PackBegin to PackEnd.
 struct stbtt_pack_context {
-   void *user_allocator_context;
-   void *pack_info;
-   int   width;
-   int   height;
-   int   stride_in_bytes;
-   int   padding;
-   int   skip_missing;
-   unsigned int   h_oversample, v_oversample;
-   unsigned char *pixels;
-   void  *nodes;
+    void          *user_allocator_context;
+    void          *pack_info;
+    int            width;
+    int            height;
+    int            stride_in_bytes;
+    int            padding;
+    int            skip_missing;
+    unsigned int   h_oversample, v_oversample;
+    unsigned char *pixels;
+    void          *nodes;
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -710,24 +709,23 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
 
 // The following structure is defined publicly so you can declare one on
 // the stack or as a global or etc, but you should treat it as opaque.
-struct stbtt_fontinfo
-{
-   void           * userdata;
-   unsigned char  * data;              // pointer to .ttf file
-   int              fontstart;         // offset of start of font
-
-   int numGlyphs;                     // number of glyphs, needed for range checking
-
-   int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf
-   int index_map;                     // a cmap mapping for our chosen character encoding
-   int indexToLocFormat;              // format needed to map from glyph index to glyph
-
-   stbtt__buf cff;                    // cff font data
-   stbtt__buf charstrings;            // the charstring index
-   stbtt__buf gsubrs;                 // global charstring subroutines index
-   stbtt__buf subrs;                  // private charstring subroutines index
-   stbtt__buf fontdicts;              // array of font dicts
-   stbtt__buf fdselect;               // map from glyph to fontdict
+struct stbtt_fontinfo {
+    void          *userdata;
+    unsigned char *data;      // pointer to .ttf file
+    int            fontstart; // offset of start of font
+
+    int numGlyphs; // number of glyphs, needed for range checking
+
+    int loca, head, glyf, hhea, hmtx, kern, gpos, svg; // table locations as offset from start of .ttf
+    int index_map;                                     // a cmap mapping for our chosen character encoding
+    int indexToLocFormat;                              // format needed to map from glyph index to glyph
+
+    stbtt__buf cff;         // cff font data
+    stbtt__buf charstrings; // the charstring index
+    stbtt__buf gsubrs;      // global charstring subroutines index
+    stbtt__buf subrs;       // private charstring subroutines index
+    stbtt__buf fontdicts;   // array of font dicts
+    stbtt__buf fdselect;    // map from glyph to fontdict
 };
 
 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
@@ -737,7 +735,6 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, in
 // need to do anything special to free it, because the contents are pure
 // value data with no additional data structures. Returns 0 on failure.
 
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // CHARACTER TO GLYPH-INDEX CONVERSIOn
@@ -749,7 +746,6 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
 // codepoint-based functions.
 // Returns 0 if the character codepoint is not defined in the font.
 
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // CHARACTER PROPERTIES
@@ -776,7 +772,7 @@ STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, in
 //   these are expressed in unscaled coordinates, so you must multiply by
 //   the scale factor for a given size
 
-STBTT_DEF int  stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap);
+STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap);
 // analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2
 // table (specific to MS/Windows TTF files).
 //
@@ -785,31 +781,32 @@ STBTT_DEF int  stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAsc
 STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1);
 // the bounding box around all possible characters
 
-STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing);
+STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth,
+                                          int *leftSideBearing);
 // leftSideBearing is the offset from the current horizontal position to the left edge of the character
 // advanceWidth is the offset from the current horizontal position to the next horizontal position
 //   these are expressed in unscaled coordinates
 
-STBTT_DEF int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
+STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
 // an additional amount to add to the 'advance' value between ch1 and ch2
 
 STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
 // Gets the bounding box of the visible part of the glyph, in unscaled coordinates
 
-STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing);
+STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth,
+                                      int *leftSideBearing);
 STBTT_DEF int  stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
 STBTT_DEF int  stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
 // as above, but takes one or more glyph indices for greater efficiency
 
-typedef struct stbtt_kerningentry
-{
-   int glyph1; // use stbtt_FindGlyphIndex
-   int glyph2;
-   int advance;
+typedef struct stbtt_kerningentry {
+    int glyph1; // use stbtt_FindGlyphIndex
+    int glyph2;
+    int advance;
 } stbtt_kerningentry;
 
-STBTT_DEF int  stbtt_GetKerningTableLength(const stbtt_fontinfo *info);
-STBTT_DEF int  stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length);
+STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info);
+STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry *table, int table_length);
 // Retrieves a complete list of all of the kerning pairs provided by the font
 // stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write.
 // The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
@@ -821,22 +818,16 @@ STBTT_DEF int  stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningen
 //
 
 #ifndef STBTT_vmove // you can predefine these to use different values (but why?)
-   enum {
-      STBTT_vmove=1,
-      STBTT_vline,
-      STBTT_vcurve,
-      STBTT_vcubic
-   };
+enum { STBTT_vmove = 1, STBTT_vline, STBTT_vcurve, STBTT_vcubic };
 #endif
 
-#ifndef stbtt_vertex // you can predefine this to use different values
-                   // (we share this with other code at RAD)
-   #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
-   typedef struct
-   {
-      stbtt_vertex_type x,y,cx,cy,cx1,cy1;
-      unsigned char type,padding;
-   } stbtt_vertex;
+#ifndef stbtt_vertex            // you can predefine this to use different values
+                                // (we share this with other code at RAD)
+#define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
+typedef struct {
+    stbtt_vertex_type x, y, cx, cy, cx1, cy1;
+    unsigned char     type, padding;
+} stbtt_vertex;
 #endif
 
 STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index);
@@ -858,8 +849,8 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertice
 // frees the data allocated above
 
 STBTT_DEF unsigned char *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl);
-STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg);
-STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg);
+STBTT_DEF int            stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg);
+STBTT_DEF int            stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg);
 // fills svg with the character's SVG data.
 // returns data size or 0 if SVG not found.
 
@@ -871,7 +862,8 @@ STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char *
 STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
 // frees the bitmap allocated below
 
-STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
+STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y,
+                                                  int codepoint, int *width, int *height, int *xoff, int *yoff);
 // allocates a large-enough single-channel 8bpp bitmap and renders the
 // specified character/glyph at the specified scale into it, with
 // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
@@ -880,63 +872,83 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, fl
 //
 // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
 
-STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
+STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y,
+                                                          float shift_x, float shift_y, int codepoint, int *width,
+                                                          int *height, int *xoff, int *yoff);
 // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
 // shift for the character
 
-STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint);
+STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h,
+                                         int out_stride, float scale_x, float scale_y, int codepoint);
 // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap
 // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
 // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the
 // width and height and positioning info for it first.
 
-STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint);
+STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w,
+                                                 int out_h, int out_stride, float scale_x, float scale_y, float shift_x,
+                                                 float shift_y, int codepoint);
 // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
 // shift for the character
 
-STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint);
+STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w,
+                                                          int out_h, int out_stride, float scale_x, float scale_y,
+                                                          float shift_x, float shift_y, int oversample_x,
+                                                          int oversample_y, float *sub_x, float *sub_y, int codepoint);
 // same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering
 // is performed (see stbtt_PackSetOversampling)
 
-STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
+STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y,
+                                           int *ix0, int *iy0, int *ix1, int *iy1);
 // get the bbox of the bitmap centered around the glyph origin; so the
 // bitmap width is ix1-ix0, height is iy1-iy0, and location to place
 // the bitmap top left is (leftSideBearing*scale,iy0).
 // (Note that the bitmap uses y-increases-down, but the shape uses
 // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
 
-STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
+STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x,
+                                                   float scale_y, float shift_x, float shift_y, int *ix0, int *iy0,
+                                                   int *ix1, int *iy1);
 // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
 // shift for the character
 
 // the following functions are equivalent to the above functions, but operate
 // on glyph indices instead of Unicode codepoints (for efficiency)
-STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff);
-STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff);
-STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph);
-STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph);
-STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph);
-STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
-STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
-
+STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph,
+                                              int *width, int *height, int *xoff, int *yoff);
+STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y,
+                                                      float shift_x, float shift_y, int glyph, int *width, int *height,
+                                                      int *xoff, int *yoff);
+STBTT_DEF void           stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h,
+                                               int out_stride, float scale_x, float scale_y, int glyph);
+STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h,
+                                             int out_stride, float scale_x, float scale_y, float shift_x, float shift_y,
+                                             int glyph);
+STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w,
+                                                      int out_h, int out_stride, float scale_x, float scale_y,
+                                                      float shift_x, float shift_y, int oversample_x, int oversample_y,
+                                                      float *sub_x, float *sub_y, int glyph);
+STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0,
+                                       int *iy0, int *ix1, int *iy1);
+STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,
+                                               float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
 
 // @TODO: don't expose this structure
-typedef struct
-{
-   int w,h,stride;
-   unsigned char *pixels;
+typedef struct {
+    int            w, h, stride;
+    unsigned char *pixels;
 } stbtt__bitmap;
 
 // rasterize a shape with quadratic beziers into a bitmap
-STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result,        // 1-channel bitmap to draw into
-                               float flatness_in_pixels,     // allowable error of curve in pixels
-                               stbtt_vertex *vertices,       // array of vertices defining shape
-                               int num_verts,                // number of vertices in above array
-                               float scale_x, float scale_y, // scale applied to input vertices
-                               float shift_x, float shift_y, // translation applied to input vertices
-                               int x_off, int y_off,         // another translation applied to input
-                               int invert,                   // if non-zero, vertically flip shape
-                               void *userdata);              // context for to STBTT_MALLOC
+STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result,             // 1-channel bitmap to draw into
+                               float          flatness_in_pixels, // allowable error of curve in pixels
+                               stbtt_vertex  *vertices,           // array of vertices defining shape
+                               int            num_verts,          // number of vertices in above array
+                               float scale_x, float scale_y,      // scale applied to input vertices
+                               float shift_x, float shift_y,      // translation applied to input vertices
+                               int x_off, int y_off,              // another translation applied to input
+                               int   invert,                      // if non-zero, vertically flip shape
+                               void *userdata);                   // context for to STBTT_MALLOC
 
 //////////////////////////////////////////////////////////////////////////////
 //
@@ -945,18 +957,23 @@ STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result,        // 1-channel bitmap
 STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata);
 // frees the SDF bitmap allocated below
 
-STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
-STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
+STBTT_DEF unsigned char *stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding,
+                                           unsigned char onedge_value, float pixel_dist_scale, int *width, int *height,
+                                           int *xoff, int *yoff);
+STBTT_DEF unsigned char *stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding,
+                                               unsigned char onedge_value, float pixel_dist_scale, int *width,
+                                               int *height, int *xoff, int *yoff);
 // These functions compute a discretized SDF field for a single character, suitable for storing
 // in a single-channel texture, sampling with bilinear filtering, and testing against
 // larger than some threshold to produce scalable fonts.
 //        info              --  the font
-//        scale             --  controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
-//        glyph/codepoint   --  the character to generate the SDF for
-//        padding           --  extra "pixels" around the character which are filled with the distance to the character (not 0),
+//        scale             --  controls the size of the resulting SDF bitmap, same as it would be creating a regular
+//        bitmap glyph/codepoint   --  the character to generate the SDF for padding           --  extra "pixels" around
+//        the character which are filled with the distance to the character (not 0),
 //                                 which allows effects like bit outlines
-//        onedge_value      --  value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character)
-//        pixel_dist_scale  --  what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale)
+//        onedge_value      --  value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of
+//        the character) pixel_dist_scale  --  what value the SDF should increase by when moving one SDF "pixel" away
+//        from the edge (on the 0..255 scale)
 //                                 if positive, > onedge_value is inside; if negative, < onedge_value is inside
 //        width,height      --  output height & width of the SDF bitmap (including padding)
 //        xoff,yoff         --  output origin of the character
@@ -994,8 +1011,6 @@ STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, floa
 // The algorithm has not been optimized at all, so expect it to be slow
 // if computing lots of characters or very large sizes.
 
-
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // Finding the right font...
@@ -1017,23 +1032,23 @@ STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, floa
 //             from the file yourself and do your own comparisons on them.
 //             You have to have called stbtt_InitFont() first.
 
-
 STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags);
 // returns the offset (not index) of the font that matches, or -1 if none
 //   if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
 //   if you use any other flag, use a font name like "Arial"; this checks
 //     the 'macStyle' header field; i don't know if fonts set this consistently
-#define STBTT_MACSTYLE_DONTCARE     0
-#define STBTT_MACSTYLE_BOLD         1
-#define STBTT_MACSTYLE_ITALIC       2
-#define STBTT_MACSTYLE_UNDERSCORE   4
-#define STBTT_MACSTYLE_NONE         8   // <= not same as 0, this makes us check the bitfield is 0
+#define STBTT_MACSTYLE_DONTCARE   0
+#define STBTT_MACSTYLE_BOLD       1
+#define STBTT_MACSTYLE_ITALIC     2
+#define STBTT_MACSTYLE_UNDERSCORE 4
+#define STBTT_MACSTYLE_NONE       8 // <= not same as 0, this makes us check the bitfield is 0
 
 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2);
 // returns 1/0 whether the first string interpreted as utf8 is identical to
 // the second string interpreted as big-endian utf16... useful for strings from next func
 
-STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID);
+STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID,
+                                              int languageID, int nameID);
 // returns the string (which may be big-endian double byte, e.g. for unicode)
 // and puts the length in bytes in *length.
 //
@@ -1042,52 +1057,69 @@ STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *l
 //     http://www.microsoft.com/typography/otspec/name.htm
 
 enum { // platformID
-   STBTT_PLATFORM_ID_UNICODE   =0,
-   STBTT_PLATFORM_ID_MAC       =1,
-   STBTT_PLATFORM_ID_ISO       =2,
-   STBTT_PLATFORM_ID_MICROSOFT =3
+    STBTT_PLATFORM_ID_UNICODE   = 0,
+    STBTT_PLATFORM_ID_MAC       = 1,
+    STBTT_PLATFORM_ID_ISO       = 2,
+    STBTT_PLATFORM_ID_MICROSOFT = 3
 };
 
 enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
-   STBTT_UNICODE_EID_UNICODE_1_0    =0,
-   STBTT_UNICODE_EID_UNICODE_1_1    =1,
-   STBTT_UNICODE_EID_ISO_10646      =2,
-   STBTT_UNICODE_EID_UNICODE_2_0_BMP=3,
-   STBTT_UNICODE_EID_UNICODE_2_0_FULL=4
+    STBTT_UNICODE_EID_UNICODE_1_0      = 0,
+    STBTT_UNICODE_EID_UNICODE_1_1      = 1,
+    STBTT_UNICODE_EID_ISO_10646        = 2,
+    STBTT_UNICODE_EID_UNICODE_2_0_BMP  = 3,
+    STBTT_UNICODE_EID_UNICODE_2_0_FULL = 4
 };
 
 enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT
-   STBTT_MS_EID_SYMBOL        =0,
-   STBTT_MS_EID_UNICODE_BMP   =1,
-   STBTT_MS_EID_SHIFTJIS      =2,
-   STBTT_MS_EID_UNICODE_FULL  =10
+    STBTT_MS_EID_SYMBOL       = 0,
+    STBTT_MS_EID_UNICODE_BMP  = 1,
+    STBTT_MS_EID_SHIFTJIS     = 2,
+    STBTT_MS_EID_UNICODE_FULL = 10
 };
 
 enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
-   STBTT_MAC_EID_ROMAN        =0,   STBTT_MAC_EID_ARABIC       =4,
-   STBTT_MAC_EID_JAPANESE     =1,   STBTT_MAC_EID_HEBREW       =5,
-   STBTT_MAC_EID_CHINESE_TRAD =2,   STBTT_MAC_EID_GREEK        =6,
-   STBTT_MAC_EID_KOREAN       =3,   STBTT_MAC_EID_RUSSIAN      =7
+    STBTT_MAC_EID_ROMAN        = 0,
+    STBTT_MAC_EID_ARABIC       = 4,
+    STBTT_MAC_EID_JAPANESE     = 1,
+    STBTT_MAC_EID_HEBREW       = 5,
+    STBTT_MAC_EID_CHINESE_TRAD = 2,
+    STBTT_MAC_EID_GREEK        = 6,
+    STBTT_MAC_EID_KOREAN       = 3,
+    STBTT_MAC_EID_RUSSIAN      = 7
 };
 
 enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
        // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
-   STBTT_MS_LANG_ENGLISH     =0x0409,   STBTT_MS_LANG_ITALIAN     =0x0410,
-   STBTT_MS_LANG_CHINESE     =0x0804,   STBTT_MS_LANG_JAPANESE    =0x0411,
-   STBTT_MS_LANG_DUTCH       =0x0413,   STBTT_MS_LANG_KOREAN      =0x0412,
-   STBTT_MS_LANG_FRENCH      =0x040c,   STBTT_MS_LANG_RUSSIAN     =0x0419,
-   STBTT_MS_LANG_GERMAN      =0x0407,   STBTT_MS_LANG_SPANISH     =0x0409,
-   STBTT_MS_LANG_HEBREW      =0x040d,   STBTT_MS_LANG_SWEDISH     =0x041D
+    STBTT_MS_LANG_ENGLISH  = 0x0409,
+    STBTT_MS_LANG_ITALIAN  = 0x0410,
+    STBTT_MS_LANG_CHINESE  = 0x0804,
+    STBTT_MS_LANG_JAPANESE = 0x0411,
+    STBTT_MS_LANG_DUTCH    = 0x0413,
+    STBTT_MS_LANG_KOREAN   = 0x0412,
+    STBTT_MS_LANG_FRENCH   = 0x040c,
+    STBTT_MS_LANG_RUSSIAN  = 0x0419,
+    STBTT_MS_LANG_GERMAN   = 0x0407,
+    STBTT_MS_LANG_SPANISH  = 0x0409,
+    STBTT_MS_LANG_HEBREW   = 0x040d,
+    STBTT_MS_LANG_SWEDISH  = 0x041D
 };
 
 enum { // languageID for STBTT_PLATFORM_ID_MAC
-   STBTT_MAC_LANG_ENGLISH      =0 ,   STBTT_MAC_LANG_JAPANESE     =11,
-   STBTT_MAC_LANG_ARABIC       =12,   STBTT_MAC_LANG_KOREAN       =23,
-   STBTT_MAC_LANG_DUTCH        =4 ,   STBTT_MAC_LANG_RUSSIAN      =32,
-   STBTT_MAC_LANG_FRENCH       =1 ,   STBTT_MAC_LANG_SPANISH      =6 ,
-   STBTT_MAC_LANG_GERMAN       =2 ,   STBTT_MAC_LANG_SWEDISH      =5 ,
-   STBTT_MAC_LANG_HEBREW       =10,   STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33,
-   STBTT_MAC_LANG_ITALIAN      =3 ,   STBTT_MAC_LANG_CHINESE_TRAD =19
+    STBTT_MAC_LANG_ENGLISH            = 0,
+    STBTT_MAC_LANG_JAPANESE           = 11,
+    STBTT_MAC_LANG_ARABIC             = 12,
+    STBTT_MAC_LANG_KOREAN             = 23,
+    STBTT_MAC_LANG_DUTCH              = 4,
+    STBTT_MAC_LANG_RUSSIAN            = 32,
+    STBTT_MAC_LANG_FRENCH             = 1,
+    STBTT_MAC_LANG_SPANISH            = 6,
+    STBTT_MAC_LANG_GERMAN             = 2,
+    STBTT_MAC_LANG_SWEDISH            = 5,
+    STBTT_MAC_LANG_HEBREW             = 10,
+    STBTT_MAC_LANG_CHINESE_SIMPLIFIED = 33,
+    STBTT_MAC_LANG_ITALIAN            = 3,
+    STBTT_MAC_LANG_CHINESE_TRAD       = 19
 };
 
 #ifdef __cplusplus
@@ -1106,23 +1138,23 @@ enum { // languageID for STBTT_PLATFORM_ID_MAC
 #ifdef STB_TRUETYPE_IMPLEMENTATION
 
 #ifndef STBTT_MAX_OVERSAMPLE
-#define STBTT_MAX_OVERSAMPLE   8
+#define STBTT_MAX_OVERSAMPLE 8
 #endif
 
 #if STBTT_MAX_OVERSAMPLE > 255
 #error "STBTT_MAX_OVERSAMPLE cannot be > 255"
 #endif
 
-typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
+typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE - 1)) == 0 ? 1 : -1];
 
 #ifndef STBTT_RASTERIZER_VERSION
 #define STBTT_RASTERIZER_VERSION 2
 #endif
 
 #ifdef _MSC_VER
-#define STBTT__NOTUSED(v)  (void)(v)
+#define STBTT__NOTUSED(v) (void)(v)
 #else
-#define STBTT__NOTUSED(v)  (void)sizeof(v)
+#define STBTT__NOTUSED(v) (void)sizeof(v)
 #endif
 
 //////////////////////////////////////////////////////////////////////////
@@ -1130,145 +1162,138 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS
 // stbtt__buf helpers to parse data from file
 //
 
-static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b)
-{
-   if (b->cursor >= b->size)
-      return 0;
-   return b->data[b->cursor++];
+static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b) {
+    if (b->cursor >= b->size)
+        return 0;
+    return b->data[b->cursor++];
 }
 
-static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b)
-{
-   if (b->cursor >= b->size)
-      return 0;
-   return b->data[b->cursor];
+static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b) {
+    if (b->cursor >= b->size)
+        return 0;
+    return b->data[b->cursor];
 }
 
-static void stbtt__buf_seek(stbtt__buf *b, int o)
-{
-   STBTT_assert(!(o > b->size || o < 0));
-   b->cursor = (o > b->size || o < 0) ? b->size : o;
+static void stbtt__buf_seek(stbtt__buf *b, int o) {
+    STBTT_assert(!(o > b->size || o < 0));
+    b->cursor = (o > b->size || o < 0) ? b->size : o;
 }
 
-static void stbtt__buf_skip(stbtt__buf *b, int o)
-{
-   stbtt__buf_seek(b, b->cursor + o);
-}
+static void stbtt__buf_skip(stbtt__buf *b, int o) { stbtt__buf_seek(b, b->cursor + o); }
 
-static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n)
-{
-   stbtt_uint32 v = 0;
-   int i;
-   STBTT_assert(n >= 1 && n <= 4);
-   for (i = 0; i < n; i++)
-      v = (v << 8) | stbtt__buf_get8(b);
-   return v;
+static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n) {
+    stbtt_uint32 v = 0;
+    int          i;
+    STBTT_assert(n >= 1 && n <= 4);
+    for (i = 0; i < n; i++)
+        v = (v << 8) | stbtt__buf_get8(b);
+    return v;
 }
 
-static stbtt__buf stbtt__new_buf(const void *p, size_t size)
-{
-   stbtt__buf r;
-   STBTT_assert(size < 0x40000000);
-   r.data = (stbtt_uint8*) p;
-   r.size = (int) size;
-   r.cursor = 0;
-   return r;
+static stbtt__buf stbtt__new_buf(const void *p, size_t size) {
+    stbtt__buf r;
+    STBTT_assert(size < 0x40000000);
+    r.data   = (stbtt_uint8 *)p;
+    r.size   = (int)size;
+    r.cursor = 0;
+    return r;
 }
 
-#define stbtt__buf_get16(b)  stbtt__buf_get((b), 2)
-#define stbtt__buf_get32(b)  stbtt__buf_get((b), 4)
+#define stbtt__buf_get16(b) stbtt__buf_get((b), 2)
+#define stbtt__buf_get32(b) stbtt__buf_get((b), 4)
 
-static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s)
-{
-   stbtt__buf r = stbtt__new_buf(NULL, 0);
-   if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r;
-   r.data = b->data + o;
-   r.size = s;
-   return r;
+static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s) {
+    stbtt__buf r = stbtt__new_buf(NULL, 0);
+    if (o < 0 || s < 0 || o > b->size || s > b->size - o)
+        return r;
+    r.data = b->data + o;
+    r.size = s;
+    return r;
 }
 
-static stbtt__buf stbtt__cff_get_index(stbtt__buf *b)
-{
-   int count, start, offsize;
-   start = b->cursor;
-   count = stbtt__buf_get16(b);
-   if (count) {
-      offsize = stbtt__buf_get8(b);
-      STBTT_assert(offsize >= 1 && offsize <= 4);
-      stbtt__buf_skip(b, offsize * count);
-      stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
-   }
-   return stbtt__buf_range(b, start, b->cursor - start);
+static stbtt__buf stbtt__cff_get_index(stbtt__buf *b) {
+    int count, start, offsize;
+    start = b->cursor;
+    count = stbtt__buf_get16(b);
+    if (count) {
+        offsize = stbtt__buf_get8(b);
+        STBTT_assert(offsize >= 1 && offsize <= 4);
+        stbtt__buf_skip(b, offsize * count);
+        stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
+    }
+    return stbtt__buf_range(b, start, b->cursor - start);
 }
 
-static stbtt_uint32 stbtt__cff_int(stbtt__buf *b)
-{
-   int b0 = stbtt__buf_get8(b);
-   if (b0 >= 32 && b0 <= 246)       return b0 - 139;
-   else if (b0 >= 247 && b0 <= 250) return (b0 - 247)*256 + stbtt__buf_get8(b) + 108;
-   else if (b0 >= 251 && b0 <= 254) return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108;
-   else if (b0 == 28)               return stbtt__buf_get16(b);
-   else if (b0 == 29)               return stbtt__buf_get32(b);
-   STBTT_assert(0);
-   return 0;
+static stbtt_uint32 stbtt__cff_int(stbtt__buf *b) {
+    int b0 = stbtt__buf_get8(b);
+    if (b0 >= 32 && b0 <= 246)
+        return b0 - 139;
+    else if (b0 >= 247 && b0 <= 250)
+        return (b0 - 247) * 256 + stbtt__buf_get8(b) + 108;
+    else if (b0 >= 251 && b0 <= 254)
+        return -(b0 - 251) * 256 - stbtt__buf_get8(b) - 108;
+    else if (b0 == 28)
+        return stbtt__buf_get16(b);
+    else if (b0 == 29)
+        return stbtt__buf_get32(b);
+    STBTT_assert(0);
+    return 0;
 }
 
 static void stbtt__cff_skip_operand(stbtt__buf *b) {
-   int v, b0 = stbtt__buf_peek8(b);
-   STBTT_assert(b0 >= 28);
-   if (b0 == 30) {
-      stbtt__buf_skip(b, 1);
-      while (b->cursor < b->size) {
-         v = stbtt__buf_get8(b);
-         if ((v & 0xF) == 0xF || (v >> 4) == 0xF)
-            break;
-      }
-   } else {
-      stbtt__cff_int(b);
-   }
-}
-
-static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key)
-{
-   stbtt__buf_seek(b, 0);
-   while (b->cursor < b->size) {
-      int start = b->cursor, end, op;
-      while (stbtt__buf_peek8(b) >= 28)
-         stbtt__cff_skip_operand(b);
-      end = b->cursor;
-      op = stbtt__buf_get8(b);
-      if (op == 12)  op = stbtt__buf_get8(b) | 0x100;
-      if (op == key) return stbtt__buf_range(b, start, end-start);
-   }
-   return stbtt__buf_range(b, 0, 0);
-}
-
-static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out)
-{
-   int i;
-   stbtt__buf operands = stbtt__dict_get(b, key);
-   for (i = 0; i < outcount && operands.cursor < operands.size; i++)
-      out[i] = stbtt__cff_int(&operands);
-}
-
-static int stbtt__cff_index_count(stbtt__buf *b)
-{
-   stbtt__buf_seek(b, 0);
-   return stbtt__buf_get16(b);
-}
-
-static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i)
-{
-   int count, offsize, start, end;
-   stbtt__buf_seek(&b, 0);
-   count = stbtt__buf_get16(&b);
-   offsize = stbtt__buf_get8(&b);
-   STBTT_assert(i >= 0 && i < count);
-   STBTT_assert(offsize >= 1 && offsize <= 4);
-   stbtt__buf_skip(&b, i*offsize);
-   start = stbtt__buf_get(&b, offsize);
-   end = stbtt__buf_get(&b, offsize);
-   return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start);
+    int v, b0 = stbtt__buf_peek8(b);
+    STBTT_assert(b0 >= 28);
+    if (b0 == 30) {
+        stbtt__buf_skip(b, 1);
+        while (b->cursor < b->size) {
+            v = stbtt__buf_get8(b);
+            if ((v & 0xF) == 0xF || (v >> 4) == 0xF)
+                break;
+        }
+    } else {
+        stbtt__cff_int(b);
+    }
+}
+
+static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key) {
+    stbtt__buf_seek(b, 0);
+    while (b->cursor < b->size) {
+        int start = b->cursor, end, op;
+        while (stbtt__buf_peek8(b) >= 28)
+            stbtt__cff_skip_operand(b);
+        end = b->cursor;
+        op  = stbtt__buf_get8(b);
+        if (op == 12)
+            op = stbtt__buf_get8(b) | 0x100;
+        if (op == key)
+            return stbtt__buf_range(b, start, end - start);
+    }
+    return stbtt__buf_range(b, 0, 0);
+}
+
+static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out) {
+    int        i;
+    stbtt__buf operands = stbtt__dict_get(b, key);
+    for (i = 0; i < outcount && operands.cursor < operands.size; i++)
+        out[i] = stbtt__cff_int(&operands);
+}
+
+static int stbtt__cff_index_count(stbtt__buf *b) {
+    stbtt__buf_seek(b, 0);
+    return stbtt__buf_get16(b);
+}
+
+static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i) {
+    int count, offsize, start, end;
+    stbtt__buf_seek(&b, 0);
+    count   = stbtt__buf_get16(&b);
+    offsize = stbtt__buf_get8(&b);
+    STBTT_assert(i >= 0 && i < count);
+    STBTT_assert(offsize >= 1 && offsize <= 4);
+    stbtt__buf_skip(&b, i * offsize);
+    start = stbtt__buf_get(&b, offsize);
+    end   = stbtt__buf_get(&b, offsize);
+    return stbtt__buf_range(&b, 2 + (count + 1) * offsize + start, end - start);
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -1279,1438 +1304,1495 @@ static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i)
 // on platforms that don't allow misaligned reads, if we want to allow
 // truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE
 
-#define ttBYTE(p)     (* (stbtt_uint8 *) (p))
-#define ttCHAR(p)     (* (stbtt_int8 *) (p))
-#define ttFixed(p)    ttLONG(p)
-
-static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; }
-static stbtt_int16 ttSHORT(stbtt_uint8 *p)   { return p[0]*256 + p[1]; }
-static stbtt_uint32 ttULONG(stbtt_uint8 *p)  { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
-static stbtt_int32 ttLONG(stbtt_uint8 *p)    { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
-
-#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
-#define stbtt_tag(p,str)           stbtt_tag4(p,str[0],str[1],str[2],str[3])
-
-static int stbtt__isfont(stbtt_uint8 *font)
-{
-   // check the version number
-   if (stbtt_tag4(font, '1',0,0,0))  return 1; // TrueType 1
-   if (stbtt_tag(font, "typ1"))   return 1; // TrueType with type 1 font -- we don't support this!
-   if (stbtt_tag(font, "OTTO"))   return 1; // OpenType with CFF
-   if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0
-   if (stbtt_tag(font, "true"))   return 1; // Apple specification for TrueType fonts
-   return 0;
+#define ttBYTE(p)  (*(stbtt_uint8 *)(p))
+#define ttCHAR(p)  (*(stbtt_int8 *)(p))
+#define ttFixed(p) ttLONG(p)
+
+static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0] * 256 + p[1]; }
+static stbtt_int16  ttSHORT(stbtt_uint8 *p) { return p[0] * 256 + p[1]; }
+static stbtt_uint32 ttULONG(stbtt_uint8 *p) { return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; }
+static stbtt_int32  ttLONG(stbtt_uint8 *p) { return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; }
+
+#define stbtt_tag4(p, c0, c1, c2, c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
+#define stbtt_tag(p, str)             stbtt_tag4(p, str[0], str[1], str[2], str[3])
+
+static int stbtt__isfont(stbtt_uint8 *font) {
+    // check the version number
+    if (stbtt_tag4(font, '1', 0, 0, 0))
+        return 1; // TrueType 1
+    if (stbtt_tag(font, "typ1"))
+        return 1; // TrueType with type 1 font -- we don't support this!
+    if (stbtt_tag(font, "OTTO"))
+        return 1; // OpenType with CFF
+    if (stbtt_tag4(font, 0, 1, 0, 0))
+        return 1; // OpenType 1.0
+    if (stbtt_tag(font, "true"))
+        return 1; // Apple specification for TrueType fonts
+    return 0;
 }
 
 // @OPTIMIZE: binary search
-static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag)
-{
-   stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
-   stbtt_uint32 tabledir = fontstart + 12;
-   stbtt_int32 i;
-   for (i=0; i < num_tables; ++i) {
-      stbtt_uint32 loc = tabledir + 16*i;
-      if (stbtt_tag(data+loc+0, tag))
-         return ttULONG(data+loc+8);
-   }
-   return 0;
-}
-
-static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int index)
-{
-   // if it's just a font, there's only one valid index
-   if (stbtt__isfont(font_collection))
-      return index == 0 ? 0 : -1;
-
-   // check if it's a TTC
-   if (stbtt_tag(font_collection, "ttcf")) {
-      // version 1?
-      if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
-         stbtt_int32 n = ttLONG(font_collection+8);
-         if (index >= n)
-            return -1;
-         return ttULONG(font_collection+12+index*4);
-      }
-   }
-   return -1;
-}
-
-static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection)
-{
-   // if it's just a font, there's only one valid font
-   if (stbtt__isfont(font_collection))
-      return 1;
-
-   // check if it's a TTC
-   if (stbtt_tag(font_collection, "ttcf")) {
-      // version 1?
-      if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
-         return ttLONG(font_collection+8);
-      }
-   }
-   return 0;
-}
-
-static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
-{
-   stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 };
-   stbtt__buf pdict;
-   stbtt__dict_get_ints(&fontdict, 18, 2, private_loc);
-   if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0);
-   pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]);
-   stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff);
-   if (!subrsoff) return stbtt__new_buf(NULL, 0);
-   stbtt__buf_seek(&cff, private_loc[1]+subrsoff);
-   return stbtt__cff_get_index(&cff);
+static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) {
+    stbtt_int32  num_tables = ttUSHORT(data + fontstart + 4);
+    stbtt_uint32 tabledir   = fontstart + 12;
+    stbtt_int32  i;
+    for (i = 0; i < num_tables; ++i) {
+        stbtt_uint32 loc = tabledir + 16 * i;
+        if (stbtt_tag(data + loc + 0, tag))
+            return ttULONG(data + loc + 8);
+    }
+    return 0;
+}
+
+static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int index) {
+    // if it's just a font, there's only one valid index
+    if (stbtt__isfont(font_collection))
+        return index == 0 ? 0 : -1;
+
+    // check if it's a TTC
+    if (stbtt_tag(font_collection, "ttcf")) {
+        // version 1?
+        if (ttULONG(font_collection + 4) == 0x00010000 || ttULONG(font_collection + 4) == 0x00020000) {
+            stbtt_int32 n = ttLONG(font_collection + 8);
+            if (index >= n)
+                return -1;
+            return ttULONG(font_collection + 12 + index * 4);
+        }
+    }
+    return -1;
+}
+
+static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection) {
+    // if it's just a font, there's only one valid font
+    if (stbtt__isfont(font_collection))
+        return 1;
+
+    // check if it's a TTC
+    if (stbtt_tag(font_collection, "ttcf")) {
+        // version 1?
+        if (ttULONG(font_collection + 4) == 0x00010000 || ttULONG(font_collection + 4) == 0x00020000) {
+            return ttLONG(font_collection + 8);
+        }
+    }
+    return 0;
+}
+
+static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) {
+    stbtt_uint32 subrsoff = 0, private_loc[2] = {0, 0};
+    stbtt__buf   pdict;
+    stbtt__dict_get_ints(&fontdict, 18, 2, private_loc);
+    if (!private_loc[1] || !private_loc[0])
+        return stbtt__new_buf(NULL, 0);
+    pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]);
+    stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff);
+    if (!subrsoff)
+        return stbtt__new_buf(NULL, 0);
+    stbtt__buf_seek(&cff, private_loc[1] + subrsoff);
+    return stbtt__cff_get_index(&cff);
 }
 
 // since most people won't use this, find this table the first time it's needed
-static int stbtt__get_svg(stbtt_fontinfo *info)
-{
-   stbtt_uint32 t;
-   if (info->svg < 0) {
-      t = stbtt__find_table(info->data, info->fontstart, "SVG ");
-      if (t) {
-         stbtt_uint32 offset = ttULONG(info->data + t + 2);
-         info->svg = t + offset;
-      } else {
-         info->svg = 0;
-      }
-   }
-   return info->svg;
-}
-
-static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart)
-{
-   stbtt_uint32 cmap, t;
-   stbtt_int32 i,numTables;
-
-   info->data = data;
-   info->fontstart = fontstart;
-   info->cff = stbtt__new_buf(NULL, 0);
-
-   cmap = stbtt__find_table(data, fontstart, "cmap");       // required
-   info->loca = stbtt__find_table(data, fontstart, "loca"); // required
-   info->head = stbtt__find_table(data, fontstart, "head"); // required
-   info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required
-   info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
-   info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
-   info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
-   info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required
-
-   if (!cmap || !info->head || !info->hhea || !info->hmtx)
-      return 0;
-   if (info->glyf) {
-      // required for truetype
-      if (!info->loca) return 0;
-   } else {
-      // initialization for CFF / Type2 fonts (OTF)
-      stbtt__buf b, topdict, topdictidx;
-      stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
-      stbtt_uint32 cff;
-
-      cff = stbtt__find_table(data, fontstart, "CFF ");
-      if (!cff) return 0;
-
-      info->fontdicts = stbtt__new_buf(NULL, 0);
-      info->fdselect = stbtt__new_buf(NULL, 0);
-
-      // @TODO this should use size from table (not 512MB)
-      info->cff = stbtt__new_buf(data+cff, 512*1024*1024);
-      b = info->cff;
-
-      // read the header
-      stbtt__buf_skip(&b, 2);
-      stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize
-
-      // @TODO the name INDEX could list multiple fonts,
-      // but we just use the first one.
-      stbtt__cff_get_index(&b);  // name INDEX
-      topdictidx = stbtt__cff_get_index(&b);
-      topdict = stbtt__cff_index_get(topdictidx, 0);
-      stbtt__cff_get_index(&b);  // string INDEX
-      info->gsubrs = stbtt__cff_get_index(&b);
-
-      stbtt__dict_get_ints(&topdict, 17, 1, &charstrings);
-      stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype);
-      stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff);
-      stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff);
-      info->subrs = stbtt__get_subrs(b, topdict);
-
-      // we only support Type 2 charstrings
-      if (cstype != 2) return 0;
-      if (charstrings == 0) return 0;
-
-      if (fdarrayoff) {
-         // looks like a CID font
-         if (!fdselectoff) return 0;
-         stbtt__buf_seek(&b, fdarrayoff);
-         info->fontdicts = stbtt__cff_get_index(&b);
-         info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff);
-      }
+static int stbtt__get_svg(stbtt_fontinfo *info) {
+    stbtt_uint32 t;
+    if (info->svg < 0) {
+        t = stbtt__find_table(info->data, info->fontstart, "SVG ");
+        if (t) {
+            stbtt_uint32 offset = ttULONG(info->data + t + 2);
+            info->svg           = t + offset;
+        } else {
+            info->svg = 0;
+        }
+    }
+    return info->svg;
+}
+
+static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) {
+    stbtt_uint32 cmap, t;
+    stbtt_int32  i, numTables;
+
+    info->data      = data;
+    info->fontstart = fontstart;
+    info->cff       = stbtt__new_buf(NULL, 0);
+
+    cmap       = stbtt__find_table(data, fontstart, "cmap"); // required
+    info->loca = stbtt__find_table(data, fontstart, "loca"); // required
+    info->head = stbtt__find_table(data, fontstart, "head"); // required
+    info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required
+    info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
+    info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
+    info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
+    info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required
+
+    if (!cmap || !info->head || !info->hhea || !info->hmtx)
+        return 0;
+    if (info->glyf) {
+        // required for truetype
+        if (!info->loca)
+            return 0;
+    } else {
+        // initialization for CFF / Type2 fonts (OTF)
+        stbtt__buf   b, topdict, topdictidx;
+        stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
+        stbtt_uint32 cff;
+
+        cff = stbtt__find_table(data, fontstart, "CFF ");
+        if (!cff)
+            return 0;
 
-      stbtt__buf_seek(&b, charstrings);
-      info->charstrings = stbtt__cff_get_index(&b);
-   }
+        info->fontdicts = stbtt__new_buf(NULL, 0);
+        info->fdselect  = stbtt__new_buf(NULL, 0);
+
+        // @TODO this should use size from table (not 512MB)
+        info->cff = stbtt__new_buf(data + cff, 512 * 1024 * 1024);
+        b         = info->cff;
+
+        // read the header
+        stbtt__buf_skip(&b, 2);
+        stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize
+
+        // @TODO the name INDEX could list multiple fonts,
+        // but we just use the first one.
+        stbtt__cff_get_index(&b); // name INDEX
+        topdictidx = stbtt__cff_get_index(&b);
+        topdict    = stbtt__cff_index_get(topdictidx, 0);
+        stbtt__cff_get_index(&b); // string INDEX
+        info->gsubrs = stbtt__cff_get_index(&b);
+
+        stbtt__dict_get_ints(&topdict, 17, 1, &charstrings);
+        stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype);
+        stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff);
+        stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff);
+        info->subrs = stbtt__get_subrs(b, topdict);
+
+        // we only support Type 2 charstrings
+        if (cstype != 2)
+            return 0;
+        if (charstrings == 0)
+            return 0;
 
-   t = stbtt__find_table(data, fontstart, "maxp");
-   if (t)
-      info->numGlyphs = ttUSHORT(data+t+4);
-   else
-      info->numGlyphs = 0xffff;
-
-   info->svg = -1;
-
-   // find a cmap encoding table we understand *now* to avoid searching
-   // later. (todo: could make this installable)
-   // the same regardless of glyph.
-   numTables = ttUSHORT(data + cmap + 2);
-   info->index_map = 0;
-   for (i=0; i < numTables; ++i) {
-      stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
-      // find an encoding we understand:
-      switch(ttUSHORT(data+encoding_record)) {
-         case STBTT_PLATFORM_ID_MICROSOFT:
-            switch (ttUSHORT(data+encoding_record+2)) {
-               case STBTT_MS_EID_UNICODE_BMP:
-               case STBTT_MS_EID_UNICODE_FULL:
-                  // MS/Unicode
-                  info->index_map = cmap + ttULONG(data+encoding_record+4);
-                  break;
+        if (fdarrayoff) {
+            // looks like a CID font
+            if (!fdselectoff)
+                return 0;
+            stbtt__buf_seek(&b, fdarrayoff);
+            info->fontdicts = stbtt__cff_get_index(&b);
+            info->fdselect  = stbtt__buf_range(&b, fdselectoff, b.size - fdselectoff);
+        }
+
+        stbtt__buf_seek(&b, charstrings);
+        info->charstrings = stbtt__cff_get_index(&b);
+    }
+
+    t = stbtt__find_table(data, fontstart, "maxp");
+    if (t)
+        info->numGlyphs = ttUSHORT(data + t + 4);
+    else
+        info->numGlyphs = 0xffff;
+
+    info->svg = -1;
+
+    // find a cmap encoding table we understand *now* to avoid searching
+    // later. (todo: could make this installable)
+    // the same regardless of glyph.
+    numTables       = ttUSHORT(data + cmap + 2);
+    info->index_map = 0;
+    for (i = 0; i < numTables; ++i) {
+        stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
+        // find an encoding we understand:
+        switch (ttUSHORT(data + encoding_record)) {
+        case STBTT_PLATFORM_ID_MICROSOFT:
+            switch (ttUSHORT(data + encoding_record + 2)) {
+            case STBTT_MS_EID_UNICODE_BMP:
+            case STBTT_MS_EID_UNICODE_FULL:
+                // MS/Unicode
+                info->index_map = cmap + ttULONG(data + encoding_record + 4);
+                break;
             }
             break;
         case STBTT_PLATFORM_ID_UNICODE:
             // Mac/iOS has these
             // all the encodingIDs are unicode, so we don't bother to check it
-            info->index_map = cmap + ttULONG(data+encoding_record+4);
+            info->index_map = cmap + ttULONG(data + encoding_record + 4);
             break;
-      }
-   }
-   if (info->index_map == 0)
-      return 0;
-
-   info->indexToLocFormat = ttUSHORT(data+info->head + 50);
-   return 1;
-}
-
-STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
-{
-   stbtt_uint8 *data = info->data;
-   stbtt_uint32 index_map = info->index_map;
-
-   stbtt_uint16 format = ttUSHORT(data + index_map + 0);
-   if (format == 0) { // apple byte encoding
-      stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
-      if (unicode_codepoint < bytes-6)
-         return ttBYTE(data + index_map + 6 + unicode_codepoint);
-      return 0;
-   } else if (format == 6) {
-      stbtt_uint32 first = ttUSHORT(data + index_map + 6);
-      stbtt_uint32 count = ttUSHORT(data + index_map + 8);
-      if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
-         return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
-      return 0;
-   } else if (format == 2) {
-      STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
-      return 0;
-   } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
-      stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
-      stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
-      stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
-      stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
-
-      // do a binary search of the segments
-      stbtt_uint32 endCount = index_map + 14;
-      stbtt_uint32 search = endCount;
-
-      if (unicode_codepoint > 0xffff)
-         return 0;
-
-      // they lie from endCount .. endCount + segCount
-      // but searchRange is the nearest power of two, so...
-      if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
-         search += rangeShift*2;
-
-      // now decrement to bias correctly to find smallest
-      search -= 2;
-      while (entrySelector) {
-         stbtt_uint16 end;
-         searchRange >>= 1;
-         end = ttUSHORT(data + search + searchRange*2);
-         if (unicode_codepoint > end)
-            search += searchRange*2;
-         --entrySelector;
-      }
-      search += 2;
-
-      {
-         stbtt_uint16 offset, start, last;
-         stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
-
-         start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
-         last = ttUSHORT(data + endCount + 2*item);
-         if (unicode_codepoint < start || unicode_codepoint > last)
+        }
+    }
+    if (info->index_map == 0)
+        return 0;
+
+    info->indexToLocFormat = ttUSHORT(data + info->head + 50);
+    return 1;
+}
+
+STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) {
+    stbtt_uint8 *data      = info->data;
+    stbtt_uint32 index_map = info->index_map;
+
+    stbtt_uint16 format = ttUSHORT(data + index_map + 0);
+    if (format == 0) { // apple byte encoding
+        stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
+        if (unicode_codepoint < bytes - 6)
+            return ttBYTE(data + index_map + 6 + unicode_codepoint);
+        return 0;
+    } else if (format == 6) {
+        stbtt_uint32 first = ttUSHORT(data + index_map + 6);
+        stbtt_uint32 count = ttUSHORT(data + index_map + 8);
+        if ((stbtt_uint32)unicode_codepoint >= first && (stbtt_uint32)unicode_codepoint < first + count)
+            return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first) * 2);
+        return 0;
+    } else if (format == 2) {
+        STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
+        return 0;
+    } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
+        stbtt_uint16 segcount      = ttUSHORT(data + index_map + 6) >> 1;
+        stbtt_uint16 searchRange   = ttUSHORT(data + index_map + 8) >> 1;
+        stbtt_uint16 entrySelector = ttUSHORT(data + index_map + 10);
+        stbtt_uint16 rangeShift    = ttUSHORT(data + index_map + 12) >> 1;
+
+        // do a binary search of the segments
+        stbtt_uint32 endCount = index_map + 14;
+        stbtt_uint32 search   = endCount;
+
+        if (unicode_codepoint > 0xffff)
             return 0;
 
-         offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
-         if (offset == 0)
-            return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
-
-         return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
-      }
-   } else if (format == 12 || format == 13) {
-      stbtt_uint32 ngroups = ttULONG(data+index_map+12);
-      stbtt_int32 low,high;
-      low = 0; high = (stbtt_int32)ngroups;
-      // Binary search the right group.
-      while (low < high) {
-         stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
-         stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
-         stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
-         if ((stbtt_uint32) unicode_codepoint < start_char)
-            high = mid;
-         else if ((stbtt_uint32) unicode_codepoint > end_char)
-            low = mid+1;
-         else {
-            stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
-            if (format == 12)
-               return start_glyph + unicode_codepoint-start_char;
-            else // format == 13
-               return start_glyph;
-         }
-      }
-      return 0; // not found
-   }
-   // @TODO
-   STBTT_assert(0);
-   return 0;
+        // they lie from endCount .. endCount + segCount
+        // but searchRange is the nearest power of two, so...
+        if (unicode_codepoint >= ttUSHORT(data + search + rangeShift * 2))
+            search += rangeShift * 2;
+
+        // now decrement to bias correctly to find smallest
+        search -= 2;
+        while (entrySelector) {
+            stbtt_uint16 end;
+            searchRange >>= 1;
+            end = ttUSHORT(data + search + searchRange * 2);
+            if (unicode_codepoint > end)
+                search += searchRange * 2;
+            --entrySelector;
+        }
+        search += 2;
+
+        {
+            stbtt_uint16 offset, start, last;
+            stbtt_uint16 item = (stbtt_uint16)((search - endCount) >> 1);
+
+            start = ttUSHORT(data + index_map + 14 + segcount * 2 + 2 + 2 * item);
+            last  = ttUSHORT(data + endCount + 2 * item);
+            if (unicode_codepoint < start || unicode_codepoint > last)
+                return 0;
+
+            offset = ttUSHORT(data + index_map + 14 + segcount * 6 + 2 + 2 * item);
+            if (offset == 0)
+                return (stbtt_uint16)(unicode_codepoint + ttSHORT(data + index_map + 14 + segcount * 4 + 2 + 2 * item));
+
+            return ttUSHORT(data + offset + (unicode_codepoint - start) * 2 + index_map + 14 + segcount * 6 + 2 +
+                            2 * item);
+        }
+    } else if (format == 12 || format == 13) {
+        stbtt_uint32 ngroups = ttULONG(data + index_map + 12);
+        stbtt_int32  low, high;
+        low  = 0;
+        high = (stbtt_int32)ngroups;
+        // Binary search the right group.
+        while (low < high) {
+            stbtt_int32  mid        = low + ((high - low) >> 1); // rounds down, so low <= mid < high
+            stbtt_uint32 start_char = ttULONG(data + index_map + 16 + mid * 12);
+            stbtt_uint32 end_char   = ttULONG(data + index_map + 16 + mid * 12 + 4);
+            if ((stbtt_uint32)unicode_codepoint < start_char)
+                high = mid;
+            else if ((stbtt_uint32)unicode_codepoint > end_char)
+                low = mid + 1;
+            else {
+                stbtt_uint32 start_glyph = ttULONG(data + index_map + 16 + mid * 12 + 8);
+                if (format == 12)
+                    return start_glyph + unicode_codepoint - start_char;
+                else // format == 13
+                    return start_glyph;
+            }
+        }
+        return 0; // not found
+    }
+    // @TODO
+    STBTT_assert(0);
+    return 0;
 }
 
-STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices)
-{
-   return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
+STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) {
+    return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
 }
 
-static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy)
-{
-   v->type = type;
-   v->x = (stbtt_int16) x;
-   v->y = (stbtt_int16) y;
-   v->cx = (stbtt_int16) cx;
-   v->cy = (stbtt_int16) cy;
+static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx,
+                            stbtt_int32 cy) {
+    v->type = type;
+    v->x    = (stbtt_int16)x;
+    v->y    = (stbtt_int16)y;
+    v->cx   = (stbtt_int16)cx;
+    v->cy   = (stbtt_int16)cy;
 }
 
-static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index)
-{
-   int g1,g2;
+static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) {
+    int g1, g2;
 
-   STBTT_assert(!info->cff.size);
+    STBTT_assert(!info->cff.size);
 
-   if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range
-   if (info->indexToLocFormat >= 2)    return -1; // unknown index->glyph map format
+    if (glyph_index >= info->numGlyphs)
+        return -1; // glyph index out of range
+    if (info->indexToLocFormat >= 2)
+        return -1; // unknown index->glyph map format
 
-   if (info->indexToLocFormat == 0) {
-      g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
-      g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
-   } else {
-      g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4);
-      g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4);
-   }
+    if (info->indexToLocFormat == 0) {
+        g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
+        g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
+    } else {
+        g1 = info->glyf + ttULONG(info->data + info->loca + glyph_index * 4);
+        g2 = info->glyf + ttULONG(info->data + info->loca + glyph_index * 4 + 4);
+    }
 
-   return g1==g2 ? -1 : g1; // if length is 0, return -1
+    return g1 == g2 ? -1 : g1; // if length is 0, return -1
 }
 
 static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
 
-STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
-{
-   if (info->cff.size) {
-      stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1);
-   } else {
-      int g = stbtt__GetGlyfOffset(info, glyph_index);
-      if (g < 0) return 0;
-
-      if (x0) *x0 = ttSHORT(info->data + g + 2);
-      if (y0) *y0 = ttSHORT(info->data + g + 4);
-      if (x1) *x1 = ttSHORT(info->data + g + 6);
-      if (y1) *y1 = ttSHORT(info->data + g + 8);
-   }
-   return 1;
-}
-
-STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1)
-{
-   return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1);
-}
-
-STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index)
-{
-   stbtt_int16 numberOfContours;
-   int g;
-   if (info->cff.size)
-      return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0;
-   g = stbtt__GetGlyfOffset(info, glyph_index);
-   if (g < 0) return 1;
-   numberOfContours = ttSHORT(info->data + g);
-   return numberOfContours == 0;
-}
-
-static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off,
-    stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
-{
-   if (start_off) {
-      if (was_off)
-         stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
-      stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy);
-   } else {
-      if (was_off)
-         stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy);
-      else
-         stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0);
-   }
-   return num_vertices;
-}
-
-static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
-{
-   stbtt_int16 numberOfContours;
-   stbtt_uint8 *endPtsOfContours;
-   stbtt_uint8 *data = info->data;
-   stbtt_vertex *vertices=0;
-   int num_vertices=0;
-   int g = stbtt__GetGlyfOffset(info, glyph_index);
-
-   *pvertices = NULL;
-
-   if (g < 0) return 0;
-
-   numberOfContours = ttSHORT(data + g);
-
-   if (numberOfContours > 0) {
-      stbtt_uint8 flags=0,flagcount;
-      stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
-      stbtt_int32 x,y,cx,cy,sx,sy, scx,scy;
-      stbtt_uint8 *points;
-      endPtsOfContours = (data + g + 10);
-      ins = ttUSHORT(data + g + 10 + numberOfContours * 2);
-      points = data + g + 10 + numberOfContours * 2 + 2 + ins;
-
-      n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
-
-      m = n + 2*numberOfContours;  // a loose bound on how many vertices we might need
-      vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
-      if (vertices == 0)
-         return 0;
-
-      next_move = 0;
-      flagcount=0;
-
-      // in first pass, we load uninterpreted data into the allocated array
-      // above, shifted to the end of the array so we won't overwrite it when
-      // we create our final data starting from the front
-
-      off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated
-
-      // first load flags
-
-      for (i=0; i < n; ++i) {
-         if (flagcount == 0) {
-            flags = *points++;
-            if (flags & 8)
-               flagcount = *points++;
-         } else
-            --flagcount;
-         vertices[off+i].type = flags;
-      }
-
-      // now load x coordinates
-      x=0;
-      for (i=0; i < n; ++i) {
-         flags = vertices[off+i].type;
-         if (flags & 2) {
-            stbtt_int16 dx = *points++;
-            x += (flags & 16) ? dx : -dx; // ???
-         } else {
-            if (!(flags & 16)) {
-               x = x + (stbtt_int16) (points[0]*256 + points[1]);
-               points += 2;
-            }
-         }
-         vertices[off+i].x = (stbtt_int16) x;
-      }
+STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) {
+    if (info->cff.size) {
+        stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1);
+    } else {
+        int g = stbtt__GetGlyfOffset(info, glyph_index);
+        if (g < 0)
+            return 0;
 
-      // now load y coordinates
-      y=0;
-      for (i=0; i < n; ++i) {
-         flags = vertices[off+i].type;
-         if (flags & 4) {
-            stbtt_int16 dy = *points++;
-            y += (flags & 32) ? dy : -dy; // ???
-         } else {
-            if (!(flags & 32)) {
-               y = y + (stbtt_int16) (points[0]*256 + points[1]);
-               points += 2;
-            }
-         }
-         vertices[off+i].y = (stbtt_int16) y;
-      }
+        if (x0)
+            *x0 = ttSHORT(info->data + g + 2);
+        if (y0)
+            *y0 = ttSHORT(info->data + g + 4);
+        if (x1)
+            *x1 = ttSHORT(info->data + g + 6);
+        if (y1)
+            *y1 = ttSHORT(info->data + g + 8);
+    }
+    return 1;
+}
+
+STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) {
+    return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info, codepoint), x0, y0, x1, y1);
+}
+
+STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) {
+    stbtt_int16 numberOfContours;
+    int         g;
+    if (info->cff.size)
+        return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0;
+    g = stbtt__GetGlyfOffset(info, glyph_index);
+    if (g < 0)
+        return 1;
+    numberOfContours = ttSHORT(info->data + g);
+    return numberOfContours == 0;
+}
+
+static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off, stbtt_int32 sx,
+                              stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) {
+    if (start_off) {
+        if (was_off)
+            stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + scx) >> 1, (cy + scy) >> 1, cx, cy);
+        stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, scx, scy);
+    } else {
+        if (was_off)
+            stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, cx, cy);
+        else
+            stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, sx, sy, 0, 0);
+    }
+    return num_vertices;
+}
+
+static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) {
+    stbtt_int16   numberOfContours;
+    stbtt_uint8  *endPtsOfContours;
+    stbtt_uint8  *data         = info->data;
+    stbtt_vertex *vertices     = 0;
+    int           num_vertices = 0;
+    int           g            = stbtt__GetGlyfOffset(info, glyph_index);
+
+    *pvertices = NULL;
+
+    if (g < 0)
+        return 0;
+
+    numberOfContours = ttSHORT(data + g);
+
+    if (numberOfContours > 0) {
+        stbtt_uint8  flags = 0, flagcount;
+        stbtt_int32  ins, i, j = 0, m, n, next_move, was_off = 0, off, start_off = 0;
+        stbtt_int32  x, y, cx, cy, sx, sy, scx, scy;
+        stbtt_uint8 *points;
+        endPtsOfContours = (data + g + 10);
+        ins              = ttUSHORT(data + g + 10 + numberOfContours * 2);
+        points           = data + g + 10 + numberOfContours * 2 + 2 + ins;
+
+        n = 1 + ttUSHORT(endPtsOfContours + numberOfContours * 2 - 2);
+
+        m        = n + 2 * numberOfContours; // a loose bound on how many vertices we might need
+        vertices = (stbtt_vertex *)STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
+        if (vertices == 0)
+            return 0;
 
-      // now convert them to our format
-      num_vertices=0;
-      sx = sy = cx = cy = scx = scy = 0;
-      for (i=0; i < n; ++i) {
-         flags = vertices[off+i].type;
-         x     = (stbtt_int16) vertices[off+i].x;
-         y     = (stbtt_int16) vertices[off+i].y;
-
-         if (next_move == i) {
-            if (i != 0)
-               num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
-
-            // now start the new one
-            start_off = !(flags & 1);
-            if (start_off) {
-               // if we start off with an off-curve point, then when we need to find a point on the curve
-               // where we can start, and we need to save some state for when we wraparound.
-               scx = x;
-               scy = y;
-               if (!(vertices[off+i+1].type & 1)) {
-                  // next point is also a curve point, so interpolate an on-point curve
-                  sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
-                  sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
-               } else {
-                  // otherwise just use the next point as our start point
-                  sx = (stbtt_int32) vertices[off+i+1].x;
-                  sy = (stbtt_int32) vertices[off+i+1].y;
-                  ++i; // we're using point i+1 as the starting point, so skip it
-               }
+        next_move = 0;
+        flagcount = 0;
+
+        // in first pass, we load uninterpreted data into the allocated array
+        // above, shifted to the end of the array so we won't overwrite it when
+        // we create our final data starting from the front
+
+        off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated
+
+        // first load flags
+
+        for (i = 0; i < n; ++i) {
+            if (flagcount == 0) {
+                flags = *points++;
+                if (flags & 8)
+                    flagcount = *points++;
+            } else
+                --flagcount;
+            vertices[off + i].type = flags;
+        }
+
+        // now load x coordinates
+        x = 0;
+        for (i = 0; i < n; ++i) {
+            flags = vertices[off + i].type;
+            if (flags & 2) {
+                stbtt_int16 dx = *points++;
+                x += (flags & 16) ? dx : -dx; // ???
             } else {
-               sx = x;
-               sy = y;
+                if (!(flags & 16)) {
+                    x = x + (stbtt_int16)(points[0] * 256 + points[1]);
+                    points += 2;
+                }
             }
-            stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0);
-            was_off = 0;
-            next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
-            ++j;
-         } else {
-            if (!(flags & 1)) { // if it's a curve
-               if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint
-                  stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
-               cx = x;
-               cy = y;
-               was_off = 1;
+            vertices[off + i].x = (stbtt_int16)x;
+        }
+
+        // now load y coordinates
+        y = 0;
+        for (i = 0; i < n; ++i) {
+            flags = vertices[off + i].type;
+            if (flags & 4) {
+                stbtt_int16 dy = *points++;
+                y += (flags & 32) ? dy : -dy; // ???
             } else {
-               if (was_off)
-                  stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy);
-               else
-                  stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0);
-               was_off = 0;
+                if (!(flags & 32)) {
+                    y = y + (stbtt_int16)(points[0] * 256 + points[1]);
+                    points += 2;
+                }
             }
-         }
-      }
-      num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
-   } else if (numberOfContours < 0) {
-      // Compound shapes.
-      int more = 1;
-      stbtt_uint8 *comp = data + g + 10;
-      num_vertices = 0;
-      vertices = 0;
-      while (more) {
-         stbtt_uint16 flags, gidx;
-         int comp_num_verts = 0, i;
-         stbtt_vertex *comp_verts = 0, *tmp = 0;
-         float mtx[6] = {1,0,0,1,0,0}, m, n;
-
-         flags = ttSHORT(comp); comp+=2;
-         gidx = ttSHORT(comp); comp+=2;
-
-         if (flags & 2) { // XY values
-            if (flags & 1) { // shorts
-               mtx[4] = ttSHORT(comp); comp+=2;
-               mtx[5] = ttSHORT(comp); comp+=2;
+            vertices[off + i].y = (stbtt_int16)y;
+        }
+
+        // now convert them to our format
+        num_vertices = 0;
+        sx = sy = cx = cy = scx = scy = 0;
+        for (i = 0; i < n; ++i) {
+            flags = vertices[off + i].type;
+            x     = (stbtt_int16)vertices[off + i].x;
+            y     = (stbtt_int16)vertices[off + i].y;
+
+            if (next_move == i) {
+                if (i != 0)
+                    num_vertices =
+                        stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy);
+
+                // now start the new one
+                start_off = !(flags & 1);
+                if (start_off) {
+                    // if we start off with an off-curve point, then when we need to find a point on the curve
+                    // where we can start, and we need to save some state for when we wraparound.
+                    scx = x;
+                    scy = y;
+                    if (!(vertices[off + i + 1].type & 1)) {
+                        // next point is also a curve point, so interpolate an on-point curve
+                        sx = (x + (stbtt_int32)vertices[off + i + 1].x) >> 1;
+                        sy = (y + (stbtt_int32)vertices[off + i + 1].y) >> 1;
+                    } else {
+                        // otherwise just use the next point as our start point
+                        sx = (stbtt_int32)vertices[off + i + 1].x;
+                        sy = (stbtt_int32)vertices[off + i + 1].y;
+                        ++i; // we're using point i+1 as the starting point, so skip it
+                    }
+                } else {
+                    sx = x;
+                    sy = y;
+                }
+                stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove, sx, sy, 0, 0);
+                was_off   = 0;
+                next_move = 1 + ttUSHORT(endPtsOfContours + j * 2);
+                ++j;
             } else {
-               mtx[4] = ttCHAR(comp); comp+=1;
-               mtx[5] = ttCHAR(comp); comp+=1;
+                if (!(flags & 1)) { // if it's a curve
+                    if (was_off)    // two off-curve control points in a row means interpolate an on-curve midpoint
+                        stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + x) >> 1, (cy + y) >> 1, cx, cy);
+                    cx      = x;
+                    cy      = y;
+                    was_off = 1;
+                } else {
+                    if (was_off)
+                        stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x, y, cx, cy);
+                    else
+                        stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x, y, 0, 0);
+                    was_off = 0;
+                }
             }
-         }
-         else {
-            // @TODO handle matching point
-            STBTT_assert(0);
-         }
-         if (flags & (1<<3)) { // WE_HAVE_A_SCALE
-            mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
-            mtx[1] = mtx[2] = 0;
-         } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE
-            mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
-            mtx[1] = mtx[2] = 0;
-            mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
-         } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO
-            mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
-            mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
-            mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
-            mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
-         }
-
-         // Find transformation scales.
-         m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
-         n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
-
-         // Get indexed glyph.
-         comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
-         if (comp_num_verts > 0) {
-            // Transform vertices.
-            for (i = 0; i < comp_num_verts; ++i) {
-               stbtt_vertex* v = &comp_verts[i];
-               stbtt_vertex_type x,y;
-               x=v->x; y=v->y;
-               v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
-               v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
-               x=v->cx; y=v->cy;
-               v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
-               v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
+        }
+        num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy);
+    } else if (numberOfContours < 0) {
+        // Compound shapes.
+        int          more = 1;
+        stbtt_uint8 *comp = data + g + 10;
+        num_vertices      = 0;
+        vertices          = 0;
+        while (more) {
+            stbtt_uint16  flags, gidx;
+            int           comp_num_verts = 0, i;
+            stbtt_vertex *comp_verts = 0, *tmp = 0;
+            float         mtx[6] = {1, 0, 0, 1, 0, 0}, m, n;
+
+            flags = ttSHORT(comp);
+            comp += 2;
+            gidx = ttSHORT(comp);
+            comp += 2;
+
+            if (flags & 2) {     // XY values
+                if (flags & 1) { // shorts
+                    mtx[4] = ttSHORT(comp);
+                    comp += 2;
+                    mtx[5] = ttSHORT(comp);
+                    comp += 2;
+                } else {
+                    mtx[4] = ttCHAR(comp);
+                    comp += 1;
+                    mtx[5] = ttCHAR(comp);
+                    comp += 1;
+                }
+            } else {
+                // @TODO handle matching point
+                STBTT_assert(0);
             }
-            // Append vertices.
-            tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata);
-            if (!tmp) {
-               if (vertices) STBTT_free(vertices, info->userdata);
-               if (comp_verts) STBTT_free(comp_verts, info->userdata);
-               return 0;
+            if (flags & (1 << 3)) { // WE_HAVE_A_SCALE
+                mtx[0] = mtx[3] = ttSHORT(comp) / 16384.0f;
+                comp += 2;
+                mtx[1] = mtx[2] = 0;
+            } else if (flags & (1 << 6)) { // WE_HAVE_AN_X_AND_YSCALE
+                mtx[0] = ttSHORT(comp) / 16384.0f;
+                comp += 2;
+                mtx[1] = mtx[2] = 0;
+                mtx[3]          = ttSHORT(comp) / 16384.0f;
+                comp += 2;
+            } else if (flags & (1 << 7)) { // WE_HAVE_A_TWO_BY_TWO
+                mtx[0] = ttSHORT(comp) / 16384.0f;
+                comp += 2;
+                mtx[1] = ttSHORT(comp) / 16384.0f;
+                comp += 2;
+                mtx[2] = ttSHORT(comp) / 16384.0f;
+                comp += 2;
+                mtx[3] = ttSHORT(comp) / 16384.0f;
+                comp += 2;
             }
-            if (num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
-            STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
-            if (vertices) STBTT_free(vertices, info->userdata);
-            vertices = tmp;
-            STBTT_free(comp_verts, info->userdata);
-            num_vertices += comp_num_verts;
-         }
-         // More components ?
-         more = flags & (1<<5);
-      }
-   } else {
-      // numberOfCounters == 0, do nothing
-   }
 
-   *pvertices = vertices;
-   return num_vertices;
-}
-
-typedef struct
-{
-   int bounds;
-   int started;
-   float first_x, first_y;
-   float x, y;
-   stbtt_int32 min_x, max_x, min_y, max_y;
-
-   stbtt_vertex *pvertices;
-   int num_vertices;
+            // Find transformation scales.
+            m = (float)STBTT_sqrt(mtx[0] * mtx[0] + mtx[1] * mtx[1]);
+            n = (float)STBTT_sqrt(mtx[2] * mtx[2] + mtx[3] * mtx[3]);
+
+            // Get indexed glyph.
+            comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
+            if (comp_num_verts > 0) {
+                // Transform vertices.
+                for (i = 0; i < comp_num_verts; ++i) {
+                    stbtt_vertex     *v = &comp_verts[i];
+                    stbtt_vertex_type x, y;
+                    x     = v->x;
+                    y     = v->y;
+                    v->x  = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4]));
+                    v->y  = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5]));
+                    x     = v->cx;
+                    y     = v->cy;
+                    v->cx = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4]));
+                    v->cy = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5]));
+                }
+                // Append vertices.
+                tmp = (stbtt_vertex *)STBTT_malloc((num_vertices + comp_num_verts) * sizeof(stbtt_vertex),
+                                                   info->userdata);
+                if (!tmp) {
+                    if (vertices)
+                        STBTT_free(vertices, info->userdata);
+                    if (comp_verts)
+                        STBTT_free(comp_verts, info->userdata);
+                    return 0;
+                }
+                if (num_vertices > 0 && vertices)
+                    STBTT_memcpy(tmp, vertices, num_vertices * sizeof(stbtt_vertex));
+                STBTT_memcpy(tmp + num_vertices, comp_verts, comp_num_verts * sizeof(stbtt_vertex));
+                if (vertices)
+                    STBTT_free(vertices, info->userdata);
+                vertices = tmp;
+                STBTT_free(comp_verts, info->userdata);
+                num_vertices += comp_num_verts;
+            }
+            // More components ?
+            more = flags & (1 << 5);
+        }
+    } else {
+        // numberOfCounters == 0, do nothing
+    }
+
+    *pvertices = vertices;
+    return num_vertices;
+}
+
+typedef struct {
+    int         bounds;
+    int         started;
+    float       first_x, first_y;
+    float       x, y;
+    stbtt_int32 min_x, max_x, min_y, max_y;
+
+    stbtt_vertex *pvertices;
+    int           num_vertices;
 } stbtt__csctx;
 
-#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0}
-
-static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y)
-{
-   if (x > c->max_x || !c->started) c->max_x = x;
-   if (y > c->max_y || !c->started) c->max_y = y;
-   if (x < c->min_x || !c->started) c->min_x = x;
-   if (y < c->min_y || !c->started) c->min_y = y;
-   c->started = 1;
-}
-
-static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1)
-{
-   if (c->bounds) {
-      stbtt__track_vertex(c, x, y);
-      if (type == STBTT_vcubic) {
-         stbtt__track_vertex(c, cx, cy);
-         stbtt__track_vertex(c, cx1, cy1);
-      }
-   } else {
-      stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy);
-      c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1;
-      c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1;
-   }
-   c->num_vertices++;
-}
-
-static void stbtt__csctx_close_shape(stbtt__csctx *ctx)
-{
-   if (ctx->first_x != ctx->x || ctx->first_y != ctx->y)
-      stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0);
-}
-
-static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy)
-{
-   stbtt__csctx_close_shape(ctx);
-   ctx->first_x = ctx->x = ctx->x + dx;
-   ctx->first_y = ctx->y = ctx->y + dy;
-   stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
+#define STBTT__CSCTX_INIT(bounds)                                                                                      \
+    { bounds, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0 }
+
+static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y) {
+    if (x > c->max_x || !c->started)
+        c->max_x = x;
+    if (y > c->max_y || !c->started)
+        c->max_y = y;
+    if (x < c->min_x || !c->started)
+        c->min_x = x;
+    if (y < c->min_y || !c->started)
+        c->min_y = y;
+    c->started = 1;
+}
+
+static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx,
+                           stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) {
+    if (c->bounds) {
+        stbtt__track_vertex(c, x, y);
+        if (type == STBTT_vcubic) {
+            stbtt__track_vertex(c, cx, cy);
+            stbtt__track_vertex(c, cx1, cy1);
+        }
+    } else {
+        stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy);
+        c->pvertices[c->num_vertices].cx1 = (stbtt_int16)cx1;
+        c->pvertices[c->num_vertices].cy1 = (stbtt_int16)cy1;
+    }
+    c->num_vertices++;
+}
+
+static void stbtt__csctx_close_shape(stbtt__csctx *ctx) {
+    if (ctx->first_x != ctx->x || ctx->first_y != ctx->y)
+        stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0);
+}
+
+static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy) {
+    stbtt__csctx_close_shape(ctx);
+    ctx->first_x = ctx->x = ctx->x + dx;
+    ctx->first_y = ctx->y = ctx->y + dy;
+    stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
+}
+
+static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy) {
+    ctx->x += dx;
+    ctx->y += dy;
+    stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
+}
+
+static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3,
+                                    float dy3) {
+    float cx1 = ctx->x + dx1;
+    float cy1 = ctx->y + dy1;
+    float cx2 = cx1 + dx2;
+    float cy2 = cy1 + dy2;
+    ctx->x    = cx2 + dx3;
+    ctx->y    = cy2 + dy3;
+    stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2);
+}
+
+static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n) {
+    int count = stbtt__cff_index_count(&idx);
+    int bias  = 107;
+    if (count >= 33900)
+        bias = 32768;
+    else if (count >= 1240)
+        bias = 1131;
+    n += bias;
+    if (n < 0 || n >= count)
+        return stbtt__new_buf(NULL, 0);
+    return stbtt__cff_index_get(idx, n);
+}
+
+static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index) {
+    stbtt__buf fdselect = info->fdselect;
+    int        nranges, start, end, v, fmt, fdselector = -1, i;
+
+    stbtt__buf_seek(&fdselect, 0);
+    fmt = stbtt__buf_get8(&fdselect);
+    if (fmt == 0) {
+        // untested
+        stbtt__buf_skip(&fdselect, glyph_index);
+        fdselector = stbtt__buf_get8(&fdselect);
+    } else if (fmt == 3) {
+        nranges = stbtt__buf_get16(&fdselect);
+        start   = stbtt__buf_get16(&fdselect);
+        for (i = 0; i < nranges; i++) {
+            v   = stbtt__buf_get8(&fdselect);
+            end = stbtt__buf_get16(&fdselect);
+            if (glyph_index >= start && glyph_index < end) {
+                fdselector = v;
+                break;
+            }
+            start = end;
+        }
+    }
+    if (fdselector == -1)
+        stbtt__new_buf(NULL, 0);
+    return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
 }
 
-static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy)
-{
-   ctx->x += dx;
-   ctx->y += dy;
-   stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
-}
+static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c) {
+    int        in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
+    int        has_subrs = 0, clear_stack;
+    float      s[48];
+    stbtt__buf subr_stack[10], subrs = info->subrs, b;
+    float      f;
 
-static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3)
-{
-   float cx1 = ctx->x + dx1;
-   float cy1 = ctx->y + dy1;
-   float cx2 = cx1 + dx2;
-   float cy2 = cy1 + dy2;
-   ctx->x = cx2 + dx3;
-   ctx->y = cy2 + dy3;
-   stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2);
-}
+#define STBTT__CSERR(s) (0)
 
-static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n)
-{
-   int count = stbtt__cff_index_count(&idx);
-   int bias = 107;
-   if (count >= 33900)
-      bias = 32768;
-   else if (count >= 1240)
-      bias = 1131;
-   n += bias;
-   if (n < 0 || n >= count)
-      return stbtt__new_buf(NULL, 0);
-   return stbtt__cff_index_get(idx, n);
-}
-
-static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index)
-{
-   stbtt__buf fdselect = info->fdselect;
-   int nranges, start, end, v, fmt, fdselector = -1, i;
-
-   stbtt__buf_seek(&fdselect, 0);
-   fmt = stbtt__buf_get8(&fdselect);
-   if (fmt == 0) {
-      // untested
-      stbtt__buf_skip(&fdselect, glyph_index);
-      fdselector = stbtt__buf_get8(&fdselect);
-   } else if (fmt == 3) {
-      nranges = stbtt__buf_get16(&fdselect);
-      start = stbtt__buf_get16(&fdselect);
-      for (i = 0; i < nranges; i++) {
-         v = stbtt__buf_get8(&fdselect);
-         end = stbtt__buf_get16(&fdselect);
-         if (glyph_index >= start && glyph_index < end) {
-            fdselector = v;
+    // this currently ignores the initial width value, which isn't needed if we have hmtx
+    b = stbtt__cff_index_get(info->charstrings, glyph_index);
+    while (b.cursor < b.size) {
+        i           = 0;
+        clear_stack = 1;
+        b0          = stbtt__buf_get8(&b);
+        switch (b0) {
+        // @TODO implement hinting
+        case 0x13: // hintmask
+        case 0x14: // cntrmask
+            if (in_header)
+                maskbits += (sp / 2); // implicit "vstem"
+            in_header = 0;
+            stbtt__buf_skip(&b, (maskbits + 7) / 8);
             break;
-         }
-         start = end;
-      }
-   }
-   if (fdselector == -1) stbtt__new_buf(NULL, 0);
-   return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
-}
-
-static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c)
-{
-   int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
-   int has_subrs = 0, clear_stack;
-   float s[48];
-   stbtt__buf subr_stack[10], subrs = info->subrs, b;
-   float f;
-
-#define STBTT__CSERR(s) (0)
 
-   // this currently ignores the initial width value, which isn't needed if we have hmtx
-   b = stbtt__cff_index_get(info->charstrings, glyph_index);
-   while (b.cursor < b.size) {
-      i = 0;
-      clear_stack = 1;
-      b0 = stbtt__buf_get8(&b);
-      switch (b0) {
-      // @TODO implement hinting
-      case 0x13: // hintmask
-      case 0x14: // cntrmask
-         if (in_header)
-            maskbits += (sp / 2); // implicit "vstem"
-         in_header = 0;
-         stbtt__buf_skip(&b, (maskbits + 7) / 8);
-         break;
-
-      case 0x01: // hstem
-      case 0x03: // vstem
-      case 0x12: // hstemhm
-      case 0x17: // vstemhm
-         maskbits += (sp / 2);
-         break;
-
-      case 0x15: // rmoveto
-         in_header = 0;
-         if (sp < 2) return STBTT__CSERR("rmoveto stack");
-         stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]);
-         break;
-      case 0x04: // vmoveto
-         in_header = 0;
-         if (sp < 1) return STBTT__CSERR("vmoveto stack");
-         stbtt__csctx_rmove_to(c, 0, s[sp-1]);
-         break;
-      case 0x16: // hmoveto
-         in_header = 0;
-         if (sp < 1) return STBTT__CSERR("hmoveto stack");
-         stbtt__csctx_rmove_to(c, s[sp-1], 0);
-         break;
-
-      case 0x05: // rlineto
-         if (sp < 2) return STBTT__CSERR("rlineto stack");
-         for (; i + 1 < sp; i += 2)
-            stbtt__csctx_rline_to(c, s[i], s[i+1]);
-         break;
-
-      // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical
-      // starting from a different place.
-
-      case 0x07: // vlineto
-         if (sp < 1) return STBTT__CSERR("vlineto stack");
-         goto vlineto;
-      case 0x06: // hlineto
-         if (sp < 1) return STBTT__CSERR("hlineto stack");
-         for (;;) {
-            if (i >= sp) break;
-            stbtt__csctx_rline_to(c, s[i], 0);
-            i++;
-      vlineto:
-            if (i >= sp) break;
-            stbtt__csctx_rline_to(c, 0, s[i]);
-            i++;
-         }
-         break;
-
-      case 0x1F: // hvcurveto
-         if (sp < 4) return STBTT__CSERR("hvcurveto stack");
-         goto hvcurveto;
-      case 0x1E: // vhcurveto
-         if (sp < 4) return STBTT__CSERR("vhcurveto stack");
-         for (;;) {
-            if (i + 3 >= sp) break;
-            stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f);
-            i += 4;
-      hvcurveto:
-            if (i + 3 >= sp) break;
-            stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]);
-            i += 4;
-         }
-         break;
-
-      case 0x08: // rrcurveto
-         if (sp < 6) return STBTT__CSERR("rcurveline stack");
-         for (; i + 5 < sp; i += 6)
-            stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
-         break;
-
-      case 0x18: // rcurveline
-         if (sp < 8) return STBTT__CSERR("rcurveline stack");
-         for (; i + 5 < sp - 2; i += 6)
-            stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
-         if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack");
-         stbtt__csctx_rline_to(c, s[i], s[i+1]);
-         break;
-
-      case 0x19: // rlinecurve
-         if (sp < 8) return STBTT__CSERR("rlinecurve stack");
-         for (; i + 1 < sp - 6; i += 2)
-            stbtt__csctx_rline_to(c, s[i], s[i+1]);
-         if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack");
-         stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
-         break;
-
-      case 0x1A: // vvcurveto
-      case 0x1B: // hhcurveto
-         if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack");
-         f = 0.0;
-         if (sp & 1) { f = s[i]; i++; }
-         for (; i + 3 < sp; i += 4) {
-            if (b0 == 0x1B)
-               stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0);
-            else
-               stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]);
-            f = 0.0;
-         }
-         break;
-
-      case 0x0A: // callsubr
-         if (!has_subrs) {
-            if (info->fdselect.size)
-               subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
-            has_subrs = 1;
-         }
-         // FALLTHROUGH
-      case 0x1D: // callgsubr
-         if (sp < 1) return STBTT__CSERR("call(g|)subr stack");
-         v = (int) s[--sp];
-         if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit");
-         subr_stack[subr_stack_height++] = b;
-         b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v);
-         if (b.size == 0) return STBTT__CSERR("subr not found");
-         b.cursor = 0;
-         clear_stack = 0;
-         break;
-
-      case 0x0B: // return
-         if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr");
-         b = subr_stack[--subr_stack_height];
-         clear_stack = 0;
-         break;
-
-      case 0x0E: // endchar
-         stbtt__csctx_close_shape(c);
-         return 1;
-
-      case 0x0C: { // two-byte escape
-         float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
-         float dx, dy;
-         int b1 = stbtt__buf_get8(&b);
-         switch (b1) {
-         // @TODO These "flex" implementations ignore the flex-depth and resolution,
-         // and always draw beziers.
-         case 0x22: // hflex
-            if (sp < 7) return STBTT__CSERR("hflex stack");
-            dx1 = s[0];
-            dx2 = s[1];
-            dy2 = s[2];
-            dx3 = s[3];
-            dx4 = s[4];
-            dx5 = s[5];
-            dx6 = s[6];
-            stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
-            stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
+        case 0x01: // hstem
+        case 0x03: // vstem
+        case 0x12: // hstemhm
+        case 0x17: // vstemhm
+            maskbits += (sp / 2);
             break;
 
-         case 0x23: // flex
-            if (sp < 13) return STBTT__CSERR("flex stack");
-            dx1 = s[0];
-            dy1 = s[1];
-            dx2 = s[2];
-            dy2 = s[3];
-            dx3 = s[4];
-            dy3 = s[5];
-            dx4 = s[6];
-            dy4 = s[7];
-            dx5 = s[8];
-            dy5 = s[9];
-            dx6 = s[10];
-            dy6 = s[11];
-            //fd is s[12]
-            stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
-            stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
+        case 0x15: // rmoveto
+            in_header = 0;
+            if (sp < 2)
+                return STBTT__CSERR("rmoveto stack");
+            stbtt__csctx_rmove_to(c, s[sp - 2], s[sp - 1]);
+            break;
+        case 0x04: // vmoveto
+            in_header = 0;
+            if (sp < 1)
+                return STBTT__CSERR("vmoveto stack");
+            stbtt__csctx_rmove_to(c, 0, s[sp - 1]);
+            break;
+        case 0x16: // hmoveto
+            in_header = 0;
+            if (sp < 1)
+                return STBTT__CSERR("hmoveto stack");
+            stbtt__csctx_rmove_to(c, s[sp - 1], 0);
             break;
 
-         case 0x24: // hflex1
-            if (sp < 9) return STBTT__CSERR("hflex1 stack");
-            dx1 = s[0];
-            dy1 = s[1];
-            dx2 = s[2];
-            dy2 = s[3];
-            dx3 = s[4];
-            dx4 = s[5];
-            dx5 = s[6];
-            dy5 = s[7];
-            dx6 = s[8];
-            stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
-            stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5));
+        case 0x05: // rlineto
+            if (sp < 2)
+                return STBTT__CSERR("rlineto stack");
+            for (; i + 1 < sp; i += 2)
+                stbtt__csctx_rline_to(c, s[i], s[i + 1]);
             break;
 
-         case 0x25: // flex1
-            if (sp < 11) return STBTT__CSERR("flex1 stack");
-            dx1 = s[0];
-            dy1 = s[1];
-            dx2 = s[2];
-            dy2 = s[3];
-            dx3 = s[4];
-            dy3 = s[5];
-            dx4 = s[6];
-            dy4 = s[7];
-            dx5 = s[8];
-            dy5 = s[9];
-            dx6 = dy6 = s[10];
-            dx = dx1+dx2+dx3+dx4+dx5;
-            dy = dy1+dy2+dy3+dy4+dy5;
-            if (STBTT_fabs(dx) > STBTT_fabs(dy))
-               dy6 = -dy;
-            else
-               dx6 = -dx;
-            stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
-            stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
+            // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical
+            // starting from a different place.
+
+        case 0x07: // vlineto
+            if (sp < 1)
+                return STBTT__CSERR("vlineto stack");
+            goto vlineto;
+        case 0x06: // hlineto
+            if (sp < 1)
+                return STBTT__CSERR("hlineto stack");
+            for (;;) {
+                if (i >= sp)
+                    break;
+                stbtt__csctx_rline_to(c, s[i], 0);
+                i++;
+            vlineto:
+                if (i >= sp)
+                    break;
+                stbtt__csctx_rline_to(c, 0, s[i]);
+                i++;
+            }
             break;
 
-         default:
-            return STBTT__CSERR("unimplemented");
-         }
-      } break;
-
-      default:
-         if (b0 != 255 && b0 != 28 && b0 < 32)
-            return STBTT__CSERR("reserved operator");
-
-         // push immediate
-         if (b0 == 255) {
-            f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
-         } else {
-            stbtt__buf_skip(&b, -1);
-            f = (float)(stbtt_int16)stbtt__cff_int(&b);
-         }
-         if (sp >= 48) return STBTT__CSERR("push stack overflow");
-         s[sp++] = f;
-         clear_stack = 0;
-         break;
-      }
-      if (clear_stack) sp = 0;
-   }
-   return STBTT__CSERR("no endchar");
+        case 0x1F: // hvcurveto
+            if (sp < 4)
+                return STBTT__CSERR("hvcurveto stack");
+            goto hvcurveto;
+        case 0x1E: // vhcurveto
+            if (sp < 4)
+                return STBTT__CSERR("vhcurveto stack");
+            for (;;) {
+                if (i + 3 >= sp)
+                    break;
+                stbtt__csctx_rccurve_to(c, 0, s[i], s[i + 1], s[i + 2], s[i + 3], (sp - i == 5) ? s[i + 4] : 0.0f);
+                i += 4;
+            hvcurveto:
+                if (i + 3 >= sp)
+                    break;
+                stbtt__csctx_rccurve_to(c, s[i], 0, s[i + 1], s[i + 2], (sp - i == 5) ? s[i + 4] : 0.0f, s[i + 3]);
+                i += 4;
+            }
+            break;
 
-#undef STBTT__CSERR
-}
+        case 0x08: // rrcurveto
+            if (sp < 6)
+                return STBTT__CSERR("rcurveline stack");
+            for (; i + 5 < sp; i += 6)
+                stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]);
+            break;
 
-static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
-{
-   // runs the charstring twice, once to count and once to output (to avoid realloc)
-   stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1);
-   stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0);
-   if (stbtt__run_charstring(info, glyph_index, &count_ctx)) {
-      *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*sizeof(stbtt_vertex), info->userdata);
-      output_ctx.pvertices = *pvertices;
-      if (stbtt__run_charstring(info, glyph_index, &output_ctx)) {
-         STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices);
-         return output_ctx.num_vertices;
-      }
-   }
-   *pvertices = NULL;
-   return 0;
-}
+        case 0x18: // rcurveline
+            if (sp < 8)
+                return STBTT__CSERR("rcurveline stack");
+            for (; i + 5 < sp - 2; i += 6)
+                stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]);
+            if (i + 1 >= sp)
+                return STBTT__CSERR("rcurveline stack");
+            stbtt__csctx_rline_to(c, s[i], s[i + 1]);
+            break;
 
-static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
-{
-   stbtt__csctx c = STBTT__CSCTX_INIT(1);
-   int r = stbtt__run_charstring(info, glyph_index, &c);
-   if (x0)  *x0 = r ? c.min_x : 0;
-   if (y0)  *y0 = r ? c.min_y : 0;
-   if (x1)  *x1 = r ? c.max_x : 0;
-   if (y1)  *y1 = r ? c.max_y : 0;
-   return r ? c.num_vertices : 0;
-}
+        case 0x19: // rlinecurve
+            if (sp < 8)
+                return STBTT__CSERR("rlinecurve stack");
+            for (; i + 1 < sp - 6; i += 2)
+                stbtt__csctx_rline_to(c, s[i], s[i + 1]);
+            if (i + 5 >= sp)
+                return STBTT__CSERR("rlinecurve stack");
+            stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]);
+            break;
 
-STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
-{
-   if (!info->cff.size)
-      return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices);
-   else
-      return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices);
-}
+        case 0x1A: // vvcurveto
+        case 0x1B: // hhcurveto
+            if (sp < 4)
+                return STBTT__CSERR("(vv|hh)curveto stack");
+            f = 0.0;
+            if (sp & 1) {
+                f = s[i];
+                i++;
+            }
+            for (; i + 3 < sp; i += 4) {
+                if (b0 == 0x1B)
+                    stbtt__csctx_rccurve_to(c, s[i], f, s[i + 1], s[i + 2], s[i + 3], 0.0);
+                else
+                    stbtt__csctx_rccurve_to(c, f, s[i], s[i + 1], s[i + 2], 0.0, s[i + 3]);
+                f = 0.0;
+            }
+            break;
 
-STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing)
-{
-   stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34);
-   if (glyph_index < numOfLongHorMetrics) {
-      if (advanceWidth)     *advanceWidth    = ttSHORT(info->data + info->hmtx + 4*glyph_index);
-      if (leftSideBearing)  *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
-   } else {
-      if (advanceWidth)     *advanceWidth    = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
-      if (leftSideBearing)  *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
-   }
-}
+        case 0x0A: // callsubr
+            if (!has_subrs) {
+                if (info->fdselect.size)
+                    subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
+                has_subrs = 1;
+            }
+            // FALLTHROUGH
+        case 0x1D: // callgsubr
+            if (sp < 1)
+                return STBTT__CSERR("call(g|)subr stack");
+            v = (int)s[--sp];
+            if (subr_stack_height >= 10)
+                return STBTT__CSERR("recursion limit");
+            subr_stack[subr_stack_height++] = b;
+            b                               = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v);
+            if (b.size == 0)
+                return STBTT__CSERR("subr not found");
+            b.cursor    = 0;
+            clear_stack = 0;
+            break;
 
-STBTT_DEF int  stbtt_GetKerningTableLength(const stbtt_fontinfo *info)
-{
-   stbtt_uint8 *data = info->data + info->kern;
+        case 0x0B: // return
+            if (subr_stack_height <= 0)
+                return STBTT__CSERR("return outside subr");
+            b           = subr_stack[--subr_stack_height];
+            clear_stack = 0;
+            break;
 
-   // we only look at the first table. it must be 'horizontal' and format 0.
-   if (!info->kern)
-      return 0;
-   if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
-      return 0;
-   if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
-      return 0;
+        case 0x0E: // endchar
+            stbtt__csctx_close_shape(c);
+            return 1;
+
+        case 0x0C: { // two-byte escape
+            float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
+            float dx, dy;
+            int   b1 = stbtt__buf_get8(&b);
+            switch (b1) {
+            // @TODO These "flex" implementations ignore the flex-depth and resolution,
+            // and always draw beziers.
+            case 0x22: // hflex
+                if (sp < 7)
+                    return STBTT__CSERR("hflex stack");
+                dx1 = s[0];
+                dx2 = s[1];
+                dy2 = s[2];
+                dx3 = s[3];
+                dx4 = s[4];
+                dx5 = s[5];
+                dx6 = s[6];
+                stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
+                stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
+                break;
+
+            case 0x23: // flex
+                if (sp < 13)
+                    return STBTT__CSERR("flex stack");
+                dx1 = s[0];
+                dy1 = s[1];
+                dx2 = s[2];
+                dy2 = s[3];
+                dx3 = s[4];
+                dy3 = s[5];
+                dx4 = s[6];
+                dy4 = s[7];
+                dx5 = s[8];
+                dy5 = s[9];
+                dx6 = s[10];
+                dy6 = s[11];
+                // fd is s[12]
+                stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
+                stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
+                break;
+
+            case 0x24: // hflex1
+                if (sp < 9)
+                    return STBTT__CSERR("hflex1 stack");
+                dx1 = s[0];
+                dy1 = s[1];
+                dx2 = s[2];
+                dy2 = s[3];
+                dx3 = s[4];
+                dx4 = s[5];
+                dx5 = s[6];
+                dy5 = s[7];
+                dx6 = s[8];
+                stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
+                stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1 + dy2 + dy5));
+                break;
+
+            case 0x25: // flex1
+                if (sp < 11)
+                    return STBTT__CSERR("flex1 stack");
+                dx1 = s[0];
+                dy1 = s[1];
+                dx2 = s[2];
+                dy2 = s[3];
+                dx3 = s[4];
+                dy3 = s[5];
+                dx4 = s[6];
+                dy4 = s[7];
+                dx5 = s[8];
+                dy5 = s[9];
+                dx6 = dy6 = s[10];
+                dx        = dx1 + dx2 + dx3 + dx4 + dx5;
+                dy        = dy1 + dy2 + dy3 + dy4 + dy5;
+                if (STBTT_fabs(dx) > STBTT_fabs(dy))
+                    dy6 = -dy;
+                else
+                    dx6 = -dx;
+                stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
+                stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
+                break;
 
-   return ttUSHORT(data+10);
-}
+            default:
+                return STBTT__CSERR("unimplemented");
+            }
+        } break;
 
-STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length)
-{
-   stbtt_uint8 *data = info->data + info->kern;
-   int k, length;
-
-   // we only look at the first table. it must be 'horizontal' and format 0.
-   if (!info->kern)
-      return 0;
-   if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
-      return 0;
-   if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
-      return 0;
-
-   length = ttUSHORT(data+10);
-   if (table_length < length)
-      length = table_length;
-
-   for (k = 0; k < length; k++)
-   {
-      table[k].glyph1 = ttUSHORT(data+18+(k*6));
-      table[k].glyph2 = ttUSHORT(data+20+(k*6));
-      table[k].advance = ttSHORT(data+22+(k*6));
-   }
+        default:
+            if (b0 != 255 && b0 != 28 && b0 < 32)
+                return STBTT__CSERR("reserved operator");
 
-   return length;
-}
+            // push immediate
+            if (b0 == 255) {
+                f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
+            } else {
+                stbtt__buf_skip(&b, -1);
+                f = (float)(stbtt_int16)stbtt__cff_int(&b);
+            }
+            if (sp >= 48)
+                return STBTT__CSERR("push stack overflow");
+            s[sp++]     = f;
+            clear_stack = 0;
+            break;
+        }
+        if (clear_stack)
+            sp = 0;
+    }
+    return STBTT__CSERR("no endchar");
 
-static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
-{
-   stbtt_uint8 *data = info->data + info->kern;
-   stbtt_uint32 needle, straw;
-   int l, r, m;
-
-   // we only look at the first table. it must be 'horizontal' and format 0.
-   if (!info->kern)
-      return 0;
-   if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
-      return 0;
-   if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
-      return 0;
-
-   l = 0;
-   r = ttUSHORT(data+10) - 1;
-   needle = glyph1 << 16 | glyph2;
-   while (l <= r) {
-      m = (l + r) >> 1;
-      straw = ttULONG(data+18+(m*6)); // note: unaligned read
-      if (needle < straw)
-         r = m - 1;
-      else if (needle > straw)
-         l = m + 1;
-      else
-         return ttSHORT(data+22+(m*6));
-   }
-   return 0;
+#undef STBTT__CSERR
 }
 
-static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph)
-{
-   stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
-   switch (coverageFormat) {
-      case 1: {
-         stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
-
-         // Binary search.
-         stbtt_int32 l=0, r=glyphCount-1, m;
-         int straw, needle=glyph;
-         while (l <= r) {
+static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) {
+    // runs the charstring twice, once to count and once to output (to avoid realloc)
+    stbtt__csctx count_ctx  = STBTT__CSCTX_INIT(1);
+    stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0);
+    if (stbtt__run_charstring(info, glyph_index, &count_ctx)) {
+        *pvertices = (stbtt_vertex *)STBTT_malloc(count_ctx.num_vertices * sizeof(stbtt_vertex), info->userdata);
+        output_ctx.pvertices = *pvertices;
+        if (stbtt__run_charstring(info, glyph_index, &output_ctx)) {
+            STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices);
+            return output_ctx.num_vertices;
+        }
+    }
+    *pvertices = NULL;
+    return 0;
+}
+
+static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) {
+    stbtt__csctx c = STBTT__CSCTX_INIT(1);
+    int          r = stbtt__run_charstring(info, glyph_index, &c);
+    if (x0)
+        *x0 = r ? c.min_x : 0;
+    if (y0)
+        *y0 = r ? c.min_y : 0;
+    if (x1)
+        *x1 = r ? c.max_x : 0;
+    if (y1)
+        *y1 = r ? c.max_y : 0;
+    return r ? c.num_vertices : 0;
+}
+
+STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) {
+    if (!info->cff.size)
+        return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices);
+    else
+        return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices);
+}
+
+STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth,
+                                      int *leftSideBearing) {
+    stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data + info->hhea + 34);
+    if (glyph_index < numOfLongHorMetrics) {
+        if (advanceWidth)
+            *advanceWidth = ttSHORT(info->data + info->hmtx + 4 * glyph_index);
+        if (leftSideBearing)
+            *leftSideBearing = ttSHORT(info->data + info->hmtx + 4 * glyph_index + 2);
+    } else {
+        if (advanceWidth)
+            *advanceWidth = ttSHORT(info->data + info->hmtx + 4 * (numOfLongHorMetrics - 1));
+        if (leftSideBearing)
+            *leftSideBearing =
+                ttSHORT(info->data + info->hmtx + 4 * numOfLongHorMetrics + 2 * (glyph_index - numOfLongHorMetrics));
+    }
+}
+
+STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info) {
+    stbtt_uint8 *data = info->data + info->kern;
+
+    // we only look at the first table. it must be 'horizontal' and format 0.
+    if (!info->kern)
+        return 0;
+    if (ttUSHORT(data + 2) < 1) // number of tables, need at least 1
+        return 0;
+    if (ttUSHORT(data + 8) != 1) // horizontal flag must be set in format
+        return 0;
+
+    return ttUSHORT(data + 10);
+}
+
+STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry *table, int table_length) {
+    stbtt_uint8 *data = info->data + info->kern;
+    int          k, length;
+
+    // we only look at the first table. it must be 'horizontal' and format 0.
+    if (!info->kern)
+        return 0;
+    if (ttUSHORT(data + 2) < 1) // number of tables, need at least 1
+        return 0;
+    if (ttUSHORT(data + 8) != 1) // horizontal flag must be set in format
+        return 0;
+
+    length = ttUSHORT(data + 10);
+    if (table_length < length)
+        length = table_length;
+
+    for (k = 0; k < length; k++) {
+        table[k].glyph1  = ttUSHORT(data + 18 + (k * 6));
+        table[k].glyph2  = ttUSHORT(data + 20 + (k * 6));
+        table[k].advance = ttSHORT(data + 22 + (k * 6));
+    }
+
+    return length;
+}
+
+static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) {
+    stbtt_uint8 *data = info->data + info->kern;
+    stbtt_uint32 needle, straw;
+    int          l, r, m;
+
+    // we only look at the first table. it must be 'horizontal' and format 0.
+    if (!info->kern)
+        return 0;
+    if (ttUSHORT(data + 2) < 1) // number of tables, need at least 1
+        return 0;
+    if (ttUSHORT(data + 8) != 1) // horizontal flag must be set in format
+        return 0;
+
+    l      = 0;
+    r      = ttUSHORT(data + 10) - 1;
+    needle = glyph1 << 16 | glyph2;
+    while (l <= r) {
+        m     = (l + r) >> 1;
+        straw = ttULONG(data + 18 + (m * 6)); // note: unaligned read
+        if (needle < straw)
+            r = m - 1;
+        else if (needle > straw)
+            l = m + 1;
+        else
+            return ttSHORT(data + 22 + (m * 6));
+    }
+    return 0;
+}
+
+static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) {
+    stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
+    switch (coverageFormat) {
+    case 1: {
+        stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
+
+        // Binary search.
+        stbtt_int32 l = 0, r      = glyphCount - 1, m;
+        int         straw, needle = glyph;
+        while (l <= r) {
             stbtt_uint8 *glyphArray = coverageTable + 4;
             stbtt_uint16 glyphID;
-            m = (l + r) >> 1;
+            m       = (l + r) >> 1;
             glyphID = ttUSHORT(glyphArray + 2 * m);
-            straw = glyphID;
+            straw   = glyphID;
             if (needle < straw)
-               r = m - 1;
+                r = m - 1;
             else if (needle > straw)
-               l = m + 1;
+                l = m + 1;
             else {
-               return m;
+                return m;
             }
-         }
-         break;
-      }
-
-      case 2: {
-         stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
-         stbtt_uint8 *rangeArray = coverageTable + 4;
-
-         // Binary search.
-         stbtt_int32 l=0, r=rangeCount-1, m;
-         int strawStart, strawEnd, needle=glyph;
-         while (l <= r) {
+        }
+        break;
+    }
+
+    case 2: {
+        stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
+        stbtt_uint8 *rangeArray = coverageTable + 4;
+
+        // Binary search.
+        stbtt_int32 l = 0, r = rangeCount - 1, m;
+        int         strawStart, strawEnd, needle = glyph;
+        while (l <= r) {
             stbtt_uint8 *rangeRecord;
-            m = (l + r) >> 1;
+            m           = (l + r) >> 1;
             rangeRecord = rangeArray + 6 * m;
-            strawStart = ttUSHORT(rangeRecord);
-            strawEnd = ttUSHORT(rangeRecord + 2);
+            strawStart  = ttUSHORT(rangeRecord);
+            strawEnd    = ttUSHORT(rangeRecord + 2);
             if (needle < strawStart)
-               r = m - 1;
+                r = m - 1;
             else if (needle > strawEnd)
-               l = m + 1;
+                l = m + 1;
             else {
-               stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
-               return startCoverageIndex + glyph - strawStart;
+                stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
+                return startCoverageIndex + glyph - strawStart;
             }
-         }
-         break;
-      }
+        }
+        break;
+    }
 
-      default: return -1; // unsupported
-   }
+    default:
+        return -1; // unsupported
+    }
 
-   return -1;
+    return -1;
 }
 
-static stbtt_int32  stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
-{
-   stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
-   switch (classDefFormat)
-   {
-      case 1: {
-         stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
-         stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
-         stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
-
-         if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
+static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) {
+    stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
+    switch (classDefFormat) {
+    case 1: {
+        stbtt_uint16 startGlyphID        = ttUSHORT(classDefTable + 2);
+        stbtt_uint16 glyphCount          = ttUSHORT(classDefTable + 4);
+        stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
+
+        if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
             return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
-         break;
-      }
+        break;
+    }
 
-      case 2: {
-         stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
-         stbtt_uint8 *classRangeRecords = classDefTable + 4;
+    case 2: {
+        stbtt_uint16 classRangeCount   = ttUSHORT(classDefTable + 2);
+        stbtt_uint8 *classRangeRecords = classDefTable + 4;
 
-         // Binary search.
-         stbtt_int32 l=0, r=classRangeCount-1, m;
-         int strawStart, strawEnd, needle=glyph;
-         while (l <= r) {
+        // Binary search.
+        stbtt_int32 l = 0, r = classRangeCount - 1, m;
+        int         strawStart, strawEnd, needle = glyph;
+        while (l <= r) {
             stbtt_uint8 *classRangeRecord;
-            m = (l + r) >> 1;
+            m                = (l + r) >> 1;
             classRangeRecord = classRangeRecords + 6 * m;
-            strawStart = ttUSHORT(classRangeRecord);
-            strawEnd = ttUSHORT(classRangeRecord + 2);
+            strawStart       = ttUSHORT(classRangeRecord);
+            strawEnd         = ttUSHORT(classRangeRecord + 2);
             if (needle < strawStart)
-               r = m - 1;
+                r = m - 1;
             else if (needle > strawEnd)
-               l = m + 1;
+                l = m + 1;
             else
-               return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
-         }
-         break;
-      }
+                return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
+        }
+        break;
+    }
 
-      default:
-         return -1; // Unsupported definition type, return an error.
-   }
+    default:
+        return -1; // Unsupported definition type, return an error.
+    }
 
-   // "All glyphs not assigned to a class fall into class 0". (OpenType spec)
-   return 0;
+    // "All glyphs not assigned to a class fall into class 0". (OpenType spec)
+    return 0;
 }
 
 // Define to STBTT_assert(x) if you want to break on unimplemented formats.
 #define STBTT_GPOS_TODO_assert(x)
 
-static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
-{
-   stbtt_uint16 lookupListOffset;
-   stbtt_uint8 *lookupList;
-   stbtt_uint16 lookupCount;
-   stbtt_uint8 *data;
-   stbtt_int32 i, sti;
-
-   if (!info->gpos) return 0;
-
-   data = info->data + info->gpos;
-
-   if (ttUSHORT(data+0) != 1) return 0; // Major version 1
-   if (ttUSHORT(data+2) != 0) return 0; // Minor version 0
-
-   lookupListOffset = ttUSHORT(data+8);
-   lookupList = data + lookupListOffset;
-   lookupCount = ttUSHORT(lookupList);
-
-   for (i=0; i<lookupCount; ++i) {
-      stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
-      stbtt_uint8 *lookupTable = lookupList + lookupOffset;
-
-      stbtt_uint16 lookupType = ttUSHORT(lookupTable);
-      stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
-      stbtt_uint8 *subTableOffsets = lookupTable + 6;
-      if (lookupType != 2) // Pair Adjustment Positioning Subtable
-         continue;
-
-      for (sti=0; sti<subTableCount; sti++) {
-         stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
-         stbtt_uint8 *table = lookupTable + subtableOffset;
-         stbtt_uint16 posFormat = ttUSHORT(table);
-         stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
-         stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
-         if (coverageIndex == -1) continue;
-
-         switch (posFormat) {
+static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) {
+    stbtt_uint16 lookupListOffset;
+    stbtt_uint8 *lookupList;
+    stbtt_uint16 lookupCount;
+    stbtt_uint8 *data;
+    stbtt_int32  i, sti;
+
+    if (!info->gpos)
+        return 0;
+
+    data = info->data + info->gpos;
+
+    if (ttUSHORT(data + 0) != 1)
+        return 0; // Major version 1
+    if (ttUSHORT(data + 2) != 0)
+        return 0; // Minor version 0
+
+    lookupListOffset = ttUSHORT(data + 8);
+    lookupList       = data + lookupListOffset;
+    lookupCount      = ttUSHORT(lookupList);
+
+    for (i = 0; i < lookupCount; ++i) {
+        stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
+        stbtt_uint8 *lookupTable  = lookupList + lookupOffset;
+
+        stbtt_uint16 lookupType      = ttUSHORT(lookupTable);
+        stbtt_uint16 subTableCount   = ttUSHORT(lookupTable + 4);
+        stbtt_uint8 *subTableOffsets = lookupTable + 6;
+        if (lookupType != 2) // Pair Adjustment Positioning Subtable
+            continue;
+
+        for (sti = 0; sti < subTableCount; sti++) {
+            stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
+            stbtt_uint8 *table          = lookupTable + subtableOffset;
+            stbtt_uint16 posFormat      = ttUSHORT(table);
+            stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
+            stbtt_int32  coverageIndex  = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
+            if (coverageIndex == -1)
+                continue;
+
+            switch (posFormat) {
             case 1: {
-               stbtt_int32 l, r, m;
-               int straw, needle;
-               stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
-               stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
-               if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
-                  stbtt_int32 valueRecordPairSizeInBytes = 2;
-                  stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
-                  stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
-                  stbtt_uint8 *pairValueTable = table + pairPosOffset;
-                  stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
-                  stbtt_uint8 *pairValueArray = pairValueTable + 2;
-
-                  if (coverageIndex >= pairSetCount) return 0;
-
-                  needle=glyph2;
-                  r=pairValueCount-1;
-                  l=0;
-
-                  // Binary search.
-                  while (l <= r) {
-                     stbtt_uint16 secondGlyph;
-                     stbtt_uint8 *pairValue;
-                     m = (l + r) >> 1;
-                     pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
-                     secondGlyph = ttUSHORT(pairValue);
-                     straw = secondGlyph;
-                     if (needle < straw)
-                        r = m - 1;
-                     else if (needle > straw)
-                        l = m + 1;
-                     else {
-                        stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
-                        return xAdvance;
-                     }
-                  }
-               } else
-                  return 0;
-               break;
+                stbtt_int32  l, r, m;
+                int          straw, needle;
+                stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
+                stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
+                if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
+                    stbtt_int32  valueRecordPairSizeInBytes = 2;
+                    stbtt_uint16 pairSetCount               = ttUSHORT(table + 8);
+                    stbtt_uint16 pairPosOffset              = ttUSHORT(table + 10 + 2 * coverageIndex);
+                    stbtt_uint8 *pairValueTable             = table + pairPosOffset;
+                    stbtt_uint16 pairValueCount             = ttUSHORT(pairValueTable);
+                    stbtt_uint8 *pairValueArray             = pairValueTable + 2;
+
+                    if (coverageIndex >= pairSetCount)
+                        return 0;
+
+                    needle = glyph2;
+                    r      = pairValueCount - 1;
+                    l      = 0;
+
+                    // Binary search.
+                    while (l <= r) {
+                        stbtt_uint16 secondGlyph;
+                        stbtt_uint8 *pairValue;
+                        m           = (l + r) >> 1;
+                        pairValue   = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
+                        secondGlyph = ttUSHORT(pairValue);
+                        straw       = secondGlyph;
+                        if (needle < straw)
+                            r = m - 1;
+                        else if (needle > straw)
+                            l = m + 1;
+                        else {
+                            stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
+                            return xAdvance;
+                        }
+                    }
+                } else
+                    return 0;
+                break;
             }
 
             case 2: {
-               stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
-               stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
-               if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
-                  stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
-                  stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
-                  int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
-                  int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
-
-                  stbtt_uint16 class1Count = ttUSHORT(table + 12);
-                  stbtt_uint16 class2Count = ttUSHORT(table + 14);
-                  stbtt_uint8 *class1Records, *class2Records;
-                  stbtt_int16 xAdvance;
-
-                  if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed
-                  if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed
-
-                  class1Records = table + 16;
-                  class2Records = class1Records + 2 * (glyph1class * class2Count);
-                  xAdvance = ttSHORT(class2Records + 2 * glyph2class);
-                  return xAdvance;
-               } else
-                  return 0;
-               break;
+                stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
+                stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
+                if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
+                    stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
+                    stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
+                    int          glyph1class     = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
+                    int          glyph2class     = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
+
+                    stbtt_uint16 class1Count = ttUSHORT(table + 12);
+                    stbtt_uint16 class2Count = ttUSHORT(table + 14);
+                    stbtt_uint8 *class1Records, *class2Records;
+                    stbtt_int16  xAdvance;
+
+                    if (glyph1class < 0 || glyph1class >= class1Count)
+                        return 0; // malformed
+                    if (glyph2class < 0 || glyph2class >= class2Count)
+                        return 0; // malformed
+
+                    class1Records = table + 16;
+                    class2Records = class1Records + 2 * (glyph1class * class2Count);
+                    xAdvance      = ttSHORT(class2Records + 2 * glyph2class);
+                    return xAdvance;
+                } else
+                    return 0;
+                break;
             }
 
             default:
-               return 0; // Unsupported position format
-         }
-      }
-   }
+                return 0; // Unsupported position format
+            }
+        }
+    }
 
-   return 0;
+    return 0;
 }
 
-STBTT_DEF int  stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2)
-{
-   int xAdvance = 0;
+STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) {
+    int xAdvance = 0;
 
-   if (info->gpos)
-      xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
-   else if (info->kern)
-      xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
+    if (info->gpos)
+        xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
+    else if (info->kern)
+        xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
 
-   return xAdvance;
+    return xAdvance;
 }
 
-STBTT_DEF int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
-{
-   if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs
-      return 0;
-   return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
+STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) {
+    if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs
+        return 0;
+    return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info, ch1), stbtt_FindGlyphIndex(info, ch2));
 }
 
-STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
-{
-   stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
+STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth,
+                                          int *leftSideBearing) {
+    stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info, codepoint), advanceWidth, leftSideBearing);
 }
 
-STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap)
-{
-   if (ascent ) *ascent  = ttSHORT(info->data+info->hhea + 4);
-   if (descent) *descent = ttSHORT(info->data+info->hhea + 6);
-   if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
+STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) {
+    if (ascent)
+        *ascent = ttSHORT(info->data + info->hhea + 4);
+    if (descent)
+        *descent = ttSHORT(info->data + info->hhea + 6);
+    if (lineGap)
+        *lineGap = ttSHORT(info->data + info->hhea + 8);
 }
 
-STBTT_DEF int  stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap)
-{
-   int tab = stbtt__find_table(info->data, info->fontstart, "OS/2");
-   if (!tab)
-      return 0;
-   if (typoAscent ) *typoAscent  = ttSHORT(info->data+tab + 68);
-   if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70);
-   if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72);
-   return 1;
+STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent,
+                                       int *typoLineGap) {
+    int tab = stbtt__find_table(info->data, info->fontstart, "OS/2");
+    if (!tab)
+        return 0;
+    if (typoAscent)
+        *typoAscent = ttSHORT(info->data + tab + 68);
+    if (typoDescent)
+        *typoDescent = ttSHORT(info->data + tab + 70);
+    if (typoLineGap)
+        *typoLineGap = ttSHORT(info->data + tab + 72);
+    return 1;
 }
 
-STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
-{
-   *x0 = ttSHORT(info->data + info->head + 36);
-   *y0 = ttSHORT(info->data + info->head + 38);
-   *x1 = ttSHORT(info->data + info->head + 40);
-   *y1 = ttSHORT(info->data + info->head + 42);
+STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) {
+    *x0 = ttSHORT(info->data + info->head + 36);
+    *y0 = ttSHORT(info->data + info->head + 38);
+    *x1 = ttSHORT(info->data + info->head + 40);
+    *y1 = ttSHORT(info->data + info->head + 42);
 }
 
-STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height)
-{
-   int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6);
-   return (float) height / fheight;
+STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) {
+    int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6);
+    return (float)height / fheight;
 }
 
-STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels)
-{
-   int unitsPerEm = ttUSHORT(info->data + info->head + 18);
-   return pixels / unitsPerEm;
+STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) {
+    int unitsPerEm = ttUSHORT(info->data + info->head + 18);
+    return pixels / unitsPerEm;
 }
 
-STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
-{
-   STBTT_free(v, info->userdata);
-}
+STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) { STBTT_free(v, info->userdata); }
 
-STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl)
-{
-   int i;
-   stbtt_uint8 *data = info->data;
-   stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info);
+STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl) {
+    int          i;
+    stbtt_uint8 *data         = info->data;
+    stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *)info);
 
-   int numEntries = ttUSHORT(svg_doc_list);
-   stbtt_uint8 *svg_docs = svg_doc_list + 2;
+    int          numEntries = ttUSHORT(svg_doc_list);
+    stbtt_uint8 *svg_docs   = svg_doc_list + 2;
 
-   for(i=0; i<numEntries; i++) {
-      stbtt_uint8 *svg_doc = svg_docs + (12 * i);
-      if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2)))
-         return svg_doc;
-   }
-   return 0;
+    for (i = 0; i < numEntries; i++) {
+        stbtt_uint8 *svg_doc = svg_docs + (12 * i);
+        if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2)))
+            return svg_doc;
+    }
+    return 0;
 }
 
-STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg)
-{
-   stbtt_uint8 *data = info->data;
-   stbtt_uint8 *svg_doc;
-
-   if (info->svg == 0)
-      return 0;
-
-   svg_doc = stbtt_FindSVGDoc(info, gl);
-   if (svg_doc != NULL) {
-      *svg = (char *) data + info->svg + ttULONG(svg_doc + 4);
-      return ttULONG(svg_doc + 8);
-   } else {
-      return 0;
-   }
+STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg) {
+    stbtt_uint8 *data = info->data;
+    stbtt_uint8 *svg_doc;
+
+    if (info->svg == 0)
+        return 0;
+
+    svg_doc = stbtt_FindSVGDoc(info, gl);
+    if (svg_doc != NULL) {
+        *svg = (char *)data + info->svg + ttULONG(svg_doc + 4);
+        return ttULONG(svg_doc + 8);
+    } else {
+        return 0;
+    }
 }
 
-STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg)
-{
-   return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg);
+STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg) {
+    return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -2718,158 +2800,165 @@ STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_code
 // antialiasing software rasterizer
 //
 
-STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
-{
-   int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning
-   if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
-      // e.g. space character
-      if (ix0) *ix0 = 0;
-      if (iy0) *iy0 = 0;
-      if (ix1) *ix1 = 0;
-      if (iy1) *iy1 = 0;
-   } else {
-      // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
-      if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
-      if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
-      if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
-      if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
-   }
-}
-
-STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
-{
-   stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
-}
-
-STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
-{
-   stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
-}
-
-STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
-{
-   stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1);
+STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,
+                                               float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) {
+    int x0 = 0, y0 = 0, x1, y1; // =0 suppresses compiler warning
+    if (!stbtt_GetGlyphBox(font, glyph, &x0, &y0, &x1, &y1)) {
+        // e.g. space character
+        if (ix0)
+            *ix0 = 0;
+        if (iy0)
+            *iy0 = 0;
+        if (ix1)
+            *ix1 = 0;
+        if (iy1)
+            *iy1 = 0;
+    } else {
+        // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
+        if (ix0)
+            *ix0 = STBTT_ifloor(x0 * scale_x + shift_x);
+        if (iy0)
+            *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
+        if (ix1)
+            *ix1 = STBTT_iceil(x1 * scale_x + shift_x);
+        if (iy1)
+            *iy1 = STBTT_iceil(-y0 * scale_y + shift_y);
+    }
+}
+
+STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0,
+                                       int *iy0, int *ix1, int *iy1) {
+    stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1);
+}
+
+STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x,
+                                                   float scale_y, float shift_x, float shift_y, int *ix0, int *iy0,
+                                                   int *ix1, int *iy1) {
+    stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font, codepoint), scale_x, scale_y, shift_x, shift_y,
+                                    ix0, iy0, ix1, iy1);
+}
+
+STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y,
+                                           int *ix0, int *iy0, int *ix1, int *iy1) {
+    stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 //
 //  Rasterizer
 
-typedef struct stbtt__hheap_chunk
-{
-   struct stbtt__hheap_chunk *next;
+typedef struct stbtt__hheap_chunk {
+    struct stbtt__hheap_chunk *next;
 } stbtt__hheap_chunk;
 
-typedef struct stbtt__hheap
-{
-   struct stbtt__hheap_chunk *head;
-   void   *first_free;
-   int    num_remaining_in_head_chunk;
+typedef struct stbtt__hheap {
+    struct stbtt__hheap_chunk *head;
+    void                      *first_free;
+    int                        num_remaining_in_head_chunk;
 } stbtt__hheap;
 
-static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata)
-{
-   if (hh->first_free) {
-      void *p = hh->first_free;
-      hh->first_free = * (void **) p;
-      return p;
-   } else {
-      if (hh->num_remaining_in_head_chunk == 0) {
-         int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
-         stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata);
-         if (c == NULL)
-            return NULL;
-         c->next = hh->head;
-         hh->head = c;
-         hh->num_remaining_in_head_chunk = count;
-      }
-      --hh->num_remaining_in_head_chunk;
-      return (char *) (hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
-   }
-}
-
-static void stbtt__hheap_free(stbtt__hheap *hh, void *p)
-{
-   *(void **) p = hh->first_free;
-   hh->first_free = p;
-}
-
-static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata)
-{
-   stbtt__hheap_chunk *c = hh->head;
-   while (c) {
-      stbtt__hheap_chunk *n = c->next;
-      STBTT_free(c, userdata);
-      c = n;
-   }
+static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) {
+    if (hh->first_free) {
+        void *p        = hh->first_free;
+        hh->first_free = *(void **)p;
+        return p;
+    } else {
+        if (hh->num_remaining_in_head_chunk == 0) {
+            int                 count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
+            stbtt__hheap_chunk *c =
+                (stbtt__hheap_chunk *)STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata);
+            if (c == NULL)
+                return NULL;
+            c->next                         = hh->head;
+            hh->head                        = c;
+            hh->num_remaining_in_head_chunk = count;
+        }
+        --hh->num_remaining_in_head_chunk;
+        return (char *)(hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
+    }
+}
+
+static void stbtt__hheap_free(stbtt__hheap *hh, void *p) {
+    *(void **)p    = hh->first_free;
+    hh->first_free = p;
+}
+
+static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) {
+    stbtt__hheap_chunk *c = hh->head;
+    while (c) {
+        stbtt__hheap_chunk *n = c->next;
+        STBTT_free(c, userdata);
+        c = n;
+    }
 }
 
 typedef struct stbtt__edge {
-   float x0,y0, x1,y1;
-   int invert;
+    float x0, y0, x1, y1;
+    int   invert;
 } stbtt__edge;
 
-
-typedef struct stbtt__active_edge
-{
-   struct stbtt__active_edge *next;
-   #if STBTT_RASTERIZER_VERSION==1
-   int x,dx;
-   float ey;
-   int direction;
-   #elif STBTT_RASTERIZER_VERSION==2
-   float fx,fdx,fdy;
-   float direction;
-   float sy;
-   float ey;
-   #else
-   #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
-   #endif
+typedef struct stbtt__active_edge {
+    struct stbtt__active_edge *next;
+#if STBTT_RASTERIZER_VERSION == 1
+    int   x, dx;
+    float ey;
+    int   direction;
+#elif STBTT_RASTERIZER_VERSION == 2
+    float fx, fdx, fdy;
+    float direction;
+    float sy;
+    float ey;
+#else
+#error "Unrecognized value of STBTT_RASTERIZER_VERSION"
+#endif
 } stbtt__active_edge;
 
 #if STBTT_RASTERIZER_VERSION == 1
-#define STBTT_FIXSHIFT   10
-#define STBTT_FIX        (1 << STBTT_FIXSHIFT)
-#define STBTT_FIXMASK    (STBTT_FIX-1)
-
-static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)
-{
-   stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
-   float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
-   STBTT_assert(z != NULL);
-   if (!z) return z;
-
-   // round dx down to avoid overshooting
-   if (dxdy < 0)
-      z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
-   else
-      z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
-
-   z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount
-   z->x -= off_x * STBTT_FIX;
-
-   z->ey = e->y1;
-   z->next = 0;
-   z->direction = e->invert ? 1 : -1;
-   return z;
+#define STBTT_FIXSHIFT 10
+#define STBTT_FIX      (1 << STBTT_FIXSHIFT)
+#define STBTT_FIXMASK  (STBTT_FIX - 1)
+
+static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point,
+                                             void *userdata) {
+    stbtt__active_edge *z    = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata);
+    float               dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
+    STBTT_assert(z != NULL);
+    if (!z)
+        return z;
+
+    // round dx down to avoid overshooting
+    if (dxdy < 0)
+        z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
+    else
+        z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
+
+    z->x = STBTT_ifloor(STBTT_FIX * e->x0 +
+                        z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount
+    z->x -= off_x * STBTT_FIX;
+
+    z->ey        = e->y1;
+    z->next      = 0;
+    z->direction = e->invert ? 1 : -1;
+    return z;
 }
 #elif STBTT_RASTERIZER_VERSION == 2
-static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)
-{
-   stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
-   float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
-   STBTT_assert(z != NULL);
-   //STBTT_assert(e->y0 <= start_point);
-   if (!z) return z;
-   z->fdx = dxdy;
-   z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
-   z->fx = e->x0 + dxdy * (start_point - e->y0);
-   z->fx -= off_x;
-   z->direction = e->invert ? 1.0f : -1.0f;
-   z->sy = e->y0;
-   z->ey = e->y1;
-   z->next = 0;
-   return z;
+static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point,
+                                             void *userdata) {
+    stbtt__active_edge *z    = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata);
+    float               dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
+    STBTT_assert(z != NULL);
+    // STBTT_assert(e->y0 <= start_point);
+    if (!z)
+        return z;
+    z->fdx = dxdy;
+    z->fdy = dxdy != 0.0f ? (1.0f / dxdy) : 0.0f;
+    z->fx  = e->x0 + dxdy * (start_point - e->y0);
+    z->fx -= off_x;
+    z->direction = e->invert ? 1.0f : -1.0f;
+    z->sy        = e->y0;
+    z->ey        = e->y1;
+    z->next      = 0;
+    return z;
 }
 #else
 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
@@ -2879,929 +2968,957 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
 // note: this routine clips fills that extend off the edges... ideally this
 // wouldn't happen, but it could happen if the truetype glyph bounding boxes
 // are wrong, or if the user supplies a too-small bitmap
-static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)
-{
-   // non-zero winding fill
-   int x0=0, w=0;
-
-   while (e) {
-      if (w == 0) {
-         // if we're currently at zero, we need to record the edge start point
-         x0 = e->x; w += e->direction;
-      } else {
-         int x1 = e->x; w += e->direction;
-         // if we went to zero, we need to draw
-         if (w == 0) {
-            int i = x0 >> STBTT_FIXSHIFT;
-            int j = x1 >> STBTT_FIXSHIFT;
-
-            if (i < len && j >= 0) {
-               if (i == j) {
-                  // x0,x1 are the same pixel, so compute combined coverage
-                  scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
-               } else {
-                  if (i >= 0) // add antialiasing for x0
-                     scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
-                  else
-                     i = -1; // clip
-
-                  if (j < len) // add antialiasing for x1
-                     scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
-                  else
-                     j = len; // clip
-
-                  for (++i; i < j; ++i) // fill pixels between x0 and x1
-                     scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
-               }
+static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) {
+    // non-zero winding fill
+    int x0 = 0, w = 0;
+
+    while (e) {
+        if (w == 0) {
+            // if we're currently at zero, we need to record the edge start point
+            x0 = e->x;
+            w += e->direction;
+        } else {
+            int x1 = e->x;
+            w += e->direction;
+            // if we went to zero, we need to draw
+            if (w == 0) {
+                int i = x0 >> STBTT_FIXSHIFT;
+                int j = x1 >> STBTT_FIXSHIFT;
+
+                if (i < len && j >= 0) {
+                    if (i == j) {
+                        // x0,x1 are the same pixel, so compute combined coverage
+                        scanline[i] = scanline[i] + (stbtt_uint8)((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
+                    } else {
+                        if (i >= 0) // add antialiasing for x0
+                            scanline[i] =
+                                scanline[i] +
+                                (stbtt_uint8)(((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
+                        else
+                            i = -1; // clip
+
+                        if (j < len) // add antialiasing for x1
+                            scanline[j] =
+                                scanline[j] + (stbtt_uint8)(((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
+                        else
+                            j = len; // clip
+
+                        for (++i; i < j; ++i) // fill pixels between x0 and x1
+                            scanline[i] = scanline[i] + (stbtt_uint8)max_weight;
+                    }
+                }
             }
-         }
-      }
-
-      e = e->next;
-   }
-}
-
-static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
-{
-   stbtt__hheap hh = { 0, 0, 0 };
-   stbtt__active_edge *active = NULL;
-   int y,j=0;
-   int max_weight = (255 / vsubsample);  // weight per vertical scanline
-   int s; // vertical subsample index
-   unsigned char scanline_data[512], *scanline;
-
-   if (result->w > 512)
-      scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
-   else
-      scanline = scanline_data;
-
-   y = off_y * vsubsample;
-   e[n].y0 = (off_y + result->h) * (float) vsubsample + 1;
-
-   while (j < result->h) {
-      STBTT_memset(scanline, 0, result->w);
-      for (s=0; s < vsubsample; ++s) {
-         // find center of pixel for this scanline
-         float scan_y = y + 0.5f;
-         stbtt__active_edge **step = &active;
-
-         // update all active edges;
-         // remove all active edges that terminate before the center of this scanline
-         while (*step) {
-            stbtt__active_edge * z = *step;
-            if (z->ey <= scan_y) {
-               *step = z->next; // delete from list
-               STBTT_assert(z->direction);
-               z->direction = 0;
-               stbtt__hheap_free(&hh, z);
-            } else {
-               z->x += z->dx; // advance to position for current scanline
-               step = &((*step)->next); // advance through list
+        }
+
+        e = e->next;
+    }
+}
+
+static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x,
+                                          int off_y, void *userdata) {
+    stbtt__hheap        hh     = {0, 0, 0};
+    stbtt__active_edge *active = NULL;
+    int                 y, j = 0;
+    int                 max_weight = (255 / vsubsample); // weight per vertical scanline
+    int                 s;                               // vertical subsample index
+    unsigned char       scanline_data[512], *scanline;
+
+    if (result->w > 512)
+        scanline = (unsigned char *)STBTT_malloc(result->w, userdata);
+    else
+        scanline = scanline_data;
+
+    y       = off_y * vsubsample;
+    e[n].y0 = (off_y + result->h) * (float)vsubsample + 1;
+
+    while (j < result->h) {
+        STBTT_memset(scanline, 0, result->w);
+        for (s = 0; s < vsubsample; ++s) {
+            // find center of pixel for this scanline
+            float                scan_y = y + 0.5f;
+            stbtt__active_edge **step   = &active;
+
+            // update all active edges;
+            // remove all active edges that terminate before the center of this scanline
+            while (*step) {
+                stbtt__active_edge *z = *step;
+                if (z->ey <= scan_y) {
+                    *step = z->next; // delete from list
+                    STBTT_assert(z->direction);
+                    z->direction = 0;
+                    stbtt__hheap_free(&hh, z);
+                } else {
+                    z->x += z->dx;           // advance to position for current scanline
+                    step = &((*step)->next); // advance through list
+                }
             }
-         }
-
-         // resort the list if needed
-         for(;;) {
-            int changed=0;
-            step = &active;
-            while (*step && (*step)->next) {
-               if ((*step)->x > (*step)->next->x) {
-                  stbtt__active_edge *t = *step;
-                  stbtt__active_edge *q = t->next;
-
-                  t->next = q->next;
-                  q->next = t;
-                  *step = q;
-                  changed = 1;
-               }
-               step = &(*step)->next;
+
+            // resort the list if needed
+            for (;;) {
+                int changed = 0;
+                step        = &active;
+                while (*step && (*step)->next) {
+                    if ((*step)->x > (*step)->next->x) {
+                        stbtt__active_edge *t = *step;
+                        stbtt__active_edge *q = t->next;
+
+                        t->next = q->next;
+                        q->next = t;
+                        *step   = q;
+                        changed = 1;
+                    }
+                    step = &(*step)->next;
+                }
+                if (!changed)
+                    break;
             }
-            if (!changed) break;
-         }
-
-         // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
-         while (e->y0 <= scan_y) {
-            if (e->y1 > scan_y) {
-               stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
-               if (z != NULL) {
-                  // find insertion point
-                  if (active == NULL)
-                     active = z;
-                  else if (z->x < active->x) {
-                     // insert at front
-                     z->next = active;
-                     active = z;
-                  } else {
-                     // find thing to insert AFTER
-                     stbtt__active_edge *p = active;
-                     while (p->next && p->next->x < z->x)
-                        p = p->next;
-                     // at this point, p->next->x is NOT < z->x
-                     z->next = p->next;
-                     p->next = z;
-                  }
-               }
+
+            // insert all edges that start before the center of this scanline -- omit ones that also end on this
+            // scanline
+            while (e->y0 <= scan_y) {
+                if (e->y1 > scan_y) {
+                    stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
+                    if (z != NULL) {
+                        // find insertion point
+                        if (active == NULL)
+                            active = z;
+                        else if (z->x < active->x) {
+                            // insert at front
+                            z->next = active;
+                            active  = z;
+                        } else {
+                            // find thing to insert AFTER
+                            stbtt__active_edge *p = active;
+                            while (p->next && p->next->x < z->x)
+                                p = p->next;
+                            // at this point, p->next->x is NOT < z->x
+                            z->next = p->next;
+                            p->next = z;
+                        }
+                    }
+                }
+                ++e;
             }
-            ++e;
-         }
 
-         // now process all active edges in XOR fashion
-         if (active)
-            stbtt__fill_active_edges(scanline, result->w, active, max_weight);
+            // now process all active edges in XOR fashion
+            if (active)
+                stbtt__fill_active_edges(scanline, result->w, active, max_weight);
 
-         ++y;
-      }
-      STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
-      ++j;
-   }
+            ++y;
+        }
+        STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
+        ++j;
+    }
 
-   stbtt__hheap_cleanup(&hh, userdata);
+    stbtt__hheap_cleanup(&hh, userdata);
 
-   if (scanline != scanline_data)
-      STBTT_free(scanline, userdata);
+    if (scanline != scanline_data)
+        STBTT_free(scanline, userdata);
 }
 
 #elif STBTT_RASTERIZER_VERSION == 2
 
 // the edge passed in here does not cross the vertical line at x or the vertical line at x+1
 // (i.e. it has already been clipped to those)
-static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)
-{
-   if (y0 == y1) return;
-   STBTT_assert(y0 < y1);
-   STBTT_assert(e->sy <= e->ey);
-   if (y0 > e->ey) return;
-   if (y1 < e->sy) return;
-   if (y0 < e->sy) {
-      x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
-      y0 = e->sy;
-   }
-   if (y1 > e->ey) {
-      x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
-      y1 = e->ey;
-   }
-
-   if (x0 == x)
-      STBTT_assert(x1 <= x+1);
-   else if (x0 == x+1)
-      STBTT_assert(x1 >= x);
-   else if (x0 <= x)
-      STBTT_assert(x1 <= x);
-   else if (x0 >= x+1)
-      STBTT_assert(x1 >= x+1);
-   else
-      STBTT_assert(x1 >= x && x1 <= x+1);
-
-   if (x0 <= x && x1 <= x)
-      scanline[x] += e->direction * (y1-y0);
-   else if (x0 >= x+1 && x1 >= x+1)
-      ;
-   else {
-      STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
-      scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position
-   }
-}
-
-static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)
-{
-   STBTT_assert(top_width >= 0);
-   STBTT_assert(bottom_width >= 0);
-   return (top_width + bottom_width) / 2.0f * height;
-}
-
-static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)
-{
-   return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0);
-}
-
-static float stbtt__sized_triangle_area(float height, float width)
-{
-   return height * width / 2;
-}
-
-static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top)
-{
-   float y_bottom = y_top+1;
-
-   while (e) {
-      // brute force every pixel
-
-      // compute intersection points with top & bottom
-      STBTT_assert(e->ey >= y_top);
-
-      if (e->fdx == 0) {
-         float x0 = e->fx;
-         if (x0 < len) {
-            if (x0 >= 0) {
-               stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom);
-               stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom);
+static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1,
+                                       float y1) {
+    if (y0 == y1)
+        return;
+    STBTT_assert(y0 < y1);
+    STBTT_assert(e->sy <= e->ey);
+    if (y0 > e->ey)
+        return;
+    if (y1 < e->sy)
+        return;
+    if (y0 < e->sy) {
+        x0 += (x1 - x0) * (e->sy - y0) / (y1 - y0);
+        y0 = e->sy;
+    }
+    if (y1 > e->ey) {
+        x1 += (x1 - x0) * (e->ey - y1) / (y1 - y0);
+        y1 = e->ey;
+    }
+
+    if (x0 == x)
+        STBTT_assert(x1 <= x + 1);
+    else if (x0 == x + 1)
+        STBTT_assert(x1 >= x);
+    else if (x0 <= x)
+        STBTT_assert(x1 <= x);
+    else if (x0 >= x + 1)
+        STBTT_assert(x1 >= x + 1);
+    else
+        STBTT_assert(x1 >= x && x1 <= x + 1);
+
+    if (x0 <= x && x1 <= x)
+        scanline[x] += e->direction * (y1 - y0);
+    else if (x0 >= x + 1 && x1 >= x + 1)
+        ;
+    else {
+        STBTT_assert(x0 >= x && x0 <= x + 1 && x1 >= x && x1 <= x + 1);
+        scanline[x] += e->direction * (y1 - y0) * (1 - ((x0 - x) + (x1 - x)) / 2); // coverage = 1 - average x position
+    }
+}
+
+static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width) {
+    STBTT_assert(top_width >= 0);
+    STBTT_assert(bottom_width >= 0);
+    return (top_width + bottom_width) / 2.0f * height;
+}
+
+static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1) {
+    return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0);
+}
+
+static float stbtt__sized_triangle_area(float height, float width) { return height * width / 2; }
+
+static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e,
+                                         float y_top) {
+    float y_bottom = y_top + 1;
+
+    while (e) {
+        // brute force every pixel
+
+        // compute intersection points with top & bottom
+        STBTT_assert(e->ey >= y_top);
+
+        if (e->fdx == 0) {
+            float x0 = e->fx;
+            if (x0 < len) {
+                if (x0 >= 0) {
+                    stbtt__handle_clipped_edge(scanline, (int)x0, e, x0, y_top, x0, y_bottom);
+                    stbtt__handle_clipped_edge(scanline_fill - 1, (int)x0 + 1, e, x0, y_top, x0, y_bottom);
+                } else {
+                    stbtt__handle_clipped_edge(scanline_fill - 1, 0, e, x0, y_top, x0, y_bottom);
+                }
+            }
+        } else {
+            float x0 = e->fx;
+            float dx = e->fdx;
+            float xb = x0 + dx;
+            float x_top, x_bottom;
+            float sy0, sy1;
+            float dy = e->fdy;
+            STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
+
+            // compute endpoints of line segment clipped to this scanline (if the
+            // line segment starts on this scanline. x0 is the intersection of the
+            // line with y_top, but that may be off the line segment.
+            if (e->sy > y_top) {
+                x_top = x0 + dx * (e->sy - y_top);
+                sy0   = e->sy;
             } else {
-               stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
+                x_top = x0;
+                sy0   = y_top;
             }
-         }
-      } else {
-         float x0 = e->fx;
-         float dx = e->fdx;
-         float xb = x0 + dx;
-         float x_top, x_bottom;
-         float sy0,sy1;
-         float dy = e->fdy;
-         STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
-
-         // compute endpoints of line segment clipped to this scanline (if the
-         // line segment starts on this scanline. x0 is the intersection of the
-         // line with y_top, but that may be off the line segment.
-         if (e->sy > y_top) {
-            x_top = x0 + dx * (e->sy - y_top);
-            sy0 = e->sy;
-         } else {
-            x_top = x0;
-            sy0 = y_top;
-         }
-         if (e->ey < y_bottom) {
-            x_bottom = x0 + dx * (e->ey - y_top);
-            sy1 = e->ey;
-         } else {
-            x_bottom = xb;
-            sy1 = y_bottom;
-         }
-
-         if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
-            // from here on, we don't have to range check x values
-
-            if ((int) x_top == (int) x_bottom) {
-               float height;
-               // simple case, only spans one pixel
-               int x = (int) x_top;
-               height = (sy1 - sy0) * e->direction;
-               STBTT_assert(x >= 0 && x < len);
-               scanline[x]      += stbtt__position_trapezoid_area(height, x_top, x+1.0f, x_bottom, x+1.0f);
-               scanline_fill[x] += height; // everything right of this pixel is filled
+            if (e->ey < y_bottom) {
+                x_bottom = x0 + dx * (e->ey - y_top);
+                sy1      = e->ey;
             } else {
-               int x,x1,x2;
-               float y_crossing, y_final, step, sign, area;
-               // covers 2+ pixels
-               if (x_top > x_bottom) {
-                  // flip scanline vertically; signed area is the same
-                  float t;
-                  sy0 = y_bottom - (sy0 - y_top);
-                  sy1 = y_bottom - (sy1 - y_top);
-                  t = sy0, sy0 = sy1, sy1 = t;
-                  t = x_bottom, x_bottom = x_top, x_top = t;
-                  dx = -dx;
-                  dy = -dy;
-                  t = x0, x0 = xb, xb = t;
-               }
-               STBTT_assert(dy >= 0);
-               STBTT_assert(dx >= 0);
-
-               x1 = (int) x_top;
-               x2 = (int) x_bottom;
-               // compute intersection with y axis at x1+1
-               y_crossing = y_top + dy * (x1+1 - x0);
-
-               // compute intersection with y axis at x2
-               y_final = y_top + dy * (x2 - x0);
-
-               //           x1    x_top                            x2    x_bottom
-               //     y_top  +------|-----+------------+------------+--------|---+------------+
-               //            |            |            |            |            |            |
-               //            |            |            |            |            |            |
-               //       sy0  |      Txxxxx|............|............|............|............|
-               // y_crossing |            *xxxxx.......|............|............|............|
-               //            |            |     xxxxx..|............|............|............|
-               //            |            |     /-   xx*xxxx........|............|............|
-               //            |            | dy <       |    xxxxxx..|............|............|
-               //   y_final  |            |     \-     |          xx*xxx.........|............|
-               //       sy1  |            |            |            |   xxxxxB...|............|
-               //            |            |            |            |            |            |
-               //            |            |            |            |            |            |
-               //  y_bottom  +------------+------------+------------+------------+------------+
-               //
-               // goal is to measure the area covered by '.' in each pixel
-
-               // if x2 is right at the right edge of x1, y_crossing can blow up, github #1057
-               // @TODO: maybe test against sy1 rather than y_bottom?
-               if (y_crossing > y_bottom)
-                  y_crossing = y_bottom;
-
-               sign = e->direction;
-
-               // area of the rectangle covered from sy0..y_crossing
-               area = sign * (y_crossing-sy0);
-
-               // area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing)
-               scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top);
-
-               // check if final y_crossing is blown up; no test case for this
-               if (y_final > y_bottom) {
-                  y_final = y_bottom;
-                  dy = (y_final - y_crossing ) / (x2 - (x1+1)); // if denom=0, y_final = y_crossing, so y_final <= y_bottom
-               }
-
-               // in second pixel, area covered by line segment found in first pixel
-               // is always a rectangle 1 wide * the height of that line segment; this
-               // is exactly what the variable 'area' stores. it also gets a contribution
-               // from the line segment within it. the THIRD pixel will get the first
-               // pixel's rectangle contribution, the second pixel's rectangle contribution,
-               // and its own contribution. the 'own contribution' is the same in every pixel except
-               // the leftmost and rightmost, a trapezoid that slides down in each pixel.
-               // the second pixel's contribution to the third pixel will be the
-               // rectangle 1 wide times the height change in the second pixel, which is dy.
-
-               step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x,
-               // which multiplied by 1-pixel-width is how much pixel area changes for each step in x
-               // so the area advances by 'step' every time
-
-               for (x = x1+1; x < x2; ++x) {
-                  scanline[x] += area + step/2; // area of trapezoid is 1*step/2
-                  area += step;
-               }
-               STBTT_assert(STBTT_fabs(area) <= 1.01f); // accumulated error from area += step unless we round step down
-               STBTT_assert(sy1 > y_final-0.01f);
-
-               // area covered in the last pixel is the rectangle from all the pixels to the left,
-               // plus the trapezoid filled by the line segment in this pixel all the way to the right edge
-               scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1-y_final, (float) x2, x2+1.0f, x_bottom, x2+1.0f);
-
-               // the rest of the line is filled based on the total height of the line segment in this pixel
-               scanline_fill[x2] += sign * (sy1-sy0);
+                x_bottom = xb;
+                sy1      = y_bottom;
             }
-         } else {
-            // if edge goes outside of box we're drawing, we require
-            // clipping logic. since this does not match the intended use
-            // of this library, we use a different, very slow brute
-            // force implementation
-            // note though that this does happen some of the time because
-            // x_top and x_bottom can be extrapolated at the top & bottom of
-            // the shape and actually lie outside the bounding box
-            int x;
-            for (x=0; x < len; ++x) {
-               // cases:
-               //
-               // there can be up to two intersections with the pixel. any intersection
-               // with left or right edges can be handled by splitting into two (or three)
-               // regions. intersections with top & bottom do not necessitate case-wise logic.
-               //
-               // the old way of doing this found the intersections with the left & right edges,
-               // then used some simple logic to produce up to three segments in sorted order
-               // from top-to-bottom. however, this had a problem: if an x edge was epsilon
-               // across the x border, then the corresponding y position might not be distinct
-               // from the other y segment, and it might ignored as an empty segment. to avoid
-               // that, we need to explicitly produce segments based on x positions.
-
-               // rename variables to clearly-defined pairs
-               float y0 = y_top;
-               float x1 = (float) (x);
-               float x2 = (float) (x+1);
-               float x3 = xb;
-               float y3 = y_bottom;
-
-               // x = e->x + e->dx * (y-y_top)
-               // (y-y_top) = (x - e->x) / e->dx
-               // y = (x - e->x) / e->dx + y_top
-               float y1 = (x - x0) / dx + y_top;
-               float y2 = (x+1 - x0) / dx + y_top;
-
-               if (x0 < x1 && x3 > x2) {         // three segments descending down-right
-                  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
-                  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2);
-                  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
-               } else if (x3 < x1 && x0 > x2) {  // three segments descending down-left
-                  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
-                  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1);
-                  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
-               } else if (x0 < x1 && x3 > x1) {  // two segments across x, down-right
-                  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
-                  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
-               } else if (x3 < x1 && x0 > x1) {  // two segments across x, down-left
-                  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
-                  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
-               } else if (x0 < x2 && x3 > x2) {  // two segments across x+1, down-right
-                  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
-                  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
-               } else if (x3 < x2 && x0 > x2) {  // two segments across x+1, down-left
-                  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
-                  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
-               } else {  // one segment
-                  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3);
-               }
+
+            if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
+                // from here on, we don't have to range check x values
+
+                if ((int)x_top == (int)x_bottom) {
+                    float height;
+                    // simple case, only spans one pixel
+                    int x  = (int)x_top;
+                    height = (sy1 - sy0) * e->direction;
+                    STBTT_assert(x >= 0 && x < len);
+                    scanline[x] += stbtt__position_trapezoid_area(height, x_top, x + 1.0f, x_bottom, x + 1.0f);
+                    scanline_fill[x] += height; // everything right of this pixel is filled
+                } else {
+                    int   x, x1, x2;
+                    float y_crossing, y_final, step, sign, area;
+                    // covers 2+ pixels
+                    if (x_top > x_bottom) {
+                        // flip scanline vertically; signed area is the same
+                        float t;
+                        sy0 = y_bottom - (sy0 - y_top);
+                        sy1 = y_bottom - (sy1 - y_top);
+                        t = sy0, sy0 = sy1, sy1 = t;
+                        t = x_bottom, x_bottom = x_top, x_top = t;
+                        dx = -dx;
+                        dy = -dy;
+                        t = x0, x0 = xb, xb = t;
+                    }
+                    STBTT_assert(dy >= 0);
+                    STBTT_assert(dx >= 0);
+
+                    x1 = (int)x_top;
+                    x2 = (int)x_bottom;
+                    // compute intersection with y axis at x1+1
+                    y_crossing = y_top + dy * (x1 + 1 - x0);
+
+                    // compute intersection with y axis at x2
+                    y_final = y_top + dy * (x2 - x0);
+
+                    //           x1    x_top                            x2    x_bottom
+                    //     y_top  +------|-----+------------+------------+--------|---+------------+
+                    //            |            |            |            |            |            |
+                    //            |            |            |            |            |            |
+                    //       sy0  |      Txxxxx|............|............|............|............|
+                    // y_crossing |            *xxxxx.......|............|............|............|
+                    //            |            |     xxxxx..|............|............|............|
+                    //            |            |     /-   xx*xxxx........|............|............|
+                    //            |            | dy <       |    xxxxxx..|............|............|
+                    //   y_final  |            |     \-     |          xx*xxx.........|............|
+                    //       sy1  |            |            |            |   xxxxxB...|............|
+                    //            |            |            |            |            |            |
+                    //            |            |            |            |            |            |
+                    //  y_bottom  +------------+------------+------------+------------+------------+
+                    //
+                    // goal is to measure the area covered by '.' in each pixel
+
+                    // if x2 is right at the right edge of x1, y_crossing can blow up, github #1057
+                    // @TODO: maybe test against sy1 rather than y_bottom?
+                    if (y_crossing > y_bottom)
+                        y_crossing = y_bottom;
+
+                    sign = e->direction;
+
+                    // area of the rectangle covered from sy0..y_crossing
+                    area = sign * (y_crossing - sy0);
+
+                    // area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing)
+                    scanline[x1] += stbtt__sized_triangle_area(area, x1 + 1 - x_top);
+
+                    // check if final y_crossing is blown up; no test case for this
+                    if (y_final > y_bottom) {
+                        y_final = y_bottom;
+                        dy      = (y_final - y_crossing) /
+                             (x2 - (x1 + 1)); // if denom=0, y_final = y_crossing, so y_final <= y_bottom
+                    }
+
+                    // in second pixel, area covered by line segment found in first pixel
+                    // is always a rectangle 1 wide * the height of that line segment; this
+                    // is exactly what the variable 'area' stores. it also gets a contribution
+                    // from the line segment within it. the THIRD pixel will get the first
+                    // pixel's rectangle contribution, the second pixel's rectangle contribution,
+                    // and its own contribution. the 'own contribution' is the same in every pixel except
+                    // the leftmost and rightmost, a trapezoid that slides down in each pixel.
+                    // the second pixel's contribution to the third pixel will be the
+                    // rectangle 1 wide times the height change in the second pixel, which is dy.
+
+                    step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x,
+                    // which multiplied by 1-pixel-width is how much pixel area changes for each step in x
+                    // so the area advances by 'step' every time
+
+                    for (x = x1 + 1; x < x2; ++x) {
+                        scanline[x] += area + step / 2; // area of trapezoid is 1*step/2
+                        area += step;
+                    }
+                    STBTT_assert(STBTT_fabs(area) <=
+                                 1.01f); // accumulated error from area += step unless we round step down
+                    STBTT_assert(sy1 > y_final - 0.01f);
+
+                    // area covered in the last pixel is the rectangle from all the pixels to the left,
+                    // plus the trapezoid filled by the line segment in this pixel all the way to the right edge
+                    scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1 - y_final, (float)x2, x2 + 1.0f,
+                                                                                 x_bottom, x2 + 1.0f);
+
+                    // the rest of the line is filled based on the total height of the line segment in this pixel
+                    scanline_fill[x2] += sign * (sy1 - sy0);
+                }
+            } else {
+                // if edge goes outside of box we're drawing, we require
+                // clipping logic. since this does not match the intended use
+                // of this library, we use a different, very slow brute
+                // force implementation
+                // note though that this does happen some of the time because
+                // x_top and x_bottom can be extrapolated at the top & bottom of
+                // the shape and actually lie outside the bounding box
+                int x;
+                for (x = 0; x < len; ++x) {
+                    // cases:
+                    //
+                    // there can be up to two intersections with the pixel. any intersection
+                    // with left or right edges can be handled by splitting into two (or three)
+                    // regions. intersections with top & bottom do not necessitate case-wise logic.
+                    //
+                    // the old way of doing this found the intersections with the left & right edges,
+                    // then used some simple logic to produce up to three segments in sorted order
+                    // from top-to-bottom. however, this had a problem: if an x edge was epsilon
+                    // across the x border, then the corresponding y position might not be distinct
+                    // from the other y segment, and it might ignored as an empty segment. to avoid
+                    // that, we need to explicitly produce segments based on x positions.
+
+                    // rename variables to clearly-defined pairs
+                    float y0 = y_top;
+                    float x1 = (float)(x);
+                    float x2 = (float)(x + 1);
+                    float x3 = xb;
+                    float y3 = y_bottom;
+
+                    // x = e->x + e->dx * (y-y_top)
+                    // (y-y_top) = (x - e->x) / e->dx
+                    // y = (x - e->x) / e->dx + y_top
+                    float y1 = (x - x0) / dx + y_top;
+                    float y2 = (x + 1 - x0) / dx + y_top;
+
+                    if (x0 < x1 && x3 > x2) { // three segments descending down-right
+                        stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
+                        stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x2, y2);
+                        stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
+                    } else if (x3 < x1 && x0 > x2) { // three segments descending down-left
+                        stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
+                        stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x1, y1);
+                        stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
+                    } else if (x0 < x1 && x3 > x1) { // two segments across x, down-right
+                        stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
+                        stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
+                    } else if (x3 < x1 && x0 > x1) { // two segments across x, down-left
+                        stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
+                        stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
+                    } else if (x0 < x2 && x3 > x2) { // two segments across x+1, down-right
+                        stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
+                        stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
+                    } else if (x3 < x2 && x0 > x2) { // two segments across x+1, down-left
+                        stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
+                        stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
+                    } else { // one segment
+                        stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x3, y3);
+                    }
+                }
             }
-         }
-      }
-      e = e->next;
-   }
+        }
+        e = e->next;
+    }
 }
 
 // directly AA rasterize edges w/o supersampling
-static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
-{
-   stbtt__hheap hh = { 0, 0, 0 };
-   stbtt__active_edge *active = NULL;
-   int y,j=0, i;
-   float scanline_data[129], *scanline, *scanline2;
-
-   STBTT__NOTUSED(vsubsample);
-
-   if (result->w > 64)
-      scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
-   else
-      scanline = scanline_data;
-
-   scanline2 = scanline + result->w;
-
-   y = off_y;
-   e[n].y0 = (float) (off_y + result->h) + 1;
-
-   while (j < result->h) {
-      // find center of pixel for this scanline
-      float scan_y_top    = y + 0.0f;
-      float scan_y_bottom = y + 1.0f;
-      stbtt__active_edge **step = &active;
-
-      STBTT_memset(scanline , 0, result->w*sizeof(scanline[0]));
-      STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0]));
-
-      // update all active edges;
-      // remove all active edges that terminate before the top of this scanline
-      while (*step) {
-         stbtt__active_edge * z = *step;
-         if (z->ey <= scan_y_top) {
-            *step = z->next; // delete from list
-            STBTT_assert(z->direction);
-            z->direction = 0;
-            stbtt__hheap_free(&hh, z);
-         } else {
-            step = &((*step)->next); // advance through list
-         }
-      }
-
-      // insert all edges that start before the bottom of this scanline
-      while (e->y0 <= scan_y_bottom) {
-         if (e->y0 != e->y1) {
-            stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
-            if (z != NULL) {
-               if (j == 0 && off_y != 0) {
-                  if (z->ey < scan_y_top) {
-                     // this can happen due to subpixel positioning and some kind of fp rounding error i think
-                     z->ey = scan_y_top;
-                  }
-               }
-               STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
-               // insert at front
-               z->next = active;
-               active = z;
+static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x,
+                                          int off_y, void *userdata) {
+    stbtt__hheap        hh     = {0, 0, 0};
+    stbtt__active_edge *active = NULL;
+    int                 y, j = 0, i;
+    float               scanline_data[129], *scanline, *scanline2;
+
+    STBTT__NOTUSED(vsubsample);
+
+    if (result->w > 64)
+        scanline = (float *)STBTT_malloc((result->w * 2 + 1) * sizeof(float), userdata);
+    else
+        scanline = scanline_data;
+
+    scanline2 = scanline + result->w;
+
+    y       = off_y;
+    e[n].y0 = (float)(off_y + result->h) + 1;
+
+    while (j < result->h) {
+        // find center of pixel for this scanline
+        float                scan_y_top    = y + 0.0f;
+        float                scan_y_bottom = y + 1.0f;
+        stbtt__active_edge **step          = &active;
+
+        STBTT_memset(scanline, 0, result->w * sizeof(scanline[0]));
+        STBTT_memset(scanline2, 0, (result->w + 1) * sizeof(scanline[0]));
+
+        // update all active edges;
+        // remove all active edges that terminate before the top of this scanline
+        while (*step) {
+            stbtt__active_edge *z = *step;
+            if (z->ey <= scan_y_top) {
+                *step = z->next; // delete from list
+                STBTT_assert(z->direction);
+                z->direction = 0;
+                stbtt__hheap_free(&hh, z);
+            } else {
+                step = &((*step)->next); // advance through list
             }
-         }
-         ++e;
-      }
-
-      // now process all active edges
-      if (active)
-         stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
-
-      {
-         float sum = 0;
-         for (i=0; i < result->w; ++i) {
-            float k;
-            int m;
-            sum += scanline2[i];
-            k = scanline[i] + sum;
-            k = (float) STBTT_fabs(k)*255 + 0.5f;
-            m = (int) k;
-            if (m > 255) m = 255;
-            result->pixels[j*result->stride + i] = (unsigned char) m;
-         }
-      }
-      // advance all the edges
-      step = &active;
-      while (*step) {
-         stbtt__active_edge *z = *step;
-         z->fx += z->fdx; // advance to position for current scanline
-         step = &((*step)->next); // advance through list
-      }
+        }
+
+        // insert all edges that start before the bottom of this scanline
+        while (e->y0 <= scan_y_bottom) {
+            if (e->y0 != e->y1) {
+                stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
+                if (z != NULL) {
+                    if (j == 0 && off_y != 0) {
+                        if (z->ey < scan_y_top) {
+                            // this can happen due to subpixel positioning and some kind of fp rounding error i think
+                            z->ey = scan_y_top;
+                        }
+                    }
+                    STBTT_assert(z->ey >=
+                                 scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
+                    // insert at front
+                    z->next = active;
+                    active  = z;
+                }
+            }
+            ++e;
+        }
+
+        // now process all active edges
+        if (active)
+            stbtt__fill_active_edges_new(scanline, scanline2 + 1, result->w, active, scan_y_top);
+
+        {
+            float sum = 0;
+            for (i = 0; i < result->w; ++i) {
+                float k;
+                int   m;
+                sum += scanline2[i];
+                k = scanline[i] + sum;
+                k = (float)STBTT_fabs(k) * 255 + 0.5f;
+                m = (int)k;
+                if (m > 255)
+                    m = 255;
+                result->pixels[j * result->stride + i] = (unsigned char)m;
+            }
+        }
+        // advance all the edges
+        step = &active;
+        while (*step) {
+            stbtt__active_edge *z = *step;
+            z->fx += z->fdx;         // advance to position for current scanline
+            step = &((*step)->next); // advance through list
+        }
 
-      ++y;
-      ++j;
-   }
+        ++y;
+        ++j;
+    }
 
-   stbtt__hheap_cleanup(&hh, userdata);
+    stbtt__hheap_cleanup(&hh, userdata);
 
-   if (scanline != scanline_data)
-      STBTT_free(scanline, userdata);
+    if (scanline != scanline_data)
+        STBTT_free(scanline, userdata);
 }
 #else
 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
 #endif
 
-#define STBTT__COMPARE(a,b)  ((a)->y0 < (b)->y0)
-
-static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
-{
-   int i,j;
-   for (i=1; i < n; ++i) {
-      stbtt__edge t = p[i], *a = &t;
-      j = i;
-      while (j > 0) {
-         stbtt__edge *b = &p[j-1];
-         int c = STBTT__COMPARE(a,b);
-         if (!c) break;
-         p[j] = p[j-1];
-         --j;
-      }
-      if (i != j)
-         p[j] = t;
-   }
-}
-
-static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
-{
-   /* threshold for transitioning to insertion sort */
-   while (n > 12) {
-      stbtt__edge t;
-      int c01,c12,c,m,i,j;
-
-      /* compute median of three */
-      m = n >> 1;
-      c01 = STBTT__COMPARE(&p[0],&p[m]);
-      c12 = STBTT__COMPARE(&p[m],&p[n-1]);
-      /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
-      if (c01 != c12) {
-         /* otherwise, we'll need to swap something else to middle */
-         int z;
-         c = STBTT__COMPARE(&p[0],&p[n-1]);
-         /* 0>mid && mid<n:  0>n => n; 0<n => 0 */
-         /* 0<mid && mid>n:  0>n => 0; 0<n => n */
-         z = (c == c12) ? 0 : n-1;
-         t = p[z];
-         p[z] = p[m];
-         p[m] = t;
-      }
-      /* now p[m] is the median-of-three */
-      /* swap it to the beginning so it won't move around */
-      t = p[0];
-      p[0] = p[m];
-      p[m] = t;
-
-      /* partition loop */
-      i=1;
-      j=n-1;
-      for(;;) {
-         /* handling of equality is crucial here */
-         /* for sentinels & efficiency with duplicates */
-         for (;;++i) {
-            if (!STBTT__COMPARE(&p[i], &p[0])) break;
-         }
-         for (;;--j) {
-            if (!STBTT__COMPARE(&p[0], &p[j])) break;
-         }
-         /* make sure we haven't crossed */
-         if (i >= j) break;
-         t = p[i];
-         p[i] = p[j];
-         p[j] = t;
-
-         ++i;
-         --j;
-      }
-      /* recurse on smaller side, iterate on larger */
-      if (j < (n-i)) {
-         stbtt__sort_edges_quicksort(p,j);
-         p = p+i;
-         n = n-i;
-      } else {
-         stbtt__sort_edges_quicksort(p+i, n-i);
-         n = j;
-      }
-   }
-}
-
-static void stbtt__sort_edges(stbtt__edge *p, int n)
-{
-   stbtt__sort_edges_quicksort(p, n);
-   stbtt__sort_edges_ins_sort(p, n);
-}
-
-typedef struct
-{
-   float x,y;
+#define STBTT__COMPARE(a, b) ((a)->y0 < (b)->y0)
+
+static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n) {
+    int i, j;
+    for (i = 1; i < n; ++i) {
+        stbtt__edge t = p[i], *a = &t;
+        j = i;
+        while (j > 0) {
+            stbtt__edge *b = &p[j - 1];
+            int          c = STBTT__COMPARE(a, b);
+            if (!c)
+                break;
+            p[j] = p[j - 1];
+            --j;
+        }
+        if (i != j)
+            p[j] = t;
+    }
+}
+
+static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) {
+    /* threshold for transitioning to insertion sort */
+    while (n > 12) {
+        stbtt__edge t;
+        int         c01, c12, c, m, i, j;
+
+        /* compute median of three */
+        m   = n >> 1;
+        c01 = STBTT__COMPARE(&p[0], &p[m]);
+        c12 = STBTT__COMPARE(&p[m], &p[n - 1]);
+        /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
+        if (c01 != c12) {
+            /* otherwise, we'll need to swap something else to middle */
+            int z;
+            c = STBTT__COMPARE(&p[0], &p[n - 1]);
+            /* 0>mid && mid<n:  0>n => n; 0<n => 0 */
+            /* 0<mid && mid>n:  0>n => 0; 0<n => n */
+            z    = (c == c12) ? 0 : n - 1;
+            t    = p[z];
+            p[z] = p[m];
+            p[m] = t;
+        }
+        /* now p[m] is the median-of-three */
+        /* swap it to the beginning so it won't move around */
+        t    = p[0];
+        p[0] = p[m];
+        p[m] = t;
+
+        /* partition loop */
+        i = 1;
+        j = n - 1;
+        for (;;) {
+            /* handling of equality is crucial here */
+            /* for sentinels & efficiency with duplicates */
+            for (;; ++i) {
+                if (!STBTT__COMPARE(&p[i], &p[0]))
+                    break;
+            }
+            for (;; --j) {
+                if (!STBTT__COMPARE(&p[0], &p[j]))
+                    break;
+            }
+            /* make sure we haven't crossed */
+            if (i >= j)
+                break;
+            t    = p[i];
+            p[i] = p[j];
+            p[j] = t;
+
+            ++i;
+            --j;
+        }
+        /* recurse on smaller side, iterate on larger */
+        if (j < (n - i)) {
+            stbtt__sort_edges_quicksort(p, j);
+            p = p + i;
+            n = n - i;
+        } else {
+            stbtt__sort_edges_quicksort(p + i, n - i);
+            n = j;
+        }
+    }
+}
+
+static void stbtt__sort_edges(stbtt__edge *p, int n) {
+    stbtt__sort_edges_quicksort(p, n);
+    stbtt__sort_edges_ins_sort(p, n);
+}
+
+typedef struct {
+    float x, y;
 } stbtt__point;
 
-static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata)
-{
-   float y_scale_inv = invert ? -scale_y : scale_y;
-   stbtt__edge *e;
-   int n,i,j,k,m;
+static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x,
+                             float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert,
+                             void *userdata) {
+    float        y_scale_inv = invert ? -scale_y : scale_y;
+    stbtt__edge *e;
+    int          n, i, j, k, m;
 #if STBTT_RASTERIZER_VERSION == 1
-   int vsubsample = result->h < 8 ? 15 : 5;
+    int vsubsample = result->h < 8 ? 15 : 5;
 #elif STBTT_RASTERIZER_VERSION == 2
-   int vsubsample = 1;
+    int vsubsample = 1;
 #else
-   #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
+#error "Unrecognized value of STBTT_RASTERIZER_VERSION"
 #endif
-   // vsubsample should divide 255 evenly; otherwise we won't reach full opacity
-
-   // now we have to blow out the windings into explicit edge lists
-   n = 0;
-   for (i=0; i < windings; ++i)
-      n += wcount[i];
-
-   e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel
-   if (e == 0) return;
-   n = 0;
-
-   m=0;
-   for (i=0; i < windings; ++i) {
-      stbtt__point *p = pts + m;
-      m += wcount[i];
-      j = wcount[i]-1;
-      for (k=0; k < wcount[i]; j=k++) {
-         int a=k,b=j;
-         // skip the edge if horizontal
-         if (p[j].y == p[k].y)
-            continue;
-         // add edge from j to k to the list
-         e[n].invert = 0;
-         if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
-            e[n].invert = 1;
-            a=j,b=k;
-         }
-         e[n].x0 = p[a].x * scale_x + shift_x;
-         e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
-         e[n].x1 = p[b].x * scale_x + shift_x;
-         e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
-         ++n;
-      }
-   }
+    // vsubsample should divide 255 evenly; otherwise we won't reach full opacity
+
+    // now we have to blow out the windings into explicit edge lists
+    n = 0;
+    for (i = 0; i < windings; ++i)
+        n += wcount[i];
+
+    e = (stbtt__edge *)STBTT_malloc(sizeof(*e) * (n + 1), userdata); // add an extra one as a sentinel
+    if (e == 0)
+        return;
+    n = 0;
+
+    m = 0;
+    for (i = 0; i < windings; ++i) {
+        stbtt__point *p = pts + m;
+        m += wcount[i];
+        j = wcount[i] - 1;
+        for (k = 0; k < wcount[i]; j = k++) {
+            int a = k, b = j;
+            // skip the edge if horizontal
+            if (p[j].y == p[k].y)
+                continue;
+            // add edge from j to k to the list
+            e[n].invert = 0;
+            if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
+                e[n].invert = 1;
+                a = j, b = k;
+            }
+            e[n].x0 = p[a].x * scale_x + shift_x;
+            e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
+            e[n].x1 = p[b].x * scale_x + shift_x;
+            e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
+            ++n;
+        }
+    }
 
-   // now sort the edges by their highest point (should snap to integer, and then by x)
-   //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
-   stbtt__sort_edges(e, n);
+    // now sort the edges by their highest point (should snap to integer, and then by x)
+    // STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
+    stbtt__sort_edges(e, n);
 
-   // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
-   stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
+    // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
+    stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
 
-   STBTT_free(e, userdata);
+    STBTT_free(e, userdata);
 }
 
-static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
-{
-   if (!points) return; // during first pass, it's unallocated
-   points[n].x = x;
-   points[n].y = y;
+static void stbtt__add_point(stbtt__point *points, int n, float x, float y) {
+    if (!points)
+        return; // during first pass, it's unallocated
+    points[n].x = x;
+    points[n].y = y;
 }
 
 // tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
-static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
-{
-   // midpoint
-   float mx = (x0 + 2*x1 + x2)/4;
-   float my = (y0 + 2*y1 + y2)/4;
-   // versus directly drawn line
-   float dx = (x0+x2)/2 - mx;
-   float dy = (y0+y2)/2 - my;
-   if (n > 16) // 65536 segments on one curve better be enough!
-      return 1;
-   if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA
-      stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
-      stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
-   } else {
-      stbtt__add_point(points, *num_points,x2,y2);
-      *num_points = *num_points+1;
-   }
-   return 1;
-}
-
-static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n)
-{
-   // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough
-   float dx0 = x1-x0;
-   float dy0 = y1-y0;
-   float dx1 = x2-x1;
-   float dy1 = y2-y1;
-   float dx2 = x3-x2;
-   float dy2 = y3-y2;
-   float dx = x3-x0;
-   float dy = y3-y0;
-   float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2));
-   float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy);
-   float flatness_squared = longlen*longlen-shortlen*shortlen;
-
-   if (n > 16) // 65536 segments on one curve better be enough!
-      return;
-
-   if (flatness_squared > objspace_flatness_squared) {
-      float x01 = (x0+x1)/2;
-      float y01 = (y0+y1)/2;
-      float x12 = (x1+x2)/2;
-      float y12 = (y1+y2)/2;
-      float x23 = (x2+x3)/2;
-      float y23 = (y2+y3)/2;
-
-      float xa = (x01+x12)/2;
-      float ya = (y01+y12)/2;
-      float xb = (x12+x23)/2;
-      float yb = (y12+y23)/2;
-
-      float mx = (xa+xb)/2;
-      float my = (ya+yb)/2;
-
-      stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1);
-      stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1);
-   } else {
-      stbtt__add_point(points, *num_points,x3,y3);
-      *num_points = *num_points+1;
-   }
+static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1,
+                                  float x2, float y2, float objspace_flatness_squared, int n) {
+    // midpoint
+    float mx = (x0 + 2 * x1 + x2) / 4;
+    float my = (y0 + 2 * y1 + y2) / 4;
+    // versus directly drawn line
+    float dx = (x0 + x2) / 2 - mx;
+    float dy = (y0 + y2) / 2 - my;
+    if (n > 16) // 65536 segments on one curve better be enough!
+        return 1;
+    if (dx * dx + dy * dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA
+        stbtt__tesselate_curve(points, num_points, x0, y0, (x0 + x1) / 2.0f, (y0 + y1) / 2.0f, mx, my,
+                               objspace_flatness_squared, n + 1);
+        stbtt__tesselate_curve(points, num_points, mx, my, (x1 + x2) / 2.0f, (y1 + y2) / 2.0f, x2, y2,
+                               objspace_flatness_squared, n + 1);
+    } else {
+        stbtt__add_point(points, *num_points, x2, y2);
+        *num_points = *num_points + 1;
+    }
+    return 1;
+}
+
+static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1,
+                                   float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) {
+    // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough
+    float dx0              = x1 - x0;
+    float dy0              = y1 - y0;
+    float dx1              = x2 - x1;
+    float dy1              = y2 - y1;
+    float dx2              = x3 - x2;
+    float dy2              = y3 - y2;
+    float dx               = x3 - x0;
+    float dy               = y3 - y0;
+    float longlen          = (float)(STBTT_sqrt(dx0 * dx0 + dy0 * dy0) + STBTT_sqrt(dx1 * dx1 + dy1 * dy1) +
+                            STBTT_sqrt(dx2 * dx2 + dy2 * dy2));
+    float shortlen         = (float)STBTT_sqrt(dx * dx + dy * dy);
+    float flatness_squared = longlen * longlen - shortlen * shortlen;
+
+    if (n > 16) // 65536 segments on one curve better be enough!
+        return;
+
+    if (flatness_squared > objspace_flatness_squared) {
+        float x01 = (x0 + x1) / 2;
+        float y01 = (y0 + y1) / 2;
+        float x12 = (x1 + x2) / 2;
+        float y12 = (y1 + y2) / 2;
+        float x23 = (x2 + x3) / 2;
+        float y23 = (y2 + y3) / 2;
+
+        float xa = (x01 + x12) / 2;
+        float ya = (y01 + y12) / 2;
+        float xb = (x12 + x23) / 2;
+        float yb = (y12 + y23) / 2;
+
+        float mx = (xa + xb) / 2;
+        float my = (ya + yb) / 2;
+
+        stbtt__tesselate_cubic(points, num_points, x0, y0, x01, y01, xa, ya, mx, my, objspace_flatness_squared, n + 1);
+        stbtt__tesselate_cubic(points, num_points, mx, my, xb, yb, x23, y23, x3, y3, objspace_flatness_squared, n + 1);
+    } else {
+        stbtt__add_point(points, *num_points, x3, y3);
+        *num_points = *num_points + 1;
+    }
 }
 
 // returns number of contours
-static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
-{
-   stbtt__point *points=0;
-   int num_points=0;
-
-   float objspace_flatness_squared = objspace_flatness * objspace_flatness;
-   int i,n=0,start=0, pass;
-
-   // count how many "moves" there are to get the contour count
-   for (i=0; i < num_verts; ++i)
-      if (vertices[i].type == STBTT_vmove)
-         ++n;
-
-   *num_contours = n;
-   if (n == 0) return 0;
-
-   *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
-
-   if (*contour_lengths == 0) {
-      *num_contours = 0;
-      return 0;
-   }
-
-   // make two passes through the points so we don't need to realloc
-   for (pass=0; pass < 2; ++pass) {
-      float x=0,y=0;
-      if (pass == 1) {
-         points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata);
-         if (points == NULL) goto error;
-      }
-      num_points = 0;
-      n= -1;
-      for (i=0; i < num_verts; ++i) {
-         switch (vertices[i].type) {
+static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness,
+                                         int **contour_lengths, int *num_contours, void *userdata) {
+    stbtt__point *points     = 0;
+    int           num_points = 0;
+
+    float objspace_flatness_squared = objspace_flatness * objspace_flatness;
+    int   i, n = 0, start = 0, pass;
+
+    // count how many "moves" there are to get the contour count
+    for (i = 0; i < num_verts; ++i)
+        if (vertices[i].type == STBTT_vmove)
+            ++n;
+
+    *num_contours = n;
+    if (n == 0)
+        return 0;
+
+    *contour_lengths = (int *)STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
+
+    if (*contour_lengths == 0) {
+        *num_contours = 0;
+        return 0;
+    }
+
+    // make two passes through the points so we don't need to realloc
+    for (pass = 0; pass < 2; ++pass) {
+        float x = 0, y = 0;
+        if (pass == 1) {
+            points = (stbtt__point *)STBTT_malloc(num_points * sizeof(points[0]), userdata);
+            if (points == NULL)
+                goto error;
+        }
+        num_points = 0;
+        n          = -1;
+        for (i = 0; i < num_verts; ++i) {
+            switch (vertices[i].type) {
             case STBTT_vmove:
-               // start the next contour
-               if (n >= 0)
-                  (*contour_lengths)[n] = num_points - start;
-               ++n;
-               start = num_points;
-
-               x = vertices[i].x, y = vertices[i].y;
-               stbtt__add_point(points, num_points++, x,y);
-               break;
+                // start the next contour
+                if (n >= 0)
+                    (*contour_lengths)[n] = num_points - start;
+                ++n;
+                start = num_points;
+
+                x = vertices[i].x, y = vertices[i].y;
+                stbtt__add_point(points, num_points++, x, y);
+                break;
             case STBTT_vline:
-               x = vertices[i].x, y = vertices[i].y;
-               stbtt__add_point(points, num_points++, x, y);
-               break;
+                x = vertices[i].x, y = vertices[i].y;
+                stbtt__add_point(points, num_points++, x, y);
+                break;
             case STBTT_vcurve:
-               stbtt__tesselate_curve(points, &num_points, x,y,
-                                        vertices[i].cx, vertices[i].cy,
-                                        vertices[i].x,  vertices[i].y,
-                                        objspace_flatness_squared, 0);
-               x = vertices[i].x, y = vertices[i].y;
-               break;
+                stbtt__tesselate_curve(points, &num_points, x, y, vertices[i].cx, vertices[i].cy, vertices[i].x,
+                                       vertices[i].y, objspace_flatness_squared, 0);
+                x = vertices[i].x, y = vertices[i].y;
+                break;
             case STBTT_vcubic:
-               stbtt__tesselate_cubic(points, &num_points, x,y,
-                                        vertices[i].cx, vertices[i].cy,
-                                        vertices[i].cx1, vertices[i].cy1,
-                                        vertices[i].x,  vertices[i].y,
-                                        objspace_flatness_squared, 0);
-               x = vertices[i].x, y = vertices[i].y;
-               break;
-         }
-      }
-      (*contour_lengths)[n] = num_points - start;
-   }
+                stbtt__tesselate_cubic(points, &num_points, x, y, vertices[i].cx, vertices[i].cy, vertices[i].cx1,
+                                       vertices[i].cy1, vertices[i].x, vertices[i].y, objspace_flatness_squared, 0);
+                x = vertices[i].x, y = vertices[i].y;
+                break;
+            }
+        }
+        (*contour_lengths)[n] = num_points - start;
+    }
 
-   return points;
+    return points;
 error:
-   STBTT_free(points, userdata);
-   STBTT_free(*contour_lengths, userdata);
-   *contour_lengths = 0;
-   *num_contours = 0;
-   return NULL;
-}
-
-STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata)
-{
-   float scale            = scale_x > scale_y ? scale_y : scale_x;
-   int winding_count      = 0;
-   int *winding_lengths   = NULL;
-   stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
-   if (windings) {
-      stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
-      STBTT_free(winding_lengths, userdata);
-      STBTT_free(windings, userdata);
-   }
-}
-
-STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
-{
-   STBTT_free(bitmap, userdata);
-}
-
-STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff)
-{
-   int ix0,iy0,ix1,iy1;
-   stbtt__bitmap gbm;
-   stbtt_vertex *vertices;
-   int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
-
-   if (scale_x == 0) scale_x = scale_y;
-   if (scale_y == 0) {
-      if (scale_x == 0) {
-         STBTT_free(vertices, info->userdata);
-         return NULL;
-      }
-      scale_y = scale_x;
-   }
+    STBTT_free(points, userdata);
+    STBTT_free(*contour_lengths, userdata);
+    *contour_lengths = 0;
+    *num_contours    = 0;
+    return NULL;
+}
+
+STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts,
+                               float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off,
+                               int invert, void *userdata) {
+    float         scale           = scale_x > scale_y ? scale_y : scale_x;
+    int           winding_count   = 0;
+    int          *winding_lengths = NULL;
+    stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths,
+                                                 &winding_count, userdata);
+    if (windings) {
+        stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off,
+                         y_off, invert, userdata);
+        STBTT_free(winding_lengths, userdata);
+        STBTT_free(windings, userdata);
+    }
+}
+
+STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) { STBTT_free(bitmap, userdata); }
+
+STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y,
+                                                      float shift_x, float shift_y, int glyph, int *width, int *height,
+                                                      int *xoff, int *yoff) {
+    int           ix0, iy0, ix1, iy1;
+    stbtt__bitmap gbm;
+    stbtt_vertex *vertices;
+    int           num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
+
+    if (scale_x == 0)
+        scale_x = scale_y;
+    if (scale_y == 0) {
+        if (scale_x == 0) {
+            STBTT_free(vertices, info->userdata);
+            return NULL;
+        }
+        scale_y = scale_x;
+    }
 
-   stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
+    stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, &ix1, &iy1);
 
-   // now we get the size
-   gbm.w = (ix1 - ix0);
-   gbm.h = (iy1 - iy0);
-   gbm.pixels = NULL; // in case we error
+    // now we get the size
+    gbm.w      = (ix1 - ix0);
+    gbm.h      = (iy1 - iy0);
+    gbm.pixels = NULL; // in case we error
 
-   if (width ) *width  = gbm.w;
-   if (height) *height = gbm.h;
-   if (xoff  ) *xoff   = ix0;
-   if (yoff  ) *yoff   = iy0;
+    if (width)
+        *width = gbm.w;
+    if (height)
+        *height = gbm.h;
+    if (xoff)
+        *xoff = ix0;
+    if (yoff)
+        *yoff = iy0;
 
-   if (gbm.w && gbm.h) {
-      gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
-      if (gbm.pixels) {
-         gbm.stride = gbm.w;
+    if (gbm.w && gbm.h) {
+        gbm.pixels = (unsigned char *)STBTT_malloc(gbm.w * gbm.h, info->userdata);
+        if (gbm.pixels) {
+            gbm.stride = gbm.w;
 
-         stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
-      }
-   }
-   STBTT_free(vertices, info->userdata);
-   return gbm.pixels;
+            stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1,
+                            info->userdata);
+        }
+    }
+    STBTT_free(vertices, info->userdata);
+    return gbm.pixels;
 }
 
-STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff)
-{
-   return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
+STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph,
+                                              int *width, int *height, int *xoff, int *yoff) {
+    return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
 }
 
-STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph)
-{
-   int ix0,iy0;
-   stbtt_vertex *vertices;
-   int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
-   stbtt__bitmap gbm;
+STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h,
+                                             int out_stride, float scale_x, float scale_y, float shift_x, float shift_y,
+                                             int glyph) {
+    int           ix0, iy0;
+    stbtt_vertex *vertices;
+    int           num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
+    stbtt__bitmap gbm;
 
-   stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
-   gbm.pixels = output;
-   gbm.w = out_w;
-   gbm.h = out_h;
-   gbm.stride = out_stride;
+    stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, 0, 0);
+    gbm.pixels = output;
+    gbm.w      = out_w;
+    gbm.h      = out_h;
+    gbm.stride = out_stride;
 
-   if (gbm.w && gbm.h)
-      stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
+    if (gbm.w && gbm.h)
+        stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1,
+                        info->userdata);
 
-   STBTT_free(vertices, info->userdata);
+    STBTT_free(vertices, info->userdata);
 }
 
-STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph)
-{
-   stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph);
+STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h,
+                                     int out_stride, float scale_x, float scale_y, int glyph) {
+    stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, glyph);
 }
 
-STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
-{
-   return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
+STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y,
+                                                          float shift_x, float shift_y, int codepoint, int *width,
+                                                          int *height, int *xoff, int *yoff) {
+    return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint),
+                                        width, height, xoff, yoff);
 }
 
-STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint)
-{
-   stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info,codepoint));
+STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w,
+                                                          int out_h, int out_stride, float scale_x, float scale_y,
+                                                          float shift_x, float shift_y, int oversample_x,
+                                                          int oversample_y, float *sub_x, float *sub_y, int codepoint) {
+    stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y,
+                                           oversample_x, oversample_y, sub_x, sub_y,
+                                           stbtt_FindGlyphIndex(info, codepoint));
 }
 
-STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint)
-{
-   stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
+STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w,
+                                                 int out_h, int out_stride, float scale_x, float scale_y, float shift_x,
+                                                 float shift_y, int codepoint) {
+    stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y,
+                                  stbtt_FindGlyphIndex(info, codepoint));
 }
 
-STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
-{
-   return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
+STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y,
+                                                  int codepoint, int *width, int *height, int *xoff, int *yoff) {
+    return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, codepoint, width, height, xoff, yoff);
 }
 
-STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint)
-{
-   stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
+STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h,
+                                         int out_stride, float scale_x, float scale_y, int codepoint) {
+    stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, codepoint);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -3810,71 +3927,70 @@ STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned ch
 //
 // This is SUPER-CRAPPY packing to keep source code small
 
-static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset,  // font location (use offset=0 for plain .ttf)
-                                float pixel_height,                     // height of font in pixels
-                                unsigned char *pixels, int pw, int ph,  // bitmap to be filled in
-                                int first_char, int num_chars,          // characters to bake
-                                stbtt_bakedchar *chardata)
-{
-   float scale;
-   int x,y,bottom_y, i;
-   stbtt_fontinfo f;
-   f.userdata = NULL;
-   if (!stbtt_InitFont(&f, data, offset))
-      return -1;
-   STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
-   x=y=1;
-   bottom_y = 1;
-
-   scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
-
-   for (i=0; i < num_chars; ++i) {
-      int advance, lsb, x0,y0,x1,y1,gw,gh;
-      int g = stbtt_FindGlyphIndex(&f, first_char + i);
-      stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
-      stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
-      gw = x1-x0;
-      gh = y1-y0;
-      if (x + gw + 1 >= pw)
-         y = bottom_y, x = 1; // advance to next row
-      if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row
-         return -i;
-      STBTT_assert(x+gw < pw);
-      STBTT_assert(y+gh < ph);
-      stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
-      chardata[i].x0 = (stbtt_int16) x;
-      chardata[i].y0 = (stbtt_int16) y;
-      chardata[i].x1 = (stbtt_int16) (x + gw);
-      chardata[i].y1 = (stbtt_int16) (y + gh);
-      chardata[i].xadvance = scale * advance;
-      chardata[i].xoff     = (float) x0;
-      chardata[i].yoff     = (float) y0;
-      x = x + gw + 1;
-      if (y+gh+1 > bottom_y)
-         bottom_y = y+gh+1;
-   }
-   return bottom_y;
-}
-
-STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
-{
-   float d3d_bias = opengl_fillrule ? 0 : -0.5f;
-   float ipw = 1.0f / pw, iph = 1.0f / ph;
-   const stbtt_bakedchar *b = chardata + char_index;
-   int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
-   int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
-
-   q->x0 = round_x + d3d_bias;
-   q->y0 = round_y + d3d_bias;
-   q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
-   q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
-
-   q->s0 = b->x0 * ipw;
-   q->t0 = b->y0 * iph;
-   q->s1 = b->x1 * ipw;
-   q->t1 = b->y1 * iph;
-
-   *xpos += b->xadvance;
+static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
+                                         float          pixel_height,     // height of font in pixels
+                                         unsigned char *pixels, int pw, int ph, // bitmap to be filled in
+                                         int first_char, int num_chars,         // characters to bake
+                                         stbtt_bakedchar *chardata) {
+    float          scale;
+    int            x, y, bottom_y, i;
+    stbtt_fontinfo f;
+    f.userdata = NULL;
+    if (!stbtt_InitFont(&f, data, offset))
+        return -1;
+    STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels
+    x = y    = 1;
+    bottom_y = 1;
+
+    scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
+
+    for (i = 0; i < num_chars; ++i) {
+        int advance, lsb, x0, y0, x1, y1, gw, gh;
+        int g = stbtt_FindGlyphIndex(&f, first_char + i);
+        stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
+        stbtt_GetGlyphBitmapBox(&f, g, scale, scale, &x0, &y0, &x1, &y1);
+        gw = x1 - x0;
+        gh = y1 - y0;
+        if (x + gw + 1 >= pw)
+            y = bottom_y, x = 1; // advance to next row
+        if (y + gh + 1 >= ph)    // check if it fits vertically AFTER potentially moving to next row
+            return -i;
+        STBTT_assert(x + gw < pw);
+        STBTT_assert(y + gh < ph);
+        stbtt_MakeGlyphBitmap(&f, pixels + x + y * pw, gw, gh, pw, scale, scale, g);
+        chardata[i].x0       = (stbtt_int16)x;
+        chardata[i].y0       = (stbtt_int16)y;
+        chardata[i].x1       = (stbtt_int16)(x + gw);
+        chardata[i].y1       = (stbtt_int16)(y + gh);
+        chardata[i].xadvance = scale * advance;
+        chardata[i].xoff     = (float)x0;
+        chardata[i].yoff     = (float)y0;
+        x                    = x + gw + 1;
+        if (y + gh + 1 > bottom_y)
+            bottom_y = y + gh + 1;
+    }
+    return bottom_y;
+}
+
+STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos,
+                                  float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) {
+    float                  d3d_bias = opengl_fillrule ? 0 : -0.5f;
+    float                  ipw = 1.0f / pw, iph = 1.0f / ph;
+    const stbtt_bakedchar *b       = chardata + char_index;
+    int                    round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
+    int                    round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
+
+    q->x0 = round_x + d3d_bias;
+    q->y0 = round_y + d3d_bias;
+    q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
+    q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
+
+    q->s0 = b->x0 * ipw;
+    q->t0 = b->y0 * iph;
+    q->s1 = b->x1 * ipw;
+    q->t1 = b->y1 * iph;
+
+    *xpos += b->xadvance;
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -3897,53 +4013,48 @@ typedef int stbrp_coord;
 //                                                                                //
 ////////////////////////////////////////////////////////////////////////////////////
 
-typedef struct
-{
-   int width,height;
-   int x,y,bottom_y;
+typedef struct {
+    int width, height;
+    int x, y, bottom_y;
 } stbrp_context;
 
-typedef struct
-{
-   unsigned char x;
+typedef struct {
+    unsigned char x;
 } stbrp_node;
 
-struct stbrp_rect
-{
-   stbrp_coord x,y;
-   int id,w,h,was_packed;
+struct stbrp_rect {
+    stbrp_coord x, y;
+    int         id, w, h, was_packed;
 };
 
-static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes)
-{
-   con->width  = pw;
-   con->height = ph;
-   con->x = 0;
-   con->y = 0;
-   con->bottom_y = 0;
-   STBTT__NOTUSED(nodes);
-   STBTT__NOTUSED(num_nodes);
-}
-
-static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
-{
-   int i;
-   for (i=0; i < num_rects; ++i) {
-      if (con->x + rects[i].w > con->width) {
-         con->x = 0;
-         con->y = con->bottom_y;
-      }
-      if (con->y + rects[i].h > con->height)
-         break;
-      rects[i].x = con->x;
-      rects[i].y = con->y;
-      rects[i].was_packed = 1;
-      con->x += rects[i].w;
-      if (con->y + rects[i].h > con->bottom_y)
-         con->bottom_y = con->y + rects[i].h;
-   }
-   for (   ; i < num_rects; ++i)
-      rects[i].was_packed = 0;
+static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) {
+    con->width    = pw;
+    con->height   = ph;
+    con->x        = 0;
+    con->y        = 0;
+    con->bottom_y = 0;
+    STBTT__NOTUSED(nodes);
+    STBTT__NOTUSED(num_nodes);
+}
+
+static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) {
+    int i;
+    for (i = 0; i < num_rects; ++i) {
+        if (con->x + rects[i].w > con->width) {
+            con->x = 0;
+            con->y = con->bottom_y;
+        }
+        if (con->y + rects[i].h > con->height)
+            break;
+        rects[i].x          = con->x;
+        rects[i].y          = con->y;
+        rects[i].was_packed = 1;
+        con->x += rects[i].w;
+        if (con->y + rects[i].h > con->bottom_y)
+            con->bottom_y = con->y + rects[i].h;
+    }
+    for (; i < num_rects; ++i)
+        rects[i].was_packed = 0;
 }
 #endif
 
@@ -3954,437 +4065,415 @@ static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rect
 // This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
 // stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
 
-STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context)
-{
-   stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context)            ,alloc_context);
-   int            num_nodes = pw - padding;
-   stbrp_node    *nodes   = (stbrp_node    *) STBTT_malloc(sizeof(*nodes  ) * num_nodes,alloc_context);
-
-   if (context == NULL || nodes == NULL) {
-      if (context != NULL) STBTT_free(context, alloc_context);
-      if (nodes   != NULL) STBTT_free(nodes  , alloc_context);
-      return 0;
-   }
-
-   spc->user_allocator_context = alloc_context;
-   spc->width = pw;
-   spc->height = ph;
-   spc->pixels = pixels;
-   spc->pack_info = context;
-   spc->nodes = nodes;
-   spc->padding = padding;
-   spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
-   spc->h_oversample = 1;
-   spc->v_oversample = 1;
-   spc->skip_missing = 0;
-
-   stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
-
-   if (pixels)
-      STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
-
-   return 1;
-}
-
-STBTT_DEF void stbtt_PackEnd  (stbtt_pack_context *spc)
-{
-   STBTT_free(spc->nodes    , spc->user_allocator_context);
-   STBTT_free(spc->pack_info, spc->user_allocator_context);
-}
-
-STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
-{
-   STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
-   STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
-   if (h_oversample <= STBTT_MAX_OVERSAMPLE)
-      spc->h_oversample = h_oversample;
-   if (v_oversample <= STBTT_MAX_OVERSAMPLE)
-      spc->v_oversample = v_oversample;
-}
-
-STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
-{
-   spc->skip_missing = skip;
-}
-
-#define STBTT__OVER_MASK  (STBTT_MAX_OVERSAMPLE-1)
-
-static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
-{
-   unsigned char buffer[STBTT_MAX_OVERSAMPLE];
-   int safe_w = w - kernel_width;
-   int j;
-   STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
-   for (j=0; j < h; ++j) {
-      int i;
-      unsigned int total;
-      STBTT_memset(buffer, 0, kernel_width);
-
-      total = 0;
-
-      // make kernel_width a constant in common cases so compiler can optimize out the divide
-      switch (kernel_width) {
-         case 2:
-            for (i=0; i <= safe_w; ++i) {
-               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-               pixels[i] = (unsigned char) (total / 2);
+STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes,
+                              int padding, void *alloc_context) {
+    stbrp_context *context   = (stbrp_context *)STBTT_malloc(sizeof(*context), alloc_context);
+    int            num_nodes = pw - padding;
+    stbrp_node    *nodes     = (stbrp_node *)STBTT_malloc(sizeof(*nodes) * num_nodes, alloc_context);
+
+    if (context == NULL || nodes == NULL) {
+        if (context != NULL)
+            STBTT_free(context, alloc_context);
+        if (nodes != NULL)
+            STBTT_free(nodes, alloc_context);
+        return 0;
+    }
+
+    spc->user_allocator_context = alloc_context;
+    spc->width                  = pw;
+    spc->height                 = ph;
+    spc->pixels                 = pixels;
+    spc->pack_info              = context;
+    spc->nodes                  = nodes;
+    spc->padding                = padding;
+    spc->stride_in_bytes        = stride_in_bytes != 0 ? stride_in_bytes : pw;
+    spc->h_oversample           = 1;
+    spc->v_oversample           = 1;
+    spc->skip_missing           = 0;
+
+    stbrp_init_target(context, pw - padding, ph - padding, nodes, num_nodes);
+
+    if (pixels)
+        STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels
+
+    return 1;
+}
+
+STBTT_DEF void stbtt_PackEnd(stbtt_pack_context *spc) {
+    STBTT_free(spc->nodes, spc->user_allocator_context);
+    STBTT_free(spc->pack_info, spc->user_allocator_context);
+}
+
+STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample,
+                                         unsigned int v_oversample) {
+    STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
+    STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
+    if (h_oversample <= STBTT_MAX_OVERSAMPLE)
+        spc->h_oversample = h_oversample;
+    if (v_oversample <= STBTT_MAX_OVERSAMPLE)
+        spc->v_oversample = v_oversample;
+}
+
+STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip) { spc->skip_missing = skip; }
+
+#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE - 1)
+
+static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) {
+    unsigned char buffer[STBTT_MAX_OVERSAMPLE];
+    int           safe_w = w - kernel_width;
+    int           j;
+    STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
+    for (j = 0; j < h; ++j) {
+        int          i;
+        unsigned int total;
+        STBTT_memset(buffer, 0, kernel_width);
+
+        total = 0;
+
+        // make kernel_width a constant in common cases so compiler can optimize out the divide
+        switch (kernel_width) {
+        case 2:
+            for (i = 0; i <= safe_w; ++i) {
+                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
+                pixels[i]                                     = (unsigned char)(total / 2);
             }
             break;
-         case 3:
-            for (i=0; i <= safe_w; ++i) {
-               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-               pixels[i] = (unsigned char) (total / 3);
+        case 3:
+            for (i = 0; i <= safe_w; ++i) {
+                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
+                pixels[i]                                     = (unsigned char)(total / 3);
             }
             break;
-         case 4:
-            for (i=0; i <= safe_w; ++i) {
-               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-               pixels[i] = (unsigned char) (total / 4);
+        case 4:
+            for (i = 0; i <= safe_w; ++i) {
+                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
+                pixels[i]                                     = (unsigned char)(total / 4);
             }
             break;
-         case 5:
-            for (i=0; i <= safe_w; ++i) {
-               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-               pixels[i] = (unsigned char) (total / 5);
+        case 5:
+            for (i = 0; i <= safe_w; ++i) {
+                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
+                pixels[i]                                     = (unsigned char)(total / 5);
             }
             break;
-         default:
-            for (i=0; i <= safe_w; ++i) {
-               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-               pixels[i] = (unsigned char) (total / kernel_width);
+        default:
+            for (i = 0; i <= safe_w; ++i) {
+                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
+                pixels[i]                                     = (unsigned char)(total / kernel_width);
             }
             break;
-      }
-
-      for (; i < w; ++i) {
-         STBTT_assert(pixels[i] == 0);
-         total -= buffer[i & STBTT__OVER_MASK];
-         pixels[i] = (unsigned char) (total / kernel_width);
-      }
-
-      pixels += stride_in_bytes;
-   }
-}
-
-static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
-{
-   unsigned char buffer[STBTT_MAX_OVERSAMPLE];
-   int safe_h = h - kernel_width;
-   int j;
-   STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
-   for (j=0; j < w; ++j) {
-      int i;
-      unsigned int total;
-      STBTT_memset(buffer, 0, kernel_width);
-
-      total = 0;
-
-      // make kernel_width a constant in common cases so compiler can optimize out the divide
-      switch (kernel_width) {
-         case 2:
-            for (i=0; i <= safe_h; ++i) {
-               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-               pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
+        }
+
+        for (; i < w; ++i) {
+            STBTT_assert(pixels[i] == 0);
+            total -= buffer[i & STBTT__OVER_MASK];
+            pixels[i] = (unsigned char)(total / kernel_width);
+        }
+
+        pixels += stride_in_bytes;
+    }
+}
+
+static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) {
+    unsigned char buffer[STBTT_MAX_OVERSAMPLE];
+    int           safe_h = h - kernel_width;
+    int           j;
+    STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
+    for (j = 0; j < w; ++j) {
+        int          i;
+        unsigned int total;
+        STBTT_memset(buffer, 0, kernel_width);
+
+        total = 0;
+
+        // make kernel_width a constant in common cases so compiler can optimize out the divide
+        switch (kernel_width) {
+        case 2:
+            for (i = 0; i <= safe_h; ++i) {
+                total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
+                pixels[i * stride_in_bytes]                   = (unsigned char)(total / 2);
             }
             break;
-         case 3:
-            for (i=0; i <= safe_h; ++i) {
-               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-               pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
+        case 3:
+            for (i = 0; i <= safe_h; ++i) {
+                total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
+                pixels[i * stride_in_bytes]                   = (unsigned char)(total / 3);
             }
             break;
-         case 4:
-            for (i=0; i <= safe_h; ++i) {
-               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-               pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
+        case 4:
+            for (i = 0; i <= safe_h; ++i) {
+                total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
+                pixels[i * stride_in_bytes]                   = (unsigned char)(total / 4);
             }
             break;
-         case 5:
-            for (i=0; i <= safe_h; ++i) {
-               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-               pixels[i*stride_in_bytes] = (unsigned char) (total / 5);
+        case 5:
+            for (i = 0; i <= safe_h; ++i) {
+                total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
+                pixels[i * stride_in_bytes]                   = (unsigned char)(total / 5);
             }
             break;
-         default:
-            for (i=0; i <= safe_h; ++i) {
-               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-               pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
+        default:
+            for (i = 0; i <= safe_h; ++i) {
+                total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
+                buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
+                pixels[i * stride_in_bytes]                   = (unsigned char)(total / kernel_width);
             }
             break;
-      }
+        }
 
-      for (; i < h; ++i) {
-         STBTT_assert(pixels[i*stride_in_bytes] == 0);
-         total -= buffer[i & STBTT__OVER_MASK];
-         pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
-      }
+        for (; i < h; ++i) {
+            STBTT_assert(pixels[i * stride_in_bytes] == 0);
+            total -= buffer[i & STBTT__OVER_MASK];
+            pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width);
+        }
 
-      pixels += 1;
-   }
+        pixels += 1;
+    }
 }
 
-static float stbtt__oversample_shift(int oversample)
-{
-   if (!oversample)
-      return 0.0f;
+static float stbtt__oversample_shift(int oversample) {
+    if (!oversample)
+        return 0.0f;
 
-   // The prefilter is a box filter of width "oversample",
-   // which shifts phase by (oversample - 1)/2 pixels in
-   // oversampled space. We want to shift in the opposite
-   // direction to counter this.
-   return (float)-(oversample - 1) / (2.0f * (float)oversample);
+    // The prefilter is a box filter of width "oversample",
+    // which shifts phase by (oversample - 1)/2 pixels in
+    // oversampled space. We want to shift in the opposite
+    // direction to counter this.
+    return (float)-(oversample - 1) / (2.0f * (float)oversample);
 }
 
 // rects array must be big enough to accommodate all characters in the given ranges
-STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
-{
-   int i,j,k;
-   int missing_glyph_added = 0;
-
-   k=0;
-   for (i=0; i < num_ranges; ++i) {
-      float fh = ranges[i].font_size;
-      float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
-      ranges[i].h_oversample = (unsigned char) spc->h_oversample;
-      ranges[i].v_oversample = (unsigned char) spc->v_oversample;
-      for (j=0; j < ranges[i].num_chars; ++j) {
-         int x0,y0,x1,y1;
-         int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
-         int glyph = stbtt_FindGlyphIndex(info, codepoint);
-         if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
-            rects[k].w = rects[k].h = 0;
-         } else {
-            stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
-                                            scale * spc->h_oversample,
-                                            scale * spc->v_oversample,
-                                            0,0,
-                                            &x0,&y0,&x1,&y1);
-            rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
-            rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
-            if (glyph == 0)
-               missing_glyph_added = 1;
-         }
-         ++k;
-      }
-   }
+STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info,
+                                              stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) {
+    int i, j, k;
+    int missing_glyph_added = 0;
+
+    k = 0;
+    for (i = 0; i < num_ranges; ++i) {
+        float fh    = ranges[i].font_size;
+        float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
+        ranges[i].h_oversample = (unsigned char)spc->h_oversample;
+        ranges[i].v_oversample = (unsigned char)spc->v_oversample;
+        for (j = 0; j < ranges[i].num_chars; ++j) {
+            int x0, y0, x1, y1;
+            int codepoint = ranges[i].array_of_unicode_codepoints == NULL
+                                ? ranges[i].first_unicode_codepoint_in_range + j
+                                : ranges[i].array_of_unicode_codepoints[j];
+            int glyph     = stbtt_FindGlyphIndex(info, codepoint);
+            if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
+                rects[k].w = rects[k].h = 0;
+            } else {
+                stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale * spc->h_oversample, scale * spc->v_oversample, 0, 0,
+                                                &x0, &y0, &x1, &y1);
+                rects[k].w = (stbrp_coord)(x1 - x0 + spc->padding + spc->h_oversample - 1);
+                rects[k].h = (stbrp_coord)(y1 - y0 + spc->padding + spc->v_oversample - 1);
+                if (glyph == 0)
+                    missing_glyph_added = 1;
+            }
+            ++k;
+        }
+    }
 
-   return k;
+    return k;
 }
 
-STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int prefilter_x, int prefilter_y, float *sub_x, float *sub_y, int glyph)
-{
-   stbtt_MakeGlyphBitmapSubpixel(info,
-                                 output,
-                                 out_w - (prefilter_x - 1),
-                                 out_h - (prefilter_y - 1),
-                                 out_stride,
-                                 scale_x,
-                                 scale_y,
-                                 shift_x,
-                                 shift_y,
-                                 glyph);
+STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w,
+                                                      int out_h, int out_stride, float scale_x, float scale_y,
+                                                      float shift_x, float shift_y, int prefilter_x, int prefilter_y,
+                                                      float *sub_x, float *sub_y, int glyph) {
+    stbtt_MakeGlyphBitmapSubpixel(info, output, out_w - (prefilter_x - 1), out_h - (prefilter_y - 1), out_stride,
+                                  scale_x, scale_y, shift_x, shift_y, glyph);
 
-   if (prefilter_x > 1)
-      stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
+    if (prefilter_x > 1)
+        stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
 
-   if (prefilter_y > 1)
-      stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
+    if (prefilter_y > 1)
+        stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
 
-   *sub_x = stbtt__oversample_shift(prefilter_x);
-   *sub_y = stbtt__oversample_shift(prefilter_y);
+    *sub_x = stbtt__oversample_shift(prefilter_x);
+    *sub_y = stbtt__oversample_shift(prefilter_y);
 }
 
 // rects array must be big enough to accommodate all characters in the given ranges
-STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
-{
-   int i,j,k, missing_glyph = -1, return_value = 1;
-
-   // save current values
-   int old_h_over = spc->h_oversample;
-   int old_v_over = spc->v_oversample;
-
-   k = 0;
-   for (i=0; i < num_ranges; ++i) {
-      float fh = ranges[i].font_size;
-      float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
-      float recip_h,recip_v,sub_x,sub_y;
-      spc->h_oversample = ranges[i].h_oversample;
-      spc->v_oversample = ranges[i].v_oversample;
-      recip_h = 1.0f / spc->h_oversample;
-      recip_v = 1.0f / spc->v_oversample;
-      sub_x = stbtt__oversample_shift(spc->h_oversample);
-      sub_y = stbtt__oversample_shift(spc->v_oversample);
-      for (j=0; j < ranges[i].num_chars; ++j) {
-         stbrp_rect *r = &rects[k];
-         if (r->was_packed && r->w != 0 && r->h != 0) {
-            stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
-            int advance, lsb, x0,y0,x1,y1;
-            int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
-            int glyph = stbtt_FindGlyphIndex(info, codepoint);
-            stbrp_coord pad = (stbrp_coord) spc->padding;
-
-            // pad on left and top
-            r->x += pad;
-            r->y += pad;
-            r->w -= pad;
-            r->h -= pad;
-            stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
-            stbtt_GetGlyphBitmapBox(info, glyph,
-                                    scale * spc->h_oversample,
-                                    scale * spc->v_oversample,
-                                    &x0,&y0,&x1,&y1);
-            stbtt_MakeGlyphBitmapSubpixel(info,
-                                          spc->pixels + r->x + r->y*spc->stride_in_bytes,
-                                          r->w - spc->h_oversample+1,
-                                          r->h - spc->v_oversample+1,
-                                          spc->stride_in_bytes,
-                                          scale * spc->h_oversample,
-                                          scale * spc->v_oversample,
-                                          0,0,
-                                          glyph);
-
-            if (spc->h_oversample > 1)
-               stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
-                                  r->w, r->h, spc->stride_in_bytes,
-                                  spc->h_oversample);
-
-            if (spc->v_oversample > 1)
-               stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
-                                  r->w, r->h, spc->stride_in_bytes,
-                                  spc->v_oversample);
-
-            bc->x0       = (stbtt_int16)  r->x;
-            bc->y0       = (stbtt_int16)  r->y;
-            bc->x1       = (stbtt_int16) (r->x + r->w);
-            bc->y1       = (stbtt_int16) (r->y + r->h);
-            bc->xadvance =                scale * advance;
-            bc->xoff     =       (float)  x0 * recip_h + sub_x;
-            bc->yoff     =       (float)  y0 * recip_v + sub_y;
-            bc->xoff2    =                (x0 + r->w) * recip_h + sub_x;
-            bc->yoff2    =                (y0 + r->h) * recip_v + sub_y;
-
-            if (glyph == 0)
-               missing_glyph = j;
-         } else if (spc->skip_missing) {
-            return_value = 0;
-         } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
-            ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
-         } else {
-            return_value = 0; // if any fail, report failure
-         }
-
-         ++k;
-      }
-   }
+STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info,
+                                                  stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) {
+    int i, j, k, missing_glyph = -1, return_value = 1;
+
+    // save current values
+    int old_h_over = spc->h_oversample;
+    int old_v_over = spc->v_oversample;
+
+    k = 0;
+    for (i = 0; i < num_ranges; ++i) {
+        float fh    = ranges[i].font_size;
+        float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
+        float recip_h, recip_v, sub_x, sub_y;
+        spc->h_oversample = ranges[i].h_oversample;
+        spc->v_oversample = ranges[i].v_oversample;
+        recip_h           = 1.0f / spc->h_oversample;
+        recip_v           = 1.0f / spc->v_oversample;
+        sub_x             = stbtt__oversample_shift(spc->h_oversample);
+        sub_y             = stbtt__oversample_shift(spc->v_oversample);
+        for (j = 0; j < ranges[i].num_chars; ++j) {
+            stbrp_rect *r = &rects[k];
+            if (r->was_packed && r->w != 0 && r->h != 0) {
+                stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
+                int               advance, lsb, x0, y0, x1, y1;
+                int               codepoint = ranges[i].array_of_unicode_codepoints == NULL
+                                                  ? ranges[i].first_unicode_codepoint_in_range + j
+                                                  : ranges[i].array_of_unicode_codepoints[j];
+                int               glyph     = stbtt_FindGlyphIndex(info, codepoint);
+                stbrp_coord       pad       = (stbrp_coord)spc->padding;
+
+                // pad on left and top
+                r->x += pad;
+                r->y += pad;
+                r->w -= pad;
+                r->h -= pad;
+                stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
+                stbtt_GetGlyphBitmapBox(info, glyph, scale * spc->h_oversample, scale * spc->v_oversample, &x0, &y0,
+                                        &x1, &y1);
+                stbtt_MakeGlyphBitmapSubpixel(info, spc->pixels + r->x + r->y * spc->stride_in_bytes,
+                                              r->w - spc->h_oversample + 1, r->h - spc->v_oversample + 1,
+                                              spc->stride_in_bytes, scale * spc->h_oversample,
+                                              scale * spc->v_oversample, 0, 0, glyph);
+
+                if (spc->h_oversample > 1)
+                    stbtt__h_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, r->w, r->h,
+                                       spc->stride_in_bytes, spc->h_oversample);
+
+                if (spc->v_oversample > 1)
+                    stbtt__v_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, r->w, r->h,
+                                       spc->stride_in_bytes, spc->v_oversample);
+
+                bc->x0       = (stbtt_int16)r->x;
+                bc->y0       = (stbtt_int16)r->y;
+                bc->x1       = (stbtt_int16)(r->x + r->w);
+                bc->y1       = (stbtt_int16)(r->y + r->h);
+                bc->xadvance = scale * advance;
+                bc->xoff     = (float)x0 * recip_h + sub_x;
+                bc->yoff     = (float)y0 * recip_v + sub_y;
+                bc->xoff2    = (x0 + r->w) * recip_h + sub_x;
+                bc->yoff2    = (y0 + r->h) * recip_v + sub_y;
+
+                if (glyph == 0)
+                    missing_glyph = j;
+            } else if (spc->skip_missing) {
+                return_value = 0;
+            } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
+                ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
+            } else {
+                return_value = 0; // if any fail, report failure
+            }
 
-   // restore original values
-   spc->h_oversample = old_h_over;
-   spc->v_oversample = old_v_over;
+            ++k;
+        }
+    }
 
-   return return_value;
+    // restore original values
+    spc->h_oversample = old_h_over;
+    spc->v_oversample = old_v_over;
+
+    return return_value;
 }
 
-STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects)
-{
-   stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects);
+STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects) {
+    stbrp_pack_rects((stbrp_context *)spc->pack_info, rects, num_rects);
 }
 
-STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
-{
-   stbtt_fontinfo info;
-   int i,j,n, return_value = 1;
-   //stbrp_context *context = (stbrp_context *) spc->pack_info;
-   stbrp_rect    *rects;
+STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index,
+                                   stbtt_pack_range *ranges, int num_ranges) {
+    stbtt_fontinfo info;
+    int            i, j, n, return_value = 1;
+    // stbrp_context *context = (stbrp_context *) spc->pack_info;
+    stbrp_rect *rects;
 
-   // flag all characters as NOT packed
-   for (i=0; i < num_ranges; ++i)
-      for (j=0; j < ranges[i].num_chars; ++j)
-         ranges[i].chardata_for_range[j].x0 =
-         ranges[i].chardata_for_range[j].y0 =
-         ranges[i].chardata_for_range[j].x1 =
-         ranges[i].chardata_for_range[j].y1 = 0;
+    // flag all characters as NOT packed
+    for (i = 0; i < num_ranges; ++i)
+        for (j = 0; j < ranges[i].num_chars; ++j)
+            ranges[i].chardata_for_range[j].x0     = ranges[i].chardata_for_range[j].y0 =
+                ranges[i].chardata_for_range[j].x1 = ranges[i].chardata_for_range[j].y1 = 0;
 
-   n = 0;
-   for (i=0; i < num_ranges; ++i)
-      n += ranges[i].num_chars;
+    n = 0;
+    for (i = 0; i < num_ranges; ++i)
+        n += ranges[i].num_chars;
 
-   rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
-   if (rects == NULL)
-      return 0;
+    rects = (stbrp_rect *)STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
+    if (rects == NULL)
+        return 0;
 
-   info.userdata = spc->user_allocator_context;
-   stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
+    info.userdata = spc->user_allocator_context;
+    stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, font_index));
 
-   n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
+    n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
 
-   stbtt_PackFontRangesPackRects(spc, rects, n);
+    stbtt_PackFontRangesPackRects(spc, rects, n);
 
-   return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
+    return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
 
-   STBTT_free(rects, spc->user_allocator_context);
-   return return_value;
+    STBTT_free(rects, spc->user_allocator_context);
+    return return_value;
 }
 
-STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size,
-            int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range)
-{
-   stbtt_pack_range range;
-   range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
-   range.array_of_unicode_codepoints = NULL;
-   range.num_chars                   = num_chars_in_range;
-   range.chardata_for_range          = chardata_for_range;
-   range.font_size                   = font_size;
-   return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
+STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index,
+                                  float font_size, int first_unicode_codepoint_in_range, int num_chars_in_range,
+                                  stbtt_packedchar *chardata_for_range) {
+    stbtt_pack_range range;
+    range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
+    range.array_of_unicode_codepoints      = NULL;
+    range.num_chars                        = num_chars_in_range;
+    range.chardata_for_range               = chardata_for_range;
+    range.font_size                        = font_size;
+    return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
 }
 
-STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
-{
-   int i_ascent, i_descent, i_lineGap;
-   float scale;
-   stbtt_fontinfo info;
-   stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
-   scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
-   stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
-   *ascent  = (float) i_ascent  * scale;
-   *descent = (float) i_descent * scale;
-   *lineGap = (float) i_lineGap * scale;
-}
-
-STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
-{
-   float ipw = 1.0f / pw, iph = 1.0f / ph;
-   const stbtt_packedchar *b = chardata + char_index;
-
-   if (align_to_integer) {
-      float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
-      float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f);
-      q->x0 = x;
-      q->y0 = y;
-      q->x1 = x + b->xoff2 - b->xoff;
-      q->y1 = y + b->yoff2 - b->yoff;
-   } else {
-      q->x0 = *xpos + b->xoff;
-      q->y0 = *ypos + b->yoff;
-      q->x1 = *xpos + b->xoff2;
-      q->y1 = *ypos + b->yoff2;
-   }
+STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent,
+                                           float *descent, float *lineGap) {
+    int            i_ascent, i_descent, i_lineGap;
+    float          scale;
+    stbtt_fontinfo info;
+    stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
+    scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
+    stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
+    *ascent  = (float)i_ascent * scale;
+    *descent = (float)i_descent * scale;
+    *lineGap = (float)i_lineGap * scale;
+}
+
+STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos,
+                                   float *ypos, stbtt_aligned_quad *q, int align_to_integer) {
+    float                   ipw = 1.0f / pw, iph = 1.0f / ph;
+    const stbtt_packedchar *b = chardata + char_index;
 
-   q->s0 = b->x0 * ipw;
-   q->t0 = b->y0 * iph;
-   q->s1 = b->x1 * ipw;
-   q->t1 = b->y1 * iph;
+    if (align_to_integer) {
+        float x = (float)STBTT_ifloor((*xpos + b->xoff) + 0.5f);
+        float y = (float)STBTT_ifloor((*ypos + b->yoff) + 0.5f);
+        q->x0   = x;
+        q->y0   = y;
+        q->x1   = x + b->xoff2 - b->xoff;
+        q->y1   = y + b->yoff2 - b->yoff;
+    } else {
+        q->x0 = *xpos + b->xoff;
+        q->y0 = *ypos + b->yoff;
+        q->x1 = *xpos + b->xoff2;
+        q->y1 = *ypos + b->yoff2;
+    }
 
-   *xpos += b->xadvance;
+    q->s0 = b->x0 * ipw;
+    q->t0 = b->y0 * iph;
+    q->s1 = b->x1 * ipw;
+    q->t1 = b->y1 * iph;
+
+    *xpos += b->xadvance;
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -4392,380 +4481,385 @@ STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int
 // sdf computation
 //
 
-#define STBTT_min(a,b)  ((a) < (b) ? (a) : (b))
-#define STBTT_max(a,b)  ((a) < (b) ? (b) : (a))
-
-static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2])
-{
-   float q0perp = q0[1]*ray[0] - q0[0]*ray[1];
-   float q1perp = q1[1]*ray[0] - q1[0]*ray[1];
-   float q2perp = q2[1]*ray[0] - q2[0]*ray[1];
-   float roperp = orig[1]*ray[0] - orig[0]*ray[1];
-
-   float a = q0perp - 2*q1perp + q2perp;
-   float b = q1perp - q0perp;
-   float c = q0perp - roperp;
-
-   float s0 = 0., s1 = 0.;
-   int num_s = 0;
-
-   if (a != 0.0) {
-      float discr = b*b - a*c;
-      if (discr > 0.0) {
-         float rcpna = -1 / a;
-         float d = (float) STBTT_sqrt(discr);
-         s0 = (b+d) * rcpna;
-         s1 = (b-d) * rcpna;
-         if (s0 >= 0.0 && s0 <= 1.0)
+#define STBTT_min(a, b) ((a) < (b) ? (a) : (b))
+#define STBTT_max(a, b) ((a) < (b) ? (b) : (a))
+
+static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2],
+                                       float hits[2][2]) {
+    float q0perp = q0[1] * ray[0] - q0[0] * ray[1];
+    float q1perp = q1[1] * ray[0] - q1[0] * ray[1];
+    float q2perp = q2[1] * ray[0] - q2[0] * ray[1];
+    float roperp = orig[1] * ray[0] - orig[0] * ray[1];
+
+    float a = q0perp - 2 * q1perp + q2perp;
+    float b = q1perp - q0perp;
+    float c = q0perp - roperp;
+
+    float s0 = 0., s1 = 0.;
+    int   num_s = 0;
+
+    if (a != 0.0) {
+        float discr = b * b - a * c;
+        if (discr > 0.0) {
+            float rcpna = -1 / a;
+            float d     = (float)STBTT_sqrt(discr);
+            s0          = (b + d) * rcpna;
+            s1          = (b - d) * rcpna;
+            if (s0 >= 0.0 && s0 <= 1.0)
+                num_s = 1;
+            if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
+                if (num_s == 0)
+                    s0 = s1;
+                ++num_s;
+            }
+        }
+    } else {
+        // 2*b*s + c = 0
+        // s = -c / (2*b)
+        s0 = c / (-2 * b);
+        if (s0 >= 0.0 && s0 <= 1.0)
             num_s = 1;
-         if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
-            if (num_s == 0) s0 = s1;
-            ++num_s;
-         }
-      }
-   } else {
-      // 2*b*s + c = 0
-      // s = -c / (2*b)
-      s0 = c / (-2 * b);
-      if (s0 >= 0.0 && s0 <= 1.0)
-         num_s = 1;
-   }
-
-   if (num_s == 0)
-      return 0;
-   else {
-      float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]);
-      float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
-
-      float q0d =   q0[0]*rayn_x +   q0[1]*rayn_y;
-      float q1d =   q1[0]*rayn_x +   q1[1]*rayn_y;
-      float q2d =   q2[0]*rayn_x +   q2[1]*rayn_y;
-      float rod = orig[0]*rayn_x + orig[1]*rayn_y;
-
-      float q10d = q1d - q0d;
-      float q20d = q2d - q0d;
-      float q0rd = q0d - rod;
-
-      hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d;
-      hits[0][1] = a*s0+b;
-
-      if (num_s > 1) {
-         hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d;
-         hits[1][1] = a*s1+b;
-         return 2;
-      } else {
-         return 1;
-      }
-   }
-}
-
-static int equal(float *a, float *b)
-{
-   return (a[0] == b[0] && a[1] == b[1]);
-}
-
-static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts)
-{
-   int i;
-   float orig[2], ray[2] = { 1, 0 };
-   float y_frac;
-   int winding = 0;
-
-   // make sure y never passes through a vertex of the shape
-   y_frac = (float) STBTT_fmod(y, 1.0f);
-   if (y_frac < 0.01f)
-      y += 0.01f;
-   else if (y_frac > 0.99f)
-      y -= 0.01f;
-
-   orig[0] = x;
-   orig[1] = y;
-
-   // test a ray from (-infinity,y) to (x,y)
-   for (i=0; i < nverts; ++i) {
-      if (verts[i].type == STBTT_vline) {
-         int x0 = (int) verts[i-1].x, y0 = (int) verts[i-1].y;
-         int x1 = (int) verts[i  ].x, y1 = (int) verts[i  ].y;
-         if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
-            float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
-            if (x_inter < x)
-               winding += (y0 < y1) ? 1 : -1;
-         }
-      }
-      if (verts[i].type == STBTT_vcurve) {
-         int x0 = (int) verts[i-1].x , y0 = (int) verts[i-1].y ;
-         int x1 = (int) verts[i  ].cx, y1 = (int) verts[i  ].cy;
-         int x2 = (int) verts[i  ].x , y2 = (int) verts[i  ].y ;
-         int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2));
-         int by = STBTT_max(y0,STBTT_max(y1,y2));
-         if (y > ay && y < by && x > ax) {
-            float q0[2],q1[2],q2[2];
-            float hits[2][2];
-            q0[0] = (float)x0;
-            q0[1] = (float)y0;
-            q1[0] = (float)x1;
-            q1[1] = (float)y1;
-            q2[0] = (float)x2;
-            q2[1] = (float)y2;
-            if (equal(q0,q1) || equal(q1,q2)) {
-               x0 = (int)verts[i-1].x;
-               y0 = (int)verts[i-1].y;
-               x1 = (int)verts[i  ].x;
-               y1 = (int)verts[i  ].y;
-               if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
-                  float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
-                  if (x_inter < x)
-                     winding += (y0 < y1) ? 1 : -1;
-               }
-            } else {
-               int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
-               if (num_hits >= 1)
-                  if (hits[0][0] < 0)
-                     winding += (hits[0][1] < 0 ? -1 : 1);
-               if (num_hits >= 2)
-                  if (hits[1][0] < 0)
-                     winding += (hits[1][1] < 0 ? -1 : 1);
+    }
+
+    if (num_s == 0)
+        return 0;
+    else {
+        float rcp_len2 = 1 / (ray[0] * ray[0] + ray[1] * ray[1]);
+        float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
+
+        float q0d = q0[0] * rayn_x + q0[1] * rayn_y;
+        float q1d = q1[0] * rayn_x + q1[1] * rayn_y;
+        float q2d = q2[0] * rayn_x + q2[1] * rayn_y;
+        float rod = orig[0] * rayn_x + orig[1] * rayn_y;
+
+        float q10d = q1d - q0d;
+        float q20d = q2d - q0d;
+        float q0rd = q0d - rod;
+
+        hits[0][0] = q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d;
+        hits[0][1] = a * s0 + b;
+
+        if (num_s > 1) {
+            hits[1][0] = q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d;
+            hits[1][1] = a * s1 + b;
+            return 2;
+        } else {
+            return 1;
+        }
+    }
+}
+
+static int equal(float *a, float *b) { return (a[0] == b[0] && a[1] == b[1]); }
+
+static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) {
+    int   i;
+    float orig[2], ray[2] = {1, 0};
+    float y_frac;
+    int   winding = 0;
+
+    // make sure y never passes through a vertex of the shape
+    y_frac = (float)STBTT_fmod(y, 1.0f);
+    if (y_frac < 0.01f)
+        y += 0.01f;
+    else if (y_frac > 0.99f)
+        y -= 0.01f;
+
+    orig[0] = x;
+    orig[1] = y;
+
+    // test a ray from (-infinity,y) to (x,y)
+    for (i = 0; i < nverts; ++i) {
+        if (verts[i].type == STBTT_vline) {
+            int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y;
+            int x1 = (int)verts[i].x, y1 = (int)verts[i].y;
+            if (y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) {
+                float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0;
+                if (x_inter < x)
+                    winding += (y0 < y1) ? 1 : -1;
             }
-         }
-      }
-   }
-   return winding;
+        }
+        if (verts[i].type == STBTT_vcurve) {
+            int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y;
+            int x1 = (int)verts[i].cx, y1 = (int)verts[i].cy;
+            int x2 = (int)verts[i].x, y2 = (int)verts[i].y;
+            int ax = STBTT_min(x0, STBTT_min(x1, x2)), ay = STBTT_min(y0, STBTT_min(y1, y2));
+            int by = STBTT_max(y0, STBTT_max(y1, y2));
+            if (y > ay && y < by && x > ax) {
+                float q0[2], q1[2], q2[2];
+                float hits[2][2];
+                q0[0] = (float)x0;
+                q0[1] = (float)y0;
+                q1[0] = (float)x1;
+                q1[1] = (float)y1;
+                q2[0] = (float)x2;
+                q2[1] = (float)y2;
+                if (equal(q0, q1) || equal(q1, q2)) {
+                    x0 = (int)verts[i - 1].x;
+                    y0 = (int)verts[i - 1].y;
+                    x1 = (int)verts[i].x;
+                    y1 = (int)verts[i].y;
+                    if (y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) {
+                        float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0;
+                        if (x_inter < x)
+                            winding += (y0 < y1) ? 1 : -1;
+                    }
+                } else {
+                    int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
+                    if (num_hits >= 1)
+                        if (hits[0][0] < 0)
+                            winding += (hits[0][1] < 0 ? -1 : 1);
+                    if (num_hits >= 2)
+                        if (hits[1][0] < 0)
+                            winding += (hits[1][1] < 0 ? -1 : 1);
+                }
+            }
+        }
+    }
+    return winding;
 }
 
-static float stbtt__cuberoot( float x )
-{
-   if (x<0)
-      return -(float) STBTT_pow(-x,1.0f/3.0f);
-   else
-      return  (float) STBTT_pow( x,1.0f/3.0f);
+static float stbtt__cuberoot(float x) {
+    if (x < 0)
+        return -(float)STBTT_pow(-x, 1.0f / 3.0f);
+    else
+        return (float)STBTT_pow(x, 1.0f / 3.0f);
 }
 
 // x^3 + a*x^2 + b*x + c = 0
-static int stbtt__solve_cubic(float a, float b, float c, float* r)
-{
-   float s = -a / 3;
-   float p = b - a*a / 3;
-   float q = a * (2*a*a - 9*b) / 27 + c;
-   float p3 = p*p*p;
-   float d = q*q + 4*p3 / 27;
-   if (d >= 0) {
-      float z = (float) STBTT_sqrt(d);
-      float u = (-q + z) / 2;
-      float v = (-q - z) / 2;
-      u = stbtt__cuberoot(u);
-      v = stbtt__cuberoot(v);
-      r[0] = s + u + v;
-      return 1;
-   } else {
-      float u = (float) STBTT_sqrt(-p/3);
-      float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative
-      float m = (float) STBTT_cos(v);
-      float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f;
-      r[0] = s + u * 2 * m;
-      r[1] = s - u * (m + n);
-      r[2] = s - u * (m - n);
-
-      //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f);  // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe?
-      //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f);
-      //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f);
-      return 3;
-   }
-}
-
-STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff)
-{
-   float scale_x = scale, scale_y = scale;
-   int ix0,iy0,ix1,iy1;
-   int w,h;
-   unsigned char *data;
-
-   if (scale == 0) return NULL;
-
-   stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
-
-   // if empty, return NULL
-   if (ix0 == ix1 || iy0 == iy1)
-      return NULL;
-
-   ix0 -= padding;
-   iy0 -= padding;
-   ix1 += padding;
-   iy1 += padding;
-
-   w = (ix1 - ix0);
-   h = (iy1 - iy0);
-
-   if (width ) *width  = w;
-   if (height) *height = h;
-   if (xoff  ) *xoff   = ix0;
-   if (yoff  ) *yoff   = iy0;
-
-   // invert for y-downwards bitmaps
-   scale_y = -scale_y;
-
-   {
-      int x,y,i,j;
-      float *precompute;
-      stbtt_vertex *verts;
-      int num_verts = stbtt_GetGlyphShape(info, glyph, &verts);
-      data = (unsigned char *) STBTT_malloc(w * h, info->userdata);
-      precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata);
-
-      for (i=0,j=num_verts-1; i < num_verts; j=i++) {
-         if (verts[i].type == STBTT_vline) {
-            float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
-            float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y;
-            float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
-            precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
-         } else if (verts[i].type == STBTT_vcurve) {
-            float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y;
-            float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y;
-            float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y;
-            float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
-            float len2 = bx*bx + by*by;
-            if (len2 != 0.0f)
-               precompute[i] = 1.0f / (bx*bx + by*by);
-            else
-               precompute[i] = 0.0f;
-         } else
-            precompute[i] = 0.0f;
-      }
-
-      for (y=iy0; y < iy1; ++y) {
-         for (x=ix0; x < ix1; ++x) {
-            float val;
-            float min_dist = 999999.0f;
-            float sx = (float) x + 0.5f;
-            float sy = (float) y + 0.5f;
-            float x_gspace = (sx / scale_x);
-            float y_gspace = (sy / scale_y);
-
-            int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path
-
-            for (i=0; i < num_verts; ++i) {
-               float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
-
-               if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) {
-                  float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y;
-
-                  float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
-                  if (dist2 < min_dist*min_dist)
-                     min_dist = (float) STBTT_sqrt(dist2);
-
-                  // coarse culling against bbox
-                  //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist &&
-                  //    sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist)
-                  dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
-                  STBTT_assert(i != 0);
-                  if (dist < min_dist) {
-                     // check position along line
-                     // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0)
-                     // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy)
-                     float dx = x1-x0, dy = y1-y0;
-                     float px = x0-sx, py = y0-sy;
-                     // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy
-                     // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve
-                     float t = -(px*dx + py*dy) / (dx*dx + dy*dy);
-                     if (t >= 0.0f && t <= 1.0f)
-                        min_dist = dist;
-                  }
-               } else if (verts[i].type == STBTT_vcurve) {
-                  float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y;
-                  float x1 = verts[i  ].cx*scale_x, y1 = verts[i  ].cy*scale_y;
-                  float box_x0 = STBTT_min(STBTT_min(x0,x1),x2);
-                  float box_y0 = STBTT_min(STBTT_min(y0,y1),y2);
-                  float box_x1 = STBTT_max(STBTT_max(x0,x1),x2);
-                  float box_y1 = STBTT_max(STBTT_max(y0,y1),y2);
-                  // coarse culling against bbox to avoid computing cubic unnecessarily
-                  if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) {
-                     int num=0;
-                     float ax = x1-x0, ay = y1-y0;
-                     float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
-                     float mx = x0 - sx, my = y0 - sy;
-                     float res[3] = {0.f,0.f,0.f};
-                     float px,py,t,it,dist2;
-                     float a_inv = precompute[i];
-                     if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula
-                        float a = 3*(ax*bx + ay*by);
-                        float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
-                        float c = mx*ax+my*ay;
-                        if (a == 0.0) { // if a is 0, it's linear
-                           if (b != 0.0) {
-                              res[num++] = -c/b;
-                           }
-                        } else {
-                           float discriminant = b*b - 4*a*c;
-                           if (discriminant < 0)
-                              num = 0;
-                           else {
-                              float root = (float) STBTT_sqrt(discriminant);
-                              res[0] = (-b - root)/(2*a);
-                              res[1] = (-b + root)/(2*a);
-                              num = 2; // don't bother distinguishing 1-solution case, as code below will still work
-                           }
-                        }
-                     } else {
-                        float b = 3*(ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point
-                        float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv;
-                        float d = (mx*ax+my*ay) * a_inv;
-                        num = stbtt__solve_cubic(b, c, d, res);
-                     }
-                     dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
-                     if (dist2 < min_dist*min_dist)
-                        min_dist = (float) STBTT_sqrt(dist2);
-
-                     if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
-                        t = res[0], it = 1.0f - t;
-                        px = it*it*x0 + 2*t*it*x1 + t*t*x2;
-                        py = it*it*y0 + 2*t*it*y1 + t*t*y2;
-                        dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
-                        if (dist2 < min_dist * min_dist)
-                           min_dist = (float) STBTT_sqrt(dist2);
-                     }
-                     if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
-                        t = res[1], it = 1.0f - t;
-                        px = it*it*x0 + 2*t*it*x1 + t*t*x2;
-                        py = it*it*y0 + 2*t*it*y1 + t*t*y2;
-                        dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
-                        if (dist2 < min_dist * min_dist)
-                           min_dist = (float) STBTT_sqrt(dist2);
-                     }
-                     if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
-                        t = res[2], it = 1.0f - t;
-                        px = it*it*x0 + 2*t*it*x1 + t*t*x2;
-                        py = it*it*y0 + 2*t*it*y1 + t*t*y2;
-                        dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
+static int stbtt__solve_cubic(float a, float b, float c, float *r) {
+    float s  = -a / 3;
+    float p  = b - a * a / 3;
+    float q  = a * (2 * a * a - 9 * b) / 27 + c;
+    float p3 = p * p * p;
+    float d  = q * q + 4 * p3 / 27;
+    if (d >= 0) {
+        float z = (float)STBTT_sqrt(d);
+        float u = (-q + z) / 2;
+        float v = (-q - z) / 2;
+        u       = stbtt__cuberoot(u);
+        v       = stbtt__cuberoot(v);
+        r[0]    = s + u + v;
+        return 1;
+    } else {
+        float u = (float)STBTT_sqrt(-p / 3);
+        float v = (float)STBTT_acos(-STBTT_sqrt(-27 / p3) * q / 2) / 3; // p3 must be negative, since d is negative
+        float m = (float)STBTT_cos(v);
+        float n = (float)STBTT_cos(v - 3.141592 / 2) * 1.732050808f;
+        r[0]    = s + u * 2 * m;
+        r[1]    = s - u * (m + n);
+        r[2]    = s - u * (m - n);
+
+        // STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f);  // these asserts may not be safe at all scales,
+        // though they're in bezier t parameter units so maybe? STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) <
+        // 0.05f); STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f);
+        return 3;
+    }
+}
+
+STBTT_DEF unsigned char *stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding,
+                                           unsigned char onedge_value, float pixel_dist_scale, int *width, int *height,
+                                           int *xoff, int *yoff) {
+    float          scale_x = scale, scale_y = scale;
+    int            ix0, iy0, ix1, iy1;
+    int            w, h;
+    unsigned char *data;
+
+    if (scale == 0)
+        return NULL;
+
+    stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f, 0.0f, &ix0, &iy0, &ix1, &iy1);
+
+    // if empty, return NULL
+    if (ix0 == ix1 || iy0 == iy1)
+        return NULL;
+
+    ix0 -= padding;
+    iy0 -= padding;
+    ix1 += padding;
+    iy1 += padding;
+
+    w = (ix1 - ix0);
+    h = (iy1 - iy0);
+
+    if (width)
+        *width = w;
+    if (height)
+        *height = h;
+    if (xoff)
+        *xoff = ix0;
+    if (yoff)
+        *yoff = iy0;
+
+    // invert for y-downwards bitmaps
+    scale_y = -scale_y;
+
+    {
+        int           x, y, i, j;
+        float        *precompute;
+        stbtt_vertex *verts;
+        int           num_verts = stbtt_GetGlyphShape(info, glyph, &verts);
+        data                    = (unsigned char *)STBTT_malloc(w * h, info->userdata);
+        precompute              = (float *)STBTT_malloc(num_verts * sizeof(float), info->userdata);
+
+        for (i = 0, j = num_verts - 1; i < num_verts; j = i++) {
+            if (verts[i].type == STBTT_vline) {
+                float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y;
+                float x1 = verts[j].x * scale_x, y1 = verts[j].y * scale_y;
+                float dist    = (float)STBTT_sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
+                precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
+            } else if (verts[i].type == STBTT_vcurve) {
+                float x2 = verts[j].x * scale_x, y2 = verts[j].y * scale_y;
+                float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y;
+                float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y;
+                float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2;
+                float len2 = bx * bx + by * by;
+                if (len2 != 0.0f)
+                    precompute[i] = 1.0f / (bx * bx + by * by);
+                else
+                    precompute[i] = 0.0f;
+            } else
+                precompute[i] = 0.0f;
+        }
+
+        for (y = iy0; y < iy1; ++y) {
+            for (x = ix0; x < ix1; ++x) {
+                float val;
+                float min_dist = 999999.0f;
+                float sx       = (float)x + 0.5f;
+                float sy       = (float)y + 0.5f;
+                float x_gspace = (sx / scale_x);
+                float y_gspace = (sy / scale_y);
+
+                int winding = stbtt__compute_crossings_x(
+                    x_gspace, y_gspace, num_verts, verts); // @OPTIMIZE: this could just be a rasterization, but needs
+                                                           // to be line vs. non-tesselated curves so a new path
+
+                for (i = 0; i < num_verts; ++i) {
+                    float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y;
+
+                    if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) {
+                        float x1 = verts[i - 1].x * scale_x, y1 = verts[i - 1].y * scale_y;
+
+                        float dist, dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy);
                         if (dist2 < min_dist * min_dist)
-                           min_dist = (float) STBTT_sqrt(dist2);
-                     }
-                  }
-               }
+                            min_dist = (float)STBTT_sqrt(dist2);
+
+                        // coarse culling against bbox
+                        // if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist &&
+                        //    sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist)
+                        dist = (float)STBTT_fabs((x1 - x0) * (y0 - sy) - (y1 - y0) * (x0 - sx)) * precompute[i];
+                        STBTT_assert(i != 0);
+                        if (dist < min_dist) {
+                            // check position along line
+                            // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0)
+                            // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy)
+                            float dx = x1 - x0, dy = y1 - y0;
+                            float px = x0 - sx, py = y0 - sy;
+                            // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t +
+                            // t^2*dy*dy derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve
+                            float t = -(px * dx + py * dy) / (dx * dx + dy * dy);
+                            if (t >= 0.0f && t <= 1.0f)
+                                min_dist = dist;
+                        }
+                    } else if (verts[i].type == STBTT_vcurve) {
+                        float x2 = verts[i - 1].x * scale_x, y2 = verts[i - 1].y * scale_y;
+                        float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y;
+                        float box_x0 = STBTT_min(STBTT_min(x0, x1), x2);
+                        float box_y0 = STBTT_min(STBTT_min(y0, y1), y2);
+                        float box_x1 = STBTT_max(STBTT_max(x0, x1), x2);
+                        float box_y1 = STBTT_max(STBTT_max(y0, y1), y2);
+                        // coarse culling against bbox to avoid computing cubic unnecessarily
+                        if (sx > box_x0 - min_dist && sx < box_x1 + min_dist && sy > box_y0 - min_dist &&
+                            sy < box_y1 + min_dist) {
+                            int   num = 0;
+                            float ax = x1 - x0, ay = y1 - y0;
+                            float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2;
+                            float mx = x0 - sx, my = y0 - sy;
+                            float res[3] = {0.f, 0.f, 0.f};
+                            float px, py, t, it, dist2;
+                            float a_inv = precompute[i];
+                            if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula
+                                float a = 3 * (ax * bx + ay * by);
+                                float b = 2 * (ax * ax + ay * ay) + (mx * bx + my * by);
+                                float c = mx * ax + my * ay;
+                                if (a == 0.0) { // if a is 0, it's linear
+                                    if (b != 0.0) {
+                                        res[num++] = -c / b;
+                                    }
+                                } else {
+                                    float discriminant = b * b - 4 * a * c;
+                                    if (discriminant < 0)
+                                        num = 0;
+                                    else {
+                                        float root = (float)STBTT_sqrt(discriminant);
+                                        res[0]     = (-b - root) / (2 * a);
+                                        res[1]     = (-b + root) / (2 * a);
+                                        num = 2; // don't bother distinguishing 1-solution case, as code below will
+                                                 // still work
+                                    }
+                                }
+                            } else {
+                                float b = 3 * (ax * bx + ay * by) *
+                                          a_inv; // could precompute this as it doesn't depend on sample point
+                                float c = (2 * (ax * ax + ay * ay) + (mx * bx + my * by)) * a_inv;
+                                float d = (mx * ax + my * ay) * a_inv;
+                                num     = stbtt__solve_cubic(b, c, d, res);
+                            }
+                            dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy);
+                            if (dist2 < min_dist * min_dist)
+                                min_dist = (float)STBTT_sqrt(dist2);
+
+                            if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
+                                t = res[0], it = 1.0f - t;
+                                px    = it * it * x0 + 2 * t * it * x1 + t * t * x2;
+                                py    = it * it * y0 + 2 * t * it * y1 + t * t * y2;
+                                dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy);
+                                if (dist2 < min_dist * min_dist)
+                                    min_dist = (float)STBTT_sqrt(dist2);
+                            }
+                            if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
+                                t = res[1], it = 1.0f - t;
+                                px    = it * it * x0 + 2 * t * it * x1 + t * t * x2;
+                                py    = it * it * y0 + 2 * t * it * y1 + t * t * y2;
+                                dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy);
+                                if (dist2 < min_dist * min_dist)
+                                    min_dist = (float)STBTT_sqrt(dist2);
+                            }
+                            if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
+                                t = res[2], it = 1.0f - t;
+                                px    = it * it * x0 + 2 * t * it * x1 + t * t * x2;
+                                py    = it * it * y0 + 2 * t * it * y1 + t * t * y2;
+                                dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy);
+                                if (dist2 < min_dist * min_dist)
+                                    min_dist = (float)STBTT_sqrt(dist2);
+                            }
+                        }
+                    }
+                }
+                if (winding == 0)
+                    min_dist = -min_dist; // if outside the shape, value is negative
+                val = onedge_value + pixel_dist_scale * min_dist;
+                if (val < 0)
+                    val = 0;
+                else if (val > 255)
+                    val = 255;
+                data[(y - iy0) * w + (x - ix0)] = (unsigned char)val;
             }
-            if (winding == 0)
-               min_dist = -min_dist;  // if outside the shape, value is negative
-            val = onedge_value + pixel_dist_scale * min_dist;
-            if (val < 0)
-               val = 0;
-            else if (val > 255)
-               val = 255;
-            data[(y-iy0)*w+(x-ix0)] = (unsigned char) val;
-         }
-      }
-      STBTT_free(precompute, info->userdata);
-      STBTT_free(verts, info->userdata);
-   }
-   return data;
+        }
+        STBTT_free(precompute, info->userdata);
+        STBTT_free(verts, info->userdata);
+    }
+    return data;
 }
 
-STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff)
-{
-   return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff);
+STBTT_DEF unsigned char *stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding,
+                                               unsigned char onedge_value, float pixel_dist_scale, int *width,
+                                               int *height, int *xoff, int *yoff) {
+    return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value,
+                             pixel_dist_scale, width, height, xoff, yoff);
 }
 
-STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
-{
-   STBTT_free(bitmap, userdata);
-}
+STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata) { STBTT_free(bitmap, userdata); }
 
 //////////////////////////////////////////////////////////////////////////////
 //
@@ -4773,158 +4867,185 @@ STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
 //
 
 // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
-static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
-{
-   stbtt_int32 i=0;
-
-   // convert utf16 to utf8 and compare the results while converting
-   while (len2) {
-      stbtt_uint16 ch = s2[0]*256 + s2[1];
-      if (ch < 0x80) {
-         if (i >= len1) return -1;
-         if (s1[i++] != ch) return -1;
-      } else if (ch < 0x800) {
-         if (i+1 >= len1) return -1;
-         if (s1[i++] != 0xc0 + (ch >> 6)) return -1;
-         if (s1[i++] != 0x80 + (ch & 0x3f)) return -1;
-      } else if (ch >= 0xd800 && ch < 0xdc00) {
-         stbtt_uint32 c;
-         stbtt_uint16 ch2 = s2[2]*256 + s2[3];
-         if (i+3 >= len1) return -1;
-         c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
-         if (s1[i++] != 0xf0 + (c >> 18)) return -1;
-         if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1;
-         if (s1[i++] != 0x80 + ((c >>  6) & 0x3f)) return -1;
-         if (s1[i++] != 0x80 + ((c      ) & 0x3f)) return -1;
-         s2 += 2; // plus another 2 below
-         len2 -= 2;
-      } else if (ch >= 0xdc00 && ch < 0xe000) {
-         return -1;
-      } else {
-         if (i+2 >= len1) return -1;
-         if (s1[i++] != 0xe0 + (ch >> 12)) return -1;
-         if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1;
-         if (s1[i++] != 0x80 + ((ch     ) & 0x3f)) return -1;
-      }
-      s2 += 2;
-      len2 -= 2;
-   }
-   return i;
-}
-
-static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2)
-{
-   return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2);
+static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2,
+                                                              stbtt_int32 len2) {
+    stbtt_int32 i = 0;
+
+    // convert utf16 to utf8 and compare the results while converting
+    while (len2) {
+        stbtt_uint16 ch = s2[0] * 256 + s2[1];
+        if (ch < 0x80) {
+            if (i >= len1)
+                return -1;
+            if (s1[i++] != ch)
+                return -1;
+        } else if (ch < 0x800) {
+            if (i + 1 >= len1)
+                return -1;
+            if (s1[i++] != 0xc0 + (ch >> 6))
+                return -1;
+            if (s1[i++] != 0x80 + (ch & 0x3f))
+                return -1;
+        } else if (ch >= 0xd800 && ch < 0xdc00) {
+            stbtt_uint32 c;
+            stbtt_uint16 ch2 = s2[2] * 256 + s2[3];
+            if (i + 3 >= len1)
+                return -1;
+            c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
+            if (s1[i++] != 0xf0 + (c >> 18))
+                return -1;
+            if (s1[i++] != 0x80 + ((c >> 12) & 0x3f))
+                return -1;
+            if (s1[i++] != 0x80 + ((c >> 6) & 0x3f))
+                return -1;
+            if (s1[i++] != 0x80 + ((c)&0x3f))
+                return -1;
+            s2 += 2; // plus another 2 below
+            len2 -= 2;
+        } else if (ch >= 0xdc00 && ch < 0xe000) {
+            return -1;
+        } else {
+            if (i + 2 >= len1)
+                return -1;
+            if (s1[i++] != 0xe0 + (ch >> 12))
+                return -1;
+            if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f))
+                return -1;
+            if (s1[i++] != 0x80 + ((ch)&0x3f))
+                return -1;
+        }
+        s2 += 2;
+        len2 -= 2;
+    }
+    return i;
+}
+
+static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) {
+    return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8 *)s1, len1, (stbtt_uint8 *)s2, len2);
 }
 
 // returns results in whatever encoding you request... but note that 2-byte encodings
 // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare
-STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID)
-{
-   stbtt_int32 i,count,stringOffset;
-   stbtt_uint8 *fc = font->data;
-   stbtt_uint32 offset = font->fontstart;
-   stbtt_uint32 nm = stbtt__find_table(fc, offset, "name");
-   if (!nm) return NULL;
-
-   count = ttUSHORT(fc+nm+2);
-   stringOffset = nm + ttUSHORT(fc+nm+4);
-   for (i=0; i < count; ++i) {
-      stbtt_uint32 loc = nm + 6 + 12 * i;
-      if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
-          && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
-         *length = ttUSHORT(fc+loc+8);
-         return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
-      }
-   }
-   return NULL;
-}
-
-static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
-{
-   stbtt_int32 i;
-   stbtt_int32 count = ttUSHORT(fc+nm+2);
-   stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
-
-   for (i=0; i < count; ++i) {
-      stbtt_uint32 loc = nm + 6 + 12 * i;
-      stbtt_int32 id = ttUSHORT(fc+loc+6);
-      if (id == target_id) {
-         // find the encoding
-         stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
-
-         // is this a Unicode encoding?
-         if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
-            stbtt_int32 slen = ttUSHORT(fc+loc+8);
-            stbtt_int32 off = ttUSHORT(fc+loc+10);
-
-            // check if there's a prefix match
-            stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
-            if (matchlen >= 0) {
-               // check for target_id+1 immediately following, with same encoding & language
-               if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) {
-                  slen = ttUSHORT(fc+loc+12+8);
-                  off = ttUSHORT(fc+loc+12+10);
-                  if (slen == 0) {
-                     if (matchlen == nlen)
-                        return 1;
-                  } else if (matchlen < nlen && name[matchlen] == ' ') {
-                     ++matchlen;
-                     if (stbtt_CompareUTF8toUTF16_bigendian_internal((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen))
-                        return 1;
-                  }
-               } else {
-                  // if nothing immediately following
-                  if (matchlen == nlen)
-                     return 1;
-               }
+STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID,
+                                              int languageID, int nameID) {
+    stbtt_int32  i, count, stringOffset;
+    stbtt_uint8 *fc     = font->data;
+    stbtt_uint32 offset = font->fontstart;
+    stbtt_uint32 nm     = stbtt__find_table(fc, offset, "name");
+    if (!nm)
+        return NULL;
+
+    count        = ttUSHORT(fc + nm + 2);
+    stringOffset = nm + ttUSHORT(fc + nm + 4);
+    for (i = 0; i < count; ++i) {
+        stbtt_uint32 loc = nm + 6 + 12 * i;
+        if (platformID == ttUSHORT(fc + loc + 0) && encodingID == ttUSHORT(fc + loc + 2) &&
+            languageID == ttUSHORT(fc + loc + 4) && nameID == ttUSHORT(fc + loc + 6)) {
+            *length = ttUSHORT(fc + loc + 8);
+            return (const char *)(fc + stringOffset + ttUSHORT(fc + loc + 10));
+        }
+    }
+    return NULL;
+}
+
+static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen,
+                            stbtt_int32 target_id, stbtt_int32 next_id) {
+    stbtt_int32 i;
+    stbtt_int32 count        = ttUSHORT(fc + nm + 2);
+    stbtt_int32 stringOffset = nm + ttUSHORT(fc + nm + 4);
+
+    for (i = 0; i < count; ++i) {
+        stbtt_uint32 loc = nm + 6 + 12 * i;
+        stbtt_int32  id  = ttUSHORT(fc + loc + 6);
+        if (id == target_id) {
+            // find the encoding
+            stbtt_int32 platform = ttUSHORT(fc + loc + 0), encoding = ttUSHORT(fc + loc + 2),
+                        language = ttUSHORT(fc + loc + 4);
+
+            // is this a Unicode encoding?
+            if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
+                stbtt_int32 slen = ttUSHORT(fc + loc + 8);
+                stbtt_int32 off  = ttUSHORT(fc + loc + 10);
+
+                // check if there's a prefix match
+                stbtt_int32 matchlen =
+                    stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc + stringOffset + off, slen);
+                if (matchlen >= 0) {
+                    // check for target_id+1 immediately following, with same encoding & language
+                    if (i + 1 < count && ttUSHORT(fc + loc + 12 + 6) == next_id &&
+                        ttUSHORT(fc + loc + 12) == platform && ttUSHORT(fc + loc + 12 + 2) == encoding &&
+                        ttUSHORT(fc + loc + 12 + 4) == language) {
+                        slen = ttUSHORT(fc + loc + 12 + 8);
+                        off  = ttUSHORT(fc + loc + 12 + 10);
+                        if (slen == 0) {
+                            if (matchlen == nlen)
+                                return 1;
+                        } else if (matchlen < nlen && name[matchlen] == ' ') {
+                            ++matchlen;
+                            if (stbtt_CompareUTF8toUTF16_bigendian_internal((char *)(name + matchlen), nlen - matchlen,
+                                                                            (char *)(fc + stringOffset + off), slen))
+                                return 1;
+                        }
+                    } else {
+                        // if nothing immediately following
+                        if (matchlen == nlen)
+                            return 1;
+                    }
+                }
             }
-         }
 
-         // @TODO handle other encodings
-      }
-   }
-   return 0;
+            // @TODO handle other encodings
+        }
+    }
+    return 0;
 }
 
-static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
-{
-   stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name);
-   stbtt_uint32 nm,hd;
-   if (!stbtt__isfont(fc+offset)) return 0;
-
-   // check italics/bold/underline flags in macStyle...
-   if (flags) {
-      hd = stbtt__find_table(fc, offset, "head");
-      if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0;
-   }
-
-   nm = stbtt__find_table(fc, offset, "name");
-   if (!nm) return 0;
-
-   if (flags) {
-      // if we checked the macStyle flags, then just check the family and ignore the subfamily
-      if (stbtt__matchpair(fc, nm, name, nlen, 16, -1))  return 1;
-      if (stbtt__matchpair(fc, nm, name, nlen,  1, -1))  return 1;
-      if (stbtt__matchpair(fc, nm, name, nlen,  3, -1))  return 1;
-   } else {
-      if (stbtt__matchpair(fc, nm, name, nlen, 16, 17))  return 1;
-      if (stbtt__matchpair(fc, nm, name, nlen,  1,  2))  return 1;
-      if (stbtt__matchpair(fc, nm, name, nlen,  3, -1))  return 1;
-   }
+static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) {
+    stbtt_int32  nlen = (stbtt_int32)STBTT_strlen((char *)name);
+    stbtt_uint32 nm, hd;
+    if (!stbtt__isfont(fc + offset))
+        return 0;
 
-   return 0;
-}
-
-static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags)
-{
-   stbtt_int32 i;
-   for (i=0;;++i) {
-      stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
-      if (off < 0) return off;
-      if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
-         return off;
-   }
+    // check italics/bold/underline flags in macStyle...
+    if (flags) {
+        hd = stbtt__find_table(fc, offset, "head");
+        if ((ttUSHORT(fc + hd + 44) & 7) != (flags & 7))
+            return 0;
+    }
+
+    nm = stbtt__find_table(fc, offset, "name");
+    if (!nm)
+        return 0;
+
+    if (flags) {
+        // if we checked the macStyle flags, then just check the family and ignore the subfamily
+        if (stbtt__matchpair(fc, nm, name, nlen, 16, -1))
+            return 1;
+        if (stbtt__matchpair(fc, nm, name, nlen, 1, -1))
+            return 1;
+        if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
+            return 1;
+    } else {
+        if (stbtt__matchpair(fc, nm, name, nlen, 16, 17))
+            return 1;
+        if (stbtt__matchpair(fc, nm, name, nlen, 1, 2))
+            return 1;
+        if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
+            return 1;
+    }
+
+    return 0;
+}
+
+static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags) {
+    stbtt_int32 i;
+    for (i = 0;; ++i) {
+        stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
+        if (off < 0)
+            return off;
+        if (stbtt__matches((stbtt_uint8 *)font_collection, off, (stbtt_uint8 *)name_utf8, flags))
+            return off;
+    }
 }
 
 #if defined(__GNUC__) || defined(__clang__)
@@ -4932,36 +5053,30 @@ static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char
 #pragma GCC diagnostic ignored "-Wcast-qual"
 #endif
 
-STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset,
-                                float pixel_height, unsigned char *pixels, int pw, int ph,
-                                int first_char, int num_chars, stbtt_bakedchar *chardata)
-{
-   return stbtt_BakeFontBitmap_internal((unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata);
+STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, float pixel_height, unsigned char *pixels,
+                                   int pw, int ph, int first_char, int num_chars, stbtt_bakedchar *chardata) {
+    return stbtt_BakeFontBitmap_internal((unsigned char *)data, offset, pixel_height, pixels, pw, ph, first_char,
+                                         num_chars, chardata);
 }
 
-STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index)
-{
-   return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index);
+STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) {
+    return stbtt_GetFontOffsetForIndex_internal((unsigned char *)data, index);
 }
 
-STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
-{
-   return stbtt_GetNumberOfFonts_internal((unsigned char *) data);
+STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) {
+    return stbtt_GetNumberOfFonts_internal((unsigned char *)data);
 }
 
-STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset)
-{
-   return stbtt_InitFont_internal(info, (unsigned char *) data, offset);
+STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset) {
+    return stbtt_InitFont_internal(info, (unsigned char *)data, offset);
 }
 
-STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags)
-{
-   return stbtt_FindMatchingFont_internal((unsigned char *) fontdata, (char *) name, flags);
+STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags) {
+    return stbtt_FindMatchingFont_internal((unsigned char *)fontdata, (char *)name, flags);
 }
 
-STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
-{
-   return stbtt_CompareUTF8toUTF16_bigendian_internal((char *) s1, len1, (char *) s2, len2);
+STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) {
+    return stbtt_CompareUTF8toUTF16_bigendian_internal((char *)s1, len1, (char *)s2, len2);
 }
 
 #if defined(__GNUC__) || defined(__clang__)
@@ -4970,7 +5085,6 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const
 
 #endif // STB_TRUETYPE_IMPLEMENTATION
 
-
 // FULL VERSION HISTORY
 //
 //   1.25 (2021-07-11) many fixes
index 090dfabb15f48a30df470966a317f7c57ebd1f41..88800c61ed2f247b91e90895d68b5ab4869fbd72 100644 (file)
 #include "vkvg_internal.h"
 
 typedef struct {
-       float x;
-       float y;
-}vec2;
+    float x;
+    float y;
+} vec2;
 
-static const vec2 vec2_unit_x = {1.f,0};
-static const vec2 vec2_unit_y = {0,1.f};
+static const vec2 vec2_unit_x = {1.f, 0};
+static const vec2 vec2_unit_y = {0, 1.f};
 
 typedef struct {
-       double x;
-       double y;
-}vec2d;
+    double x;
+    double y;
+} vec2d;
 
 /*const vec2d vec2d_unit_x = {1.0,0};
 const vec2d vec2d_unit_y = {0,1.0};*/
 
 typedef struct {
-       float x;
-       float y;
-       float z;
-}vec3;
+    float x;
+    float y;
+    float z;
+} vec3;
 
 typedef struct {
-       union {
-               float x;
-               float r;
-               float xMin;
-       };
-       union {
-               float y;
-               float g;
-               float yMin;
-       };
-       union {
-               float z;
-               float width;
-               float b;
-               float xMax;
-       };
-       union {
-               float w;
-               float height;
-               float a;
-               float yMax;
-       };
-
-}vec4;
+    union {
+        float x;
+        float r;
+        float xMin;
+    };
+    union {
+        float y;
+        float g;
+        float yMin;
+    };
+    union {
+        float z;
+        float width;
+        float b;
+        float xMax;
+    };
+    union {
+        float w;
+        float height;
+        float a;
+        float yMax;
+    };
+
+} vec4;
 
 typedef struct {
-       uint16_t x;
-       uint16_t y;
-       uint16_t z;
-       uint16_t w;
-}vec4i16;
+    uint16_t x;
+    uint16_t y;
+    uint16_t z;
+    uint16_t w;
+} vec4i16;
 
 typedef struct {
-       int16_t x;
-       int16_t y;
-}vec2i16;
+    int16_t x;
+    int16_t y;
+} vec2i16;
 
 typedef struct {
-       vec2 row0;
-       vec2 row1;
-}mat2;
+    vec2 row0;
+    vec2 row1;
+} mat2;
 
 // compute length of float vector 2d
-vkvg_inline    float vec2_length(vec2 v){
-       return sqrtf (v.x*v.x + v.y*v.y);
-}
+vkvg_inline float vec2_length(vec2 v) { return sqrtf(v.x * v.x + v.y * v.y); }
 // compute normal direction vector from line defined by 2 points in double precision
-vkvg_inline    vec2d vec2d_line_norm(vec2d a, vec2d b)
-{
-       vec2d d = {b.x - a.x, b.y - a.y};
-       double md = sqrt (d.x*d.x + d.y*d.y);
-       d.x/=md;
-       d.y/=md;
-       return d;
+vkvg_inline vec2d vec2d_line_norm(vec2d a, vec2d b) {
+    vec2d  d  = {b.x - a.x, b.y - a.y};
+    double md = sqrt(d.x * d.x + d.y * d.y);
+    d.x /= md;
+    d.y /= md;
+    return d;
 }
 // compute normal direction vector from line defined by 2 points
-vkvg_inline    vec2 vec2_line_norm(vec2 a, vec2 b)
-{
-       vec2 d = {b.x - a.x, b.y - a.y};
-       float md = sqrtf (d.x*d.x + d.y*d.y);
-       d.x/=md;
-       d.y/=md;
-       return d;
+vkvg_inline vec2 vec2_line_norm(vec2 a, vec2 b) {
+    vec2  d  = {b.x - a.x, b.y - a.y};
+    float md = sqrtf(d.x * d.x + d.y * d.y);
+    d.x /= md;
+    d.y /= md;
+    return d;
 }
 // compute sum of two double precision vectors
-vkvg_inline    vec2d vec2d_add (vec2d a, vec2d b){
-       return (vec2d){a.x + b.x, a.y + b.y};
-}
+vkvg_inline vec2d vec2d_add(vec2d a, vec2d b) { return (vec2d){a.x + b.x, a.y + b.y}; }
 // compute subbstraction of two double precision vectors
-vkvg_inline    vec2d vec2d_sub (vec2d a, vec2d b){
-       return (vec2d){a.x - b.x, a.y - b.y};
-}
+vkvg_inline vec2d vec2d_sub(vec2d a, vec2d b) { return (vec2d){a.x - b.x, a.y - b.y}; }
 // multiply 2d vector by scalar
-vkvg_inline    vec2d vec2d_mult_s(vec2d a, double m){
-       return (vec2d){a.x*m,a.y*m};
-}
-vkvg_inline    vec2d vec2d_div_s(vec2d a, double m){
-       return (vec2d){a.x/m,a.y/m};
-}
+vkvg_inline vec2d vec2d_mult_s(vec2d a, double m) { return (vec2d){a.x * m, a.y * m}; }
+vkvg_inline vec2d vec2d_div_s(vec2d a, double m) { return (vec2d){a.x / m, a.y / m}; }
 // compute length of double vector 2d
-vkvg_inline    double vec2d_length(vec2d v){
-       return sqrt (v.x*v.x + v.y*v.y);
-}
+vkvg_inline double vec2d_length(vec2d v) { return sqrt(v.x * v.x + v.y * v.y); }
 // normalize double vector
-vkvg_inline    vec2d vec2d_norm(vec2d a)
-{
-       double m = sqrt (a.x*a.x + a.y*a.y);
-       return (vec2d){a.x/m, a.y/m};
+vkvg_inline vec2d vec2d_norm(vec2d a) {
+    double m = sqrt(a.x * a.x + a.y * a.y);
+    return (vec2d){a.x / m, a.y / m};
 }
 // compute perpendicular vector
-vkvg_inline    vec2d vec2d_perp (vec2d a){
-       return (vec2d){a.y, -a.x};
-}
-vkvg_inline    bool vec2d_isnan (vec2d v){
-       return (bool)(isnan (v.x) || isnan (v.y));
-}
-
+vkvg_inline vec2d vec2d_perp(vec2d a) { return (vec2d){a.y, -a.x}; }
+vkvg_inline bool  vec2d_isnan(vec2d v) { return (bool)(isnan(v.x) || isnan(v.y)); }
 
 // test equality of two single precision vectors
-vkvg_inline    bool vec2_equ (vec2 a, vec2 b){
-       return (EQUF(a.x,b.x)&EQUF(a.y,b.y));
-}
+vkvg_inline bool vec2_equ(vec2 a, vec2 b) { return (EQUF(a.x, b.x) & EQUF(a.y, b.y)); }
 // compute sum of two single precision vectors
-vkvg_inline    vec2 vec2_add (vec2 a, vec2 b){
-       return (vec2){a.x + b.x, a.y + b.y};
-}
+vkvg_inline vec2 vec2_add(vec2 a, vec2 b) { return (vec2){a.x + b.x, a.y + b.y}; }
 // compute subbstraction of two single precision vectors
-vkvg_inline    vec2 vec2_sub (vec2 a, vec2 b){
-       return (vec2){a.x - b.x, a.y - b.y};
-}
+vkvg_inline vec2 vec2_sub(vec2 a, vec2 b) { return (vec2){a.x - b.x, a.y - b.y}; }
 // multiply 2d vector by scalar
-vkvg_inline    vec2 vec2_mult_s(vec2 a, float m){
-       return (vec2){a.x*m,a.y*m};
-}
+vkvg_inline vec2 vec2_mult_s(vec2 a, float m) { return (vec2){a.x * m, a.y * m}; }
 // devide 2d vector by scalar
-vkvg_inline    vec2 vec2_div_s(vec2 a, float m){
-       return (vec2){a.x/m,a.y/m};
-}
+vkvg_inline vec2 vec2_div_s(vec2 a, float m) { return (vec2){a.x / m, a.y / m}; }
 // normalize float vector
-vkvg_inline    vec2 vec2_norm(vec2 a)
-{
-       float m = sqrtf (a.x*a.x + a.y*a.y);
-       return (vec2){a.x/m, a.y/m};
+vkvg_inline vec2 vec2_norm(vec2 a) {
+    float m = sqrtf(a.x * a.x + a.y * a.y);
+    return (vec2){a.x / m, a.y / m};
 }
 // compute perpendicular vector
-vkvg_inline    vec2 vec2_perp (vec2 a){
-       return (vec2){a.y, -a.x};
-}
+vkvg_inline vec2 vec2_perp(vec2 a) { return (vec2){a.y, -a.x}; }
 // compute opposite of single precision vector
-vkvg_inline    void vec2_inv (vec2* v){
-       v->x = -v->x;
-       v->y = -v->y;
+vkvg_inline void vec2_inv(vec2 *v) {
+    v->x = -v->x;
+    v->y = -v->y;
 }
 // test if one component of float vector is nan
-vkvg_inline    bool vec2_isnan (vec2 v){
-       return (bool)(isnan (v.x) || isnan (v.y));
-}
+vkvg_inline bool vec2_isnan(vec2 v) { return (bool)(isnan(v.x) || isnan(v.y)); }
 // test if one component of double vector is nan
-vkvg_inline float vec2_dot (vec2 a, vec2 b) {
-       return (a.x * b.x) + (a.y * b.y);
-}
-vkvg_inline float vec2_det (vec2 a, vec2 b) {
-       return a.x * b.y - a.y * b.x;
-}
-vkvg_inline float vec2_slope (vec2 a, vec2 b) {
-       return (b.y - a.y) / (b.x - a.x);
-}
-
+vkvg_inline float vec2_dot(vec2 a, vec2 b) { return (a.x * b.x) + (a.y * b.y); }
+vkvg_inline float vec2_det(vec2 a, vec2 b) { return a.x * b.y - a.y * b.x; }
+vkvg_inline float vec2_slope(vec2 a, vec2 b) { return (b.y - a.y) / (b.x - a.x); }
 
 // convert double precision vector to single precision
-vkvg_inline    vec2 vec2d_to_vec2(vec2d vd){
-       return (vec2){(float)vd.x,(float)vd.y};
-}
-vkvg_inline    bool vec4_equ (vec4 a, vec4 b){
-       return (EQUF(a.x,b.x)&EQUF(a.y,b.y)&EQUF(a.z,b.z)&EQUF(a.w,b.w));
-}
-vkvg_inline    vec2 mat2_mult_vec2 (mat2 m, vec2 v) {
-       return (vec2){
-               (m.row0.x * v.x) + (m.row0.y * v.y),
-               (m.row1.x * v.x) + (m.row1.y * v.y)
-       };
+vkvg_inline vec2 vec2d_to_vec2(vec2d vd) { return (vec2){(float)vd.x, (float)vd.y}; }
+vkvg_inline bool vec4_equ(vec4 a, vec4 b) {
+    return (EQUF(a.x, b.x) & EQUF(a.y, b.y) & EQUF(a.z, b.z) & EQUF(a.w, b.w));
 }
-vkvg_inline    float mat2_det (mat2* m) {
-       return (m->row0.x * m->row1.y) - (m->row0.y * m->row1.y);
+vkvg_inline vec2 mat2_mult_vec2(mat2 m, vec2 v) {
+    return (vec2){(m.row0.x * v.x) + (m.row0.y * v.y), (m.row1.x * v.x) + (m.row1.y * v.y)};
 }
+vkvg_inline float mat2_det(mat2 *m) { return (m->row0.x * m->row1.y) - (m->row0.y * m->row1.y); }
 
 #endif
index cfbabe8cb9125916cec9078b0168af33638b8cd7..877afb8293e5f3bf43daf252bf067b26a1c426da 100644 (file)
 #include "vkh_queue.h"
 
 #ifdef DEBUG
-       static vec2 debugLinePoints[1000];
-       static uint32_t dlpCount = 0;
-       #if defined (VKVG_DBG_UTILS)
-               const float DBG_LAB_COLOR_SAV[4]        = {1,0,1,1};
-               const float DBG_LAB_COLOR_CLIP[4]       = {0,1,1,1};
-       #endif
+static vec2     debugLinePoints[1000];
+static uint32_t dlpCount = 0;
+#if defined(VKVG_DBG_UTILS)
+const float DBG_LAB_COLOR_SAV[4]  = {1, 0, 1, 1};
+const float DBG_LAB_COLOR_CLIP[4] = {0, 1, 1, 1};
+#endif
 #endif
 
-//todo:this could be used to define a default background
+// todo:this could be used to define a default background
 static VkClearValue clearValues[3] = {
-       { .color.float32 = {0,0,0,0} },
-       { .depthStencil  = {1.0f, 0} },
-       { .color.float32 = {0,0,0,0} }
-};
-
-void _init_ctx (VkvgContext ctx) {
-       ctx->lineWidth          = 1;
-       ctx->miterLimit         = 10;
-       ctx->curOperator        = VKVG_OPERATOR_OVER;
-       ctx->curFillRule        = VKVG_FILL_RULE_NON_ZERO;
-       ctx->bounds = (VkRect2D) {{0,0},{ctx->pSurf->width,ctx->pSurf->height}};
-       ctx->pushConsts = (push_constants) {
-                       {.a = 1},
-                       {(float)ctx->pSurf->width,(float)ctx->pSurf->height},
-                       VKVG_PATTERN_TYPE_SOLID,
-                       1.0f,
-                       VKVG_IDENTITY_MATRIX,
-                       VKVG_IDENTITY_MATRIX
-       };
-       ctx->clearRect = (VkClearRect) {{{0},{ctx->pSurf->width, ctx->pSurf->height}},0,1};
-       ctx->renderPassBeginInfo.framebuffer = ctx->pSurf->fb;
-       ctx->renderPassBeginInfo.renderArea.extent.width = ctx->pSurf->width;
-       ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height;
-       ctx->renderPassBeginInfo.pClearValues = clearValues;
-
-       LOCK_SURFACE (ctx->pSurf)
-
-       if (ctx->pSurf->newSurf)
-               ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll;
-       else
-               ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil;
-       ctx->pSurf->newSurf = false;
-
-       UNLOCK_SURFACE (ctx->pSurf);
-
-       vkvg_surface_reference (ctx->pSurf);
-
-       if (ctx->dev->samples == VK_SAMPLE_COUNT_1_BIT)
-               ctx->renderPassBeginInfo.clearValueCount = 2;
-       else
-               ctx->renderPassBeginInfo.clearValueCount = 3;
-
-       ctx->selectedCharSize   = 10 << 6;
-       ctx->currentFont                = NULL;
-       ctx->selectedFontName[0]= 0;
-       ctx->pattern                    = NULL;
-       ctx->curColor                   = 0xff000000;//opaque black
-       ctx->cmdStarted                 = false;
-       ctx->curClipState               = vkvg_clip_state_none;
-       ctx->vertCount                  = ctx->indCount = 0;
+    {.color.float32 = {0, 0, 0, 0}}, {.depthStencil = {1.0f, 0}}, {.color.float32 = {0, 0, 0, 0}}};
+
+void _init_ctx(VkvgContext ctx) {
+    ctx->lineWidth                       = 1;
+    ctx->miterLimit                      = 10;
+    ctx->curOperator                     = VKVG_OPERATOR_OVER;
+    ctx->curFillRule                     = VKVG_FILL_RULE_NON_ZERO;
+    ctx->bounds                          = (VkRect2D){{0, 0}, {ctx->pSurf->width, ctx->pSurf->height}};
+    ctx->pushConsts                      = (push_constants){{.a = 1},
+                                                            {(float)ctx->pSurf->width, (float)ctx->pSurf->height},
+                                                            VKVG_PATTERN_TYPE_SOLID,
+                                                            1.0f,
+                                                            VKVG_IDENTITY_MATRIX,
+                                                            VKVG_IDENTITY_MATRIX};
+    ctx->clearRect                       = (VkClearRect){{{0}, {ctx->pSurf->width, ctx->pSurf->height}}, 0, 1};
+    ctx->renderPassBeginInfo.framebuffer = ctx->pSurf->fb;
+    ctx->renderPassBeginInfo.renderArea.extent.width  = ctx->pSurf->width;
+    ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height;
+    ctx->renderPassBeginInfo.pClearValues             = clearValues;
+
+    LOCK_SURFACE(ctx->pSurf)
+
+    if (ctx->pSurf->newSurf)
+        ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll;
+    else
+        ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil;
+    ctx->pSurf->newSurf = false;
+
+    UNLOCK_SURFACE(ctx->pSurf);
+
+    vkvg_surface_reference(ctx->pSurf);
+
+    if (ctx->dev->samples == VK_SAMPLE_COUNT_1_BIT)
+        ctx->renderPassBeginInfo.clearValueCount = 2;
+    else
+        ctx->renderPassBeginInfo.clearValueCount = 3;
+
+    ctx->selectedCharSize    = 10 << 6;
+    ctx->currentFont         = NULL;
+    ctx->selectedFontName[0] = 0;
+    ctx->pattern             = NULL;
+    ctx->curColor            = 0xff000000; // opaque black
+    ctx->cmdStarted          = false;
+    ctx->curClipState        = vkvg_clip_state_none;
+    ctx->vertCount = ctx->indCount = 0;
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       ctx->timelineStep               = 0;
+    ctx->timelineStep = 0;
 #endif
 }
 
-VkvgContext vkvg_create(VkvgSurface surf)
-{
-       VkvgDevice dev = surf->dev;
-       VkvgContext ctx = NULL;
+VkvgContext vkvg_create(VkvgSurface surf) {
+    VkvgDevice  dev = surf->dev;
+    VkvgContext ctx = NULL;
 
-       if (_device_try_get_cached_context (dev, &ctx) ) {
-               ctx->pSurf = surf;
+    if (_device_try_get_cached_context(dev, &ctx)) {
+        ctx->pSurf = surf;
 
-               if (!surf || surf->status) {
-                       ctx->status = VKVG_STATUS_INVALID_SURFACE;
-                       return ctx;
-               }
+        if (!surf || surf->status) {
+            ctx->status = VKVG_STATUS_INVALID_SURFACE;
+            return ctx;
+        }
 
-               _init_ctx (ctx);
-               _update_descriptor_set (ctx, surf->dev->emptyImg, ctx->dsSrc);
-               _clear_path     (ctx);
-               ctx->cmd = ctx->cmdBuffers[0];//current recording buffer
-               ctx->status = VKVG_STATUS_SUCCESS;
-               return ctx;
-       }
-       ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context));
+        _init_ctx(ctx);
+        _update_descriptor_set(ctx, surf->dev->emptyImg, ctx->dsSrc);
+        _clear_path(ctx);
+        ctx->cmd    = ctx->cmdBuffers[0]; // current recording buffer
+        ctx->status = VKVG_STATUS_SUCCESS;
+        return ctx;
+    }
+    ctx = (vkvg_context *)calloc(1, sizeof(vkvg_context));
 
-       LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf);
+    LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf);
 
-       if (!ctx)
-               return (VkvgContext)&_no_mem_status;
+    if (!ctx)
+        return (VkvgContext)&_no_mem_status;
 
-       ctx->pSurf = surf;
+    ctx->pSurf = surf;
 
-       if (!surf || surf->status) {
-               ctx->status = VKVG_STATUS_INVALID_SURFACE;
-               return ctx;
-       }
+    if (!surf || surf->status) {
+        ctx->status = VKVG_STATUS_INVALID_SURFACE;
+        return ctx;
+    }
 
-       ctx->sizePoints         = VKVG_PTS_SIZE;
-       ctx->sizeVertices       = ctx->sizeVBO = VKVG_VBO_SIZE;
-       ctx->sizeIndices        = ctx->sizeIBO = VKVG_IBO_SIZE;
-       ctx->sizePathes         = VKVG_PATHES_SIZE;
-       ctx->renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+    ctx->sizePoints   = VKVG_PTS_SIZE;
+    ctx->sizeVertices = ctx->sizeVBO = VKVG_VBO_SIZE;
+    ctx->sizeIndices = ctx->sizeIBO = VKVG_IBO_SIZE;
+    ctx->sizePathes                 = VKVG_PATHES_SIZE;
+    ctx->renderPassBeginInfo.sType  = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
 
-       ctx->dev = surf->dev;
+    ctx->dev = surf->dev;
 
-       _init_ctx (ctx);
+    _init_ctx(ctx);
 
-       ctx->points                     = (vec2*)malloc (VKVG_VBO_SIZE * sizeof(vec2));
-       ctx->pathes                     = (uint32_t*)malloc (VKVG_PATHES_SIZE * sizeof(uint32_t));
-       ctx->vertexCache        = (Vertex*)malloc (ctx->sizeVertices * sizeof(Vertex));
-       ctx->indexCache         = (VKVG_IBO_INDEX_TYPE*)malloc (ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE));
+    ctx->points      = (vec2 *)malloc(VKVG_VBO_SIZE * sizeof(vec2));
+    ctx->pathes      = (uint32_t *)malloc(VKVG_PATHES_SIZE * sizeof(uint32_t));
+    ctx->vertexCache = (Vertex *)malloc(ctx->sizeVertices * sizeof(Vertex));
+    ctx->indexCache  = (VKVG_IBO_INDEX_TYPE *)malloc(ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE));
 
-       if (!ctx->points || !ctx->pathes || !ctx->vertexCache || !ctx->indexCache) {
-               dev->status = VKVG_STATUS_NO_MEMORY;
-               if (ctx->points)
-                       free(ctx->points);
-               if (ctx->pathes)
-                       free(ctx->pathes);
-               if (ctx->vertexCache)
-                       free(ctx->vertexCache);
-               if (ctx->indexCache)
-                       free(ctx->indexCache);
-               return NULL;
-       }
+    if (!ctx->points || !ctx->pathes || !ctx->vertexCache || !ctx->indexCache) {
+        dev->status = VKVG_STATUS_NO_MEMORY;
+        if (ctx->points)
+            free(ctx->points);
+        if (ctx->pathes)
+            free(ctx->pathes);
+        if (ctx->vertexCache)
+            free(ctx->vertexCache);
+        if (ctx->indexCache)
+            free(ctx->indexCache);
+        return NULL;
+    }
 
-       //for context to be thread safe, command pool and descriptor pool have to be created in the thread of the context.
-       ctx->cmdPool    = vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
+    // for context to be thread safe, command pool and descriptor pool have to be created in the thread of the context.
+    ctx->cmdPool =
+        vkh_cmd_pool_create((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
 
 #ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)ctx->dev);
+    ctx->flushFence = vkh_fence_create_signaled((VkhDevice)ctx->dev);
 #endif
 
-       _create_vertices_buff   (ctx);
-       _create_gradient_buff   (ctx);
-       _create_cmd_buff                (ctx);
-       _createDescriptorPool   (ctx);
-       _init_descriptor_sets   (ctx);
-       _font_cache_update_context_descset (ctx);
-       _update_descriptor_set  (ctx, surf->dev->emptyImg, ctx->dsSrc);
-       _update_gradient_desc_set(ctx);
+    _create_vertices_buff(ctx);
+    _create_gradient_buff(ctx);
+    _create_cmd_buff(ctx);
+    _createDescriptorPool(ctx);
+    _init_descriptor_sets(ctx);
+    _font_cache_update_context_descset(ctx);
+    _update_descriptor_set(ctx, surf->dev->emptyImg, ctx->dsSrc);
+    _update_gradient_desc_set(ctx);
 
-       _clear_path                             (ctx);
+    _clear_path(ctx);
 
-       ctx->cmd = ctx->cmdBuffers[0];//current recording buffer
+    ctx->cmd = ctx->cmdBuffers[0]; // current recording buffer
 
-       ctx->references = 1;
-       ctx->status = VKVG_STATUS_SUCCESS;
+    ctx->references = 1;
+    ctx->status     = VKVG_STATUS_SUCCESS;
 
-       LOG(VKVG_LOG_DBG_ARRAYS, "INIT\tctx = %p; pathes:%ju pts:%ju vch:%d vbo:%d ich:%d ibo:%d\n", ctx, (uint64_t)ctx->sizePathes, (uint64_t)ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices, ctx->sizeIBO);
+    LOG(VKVG_LOG_DBG_ARRAYS, "INIT\tctx = %p; pathes:%ju pts:%ju vch:%d vbo:%d ich:%d ibo:%d\n", ctx,
+        (uint64_t)ctx->sizePathes, (uint64_t)ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices,
+        ctx->sizeIBO);
 
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)ctx->cmdPool, "CTX Cmd Pool");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[0], "CTX Cmd Buff A");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[1], "CTX Cmd Buff B");
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)ctx->cmdPool, "CTX Cmd Pool");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[0],
+                               "CTX Cmd Buff A");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[1],
+                               "CTX Cmd Buff B");
 #ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)ctx->flushFence, "CTX Flush Fence");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)ctx->flushFence, "CTX Flush Fence");
 #endif
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (uint64_t)ctx->descriptorPool, "CTX Descriptor Pool");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsSrc, "CTX DescSet SOURCE");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsFont, "CTX DescSet FONT");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsGrad, "CTX DescSet GRADIENT");
-
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->indices.buffer, "CTX Index Buff");
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->vertices.buffer, "CTX Vertex Buff");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (uint64_t)ctx->descriptorPool,
+                               "CTX Descriptor Pool");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsSrc,
+                               "CTX DescSet SOURCE");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsFont,
+                               "CTX DescSet FONT");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsGrad,
+                               "CTX DescSet GRADIENT");
+
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->indices.buffer, "CTX Index Buff");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->vertices.buffer,
+                               "CTX Vertex Buff");
 #endif
 
-       return ctx;
-}
-void vkvg_flush (VkvgContext ctx){
-       if (ctx->status)
-               return;
-       _flush_cmd_buff         (ctx);
-       _wait_ctx_flush_end     (ctx);
-/*
-#ifdef DEBUG
-
-       vec4 red = {0,0,1,1};
-       vec4 green = {0,1,0,1};
-       vec4 white = {1,1,1,1};
-
-       int j = 0;
-       while (j < dlpCount) {
-               add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],green);
-               j+=2;
-               add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],red);
-               j+=2;
-               add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],white);
-               j+=2;
-       }
-       dlpCount = 0;
-       CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLineList);
-       CmdDrawIndexed(ctx->cmd, ctx->indCount-ctx->curIndStart, 1, ctx->curIndStart, 0, 1);
-       _flush_cmd_buff(ctx);
-#endif
-*/
-}
-
-void _clear_context (VkvgContext ctx) {
-       //free saved context stack elmt
-       vkvg_context_save_t* next = ctx->pSavedCtxs;
-       ctx->pSavedCtxs = NULL;
-       while (next != NULL) {
-               vkvg_context_save_t* cur = next;
-               next = cur->pNext;
-               _free_ctx_save (cur);
-       }
-       //free additional stencil use in save/restore process
-       if (ctx->savedStencils) {
-               uint8_t curSaveStencil = ctx->curSavBit / 6;
-               for (int i=curSaveStencil;i>0;i--)
-                       vkh_image_destroy(ctx->savedStencils[i-1]);
-               free(ctx->savedStencils);
-               ctx->savedStencils = NULL;
-               ctx->curSavBit = 0;
-       }
-
-       //remove context from double linked list of context in device
-       /*if (ctx->dev->lastCtx == ctx){
-               ctx->dev->lastCtx = ctx->pPrev;
-               if (ctx->pPrev != NULL)
-                       ctx->pPrev->pNext = NULL;
-       }else if (ctx->pPrev == NULL){
-               //first elmt, and it's not last one so pnext is not null
-               ctx->pNext->pPrev = NULL;
-       }else{
-               ctx->pPrev->pNext = ctx->pNext;
-               ctx->pNext->pPrev = ctx->pPrev;
-       }*/
-       if (ctx->dashCount > 0) {
-               free(ctx->dashes);
-               ctx->dashCount = 0;
-       }
-}
-
-void vkvg_destroy (VkvgContext ctx)
-{
-       if (ctx->status)
-               return;
-
-       ctx->references--;
-       if (ctx->references > 0)
-               return;
-
-       LOG(VKVG_LOG_INFO, "DESTROY Context: ctx = %p (status:%d); surf = %p\n", ctx, ctx->status, ctx->pSurf);
-
-       vkvg_flush (ctx);
-
-       LOG(VKVG_LOG_DBG_ARRAYS, "END\tctx = %p; pathes:%d pts:%d vch:%d vbo:%d ich:%d ibo:%d\n", ctx, ctx->sizePathes, ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices, ctx->sizeIBO);
+    return ctx;
+}
+void vkvg_flush(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    _flush_cmd_buff(ctx);
+    _wait_ctx_flush_end(ctx);
+    /*
+    #ifdef DEBUG
+
+        vec4 red = {0,0,1,1};
+        vec4 green = {0,1,0,1};
+        vec4 white = {1,1,1,1};
+
+        int j = 0;
+        while (j < dlpCount) {
+            add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],green);
+            j+=2;
+            add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],red);
+            j+=2;
+            add_line(ctx, debugLinePoints[j], debugLinePoints[j+1],white);
+            j+=2;
+        }
+        dlpCount = 0;
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLineList);
+        CmdDrawIndexed(ctx->cmd, ctx->indCount-ctx->curIndStart, 1, ctx->curIndStart, 0, 1);
+        _flush_cmd_buff(ctx);
+    #endif
+    */
+}
+
+void _clear_context(VkvgContext ctx) {
+    // free saved context stack elmt
+    vkvg_context_save_t *next = ctx->pSavedCtxs;
+    ctx->pSavedCtxs           = NULL;
+    while (next != NULL) {
+        vkvg_context_save_t *cur = next;
+        next                     = cur->pNext;
+        _free_ctx_save(cur);
+    }
+    // free additional stencil use in save/restore process
+    if (ctx->savedStencils) {
+        uint8_t curSaveStencil = ctx->curSavBit / 6;
+        for (int i = curSaveStencil; i > 0; i--)
+            vkh_image_destroy(ctx->savedStencils[i - 1]);
+        free(ctx->savedStencils);
+        ctx->savedStencils = NULL;
+        ctx->curSavBit     = 0;
+    }
+
+    // remove context from double linked list of context in device
+    /*if (ctx->dev->lastCtx == ctx){
+        ctx->dev->lastCtx = ctx->pPrev;
+        if (ctx->pPrev != NULL)
+            ctx->pPrev->pNext = NULL;
+    }else if (ctx->pPrev == NULL){
+        //first elmt, and it's not last one so pnext is not null
+        ctx->pNext->pPrev = NULL;
+    }else{
+        ctx->pPrev->pNext = ctx->pNext;
+        ctx->pNext->pPrev = ctx->pPrev;
+    }*/
+    if (ctx->dashCount > 0) {
+        free(ctx->dashes);
+        ctx->dashCount = 0;
+    }
+}
+
+void vkvg_destroy(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+
+    ctx->references--;
+    if (ctx->references > 0)
+        return;
+
+    LOG(VKVG_LOG_INFO, "DESTROY Context: ctx = %p (status:%d); surf = %p\n", ctx, ctx->status, ctx->pSurf);
+
+    vkvg_flush(ctx);
+
+    LOG(VKVG_LOG_DBG_ARRAYS, "END\tctx = %p; pathes:%d pts:%d vch:%d vbo:%d ich:%d ibo:%d\n", ctx, ctx->sizePathes,
+        ctx->sizePoints, ctx->sizeVertices, ctx->sizeVBO, ctx->sizeIndices, ctx->sizeIBO);
 
 #if VKVG_RECORDING
-       if (ctx->recording)
-               _destroy_recording(ctx->recording);
+    if (ctx->recording)
+        _destroy_recording(ctx->recording);
 #endif
 
-       if (ctx->pattern)
-               vkvg_pattern_destroy (ctx->pattern);
+    if (ctx->pattern)
+        vkvg_pattern_destroy(ctx->pattern);
 
-       _clear_context (ctx);
+    _clear_context(ctx);
 
 #if VKVG_DBG_STATS
-       if (ctx->dev->threadAware)
-               mtx_lock (&ctx->dev->mutex);
-       
-       vkvg_debug_stats_t* dbgstats = &ctx->dev->debug_stats;
-       if (dbgstats->sizePoints < ctx->sizePoints)
-               dbgstats->sizePoints = ctx->sizePoints;
-       if (dbgstats->sizePathes < ctx->sizePathes)
-               dbgstats->sizePathes = ctx->sizePathes;
-       if (dbgstats->sizeVertices < ctx->sizeVertices)
-               dbgstats->sizeVertices = ctx->sizeVertices;
-       if (dbgstats->sizeIndices < ctx->sizeIndices)
-               dbgstats->sizeIndices = ctx->sizeIndices;
-       if (dbgstats->sizeVBO < ctx->sizeVBO)
-               dbgstats->sizeVBO = ctx->sizeVBO;
-       if (dbgstats->sizeIBO < ctx->sizeIBO)
-               dbgstats->sizeIBO = ctx->sizeIBO;
-
-       if (ctx->dev->threadAware)
-               mtx_unlock (&ctx->dev->mutex);
+    if (ctx->dev->threadAware)
+        mtx_lock(&ctx->dev->mutex);
+
+    vkvg_debug_stats_t *dbgstats = &ctx->dev->debug_stats;
+    if (dbgstats->sizePoints < ctx->sizePoints)
+        dbgstats->sizePoints = ctx->sizePoints;
+    if (dbgstats->sizePathes < ctx->sizePathes)
+        dbgstats->sizePathes = ctx->sizePathes;
+    if (dbgstats->sizeVertices < ctx->sizeVertices)
+        dbgstats->sizeVertices = ctx->sizeVertices;
+    if (dbgstats->sizeIndices < ctx->sizeIndices)
+        dbgstats->sizeIndices = ctx->sizeIndices;
+    if (dbgstats->sizeVBO < ctx->sizeVBO)
+        dbgstats->sizeVBO = ctx->sizeVBO;
+    if (dbgstats->sizeIBO < ctx->sizeIBO)
+        dbgstats->sizeIBO = ctx->sizeIBO;
+
+    if (ctx->dev->threadAware)
+        mtx_unlock(&ctx->dev->mutex);
 #endif
 
-       vkvg_surface_destroy(ctx->pSurf);
+    vkvg_surface_destroy(ctx->pSurf);
 
-       if (!ctx->status && ctx->dev->cachedContextCount < VKVG_MAX_CACHED_CONTEXT_COUNT) {
-               _device_store_context (ctx);
-               return;
-       }
+    if (!ctx->status && ctx->dev->cachedContextCount < VKVG_MAX_CACHED_CONTEXT_COUNT) {
+        _device_store_context(ctx);
+        return;
+    }
 
-       _release_context_ressources (ctx);
+    _release_context_ressources(ctx);
 }
-void vkvg_set_opacity (VkvgContext ctx, float opacity) {
-       if (ctx->status)
-               return;
+void vkvg_set_opacity(VkvgContext ctx, float opacity) {
+    if (ctx->status)
+        return;
 
-       if (EQUF(ctx->pushConsts.opacity, opacity))
-               return;
+    if (EQUF(ctx->pushConsts.opacity, opacity))
+        return;
 
-       _emit_draw_cmd_undrawn_vertices (ctx);
-       ctx->pushConsts.opacity = opacity;
-       ctx->pushCstDirty = true;
-}
-float vkvg_get_opacity (VkvgContext ctx) {
-       if (ctx->status)
-               return 0;
-       return ctx->pushConsts.opacity;
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    ctx->pushConsts.opacity = opacity;
+    ctx->pushCstDirty       = true;
 }
-vkvg_status_t vkvg_status (VkvgContext ctx) {
-       return ctx->status;
+float vkvg_get_opacity(VkvgContext ctx) {
+    if (ctx->status)
+        return 0;
+    return ctx->pushConsts.opacity;
 }
-VkvgContext vkvg_reference (VkvgContext ctx) {
-       if (!ctx->status)
-               ctx->references++;
-       return ctx;
+vkvg_status_t vkvg_status(VkvgContext ctx) { return ctx->status; }
+VkvgContext   vkvg_reference(VkvgContext ctx) {
+    if (!ctx->status)
+        ctx->references++;
+    return ctx;
 }
-uint32_t vkvg_get_reference_count (VkvgContext ctx) {
-       if (ctx->status)
-               return 0;
-       return ctx->references;
+uint32_t vkvg_get_reference_count(VkvgContext ctx) {
+    if (ctx->status)
+        return 0;
+    return ctx->references;
 }
-void vkvg_new_sub_path (VkvgContext ctx){
-       if (ctx->status)
-               return;
+void vkvg_new_sub_path(VkvgContext ctx) {
+    if (ctx->status)
+        return;
 
-       RECORD(ctx, VKVG_CMD_NEW_SUB_PATH);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: new_sub_path:\n");
+    RECORD(ctx, VKVG_CMD_NEW_SUB_PATH);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: new_sub_path:\n");
 
-       _finish_path(ctx);
+    _finish_path(ctx);
 }
-void vkvg_new_path (VkvgContext ctx){
-       if (ctx->status)
-               return;
+void vkvg_new_path(VkvgContext ctx) {
+    if (ctx->status)
+        return;
 
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: new_path:\n");
-
-       _clear_path(ctx);
-       RECORD(ctx, VKVG_CMD_NEW_PATH);
-}
-void vkvg_close_path (VkvgContext ctx){
-       if (ctx->status)
-               return;
-
-       RECORD(ctx, VKVG_CMD_CLOSE_PATH);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: close_path:\n");
-
-       if (ctx->pathes[ctx->pathPtr] & PATH_CLOSED_BIT) //already closed
-               return;
-       //check if at least 3 points are present
-       if (ctx->pathes[ctx->pathPtr] < 3)
-               return;
-
-       //prevent closing on the same point
-       if (vec2_equ(ctx->points[ctx->pointCount-1],
-                                ctx->points[ctx->pointCount - ctx->pathes[ctx->pathPtr]])) {
-               if (ctx->pathes[ctx->pathPtr] < 4)//ensure enough points left for closing
-                       return;
-               _remove_last_point(ctx);
-       }
-
-       ctx->pathes[ctx->pathPtr] |= PATH_CLOSED_BIT;
-
-       _finish_path(ctx);
-}
-void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy){
-       if (ctx->status)
-               return;
-
-       RECORD(ctx, VKVG_CMD_REL_LINE_TO, dx, dy);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_line_to: %f, %f\n", dx, dy);
-
-       if (_current_path_is_empty(ctx))
-               _add_point(ctx, 0, 0);
-       vec2 cp = _get_current_position(ctx);
-       _line_to(ctx, cp.x + dx, cp.y + dy);
-}
-void vkvg_line_to (VkvgContext ctx, float x, float y)
-{
-       if (ctx->status)
-               return;
-
-       RECORD(ctx, VKVG_CMD_LINE_TO, x, y);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: line_to: %f, %f\n", x, y);
-       _line_to(ctx, x, y);
-}
-void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2){
-       if (ctx->status)
-               return;
-
-       RECORD(ctx, VKVG_CMD_ARC, xc, yc, radius, a1, a2);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: arc: %f,%f %f %f %f\n", xc, yc, radius, a1, a2);
-
-       while (a2 < a1)//positive arc must have a1<a2
-               a2 += 2.f*M_PIF;
-
-       if (a2 - a1 > 2.f * M_PIF) //limit arc to 2PI
-               a2 = a1 + 2.f * M_PIF;
-
-       vec2 v = {cosf(a1)*radius + xc, sinf(a1)*radius + yc};
-
-       float step = _get_arc_step(ctx, radius);
-       float a = a1;
-
-       if (_current_path_is_empty(ctx)){
-               _set_curve_start (ctx);
-               _add_point (ctx, v.x, v.y);
-               if (!ctx->pathPtr)
-                       ctx->simpleConvex = true;
-               else
-                       ctx->simpleConvex = false;
-       }else{
-               _line_to(ctx, v.x, v.y);
-               _set_curve_start (ctx);
-               ctx->simpleConvex = false;
-       }
-
-       a+=step;
-
-       if (EQUF(a2, a1))
-               return;
-
-       while(a < a2){
-               v.x = cosf(a)*radius + xc;
-               v.y = sinf(a)*radius + yc;
-               _add_point (ctx, v.x, v.y);
-               a+=step;
-       }
-
-       if (EQUF(a2-a1,M_PIF*2.f)){//if arc is complete circle, last point is the same as the first one
-               _set_curve_end(ctx);
-               vkvg_close_path(ctx);
-               return;
-       }
-       a = a2;
-       //vec2 lastP = v;
-       v.x = cosf(a)*radius + xc;
-       v.y = sinf(a)*radius + yc;
-       //if (!vec2_equ (v,lastP))//this test should not be required
-               _add_point (ctx, v.x, v.y);
-       _set_curve_end(ctx);
-}
-void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_ARC_NEG, xc, yc, radius, a1, a2);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: %f,%f %f %f %f\n", xc, yc, radius, a1, a2);
-       while (a2 > a1)
-               a2 -= 2.f*M_PIF;
-       if (a1 - a2 > a1 + 2.f * M_PIF) //limit arc to 2PI
-               a2 = a1 - 2.f * M_PIF;
-
-       vec2 v = {cosf(a1)*radius + xc, sinf(a1)*radius + yc};
-
-       float step = _get_arc_step(ctx, radius);
-       float a = a1;
-
-       if (_current_path_is_empty(ctx)){
-               _set_curve_start (ctx);
-               _add_point (ctx, v.x, v.y);
-               if (!ctx->pathPtr)
-                       ctx->simpleConvex = true;
-               else
-                       ctx->simpleConvex = false;
-       }else{
-               _line_to(ctx, v.x, v.y);
-               _set_curve_start (ctx);
-               ctx->simpleConvex = false;
-       }
-
-       a-=step;
-
-       if (EQUF(a2, a1))
-               return;
-
-       while(a > a2){
-               v.x = cosf(a)*radius + xc;
-               v.y = sinf(a)*radius + yc;
-               _add_point (ctx,v.x,v.y);
-               a-=step;
-       }
-
-       if (EQUF(a1-a2,M_PIF*2.f)){//if arc is complete circle, last point is the same as the first one
-               _set_curve_end(ctx);
-               vkvg_close_path(ctx);
-               return;
-       }
-
-       a = a2;
-       //vec2 lastP = v;
-       v.x = cosf(a)*radius + xc;
-       v.y = sinf(a)*radius + yc;
-       //if (!vec2_equ (v,lastP))
-               _add_point (ctx, v.x, v.y);
-       _set_curve_end(ctx);
-}
-void vkvg_rel_move_to (VkvgContext ctx, float x, float y)
-{
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_REL_MOVE_TO, x, y);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_mote_to: %f, %f\n", x, y);
-       if (_current_path_is_empty(ctx))
-               _add_point(ctx, 0, 0);
-       vec2 cp = _get_current_position(ctx);
-       _finish_path(ctx);
-       _add_point (ctx, cp.x + x, cp.y + y);
-}
-void vkvg_move_to (VkvgContext ctx, float x, float y)
-{
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_MOVE_TO, x, y);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: move_to: %f,%f\n", x, y);
-       _finish_path(ctx);
-       _add_point (ctx, x, y);
-}
-bool vkvg_has_current_point (VkvgContext ctx) {
-       if (ctx->status)
-               return false;
-       return !_current_path_is_empty(ctx);
-}
-void vkvg_get_current_point (VkvgContext ctx, float* x, float* y) {
-       if (ctx->status || _current_path_is_empty(ctx)) {
-               *x = *y = 0;
-               return;
-       }
-       vec2 cp = _get_current_position(ctx);
-       *x = cp.x;
-       *y = cp.y;
-}
-void _curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
-       //prevent running _recursive_bezier when all 4 curve points are equal
-       if (EQUF(x1,x2) && EQUF(x2,x3) && EQUF(y1,y2) && EQUF(y2,y3)) {
-               if (_current_path_is_empty(ctx) || (EQUF(_get_current_position(ctx).x,x1) && EQUF(_get_current_position(ctx).y,y1)))
-                       return;
-       }
-       ctx->simpleConvex = false;
-       _set_curve_start (ctx);
-       if (_current_path_is_empty(ctx))
-               _add_point(ctx, x1, y1);
-
-       vec2 cp = _get_current_position(ctx);
-
-       //compute dyn distanceTolerance depending on current scale
-       float sx = 1, sy = 1;
-       vkvg_matrix_get_scale (&ctx->pushConsts.mat, &sx, &sy);
-       float distanceTolerance = fabs(0.25f / fmaxf(sx,sy));
-
-       _recursive_bezier (ctx, distanceTolerance, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0);
-       /*cp.x = x3;
-       cp.y = y3;
-       if (!vec2_equ(ctx->points[ctx->pointCount-1],cp))*/
-               _add_point(ctx,x3,y3);
-       _set_curve_end (ctx);
-}
-const double quadraticFact = 2.0/3.0;
-void _quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2) {
-       float x0, y0;
-       if (_current_path_is_empty(ctx)) {
-               x0 = x1;
-               y0 = y1;
-       } else
-               vkvg_get_current_point (ctx, &x0, &y0);
-       _curve_to (ctx,
-                                       x0 + (x1 - x0) * quadraticFact,
-                                       y0 + (y1 - y0) * quadraticFact,
-                                       x2 + (x1 - x2) * quadraticFact,
-                                       y2 + (y1 - y2) * quadraticFact,
-                                       x2, y2);
-}
-void vkvg_quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_QUADRATIC_TO, x1, y1, x2, y2);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: quadratic_to: %f, %f, %f, %f\n", x1, y1, x2, y2);
-       _quadratic_to(ctx, x1, y1, x2, y2);
-}
-void vkvg_rel_quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_REL_QUADRATIC_TO, x1, y1, x2, y2);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_quadratic_to: %f, %f, %f, %f\n", x1, y1, x2, y2);
-       vec2 cp = _get_current_position(ctx);
-       _quadratic_to (ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2);
-}
-void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_CURVE_TO, x1, y1, x2, y2, x3, y3);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: curve_to %f,%f %f,%f %f,%f:\n", x1, y1, x2, y2, x3, y3);
-       _curve_to (ctx, x1, y1, x2, y2, x3, y3);
-}
-void vkvg_rel_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
-       if (ctx->status)
-               return;
-       if (_current_path_is_empty(ctx)) {
-               ctx->status = VKVG_STATUS_NO_CURRENT_POINT;
-               return;
-       }
-       RECORD(ctx, (uint32_t)VKVG_CMD_REL_CURVE_TO, x1, y1, x2, y2, x3, y3);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel curve_to %f,%f %f,%f %f,%f:\n", x1, y1, x2, y2, x3, y3);
-       vec2 cp = _get_current_position(ctx);
-       _curve_to (ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2, cp.x + x3, cp.y + y3);
-}
-void vkvg_fill_rectangle (VkvgContext ctx, float x, float y, float w, float h){
-       if (ctx->status)
-               return;
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: fill_rectangle:\n");
-       _vao_add_rectangle (ctx,x,y,w,h);
-       //_record_draw_cmd(ctx);
-}
-
-vkvg_status_t vkvg_rectangle (VkvgContext ctx, float x, float y, float w, float h){
-       if (ctx->status)
-               return ctx->status;
-       RECORD2(ctx, VKVG_CMD_RECTANGLE, x, y, w, h);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: rectangle: %f,%f,%f,%f\n", x, y, w, h);
-       _finish_path (ctx);
-
-       if (w <= 0 || h <= 0)
-               return VKVG_STATUS_INVALID_RECT;
-
-       _add_point (ctx, x, y);
-       _add_point (ctx, x + w, y);
-       _add_point (ctx, x + w, y + h);
-       _add_point (ctx, x, y + h);     
-
-       ctx->pathes[ctx->pathPtr] |= (PATH_CLOSED_BIT|PATH_IS_CONVEX_BIT);
-
-       _finish_path(ctx);
-       return VKVG_STATUS_SUCCESS;
-}
-vkvg_status_t vkvg_rounded_rectangle (VkvgContext ctx, float x, float y, float w, float h, float radius){
-       if (ctx->status)
-               return ctx->status;
-       LOG(VKVG_LOG_INFO_CMD, "CMD: rounded_rectangle:\n");
-       _finish_path (ctx);
-
-       if (w <= 0 || h <= 0)
-               return VKVG_STATUS_INVALID_RECT;
-
-       if ((radius > w / 2.0f) || (radius > h / 2.0f))
-               radius = fmin (w / 2.0f, h / 2.0f);
-
-       vkvg_move_to(ctx, x, y + radius);
-       vkvg_arc(ctx, x + radius, y + radius, radius, M_PIF, -M_PIF_2);
-       vkvg_line_to(ctx, x + w - radius, y);
-       vkvg_arc(ctx, x + w - radius, y + radius, radius, -M_PIF_2, 0);
-       vkvg_line_to(ctx, x + w, y + h - radius);
-       vkvg_arc(ctx, x + w - radius, y + h - radius, radius, 0, M_PIF_2);
-       vkvg_line_to(ctx, x + radius, y + h);
-       vkvg_arc(ctx, x + radius, y + h - radius, radius, M_PIF_2, M_PIF);
-       vkvg_line_to(ctx, x, y + radius);
-       vkvg_close_path(ctx);
-
-       return VKVG_STATUS_SUCCESS;
-}
-void vkvg_rounded_rectangle2 (VkvgContext ctx, float x, float y, float w, float h, float rx, float ry){
-       if (ctx->status)
-               return;
-       LOG(VKVG_LOG_INFO_CMD, "CMD: rounded_rectangle2:\n");
-       vkvg_move_to (ctx, x+rx, y);
-       vkvg_line_to (ctx, x+w-rx, y);
-       vkvg_elliptic_arc_to(ctx, x+w, y+ry, false, true, rx, ry, 0);
-
-       vkvg_line_to (ctx, x+w, y+h-ry);
-       vkvg_elliptic_arc_to(ctx, x+w-rx, y+h, false, true, rx, ry, 0);
-
-       vkvg_line_to (ctx, x+rx, y+h);
-       vkvg_elliptic_arc_to(ctx, x, y+h-ry , false, true, rx, ry, 0);
-
-       vkvg_line_to (ctx, x, y+ry);
-       vkvg_elliptic_arc_to(ctx, x+rx, y , false, true, rx, ry, 0);
-
-       vkvg_close_path(ctx);
-}
-void vkvg_path_extents (VkvgContext ctx, float *x1, float *y1, float *x2, float *y2) {
-       if (ctx->status)
-               return;
-
-       _finish_path(ctx);
-
-       if (!ctx->pathPtr) {//no path
-               *x1 = *x2 = *y1 = *y2 = 0;
-               return;
-       }
-
-       _vkvg_path_extents(ctx, false, x1, y1, x2, y2);
-}
-
-vkvg_clip_state_t _get_previous_clip_state (VkvgContext ctx) {
-       if (!ctx->pSavedCtxs)//no clip saved => clear
-               return vkvg_clip_state_clear;
-       return ctx->pSavedCtxs->clippingState;
-}
-static const VkClearAttachment clearStencil               = {VK_IMAGE_ASPECT_STENCIL_BIT, 1, {{{0}}}};
-static const VkClearAttachment clearColorAttach           = {VK_IMAGE_ASPECT_COLOR_BIT,   0, {{{0}}}};
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: new_path:\n");
+
+    _clear_path(ctx);
+    RECORD(ctx, VKVG_CMD_NEW_PATH);
+}
+void vkvg_close_path(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+
+    RECORD(ctx, VKVG_CMD_CLOSE_PATH);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: close_path:\n");
+
+    if (ctx->pathes[ctx->pathPtr] & PATH_CLOSED_BIT) // already closed
+        return;
+    // check if at least 3 points are present
+    if (ctx->pathes[ctx->pathPtr] < 3)
+        return;
+
+    // prevent closing on the same point
+    if (vec2_equ(ctx->points[ctx->pointCount - 1], ctx->points[ctx->pointCount - ctx->pathes[ctx->pathPtr]])) {
+        if (ctx->pathes[ctx->pathPtr] < 4) // ensure enough points left for closing
+            return;
+        _remove_last_point(ctx);
+    }
+
+    ctx->pathes[ctx->pathPtr] |= PATH_CLOSED_BIT;
+
+    _finish_path(ctx);
+}
+void vkvg_rel_line_to(VkvgContext ctx, float dx, float dy) {
+    if (ctx->status)
+        return;
+
+    RECORD(ctx, VKVG_CMD_REL_LINE_TO, dx, dy);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_line_to: %f, %f\n", dx, dy);
+
+    if (_current_path_is_empty(ctx))
+        _add_point(ctx, 0, 0);
+    vec2 cp = _get_current_position(ctx);
+    _line_to(ctx, cp.x + dx, cp.y + dy);
+}
+void vkvg_line_to(VkvgContext ctx, float x, float y) {
+    if (ctx->status)
+        return;
+
+    RECORD(ctx, VKVG_CMD_LINE_TO, x, y);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: line_to: %f, %f\n", x, y);
+    _line_to(ctx, x, y);
+}
+void vkvg_arc(VkvgContext ctx, float xc, float yc, float radius, float a1, float a2) {
+    if (ctx->status)
+        return;
+
+    RECORD(ctx, VKVG_CMD_ARC, xc, yc, radius, a1, a2);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: arc: %f,%f %f %f %f\n", xc, yc, radius, a1, a2);
+
+    while (a2 < a1) // positive arc must have a1<a2
+        a2 += 2.f * M_PIF;
+
+    if (a2 - a1 > 2.f * M_PIF) // limit arc to 2PI
+        a2 = a1 + 2.f * M_PIF;
+
+    vec2 v = {cosf(a1) * radius + xc, sinf(a1) * radius + yc};
+
+    float step = _get_arc_step(ctx, radius);
+    float a    = a1;
+
+    if (_current_path_is_empty(ctx)) {
+        _set_curve_start(ctx);
+        _add_point(ctx, v.x, v.y);
+        if (!ctx->pathPtr)
+            ctx->simpleConvex = true;
+        else
+            ctx->simpleConvex = false;
+    } else {
+        _line_to(ctx, v.x, v.y);
+        _set_curve_start(ctx);
+        ctx->simpleConvex = false;
+    }
+
+    a += step;
+
+    if (EQUF(a2, a1))
+        return;
+
+    while (a < a2) {
+        v.x = cosf(a) * radius + xc;
+        v.y = sinf(a) * radius + yc;
+        _add_point(ctx, v.x, v.y);
+        a += step;
+    }
+
+    if (EQUF(a2 - a1, M_PIF * 2.f)) { // if arc is complete circle, last point is the same as the first one
+        _set_curve_end(ctx);
+        vkvg_close_path(ctx);
+        return;
+    }
+    a = a2;
+    // vec2 lastP = v;
+    v.x = cosf(a) * radius + xc;
+    v.y = sinf(a) * radius + yc;
+    // if (!vec2_equ (v,lastP))//this test should not be required
+    _add_point(ctx, v.x, v.y);
+    _set_curve_end(ctx);
+}
+void vkvg_arc_negative(VkvgContext ctx, float xc, float yc, float radius, float a1, float a2) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_ARC_NEG, xc, yc, radius, a1, a2);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: %f,%f %f %f %f\n", xc, yc, radius, a1, a2);
+    while (a2 > a1)
+        a2 -= 2.f * M_PIF;
+    if (a1 - a2 > a1 + 2.f * M_PIF) // limit arc to 2PI
+        a2 = a1 - 2.f * M_PIF;
+
+    vec2 v = {cosf(a1) * radius + xc, sinf(a1) * radius + yc};
+
+    float step = _get_arc_step(ctx, radius);
+    float a    = a1;
+
+    if (_current_path_is_empty(ctx)) {
+        _set_curve_start(ctx);
+        _add_point(ctx, v.x, v.y);
+        if (!ctx->pathPtr)
+            ctx->simpleConvex = true;
+        else
+            ctx->simpleConvex = false;
+    } else {
+        _line_to(ctx, v.x, v.y);
+        _set_curve_start(ctx);
+        ctx->simpleConvex = false;
+    }
+
+    a -= step;
+
+    if (EQUF(a2, a1))
+        return;
+
+    while (a > a2) {
+        v.x = cosf(a) * radius + xc;
+        v.y = sinf(a) * radius + yc;
+        _add_point(ctx, v.x, v.y);
+        a -= step;
+    }
+
+    if (EQUF(a1 - a2, M_PIF * 2.f)) { // if arc is complete circle, last point is the same as the first one
+        _set_curve_end(ctx);
+        vkvg_close_path(ctx);
+        return;
+    }
+
+    a = a2;
+    // vec2 lastP = v;
+    v.x = cosf(a) * radius + xc;
+    v.y = sinf(a) * radius + yc;
+    // if (!vec2_equ (v,lastP))
+    _add_point(ctx, v.x, v.y);
+    _set_curve_end(ctx);
+}
+void vkvg_rel_move_to(VkvgContext ctx, float x, float y) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_REL_MOVE_TO, x, y);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_mote_to: %f, %f\n", x, y);
+    if (_current_path_is_empty(ctx))
+        _add_point(ctx, 0, 0);
+    vec2 cp = _get_current_position(ctx);
+    _finish_path(ctx);
+    _add_point(ctx, cp.x + x, cp.y + y);
+}
+void vkvg_move_to(VkvgContext ctx, float x, float y) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_MOVE_TO, x, y);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: move_to: %f,%f\n", x, y);
+    _finish_path(ctx);
+    _add_point(ctx, x, y);
+}
+bool vkvg_has_current_point(VkvgContext ctx) {
+    if (ctx->status)
+        return false;
+    return !_current_path_is_empty(ctx);
+}
+void vkvg_get_current_point(VkvgContext ctx, float *x, float *y) {
+    if (ctx->status || _current_path_is_empty(ctx)) {
+        *x = *y = 0;
+        return;
+    }
+    vec2 cp = _get_current_position(ctx);
+    *x      = cp.x;
+    *y      = cp.y;
+}
+void _curve_to(VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
+    // prevent running _recursive_bezier when all 4 curve points are equal
+    if (EQUF(x1, x2) && EQUF(x2, x3) && EQUF(y1, y2) && EQUF(y2, y3)) {
+        if (_current_path_is_empty(ctx) ||
+            (EQUF(_get_current_position(ctx).x, x1) && EQUF(_get_current_position(ctx).y, y1)))
+            return;
+    }
+    ctx->simpleConvex = false;
+    _set_curve_start(ctx);
+    if (_current_path_is_empty(ctx))
+        _add_point(ctx, x1, y1);
+
+    vec2 cp = _get_current_position(ctx);
+
+    // compute dyn distanceTolerance depending on current scale
+    float sx = 1, sy = 1;
+    vkvg_matrix_get_scale(&ctx->pushConsts.mat, &sx, &sy);
+    float distanceTolerance = fabs(0.25f / fmaxf(sx, sy));
+
+    _recursive_bezier(ctx, distanceTolerance, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0);
+    /*cp.x = x3;
+    cp.y = y3;
+    if (!vec2_equ(ctx->points[ctx->pointCount-1],cp))*/
+    _add_point(ctx, x3, y3);
+    _set_curve_end(ctx);
+}
+const double quadraticFact = 2.0 / 3.0;
+void         _quadratic_to(VkvgContext ctx, float x1, float y1, float x2, float y2) {
+    float x0, y0;
+    if (_current_path_is_empty(ctx)) {
+        x0 = x1;
+        y0 = y1;
+    } else
+        vkvg_get_current_point(ctx, &x0, &y0);
+    _curve_to(ctx, x0 + (x1 - x0) * quadraticFact, y0 + (y1 - y0) * quadraticFact, x2 + (x1 - x2) * quadraticFact,
+                      y2 + (y1 - y2) * quadraticFact, x2, y2);
+}
+void vkvg_quadratic_to(VkvgContext ctx, float x1, float y1, float x2, float y2) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_QUADRATIC_TO, x1, y1, x2, y2);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: quadratic_to: %f, %f, %f, %f\n", x1, y1, x2, y2);
+    _quadratic_to(ctx, x1, y1, x2, y2);
+}
+void vkvg_rel_quadratic_to(VkvgContext ctx, float x1, float y1, float x2, float y2) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_REL_QUADRATIC_TO, x1, y1, x2, y2);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_quadratic_to: %f, %f, %f, %f\n", x1, y1, x2, y2);
+    vec2 cp = _get_current_position(ctx);
+    _quadratic_to(ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2);
+}
+void vkvg_curve_to(VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_CURVE_TO, x1, y1, x2, y2, x3, y3);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: curve_to %f,%f %f,%f %f,%f:\n", x1, y1, x2, y2, x3, y3);
+    _curve_to(ctx, x1, y1, x2, y2, x3, y3);
+}
+void vkvg_rel_curve_to(VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
+    if (ctx->status)
+        return;
+    if (_current_path_is_empty(ctx)) {
+        ctx->status = VKVG_STATUS_NO_CURRENT_POINT;
+        return;
+    }
+    RECORD(ctx, (uint32_t)VKVG_CMD_REL_CURVE_TO, x1, y1, x2, y2, x3, y3);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel curve_to %f,%f %f,%f %f,%f:\n", x1, y1, x2, y2, x3, y3);
+    vec2 cp = _get_current_position(ctx);
+    _curve_to(ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2, cp.x + x3, cp.y + y3);
+}
+void vkvg_fill_rectangle(VkvgContext ctx, float x, float y, float w, float h) {
+    if (ctx->status)
+        return;
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: fill_rectangle:\n");
+    _vao_add_rectangle(ctx, x, y, w, h);
+    //_record_draw_cmd(ctx);
+}
+
+vkvg_status_t vkvg_rectangle(VkvgContext ctx, float x, float y, float w, float h) {
+    if (ctx->status)
+        return ctx->status;
+    RECORD2(ctx, VKVG_CMD_RECTANGLE, x, y, w, h);
+    LOG(VKVG_LOG_INFO_CMD, "\tCMD: rectangle: %f,%f,%f,%f\n", x, y, w, h);
+    _finish_path(ctx);
+
+    if (w <= 0 || h <= 0)
+        return VKVG_STATUS_INVALID_RECT;
+
+    _add_point(ctx, x, y);
+    _add_point(ctx, x + w, y);
+    _add_point(ctx, x + w, y + h);
+    _add_point(ctx, x, y + h);
+
+    ctx->pathes[ctx->pathPtr] |= (PATH_CLOSED_BIT | PATH_IS_CONVEX_BIT);
+
+    _finish_path(ctx);
+    return VKVG_STATUS_SUCCESS;
+}
+vkvg_status_t vkvg_rounded_rectangle(VkvgContext ctx, float x, float y, float w, float h, float radius) {
+    if (ctx->status)
+        return ctx->status;
+    LOG(VKVG_LOG_INFO_CMD, "CMD: rounded_rectangle:\n");
+    _finish_path(ctx);
+
+    if (w <= 0 || h <= 0)
+        return VKVG_STATUS_INVALID_RECT;
+
+    if ((radius > w / 2.0f) || (radius > h / 2.0f))
+        radius = fmin(w / 2.0f, h / 2.0f);
+
+    vkvg_move_to(ctx, x, y + radius);
+    vkvg_arc(ctx, x + radius, y + radius, radius, M_PIF, -M_PIF_2);
+    vkvg_line_to(ctx, x + w - radius, y);
+    vkvg_arc(ctx, x + w - radius, y + radius, radius, -M_PIF_2, 0);
+    vkvg_line_to(ctx, x + w, y + h - radius);
+    vkvg_arc(ctx, x + w - radius, y + h - radius, radius, 0, M_PIF_2);
+    vkvg_line_to(ctx, x + radius, y + h);
+    vkvg_arc(ctx, x + radius, y + h - radius, radius, M_PIF_2, M_PIF);
+    vkvg_line_to(ctx, x, y + radius);
+    vkvg_close_path(ctx);
+
+    return VKVG_STATUS_SUCCESS;
+}
+void vkvg_rounded_rectangle2(VkvgContext ctx, float x, float y, float w, float h, float rx, float ry) {
+    if (ctx->status)
+        return;
+    LOG(VKVG_LOG_INFO_CMD, "CMD: rounded_rectangle2:\n");
+    vkvg_move_to(ctx, x + rx, y);
+    vkvg_line_to(ctx, x + w - rx, y);
+    vkvg_elliptic_arc_to(ctx, x + w, y + ry, false, true, rx, ry, 0);
+
+    vkvg_line_to(ctx, x + w, y + h - ry);
+    vkvg_elliptic_arc_to(ctx, x + w - rx, y + h, false, true, rx, ry, 0);
+
+    vkvg_line_to(ctx, x + rx, y + h);
+    vkvg_elliptic_arc_to(ctx, x, y + h - ry, false, true, rx, ry, 0);
+
+    vkvg_line_to(ctx, x, y + ry);
+    vkvg_elliptic_arc_to(ctx, x + rx, y, false, true, rx, ry, 0);
+
+    vkvg_close_path(ctx);
+}
+void vkvg_path_extents(VkvgContext ctx, float *x1, float *y1, float *x2, float *y2) {
+    if (ctx->status)
+        return;
+
+    _finish_path(ctx);
+
+    if (!ctx->pathPtr) { // no path
+        *x1 = *x2 = *y1 = *y2 = 0;
+        return;
+    }
+
+    _vkvg_path_extents(ctx, false, x1, y1, x2, y2);
+}
+
+vkvg_clip_state_t _get_previous_clip_state(VkvgContext ctx) {
+    if (!ctx->pSavedCtxs) // no clip saved => clear
+        return vkvg_clip_state_clear;
+    return ctx->pSavedCtxs->clippingState;
+}
+static const VkClearAttachment clearStencil     = {VK_IMAGE_ASPECT_STENCIL_BIT, 1, {{{0}}}};
+static const VkClearAttachment clearColorAttach = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {{{0}}}};
 
-void _reset_clip (VkvgContext ctx) {
-       _emit_draw_cmd_undrawn_vertices(ctx);
-       if (!ctx->cmdStarted) {
-               //if command buffer is not already started and in a renderpass, we use the renderpass
-               //with the loadop clear for stencil
-               ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil;
-               //force run of one renderpass (even empty) to perform clear load op
-               _start_cmd_for_render_pass(ctx);
-               return;
-       }
-       vkCmdClearAttachments(ctx->cmd, 1, &clearStencil, 1, &ctx->clearRect);
+void _reset_clip(VkvgContext ctx) {
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    if (!ctx->cmdStarted) {
+        // if command buffer is not already started and in a renderpass, we use the renderpass
+        // with the loadop clear for stencil
+        ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil;
+        // force run of one renderpass (even empty) to perform clear load op
+        _start_cmd_for_render_pass(ctx);
+        return;
+    }
+    vkCmdClearAttachments(ctx->cmd, 1, &clearStencil, 1, &ctx->clearRect);
 }
 
-void vkvg_reset_clip (VkvgContext ctx){
-       if (ctx->status)
-               return;
+void vkvg_reset_clip(VkvgContext ctx) {
+    if (ctx->status)
+        return;
 
-       RECORD(ctx, VKVG_CMD_RESET_CLIP);
+    RECORD(ctx, VKVG_CMD_RESET_CLIP);
 
-       if (ctx->curClipState == vkvg_clip_state_clear)
-               return;
-       if (_get_previous_clip_state(ctx) == vkvg_clip_state_clear)
-               ctx->curClipState = vkvg_clip_state_none;
-       else
-               ctx->curClipState = vkvg_clip_state_clear;
+    if (ctx->curClipState == vkvg_clip_state_clear)
+        return;
+    if (_get_previous_clip_state(ctx) == vkvg_clip_state_clear)
+        ctx->curClipState = vkvg_clip_state_none;
+    else
+        ctx->curClipState = vkvg_clip_state_clear;
 
-       _reset_clip (ctx);
+    _reset_clip(ctx);
 }
-void vkvg_clear (VkvgContext ctx){
-       if (ctx->status)
-               return;
+void vkvg_clear(VkvgContext ctx) {
+    if (ctx->status)
+        return;
 
-       RECORD(ctx, VKVG_CMD_CLEAR);
+    RECORD(ctx, VKVG_CMD_CLEAR);
 
-       if (_get_previous_clip_state(ctx) == vkvg_clip_state_clear)
-               ctx->curClipState = vkvg_clip_state_none;
-       else
-               ctx->curClipState = vkvg_clip_state_clear;
+    if (_get_previous_clip_state(ctx) == vkvg_clip_state_clear)
+        ctx->curClipState = vkvg_clip_state_none;
+    else
+        ctx->curClipState = vkvg_clip_state_clear;
 
-       _emit_draw_cmd_undrawn_vertices(ctx);
-       if (!ctx->cmdStarted) {
-               ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll;
-               _start_cmd_for_render_pass(ctx);
-               return;
-       }
-       VkClearAttachment ca[2] = {clearColorAttach, clearStencil};
-       vkCmdClearAttachments(ctx->cmd, 2, ca, 1, &ctx->clearRect);
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    if (!ctx->cmdStarted) {
+        ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll;
+        _start_cmd_for_render_pass(ctx);
+        return;
+    }
+    VkClearAttachment ca[2] = {clearColorAttach, clearStencil};
+    vkCmdClearAttachments(ctx->cmd, 2, ca, 1, &ctx->clearRect);
 }
-void _clip_preserve (VkvgContext ctx){
-       _finish_path(ctx);
+void _clip_preserve(VkvgContext ctx) {
+    _finish_path(ctx);
 
-       if (!ctx->pathPtr)//nothing to clip
-               return;
+    if (!ctx->pathPtr) // nothing to clip
+        return;
 
-       _emit_draw_cmd_undrawn_vertices(ctx);
+    _emit_draw_cmd_undrawn_vertices(ctx);
 
-       LOG(VKVG_LOG_INFO, "CLIP: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
+    LOG(VKVG_LOG_INFO, "CLIP: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
 
-       _ensure_renderpass_is_started(ctx);
+    _ensure_renderpass_is_started(ctx);
 
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_cmd_label_start(ctx->cmd, "clip", DBG_LAB_COLOR_CLIP);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_cmd_label_start(ctx->cmd, "clip", DBG_LAB_COLOR_CLIP);
 #endif
 
-       if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){
-               _poly_fill                              (ctx, NULL);
-               CmdBindPipeline                 (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping);
-       }else{
-               CmdBindPipeline                 (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping);
-               CmdSetStencilReference  (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
-               CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
-               CmdSetStencilWriteMask  (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
-               _fill_non_zero(ctx);
-               _emit_draw_cmd_undrawn_vertices(ctx);
-       }
-       CmdSetStencilReference  (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
-       CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
-       CmdSetStencilWriteMask  (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_ALL_BIT);
-
-       _draw_full_screen_quad (ctx, NULL);
-
-       _bind_draw_pipeline (ctx);
-       CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
-
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_cmd_label_end (ctx->cmd);
+    if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD) {
+        _poly_fill(ctx, NULL);
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping);
+    } else {
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping);
+        CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
+        CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+        CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
+        _fill_non_zero(ctx);
+        _emit_draw_cmd_undrawn_vertices(ctx);
+    }
+    CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+    CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
+    CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_ALL_BIT);
+
+    _draw_full_screen_quad(ctx, NULL);
+
+    _bind_draw_pipeline(ctx);
+    CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_cmd_label_end(ctx->cmd);
 #endif
 
-       ctx->curClipState = vkvg_clip_state_clip;
-}
-void _fill_preserve (VkvgContext ctx){
-       _finish_path(ctx);
-
-       if (!ctx->pathPtr)//nothing to fill
-               return;
-
-       LOG(VKVG_LOG_INFO, "FILL: ctx = %p; path cpt = %d;\n", ctx, ctx->subpathCount);
-
-        if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){
-                _emit_draw_cmd_undrawn_vertices(ctx);
-               vec4 bounds = {FLT_MAX,FLT_MAX,FLT_MIN,FLT_MIN};
-               _poly_fill                              (ctx, &bounds);
-               _bind_draw_pipeline             (ctx);
-               CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
-               _draw_full_screen_quad  (ctx, &bounds);
-               CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
-               return;
-       }
-
-       if (ctx->vertCount - ctx->curVertOffset + ctx->pointCount > VKVG_IBO_MAX)
-               _emit_draw_cmd_undrawn_vertices(ctx);//limit draw call to addressable vx with choosen index type
-
-       if (ctx->pattern)//if not solid color, source img or gradient has to be bound
-               _ensure_renderpass_is_started(ctx);
-       _fill_non_zero(ctx);
-}
-void _stroke_preserve (VkvgContext ctx)
-{
-       _finish_path(ctx);
-
-       if (!ctx->pathPtr)//nothing to stroke
-               return;
-
-       LOG(VKVG_LOG_INFO, "STROKE: ctx = %p; path ptr = %d;\n", ctx, ctx->pathPtr);
-
-       stroke_context_t str = {0};
-       str.hw = ctx->lineWidth * 0.5f;
-       str.lhMax = ctx->miterLimit * ctx->lineWidth;
-       uint32_t ptrPath = 0;
-
-       while (ptrPath < ctx->pathPtr){
-               uint32_t ptrSegment = 0, lastSegmentPointIdx = 0;
-               uint32_t firstPathPointIdx = str.cp;
-               uint32_t pathPointCount = ctx->pathes[ptrPath]&PATH_ELT_MASK;
-               uint32_t lastPathPointIdx = str.cp + pathPointCount - 1;
-
-               dash_context_t dc = {0};
-
-               if (_path_has_curves (ctx,ptrPath)) {
-                       ptrSegment = 1;
-                       lastSegmentPointIdx = str.cp + (ctx->pathes[ptrPath+ptrSegment]&PATH_ELT_MASK)-1;
-               }
-
-               str.firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-
-               //LOG(VKVG_LOG_INFO_PATH, "\tPATH: points count=%10d end point idx=%10d", ctx->pathes[ptrPath]&PATH_ELT_MASK, lastPathPointIdx);
-
-               if (ctx->dashCount > 0) {
-                       //init dash stroke
-                       dc.dashOn = true;
-                       dc.curDash = 0; //current dash index
-                       dc.totDashLength = 0;//limit offset to total length of dashes
-                       for (uint32_t i=0;i<ctx->dashCount;i++)
-                               dc.totDashLength += ctx->dashes[i];
-                       if (dc.totDashLength == 0){
-                               ctx->status = VKVG_STATUS_INVALID_DASH;
-                               return;
-                       }
-                       dc.curDashOffset = fmodf(ctx->dashOffset, dc.totDashLength);    //cur dash offset between defined path point and last dash segment(on/off) start
-                       str.iL = lastPathPointIdx;
-               } else if (_path_is_closed(ctx,ptrPath)){
-                       str.iL = lastPathPointIdx;
-               }else{
-                       _draw_stoke_cap(ctx, &str, ctx->points[str.cp], vec2_line_norm(ctx->points[str.cp], ctx->points[str.cp+1]), true);
-                       str.iL = str.cp++;
-               }
-
-               if (_path_has_curves (ctx,ptrPath)) {
-                       while (str.cp < lastPathPointIdx){
-
-                               bool curved = ctx->pathes [ptrPath + ptrSegment] & PATH_HAS_CURVES_BIT;
-                               if (lastSegmentPointIdx == lastPathPointIdx)//last segment of path, dont draw end point here
-                                       lastSegmentPointIdx--;
-                               while (str.cp <= lastSegmentPointIdx)
-                                       _draw_segment(ctx, &str, &dc, curved);
-
-                               ptrSegment ++;
-                               uint32_t cptSegPts = ctx->pathes [ptrPath + ptrSegment]&PATH_ELT_MASK;
-                               lastSegmentPointIdx = str.cp + cptSegPts - 1;
-                               if (lastSegmentPointIdx == lastPathPointIdx && cptSegPts == 1) {
-                                       //single point last segment
-                                       ptrSegment++;
-                                       break;
-                               }
-                       }
-               }else while (str.cp < lastPathPointIdx)
-                       _draw_segment(ctx, &str, &dc, false);
-
-               if (ctx->dashCount > 0) {
-                       if (_path_is_closed(ctx,ptrPath)){
-                               str.iR = firstPathPointIdx;
-
-                               _draw_dashed_segment(ctx, &str, &dc, false);
-
-                               str.iL++;
-                               str.cp++;
-                       }
-                       if (!dc.dashOn){
-                               //finishing last dash that is already started, draw end caps but not too close to start
-                               //the default gap is the next void
-                               int32_t prevDash = (int32_t)dc.curDash-1;
-                               if (prevDash < 0)
-                                       dc.curDash = ctx->dashCount-1;
-                               float m = fminf (ctx->dashes[prevDash] - dc.curDashOffset, ctx->dashes[dc.curDash]);
-                               vec2 p = vec2_sub(ctx->points[str.iR], vec2_mult_s(dc.normal, m));
-                               _draw_stoke_cap (ctx, &str, p, dc.normal, false);
-                       }
-               } else if (_path_is_closed(ctx,ptrPath)){
-                       str.iR = firstPathPointIdx;
-                       bool inverse = _build_vb_step (ctx, &str, false);
-
-                       VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache [ctx->indCount-6];
-                       VKVG_IBO_INDEX_TYPE ii = str.firstIdx;
-                       if (inverse){
-                               inds[1] = ii+1;
-                               inds[4] = ii+1;
-                               inds[5] = ii;
-                       }else{
-                               inds[1] = ii;
-                               inds[4] = ii;
-                               inds[5] = ii+1;
-                       }
-                       str.cp++;
-               }else
-                       _draw_stoke_cap (ctx, &str, ctx->points[str.cp], vec2_line_norm(ctx->points[str.cp-1], ctx->points[str.cp]), false);
-
-               str.cp = firstPathPointIdx + pathPointCount;
-
-               if (ptrSegment > 0)
-                       ptrPath += ptrSegment;
-               else
-                       ptrPath++;
-
-               //limit batch size here to 1/3 of the ibo index type ability
-               if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3)
-                       _emit_draw_cmd_undrawn_vertices (ctx);
-       }
-
-}
-
-void vkvg_clip (VkvgContext ctx){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_CLIP);
-       _clip_preserve(ctx);
-       _clear_path(ctx);
-}
-void vkvg_stroke (VkvgContext ctx)
-{
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_STROKE);
-       _stroke_preserve(ctx);
-       _clear_path(ctx);
-}
-void vkvg_fill (VkvgContext ctx){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_FILL);
-       _fill_preserve(ctx);
-       _clear_path(ctx);
-}
-void vkvg_clip_preserve (VkvgContext ctx) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_CLIP_PRESERVE);
-       _clip_preserve (ctx);
-}
-void vkvg_fill_preserve (VkvgContext ctx) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_FILL_PRESERVE);
-       _fill_preserve (ctx);
-}
-void vkvg_stroke_preserve (VkvgContext ctx) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_STROKE_PRESERVE);
-       _stroke_preserve (ctx);
-}
-
-void vkvg_paint (VkvgContext ctx){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_PAINT);
-       _finish_path (ctx);
-
-       if (ctx->pathPtr) {
-               vkvg_fill(ctx);
-               return;
-       }
-
-       _ensure_renderpass_is_started (ctx);
-       _draw_full_screen_quad (ctx, NULL);
-}
-void vkvg_set_source_color (VkvgContext ctx, uint32_t c) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_SOURCE_COLOR, c);
-       ctx->curColor = c;
-       _update_cur_pattern (ctx, NULL);
-}
-void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_SOURCE_RGB, r, g, b);
-       ctx->curColor = CreateRgbaf(r,g,b,1);
-       _update_cur_pattern (ctx, NULL);
-}
-void vkvg_set_source_rgba (VkvgContext ctx, float r, float g, float b, float a)
-{
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_SOURCE_RGBA, r, g, b, a);
-       ctx->curColor = CreateRgbaf(r,g,b,a);
-       _update_cur_pattern (ctx, NULL);
-}
-void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y){
-       if (ctx->status || surf->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_SOURCE_SURFACE, x, y, surf);
-       ctx->pushConsts.source.x = x;
-       ctx->pushConsts.source.y = y;
-       _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf));
-       ctx->pushCstDirty = true;
-}
-void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){
-       if (ctx->status || pat->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_SOURCE, pat);
-       _update_cur_pattern (ctx, pat);
-       vkvg_pattern_reference  (pat);
-}
-void vkvg_set_line_width (VkvgContext ctx, float width){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_LINE_WIDTH, width);
-       ctx->lineWidth = width;
-}
-void vkvg_set_miter_limit (VkvgContext ctx, float limit){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_LINE_WIDTH, limit);
-       ctx->miterLimit = limit;
-}
-void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_LINE_CAP, cap);
-       ctx->lineCap = cap;
-}
-void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_LINE_JOIN, join);
-       ctx->lineJoin = join;
-}
-void vkvg_set_operator (VkvgContext ctx, vkvg_operator_t op){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_OPERATOR, op);
-       if (op == ctx->curOperator)
-               return;
-
-       _emit_draw_cmd_undrawn_vertices(ctx);//draw call with different ops cant be combined, so emit draw cmd for previous vertices.
-
-       ctx->curOperator = op;
-
-       if (ctx->cmdStarted)
-               _bind_draw_pipeline (ctx);
-}
-void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr){
-       if (ctx->status)
-               return;
+    ctx->curClipState = vkvg_clip_state_clip;
+}
+void _fill_preserve(VkvgContext ctx) {
+    _finish_path(ctx);
+
+    if (!ctx->pathPtr) // nothing to fill
+        return;
+
+    LOG(VKVG_LOG_INFO, "FILL: ctx = %p; path cpt = %d;\n", ctx, ctx->subpathCount);
+
+    if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD) {
+        _emit_draw_cmd_undrawn_vertices(ctx);
+        vec4 bounds = {FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN};
+        _poly_fill(ctx, &bounds);
+        _bind_draw_pipeline(ctx);
+        CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT);
+        _draw_full_screen_quad(ctx, &bounds);
+        CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+        return;
+    }
+
+    if (ctx->vertCount - ctx->curVertOffset + ctx->pointCount > VKVG_IBO_MAX)
+        _emit_draw_cmd_undrawn_vertices(ctx); // limit draw call to addressable vx with choosen index type
+
+    if (ctx->pattern) // if not solid color, source img or gradient has to be bound
+        _ensure_renderpass_is_started(ctx);
+    _fill_non_zero(ctx);
+}
+void _stroke_preserve(VkvgContext ctx) {
+    _finish_path(ctx);
+
+    if (!ctx->pathPtr) // nothing to stroke
+        return;
+
+    LOG(VKVG_LOG_INFO, "STROKE: ctx = %p; path ptr = %d;\n", ctx, ctx->pathPtr);
+
+    stroke_context_t str = {0};
+    str.hw               = ctx->lineWidth * 0.5f;
+    str.lhMax            = ctx->miterLimit * ctx->lineWidth;
+    uint32_t ptrPath     = 0;
+
+    while (ptrPath < ctx->pathPtr) {
+        uint32_t ptrSegment = 0, lastSegmentPointIdx = 0;
+        uint32_t firstPathPointIdx = str.cp;
+        uint32_t pathPointCount    = ctx->pathes[ptrPath] & PATH_ELT_MASK;
+        uint32_t lastPathPointIdx  = str.cp + pathPointCount - 1;
+
+        dash_context_t dc = {0};
+
+        if (_path_has_curves(ctx, ptrPath)) {
+            ptrSegment          = 1;
+            lastSegmentPointIdx = str.cp + (ctx->pathes[ptrPath + ptrSegment] & PATH_ELT_MASK) - 1;
+        }
+
+        str.firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+
+        // LOG(VKVG_LOG_INFO_PATH, "\tPATH: points count=%10d end point idx=%10d", ctx->pathes[ptrPath]&PATH_ELT_MASK,
+        // lastPathPointIdx);
+
+        if (ctx->dashCount > 0) {
+            // init dash stroke
+            dc.dashOn        = true;
+            dc.curDash       = 0; // current dash index
+            dc.totDashLength = 0; // limit offset to total length of dashes
+            for (uint32_t i = 0; i < ctx->dashCount; i++)
+                dc.totDashLength += ctx->dashes[i];
+            if (dc.totDashLength == 0) {
+                ctx->status = VKVG_STATUS_INVALID_DASH;
+                return;
+            }
+            dc.curDashOffset = fmodf(
+                ctx->dashOffset,
+                dc.totDashLength); // cur dash offset between defined path point and last dash segment(on/off) start
+            str.iL = lastPathPointIdx;
+        } else if (_path_is_closed(ctx, ptrPath)) {
+            str.iL = lastPathPointIdx;
+        } else {
+            _draw_stoke_cap(ctx, &str, ctx->points[str.cp],
+                            vec2_line_norm(ctx->points[str.cp], ctx->points[str.cp + 1]), true);
+            str.iL = str.cp++;
+        }
+
+        if (_path_has_curves(ctx, ptrPath)) {
+            while (str.cp < lastPathPointIdx) {
+
+                bool curved = ctx->pathes[ptrPath + ptrSegment] & PATH_HAS_CURVES_BIT;
+                if (lastSegmentPointIdx == lastPathPointIdx) // last segment of path, dont draw end point here
+                    lastSegmentPointIdx--;
+                while (str.cp <= lastSegmentPointIdx)
+                    _draw_segment(ctx, &str, &dc, curved);
+
+                ptrSegment++;
+                uint32_t cptSegPts  = ctx->pathes[ptrPath + ptrSegment] & PATH_ELT_MASK;
+                lastSegmentPointIdx = str.cp + cptSegPts - 1;
+                if (lastSegmentPointIdx == lastPathPointIdx && cptSegPts == 1) {
+                    // single point last segment
+                    ptrSegment++;
+                    break;
+                }
+            }
+        } else
+            while (str.cp < lastPathPointIdx)
+                _draw_segment(ctx, &str, &dc, false);
+
+        if (ctx->dashCount > 0) {
+            if (_path_is_closed(ctx, ptrPath)) {
+                str.iR = firstPathPointIdx;
+
+                _draw_dashed_segment(ctx, &str, &dc, false);
+
+                str.iL++;
+                str.cp++;
+            }
+            if (!dc.dashOn) {
+                // finishing last dash that is already started, draw end caps but not too close to start
+                // the default gap is the next void
+                int32_t prevDash = (int32_t)dc.curDash - 1;
+                if (prevDash < 0)
+                    dc.curDash = ctx->dashCount - 1;
+                float m = fminf(ctx->dashes[prevDash] - dc.curDashOffset, ctx->dashes[dc.curDash]);
+                vec2  p = vec2_sub(ctx->points[str.iR], vec2_mult_s(dc.normal, m));
+                _draw_stoke_cap(ctx, &str, p, dc.normal, false);
+            }
+        } else if (_path_is_closed(ctx, ptrPath)) {
+            str.iR       = firstPathPointIdx;
+            bool inverse = _build_vb_step(ctx, &str, false);
+
+            VKVG_IBO_INDEX_TYPE *inds = &ctx->indexCache[ctx->indCount - 6];
+            VKVG_IBO_INDEX_TYPE  ii   = str.firstIdx;
+            if (inverse) {
+                inds[1] = ii + 1;
+                inds[4] = ii + 1;
+                inds[5] = ii;
+            } else {
+                inds[1] = ii;
+                inds[4] = ii;
+                inds[5] = ii + 1;
+            }
+            str.cp++;
+        } else
+            _draw_stoke_cap(ctx, &str, ctx->points[str.cp],
+                            vec2_line_norm(ctx->points[str.cp - 1], ctx->points[str.cp]), false);
+
+        str.cp = firstPathPointIdx + pathPointCount;
+
+        if (ptrSegment > 0)
+            ptrPath += ptrSegment;
+        else
+            ptrPath++;
+
+        // limit batch size here to 1/3 of the ibo index type ability
+        if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3)
+            _emit_draw_cmd_undrawn_vertices(ctx);
+    }
+}
+
+void vkvg_clip(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_CLIP);
+    _clip_preserve(ctx);
+    _clear_path(ctx);
+}
+void vkvg_stroke(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_STROKE);
+    _stroke_preserve(ctx);
+    _clear_path(ctx);
+}
+void vkvg_fill(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_FILL);
+    _fill_preserve(ctx);
+    _clear_path(ctx);
+}
+void vkvg_clip_preserve(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_CLIP_PRESERVE);
+    _clip_preserve(ctx);
+}
+void vkvg_fill_preserve(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_FILL_PRESERVE);
+    _fill_preserve(ctx);
+}
+void vkvg_stroke_preserve(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_STROKE_PRESERVE);
+    _stroke_preserve(ctx);
+}
+
+void vkvg_paint(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_PAINT);
+    _finish_path(ctx);
+
+    if (ctx->pathPtr) {
+        vkvg_fill(ctx);
+        return;
+    }
+
+    _ensure_renderpass_is_started(ctx);
+    _draw_full_screen_quad(ctx, NULL);
+}
+void vkvg_set_source_color(VkvgContext ctx, uint32_t c) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_SOURCE_COLOR, c);
+    ctx->curColor = c;
+    _update_cur_pattern(ctx, NULL);
+}
+void vkvg_set_source_rgb(VkvgContext ctx, float r, float g, float b) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_SOURCE_RGB, r, g, b);
+    ctx->curColor = CreateRgbaf(r, g, b, 1);
+    _update_cur_pattern(ctx, NULL);
+}
+void vkvg_set_source_rgba(VkvgContext ctx, float r, float g, float b, float a) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_SOURCE_RGBA, r, g, b, a);
+    ctx->curColor = CreateRgbaf(r, g, b, a);
+    _update_cur_pattern(ctx, NULL);
+}
+void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y) {
+    if (ctx->status || surf->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_SOURCE_SURFACE, x, y, surf);
+    ctx->pushConsts.source.x = x;
+    ctx->pushConsts.source.y = y;
+    _update_cur_pattern(ctx, vkvg_pattern_create_for_surface(surf));
+    ctx->pushCstDirty = true;
+}
+void vkvg_set_source(VkvgContext ctx, VkvgPattern pat) {
+    if (ctx->status || pat->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_SOURCE, pat);
+    _update_cur_pattern(ctx, pat);
+    vkvg_pattern_reference(pat);
+}
+void vkvg_set_line_width(VkvgContext ctx, float width) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_LINE_WIDTH, width);
+    ctx->lineWidth = width;
+}
+void vkvg_set_miter_limit(VkvgContext ctx, float limit) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_LINE_WIDTH, limit);
+    ctx->miterLimit = limit;
+}
+void vkvg_set_line_cap(VkvgContext ctx, vkvg_line_cap_t cap) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_LINE_CAP, cap);
+    ctx->lineCap = cap;
+}
+void vkvg_set_line_join(VkvgContext ctx, vkvg_line_join_t join) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_LINE_JOIN, join);
+    ctx->lineJoin = join;
+}
+void vkvg_set_operator(VkvgContext ctx, vkvg_operator_t op) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_OPERATOR, op);
+    if (op == ctx->curOperator)
+        return;
+
+    _emit_draw_cmd_undrawn_vertices(
+        ctx); // draw call with different ops cant be combined, so emit draw cmd for previous vertices.
+
+    ctx->curOperator = op;
+
+    if (ctx->cmdStarted)
+        _bind_draw_pipeline(ctx);
+}
+void vkvg_set_fill_rule(VkvgContext ctx, vkvg_fill_rule_t fr) {
+    if (ctx->status)
+        return;
 #ifndef __APPLE__
-       RECORD(ctx, VKVG_CMD_SET_FILL_RULE, fr);
-       ctx->curFillRule = fr;
+    RECORD(ctx, VKVG_CMD_SET_FILL_RULE, fr);
+    ctx->curFillRule = fr;
 #endif
 }
-vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx){
-       if (ctx->status)
-               return VKVG_FILL_RULE_NON_ZERO;
-       return ctx->curFillRule;
-}
-float vkvg_get_line_width (VkvgContext ctx){
-       if (ctx->status)
-               return 0;
-       return ctx->lineWidth;
-}
-void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset){
-       if (ctx->status)
-               return;
-       if (ctx->dashCount > 0)
-               free (ctx->dashes);
-       RECORD(ctx, VKVG_CMD_SET_DASH, num_dashes, offset, dashes);
-       ctx->dashCount = num_dashes;
-       ctx->dashOffset = offset;
-       if (ctx->dashCount == 0)
-               return;
-       ctx->dashes = (float*)malloc (sizeof(float) * ctx->dashCount);
-       memcpy (ctx->dashes, dashes, sizeof(float) * ctx->dashCount);
-}
-void vkvg_get_dash (VkvgContext ctx, const float* dashes, uint32_t* num_dashes, float* offset){
-       if (ctx->status)
-               return;
-       *num_dashes = ctx->dashCount;
-       *offset = ctx->dashOffset;
-       if (ctx->dashCount == 0 || dashes == NULL)
-               return;
-       memcpy ((float*)dashes, ctx->dashes, sizeof(float) * ctx->dashCount);
-}
-
-
-vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx){
-       if (ctx->status)
-               return (vkvg_line_cap_t)0;
-       return ctx->lineCap;
-}
-vkvg_line_join_t vkvg_get_line_join (VkvgContext ctx){
-       if (ctx->status)
-               return (vkvg_line_join_t)0;
-       return ctx->lineJoin;
-}
-vkvg_operator_t vkvg_get_operator (VkvgContext ctx){
-       if (ctx->status)
-               return (vkvg_operator_t)0;
-       return ctx->curOperator;
-}
-VkvgPattern vkvg_get_source (VkvgContext ctx){
-       if (ctx->status)
-               return NULL;
-       vkvg_pattern_reference (ctx->pattern);
-       return ctx->pattern;
-}
-
-void vkvg_select_font_face (VkvgContext ctx, const char* name){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_FONT_FACE, name);
-       _select_font_face (ctx, name);
-}
-void vkvg_load_font_from_path (VkvgContext ctx, const char* path, const char* name){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_FONT_PATH, name);
-       _vkvg_font_identity_t* fid = _font_cache_add_font_identity(ctx, path, name);
-       if (!_font_cache_load_font_file_in_memory (fid)) {
-               ctx->status = VKVG_STATUS_FILE_NOT_FOUND;
-               return;
-       }
-       _select_font_face (ctx, name);
-}
-void vkvg_load_font_from_memory (VkvgContext ctx, unsigned char* fontBuffer, long fontBufferByteSize, const char* name) {
-       if (ctx->status)
-               return;
-       //RECORD(ctx, VKVG_CMD_SET_FONT_PATH, name);
-       _vkvg_font_identity_t* fid = _font_cache_add_font_identity (ctx, NULL, name);
-       fid->fontBuffer = fontBuffer;
-       fid->fontBufSize = fontBufferByteSize;
-
-       _select_font_face (ctx, name);
-}
-void vkvg_set_font_size (VkvgContext ctx, uint32_t size){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_FONT_SIZE, size);
+vkvg_fill_rule_t vkvg_get_fill_rule(VkvgContext ctx) {
+    if (ctx->status)
+        return VKVG_FILL_RULE_NON_ZERO;
+    return ctx->curFillRule;
+}
+float vkvg_get_line_width(VkvgContext ctx) {
+    if (ctx->status)
+        return 0;
+    return ctx->lineWidth;
+}
+void vkvg_set_dash(VkvgContext ctx, const float *dashes, uint32_t num_dashes, float offset) {
+    if (ctx->status)
+        return;
+    if (ctx->dashCount > 0)
+        free(ctx->dashes);
+    RECORD(ctx, VKVG_CMD_SET_DASH, num_dashes, offset, dashes);
+    ctx->dashCount  = num_dashes;
+    ctx->dashOffset = offset;
+    if (ctx->dashCount == 0)
+        return;
+    ctx->dashes = (float *)malloc(sizeof(float) * ctx->dashCount);
+    memcpy(ctx->dashes, dashes, sizeof(float) * ctx->dashCount);
+}
+void vkvg_get_dash(VkvgContext ctx, const float *dashes, uint32_t *num_dashes, float *offset) {
+    if (ctx->status)
+        return;
+    *num_dashes = ctx->dashCount;
+    *offset     = ctx->dashOffset;
+    if (ctx->dashCount == 0 || dashes == NULL)
+        return;
+    memcpy((float *)dashes, ctx->dashes, sizeof(float) * ctx->dashCount);
+}
+
+vkvg_line_cap_t vkvg_get_line_cap(VkvgContext ctx) {
+    if (ctx->status)
+        return (vkvg_line_cap_t)0;
+    return ctx->lineCap;
+}
+vkvg_line_join_t vkvg_get_line_join(VkvgContext ctx) {
+    if (ctx->status)
+        return (vkvg_line_join_t)0;
+    return ctx->lineJoin;
+}
+vkvg_operator_t vkvg_get_operator(VkvgContext ctx) {
+    if (ctx->status)
+        return (vkvg_operator_t)0;
+    return ctx->curOperator;
+}
+VkvgPattern vkvg_get_source(VkvgContext ctx) {
+    if (ctx->status)
+        return NULL;
+    vkvg_pattern_reference(ctx->pattern);
+    return ctx->pattern;
+}
+
+void vkvg_select_font_face(VkvgContext ctx, const char *name) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_FONT_FACE, name);
+    _select_font_face(ctx, name);
+}
+void vkvg_load_font_from_path(VkvgContext ctx, const char *path, const char *name) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_FONT_PATH, name);
+    _vkvg_font_identity_t *fid = _font_cache_add_font_identity(ctx, path, name);
+    if (!_font_cache_load_font_file_in_memory(fid)) {
+        ctx->status = VKVG_STATUS_FILE_NOT_FOUND;
+        return;
+    }
+    _select_font_face(ctx, name);
+}
+void vkvg_load_font_from_memory(VkvgContext ctx, unsigned char *fontBuffer, long fontBufferByteSize, const char *name) {
+    if (ctx->status)
+        return;
+    // RECORD(ctx, VKVG_CMD_SET_FONT_PATH, name);
+    _vkvg_font_identity_t *fid = _font_cache_add_font_identity(ctx, NULL, name);
+    fid->fontBuffer            = fontBuffer;
+    fid->fontBufSize           = fontBufferByteSize;
+
+    _select_font_face(ctx, name);
+}
+void vkvg_set_font_size(VkvgContext ctx, uint32_t size) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_FONT_SIZE, size);
 #ifdef VKVG_USE_FREETYPE
-       long newSize = size << 6;
+    long newSize = size << 6;
 #else
-       long newSize = size;
+    long newSize = size;
 #endif
-       if (ctx->selectedCharSize == newSize)
-               return;
-       ctx->selectedCharSize = newSize;
-       ctx->currentFont = NULL;
-       ctx->currentFontSize = NULL;
-}
-
-void vkvg_set_text_direction (vkvg_context* ctx, vkvg_direction_t direction){
-
-}
-
-void vkvg_show_text (VkvgContext ctx, const char* text){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SHOW_TEXT, text);
-       LOG(VKVG_LOG_INFO_CMD, "CMD: show_text:\n");
-       //_ensure_renderpass_is_started(ctx);
-       _font_cache_show_text (ctx, text);
-       //_flush_undrawn_vertices (ctx);
-}
-
-VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text) {
-       if (ctx->status)
-               return NULL;
-       VkvgText tr = (vkvg_text_run_t*)calloc(1, sizeof(vkvg_text_run_t));
-       _font_cache_create_text_run(ctx, text, -1, tr);
-       return tr;
-}
-VkvgText vkvg_text_run_create_with_length (VkvgContext ctx, const char* text, uint32_t length) {
-       if (ctx->status)
-               return NULL;
-       VkvgText tr = (vkvg_text_run_t*)calloc(1, sizeof(vkvg_text_run_t));
-       _font_cache_create_text_run(ctx, text, length, tr);
-       return tr;
-}
-uint32_t vkvg_text_run_get_glyph_count (VkvgText textRun) {
-       return textRun->glyph_count;
-}
-void vkvg_text_run_get_glyph_position (VkvgText textRun,
-                                                                          uint32_t index,
-                                                                          vkvg_glyph_info_t* pGlyphInfo) {
-       if (index >= textRun->glyph_count) {
-               *pGlyphInfo = (vkvg_glyph_info_t){0};
-               return;
-       }
+    if (ctx->selectedCharSize == newSize)
+        return;
+    ctx->selectedCharSize = newSize;
+    ctx->currentFont      = NULL;
+    ctx->currentFontSize  = NULL;
+}
+
+void vkvg_set_text_direction(vkvg_context *ctx, vkvg_direction_t direction) {}
+
+void vkvg_show_text(VkvgContext ctx, const char *text) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SHOW_TEXT, text);
+    LOG(VKVG_LOG_INFO_CMD, "CMD: show_text:\n");
+    //_ensure_renderpass_is_started(ctx);
+    _font_cache_show_text(ctx, text);
+    //_flush_undrawn_vertices (ctx);
+}
+
+VkvgText vkvg_text_run_create(VkvgContext ctx, const char *text) {
+    if (ctx->status)
+        return NULL;
+    VkvgText tr = (vkvg_text_run_t *)calloc(1, sizeof(vkvg_text_run_t));
+    _font_cache_create_text_run(ctx, text, -1, tr);
+    return tr;
+}
+VkvgText vkvg_text_run_create_with_length(VkvgContext ctx, const char *text, uint32_t length) {
+    if (ctx->status)
+        return NULL;
+    VkvgText tr = (vkvg_text_run_t *)calloc(1, sizeof(vkvg_text_run_t));
+    _font_cache_create_text_run(ctx, text, length, tr);
+    return tr;
+}
+uint32_t vkvg_text_run_get_glyph_count(VkvgText textRun) { return textRun->glyph_count; }
+void     vkvg_text_run_get_glyph_position(VkvgText textRun, uint32_t index, vkvg_glyph_info_t *pGlyphInfo) {
+    if (index >= textRun->glyph_count) {
+        *pGlyphInfo = (vkvg_glyph_info_t){0};
+        return;
+    }
 #if VKVG_USE_HARFBUZZ
-       memcpy (pGlyphInfo, &textRun->glyphs[index], sizeof(vkvg_glyph_info_t));
+    memcpy(pGlyphInfo, &textRun->glyphs[index], sizeof(vkvg_glyph_info_t));
 #else
-       *pGlyphInfo = textRun->glyphs[index];
+    *pGlyphInfo  = textRun->glyphs[index];
 #endif
 }
-void vkvg_text_run_destroy (VkvgText textRun) {
-       _font_cache_destroy_text_run (textRun);
-       free (textRun);
-}
-void vkvg_show_text_run (VkvgContext ctx, VkvgText textRun) {
-       if (ctx->status)
-               return;
-       _font_cache_show_text_run(ctx, textRun);
-}
-void vkvg_text_run_get_extents (VkvgText textRun, vkvg_text_extents_t* extents) {
-       *extents = textRun->extents;
-}
-
-void vkvg_text_extents (VkvgContext ctx, const char* text, vkvg_text_extents_t* extents) {
-       if (ctx->status)
-               return;
-       _font_cache_text_extents(ctx, text, -1, extents);
-}
-void vkvg_font_extents (VkvgContext ctx, vkvg_font_extents_t* extents) {
-       if (ctx->status)
-               return;
-       _font_cache_font_extents(ctx, extents);
-}
-
-void vkvg_save (VkvgContext ctx){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SAVE);
-       LOG(VKVG_LOG_INFO, "SAVE CONTEXT: ctx = %p\n", ctx);
-
-       VkvgDevice dev = ctx->dev;
-       vkvg_context_save_t* sav = (vkvg_context_save_t*)calloc(1,sizeof(vkvg_context_save_t));
-
-       _flush_cmd_buff (ctx);
-       if (!_wait_ctx_flush_end (ctx)) {
-               free (sav);
-               return;
-       }
-
-       if (ctx->curClipState == vkvg_clip_state_clip) {
-               sav->clippingState = vkvg_clip_state_clip_saved;
-
-               uint8_t curSaveStencil = ctx->curSavBit / 6;
-
-               if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//new save/restore stencil image have to be created
-                       VkhImage* savedStencilsPtr = NULL;
-                       if (savedStencilsPtr)
-                               savedStencilsPtr = (VkhImage*)realloc(ctx->savedStencils, curSaveStencil * sizeof(VkhImage));
-                       else
-                               savedStencilsPtr = (VkhImage*)malloc(curSaveStencil * sizeof(VkhImage));
-                       if (savedStencilsPtr == NULL) {
-                               free(sav);
-                               ctx->status = VKVG_STATUS_NO_MEMORY;
-                               return;
-                       }
-                       ctx->savedStencils = savedStencilsPtr;
-                       VkhImage savStencil = vkh_image_ms_create ((VkhDevice)dev, dev->stencilFormat, dev->samples, ctx->pSurf->width, ctx->pSurf->height,
-                                                                       VKH_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
-                       ctx->savedStencils[curSaveStencil-1] = savStencil;
-
-                       vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-                       ctx->cmdStarted = true;
-
-       #if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-                       vkh_cmd_label_start(ctx->cmd, "new save/restore stencil", DBG_LAB_COLOR_SAV);
-       #endif
-
-                       vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, dev->stencilAspectFlag,
-                                                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                                 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-                       vkh_image_set_layout (ctx->cmd, savStencil, dev->stencilAspectFlag,
-                                                                 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                                 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-
-                       VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
-                                                                       .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
-                                                                       .extent = {ctx->pSurf->width,ctx->pSurf->height,1}};
-                       vkCmdCopyImage(ctx->cmd,
-                                                  vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                  vkh_image_get_vkimage (savStencil),           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                  1, &cregion);
-
-                       vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, dev->stencilAspectFlag,
-                                                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                                                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
-
-       #if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-                       vkh_cmd_label_end (ctx->cmd);
-       #endif
-
-                       VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd));
-                       _wait_and_submit_cmd(ctx);
-               }
-
-               uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2);
-
-               _start_cmd_for_render_pass (ctx);
-
-       #if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-               vkh_cmd_label_start(ctx->cmd, "save rp", DBG_LAB_COLOR_SAV);
-       #endif
-
-               CmdBindPipeline                 (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping);
-
-               CmdSetStencilReference  (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit);
-               CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
-               CmdSetStencilWriteMask  (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit);
-
-               _draw_full_screen_quad (ctx, NULL);
-
-               _bind_draw_pipeline (ctx);
-               CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
-
-       #if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-               vkh_cmd_label_end (ctx->cmd);
-       #endif
-               ctx->curSavBit++;
-       } else if (ctx->curClipState == vkvg_clip_state_none)
-               sav->clippingState = (_get_previous_clip_state(ctx) & 0x03);
-       else
-               sav->clippingState = vkvg_clip_state_clear;
-
-       sav->dashOffset = ctx->dashOffset;
-       sav->dashCount  = ctx->dashCount;
-       if (ctx->dashCount > 0) {
-               sav->dashes = (float*)malloc (sizeof(float) * ctx->dashCount);
-               memcpy (sav->dashes, ctx->dashes, sizeof(float) * ctx->dashCount);
-       }
-       sav->lineWidth  = ctx->lineWidth;
-       sav->miterLimit = ctx->miterLimit;
-       sav->curOperator= ctx->curOperator;
-       sav->lineCap    = ctx->lineCap;
-       sav->lineWidth  = ctx->lineWidth;
-       sav->curFillRule= ctx->curFillRule;
-
-       sav->selectedCharSize = ctx->selectedCharSize;
-       strcpy (sav->selectedFontName, ctx->selectedFontName);
-
-       sav->currentFont  = ctx->currentFont;
-       sav->textDirection= ctx->textDirection;
-       sav->pushConsts   = ctx->pushConsts;
-       if (ctx->pattern) {
-               sav->pattern = ctx->pattern;//TODO:pattern sav must be imutable (copy?)
-               vkvg_pattern_reference (ctx->pattern);
-       } else
-               sav->curColor = ctx->curColor;
-
-       sav->pNext              = ctx->pSavedCtxs;
-       ctx->pSavedCtxs = sav;
-
-}
-void vkvg_restore (VkvgContext ctx){
-       if (ctx->status)
-               return;
-
-       RECORD(ctx, VKVG_CMD_RESTORE);
-
-       if (ctx->pSavedCtxs == NULL){
-               ctx->status = VKVG_STATUS_INVALID_RESTORE;
-               return;
-       }
-
-       LOG(VKVG_LOG_INFO, "RESTORE CONTEXT: ctx = %p\n", ctx);
-
-       vkvg_context_save_t* sav = ctx->pSavedCtxs;
-       ctx->pSavedCtxs = sav->pNext;
-
-       _flush_cmd_buff (ctx);
-       if (!_wait_ctx_flush_end (ctx))
-               return;
+void vkvg_text_run_destroy(VkvgText textRun) {
+    _font_cache_destroy_text_run(textRun);
+    free(textRun);
+}
+void vkvg_show_text_run(VkvgContext ctx, VkvgText textRun) {
+    if (ctx->status)
+        return;
+    _font_cache_show_text_run(ctx, textRun);
+}
+void vkvg_text_run_get_extents(VkvgText textRun, vkvg_text_extents_t *extents) { *extents = textRun->extents; }
+
+void vkvg_text_extents(VkvgContext ctx, const char *text, vkvg_text_extents_t *extents) {
+    if (ctx->status)
+        return;
+    _font_cache_text_extents(ctx, text, -1, extents);
+}
+void vkvg_font_extents(VkvgContext ctx, vkvg_font_extents_t *extents) {
+    if (ctx->status)
+        return;
+    _font_cache_font_extents(ctx, extents);
+}
+
+void vkvg_save(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SAVE);
+    LOG(VKVG_LOG_INFO, "SAVE CONTEXT: ctx = %p\n", ctx);
+
+    VkvgDevice           dev = ctx->dev;
+    vkvg_context_save_t *sav = (vkvg_context_save_t *)calloc(1, sizeof(vkvg_context_save_t));
+
+    _flush_cmd_buff(ctx);
+    if (!_wait_ctx_flush_end(ctx)) {
+        free(sav);
+        return;
+    }
+
+    if (ctx->curClipState == vkvg_clip_state_clip) {
+        sav->clippingState = vkvg_clip_state_clip_saved;
+
+        uint8_t curSaveStencil = ctx->curSavBit / 6;
+
+        if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0) { // new save/restore stencil image have to be created
+            VkhImage *savedStencilsPtr = NULL;
+            if (savedStencilsPtr)
+                savedStencilsPtr = (VkhImage *)realloc(ctx->savedStencils, curSaveStencil * sizeof(VkhImage));
+            else
+                savedStencilsPtr = (VkhImage *)malloc(curSaveStencil * sizeof(VkhImage));
+            if (savedStencilsPtr == NULL) {
+                free(sav);
+                ctx->status = VKVG_STATUS_NO_MEMORY;
+                return;
+            }
+            ctx->savedStencils  = savedStencilsPtr;
+            VkhImage savStencil = vkh_image_ms_create(
+                (VkhDevice)dev, dev->stencilFormat, dev->samples, ctx->pSurf->width, ctx->pSurf->height,
+                VKH_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+            ctx->savedStencils[curSaveStencil - 1] = savStencil;
+
+            vkh_cmd_begin(ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+            ctx->cmdStarted = true;
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+            vkh_cmd_label_start(ctx->cmd, "new save/restore stencil", DBG_LAB_COLOR_SAV);
+#endif
 
-       ctx->pushConsts   = sav->pushConsts;
-       ctx->pushCstDirty = true;
+            vkh_image_set_layout(ctx->cmd, ctx->pSurf->stencil, dev->stencilAspectFlag,
+                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+            vkh_image_set_layout(ctx->cmd, savStencil, dev->stencilAspectFlag, VK_IMAGE_LAYOUT_GENERAL,
+                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
+                                 VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+            VkImageCopy cregion = {.srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
+                                   .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
+                                   .extent         = {ctx->pSurf->width, ctx->pSurf->height, 1}};
+            vkCmdCopyImage(ctx->cmd, vkh_image_get_vkimage(ctx->pSurf->stencil), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                           vkh_image_get_vkimage(savStencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
+
+            vkh_image_set_layout(ctx->cmd, ctx->pSurf->stencil, dev->stencilAspectFlag,
+                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+            vkh_cmd_label_end(ctx->cmd);
+#endif
 
-       if (ctx->curClipState) {//!=none
-               if (ctx->curClipState == vkvg_clip_state_clip && sav->clippingState == vkvg_clip_state_clear) {
-                       _reset_clip (ctx);
-               } else {
+            VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd));
+            _wait_and_submit_cmd(ctx);
+        }
 
-                       uint8_t curSaveBit = 1 << ((ctx->curSavBit-1) % 6 + 2);
+        uint8_t curSaveBit = 1 << (ctx->curSavBit % 6 + 2);
 
-                       _start_cmd_for_render_pass (ctx);
+        _start_cmd_for_render_pass(ctx);
 
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-                       vkh_cmd_label_start(ctx->cmd, "restore rp", DBG_LAB_COLOR_SAV);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+        vkh_cmd_label_start(ctx->cmd, "save rp", DBG_LAB_COLOR_SAV);
 #endif
 
-                       CmdBindPipeline                 (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping);
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping);
 
-                       CmdSetStencilReference  (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit);
-                       CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit);
-                       CmdSetStencilWriteMask  (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+        CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT | curSaveBit);
+        CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+        CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit);
 
-                       _draw_full_screen_quad (ctx, NULL);
+        _draw_full_screen_quad(ctx, NULL);
 
-                       _bind_draw_pipeline (ctx);
-                       CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+        _bind_draw_pipeline(ctx);
+        CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
 
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-                       vkh_cmd_label_end (ctx->cmd);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+        vkh_cmd_label_end(ctx->cmd);
 #endif
+        ctx->curSavBit++;
+    } else if (ctx->curClipState == vkvg_clip_state_none)
+        sav->clippingState = (_get_previous_clip_state(ctx) & 0x03);
+    else
+        sav->clippingState = vkvg_clip_state_clear;
+
+    sav->dashOffset = ctx->dashOffset;
+    sav->dashCount  = ctx->dashCount;
+    if (ctx->dashCount > 0) {
+        sav->dashes = (float *)malloc(sizeof(float) * ctx->dashCount);
+        memcpy(sav->dashes, ctx->dashes, sizeof(float) * ctx->dashCount);
+    }
+    sav->lineWidth   = ctx->lineWidth;
+    sav->miterLimit  = ctx->miterLimit;
+    sav->curOperator = ctx->curOperator;
+    sav->lineCap     = ctx->lineCap;
+    sav->lineWidth   = ctx->lineWidth;
+    sav->curFillRule = ctx->curFillRule;
+
+    sav->selectedCharSize = ctx->selectedCharSize;
+    strcpy(sav->selectedFontName, ctx->selectedFontName);
+
+    sav->currentFont   = ctx->currentFont;
+    sav->textDirection = ctx->textDirection;
+    sav->pushConsts    = ctx->pushConsts;
+    if (ctx->pattern) {
+        sav->pattern = ctx->pattern; // TODO:pattern sav must be imutable (copy?)
+        vkvg_pattern_reference(ctx->pattern);
+    } else
+        sav->curColor = ctx->curColor;
+
+    sav->pNext      = ctx->pSavedCtxs;
+    ctx->pSavedCtxs = sav;
+}
+void vkvg_restore(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+
+    RECORD(ctx, VKVG_CMD_RESTORE);
+
+    if (ctx->pSavedCtxs == NULL) {
+        ctx->status = VKVG_STATUS_INVALID_RESTORE;
+        return;
+    }
+
+    LOG(VKVG_LOG_INFO, "RESTORE CONTEXT: ctx = %p\n", ctx);
+
+    vkvg_context_save_t *sav = ctx->pSavedCtxs;
+    ctx->pSavedCtxs          = sav->pNext;
+
+    _flush_cmd_buff(ctx);
+    if (!_wait_ctx_flush_end(ctx))
+        return;
+
+    ctx->pushConsts   = sav->pushConsts;
+    ctx->pushCstDirty = true;
+
+    if (ctx->curClipState) { //!=none
+        if (ctx->curClipState == vkvg_clip_state_clip && sav->clippingState == vkvg_clip_state_clear) {
+            _reset_clip(ctx);
+        } else {
+
+            uint8_t curSaveBit = 1 << ((ctx->curSavBit - 1) % 6 + 2);
+
+            _start_cmd_for_render_pass(ctx);
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+            vkh_cmd_label_start(ctx->cmd, "restore rp", DBG_LAB_COLOR_SAV);
+#endif
+
+            CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping);
 
-                       _flush_cmd_buff (ctx);
-                       if (!_wait_ctx_flush_end (ctx))
-                               return;
-               }
-       }
-       if (sav->clippingState == vkvg_clip_state_clip_saved) {
-               ctx->curSavBit--;
+            CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT | curSaveBit);
+            CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit);
+            CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
 
-               uint8_t curSaveStencil = ctx->curSavBit / 6;
-               if (ctx->curSavBit > 0 && ctx->curSavBit % 6 == 0){//addtional save/restore stencil image have to be copied back to surf stencil first
-                       VkhImage savStencil = ctx->savedStencils[curSaveStencil-1];
+            _draw_full_screen_quad(ctx, NULL);
 
-                       vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-                       ctx->cmdStarted = true;
+            _bind_draw_pipeline(ctx);
+            CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+            vkh_cmd_label_end(ctx->cmd);
+#endif
 
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-                       vkh_cmd_label_start(ctx->cmd, "additional stencil copy while restoring", DBG_LAB_COLOR_SAV);
+            _flush_cmd_buff(ctx);
+            if (!_wait_ctx_flush_end(ctx))
+                return;
+        }
+    }
+    if (sav->clippingState == vkvg_clip_state_clip_saved) {
+        ctx->curSavBit--;
+
+        uint8_t curSaveStencil = ctx->curSavBit / 6;
+        if (ctx->curSavBit > 0 &&
+            ctx->curSavBit % 6 ==
+                0) { // addtional save/restore stencil image have to be copied back to surf stencil first
+            VkhImage savStencil = ctx->savedStencils[curSaveStencil - 1];
+
+            vkh_cmd_begin(ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+            ctx->cmdStarted = true;
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+            vkh_cmd_label_start(ctx->cmd, "additional stencil copy while restoring", DBG_LAB_COLOR_SAV);
 #endif
 
-                       vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, ctx->dev->stencilAspectFlag,
-                                                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                                 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-                       vkh_image_set_layout (ctx->cmd, savStencil, ctx->dev->stencilAspectFlag,
-                                                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-
-                       VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
-                                                                       .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
-                                                                       .extent = {ctx->pSurf->width,ctx->pSurf->height,1}};
-                       vkCmdCopyImage(ctx->cmd,
-                                                  vkh_image_get_vkimage (savStencil),           VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                  vkh_image_get_vkimage (ctx->pSurf->stencil),VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                  1, &cregion);
-                       vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, ctx->dev->stencilAspectFlag,
-                                                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                                                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
-
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-                       vkh_cmd_label_end (ctx->cmd);
+            vkh_image_set_layout(ctx->cmd, ctx->pSurf->stencil, ctx->dev->stencilAspectFlag,
+                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+            vkh_image_set_layout(ctx->cmd, savStencil, ctx->dev->stencilAspectFlag,
+                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+            VkImageCopy cregion = {.srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
+                                   .dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1},
+                                   .extent         = {ctx->pSurf->width, ctx->pSurf->height, 1}};
+            vkCmdCopyImage(ctx->cmd, vkh_image_get_vkimage(savStencil), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                           vkh_image_get_vkimage(ctx->pSurf->stencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
+                           &cregion);
+            vkh_image_set_layout(ctx->cmd, ctx->pSurf->stencil, ctx->dev->stencilAspectFlag,
+                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+            vkh_cmd_label_end(ctx->cmd);
 #endif
 
-                       VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd));
-                       _wait_and_submit_cmd (ctx);
-                       if (!_wait_ctx_flush_end (ctx))
-                               return;
-                       vkh_image_destroy (savStencil);
-               }
-       }
-
-       ctx->curClipState = vkvg_clip_state_none;
-
-       ctx->dashOffset = sav->dashOffset;
-       if (ctx->dashCount > 0)
-               free (ctx->dashes);
-       ctx->dashCount  = sav->dashCount;
-       if (ctx->dashCount > 0) {
-               ctx->dashes = (float*)malloc (sizeof(float) * ctx->dashCount);
-               memcpy (ctx->dashes, sav->dashes, sizeof(float) * ctx->dashCount);
-       }
-
-       ctx->lineWidth  = sav->lineWidth;
-       ctx->miterLimit = sav->miterLimit;
-       ctx->curOperator= sav->curOperator;
-       ctx->lineCap    = sav->lineCap;
-       ctx->lineJoin   = sav->lineJoint;
-       ctx->curFillRule= sav->curFillRule;
-
-       ctx->selectedCharSize = sav->selectedCharSize;
-       strcpy (ctx->selectedFontName, sav->selectedFontName);
-
-       ctx->currentFont  = sav->currentFont;
-       ctx->textDirection= sav->textDirection;
-
-       if (sav->pattern) {
-               if (sav->pattern != ctx->pattern)
-                       _update_cur_pattern (ctx, sav->pattern);
-               else
-                       vkvg_pattern_destroy(sav->pattern);
-       } else {
-               ctx->curColor = sav->curColor;
-               _update_cur_pattern (ctx, NULL);
-       }
-
-       _free_ctx_save(sav);
-}
-
-void vkvg_translate (VkvgContext ctx, float dx, float dy){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_TRANSLATE, dx, dy);
-       LOG(VKVG_LOG_INFO_CMD, "CMD: translate: %f, %f\n", dx, dy);
-       _emit_draw_cmd_undrawn_vertices(ctx);
-       vkvg_matrix_translate (&ctx->pushConsts.mat, dx, dy);
-       _set_mat_inv_and_vkCmdPush (ctx);
-}
-void vkvg_scale (VkvgContext ctx, float sx, float sy){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SCALE, sx, sy);
-       LOG(VKVG_LOG_INFO_CMD, "CMD: scale: %f, %f\n", sx, sy);
-       _emit_draw_cmd_undrawn_vertices(ctx);
-       vkvg_matrix_scale (&ctx->pushConsts.mat, sx, sy);
-       _set_mat_inv_and_vkCmdPush (ctx);
-}
-void vkvg_rotate (VkvgContext ctx, float radians){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_ROTATE, radians);
-       LOG(VKVG_LOG_INFO_CMD, "CMD: rotate: %f\n", radians);
-       _emit_draw_cmd_undrawn_vertices(ctx);
-       vkvg_matrix_rotate (&ctx->pushConsts.mat, radians);
-       _set_mat_inv_and_vkCmdPush (ctx);
-}
-void vkvg_transform (VkvgContext ctx, const vkvg_matrix_t* matrix) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_TRANSFORM, matrix);
-       LOG(VKVG_LOG_INFO_CMD, "CMD: transform: %f, %f, %f, %f, %f, %f\n", matrix->xx, matrix->yx, matrix->xy, matrix->yy, matrix->x0, matrix->y0);
-       _emit_draw_cmd_undrawn_vertices(ctx);
-       vkvg_matrix_t res;
-       vkvg_matrix_multiply (&res, &ctx->pushConsts.mat, matrix);
-       ctx->pushConsts.mat = res;
-       _set_mat_inv_and_vkCmdPush (ctx);
-}
-void vkvg_identity_matrix (VkvgContext ctx) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_IDENTITY_MATRIX);
-       LOG(VKVG_LOG_INFO_CMD, "CMD: identity_matrix:\n");
-       _emit_draw_cmd_undrawn_vertices(ctx);
-       vkvg_matrix_t im = VKVG_IDENTITY_MATRIX;
-       ctx->pushConsts.mat = im;
-       _set_mat_inv_and_vkCmdPush (ctx);
-}
-void vkvg_set_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix){
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_SET_MATRIX, matrix);
-       LOG(VKVG_LOG_INFO_CMD, "CMD: set_matrix: %f, %f, %f, %f, %f, %f\n", matrix->xx, matrix->yx, matrix->xy, matrix->yy, matrix->x0, matrix->y0);
-       _emit_draw_cmd_undrawn_vertices(ctx);
-       ctx->pushConsts.mat = (*matrix);
-       _set_mat_inv_and_vkCmdPush (ctx);
-}
-void vkvg_get_matrix (VkvgContext ctx, vkvg_matrix_t* const matrix){
-       *matrix = ctx->pushConsts.mat;
-}
-
-void vkvg_elliptic_arc_to (VkvgContext ctx, float x2, float y2, bool largeArc, bool sweepFlag, float rx, float ry, float phi) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_ELLIPTICAL_ARC_TO, x2, y2, rx, ry, phi, largeArc, sweepFlag);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: elliptic_arc_to: x2:%10.5f y2:%10.5f large:%d sweep:%d rx:%10.5f ry:%10.5f phi:%10.5f \n", x2,y2,largeArc,sweepFlag,rx,ry,phi);
-       float x1, y1;
-       vkvg_get_current_point(ctx, &x1, &y1);
-       _elliptic_arc(ctx, x1, y1, x2, y2, largeArc, sweepFlag, rx, ry, phi);
-}
-void vkvg_rel_elliptic_arc_to (VkvgContext ctx, float x2, float y2, bool largeArc, bool sweepFlag, float rx, float ry, float phi) {
-       if (ctx->status)
-               return;
-       RECORD(ctx, VKVG_CMD_REL_ELLIPTICAL_ARC_TO, x2, y2, rx, ry, phi, largeArc, sweepFlag);
-       LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_elliptic_arc_to: x2:%10.5f y2:%10.5f large:%d sweep:%d rx:%10.5f ry:%10.5f phi:%10.5f \n", x2,y2,largeArc,sweepFlag,rx,ry,phi);
-
-       float x1, y1;
-       vkvg_get_current_point(ctx, &x1, &y1);
-       _elliptic_arc(ctx, x1, y1, x2+x1, y2+y1, largeArc, sweepFlag, rx, ry, phi);
-}
-
-void vkvg_ellipse (VkvgContext ctx, float radiusX, float radiusY, float x, float y, float rotationAngle) {
-       if (ctx->status)
-               return;
-       LOG(VKVG_LOG_INFO_CMD, "CMD: ellipse:\n");
-
-       float width_two_thirds = radiusX * 4 / 3;
-
-       float dx1 = sinf(rotationAngle) * radiusY;
-       float dy1 = cosf(rotationAngle) * radiusY;
-       float dx2 = cosf(rotationAngle) * width_two_thirds;
-       float dy2 = sinf(rotationAngle) * width_two_thirds;
-
-       float topCenterX = x - dx1;
-       float topCenterY = y + dy1;
-       float topRightX = topCenterX + dx2;
-       float topRightY = topCenterY + dy2;
-       float topLeftX = topCenterX - dx2;
-       float topLeftY = topCenterY - dy2;
-
-       float bottomCenterX = x + dx1;
-       float bottomCenterY = y - dy1;
-       float bottomRightX = bottomCenterX + dx2;
-       float bottomRightY = bottomCenterY + dy2;
-       float bottomLeftX = bottomCenterX - dx2;
-       float bottomLeftY = bottomCenterY - dy2;
-
-       _finish_path(ctx);
-       _add_point (ctx, bottomCenterX, bottomCenterY);
-
-       _curve_to (ctx, bottomRightX, bottomRightY, topRightX, topRightY, topCenterX, topCenterY);
-       _curve_to (ctx, topLeftX, topLeftY, bottomLeftX, bottomLeftY, bottomCenterX, bottomCenterY);
-
-       ctx->pathes[ctx->pathPtr] |= PATH_CLOSED_BIT;
-       _finish_path(ctx);
-}
-
-VkvgSurface vkvg_get_target (VkvgContext ctx) {
-       if (ctx->status)
-               return NULL;
-       return ctx->pSurf;
-}
-
-const char *
-vkvg_status_to_string (vkvg_status_t status) {
-       switch (status) {
-       case VKVG_STATUS_SUCCESS:
-               return "no error has occurred";
-       case VKVG_STATUS_NO_MEMORY:
-               return "out of memory";
-       case VKVG_STATUS_INVALID_RESTORE:
-               return "vkvg_restore() without matching vkvg_save()";
-       case VKVG_STATUS_NO_CURRENT_POINT:
-               return "no current point defined";
-       case VKVG_STATUS_INVALID_MATRIX:
-               return "invalid matrix (not invertible)";
-       case VKVG_STATUS_INVALID_STATUS:
-               return "invalid value for an input vkvg_status_t";
-       case VKVG_STATUS_INVALID_INDEX:
-               return "invalid index passed to getter";
-       case VKVG_STATUS_NULL_POINTER:
-               return "NULL pointer";
-       case VKVG_STATUS_WRITE_ERROR:
-               return "error while writing to output stream";
-       case VKVG_STATUS_PATTERN_TYPE_MISMATCH:
-               return "the pattern type is not appropriate for the operation";
-       case VKVG_STATUS_PATTERN_INVALID_GRADIENT:
-               return "the stops count is zero";
-       case VKVG_STATUS_INVALID_FORMAT:
-               return "invalid value for an input vkvg_format_t";
-       case VKVG_STATUS_FILE_NOT_FOUND:
-               return "file not found";
-       case VKVG_STATUS_INVALID_DASH:
-               return "invalid value for a dash setting";
-       case VKVG_STATUS_INVALID_RECT:
-               return "a rectangle has the height or width equal to 0";
-       case VKVG_STATUS_TIMEOUT:
-               return "waiting for a Vulkan operation to finish resulted in a fence timeout (5 seconds)";
-       case VKVG_STATUS_DEVICE_ERROR:
-               return "the initialization of the device resulted in an error";
-       case VKVG_STATUS_INVALID_IMAGE:
-               return "invalid image";
-       case VKVG_STATUS_INVALID_SURFACE:
-               return "invalid surface";
-       case VKVG_STATUS_INVALID_FONT:
-               return "unresolved font name";
-       default:
-               return "<unknown error status>";
-       }
+            VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd));
+            _wait_and_submit_cmd(ctx);
+            if (!_wait_ctx_flush_end(ctx))
+                return;
+            vkh_image_destroy(savStencil);
+        }
+    }
+
+    ctx->curClipState = vkvg_clip_state_none;
+
+    ctx->dashOffset = sav->dashOffset;
+    if (ctx->dashCount > 0)
+        free(ctx->dashes);
+    ctx->dashCount = sav->dashCount;
+    if (ctx->dashCount > 0) {
+        ctx->dashes = (float *)malloc(sizeof(float) * ctx->dashCount);
+        memcpy(ctx->dashes, sav->dashes, sizeof(float) * ctx->dashCount);
+    }
+
+    ctx->lineWidth   = sav->lineWidth;
+    ctx->miterLimit  = sav->miterLimit;
+    ctx->curOperator = sav->curOperator;
+    ctx->lineCap     = sav->lineCap;
+    ctx->lineJoin    = sav->lineJoint;
+    ctx->curFillRule = sav->curFillRule;
+
+    ctx->selectedCharSize = sav->selectedCharSize;
+    strcpy(ctx->selectedFontName, sav->selectedFontName);
+
+    ctx->currentFont   = sav->currentFont;
+    ctx->textDirection = sav->textDirection;
+
+    if (sav->pattern) {
+        if (sav->pattern != ctx->pattern)
+            _update_cur_pattern(ctx, sav->pattern);
+        else
+            vkvg_pattern_destroy(sav->pattern);
+    } else {
+        ctx->curColor = sav->curColor;
+        _update_cur_pattern(ctx, NULL);
+    }
+
+    _free_ctx_save(sav);
+}
+
+void vkvg_translate(VkvgContext ctx, float dx, float dy) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_TRANSLATE, dx, dy);
+    LOG(VKVG_LOG_INFO_CMD, "CMD: translate: %f, %f\n", dx, dy);
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    vkvg_matrix_translate(&ctx->pushConsts.mat, dx, dy);
+    _set_mat_inv_and_vkCmdPush(ctx);
+}
+void vkvg_scale(VkvgContext ctx, float sx, float sy) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SCALE, sx, sy);
+    LOG(VKVG_LOG_INFO_CMD, "CMD: scale: %f, %f\n", sx, sy);
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    vkvg_matrix_scale(&ctx->pushConsts.mat, sx, sy);
+    _set_mat_inv_and_vkCmdPush(ctx);
+}
+void vkvg_rotate(VkvgContext ctx, float radians) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_ROTATE, radians);
+    LOG(VKVG_LOG_INFO_CMD, "CMD: rotate: %f\n", radians);
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    vkvg_matrix_rotate(&ctx->pushConsts.mat, radians);
+    _set_mat_inv_and_vkCmdPush(ctx);
+}
+void vkvg_transform(VkvgContext ctx, const vkvg_matrix_t *matrix) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_TRANSFORM, matrix);
+    LOG(VKVG_LOG_INFO_CMD, "CMD: transform: %f, %f, %f, %f, %f, %f\n", matrix->xx, matrix->yx, matrix->xy, matrix->yy,
+        matrix->x0, matrix->y0);
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    vkvg_matrix_t res;
+    vkvg_matrix_multiply(&res, &ctx->pushConsts.mat, matrix);
+    ctx->pushConsts.mat = res;
+    _set_mat_inv_and_vkCmdPush(ctx);
+}
+void vkvg_identity_matrix(VkvgContext ctx) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_IDENTITY_MATRIX);
+    LOG(VKVG_LOG_INFO_CMD, "CMD: identity_matrix:\n");
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    vkvg_matrix_t im    = VKVG_IDENTITY_MATRIX;
+    ctx->pushConsts.mat = im;
+    _set_mat_inv_and_vkCmdPush(ctx);
+}
+void vkvg_set_matrix(VkvgContext ctx, const vkvg_matrix_t *matrix) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_SET_MATRIX, matrix);
+    LOG(VKVG_LOG_INFO_CMD, "CMD: set_matrix: %f, %f, %f, %f, %f, %f\n", matrix->xx, matrix->yx, matrix->xy, matrix->yy,
+        matrix->x0, matrix->y0);
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    ctx->pushConsts.mat = (*matrix);
+    _set_mat_inv_and_vkCmdPush(ctx);
+}
+void vkvg_get_matrix(VkvgContext ctx, vkvg_matrix_t *const matrix) { *matrix = ctx->pushConsts.mat; }
+
+void vkvg_elliptic_arc_to(VkvgContext ctx, float x2, float y2, bool largeArc, bool sweepFlag, float rx, float ry,
+                          float phi) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_ELLIPTICAL_ARC_TO, x2, y2, rx, ry, phi, largeArc, sweepFlag);
+    LOG(VKVG_LOG_INFO_CMD,
+        "\tCMD: elliptic_arc_to: x2:%10.5f y2:%10.5f large:%d sweep:%d rx:%10.5f ry:%10.5f phi:%10.5f \n", x2, y2,
+        largeArc, sweepFlag, rx, ry, phi);
+    float x1, y1;
+    vkvg_get_current_point(ctx, &x1, &y1);
+    _elliptic_arc(ctx, x1, y1, x2, y2, largeArc, sweepFlag, rx, ry, phi);
+}
+void vkvg_rel_elliptic_arc_to(VkvgContext ctx, float x2, float y2, bool largeArc, bool sweepFlag, float rx, float ry,
+                              float phi) {
+    if (ctx->status)
+        return;
+    RECORD(ctx, VKVG_CMD_REL_ELLIPTICAL_ARC_TO, x2, y2, rx, ry, phi, largeArc, sweepFlag);
+    LOG(VKVG_LOG_INFO_CMD,
+        "\tCMD: rel_elliptic_arc_to: x2:%10.5f y2:%10.5f large:%d sweep:%d rx:%10.5f ry:%10.5f phi:%10.5f \n", x2, y2,
+        largeArc, sweepFlag, rx, ry, phi);
+
+    float x1, y1;
+    vkvg_get_current_point(ctx, &x1, &y1);
+    _elliptic_arc(ctx, x1, y1, x2 + x1, y2 + y1, largeArc, sweepFlag, rx, ry, phi);
+}
+
+void vkvg_ellipse(VkvgContext ctx, float radiusX, float radiusY, float x, float y, float rotationAngle) {
+    if (ctx->status)
+        return;
+    LOG(VKVG_LOG_INFO_CMD, "CMD: ellipse:\n");
+
+    float width_two_thirds = radiusX * 4 / 3;
+
+    float dx1 = sinf(rotationAngle) * radiusY;
+    float dy1 = cosf(rotationAngle) * radiusY;
+    float dx2 = cosf(rotationAngle) * width_two_thirds;
+    float dy2 = sinf(rotationAngle) * width_two_thirds;
+
+    float topCenterX = x - dx1;
+    float topCenterY = y + dy1;
+    float topRightX  = topCenterX + dx2;
+    float topRightY  = topCenterY + dy2;
+    float topLeftX   = topCenterX - dx2;
+    float topLeftY   = topCenterY - dy2;
+
+    float bottomCenterX = x + dx1;
+    float bottomCenterY = y - dy1;
+    float bottomRightX  = bottomCenterX + dx2;
+    float bottomRightY  = bottomCenterY + dy2;
+    float bottomLeftX   = bottomCenterX - dx2;
+    float bottomLeftY   = bottomCenterY - dy2;
+
+    _finish_path(ctx);
+    _add_point(ctx, bottomCenterX, bottomCenterY);
+
+    _curve_to(ctx, bottomRightX, bottomRightY, topRightX, topRightY, topCenterX, topCenterY);
+    _curve_to(ctx, topLeftX, topLeftY, bottomLeftX, bottomLeftY, bottomCenterX, bottomCenterY);
+
+    ctx->pathes[ctx->pathPtr] |= PATH_CLOSED_BIT;
+    _finish_path(ctx);
+}
+
+VkvgSurface vkvg_get_target(VkvgContext ctx) {
+    if (ctx->status)
+        return NULL;
+    return ctx->pSurf;
+}
+
+const char *vkvg_status_to_string(vkvg_status_t status) {
+    switch (status) {
+    case VKVG_STATUS_SUCCESS:
+        return "no error has occurred";
+    case VKVG_STATUS_NO_MEMORY:
+        return "out of memory";
+    case VKVG_STATUS_INVALID_RESTORE:
+        return "vkvg_restore() without matching vkvg_save()";
+    case VKVG_STATUS_NO_CURRENT_POINT:
+        return "no current point defined";
+    case VKVG_STATUS_INVALID_MATRIX:
+        return "invalid matrix (not invertible)";
+    case VKVG_STATUS_INVALID_STATUS:
+        return "invalid value for an input vkvg_status_t";
+    case VKVG_STATUS_INVALID_INDEX:
+        return "invalid index passed to getter";
+    case VKVG_STATUS_NULL_POINTER:
+        return "NULL pointer";
+    case VKVG_STATUS_WRITE_ERROR:
+        return "error while writing to output stream";
+    case VKVG_STATUS_PATTERN_TYPE_MISMATCH:
+        return "the pattern type is not appropriate for the operation";
+    case VKVG_STATUS_PATTERN_INVALID_GRADIENT:
+        return "the stops count is zero";
+    case VKVG_STATUS_INVALID_FORMAT:
+        return "invalid value for an input vkvg_format_t";
+    case VKVG_STATUS_FILE_NOT_FOUND:
+        return "file not found";
+    case VKVG_STATUS_INVALID_DASH:
+        return "invalid value for a dash setting";
+    case VKVG_STATUS_INVALID_RECT:
+        return "a rectangle has the height or width equal to 0";
+    case VKVG_STATUS_TIMEOUT:
+        return "waiting for a Vulkan operation to finish resulted in a fence timeout (5 seconds)";
+    case VKVG_STATUS_DEVICE_ERROR:
+        return "the initialization of the device resulted in an error";
+    case VKVG_STATUS_INVALID_IMAGE:
+        return "invalid image";
+    case VKVG_STATUS_INVALID_SURFACE:
+        return "invalid surface";
+    case VKVG_STATUS_INVALID_FONT:
+        return "unresolved font name";
+    default:
+        return "<unknown error status>";
+    }
 }
index b6a9068f76c6b7bfc565867eee9a800226eaf677..ce689474970424de2259579048dbe96a5139d40d 100644 (file)
@@ -20,7 +20,7 @@
  * THE SOFTWARE.
  */
 
-//credits for bezier algorithms to:
+// credits for bezier algorithms to:
 //             Anti-Grain Geometry (AGG) - Version 2.5
 //             A high quality rendering engine for C++
 //             Copyright (C) 2002-2006 Maxim Shemanarev
@@ -28,7 +28,6 @@
 //                              mcseemagg@yahoo.com
 //                              http://antigrain.com
 
-
 #include "vkvg_surface_internal.h"
 #include "vkvg_context_internal.h"
 #include "vkvg_device_internal.h"
 #include "glutess.h"
 #endif
 
-void _resize_vertex_cache (VkvgContext ctx, uint32_t newSize) {
-       Vertex* tmp = (Vertex*) realloc (ctx->vertexCache, (size_t)newSize * sizeof(Vertex));
-       LOG(VKVG_LOG_DBG_ARRAYS, "resize vertex cache (vx count=%u): old size: %u -> new size: %u size(byte): %zu Ptr: %p -> %p\n",
-               ctx->vertCount, ctx->sizeVertices, newSize, (size_t)newSize * sizeof(Vertex), ctx->vertexCache, tmp);
-       if (tmp == NULL){
-               ctx->status = VKVG_STATUS_NO_MEMORY;
-               LOG(VKVG_LOG_ERR, "resize vertex cache failed: vert count: %u byte size: %zu\n", newSize, newSize * sizeof(Vertex));
-               return;
-       }
-       ctx->vertexCache = tmp;
-       ctx->sizeVertices = newSize;
-}
-void _resize_index_cache (VkvgContext ctx, uint32_t newSize) {
-       VKVG_IBO_INDEX_TYPE* tmp = (VKVG_IBO_INDEX_TYPE*) realloc (ctx->indexCache, (size_t)newSize * sizeof(VKVG_IBO_INDEX_TYPE));
-       LOG(VKVG_LOG_DBG_ARRAYS, "resize IBO: new size: %lu Ptr: %p -> %p\n", (size_t)newSize * sizeof(VKVG_IBO_INDEX_TYPE), ctx->indexCache, tmp);
-       if (tmp == NULL){
-               ctx->status = VKVG_STATUS_NO_MEMORY;
-               LOG(VKVG_LOG_ERR, "resize IBO failed: idx count: %u size(byte): %zu\n", newSize, (size_t)newSize * sizeof(VKVG_IBO_INDEX_TYPE));
-               return;
-       }
-       ctx->indexCache = tmp;
-       ctx->sizeIndices = newSize;
-}
-void _ensure_vertex_cache_size (VkvgContext ctx, uint32_t addedVerticesCount) {
-       if (ctx->sizeVertices - ctx->vertCount > VKVG_ARRAY_THRESHOLD + addedVerticesCount)
-               return;
-       uint32_t newSize = ctx->sizeVertices + addedVerticesCount;
-       uint32_t modulo = addedVerticesCount % VKVG_VBO_SIZE;
-       if (modulo > 0)
-               newSize += VKVG_VBO_SIZE - modulo;
-       _resize_vertex_cache (ctx, newSize);
-}
-void _check_vertex_cache_size (VkvgContext ctx) {
-       assert(ctx->sizeVertices > ctx->vertCount);
-       if (ctx->sizeVertices - VKVG_ARRAY_THRESHOLD > ctx->vertCount)
-               return;
-       _resize_vertex_cache (ctx, ctx->sizeVertices + VKVG_VBO_SIZE);
-}
-void _ensure_index_cache_size (VkvgContext ctx, uint32_t addedIndicesCount) {
-       assert(ctx->sizeIndices > ctx->indCount);
-       if (ctx->sizeIndices - VKVG_ARRAY_THRESHOLD > ctx->indCount + addedIndicesCount)
-               return;
-       uint32_t newSize = ctx->sizeIndices + addedIndicesCount;
-       uint32_t modulo = addedIndicesCount % VKVG_IBO_SIZE;
-       if (modulo > 0)
-               newSize += VKVG_IBO_SIZE - modulo;
-       _resize_index_cache (ctx, newSize);
-}
-void _check_index_cache_size (VkvgContext ctx) {
-       if (ctx->sizeIndices - VKVG_ARRAY_THRESHOLD > ctx->indCount)
-               return;
-       _resize_index_cache (ctx, ctx->sizeIndices + VKVG_IBO_SIZE);
-}
-//check host path array size, return true if error. pathPtr is already incremented
-bool _check_pathes_array (VkvgContext ctx){
-       if (ctx->sizePathes - ctx->pathPtr - ctx->segmentPtr > VKVG_ARRAY_THRESHOLD)
-               return false;
-       ctx->sizePathes += VKVG_PATHES_SIZE;
-       uint32_t* tmp = (uint32_t*) realloc (ctx->pathes, (size_t)ctx->sizePathes * sizeof(uint32_t));
-       LOG(VKVG_LOG_DBG_ARRAYS, "resize PATH: new size: %u Ptr: %p -> %p\n", ctx->sizePathes, ctx->pathes, tmp);
-       if (tmp == NULL){
-               ctx->status = VKVG_STATUS_NO_MEMORY;
-               LOG(VKVG_LOG_ERR, "resize PATH failed: new size(byte): %zu\n", ctx->sizePathes * sizeof(uint32_t));
-               _clear_path(ctx);
-               return true;
-       }
-       ctx->pathes = tmp;
-       return false;
-}
-//check host point array size, return true if error
-bool _check_point_array (VkvgContext ctx){
-       if (ctx->sizePoints - VKVG_ARRAY_THRESHOLD > ctx->pointCount)
-               return false;
-       ctx->sizePoints += VKVG_PTS_SIZE;
-       vec2* tmp = (vec2*) realloc (ctx->points, (size_t)ctx->sizePoints * sizeof(vec2));
-       LOG(VKVG_LOG_DBG_ARRAYS, "resize Points: new size(point): %u Ptr: %p -> %p\n", ctx->sizePoints, ctx->points, tmp);
-       if (tmp == NULL){
-               ctx->status = VKVG_STATUS_NO_MEMORY;
-               LOG(VKVG_LOG_ERR, "resize PATH failed: new size(byte): %zu\n", ctx->sizePoints * sizeof(vec2));
-               _clear_path (ctx);
-               return true;
-       }
-       ctx->points = tmp;
-       return false;
-}
-bool _current_path_is_empty (VkvgContext ctx) {
-       return ctx->pathes [ctx->pathPtr] == 0;
-}
-//this function expect that current point exists
-vec2 _get_current_position (VkvgContext ctx) {
-       return ctx->points[ctx->pointCount-1];
-}
-//set curve start point and set path has curve bit
-void _set_curve_start (VkvgContext ctx) {
-       if (ctx->segmentPtr > 0) {
-               //check if current segment has points (straight)
-               if ((ctx->pathes [ctx->pathPtr + ctx->segmentPtr]&PATH_ELT_MASK) > 0)
-                       ctx->segmentPtr++;
-       }else{
-               //not yet segmented path, first segment length is copied
-               if (ctx->pathes [ctx->pathPtr] > 0){//create first straight segment first
-                       ctx->pathes [ctx->pathPtr + 1] = ctx->pathes [ctx->pathPtr];
-                       ctx->segmentPtr = 2;
-               }else
-                       ctx->segmentPtr = 1;
-       }
-       _check_pathes_array(ctx);
-       ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = 0;
-}
-//compute segment length and set is curved bit
-void _set_curve_end (VkvgContext ctx) {
-       //ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = ctx->pathes [ctx->pathPtr] - ctx->pathes [ctx->pathPtr + ctx->segmentPtr];
-       ctx->pathes [ctx->pathPtr + ctx->segmentPtr] |= PATH_HAS_CURVES_BIT;
-       ctx->segmentPtr++;
-       _check_pathes_array(ctx);
-       ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = 0;
-}
-//path start pointed at ptrPath has curve bit
-bool _path_has_curves (VkvgContext ctx, uint32_t ptrPath) {
-       return ctx->pathes[ptrPath] & PATH_HAS_CURVES_BIT;
-}
-void _finish_path (VkvgContext ctx){
-       if (ctx->pathes [ctx->pathPtr] == 0)//empty
-               return;
-       if ((ctx->pathes [ctx->pathPtr]&PATH_ELT_MASK) < 2){
-               //only current pos is in path
-               ctx->pointCount -= ctx->pathes[ctx->pathPtr];//what about the bounds?
-               ctx->pathes[ctx->pathPtr] = 0;
-               ctx->segmentPtr = 0;
-               return;
-       }
-
-       LOG(VKVG_LOG_INFO_PATH, "PATH: points count=%10d\n", ctx->pathes[ctx->pathPtr]&PATH_ELT_MASK);
-
-       if (ctx->pathPtr == 0 && ctx->simpleConvex)
-               ctx->pathes[0] |= PATH_IS_CONVEX_BIT;
-
-       if (ctx->segmentPtr > 0) {//pathes having curves are segmented
-               ctx->pathes[ctx->pathPtr] |= PATH_HAS_CURVES_BIT;
-               //curved segment increment segmentPtr on curve end,
-               //so if last segment is not a curve and point count > 0
-               if ((ctx->pathes[ctx->pathPtr+ctx->segmentPtr]&PATH_HAS_CURVES_BIT)==0 &&
-                               (ctx->pathes[ctx->pathPtr+ctx->segmentPtr]&PATH_ELT_MASK) > 0)
-                       ctx->segmentPtr++;//current segment has to be included
-               ctx->pathPtr += ctx->segmentPtr;
-       }else
-               ctx->pathPtr ++;
-
-       if (_check_pathes_array(ctx))
-               return;
-
-       ctx->pathes[ctx->pathPtr] = 0;
-       ctx->segmentPtr = 0;
-       ctx->subpathCount++;
-       ctx->simpleConvex = false;
-}
-//clear path datas in context
-void _clear_path (VkvgContext ctx){
-       ctx->pathPtr = 0;
-       ctx->pathes [ctx->pathPtr] = 0;
-       ctx->pointCount = 0;
-       ctx->segmentPtr = 0;
-       ctx->subpathCount = 0;
-       ctx->simpleConvex = false;
-}
-void _remove_last_point (VkvgContext ctx){
-       ctx->pathes[ctx->pathPtr]--;
-       ctx->pointCount--;
-       if (ctx->segmentPtr > 0){//if path is segmented
-               if (!ctx->pathes [ctx->pathPtr + ctx->segmentPtr])//if current segment is empty
-                       ctx->segmentPtr--;
-               ctx->pathes [ctx->pathPtr + ctx->segmentPtr]--;//decrement last segment point count
-               if ((ctx->pathes [ctx->pathPtr + ctx->segmentPtr]&PATH_ELT_MASK) == 0)//if no point left (was only one)
-                       ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = 0;//reset current segment
-               else if (ctx->pathes [ctx->pathPtr + ctx->segmentPtr]&PATH_HAS_CURVES_BIT)//if segment is a curve
-                       ctx->segmentPtr++;//then segPtr has to be forwarded to new segment
-       }
-}
-bool _path_is_closed (VkvgContext ctx, uint32_t ptrPath){
-       return ctx->pathes[ptrPath] & PATH_CLOSED_BIT;
-}
-void _add_point (VkvgContext ctx, float x, float y){
-       if (_check_point_array(ctx))
-               return;
-       if (isnan(x) || isnan(y)) {
-               LOG(VKVG_LOG_DEBUG, "_add_point: (%f, %f)\n", x, y);
-               return;
-       }
-       vec2 v = {x,y};
-       /*if (!_current_path_is_empty(ctx) && vec2_length(vec2_sub(ctx->points[ctx->pointCount-1], v))<1.f)
-               return;*/
-       LOG(VKVG_LOG_INFO_PTS, "_add_point: (%f, %f)\n", x, y);
-
-       ctx->points[ctx->pointCount] = v;
-       ctx->pointCount++;//total point count of pathes, (for array bounds check)
-       ctx->pathes[ctx->pathPtr]++;//total point count in path
-       if (ctx->segmentPtr > 0)
-               ctx->pathes[ctx->pathPtr + ctx->segmentPtr]++;//total point count in path's segment
-}
-float _normalizeAngle(float a)
-{
-       float res = ROUND_DOWN(fmodf(a, 2.0f * M_PIF), 100);
-       if (res < 0.0f)
-               res += 2.0f * M_PIF;
-       return res;
-}
-float _get_arc_step (VkvgContext ctx, float radius) {
-       float sx, sy;
-       vkvg_matrix_get_scale (&ctx->pushConsts.mat, &sx, &sy);
-       float r = radius * fabsf(fmaxf(sx,sy));
-       if (r < 30.0f)
-               return fminf(M_PIF / 3.f, M_PIF / r);
-       return fminf(M_PIF / 3.f,M_PIF / (r * 0.4f));
-}
-void _create_gradient_buff (VkvgContext ctx){
-       vkh_buffer_init ((VkhDevice)ctx->dev,
-               VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
-               VKH_MEMORY_USAGE_CPU_TO_GPU,
-               sizeof(vkvg_gradient_t), &ctx->uboGrad, true);
-}
-void _create_vertices_buff (VkvgContext ctx){
-       vkh_buffer_init ((VkhDevice)ctx->dev,
-               VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
-               VKH_MEMORY_USAGE_CPU_TO_GPU,
-               ctx->sizeVBO * sizeof(Vertex), &ctx->vertices, true);
-       vkh_buffer_init ((VkhDevice)ctx->dev,
-               VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
-               VKH_MEMORY_USAGE_CPU_TO_GPU,
-               ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices, true);
-}
-void _resize_vbo (VkvgContext ctx, uint32_t new_size) {
-       if (!_wait_ctx_flush_end (ctx))//wait previous cmd if not completed
-               return;
-       LOG(VKVG_LOG_DBG_ARRAYS, "resize VBO: %d -> ", ctx->sizeVBO);
-       ctx->sizeVBO = new_size;
-       uint32_t mod = ctx->sizeVBO % VKVG_VBO_SIZE;
-       if (mod > 0)
-               ctx->sizeVBO += VKVG_VBO_SIZE - mod;
-       LOG(VKVG_LOG_DBG_ARRAYS, "%d\n", ctx->sizeVBO);
-       vkh_buffer_resize (&ctx->vertices, ctx->sizeVBO * sizeof(Vertex), true);
-}
-void _resize_ibo (VkvgContext ctx, size_t new_size) {
-       if (!_wait_ctx_flush_end (ctx))//wait previous cmd if not completed
-               return;
-       ctx->sizeIBO = new_size;
-       uint32_t mod = ctx->sizeIBO % VKVG_IBO_SIZE;
-       if (mod > 0)
-               ctx->sizeIBO += VKVG_IBO_SIZE - mod;
-       LOG(VKVG_LOG_DBG_ARRAYS, "resize IBO: new size: %d\n", ctx->sizeIBO);   
-       vkh_buffer_resize (&ctx->indices, ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), true);
-}
-void _add_vertexf (VkvgContext ctx, float x, float y){
-       Vertex* pVert = &ctx->vertexCache[ctx->vertCount];
-       pVert->pos.x = x;
-       pVert->pos.y = y;
-       pVert->color = ctx->curColor;
-       pVert->uv.z = -1;
-       LOG(VKVG_LOG_INFO_VBO, "Add Vertexf %10d: pos:(%10.4f, %10.4f) uv:(%10.4f,%10.4f,%10.4f) color:0x%.8x \n", ctx->vertCount, pVert->pos.x, pVert->pos.y, pVert->uv.x, pVert->uv.y, pVert->uv.z, pVert->color);
-       ctx->vertCount++;
-       _check_vertex_cache_size(ctx);
-}
-void _add_vertexf_unchecked (VkvgContext ctx, float x, float y){
-       Vertex* pVert = &ctx->vertexCache[ctx->vertCount];
-       pVert->pos.x = x;
-       pVert->pos.y = y;
-       pVert->color = ctx->curColor;
-       pVert->uv.z = -1;
-       LOG(VKVG_LOG_INFO_VBO, "Add Vertexf %10d: pos:(%10.4f, %10.4f) uv:(%10.4f,%10.4f,%10.4f) color:0x%.8x \n", ctx->vertCount, pVert->pos.x, pVert->pos.y, pVert->uv.x, pVert->uv.y, pVert->uv.z, pVert->color);
-       ctx->vertCount++;
-}
-void _add_vertex(VkvgContext ctx, Vertex v){
-       ctx->vertexCache[ctx->vertCount] = v;
-       LOG(VKVG_LOG_INFO_VBO, "Add Vertex  %10d: pos:(%10.4f, %10.4f) uv:(%10.4f,%10.4f,%10.4f) color:0x%.8x \n", ctx->vertCount, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.uv.z, v.color);
-       ctx->vertCount++;
-       _check_vertex_cache_size(ctx);
-}
-void _set_vertex(VkvgContext ctx, uint32_t idx, Vertex v){
-       ctx->vertexCache[idx] = v;
-}
+void _resize_vertex_cache(VkvgContext ctx, uint32_t newSize) {
+    Vertex *tmp = (Vertex *)realloc(ctx->vertexCache, (size_t)newSize * sizeof(Vertex));
+    LOG(VKVG_LOG_DBG_ARRAYS,
+        "resize vertex cache (vx count=%u): old size: %u -> new size: %u size(byte): %zu Ptr: %p -> %p\n",
+        ctx->vertCount, ctx->sizeVertices, newSize, (size_t)newSize * sizeof(Vertex), ctx->vertexCache, tmp);
+    if (tmp == NULL) {
+        ctx->status = VKVG_STATUS_NO_MEMORY;
+        LOG(VKVG_LOG_ERR, "resize vertex cache failed: vert count: %u byte size: %zu\n", newSize,
+            newSize * sizeof(Vertex));
+        return;
+    }
+    ctx->vertexCache  = tmp;
+    ctx->sizeVertices = newSize;
+}
+void _resize_index_cache(VkvgContext ctx, uint32_t newSize) {
+    VKVG_IBO_INDEX_TYPE *tmp =
+        (VKVG_IBO_INDEX_TYPE *)realloc(ctx->indexCache, (size_t)newSize * sizeof(VKVG_IBO_INDEX_TYPE));
+    LOG(VKVG_LOG_DBG_ARRAYS, "resize IBO: new size: %lu Ptr: %p -> %p\n", (size_t)newSize * sizeof(VKVG_IBO_INDEX_TYPE),
+        ctx->indexCache, tmp);
+    if (tmp == NULL) {
+        ctx->status = VKVG_STATUS_NO_MEMORY;
+        LOG(VKVG_LOG_ERR, "resize IBO failed: idx count: %u size(byte): %zu\n", newSize,
+            (size_t)newSize * sizeof(VKVG_IBO_INDEX_TYPE));
+        return;
+    }
+    ctx->indexCache  = tmp;
+    ctx->sizeIndices = newSize;
+}
+void _ensure_vertex_cache_size(VkvgContext ctx, uint32_t addedVerticesCount) {
+    if (ctx->sizeVertices - ctx->vertCount > VKVG_ARRAY_THRESHOLD + addedVerticesCount)
+        return;
+    uint32_t newSize = ctx->sizeVertices + addedVerticesCount;
+    uint32_t modulo  = addedVerticesCount % VKVG_VBO_SIZE;
+    if (modulo > 0)
+        newSize += VKVG_VBO_SIZE - modulo;
+    _resize_vertex_cache(ctx, newSize);
+}
+void _check_vertex_cache_size(VkvgContext ctx) {
+    assert(ctx->sizeVertices > ctx->vertCount);
+    if (ctx->sizeVertices - VKVG_ARRAY_THRESHOLD > ctx->vertCount)
+        return;
+    _resize_vertex_cache(ctx, ctx->sizeVertices + VKVG_VBO_SIZE);
+}
+void _ensure_index_cache_size(VkvgContext ctx, uint32_t addedIndicesCount) {
+    assert(ctx->sizeIndices > ctx->indCount);
+    if (ctx->sizeIndices - VKVG_ARRAY_THRESHOLD > ctx->indCount + addedIndicesCount)
+        return;
+    uint32_t newSize = ctx->sizeIndices + addedIndicesCount;
+    uint32_t modulo  = addedIndicesCount % VKVG_IBO_SIZE;
+    if (modulo > 0)
+        newSize += VKVG_IBO_SIZE - modulo;
+    _resize_index_cache(ctx, newSize);
+}
+void _check_index_cache_size(VkvgContext ctx) {
+    if (ctx->sizeIndices - VKVG_ARRAY_THRESHOLD > ctx->indCount)
+        return;
+    _resize_index_cache(ctx, ctx->sizeIndices + VKVG_IBO_SIZE);
+}
+// check host path array size, return true if error. pathPtr is already incremented
+bool _check_pathes_array(VkvgContext ctx) {
+    if (ctx->sizePathes - ctx->pathPtr - ctx->segmentPtr > VKVG_ARRAY_THRESHOLD)
+        return false;
+    ctx->sizePathes += VKVG_PATHES_SIZE;
+    uint32_t *tmp = (uint32_t *)realloc(ctx->pathes, (size_t)ctx->sizePathes * sizeof(uint32_t));
+    LOG(VKVG_LOG_DBG_ARRAYS, "resize PATH: new size: %u Ptr: %p -> %p\n", ctx->sizePathes, ctx->pathes, tmp);
+    if (tmp == NULL) {
+        ctx->status = VKVG_STATUS_NO_MEMORY;
+        LOG(VKVG_LOG_ERR, "resize PATH failed: new size(byte): %zu\n", ctx->sizePathes * sizeof(uint32_t));
+        _clear_path(ctx);
+        return true;
+    }
+    ctx->pathes = tmp;
+    return false;
+}
+// check host point array size, return true if error
+bool _check_point_array(VkvgContext ctx) {
+    if (ctx->sizePoints - VKVG_ARRAY_THRESHOLD > ctx->pointCount)
+        return false;
+    ctx->sizePoints += VKVG_PTS_SIZE;
+    vec2 *tmp = (vec2 *)realloc(ctx->points, (size_t)ctx->sizePoints * sizeof(vec2));
+    LOG(VKVG_LOG_DBG_ARRAYS, "resize Points: new size(point): %u Ptr: %p -> %p\n", ctx->sizePoints, ctx->points, tmp);
+    if (tmp == NULL) {
+        ctx->status = VKVG_STATUS_NO_MEMORY;
+        LOG(VKVG_LOG_ERR, "resize PATH failed: new size(byte): %zu\n", ctx->sizePoints * sizeof(vec2));
+        _clear_path(ctx);
+        return true;
+    }
+    ctx->points = tmp;
+    return false;
+}
+bool _current_path_is_empty(VkvgContext ctx) { return ctx->pathes[ctx->pathPtr] == 0; }
+// this function expect that current point exists
+vec2 _get_current_position(VkvgContext ctx) { return ctx->points[ctx->pointCount - 1]; }
+// set curve start point and set path has curve bit
+void _set_curve_start(VkvgContext ctx) {
+    if (ctx->segmentPtr > 0) {
+        // check if current segment has points (straight)
+        if ((ctx->pathes[ctx->pathPtr + ctx->segmentPtr] & PATH_ELT_MASK) > 0)
+            ctx->segmentPtr++;
+    } else {
+        // not yet segmented path, first segment length is copied
+        if (ctx->pathes[ctx->pathPtr] > 0) { // create first straight segment first
+            ctx->pathes[ctx->pathPtr + 1] = ctx->pathes[ctx->pathPtr];
+            ctx->segmentPtr               = 2;
+        } else
+            ctx->segmentPtr = 1;
+    }
+    _check_pathes_array(ctx);
+    ctx->pathes[ctx->pathPtr + ctx->segmentPtr] = 0;
+}
+// compute segment length and set is curved bit
+void _set_curve_end(VkvgContext ctx) {
+    // ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = ctx->pathes [ctx->pathPtr] - ctx->pathes [ctx->pathPtr +
+    // ctx->segmentPtr];
+    ctx->pathes[ctx->pathPtr + ctx->segmentPtr] |= PATH_HAS_CURVES_BIT;
+    ctx->segmentPtr++;
+    _check_pathes_array(ctx);
+    ctx->pathes[ctx->pathPtr + ctx->segmentPtr] = 0;
+}
+// path start pointed at ptrPath has curve bit
+bool _path_has_curves(VkvgContext ctx, uint32_t ptrPath) { return ctx->pathes[ptrPath] & PATH_HAS_CURVES_BIT; }
+void _finish_path(VkvgContext ctx) {
+    if (ctx->pathes[ctx->pathPtr] == 0) // empty
+        return;
+    if ((ctx->pathes[ctx->pathPtr] & PATH_ELT_MASK) < 2) {
+        // only current pos is in path
+        ctx->pointCount -= ctx->pathes[ctx->pathPtr]; // what about the bounds?
+        ctx->pathes[ctx->pathPtr] = 0;
+        ctx->segmentPtr           = 0;
+        return;
+    }
+
+    LOG(VKVG_LOG_INFO_PATH, "PATH: points count=%10d\n", ctx->pathes[ctx->pathPtr] & PATH_ELT_MASK);
+
+    if (ctx->pathPtr == 0 && ctx->simpleConvex)
+        ctx->pathes[0] |= PATH_IS_CONVEX_BIT;
+
+    if (ctx->segmentPtr > 0) { // pathes having curves are segmented
+        ctx->pathes[ctx->pathPtr] |= PATH_HAS_CURVES_BIT;
+        // curved segment increment segmentPtr on curve end,
+        // so if last segment is not a curve and point count > 0
+        if ((ctx->pathes[ctx->pathPtr + ctx->segmentPtr] & PATH_HAS_CURVES_BIT) == 0 &&
+            (ctx->pathes[ctx->pathPtr + ctx->segmentPtr] & PATH_ELT_MASK) > 0)
+            ctx->segmentPtr++; // current segment has to be included
+        ctx->pathPtr += ctx->segmentPtr;
+    } else
+        ctx->pathPtr++;
+
+    if (_check_pathes_array(ctx))
+        return;
+
+    ctx->pathes[ctx->pathPtr] = 0;
+    ctx->segmentPtr           = 0;
+    ctx->subpathCount++;
+    ctx->simpleConvex = false;
+}
+// clear path datas in context
+void _clear_path(VkvgContext ctx) {
+    ctx->pathPtr              = 0;
+    ctx->pathes[ctx->pathPtr] = 0;
+    ctx->pointCount           = 0;
+    ctx->segmentPtr           = 0;
+    ctx->subpathCount         = 0;
+    ctx->simpleConvex         = false;
+}
+void _remove_last_point(VkvgContext ctx) {
+    ctx->pathes[ctx->pathPtr]--;
+    ctx->pointCount--;
+    if (ctx->segmentPtr > 0) {                            // if path is segmented
+        if (!ctx->pathes[ctx->pathPtr + ctx->segmentPtr]) // if current segment is empty
+            ctx->segmentPtr--;
+        ctx->pathes[ctx->pathPtr + ctx->segmentPtr]--;                          // decrement last segment point count
+        if ((ctx->pathes[ctx->pathPtr + ctx->segmentPtr] & PATH_ELT_MASK) == 0) // if no point left (was only one)
+            ctx->pathes[ctx->pathPtr + ctx->segmentPtr] = 0;                    // reset current segment
+        else if (ctx->pathes[ctx->pathPtr + ctx->segmentPtr] & PATH_HAS_CURVES_BIT) // if segment is a curve
+            ctx->segmentPtr++; // then segPtr has to be forwarded to new segment
+    }
+}
+bool _path_is_closed(VkvgContext ctx, uint32_t ptrPath) { return ctx->pathes[ptrPath] & PATH_CLOSED_BIT; }
+void _add_point(VkvgContext ctx, float x, float y) {
+    if (_check_point_array(ctx))
+        return;
+    if (isnan(x) || isnan(y)) {
+        LOG(VKVG_LOG_DEBUG, "_add_point: (%f, %f)\n", x, y);
+        return;
+    }
+    vec2 v = {x, y};
+    /*if (!_current_path_is_empty(ctx) && vec2_length(vec2_sub(ctx->points[ctx->pointCount-1], v))<1.f)
+        return;*/
+    LOG(VKVG_LOG_INFO_PTS, "_add_point: (%f, %f)\n", x, y);
+
+    ctx->points[ctx->pointCount] = v;
+    ctx->pointCount++;           // total point count of pathes, (for array bounds check)
+    ctx->pathes[ctx->pathPtr]++; // total point count in path
+    if (ctx->segmentPtr > 0)
+        ctx->pathes[ctx->pathPtr + ctx->segmentPtr]++; // total point count in path's segment
+}
+float _normalizeAngle(float a) {
+    float res = ROUND_DOWN(fmodf(a, 2.0f * M_PIF), 100);
+    if (res < 0.0f)
+        res += 2.0f * M_PIF;
+    return res;
+}
+float _get_arc_step(VkvgContext ctx, float radius) {
+    float sx, sy;
+    vkvg_matrix_get_scale(&ctx->pushConsts.mat, &sx, &sy);
+    float r = radius * fabsf(fmaxf(sx, sy));
+    if (r < 30.0f)
+        return fminf(M_PIF / 3.f, M_PIF / r);
+    return fminf(M_PIF / 3.f, M_PIF / (r * 0.4f));
+}
+void _create_gradient_buff(VkvgContext ctx) {
+    vkh_buffer_init((VkhDevice)ctx->dev, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VKH_MEMORY_USAGE_CPU_TO_GPU,
+                    sizeof(vkvg_gradient_t), &ctx->uboGrad, true);
+}
+void _create_vertices_buff(VkvgContext ctx) {
+    vkh_buffer_init((VkhDevice)ctx->dev, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VKH_MEMORY_USAGE_CPU_TO_GPU,
+                    ctx->sizeVBO * sizeof(Vertex), &ctx->vertices, true);
+    vkh_buffer_init((VkhDevice)ctx->dev, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VKH_MEMORY_USAGE_CPU_TO_GPU,
+                    ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), &ctx->indices, true);
+}
+void _resize_vbo(VkvgContext ctx, uint32_t new_size) {
+    if (!_wait_ctx_flush_end(ctx)) // wait previous cmd if not completed
+        return;
+    LOG(VKVG_LOG_DBG_ARRAYS, "resize VBO: %d -> ", ctx->sizeVBO);
+    ctx->sizeVBO = new_size;
+    uint32_t mod = ctx->sizeVBO % VKVG_VBO_SIZE;
+    if (mod > 0)
+        ctx->sizeVBO += VKVG_VBO_SIZE - mod;
+    LOG(VKVG_LOG_DBG_ARRAYS, "%d\n", ctx->sizeVBO);
+    vkh_buffer_resize(&ctx->vertices, ctx->sizeVBO * sizeof(Vertex), true);
+}
+void _resize_ibo(VkvgContext ctx, size_t new_size) {
+    if (!_wait_ctx_flush_end(ctx)) // wait previous cmd if not completed
+        return;
+    ctx->sizeIBO = new_size;
+    uint32_t mod = ctx->sizeIBO % VKVG_IBO_SIZE;
+    if (mod > 0)
+        ctx->sizeIBO += VKVG_IBO_SIZE - mod;
+    LOG(VKVG_LOG_DBG_ARRAYS, "resize IBO: new size: %d\n", ctx->sizeIBO);
+    vkh_buffer_resize(&ctx->indices, ctx->sizeIBO * sizeof(VKVG_IBO_INDEX_TYPE), true);
+}
+void _add_vertexf(VkvgContext ctx, float x, float y) {
+    Vertex *pVert = &ctx->vertexCache[ctx->vertCount];
+    pVert->pos.x  = x;
+    pVert->pos.y  = y;
+    pVert->color  = ctx->curColor;
+    pVert->uv.z   = -1;
+    LOG(VKVG_LOG_INFO_VBO, "Add Vertexf %10d: pos:(%10.4f, %10.4f) uv:(%10.4f,%10.4f,%10.4f) color:0x%.8x \n",
+        ctx->vertCount, pVert->pos.x, pVert->pos.y, pVert->uv.x, pVert->uv.y, pVert->uv.z, pVert->color);
+    ctx->vertCount++;
+    _check_vertex_cache_size(ctx);
+}
+void _add_vertexf_unchecked(VkvgContext ctx, float x, float y) {
+    Vertex *pVert = &ctx->vertexCache[ctx->vertCount];
+    pVert->pos.x  = x;
+    pVert->pos.y  = y;
+    pVert->color  = ctx->curColor;
+    pVert->uv.z   = -1;
+    LOG(VKVG_LOG_INFO_VBO, "Add Vertexf %10d: pos:(%10.4f, %10.4f) uv:(%10.4f,%10.4f,%10.4f) color:0x%.8x \n",
+        ctx->vertCount, pVert->pos.x, pVert->pos.y, pVert->uv.x, pVert->uv.y, pVert->uv.z, pVert->color);
+    ctx->vertCount++;
+}
+void _add_vertex(VkvgContext ctx, Vertex v) {
+    ctx->vertexCache[ctx->vertCount] = v;
+    LOG(VKVG_LOG_INFO_VBO, "Add Vertex  %10d: pos:(%10.4f, %10.4f) uv:(%10.4f,%10.4f,%10.4f) color:0x%.8x \n",
+        ctx->vertCount, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.uv.z, v.color);
+    ctx->vertCount++;
+    _check_vertex_cache_size(ctx);
+}
+void _set_vertex(VkvgContext ctx, uint32_t idx, Vertex v) { ctx->vertexCache[idx] = v; }
 #ifdef VKVG_FILL_NZ_GLUTESS
-void _add_indice (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i) {
-       ctx->indexCache[ctx->indCount++] = i;
-       _check_index_cache_size(ctx);
-}
-void _add_indice_for_fan (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i) {
-       VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount];
-       inds[0] = ctx->tesselator_fan_start;
-       inds[1] = ctx->indexCache[ctx->indCount-1];
-       inds[2] = i;
-       ctx->indCount+=3;
-       _check_index_cache_size(ctx);
-}
-void _add_indice_for_strip (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i, bool odd) {
-       VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount];
-       if (odd) {
-               inds[0] = ctx->indexCache[ctx->indCount-2];
-               inds[1] = i;
-               inds[2] = ctx->indexCache[ctx->indCount-1];
-       } else {
-               inds[0] = ctx->indexCache[ctx->indCount-1];
-               inds[1] = ctx->indexCache[ctx->indCount-2];
-               inds[2] = i;
-       }
-       ctx->indCount+=3;
-       _check_index_cache_size(ctx);
+void _add_indice(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i) {
+    ctx->indexCache[ctx->indCount++] = i;
+    _check_index_cache_size(ctx);
+}
+void _add_indice_for_fan(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i) {
+    VKVG_IBO_INDEX_TYPE *inds = &ctx->indexCache[ctx->indCount];
+    inds[0]                   = ctx->tesselator_fan_start;
+    inds[1]                   = ctx->indexCache[ctx->indCount - 1];
+    inds[2]                   = i;
+    ctx->indCount += 3;
+    _check_index_cache_size(ctx);
+}
+void _add_indice_for_strip(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i, bool odd) {
+    VKVG_IBO_INDEX_TYPE *inds = &ctx->indexCache[ctx->indCount];
+    if (odd) {
+        inds[0] = ctx->indexCache[ctx->indCount - 2];
+        inds[1] = i;
+        inds[2] = ctx->indexCache[ctx->indCount - 1];
+    } else {
+        inds[0] = ctx->indexCache[ctx->indCount - 1];
+        inds[1] = ctx->indexCache[ctx->indCount - 2];
+        inds[2] = i;
+    }
+    ctx->indCount += 3;
+    _check_index_cache_size(ctx);
 }
 #endif
-void _add_tri_indices_for_rect (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i){
-       VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount];
-       inds[0] = i;
-       inds[1] = i+2;
-       inds[2] = i+1;
-       inds[3] = i+1;
-       inds[4] = i+2;
-       inds[5] = i+3;
-       ctx->indCount+=6;
-
-       _check_index_cache_size(ctx);
-       LOG(VKVG_LOG_INFO_IBO, "Rectangle IDX: %d %d %d | %d %d %d (count=%d)\n", inds[0], inds[1], inds[2], inds[3], inds[4], inds[5], ctx->indCount);
-}
-void _add_triangle_indices(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2){
-       VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount];
-       inds[0] = i0;
-       inds[1] = i1;
-       inds[2] = i2;
-       ctx->indCount+=3;
-
-       _check_index_cache_size(ctx);
-       LOG(VKVG_LOG_INFO_IBO, "Triangle IDX: %d %d %d (indCount=%d)\n", i0,i1,i2,ctx->indCount);
-}
-void _add_triangle_indices_unchecked (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2){
-       VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount];
-       inds[0] = i0;
-       inds[1] = i1;
-       inds[2] = i2;
-       ctx->indCount+=3;
-
-       LOG(VKVG_LOG_INFO_IBO, "Triangle IDX: %d %d %d (indCount=%d)\n", i0,i1,i2,ctx->indCount);
-}
-void _vao_add_rectangle (VkvgContext ctx, float x, float y, float width, float height){
-       Vertex v[4] =
-       {
-               {{x,y},                         ctx->curColor, {0,0,-1}},
-               {{x,y+height},          ctx->curColor, {0,0,-1}},
-               {{x+width,y},           ctx->curColor, {0,0,-1}},
-               {{x+width,y+height},ctx->curColor, {0,0,-1}}
-       };
-       VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-       Vertex* pVert = &ctx->vertexCache[ctx->vertCount];
-       memcpy (pVert,v,4*sizeof(Vertex));
-       ctx->vertCount+=4;
-
-       _check_vertex_cache_size(ctx);
-
-       _add_tri_indices_for_rect(ctx, firstIdx);
-}
-//start render pass if not yet started or update push const if requested
-void _ensure_renderpass_is_started (VkvgContext ctx) {
-       LOG(VKVG_LOG_INFO, "_ensure_renderpass_is_started\n");
-       if (!ctx->cmdStarted)
-               _start_cmd_for_render_pass(ctx);
-       else if (ctx->pushCstDirty)
-               _update_push_constants(ctx);
-}
-void _create_cmd_buff (VkvgContext ctx){
-       vkh_cmd_buffs_create((VkhDevice)ctx->dev, ctx->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY, 2, ctx->cmdBuffers);
+void _add_tri_indices_for_rect(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i) {
+    VKVG_IBO_INDEX_TYPE *inds = &ctx->indexCache[ctx->indCount];
+    inds[0]                   = i;
+    inds[1]                   = i + 2;
+    inds[2]                   = i + 1;
+    inds[3]                   = i + 1;
+    inds[4]                   = i + 2;
+    inds[5]                   = i + 3;
+    ctx->indCount += 6;
+
+    _check_index_cache_size(ctx);
+    LOG(VKVG_LOG_INFO_IBO, "Rectangle IDX: %d %d %d | %d %d %d (count=%d)\n", inds[0], inds[1], inds[2], inds[3],
+        inds[4], inds[5], ctx->indCount);
+}
+void _add_triangle_indices(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2) {
+    VKVG_IBO_INDEX_TYPE *inds = &ctx->indexCache[ctx->indCount];
+    inds[0]                   = i0;
+    inds[1]                   = i1;
+    inds[2]                   = i2;
+    ctx->indCount += 3;
+
+    _check_index_cache_size(ctx);
+    LOG(VKVG_LOG_INFO_IBO, "Triangle IDX: %d %d %d (indCount=%d)\n", i0, i1, i2, ctx->indCount);
+}
+void _add_triangle_indices_unchecked(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1,
+                                     VKVG_IBO_INDEX_TYPE i2) {
+    VKVG_IBO_INDEX_TYPE *inds = &ctx->indexCache[ctx->indCount];
+    inds[0]                   = i0;
+    inds[1]                   = i1;
+    inds[2]                   = i2;
+    ctx->indCount += 3;
+
+    LOG(VKVG_LOG_INFO_IBO, "Triangle IDX: %d %d %d (indCount=%d)\n", i0, i1, i2, ctx->indCount);
+}
+void _vao_add_rectangle(VkvgContext ctx, float x, float y, float width, float height) {
+    Vertex              v[4]     = {{{x, y}, ctx->curColor, {0, 0, -1}},
+                                    {{x, y + height}, ctx->curColor, {0, 0, -1}},
+                                    {{x + width, y}, ctx->curColor, {0, 0, -1}},
+                                    {{x + width, y + height}, ctx->curColor, {0, 0, -1}}};
+    VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+    Vertex             *pVert    = &ctx->vertexCache[ctx->vertCount];
+    memcpy(pVert, v, 4 * sizeof(Vertex));
+    ctx->vertCount += 4;
+
+    _check_vertex_cache_size(ctx);
+
+    _add_tri_indices_for_rect(ctx, firstIdx);
+}
+// start render pass if not yet started or update push const if requested
+void _ensure_renderpass_is_started(VkvgContext ctx) {
+    LOG(VKVG_LOG_INFO, "_ensure_renderpass_is_started\n");
+    if (!ctx->cmdStarted)
+        _start_cmd_for_render_pass(ctx);
+    else if (ctx->pushCstDirty)
+        _update_push_constants(ctx);
+}
+void _create_cmd_buff(VkvgContext ctx) {
+    vkh_cmd_buffs_create((VkhDevice)ctx->dev, ctx->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 2, ctx->cmdBuffers);
 #if defined(DEBUG) && defined(ENABLE_VALIDATION)
-       vkh_device_set_object_name((VkhDevice)ctx->pSurf->dev, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)ctx->cmd, "vkvgCtxCmd");
+    vkh_device_set_object_name((VkhDevice)ctx->pSurf->dev, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                               (uint64_t)ctx->cmd, "vkvgCtxCmd");
 #endif
 }
-void _clear_attachment (VkvgContext ctx) {
-
-}
+void _clear_attachment(VkvgContext ctx) {}
 
-bool _wait_ctx_flush_end (VkvgContext ctx) {
-       LOG(VKVG_LOG_INFO, "CTX: _wait_flush_fence\n");
+bool _wait_ctx_flush_end(VkvgContext ctx) {
+    LOG(VKVG_LOG_INFO, "CTX: _wait_flush_fence\n");
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       if (vkh_timeline_wait ((VkhDevice)ctx->dev, ctx->pSurf->timeline, ctx->timelineStep) == VK_SUCCESS)
-               return true;
+    if (vkh_timeline_wait((VkhDevice)ctx->dev, ctx->pSurf->timeline, ctx->timelineStep) == VK_SUCCESS)
+        return true;
 #else
-       if (WaitForFences (ctx->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS)
-               return true;
+    if (WaitForFences(ctx->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS)
+        return true;
 #endif
-       LOG(VKVG_LOG_DEBUG, "CTX: _wait_flush_fence timeout\n");
-       ctx->status = VKVG_STATUS_TIMEOUT;
-       return false;
+    LOG(VKVG_LOG_DEBUG, "CTX: _wait_flush_fence timeout\n");
+    ctx->status = VKVG_STATUS_TIMEOUT;
+    return false;
 }
 
+bool _wait_and_submit_cmd(VkvgContext ctx) {
+    if (!ctx->cmdStarted) // current cmd buff is empty, be aware that wait is also canceled!!
+        return true;
 
-bool _wait_and_submit_cmd (VkvgContext ctx){
-       if (!ctx->cmdStarted)//current cmd buff is empty, be aware that wait is also canceled!!
-               return true;
-
-       LOG(VKVG_LOG_INFO, "CTX: _wait_and_submit_cmd\n");
+    LOG(VKVG_LOG_INFO, "CTX: _wait_and_submit_cmd\n");
 
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       VkvgSurface surf = ctx->pSurf;
-       VkvgDevice dev = surf->dev;
-       //vkh_timeline_wait ((VkhDevice)dev, surf->timeline, ct->timelineStep);
-       if (ctx->pattern && ctx->pattern->type == VKVG_PATTERN_TYPE_SURFACE) {
-               //add source surface timeline sync.
-               VkvgSurface source = (VkvgSurface)ctx->pattern->data;
-               LOCK_SURFACE(surf)
-               LOCK_SURFACE(source)
-               LOCK_DEVICE
-               vkh_cmd_submit_timelined2 (dev->gQueue, &ctx->cmd,
-                                                                 (VkSemaphore[2]){surf->timeline,source->timeline},
-                                                                 (uint64_t[2]){surf->timelineStep,source->timelineStep},
-                                                                 (uint64_t[2]){surf->timelineStep+1,source->timelineStep+1});
-               surf->timelineStep++;
-               source->timelineStep++;
-               ctx->timelineStep = surf->timelineStep;
-               UNLOCK_DEVICE
-               UNLOCK_SURFACE(source)
-               UNLOCK_SURFACE(surf)
-       } else {
-               LOCK_SURFACE(surf)
-               LOCK_DEVICE
-               vkh_cmd_submit_timelined (dev->gQueue, &ctx->cmd, surf->timeline, surf->timelineStep, surf->timelineStep+1);
-               surf->timelineStep++;
-               ctx->timelineStep = surf->timelineStep;
-               UNLOCK_DEVICE
-               UNLOCK_SURFACE(surf)
-       }
+    VkvgSurface surf = ctx->pSurf;
+    VkvgDevice  dev  = surf->dev;
+    // vkh_timeline_wait ((VkhDevice)dev, surf->timeline, ct->timelineStep);
+    if (ctx->pattern && ctx->pattern->type == VKVG_PATTERN_TYPE_SURFACE) {
+        // add source surface timeline sync.
+        VkvgSurface source = (VkvgSurface)ctx->pattern->data;
+        LOCK_SURFACE(surf)
+        LOCK_SURFACE(source)
+        LOCK_DEVICE
+        vkh_cmd_submit_timelined2(dev->gQueue, &ctx->cmd, (VkSemaphore[2]){surf->timeline, source->timeline},
+                                  (uint64_t[2]){surf->timelineStep, source->timelineStep},
+                                  (uint64_t[2]){surf->timelineStep + 1, source->timelineStep + 1});
+        surf->timelineStep++;
+        source->timelineStep++;
+        ctx->timelineStep = surf->timelineStep;
+        UNLOCK_DEVICE
+        UNLOCK_SURFACE(source)
+        UNLOCK_SURFACE(surf)
+    } else {
+        LOCK_SURFACE(surf)
+        LOCK_DEVICE
+        vkh_cmd_submit_timelined(dev->gQueue, &ctx->cmd, surf->timeline, surf->timelineStep, surf->timelineStep + 1);
+        surf->timelineStep++;
+        ctx->timelineStep = surf->timelineStep;
+        UNLOCK_DEVICE
+        UNLOCK_SURFACE(surf)
+    }
 #else
 
-       if (!_wait_ctx_flush_end (ctx))
-               return false;
-       ResetFences (ctx->dev->vkDev, 1, &ctx->flushFence);
-       _device_submit_cmd (ctx->dev, &ctx->cmd, ctx->flushFence);
+    if (!_wait_ctx_flush_end(ctx))
+        return false;
+    ResetFences(ctx->dev->vkDev, 1, &ctx->flushFence);
+    _device_submit_cmd(ctx->dev, &ctx->cmd, ctx->flushFence);
 #endif
 
-       if (ctx->cmd == ctx->cmdBuffers[0])
-               ctx->cmd = ctx->cmdBuffers[1];
-       else
-               ctx->cmd = ctx->cmdBuffers[0];
-
-       ResetCommandBuffer (ctx->cmd, 0);
-       ctx->cmdStarted = false;
-       return true;
-}
-/*void _explicit_ms_resolve (VkvgContext ctx){//should init cmd before calling this (unused, using automatic resolve by renderpass)
-       vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-       vkh_image_set_layout (ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-
-       VkImageResolve re = {
-               .extent = {ctx->pSurf->width, ctx->pSurf->height,1},
-               .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1},
-               .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}
-       };
-
-       vkCmdResolveImage(ctx->cmd,
-                                         vkh_image_get_vkimage (ctx->pSurf->imgMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                         vkh_image_get_vkimage (ctx->pSurf->img) ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                         1,&re);
-       vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ,
-                                                 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
+    if (ctx->cmd == ctx->cmdBuffers[0])
+        ctx->cmd = ctx->cmdBuffers[1];
+    else
+        ctx->cmd = ctx->cmdBuffers[0];
+
+    ResetCommandBuffer(ctx->cmd, 0);
+    ctx->cmdStarted = false;
+    return true;
+}
+/*void _explicit_ms_resolve (VkvgContext ctx){//should init cmd before calling this (unused, using automatic resolve by
+renderpass) vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT,
+                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+    vkh_image_set_layout (ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT,
+                          VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+    VkImageResolve re = {
+        .extent = {ctx->pSurf->width, ctx->pSurf->height,1},
+        .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1},
+        .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}
+    };
+
+    vkCmdResolveImage(ctx->cmd,
+                      vkh_image_get_vkimage (ctx->pSurf->imgMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                      vkh_image_get_vkimage (ctx->pSurf->img) ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                      1,&re);
+    vkh_image_set_layout (ctx->cmd, ctx->pSurf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT,
+                          VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ,
+                          VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
 }*/
 
-//pre flush vertices because of vbo or ibo too small, all vertices except last draw call are flushed
-//this function expects a vertex offset > 0
-void _flush_vertices_caches_until_vertex_base (VkvgContext ctx) {
-       _wait_ctx_flush_end (ctx);
-
-       memcpy(vkh_buffer_get_mapped_pointer(&ctx->vertices), ctx->vertexCache, ctx->curVertOffset * sizeof (Vertex));
-       memcpy(vkh_buffer_get_mapped_pointer(&ctx->indices), ctx->indexCache, ctx->curIndStart * sizeof (VKVG_IBO_INDEX_TYPE));
-
-       //copy remaining vertices and indices to caches starts
-       //this could be optimized at the cost of additional offsets.
-       ctx->vertCount -= ctx->curVertOffset;
-       ctx->indCount -= ctx->curIndStart;
-       memcpy(ctx->vertexCache, &ctx->vertexCache[ctx->curVertOffset], ctx->vertCount * sizeof (Vertex));
-       memcpy(ctx->indexCache, &ctx->indexCache[ctx->curIndStart], ctx->indCount * sizeof (VKVG_IBO_INDEX_TYPE));
-
-       ctx->curVertOffset = 0;
-       ctx->curIndStart = 0;
-}
-//copy vertex and index caches to the vbo and ibo vkbuffers used by gpu for drawing
-//current running cmd has to be completed to free usage of those
-void _flush_vertices_caches (VkvgContext ctx) {
-       if (!_wait_ctx_flush_end (ctx))
-               return;
-
-       memcpy(vkh_buffer_get_mapped_pointer(&ctx->vertices), ctx->vertexCache, ctx->vertCount * sizeof (Vertex));
-       memcpy(vkh_buffer_get_mapped_pointer(&ctx->indices), ctx->indexCache, ctx->indCount * sizeof (VKVG_IBO_INDEX_TYPE));
-
-       ctx->vertCount = ctx->indCount = ctx->curIndStart = ctx->curVertOffset = 0;
-}
-//this func expect cmdStarted to be true
-void _end_render_pass (VkvgContext ctx) {
-       LOG(VKVG_LOG_INFO, "END RENDER PASS: ctx = %p;\n", ctx);
-       CmdEndRenderPass          (ctx->cmd);
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_cmd_label_end (ctx->cmd);
+// pre flush vertices because of vbo or ibo too small, all vertices except last draw call are flushed
+// this function expects a vertex offset > 0
+void _flush_vertices_caches_until_vertex_base(VkvgContext ctx) {
+    _wait_ctx_flush_end(ctx);
+
+    memcpy(vkh_buffer_get_mapped_pointer(&ctx->vertices), ctx->vertexCache, ctx->curVertOffset * sizeof(Vertex));
+    memcpy(vkh_buffer_get_mapped_pointer(&ctx->indices), ctx->indexCache,
+           ctx->curIndStart * sizeof(VKVG_IBO_INDEX_TYPE));
+
+    // copy remaining vertices and indices to caches starts
+    // this could be optimized at the cost of additional offsets.
+    ctx->vertCount -= ctx->curVertOffset;
+    ctx->indCount -= ctx->curIndStart;
+    memcpy(ctx->vertexCache, &ctx->vertexCache[ctx->curVertOffset], ctx->vertCount * sizeof(Vertex));
+    memcpy(ctx->indexCache, &ctx->indexCache[ctx->curIndStart], ctx->indCount * sizeof(VKVG_IBO_INDEX_TYPE));
+
+    ctx->curVertOffset = 0;
+    ctx->curIndStart   = 0;
+}
+// copy vertex and index caches to the vbo and ibo vkbuffers used by gpu for drawing
+// current running cmd has to be completed to free usage of those
+void _flush_vertices_caches(VkvgContext ctx) {
+    if (!_wait_ctx_flush_end(ctx))
+        return;
+
+    memcpy(vkh_buffer_get_mapped_pointer(&ctx->vertices), ctx->vertexCache, ctx->vertCount * sizeof(Vertex));
+    memcpy(vkh_buffer_get_mapped_pointer(&ctx->indices), ctx->indexCache, ctx->indCount * sizeof(VKVG_IBO_INDEX_TYPE));
+
+    ctx->vertCount = ctx->indCount = ctx->curIndStart = ctx->curVertOffset = 0;
+}
+// this func expect cmdStarted to be true
+void _end_render_pass(VkvgContext ctx) {
+    LOG(VKVG_LOG_INFO, "END RENDER PASS: ctx = %p;\n", ctx);
+    CmdEndRenderPass(ctx->cmd);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_cmd_label_end(ctx->cmd);
 #endif
-       ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass;
+    ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass;
 }
 
-void _check_vao_size (VkvgContext ctx) {
-       if (ctx->vertCount > ctx->sizeVBO || ctx->indCount > ctx->sizeIBO){
-               //vbo or ibo buffers too small
-               if (ctx->cmdStarted)
-                       //if cmd is started buffers, are already bound, so no resize is possible
-                       //instead we flush, and clear vbo and ibo caches
-                       _flush_cmd_until_vx_base (ctx);
-               if (ctx->vertCount > ctx->sizeVBO)              
-                       _resize_vbo(ctx, ctx->sizeVertices);
-               if (ctx->indCount > ctx->sizeIBO)
-                       _resize_ibo(ctx, ctx->sizeIndices);
-       }
+void _check_vao_size(VkvgContext ctx) {
+    if (ctx->vertCount > ctx->sizeVBO || ctx->indCount > ctx->sizeIBO) {
+        // vbo or ibo buffers too small
+        if (ctx->cmdStarted)
+            // if cmd is started buffers, are already bound, so no resize is possible
+            // instead we flush, and clear vbo and ibo caches
+            _flush_cmd_until_vx_base(ctx);
+        if (ctx->vertCount > ctx->sizeVBO)
+            _resize_vbo(ctx, ctx->sizeVertices);
+        if (ctx->indCount > ctx->sizeIBO)
+            _resize_ibo(ctx, ctx->sizeIndices);
+    }
 }
 
-//stroke and non-zero draw call for solid color flush
-void _emit_draw_cmd_undrawn_vertices (VkvgContext ctx){
-       if (ctx->indCount == ctx->curIndStart)
-               return;
+// stroke and non-zero draw call for solid color flush
+void _emit_draw_cmd_undrawn_vertices(VkvgContext ctx) {
+    if (ctx->indCount == ctx->curIndStart)
+        return;
 
-       _check_vao_size (ctx);
+    _check_vao_size(ctx);
 
-       _ensure_renderpass_is_started (ctx);
+    _ensure_renderpass_is_started(ctx);
 
 #ifdef VKVG_WIRED_DEBUG
-       if (vkvg_wired_debug&vkvg_wired_debug_mode_normal)
-               CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
-       if (vkvg_wired_debug&vkvg_wired_debug_mode_lines) {
-               CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLineList);
-               CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
-       }
-       if (vkvg_wired_debug&vkvg_wired_debug_mode_points) {
-               CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired);
-               CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
-       }
-       if (vkvg_wired_debug&vkvg_wired_debug_mode_both)
-               CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER);
+    if (vkvg_wired_debug & vkvg_wired_debug_mode_normal)
+        CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
+    if (vkvg_wired_debug & vkvg_wired_debug_mode_lines) {
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineLineList);
+        CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
+    }
+    if (vkvg_wired_debug & vkvg_wired_debug_mode_points) {
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired);
+        CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
+    }
+    if (vkvg_wired_debug & vkvg_wired_debug_mode_both)
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER);
 #else
-       CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
+    CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
 #endif
-       LOG(VKVG_LOG_INFO, "RECORD DRAW CMD: ctx = %p; vertices = %d; indices = %d (vxOff = %d idxStart = %d idxTot = %d )\n",
-               ctx, ctx->vertCount - ctx->curVertOffset,
-               ctx->indCount - ctx->curIndStart, ctx->curVertOffset, ctx->curIndStart, ctx->indCount);
-
-       ctx->curIndStart = ctx->indCount;
-       ctx->curVertOffset = ctx->vertCount;
-}
-//preflush vertices with drawcommand already emited
-void _flush_cmd_until_vx_base (VkvgContext ctx){
-       _end_render_pass (ctx);
-       if (ctx->curVertOffset > 0){
-               LOG(VKVG_LOG_INFO, "FLUSH UNTIL VX BASE CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount);
-               _flush_vertices_caches_until_vertex_base (ctx);
-       }
-       vkh_cmd_end (ctx->cmd);
-       _wait_and_submit_cmd (ctx);
-}
-void _flush_cmd_buff (VkvgContext ctx){
-       _emit_draw_cmd_undrawn_vertices (ctx);
-       if (!ctx->cmdStarted)
-               return;
-       _end_render_pass                (ctx);
-       LOG(VKVG_LOG_INFO, "FLUSH CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount);
-       _flush_vertices_caches  (ctx);
-       vkh_cmd_end                             (ctx->cmd);
-
-       _wait_and_submit_cmd    (ctx);
-}
-
-//bind correct draw pipeline depending on current OPERATOR
-void _bind_draw_pipeline (VkvgContext ctx) {
-       switch (ctx->curOperator) {
-       case VKVG_OPERATOR_OVER:
-               CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_OVER);
-               break;
-       case VKVG_OPERATOR_CLEAR:
-               CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_CLEAR);
-               break;
-       case VKVG_OPERATOR_DIFFERENCE:
-               CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_SUB);
-               break;
-       default:
-               CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_OVER);
-               break;
-       }
-}
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-const float DBG_LAB_COLOR_RP[4]                = {0,0,1,1};
-const float DBG_LAB_COLOR_FSQ[4]       = {1,0,0,1};
+    LOG(VKVG_LOG_INFO,
+        "RECORD DRAW CMD: ctx = %p; vertices = %d; indices = %d (vxOff = %d idxStart = %d idxTot = %d )\n", ctx,
+        ctx->vertCount - ctx->curVertOffset, ctx->indCount - ctx->curIndStart, ctx->curVertOffset, ctx->curIndStart,
+        ctx->indCount);
+
+    ctx->curIndStart   = ctx->indCount;
+    ctx->curVertOffset = ctx->vertCount;
+}
+// preflush vertices with drawcommand already emited
+void _flush_cmd_until_vx_base(VkvgContext ctx) {
+    _end_render_pass(ctx);
+    if (ctx->curVertOffset > 0) {
+        LOG(VKVG_LOG_INFO, "FLUSH UNTIL VX BASE CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount,
+            ctx->indCount);
+        _flush_vertices_caches_until_vertex_base(ctx);
+    }
+    vkh_cmd_end(ctx->cmd);
+    _wait_and_submit_cmd(ctx);
+}
+void _flush_cmd_buff(VkvgContext ctx) {
+    _emit_draw_cmd_undrawn_vertices(ctx);
+    if (!ctx->cmdStarted)
+        return;
+    _end_render_pass(ctx);
+    LOG(VKVG_LOG_INFO, "FLUSH CTX: ctx = %p; vertices = %d; indices = %d\n", ctx, ctx->vertCount, ctx->indCount);
+    _flush_vertices_caches(ctx);
+    vkh_cmd_end(ctx->cmd);
+
+    _wait_and_submit_cmd(ctx);
+}
+
+// bind correct draw pipeline depending on current OPERATOR
+void _bind_draw_pipeline(VkvgContext ctx) {
+    switch (ctx->curOperator) {
+    case VKVG_OPERATOR_OVER:
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_OVER);
+        break;
+    case VKVG_OPERATOR_CLEAR:
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_CLEAR);
+        break;
+    case VKVG_OPERATOR_DIFFERENCE:
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_SUB);
+        break;
+    default:
+        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_OVER);
+        break;
+    }
+}
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+const float DBG_LAB_COLOR_RP[4]  = {0, 0, 1, 1};
+const float DBG_LAB_COLOR_FSQ[4] = {1, 0, 0, 1};
 #endif
 
-void _start_cmd_for_render_pass (VkvgContext ctx) {
-       LOG(VKVG_LOG_INFO, "START RENDER PASS: ctx = %p\n", ctx);
-       vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-
-       if (ctx->pSurf->img->layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || ctx->dev->threadAware){
-               VkhImage imgMs = ctx->pSurf->imgMS;
-               if (imgMs != NULL)
-                       vkh_image_set_layout(ctx->cmd, imgMs, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                                VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
-
-               vkh_image_set_layout(ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
-               vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, ctx->dev->stencilAspectFlag,
-                                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                                                         VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
-       }
-
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_cmd_label_start(ctx->cmd, "ctx render pass", DBG_LAB_COLOR_RP);
+void _start_cmd_for_render_pass(VkvgContext ctx) {
+    LOG(VKVG_LOG_INFO, "START RENDER PASS: ctx = %p\n", ctx);
+    vkh_cmd_begin(ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+
+    if (ctx->pSurf->img->layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || ctx->dev->threadAware) {
+        VkhImage imgMs = ctx->pSurf->imgMS;
+        if (imgMs != NULL)
+            vkh_image_set_layout(ctx->cmd, imgMs, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+
+        vkh_image_set_layout(ctx->cmd, ctx->pSurf->img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+                             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+        vkh_image_set_layout(ctx->cmd, ctx->pSurf->stencil, ctx->dev->stencilAspectFlag,
+                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+                             VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+    }
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_cmd_label_start(ctx->cmd, "ctx render pass", DBG_LAB_COLOR_RP);
 #endif
 
-       CmdBeginRenderPass (ctx->cmd, &ctx->renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
-       VkViewport viewport = {0,0,(float)ctx->pSurf->width,(float)ctx->pSurf->height,0,1.f};
-       CmdSetViewport(ctx->cmd, 0, 1, &viewport);
-
-       CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds);
-
-       VkDescriptorSet dss[] = {ctx->dsFont, ctx->dsSrc,ctx->dsGrad};
-       CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout,
-                                                       0, 3, dss, 0, NULL);
-
-       VkDeviceSize offsets[1] = { 0 };
-       CmdBindVertexBuffers(ctx->cmd, 0, 1, &ctx->vertices.buffer, offsets);
-       CmdBindIndexBuffer(ctx->cmd, ctx->indices.buffer, 0, VKVG_VK_INDEX_TYPE);
-
-       _update_push_constants  (ctx);
-
-       _bind_draw_pipeline (ctx);
-       CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
-       ctx->cmdStarted = true;
-}
-//compute inverse mat used in shader when context matrix has changed
-//then trigger push constants command
-void _set_mat_inv_and_vkCmdPush (VkvgContext ctx) {
-       ctx->pushConsts.matInv = ctx->pushConsts.mat;
-       vkvg_matrix_invert (&ctx->pushConsts.matInv);
-       ctx->pushCstDirty = true;
-}
-void _update_push_constants (VkvgContext ctx) {
-       CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout,
-                                          VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants),&ctx->pushConsts);
-       ctx->pushCstDirty = false;
-}
-void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) {
-       VkvgPattern lastPat = ctx->pattern;
-       ctx->pattern = pat;
-
-       uint32_t newPatternType = VKVG_PATTERN_TYPE_SOLID;
-
-       LOG(VKVG_LOG_INFO, "CTX: _update_cur_pattern: %p -> %p\n", lastPat, pat);
-
-       if (pat == NULL) {//solid color
-               if (lastPat == NULL)//solid
-                       return;//solid to solid transition, no extra action requested
-       }else
-               newPatternType = pat->type;
-
-       switch (newPatternType)  {
-       case VKVG_PATTERN_TYPE_SOLID:
-               _flush_cmd_buff                         (ctx);
-               if (!_wait_ctx_flush_end (ctx))
-                       return;
-               if (lastPat->type == VKVG_PATTERN_TYPE_SURFACE)//unbind current source surface by replacing it with empty texture
-                       _update_descriptor_set          (ctx, ctx->dev->emptyImg, ctx->dsSrc);
-               break;
-       case VKVG_PATTERN_TYPE_SURFACE:
-       {
-               _emit_draw_cmd_undrawn_vertices(ctx);
-
-               VkvgSurface surf = (VkvgSurface)pat->data;
-
-               //flush ctx in two steps to add the src transitioning in the cmd buff
-               if (ctx->cmdStarted){//transition of img without appropriate dependencies in subpass must be done outside renderpass.
-                       _end_render_pass (ctx);
-                       _flush_vertices_caches (ctx);
-               } else {
-                       vkh_cmd_begin (ctx->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-                       ctx->cmdStarted = true;
-               }
-
-               //transition source surface for sampling
-               vkh_image_set_layout (ctx->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
-                                                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
-
-               vkh_cmd_end                             (ctx->cmd);
-               _wait_and_submit_cmd    (ctx);
-               if (!_wait_ctx_flush_end (ctx))
-                       return;
-
-               VkSamplerAddressMode addrMode = 0;
-               VkFilter filter = VK_FILTER_NEAREST;
-               switch (pat->extend) {
-               case VKVG_EXTEND_NONE:
-                       addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
-                       break;
-               case VKVG_EXTEND_PAD:
-                       addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
-                       break;
-               case VKVG_EXTEND_REPEAT:
-                       addrMode = VK_SAMPLER_ADDRESS_MODE_REPEAT;
-                       break;
-               case VKVG_EXTEND_REFLECT:
-                       addrMode = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
-                       break;
-               }
-               switch (pat->filter) {
-               case VKVG_FILTER_BILINEAR:
-               case VKVG_FILTER_BEST:
-                       filter = VK_FILTER_LINEAR;
-                       break;
-               default:
-                       filter = VK_FILTER_NEAREST;
-                       break;
-               }
-               vkh_image_create_sampler (surf->img, filter, filter,
-                                                                       VK_SAMPLER_MIPMAP_MODE_NEAREST, addrMode);
-
-               _update_descriptor_set (ctx, surf->img, ctx->dsSrc);
-
-               if (pat->hasMatrix) {
-
-               }
-
-               ctx->pushConsts.source.width    = (float)surf->width;
-               ctx->pushConsts.source.height   = (float)surf->height;
-               break;
-       }
-       case VKVG_PATTERN_TYPE_LINEAR:
-       case VKVG_PATTERN_TYPE_RADIAL:
-               _flush_cmd_buff (ctx);
-               if (!_wait_ctx_flush_end (ctx))
-                       return;
-
-               if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE)
-                       _update_descriptor_set (ctx, ctx->dev->emptyImg, ctx->dsSrc);
-
-               vec4 bounds = {{(float)ctx->pSurf->width}, {(float)ctx->pSurf->height}, {0}, {0}};//store img bounds in unused source field
-               ctx->pushConsts.source = bounds;
-
-               //transform control point with current ctx matrix
-               vkvg_gradient_t grad = *(vkvg_gradient_t*)pat->data;
-
-               if (grad.count < 2) {
-                       ctx->status = VKVG_STATUS_PATTERN_INVALID_GRADIENT;
-                       return;
-               }
-               vkvg_matrix_t mat;
-               if (pat->hasMatrix) {
-                       vkvg_pattern_get_matrix (pat, &mat);
-                       if (vkvg_matrix_invert (&mat) != VKVG_STATUS_SUCCESS)
-                               mat = VKVG_IDENTITY_MATRIX;
-               }
-
-               if (pat->hasMatrix)
-                       vkvg_matrix_transform_point (&mat, &grad.cp[0].x, &grad.cp[0].y);
-               vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y);
-               if (pat->type == VKVG_PATTERN_TYPE_LINEAR) {
-                       if (pat->hasMatrix)
-                               vkvg_matrix_transform_point (&mat, &grad.cp[0].z, &grad.cp[0].w);
-                       vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w);
-               } else {
-                       if (pat->hasMatrix)
-                               vkvg_matrix_transform_point (&mat, &grad.cp[1].x, &grad.cp[1].y);
-                       vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y);
-
-                       //radii
-                       if (pat->hasMatrix) {
-                               vkvg_matrix_transform_distance (&mat, &grad.cp[0].z, &grad.cp[0].w);
-                               vkvg_matrix_transform_distance (&mat, &grad.cp[1].z, &grad.cp[0].w);
-                       }
-                       vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w);
-                       vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &grad.cp[1].z, &grad.cp[0].w);
-               }
-
-               memcpy (vkh_buffer_get_mapped_pointer(&ctx->uboGrad) , &grad, sizeof(vkvg_gradient_t));
-               vkh_buffer_flush(&ctx->uboGrad);
-               break;
-       }
-       ctx->pushConsts.fsq_patternType = (ctx->pushConsts.fsq_patternType & FULLSCREEN_BIT) + newPatternType;
-       ctx->pushCstDirty = true;
-       if (lastPat)
-               vkvg_pattern_destroy (lastPat);
-}
-void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds){
-       VkDescriptorImageInfo descSrcTex = vkh_image_get_descriptor (img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-       VkWriteDescriptorSet writeDescriptorSet = {
-                       .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
-                       .dstSet = ds,
-                       .dstBinding = 0,
-                       .descriptorCount = 1,
-                       .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-                       .pImageInfo = &descSrcTex
-       };
-       vkUpdateDescriptorSets(ctx->dev->vkDev, 1, &writeDescriptorSet, 0, NULL);
-}
-
-void _update_gradient_desc_set (VkvgContext ctx){
-       VkDescriptorBufferInfo dbi = {ctx->uboGrad.buffer, 0, VK_WHOLE_SIZE};
-       VkWriteDescriptorSet writeDescriptorSet = {
-                       .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
-                       .dstSet = ctx->dsGrad,
-                       .dstBinding = 0,
-                       .descriptorCount = 1,
-                       .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
-                       .pBufferInfo = &dbi
-       };
-       vkUpdateDescriptorSets(ctx->dev->vkDev, 1, &writeDescriptorSet, 0, NULL);
+    CmdBeginRenderPass(ctx->cmd, &ctx->renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+    VkViewport viewport = {0, 0, (float)ctx->pSurf->width, (float)ctx->pSurf->height, 0, 1.f};
+    CmdSetViewport(ctx->cmd, 0, 1, &viewport);
+
+    CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds);
+
+    VkDescriptorSet dss[] = {ctx->dsFont, ctx->dsSrc, ctx->dsGrad};
+    CmdBindDescriptorSets(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineLayout, 0, 3, dss, 0, NULL);
+
+    VkDeviceSize offsets[1] = {0};
+    CmdBindVertexBuffers(ctx->cmd, 0, 1, &ctx->vertices.buffer, offsets);
+    CmdBindIndexBuffer(ctx->cmd, ctx->indices.buffer, 0, VKVG_VK_INDEX_TYPE);
+
+    _update_push_constants(ctx);
+
+    _bind_draw_pipeline(ctx);
+    CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT);
+    ctx->cmdStarted = true;
+}
+// compute inverse mat used in shader when context matrix has changed
+// then trigger push constants command
+void _set_mat_inv_and_vkCmdPush(VkvgContext ctx) {
+    ctx->pushConsts.matInv = ctx->pushConsts.mat;
+    vkvg_matrix_invert(&ctx->pushConsts.matInv);
+    ctx->pushCstDirty = true;
+}
+void _update_push_constants(VkvgContext ctx) {
+    CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants),
+                     &ctx->pushConsts);
+    ctx->pushCstDirty = false;
+}
+void _update_cur_pattern(VkvgContext ctx, VkvgPattern pat) {
+    VkvgPattern lastPat = ctx->pattern;
+    ctx->pattern        = pat;
+
+    uint32_t newPatternType = VKVG_PATTERN_TYPE_SOLID;
+
+    LOG(VKVG_LOG_INFO, "CTX: _update_cur_pattern: %p -> %p\n", lastPat, pat);
+
+    if (pat == NULL) {       // solid color
+        if (lastPat == NULL) // solid
+            return;          // solid to solid transition, no extra action requested
+    } else
+        newPatternType = pat->type;
+
+    switch (newPatternType) {
+    case VKVG_PATTERN_TYPE_SOLID:
+        _flush_cmd_buff(ctx);
+        if (!_wait_ctx_flush_end(ctx))
+            return;
+        if (lastPat->type ==
+            VKVG_PATTERN_TYPE_SURFACE) // unbind current source surface by replacing it with empty texture
+            _update_descriptor_set(ctx, ctx->dev->emptyImg, ctx->dsSrc);
+        break;
+    case VKVG_PATTERN_TYPE_SURFACE: {
+        _emit_draw_cmd_undrawn_vertices(ctx);
+
+        VkvgSurface surf = (VkvgSurface)pat->data;
+
+        // flush ctx in two steps to add the src transitioning in the cmd buff
+        if (ctx->cmdStarted) { // transition of img without appropriate dependencies in subpass must be done outside
+                               // renderpass.
+            _end_render_pass(ctx);
+            _flush_vertices_caches(ctx);
+        } else {
+            vkh_cmd_begin(ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+            ctx->cmdStarted = true;
+        }
+
+        // transition source surface for sampling
+        vkh_image_set_layout(ctx->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                             VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
+
+        vkh_cmd_end(ctx->cmd);
+        _wait_and_submit_cmd(ctx);
+        if (!_wait_ctx_flush_end(ctx))
+            return;
+
+        VkSamplerAddressMode addrMode = 0;
+        VkFilter             filter   = VK_FILTER_NEAREST;
+        switch (pat->extend) {
+        case VKVG_EXTEND_NONE:
+            addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
+            break;
+        case VKVG_EXTEND_PAD:
+            addrMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+            break;
+        case VKVG_EXTEND_REPEAT:
+            addrMode = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+            break;
+        case VKVG_EXTEND_REFLECT:
+            addrMode = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
+            break;
+        }
+        switch (pat->filter) {
+        case VKVG_FILTER_BILINEAR:
+        case VKVG_FILTER_BEST:
+            filter = VK_FILTER_LINEAR;
+            break;
+        default:
+            filter = VK_FILTER_NEAREST;
+            break;
+        }
+        vkh_image_create_sampler(surf->img, filter, filter, VK_SAMPLER_MIPMAP_MODE_NEAREST, addrMode);
+
+        _update_descriptor_set(ctx, surf->img, ctx->dsSrc);
+
+        if (pat->hasMatrix) {
+        }
+
+        ctx->pushConsts.source.width  = (float)surf->width;
+        ctx->pushConsts.source.height = (float)surf->height;
+        break;
+    }
+    case VKVG_PATTERN_TYPE_LINEAR:
+    case VKVG_PATTERN_TYPE_RADIAL:
+        _flush_cmd_buff(ctx);
+        if (!_wait_ctx_flush_end(ctx))
+            return;
+
+        if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE)
+            _update_descriptor_set(ctx, ctx->dev->emptyImg, ctx->dsSrc);
+
+        vec4 bounds            = {{(float)ctx->pSurf->width},
+                                  {(float)ctx->pSurf->height},
+                                  {0},
+                                  {0}}; // store img bounds in unused source field
+        ctx->pushConsts.source = bounds;
+
+        // transform control point with current ctx matrix
+        vkvg_gradient_t grad = *(vkvg_gradient_t *)pat->data;
+
+        if (grad.count < 2) {
+            ctx->status = VKVG_STATUS_PATTERN_INVALID_GRADIENT;
+            return;
+        }
+        vkvg_matrix_t mat;
+        if (pat->hasMatrix) {
+            vkvg_pattern_get_matrix(pat, &mat);
+            if (vkvg_matrix_invert(&mat) != VKVG_STATUS_SUCCESS)
+                mat = VKVG_IDENTITY_MATRIX;
+        }
+
+        if (pat->hasMatrix)
+            vkvg_matrix_transform_point(&mat, &grad.cp[0].x, &grad.cp[0].y);
+        vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y);
+        if (pat->type == VKVG_PATTERN_TYPE_LINEAR) {
+            if (pat->hasMatrix)
+                vkvg_matrix_transform_point(&mat, &grad.cp[0].z, &grad.cp[0].w);
+            vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w);
+        } else {
+            if (pat->hasMatrix)
+                vkvg_matrix_transform_point(&mat, &grad.cp[1].x, &grad.cp[1].y);
+            vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y);
+
+            // radii
+            if (pat->hasMatrix) {
+                vkvg_matrix_transform_distance(&mat, &grad.cp[0].z, &grad.cp[0].w);
+                vkvg_matrix_transform_distance(&mat, &grad.cp[1].z, &grad.cp[0].w);
+            }
+            vkvg_matrix_transform_distance(&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w);
+            vkvg_matrix_transform_distance(&ctx->pushConsts.mat, &grad.cp[1].z, &grad.cp[0].w);
+        }
+
+        memcpy(vkh_buffer_get_mapped_pointer(&ctx->uboGrad), &grad, sizeof(vkvg_gradient_t));
+        vkh_buffer_flush(&ctx->uboGrad);
+        break;
+    }
+    ctx->pushConsts.fsq_patternType = (ctx->pushConsts.fsq_patternType & FULLSCREEN_BIT) + newPatternType;
+    ctx->pushCstDirty               = true;
+    if (lastPat)
+        vkvg_pattern_destroy(lastPat);
+}
+void _update_descriptor_set(VkvgContext ctx, VkhImage img, VkDescriptorSet ds) {
+    VkDescriptorImageInfo descSrcTex         = vkh_image_get_descriptor(img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+    VkWriteDescriptorSet  writeDescriptorSet = {.sType           = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+                                                .dstSet          = ds,
+                                                .dstBinding      = 0,
+                                                .descriptorCount = 1,
+                                                .descriptorType  = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+                                                .pImageInfo      = &descSrcTex};
+    vkUpdateDescriptorSets(ctx->dev->vkDev, 1, &writeDescriptorSet, 0, NULL);
+}
+
+void _update_gradient_desc_set(VkvgContext ctx) {
+    VkDescriptorBufferInfo dbi                = {ctx->uboGrad.buffer, 0, VK_WHOLE_SIZE};
+    VkWriteDescriptorSet   writeDescriptorSet = {.sType           = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+                                                 .dstSet          = ctx->dsGrad,
+                                                 .dstBinding      = 0,
+                                                 .descriptorCount = 1,
+                                                 .descriptorType  = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+                                                 .pBufferInfo     = &dbi};
+    vkUpdateDescriptorSets(ctx->dev->vkDev, 1, &writeDescriptorSet, 0, NULL);
 }
 /*
  * Reset currently bound descriptor which image could be destroyed
  */
 /*void _reset_src_descriptor_set (VkvgContext ctx){
-       VkvgDevice dev = ctx->pSurf->dev;
-       //VkDescriptorSet dss[] = {ctx->dsSrc};
-       vkFreeDescriptorSets    (dev->vkDev, ctx->descriptorPool, 1, &ctx->dsSrc);
-
-       VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
-                                                                                                                         .descriptorPool = ctx->descriptorPool,
-                                                                                                                         .descriptorSetCount = 1,
-                                                                                                                         .pSetLayouts = &dev->dslSrc };
-       VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsSrc));
+    VkvgDevice dev = ctx->pSurf->dev;
+    //VkDescriptorSet dss[] = {ctx->dsSrc};
+    vkFreeDescriptorSets       (dev->vkDev, ctx->descriptorPool, 1, &ctx->dsSrc);
+
+    VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+                                                              .descriptorPool = ctx->descriptorPool,
+                                                              .descriptorSetCount = 1,
+                                                              .pSetLayouts = &dev->dslSrc };
+    VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsSrc));
 }*/
 
-void _createDescriptorPool (VkvgContext ctx) {
-       VkvgDevice dev = ctx->dev;
-       const VkDescriptorPoolSize descriptorPoolSize[] = {
-               {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2 },
-               {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1 }
-       };
-       VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
-                                                                                                                       .maxSets = 3,
-                                                                                                                       .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
-                                                                                                                       .poolSizeCount = 2,
-                                                                                                                       .pPoolSizes = descriptorPoolSize };
-       VK_CHECK_RESULT(vkCreateDescriptorPool (dev->vkDev, &descriptorPoolCreateInfo, NULL, &ctx->descriptorPool));
-}
-void _init_descriptor_sets (VkvgContext ctx){
-       VkvgDevice dev = ctx->dev;
-       VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
-                                                                                                                         .descriptorPool = ctx->descriptorPool,
-                                                                                                                         .descriptorSetCount = 1,
-                                                                                                                         .pSetLayouts = &dev->dslFont
-                                                                                                                       };
-       VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsFont));
-       descriptorSetAllocateInfo.pSetLayouts = &dev->dslSrc;
-       VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsSrc));
-       descriptorSetAllocateInfo.pSetLayouts = &dev->dslGrad;
-       VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsGrad));
-}
-void _release_context_ressources (VkvgContext ctx) {
-       VkDevice dev = ctx->dev->vkDev;
-       
+void _createDescriptorPool(VkvgContext ctx) {
+    VkvgDevice                 dev                      = ctx->dev;
+    const VkDescriptorPoolSize descriptorPoolSize[]     = {{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2},
+                                                           {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1}};
+    VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {.sType   = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+                                                           .maxSets = 3,
+                                                           .flags   = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
+                                                           .poolSizeCount = 2,
+                                                           .pPoolSizes    = descriptorPoolSize};
+    VK_CHECK_RESULT(vkCreateDescriptorPool(dev->vkDev, &descriptorPoolCreateInfo, NULL, &ctx->descriptorPool));
+}
+void _init_descriptor_sets(VkvgContext ctx) {
+    VkvgDevice                  dev                       = ctx->dev;
+    VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+                                                             .descriptorPool     = ctx->descriptorPool,
+                                                             .descriptorSetCount = 1,
+                                                             .pSetLayouts        = &dev->dslFont};
+    VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsFont));
+    descriptorSetAllocateInfo.pSetLayouts = &dev->dslSrc;
+    VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsSrc));
+    descriptorSetAllocateInfo.pSetLayouts = &dev->dslGrad;
+    VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsGrad));
+}
+void _release_context_ressources(VkvgContext ctx) {
+    VkDevice dev = ctx->dev->vkDev;
+
 #ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       vkDestroyFence (dev, ctx->flushFence, NULL);
+    vkDestroyFence(dev, ctx->flushFence, NULL);
 #endif
 
-       vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers);
-       vkDestroyCommandPool(dev, ctx->cmdPool, NULL);
-
-       VkDescriptorSet dss[] = {ctx->dsFont, ctx->dsSrc, ctx->dsGrad};
-       vkFreeDescriptorSets    (dev, ctx->descriptorPool, 3, dss);
-
-       vkDestroyDescriptorPool (dev, ctx->descriptorPool,NULL);
-
-       vkh_buffer_reset (&ctx->uboGrad);
-       vkh_buffer_reset (&ctx->indices);
-       vkh_buffer_reset (&ctx->vertices);
-
-       free(ctx->vertexCache);
-       free(ctx->indexCache);
-
-       vkh_image_destroy         (ctx->fontCacheImg);
-       //TODO:check this for source counter
-       //vkh_image_destroy       (ctx->source);
-
-       free(ctx->pathes);
-       free(ctx->points);
-
-       free(ctx);
-}
-//populate vertice buff for stroke
-bool _build_vb_step(VkvgContext ctx, stroke_context_t* str, bool isCurve){
-       Vertex v = {{0},ctx->curColor, {0,0,-1}};
-       vec2 p0 = ctx->points[str->cp];
-       vec2 v0 = vec2_sub(p0, ctx->points[str->iL]);
-       vec2 v1 = vec2_sub(ctx->points[str->iR], p0);
-       float length_v0 = vec2_length(v0);
-       float length_v1 = vec2_length(v1);
-       if (length_v0 < FLT_EPSILON || length_v1 < FLT_EPSILON) {
-               LOG(VKVG_LOG_STROKE, "vb_step discard, length<epsilon: l0:%f l1:%f\n", length_v0, length_v1);
-               return false;
-       }
-       vec2 v0n = vec2_div_s (v0, length_v0);
-       vec2 v1n = vec2_div_s (v1, length_v1);
-       float dot = vec2_dot (v0n, v1n);
-       float det = v0n.x * v1n.y - v0n.y * v1n.x;
-       if (EQUF(dot,1.0f)) {//colinear
-               LOG(VKVG_LOG_STROKE, "vb_step discard, dot==1\n");
-               return false;
-       }
-
-       if (EQUF(dot,-1.0f)) {//cusp (could draw line butt?)
-               vec2 vPerp = vec2_mult_s(vec2_perp (v0n), str->hw);
-
-               VKVG_IBO_INDEX_TYPE idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-
-               v.pos = vec2_add(p0, vPerp);
-               _add_vertex(ctx, v);
-               v.pos = vec2_sub(p0, vPerp);
-               _add_vertex(ctx, v);
-
-               _add_triangle_indices(ctx, idx, idx+1, idx+2);
-               _add_triangle_indices(ctx, idx, idx+2, idx+3);
-               LOG(VKVG_LOG_STROKE, "vb_step cusp, dot==-1\n");
-               return true;
-       }
-
-       vec2 bisec_n = vec2_norm(vec2_add(v0n,v1n));//bisec/bisec_perp are inverted names
-       float alpha = acosf(dot);
-
-       if (det<0)
-               alpha = -alpha;
-
-       float halfAlpha = alpha / 2.f;
-       float cosHalfAlpha = cosf(halfAlpha);
-       float lh = str->hw / cosHalfAlpha;
-       vec2 bisec_n_perp = vec2_perp(bisec_n);
-
-       //limit bisectrice length
-       float rlh = lh;//rlh is for inside pos tweeks
-       if (dot < 0.f)
-               rlh = fminf (rlh, fminf (length_v0, length_v1));
-       //---
-
-       vec2 bisec = vec2_mult_s (bisec_n_perp, rlh);
-
-       VKVG_IBO_INDEX_TYPE idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-
-       vec2 rlh_inside_pos, rlh_outside_pos;
-       if (rlh < lh) {
-               vec2 vnPerp;
-               if (length_v0 < length_v1)
-                       vnPerp = vec2_perp (v1n);
-               else
-                       vnPerp = vec2_perp (v0n);
-               vec2 vHwPerp = vec2_mult_s (vnPerp, str->hw);
-
-               double lbc = cosHalfAlpha * rlh;
-               if (det < 0.f) {
-                       rlh_inside_pos  = vec2_add (vec2_add (vec2_mult_s(vnPerp, -lbc), vec2_add(p0, bisec)), vHwPerp);
-                       rlh_outside_pos = vec2_sub (p0, vec2_mult_s (bisec_n_perp, lh));
-               } else {
-                       rlh_inside_pos  = vec2_sub (vec2_add (vec2_mult_s(vnPerp, lbc), vec2_sub(p0, bisec)), vHwPerp);
-                       rlh_outside_pos = vec2_add (p0, vec2_mult_s (bisec_n_perp, lh));
-               }
-       } else {
-               if (det < 0.0) {
-                       rlh_inside_pos  = vec2_add (p0, bisec);
-                       rlh_outside_pos = vec2_sub (p0, bisec);
-               } else {
-                       rlh_inside_pos  = vec2_sub (p0, bisec);
-                       rlh_outside_pos = vec2_add (p0, bisec);
-               }
-       }
-
-       vkvg_line_join_t join = ctx->lineJoin;
-
-       if (isCurve) {
-               if (dot < 0.8f)
-                       join = VKVG_LINE_JOIN_ROUND;
-               else
-                       join = VKVG_LINE_JOIN_MITER;
-       }
-
-       if (join == VKVG_LINE_JOIN_MITER){
-               if (lh > str->lhMax) {//miter limit
-                       double x = (lh - str->lhMax) * cosHalfAlpha;
-                       vec2 bisecPerp = vec2_mult_s (bisec_n, x);
-                       bisec = vec2_mult_s (bisec_n_perp, str->lhMax);
-                       if (det < 0) {
-                               v.pos = rlh_inside_pos;
-                               _add_vertex(ctx, v);
-
-                               vec2 p = vec2_sub(p0, bisec);
-
-                               v.pos = vec2_sub(p, bisecPerp);
-                               _add_vertex(ctx, v);
-                               v.pos = vec2_add(p, bisecPerp);
-                               _add_vertex(ctx, v);
-
-                               _add_triangle_indices(ctx, idx, idx+2, idx+1);
-                               _add_triangle_indices(ctx, idx+2, idx+4, idx);
-                               _add_triangle_indices(ctx, idx, idx+3, idx+4);
-                               return true;
-                       } else {
-                               vec2 p = vec2_add(p0, bisec);
-                               v.pos = vec2_sub(p, bisecPerp);
-                               _add_vertex(ctx, v);
-
-                               v.pos = rlh_inside_pos;
-                               _add_vertex(ctx, v);
-
-                               v.pos = vec2_add(p, bisecPerp);
-                               _add_vertex(ctx, v);
-
-                               _add_triangle_indices(ctx, idx, idx+2, idx+1);
-                               _add_triangle_indices(ctx, idx+2, idx+3, idx+1);
-                               _add_triangle_indices(ctx, idx+1, idx+3, idx+4);
-                               return false;
-                       }
-
-               } else {//normal miter
-                       if (det < 0) {
-                               v.pos = rlh_inside_pos;
-                               _add_vertex(ctx, v);
-                               v.pos = rlh_outside_pos;
-                               _add_vertex(ctx, v);
-                       } else {
-                               v.pos = rlh_outside_pos;
-                               _add_vertex(ctx, v);
-                               v.pos = rlh_inside_pos;
-                               _add_vertex(ctx, v);
-                       }
-
-                       _add_tri_indices_for_rect(ctx, idx);
-                       return false;
-               }
-       }else{
-               vec2 vp = vec2_perp(v0n);
-
-               if (det<0){
-                       if (dot < 0 && rlh < lh)
-                               v.pos = rlh_inside_pos;
-                       else
-                               v.pos = vec2_add (p0, bisec);
-                       _add_vertex(ctx, v);
-                       v.pos = vec2_sub (p0, vec2_mult_s (vp, str->hw));
-               }else{
-                       v.pos = vec2_add (p0, vec2_mult_s (vp, str->hw));
-                       _add_vertex(ctx, v);
-                       if (dot < 0 && rlh < lh)
-                               v.pos = rlh_inside_pos;
-                       else
-                               v.pos = vec2_sub (p0, bisec);
-               }
-               _add_vertex(ctx, v);
-
-               if (join == VKVG_LINE_JOIN_BEVEL){
-                       if (det<0){
-                               _add_triangle_indices(ctx, idx, idx+2, idx+1);
-                               _add_triangle_indices(ctx, idx+2, idx+4, idx+0);
-                               _add_triangle_indices(ctx, idx, idx+3, idx+4);
-                       }else{
-                               _add_triangle_indices(ctx, idx, idx+2, idx+1);
-                               _add_triangle_indices(ctx, idx+2, idx+3, idx+1);
-                               _add_triangle_indices(ctx, idx+1, idx+3, idx+4);
-                       }
-               }else if (join == VKVG_LINE_JOIN_ROUND){
-                       if (!str->arcStep)
-                               str->arcStep = _get_arc_step (ctx, str->hw);
-                       float a = acosf(vp.x);
-                       if (vp.y < 0)
-                               a = -a;
-
-                       if (det<0){
-                               a+=M_PIF;
-                               float a1 = a + alpha;
-                               a-=str->arcStep;
-                               while (a > a1){
-                                       _add_vertexf(ctx, cosf(a) * str->hw + p0.x, sinf(a) * str->hw + p0.y);
-                                       a-=str->arcStep;
-                               }
-                       }else{
-                               float a1 = a + alpha;
-                               a+=str->arcStep;
-                               while (a < a1){
-                                       _add_vertexf(ctx, cosf(a) * str->hw + p0.x, sinf(a) * str->hw + p0.y);
-                                       a+=str->arcStep;
-                               }
-                       }
-                       VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-                       _add_triangle_indices(ctx, idx, idx+2, idx+1);
-                       if (det < 0){
-                               for (VKVG_IBO_INDEX_TYPE p = idx+2; p < p0Idx; p++)
-                                       _add_triangle_indices(ctx, p, p+1, idx);
-                               _add_triangle_indices(ctx, p0Idx, p0Idx+2, idx);
-                               _add_triangle_indices(ctx, idx, p0Idx+1, p0Idx+2);
-                       }else{
-                               for (VKVG_IBO_INDEX_TYPE p = idx+2; p < p0Idx; p++)
-                                       _add_triangle_indices(ctx, p, p+1, idx+1);
-                               _add_triangle_indices(ctx, p0Idx, p0Idx+1, idx+1);
-                               _add_triangle_indices(ctx, idx+1, p0Idx+1, p0Idx+2);
-                       }
-
-               }
-
-               vp = vec2_mult_s (vec2_perp(v1n), str->hw);
-               if (det < 0)
-                       v.pos = vec2_sub (p0, vp);
-               else
-                       v.pos = vec2_add (p0, vp);
-               _add_vertex(ctx, v);
-       }
-
-/*
-#ifdef DEBUG
-
-       debugLinePoints[dlpCount] = p0;
-       debugLinePoints[dlpCount+1] = _v2add(p0, _vec2dToVec2(_v2Multd(v0n,10)));
-       dlpCount+=2;
-       debugLinePoints[dlpCount] = p0;
-       debugLinePoints[dlpCount+1] = _v2add(p0, _vec2dToVec2(_v2Multd(v1n,10)));
-       dlpCount+=2;
-       debugLinePoints[dlpCount] = p0;
-       debugLinePoints[dlpCount+1] = pR;
-       dlpCount+=2;
-#endif*/
-       /*if (reducedLH)
-               return -det;
-       else*/
-       return (det < 0);
-}
-
-void _draw_stoke_cap (VkvgContext ctx, stroke_context_t *str, vec2 p0, vec2 n, bool isStart) {
-       Vertex v = {{0},ctx->curColor,{0,0,-1}};
-
-       VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-
-       if (isStart){
-               vec2 vhw = vec2_mult_s (n, str->hw);
-
-               if (ctx->lineCap == VKVG_LINE_CAP_SQUARE)
-                       p0 = vec2_sub (p0, vhw);
-
-               vhw = vec2_perp (vhw);
-
-               if (ctx->lineCap == VKVG_LINE_CAP_ROUND){
-                       if (!str->arcStep)
-                               str->arcStep = _get_arc_step (ctx, str->hw);
-
-                       float a = acosf(n.x) + M_PIF_2;
-                       if (n.y < 0)
-                               a = M_PIF-a;
-                       float a1 = a + M_PIF;
-
-                       a += str->arcStep;
-                       while (a < a1){
-                               _add_vertexf (ctx, cosf(a) * str->hw + p0.x, sinf(a) * str->hw + p0.y);
-                               a += str->arcStep;
-                       }
-                       VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-                       for (VKVG_IBO_INDEX_TYPE p = firstIdx; p < p0Idx; p++)
-                               _add_triangle_indices (ctx, p0Idx+1, p, p+1);
-                       firstIdx = p0Idx;
-               }
-
-               v.pos = vec2_add (p0, vhw);
-               _add_vertex (ctx, v);
-               v.pos = vec2_sub (p0, vhw);
-               _add_vertex (ctx, v);
-
-               _add_tri_indices_for_rect (ctx, firstIdx);
-       }else{
-               vec2 vhw = vec2_mult_s (n, str->hw);
-
-               if (ctx->lineCap == VKVG_LINE_CAP_SQUARE)
-                       p0 = vec2_add (p0, vhw);
-
-               vhw = vec2_perp (vhw);
-
-               v.pos = vec2_add (p0, vhw);
-               _add_vertex (ctx, v);
-               v.pos = vec2_sub (p0, vhw);
-               _add_vertex (ctx, v);
-
-               firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-
-               if (ctx->lineCap == VKVG_LINE_CAP_ROUND){
-                       if (!str->arcStep)
-                               str->arcStep = _get_arc_step (ctx, str->hw);
-
-                       float a = acosf(n.x)+ M_PIF_2;
-                       if (n.y < 0)
-                               a = M_PIF-a;
-                       float a1 = a - M_PIF;
-
-                       a -= str->arcStep;
-                       while ( a > a1){
-                               _add_vertexf (ctx, cosf(a) * str->hw + p0.x, sinf(a) * str->hw + p0.y);
-                               a -= str->arcStep;
-                       }
-
-                       VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset - 1);
-                       for (VKVG_IBO_INDEX_TYPE p = firstIdx-1 ; p < p0Idx; p++)
-                               _add_triangle_indices (ctx, p+1, p, firstIdx-2);
-               }
-       }
-}
-float _draw_dashed_segment (VkvgContext ctx, stroke_context_t* str, dash_context_t* dc, bool isCurve) {
-       //vec2 pL = ctx->points[str->iL];
-       vec2 p = ctx->points[str->cp];
-       vec2 pR = ctx->points[str->iR];
-
-       if (!dc->dashOn)//we test in fact the next dash start, if dashOn = true => next segment is a void.
-               _build_vb_step (ctx, str, isCurve);
-
-       vec2 d = vec2_sub (pR, p);
-       dc->normal = vec2_norm (d);
-       float segmentLength = vec2_length(d);
-
-       while (dc->curDashOffset < segmentLength){
-               vec2 p0 = vec2_add (p, vec2_mult_s(dc->normal, dc->curDashOffset));
-
-               _draw_stoke_cap (ctx, str, p0, dc->normal, dc->dashOn);
-               dc->dashOn ^= true;
-               dc->curDashOffset += ctx->dashes[dc->curDash];
-               if (++dc->curDash == ctx->dashCount)
-                       dc->curDash = 0;
-       }
-       dc->curDashOffset -= segmentLength;
-       dc->curDashOffset = fmodf(dc->curDashOffset, dc->totDashLength);
-       return segmentLength;
-}
-void _draw_segment (VkvgContext ctx, stroke_context_t* str, dash_context_t* dc, bool isCurve) {
-       str->iR = str->cp + 1;
-       if (ctx->dashCount > 0)
-               _draw_dashed_segment(ctx, str, dc, isCurve);
-       else
-               _build_vb_step (ctx, str, isCurve);
-       str->iL = str->cp++;
-       if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3) {
-               Vertex v0 = ctx->vertexCache[ctx->curVertOffset + str->firstIdx];
-               Vertex v1 = ctx->vertexCache[ctx->curVertOffset + str->firstIdx + 1];
-               _emit_draw_cmd_undrawn_vertices(ctx);
-               //repeat first 2 vertices for closed pathes
-               str->firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-               _add_vertex(ctx, v0);
-               _add_vertex(ctx, v1);
-               ctx->curVertOffset = ctx->vertCount;//prevent redrawing them at the start of the batch
-       }
+    vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers);
+    vkDestroyCommandPool(dev, ctx->cmdPool, NULL);
+
+    VkDescriptorSet dss[] = {ctx->dsFont, ctx->dsSrc, ctx->dsGrad};
+    vkFreeDescriptorSets(dev, ctx->descriptorPool, 3, dss);
+
+    vkDestroyDescriptorPool(dev, ctx->descriptorPool, NULL);
+
+    vkh_buffer_reset(&ctx->uboGrad);
+    vkh_buffer_reset(&ctx->indices);
+    vkh_buffer_reset(&ctx->vertices);
+
+    free(ctx->vertexCache);
+    free(ctx->indexCache);
+
+    vkh_image_destroy(ctx->fontCacheImg);
+    // TODO:check this for source counter
+    // vkh_image_destroy         (ctx->source);
+
+    free(ctx->pathes);
+    free(ctx->points);
+
+    free(ctx);
+}
+// populate vertice buff for stroke
+bool _build_vb_step(VkvgContext ctx, stroke_context_t *str, bool isCurve) {
+    Vertex v         = {{0}, ctx->curColor, {0, 0, -1}};
+    vec2   p0        = ctx->points[str->cp];
+    vec2   v0        = vec2_sub(p0, ctx->points[str->iL]);
+    vec2   v1        = vec2_sub(ctx->points[str->iR], p0);
+    float  length_v0 = vec2_length(v0);
+    float  length_v1 = vec2_length(v1);
+    if (length_v0 < FLT_EPSILON || length_v1 < FLT_EPSILON) {
+        LOG(VKVG_LOG_STROKE, "vb_step discard, length<epsilon: l0:%f l1:%f\n", length_v0, length_v1);
+        return false;
+    }
+    vec2  v0n = vec2_div_s(v0, length_v0);
+    vec2  v1n = vec2_div_s(v1, length_v1);
+    float dot = vec2_dot(v0n, v1n);
+    float det = v0n.x * v1n.y - v0n.y * v1n.x;
+    if (EQUF(dot, 1.0f)) { // colinear
+        LOG(VKVG_LOG_STROKE, "vb_step discard, dot==1\n");
+        return false;
+    }
+
+    if (EQUF(dot, -1.0f)) { // cusp (could draw line butt?)
+        vec2 vPerp = vec2_mult_s(vec2_perp(v0n), str->hw);
+
+        VKVG_IBO_INDEX_TYPE idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+
+        v.pos = vec2_add(p0, vPerp);
+        _add_vertex(ctx, v);
+        v.pos = vec2_sub(p0, vPerp);
+        _add_vertex(ctx, v);
+
+        _add_triangle_indices(ctx, idx, idx + 1, idx + 2);
+        _add_triangle_indices(ctx, idx, idx + 2, idx + 3);
+        LOG(VKVG_LOG_STROKE, "vb_step cusp, dot==-1\n");
+        return true;
+    }
+
+    vec2  bisec_n = vec2_norm(vec2_add(v0n, v1n)); // bisec/bisec_perp are inverted names
+    float alpha   = acosf(dot);
+
+    if (det < 0)
+        alpha = -alpha;
+
+    float halfAlpha    = alpha / 2.f;
+    float cosHalfAlpha = cosf(halfAlpha);
+    float lh           = str->hw / cosHalfAlpha;
+    vec2  bisec_n_perp = vec2_perp(bisec_n);
+
+    // limit bisectrice length
+    float rlh = lh; // rlh is for inside pos tweeks
+    if (dot < 0.f)
+        rlh = fminf(rlh, fminf(length_v0, length_v1));
+    //---
+
+    vec2 bisec = vec2_mult_s(bisec_n_perp, rlh);
+
+    VKVG_IBO_INDEX_TYPE idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+
+    vec2 rlh_inside_pos, rlh_outside_pos;
+    if (rlh < lh) {
+        vec2 vnPerp;
+        if (length_v0 < length_v1)
+            vnPerp = vec2_perp(v1n);
+        else
+            vnPerp = vec2_perp(v0n);
+        vec2 vHwPerp = vec2_mult_s(vnPerp, str->hw);
+
+        double lbc = cosHalfAlpha * rlh;
+        if (det < 0.f) {
+            rlh_inside_pos  = vec2_add(vec2_add(vec2_mult_s(vnPerp, -lbc), vec2_add(p0, bisec)), vHwPerp);
+            rlh_outside_pos = vec2_sub(p0, vec2_mult_s(bisec_n_perp, lh));
+        } else {
+            rlh_inside_pos  = vec2_sub(vec2_add(vec2_mult_s(vnPerp, lbc), vec2_sub(p0, bisec)), vHwPerp);
+            rlh_outside_pos = vec2_add(p0, vec2_mult_s(bisec_n_perp, lh));
+        }
+    } else {
+        if (det < 0.0) {
+            rlh_inside_pos  = vec2_add(p0, bisec);
+            rlh_outside_pos = vec2_sub(p0, bisec);
+        } else {
+            rlh_inside_pos  = vec2_sub(p0, bisec);
+            rlh_outside_pos = vec2_add(p0, bisec);
+        }
+    }
+
+    vkvg_line_join_t join = ctx->lineJoin;
+
+    if (isCurve) {
+        if (dot < 0.8f)
+            join = VKVG_LINE_JOIN_ROUND;
+        else
+            join = VKVG_LINE_JOIN_MITER;
+    }
+
+    if (join == VKVG_LINE_JOIN_MITER) {
+        if (lh > str->lhMax) { // miter limit
+            double x         = (lh - str->lhMax) * cosHalfAlpha;
+            vec2   bisecPerp = vec2_mult_s(bisec_n, x);
+            bisec            = vec2_mult_s(bisec_n_perp, str->lhMax);
+            if (det < 0) {
+                v.pos = rlh_inside_pos;
+                _add_vertex(ctx, v);
+
+                vec2 p = vec2_sub(p0, bisec);
+
+                v.pos = vec2_sub(p, bisecPerp);
+                _add_vertex(ctx, v);
+                v.pos = vec2_add(p, bisecPerp);
+                _add_vertex(ctx, v);
+
+                _add_triangle_indices(ctx, idx, idx + 2, idx + 1);
+                _add_triangle_indices(ctx, idx + 2, idx + 4, idx);
+                _add_triangle_indices(ctx, idx, idx + 3, idx + 4);
+                return true;
+            } else {
+                vec2 p = vec2_add(p0, bisec);
+                v.pos  = vec2_sub(p, bisecPerp);
+                _add_vertex(ctx, v);
+
+                v.pos = rlh_inside_pos;
+                _add_vertex(ctx, v);
+
+                v.pos = vec2_add(p, bisecPerp);
+                _add_vertex(ctx, v);
+
+                _add_triangle_indices(ctx, idx, idx + 2, idx + 1);
+                _add_triangle_indices(ctx, idx + 2, idx + 3, idx + 1);
+                _add_triangle_indices(ctx, idx + 1, idx + 3, idx + 4);
+                return false;
+            }
+
+        } else { // normal miter
+            if (det < 0) {
+                v.pos = rlh_inside_pos;
+                _add_vertex(ctx, v);
+                v.pos = rlh_outside_pos;
+                _add_vertex(ctx, v);
+            } else {
+                v.pos = rlh_outside_pos;
+                _add_vertex(ctx, v);
+                v.pos = rlh_inside_pos;
+                _add_vertex(ctx, v);
+            }
+
+            _add_tri_indices_for_rect(ctx, idx);
+            return false;
+        }
+    } else {
+        vec2 vp = vec2_perp(v0n);
+
+        if (det < 0) {
+            if (dot < 0 && rlh < lh)
+                v.pos = rlh_inside_pos;
+            else
+                v.pos = vec2_add(p0, bisec);
+            _add_vertex(ctx, v);
+            v.pos = vec2_sub(p0, vec2_mult_s(vp, str->hw));
+        } else {
+            v.pos = vec2_add(p0, vec2_mult_s(vp, str->hw));
+            _add_vertex(ctx, v);
+            if (dot < 0 && rlh < lh)
+                v.pos = rlh_inside_pos;
+            else
+                v.pos = vec2_sub(p0, bisec);
+        }
+        _add_vertex(ctx, v);
+
+        if (join == VKVG_LINE_JOIN_BEVEL) {
+            if (det < 0) {
+                _add_triangle_indices(ctx, idx, idx + 2, idx + 1);
+                _add_triangle_indices(ctx, idx + 2, idx + 4, idx + 0);
+                _add_triangle_indices(ctx, idx, idx + 3, idx + 4);
+            } else {
+                _add_triangle_indices(ctx, idx, idx + 2, idx + 1);
+                _add_triangle_indices(ctx, idx + 2, idx + 3, idx + 1);
+                _add_triangle_indices(ctx, idx + 1, idx + 3, idx + 4);
+            }
+        } else if (join == VKVG_LINE_JOIN_ROUND) {
+            if (!str->arcStep)
+                str->arcStep = _get_arc_step(ctx, str->hw);
+            float a = acosf(vp.x);
+            if (vp.y < 0)
+                a = -a;
+
+            if (det < 0) {
+                a += M_PIF;
+                float a1 = a + alpha;
+                a -= str->arcStep;
+                while (a > a1) {
+                    _add_vertexf(ctx, cosf(a) * str->hw + p0.x, sinf(a) * str->hw + p0.y);
+                    a -= str->arcStep;
+                }
+            } else {
+                float a1 = a + alpha;
+                a += str->arcStep;
+                while (a < a1) {
+                    _add_vertexf(ctx, cosf(a) * str->hw + p0.x, sinf(a) * str->hw + p0.y);
+                    a += str->arcStep;
+                }
+            }
+            VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+            _add_triangle_indices(ctx, idx, idx + 2, idx + 1);
+            if (det < 0) {
+                for (VKVG_IBO_INDEX_TYPE p = idx + 2; p < p0Idx; p++)
+                    _add_triangle_indices(ctx, p, p + 1, idx);
+                _add_triangle_indices(ctx, p0Idx, p0Idx + 2, idx);
+                _add_triangle_indices(ctx, idx, p0Idx + 1, p0Idx + 2);
+            } else {
+                for (VKVG_IBO_INDEX_TYPE p = idx + 2; p < p0Idx; p++)
+                    _add_triangle_indices(ctx, p, p + 1, idx + 1);
+                _add_triangle_indices(ctx, p0Idx, p0Idx + 1, idx + 1);
+                _add_triangle_indices(ctx, idx + 1, p0Idx + 1, p0Idx + 2);
+            }
+        }
+
+        vp = vec2_mult_s(vec2_perp(v1n), str->hw);
+        if (det < 0)
+            v.pos = vec2_sub(p0, vp);
+        else
+            v.pos = vec2_add(p0, vp);
+        _add_vertex(ctx, v);
+    }
+
+    /*
+    #ifdef DEBUG
+
+        debugLinePoints[dlpCount] = p0;
+        debugLinePoints[dlpCount+1] = _v2add(p0, _vec2dToVec2(_v2Multd(v0n,10)));
+        dlpCount+=2;
+        debugLinePoints[dlpCount] = p0;
+        debugLinePoints[dlpCount+1] = _v2add(p0, _vec2dToVec2(_v2Multd(v1n,10)));
+        dlpCount+=2;
+        debugLinePoints[dlpCount] = p0;
+        debugLinePoints[dlpCount+1] = pR;
+        dlpCount+=2;
+    #endif*/
+    /*if (reducedLH)
+        return -det;
+    else*/
+    return (det < 0);
+}
+
+void _draw_stoke_cap(VkvgContext ctx, stroke_context_t *str, vec2 p0, vec2 n, bool isStart) {
+    Vertex v = {{0}, ctx->curColor, {0, 0, -1}};
+
+    VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+
+    if (isStart) {
+        vec2 vhw = vec2_mult_s(n, str->hw);
+
+        if (ctx->lineCap == VKVG_LINE_CAP_SQUARE)
+            p0 = vec2_sub(p0, vhw);
+
+        vhw = vec2_perp(vhw);
+
+        if (ctx->lineCap == VKVG_LINE_CAP_ROUND) {
+            if (!str->arcStep)
+                str->arcStep = _get_arc_step(ctx, str->hw);
+
+            float a = acosf(n.x) + M_PIF_2;
+            if (n.y < 0)
+                a = M_PIF - a;
+            float a1 = a + M_PIF;
+
+            a += str->arcStep;
+            while (a < a1) {
+                _add_vertexf(ctx, cosf(a) * str->hw + p0.x, sinf(a) * str->hw + p0.y);
+                a += str->arcStep;
+            }
+            VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+            for (VKVG_IBO_INDEX_TYPE p = firstIdx; p < p0Idx; p++)
+                _add_triangle_indices(ctx, p0Idx + 1, p, p + 1);
+            firstIdx = p0Idx;
+        }
+
+        v.pos = vec2_add(p0, vhw);
+        _add_vertex(ctx, v);
+        v.pos = vec2_sub(p0, vhw);
+        _add_vertex(ctx, v);
+
+        _add_tri_indices_for_rect(ctx, firstIdx);
+    } else {
+        vec2 vhw = vec2_mult_s(n, str->hw);
+
+        if (ctx->lineCap == VKVG_LINE_CAP_SQUARE)
+            p0 = vec2_add(p0, vhw);
+
+        vhw = vec2_perp(vhw);
+
+        v.pos = vec2_add(p0, vhw);
+        _add_vertex(ctx, v);
+        v.pos = vec2_sub(p0, vhw);
+        _add_vertex(ctx, v);
+
+        firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+
+        if (ctx->lineCap == VKVG_LINE_CAP_ROUND) {
+            if (!str->arcStep)
+                str->arcStep = _get_arc_step(ctx, str->hw);
+
+            float a = acosf(n.x) + M_PIF_2;
+            if (n.y < 0)
+                a = M_PIF - a;
+            float a1 = a - M_PIF;
+
+            a -= str->arcStep;
+            while (a > a1) {
+                _add_vertexf(ctx, cosf(a) * str->hw + p0.x, sinf(a) * str->hw + p0.y);
+                a -= str->arcStep;
+            }
+
+            VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset - 1);
+            for (VKVG_IBO_INDEX_TYPE p = firstIdx - 1; p < p0Idx; p++)
+                _add_triangle_indices(ctx, p + 1, p, firstIdx - 2);
+        }
+    }
+}
+float _draw_dashed_segment(VkvgContext ctx, stroke_context_t *str, dash_context_t *dc, bool isCurve) {
+    // vec2 pL = ctx->points[str->iL];
+    vec2 p  = ctx->points[str->cp];
+    vec2 pR = ctx->points[str->iR];
+
+    if (!dc->dashOn) // we test in fact the next dash start, if dashOn = true => next segment is a void.
+        _build_vb_step(ctx, str, isCurve);
+
+    vec2 d              = vec2_sub(pR, p);
+    dc->normal          = vec2_norm(d);
+    float segmentLength = vec2_length(d);
+
+    while (dc->curDashOffset < segmentLength) {
+        vec2 p0 = vec2_add(p, vec2_mult_s(dc->normal, dc->curDashOffset));
+
+        _draw_stoke_cap(ctx, str, p0, dc->normal, dc->dashOn);
+        dc->dashOn ^= true;
+        dc->curDashOffset += ctx->dashes[dc->curDash];
+        if (++dc->curDash == ctx->dashCount)
+            dc->curDash = 0;
+    }
+    dc->curDashOffset -= segmentLength;
+    dc->curDashOffset = fmodf(dc->curDashOffset, dc->totDashLength);
+    return segmentLength;
+}
+void _draw_segment(VkvgContext ctx, stroke_context_t *str, dash_context_t *dc, bool isCurve) {
+    str->iR = str->cp + 1;
+    if (ctx->dashCount > 0)
+        _draw_dashed_segment(ctx, str, dc, isCurve);
+    else
+        _build_vb_step(ctx, str, isCurve);
+    str->iL = str->cp++;
+    if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3) {
+        Vertex v0 = ctx->vertexCache[ctx->curVertOffset + str->firstIdx];
+        Vertex v1 = ctx->vertexCache[ctx->curVertOffset + str->firstIdx + 1];
+        _emit_draw_cmd_undrawn_vertices(ctx);
+        // repeat first 2 vertices for closed pathes
+        str->firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+        _add_vertex(ctx, v0);
+        _add_vertex(ctx, v1);
+        ctx->curVertOffset = ctx->vertCount; // prevent redrawing them at the start of the batch
+    }
 }
 
 bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) {
-       float dX = p.x-p2.x;
-       float dY = p.y-p2.y;
-       float dX21 = p2.x-p1.x;
-       float dY12 = p1.y-p2.y;
-       float D = dY12*(p0.x-p2.x) + dX21*(p0.y-p2.y);
-       float s = dY12*dX + dX21*dY;
-       float t = (p2.y-p0.y)*dX + (p0.x-p2.x)*dY;
-       if (D<0)
-               return (s<=0) && (t<=0) && (s+t>=D);
-       return (s>=0) && (t>=0) && (s+t<=D);
-}
-
-void _free_ctx_save (vkvg_context_save_t* sav){
-       if (sav->dashCount > 0)
-               free (sav->dashes);
-       if (sav->pattern)
-               vkvg_pattern_destroy(sav->pattern);
-       free (sav);
-}
-
-
-#define M_APPROXIMATION_SCALE  1.0
-#define M_ANGLE_TOLERANCE              0.01
-#define M_CUSP_LIMIT                   0.01
-#define CURVE_RECURSION_LIMIT  100
-#define CURVE_COLLINEARITY_EPSILON 1.7
+    float dX   = p.x - p2.x;
+    float dY   = p.y - p2.y;
+    float dX21 = p2.x - p1.x;
+    float dY12 = p1.y - p2.y;
+    float D    = dY12 * (p0.x - p2.x) + dX21 * (p0.y - p2.y);
+    float s    = dY12 * dX + dX21 * dY;
+    float t    = (p2.y - p0.y) * dX + (p0.x - p2.x) * dY;
+    if (D < 0)
+        return (s <= 0) && (t <= 0) && (s + t >= D);
+    return (s >= 0) && (t >= 0) && (s + t <= D);
+}
+
+void _free_ctx_save(vkvg_context_save_t *sav) {
+    if (sav->dashCount > 0)
+        free(sav->dashes);
+    if (sav->pattern)
+        vkvg_pattern_destroy(sav->pattern);
+    free(sav);
+}
+
+#define M_APPROXIMATION_SCALE         1.0
+#define M_ANGLE_TOLERANCE             0.01
+#define M_CUSP_LIMIT                  0.01
+#define CURVE_RECURSION_LIMIT         100
+#define CURVE_COLLINEARITY_EPSILON    1.7
 #define CURVE_ANGLE_TOLERANCE_EPSILON 0.001
-//no floating point arithmetic operation allowed in macro.
-#pragma warning(disable:4127)
-void _recursive_bezier (VkvgContext ctx, float distanceTolerance,
-                                               float x1, float y1, float x2, float y2,
-                                               float x3, float y3, float x4, float y4,
-                                               unsigned level) {
-       if(level > CURVE_RECURSION_LIMIT)
-       {
-               return;
-       }
-
-       // Calculate all the mid-points of the line segments
-       //----------------------
-       float x12       = (x1 + x2) / 2;
-       float y12       = (y1 + y2) / 2;
-       float x23       = (x2 + x3) / 2;
-       float y23       = (y2 + y3) / 2;
-       float x34       = (x3 + x4) / 2;
-       float y34       = (y3 + y4) / 2;
-       float x123      = (x12 + x23) / 2;
-       float y123      = (y12 + y23) / 2;
-       float x234      = (x23 + x34) / 2;
-       float y234      = (y23 + y34) / 2;
-       float x1234 = (x123 + x234) / 2;
-       float y1234 = (y123 + y234) / 2;
-
-       if(level > 0) // Enforce subdivision first time
-       {
-               // Try to approximate the full cubic curve by a single straight line
-               //------------------
-               float dx = x4-x1;
-               float dy = y4-y1;
-
-               float d2 = fabsf(((x2 - x4) * dy - (y2 - y4) * dx));
-               float d3 = fabsf(((x3 - x4) * dy - (y3 - y4) * dx));
-
-               float da1, da2;
-
-               if(d2 > CURVE_COLLINEARITY_EPSILON && d3 > CURVE_COLLINEARITY_EPSILON)
-               {
-                       // Regular care
-                       //-----------------
-                       if((d2 + d3)*(d2 + d3) <= (dx*dx + dy*dy) * distanceTolerance)
-                       {
-                               // If the curvature doesn't exceed the distance_tolerance value
-                               // we tend to finish subdivisions.
-                               //----------------------
-                               if (M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) {
-                                       _add_point(ctx, x1234, y1234);
-                                       return;
-                               }
-
-                               // Angle & Cusp Condition
-                               //----------------------
-                               float a23 = atan2f(y3 - y2, x3 - x2);
-                               da1 = fabsf(a23 - atan2f(y2 - y1, x2 - x1));
-                               da2 = fabsf(atan2f(y4 - y3, x4 - x3) - a23);
-                               if(da1 >= M_PIF) da1 = M_2_PIF - da1;
-                               if(da2 >= M_PIF) da2 = M_2_PIF - da2;
-
-                               if(da1 + da2 < (float)M_ANGLE_TOLERANCE)
-                               {
-                                       // Finally we can stop the recursion
-                                       //----------------------
-                                       _add_point (ctx, x1234, y1234);
-                                       return;
-                               }
-
-                               if(M_CUSP_LIMIT != 0.0)
-                               {
-                                       if(da1 > M_CUSP_LIMIT)
-                                       {
-                                               _add_point (ctx, x2, y2);
-                                               return;
-                                       }
-
-                                       if(da2 > M_CUSP_LIMIT)
-                                       {
-                                               _add_point (ctx, x3, y3);
-                                               return;
-                                       }
-                               }
-                       }
-               } else {
-                       if(d2 > CURVE_COLLINEARITY_EPSILON)
-                       {
-                               // p1,p3,p4 are collinear, p2 is considerable
-                               //----------------------
-                               if(d2 * d2 <= distanceTolerance * (dx*dx + dy*dy))
-                               {
-                                       if(M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON)
-                                       {
-                                               _add_point (ctx, x1234, y1234);
-                                               return;
-                                       }
-
-                                       // Angle Condition
-                                       //----------------------
-                                       da1 = fabsf(atan2f(y3 - y2, x3 - x2) - atan2f(y2 - y1, x2 - x1));
-                                       if(da1 >= M_PIF) da1 = M_2_PIF - da1;
-
-                                       if(da1 < M_ANGLE_TOLERANCE)
-                                       {
-                                               _add_point (ctx, x2, y2);
-                                               _add_point (ctx, x3, y3);
-                                               return;
-                                       }
-
-                                       if(M_CUSP_LIMIT != 0.0)
-                                       {
-                                               if(da1 > M_CUSP_LIMIT)
-                                               {
-                                                       _add_point (ctx, x2, y2);
-                                                       return;
-                                               }
-                                       }
-                               }
-                       } else if(d3 > CURVE_COLLINEARITY_EPSILON) {
-                               // p1,p2,p4 are collinear, p3 is considerable
-                               //----------------------
-                               if(d3 * d3 <= distanceTolerance* (dx*dx + dy*dy))
-                               {
-                                       if(M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON)
-                                       {
-                                               _add_point (ctx, x1234, y1234);
-                                               return;
-                                       }
-
-                                       // Angle Condition
-                                       //----------------------
-                                       da1 = fabsf(atan2f(y4 - y3, x4 - x3) - atan2f(y3 - y2, x3 - x2));
-                                       if(da1 >= M_PIF) da1 = M_2_PIF - da1;
-
-                                       if(da1 < M_ANGLE_TOLERANCE)
-                                       {
-                                               _add_point (ctx, x2, y2);
-                                               _add_point (ctx, x3, y3);
-                                               return;
-                                       }
-
-                                       if(M_CUSP_LIMIT != 0.0)
-                                       {
-                                               if(da1 > M_CUSP_LIMIT)
-                                               {
-                                                       _add_point (ctx, x3, y3);
-                                                       return;
-                                               }
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               // Collinear case
-                               //-----------------
-                               dx = x1234 - (x1 + x4) / 2;
-                               dy = y1234 - (y1 + y4) / 2;
-                               if(dx*dx + dy*dy <= distanceTolerance)
-                               {
-                                       _add_point (ctx, x1234, y1234);
-                                       return;
-                               }
-                       }
-               }
-       }
-
-       // Continue subdivision
-       //----------------------
-       _recursive_bezier (ctx, distanceTolerance, x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1);
-       _recursive_bezier (ctx, distanceTolerance,x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);
-}
-#pragma warning(default:4127)
-void _line_to (VkvgContext ctx, float x, float y) {
-       vec2 p = {x,y};
-       if (!_current_path_is_empty (ctx)){
-               //prevent adding the same point
-               if (vec2_equ (_get_current_position (ctx), p))
-                       return;
-       }
-       _add_point (ctx, x, y);
-       ctx->simpleConvex = false;
-}
-void _elliptic_arc (VkvgContext ctx, float x1, float y1, float x2, float y2, bool largeArc, bool counterClockWise, float _rx, float _ry, float phi) {
-       if (ctx->status)
-               return;
-
-       if (_rx==0||_ry==0) {
-               if (_current_path_is_empty(ctx))
-                       vkvg_move_to(ctx, x1, y1);
-               vkvg_line_to(ctx, x2, y2);
-               return;
-       }
-       float rx = fabsf(_rx);
-       float ry = fabsf(_ry);
-
-       mat2 m = {
-               { cosf (phi), sinf (phi)},
-               {-sinf (phi), cosf (phi)}
-       };
-       vec2 p = {(x1 - x2)/2, (y1 - y2)/2};
-       vec2 p1 = mat2_mult_vec2 (m, p);
-
-       //radii corrections
-       double lambda = powf (p1.x, 2) / powf (rx, 2) + powf (p1.y, 2) / powf (ry, 2);
-       if (lambda > 1) {
-               lambda = sqrtf (lambda);
-               rx *= lambda;
-               ry *= lambda;
-       }
-
-       p = (vec2){rx * p1.y / ry, -ry * p1.x / rx};
-
-       vec2 cp = vec2_mult_s (p, sqrtf (fabsf (
-               (powf (rx,2) * powf (ry,2) - powf (rx,2) * powf (p1.y, 2) - powf (ry,2) * powf (p1.x, 2)) /
-               (powf (rx,2) * powf (p1.y, 2) + powf (ry,2) * powf (p1.x, 2))
-       )));
-
-       if (largeArc == counterClockWise)
-               vec2_inv(&cp);
-
-       m = (mat2) {
-               {cosf (phi),-sinf (phi)},
-               {sinf (phi), cosf (phi)}
-       };
-       p = (vec2){(x1 + x2)/2, (y1 + y2)/2};
-       vec2 c = vec2_add (mat2_mult_vec2(m, cp) , p);
-
-       vec2 u = vec2_unit_x;
-       vec2 v = {(p1.x-cp.x)/rx, (p1.y-cp.y)/ry};
-       double sa = acosf (vec2_dot (u, v) / (fabsf(vec2_length(v)) * fabsf(vec2_length(u))));
-       if (isnan(sa))
-               sa=M_PIF;
-       if (u.x*v.y-u.y*v.x < 0)
-               sa = -sa;
-
-       u = v;
-       v = (vec2) {(-p1.x-cp.x)/rx, (-p1.y-cp.y)/ry};
-       double delta_theta = acosf (vec2_dot (u, v) / (fabsf(vec2_length (v)) * fabsf(vec2_length (u))));
-       if (isnan(delta_theta))
-               delta_theta=M_PIF;
-       if (u.x*v.y-u.y*v.x < 0)
-               delta_theta = -delta_theta;
-
-       if (counterClockWise) {
-               if (delta_theta < 0)
-                       delta_theta += M_PIF * 2.0;
-       } else if (delta_theta > 0)
-               delta_theta -= M_PIF * 2.0;
-
-       m = (mat2) {
-               {cosf (phi),-sinf (phi)},
-               {sinf (phi), cosf (phi)}
-       };
-
-       double theta = sa;
-       double ea = sa + delta_theta;
-
-       float step = fmaxf(0.001f, fminf(M_PIF, _get_arc_step(ctx, fminf (rx, ry))*0.1f));
-
-       p = (vec2) {
-               rx * cosf (theta),
-               ry * sinf (theta)
-       };
-       vec2 xy = vec2_add (mat2_mult_vec2 (m, p), c);
-
-       if (_current_path_is_empty(ctx)){
-               _set_curve_start (ctx);
-               _add_point (ctx, xy.x, xy.y);
-               if (!ctx->pathPtr)
-                       ctx->simpleConvex = true;
-               else
-                       ctx->simpleConvex = false;
-       }else{
-               _line_to(ctx, xy.x, xy.y);
-               _set_curve_start (ctx);
-               ctx->simpleConvex = false;
-       }
-
-       _set_curve_start (ctx);
-
-       if (sa < ea) {
-               theta += step;
-               while (theta < ea) {
-                       p = (vec2) {
-                               rx * cosf (theta),
-                               ry * sinf (theta)
-                       };
-                       xy = vec2_add (mat2_mult_vec2 (m, p), c);
-                       _add_point (ctx, xy.x, xy.y);
-                       theta += step;
-               }
-       } else {
-               theta -= step;
-               while (theta > ea) {
-                       p = (vec2) {
-                               rx * cosf (theta),
-                               ry * sinf (theta)
-                       };
-                       xy = vec2_add (mat2_mult_vec2 (m, p), c);
-                       _add_point (ctx, xy.x, xy.y);
-                       theta -= step;
-               }
-       }
-       p = (vec2) {
-               rx * cosf (ea),
-               ry * sinf (ea)
-       };
-       xy = vec2_add (mat2_mult_vec2 (m, p), c);
-       _add_point (ctx, xy.x, xy.y);
-       _set_curve_end(ctx);
-}
-
-
-//Even-Odd inside test with stencil buffer implementation.
-void _poly_fill (VkvgContext ctx, vec4* bounds){
-       //we anticipate the check for vbo buffer size, ibo is not used in poly_fill
-       //the polyfill emit a single vertex for each point in the path.
-       if (ctx->sizeVBO - VKVG_ARRAY_THRESHOLD <  ctx->vertCount + ctx->pointCount) {
-               if (ctx->cmdStarted) {
-                       _end_render_pass (ctx);
-                       if (ctx->vertCount > 0)
-                               _flush_vertices_caches (ctx);
-                       vkh_cmd_end (ctx->cmd);
-                       _wait_and_submit_cmd (ctx);
-                       _wait_ctx_flush_end (ctx);
-                       if (ctx->sizeVBO - VKVG_ARRAY_THRESHOLD < ctx->pointCount){
-                               _resize_vbo (ctx, ctx->pointCount + VKVG_ARRAY_THRESHOLD);
-                               _resize_vertex_cache (ctx, ctx->sizeVBO);
-                       }
-               }else{
-                       _resize_vbo (ctx, ctx->vertCount + ctx->pointCount + VKVG_ARRAY_THRESHOLD);
-                       _resize_vertex_cache (ctx, ctx->sizeVBO);
-               }
-
-               _start_cmd_for_render_pass(ctx);
-       } else {
-               _ensure_vertex_cache_size (ctx, ctx->pointCount);
-               _ensure_renderpass_is_started (ctx);
-       }
-
-       CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelinePolyFill);
-
-       Vertex v = {{0}, ctx->curColor, {0,0,-1}};
-       uint32_t ptrPath = 0;
-       uint32_t firstPtIdx = 0;
-
-       while (ptrPath < ctx->pathPtr){
-               uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
-               if (pathPointCount > 2) {
-                       VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)ctx->vertCount;
-
-                       for (uint32_t i = 0; i < pathPointCount; i++) {
-                               v.pos = ctx->points [i+firstPtIdx];
-                               ctx->vertexCache[ctx->vertCount++] = v;
-                               if (!bounds)
-                                       continue;
-                               //bounds are computed here to scissor the painting operation
-                               //that speed up fill drastically.
-                               vkvg_matrix_transform_point (&ctx->pushConsts.mat, &v.pos.x, &v.pos.y);
-
-                               if (v.pos.x < bounds->xMin)
-                                       bounds->xMin = v.pos.x;
-                               if (v.pos.x > bounds->xMax)
-                                       bounds->xMax = v.pos.x;
-                               if (v.pos.y < bounds->yMin)
-                                       bounds->yMin = v.pos.y;
-                               if (v.pos.y > bounds->yMax)
-                                       bounds->yMax = v.pos.y;
-                       }
-
-                       LOG(VKVG_LOG_INFO_PATH, "\tpoly fill: point count = %d; 1st vert = %d; vert count = %d\n", pathPointCount, firstVertIdx, ctx->vertCount - firstVertIdx);
-                       CmdDraw (ctx->cmd, pathPointCount, 1, firstVertIdx , 0);
-               }
-               firstPtIdx += pathPointCount;
-
-               if (_path_has_curves (ctx, ptrPath)) {
-                       //skip segments lengths used in stroke
-                       ptrPath++;
-                       uint32_t totPts = 0;
-                       while (totPts < pathPointCount)
-                               totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK);
-               }else
-                       ptrPath++;
-       }
-       ctx->curVertOffset = ctx->vertCount;
+// no floating point arithmetic operation allowed in macro.
+#pragma warning(disable : 4127)
+void _recursive_bezier(VkvgContext ctx, float distanceTolerance, float x1, float y1, float x2, float y2, float x3,
+                       float y3, float x4, float y4, unsigned level) {
+    if (level > CURVE_RECURSION_LIMIT) {
+        return;
+    }
+
+    // Calculate all the mid-points of the line segments
+    //----------------------
+    float x12   = (x1 + x2) / 2;
+    float y12   = (y1 + y2) / 2;
+    float x23   = (x2 + x3) / 2;
+    float y23   = (y2 + y3) / 2;
+    float x34   = (x3 + x4) / 2;
+    float y34   = (y3 + y4) / 2;
+    float x123  = (x12 + x23) / 2;
+    float y123  = (y12 + y23) / 2;
+    float x234  = (x23 + x34) / 2;
+    float y234  = (y23 + y34) / 2;
+    float x1234 = (x123 + x234) / 2;
+    float y1234 = (y123 + y234) / 2;
+
+    if (level > 0) // Enforce subdivision first time
+    {
+        // Try to approximate the full cubic curve by a single straight line
+        //------------------
+        float dx = x4 - x1;
+        float dy = y4 - y1;
+
+        float d2 = fabsf(((x2 - x4) * dy - (y2 - y4) * dx));
+        float d3 = fabsf(((x3 - x4) * dy - (y3 - y4) * dx));
+
+        float da1, da2;
+
+        if (d2 > CURVE_COLLINEARITY_EPSILON && d3 > CURVE_COLLINEARITY_EPSILON) {
+            // Regular care
+            //-----------------
+            if ((d2 + d3) * (d2 + d3) <= (dx * dx + dy * dy) * distanceTolerance) {
+                // If the curvature doesn't exceed the distance_tolerance value
+                // we tend to finish subdivisions.
+                //----------------------
+                if (M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) {
+                    _add_point(ctx, x1234, y1234);
+                    return;
+                }
+
+                // Angle & Cusp Condition
+                //----------------------
+                float a23 = atan2f(y3 - y2, x3 - x2);
+                da1       = fabsf(a23 - atan2f(y2 - y1, x2 - x1));
+                da2       = fabsf(atan2f(y4 - y3, x4 - x3) - a23);
+                if (da1 >= M_PIF)
+                    da1 = M_2_PIF - da1;
+                if (da2 >= M_PIF)
+                    da2 = M_2_PIF - da2;
+
+                if (da1 + da2 < (float)M_ANGLE_TOLERANCE) {
+                    // Finally we can stop the recursion
+                    //----------------------
+                    _add_point(ctx, x1234, y1234);
+                    return;
+                }
+
+                if (M_CUSP_LIMIT != 0.0) {
+                    if (da1 > M_CUSP_LIMIT) {
+                        _add_point(ctx, x2, y2);
+                        return;
+                    }
+
+                    if (da2 > M_CUSP_LIMIT) {
+                        _add_point(ctx, x3, y3);
+                        return;
+                    }
+                }
+            }
+        } else {
+            if (d2 > CURVE_COLLINEARITY_EPSILON) {
+                // p1,p3,p4 are collinear, p2 is considerable
+                //----------------------
+                if (d2 * d2 <= distanceTolerance * (dx * dx + dy * dy)) {
+                    if (M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) {
+                        _add_point(ctx, x1234, y1234);
+                        return;
+                    }
+
+                    // Angle Condition
+                    //----------------------
+                    da1 = fabsf(atan2f(y3 - y2, x3 - x2) - atan2f(y2 - y1, x2 - x1));
+                    if (da1 >= M_PIF)
+                        da1 = M_2_PIF - da1;
+
+                    if (da1 < M_ANGLE_TOLERANCE) {
+                        _add_point(ctx, x2, y2);
+                        _add_point(ctx, x3, y3);
+                        return;
+                    }
+
+                    if (M_CUSP_LIMIT != 0.0) {
+                        if (da1 > M_CUSP_LIMIT) {
+                            _add_point(ctx, x2, y2);
+                            return;
+                        }
+                    }
+                }
+            } else if (d3 > CURVE_COLLINEARITY_EPSILON) {
+                // p1,p2,p4 are collinear, p3 is considerable
+                //----------------------
+                if (d3 * d3 <= distanceTolerance * (dx * dx + dy * dy)) {
+                    if (M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) {
+                        _add_point(ctx, x1234, y1234);
+                        return;
+                    }
+
+                    // Angle Condition
+                    //----------------------
+                    da1 = fabsf(atan2f(y4 - y3, x4 - x3) - atan2f(y3 - y2, x3 - x2));
+                    if (da1 >= M_PIF)
+                        da1 = M_2_PIF - da1;
+
+                    if (da1 < M_ANGLE_TOLERANCE) {
+                        _add_point(ctx, x2, y2);
+                        _add_point(ctx, x3, y3);
+                        return;
+                    }
+
+                    if (M_CUSP_LIMIT != 0.0) {
+                        if (da1 > M_CUSP_LIMIT) {
+                            _add_point(ctx, x3, y3);
+                            return;
+                        }
+                    }
+                }
+            } else {
+                // Collinear case
+                //-----------------
+                dx = x1234 - (x1 + x4) / 2;
+                dy = y1234 - (y1 + y4) / 2;
+                if (dx * dx + dy * dy <= distanceTolerance) {
+                    _add_point(ctx, x1234, y1234);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Continue subdivision
+    //----------------------
+    _recursive_bezier(ctx, distanceTolerance, x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1);
+    _recursive_bezier(ctx, distanceTolerance, x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);
+}
+#pragma warning(default : 4127)
+void _line_to(VkvgContext ctx, float x, float y) {
+    vec2 p = {x, y};
+    if (!_current_path_is_empty(ctx)) {
+        // prevent adding the same point
+        if (vec2_equ(_get_current_position(ctx), p))
+            return;
+    }
+    _add_point(ctx, x, y);
+    ctx->simpleConvex = false;
+}
+void _elliptic_arc(VkvgContext ctx, float x1, float y1, float x2, float y2, bool largeArc, bool counterClockWise,
+                   float _rx, float _ry, float phi) {
+    if (ctx->status)
+        return;
+
+    if (_rx == 0 || _ry == 0) {
+        if (_current_path_is_empty(ctx))
+            vkvg_move_to(ctx, x1, y1);
+        vkvg_line_to(ctx, x2, y2);
+        return;
+    }
+    float rx = fabsf(_rx);
+    float ry = fabsf(_ry);
+
+    mat2 m  = {{cosf(phi), sinf(phi)}, {-sinf(phi), cosf(phi)}};
+    vec2 p  = {(x1 - x2) / 2, (y1 - y2) / 2};
+    vec2 p1 = mat2_mult_vec2(m, p);
+
+    // radii corrections
+    double lambda = powf(p1.x, 2) / powf(rx, 2) + powf(p1.y, 2) / powf(ry, 2);
+    if (lambda > 1) {
+        lambda = sqrtf(lambda);
+        rx *= lambda;
+        ry *= lambda;
+    }
+
+    p = (vec2){rx * p1.y / ry, -ry * p1.x / rx};
+
+    vec2 cp = vec2_mult_s(
+        p, sqrtf(fabsf((powf(rx, 2) * powf(ry, 2) - powf(rx, 2) * powf(p1.y, 2) - powf(ry, 2) * powf(p1.x, 2)) /
+                       (powf(rx, 2) * powf(p1.y, 2) + powf(ry, 2) * powf(p1.x, 2)))));
+
+    if (largeArc == counterClockWise)
+        vec2_inv(&cp);
+
+    m      = (mat2){{cosf(phi), -sinf(phi)}, {sinf(phi), cosf(phi)}};
+    p      = (vec2){(x1 + x2) / 2, (y1 + y2) / 2};
+    vec2 c = vec2_add(mat2_mult_vec2(m, cp), p);
+
+    vec2   u  = vec2_unit_x;
+    vec2   v  = {(p1.x - cp.x) / rx, (p1.y - cp.y) / ry};
+    double sa = acosf(vec2_dot(u, v) / (fabsf(vec2_length(v)) * fabsf(vec2_length(u))));
+    if (isnan(sa))
+        sa = M_PIF;
+    if (u.x * v.y - u.y * v.x < 0)
+        sa = -sa;
+
+    u                  = v;
+    v                  = (vec2){(-p1.x - cp.x) / rx, (-p1.y - cp.y) / ry};
+    double delta_theta = acosf(vec2_dot(u, v) / (fabsf(vec2_length(v)) * fabsf(vec2_length(u))));
+    if (isnan(delta_theta))
+        delta_theta = M_PIF;
+    if (u.x * v.y - u.y * v.x < 0)
+        delta_theta = -delta_theta;
+
+    if (counterClockWise) {
+        if (delta_theta < 0)
+            delta_theta += M_PIF * 2.0;
+    } else if (delta_theta > 0)
+        delta_theta -= M_PIF * 2.0;
+
+    m = (mat2){{cosf(phi), -sinf(phi)}, {sinf(phi), cosf(phi)}};
+
+    double theta = sa;
+    double ea    = sa + delta_theta;
+
+    float step = fmaxf(0.001f, fminf(M_PIF, _get_arc_step(ctx, fminf(rx, ry)) * 0.1f));
+
+    p       = (vec2){rx * cosf(theta), ry * sinf(theta)};
+    vec2 xy = vec2_add(mat2_mult_vec2(m, p), c);
+
+    if (_current_path_is_empty(ctx)) {
+        _set_curve_start(ctx);
+        _add_point(ctx, xy.x, xy.y);
+        if (!ctx->pathPtr)
+            ctx->simpleConvex = true;
+        else
+            ctx->simpleConvex = false;
+    } else {
+        _line_to(ctx, xy.x, xy.y);
+        _set_curve_start(ctx);
+        ctx->simpleConvex = false;
+    }
+
+    _set_curve_start(ctx);
+
+    if (sa < ea) {
+        theta += step;
+        while (theta < ea) {
+            p  = (vec2){rx * cosf(theta), ry * sinf(theta)};
+            xy = vec2_add(mat2_mult_vec2(m, p), c);
+            _add_point(ctx, xy.x, xy.y);
+            theta += step;
+        }
+    } else {
+        theta -= step;
+        while (theta > ea) {
+            p  = (vec2){rx * cosf(theta), ry * sinf(theta)};
+            xy = vec2_add(mat2_mult_vec2(m, p), c);
+            _add_point(ctx, xy.x, xy.y);
+            theta -= step;
+        }
+    }
+    p  = (vec2){rx * cosf(ea), ry * sinf(ea)};
+    xy = vec2_add(mat2_mult_vec2(m, p), c);
+    _add_point(ctx, xy.x, xy.y);
+    _set_curve_end(ctx);
+}
+
+// Even-Odd inside test with stencil buffer implementation.
+void _poly_fill(VkvgContext ctx, vec4 *bounds) {
+    // we anticipate the check for vbo buffer size, ibo is not used in poly_fill
+    // the polyfill emit a single vertex for each point in the path.
+    if (ctx->sizeVBO - VKVG_ARRAY_THRESHOLD < ctx->vertCount + ctx->pointCount) {
+        if (ctx->cmdStarted) {
+            _end_render_pass(ctx);
+            if (ctx->vertCount > 0)
+                _flush_vertices_caches(ctx);
+            vkh_cmd_end(ctx->cmd);
+            _wait_and_submit_cmd(ctx);
+            _wait_ctx_flush_end(ctx);
+            if (ctx->sizeVBO - VKVG_ARRAY_THRESHOLD < ctx->pointCount) {
+                _resize_vbo(ctx, ctx->pointCount + VKVG_ARRAY_THRESHOLD);
+                _resize_vertex_cache(ctx, ctx->sizeVBO);
+            }
+        } else {
+            _resize_vbo(ctx, ctx->vertCount + ctx->pointCount + VKVG_ARRAY_THRESHOLD);
+            _resize_vertex_cache(ctx, ctx->sizeVBO);
+        }
+
+        _start_cmd_for_render_pass(ctx);
+    } else {
+        _ensure_vertex_cache_size(ctx, ctx->pointCount);
+        _ensure_renderpass_is_started(ctx);
+    }
+
+    CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelinePolyFill);
+
+    Vertex   v          = {{0}, ctx->curColor, {0, 0, -1}};
+    uint32_t ptrPath    = 0;
+    uint32_t firstPtIdx = 0;
+
+    while (ptrPath < ctx->pathPtr) {
+        uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
+        if (pathPointCount > 2) {
+            VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)ctx->vertCount;
+
+            for (uint32_t i = 0; i < pathPointCount; i++) {
+                v.pos                              = ctx->points[i + firstPtIdx];
+                ctx->vertexCache[ctx->vertCount++] = v;
+                if (!bounds)
+                    continue;
+                // bounds are computed here to scissor the painting operation
+                // that speed up fill drastically.
+                vkvg_matrix_transform_point(&ctx->pushConsts.mat, &v.pos.x, &v.pos.y);
+
+                if (v.pos.x < bounds->xMin)
+                    bounds->xMin = v.pos.x;
+                if (v.pos.x > bounds->xMax)
+                    bounds->xMax = v.pos.x;
+                if (v.pos.y < bounds->yMin)
+                    bounds->yMin = v.pos.y;
+                if (v.pos.y > bounds->yMax)
+                    bounds->yMax = v.pos.y;
+            }
+
+            LOG(VKVG_LOG_INFO_PATH, "\tpoly fill: point count = %d; 1st vert = %d; vert count = %d\n", pathPointCount,
+                firstVertIdx, ctx->vertCount - firstVertIdx);
+            CmdDraw(ctx->cmd, pathPointCount, 1, firstVertIdx, 0);
+        }
+        firstPtIdx += pathPointCount;
+
+        if (_path_has_curves(ctx, ptrPath)) {
+            // skip segments lengths used in stroke
+            ptrPath++;
+            uint32_t totPts = 0;
+            while (totPts < pathPointCount)
+                totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK);
+        } else
+            ptrPath++;
+    }
+    ctx->curVertOffset = ctx->vertCount;
 }
 #ifdef VKVG_FILL_NZ_GLUTESS
 void fan_vertex2(VKVG_IBO_INDEX_TYPE v, VkvgContext ctx) {
-       VKVG_IBO_INDEX_TYPE i = (VKVG_IBO_INDEX_TYPE)v;
-       switch (ctx->tesselator_idx_counter) {
-       case 0:
-               _add_indice(ctx, i);
-               ctx->tesselator_fan_start = i;
-               ctx->tesselator_idx_counter ++;
-               break;
-       case 1:
-       case 2:
-               _add_indice(ctx, i);
-               ctx->tesselator_idx_counter ++;
-               break;
-       default:
-               _add_indice_for_fan (ctx, i);
-               break;
-       }
+    VKVG_IBO_INDEX_TYPE i = (VKVG_IBO_INDEX_TYPE)v;
+    switch (ctx->tesselator_idx_counter) {
+    case 0:
+        _add_indice(ctx, i);
+        ctx->tesselator_fan_start = i;
+        ctx->tesselator_idx_counter++;
+        break;
+    case 1:
+    case 2:
+        _add_indice(ctx, i);
+        ctx->tesselator_idx_counter++;
+        break;
+    default:
+        _add_indice_for_fan(ctx, i);
+        break;
+    }
 }
 
 void strip_vertex2(VKVG_IBO_INDEX_TYPE v, VkvgContext ctx) {
-       VKVG_IBO_INDEX_TYPE i = (VKVG_IBO_INDEX_TYPE)v;
-       if (ctx->tesselator_idx_counter < 3) {
-               _add_indice(ctx, i);
-       } else
-               _add_indice_for_strip(ctx, i, ctx->tesselator_idx_counter % 2);
-       ctx->tesselator_idx_counter ++;
-}
-
-void triangle_vertex2 (VKVG_IBO_INDEX_TYPE v, VkvgContext ctx) {
-       VKVG_IBO_INDEX_TYPE i = (VKVG_IBO_INDEX_TYPE)v;
-       _add_indice(ctx, i);
-}
-void skip_vertex2 (VKVG_IBO_INDEX_TYPE v, VkvgContext ctx) {}
-void begin2(GLenum which, void *poly_data)
-{
-       VkvgContext ctx = (VkvgContext)poly_data;
-       switch (which) {
-       case GL_TRIANGLES:
-               ctx->vertex_cb = &triangle_vertex2;
-               break;
-       case GL_TRIANGLE_STRIP:
-               ctx->tesselator_idx_counter = 0;
-               ctx->vertex_cb = &strip_vertex2;
-               break;
-       case GL_TRIANGLE_FAN:
-               ctx->tesselator_idx_counter = ctx->tesselator_fan_start = 0;
-               ctx->vertex_cb = &fan_vertex2;
-               break;
-       default:
-               fprintf(stderr, "ERROR, can't handle %d\n", (int)which);
-               ctx->vertex_cb = &skip_vertex2;
-       }
-}
-
-void combine2(const GLdouble newVertex[3],
-                        const void *neighborVertex_s[4],
-                        const GLfloat neighborWeight[4], void **outData, void *poly_data)
-{
-       VkvgContext ctx = (VkvgContext)poly_data;
-       Vertex v = {{newVertex[0],newVertex[1]},ctx->curColor, {0,0,-1}};
-       *outData = (void*)((unsigned long)(ctx->vertCount - ctx->curVertOffset));
-       _add_vertex(ctx, v);
-}
-void vertex2(void *vertex_data, void *poly_data)
-{
-       VKVG_IBO_INDEX_TYPE i = (VKVG_IBO_INDEX_TYPE)vertex_data;
-       VkvgContext ctx = (VkvgContext)poly_data;
-       ctx->vertex_cb(i, ctx);
-}
-void _fill_non_zero (VkvgContext ctx){
-       Vertex v = {{0},ctx->curColor, {0,0,-1}};
-
-       uint32_t ptrPath = 0;
-       uint32_t firstPtIdx = 0;
-
-       if (ctx->pathPtr == 1 && ctx->pathes[0] & PATH_IS_CONVEX_BIT) {
-               //simple concave rectangle or circle
-               VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-               uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
-
-               _ensure_vertex_cache_size(ctx, pathPointCount);
-               _ensure_index_cache_size(ctx, (pathPointCount-2)*3);
-
-               VKVG_IBO_INDEX_TYPE i = 0;
-               while (i < 2){
-                       v.pos = ctx->points [i++];
-                       _set_vertex (ctx, ctx->vertCount++, v);
-               }
-               while (i < pathPointCount){
-                       v.pos = ctx->points [i];
-                       _set_vertex (ctx, ctx->vertCount++, v);
-                       _add_triangle_indices_unchecked(ctx, firstVertIdx, firstVertIdx + i - 1, firstVertIdx + i);
-                       i++;
-               }
-               return;
-       }
-
-
-       GLUtesselator *tess = gluNewTess();
-       gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
-       gluTessCallback(tess, GLU_TESS_VERTEX_DATA,  (GLvoid (*) ()) &vertex2);
-       gluTessCallback(tess, GLU_TESS_BEGIN_DATA,   (GLvoid (*) ()) &begin2);
-       gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (GLvoid (*) ()) &combine2);
-
-       gluTessBeginPolygon(tess, ctx);
-
-       while (ptrPath < ctx->pathPtr){
-               uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
-
-               if (pathPointCount > 2) {
-                       VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-                       gluTessBeginContour(tess);
-
-                       VKVG_IBO_INDEX_TYPE i = 0;
-
-                       while (i < pathPointCount){
-                               v.pos = ctx->points[i+firstPtIdx];
-                               double dp[] = {v.pos.x,v.pos.y,0};
-                               _add_vertex(ctx, v);
-                               gluTessVertex(tess, dp, (void*)((unsigned long)firstVertIdx + i));
-                               i++;
-                       }
-                       gluTessEndContour(tess);
-
-                       //limit batch size here to 1/3 of the ibo index type ability
-                       //if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3)
-                       //      _emit_draw_cmd_undrawn_vertices(ctx);
-               }
-
-               firstPtIdx += pathPointCount;
-               if (_path_has_curves (ctx, ptrPath)) {
-                       //skip segments lengths used in stroke
-                       ptrPath++;
-                       uint32_t totPts = 0;
-                       while (totPts < pathPointCount)
-                               totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK);
-               }else
-                       ptrPath++;
-       }
-
-       gluTessEndPolygon(tess);
-
-       gluDeleteTess(tess);
+    VKVG_IBO_INDEX_TYPE i = (VKVG_IBO_INDEX_TYPE)v;
+    if (ctx->tesselator_idx_counter < 3) {
+        _add_indice(ctx, i);
+    } else
+        _add_indice_for_strip(ctx, i, ctx->tesselator_idx_counter % 2);
+    ctx->tesselator_idx_counter++;
+}
+
+void triangle_vertex2(VKVG_IBO_INDEX_TYPE v, VkvgContext ctx) {
+    VKVG_IBO_INDEX_TYPE i = (VKVG_IBO_INDEX_TYPE)v;
+    _add_indice(ctx, i);
+}
+void skip_vertex2(VKVG_IBO_INDEX_TYPE v, VkvgContext ctx) {}
+void begin2(GLenum which, void *poly_data) {
+    VkvgContext ctx = (VkvgContext)poly_data;
+    switch (which) {
+    case GL_TRIANGLES:
+        ctx->vertex_cb = &triangle_vertex2;
+        break;
+    case GL_TRIANGLE_STRIP:
+        ctx->tesselator_idx_counter = 0;
+        ctx->vertex_cb              = &strip_vertex2;
+        break;
+    case GL_TRIANGLE_FAN:
+        ctx->tesselator_idx_counter = ctx->tesselator_fan_start = 0;
+        ctx->vertex_cb                                          = &fan_vertex2;
+        break;
+    default:
+        fprintf(stderr, "ERROR, can't handle %d\n", (int)which);
+        ctx->vertex_cb = &skip_vertex2;
+    }
+}
+
+void combine2(const GLdouble newVertex[3], const void *neighborVertex_s[4], const GLfloat neighborWeight[4],
+              void **outData, void *poly_data) {
+    VkvgContext ctx = (VkvgContext)poly_data;
+    Vertex      v   = {{newVertex[0], newVertex[1]}, ctx->curColor, {0, 0, -1}};
+    *outData        = (void *)((unsigned long)(ctx->vertCount - ctx->curVertOffset));
+    _add_vertex(ctx, v);
+}
+void vertex2(void *vertex_data, void *poly_data) {
+    VKVG_IBO_INDEX_TYPE i   = (VKVG_IBO_INDEX_TYPE)vertex_data;
+    VkvgContext         ctx = (VkvgContext)poly_data;
+    ctx->vertex_cb(i, ctx);
+}
+void _fill_non_zero(VkvgContext ctx) {
+    Vertex v = {{0}, ctx->curColor, {0, 0, -1}};
+
+    uint32_t ptrPath    = 0;
+    uint32_t firstPtIdx = 0;
+
+    if (ctx->pathPtr == 1 && ctx->pathes[0] & PATH_IS_CONVEX_BIT) {
+        // simple concave rectangle or circle
+        VKVG_IBO_INDEX_TYPE firstVertIdx   = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+        uint32_t            pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
+
+        _ensure_vertex_cache_size(ctx, pathPointCount);
+        _ensure_index_cache_size(ctx, (pathPointCount - 2) * 3);
+
+        VKVG_IBO_INDEX_TYPE i = 0;
+        while (i < 2) {
+            v.pos = ctx->points[i++];
+            _set_vertex(ctx, ctx->vertCount++, v);
+        }
+        while (i < pathPointCount) {
+            v.pos = ctx->points[i];
+            _set_vertex(ctx, ctx->vertCount++, v);
+            _add_triangle_indices_unchecked(ctx, firstVertIdx, firstVertIdx + i - 1, firstVertIdx + i);
+            i++;
+        }
+        return;
+    }
+
+    GLUtesselator *tess = gluNewTess();
+    gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
+    gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (GLvoid(*)()) & vertex2);
+    gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (GLvoid(*)()) & begin2);
+    gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (GLvoid(*)()) & combine2);
+
+    gluTessBeginPolygon(tess, ctx);
+
+    while (ptrPath < ctx->pathPtr) {
+        uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
+
+        if (pathPointCount > 2) {
+            VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+            gluTessBeginContour(tess);
+
+            VKVG_IBO_INDEX_TYPE i = 0;
+
+            while (i < pathPointCount) {
+                v.pos       = ctx->points[i + firstPtIdx];
+                double dp[] = {v.pos.x, v.pos.y, 0};
+                _add_vertex(ctx, v);
+                gluTessVertex(tess, dp, (void *)((unsigned long)firstVertIdx + i));
+                i++;
+            }
+            gluTessEndContour(tess);
+
+            // limit batch size here to 1/3 of the ibo index type ability
+            // if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3)
+            // _emit_draw_cmd_undrawn_vertices(ctx);
+        }
+
+        firstPtIdx += pathPointCount;
+        if (_path_has_curves(ctx, ptrPath)) {
+            // skip segments lengths used in stroke
+            ptrPath++;
+            uint32_t totPts = 0;
+            while (totPts < pathPointCount)
+                totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK);
+        } else
+            ptrPath++;
+    }
+
+    gluTessEndPolygon(tess);
+
+    gluDeleteTess(tess);
 }
 #else
-//create fill from current path with ear clipping technic
-void _fill_non_zero (VkvgContext ctx){
-       Vertex v = {{0},ctx->curColor, {0,0,-1}};
-
-       uint32_t ptrPath = 0;
-       uint32_t firstPtIdx = 0;
-
-       while (ptrPath < ctx->pathPtr){
-               uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
-
-               if (pathPointCount > 2) {
-                       VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-            //ear_clip_point* ecps = (ear_clip_point*)malloc(pathPointCount*sizeof(ear_clip_point));
-            ear_clip_point ecps[pathPointCount];
-                       uint32_t ecps_count = pathPointCount;
-                       VKVG_IBO_INDEX_TYPE i = 0;
-
-                       //init points link list
-                       while (i < pathPointCount-1){
-                               v.pos = ctx->points[i+firstPtIdx];
-                               ear_clip_point ecp = {v.pos, firstVertIdx+i, &ecps[i+1]};
-                               ecps[i] = ecp;
-                               _add_vertex(ctx, v);
-                               i++;
-                       }
-
-                       v.pos = ctx->points[i+firstPtIdx];
-                       ear_clip_point ecp = {v.pos, firstVertIdx+i, ecps};
-                       ecps[i] = ecp;
-                       _add_vertex(ctx, v);
-
-                       ear_clip_point* ecp_current = ecps;
-                       uint32_t tries = 0;
-
-                       while (ecps_count > 3) {
-                               if (tries > ecps_count) {
-                                       break;
-                               }
-                               ear_clip_point* v0 = ecp_current->next,
-                                               *v1 = ecp_current, *v2 = ecp_current->next->next;
-                               if (ecp_zcross (v0, v2, v1)<0){
-                                       ecp_current = ecp_current->next;
-                                       tries++;
-                                       continue;
-                               }
-                               ear_clip_point* vP = v2->next;
-                               bool isEar = true;
-                               while (vP!=v1){
-                                       if (ptInTriangle (vP->pos, v0->pos, v2->pos, v1->pos)){
-                                               isEar = false;
-                                               break;
-                                       }
-                                       vP = vP->next;
-                               }
-                               if (isEar){
-                                       _add_triangle_indices (ctx, v0->idx, v1->idx, v2->idx);
-                                       v1->next = v2;
-                                       ecps_count --;
-                                       tries = 0;
-                               }else{
-                                       ecp_current = ecp_current->next;
-                                       tries++;
-                               }
-                       }
-                       if (ecps_count == 3)
-                               _add_triangle_indices(ctx, ecp_current->next->idx, ecp_current->idx, ecp_current->next->next->idx);
-
-                       //limit batch size here to 1/3 of the ibo index type ability
-                       if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3)
-                               _emit_draw_cmd_undrawn_vertices(ctx);
-               }
-
-               firstPtIdx += pathPointCount;
-               if (_path_has_curves (ctx, ptrPath)) {
-                       //skip segments lengths used in stroke
-                       ptrPath++;
-                       uint32_t totPts = 0;
-                       while (totPts < pathPointCount)
-                               totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK);
-               }else
-                       ptrPath++;
-       }
+// create fill from current path with ear clipping technic
+void _fill_non_zero(VkvgContext ctx) {
+    Vertex v = {{0}, ctx->curColor, {0, 0, -1}};
+
+    uint32_t ptrPath    = 0;
+    uint32_t firstPtIdx = 0;
+
+    while (ptrPath < ctx->pathPtr) {
+        uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
+
+        if (pathPointCount > 2) {
+            VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+            // ear_clip_point* ecps = (ear_clip_point*)malloc(pathPointCount*sizeof(ear_clip_point));
+            ear_clip_point      ecps[pathPointCount];
+            uint32_t            ecps_count = pathPointCount;
+            VKVG_IBO_INDEX_TYPE i          = 0;
+
+            // init points link list
+            while (i < pathPointCount - 1) {
+                v.pos              = ctx->points[i + firstPtIdx];
+                ear_clip_point ecp = {v.pos, firstVertIdx + i, &ecps[i + 1]};
+                ecps[i]            = ecp;
+                _add_vertex(ctx, v);
+                i++;
+            }
+
+            v.pos              = ctx->points[i + firstPtIdx];
+            ear_clip_point ecp = {v.pos, firstVertIdx + i, ecps};
+            ecps[i]            = ecp;
+            _add_vertex(ctx, v);
+
+            ear_clip_point *ecp_current = ecps;
+            uint32_t        tries       = 0;
+
+            while (ecps_count > 3) {
+                if (tries > ecps_count) {
+                    break;
+                }
+                ear_clip_point *v0 = ecp_current->next, *v1 = ecp_current, *v2 = ecp_current->next->next;
+                if (ecp_zcross(v0, v2, v1) < 0) {
+                    ecp_current = ecp_current->next;
+                    tries++;
+                    continue;
+                }
+                ear_clip_point *vP    = v2->next;
+                bool            isEar = true;
+                while (vP != v1) {
+                    if (ptInTriangle(vP->pos, v0->pos, v2->pos, v1->pos)) {
+                        isEar = false;
+                        break;
+                    }
+                    vP = vP->next;
+                }
+                if (isEar) {
+                    _add_triangle_indices(ctx, v0->idx, v1->idx, v2->idx);
+                    v1->next = v2;
+                    ecps_count--;
+                    tries = 0;
+                } else {
+                    ecp_current = ecp_current->next;
+                    tries++;
+                }
+            }
+            if (ecps_count == 3)
+                _add_triangle_indices(ctx, ecp_current->next->idx, ecp_current->idx, ecp_current->next->next->idx);
+
+            // limit batch size here to 1/3 of the ibo index type ability
+            if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3)
+                _emit_draw_cmd_undrawn_vertices(ctx);
+        }
+
+        firstPtIdx += pathPointCount;
+        if (_path_has_curves(ctx, ptrPath)) {
+            // skip segments lengths used in stroke
+            ptrPath++;
+            uint32_t totPts = 0;
+            while (totPts < pathPointCount)
+                totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK);
+        } else
+            ptrPath++;
+    }
 }
 #endif
 
-void _vkvg_path_extents (VkvgContext ctx, bool transformed, float *x1, float *y1, float *x2, float *y2) {
-       uint32_t ptrPath = 0;
-       uint32_t firstPtIdx = 0;
-
-       float xMin = FLT_MAX, yMin = FLT_MAX;
-       float xMax = FLT_MIN, yMax = FLT_MIN;
-
-       while (ptrPath < ctx->pathPtr){
-               uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
-
-               for (uint32_t i = firstPtIdx; i < firstPtIdx + pathPointCount; i++){
-                       vec2 p = ctx->points[i];
-                       if (transformed)
-                               vkvg_matrix_transform_point (&ctx->pushConsts.mat, &p.x, &p.y);
-                       if (p.x < xMin)
-                               xMin = p.x;
-                       if (p.x > xMax)
-                               xMax = p.x;
-                       if (p.y < yMin)
-                               yMin = p.y;
-                       if (p.y > yMax)
-                               yMax = p.y;
-               }
-
-               firstPtIdx += pathPointCount;
-               if (_path_has_curves (ctx, ptrPath)) {
-                       //skip segments lengths used in stroke
-                       ptrPath++;
-                       uint32_t totPts = 0;
-                       while (totPts < pathPointCount)
-                               totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK);
-               }else
-                       ptrPath++;
-       }
-       *x1 = xMin;
-       *x2 = xMax;
-       *y1 = yMin;
-       *y2 = yMax;
-}
-
-void _draw_full_screen_quad (VkvgContext ctx, vec4* scissor) {
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_cmd_label_start(ctx->cmd, "_draw_full_screen_quad", DBG_LAB_COLOR_FSQ);
+void _vkvg_path_extents(VkvgContext ctx, bool transformed, float *x1, float *y1, float *x2, float *y2) {
+    uint32_t ptrPath    = 0;
+    uint32_t firstPtIdx = 0;
+
+    float xMin = FLT_MAX, yMin = FLT_MAX;
+    float xMax = FLT_MIN, yMax = FLT_MIN;
+
+    while (ptrPath < ctx->pathPtr) {
+        uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
+
+        for (uint32_t i = firstPtIdx; i < firstPtIdx + pathPointCount; i++) {
+            vec2 p = ctx->points[i];
+            if (transformed)
+                vkvg_matrix_transform_point(&ctx->pushConsts.mat, &p.x, &p.y);
+            if (p.x < xMin)
+                xMin = p.x;
+            if (p.x > xMax)
+                xMax = p.x;
+            if (p.y < yMin)
+                yMin = p.y;
+            if (p.y > yMax)
+                yMax = p.y;
+        }
+
+        firstPtIdx += pathPointCount;
+        if (_path_has_curves(ctx, ptrPath)) {
+            // skip segments lengths used in stroke
+            ptrPath++;
+            uint32_t totPts = 0;
+            while (totPts < pathPointCount)
+                totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK);
+        else
+            ptrPath++;
+    }
+    *x1 = xMin;
+    *x2 = xMax;
+    *y1 = yMin;
+    *y2 = yMax;
+}
+
+void _draw_full_screen_quad(VkvgContext ctx, vec4 *scissor) {
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_cmd_label_start(ctx->cmd, "_draw_full_screen_quad", DBG_LAB_COLOR_FSQ);
 #endif
-       if (scissor) {
-               VkRect2D r = {
-                       {(int32_t)MAX(scissor->xMin, 0), (int32_t)MAX(scissor->yMin, 0)},
-                       {(int32_t)MAX(scissor->xMax - (int32_t)scissor->xMin + 1, 1), (int32_t)MAX(scissor->yMax - (int32_t)scissor->yMin + 1, 1)}
-               };
-               CmdSetScissor(ctx->cmd, 0, 1, &r);
-       }
-
-       uint32_t firstVertIdx = ctx->vertCount;
-       _ensure_vertex_cache_size (ctx, 3);
-
-       _add_vertexf_unchecked (ctx, -1, -1);
-       _add_vertexf_unchecked (ctx,  3, -1);
-       _add_vertexf_unchecked (ctx, -1,  3);
-
-       ctx->curVertOffset = ctx->vertCount;
-
-       ctx->pushConsts.fsq_patternType |= FULLSCREEN_BIT;
-       CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout,
-                                          VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType);
-       CmdDraw (ctx->cmd,3,1,firstVertIdx,0);
-       ctx->pushConsts.fsq_patternType &= ~FULLSCREEN_BIT;
-       CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout,
-                                          VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType);
-       if (scissor)
-               CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds);
-
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_cmd_label_end (ctx->cmd);
+    if (scissor) {
+        VkRect2D r = {{(int32_t)MAX(scissor->xMin, 0), (int32_t)MAX(scissor->yMin, 0)},
+                      {(int32_t)MAX(scissor->xMax - (int32_t)scissor->xMin + 1, 1),
+                       (int32_t)MAX(scissor->yMax - (int32_t)scissor->yMin + 1, 1)}};
+        CmdSetScissor(ctx->cmd, 0, 1, &r);
+    }
+
+    uint32_t firstVertIdx = ctx->vertCount;
+    _ensure_vertex_cache_size(ctx, 3);
+
+    _add_vertexf_unchecked(ctx, -1, -1);
+    _add_vertexf_unchecked(ctx, 3, -1);
+    _add_vertexf_unchecked(ctx, -1, 3);
+
+    ctx->curVertOffset = ctx->vertCount;
+
+    ctx->pushConsts.fsq_patternType |= FULLSCREEN_BIT;
+    CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 24, 4,
+                     &ctx->pushConsts.fsq_patternType);
+    CmdDraw(ctx->cmd, 3, 1, firstVertIdx, 0);
+    ctx->pushConsts.fsq_patternType &= ~FULLSCREEN_BIT;
+    CmdPushConstants(ctx->cmd, ctx->dev->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 24, 4,
+                     &ctx->pushConsts.fsq_patternType);
+    if (scissor)
+        CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds);
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_cmd_label_end(ctx->cmd);
 #endif
 }
 
-void _select_font_face (VkvgContext ctx, const char* name){
-       if (strcmp(ctx->selectedFontName, name) == 0)
-               return;
-       strcpy (ctx->selectedFontName, name);
-       ctx->currentFont = NULL;
-       ctx->currentFontSize = NULL;
+void _select_font_face(VkvgContext ctx, const char *name) {
+    if (strcmp(ctx->selectedFontName, name) == 0)
+        return;
+    strcpy(ctx->selectedFontName, name);
+    ctx->currentFont     = NULL;
+    ctx->currentFontSize = NULL;
 }
index 3e74ae7d1a33fbe31f8d4b8c98abd0c1ff91eab3..4c598b7ff872e8234f68b25f991cf37b12096a5d 100644 (file)
 #include "vkvg_fonts.h"
 
 #if VKVG_RECORDING
-       #include "recording/vkvg_record_internal.h"
+#include "recording/vkvg_record_internal.h"
 #else
-       #define RECORD(ctx,cmd,...)
-       #define RECORD2(ctx,cmd,...)
+#define RECORD(ctx, cmd, ...)
+#define RECORD2(ctx, cmd, ...)
 #endif
 
-#define VKVG_PTS_SIZE                          1024
-#define VKVG_VBO_SIZE                          (VKVG_PTS_SIZE * 4)
-#define VKVG_IBO_SIZE                          (VKVG_VBO_SIZE * 6)
-#define VKVG_PATHES_SIZE                       16
-#define VKVG_ARRAY_THRESHOLD           8
+#define VKVG_PTS_SIZE        1024
+#define VKVG_VBO_SIZE        (VKVG_PTS_SIZE * 4)
+#define VKVG_IBO_SIZE        (VKVG_VBO_SIZE * 6)
+#define VKVG_PATHES_SIZE     16
+#define VKVG_ARRAY_THRESHOLD 8
 
-#define VKVG_IBO_16                                    0
-#define VKVG_IBO_32                                    1
+#define VKVG_IBO_16          0
+#define VKVG_IBO_32          1
 
-#define VKVG_CUR_IBO_TYPE                      VKVG_IBO_32//change this only
+#define VKVG_CUR_IBO_TYPE    VKVG_IBO_32 // change this only
 
 #if VKVG_CUR_IBO_TYPE == VKVG_IBO_16
-       #define VKVG_IBO_MAX                    UINT16_MAX
-       #define VKVG_IBO_INDEX_TYPE             uint16_t
-       #define VKVG_VK_INDEX_TYPE              VK_INDEX_TYPE_UINT16
+#define VKVG_IBO_MAX        UINT16_MAX
+#define VKVG_IBO_INDEX_TYPE uint16_t
+#define VKVG_VK_INDEX_TYPE  VK_INDEX_TYPE_UINT16
 #else
-       #define VKVG_IBO_MAX                    UINT32_MAX
-       #define VKVG_IBO_INDEX_TYPE             uint32_t
-       #define VKVG_VK_INDEX_TYPE              VK_INDEX_TYPE_UINT32
+#define VKVG_IBO_MAX        UINT32_MAX
+#define VKVG_IBO_INDEX_TYPE uint32_t
+#define VKVG_VK_INDEX_TYPE  VK_INDEX_TYPE_UINT32
 #endif
 
-#define FULLSCREEN_BIT 0x10000000
-#define SRCTYPE_MASK   0x000000FF
+#define FULLSCREEN_BIT         0x10000000
+#define SRCTYPE_MASK           0x000000FF
 
 #define CreateRgba(r, g, b, a) ((a << 24) | (r << 16) | (g << 8) | b)
 #ifdef VKVG_PREMULT_ALPHA
-       #define CreateRgbaf(r, g, b, a) (((int)(a * 255.0f) << 24) | ((int)(b * a * 255.0f) << 16) | ((int)(g * a * 255.0f) << 8) | (int)(r * a * 255.0f))
+#define CreateRgbaf(r, g, b, a)                                                                                        \
+    (((int)(a * 255.0f) << 24) | ((int)(b * a * 255.0f) << 16) | ((int)(g * a * 255.0f) << 8) | (int)(r * a * 255.0f))
 #else
-       #define CreateRgbaf(r, g, b, a) (((int)(a * 255.0f) << 24) | ((int)(b * 255.0f) << 16) | ((int)(g * 255.0f) << 8) | (int)(r * 255.0f))
+#define CreateRgbaf(r, g, b, a)                                                                                        \
+    (((int)(a * 255.0f) << 24) | ((int)(b * 255.0f) << 16) | ((int)(g * 255.0f) << 8) | (int)(r * 255.0f))
 #endif
 
 typedef struct {
-       vec2            pos;
-       uint32_t        color;
-       vec3            uv;
+    vec2     pos;
+    uint32_t color;
+    vec3     uv;
 } Vertex;
 
 typedef struct {
-       vec4                    source;
-       vec2                    size;
-       uint32_t                fsq_patternType;
-       float                   opacity;
-       vkvg_matrix_t   mat;
-       vkvg_matrix_t   matInv;
+    vec4          source;
+    vec2          size;
+    uint32_t      fsq_patternType;
+    float         opacity;
+    vkvg_matrix_t mat;
+    vkvg_matrix_t matInv;
 } push_constants;
 
 /* context.curClipState may be one of the following, it's set
@@ -90,249 +92,244 @@ typedef struct {
  * - clip_saved: context is clipped and the clip region is saved at that level.
  */
 typedef enum {
-       vkvg_clip_state_none            = 0x00,
-       vkvg_clip_state_clear           = 0x01,
-       vkvg_clip_state_clip            = 0x02,
-       vkvg_clip_state_clip_saved      = 0x06,
+    vkvg_clip_state_none       = 0x00,
+    vkvg_clip_state_clear      = 0x01,
+    vkvg_clip_state_clip       = 0x02,
+    vkvg_clip_state_clip_saved = 0x06,
 } vkvg_clip_state_t;
 
 typedef struct _vkvg_context_save_t {
-       struct _vkvg_context_save_t* pNext;
-
-       float                                   lineWidth;
-       float                                   miterLimit;
-       uint32_t                                dashCount;              //value count in dash array, 0 if dash not set.
-       float                                   dashOffset;             //an offset for dash
-       float*                                  dashes;                 //an array of alternate lengths of on and off stroke.
-
-       vkvg_operator_t                 curOperator;
-       vkvg_line_cap_t                 lineCap;
-       vkvg_line_join_t                lineJoint;
-       vkvg_fill_rule_t                curFillRule;
-
-       long                                    selectedCharSize; /* Font size*/
-       char                                    selectedFontName[FONT_NAME_MAX_SIZE];
-       _vkvg_font_identity_t   selectedFont;      //hold current face and size before cache addition
-       _vkvg_font_identity_t*  currentFont;       //font ready for lookup
-       vkvg_direction_t                textDirection;
-       push_constants                  pushConsts;
-       uint32_t                                curColor;
-       VkvgPattern                             pattern;
-       vkvg_clip_state_t               clippingState;
+    struct _vkvg_context_save_t *pNext;
+
+    float    lineWidth;
+    float    miterLimit;
+    uint32_t dashCount;  // value count in dash array, 0 if dash not set.
+    float    dashOffset; // an offset for dash
+    float   *dashes;     // an array of alternate lengths of on and off stroke.
+
+    vkvg_operator_t  curOperator;
+    vkvg_line_cap_t  lineCap;
+    vkvg_line_join_t lineJoint;
+    vkvg_fill_rule_t curFillRule;
+
+    long                   selectedCharSize; /* Font size*/
+    char                   selectedFontName[FONT_NAME_MAX_SIZE];
+    _vkvg_font_identity_t  selectedFont; // hold current face and size before cache addition
+    _vkvg_font_identity_t *currentFont;  // font ready for lookup
+    vkvg_direction_t       textDirection;
+    push_constants         pushConsts;
+    uint32_t               curColor;
+    VkvgPattern            pattern;
+    vkvg_clip_state_t      clippingState;
 
 } vkvg_context_save_t;
 
 typedef struct _vkvg_context_t {
-       vkvg_status_t           status;
-       uint32_t                        references;             //reference count
+    vkvg_status_t status;
+    uint32_t      references; // reference count
 
-       VkvgDevice                      dev;
-       VkvgSurface                     pSurf;                  //surface bound to context, set on creation of ctx
+    VkvgDevice  dev;
+    VkvgSurface pSurf; // surface bound to context, set on creation of ctx
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       uint64_t                        timelineStep;   //context cmd last submission timeline id.
+    uint64_t timelineStep; // context cmd last submission timeline id.
 #else
-       VkFence                         flushFence;             //context fence
+    VkFence flushFence; // context fence
 #endif
-       //VkDescriptorImageInfo sourceDescriptor;       //Store view/sampler in context
+    // VkDescriptorImageInfo sourceDescriptor; //Store view/sampler in context
 
-       VkCommandPool           cmdPool;                //local pools ensure thread safety
-       VkCommandBuffer         cmdBuffers[2];  //double cmd buff for context operations
-       VkCommandBuffer         cmd;                    //current recording buffer
-       bool                            cmdStarted;             //prevent flushing empty renderpass
-       bool                            pushCstDirty;   //prevent pushing to gpu if not requested
-       VkDescriptorPool        descriptorPool; //one pool per thread
-       VkDescriptorSet         dsFont;                 //fonts glyphs texture atlas descriptor (local for thread safety)
-       VkDescriptorSet         dsSrc;                  //source ds
-       VkDescriptorSet         dsGrad;                 //gradient uniform buffer
+    VkCommandPool    cmdPool;        // local pools ensure thread safety
+    VkCommandBuffer  cmdBuffers[2];  // double cmd buff for context operations
+    VkCommandBuffer  cmd;            // current recording buffer
+    bool             cmdStarted;     // prevent flushing empty renderpass
+    bool             pushCstDirty;   // prevent pushing to gpu if not requested
+    VkDescriptorPool descriptorPool; // one pool per thread
+    VkDescriptorSet  dsFont;         // fonts glyphs texture atlas descriptor (local for thread safety)
+    VkDescriptorSet  dsSrc;          // source ds
+    VkDescriptorSet  dsGrad;         // gradient uniform buffer
 
-       VkhImage                        fontCacheImg;   //current font cache, may not be the last one, updated only if new glyphs are
-                                                                               //uploaded by the current context
+    VkhImage fontCacheImg; // current font cache, may not be the last one, updated only if new glyphs are
+                           // uploaded by the current context
 
-       VkRect2D                        bounds;
+    VkRect2D bounds;
 
-       uint32_t                        curColor;
+    uint32_t curColor;
 
 #if VKVG_FILL_NZ_GLUTESS
-       void (*vertex_cb)(VKVG_IBO_INDEX_TYPE, VkvgContext);//tesselator vertex callback
-       VKVG_IBO_INDEX_TYPE tesselator_fan_start;
-       uint32_t                        tesselator_idx_counter;
+    void (*vertex_cb)(VKVG_IBO_INDEX_TYPE, VkvgContext); // tesselator vertex callback
+    VKVG_IBO_INDEX_TYPE tesselator_fan_start;
+    uint32_t            tesselator_idx_counter;
 #endif
 
 #if VKVG_RECORDING
-       vkvg_recording_t*       recording;
+    vkvg_recording_t *recording;
 #endif
 
-       vkh_buffer_t            uboGrad;                //uniform buff obj holdings gradient infos
-
-       //vk buffers, holds data until flush
-       vkh_buffer_t            indices;                //index buffer with persistent map memory
-       uint32_t                        sizeIBO;                //size of vk ibo
-       uint32_t                        sizeIndices;    //reserved size
-       uint32_t                        indCount;               //current indice count
-
-       uint32_t                        curIndStart;    //last index recorded in cmd buff
-       VKVG_IBO_INDEX_TYPE     curVertOffset;  //vertex offset in draw indexed command
-
-       vkh_buffer_t            vertices;               //vertex buffer with persistent mapped memory
-       uint32_t                        sizeVBO;                //size of vk vbo size
-       uint32_t                        sizeVertices;   //reserved size
-       uint32_t                        vertCount;              //effective vertices count
-
-       Vertex*                         vertexCache;
-       VKVG_IBO_INDEX_TYPE* indexCache;
-
-       //pathes, exists until stroke of fill
-       vec2*                           points;                 //points array
-       uint32_t                        sizePoints;             //reserved size
-       uint32_t                        pointCount;             //effective points count
-
-       //pathes array is a list of point count per segment
-       uint32_t                        pathPtr;                //pointer in the path array
-       uint32_t*                       pathes;
-       uint32_t                        sizePathes;
-
-       uint32_t                        segmentPtr;             //current segment count in current path having curves
-       uint32_t                        subpathCount;   //store count of subpath, not straight forward to retrieve from segmented path array
-       bool                            simpleConvex;   //true if path is single rect or concave closed curve.
-
-       float                           lineWidth;
-       float                           miterLimit;
-       uint32_t                        dashCount;              //value count in dash array, 0 if dash not set.
-       float                           dashOffset;             //an offset for dash
-       float*                          dashes;                 //an array of alternate lengths of on and off stroke.
-
-       vkvg_operator_t         curOperator;
-       vkvg_line_cap_t         lineCap;
-       vkvg_line_join_t        lineJoin;
-       vkvg_fill_rule_t        curFillRule;
-
-       long                            selectedCharSize; /* Font size*/
-       char                            selectedFontName[FONT_NAME_MAX_SIZE];
-       //_vkvg_font_t            selectedFont;         //hold current face and size before cache addition
-       _vkvg_font_identity_t*           currentFont;           //font pointing to cached fonts identity
-       _vkvg_font_t*           currentFontSize;        //font structure by size ready for lookup
-       vkvg_direction_t        textDirection;
-
-       push_constants          pushConsts;
-       VkvgPattern                     pattern;
-
-       vkvg_context_save_t* pSavedCtxs;                //last ctx saved ptr
-       uint8_t                         curSavBit;                      //current stencil bit used to save context, 6 bits used by stencil for save/restore
-       VkhImage*                       savedStencils;          //additional image for saving contexes once more than 6 save/restore are reached
-       vkvg_clip_state_t       curClipState;           //current clipping status relative to the previous saved one or clear state if none.
-
-       VkClearRect                     clearRect;
-       VkRenderPassBeginInfo renderPassBeginInfo;
+    vkh_buffer_t uboGrad; // uniform buff obj holdings gradient infos
+
+    // vk buffers, holds data until flush
+    vkh_buffer_t indices;     // index buffer with persistent map memory
+    uint32_t     sizeIBO;     // size of vk ibo
+    uint32_t     sizeIndices; // reserved size
+    uint32_t     indCount;    // current indice count
+
+    uint32_t            curIndStart;   // last index recorded in cmd buff
+    VKVG_IBO_INDEX_TYPE curVertOffset; // vertex offset in draw indexed command
+
+    vkh_buffer_t vertices;     // vertex buffer with persistent mapped memory
+    uint32_t     sizeVBO;      // size of vk vbo size
+    uint32_t     sizeVertices; // reserved size
+    uint32_t     vertCount;    // effective vertices count
+
+    Vertex              *vertexCache;
+    VKVG_IBO_INDEX_TYPE *indexCache;
+
+    // pathes, exists until stroke of fill
+    vec2    *points;     // points array
+    uint32_t sizePoints; // reserved size
+    uint32_t pointCount; // effective points count
+
+    // pathes array is a list of point count per segment
+    uint32_t  pathPtr; // pointer in the path array
+    uint32_t *pathes;
+    uint32_t  sizePathes;
+
+    uint32_t segmentPtr;   // current segment count in current path having curves
+    uint32_t subpathCount; // store count of subpath, not straight forward to retrieve from segmented path array
+    bool     simpleConvex; // true if path is single rect or concave closed curve.
+
+    float    lineWidth;
+    float    miterLimit;
+    uint32_t dashCount;  // value count in dash array, 0 if dash not set.
+    float    dashOffset; // an offset for dash
+    float   *dashes;     // an array of alternate lengths of on and off stroke.
+
+    vkvg_operator_t  curOperator;
+    vkvg_line_cap_t  lineCap;
+    vkvg_line_join_t lineJoin;
+    vkvg_fill_rule_t curFillRule;
+
+    long selectedCharSize; /* Font size*/
+    char selectedFontName[FONT_NAME_MAX_SIZE];
+    //_vkvg_font_t               selectedFont;         //hold current face and size before cache addition
+    _vkvg_font_identity_t *currentFont;     // font pointing to cached fonts identity
+    _vkvg_font_t          *currentFontSize; // font structure by size ready for lookup
+    vkvg_direction_t       textDirection;
+
+    push_constants pushConsts;
+    VkvgPattern    pattern;
+
+    vkvg_context_save_t *pSavedCtxs; // last ctx saved ptr
+    uint8_t           curSavBit; // current stencil bit used to save context, 6 bits used by stencil for save/restore
+    VkhImage         *savedStencils; // additional image for saving contexes once more than 6 save/restore are reached
+    vkvg_clip_state_t curClipState;  // current clipping status relative to the previous saved one or clear state if
+                                    // none.
+
+    VkClearRect           clearRect;
+    VkRenderPassBeginInfo renderPassBeginInfo;
 } vkvg_context;
 
 typedef struct _ear_clip_point {
-       vec2                                    pos;
-       VKVG_IBO_INDEX_TYPE             idx;
-       struct _ear_clip_point* next;
+    vec2                    pos;
+    VKVG_IBO_INDEX_TYPE     idx;
+    struct _ear_clip_point *next;
 } ear_clip_point;
 
 typedef struct {
-       bool            dashOn;
-       uint32_t        curDash;                //current dash index
-       float           curDashOffset;  //cur dash offset between defined path point and last dash segment(on/off) start
-       float           totDashLength;  //total length of dashes
-       vec2            normal;
+    bool     dashOn;
+    uint32_t curDash;       // current dash index
+    float    curDashOffset; // cur dash offset between defined path point and last dash segment(on/off) start
+    float    totDashLength; // total length of dashes
+    vec2     normal;
 } dash_context_t;
 
 typedef struct {
-       uint32_t        iL;
-       uint32_t        iR;
-       uint32_t        cp;//current point
-
-       VKVG_IBO_INDEX_TYPE firstIdx;//save first point idx for closed path
-       float           hw;                             //stroke half width, computed once.
-       float           lhMax;                  //miter limit * line width
-       float           arcStep;                //cached arcStep, prevent compute multiple times for same stroke, 0 if not yet computed
+    uint32_t iL;
+    uint32_t iR;
+    uint32_t cp; // current point
+
+    VKVG_IBO_INDEX_TYPE firstIdx; // save first point idx for closed path
+    float               hw;       // stroke half width, computed once.
+    float               lhMax;    // miter limit * line width
+    float arcStep; // cached arcStep, prevent compute multiple times for same stroke, 0 if not yet computed
 } stroke_context_t;
 
-void _check_vertex_cache_size  (VkvgContext ctx);
-void _ensure_vertex_cache_size (VkvgContext ctx, uint32_t addedVerticesCount);
-void _resize_vertex_cache              (VkvgContext ctx, uint32_t newSize);
-
-void _check_index_cache_size   (VkvgContext ctx);
-void _ensure_index_cache_size  (VkvgContext ctx, uint32_t addedIndicesCount);
-void _resize_index_cache               (VkvgContext ctx, uint32_t newSize);
-
-bool _check_pathes_array               (VkvgContext ctx);
-
-bool _current_path_is_empty            (VkvgContext ctx);
-void _finish_path                              (VkvgContext ctx);
-void _clear_path                               (VkvgContext ctx);
-void _remove_last_point                        (VkvgContext ctx);
-bool _path_is_closed                   (VkvgContext ctx, uint32_t ptrPath);
-void _set_curve_start                  (VkvgContext ctx);
-void _set_curve_end                            (VkvgContext ctx);
-bool _path_has_curves                  (VkvgContext ctx, uint32_t ptrPath);
-
-float _normalizeAngle                  (float a);
-float _get_arc_step                            (VkvgContext ctx, float radius);
-
-vec2 _get_current_position             (VkvgContext ctx);
-void _add_point                                        (VkvgContext ctx, float x, float y);
-
-void _resetMinMax                              (VkvgContext ctx);
-void _vkvg_path_extents                        (VkvgContext ctx, bool transformed, float *x1, float *y1, float *x2, float *y2);
-void _draw_stoke_cap                   (VkvgContext ctx, stroke_context_t* str, vec2 p0, vec2 n, bool isStart);
-void _draw_segment                             (VkvgContext ctx, stroke_context_t* str, dash_context_t* dc, bool isCurve);
-float _draw_dashed_segment             (VkvgContext ctx, stroke_context_t *str, dash_context_t* dc, bool isCurve);
-bool _build_vb_step                            (VkvgContext ctx, stroke_context_t *str, bool isCurve);
-
-void _poly_fill                                        (VkvgContext ctx, vec4 *bounds);
-void _fill_non_zero                            (VkvgContext ctx);
-void _draw_full_screen_quad            (VkvgContext ctx, vec4 *scissor);
-
-void _create_gradient_buff             (VkvgContext ctx);
-void _create_vertices_buff             (VkvgContext ctx);
-void _add_vertex                               (VkvgContext ctx, Vertex v);
-void _add_vertexf                              (VkvgContext ctx, float x, float y);
-void _set_vertex                               (VkvgContext ctx, uint32_t idx, Vertex v);
-void _add_triangle_indices             (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2);
-void _add_tri_indices_for_rect (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i);
-
-void _vao_add_rectangle                        (VkvgContext ctx, float x, float y, float width, float height);
-
-void _bind_draw_pipeline               (VkvgContext ctx);
-void _create_cmd_buff                  (VkvgContext ctx);
-void _check_vao_size                   (VkvgContext ctx);
-void _flush_cmd_buff                   (VkvgContext ctx);
-void _ensure_renderpass_is_started             (VkvgContext ctx);
-void _emit_draw_cmd_undrawn_vertices   (VkvgContext ctx);
-void _flush_cmd_until_vx_base  (VkvgContext ctx);
-bool _wait_ctx_flush_end               (VkvgContext ctx);
-bool _wait_and_submit_cmd              (VkvgContext ctx);
-void _update_push_constants            (VkvgContext ctx);
-void _update_cur_pattern               (VkvgContext ctx, VkvgPattern pat);
-void _set_mat_inv_and_vkCmdPush (VkvgContext ctx);
-void _start_cmd_for_render_pass (VkvgContext ctx);
-
-void _createDescriptorPool             (VkvgContext ctx);
-void _init_descriptor_sets             (VkvgContext ctx);
-void _update_descriptor_set            (VkvgContext ctx, VkhImage img, VkDescriptorSet ds);
-void _update_gradient_desc_set (VkvgContext ctx);
-void _free_ctx_save                            (vkvg_context_save_t* sav);
+void _check_vertex_cache_size(VkvgContext ctx);
+void _ensure_vertex_cache_size(VkvgContext ctx, uint32_t addedVerticesCount);
+void _resize_vertex_cache(VkvgContext ctx, uint32_t newSize);
+
+void _check_index_cache_size(VkvgContext ctx);
+void _ensure_index_cache_size(VkvgContext ctx, uint32_t addedIndicesCount);
+void _resize_index_cache(VkvgContext ctx, uint32_t newSize);
+
+bool _check_pathes_array(VkvgContext ctx);
+
+bool _current_path_is_empty(VkvgContext ctx);
+void _finish_path(VkvgContext ctx);
+void _clear_path(VkvgContext ctx);
+void _remove_last_point(VkvgContext ctx);
+bool _path_is_closed(VkvgContext ctx, uint32_t ptrPath);
+void _set_curve_start(VkvgContext ctx);
+void _set_curve_end(VkvgContext ctx);
+bool _path_has_curves(VkvgContext ctx, uint32_t ptrPath);
+
+float _normalizeAngle(float a);
+float _get_arc_step(VkvgContext ctx, float radius);
+
+vec2 _get_current_position(VkvgContext ctx);
+void _add_point(VkvgContext ctx, float x, float y);
+
+void  _resetMinMax(VkvgContext ctx);
+void  _vkvg_path_extents(VkvgContext ctx, bool transformed, float *x1, float *y1, float *x2, float *y2);
+void  _draw_stoke_cap(VkvgContext ctx, stroke_context_t *str, vec2 p0, vec2 n, bool isStart);
+void  _draw_segment(VkvgContext ctx, stroke_context_t *str, dash_context_t *dc, bool isCurve);
+float _draw_dashed_segment(VkvgContext ctx, stroke_context_t *str, dash_context_t *dc, bool isCurve);
+bool  _build_vb_step(VkvgContext ctx, stroke_context_t *str, bool isCurve);
+
+void _poly_fill(VkvgContext ctx, vec4 *bounds);
+void _fill_non_zero(VkvgContext ctx);
+void _draw_full_screen_quad(VkvgContext ctx, vec4 *scissor);
+
+void _create_gradient_buff(VkvgContext ctx);
+void _create_vertices_buff(VkvgContext ctx);
+void _add_vertex(VkvgContext ctx, Vertex v);
+void _add_vertexf(VkvgContext ctx, float x, float y);
+void _set_vertex(VkvgContext ctx, uint32_t idx, Vertex v);
+void _add_triangle_indices(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2);
+void _add_tri_indices_for_rect(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i);
+
+void _vao_add_rectangle(VkvgContext ctx, float x, float y, float width, float height);
+
+void _bind_draw_pipeline(VkvgContext ctx);
+void _create_cmd_buff(VkvgContext ctx);
+void _check_vao_size(VkvgContext ctx);
+void _flush_cmd_buff(VkvgContext ctx);
+void _ensure_renderpass_is_started(VkvgContext ctx);
+void _emit_draw_cmd_undrawn_vertices(VkvgContext ctx);
+void _flush_cmd_until_vx_base(VkvgContext ctx);
+bool _wait_ctx_flush_end(VkvgContext ctx);
+bool _wait_and_submit_cmd(VkvgContext ctx);
+void _update_push_constants(VkvgContext ctx);
+void _update_cur_pattern(VkvgContext ctx, VkvgPattern pat);
+void _set_mat_inv_and_vkCmdPush(VkvgContext ctx);
+void _start_cmd_for_render_pass(VkvgContext ctx);
+
+void _createDescriptorPool(VkvgContext ctx);
+void _init_descriptor_sets(VkvgContext ctx);
+void _update_descriptor_set(VkvgContext ctx, VkhImage img, VkDescriptorSet ds);
+void _update_gradient_desc_set(VkvgContext ctx);
+void _free_ctx_save(vkvg_context_save_t *sav);
 void _release_context_ressources(VkvgContext ctx);
 
-static inline float vec2_zcross (vec2 v1, vec2 v2){
-       return v1.x*v2.y-v1.y*v2.x;
+static inline float vec2_zcross(vec2 v1, vec2 v2) { return v1.x * v2.y - v1.y * v2.x; }
+static inline float ecp_zcross(ear_clip_point *p0, ear_clip_point *p1, ear_clip_point *p2) {
+    return vec2_zcross(vec2_sub(p1->pos, p0->pos), vec2_sub(p2->pos, p0->pos));
 }
-static inline float ecp_zcross (ear_clip_point* p0, ear_clip_point* p1, ear_clip_point* p2){
-       return vec2_zcross (vec2_sub (p1->pos, p0->pos), vec2_sub (p2->pos, p0->pos));
-}
-void _recursive_bezier(VkvgContext ctx, float distanceTolerance,
-                                          float x1, float y1, float x2, float y2,
-                                          float x3, float y3, float x4, float y4,
-                                          unsigned level);
-void _bezier (VkvgContext ctx,
-                         float x1, float y1, float x2, float y2,
-                         float x3, float y3, float x4, float y4);
-void _line_to          (VkvgContext ctx, float x, float y);
-void _elliptic_arc     (VkvgContext ctx, float x1, float y1, float x2, float y2,
-                                        bool largeArc, bool counterClockWise, float _rx, float _ry, float phi);
-
-void _select_font_face                 (VkvgContext ctx, const char* name);
+void _recursive_bezier(VkvgContext ctx, float distanceTolerance, float x1, float y1, float x2, float y2, float x3,
+                       float y3, float x4, float y4, unsigned level);
+void _bezier(VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4);
+void _line_to(VkvgContext ctx, float x, float y);
+void _elliptic_arc(VkvgContext ctx, float x1, float y1, float x2, float y2, bool largeArc, bool counterClockWise,
+                   float _rx, float _ry, float phi);
+
+void _select_font_face(VkvgContext ctx, const char *name);
 #endif
index 893d23efff336e066328a36f7e8ad4853e07641a..ad54fea3d0f7cfce003a0653e5199b7ff962efad 100644 (file)
 #include "vkh_phyinfo.h"
 #include "vk_mem_alloc.h"
 
-#define TRY_LOAD_DEVICE_EXT(ext) {                                                             \
-if (vkh_phyinfo_try_get_extension_properties(pi, #ext, NULL))  \
-       enabledExts[enabledExtsCount++] = #ext;                                         \
-}
-void vkvg_device_set_context_cache_size (VkvgDevice dev, uint32_t maxCount) {
-       if (maxCount == dev->cachedContextMaxCount)
-               return;
-
-       dev->cachedContextMaxCount = maxCount;
-
-       _cached_ctx* cur = dev->cachedContextLast;
-       while (cur && dev->cachedContextCount > dev->cachedContextMaxCount) {
-               _release_context_ressources (cur->ctx);
-               _cached_ctx* prev = cur;
-               cur = cur->pNext;
-               free (prev);
-               dev->cachedContextCount--;
-       }
-       dev->cachedContextLast = cur;
+#define TRY_LOAD_DEVICE_EXT(ext)                                                                                       \
+    {                                                                                                                  \
+        if (vkh_phyinfo_try_get_extension_properties(pi, #ext, NULL))                                                  \
+            enabledExts[enabledExtsCount++] = #ext;                                                                    \
+    }
+void vkvg_device_set_context_cache_size(VkvgDevice dev, uint32_t maxCount) {
+    if (maxCount == dev->cachedContextMaxCount)
+        return;
+
+    dev->cachedContextMaxCount = maxCount;
+
+    _cached_ctx *cur = dev->cachedContextLast;
+    while (cur && dev->cachedContextCount > dev->cachedContextMaxCount) {
+        _release_context_ressources(cur->ctx);
+        _cached_ctx *prev = cur;
+        cur               = cur->pNext;
+        free(prev);
+        dev->cachedContextCount--;
+    }
+    dev->cachedContextLast = cur;
 }
-void _device_init (VkvgDevice dev, const vkvg_device_create_info_t* info) {
-    dev->vkDev = info->vkdev;
-    dev->phy   = info->phy;
+void _device_init(VkvgDevice dev, const vkvg_device_create_info_t *info) {
+    dev->vkDev    = info->vkdev;
+    dev->phy      = info->phy;
     dev->instance = info->inst;
-       dev->hdpi       = 72;
-    dev->vdpi  = 72;
-    dev->samples= info->samples;
-       if (dev->samples == VK_SAMPLE_COUNT_1_BIT)
-               dev->deferredResolve = false;
+    dev->hdpi     = 72;
+    dev->vdpi     = 72;
+    dev->samples  = info->samples;
+    if (dev->samples == VK_SAMPLE_COUNT_1_BIT)
+        dev->deferredResolve = false;
     else
         dev->deferredResolve = info->deferredResolve;
 
-       dev->cachedContextMaxCount = VKVG_MAX_CACHED_CONTEXT_COUNT;
+    dev->cachedContextMaxCount = VKVG_MAX_CACHED_CONTEXT_COUNT;
 
 #if VKVG_DBG_STATS
-       dev->debug_stats = (vkvg_debug_stats_t) {0};
+    dev->debug_stats = (vkvg_debug_stats_t){0};
 #endif
 
-       VkFormat format = FB_COLOR_FORMAT;
+    VkFormat format = FB_COLOR_FORMAT;
 
-       _device_check_best_image_tiling(dev, format);
-       if (dev->status != VKVG_STATUS_SUCCESS)
-               return;
+    _device_check_best_image_tiling(dev, format);
+    if (dev->status != VKVG_STATUS_SUCCESS)
+        return;
 
-       if (!_device_init_function_pointers (dev)){
-               dev->status = VKVG_STATUS_NULL_POINTER;
-               return;
-       }
+    if (!_device_init_function_pointers(dev)) {
+        dev->status = VKVG_STATUS_NULL_POINTER;
+        return;
+    }
 
-       VkhPhyInfo phyInfos = vkh_phyinfo_create (dev->phy, NULL);
+    VkhPhyInfo phyInfos = vkh_phyinfo_create(dev->phy, NULL);
 
     dev->phyMemProps = phyInfos->memProps;
-    dev->gQueue = vkh_queue_create ((VkhDevice)dev, info->qFamIdx, info->qIndex);
-       //mtx_init (&dev->gQMutex, mtx_plain);
+    dev->gQueue      = vkh_queue_create((VkhDevice)dev, info->qFamIdx, info->qIndex);
+    // mtx_init (&dev->gQMutex, mtx_plain);
 
-       vkh_phyinfo_destroy (phyInfos);
+    vkh_phyinfo_destroy(phyInfos);
 
 #ifdef VKH_USE_VMA
-       VmaAllocatorCreateInfo allocatorInfo = {
-        .physicalDevice = info->phy,
-        .device = info->vkdev
-       };
-       vmaCreateAllocator(&allocatorInfo, (VmaAllocator*)&dev->allocator);
+    VmaAllocatorCreateInfo allocatorInfo = {.physicalDevice = info->phy, .device = info->vkdev};
+    vmaCreateAllocator(&allocatorInfo, (VmaAllocator *)&dev->allocator);
 #endif
 
-       dev->cmdPool= vkh_cmd_pool_create               ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
-       dev->cmd        = vkh_cmd_buff_create           ((VkhDevice)dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
-       dev->fence      = vkh_fence_create_signaled ((VkhDevice)dev);
-
-       _device_create_pipeline_cache           (dev);
-       _fonts_cache_create                                     (dev);
-       if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT){
-               dev->renderPass                                 = _device_createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
-               dev->renderPass_ClearStencil    = _device_createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
-               dev->renderPass_ClearAll                = _device_createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
-       }else{
-               dev->renderPass                                 = _device_createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
-               dev->renderPass_ClearStencil    = _device_createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
-               dev->renderPass_ClearAll                = _device_createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
-       }
-       _device_createDescriptorSetLayout       (dev);
-       _device_setupPipelines                          (dev);
-
-       _device_create_empty_texture            (dev, format, dev->supportedTiling);
+    dev->cmdPool =
+        vkh_cmd_pool_create((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
+    dev->cmd   = vkh_cmd_buff_create((VkhDevice)dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+    dev->fence = vkh_fence_create_signaled((VkhDevice)dev);
+
+    _device_create_pipeline_cache(dev);
+    _fonts_cache_create(dev);
+    if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT) {
+        dev->renderPass =
+            _device_createRenderPassNoResolve(dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
+        dev->renderPass_ClearStencil =
+            _device_createRenderPassNoResolve(dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
+        dev->renderPass_ClearAll =
+            _device_createRenderPassNoResolve(dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
+    } else {
+        dev->renderPass = _device_createRenderPassMS(dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
+        dev->renderPass_ClearStencil =
+            _device_createRenderPassMS(dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
+        dev->renderPass_ClearAll =
+            _device_createRenderPassMS(dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
+    }
+    _device_createDescriptorSetLayout(dev);
+    _device_setupPipelines(dev);
+
+    _device_create_empty_texture(dev, format, dev->supportedTiling);
 
 #ifdef DEBUG
-       #if defined(__linux__) && defined(__GLIBC__)
-               _linux_register_error_handler ();
-       #endif
-       #ifdef VKVG_DBG_UTILS
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)dev->cmdPool, "Device Cmd Pool");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)dev->cmd, "Device Cmd Buff");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)dev->fence, "Device Fence");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass, "RP load img/stencil");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearStencil, "RP clear stencil");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearAll, "RP clear all");
-
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslSrc, "DSLayout SOURCE");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslFont, "DSLayout FONT");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslGrad, "DSLayout GRADIENT");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)dev->pipelineLayout, "PLLayout dev");
-
-               #ifndef __APPLE__
-                       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelinePolyFill, "PL Poly fill");
-               #endif
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelineClipping, "PL Clipping");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_OVER, "PL draw Over");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_SUB, "PL draw Substract");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_CLEAR, "PL draw Clear");
-
-               vkh_image_set_name(dev->emptyImg, "empty IMG");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(dev->emptyImg), "empty IMG VIEW");
-               vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(dev->emptyImg), "empty IMG SAMPLER");
-       #endif
+#if defined(__linux__) && defined(__GLIBC__)
+    _linux_register_error_handler();
 #endif
-       dev->status = VKVG_STATUS_SUCCESS;
-}
+#ifdef VKVG_DBG_UTILS
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)dev->cmdPool, "Device Cmd Pool");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)dev->cmd, "Device Cmd Buff");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)dev->fence, "Device Fence");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass,
+                               "RP load img/stencil");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearStencil,
+                               "RP clear stencil");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearAll,
+                               "RP clear all");
+
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslSrc,
+                               "DSLayout SOURCE");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslFont,
+                               "DSLayout FONT");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslGrad,
+                               "DSLayout GRADIENT");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)dev->pipelineLayout,
+                               "PLLayout dev");
 
-#define _CHECK_INST_EXT(ext)\
-if (vkh_instance_extension_supported(#ext)) {  \
-       if (pExtensions)                                                        \
-          pExtensions[*pExtCount] = #ext;                      \
-       (*pExtCount)++;                                                         \
+#ifndef __APPLE__
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelinePolyFill,
+                               "PL Poly fill");
+#endif
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelineClipping, "PL Clipping");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_OVER, "PL draw Over");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_SUB, "PL draw Substract");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_CLEAR, "PL draw Clear");
+
+    vkh_image_set_name(dev->emptyImg, "empty IMG");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(dev->emptyImg),
+                               "empty IMG VIEW");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(dev->emptyImg),
+                               "empty IMG SAMPLER");
+#endif
+#endif
+    dev->status = VKVG_STATUS_SUCCESS;
 }
-void vkvg_get_required_instance_extensions (const char** pExtensions, uint32_t* pExtCount) {
-       *pExtCount = 0;
 
-       vkh_instance_extensions_check_init ();
+#define _CHECK_INST_EXT(ext)                                                                                           \
+    if (vkh_instance_extension_supported(#ext)) {                                                                      \
+        if (pExtensions)                                                                                               \
+            pExtensions[*pExtCount] = #ext;                                                                            \
+        (*pExtCount)++;                                                                                                \
+    }
+void vkvg_get_required_instance_extensions(const char **pExtensions, uint32_t *pExtCount) {
+    *pExtCount = 0;
+
+    vkh_instance_extensions_check_init();
 
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       _CHECK_INST_EXT(VK_EXT_debug_utils)
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    _CHECK_INST_EXT(VK_EXT_debug_utils)
 #endif
-       _CHECK_INST_EXT(VK_KHR_get_physical_device_properties2)
+    _CHECK_INST_EXT(VK_KHR_get_physical_device_properties2)
 
-       vkh_instance_extensions_check_release();
+    vkh_instance_extensions_check_release();
 }
 
-bool _get_dev_extension_is_supported (VkExtensionProperties* pExtensionProperties, uint32_t extensionCount, const char* name) {
-       for (uint32_t i=0; i<extensionCount; i++) {
-               if (strcmp(name, pExtensionProperties[i].extensionName)==0)
-                       return true;
-       }
-       return false;
-}
-#define _CHECK_DEV_EXT(ext) {                                  \
-       if (_get_dev_extension_is_supported(pExtensionProperties, extensionCount, #ext)){\
-               if (pExtensions)                                                        \
-                       pExtensions[*pExtCount] = #ext;                 \
-               (*pExtCount)++;                                                         \
-       }\
+bool _get_dev_extension_is_supported(VkExtensionProperties *pExtensionProperties, uint32_t extensionCount,
+                                     const char *name) {
+    for (uint32_t i = 0; i < extensionCount; i++) {
+        if (strcmp(name, pExtensionProperties[i].extensionName) == 0)
+            return true;
+    }
+    return false;
 }
+#define _CHECK_DEV_EXT(ext)                                                                                            \
+    {                                                                                                                  \
+        if (_get_dev_extension_is_supported(pExtensionProperties, extensionCount, #ext)) {                             \
+            if (pExtensions)                                                                                           \
+                pExtensions[*pExtCount] = #ext;                                                                        \
+            (*pExtCount)++;                                                                                            \
+        }                                                                                                              \
+    }
 
-vkvg_status_t vkvg_get_required_device_extensions (VkPhysicalDevice phy, const char** pExtensions, uint32_t* pExtCount) {
-       VkExtensionProperties* pExtensionProperties;
-       uint32_t extensionCount;
+vkvg_status_t vkvg_get_required_device_extensions(VkPhysicalDevice phy, const char **pExtensions, uint32_t *pExtCount) {
+    VkExtensionProperties *pExtensionProperties;
+    uint32_t               extensionCount;
 
-       *pExtCount = 0;
+    *pExtCount = 0;
 
-       VK_CHECK_RESULT(vkEnumerateDeviceExtensionProperties(phy, NULL, &extensionCount, NULL));
-       pExtensionProperties = (VkExtensionProperties*)malloc(extensionCount * sizeof(VkExtensionProperties));
-       VK_CHECK_RESULT(vkEnumerateDeviceExtensionProperties(phy, NULL, &extensionCount, pExtensionProperties));
+    VK_CHECK_RESULT(vkEnumerateDeviceExtensionProperties(phy, NULL, &extensionCount, NULL));
+    pExtensionProperties = (VkExtensionProperties *)malloc(extensionCount * sizeof(VkExtensionProperties));
+    VK_CHECK_RESULT(vkEnumerateDeviceExtensionProperties(phy, NULL, &extensionCount, pExtensionProperties));
 
-       //https://vulkan.lunarg.com/doc/view/1.2.162.0/mac/1.2-extensions/vkspec.html#VK_KHR_portability_subset
-       _CHECK_DEV_EXT(VK_KHR_portability_subset);
-       VkPhysicalDeviceFeatures2 phyFeat2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
+    // https://vulkan.lunarg.com/doc/view/1.2.162.0/mac/1.2-extensions/vkspec.html#VK_KHR_portability_subset
+    _CHECK_DEV_EXT(VK_KHR_portability_subset);
+    VkPhysicalDeviceFeatures2 phyFeat2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
 
 #ifdef VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT
-       //ensure feature is implemented by driver.
-       VkPhysicalDeviceScalarBlockLayoutFeatures scalarBlockLayoutSupport = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES};
-       phyFeat2.pNext = &scalarBlockLayoutSupport;
+    // ensure feature is implemented by driver.
+    VkPhysicalDeviceScalarBlockLayoutFeatures scalarBlockLayoutSupport = {
+        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES};
+    phyFeat2.pNext = &scalarBlockLayoutSupport;
 #endif
 
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       VkPhysicalDeviceTimelineSemaphoreFeatures timelineSemaphoreSupport = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES};
-       timelineSemaphoreSupport.pNext = phyFeat2.pNext;
-       phyFeat2.pNext = &timelineSemaphoreSupport;
+    VkPhysicalDeviceTimelineSemaphoreFeatures timelineSemaphoreSupport = {
+        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES};
+    timelineSemaphoreSupport.pNext = phyFeat2.pNext;
+    phyFeat2.pNext                 = &timelineSemaphoreSupport;
 #endif
 
-       vkGetPhysicalDeviceFeatures2(phy, &phyFeat2);
+    vkGetPhysicalDeviceFeatures2(phy, &phyFeat2);
 
 #ifdef VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT
-       if (!scalarBlockLayoutSupport.scalarBlockLayout) {
-               LOG(VKVG_LOG_ERR, "CREATE Device failed, vkvg compiled with VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT and feature is not implemented for physical device.\n");
-               return VKVG_STATUS_DEVICE_ERROR;
-       }
-       _CHECK_DEV_EXT(VK_EXT_scalar_block_layout)
+    if (!scalarBlockLayoutSupport.scalarBlockLayout) {
+        LOG(VKVG_LOG_ERR, "CREATE Device failed, vkvg compiled with VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT and feature is "
+                          "not implemented for physical device.\n");
+        return VKVG_STATUS_DEVICE_ERROR;
+    }
+    _CHECK_DEV_EXT(VK_EXT_scalar_block_layout)
 #endif
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       if (!timelineSemaphoreSupport.timelineSemaphore) {
-               LOG(VKVG_LOG_ERR, "CREATE Device failed, VK_SEMAPHORE_TYPE_TIMELINE not supported.\n");
-               return VKVG_STATUS_DEVICE_ERROR;
-       }
-       _CHECK_DEV_EXT(VK_KHR_timeline_semaphore)
+    if (!timelineSemaphoreSupport.timelineSemaphore) {
+        LOG(VKVG_LOG_ERR, "CREATE Device failed, VK_SEMAPHORE_TYPE_TIMELINE not supported.\n");
+        return VKVG_STATUS_DEVICE_ERROR;
+    }
+    _CHECK_DEV_EXT(VK_KHR_timeline_semaphore)
 #endif
 
-       return VKVG_STATUS_SUCCESS;
+    return VKVG_STATUS_SUCCESS;
 }
 
-//enabledFeature12 is guarantied to be the first in pNext chain
-const void* vkvg_get_device_requirements (VkPhysicalDeviceFeatures* pEnabledFeatures) {
+// enabledFeature12 is guarantied to be the first in pNext chain
+const void *vkvg_get_device_requirements(VkPhysicalDeviceFeatures *pEnabledFeatures) {
 
-       pEnabledFeatures->fillModeNonSolid      = VK_TRUE;
-       pEnabledFeatures->sampleRateShading     = VK_TRUE;
-       pEnabledFeatures->logicOp                       = VK_TRUE;
+    pEnabledFeatures->fillModeNonSolid  = VK_TRUE;
+    pEnabledFeatures->sampleRateShading = VK_TRUE;
+    pEnabledFeatures->logicOp           = VK_TRUE;
 
-       void* pNext = NULL;
+    void *pNext = NULL;
 
 #ifdef VK_VERSION_1_2
-       static VkPhysicalDeviceVulkan12Features enabledFeatures12 = {
-               .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES
+    static VkPhysicalDeviceVulkan12Features enabledFeatures12 = {
+        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES
 #ifdef VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT
-               ,.scalarBlockLayout = VK_TRUE
+        ,
+        .scalarBlockLayout = VK_TRUE
 #endif
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-               ,.timelineSemaphore = VK_TRUE
+        ,
+        .timelineSemaphore = VK_TRUE
 #endif
-       };
-       enabledFeatures12.pNext = pNext;
-       pNext = &enabledFeatures12;
+    };
+    enabledFeatures12.pNext = pNext;
+    pNext                   = &enabledFeatures12;
 #else
 #ifdef VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT
-       static VkPhysicalDeviceScalarBlockLayoutFeaturesEXT scalarBlockFeat = {
-               .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT
-               ,.scalarBlockLayout = VK_TRUE
-       };
-       scalarBlockFeat.pNext = pNext;
-       pNext = &scalarBlockFeat;
+    static VkPhysicalDeviceScalarBlockLayoutFeaturesEXT scalarBlockFeat = {
+        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT, .scalarBlockLayout = VK_TRUE};
+    scalarBlockFeat.pNext                                                = pNext;
+    pNext                                                                = &scalarBlockFeat;
 #endif
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       static VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timelineSemaFeat = {
-               .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR
-               ,.timelineSemaphore = VK_TRUE
-       };
-       timelineSemaFeat.pNext = pNext;
-       pNext = &timelineSemaFeat;
+    static VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timelineSemaFeat = {
+        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR, .timelineSemaphore = VK_TRUE};
+    timelineSemaFeat.pNext = pNext;
+    pNext                  = &timelineSemaFeat;
 #endif
 #endif
 
-       return pNext;
+    return pNext;
 }
 
+VkvgDevice vkvg_device_create(vkvg_device_create_info_t *info) {
+    LOG(VKVG_LOG_INFO, "CREATE Device\n");
+    VkvgDevice dev = (vkvg_device *)calloc(1, sizeof(vkvg_device));
+    if (!dev) {
+        LOG(VKVG_LOG_ERR, "CREATE Device failed, no memory\n");
+        exit(-1);
+    }
 
-VkvgDevice vkvg_device_create (vkvg_device_create_info_t* info) {
-       LOG(VKVG_LOG_INFO, "CREATE Device\n");
-       VkvgDevice dev = (vkvg_device*)calloc(1,sizeof(vkvg_device));
-       if (!dev) {
-               LOG(VKVG_LOG_ERR, "CREATE Device failed, no memory\n");
-               exit(-1);
-       }
-
-       dev->references = 1;
+    dev->references = 1;
 
     if (!info->vkdev) {
-        const char* enabledExts [10];
-        const charenabledLayers[10];
-        uint32_t enabledExtsCount = 0, enabledLayersCount = 0, phyCount = 0;
+        const char *enabledExts[10];
+        const char *enabledLayers[10];
+        uint32_t    enabledExtsCount = 0, enabledLayersCount = 0, phyCount = 0;
 
         vkh_layers_check_init();
 
-    #ifdef VKVG_USE_VALIDATION
+#ifdef VKVG_USE_VALIDATION
         if (vkh_layer_is_present("VK_LAYER_KHRONOS_validation"))
             enabledLayers[enabledLayersCount++] = "VK_LAYER_KHRONOS_validation";
-    #endif
+#endif
 
-    #ifdef VKVG_USE_RENDERDOC
+#ifdef VKVG_USE_RENDERDOC
         if (vkh_layer_is_present("VK_LAYER_RENDERDOC_Capture"))
             enabledLayers[enabledLayersCount++] = "VK_LAYER_RENDERDOC_Capture";
-    #endif
+#endif
         vkh_layers_check_release();
 
-        vkvg_get_required_instance_extensions (enabledExts, &enabledExtsCount);
+        vkvg_get_required_instance_extensions(enabledExts, &enabledExtsCount);
 
-    #ifdef VK_VERSION_1_2
+#ifdef VK_VERSION_1_2
         VkhApp app = vkh_app_create(1, 2, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
-    #else
+#else
         VkhApp app = vkh_app_create(1, 1, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
-    #endif
+#endif
 
-    #if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-        vkh_app_enable_debug_messenger(app
-                , VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
-                , VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
-                , NULL);
-    #endif
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+        vkh_app_enable_debug_messenger(app, VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
+                                       VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, NULL);
+#endif
 
-        VkhPhyInfo* phys = vkh_app_get_phyinfos (app, &phyCount, VK_NULL_HANDLE);
+        VkhPhyInfo *phys = vkh_app_get_phyinfos(app, &phyCount, VK_NULL_HANDLE);
         if (phyCount == 0) {
             dev->status = VKVG_STATUS_DEVICE_ERROR;
-            vkh_app_destroy (app);
+            vkh_app_destroy(app);
             return dev;
         }
 
@@ -326,170 +340,159 @@ VkvgDevice vkvg_device_create (vkvg_device_create_info_t* info) {
         if (!(pi->properties.limits.framebufferColorSampleCounts & info->samples)) {
             LOG(VKVG_LOG_ERR, "CREATE Device failed: sample count not supported: %d\n", info->samples);
             dev->status = VKVG_STATUS_DEVICE_ERROR;
-            vkh_app_free_phyinfos (phyCount, phys);
-            vkh_app_destroy (app);
+            vkh_app_free_phyinfos(phyCount, phys);
+            vkh_app_destroy(app);
             return dev;
         }
 
-        uint32_t qCount = 0;
-        float qPriorities[] = {0.0};
-        VkDeviceQueueCreateInfo pQueueInfos[] = { {0},{0},{0} };
+        uint32_t                qCount        = 0;
+        float                   qPriorities[] = {0.0};
+        VkDeviceQueueCreateInfo pQueueInfos[] = {{0}, {0}, {0}};
 
-        if (vkh_phyinfo_create_queues (pi, pi->gQueue, 1, qPriorities, &pQueueInfos[qCount]))
+        if (vkh_phyinfo_create_queues(pi, pi->gQueue, 1, qPriorities, &pQueueInfos[qCount]))
             qCount++;
 
-        enabledExtsCount=0;
+        enabledExtsCount = 0;
 
-        if (vkvg_get_required_device_extensions (pi->phy, enabledExts, &enabledExtsCount) != VKVG_STATUS_SUCCESS){
+        if (vkvg_get_required_device_extensions(pi->phy, enabledExts, &enabledExtsCount) != VKVG_STATUS_SUCCESS) {
             dev->status = VKVG_STATUS_DEVICE_ERROR;
-            vkh_app_free_phyinfos (phyCount, phys);
-            vkh_app_destroy (app);
+            vkh_app_free_phyinfos(phyCount, phys);
+            vkh_app_destroy(app);
             return dev;
         }
 
         VkPhysicalDeviceFeatures enabledFeatures = {0};
-        const void* pNext = vkvg_get_device_requirements (&enabledFeatures);
-
-        VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
-                                           .queueCreateInfoCount = qCount,
-                                           .pQueueCreateInfos = (VkDeviceQueueCreateInfo*)&pQueueInfos,
-                                           .enabledExtensionCount = enabledExtsCount,
-                                           .ppEnabledExtensionNames = enabledExts,
-                                           .pEnabledFeatures = &enabledFeatures,
-                                           .pNext = pNext};
-        dev->vkhDev = vkh_device_create(app, pi, &device_info);
-
-        vkh_app_free_phyinfos (phyCount, phys);
-
-        info->inst      = vkh_app_get_inst(app);
-        info->phy       = vkh_device_get_phy(dev->vkhDev);
-        info->vkdev     = vkh_device_get_vkdev(dev->vkhDev);
-        info->qFamIdx   = pi->gQueue;
-        info->qIndex    = 0;
+        const void              *pNext           = vkvg_get_device_requirements(&enabledFeatures);
+
+        VkDeviceCreateInfo device_info = {.sType                   = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+                                          .queueCreateInfoCount    = qCount,
+                                          .pQueueCreateInfos       = (VkDeviceQueueCreateInfo *)&pQueueInfos,
+                                          .enabledExtensionCount   = enabledExtsCount,
+                                          .ppEnabledExtensionNames = enabledExts,
+                                          .pEnabledFeatures        = &enabledFeatures,
+                                          .pNext                   = pNext};
+        dev->vkhDev                    = vkh_device_create(app, pi, &device_info);
+
+        vkh_app_free_phyinfos(phyCount, phys);
+
+        info->inst    = vkh_app_get_inst(app);
+        info->phy     = vkh_device_get_phy(dev->vkhDev);
+        info->vkdev   = vkh_device_get_vkdev(dev->vkhDev);
+        info->qFamIdx = pi->gQueue;
+        info->qIndex  = 0;
     }
 
-    _device_init (dev, info);
+    _device_init(dev, info);
 
-       return dev;
+    return dev;
 }
 
-void vkvg_device_destroy (VkvgDevice dev)
-{
-       LOCK_DEVICE
-       dev->references--;
-       if (dev->references > 0) {
-               UNLOCK_DEVICE
-               return;
-       }
-       UNLOCK_DEVICE
-
-
-       if (dev->cachedContextCount > 0) {
-               _cached_ctx* cur = dev->cachedContextLast;
-               while (cur) {
-                       _release_context_ressources (cur->ctx);
-                       _cached_ctx* prev = cur;
-                       cur = cur->pNext;
-                       free (prev);
-               }
-       }
-
+void vkvg_device_destroy(VkvgDevice dev) {
+    LOCK_DEVICE
+    dev->references--;
+    if (dev->references > 0) {
+        UNLOCK_DEVICE
+        return;
+    }
+    UNLOCK_DEVICE
+
+    if (dev->cachedContextCount > 0) {
+        _cached_ctx *cur = dev->cachedContextLast;
+        while (cur) {
+            _release_context_ressources(cur->ctx);
+            _cached_ctx *prev = cur;
+            cur               = cur->pNext;
+            free(prev);
+        }
+    }
 
-       LOG(VKVG_LOG_INFO, "DESTROY Device\n");
+    LOG(VKVG_LOG_INFO, "DESTROY Device\n");
 
-       vkDeviceWaitIdle (dev->vkDev);
+    vkDeviceWaitIdle(dev->vkDev);
 
-       vkh_image_destroy                               (dev->emptyImg);
+    vkh_image_destroy(dev->emptyImg);
 
-       vkDestroyDescriptorSetLayout    (dev->vkDev, dev->dslGrad,NULL);
-       vkDestroyDescriptorSetLayout    (dev->vkDev, dev->dslFont,NULL);
-       vkDestroyDescriptorSetLayout    (dev->vkDev, dev->dslSrc, NULL);
+    vkDestroyDescriptorSetLayout(dev->vkDev, dev->dslGrad, NULL);
+    vkDestroyDescriptorSetLayout(dev->vkDev, dev->dslFont, NULL);
+    vkDestroyDescriptorSetLayout(dev->vkDev, dev->dslSrc, NULL);
 #ifndef __APPLE__
-       vkDestroyPipeline                               (dev->vkDev, dev->pipelinePolyFill, NULL);
+    vkDestroyPipeline(dev->vkDev, dev->pipelinePolyFill, NULL);
 #endif
-       vkDestroyPipeline                               (dev->vkDev, dev->pipelineClipping, NULL);
+    vkDestroyPipeline(dev->vkDev, dev->pipelineClipping, NULL);
 
-       vkDestroyPipeline                               (dev->vkDev, dev->pipe_OVER,    NULL);
-       vkDestroyPipeline                               (dev->vkDev, dev->pipe_SUB,             NULL);
-       vkDestroyPipeline                               (dev->vkDev, dev->pipe_CLEAR,   NULL);
+    vkDestroyPipeline(dev->vkDev, dev->pipe_OVER, NULL);
+    vkDestroyPipeline(dev->vkDev, dev->pipe_SUB, NULL);
+    vkDestroyPipeline(dev->vkDev, dev->pipe_CLEAR, NULL);
 
 #ifdef VKVG_WIRED_DEBUG
-       vkDestroyPipeline                               (dev->vkDev, dev->pipelineWired, NULL);
-       vkDestroyPipeline                               (dev->vkDev, dev->pipelineLineList, NULL);
+    vkDestroyPipeline(dev->vkDev, dev->pipelineWired, NULL);
+    vkDestroyPipeline(dev->vkDev, dev->pipelineLineList, NULL);
 #endif
 
-       vkDestroyPipelineLayout                 (dev->vkDev, dev->pipelineLayout, NULL);
-       vkDestroyPipelineCache                  (dev->vkDev, dev->pipelineCache, NULL);
-       vkDestroyRenderPass                             (dev->vkDev, dev->renderPass, NULL);
-       vkDestroyRenderPass                             (dev->vkDev, dev->renderPass_ClearStencil, NULL);
-       vkDestroyRenderPass                             (dev->vkDev, dev->renderPass_ClearAll, NULL);
+    vkDestroyPipelineLayout(dev->vkDev, dev->pipelineLayout, NULL);
+    vkDestroyPipelineCache(dev->vkDev, dev->pipelineCache, NULL);
+    vkDestroyRenderPass(dev->vkDev, dev->renderPass, NULL);
+    vkDestroyRenderPass(dev->vkDev, dev->renderPass_ClearStencil, NULL);
+    vkDestroyRenderPass(dev->vkDev, dev->renderPass_ClearAll, NULL);
 
-       vkWaitForFences                                 (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
-       vkDestroyFence                                  (dev->vkDev, dev->fence,NULL);
+    vkWaitForFences(dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
+    vkDestroyFence(dev->vkDev, dev->fence, NULL);
 
-       vkFreeCommandBuffers                    (dev->vkDev, dev->cmdPool, 1, &dev->cmd);
-       vkDestroyCommandPool                    (dev->vkDev, dev->cmdPool, NULL);
+    vkFreeCommandBuffers(dev->vkDev, dev->cmdPool, 1, &dev->cmd);
+    vkDestroyCommandPool(dev->vkDev, dev->cmdPool, NULL);
 
-       vkh_queue_destroy(dev->gQueue);
+    vkh_queue_destroy(dev->gQueue);
 
-       _font_cache_destroy(dev);
+    _font_cache_destroy(dev);
 
 #ifdef VKH_USE_VMA
-       vmaDestroyAllocator (dev->allocator);
+    vmaDestroyAllocator(dev->allocator);
 #endif
 
-       if (dev->threadAware)
-               mtx_destroy (&dev->mutex);
+    if (dev->threadAware)
+        mtx_destroy(&dev->mutex);
 
-       if (dev->vkhDev) {
-               VkhApp app = vkh_device_get_app (dev->vkhDev);
-               vkh_device_destroy (dev->vkhDev);
-               vkh_app_destroy (app);
-       }
+    if (dev->vkhDev) {
+        VkhApp app = vkh_device_get_app(dev->vkhDev);
+        vkh_device_destroy(dev->vkhDev);
+        vkh_app_destroy(app);
+    }
 
-       free(dev);
+    free(dev);
 }
 
-vkvg_status_t vkvg_device_status (VkvgDevice dev) {
-       return dev->status;
-}
-VkvgDevice vkvg_device_reference (VkvgDevice dev) {
-       LOCK_DEVICE
-       dev->references++;
-       UNLOCK_DEVICE
-       return dev;
+vkvg_status_t vkvg_device_status(VkvgDevice dev) { return dev->status; }
+VkvgDevice    vkvg_device_reference(VkvgDevice dev) {
+    LOCK_DEVICE
+    dev->references++;
+    UNLOCK_DEVICE
+    return dev;
 }
-uint32_t vkvg_device_get_reference_count (VkvgDevice dev) {
-       return dev->references;
-}
-void vkvg_device_set_dpy (VkvgDevice dev, int hdpy, int vdpy) {
-       dev->hdpi = hdpy;
-       dev->vdpi = vdpy;
+uint32_t vkvg_device_get_reference_count(VkvgDevice dev) { return dev->references; }
+void     vkvg_device_set_dpy(VkvgDevice dev, int hdpy, int vdpy) {
+    dev->hdpi = hdpy;
+    dev->vdpi = vdpy;
 
-       //TODO: reset font cache
+    // TODO: reset font cache
 }
-void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdpy) {
-       *hdpy = dev->hdpi;
-       *vdpy = dev->vdpi;
+void vkvg_device_get_dpy(VkvgDevice dev, int *hdpy, int *vdpy) {
+    *hdpy = dev->hdpi;
+    *vdpy = dev->vdpi;
 }
-void vkvg_device_set_thread_aware (VkvgDevice dev, uint32_t thread_aware) {
-       if (thread_aware) {
-               if (dev->threadAware)
-                       return;
-               mtx_init (&dev->mutex, mtx_plain);
-               mtx_init (&dev->fontCache->mutex, mtx_plain);
-               dev->threadAware = true;
-       } else if (dev->threadAware) {
-               mtx_destroy (&dev->mutex);
-               mtx_destroy (&dev->fontCache->mutex);
-               dev->threadAware = false;
-       }
+void vkvg_device_set_thread_aware(VkvgDevice dev, uint32_t thread_aware) {
+    if (thread_aware) {
+        if (dev->threadAware)
+            return;
+        mtx_init(&dev->mutex, mtx_plain);
+        mtx_init(&dev->fontCache->mutex, mtx_plain);
+        dev->threadAware = true;
+    } else if (dev->threadAware) {
+        mtx_destroy(&dev->mutex);
+        mtx_destroy(&dev->fontCache->mutex);
+        dev->threadAware = false;
+    }
 }
 #if VKVG_DBG_STATS
-vkvg_debug_stats_t vkvg_device_get_stats (VkvgDevice dev) {
-       return dev->debug_stats;
-}
-vkvg_debug_stats_t vkvg_device_reset_stats (VkvgDevice dev) {
-       dev->debug_stats = (vkvg_debug_stats_t) {0};
-}
+vkvg_debug_stats_t vkvg_device_get_stats(VkvgDevice dev) { return dev->debug_stats; }
+vkvg_debug_stats_t vkvg_device_reset_stats(VkvgDevice dev) { dev->debug_stats = (vkvg_debug_stats_t){0}; }
 #endif
index f9f865c160cfd26381673bccf3635c335e61cb55..1264d2ffe81cf271d30ca39a3a875a96ab2834f2 100644 (file)
  * THE SOFTWARE.
  */
 
-#define GetInstProcAddress(inst, func)(PFN_##func)vkGetInstanceProcAddr(inst, #func);
+#define GetInstProcAddress(inst, func) (PFN_##func) vkGetInstanceProcAddr(inst, #func);
 
-#define GetVkProcAddress(dev, inst, func)(vkGetDeviceProcAddr(dev,#func)==NULL)?(PFN_##func)vkGetInstanceProcAddr(inst, #func):(PFN_##func)vkGetDeviceProcAddr(dev, #func)
+#define GetVkProcAddress(dev, inst, func)                                                                              \
+    (vkGetDeviceProcAddr(dev, #func) == NULL) ? (PFN_##func)vkGetInstanceProcAddr(inst, #func)                         \
+                                              : (PFN_##func)vkGetDeviceProcAddr(dev, #func)
 
 #include "vkvg_device_internal.h"
 #include "vkvg_context_internal.h"
@@ -33,575 +35,586 @@ uint32_t vkvg_log_level = VKVG_LOG_DEBUG;
 vkvg_wired_debug_mode vkvg_wired_debug = vkvg_wired_debug_mode_normal;
 #endif
 
-PFN_vkCmdBindPipeline                  CmdBindPipeline;
-PFN_vkCmdBindDescriptorSets            CmdBindDescriptorSets;
-PFN_vkCmdBindIndexBuffer               CmdBindIndexBuffer;
-PFN_vkCmdBindVertexBuffers             CmdBindVertexBuffers;
-
-PFN_vkCmdDrawIndexed                   CmdDrawIndexed;
-PFN_vkCmdDraw                                  CmdDraw;
-
-PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask;
-PFN_vkCmdSetStencilReference   CmdSetStencilReference;
-PFN_vkCmdSetStencilWriteMask   CmdSetStencilWriteMask;
-PFN_vkCmdBeginRenderPass               CmdBeginRenderPass;
-PFN_vkCmdEndRenderPass                 CmdEndRenderPass;
-PFN_vkCmdSetViewport                   CmdSetViewport;
-PFN_vkCmdSetScissor                            CmdSetScissor;
-
-PFN_vkCmdPushConstants                 CmdPushConstants;
-
-PFN_vkWaitForFences                            WaitForFences;
-PFN_vkResetFences                              ResetFences;
-PFN_vkResetCommandBuffer               ResetCommandBuffer;
-
-bool _device_try_get_phyinfo (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy) {
-       for (uint32_t i=0; i<phyCount; i++){
-               if (vkh_phyinfo_get_properties(phys[i]).deviceType == gpuType) {
-                        *phy = phys[i];
-                        return true;
-               }
-       }
-       return false;
+PFN_vkCmdBindPipeline       CmdBindPipeline;
+PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets;
+PFN_vkCmdBindIndexBuffer    CmdBindIndexBuffer;
+PFN_vkCmdBindVertexBuffers  CmdBindVertexBuffers;
+
+PFN_vkCmdDrawIndexed CmdDrawIndexed;
+PFN_vkCmdDraw        CmdDraw;
+
+PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask;
+PFN_vkCmdSetStencilReference   CmdSetStencilReference;
+PFN_vkCmdSetStencilWriteMask   CmdSetStencilWriteMask;
+PFN_vkCmdBeginRenderPass       CmdBeginRenderPass;
+PFN_vkCmdEndRenderPass         CmdEndRenderPass;
+PFN_vkCmdSetViewport           CmdSetViewport;
+PFN_vkCmdSetScissor            CmdSetScissor;
+
+PFN_vkCmdPushConstants CmdPushConstants;
+
+PFN_vkWaitForFences      WaitForFences;
+PFN_vkResetFences        ResetFences;
+PFN_vkResetCommandBuffer ResetCommandBuffer;
+
+bool _device_try_get_phyinfo(VkhPhyInfo *phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo *phy) {
+    for (uint32_t i = 0; i < phyCount; i++) {
+        if (vkh_phyinfo_get_properties(phys[i]).deviceType == gpuType) {
+            *phy = phys[i];
+            return true;
+        }
+    }
+    return false;
 }
-//TODO:save/reload cache in user temp directory
-void _device_create_pipeline_cache(VkvgDevice dev){
+// TODO:save/reload cache in user temp directory
+void _device_create_pipeline_cache(VkvgDevice dev) {
 
-       VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO};
-       VK_CHECK_RESULT(vkCreatePipelineCache(dev->vkDev, &pipelineCacheCreateInfo, NULL, &dev->pipelineCache));
+    VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO};
+    VK_CHECK_RESULT(vkCreatePipelineCache(dev->vkDev, &pipelineCacheCreateInfo, NULL, &dev->pipelineCache));
 }
 
-VkRenderPass _device_createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp)
-{
-       VkAttachmentDescription attColor = {
-                                       .format = FB_COLOR_FORMAT,
-                                       .samples = dev->samples,
-                                       .loadOp = loadOp,
-                                       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
-                                       .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                       .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                       .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                       .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
-       VkAttachmentDescription attDS = {
-                                       .format = dev->stencilFormat,
-                                       .samples = dev->samples,
-                                       .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                       .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                       .stencilLoadOp = stencilLoadOp,
-                                       .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
-                                       .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                                       .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
-
-       VkAttachmentDescription attachments[] = {attColor,attDS};
-       VkAttachmentReference colorRef  = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-       VkAttachmentReference dsRef             = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
-
-       VkSubpassDescription subpassDescription = { .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
-                                               .colorAttachmentCount   = 1,
-                                               .pColorAttachments              = &colorRef,
-                                               .pDepthStencilAttachment= &dsRef};
-
-       VkSubpassDependency dependencies[] =
-       {
-               { VK_SUBPASS_EXTERNAL, 0,
-                 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                 VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                 VK_DEPENDENCY_BY_REGION_BIT},
-               { 0, VK_SUBPASS_EXTERNAL,
-                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
-                 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
-                 VK_DEPENDENCY_BY_REGION_BIT},
-       };
-
-       VkRenderPassCreateInfo renderPassInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
-                               .attachmentCount = 2,
-                               .pAttachments = attachments,
-                               .subpassCount = 1,
-                               .pSubpasses = &subpassDescription,
-                               .dependencyCount = 2,
-                               .pDependencies = dependencies
-       };
-       VkRenderPass rp;
-       VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp));
-       return rp;
+VkRenderPass _device_createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp,
+                                               VkAttachmentLoadOp stencilLoadOp) {
+    VkAttachmentDescription attColor = {.format         = FB_COLOR_FORMAT,
+                                        .samples        = dev->samples,
+                                        .loadOp         = loadOp,
+                                        .storeOp        = VK_ATTACHMENT_STORE_OP_STORE,
+                                        .stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                                        .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+                                        .initialLayout  = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                                        .finalLayout    = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+    VkAttachmentDescription attDS    = {.format         = dev->stencilFormat,
+                                        .samples        = dev->samples,
+                                        .loadOp         = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                                        .storeOp        = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+                                        .stencilLoadOp  = stencilLoadOp,
+                                        .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
+                                        .initialLayout  = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+                                        .finalLayout    = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
+
+    VkAttachmentDescription attachments[] = {attColor, attDS};
+    VkAttachmentReference   colorRef      = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+    VkAttachmentReference   dsRef         = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
+
+    VkSubpassDescription subpassDescription = {.pipelineBindPoint       = VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                               .colorAttachmentCount    = 1,
+                                               .pColorAttachments       = &colorRef,
+                                               .pDepthStencilAttachment = &dsRef};
+
+    VkSubpassDependency dependencies[] = {
+        {VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+         VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+         VK_DEPENDENCY_BY_REGION_BIT},
+        {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
+         VK_DEPENDENCY_BY_REGION_BIT},
+    };
+
+    VkRenderPassCreateInfo renderPassInfo = {.sType           = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+                                             .attachmentCount = 2,
+                                             .pAttachments    = attachments,
+                                             .subpassCount    = 1,
+                                             .pSubpasses      = &subpassDescription,
+                                             .dependencyCount = 2,
+                                             .pDependencies   = dependencies};
+    VkRenderPass           rp;
+    VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp));
+    return rp;
 }
-VkRenderPass _device_createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp)
-{
-       VkAttachmentDescription attColor = {
-                                       .format = FB_COLOR_FORMAT,
-                                       .samples = dev->samples,
-                                       .loadOp = loadOp,
-                                       .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                       .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                       .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                       .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                       .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
-       VkAttachmentDescription attColorResolve = {
-                                       .format = FB_COLOR_FORMAT,
-                                       .samples = VK_SAMPLE_COUNT_1_BIT,
-                                       .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                       .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
-                                       .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                       .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                       .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
-                                       .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
-       VkAttachmentDescription attDS = {
-                                       .format = dev->stencilFormat,
-                                       .samples = dev->samples,
-                                       .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                       .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                       .stencilLoadOp = stencilLoadOp,
-                                       .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
-                                       .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                                       .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
-
-       VkAttachmentDescription attachments[] = {attColorResolve,attDS,attColor};
-       VkAttachmentReference resolveRef= {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-       VkAttachmentReference dsRef             = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
-       VkAttachmentReference colorRef  = {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-
-       VkSubpassDescription subpassDescription = { .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
-                                               .colorAttachmentCount   = 1,
-                                               .pColorAttachments              = &colorRef,
-                                               .pResolveAttachments    = &resolveRef,
-                                               .pDepthStencilAttachment= &dsRef};
-
-       VkSubpassDependency dependencies[] =
-       {
-               { VK_SUBPASS_EXTERNAL, 0,
-                 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                 VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                 VK_DEPENDENCY_BY_REGION_BIT},
-               { 0, VK_SUBPASS_EXTERNAL,
-                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
-                 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
-                 VK_DEPENDENCY_BY_REGION_BIT},
-       };
-
-       VkRenderPassCreateInfo renderPassInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
-                               .attachmentCount = 3,
-                               .pAttachments = attachments,
-                               .subpassCount = 1,
-                               .pSubpasses = &subpassDescription,
-                               .dependencyCount = 2,
-                               .pDependencies = dependencies
-       };
-       VkRenderPass rp;
-       VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp));
-       return rp;
+VkRenderPass _device_createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp) {
+    VkAttachmentDescription attColor        = {.format         = FB_COLOR_FORMAT,
+                                               .samples        = dev->samples,
+                                               .loadOp         = loadOp,
+                                               .storeOp        = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+                                               .stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                                               .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+                                               .initialLayout  = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                                               .finalLayout    = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+    VkAttachmentDescription attColorResolve = {.format         = FB_COLOR_FORMAT,
+                                               .samples        = VK_SAMPLE_COUNT_1_BIT,
+                                               .loadOp         = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                                               .storeOp        = VK_ATTACHMENT_STORE_OP_STORE,
+                                               .stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                                               .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+                                               .initialLayout  = VK_IMAGE_LAYOUT_UNDEFINED,
+                                               .finalLayout    = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+    VkAttachmentDescription attDS           = {.format         = dev->stencilFormat,
+                                               .samples        = dev->samples,
+                                               .loadOp         = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                                               .storeOp        = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+                                               .stencilLoadOp  = stencilLoadOp,
+                                               .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
+                                               .initialLayout  = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+                                               .finalLayout    = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
+
+    VkAttachmentDescription attachments[] = {attColorResolve, attDS, attColor};
+    VkAttachmentReference   resolveRef    = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+    VkAttachmentReference   dsRef         = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
+    VkAttachmentReference   colorRef      = {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+
+    VkSubpassDescription subpassDescription = {.pipelineBindPoint       = VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                               .colorAttachmentCount    = 1,
+                                               .pColorAttachments       = &colorRef,
+                                               .pResolveAttachments     = &resolveRef,
+                                               .pDepthStencilAttachment = &dsRef};
+
+    VkSubpassDependency dependencies[] = {
+        {VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+         VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+         VK_DEPENDENCY_BY_REGION_BIT},
+        {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
+         VK_DEPENDENCY_BY_REGION_BIT},
+    };
+
+    VkRenderPassCreateInfo renderPassInfo = {.sType           = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+                                             .attachmentCount = 3,
+                                             .pAttachments    = attachments,
+                                             .subpassCount    = 1,
+                                             .pSubpasses      = &subpassDescription,
+                                             .dependencyCount = 2,
+                                             .pDependencies   = dependencies};
+    VkRenderPass           rp;
+    VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp));
+    return rp;
 }
 
-void _device_setupPipelines(VkvgDevice dev)
-{
-       VkGraphicsPipelineCreateInfo pipelineCreateInfo = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
-                               .renderPass = dev->renderPass };
-
-       VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
-                               .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN };
-
-       VkPipelineRasterizationStateCreateInfo rasterizationState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
-                               .polygonMode = VK_POLYGON_MODE_FILL,
-                               .cullMode = VK_CULL_MODE_NONE,
-                               .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
-                               .depthClampEnable = VK_FALSE,
-                               .rasterizerDiscardEnable = VK_FALSE,
-                               .depthBiasEnable = VK_FALSE,
-                               .lineWidth = 1.0f };
-
-       VkPipelineColorBlendAttachmentState blendAttachmentState =
-       { .colorWriteMask = 0x0, .blendEnable = VK_TRUE,
+void _device_setupPipelines(VkvgDevice dev) {
+    VkGraphicsPipelineCreateInfo pipelineCreateInfo = {.sType      = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+                                                       .renderPass = dev->renderPass};
+
+    VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {
+        .sType    = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+        .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN};
+
+    VkPipelineRasterizationStateCreateInfo rasterizationState = {
+        .sType                   = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+        .polygonMode             = VK_POLYGON_MODE_FILL,
+        .cullMode                = VK_CULL_MODE_NONE,
+        .frontFace               = VK_FRONT_FACE_COUNTER_CLOCKWISE,
+        .depthClampEnable        = VK_FALSE,
+        .rasterizerDiscardEnable = VK_FALSE,
+        .depthBiasEnable         = VK_FALSE,
+        .lineWidth               = 1.0f};
+
+    VkPipelineColorBlendAttachmentState blendAttachmentState = {
+        .colorWriteMask = 0x0,
+        .blendEnable    = VK_TRUE,
 #ifdef VKVG_PREMULT_ALPHA
-         .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
-         .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
-         .colorBlendOp = VK_BLEND_OP_ADD,
-         .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
-         .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
-         .alphaBlendOp = VK_BLEND_OP_ADD,
+        .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
+        .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
+        .colorBlendOp        = VK_BLEND_OP_ADD,
+        .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
+        .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
+        .alphaBlendOp        = VK_BLEND_OP_ADD,
 #else
-         .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
-         .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
-         .colorBlendOp = VK_BLEND_OP_ADD,
-         .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
-         .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
-         .alphaBlendOp = VK_BLEND_OP_ADD,
+        .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
+        .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
+        .colorBlendOp        = VK_BLEND_OP_ADD,
+        .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
+        .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
+        .alphaBlendOp        = VK_BLEND_OP_ADD,
 #endif
-       };
-
-       VkPipelineColorBlendStateCreateInfo colorBlendState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
-                               .attachmentCount = 1,
-                               .pAttachments = &blendAttachmentState };
-
-                                                                               /*failOp,passOp,depthFailOp,compareOp, compareMask, writeMask, reference;*/
-       VkStencilOpState polyFillOpState ={VK_STENCIL_OP_KEEP,VK_STENCIL_OP_INVERT,     VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_CLIP_BIT,STENCIL_FILL_BIT,0};
-       VkStencilOpState clipingOpState = {VK_STENCIL_OP_ZERO,VK_STENCIL_OP_REPLACE,VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_FILL_BIT,STENCIL_ALL_BIT, 0x2};
-       VkStencilOpState stencilOpState = {VK_STENCIL_OP_KEEP,VK_STENCIL_OP_ZERO,       VK_STENCIL_OP_KEEP,VK_COMPARE_OP_EQUAL,STENCIL_FILL_BIT,STENCIL_FILL_BIT,0x1};
-
-       VkPipelineDepthStencilStateCreateInfo dsStateCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
-                               .depthTestEnable = VK_FALSE,
-                               .depthWriteEnable = VK_FALSE,
-                               .depthCompareOp = VK_COMPARE_OP_ALWAYS,
-                               .stencilTestEnable = VK_TRUE,
-                               .front = polyFillOpState,
-                               .back = polyFillOpState };
-
-       VkDynamicState dynamicStateEnables[] = {
-               VK_DYNAMIC_STATE_VIEWPORT,
-               VK_DYNAMIC_STATE_SCISSOR,
-               VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
-               VK_DYNAMIC_STATE_STENCIL_REFERENCE,
-               VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
-       };
-       VkPipelineDynamicStateCreateInfo dynamicState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
-                               .dynamicStateCount = 2,
-                               .pDynamicStates = dynamicStateEnables };
-
-       VkPipelineViewportStateCreateInfo viewportState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
-                               .viewportCount = 1, .scissorCount = 1 };
-
-       VkPipelineMultisampleStateCreateInfo multisampleState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
-                               .rasterizationSamples = dev->samples };
-       /*if (dev->samples != VK_SAMPLE_COUNT_1_BIT){
-               multisampleState.sampleShadingEnable = VK_TRUE;
-               multisampleState.minSampleShading = 0.5f;
-       }*/
-       VkVertexInputBindingDescription vertexInputBinding = { .binding = 0,
-                               .stride = sizeof(Vertex),
-                               .inputRate = VK_VERTEX_INPUT_RATE_VERTEX };
-
-       VkVertexInputAttributeDescription vertexInputAttributs[3] = {
-               {0, 0, VK_FORMAT_R32G32_SFLOAT,         0},
-               {1, 0, VK_FORMAT_R8G8B8A8_UNORM,        8},
-               {2, 0, VK_FORMAT_R32G32B32_SFLOAT, 12}
-       };
-
-       VkPipelineVertexInputStateCreateInfo vertexInputState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
-               .vertexBindingDescriptionCount  = 1,
-               .pVertexBindingDescriptions             = &vertexInputBinding,
-               .vertexAttributeDescriptionCount= 3,
-               .pVertexAttributeDescriptions   = vertexInputAttributs };
+    };
+
+    VkPipelineColorBlendStateCreateInfo colorBlendState = {.sType =
+                                                               VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+                                                           .attachmentCount = 1,
+                                                           .pAttachments    = &blendAttachmentState};
+
+    /*failOp,passOp,depthFailOp,compareOp, compareMask, writeMask, reference;*/
+    VkStencilOpState polyFillOpState = {VK_STENCIL_OP_KEEP,
+                                        VK_STENCIL_OP_INVERT,
+                                        VK_STENCIL_OP_KEEP,
+                                        VK_COMPARE_OP_EQUAL,
+                                        STENCIL_CLIP_BIT,
+                                        STENCIL_FILL_BIT,
+                                        0};
+    VkStencilOpState clipingOpState  = {VK_STENCIL_OP_ZERO,
+                                        VK_STENCIL_OP_REPLACE,
+                                        VK_STENCIL_OP_KEEP,
+                                        VK_COMPARE_OP_EQUAL,
+                                        STENCIL_FILL_BIT,
+                                        STENCIL_ALL_BIT,
+                                        0x2};
+    VkStencilOpState stencilOpState  = {VK_STENCIL_OP_KEEP,
+                                        VK_STENCIL_OP_ZERO,
+                                        VK_STENCIL_OP_KEEP,
+                                        VK_COMPARE_OP_EQUAL,
+                                        STENCIL_FILL_BIT,
+                                        STENCIL_FILL_BIT,
+                                        0x1};
+
+    VkPipelineDepthStencilStateCreateInfo dsStateCreateInfo = {
+        .sType             = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+        .depthTestEnable   = VK_FALSE,
+        .depthWriteEnable  = VK_FALSE,
+        .depthCompareOp    = VK_COMPARE_OP_ALWAYS,
+        .stencilTestEnable = VK_TRUE,
+        .front             = polyFillOpState,
+        .back              = polyFillOpState};
+
+    VkDynamicState dynamicStateEnables[] = {
+        VK_DYNAMIC_STATE_VIEWPORT,
+        VK_DYNAMIC_STATE_SCISSOR,
+        VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
+        VK_DYNAMIC_STATE_STENCIL_REFERENCE,
+        VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
+    };
+    VkPipelineDynamicStateCreateInfo dynamicState = {.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+                                                     .dynamicStateCount = 2,
+                                                     .pDynamicStates    = dynamicStateEnables};
+
+    VkPipelineViewportStateCreateInfo viewportState = {
+        .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, .viewportCount = 1, .scissorCount = 1};
+
+    VkPipelineMultisampleStateCreateInfo multisampleState = {
+        .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .rasterizationSamples = dev->samples};
+    /*if (dev->samples != VK_SAMPLE_COUNT_1_BIT){
+        multisampleState.sampleShadingEnable = VK_TRUE;
+        multisampleState.minSampleShading = 0.5f;
+    }*/
+    VkVertexInputBindingDescription vertexInputBinding = {
+        .binding = 0, .stride = sizeof(Vertex), .inputRate = VK_VERTEX_INPUT_RATE_VERTEX};
+
+    VkVertexInputAttributeDescription vertexInputAttributs[3] = {{0, 0, VK_FORMAT_R32G32_SFLOAT, 0},
+                                                                 {1, 0, VK_FORMAT_R8G8B8A8_UNORM, 8},
+                                                                 {2, 0, VK_FORMAT_R32G32B32_SFLOAT, 12}};
+
+    VkPipelineVertexInputStateCreateInfo vertexInputState = {
+        .sType                           = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+        .vertexBindingDescriptionCount   = 1,
+        .pVertexBindingDescriptions      = &vertexInputBinding,
+        .vertexAttributeDescriptionCount = 3,
+        .pVertexAttributeDescriptions    = vertexInputAttributs};
 #ifdef VKVG_WIRED_DEBUG
-       VkShaderModule modVert, modFrag, modFragWired;
+    VkShaderModule modVert, modFrag, modFragWired;
 #else
-       VkShaderModule modVert, modFrag;
+    VkShaderModule modVert, modFrag;
 #endif
-       VkShaderModuleCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
-                                                                                       .pCode = (uint32_t*)vkvg_main_vert_spv,
-                                                                                       .codeSize = vkvg_main_vert_spv_len };
-       VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modVert));
+    VkShaderModuleCreateInfo createInfo = {.sType    = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+                                           .pCode    = (uint32_t *)vkvg_main_vert_spv,
+                                           .codeSize = vkvg_main_vert_spv_len};
+    VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modVert));
 #if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
-       createInfo.pCode = (uint32_t*)vkvg_main_lcd_frag_spv;
-       createInfo.codeSize = vkvg_main_lcd_frag_spv_len;
+    createInfo.pCode    = (uint32_t *)vkvg_main_lcd_frag_spv;
+    createInfo.codeSize = vkvg_main_lcd_frag_spv_len;
 #else
-       createInfo.pCode = (uint32_t*)vkvg_main_frag_spv;
-       createInfo.codeSize = vkvg_main_frag_spv_len;
+    createInfo.pCode    = (uint32_t *)vkvg_main_frag_spv;
+    createInfo.codeSize = vkvg_main_frag_spv_len;
 #endif
-       VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFrag));
-
-       VkPipelineShaderStageCreateInfo vertStage = { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
-               .stage = VK_SHADER_STAGE_VERTEX_BIT,
-               .module = modVert,
-               .pName = "main",
-       };
-       VkPipelineShaderStageCreateInfo fragStage = { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
-               .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
-               .module = modFrag,
-               .pName = "main",
-       };
-
-       // Use specialization constants to pass number of samples to the shader (used for MSAA resolve)
-       /*VkSpecializationMapEntry specializationEntry = {
-               .constantID = 0,
-               .offset = 0,
-               .size = sizeof(uint32_t)};
-       uint32_t specializationData = VKVG_SAMPLES;
-       VkSpecializationInfo specializationInfo = {
-               .mapEntryCount = 1,
-               .pMapEntries = &specializationEntry,
-               .dataSize = sizeof(specializationData),
-               .pData = &specializationData};*/
-
-       VkPipelineShaderStageCreateInfo shaderStages[] = {vertStage,fragStage};
-
-       pipelineCreateInfo.stageCount = 1;
-       pipelineCreateInfo.pStages = shaderStages;
-       pipelineCreateInfo.pVertexInputState = &vertexInputState;
-       pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
-       pipelineCreateInfo.pViewportState = &viewportState;
-       pipelineCreateInfo.pRasterizationState = &rasterizationState;
-       pipelineCreateInfo.pMultisampleState = &multisampleState;
-       pipelineCreateInfo.pColorBlendState = &colorBlendState;
-       pipelineCreateInfo.pDepthStencilState = &dsStateCreateInfo;
-       pipelineCreateInfo.pDynamicState = &dynamicState;
-       pipelineCreateInfo.layout = dev->pipelineLayout;
+    VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFrag));
+
+    VkPipelineShaderStageCreateInfo vertStage = {
+        .sType  = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+        .stage  = VK_SHADER_STAGE_VERTEX_BIT,
+        .module = modVert,
+        .pName  = "main",
+    };
+    VkPipelineShaderStageCreateInfo fragStage = {
+        .sType  = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+        .stage  = VK_SHADER_STAGE_FRAGMENT_BIT,
+        .module = modFrag,
+        .pName  = "main",
+    };
+
+    // Use specialization constants to pass number of samples to the shader (used for MSAA resolve)
+    /*VkSpecializationMapEntry specializationEntry = {
+        .constantID = 0,
+        .offset = 0,
+        .size = sizeof(uint32_t)};
+    uint32_t specializationData = VKVG_SAMPLES;
+    VkSpecializationInfo specializationInfo = {
+        .mapEntryCount = 1,
+        .pMapEntries = &specializationEntry,
+        .dataSize = sizeof(specializationData),
+        .pData = &specializationData};*/
+
+    VkPipelineShaderStageCreateInfo shaderStages[] = {vertStage, fragStage};
+
+    pipelineCreateInfo.stageCount          = 1;
+    pipelineCreateInfo.pStages             = shaderStages;
+    pipelineCreateInfo.pVertexInputState   = &vertexInputState;
+    pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
+    pipelineCreateInfo.pViewportState      = &viewportState;
+    pipelineCreateInfo.pRasterizationState = &rasterizationState;
+    pipelineCreateInfo.pMultisampleState   = &multisampleState;
+    pipelineCreateInfo.pColorBlendState    = &colorBlendState;
+    pipelineCreateInfo.pDepthStencilState  = &dsStateCreateInfo;
+    pipelineCreateInfo.pDynamicState       = &dynamicState;
+    pipelineCreateInfo.layout              = dev->pipelineLayout;
 
 #ifndef __APPLE__
-       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelinePolyFill));
+    VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL,
+                                              &dev->pipelinePolyFill));
 #endif
 
-       inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
-       dsStateCreateInfo.back = dsStateCreateInfo.front = clipingOpState;
-       dynamicState.dynamicStateCount = 5;
-       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineClipping));
-
-       dsStateCreateInfo.back = dsStateCreateInfo.front = stencilOpState;
-       blendAttachmentState.colorWriteMask=0xf;
-       dynamicState.dynamicStateCount = 3;
-       pipelineCreateInfo.stageCount = 2;
-       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_OVER));
-
-       blendAttachmentState.alphaBlendOp = blendAttachmentState.colorBlendOp = VK_BLEND_OP_SUBTRACT;
-       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_SUB));
-
-       colorBlendState.logicOpEnable = VK_TRUE;
-       blendAttachmentState.blendEnable = VK_FALSE;
-       colorBlendState.logicOp = VK_LOGIC_OP_CLEAR;
-       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_CLEAR));
-
+    inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+    dsStateCreateInfo.back = dsStateCreateInfo.front = clipingOpState;
+    dynamicState.dynamicStateCount                   = 5;
+    VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL,
+                                              &dev->pipelineClipping));
+
+    dsStateCreateInfo.back = dsStateCreateInfo.front = stencilOpState;
+    blendAttachmentState.colorWriteMask              = 0xf;
+    dynamicState.dynamicStateCount                   = 3;
+    pipelineCreateInfo.stageCount                    = 2;
+    VK_CHECK_RESULT(
+        vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_OVER));
+
+    blendAttachmentState.alphaBlendOp = blendAttachmentState.colorBlendOp = VK_BLEND_OP_SUBTRACT;
+    VK_CHECK_RESULT(
+        vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_SUB));
+
+    colorBlendState.logicOpEnable    = VK_TRUE;
+    blendAttachmentState.blendEnable = VK_FALSE;
+    colorBlendState.logicOp          = VK_LOGIC_OP_CLEAR;
+    VK_CHECK_RESULT(
+        vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_CLEAR));
 
 #ifdef VKVG_WIRED_DEBUG
-       colorBlendState.logicOpEnable = VK_FALSE;
-       blendAttachmentState.blendEnable = VK_TRUE;
-       colorBlendState.logicOp = VK_LOGIC_OP_CLEAR;
+    colorBlendState.logicOpEnable    = VK_FALSE;
+    blendAttachmentState.blendEnable = VK_TRUE;
+    colorBlendState.logicOp          = VK_LOGIC_OP_CLEAR;
 
-       createInfo.pCode = (uint32_t*)wired_frag_spv;
+    createInfo.pCode = (uint32_t *)wired_frag_spv;
 
-       createInfo.codeSize = wired_frag_spv_len;
-       VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired));
+    createInfo.codeSize = wired_frag_spv_len;
+    VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired));
 
-       shaderStages[1].module = modFragWired;
+    shaderStages[1].module = modFragWired;
 
-       rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
-       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineLineList));
+    rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
+    VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL,
+                                              &dev->pipelineLineList));
 
-       inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
-       rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
-       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired));
+    inputAssemblyState.topology    = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
+    rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
+    VK_CHECK_RESULT(
+        vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired));
 
-       vkDestroyShaderModule(dev->vkDev, modFragWired, NULL);
+    vkDestroyShaderModule(dev->vkDev, modFragWired, NULL);
 #endif
 
-       vkDestroyShaderModule(dev->vkDev, modVert, NULL);
-       vkDestroyShaderModule(dev->vkDev, modFrag, NULL);
+    vkDestroyShaderModule(dev->vkDev, modVert, NULL);
+    vkDestroyShaderModule(dev->vkDev, modFrag, NULL);
 }
 
-void _device_createDescriptorSetLayout (VkvgDevice dev) {
-
-       VkDescriptorSetLayoutBinding dsLayoutBinding =
-               {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1,VK_SHADER_STAGE_FRAGMENT_BIT, NULL};
-       VkDescriptorSetLayoutCreateInfo dsLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
-                                                                                                                 .bindingCount = 1,
-                                                                                                                 .pBindings = &dsLayoutBinding };
-       VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslFont));
-       VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslSrc));
-       dsLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
-       VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslGrad));
-
-       VkPushConstantRange pushConstantRange[] = {
-               {VK_SHADER_STAGE_VERTEX_BIT,0,sizeof(push_constants)},
-               //{VK_SHADER_STAGE_FRAGMENT_BIT,0,sizeof(push_constants)}
-       };
-       VkDescriptorSetLayout dsls[] = {dev->dslFont,dev->dslSrc,dev->dslGrad};
-
-       VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
-                                                                                                                       .pushConstantRangeCount = 1,
-                                                                                                                       .pPushConstantRanges = (VkPushConstantRange*)&pushConstantRange,
-                                                                                                                       .setLayoutCount = 3,
-                                                                                                                       .pSetLayouts = dsls };
-       VK_CHECK_RESULT(vkCreatePipelineLayout(dev->vkDev, &pipelineLayoutCreateInfo, NULL, &dev->pipelineLayout));
+void _device_createDescriptorSetLayout(VkvgDevice dev) {
+
+    VkDescriptorSetLayoutBinding    dsLayoutBinding    = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1,
+                                                          VK_SHADER_STAGE_FRAGMENT_BIT, NULL};
+    VkDescriptorSetLayoutCreateInfo dsLayoutCreateInfo = {
+        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .bindingCount = 1, .pBindings = &dsLayoutBinding};
+    VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslFont));
+    VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslSrc));
+    dsLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    VK_CHECK_RESULT(vkCreateDescriptorSetLayout(dev->vkDev, &dsLayoutCreateInfo, NULL, &dev->dslGrad));
+
+    VkPushConstantRange pushConstantRange[] = {
+        {VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push_constants)},
+        //{VK_SHADER_STAGE_FRAGMENT_BIT,0,sizeof(push_constants)}
+    };
+    VkDescriptorSetLayout dsls[] = {dev->dslFont, dev->dslSrc, dev->dslGrad};
+
+    VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+                                                           .pushConstantRangeCount = 1,
+                                                           .pPushConstantRanges =
+                                                               (VkPushConstantRange *)&pushConstantRange,
+                                                           .setLayoutCount = 3,
+                                                           .pSetLayouts    = dsls};
+    VK_CHECK_RESULT(vkCreatePipelineLayout(dev->vkDev, &pipelineLayoutCreateInfo, NULL, &dev->pipelineLayout));
 }
 
-void _device_wait_idle (VkvgDevice dev) {
-       vkDeviceWaitIdle (dev->vkDev);
-}
-void _device_wait_and_reset_device_fence (VkvgDevice dev) {
-       vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
-       ResetFences (dev->vkDev, 1, &dev->fence);
+void _device_wait_idle(VkvgDevice dev) { vkDeviceWaitIdle(dev->vkDev); }
+void _device_wait_and_reset_device_fence(VkvgDevice dev) {
+    vkWaitForFences(dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
+    ResetFences(dev->vkDev, 1, &dev->fence);
 }
 
-bool _device_try_get_cached_context (VkvgDevice dev, VkvgContext* pCtx) {
-       LOCK_DEVICE
-
-       if (dev->cachedContextCount) {
-               thrd_t curThread = thrd_current ();
-               _cached_ctx* prev = NULL;
-               _cached_ctx* cur = dev->cachedContextLast;
-               while (cur) {
-                       if (thrd_equal (cur->thread, curThread)) {
-                               if (prev)
-                                       prev->pNext = cur->pNext;
-                               else
-                                       dev->cachedContextLast = cur->pNext;
-
-                               dev->cachedContextCount--;
-
-                               LOG(VKVG_LOG_THREAD,"get cached context: %p, thd:%lu cached ctx: %d\n", cur->ctx, cur->thread, dev->cachedContextCount);
-
-                               *pCtx = cur->ctx;
-                               free (cur);
-                               UNLOCK_DEVICE
-                               return true;
-                       }
-                       prev = cur;
-                       cur = cur->pNext;
-               }
-       }
-       *pCtx = NULL;
-       UNLOCK_DEVICE
-       return false;
+bool _device_try_get_cached_context(VkvgDevice dev, VkvgContext *pCtx) {
+    LOCK_DEVICE
+
+    if (dev->cachedContextCount) {
+        thrd_t       curThread = thrd_current();
+        _cached_ctx *prev      = NULL;
+        _cached_ctx *cur       = dev->cachedContextLast;
+        while (cur) {
+            if (thrd_equal(cur->thread, curThread)) {
+                if (prev)
+                    prev->pNext = cur->pNext;
+                else
+                    dev->cachedContextLast = cur->pNext;
+
+                dev->cachedContextCount--;
+
+                LOG(VKVG_LOG_THREAD, "get cached context: %p, thd:%lu cached ctx: %d\n", cur->ctx, cur->thread,
+                    dev->cachedContextCount);
+
+                *pCtx = cur->ctx;
+                free(cur);
+                UNLOCK_DEVICE
+                return true;
+            }
+            prev = cur;
+            cur  = cur->pNext;
+        }
+    }
+    *pCtx = NULL;
+    UNLOCK_DEVICE
+    return false;
 }
-void _device_store_context (VkvgContext ctx) {
-       VkvgDevice dev = ctx->dev;
+void _device_store_context(VkvgContext ctx) {
+    VkvgDevice dev = ctx->dev;
 
-       LOCK_DEVICE
+    LOCK_DEVICE
 
-       _cached_ctx* cur = (_cached_ctx*)calloc(1, sizeof(_cached_ctx));
-       cur->ctx        = ctx;
-       cur->thread     = thrd_current ();
-       cur->pNext      = dev->cachedContextLast;
+    _cached_ctx *cur = (_cached_ctx *)calloc(1, sizeof(_cached_ctx));
+    cur->ctx         = ctx;
+    cur->thread      = thrd_current();
+    cur->pNext       = dev->cachedContextLast;
 
-       dev->cachedContextLast = cur;
-       dev->cachedContextCount++;
+    dev->cachedContextLast = cur;
+    dev->cachedContextCount++;
 
-       LOG(VKVG_LOG_THREAD,"store context: %p, thd:%lu cached ctx: %d\n", cur->ctx, cur->thread, dev->cachedContextCount);
+    LOG(VKVG_LOG_THREAD, "store context: %p, thd:%lu cached ctx: %d\n", cur->ctx, cur->thread, dev->cachedContextCount);
 
-       ctx->references++;
+    ctx->references++;
 
-       UNLOCK_DEVICE
+    UNLOCK_DEVICE
 }
-void _device_submit_cmd (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence) {
-       LOCK_DEVICE
-       vkh_cmd_submit (dev->gQueue, cmd, fence);
-       UNLOCK_DEVICE
+void _device_submit_cmd(VkvgDevice dev, VkCommandBuffer *cmd, VkFence fence) {
+    LOCK_DEVICE
+    vkh_cmd_submit(dev->gQueue, cmd, fence);
+    UNLOCK_DEVICE
 }
 
-bool _device_init_function_pointers (VkvgDevice dev) {
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       if (vkGetInstanceProcAddr(dev->instance, "vkSetDebugUtilsObjectNameEXT")==VK_NULL_HANDLE){
-               LOG(VKVG_LOG_ERR, "vkvg create device failed: 'VK_EXT_debug_utils' has to be loaded for Debug build\n");
-               return false;
-       }
-       vkh_device_init_debug_utils ((VkhDevice)dev);
+bool _device_init_function_pointers(VkvgDevice dev) {
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    if (vkGetInstanceProcAddr(dev->instance, "vkSetDebugUtilsObjectNameEXT") == VK_NULL_HANDLE) {
+        LOG(VKVG_LOG_ERR, "vkvg create device failed: 'VK_EXT_debug_utils' has to be loaded for Debug build\n");
+        return false;
+    }
+    vkh_device_init_debug_utils((VkhDevice)dev);
 #endif
-       CmdBindPipeline                 = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBindPipeline);
-       CmdBindDescriptorSets   = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBindDescriptorSets);
-       CmdBindIndexBuffer              = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBindIndexBuffer);
-       CmdBindVertexBuffers    = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBindVertexBuffers);
-       CmdDrawIndexed                  = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdDrawIndexed);
-       CmdDraw                                 = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdDraw);
-       CmdSetStencilCompareMask= GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetStencilCompareMask);
-       CmdSetStencilReference  = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetStencilReference);
-       CmdSetStencilWriteMask  = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetStencilWriteMask);
-       CmdBeginRenderPass              = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBeginRenderPass);
-       CmdEndRenderPass                = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdEndRenderPass);
-       CmdSetViewport                  = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetViewport);
-       CmdSetScissor                   = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetScissor);
-       CmdPushConstants                = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdPushConstants);
-       WaitForFences                   = GetVkProcAddress(dev->vkDev, dev->instance, vkWaitForFences);
-       ResetFences                             = GetVkProcAddress(dev->vkDev, dev->instance, vkResetFences);
-       ResetCommandBuffer              = GetVkProcAddress(dev->vkDev, dev->instance, vkResetCommandBuffer);
-       return true;
+    CmdBindPipeline          = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBindPipeline);
+    CmdBindDescriptorSets    = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBindDescriptorSets);
+    CmdBindIndexBuffer       = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBindIndexBuffer);
+    CmdBindVertexBuffers     = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBindVertexBuffers);
+    CmdDrawIndexed           = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdDrawIndexed);
+    CmdDraw                  = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdDraw);
+    CmdSetStencilCompareMask = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetStencilCompareMask);
+    CmdSetStencilReference   = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetStencilReference);
+    CmdSetStencilWriteMask   = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetStencilWriteMask);
+    CmdBeginRenderPass       = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdBeginRenderPass);
+    CmdEndRenderPass         = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdEndRenderPass);
+    CmdSetViewport           = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetViewport);
+    CmdSetScissor            = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdSetScissor);
+    CmdPushConstants         = GetVkProcAddress(dev->vkDev, dev->instance, vkCmdPushConstants);
+    WaitForFences            = GetVkProcAddress(dev->vkDev, dev->instance, vkWaitForFences);
+    ResetFences              = GetVkProcAddress(dev->vkDev, dev->instance, vkResetFences);
+    ResetCommandBuffer       = GetVkProcAddress(dev->vkDev, dev->instance, vkResetCommandBuffer);
+    return true;
 }
 
-void _device_create_empty_texture (VkvgDevice dev, VkFormat format, VkImageTiling tiling) {
-       //create empty image to bind to context source descriptor when not in use
-       dev->emptyImg = vkh_image_create((VkhDevice)dev,format,16,16,tiling,VKH_MEMORY_USAGE_GPU_ONLY,
-                                                                        VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
-       vkh_image_create_descriptor(dev->emptyImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
-
-       _device_wait_and_reset_device_fence (dev);
-
-       vkh_cmd_begin (dev->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-       vkh_image_set_layout (dev->cmd, dev->emptyImg, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
-       vkh_cmd_end (dev->cmd);
-       _device_submit_cmd (dev, &dev->cmd, dev->fence);
+void _device_create_empty_texture(VkvgDevice dev, VkFormat format, VkImageTiling tiling) {
+    // create empty image to bind to context source descriptor when not in use
+    dev->emptyImg = vkh_image_create((VkhDevice)dev, format, 16, 16, tiling, VKH_MEMORY_USAGE_GPU_ONLY,
+                                     VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
+    vkh_image_create_descriptor(dev->emptyImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST,
+                                VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                                VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
+
+    _device_wait_and_reset_device_fence(dev);
+
+    vkh_cmd_begin(dev->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_image_set_layout(dev->cmd, dev->emptyImg, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                         VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
+    vkh_cmd_end(dev->cmd);
+    _device_submit_cmd(dev, &dev->cmd, dev->fence);
 }
-void _device_check_best_image_tiling (VkvgDevice dev, VkFormat format) {
-       VkFlags stencilFormats[] = { VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
-       VkFormatProperties phyStencilProps = { 0 }, phyImgProps = { 0 };
-
-       //check png blit format
-       VkFlags pngBlitFormats[] = { VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_R8G8B8A8_UNORM};
-       dev->pngStagFormat = VK_FORMAT_UNDEFINED;
-       for (int i = 0; i < 2; i++)
-       {
-               vkGetPhysicalDeviceFormatProperties(dev->phy, pngBlitFormats[i], &phyImgProps);
-               if ((phyImgProps.linearTilingFeatures & VKVG_PNG_WRITE_IMG_REQUIREMENTS) == VKVG_PNG_WRITE_IMG_REQUIREMENTS) {
-                       dev->pngStagFormat = pngBlitFormats[i];
-                       dev->pngStagTiling = VK_IMAGE_TILING_LINEAR;
-                       break;
-               } else if ((phyImgProps.optimalTilingFeatures & VKVG_PNG_WRITE_IMG_REQUIREMENTS) == VKVG_PNG_WRITE_IMG_REQUIREMENTS) {
-                       dev->pngStagFormat = pngBlitFormats[i];
-                       dev->pngStagTiling = VK_IMAGE_TILING_OPTIMAL;
-                       break;
-               }
-       }
-
-       if (dev->pngStagFormat == VK_FORMAT_UNDEFINED)
-               LOG(VKVG_LOG_DEBUG, "vkvg create device failed: no suitable image format for png write\n");
-
-       dev->stencilFormat = VK_FORMAT_UNDEFINED;
-       dev->stencilAspectFlag = VK_IMAGE_ASPECT_STENCIL_BIT;
-       dev->supportedTiling = 0xff;
-       
-       vkGetPhysicalDeviceFormatProperties(dev->phy, format, &phyImgProps);
-       
-       if ((phyImgProps.optimalTilingFeatures & VKVG_SURFACE_IMGS_REQUIREMENTS) == VKVG_SURFACE_IMGS_REQUIREMENTS) {
-               for (int i = 0; i < 4; i++)
-               {
-                       vkGetPhysicalDeviceFormatProperties(dev->phy, stencilFormats[i], &phyStencilProps);
-                       if (phyStencilProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-                               dev->stencilFormat = stencilFormats[i];
-                               if (i > 0)
-                                       dev->stencilAspectFlag |= VK_IMAGE_ASPECT_DEPTH_BIT;
-                               dev->supportedTiling = VK_IMAGE_TILING_OPTIMAL;
-                               return;
-                       }
-               }
-       }
-       if ((phyImgProps.linearTilingFeatures & VKVG_SURFACE_IMGS_REQUIREMENTS) == VKVG_SURFACE_IMGS_REQUIREMENTS) {
-               for (int i = 0; i < 4; i++)
-               {
-                       vkGetPhysicalDeviceFormatProperties(dev->phy, stencilFormats[i], &phyStencilProps);
-                       if (phyStencilProps.linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-                               dev->stencilFormat = stencilFormats[i];
-                               if (i > 0)
-                                       dev->stencilAspectFlag |= VK_IMAGE_ASPECT_DEPTH_BIT;
-                               dev->supportedTiling = VK_IMAGE_TILING_LINEAR;
-                               return;
-                       }
-               }
-       }
-       dev->status = VKVG_STATUS_INVALID_FORMAT;
-       LOG(VKVG_LOG_ERR, "vkvg create device failed: image format not supported: %d\n", format);
+void _device_check_best_image_tiling(VkvgDevice dev, VkFormat format) {
+    VkFlags            stencilFormats[] = {VK_FORMAT_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT,
+                                           VK_FORMAT_D32_SFLOAT_S8_UINT};
+    VkFormatProperties phyStencilProps = {0}, phyImgProps = {0};
+
+    // check png blit format
+    VkFlags pngBlitFormats[] = {VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_R8G8B8A8_UNORM};
+    dev->pngStagFormat       = VK_FORMAT_UNDEFINED;
+    for (int i = 0; i < 2; i++) {
+        vkGetPhysicalDeviceFormatProperties(dev->phy, pngBlitFormats[i], &phyImgProps);
+        if ((phyImgProps.linearTilingFeatures & VKVG_PNG_WRITE_IMG_REQUIREMENTS) == VKVG_PNG_WRITE_IMG_REQUIREMENTS) {
+            dev->pngStagFormat = pngBlitFormats[i];
+            dev->pngStagTiling = VK_IMAGE_TILING_LINEAR;
+            break;
+        } else if ((phyImgProps.optimalTilingFeatures & VKVG_PNG_WRITE_IMG_REQUIREMENTS) ==
+                   VKVG_PNG_WRITE_IMG_REQUIREMENTS) {
+            dev->pngStagFormat = pngBlitFormats[i];
+            dev->pngStagTiling = VK_IMAGE_TILING_OPTIMAL;
+            break;
+        }
+    }
+
+    if (dev->pngStagFormat == VK_FORMAT_UNDEFINED)
+        LOG(VKVG_LOG_DEBUG, "vkvg create device failed: no suitable image format for png write\n");
+
+    dev->stencilFormat     = VK_FORMAT_UNDEFINED;
+    dev->stencilAspectFlag = VK_IMAGE_ASPECT_STENCIL_BIT;
+    dev->supportedTiling   = 0xff;
+
+    vkGetPhysicalDeviceFormatProperties(dev->phy, format, &phyImgProps);
+
+    if ((phyImgProps.optimalTilingFeatures & VKVG_SURFACE_IMGS_REQUIREMENTS) == VKVG_SURFACE_IMGS_REQUIREMENTS) {
+        for (int i = 0; i < 4; i++) {
+            vkGetPhysicalDeviceFormatProperties(dev->phy, stencilFormats[i], &phyStencilProps);
+            if (phyStencilProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+                dev->stencilFormat = stencilFormats[i];
+                if (i > 0)
+                    dev->stencilAspectFlag |= VK_IMAGE_ASPECT_DEPTH_BIT;
+                dev->supportedTiling = VK_IMAGE_TILING_OPTIMAL;
+                return;
+            }
+        }
+    }
+    if ((phyImgProps.linearTilingFeatures & VKVG_SURFACE_IMGS_REQUIREMENTS) == VKVG_SURFACE_IMGS_REQUIREMENTS) {
+        for (int i = 0; i < 4; i++) {
+            vkGetPhysicalDeviceFormatProperties(dev->phy, stencilFormats[i], &phyStencilProps);
+            if (phyStencilProps.linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+                dev->stencilFormat = stencilFormats[i];
+                if (i > 0)
+                    dev->stencilAspectFlag |= VK_IMAGE_ASPECT_DEPTH_BIT;
+                dev->supportedTiling = VK_IMAGE_TILING_LINEAR;
+                return;
+            }
+        }
+    }
+    dev->status = VKVG_STATUS_INVALID_FORMAT;
+    LOG(VKVG_LOG_ERR, "vkvg create device failed: image format not supported: %d\n", format);
 }
 
-void _dump_image_format_properties (VkvgDevice dev, VkFormat format) {
-       /*VkImageFormatProperties imgProps;
-       VK_CHECK_RESULT(vkGetPhysicalDeviceImageFormatProperties(dev->phy,
-                                                                                                                        format, VK_IMAGE_TYPE_2D, VKVG_TILING,
-                                                                                                                        VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT,
-                                                                                                                        0, &imgProps));
-       printf ("tiling                   = %d\n", VKVG_TILING);
-       printf ("max extend               = (%d, %d, %d)\n", imgProps.maxExtent.width, imgProps.maxExtent.height, imgProps.maxExtent.depth);
-       printf ("max mip levels   = %d\n", imgProps.maxMipLevels);
-       printf ("max array layers = %d\n", imgProps.maxArrayLayers);
-       printf ("sample counts    = ");
-       if (imgProps.sampleCounts & VK_SAMPLE_COUNT_1_BIT)
-               printf ("1,");
-       if (imgProps.sampleCounts & VK_SAMPLE_COUNT_2_BIT)
-               printf ("2,");
-       if (imgProps.sampleCounts & VK_SAMPLE_COUNT_4_BIT)
-               printf ("4,");
-       if (imgProps.sampleCounts & VK_SAMPLE_COUNT_8_BIT)
-               printf ("8,");
-       if (imgProps.sampleCounts & VK_SAMPLE_COUNT_16_BIT)
-               printf ("16,");
-       if (imgProps.sampleCounts & VK_SAMPLE_COUNT_32_BIT)
-               printf ("32,");
-       printf ("\n");
-       printf ("max resource size= %lu\n", imgProps.maxResourceSize);
+void _dump_image_format_properties(VkvgDevice dev, VkFormat format) {
+    /*VkImageFormatProperties imgProps;
+    VK_CHECK_RESULT(vkGetPhysicalDeviceImageFormatProperties(dev->phy,
+                                                             format, VK_IMAGE_TYPE_2D, VKVG_TILING,
+                                                             VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+                                                             0, &imgProps));
+    printf ("tiling                      = %d\n", VKVG_TILING);
+    printf ("max extend                  = (%d, %d, %d)\n", imgProps.maxExtent.width, imgProps.maxExtent.height,
+    imgProps.maxExtent.depth); printf ("max mip levels   = %d\n", imgProps.maxMipLevels); printf ("max array layers =
+    %d\n", imgProps.maxArrayLayers); printf ("sample counts      = "); if (imgProps.sampleCounts & VK_SAMPLE_COUNT_1_BIT)
+        printf ("1,");
+    if (imgProps.sampleCounts & VK_SAMPLE_COUNT_2_BIT)
+        printf ("2,");
+    if (imgProps.sampleCounts & VK_SAMPLE_COUNT_4_BIT)
+        printf ("4,");
+    if (imgProps.sampleCounts & VK_SAMPLE_COUNT_8_BIT)
+        printf ("8,");
+    if (imgProps.sampleCounts & VK_SAMPLE_COUNT_16_BIT)
+        printf ("16,");
+    if (imgProps.sampleCounts & VK_SAMPLE_COUNT_32_BIT)
+        printf ("32,");
+    printf ("\n");
+    printf ("max resource size= %lu\n", imgProps.maxResourceSize);
 */
-
 }
index ef8c95f0ad1032509bc32d76bf13203624b4ae9a..d17eae1a2f942209648c928ce138105dce0c2f68 100644 (file)
 #include "vkvg_internal.h"
 #include "vkvg_fonts.h"
 
-#define STENCIL_FILL_BIT       0x1
-#define STENCIL_CLIP_BIT       0x2
-#define STENCIL_ALL_BIT                0x3
+#define STENCIL_FILL_BIT              0x1
+#define STENCIL_CLIP_BIT              0x2
+#define STENCIL_ALL_BIT               0x3
 
 #define VKVG_MAX_CACHED_CONTEXT_COUNT 2
 
-extern PFN_vkCmdBindPipeline                   CmdBindPipeline;
-extern PFN_vkCmdBindDescriptorSets             CmdBindDescriptorSets;
-extern PFN_vkCmdBindIndexBuffer                        CmdBindIndexBuffer;
-extern PFN_vkCmdBindVertexBuffers              CmdBindVertexBuffers;
-
-extern PFN_vkCmdDrawIndexed                            CmdDrawIndexed;
-extern PFN_vkCmdDraw                                   CmdDraw;
-
-extern PFN_vkCmdSetStencilCompareMask  CmdSetStencilCompareMask;
-extern PFN_vkCmdSetStencilReference            CmdSetStencilReference;
-extern PFN_vkCmdSetStencilWriteMask            CmdSetStencilWriteMask;
-extern PFN_vkCmdBeginRenderPass                        CmdBeginRenderPass;
-extern PFN_vkCmdEndRenderPass                  CmdEndRenderPass;
-extern PFN_vkCmdSetViewport                            CmdSetViewport;
-extern PFN_vkCmdSetScissor                             CmdSetScissor;
-
-extern PFN_vkCmdPushConstants                  CmdPushConstants;
-extern PFN_vkWaitForFences                             WaitForFences;
-extern PFN_vkResetFences                               ResetFences;
-extern PFN_vkResetCommandBuffer                        ResetCommandBuffer;
-
-typedef struct _cached_ctx{
-       thrd_t                          thread;
-       VkvgContext                     ctx;
-       struct _cached_ctx*     pNext;
+extern PFN_vkCmdBindPipeline       CmdBindPipeline;
+extern PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets;
+extern PFN_vkCmdBindIndexBuffer    CmdBindIndexBuffer;
+extern PFN_vkCmdBindVertexBuffers  CmdBindVertexBuffers;
+
+extern PFN_vkCmdDrawIndexed CmdDrawIndexed;
+extern PFN_vkCmdDraw        CmdDraw;
+
+extern PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask;
+extern PFN_vkCmdSetStencilReference   CmdSetStencilReference;
+extern PFN_vkCmdSetStencilWriteMask   CmdSetStencilWriteMask;
+extern PFN_vkCmdBeginRenderPass       CmdBeginRenderPass;
+extern PFN_vkCmdEndRenderPass         CmdEndRenderPass;
+extern PFN_vkCmdSetViewport           CmdSetViewport;
+extern PFN_vkCmdSetScissor            CmdSetScissor;
+
+extern PFN_vkCmdPushConstants   CmdPushConstants;
+extern PFN_vkWaitForFences      WaitForFences;
+extern PFN_vkResetFences        ResetFences;
+extern PFN_vkResetCommandBuffer ResetCommandBuffer;
+
+typedef struct _cached_ctx {
+    thrd_t              thread;
+    VkvgContext         ctx;
+    struct _cached_ctx *pNext;
 } _cached_ctx;
 
 typedef struct _vkvg_device_t {
-       VkDevice                                vkDev;                                  /**< Vulkan Logical Device */
-       VkPhysicalDeviceMemoryProperties phyMemProps;   /**< Vulkan Physical device memory properties */
-       VkPhysicalDevice                phy;                                    /**< Vulkan Physical device */
-       VkInstance                              instance;                               /**< Vulkan instance */
+    VkDevice                         vkDev;       /**< Vulkan Logical Device */
+    VkPhysicalDeviceMemoryProperties phyMemProps; /**< Vulkan Physical device memory properties */
+    VkPhysicalDevice                 phy;         /**< Vulkan Physical device */
+    VkInstance                       instance;    /**< Vulkan instance */
 #ifdef VKH_USE_VMA
-       void*                                   allocator;                              /**< Vulkan Memory allocator */
+    void *allocator; /**< Vulkan Memory allocator */
 #endif
 
-       VkImageTiling                   supportedTiling;                /**< Supported image tiling for surface, 0xFF=no support */
-       VkFormat                                stencilFormat;                  /**< Supported vulkan image format for stencil */
-       VkImageAspectFlags              stencilAspectFlag;              /**< stencil only or depth stencil, could be solved by VK_KHR_separate_depth_stencil_layouts*/
-       VkFormat                                pngStagFormat;                  /**< Supported vulkan image format png write staging img */
-       VkImageTiling                   pngStagTiling;                  /**< tiling for the blit operation */
+    VkImageTiling      supportedTiling;   /**< Supported image tiling for surface, 0xFF=no support */
+    VkFormat           stencilFormat;     /**< Supported vulkan image format for stencil */
+    VkImageAspectFlags stencilAspectFlag; /**< stencil only or depth stencil, could be solved by
+                                             VK_KHR_separate_depth_stencil_layouts*/
+    VkFormat      pngStagFormat;          /**< Supported vulkan image format png write staging img */
+    VkImageTiling pngStagTiling;          /**< tiling for the blit operation */
 
-       mtx_t                                   mutex;                                  /**< protect device access (queue, cahes, ...)from ctxs in separate threads */
-       bool                                    threadAware;                    /**< if true, mutex is created and guard device queue and caches access */
-       VkhQueue                                gQueue;                                 /**< Vulkan Queue with Graphic flag */
+    mtx_t    mutex;       /**< protect device access (queue, cahes, ...)from ctxs in separate threads */
+    bool     threadAware; /**< if true, mutex is created and guard device queue and caches access */
+    VkhQueue gQueue;      /**< Vulkan Queue with Graphic flag */
 
-       VkRenderPass                    renderPass;                             /**< Vulkan render pass, common for all surfaces */
-       VkRenderPass                    renderPass_ClearStencil;/**< Vulkan render pass for first draw with context, stencil has to be cleared */
-       VkRenderPass                    renderPass_ClearAll;    /**< Vulkan render pass for new surface, clear all attacments*/
+    VkRenderPass renderPass; /**< Vulkan render pass, common for all surfaces */
+    VkRenderPass
+        renderPass_ClearStencil;      /**< Vulkan render pass for first draw with context, stencil has to be cleared */
+    VkRenderPass renderPass_ClearAll; /**< Vulkan render pass for new surface, clear all attacments*/
 
-       uint32_t                                references;                             /**< Reference count, prevent destroying device if still in use */
-       VkCommandPool                   cmdPool;                                /**< Global command pool for processing on surfaces without context */
-       VkCommandBuffer                 cmd;                                    /**< Global command buffer */
-       VkFence                                 fence;                                  /**< this fence is kept signaled when idle, wait and reset are called before each recording. */
+    uint32_t        references; /**< Reference count, prevent destroying device if still in use */
+    VkCommandPool   cmdPool;    /**< Global command pool for processing on surfaces without context */
+    VkCommandBuffer cmd;        /**< Global command buffer */
+    VkFence fence; /**< this fence is kept signaled when idle, wait and reset are called before each recording. */
 
-       VkPipeline                              pipe_OVER;                              /**< default operator */
-       VkPipeline                              pipe_SUB;
-       VkPipeline                              pipe_CLEAR;                             /**< clear operator */
+    VkPipeline pipe_OVER; /**< default operator */
+    VkPipeline pipe_SUB;
+    VkPipeline pipe_CLEAR; /**< clear operator */
 
-       VkPipeline                              pipelinePolyFill;               /**< even-odd polygon filling first step */
-       VkPipeline                              pipelineClipping;               /**< draw on stencil to update clipping regions */
+    VkPipeline pipelinePolyFill; /**< even-odd polygon filling first step */
+    VkPipeline pipelineClipping; /**< draw on stencil to update clipping regions */
 
-       VkPipelineCache                 pipelineCache;                  /**< speed up startup by caching configured pipelines on disk */
-       VkPipelineLayout                pipelineLayout;                 /**< layout common to all pipelines */
-       VkDescriptorSetLayout   dslFont;                                /**< font cache descriptors layout */
-       VkDescriptorSetLayout   dslSrc;                                 /**< context source surface descriptors layout */
-       VkDescriptorSetLayout   dslGrad;                                /**< context gradient descriptors layout */
+    VkPipelineCache       pipelineCache;  /**< speed up startup by caching configured pipelines on disk */
+    VkPipelineLayout      pipelineLayout; /**< layout common to all pipelines */
+    VkDescriptorSetLayout dslFont;        /**< font cache descriptors layout */
+    VkDescriptorSetLayout dslSrc;         /**< context source surface descriptors layout */
+    VkDescriptorSetLayout dslGrad;        /**< context gradient descriptors layout */
 
-       int                                             hdpi,                                   /**< only used for FreeType fonts and svg loading */
-                                                       vdpi;
+    int hdpi, /**< only used for FreeType fonts and svg loading */
+        vdpi;
 
-       VkhDevice                               vkhDev;                                 /**< old VkhDev created during vulkan context creation by @ref vkvg_device_create. */
+    VkhDevice vkhDev; /**< old VkhDev created during vulkan context creation by @ref vkvg_device_create. */
 
-       VkhImage                                emptyImg;                               /**< prevent unbound descriptor to trigger Validation error 61 */
-       VkSampleCountFlags              samples;                                /**< samples count common to all surfaces */
-       bool                                    deferredResolve;                /**< if true, resolve only on context destruction and set as source */
-       vkvg_status_t                   status;                                 /**< Current status of device, affected by last operation */
+    VkhImage           emptyImg;        /**< prevent unbound descriptor to trigger Validation error 61 */
+    VkSampleCountFlags samples;         /**< samples count common to all surfaces */
+    bool               deferredResolve; /**< if true, resolve only on context destruction and set as source */
+    vkvg_status_t      status;          /**< Current status of device, affected by last operation */
 
-       _font_cache_t*                  fontCache;                              /**< Store everything relative to common font caching system */
+    _font_cache_t *fontCache; /**< Store everything relative to common font caching system */
 
-       VkvgContext                             lastCtx;                                /**< last element of double linked list of context, used to trigger font caching system update on all contexts*/
+    VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update
+                            on all contexts*/
 
-       int32_t                                 cachedContextMaxCount;  /**< Maximum context cache element count.*/
-       int32_t                                 cachedContextCount;             /**< Current context cache element count.*/
-       _cached_ctx*                    cachedContextLast;              /**< Last element of single linked list of saved context for fast reuse.*/
+    int32_t      cachedContextMaxCount; /**< Maximum context cache element count.*/
+    int32_t      cachedContextCount;    /**< Current context cache element count.*/
+    _cached_ctx *cachedContextLast;     /**< Last element of single linked list of saved context for fast reuse.*/
 
 #ifdef VKVG_WIRED_DEBUG
-       VkPipeline                              pipelineWired;
-       VkPipeline                              pipelineLineList;
+    VkPipeline pipelineWired;
+    VkPipeline pipelineLineList;
 #endif
 #if VKVG_DBG_STATS
-       vkvg_debug_stats_t              debug_stats;                    /**< debug statistics on memory usage and vulkan ressources */
+    vkvg_debug_stats_t debug_stats; /**< debug statistics on memory usage and vulkan ressources */
 #endif
-}vkvg_device;
-
-#define LOCK_DEVICE \
-       if (dev->threadAware)\
-               mtx_lock (&dev->mutex);
-#define UNLOCK_DEVICE \
-       if (dev->threadAware)\
-               mtx_unlock (&dev->mutex);
-
-bool _device_try_get_phyinfo                   (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy);
-bool _device_init_function_pointers            (VkvgDevice dev);
-void _device_create_empty_texture              (VkvgDevice dev, VkFormat format, VkImageTiling tiling);
-void _device_get_best_image_tiling             (VkvgDevice dev, VkFormat format, VkImageTiling* pTiling);
-void _device_check_best_image_tiling   (VkvgDevice dev, VkFormat format);
-void _device_create_pipeline_cache             (VkvgDevice dev);
-VkRenderPass _device_createRenderPassMS        (VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp);
-VkRenderPass _device_createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp);
-void _device_setupPipelines                            (VkvgDevice dev);
-void _device_createDescriptorSetLayout         (VkvgDevice dev);
-void _device_wait_idle                                 (VkvgDevice dev);
-void _device_wait_and_reset_device_fence(VkvgDevice dev);
-void _device_submit_cmd                                        (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence);
-
-bool _device_try_get_cached_context            (VkvgDevice dev, VkvgContext* pCtx);
-void _device_store_context                             (VkvgContext ctx);
+} vkvg_device;
+
+#define LOCK_DEVICE                                                                                                    \
+    if (dev->threadAware)                                                                                              \
+        mtx_lock(&dev->mutex);
+#define UNLOCK_DEVICE                                                                                                  \
+    if (dev->threadAware)                                                                                              \
+        mtx_unlock(&dev->mutex);
+
+bool _device_try_get_phyinfo(VkhPhyInfo *phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo *phy);
+bool _device_init_function_pointers(VkvgDevice dev);
+void _device_create_empty_texture(VkvgDevice dev, VkFormat format, VkImageTiling tiling);
+void _device_get_best_image_tiling(VkvgDevice dev, VkFormat format, VkImageTiling *pTiling);
+void _device_check_best_image_tiling(VkvgDevice dev, VkFormat format);
+void _device_create_pipeline_cache(VkvgDevice dev);
+VkRenderPass _device_createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp);
+VkRenderPass _device_createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp,
+                                               VkAttachmentLoadOp stencilLoadOp);
+void         _device_setupPipelines(VkvgDevice dev);
+void         _device_createDescriptorSetLayout(VkvgDevice dev);
+void         _device_wait_idle(VkvgDevice dev);
+void         _device_wait_and_reset_device_fence(VkvgDevice dev);
+void         _device_submit_cmd(VkvgDevice dev, VkCommandBuffer *cmd, VkFence fence);
+
+bool _device_try_get_cached_context(VkvgDevice dev, VkvgContext *pCtx);
+void _device_store_context(VkvgContext ctx);
 #endif
index 3e3e022fe531791b4b2d13998558b49759cfac32..31679c0ea0771f927b569f44ccfb61d0c00d770a 100644 (file)
@@ -23,6 +23,3 @@
 #include <string.h>
 #include "vkvg_experimental.h"
 #include "vkvg_context_internal.h"
-
-
-
index 35858f3b79e6e39466375716f3cb2748bfd3ff4b..868f42b45e4d4876c1e590751391c51791c45585 100644 (file)
 #include <wchar.h>
 
 #ifndef VKVG_USE_FREETYPE
-       #define STB_TRUETYPE_IMPLEMENTATION
-       #include "stb_truetype.h"
+#define STB_TRUETYPE_IMPLEMENTATION
+#include "stb_truetype.h"
 #endif
 
-static int defaultFontCharSize = 12<<6;
+static int defaultFontCharSize = 12 << 6;
 
-void _fonts_cache_create (VkvgDevice dev){
-       _font_cache_t* cache = (_font_cache_t*)calloc(1, sizeof(_font_cache_t));
+void _fonts_cache_create(VkvgDevice dev) {
+    _font_cache_t *cache = (_font_cache_t *)calloc(1, sizeof(_font_cache_t));
 
-       if (dev->threadAware)
-               mtx_init (&cache->mutex, mtx_plain);
+    if (dev->threadAware)
+        mtx_init(&cache->mutex, mtx_plain);
 
 #ifdef VKVG_USE_FONTCONFIG
-       cache->config = FcInitLoadConfigAndFonts ();
-       if (!cache->config) {
-               LOG(VKVG_LOG_DEBUG, "Font config initialisation failed, consider using 'FONTCONFIG_PATH' and 'FONTCONFIG_FILE' environmane\
+    cache->config = FcInitLoadConfigAndFonts();
+    if (!cache->config) {
+        LOG(VKVG_LOG_DEBUG,
+            "Font config initialisation failed, consider using 'FONTCONFIG_PATH' and 'FONTCONFIG_FILE' environmane\
                                           variables to point to 'fonts.conf' needed for FontConfig startup");
-               assert(cache->config);
-       }
+        assert(cache->config);
+    }
 #endif
 
 #ifdef VKVG_USE_FREETYPE
-       FT_CHECK_RESULT(FT_Init_FreeType(&cache->library));
+    FT_CHECK_RESULT(FT_Init_FreeType(&cache->library));
 #endif
 
 #if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
-       FT_CHECK_RESULT(FT_Library_SetLcdFilter (cache->library, FT_LCD_FILTER_LIGHT));
-       cache->texFormat = FB_COLOR_FORMAT;
-       cache->texPixelSize = 4;
+    FT_CHECK_RESULT(FT_Library_SetLcdFilter(cache->library, FT_LCD_FILTER_LIGHT));
+    cache->texFormat    = FB_COLOR_FORMAT;
+    cache->texPixelSize = 4;
 #else
-       cache->texFormat = VK_FORMAT_R8_UNORM;
-       cache->texPixelSize = 1;
+    cache->texFormat    = VK_FORMAT_R8_UNORM;
+    cache->texPixelSize = 1;
 #endif
 
-       cache->texLength = FONT_CACHE_INIT_LAYERS;
-       cache->texture = vkh_tex2d_array_create ((VkhDevice)dev, cache->texFormat, FONT_PAGE_SIZE, FONT_PAGE_SIZE,
-                                                       cache->texLength ,VKH_MEMORY_USAGE_GPU_ONLY,
-                                                       VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
-       vkh_image_create_descriptor (cache->texture, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                                VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
+    cache->texLength = FONT_CACHE_INIT_LAYERS;
+    cache->texture   = vkh_tex2d_array_create(
+        (VkhDevice)dev, cache->texFormat, FONT_PAGE_SIZE, FONT_PAGE_SIZE, cache->texLength, VKH_MEMORY_USAGE_GPU_ONLY,
+        VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+    vkh_image_create_descriptor(cache->texture, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_ASPECT_COLOR_BIT,
+                                VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                                VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
 
-       cache->uploadFence = vkh_fence_create((VkhDevice)dev);
+    cache->uploadFence = vkh_fence_create((VkhDevice)dev);
 
-       const uint32_t buffLength = FONT_PAGE_SIZE*FONT_PAGE_SIZE*cache->texPixelSize;
+    const uint32_t buffLength = FONT_PAGE_SIZE * FONT_PAGE_SIZE * cache->texPixelSize;
 
-       vkh_buffer_init ((VkhDevice)dev,
-               VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
-               VKH_MEMORY_USAGE_CPU_TO_GPU,
-               buffLength, &cache->buff, true);
+    vkh_buffer_init((VkhDevice)dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VKH_MEMORY_USAGE_CPU_TO_GPU, buffLength,
+                    &cache->buff, true);
 
-       cache->cmd = vkh_cmd_buff_create((VkhDevice)dev,dev->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+    cache->cmd = vkh_cmd_buff_create((VkhDevice)dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
 
-       //Set texture cache initial layout to shaderReadOnly to prevent error msg if cache is not fill
-       const VkImageSubresourceRange subres = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,cache->texLength};
-       vkh_cmd_begin (cache->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-       vkh_image_set_layout_subres(cache->cmd, cache->texture, subres,
-                                                               VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
-                                                               VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
-       VK_CHECK_RESULT(vkEndCommandBuffer(cache->cmd));
-       _device_submit_cmd (dev, &cache->cmd, cache->uploadFence);
+    // Set texture cache initial layout to shaderReadOnly to prevent error msg if cache is not fill
+    const VkImageSubresourceRange subres = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, cache->texLength};
+    vkh_cmd_begin(cache->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_image_set_layout_subres(cache->cmd, cache->texture, subres, VK_IMAGE_LAYOUT_UNDEFINED,
+                                VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
+    VK_CHECK_RESULT(vkEndCommandBuffer(cache->cmd));
+    _device_submit_cmd(dev, &cache->cmd, cache->uploadFence);
 
-       cache->hostBuff = (uint8_t*)malloc(buffLength);
-       cache->pensY = (int*)calloc(cache->texLength, sizeof(int));
+    cache->hostBuff = (uint8_t *)malloc(buffLength);
+    cache->pensY    = (int *)calloc(cache->texLength, sizeof(int));
 
-       dev->fontCache = cache;
+    dev->fontCache = cache;
 }
-///increase layer count of 2d texture array used as font cache.
-void _increase_font_tex_array (VkvgDevice dev){
-       LOG(VKVG_LOG_INFO, "_increase_font_tex_array\n");
+/// increase layer count of 2d texture array used as font cache.
+void _increase_font_tex_array(VkvgDevice dev) {
+    LOG(VKVG_LOG_INFO, "_increase_font_tex_array\n");
 
-       _font_cache_t* cache = dev->fontCache;
+    _font_cache_t *cache = dev->fontCache;
 
-       vkWaitForFences         (dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
-       ResetFences (dev->vkDev, 1, &cache->uploadFence);
+    vkWaitForFences(dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
+    ResetFences(dev->vkDev, 1, &cache->uploadFence);
 
-       vkResetCommandBuffer(cache->cmd, 0);
+    vkResetCommandBuffer(cache->cmd, 0);
 
-       uint8_t newSize = cache->texLength + FONT_CACHE_INIT_LAYERS;
-       VkhImage newImg = vkh_tex2d_array_create ((VkhDevice)dev, cache->texFormat, FONT_PAGE_SIZE, FONT_PAGE_SIZE,
-                                                                                         newSize ,VKH_MEMORY_USAGE_GPU_ONLY,
-                                                                                         VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
-       vkh_image_create_descriptor (newImg, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                          VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
+    uint8_t  newSize = cache->texLength + FONT_CACHE_INIT_LAYERS;
+    VkhImage newImg  = vkh_tex2d_array_create(
+        (VkhDevice)dev, cache->texFormat, FONT_PAGE_SIZE, FONT_PAGE_SIZE, newSize, VKH_MEMORY_USAGE_GPU_ONLY,
+        VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+    vkh_image_create_descriptor(newImg, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST,
+                                VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                                VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
 
-       VkImageSubresourceRange subresNew       = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,newSize};
-       VkImageSubresourceRange subres          = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,cache->texLength};
+    VkImageSubresourceRange subresNew = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, newSize};
+    VkImageSubresourceRange subres    = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, cache->texLength};
 
-       vkh_cmd_begin (cache->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_cmd_begin(cache->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
 
-       vkh_image_set_layout_subres(cache->cmd, newImg, subresNew,
-                                                               VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                               VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-       vkh_image_set_layout_subres(cache->cmd, cache->texture, subres,
-                                                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                               VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+    vkh_image_set_layout_subres(cache->cmd, newImg, subresNew, VK_IMAGE_LAYOUT_UNDEFINED,
+                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                                VK_PIPELINE_STAGE_TRANSFER_BIT);
+    vkh_image_set_layout_subres(cache->cmd, cache->texture, subres, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                                VK_PIPELINE_STAGE_TRANSFER_BIT);
 
-       VkImageCopy cregion = { .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, cache->texLength},
-                                                       .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, cache->texLength},
-                                                       .extent = {FONT_PAGE_SIZE,FONT_PAGE_SIZE,1}};
+    VkImageCopy cregion = {.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, cache->texLength},
+                           .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, cache->texLength},
+                           .extent         = {FONT_PAGE_SIZE, FONT_PAGE_SIZE, 1}};
 
-       vkCmdCopyImage (cache->cmd, vkh_image_get_vkimage (cache->texture), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                               vkh_image_get_vkimage (newImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
+    vkCmdCopyImage(cache->cmd, vkh_image_get_vkimage(cache->texture), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                   vkh_image_get_vkimage(newImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
 
-       vkh_image_set_layout_subres(cache->cmd, newImg, subresNew,
-                                                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
-                                                               VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
-       vkh_image_set_layout_subres(cache->cmd, cache->texture, subres,
-                                                               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
-                                                               VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
+    vkh_image_set_layout_subres(cache->cmd, newImg, subresNew, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
+    vkh_image_set_layout_subres(cache->cmd, cache->texture, subres, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
 
-       VK_CHECK_RESULT(vkEndCommandBuffer(cache->cmd));
+    VK_CHECK_RESULT(vkEndCommandBuffer(cache->cmd));
 
-       _device_submit_cmd                      (dev, &cache->cmd, cache->uploadFence);
-       vkWaitForFences         (dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
+    _device_submit_cmd(dev, &cache->cmd, cache->uploadFence);
+    vkWaitForFences(dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
 
-       cache->pensY = (int*)realloc(cache->pensY, newSize * sizeof(int));
-       void* tmp = memset (&cache->pensY[cache->texLength],0,FONT_CACHE_INIT_LAYERS*sizeof(int));
+    cache->pensY = (int *)realloc(cache->pensY, newSize * sizeof(int));
+    void *tmp    = memset(&cache->pensY[cache->texLength], 0, FONT_CACHE_INIT_LAYERS * sizeof(int));
 
-       vkh_image_destroy       (cache->texture);
+    vkh_image_destroy(cache->texture);
 
-       cache->texLength   = newSize;
-       cache->texture     = newImg;
+    cache->texLength = newSize;
+    cache->texture   = newImg;
 
-       _device_wait_idle(dev);
+    _device_wait_idle(dev);
 }
-//flush font stagging buffer to cache texture array
-//Trigger stagging buffer to be uploaded in font cache. Groupping upload improve performances.
-void _flush_chars_to_tex (VkvgDevice dev, _vkvg_font_t* f) {
+// flush font stagging buffer to cache texture array
+// Trigger stagging buffer to be uploaded in font cache. Groupping upload improve performances.
+void _flush_chars_to_tex(VkvgDevice dev, _vkvg_font_t *f) {
 
-       _font_cache_t* cache = dev->fontCache;
-       if (cache->stagingX == 0)//no char in stagging buff to flush
-               return;
+    _font_cache_t *cache = dev->fontCache;
+    if (cache->stagingX == 0) // no char in stagging buff to flush
+        return;
 
-       LOG(VKVG_LOG_INFO, "_flush_chars_to_tex pen(%d, %d)\n",f->curLine.penX, f->curLine.penY);
-       vkWaitForFences         (dev->vkDev,1,&cache->uploadFence,VK_TRUE,UINT64_MAX);
-       ResetFences (dev->vkDev, 1, &cache->uploadFence);
+    LOG(VKVG_LOG_INFO, "_flush_chars_to_tex pen(%d, %d)\n", f->curLine.penX, f->curLine.penY);
+    vkWaitForFences(dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
+    ResetFences(dev->vkDev, 1, &cache->uploadFence);
 
-       vkResetCommandBuffer(cache->cmd,0);
+    vkResetCommandBuffer(cache->cmd, 0);
 
-       memcpy(vkh_buffer_get_mapped_pointer (&cache->buff), cache->hostBuff, (uint64_t)f->curLine.height * FONT_PAGE_SIZE * cache->texPixelSize);
+    memcpy(vkh_buffer_get_mapped_pointer(&cache->buff), cache->hostBuff,
+           (uint64_t)f->curLine.height * FONT_PAGE_SIZE * cache->texPixelSize);
 
-       vkh_cmd_begin (cache->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_cmd_begin(cache->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
 
-       VkImageSubresourceRange subres          = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,f->curLine.pageIdx,1};
-       vkh_image_set_layout_subres(cache->cmd, cache->texture, subres,
-                                                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                               VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+    VkImageSubresourceRange subres = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, f->curLine.pageIdx, 1};
+    vkh_image_set_layout_subres(cache->cmd, cache->texture, subres, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                                VK_PIPELINE_STAGE_TRANSFER_BIT);
 
-       VkBufferImageCopy bufferCopyRegion = { .imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,f->curLine.pageIdx,1},
-                                                                                  .bufferRowLength = FONT_PAGE_SIZE,
-                                                                                  .bufferImageHeight = f->curLine.height,
-                                                                                  .imageOffset = {f->curLine.penX,f->curLine.penY,0},
-                                                                                  .imageExtent = {FONT_PAGE_SIZE-f->curLine.penX,f->curLine.height,1}};
+    VkBufferImageCopy bufferCopyRegion = {.imageSubresource  = {VK_IMAGE_ASPECT_COLOR_BIT, 0, f->curLine.pageIdx, 1},
+                                          .bufferRowLength   = FONT_PAGE_SIZE,
+                                          .bufferImageHeight = f->curLine.height,
+                                          .imageOffset       = {f->curLine.penX, f->curLine.penY, 0},
+                                          .imageExtent = {FONT_PAGE_SIZE - f->curLine.penX, f->curLine.height, 1}};
 
-       vkCmdCopyBufferToImage(cache->cmd, cache->buff.buffer,
-                                                  vkh_image_get_vkimage (cache->texture), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion);
+    vkCmdCopyBufferToImage(cache->cmd, cache->buff.buffer, vkh_image_get_vkimage(cache->texture),
+                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion);
 
-       vkh_image_set_layout_subres(cache->cmd, cache->texture, subres,
-                                                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
-                                                               VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
+    vkh_image_set_layout_subres(cache->cmd, cache->texture, subres, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
 
-       VK_CHECK_RESULT(vkEndCommandBuffer(cache->cmd));
+    VK_CHECK_RESULT(vkEndCommandBuffer(cache->cmd));
 
-       _device_submit_cmd (dev, &cache->cmd, cache->uploadFence);
+    _device_submit_cmd(dev, &cache->cmd, cache->uploadFence);
 
-       f->curLine.penX += cache->stagingX;
-       cache->stagingX = 0;
-       memset(cache->hostBuff, 0, (uint64_t)FONT_PAGE_SIZE * FONT_PAGE_SIZE * cache->texPixelSize);
+    f->curLine.penX += cache->stagingX;
+    cache->stagingX = 0;
+    memset(cache->hostBuff, 0, (uint64_t)FONT_PAGE_SIZE * FONT_PAGE_SIZE * cache->texPixelSize);
 }
-///Start a new line in font cache, increase texture layer count if needed.
-void _init_next_line_in_tex_cache (VkvgDevice dev, _vkvg_font_t* f){
-       _font_cache_t* cache = dev->fontCache;
-       int i;
-       for (i = 0; i < cache->texLength; ++i) {
-               if (cache->pensY[i] + f->curLine.height >= FONT_PAGE_SIZE)
-                       continue;
-               f->curLine.pageIdx = (unsigned char)i;
-               f->curLine.penX = 0;
-               f->curLine.penY = cache->pensY[i];
-               cache->pensY[i] += f->curLine.height;
-               return;
-       }
-       _flush_chars_to_tex                     (dev, f);
-       _increase_font_tex_array        (dev);
-       _init_next_line_in_tex_cache(dev, f);
+/// Start a new line in font cache, increase texture layer count if needed.
+void _init_next_line_in_tex_cache(VkvgDevice dev, _vkvg_font_t *f) {
+    _font_cache_t *cache = dev->fontCache;
+    int            i;
+    for (i = 0; i < cache->texLength; ++i) {
+        if (cache->pensY[i] + f->curLine.height >= FONT_PAGE_SIZE)
+            continue;
+        f->curLine.pageIdx = (unsigned char)i;
+        f->curLine.penX    = 0;
+        f->curLine.penY    = cache->pensY[i];
+        cache->pensY[i] += f->curLine.height;
+        return;
+    }
+    _flush_chars_to_tex(dev, f);
+    _increase_font_tex_array(dev);
+    _init_next_line_in_tex_cache(dev, f);
 }
-void _font_cache_destroy (VkvgDevice dev){
-       _font_cache_t* cache = (_font_cache_t*)dev->fontCache;
+void _font_cache_destroy(VkvgDevice dev) {
+    _font_cache_t *cache = (_font_cache_t *)dev->fontCache;
 
-       free (cache->hostBuff);
+    free(cache->hostBuff);
 
-       for (int i = 0; i < cache->fontsCount; ++i) {
-               _vkvg_font_identity_t* f = &cache->fonts[i];
-               for (uint32_t j = 0; j < f->sizeCount; j++) {
-                       _vkvg_font_t* s = &f->sizes[j];
+    for (int i = 0; i < cache->fontsCount; ++i) {
+        _vkvg_font_identity_t *f = &cache->fonts[i];
+        for (uint32_t j = 0; j < f->sizeCount; j++) {
+            _vkvg_font_t *s = &f->sizes[j];
 #ifdef VKVG_USE_FREETYPE
-                       for (int g = 0; g < s->face->num_glyphs; ++g) {
-                               if (s->charLookup[g]!=NULL)
-                                       free(s->charLookup[g]);
-                       }
-                       FT_Done_Face (s->face);
+            for (int g = 0; g < s->face->num_glyphs; ++g) {
+                if (s->charLookup[g] != NULL)
+                    free(s->charLookup[g]);
+            }
+            FT_Done_Face(s->face);
 #else
-                       for (int g = 0; g < f->stbInfo.numGlyphs; ++g) {
-                               if (s->charLookup[g]!=NULL)
-                                       free(s->charLookup[g]);
-                       }
+            for (int g = 0; g < f->stbInfo.numGlyphs; ++g) {
+                if (s->charLookup[g] != NULL)
+                    free(s->charLookup[g]);
+            }
 #endif
 
 #ifdef VKVG_USE_HARFBUZZ
-                       hb_font_destroy (s->hb_font);
+            hb_font_destroy(s->hb_font);
 #endif
 
-                       free(s->charLookup);
-               }
-               free (f->sizes);
-               free(f->fontFile);
-               for (uint32_t j = 0; j < f->namesCount; j++)
-                       free (f->names[j]);
-               if (f->namesCount > 0)
-                       free (f->names);
-               free (f->fontBuffer);
-       }
-
-       free(cache->fonts);
-       free(cache->pensY);
-
-       vkh_buffer_reset        (&cache->buff);
-       vkh_image_destroy       (cache->texture);
-       //vkFreeCommandBuffers(dev->vkDev,dev->cmdPool, 1, &cache->cmd);
-       vkDestroyFence          (dev->vkDev,cache->uploadFence,NULL);
+            free(s->charLookup);
+        }
+        free(f->sizes);
+        free(f->fontFile);
+        for (uint32_t j = 0; j < f->namesCount; j++)
+            free(f->names[j]);
+        if (f->namesCount > 0)
+            free(f->names);
+        free(f->fontBuffer);
+    }
+
+    free(cache->fonts);
+    free(cache->pensY);
+
+    vkh_buffer_reset(&cache->buff);
+    vkh_image_destroy(cache->texture);
+    // vkFreeCommandBuffers(dev->vkDev,dev->cmdPool, 1, &cache->cmd);
+    vkDestroyFence(dev->vkDev, cache->uploadFence, NULL);
 #ifdef VKVG_USE_FREETYPE
-       FT_Done_FreeType(cache->library);
+    FT_Done_FreeType(cache->library);
 #endif
 #ifdef VKVG_USE_FONTCONFIG
-       FcConfigDestroy(cache->config);
-       FcFini();
+    FcConfigDestroy(cache->config);
+    FcFini();
 #endif
 
-       if (dev->threadAware)
-               mtx_destroy (&cache->mutex);
-
-       free (dev->fontCache);
+    if (dev->threadAware)
+        mtx_destroy(&cache->mutex);
 
+    free(dev->fontCache);
 }
 
-void _font_cache_update_context_descset (VkvgContext ctx) {
-       if (ctx->fontCacheImg)
-               vkh_image_destroy (ctx->fontCacheImg);
+void _font_cache_update_context_descset(VkvgContext ctx) {
+    if (ctx->fontCacheImg)
+        vkh_image_destroy(ctx->fontCacheImg);
 
-       LOCK_FONTCACHE (ctx->dev)
+    LOCK_FONTCACHE(ctx->dev)
 
-       ctx->fontCacheImg = ctx->dev->fontCache->texture;
-       vkh_image_reference (ctx->fontCacheImg);
+    ctx->fontCacheImg = ctx->dev->fontCache->texture;
+    vkh_image_reference(ctx->fontCacheImg);
 
-       _update_descriptor_set (ctx, ctx->fontCacheImg, ctx->dsFont);
+    _update_descriptor_set(ctx, ctx->fontCacheImg, ctx->dsFont);
 
-       UNLOCK_FONTCACHE (ctx->dev)
+    UNLOCK_FONTCACHE(ctx->dev)
 }
-//create a new char entry and put glyph in stagging buffer, ready for upload.
-_char_ref* _prepare_char (VkvgDevice dev, VkvgText tr, uint32_t gindex){
-       _vkvg_font_t* f = tr->font;
+// create a new char entry and put glyph in stagging buffer, ready for upload.
+_char_ref *_prepare_char(VkvgDevice dev, VkvgText tr, uint32_t gindex) {
+    _vkvg_font_t *f = tr->font;
 #ifdef VKVG_USE_FREETYPE
-       #if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
-               FT_CHECK_RESULT(FT_Load_Glyph(f->face, gindex, FT_LOAD_TARGET_NORMAL));
-               FT_CHECK_RESULT(FT_Render_Glyph(f->face->glyph, FT_RENDER_MODE_LCD));
-       #else
-               FT_CHECK_RESULT(FT_Load_Glyph(f->face, gindex, FT_LOAD_RENDER));
-       #endif
-
-       FT_GlyphSlot    slot                    = f->face->glyph;
-       FT_Bitmap               bmp                             = slot->bitmap;
-       uint32_t                bmpByteWidth    = bmp.width;
-       uint32_t                bmpPixelWidth   = bmp.width;
-       uint32_t                bmpRows                 = bmp.rows;
-       unsigned char*  buffer                  = bmp.buffer;
+#if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
+    FT_CHECK_RESULT(FT_Load_Glyph(f->face, gindex, FT_LOAD_TARGET_NORMAL));
+    FT_CHECK_RESULT(FT_Render_Glyph(f->face->glyph, FT_RENDER_MODE_LCD));
+#else
+    FT_CHECK_RESULT(FT_Load_Glyph(f->face, gindex, FT_LOAD_RENDER));
+#endif
+
+    FT_GlyphSlot   slot          = f->face->glyph;
+    FT_Bitmap      bmp           = slot->bitmap;
+    uint32_t       bmpByteWidth  = bmp.width;
+    uint32_t       bmpPixelWidth = bmp.width;
+    uint32_t       bmpRows       = bmp.rows;
+    unsigned char *buffer        = bmp.buffer;
 
 #if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
-       bmpPixelWidth /= 3;
+    bmpPixelWidth /= 3;
 #endif
 #else
-       stbtt_fontinfo* pStbInfo = &tr->fontId->stbInfo;
-       int c_x1, c_y1, c_x2, c_y2;
-       stbtt_GetGlyphBitmapBox (pStbInfo, gindex, f->scale, f->scale, &c_x1, &c_y1, &c_x2, &c_y2);
-       uint32_t bmpByteWidth   = c_x2 - c_x1;
-       uint32_t bmpPixelWidth  = bmpByteWidth;
-       uint32_t bmpRows                = c_y2 - c_y1;
+    stbtt_fontinfo *pStbInfo = &tr->fontId->stbInfo;
+    int             c_x1, c_y1, c_x2, c_y2;
+    stbtt_GetGlyphBitmapBox(pStbInfo, gindex, f->scale, f->scale, &c_x1, &c_y1, &c_x2, &c_y2);
+    uint32_t bmpByteWidth  = c_x2 - c_x1;
+    uint32_t bmpPixelWidth = bmpByteWidth;
+    uint32_t bmpRows       = c_y2 - c_y1;
 #endif
-       uint8_t* data = dev->fontCache->hostBuff;
+    uint8_t *data = dev->fontCache->hostBuff;
 
-       if (dev->fontCache->stagingX + f->curLine.penX + bmpPixelWidth > FONT_PAGE_SIZE){
-               _flush_chars_to_tex (dev, f);
-               _init_next_line_in_tex_cache (dev, f);
-       }
+    if (dev->fontCache->stagingX + f->curLine.penX + bmpPixelWidth > FONT_PAGE_SIZE) {
+        _flush_chars_to_tex(dev, f);
+        _init_next_line_in_tex_cache(dev, f);
+    }
 
-       _char_ref* cr = (_char_ref*)malloc(sizeof(_char_ref));
-       int penX = dev->fontCache->stagingX;
+    _char_ref *cr   = (_char_ref *)malloc(sizeof(_char_ref));
+    int        penX = dev->fontCache->stagingX;
 
 #ifdef VKVG_USE_FREETYPE
-       for(uint32_t y=0; y < bmpRows; y++) {
-               for(uint32_t x=0; x < bmpPixelWidth; x++) {
+    for (uint32_t y = 0; y < bmpRows; y++) {
+        for (uint32_t x = 0; x < bmpPixelWidth; x++) {
 #if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
-                       unsigned char r = buffer[y * bmp.pitch + x * 3];
-                       unsigned char g = buffer[y * bmp.pitch + x * 3 + 1];
-                       unsigned char b = buffer[y * bmp.pitch + x * 3 + 2];
-
-                       data[(penX + x + y * FONT_PAGE_SIZE) * 4] = b;
-                       data[(penX + x + y * FONT_PAGE_SIZE) * 4 + 1] = g;
-                       data[(penX + x + y * FONT_PAGE_SIZE) * 4 + 2] = r;
-                       data[(penX + x + y * FONT_PAGE_SIZE) * 4 + 3] = (r+g+b)/3;
+            unsigned char r = buffer[y * bmp.pitch + x * 3];
+            unsigned char g = buffer[y * bmp.pitch + x * 3 + 1];
+            unsigned char b = buffer[y * bmp.pitch + x * 3 + 2];
+
+            data[(penX + x + y * FONT_PAGE_SIZE) * 4]     = b;
+            data[(penX + x + y * FONT_PAGE_SIZE) * 4 + 1] = g;
+            data[(penX + x + y * FONT_PAGE_SIZE) * 4 + 2] = r;
+            data[(penX + x + y * FONT_PAGE_SIZE) * 4 + 3] = (r + g + b) / 3;
 #else
-                       data[penX + x + y * FONT_PAGE_SIZE ] = buffer[x + y * bmpPixelWidth];
+            data[penX + x + y * FONT_PAGE_SIZE] = buffer[x + y * bmpPixelWidth];
 #endif
-               }
-       }
-       cr->bmpDiff.x   = (int16_t)slot->bitmap_left;
-       cr->bmpDiff.y   = (int16_t)slot->bitmap_top;
-       cr->advance             = slot->advance;
+        }
+    }
+    cr->bmpDiff.x = (int16_t)slot->bitmap_left;
+    cr->bmpDiff.y = (int16_t)slot->bitmap_top;
+    cr->advance   = slot->advance;
 #else
-       int advance;
-       int lsb;
-       stbtt_GetGlyphHMetrics(pStbInfo, gindex, &advance, &lsb);
-       stbtt_MakeGlyphBitmap (pStbInfo, data + penX, bmpPixelWidth, bmpRows, FONT_PAGE_SIZE, f->scale, f->scale, gindex);
-       cr->bmpDiff.x   = (int16_t)c_x1;
-       cr->bmpDiff.y   = (int16_t)-c_y1;
-       cr->advance             = (vec2) {(uint32_t)roundf (f->scale * advance) << 6, 0};
+    int      advance;
+    int      lsb;
+    stbtt_GetGlyphHMetrics(pStbInfo, gindex, &advance, &lsb);
+    stbtt_MakeGlyphBitmap(pStbInfo, data + penX, bmpPixelWidth, bmpRows, FONT_PAGE_SIZE, f->scale, f->scale, gindex);
+    cr->bmpDiff.x = (int16_t)c_x1;
+    cr->bmpDiff.y = (int16_t)-c_y1;
+    cr->advance   = (vec2){(uint32_t)roundf(f->scale * advance) << 6, 0};
 #endif
-       vec4 uvBounds = {
-               {(float)(penX + f->curLine.penX) / (float)FONT_PAGE_SIZE},
-               {(float)f->curLine.penY / (float)FONT_PAGE_SIZE},
-               {(float)bmpPixelWidth},
-               {(float)bmpRows}};
-       cr->bounds              = uvBounds;
-       cr->pageIdx             = f->curLine.pageIdx;
-
-       f->charLookup[gindex] = cr;
-       dev->fontCache->stagingX += bmpPixelWidth;
-       return cr;
+    vec4 uvBounds = {{(float)(penX + f->curLine.penX) / (float)FONT_PAGE_SIZE},
+                     {(float)f->curLine.penY / (float)FONT_PAGE_SIZE},
+                     {(float)bmpPixelWidth},
+                     {(float)bmpRows}};
+    cr->bounds    = uvBounds;
+    cr->pageIdx   = f->curLine.pageIdx;
+
+    f->charLookup[gindex] = cr;
+    dev->fontCache->stagingX += bmpPixelWidth;
+    return cr;
 }
-void _font_add_name (_vkvg_font_identity_t* font, const char* name) {
-       if (++font->namesCount == 1)
-               font->names = (char**) malloc (sizeof(char*));
-       else
-               font->names = (char**) realloc (font->names, font->namesCount * sizeof(char*));
-       font->names[font->namesCount-1] = (char*)calloc(strlen(name)+1, sizeof (char));
-       strcpy (font->names[font->namesCount-1], name);
+void _font_add_name(_vkvg_font_identity_t *font, const char *name) {
+    if (++font->namesCount == 1)
+        font->names = (char **)malloc(sizeof(char *));
+    else
+        font->names = (char **)realloc(font->names, font->namesCount * sizeof(char *));
+    font->names[font->namesCount - 1] = (char *)calloc(strlen(name) + 1, sizeof(char));
+    strcpy(font->names[font->namesCount - 1], name);
 }
-bool _font_cache_load_font_file_in_memory (_vkvg_font_identity_t* fontId) {
-       FILE* fontFile = fopen(fontId->fontFile, "rb");
-       if (!fontFile)
-               return false;
-       fseek(fontFile, 0, SEEK_END);
-       fontId->fontBufSize = ftell(fontFile); /* how long is the file ? */
-       fseek(fontFile, 0, SEEK_SET); /* reset */
-       fontId->fontBuffer = malloc(fontId->fontBufSize);
-       fread(fontId->fontBuffer, fontId->fontBufSize, 1, fontFile);
-       fclose(fontFile);
-       return true;
+bool _font_cache_load_font_file_in_memory(_vkvg_font_identity_t *fontId) {
+    FILE *fontFile = fopen(fontId->fontFile, "rb");
+    if (!fontFile)
+        return false;
+    fseek(fontFile, 0, SEEK_END);
+    fontId->fontBufSize = ftell(fontFile); /* how long is the file ? */
+    fseek(fontFile, 0, SEEK_SET);          /* reset */
+    fontId->fontBuffer = malloc(fontId->fontBufSize);
+    fread(fontId->fontBuffer, fontId->fontBufSize, 1, fontFile);
+    fclose(fontFile);
+    return true;
 }
-_vkvg_font_identity_t* _font_cache_add_font_identity (VkvgContext ctx, const char* fontFilePath, const char* name){
-       _font_cache_t*  cache = (_font_cache_t*)ctx->dev->fontCache;
-       if (++cache->fontsCount == 1)
-               cache->fonts = (_vkvg_font_identity_t*) malloc (cache->fontsCount * sizeof(_vkvg_font_identity_t));
-       else
-               cache->fonts = (_vkvg_font_identity_t*) realloc (cache->fonts, cache->fontsCount * sizeof(_vkvg_font_identity_t));
-       _vkvg_font_identity_t nf = {0};
-
-       if (fontFilePath) {
-               int fflength = strlen (fontFilePath) + 1;
-               nf.fontFile = (char*)malloc (fflength * sizeof(char));
-               strcpy (nf.fontFile, fontFilePath);
-       }
-
-       _font_add_name (&nf, name);
-
-       cache->fonts[cache->fontsCount-1] = nf;
-       return &cache->fonts[cache->fontsCount-1];
+_vkvg_font_identity_t *_font_cache_add_font_identity(VkvgContext ctx, const char *fontFilePath, const char *name) {
+    _font_cache_t *cache = (_font_cache_t *)ctx->dev->fontCache;
+    if (++cache->fontsCount == 1)
+        cache->fonts = (_vkvg_font_identity_t *)malloc(cache->fontsCount * sizeof(_vkvg_font_identity_t));
+    else
+        cache->fonts =
+            (_vkvg_font_identity_t *)realloc(cache->fonts, cache->fontsCount * sizeof(_vkvg_font_identity_t));
+    _vkvg_font_identity_t nf = {0};
+
+    if (fontFilePath) {
+        int fflength = strlen(fontFilePath) + 1;
+        nf.fontFile  = (char *)malloc(fflength * sizeof(char));
+        strcpy(nf.fontFile, fontFilePath);
+    }
+
+    _font_add_name(&nf, name);
+
+    cache->fonts[cache->fontsCount - 1] = nf;
+    return &cache->fonts[cache->fontsCount - 1];
 }
-//select current font for context
-_vkvg_font_t* _find_or_create_font_size (VkvgContext ctx) {
-       _vkvg_font_identity_t* font = ctx->currentFont;
-
-       for (uint32_t i = 0; i < font->sizeCount; ++i) {
-               if (font->sizes[i].charSize == ctx->selectedCharSize)
-                       return &font->sizes[i];
-       }
-       //if not found, create a new font size structure
-       if (++font->sizeCount == 1)
-               font->sizes = (_vkvg_font_t*) malloc (sizeof(_vkvg_font_t));
-       else
-               font->sizes = (_vkvg_font_t*) realloc (font->sizes, font->sizeCount * sizeof(_vkvg_font_t));
-       _vkvg_font_t newSize = {.charSize = ctx->selectedCharSize};
-
-       VkvgDevice dev = ctx->dev;
+// select current font for context
+_vkvg_font_t *_find_or_create_font_size(VkvgContext ctx) {
+    _vkvg_font_identity_t *font = ctx->currentFont;
+
+    for (uint32_t i = 0; i < font->sizeCount; ++i) {
+        if (font->sizes[i].charSize == ctx->selectedCharSize)
+            return &font->sizes[i];
+    }
+    // if not found, create a new font size structure
+    if (++font->sizeCount == 1)
+        font->sizes = (_vkvg_font_t *)malloc(sizeof(_vkvg_font_t));
+    else
+        font->sizes = (_vkvg_font_t *)realloc(font->sizes, font->sizeCount * sizeof(_vkvg_font_t));
+    _vkvg_font_t newSize = {.charSize = ctx->selectedCharSize};
+
+    VkvgDevice dev = ctx->dev;
 #ifdef VKVG_USE_FREETYPE
-       _font_cache_t*  cache = (_font_cache_t*)ctx->dev->fontCache;
-       FT_CHECK_RESULT(FT_New_Memory_Face (cache->library, font->fontBuffer, font->fontBufSize, 0, &newSize.face));
-       FT_CHECK_RESULT(FT_Set_Char_Size(newSize.face, 0, newSize.charSize, dev->hdpi, dev->vdpi ));
+    _font_cache_t *cache = (_font_cache_t *)ctx->dev->fontCache;
+    FT_CHECK_RESULT(FT_New_Memory_Face(cache->library, font->fontBuffer, font->fontBufSize, 0, &newSize.face));
+    FT_CHECK_RESULT(FT_Set_Char_Size(newSize.face, 0, newSize.charSize, dev->hdpi, dev->vdpi));
 
-       newSize.charLookup = (_char_ref**)calloc (newSize.face->num_glyphs, sizeof(_char_ref*));
+    newSize.charLookup = (_char_ref **)calloc(newSize.face->num_glyphs, sizeof(_char_ref *));
 
-       if (FT_IS_SCALABLE(newSize.face))
-               newSize.curLine.height = newSize.face->size->metrics.height >> 6;
-       else
-               newSize.curLine.height = newSize.face->height >> 6;
+    if (FT_IS_SCALABLE(newSize.face))
+        newSize.curLine.height = newSize.face->size->metrics.height >> 6;
+    else
+        newSize.curLine.height = newSize.face->height >> 6;
 #else
-       int result = stbtt_InitFont(&font->stbInfo, font->fontBuffer, 0);
-       assert(result && "stbtt_initFont failed");
-       if (!result) {
-               ctx->status = VKVG_STATUS_INVALID_FONT;
-               return NULL;
-       }
-       stbtt_GetFontVMetrics(&font->stbInfo, &font->ascent, &font->descent, &font->lineGap);
-       newSize.charLookup      = (_char_ref**)calloc (font->stbInfo.numGlyphs, sizeof(_char_ref*));
-       //newSize.scale         = stbtt_ScaleForPixelHeight(&font->stbInfo, newSize.charSize);
-       newSize.scale           = stbtt_ScaleForMappingEmToPixels(&font->stbInfo, newSize.charSize);
-       newSize.curLine.height = roundf (newSize.scale * (font->ascent - font->descent + font->lineGap));
-       newSize.ascent          = roundf (newSize.scale * font->ascent);
-       newSize.descent         = roundf (newSize.scale * font->descent);
-       newSize.lineGap         = roundf (newSize.scale * font->lineGap);
+    int result    = stbtt_InitFont(&font->stbInfo, font->fontBuffer, 0);
+    assert(result && "stbtt_initFont failed");
+    if (!result) {
+        ctx->status = VKVG_STATUS_INVALID_FONT;
+        return NULL;
+    }
+    stbtt_GetFontVMetrics(&font->stbInfo, &font->ascent, &font->descent, &font->lineGap);
+    newSize.charLookup = (_char_ref **)calloc(font->stbInfo.numGlyphs, sizeof(_char_ref *));
+    // newSize.scale           = stbtt_ScaleForPixelHeight(&font->stbInfo, newSize.charSize);
+    newSize.scale          = stbtt_ScaleForMappingEmToPixels(&font->stbInfo, newSize.charSize);
+    newSize.curLine.height = roundf(newSize.scale * (font->ascent - font->descent + font->lineGap));
+    newSize.ascent         = roundf(newSize.scale * font->ascent);
+    newSize.descent        = roundf(newSize.scale * font->descent);
+    newSize.lineGap        = roundf(newSize.scale * font->lineGap);
 #endif
 
 #ifdef VKVG_USE_HARFBUZZ
-       newSize.hb_font = hb_ft_font_create(newSize.face, NULL);
+    newSize.hb_font = hb_ft_font_create(newSize.face, NULL);
 #endif
 
-       _init_next_line_in_tex_cache (dev, &newSize);
+    _init_next_line_in_tex_cache(dev, &newSize);
 
-       font->sizes[font->sizeCount-1] = newSize;
-       return &font->sizes[font->sizeCount-1];
+    font->sizes[font->sizeCount - 1] = newSize;
+    return &font->sizes[font->sizeCount - 1];
 }
 
-//try find font already resolved with fontconfig by font name
-bool _tryFindFontByName (VkvgContext ctx, _vkvg_font_identity_t** font){
-       _font_cache_t*  cache = ctx->dev->fontCache;
-       for (int i = 0; i < cache->fontsCount; ++i) {
-               for (uint32_t j = 0; j < cache->fonts[i].namesCount; j++) {
-                       if (strcmp (cache->fonts[i].names[j], ctx->selectedFontName) == 0) {
-                               *font = &cache->fonts[i];
-                               return true;
-                       }
-               }
-       }
-       return false;
+// try find font already resolved with fontconfig by font name
+bool _tryFindFontByName(VkvgContext ctx, _vkvg_font_identity_t **font) {
+    _font_cache_t *cache = ctx->dev->fontCache;
+    for (int i = 0; i < cache->fontsCount; ++i) {
+        for (uint32_t j = 0; j < cache->fonts[i].namesCount; j++) {
+            if (strcmp(cache->fonts[i].names[j], ctx->selectedFontName) == 0) {
+                *font = &cache->fonts[i];
+                return true;
+            }
+        }
+    }
+    return false;
 }
 
 #ifdef VKVG_USE_FONTCONFIG
-bool _tryResolveFontNameWithFontConfig (VkvgContext ctx, _vkvg_font_identity_t** resolvedFont) {
-       _font_cache_t*  cache = (_font_cache_t*)ctx->dev->fontCache;
-       char* fontFile = NULL;
-
-       FcPattern* pat = FcNameParse((const FcChar8*)ctx->selectedFontName);
-       FcConfigSubstitute(cache->config, pat, FcMatchPattern);
-       FcDefaultSubstitute(pat);
-       FcResult result;
-       FcPattern* font = FcFontMatch(cache->config, pat, &result);
-       if (font)
-               FcPatternGetString(font, FC_FILE, 0, (FcChar8 **)&fontFile);
-       *resolvedFont = NULL;
-       if (fontFile) {
-               //try find font in cache by path
-               for (int i = 0; i < cache->fontsCount; ++i) {
-                       if (cache->fonts[i].fontFile && strcmp (cache->fonts[i].fontFile, fontFile) == 0) {
-                               _font_add_name (&cache->fonts[i], ctx->selectedFontName);
-                               *resolvedFont = &cache->fonts[i];
-                               break;
-                       }
-               }
-               if (!*resolvedFont) {
-                       //if not found, create a new vkvg_font
-                       _vkvg_font_identity_t* fid = _font_cache_add_font_identity(ctx, fontFile, ctx->selectedFontName);
-                       _font_cache_load_font_file_in_memory (fid);
-                       *resolvedFont = &cache->fonts[cache->fontsCount-1];
-               }
-       }
-
-       FcPatternDestroy(pat);
-       FcPatternDestroy(font);
-
-       return (fontFile != NULL);
+bool _tryResolveFontNameWithFontConfig(VkvgContext ctx, _vkvg_font_identity_t **resolvedFont) {
+    _font_cache_t *cache    = (_font_cache_t *)ctx->dev->fontCache;
+    char          *fontFile = NULL;
+
+    FcPattern *pat = FcNameParse((const FcChar8 *)ctx->selectedFontName);
+    FcConfigSubstitute(cache->config, pat, FcMatchPattern);
+    FcDefaultSubstitute(pat);
+    FcResult   result;
+    FcPattern *font = FcFontMatch(cache->config, pat, &result);
+    if (font)
+        FcPatternGetString(font, FC_FILE, 0, (FcChar8 **)&fontFile);
+    *resolvedFont = NULL;
+    if (fontFile) {
+        // try find font in cache by path
+        for (int i = 0; i < cache->fontsCount; ++i) {
+            if (cache->fonts[i].fontFile && strcmp(cache->fonts[i].fontFile, fontFile) == 0) {
+                _font_add_name(&cache->fonts[i], ctx->selectedFontName);
+                *resolvedFont = &cache->fonts[i];
+                break;
+            }
+        }
+        if (!*resolvedFont) {
+            // if not found, create a new vkvg_font
+            _vkvg_font_identity_t *fid = _font_cache_add_font_identity(ctx, fontFile, ctx->selectedFontName);
+            _font_cache_load_font_file_in_memory(fid);
+            *resolvedFont = &cache->fonts[cache->fontsCount - 1];
+        }
+    }
+
+    FcPatternDestroy(pat);
+    FcPatternDestroy(font);
+
+    return (fontFile != NULL);
 }
 #endif
 
+// try to find corresponding font in cache (defined by context selectedFont) and create a new font entry if not found.
+void _update_current_font(VkvgContext ctx) {
+    if (ctx->currentFont == NULL) {
+        LOCK_FONTCACHE(ctx->dev)
+        if (ctx->selectedFontName[0] == 0)
+            _select_font_face(ctx, "sans");
 
-//try to find corresponding font in cache (defined by context selectedFont) and create a new font entry if not found.
-void _update_current_font (VkvgContext ctx) {
-       if (ctx->currentFont == NULL){
-               LOCK_FONTCACHE(ctx->dev)
-               if (ctx->selectedFontName[0] == 0)
-                       _select_font_face (ctx, "sans");
-
-               if (!_tryFindFontByName (ctx, &ctx->currentFont)) {
+        if (!_tryFindFontByName(ctx, &ctx->currentFont)) {
 #ifdef VKVG_USE_FONTCONFIG
-                       _tryResolveFontNameWithFontConfig (ctx, &ctx->currentFont);
+            _tryResolveFontNameWithFontConfig(ctx, &ctx->currentFont);
 #else
-                       LOG(VKVG_LOG_ERR, "Unresolved font: %s\n", ctx->selectedFontName);
-                       UNLOCK_FONTCACHE(ctx->dev)
-                       ctx->status = VKVG_STATUS_INVALID_FONT;
-                       return;
+            LOG(VKVG_LOG_ERR, "Unresolved font: %s\n", ctx->selectedFontName);
+            UNLOCK_FONTCACHE(ctx->dev)
+            ctx->status = VKVG_STATUS_INVALID_FONT;
+            return;
 #endif
-               }
+        }
 
-               ctx->currentFontSize = _find_or_create_font_size (ctx);
-               UNLOCK_FONTCACHE(ctx->dev)
-       }       
+        ctx->currentFontSize = _find_or_create_font_size(ctx);
+        UNLOCK_FONTCACHE(ctx->dev)
+    }
 }
 
 #ifdef VKVG_USE_HARFBUZZ
-//Get harfBuzz buffer for provided text.
-hb_buffer_t * _get_hb_buffer (_vkvg_font_t* font, const char* text, int length) {
-       hb_buffer_t *buf = hb_buffer_create();
+// Get harfBuzz buffer for provided text.
+hb_buffer_t *_get_hb_buffer(_vkvg_font_t *font, const char *text, int length) {
+    hb_buffer_t *buf = hb_buffer_create();
 
-       hb_script_t script = HB_SCRIPT_LATIN;
-       hb_unicode_funcs_t* ucfunc = hb_unicode_funcs_get_default ();
-       wchar_t firstChar = 0;
-       if (mbstowcs (&firstChar, text, 1))
-               script = hb_unicode_script (ucfunc, firstChar);
+    hb_script_t         script    = HB_SCRIPT_LATIN;
+    hb_unicode_funcs_t *ucfunc    = hb_unicode_funcs_get_default();
+    wchar_t             firstChar = 0;
+    if (mbstowcs(&firstChar, text, 1))
+        script = hb_unicode_script(ucfunc, firstChar);
 
-       hb_direction_t dir = hb_script_get_horizontal_direction(script);
-       hb_buffer_set_direction (buf, dir);
-       hb_buffer_set_script    (buf, script);
-       //hb_buffer_set_language        (buf, hb_language_from_string (lng, (int)strlen(lng)));
-       hb_buffer_add_utf8              (buf, text, length, 0, length);
+    hb_direction_t dir = hb_script_get_horizontal_direction(script);
+    hb_buffer_set_direction(buf, dir);
+    hb_buffer_set_script(buf, script);
+    // hb_buffer_set_language  (buf, hb_language_from_string (lng, (int)strlen(lng)));
+    hb_buffer_add_utf8(buf, text, length, 0, length);
 
-       hb_shape (font->hb_font, buf, NULL, 0);
+    hb_shape(font->hb_font, buf, NULL, 0);
 
-       return buf;
+    return buf;
 }
 #endif
 
-//retrieve global font extends of context's current font as defined by FreeType
-void _font_cache_font_extents (VkvgContext ctx, vkvg_font_extents_t *extents) {
-       _update_current_font (ctx);
+// retrieve global font extends of context's current font as defined by FreeType
+void _font_cache_font_extents(VkvgContext ctx, vkvg_font_extents_t *extents) {
+    _update_current_font(ctx);
 
-       if (ctx->status)
-               return;
+    if (ctx->status)
+        return;
 
-       //TODO: ensure correct metrics are returned (scalled/unscalled, etc..)
-       _vkvg_font_t* font = ctx->currentFontSize;
+    // TODO: ensure correct metrics are returned (scalled/unscalled, etc..)
+    _vkvg_font_t *font = ctx->currentFontSize;
 #ifdef VKVG_USE_FREETYPE
-       FT_BBox*                        bbox    = &font->face->bbox;
-       FT_Size_Metrics*        metrics = &font->face->size->metrics;
-
-       extents->ascent                 = (float)(FT_MulFix(font->face->ascender, metrics->y_scale) >> 6);//metrics->ascender >> 6;
-       extents->descent                =-(float)(FT_MulFix(font->face->descender, metrics->y_scale) >> 6);//metrics->descender >> 6;
-       extents->height                 = (float)(FT_MulFix(font->face->height, metrics->y_scale) >> 6);//metrics->height >> 6;
-       extents->max_x_advance  = (float)(bbox->xMax >> 6);
-       extents->max_y_advance  = (float)(bbox->yMax >> 6);
+    FT_BBox         *bbox    = &font->face->bbox;
+    FT_Size_Metrics *metrics = &font->face->size->metrics;
+
+    extents->ascent  = (float)(FT_MulFix(font->face->ascender, metrics->y_scale) >> 6);   // metrics->ascender >> 6;
+    extents->descent = -(float)(FT_MulFix(font->face->descender, metrics->y_scale) >> 6); // metrics->descender >> 6;
+    extents->height  = (float)(FT_MulFix(font->face->height, metrics->y_scale) >> 6);     // metrics->height >> 6;
+    extents->max_x_advance = (float)(bbox->xMax >> 6);
+    extents->max_y_advance = (float)(bbox->yMax >> 6);
 #else
-       extents->ascent                 = roundf (font->scale * ctx->currentFont->ascent);
-       extents->descent                =-roundf (font->scale * ctx->currentFont->descent);
-       extents->height                 = roundf (font->scale * (ctx->currentFont->ascent - ctx->currentFont->descent + ctx->currentFont->lineGap));
-       extents->max_x_advance  = 0;//TODO
-       extents->max_y_advance  = 0;
+    extents->ascent  = roundf(font->scale * ctx->currentFont->ascent);
+    extents->descent = -roundf(font->scale * ctx->currentFont->descent);
+    extents->height =
+        roundf(font->scale * (ctx->currentFont->ascent - ctx->currentFont->descent + ctx->currentFont->lineGap));
+    extents->max_x_advance = 0; // TODO
+    extents->max_y_advance = 0;
 #endif
 }
-//compute text extends for provided string.
-void _font_cache_text_extents (VkvgContext ctx, const char* text, int length, vkvg_text_extents_t *extents) {
-       if (text == NULL) {
-               memset(extents, 0, sizeof(vkvg_text_extents_t));
-               return;
-       }
+// compute text extends for provided string.
+void _font_cache_text_extents(VkvgContext ctx, const char *text, int length, vkvg_text_extents_t *extents) {
+    if (text == NULL) {
+        memset(extents, 0, sizeof(vkvg_text_extents_t));
+        return;
+    }
 
-       vkvg_text_run_t tr = {0};
-       _font_cache_create_text_run (ctx, text, length, &tr);
+    vkvg_text_run_t tr = {0};
+    _font_cache_create_text_run(ctx, text, length, &tr);
 
-       if (ctx->status)
-               return;
+    if (ctx->status)
+        return;
 
-       *extents = tr.extents;
+    *extents = tr.extents;
 
-       _font_cache_destroy_text_run (&tr);
+    _font_cache_destroy_text_run(&tr);
 }
-//text is expected as utf8 encoded
-//if length is < 0, text must be null terminated, else it contains glyph count
-void _font_cache_create_text_run (VkvgContext ctx, const char* text, int length, VkvgText textRun) {
+// text is expected as utf8 encoded
+// if length is < 0, text must be null terminated, else it contains glyph count
+void _font_cache_create_text_run(VkvgContext ctx, const char *text, int length, VkvgText textRun) {
 
-       _update_current_font (ctx);
+    _update_current_font(ctx);
 
-       if (ctx->status)
-               return;
+    if (ctx->status)
+        return;
 
-       textRun->fontId = ctx->currentFont;
-       textRun->font = ctx->currentFontSize;
-       textRun->dev = ctx->dev;
+    textRun->fontId = ctx->currentFont;
+    textRun->font   = ctx->currentFontSize;
+    textRun->dev    = ctx->dev;
 
-       LOCK_FONTCACHE (ctx->dev)
+    LOCK_FONTCACHE(ctx->dev)
 
 #ifdef VKVG_USE_HARFBUZZ
-       textRun->hbBuf = _get_hb_buffer (ctx->currentFontSize, text,  length);
-       textRun->glyphs = hb_buffer_get_glyph_positions  (textRun->hbBuf, &textRun->glyph_count);
+    textRun->hbBuf  = _get_hb_buffer(ctx->currentFontSize, text, length);
+    textRun->glyphs = hb_buffer_get_glyph_positions(textRun->hbBuf, &textRun->glyph_count);
 #else
 
-       size_t wsize;
-       if (length < 0)
-               wsize = mbstowcs(NULL, text, 0);
-       else
-               wsize = (size_t)length;
-       wchar_t *tmp = (wchar_t*)malloc((wsize+1) * sizeof (wchar_t));
-       textRun->glyph_count = mbstowcs (tmp, text, wsize);
-       textRun->glyphs = (vkvg_glyph_info_t*)malloc(textRun->glyph_count * sizeof (vkvg_glyph_info_t));
-       for (unsigned int i=0; i<textRun->glyph_count; i++) {
+    size_t wsize;
+    if (length < 0)
+        wsize = mbstowcs(NULL, text, 0);
+    else
+        wsize = (size_t)length;
+    wchar_t *tmp         = (wchar_t *)malloc((wsize + 1) * sizeof(wchar_t));
+    textRun->glyph_count = mbstowcs(tmp, text, wsize);
+    textRun->glyphs      = (vkvg_glyph_info_t *)malloc(textRun->glyph_count * sizeof(vkvg_glyph_info_t));
+    for (unsigned int i = 0; i < textRun->glyph_count; i++) {
 #ifdef VKVG_USE_FREETYPE
-               uint32_t gindex = FT_Get_Char_Index (textRun->font->face, tmp[i]);
+        uint32_t   gindex = FT_Get_Char_Index(textRun->font->face, tmp[i]);
 #else
-               uint32_t gindex = stbtt_FindGlyphIndex (&textRun->fontId->stbInfo, tmp[i]);
+        uint32_t gindex = stbtt_FindGlyphIndex(&textRun->fontId->stbInfo, tmp[i]);
 #endif
-               _char_ref* cr = textRun->font->charLookup[gindex];
-               if (cr==NULL)
-                       cr = _prepare_char (textRun->dev, textRun, gindex);
-               textRun->glyphs[i].codepoint = gindex;
-               textRun->glyphs[i].x_advance = cr->advance.x;
-               textRun->glyphs[i].y_advance = cr->advance.y;
-               textRun->glyphs[i].x_offset      = 0;
-               textRun->glyphs[i].y_offset      = 0;
-               /*textRun->glyphs[i].x_offset    = cr->bmpDiff.x;
-               textRun->glyphs[i].y_offset      = cr->bmpDiff.y;*/
-       }
-       free (tmp);
+        _char_ref *cr     = textRun->font->charLookup[gindex];
+        if (cr == NULL)
+            cr = _prepare_char(textRun->dev, textRun, gindex);
+        textRun->glyphs[i].codepoint = gindex;
+        textRun->glyphs[i].x_advance = cr->advance.x;
+        textRun->glyphs[i].y_advance = cr->advance.y;
+        textRun->glyphs[i].x_offset  = 0;
+        textRun->glyphs[i].y_offset  = 0;
+        /*textRun->glyphs[i].x_offset   = cr->bmpDiff.x;
+        textRun->glyphs[i].y_offset     = cr->bmpDiff.y;*/
+    }
+    free(tmp);
 #endif
-       
-       UNLOCK_FONTCACHE (ctx->dev)
 
-       unsigned int string_width_in_pixels = 0;
-       for (uint32_t i=0; i < textRun->glyph_count; ++i)
-               string_width_in_pixels += textRun->glyphs[i].x_advance >> 6;
+    UNLOCK_FONTCACHE(ctx->dev)
+
+    unsigned int string_width_in_pixels = 0;
+    for (uint32_t i = 0; i < textRun->glyph_count; ++i)
+        string_width_in_pixels += textRun->glyphs[i].x_advance >> 6;
 #ifdef VKVG_USE_FREETYPE
-       FT_Size_Metrics* metrics = &ctx->currentFontSize->face->size->metrics;
-       textRun->extents.height = (float)(FT_MulFix(ctx->currentFontSize->face->height, metrics->y_scale) >> 6);// (metrics->ascender + metrics->descender) >> 6;
+    FT_Size_Metrics *metrics = &ctx->currentFontSize->face->size->metrics;
+    textRun->extents.height  = (float)(FT_MulFix(ctx->currentFontSize->face->height, metrics->y_scale) >>
+                                      6); // (metrics->ascender + metrics->descender) >> 6;
 #else
-       textRun->extents.height = textRun->font->ascent - textRun->font->descent + textRun->font->lineGap;
+    textRun->extents.height = textRun->font->ascent - textRun->font->descent + textRun->font->lineGap;
 #endif
-       textRun->extents.x_advance = (float)string_width_in_pixels;
-       if (textRun->glyph_count > 0) {
-               textRun->extents.y_advance = (float)(textRun->glyphs[textRun->glyph_count-1].y_advance >> 6);
-               textRun->extents.x_bearing = -(float)(textRun->glyphs[0].x_offset >> 6);
-               textRun->extents.y_bearing = -(float)(textRun->glyphs[0].y_offset >> 6);
-       }
-
-       textRun->extents.width  = textRun->extents.x_advance;
+    textRun->extents.x_advance = (float)string_width_in_pixels;
+    if (textRun->glyph_count > 0) {
+        textRun->extents.y_advance = (float)(textRun->glyphs[textRun->glyph_count - 1].y_advance >> 6);
+        textRun->extents.x_bearing = -(float)(textRun->glyphs[0].x_offset >> 6);
+        textRun->extents.y_bearing = -(float)(textRun->glyphs[0].y_offset >> 6);
+    }
+
+    textRun->extents.width = textRun->extents.x_advance;
 }
-void _font_cache_destroy_text_run (VkvgText textRun) {
+void _font_cache_destroy_text_run(VkvgText textRun) {
 #ifdef VKVG_USE_HARFBUZZ
-       hb_buffer_destroy (textRun->hbBuf);
+    hb_buffer_destroy(textRun->hbBuf);
 #else
-       if (textRun->glyph_count > 0)
-               free (textRun->glyphs);
+    if (textRun->glyph_count > 0)
+        free(textRun->glyphs);
 #endif
 }
 #ifdef DEBUG
-void _show_texture (vkvg_context* ctx){
-       Vertex vs[] = {
-               {{0,0},                                                   0,  {0,0,0}},
-               {{0,FONT_PAGE_SIZE},                      0,  {0,1,0}},
-               {{FONT_PAGE_SIZE,0},                      0,  {1,0,0}},
-               {{FONT_PAGE_SIZE,FONT_PAGE_SIZE}, 0,  {1,1,0}}
-       };
-
-       VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-       Vertex* pVert = &ctx->vertexCache[ctx->vertCount];
-       memcpy (pVert,vs,4*sizeof(Vertex));
-       ctx->vertCount+=4;
-
-       _check_vertex_cache_size(ctx);
-
-       _add_tri_indices_for_rect(ctx, firstIdx);
+void _show_texture(vkvg_context *ctx) {
+    Vertex vs[] = {{{0, 0}, 0, {0, 0, 0}},
+                   {{0, FONT_PAGE_SIZE}, 0, {0, 1, 0}},
+                   {{FONT_PAGE_SIZE, 0}, 0, {1, 0, 0}},
+                   {{FONT_PAGE_SIZE, FONT_PAGE_SIZE}, 0, {1, 1, 0}}};
+
+    VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+    Vertex             *pVert    = &ctx->vertexCache[ctx->vertCount];
+    memcpy(pVert, vs, 4 * sizeof(Vertex));
+    ctx->vertCount += 4;
+
+    _check_vertex_cache_size(ctx);
+
+    _add_tri_indices_for_rect(ctx, firstIdx);
 }
 #endif
-void _font_cache_show_text_run (VkvgContext ctx, VkvgText tr) {
-       unsigned int glyph_count;
+void _font_cache_show_text_run(VkvgContext ctx, VkvgText tr) {
+    unsigned int glyph_count;
 #ifdef VKVG_USE_HARFBUZZ
-       hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos (tr->hbBuf, &glyph_count);
+    hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(tr->hbBuf, &glyph_count);
 #else
-       vkvg_glyph_info_t* glyph_info = tr->glyphs;
-       glyph_count = tr->glyph_count;
+    vkvg_glyph_info_t *glyph_info = tr->glyphs;
+    glyph_count                   = tr->glyph_count;
 #endif
 
-       Vertex v = {{0},ctx->curColor,{0,0,-1}};
-       vec2 pen = {0,0};
+    Vertex v   = {{0}, ctx->curColor, {0, 0, -1}};
+    vec2   pen = {0, 0};
 
-       if (!_current_path_is_empty(ctx))
-               pen = _get_current_position(ctx);
+    if (!_current_path_is_empty(ctx))
+        pen = _get_current_position(ctx);
 
-       LOCK_FONTCACHE (ctx->dev)
+    LOCK_FONTCACHE(ctx->dev)
 
-       for (uint32_t i=0; i < glyph_count; ++i) {
-               _char_ref* cr = tr->font->charLookup[glyph_info[i].codepoint];
+    for (uint32_t i = 0; i < glyph_count; ++i) {
+        _char_ref *cr = tr->font->charLookup[glyph_info[i].codepoint];
 
 #ifdef VKVG_USE_HARFBUZZ
-               if (cr==NULL)
-                       cr = _prepare_char(tr->dev, tr, glyph_info[i].codepoint);
+        if (cr == NULL)
+            cr = _prepare_char(tr->dev, tr, glyph_info[i].codepoint);
 #endif
 
-               float uvWidth   = cr->bounds.width  / (float)FONT_PAGE_SIZE;
-               float uvHeight  = cr->bounds.height / (float)FONT_PAGE_SIZE;
-               vec2 p0 = {pen.x + cr->bmpDiff.x + (tr->glyphs[i].x_offset >> 6),
-                                  pen.y - cr->bmpDiff.y + (tr->glyphs[i].y_offset >> 6)};
-               v.pos = p0;
-
-               VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
-
-
-               v.uv.x = cr->bounds.x;
-               v.uv.y = cr->bounds.y;
-               v.uv.z = cr->pageIdx;
-               _add_vertex(ctx,v);
-
-               v.pos.y += cr->bounds.height;
-               v.uv.y += uvHeight;
-               _add_vertex(ctx,v);
-
-               v.pos.x += cr->bounds.width;
-               v.pos.y = p0.y;
-               v.uv.x += uvWidth;
-               v.uv.y = cr->bounds.y;
-               _add_vertex(ctx,v);
-
-               v.pos.y += cr->bounds.height;
-               v.uv.y += uvHeight;
-               _add_vertex(ctx,v);
-
-               _add_tri_indices_for_rect (ctx, firstIdx);
-
-               pen.x += (tr->glyphs[i].x_advance >> 6);
-               pen.y -= (tr->glyphs[i].y_advance >> 6);
-       }
-
-       //equivalent to a moveto
-       _finish_path(ctx);
-       _add_point (ctx, pen.x, pen.y);
-       _flush_chars_to_tex(tr->dev, tr->font); 
-       UNLOCK_FONTCACHE (ctx->dev)
-
-       if (ctx->fontCacheImg != ctx->dev->fontCache->texture) {
-               vkvg_flush (ctx);
-               _font_cache_update_context_descset (ctx);
-       }
+        float uvWidth  = cr->bounds.width / (float)FONT_PAGE_SIZE;
+        float uvHeight = cr->bounds.height / (float)FONT_PAGE_SIZE;
+        vec2  p0       = {pen.x + cr->bmpDiff.x + (tr->glyphs[i].x_offset >> 6),
+                          pen.y - cr->bmpDiff.y + (tr->glyphs[i].y_offset >> 6)};
+        v.pos          = p0;
+
+        VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+
+        v.uv.x = cr->bounds.x;
+        v.uv.y = cr->bounds.y;
+        v.uv.z = cr->pageIdx;
+        _add_vertex(ctx, v);
+
+        v.pos.y += cr->bounds.height;
+        v.uv.y += uvHeight;
+        _add_vertex(ctx, v);
+
+        v.pos.x += cr->bounds.width;
+        v.pos.y = p0.y;
+        v.uv.x += uvWidth;
+        v.uv.y = cr->bounds.y;
+        _add_vertex(ctx, v);
+
+        v.pos.y += cr->bounds.height;
+        v.uv.y += uvHeight;
+        _add_vertex(ctx, v);
+
+        _add_tri_indices_for_rect(ctx, firstIdx);
+
+        pen.x += (tr->glyphs[i].x_advance >> 6);
+        pen.y -= (tr->glyphs[i].y_advance >> 6);
+    }
+
+    // equivalent to a moveto
+    _finish_path(ctx);
+    _add_point(ctx, pen.x, pen.y);
+    _flush_chars_to_tex(tr->dev, tr->font);
+    UNLOCK_FONTCACHE(ctx->dev)
+
+    if (ctx->fontCacheImg != ctx->dev->fontCache->texture) {
+        vkvg_flush(ctx);
+        _font_cache_update_context_descset(ctx);
+    }
 }
 
-void _font_cache_show_text (VkvgContext ctx, const char* text){
+void _font_cache_show_text(VkvgContext ctx, const char *text) {
 
-       vkvg_text_run_t tr = {0};
-       _font_cache_create_text_run (ctx, text, -1, &tr);
+    vkvg_text_run_t tr = {0};
+    _font_cache_create_text_run(ctx, text, -1, &tr);
 
-       if (ctx->status)
-               return;
+    if (ctx->status)
+        return;
 
-       _font_cache_show_text_run (ctx, &tr);
+    _font_cache_show_text_run(ctx, &tr);
 
-       _font_cache_destroy_text_run (&tr);
+    _font_cache_destroy_text_run(&tr);
 
-       //_show_texture(ctx); return;
+    //_show_texture(ctx); return;
 }
 
-
 /*void testfonts(){
-       FT_Library              library;
-       FT_Face                 face;
-       FT_GlyphSlot    slot;
+    FT_Library         library;
+    FT_Face                    face;
+    FT_GlyphSlot       slot;
 
-       assert(!FT_Init_FreeType(&library));
-       assert(!FT_New_Face(library, "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 0, &face));
-       assert(!FT_Set_Char_Size(face, 0, ptSize, device_hdpi, device_vdpi ));
+    assert(!FT_Init_FreeType(&library));
+    assert(!FT_New_Face(library, "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 0, &face));
+    assert(!FT_Set_Char_Size(face, 0, ptSize, device_hdpi, device_vdpi ));
 
-       //_build_face_tex(face);
+    //_build_face_tex(face);
 
-       hb_font_t *hb_font = hb_ft_font_create(face, NULL);
-       hb_buffer_t *buf = hb_buffer_create();
+    hb_font_t *hb_font = hb_ft_font_create(face, NULL);
+    hb_buffer_t *buf = hb_buffer_create();
 
-       const char *text = "Ленивый рыжий кот";
-       const char *lng  = "en";
-       //"كسول الزنجبيل القط","懶惰的姜貓",
+    const char *text = "Ленивый рыжий кот";
+    const char *lng     = "en";
+    //"كسول الزنجبيل القط","懶惰的姜貓",
 
 
-       hb_buffer_set_direction (buf, HB_DIRECTION_LTR);
-       hb_buffer_set_script    (buf, HB_SCRIPT_LATIN);
-       hb_buffer_set_language  (buf, hb_language_from_string(lng,strlen(lng)));
-       hb_buffer_add_utf8              (buf, text, strlen(text), 0, strlen(text));
+    hb_buffer_set_direction (buf, HB_DIRECTION_LTR);
+    hb_buffer_set_script       (buf, HB_SCRIPT_LATIN);
+    hb_buffer_set_language     (buf, hb_language_from_string(lng,strlen(lng)));
+    hb_buffer_add_utf8         (buf, text, strlen(text), 0, strlen(text));
 
-       hb_unicode_funcs_t * unifc = hb_unicode_funcs_get_default();
-       hb_script_t sc = hb_buffer_get_script(buf);
+    hb_unicode_funcs_t * unifc = hb_unicode_funcs_get_default();
+    hb_script_t sc = hb_buffer_get_script(buf);
 
-       sc = hb_unicode_script(unifc,0x0260);
+    sc = hb_unicode_script(unifc,0x0260);
 
-       FT_CharMap* cm = face->charmap;
+    FT_CharMap* cm = face->charmap;
 
-       //hb_script_to_iso15924_tag()
+    //hb_script_to_iso15924_tag()
 
 
-       FT_Done_Face    ( face );
-       FT_Done_FreeType( library );
+    FT_Done_Face       ( face );
+    FT_Done_FreeType( library );
 }*/
index 959c5c812ae12653404ec9c16cdf0b62edf1a46c..5e063446d7b9d182349a11f3f5b05ee110cd9d28 100644 (file)
 #ifndef VKVG_FONTS_H
 #define VKVG_FONTS_H
 
- //disable warning on iostream functions on windows
+// disable warning on iostream functions on windows
 #define _CRT_SECURE_NO_WARNINGS
 
 #ifdef VKVG_USE_FREETYPE
-       #include <ft2build.h>
-       #include FT_FREETYPE_H
-       #if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
-               #include <freetype/ftlcdfil.h>
-       #endif
-       #define FT_CHECK_RESULT(f)                                                                                                                                                              \
-       {                                                                                                                                                                                                               \
-               FT_Error res = (f);                                                                                                                                                                     \
-               if (res != 0)                                                                                                                                                           \
-               {                                                                                                                                                                                                       \
-                       fprintf(stderr,"Fatal : FreeType error is %d in %s at line %d\n", res,  __FILE__, __LINE__); \
-                       assert(res == 0);                                                                                                                                               \
-               }                                                                                                                                                                                                       \
-       }
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
+#include <freetype/ftlcdfil.h>
+#endif
+#define FT_CHECK_RESULT(f)                                                                                             \
+    {                                                                                                                  \
+        FT_Error res = (f);                                                                                            \
+        if (res != 0) {                                                                                                \
+            fprintf(stderr, "Fatal : FreeType error is %d in %s at line %d\n", res, __FILE__, __LINE__);               \
+            assert(res == 0);                                                                                          \
+        }                                                                                                              \
+    }
 #else
-       #include "stb_truetype.h"
+#include "stb_truetype.h"
 #endif
 
 #ifdef VKVG_USE_HARFBUZZ
-       #include <harfbuzz/hb.h>
-       #include <harfbuzz/hb-ft.h>
+#include <harfbuzz/hb.h>
+#include <harfbuzz/hb-ft.h>
 #else
 #endif
 
 #ifdef VKVG_USE_FONTCONFIG
-       #include <fontconfig/fontconfig.h>
+#include <fontconfig/fontconfig.h>
 #endif
 
-#define FONT_PAGE_SIZE                 1024
-#define FONT_CACHE_INIT_LAYERS 1
+#define FONT_PAGE_SIZE          1024
+#define FONT_CACHE_INIT_LAYERS  1
 #define FONT_FILE_NAME_MAX_SIZE 1024
-#define FONT_NAME_MAX_SIZE             128
+#define FONT_NAME_MAX_SIZE      128
 
 #include "vkvg_internal.h"
 #include "vkh_buffer.h"
 
-//texture coordinates of one character in font cache array texture.
+// texture coordinates of one character in font cache array texture.
 typedef struct {
-       vec4            bounds;                         /* normalized float bounds of character bitmap in font cache texture. */
-       vec2i16         bmpDiff;                        /* Difference in pixel between char bitmap top left corner and char glyph*/
-       uint8_t         pageIdx;                        /* Page index in font cache texture array */
+    vec4    bounds;  /* normalized float bounds of character bitmap in font cache texture. */
+    vec2i16 bmpDiff; /* Difference in pixel between char bitmap top left corner and char glyph*/
+    uint8_t pageIdx; /* Page index in font cache texture array */
 #ifdef VKVG_USE_FREETYPE
-       FT_Vector       advance;                        /* horizontal or vertical advance */
+    FT_Vector advance; /* horizontal or vertical advance */
 #else
-       vec2            advance;
+    vec2               advance;
 #endif
-}_char_ref;
+} _char_ref;
 
 // Current location in font cache texture array for new character addition. Each font holds such structure to locate
 // where to upload new chars.
 typedef struct {
-       uint8_t         pageIdx;                        /* Current page number in font cache */
-       int                     penX;                           /* Current X in cache for next char addition */
-       int                     penY;                           /* Current Y in cache for next char addition */
-       int                     height;                         /* Height of current line pointed by this structure */
-}_tex_ref_t;
-
-// Loaded font structure, one per size, holds informations for glyphes upload in cache and the lookup table of characters.
+    uint8_t pageIdx; /* Current page number in font cache */
+    int     penX;    /* Current X in cache for next char addition */
+    int     penY;    /* Current Y in cache for next char addition */
+    int     height;  /* Height of current line pointed by this structure */
+} _tex_ref_t;
+
+// Loaded font structure, one per size, holds informations for glyphes upload in cache and the lookup table of
+// characters.
 typedef struct {
 #ifdef VKVG_USE_FREETYPE
-       FT_F26Dot6              charSize;               /* Font size*/
-       FT_Face                 face;                   /* FreeType face*/
+    FT_F26Dot6 charSize; /* Font size*/
+    FT_Face    face;     /* FreeType face*/
 #else
-       uint32_t                charSize;               /* Font size in pixel */
-       float                   scale;                  /* scale factor for the given size */
-       int                             ascent;                 /* unscalled stb font metrics */
-       int                             descent;
-       int                             lineGap;
+    uint32_t           charSize; /* Font size in pixel */
+    float              scale;    /* scale factor for the given size */
+    int                ascent;   /* unscalled stb font metrics */
+    int                descent;
+    int                lineGap;
 #endif
 
 #ifdef VKVG_USE_HARFBUZZ
-       hb_font_t*              hb_font;                /* HarfBuzz font instance*/
+    hb_font_t *hb_font; /* HarfBuzz font instance*/
 #endif
-       _char_ref**             charLookup;             /* Lookup table of characteres in cache, if not found, upload is queued*/
+    _char_ref **charLookup; /* Lookup table of characteres in cache, if not found, upload is queued*/
 
-       _tex_ref_t              curLine;                /* tex coord where to add new char bmp's */
-}_vkvg_font_t;
+    _tex_ref_t curLine; /* tex coord where to add new char bmp's */
+} _vkvg_font_t;
 
 /* Font identification structure */
 typedef struct {
-       char**                          names;          /* Resolved Input names to this font by fontConfig or custom name set by @ref vkvg_load_from_path*/
-       uint32_t                        namesCount;     /* Count of resolved names by fontConfig */
-       unsigned char*          fontBuffer;     /* stb_truetype in memory buffer */
-       long                            fontBufSize;/* */
-       char*                           fontFile;       /* Font file full path*/
+    char   **names; /* Resolved Input names to this font by fontConfig or custom name set by @ref vkvg_load_from_path*/
+    uint32_t namesCount;        /* Count of resolved names by fontConfig */
+    unsigned char *fontBuffer;  /* stb_truetype in memory buffer */
+    long           fontBufSize; /* */
+    char          *fontFile;    /* Font file full path*/
 #ifndef VKVG_USE_FREETYPE
-       stbtt_fontinfo          stbInfo;        /* stb_truetype structure */
-       int                                     ascent;         /* unscalled stb font metrics */
-       int                                     descent;
-       int                                     lineGap;
+    stbtt_fontinfo stbInfo; /* stb_truetype structure */
+    int            ascent;  /* unscalled stb font metrics */
+    int            descent;
+    int            lineGap;
 #endif
-       uint32_t                        sizeCount;      /* available font size loaded */
-       _vkvg_font_t*           sizes;          /* loaded font size array */
-}_vkvg_font_identity_t;
+    uint32_t      sizeCount; /* available font size loaded */
+    _vkvg_font_t *sizes;     /* loaded font size array */
+} _vkvg_font_identity_t;
 
 // Font cache global structure, entry point for all font related operations.
 typedef struct {
 #ifdef VKVG_USE_FREETYPE
-       FT_Library              library;                /* FreeType library*/
+    FT_Library library; /* FreeType library*/
 #else
 #endif
 #ifdef VKVG_USE_FONTCONFIG
-       FcConfig*               config;                 /* Font config, used to find font files by font names*/
+    FcConfig *config; /* Font config, used to find font files by font names*/
 #endif
 
-       int                             stagingX;               /* x pen in host buffer */
-       uint8_t*                hostBuff;               /* host memory where bitmaps are first loaded */
-
-       VkCommandBuffer cmd;                    /* vulkan command buffer for font textures upload */
-       vkh_buffer_t    buff;                   /* stagin buffer */
-       VkhImage                texture;                /* 2d array texture used by contexts to draw characteres */
-       VkFormat                texFormat;              /* Format of the fonts texture array */
-       uint8_t                 texPixelSize;   /* Size in byte of a single pixel in a font texture */
-       uint8_t                 texLength;              /* layer count of 2d array texture, starts with FONT_CACHE_INIT_LAYERS count and increased when needed */
-       int*                    pensY;                  /* array of current y pen positions for each texture in cache 2d array */
-       VkFence                 uploadFence;    /* Signaled when upload is finished */
-       mtx_t                   mutex;                  /* font cache global mutex, used only if device is in thread aware mode (see: vkvg_device_set_thread_aware) */
-
-       _vkvg_font_identity_t*  fonts;  /* Loaded fonts structure array */
-       int32_t                 fontsCount;             /* Loaded fonts array count*/
-}_font_cache_t;
-
-#define LOCK_FONTCACHE(dev) \
-       if (dev->threadAware)\
-               mtx_lock (&dev->fontCache->mutex);
-#define UNLOCK_FONTCACHE(dev) \
-       if (dev->threadAware)\
-               mtx_unlock (&dev->fontCache->mutex);
+    int      stagingX; /* x pen in host buffer */
+    uint8_t *hostBuff; /* host memory where bitmaps are first loaded */
+
+    VkCommandBuffer cmd;          /* vulkan command buffer for font textures upload */
+    vkh_buffer_t    buff;         /* stagin buffer */
+    VkhImage        texture;      /* 2d array texture used by contexts to draw characteres */
+    VkFormat        texFormat;    /* Format of the fonts texture array */
+    uint8_t         texPixelSize; /* Size in byte of a single pixel in a font texture */
+    uint8_t texLength;   /* layer count of 2d array texture, starts with FONT_CACHE_INIT_LAYERS count and increased when
+                            needed */
+    int    *pensY;       /* array of current y pen positions for each texture in cache 2d array */
+    VkFence uploadFence; /* Signaled when upload is finished */
+    mtx_t   mutex;       /* font cache global mutex, used only if device is in thread aware mode (see:
+                            vkvg_device_set_thread_aware) */
+
+    _vkvg_font_identity_t *fonts;      /* Loaded fonts structure array */
+    int32_t                fontsCount; /* Loaded fonts array count*/
+} _font_cache_t;
+
+#define LOCK_FONTCACHE(dev)                                                                                            \
+    if (dev->threadAware)                                                                                              \
+        mtx_lock(&dev->fontCache->mutex);
+#define UNLOCK_FONTCACHE(dev)                                                                                          \
+    if (dev->threadAware)                                                                                              \
+        mtx_unlock(&dev->fontCache->mutex);
 
 // Precompute everything necessary to measure and draw one line of text, usefull to draw the same text multiple times.
 typedef struct _vkvg_text_run_t {
-       _vkvg_font_identity_t*  fontId;         /* vkvg font structure pointer */
-       _vkvg_font_t*                   font;           /* vkvg font structure pointer */
-       VkvgDevice                              dev;            /* vkvg device associated with this text run */
-       vkvg_text_extents_t             extents;        /* store computed text extends */
-       const char*                             text;           /* utf8 char array of text*/
-       unsigned int                    glyph_count;/* Total glyph count */
+    _vkvg_font_identity_t *fontId;      /* vkvg font structure pointer */
+    _vkvg_font_t          *font;        /* vkvg font structure pointer */
+    VkvgDevice             dev;         /* vkvg device associated with this text run */
+    vkvg_text_extents_t    extents;     /* store computed text extends */
+    const char            *text;        /* utf8 char array of text*/
+    unsigned int           glyph_count; /* Total glyph count */
 #ifdef VKVG_USE_HARFBUZZ
-       hb_buffer_t*                    hbBuf;          /* HarfBuzz buffer of text */
-       hb_glyph_position_t*    glyphs;         /* HarfBuzz computed glyph positions array */
+    hb_buffer_t         *hbBuf;  /* HarfBuzz buffer of text */
+    hb_glyph_position_t *glyphs; /* HarfBuzz computed glyph positions array */
 #else
-       vkvg_glyph_info_t*              glyphs;         /* computed glyph positions array */
+    vkvg_glyph_info_t *glyphs; /* computed glyph positions array */
 #endif
 } vkvg_text_run_t;
 
-//Create font cache.
-void _fonts_cache_create               (VkvgDevice dev);
-//Release all ressources of font cache.
-void _font_cache_destroy       (VkvgDevice dev);
-_vkvg_font_identity_t *_font_cache_add_font_identity (VkvgContext ctx, const char* fontFile, const char *name);
-bool _font_cache_load_font_file_in_memory (_vkvg_font_identity_t* fontId);
-//Draw text
-void _font_cache_show_text                             (VkvgContext ctx, const char* text);
-//Get text dimmensions
-void _font_cache_text_extents                  (VkvgContext ctx, const char* text, int length, vkvg_text_extents_t *extents);
-//Get font global dimmensions
-void _font_cache_font_extents                  (VkvgContext ctx, vkvg_font_extents_t* extents);
-//Create text object that could be drawn multiple times minimizing harfbuzz and compute processing.
-void _font_cache_create_text_run               (VkvgContext ctx, const char* text, int length, VkvgText textRun);
-//Release ressources held by a text run.
-void _font_cache_destroy_text_run              (VkvgText textRun);
-//Draw text run
-void _font_cache_show_text_run                 (VkvgContext ctx, VkvgText tr);
-//update context font cache descriptor set
-void _font_cache_update_context_descset (VkvgContext ctx);
+// Create font cache.
+void _fonts_cache_create(VkvgDevice dev);
+// Release all ressources of font cache.
+void                   _font_cache_destroy(VkvgDevice dev);
+_vkvg_font_identity_t *_font_cache_add_font_identity(VkvgContext ctx, const char *fontFile, const char *name);
+bool                   _font_cache_load_font_file_in_memory(_vkvg_font_identity_t *fontId);
+// Draw text
+void _font_cache_show_text(VkvgContext ctx, const char *text);
+// Get text dimmensions
+void _font_cache_text_extents(VkvgContext ctx, const char *text, int length, vkvg_text_extents_t *extents);
+// Get font global dimmensions
+void _font_cache_font_extents(VkvgContext ctx, vkvg_font_extents_t *extents);
+// Create text object that could be drawn multiple times minimizing harfbuzz and compute processing.
+void _font_cache_create_text_run(VkvgContext ctx, const char *text, int length, VkvgText textRun);
+// Release ressources held by a text run.
+void _font_cache_destroy_text_run(VkvgText textRun);
+// Draw text run
+void _font_cache_show_text_run(VkvgContext ctx, VkvgText tr);
+// update context font cache descriptor set
+void _font_cache_update_context_descset(VkvgContext ctx);
 #endif
index 535ca8171e3894ec453a72a00c6bf629d81b5f59..3afbe43ff3ca7a3cc931fa38a5e583e3c75e94b6 100644 (file)
 #ifndef VKVG_INTERNAL_H
 #define VKVG_INTERNAL_H
 
- //disable warning on iostream functions on windows
+// disable warning on iostream functions on windows
 #define _CRT_SECURE_NO_WARNINGS
 
 #include <assert.h>
 #include <float.h>
 #include <stdbool.h>
 #include <stdint.h>
-#include <stdio.h>  // needed before stdarg.h on Windows
+#include <stdio.h> // needed before stdarg.h on Windows
 #include <stdarg.h>
 #include <string.h>
 
 #include <math.h>
 
 #ifndef M_PIF
-       #define M_PIF                           3.14159265358979323846f /* float pi */
-       #define M_PIF_2                         1.57079632679489661923f
-       #define M_2_PIF                         0.63661977236758134308f  // 2/pi
+#define M_PIF   3.14159265358979323846f /* float pi */
+#define M_PIF_2 1.57079632679489661923f
+#define M_2_PIF 0.63661977236758134308f // 2/pi
 #endif
 
 /*#ifndef M_2_PI
-       #define M_2_PI          0.63661977236758134308  // 2/pi
+    #define M_2_PI             0.63661977236758134308  // 2/pi
 #endif*/
 
 #ifdef DEBUG
-#define LOG(level,...) {                               \
-       if ((vkvg_log_level) & (level))         \
-               fprintf (stdout, __VA_ARGS__);  \
-}
+#define LOG(level, ...)                                                                                                \
+    {                                                                                                                  \
+        if ((vkvg_log_level) & (level))                                                                                \
+            fprintf(stdout, __VA_ARGS__);                                                                              \
+    }
 #else
 #define LOG
 #endif
 
-#define PATH_CLOSED_BIT                0x80000000                              /* most significant bit of path elmts is closed/open path state */
-#define PATH_HAS_CURVES_BIT 0x40000000                         /* 2rd most significant bit of path elmts is curved status
-                                                                                                        * for main path, this indicate that curve datas are present.
-                                                                                                        * For segments, this indicate that the segment is curved or not */
-#define PATH_IS_CONVEX_BIT     0x20000000                              /* simple rectangle or circle. */
-#define PATH_ELT_MASK          0x1FFFFFFF                              /* Bit mask for fetching path element value */
+#define PATH_CLOSED_BIT 0x80000000 /* most significant bit of path elmts is closed/open path state */
+#define PATH_HAS_CURVES_BIT                                                                                            \
+    0x40000000                        /* 2rd most significant bit of path elmts is curved status                       \
+                                       * for main path, this indicate that curve datas are present.                    \
+                                       * For segments, this indicate that the segment is curved or not */
+#define PATH_IS_CONVEX_BIT 0x20000000 /* simple rectangle or circle. */
+#define PATH_ELT_MASK      0x1FFFFFFF /* Bit mask for fetching path element value */
 
-#define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c)))
-#define ROUND_DOWN(v,p) (floorf(v * p) / p)
-#define EQUF(a, b) (fabsf(a-(b))<=FLT_EPSILON)
+#define ROUNDF(f, c)       (((float)((int)((f) * (c))) / (c)))
+#define ROUND_DOWN(v, p)   (floorf(v * p) / p)
+#define EQUF(a, b)         (fabsf(a - (b)) <= FLT_EPSILON)
 
 #ifndef MAX
-       #define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
 #endif
 #ifndef MIN
-       #define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
 #endif
 
 #include "deps/tinycthread.h"
 #include "cross_os.h"
-//width of the stencil buffer will determine the number of context saving/restore layers
-//the two first bits of the stencil are the FILL and the CLIP bits, all other bits are
-//used to store clipping bit on context saving. 8 bit stencil will allow 6 save/restore layer
+// width of the stencil buffer will determine the number of context saving/restore layers
+// the two first bits of the stencil are the FILL and the CLIP bits, all other bits are
+// used to store clipping bit on context saving. 8 bit stencil will allow 6 save/restore layer
 #define FB_COLOR_FORMAT VK_FORMAT_B8G8R8A8_UNORM
-#define VKVG_SURFACE_IMGS_REQUIREMENTS (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|\
-       VK_FORMAT_FEATURE_TRANSFER_DST_BIT|VK_FORMAT_FEATURE_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_BLIT_SRC_BIT)
-#define VKVG_PNG_WRITE_IMG_REQUIREMENTS (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_TRANSFER_DST_BIT|VK_FORMAT_FEATURE_BLIT_DST_BIT)
-//30 seconds fence timeout
+#define VKVG_SURFACE_IMGS_REQUIREMENTS                                                                                 \
+    (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |                                    \
+     VK_FORMAT_FEATURE_TRANSFER_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT)
+#define VKVG_PNG_WRITE_IMG_REQUIREMENTS                                                                                \
+    (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT)
+// 30 seconds fence timeout
 #define VKVG_FENCE_TIMEOUT 30000000000
-//#define VKVG_FENCE_TIMEOUT 10000
+// #define VKVG_FENCE_TIMEOUT 10000
 
 #include "vkvg.h"
 #include "vkh.h"
 #include "vectors.h"
 
 /*typedef struct {
-       vkvg_status_t status;
+    vkvg_status_t status;
 } _vkvg_no_mem_struct;*/
 
 static vkvg_status_t _no_mem_status = VKVG_STATUS_NO_MEMORY;
index 998ece03a68409062bfc934bef6a326c2c5b8290..c77f3291c7b5b6837ad74346d9973e343044689e 100644 (file)
@@ -20,8 +20,8 @@
  * THE SOFTWARE.
  */
 
-//most of the matrix logic is grabbed from cairo, so here is the
-//licence:
+// most of the matrix logic is grabbed from cairo, so here is the
+// licence:
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2002 University of Southern California
 
 #define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
 
-//matrix computations mainly taken from http://cairographics.org
-static void _vkvg_matrix_scalar_multiply (vkvg_matrix_t *matrix, float scalar)
-{
-       matrix->xx *= scalar;
-       matrix->yx *= scalar;
+// matrix computations mainly taken from http://cairographics.org
+static void _vkvg_matrix_scalar_multiply(vkvg_matrix_t *matrix, float scalar) {
+    matrix->xx *= scalar;
+    matrix->yx *= scalar;
 
-       matrix->xy *= scalar;
-       matrix->yy *= scalar;
+    matrix->xy *= scalar;
+    matrix->yy *= scalar;
 
-       matrix->x0 *= scalar;
-       matrix->y0 *= scalar;
+    matrix->x0 *= scalar;
+    matrix->y0 *= scalar;
 }
-void _vkvg_matrix_get_affine (const vkvg_matrix_t *matrix,
-                         float *xx, float *yx,
-                         float *xy, float *yy,
-                         float *x0, float *y0)
-{
-       *xx      = matrix->xx;
-       *yx      = matrix->yx;
-
-       *xy      = matrix->xy;
-       *yy      = matrix->yy;
-
-       if (x0)
-       *x0 = matrix->x0;
-       if (y0)
-       *y0 = matrix->y0;
+void _vkvg_matrix_get_affine(const vkvg_matrix_t *matrix, float *xx, float *yx, float *xy, float *yy, float *x0,
+                             float *y0) {
+    *xx = matrix->xx;
+    *yx = matrix->yx;
+
+    *xy = matrix->xy;
+    *yy = matrix->yy;
+
+    if (x0)
+        *x0 = matrix->x0;
+    if (y0)
+        *y0 = matrix->y0;
 }
-static void _vkvg_matrix_compute_adjoint (vkvg_matrix_t *matrix)
-{
-       /* adj (A) = transpose (C:cofactor (A,i,j)) */
-       float a, b, c, d, tx, ty;
-
-       _vkvg_matrix_get_affine (matrix,
-                                 &a,  &b,
-                                 &c,  &d,
-                                 &tx, &ty);
-
-       vkvg_matrix_init (matrix,
-                          d, -b,
-                          -c, a,
-                          c*ty - d*tx, b*tx - a*ty);
+static void _vkvg_matrix_compute_adjoint(vkvg_matrix_t *matrix) {
+    /* adj (A) = transpose (C:cofactor (A,i,j)) */
+    float a, b, c, d, tx, ty;
+
+    _vkvg_matrix_get_affine(matrix, &a, &b, &c, &d, &tx, &ty);
+
+    vkvg_matrix_init(matrix, d, -b, -c, a, c * ty - d * tx, b * tx - a * ty);
 }
-float _vkvg_matrix_compute_determinant (const vkvg_matrix_t *matrix)
-{
-       float a, b, c, d;
+float _vkvg_matrix_compute_determinant(const vkvg_matrix_t *matrix) {
+    float a, b, c, d;
 
-       a = matrix->xx; b = matrix->yx;
-       c = matrix->xy; d = matrix->yy;
+    a = matrix->xx;
+    b = matrix->yx;
+    c = matrix->xy;
+    d = matrix->yy;
 
-       return a*d - b*c;
+    return a * d - b * c;
 }
-vkvg_status_t vkvg_matrix_invert (vkvg_matrix_t *matrix)
-{
-       float det;
+vkvg_status_t vkvg_matrix_invert(vkvg_matrix_t *matrix) {
+    float det;
 
-       /* Simple scaling|translation matrices are quite common... */
-       if (matrix->xy == 0. && matrix->yx == 0.) {
-               matrix->x0 = -matrix->x0;
-               matrix->y0 = -matrix->y0;
+    /* Simple scaling|translation matrices are quite common... */
+    if (matrix->xy == 0. && matrix->yx == 0.) {
+        matrix->x0 = -matrix->x0;
+        matrix->y0 = -matrix->y0;
 
-               if (matrix->xx != 1.f) {
-                       if (matrix->xx == 0.)
-                       return VKVG_STATUS_INVALID_MATRIX;
+        if (matrix->xx != 1.f) {
+            if (matrix->xx == 0.)
+                return VKVG_STATUS_INVALID_MATRIX;
 
-                       matrix->xx = 1.f / matrix->xx;
-                       matrix->x0 *= matrix->xx;
-               }
+            matrix->xx = 1.f / matrix->xx;
+            matrix->x0 *= matrix->xx;
+        }
 
-               if (matrix->yy != 1.f) {
-                       if (matrix->yy == 0.)
-                       return VKVG_STATUS_INVALID_MATRIX;
+        if (matrix->yy != 1.f) {
+            if (matrix->yy == 0.)
+                return VKVG_STATUS_INVALID_MATRIX;
 
-                       matrix->yy = 1.f / matrix->yy;
-                       matrix->y0 *= matrix->yy;
-               }
+            matrix->yy = 1.f / matrix->yy;
+            matrix->y0 *= matrix->yy;
+        }
 
-               return VKVG_STATUS_SUCCESS;
-       }
+        return VKVG_STATUS_SUCCESS;
+    }
 
-       /* inv (A) = 1/det (A) * adj (A) */
-       det = _vkvg_matrix_compute_determinant (matrix);
+    /* inv (A) = 1/det (A) * adj (A) */
+    det = _vkvg_matrix_compute_determinant(matrix);
 
-       if (! ISFINITE (det))
-               return VKVG_STATUS_INVALID_MATRIX;
+    if (!ISFINITE(det))
+        return VKVG_STATUS_INVALID_MATRIX;
 
-       if (det == 0)
-               return VKVG_STATUS_INVALID_MATRIX;
+    if (det == 0)
+        return VKVG_STATUS_INVALID_MATRIX;
 
-       _vkvg_matrix_compute_adjoint (matrix);
-       _vkvg_matrix_scalar_multiply (matrix, 1 / det);
+    _vkvg_matrix_compute_adjoint(matrix);
+    _vkvg_matrix_scalar_multiply(matrix, 1 / det);
 
-       return VKVG_STATUS_SUCCESS;
-}
-void vkvg_matrix_init_identity (vkvg_matrix_t *matrix)
-{
-       vkvg_matrix_init (matrix,
-                          1, 0,
-                          0, 1,
-                          0, 0);
+    return VKVG_STATUS_SUCCESS;
 }
+void vkvg_matrix_init_identity(vkvg_matrix_t *matrix) { vkvg_matrix_init(matrix, 1, 0, 0, 1, 0, 0); }
 
-void vkvg_matrix_init (vkvg_matrix_t *matrix,
-                  float xx, float yx,
-                  float xy, float yy,
-                  float x0, float y0)
-{
-       matrix->xx = xx; matrix->yx = yx;
-       matrix->xy = xy; matrix->yy = yy;
-       matrix->x0 = x0; matrix->y0 = y0;
+void vkvg_matrix_init(vkvg_matrix_t *matrix, float xx, float yx, float xy, float yy, float x0, float y0) {
+    matrix->xx = xx;
+    matrix->yx = yx;
+    matrix->xy = xy;
+    matrix->yy = yy;
+    matrix->x0 = x0;
+    matrix->y0 = y0;
 }
 
-void vkvg_matrix_init_translate (vkvg_matrix_t *matrix, float tx, float ty)
-{
-       vkvg_matrix_init (matrix,
-                          1, 0,
-                          0, 1,
-                          tx, ty);
-}
-void vkvg_matrix_init_scale (vkvg_matrix_t *matrix, float sx, float sy)
-{
-       vkvg_matrix_init (matrix,
-                          sx,  0,
-                          0, sy,
-                          0, 0);
+void vkvg_matrix_init_translate(vkvg_matrix_t *matrix, float tx, float ty) {
+    vkvg_matrix_init(matrix, 1, 0, 0, 1, tx, ty);
 }
-void vkvg_matrix_init_rotate (vkvg_matrix_t *matrix, float radians)
-{
-       float  s;
-       float  c;
-
-       s = sinf (radians);
-       c = cosf (radians);
-
-       vkvg_matrix_init (matrix,
-                          c, s,
-                          -s, c,
-                          0, 0);
+void vkvg_matrix_init_scale(vkvg_matrix_t *matrix, float sx, float sy) { vkvg_matrix_init(matrix, sx, 0, 0, sy, 0, 0); }
+void vkvg_matrix_init_rotate(vkvg_matrix_t *matrix, float radians) {
+    float s;
+    float c;
+
+    s = sinf(radians);
+    c = cosf(radians);
+
+    vkvg_matrix_init(matrix, c, s, -s, c, 0, 0);
 }
-void vkvg_matrix_translate (vkvg_matrix_t *matrix, float tx, float ty)
-{
-       vkvg_matrix_t tmp;
+void vkvg_matrix_translate(vkvg_matrix_t *matrix, float tx, float ty) {
+    vkvg_matrix_t tmp;
 
-       vkvg_matrix_init_translate (&tmp, tx, ty);
+    vkvg_matrix_init_translate(&tmp, tx, ty);
 
-       vkvg_matrix_multiply (matrix, &tmp, matrix);
+    vkvg_matrix_multiply(matrix, &tmp, matrix);
 }
-void vkvg_matrix_scale (vkvg_matrix_t *matrix, float sx, float sy)
-{
-       vkvg_matrix_t tmp;
+void vkvg_matrix_scale(vkvg_matrix_t *matrix, float sx, float sy) {
+    vkvg_matrix_t tmp;
 
-       vkvg_matrix_init_scale (&tmp, sx, sy);
+    vkvg_matrix_init_scale(&tmp, sx, sy);
 
-       vkvg_matrix_multiply (matrix, &tmp, matrix);
+    vkvg_matrix_multiply(matrix, &tmp, matrix);
 }
-void vkvg_matrix_rotate (vkvg_matrix_t *matrix, float radians)
-{
-       vkvg_matrix_t tmp;
+void vkvg_matrix_rotate(vkvg_matrix_t *matrix, float radians) {
+    vkvg_matrix_t tmp;
 
-       vkvg_matrix_init_rotate (&tmp, radians);
+    vkvg_matrix_init_rotate(&tmp, radians);
 
-       vkvg_matrix_multiply (matrix, &tmp, matrix);
+    vkvg_matrix_multiply(matrix, &tmp, matrix);
 }
-void vkvg_matrix_multiply (vkvg_matrix_t *result, const vkvg_matrix_t *a, const vkvg_matrix_t *b)
-{
-       vkvg_matrix_t r;
+void vkvg_matrix_multiply(vkvg_matrix_t *result, const vkvg_matrix_t *a, const vkvg_matrix_t *b) {
+    vkvg_matrix_t r;
 
-       r.xx = a->xx * b->xx + a->yx * b->xy;
-       r.yx = a->xx * b->yx + a->yx * b->yy;
+    r.xx = a->xx * b->xx + a->yx * b->xy;
+    r.yx = a->xx * b->yx + a->yx * b->yy;
 
-       r.xy = a->xy * b->xx + a->yy * b->xy;
-       r.yy = a->xy * b->yx + a->yy * b->yy;
+    r.xy = a->xy * b->xx + a->yy * b->xy;
+    r.yy = a->xy * b->yx + a->yy * b->yy;
 
-       r.x0 = a->x0 * b->xx + a->y0 * b->xy + b->x0;
-       r.y0 = a->x0 * b->yx + a->y0 * b->yy + b->y0;
+    r.x0 = a->x0 * b->xx + a->y0 * b->xy + b->x0;
+    r.y0 = a->x0 * b->yx + a->y0 * b->yy + b->y0;
 
-       *result = r;
+    *result = r;
 }
-void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, float *dx, float *dy)
-{
-       float new_x, new_y;
+void vkvg_matrix_transform_distance(const vkvg_matrix_t *matrix, float *dx, float *dy) {
+    float new_x, new_y;
 
-       new_x = (matrix->xx * *dx + matrix->xy * *dy);
-       new_y = (matrix->yx * *dx + matrix->yy * *dy);
+    new_x = (matrix->xx * *dx + matrix->xy * *dy);
+    new_y = (matrix->yx * *dx + matrix->yy * *dy);
 
-       *dx = new_x;
-       *dy = new_y;
+    *dx = new_x;
+    *dy = new_y;
 }
-void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, float *x, float *y)
-{
-       vkvg_matrix_transform_distance (matrix, x, y);
+void vkvg_matrix_transform_point(const vkvg_matrix_t *matrix, float *x, float *y) {
+    vkvg_matrix_transform_distance(matrix, x, y);
 
-       *x += matrix->x0;
-       *y += matrix->y0;
+    *x += matrix->x0;
+    *y += matrix->y0;
 }
-void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy) {
-       *sx = sqrt (matrix->xx * matrix->xx + matrix->xy * matrix->xy);
-       /*if (matrix->xx < 0)
-               *sx = -*sx;*/
-       *sy = sqrt (matrix->yx * matrix->yx + matrix->yy * matrix->yy);
-       /*if (matrix->yy < 0)
-               *sy = -*sy;*/
+void vkvg_matrix_get_scale(const vkvg_matrix_t *matrix, float *sx, float *sy) {
+    *sx = sqrt(matrix->xx * matrix->xx + matrix->xy * matrix->xy);
+    /*if (matrix->xx < 0)
+     *sx = -*sx;*/
+    *sy = sqrt(matrix->yx * matrix->yx + matrix->yy * matrix->yy);
+    /*if (matrix->yy < 0)
+     *sy = -*sy;*/
 }
index 76077917bccd0bc02edd711d3f9710d71e1f51c3..66db3501d4a794358f4a8cef0f23d742844cf1e5 100644 (file)
@@ -27,7 +27,4 @@
 #include <stdbool.h>
 #include "vkvg.h"
 
-
-
-
 #endif
index acefab62134e3a5318b5a9e8a29b4f7403a62742..2aad0917dec4d381f680964e78db1ea3d0f948c8 100644 (file)
 #include "vkvg_device_internal.h"
 #include "vkvg_pattern.h"
 
-VkvgPattern vkvg_pattern_create_for_surface (VkvgSurface surf){
-       VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t));
-       if (!pat)
-               return (VkvgPattern)&_no_mem_status;
-
-       pat->type = VKVG_PATTERN_TYPE_SURFACE;
-       pat->extend = VKVG_EXTEND_NONE;
-       pat->data = surf;
-       pat->references = 1;
-
-       vkvg_surface_reference (surf);
-       if (surf->status)
-               pat->status = surf->status;
-
-       return pat;
-}
-vkvg_status_t vkvg_pattern_get_linear_points (VkvgPattern pat, float* x0, float* y0, float* x1, float* y1) {
-       if (pat->status)
-               return pat->status;
-       if (pat->type != VKVG_PATTERN_TYPE_LINEAR)
-               return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
-
-       vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data;
-
-       *x0 = grad->cp[0].x;
-       *y0 = grad->cp[0].y;
-       *x1 = grad->cp[0].z;
-       *y1 = grad->cp[0].w;
-       return VKVG_STATUS_SUCCESS;
-}
-vkvg_status_t vkvg_pattern_edit_linear (VkvgPattern pat, float x0, float y0, float x1, float y1){
-       if (pat->status)
-               return pat->status;
-       if (pat->type != VKVG_PATTERN_TYPE_LINEAR)
-               return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
-
-       vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data;
-
-       grad->cp[0] = (vec4){{x0}, {y0}, {x1}, {y1}};
-       return VKVG_STATUS_SUCCESS;
-}
-VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1){
-       VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t));
-       if (!pat)
-               return (VkvgPattern)&_no_mem_status;
-       pat->type = VKVG_PATTERN_TYPE_LINEAR;
-       pat->extend = VKVG_EXTEND_NONE;
-
-       pat->data = (void*)calloc(1,sizeof(vkvg_gradient_t));
-
-       if (pat->data) {
-               vkvg_pattern_edit_linear(pat, x0, y0, x1, y1);
-               pat->references = 1;
-       } else
-               pat->status = VKVG_STATUS_NO_MEMORY;
-
-       return pat;
-}
-vkvg_status_t vkvg_pattern_edit_radial (VkvgPattern pat,
-                                                                               float cx0, float cy0, float radius0,
-                                                                               float cx1, float cy1, float radius1) {
-       if (pat->status)
-               return pat->status;
-       if (pat->type != VKVG_PATTERN_TYPE_RADIAL)
-               return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
-
-       vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data;
-
-       vec2 c0 = {cx0, cy0};
-       vec2 c1 = {cx1, cy1};
-
-       if (radius0 > radius1 - 1.0f)
-               radius0 = radius1 - 1.0f;
-       vec2 u = vec2_sub (c0, c1);
-       float l = vec2_length(u);
-       if (l + radius0 + 1.0f >= radius1) {
-               vec2 v = vec2_div_s(u, l);
-               c0 = vec2_add(c1, vec2_mult_s (v, radius1 - radius0 - 1.0f));
-       }
-
-       grad->cp[0] = (vec4){{c0.x}, {c0.y},{radius0},{0}};
-       grad->cp[1] = (vec4){{c1.x}, {c1.y},{radius1},{0}};
-       return VKVG_STATUS_SUCCESS;
-}
-VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0,
-                                                                               float cx1, float cy1, float radius1){
-       VkvgPattern pat = (vkvg_pattern_t*)calloc(1, sizeof(vkvg_pattern_t));
-       if (!pat)
-               return (VkvgPattern)&_no_mem_status;
-       pat->type = VKVG_PATTERN_TYPE_RADIAL;
-       pat->extend = VKVG_EXTEND_NONE;
-
-       pat->data = (void*)calloc(1,sizeof(vkvg_gradient_t));
-
-       if (pat->data) {
-               vkvg_pattern_edit_radial (pat, cx0, cy0, radius0, cx1, cy1, radius1);
-               pat->references = 1;
-       } else
-               pat->status = VKVG_STATUS_NO_MEMORY;
-
-       return pat;
-}
-VkvgPattern vkvg_pattern_reference (VkvgPattern pat) {
-       if (!pat->status)
-               pat->references++;
-       return pat;
-}
-uint32_t vkvg_pattern_get_reference_count (VkvgPattern pat) {
-       if (pat->status)
-               return 0;
-       return pat->references;
-}
-vkvg_status_t vkvg_pattern_add_color_stop (VkvgPattern pat, float offset, float r, float g, float b, float a) {
-       if (pat->status)
-               return pat->status;
-       if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
-               return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
-
-       vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data;
+VkvgPattern vkvg_pattern_create_for_surface(VkvgSurface surf) {
+    VkvgPattern pat = (vkvg_pattern_t *)calloc(1, sizeof(vkvg_pattern_t));
+    if (!pat)
+        return (VkvgPattern)&_no_mem_status;
+
+    pat->type       = VKVG_PATTERN_TYPE_SURFACE;
+    pat->extend     = VKVG_EXTEND_NONE;
+    pat->data       = surf;
+    pat->references = 1;
+
+    vkvg_surface_reference(surf);
+    if (surf->status)
+        pat->status = surf->status;
+
+    return pat;
+}
+vkvg_status_t vkvg_pattern_get_linear_points(VkvgPattern pat, float *x0, float *y0, float *x1, float *y1) {
+    if (pat->status)
+        return pat->status;
+    if (pat->type != VKVG_PATTERN_TYPE_LINEAR)
+        return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
+
+    vkvg_gradient_t *grad = (vkvg_gradient_t *)pat->data;
+
+    *x0 = grad->cp[0].x;
+    *y0 = grad->cp[0].y;
+    *x1 = grad->cp[0].z;
+    *y1 = grad->cp[0].w;
+    return VKVG_STATUS_SUCCESS;
+}
+vkvg_status_t vkvg_pattern_edit_linear(VkvgPattern pat, float x0, float y0, float x1, float y1) {
+    if (pat->status)
+        return pat->status;
+    if (pat->type != VKVG_PATTERN_TYPE_LINEAR)
+        return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
+
+    vkvg_gradient_t *grad = (vkvg_gradient_t *)pat->data;
+
+    grad->cp[0] = (vec4){{x0}, {y0}, {x1}, {y1}};
+    return VKVG_STATUS_SUCCESS;
+}
+VkvgPattern vkvg_pattern_create_linear(float x0, float y0, float x1, float y1) {
+    VkvgPattern pat = (vkvg_pattern_t *)calloc(1, sizeof(vkvg_pattern_t));
+    if (!pat)
+        return (VkvgPattern)&_no_mem_status;
+    pat->type   = VKVG_PATTERN_TYPE_LINEAR;
+    pat->extend = VKVG_EXTEND_NONE;
+
+    pat->data = (void *)calloc(1, sizeof(vkvg_gradient_t));
+
+    if (pat->data) {
+        vkvg_pattern_edit_linear(pat, x0, y0, x1, y1);
+        pat->references = 1;
+    } else
+        pat->status = VKVG_STATUS_NO_MEMORY;
+
+    return pat;
+}
+vkvg_status_t vkvg_pattern_edit_radial(VkvgPattern pat, float cx0, float cy0, float radius0, float cx1, float cy1,
+                                       float radius1) {
+    if (pat->status)
+        return pat->status;
+    if (pat->type != VKVG_PATTERN_TYPE_RADIAL)
+        return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
+
+    vkvg_gradient_t *grad = (vkvg_gradient_t *)pat->data;
+
+    vec2 c0 = {cx0, cy0};
+    vec2 c1 = {cx1, cy1};
+
+    if (radius0 > radius1 - 1.0f)
+        radius0 = radius1 - 1.0f;
+    vec2  u = vec2_sub(c0, c1);
+    float l = vec2_length(u);
+    if (l + radius0 + 1.0f >= radius1) {
+        vec2 v = vec2_div_s(u, l);
+        c0     = vec2_add(c1, vec2_mult_s(v, radius1 - radius0 - 1.0f));
+    }
+
+    grad->cp[0] = (vec4){{c0.x}, {c0.y}, {radius0}, {0}};
+    grad->cp[1] = (vec4){{c1.x}, {c1.y}, {radius1}, {0}};
+    return VKVG_STATUS_SUCCESS;
+}
+VkvgPattern vkvg_pattern_create_radial(float cx0, float cy0, float radius0, float cx1, float cy1, float radius1) {
+    VkvgPattern pat = (vkvg_pattern_t *)calloc(1, sizeof(vkvg_pattern_t));
+    if (!pat)
+        return (VkvgPattern)&_no_mem_status;
+    pat->type   = VKVG_PATTERN_TYPE_RADIAL;
+    pat->extend = VKVG_EXTEND_NONE;
+
+    pat->data = (void *)calloc(1, sizeof(vkvg_gradient_t));
+
+    if (pat->data) {
+        vkvg_pattern_edit_radial(pat, cx0, cy0, radius0, cx1, cy1, radius1);
+        pat->references = 1;
+    } else
+        pat->status = VKVG_STATUS_NO_MEMORY;
+
+    return pat;
+}
+VkvgPattern vkvg_pattern_reference(VkvgPattern pat) {
+    if (!pat->status)
+        pat->references++;
+    return pat;
+}
+uint32_t vkvg_pattern_get_reference_count(VkvgPattern pat) {
+    if (pat->status)
+        return 0;
+    return pat->references;
+}
+vkvg_status_t vkvg_pattern_add_color_stop(VkvgPattern pat, float offset, float r, float g, float b, float a) {
+    if (pat->status)
+        return pat->status;
+    if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
+        return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
+
+    vkvg_gradient_t *grad = (vkvg_gradient_t *)pat->data;
 #ifdef VKVG_PREMULT_ALPHA
-       vkvg_color_t c = {a*r,a*g,a*b,a};
+    vkvg_color_t c = {a * r, a * g, a * b, a};
 #else
-       vkvg_color_t c = {r,g,b,a};
+    vkvg_color_t c             = {r, g, b, a};
 #endif
-       grad->colors[grad->count] = c;
+    grad->colors[grad->count] = c;
 #ifdef VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT
-       grad->stops[grad->count] = offset;
+    grad->stops[grad->count] = offset;
 #else
-       grad->stops[grad->count].r = offset;
+    grad->stops[grad->count].r = offset;
 #endif
-       grad->count++;
-}
-void vkvg_pattern_set_extend (VkvgPattern pat, vkvg_extend_t extend){
-       if (pat->status)
-               return;
-       pat->extend = extend;
-}
-void vkvg_pattern_set_filter (VkvgPattern pat, vkvg_filter_t filter){
-       if (pat->status)
-               return;
-       pat->filter = filter;
-}
-
-vkvg_extend_t vkvg_pattern_get_extend (VkvgPattern pat){
-       if (pat->status)
-               return (vkvg_extend_t)0;
-       return pat->extend;
-}
-vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat){
-       if (pat->status)
-               return (vkvg_filter_t)0;
-       return pat->filter;
-}
-vkvg_pattern_type_t vkvg_pattern_get_type (VkvgPattern pat){
-       if (pat->status)
-               return (vkvg_pattern_type_t)0;
-       return pat->type;
-}
-vkvg_status_t vkvg_pattern_get_color_stop_count (VkvgPattern pat, uint32_t* count) {
-       if (pat->status)
-               return pat->status;
-       if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
-               return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
-       vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data;
-       *count = grad->count;
-       return VKVG_STATUS_SUCCESS;
-}
-vkvg_status_t vkvg_pattern_get_color_stop_rgba (VkvgPattern pat, uint32_t index,
-                                                                                               float* offset, float* r, float* g, float* b, float* a) {
-       if (pat->status)
-               return pat->status;
-       if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
-               return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
-       vkvg_gradient_t* grad = (vkvg_gradient_t*)pat->data;
-       if (index >= grad->count)
-               return VKVG_STATUS_INVALID_INDEX;
+    grad->count++;
+}
+void vkvg_pattern_set_extend(VkvgPattern pat, vkvg_extend_t extend) {
+    if (pat->status)
+        return;
+    pat->extend = extend;
+}
+void vkvg_pattern_set_filter(VkvgPattern pat, vkvg_filter_t filter) {
+    if (pat->status)
+        return;
+    pat->filter = filter;
+}
+
+vkvg_extend_t vkvg_pattern_get_extend(VkvgPattern pat) {
+    if (pat->status)
+        return (vkvg_extend_t)0;
+    return pat->extend;
+}
+vkvg_filter_t vkvg_pattern_get_filter(VkvgPattern pat) {
+    if (pat->status)
+        return (vkvg_filter_t)0;
+    return pat->filter;
+}
+vkvg_pattern_type_t vkvg_pattern_get_type(VkvgPattern pat) {
+    if (pat->status)
+        return (vkvg_pattern_type_t)0;
+    return pat->type;
+}
+vkvg_status_t vkvg_pattern_get_color_stop_count(VkvgPattern pat, uint32_t *count) {
+    if (pat->status)
+        return pat->status;
+    if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
+        return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
+    vkvg_gradient_t *grad = (vkvg_gradient_t *)pat->data;
+    *count                = grad->count;
+    return VKVG_STATUS_SUCCESS;
+}
+vkvg_status_t vkvg_pattern_get_color_stop_rgba(VkvgPattern pat, uint32_t index, float *offset, float *r, float *g,
+                                               float *b, float *a) {
+    if (pat->status)
+        return pat->status;
+    if (pat->type == VKVG_PATTERN_TYPE_SURFACE || pat->type == VKVG_PATTERN_TYPE_SOLID)
+        return VKVG_STATUS_PATTERN_TYPE_MISMATCH;
+    vkvg_gradient_t *grad = (vkvg_gradient_t *)pat->data;
+    if (index >= grad->count)
+        return VKVG_STATUS_INVALID_INDEX;
 #ifdef VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT
-       *offset = grad->stops[index];
+    *offset = grad->stops[index];
 #else
-       *offset = grad->stops[index].r;
+    *offset                    = grad->stops[index].r;
 #endif
-       vkvg_color_t c = grad->colors[index];
-       *r = c.r;
-       *g = c.g;
-       *b = c.b;
-       *a = c.a;
-       return VKVG_STATUS_SUCCESS;
-}
-void vkvg_pattern_set_matrix (VkvgPattern pat, const vkvg_matrix_t* matrix) {
-       if (pat->status)
-               return;
-       pat->matrix             = *matrix;
-       pat->hasMatrix  = true;
-}
-void vkvg_pattern_get_matrix (VkvgPattern pat, vkvg_matrix_t* matrix) {
-       if (pat->status)
-               return;
-       if (pat->hasMatrix)
-               *matrix = pat->matrix;
-       else
-               *matrix = VKVG_IDENTITY_MATRIX;
-}
-vkvg_status_t vkvg_pattern_status (VkvgPattern pat) {
-       return pat->status;
-}
-
-void vkvg_pattern_destroy(VkvgPattern pat)
-{
-       if (pat->status)
-               return;
-       pat->references--;
-       if (pat->references > 0)
-               return;
-
-       if (pat->type == VKVG_PATTERN_TYPE_SURFACE) {
-               VkvgSurface surf = (VkvgSurface)pat->data;
-               vkvg_surface_destroy (surf);
-       }else
-               free (pat->data);
-
-       free(pat);
+    vkvg_color_t c = grad->colors[index];
+    *r             = c.r;
+    *g             = c.g;
+    *b             = c.b;
+    *a             = c.a;
+    return VKVG_STATUS_SUCCESS;
+}
+void vkvg_pattern_set_matrix(VkvgPattern pat, const vkvg_matrix_t *matrix) {
+    if (pat->status)
+        return;
+    pat->matrix    = *matrix;
+    pat->hasMatrix = true;
+}
+void vkvg_pattern_get_matrix(VkvgPattern pat, vkvg_matrix_t *matrix) {
+    if (pat->status)
+        return;
+    if (pat->hasMatrix)
+        *matrix = pat->matrix;
+    else
+        *matrix = VKVG_IDENTITY_MATRIX;
+}
+vkvg_status_t vkvg_pattern_status(VkvgPattern pat) { return pat->status; }
+
+void vkvg_pattern_destroy(VkvgPattern pat) {
+    if (pat->status)
+        return;
+    pat->references--;
+    if (pat->references > 0)
+        return;
+
+    if (pat->type == VKVG_PATTERN_TYPE_SURFACE) {
+        VkvgSurface surf = (VkvgSurface)pat->data;
+        vkvg_surface_destroy(surf);
+    } else
+        free(pat->data);
+
+    free(pat);
 }
index 2ad068dc4c888837110abbb645ddcf43284842f0..0ccc7a5cbc9ba85ef8d0743bd7232974ddb0d859 100644 (file)
 #include "vkvg_internal.h"
 
 typedef struct _vkvg_pattern_t {
-       vkvg_status_t           status;
-       uint32_t                        references;
-       vkvg_pattern_type_t type;
-       vkvg_extend_t           extend;
-       vkvg_filter_t           filter;
-       vkvg_matrix_t           matrix;
-       bool                            hasMatrix;
-       void*                           data;
-}vkvg_pattern_t;
+    vkvg_status_t       status;
+    uint32_t            references;
+    vkvg_pattern_type_t type;
+    vkvg_extend_t       extend;
+    vkvg_filter_t       filter;
+    vkvg_matrix_t       matrix;
+    bool                hasMatrix;
+    void               *data;
+} vkvg_pattern_t;
 
 typedef struct _vkvg_gradient_t {
-       vkvg_color_t    colors[16];
+    vkvg_color_t colors[16];
 #ifdef VKVG_ENABLE_VK_SCALAR_BLOCK_LAYOUT
-       float                   stops[16];
+    float stops[16];
 #else
-       vec4                    stops[16];
+    vec4 stops[16];
 #endif
-       vec4                    cp[2];
-       uint32_t                count;
-}vkvg_gradient_t;
+    vec4     cp[2];
+    uint32_t count;
+} vkvg_gradient_t;
 
 #endif
index 369adbd26c1363cea09c77aa561848e7f85a3576..fc281752c72476031c1ed3c7f505d48c133be36d 100644 (file)
 #include "stb_image_write.h"
 #include "vkh_image.h"
 
-#define max(x,y)
-void _transition_surf_images (VkvgSurface surf) {
-       LOCK_SURFACE(surf)
-       VkvgDevice dev = surf->dev;
-
-       //_surface_wait_cmd (surf);
-
-       vkh_cmd_begin (surf->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-       VkhImage imgMs = surf->imgMS;
-       if (imgMs != NULL)
-               vkh_image_set_layout(surf->cmd, imgMs, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                        VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
-
-       vkh_image_set_layout(surf->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                        VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
-       vkh_image_set_layout (surf->cmd, surf->stencil, dev->stencilAspectFlag,
-                                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
-       vkh_cmd_end (surf->cmd);
-
-       _surface_submit_cmd (surf);
-
-       UNLOCK_SURFACE(surf)
+#define max(x, y)
+void _transition_surf_images(VkvgSurface surf) {
+    LOCK_SURFACE(surf)
+    VkvgDevice dev = surf->dev;
+
+    //_surface_wait_cmd (surf);
+
+    vkh_cmd_begin(surf->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    VkhImage imgMs = surf->imgMS;
+    if (imgMs != NULL)
+        vkh_image_set_layout(surf->cmd, imgMs, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+                             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+
+    vkh_image_set_layout(surf->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+    vkh_image_set_layout(surf->cmd, surf->stencil, dev->stencilAspectFlag, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                         VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+    vkh_cmd_end(surf->cmd);
+
+    _surface_submit_cmd(surf);
+
+    UNLOCK_SURFACE(surf)
 }
-void vkvg_surface_clear (VkvgSurface surf) {
-       if (surf->status)
-               return;
-       _clear_surface(surf, VK_IMAGE_ASPECT_STENCIL_BIT|VK_IMAGE_ASPECT_COLOR_BIT);
+void vkvg_surface_clear(VkvgSurface surf) {
+    if (surf->status)
+        return;
+    _clear_surface(surf, VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_COLOR_BIT);
 }
-VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height){
-       VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
-       if (surf->status)
-               return surf;
+VkvgSurface vkvg_surface_create(VkvgDevice dev, uint32_t width, uint32_t height) {
+    VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
+    if (surf->status)
+        return surf;
 
-       surf->width = MAX(1, width);
-       surf->height = MAX(1, height);
-       surf->newSurf = true;//used to clear all attacments on first render pass
+    surf->width   = MAX(1, width);
+    surf->height  = MAX(1, height);
+    surf->newSurf = true; // used to clear all attacments on first render pass
 
-       _create_surface_images (surf);
+    _create_surface_images(surf);
 
-       _transition_surf_images (surf);
+    _transition_surf_images(surf);
 
-       surf->status = VKVG_STATUS_SUCCESS;
-       vkvg_device_reference (surf->dev);
-       return surf;
+    surf->status = VKVG_STATUS_SUCCESS;
+    vkvg_device_reference(surf->dev);
+    return surf;
 }
-VkvgSurface vkvg_surface_create_for_VkhImage (VkvgDevice dev, void* vkhImg) {
-       VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
-       if (surf->status)
-               return surf;
+VkvgSurface vkvg_surface_create_for_VkhImage(VkvgDevice dev, void *vkhImg) {
+    VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
+    if (surf->status)
+        return surf;
 
-       if (!vkhImg) {
-               surf->status = VKVG_STATUS_INVALID_IMAGE;
-               return surf;
-       }
+    if (!vkhImg) {
+        surf->status = VKVG_STATUS_INVALID_IMAGE;
+        return surf;
+    }
 
-       VkhImage img = (VkhImage)vkhImg;
-       surf->width = img->infos.extent.width;
-       surf->height= img->infos.extent.height;
+    VkhImage img = (VkhImage)vkhImg;
+    surf->width  = img->infos.extent.width;
+    surf->height = img->infos.extent.height;
 
-       surf->img = img;
+    surf->img = img;
 
-       vkh_image_create_sampler(img, VK_FILTER_NEAREST, VK_FILTER_NEAREST,
-                                                        VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
+    vkh_image_create_sampler(img, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
 
-       _create_surface_secondary_images        (surf);
-       _create_framebuffer                                     (surf);
+    _create_surface_secondary_images(surf);
+    _create_framebuffer(surf);
 
-       _transition_surf_images (surf);
-       //_clear_surface                                                (surf, VK_IMAGE_ASPECT_STENCIL_BIT);
+    _transition_surf_images(surf);
+    //_clear_surface                                           (surf, VK_IMAGE_ASPECT_STENCIL_BIT);
 
-       surf->status = VKVG_STATUS_SUCCESS;
-       vkvg_device_reference (surf->dev);
-       return surf;
+    surf->status = VKVG_STATUS_SUCCESS;
+    vkvg_device_reference(surf->dev);
+    return surf;
 }
-//TODO: it would be better to blit in original size and create ms final image with dest surf dims
-VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, uint32_t width, uint32_t height) {
-       VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
-       if (surf->status)
-               return surf;
-       if (!img || width <= 0 || height <= 0) {
-               surf->status = VKVG_STATUS_INVALID_IMAGE;
-               return surf;
-       }
-
-       surf->width = MAX(1, width);
-       surf->height = MAX(1, height);
-
-       _create_surface_images (surf);
-
-       uint32_t imgSize = width * height * 4;
-       VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1};
-       //original format image
-       VkhImage stagImg= vkh_image_create ((VkhDevice)surf->dev,VK_FORMAT_R8G8B8A8_UNORM,surf->width,surf->height,VK_IMAGE_TILING_LINEAR,
-                                                                                VKH_MEMORY_USAGE_GPU_ONLY,
-                                                                                VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
-       //bgra bliting target
-       VkhImage tmpImg = vkh_image_create ((VkhDevice)surf->dev,surf->format,surf->width,surf->height,VK_IMAGE_TILING_LINEAR,
-                                                                                VKH_MEMORY_USAGE_GPU_ONLY,
-                                                                                VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
-       vkh_image_create_descriptor (tmpImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                                VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
-       //staging buffer
-       vkh_buffer_t buff = {0};
-       vkh_buffer_init((VkhDevice)dev,
-                                       VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
-                                       VKH_MEMORY_USAGE_CPU_TO_GPU,
-                                       imgSize, &buff, true);
-
-       memcpy (vkh_buffer_get_mapped_pointer (&buff), img, imgSize);
-
-       VkCommandBuffer cmd = surf->cmd;
-
-       vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-       vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-
-
-       VkBufferImageCopy bufferCopyRegion = { .imageSubresource = imgSubResLayers,
-                                                                                  .imageExtent = {surf->width,surf->height,1}};
-
-       vkCmdCopyBufferToImage(cmd, buff.buffer,
-               vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion);
-
-       vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-       vkh_image_set_layout (cmd, tmpImg, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-
-       VkImageBlit blit = {
-               .srcSubresource = imgSubResLayers,
-               .srcOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1},
-               .dstSubresource = imgSubResLayers,
-               .dstOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1},
-       };
-       vkCmdBlitImage  (cmd,
-                                        vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                        vkh_image_get_vkimage (tmpImg),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR);
-
-       vkh_image_set_layout (cmd, tmpImg, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
-
-       vkh_cmd_end             (cmd);
-
-       _surface_submit_cmd (surf);//lock surface?
-
-       vkh_buffer_reset        (&buff);
-       vkh_image_destroy       (stagImg);
-
-       surf->newSurf = false;
-
-       //create tmp context with rendering pipeline to create the multisample img
-       VkvgContext ctx = vkvg_create (surf);
-
-/*       VkClearAttachment ca = {VK_IMAGE_ASPECT_COLOR_BIT,0, { 0.0f, 0.0f, 0.0f, 0.0f }};
-       VkClearRect cr = {{{0,0},{surf->width,surf->height}},0,1};
-       vkCmdClearAttachments(ctx->cmd, 1, &ca, 1, &cr);*/
-
-       vec4 srcRect = {.x=0,.y=0,.width=(float)surf->width,.height=(float)surf->height};
-       ctx->pushConsts.source = srcRect;
-       ctx->pushConsts.fsq_patternType = (ctx->pushConsts.fsq_patternType & FULLSCREEN_BIT) + VKVG_PATTERN_TYPE_SURFACE;
-
-       //_update_push_constants (ctx);
-       _update_descriptor_set (ctx, tmpImg, ctx->dsSrc);
-       _ensure_renderpass_is_started  (ctx);
-
-       vkvg_paint                      (ctx);
-       vkvg_destroy            (ctx);
-
-       vkh_image_destroy       (tmpImg);
-
-       surf->status = VKVG_STATUS_SUCCESS;
-       vkvg_device_reference (surf->dev);
-       return surf;
+// TODO: it would be better to blit in original size and create ms final image with dest surf dims
+VkvgSurface vkvg_surface_create_from_bitmap(VkvgDevice dev, unsigned char *img, uint32_t width, uint32_t height) {
+    VkvgSurface surf = _create_surface(dev, FB_COLOR_FORMAT);
+    if (surf->status)
+        return surf;
+    if (!img || width <= 0 || height <= 0) {
+        surf->status = VKVG_STATUS_INVALID_IMAGE;
+        return surf;
+    }
+
+    surf->width  = MAX(1, width);
+    surf->height = MAX(1, height);
+
+    _create_surface_images(surf);
+
+    uint32_t                 imgSize         = width * height * 4;
+    VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
+    // original format image
+    VkhImage stagImg = vkh_image_create((VkhDevice)surf->dev, VK_FORMAT_R8G8B8A8_UNORM, surf->width, surf->height,
+                                        VK_IMAGE_TILING_LINEAR, VKH_MEMORY_USAGE_GPU_ONLY,
+                                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+    // bgra bliting target
+    VkhImage tmpImg =
+        vkh_image_create((VkhDevice)surf->dev, surf->format, surf->width, surf->height, VK_IMAGE_TILING_LINEAR,
+                         VKH_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+    vkh_image_create_descriptor(tmpImg, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST,
+                                VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                                VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
+    // staging buffer
+    vkh_buffer_t buff = {0};
+    vkh_buffer_init((VkhDevice)dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VKH_MEMORY_USAGE_CPU_TO_GPU, imgSize, &buff,
+                    true);
+
+    memcpy(vkh_buffer_get_mapped_pointer(&buff), img, imgSize);
+
+    VkCommandBuffer cmd = surf->cmd;
+
+    vkh_cmd_begin(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_image_set_layout(cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+    VkBufferImageCopy bufferCopyRegion = {.imageSubresource = imgSubResLayers,
+                                          .imageExtent      = {surf->width, surf->height, 1}};
+
+    vkCmdCopyBufferToImage(cmd, buff.buffer, vkh_image_get_vkimage(stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
+                           &bufferCopyRegion);
+
+    vkh_image_set_layout(cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+    vkh_image_set_layout(cmd, tmpImg, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+    VkImageBlit blit = {
+        .srcSubresource = imgSubResLayers,
+        .srcOffsets[1]  = {(int32_t)surf->width, (int32_t)surf->height, 1},
+        .dstSubresource = imgSubResLayers,
+        .dstOffsets[1]  = {(int32_t)surf->width, (int32_t)surf->height, 1},
+    };
+    vkCmdBlitImage(cmd, vkh_image_get_vkimage(stagImg), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                   vkh_image_get_vkimage(tmpImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR);
+
+    vkh_image_set_layout(cmd, tmpImg, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
+
+    vkh_cmd_end(cmd);
+
+    _surface_submit_cmd(surf); // lock surface?
+
+    vkh_buffer_reset(&buff);
+    vkh_image_destroy(stagImg);
+
+    surf->newSurf = false;
+
+    // create tmp context with rendering pipeline to create the multisample img
+    VkvgContext ctx = vkvg_create(surf);
+
+    /*   VkClearAttachment ca = {VK_IMAGE_ASPECT_COLOR_BIT,0, { 0.0f, 0.0f, 0.0f, 0.0f }};
+        VkClearRect cr = {{{0,0},{surf->width,surf->height}},0,1};
+        vkCmdClearAttachments(ctx->cmd, 1, &ca, 1, &cr);*/
+
+    vec4 srcRect                    = {.x = 0, .y = 0, .width = (float)surf->width, .height = (float)surf->height};
+    ctx->pushConsts.source          = srcRect;
+    ctx->pushConsts.fsq_patternType = (ctx->pushConsts.fsq_patternType & FULLSCREEN_BIT) + VKVG_PATTERN_TYPE_SURFACE;
+
+    //_update_push_constants (ctx);
+    _update_descriptor_set(ctx, tmpImg, ctx->dsSrc);
+    _ensure_renderpass_is_started(ctx);
+
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
+
+    vkh_image_destroy(tmpImg);
+
+    surf->status = VKVG_STATUS_SUCCESS;
+    vkvg_device_reference(surf->dev);
+    return surf;
 }
-VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath) {
-       int w = 0,
-               h = 0,
-               channels = 0;
-       unsigned char *img = stbi_load(filePath, &w, &h, &channels, 4);//force 4 components per pixel
-       if (!img){
-               LOG(VKVG_LOG_ERR, "Could not load texture from %s, %s\n", filePath, stbi_failure_reason());
-               return (VkvgSurface)&_no_mem_status;
-       }
+VkvgSurface vkvg_surface_create_from_image(VkvgDevice dev, const char *filePath) {
+    int            w = 0, h = 0, channels = 0;
+    unsigned char *img = stbi_load(filePath, &w, &h, &channels, 4); // force 4 components per pixel
+    if (!img) {
+        LOG(VKVG_LOG_ERR, "Could not load texture from %s, %s\n", filePath, stbi_failure_reason());
+        return (VkvgSurface)&_no_mem_status;
+    }
 
-       VkvgSurface surf = vkvg_surface_create_from_bitmap(dev, img, (uint32_t)w, (uint32_t)h);
+    VkvgSurface surf = vkvg_surface_create_from_bitmap(dev, img, (uint32_t)w, (uint32_t)h);
 
-       stbi_image_free (img);
+    stbi_image_free(img);
 
-       return surf;
+    return surf;
 }
 
-void vkvg_surface_destroy(VkvgSurface surf)
-{
-       if (surf->status)
-               return;
+void vkvg_surface_destroy(VkvgSurface surf) {
+    if (surf->status)
+        return;
 
-       LOCK_SURFACE(surf)
-       surf->references--;
-       if (surf->references > 0) {
-               UNLOCK_SURFACE(surf)
-               return;
-       }
-       UNLOCK_SURFACE(surf)
+    LOCK_SURFACE(surf)
+    surf->references--;
+    if (surf->references > 0) {
+        UNLOCK_SURFACE(surf)
+        return;
+    }
+    UNLOCK_SURFACE(surf)
 
-       vkDestroyCommandPool(surf->dev->vkDev, surf->cmdPool, NULL);
-       vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL);
+    vkDestroyCommandPool(surf->dev->vkDev, surf->cmdPool, NULL);
+    vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL);
 
-       if (!surf->img->imported)
-               vkh_image_destroy(surf->img);
+    if (!surf->img->imported)
+        vkh_image_destroy(surf->img);
 
-       vkh_image_destroy(surf->imgMS);
-       vkh_image_destroy(surf->stencil);
+    vkh_image_destroy(surf->imgMS);
+    vkh_image_destroy(surf->stencil);
 
-       if (surf->dev->threadAware)
-               mtx_destroy (&surf->mutex);
+    if (surf->dev->threadAware)
+        mtx_destroy(&surf->mutex);
 
 #if VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       vkDestroySemaphore (surf->dev->vkDev, surf->timeline, NULL);
+    vkDestroySemaphore(surf->dev->vkDev, surf->timeline, NULL);
 #else
-       vkDestroyFence (surf->dev->vkDev, surf->flushFence, NULL);
+    vkDestroyFence(surf->dev->vkDev, surf->flushFence, NULL);
 #endif
 
-       vkvg_device_destroy (surf->dev);
-       free(surf);
+    vkvg_device_destroy(surf->dev);
+    free(surf);
 }
 
-VkvgSurface vkvg_surface_reference (VkvgSurface surf) {
-       if (!surf->status) {
-               LOCK_SURFACE(surf)
-               surf->references++;
-               UNLOCK_SURFACE(surf)
-       }
-       return surf;
+VkvgSurface vkvg_surface_reference(VkvgSurface surf) {
+    if (!surf->status) {
+        LOCK_SURFACE(surf)
+        surf->references++;
+        UNLOCK_SURFACE(surf)
+    }
+    return surf;
 }
-uint32_t vkvg_surface_get_reference_count (VkvgSurface surf) {
-       if (surf->status)
-               return 0;
-       return surf->references;
+uint32_t vkvg_surface_get_reference_count(VkvgSurface surf) {
+    if (surf->status)
+        return 0;
+    return surf->references;
 }
 
-VkImage vkvg_surface_get_vk_image(VkvgSurface surf)
-{
-       if (surf->status)
-               return NULL;
-       if (surf->dev->deferredResolve)
-               _explicit_ms_resolve(surf);
-       return vkh_image_get_vkimage (surf->img);
+VkImage vkvg_surface_get_vk_image(VkvgSurface surf) {
+    if (surf->status)
+        return NULL;
+    if (surf->dev->deferredResolve)
+        _explicit_ms_resolve(surf);
+    return vkh_image_get_vkimage(surf->img);
 }
-void vkvg_surface_resolve (VkvgSurface surf){
-       if (surf->status || !surf->dev->deferredResolve)
-               return;
-       _explicit_ms_resolve(surf);
+void vkvg_surface_resolve(VkvgSurface surf) {
+    if (surf->status || !surf->dev->deferredResolve)
+        return;
+    _explicit_ms_resolve(surf);
 }
-VkFormat vkvg_surface_get_vk_format(VkvgSurface surf)
-{
-       if (surf->status)
-               return VK_FORMAT_UNDEFINED;
-       return surf->format;
+VkFormat vkvg_surface_get_vk_format(VkvgSurface surf) {
+    if (surf->status)
+        return VK_FORMAT_UNDEFINED;
+    return surf->format;
 }
-uint32_t vkvg_surface_get_width (VkvgSurface surf) {
-       if (surf->status)
-               return 0;
-       return surf->width;
+uint32_t vkvg_surface_get_width(VkvgSurface surf) {
+    if (surf->status)
+        return 0;
+    return surf->width;
 }
-uint32_t vkvg_surface_get_height (VkvgSurface surf) {
-       if (surf->status)
-               return 0;
-       return surf->height;
+uint32_t vkvg_surface_get_height(VkvgSurface surf) {
+    if (surf->status)
+        return 0;
+    return surf->height;
 }
 
-vkvg_status_t vkvg_surface_write_to_png (VkvgSurface surf, const char* path){
-       if (surf->status) {
-               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_png failed, invalid status: %d\n", surf->status);
-               return VKVG_STATUS_INVALID_STATUS;
-       }
-       if (surf->dev->status) {
-               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_png failed, invalid device status: %d\n", surf->dev->status);
-               return VKVG_STATUS_INVALID_STATUS;
-       }
-       if (surf->dev->pngStagFormat == VK_FORMAT_UNDEFINED) {
-               LOG(VKVG_LOG_ERR, "no suitable image format for png write\n");
-               return VKVG_STATUS_INVALID_FORMAT;
-       }
-       if (!path) {
-               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_png failed, null path\n");
-               return VKVG_STATUS_WRITE_ERROR;
-       }
-       LOCK_SURFACE(surf)
-       VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1};
-       VkvgDevice dev = surf->dev;
-
-       //RGBA to blit to, surf img is bgra
-       VkhImage stagImg;
-
-       if (dev->pngStagTiling == VK_IMAGE_TILING_LINEAR)
-               stagImg = vkh_image_create ((VkhDevice)surf->dev, dev->pngStagFormat, surf->width, surf->height, dev->pngStagTiling,
-                                                                                VKH_MEMORY_USAGE_GPU_TO_CPU,
-                                                                                VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
-       else
-               stagImg = vkh_image_create ((VkhDevice)surf->dev, dev->pngStagFormat, surf->width,surf->height, dev->pngStagTiling,
-                                                                                VKH_MEMORY_USAGE_GPU_ONLY,
-                                                                                VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
-
-       VkCommandBuffer cmd = surf->cmd;
-       vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-       vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-       vkh_image_set_layout (cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-
-       VkImageBlit blit = {
-               .srcSubresource = imgSubResLayers,
-               .srcOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1},
-               .dstSubresource = imgSubResLayers,
-               .dstOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1},
-       };
-       vkCmdBlitImage  (cmd,
-                                        vkh_image_get_vkimage (surf->img), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                        vkh_image_get_vkimage (stagImg),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST);
-
-       vkh_cmd_end             (cmd);
-
-       _surface_submit_cmd (surf);
-
-       VkhImage stagImgLinear = stagImg;
-
-       if (dev->pngStagTiling == VK_IMAGE_TILING_OPTIMAL) {
-               stagImgLinear = vkh_image_create ((VkhDevice)surf->dev, dev->pngStagFormat, surf->width, surf->height, VK_IMAGE_TILING_LINEAR,
-                                                                                 VKH_MEMORY_USAGE_GPU_TO_CPU,
-                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
-               VkImageCopy cpy = {
-                       .srcSubresource = imgSubResLayers,
-                       .srcOffset = {0},
-                       .dstSubresource = imgSubResLayers,
-                       .dstOffset = {0},
-                       .extent = {(int32_t)surf->width, (int32_t)surf->height, 1}
-               };
-
-               vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-               vkh_image_set_layout (cmd, stagImgLinear, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                         VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                         VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-               vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                         VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-               vkCmdCopyImage(cmd,
-                                          vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                          vkh_image_get_vkimage (stagImgLinear),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy);
-
-               vkh_cmd_end             (cmd);
-
-               _surface_submit_cmd (surf);
-
-               vkh_image_destroy (stagImg);
-       }
-
-       void* img = vkh_image_map (stagImgLinear);
-
-       uint64_t stride = vkh_image_get_stride(stagImgLinear);
-
-       stbi_write_png (path, (int32_t)surf->width, (int32_t)surf->height, 4, img, (int32_t)stride);
-
-       vkh_image_unmap (stagImgLinear);
-       vkh_image_destroy (stagImgLinear);
-
-       UNLOCK_SURFACE(surf)
-       return VKVG_STATUS_SUCCESS;
+vkvg_status_t vkvg_surface_write_to_png(VkvgSurface surf, const char *path) {
+    if (surf->status) {
+        LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_png failed, invalid status: %d\n", surf->status);
+        return VKVG_STATUS_INVALID_STATUS;
+    }
+    if (surf->dev->status) {
+        LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_png failed, invalid device status: %d\n", surf->dev->status);
+        return VKVG_STATUS_INVALID_STATUS;
+    }
+    if (surf->dev->pngStagFormat == VK_FORMAT_UNDEFINED) {
+        LOG(VKVG_LOG_ERR, "no suitable image format for png write\n");
+        return VKVG_STATUS_INVALID_FORMAT;
+    }
+    if (!path) {
+        LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_png failed, null path\n");
+        return VKVG_STATUS_WRITE_ERROR;
+    }
+    LOCK_SURFACE(surf)
+    VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
+    VkvgDevice               dev             = surf->dev;
+
+    // RGBA to blit to, surf img is bgra
+    VkhImage stagImg;
+
+    if (dev->pngStagTiling == VK_IMAGE_TILING_LINEAR)
+        stagImg = vkh_image_create((VkhDevice)surf->dev, dev->pngStagFormat, surf->width, surf->height,
+                                   dev->pngStagTiling, VKH_MEMORY_USAGE_GPU_TO_CPU,
+                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+    else
+        stagImg = vkh_image_create((VkhDevice)surf->dev, dev->pngStagFormat, surf->width, surf->height,
+                                   dev->pngStagTiling, VKH_MEMORY_USAGE_GPU_ONLY,
+                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+
+    VkCommandBuffer cmd = surf->cmd;
+    vkh_cmd_begin(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_image_set_layout(cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
+                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+    vkh_image_set_layout(cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+    VkImageBlit blit = {
+        .srcSubresource = imgSubResLayers,
+        .srcOffsets[1]  = {(int32_t)surf->width, (int32_t)surf->height, 1},
+        .dstSubresource = imgSubResLayers,
+        .dstOffsets[1]  = {(int32_t)surf->width, (int32_t)surf->height, 1},
+    };
+    vkCmdBlitImage(cmd, vkh_image_get_vkimage(surf->img), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                   vkh_image_get_vkimage(stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST);
+
+    vkh_cmd_end(cmd);
+
+    _surface_submit_cmd(surf);
+
+    VkhImage stagImgLinear = stagImg;
+
+    if (dev->pngStagTiling == VK_IMAGE_TILING_OPTIMAL) {
+        stagImgLinear   = vkh_image_create((VkhDevice)surf->dev, dev->pngStagFormat, surf->width, surf->height,
+                                           VK_IMAGE_TILING_LINEAR, VKH_MEMORY_USAGE_GPU_TO_CPU,
+                                           VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+        VkImageCopy cpy = {.srcSubresource = imgSubResLayers,
+                           .srcOffset      = {0},
+                           .dstSubresource = imgSubResLayers,
+                           .dstOffset      = {0},
+                           .extent         = {(int32_t)surf->width, (int32_t)surf->height, 1}};
+
+        vkh_cmd_begin(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+        vkh_image_set_layout(cmd, stagImgLinear, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
+                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                             VK_PIPELINE_STAGE_TRANSFER_BIT);
+        vkh_image_set_layout(cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                             VK_PIPELINE_STAGE_TRANSFER_BIT);
+        vkCmdCopyImage(cmd, vkh_image_get_vkimage(stagImg), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                       vkh_image_get_vkimage(stagImgLinear), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy);
+
+        vkh_cmd_end(cmd);
+
+        _surface_submit_cmd(surf);
+
+        vkh_image_destroy(stagImg);
+    }
+
+    void *img = vkh_image_map(stagImgLinear);
+
+    uint64_t stride = vkh_image_get_stride(stagImgLinear);
+
+    stbi_write_png(path, (int32_t)surf->width, (int32_t)surf->height, 4, img, (int32_t)stride);
+
+    vkh_image_unmap(stagImgLinear);
+    vkh_image_destroy(stagImgLinear);
+
+    UNLOCK_SURFACE(surf)
+    return VKVG_STATUS_SUCCESS;
 }
 
-vkvg_status_t vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap){
-       if (surf->status) {
-               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_memory failed, invalid status: %d\n", surf->status);
-               return VKVG_STATUS_INVALID_STATUS;
-       }
-       if (!bitmap) {
-               LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_memory failed, null path\n");
-               return VKVG_STATUS_INVALID_IMAGE;
-       }
-
-       LOCK_SURFACE(surf)
-
-       VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1};
-       VkvgDevice dev = surf->dev;
-
-       //RGBA to blit to, surf img is bgra
-       VkhImage stagImg= vkh_image_create ((VkhDevice)surf->dev,VK_FORMAT_B8G8R8A8_UNORM ,surf->width,surf->height,VK_IMAGE_TILING_LINEAR,
-                                                                                VKH_MEMORY_USAGE_GPU_TO_CPU,
-                                                                                VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
-
-       VkCommandBuffer cmd = surf->cmd;
-
-       vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-       vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-       vkh_image_set_layout (cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-
-       VkImageBlit blit = {
-               .srcSubresource = imgSubResLayers,
-               .srcOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1},
-               .dstSubresource = imgSubResLayers,
-               .dstOffsets[1] = {(int32_t)surf->width, (int32_t)surf->height, 1},
-       };
-       vkCmdBlitImage  (cmd,
-                                        vkh_image_get_vkimage (surf->img), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                        vkh_image_get_vkimage (stagImg),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST);
-
-       vkh_cmd_end             (cmd);
-
-       _surface_submit_cmd (surf);
-
-       uint64_t stride = vkh_image_get_stride(stagImg);
-       uint32_t dest_stride = surf->width * 4;
-
-       char* img = vkh_image_map (stagImg);
-       char* row = (char*)bitmap;
-       for (uint32_t y = 0; y < surf->height; y++) {
-               memcpy(row, img, dest_stride);
-               row += dest_stride;
-               img += stride;
-       }
-
-       vkh_image_unmap (stagImg);
-       vkh_image_destroy (stagImg);
-
-       UNLOCK_SURFACE(surf)
-
-       return VKVG_STATUS_SUCCESS;
+vkvg_status_t vkvg_surface_write_to_memory(VkvgSurface surf, unsigned char *const bitmap) {
+    if (surf->status) {
+        LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_memory failed, invalid status: %d\n", surf->status);
+        return VKVG_STATUS_INVALID_STATUS;
+    }
+    if (!bitmap) {
+        LOG(VKVG_LOG_ERR, "vkvg_surface_write_to_memory failed, null path\n");
+        return VKVG_STATUS_INVALID_IMAGE;
+    }
+
+    LOCK_SURFACE(surf)
+
+    VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
+    VkvgDevice               dev             = surf->dev;
+
+    // RGBA to blit to, surf img is bgra
+    VkhImage stagImg = vkh_image_create((VkhDevice)surf->dev, VK_FORMAT_B8G8R8A8_UNORM, surf->width, surf->height,
+                                        VK_IMAGE_TILING_LINEAR, VKH_MEMORY_USAGE_GPU_TO_CPU,
+                                        VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+
+    VkCommandBuffer cmd = surf->cmd;
+
+    vkh_cmd_begin(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_image_set_layout(cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
+                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+    vkh_image_set_layout(cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+    VkImageBlit blit = {
+        .srcSubresource = imgSubResLayers,
+        .srcOffsets[1]  = {(int32_t)surf->width, (int32_t)surf->height, 1},
+        .dstSubresource = imgSubResLayers,
+        .dstOffsets[1]  = {(int32_t)surf->width, (int32_t)surf->height, 1},
+    };
+    vkCmdBlitImage(cmd, vkh_image_get_vkimage(surf->img), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                   vkh_image_get_vkimage(stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST);
+
+    vkh_cmd_end(cmd);
+
+    _surface_submit_cmd(surf);
+
+    uint64_t stride      = vkh_image_get_stride(stagImg);
+    uint32_t dest_stride = surf->width * 4;
+
+    char *img = vkh_image_map(stagImg);
+    char *row = (char *)bitmap;
+    for (uint32_t y = 0; y < surf->height; y++) {
+        memcpy(row, img, dest_stride);
+        row += dest_stride;
+        img += stride;
+    }
+
+    vkh_image_unmap(stagImg);
+    vkh_image_destroy(stagImg);
+
+    UNLOCK_SURFACE(surf)
+
+    return VKVG_STATUS_SUCCESS;
 }
index ec0cc078743db5f4c668b66e912c4ab8bf2d94d5..f1bf9dd688ad7cd6a08d9cf5f6c81bae959fbac9 100644 (file)
 #include "vkh_image.h"
 #include "vkh_queue.h"
 
-void _explicit_ms_resolve (VkvgSurface surf){
-       LOCK_SURFACE (surf)
-
-       VkCommandBuffer cmd = surf->cmd;
-
-       vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
-       vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-       vkh_image_set_layout (cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
-
-       VkImageResolve re = {
-               .extent = {surf->width, surf->height,1},
-               .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1},
-               .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}
-       };
-
-       vkCmdResolveImage(cmd,
-                                         vkh_image_get_vkimage (surf->imgMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                         vkh_image_get_vkimage (surf->img) ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                         1,&re);
-       vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                                 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
-       vkh_cmd_end (cmd);
-
-       _surface_submit_cmd (surf);
-
-       UNLOCK_SURFACE (surf)
+void _explicit_ms_resolve(VkvgSurface surf) {
+    LOCK_SURFACE(surf)
+
+    VkCommandBuffer cmd = surf->cmd;
+
+    vkh_cmd_begin(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_image_set_layout(cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+    vkh_image_set_layout(cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
+                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_PIPELINE_STAGE_TRANSFER_BIT);
+
+    VkImageResolve re = {.extent         = {surf->width, surf->height, 1},
+                         .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
+                         .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}};
+
+    vkCmdResolveImage(cmd, vkh_image_get_vkimage(surf->imgMS), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                      vkh_image_get_vkimage(surf->img), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &re);
+    vkh_image_set_layout(cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+    vkh_cmd_end(cmd);
+
+    _surface_submit_cmd(surf);
+
+    UNLOCK_SURFACE(surf)
 }
 
-void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect)
-{
-       LOCK_SURFACE (surf)
+void _clear_surface(VkvgSurface surf, VkImageAspectFlags aspect) {
+    LOCK_SURFACE(surf)
 
-       VkCommandBuffer cmd = surf->cmd;
+    VkCommandBuffer cmd = surf->cmd;
 
-       vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+    vkh_cmd_begin(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
 
-       if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
-               VkClearColorValue cclr = {{0,0,0,0}};
-               VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1};
+    if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
+        VkClearColorValue       cclr  = {{0, 0, 0, 0}};
+        VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
 
-               VkhImage img = surf->imgMS;
-               if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT)
-                       img = surf->img;
+        VkhImage img = surf->imgMS;
+        if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT)
+            img = surf->img;
 
-               vkh_image_set_layout (cmd, img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+        vkh_image_set_layout(cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                             VK_PIPELINE_STAGE_TRANSFER_BIT);
 
-               vkCmdClearColorImage(cmd, vkh_image_get_vkimage (img),
-                                                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cclr, 1, &range);
+        vkCmdClearColorImage(cmd, vkh_image_get_vkimage(img), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cclr, 1, &range);
 
-               vkh_image_set_layout (cmd, img, VK_IMAGE_ASPECT_COLOR_BIT,
-                                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                                         VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
-       }
-       if (aspect & VK_IMAGE_ASPECT_STENCIL_BIT) {
-               VkClearDepthStencilValue clr = {0,0};
-               VkImageSubresourceRange range = {VK_IMAGE_ASPECT_STENCIL_BIT,0,1,0,1};
+        vkh_image_set_layout(cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+    }
+    if (aspect & VK_IMAGE_ASPECT_STENCIL_BIT) {
+        VkClearDepthStencilValue clr   = {0, 0};
+        VkImageSubresourceRange  range = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1};
 
-               vkh_image_set_layout (cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT,
-                                                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
+        vkh_image_set_layout(cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT,
+                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
 
-               vkCmdClearDepthStencilImage (cmd, vkh_image_get_vkimage (surf->stencil),
-                                                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,&clr,1,&range);
+        vkCmdClearDepthStencilImage(cmd, vkh_image_get_vkimage(surf->stencil), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                    &clr, 1, &range);
 
-               vkh_image_set_layout (cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT,
-                                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                                                         VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
-       }
-       vkh_cmd_end (cmd);
+        vkh_image_set_layout(cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+    }
+    vkh_cmd_end(cmd);
 
-       _surface_submit_cmd (surf);
+    _surface_submit_cmd(surf);
 
-       UNLOCK_SURFACE (surf)
+    UNLOCK_SURFACE(surf)
 }
 
-void _create_surface_main_image (VkvgSurface surf){
-       surf->img = vkh_image_create((VkhDevice)surf->dev,surf->format,surf->width,surf->height,surf->dev->supportedTiling,VKH_MEMORY_USAGE_GPU_ONLY,
-                                                                        VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
-       vkh_image_create_descriptor(surf->img, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_image_set_name(surf->img, "SURF main color");
-       vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->img), "SURF main color VIEW");
-       vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->img), "SURF main color SAMPLER");
+void _create_surface_main_image(VkvgSurface surf) {
+    surf->img = vkh_image_create((VkhDevice)surf->dev, surf->format, surf->width, surf->height,
+                                 surf->dev->supportedTiling, VKH_MEMORY_USAGE_GPU_ONLY,
+                                 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                                     VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
+    vkh_image_create_descriptor(surf->img, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST,
+                                VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                                VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_image_set_name(surf->img, "SURF main color");
+    vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->img),
+                               "SURF main color VIEW");
+    vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->img),
+                               "SURF main color SAMPLER");
 #endif
 }
-//create multisample color img if sample count > 1 and the stencil buffer multisampled or not
-void _create_surface_secondary_images (VkvgSurface surf) {
-       if (surf->dev->samples > VK_SAMPLE_COUNT_1_BIT){
-               surf->imgMS = vkh_image_ms_create((VkhDevice)surf->dev,surf->format,surf->dev->samples,surf->width,surf->height,VKH_MEMORY_USAGE_GPU_ONLY,
-                                                                                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
-               vkh_image_create_descriptor(surf->imgMS, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST,
-                                                                       VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-               vkh_image_set_name(surf->imgMS, "SURF MS color IMG");
-               vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->imgMS), "SURF MS color VIEW");
-               vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->imgMS), "SURF MS color SAMPLER");
+// create multisample color img if sample count > 1 and the stencil buffer multisampled or not
+void _create_surface_secondary_images(VkvgSurface surf) {
+    if (surf->dev->samples > VK_SAMPLE_COUNT_1_BIT) {
+        surf->imgMS = vkh_image_ms_create((VkhDevice)surf->dev, surf->format, surf->dev->samples, surf->width,
+                                          surf->height, VKH_MEMORY_USAGE_GPU_ONLY,
+                                          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
+                                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+        vkh_image_create_descriptor(surf->imgMS, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST,
+                                    VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                                    VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+        vkh_image_set_name(surf->imgMS, "SURF MS color IMG");
+        vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW,
+                                   (uint64_t)vkh_image_get_view(surf->imgMS), "SURF MS color VIEW");
+        vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER,
+                                   (uint64_t)vkh_image_get_sampler(surf->imgMS), "SURF MS color SAMPLER");
 #endif
-       }
-       surf->stencil = vkh_image_ms_create((VkhDevice)surf->dev,surf->dev->stencilFormat,surf->dev->samples,surf->width,surf->height,VKH_MEMORY_USAGE_GPU_ONLY,                                                                         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
-       vkh_image_create_descriptor(surf->stencil, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_STENCIL_BIT, VK_FILTER_NEAREST,
-                                                               VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_image_set_name(surf->stencil, "SURF stencil");
-       vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(surf->stencil), "SURF stencil VIEW");
-       vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER, (uint64_t)vkh_image_get_sampler(surf->stencil), "SURF stencil SAMPLER");
+    }
+    surf->stencil = vkh_image_ms_create((VkhDevice)surf->dev, surf->dev->stencilFormat, surf->dev->samples, surf->width,
+                                        surf->height, VKH_MEMORY_USAGE_GPU_ONLY,
+                                        VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
+                                            VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+    vkh_image_create_descriptor(surf->stencil, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_STENCIL_BIT, VK_FILTER_NEAREST,
+                                VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                                VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_image_set_name(surf->stencil, "SURF stencil");
+    vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_IMAGE_VIEW,
+                               (uint64_t)vkh_image_get_view(surf->stencil), "SURF stencil VIEW");
+    vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_SAMPLER,
+                               (uint64_t)vkh_image_get_sampler(surf->stencil), "SURF stencil SAMPLER");
 #endif
 }
-void _create_framebuffer (VkvgSurface surf) {
-       VkImageView attachments[] = {
-               vkh_image_get_view (surf->img),
-               vkh_image_get_view (surf->stencil),
-               vkh_image_get_view (surf->imgMS),
-       };
-       VkFramebufferCreateInfo frameBufferCreateInfo = { .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
-                                                                                                         .renderPass = surf->dev->renderPass,
-                                                                                                         .attachmentCount = 3,
-                                                                                                         .pAttachments = attachments,
-                                                                                                         .width = surf->width,
-                                                                                                         .height = surf->height,
-                                                                                                         .layers = 1 };
-       if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT)
-               frameBufferCreateInfo.attachmentCount = 2;
-       else if (surf->dev->deferredResolve) {
-               attachments[0] = attachments[2];
-               frameBufferCreateInfo.attachmentCount = 2;
-       }
-       VK_CHECK_RESULT(vkCreateFramebuffer(surf->dev->vkDev, &frameBufferCreateInfo, NULL, &surf->fb));
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_FRAMEBUFFER, (uint64_t)surf->fb, "SURF FB");
+void _create_framebuffer(VkvgSurface surf) {
+    VkImageView attachments[] = {
+        vkh_image_get_view(surf->img),
+        vkh_image_get_view(surf->stencil),
+        vkh_image_get_view(surf->imgMS),
+    };
+    VkFramebufferCreateInfo frameBufferCreateInfo = {.sType           = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+                                                     .renderPass      = surf->dev->renderPass,
+                                                     .attachmentCount = 3,
+                                                     .pAttachments    = attachments,
+                                                     .width           = surf->width,
+                                                     .height          = surf->height,
+                                                     .layers          = 1};
+    if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT)
+        frameBufferCreateInfo.attachmentCount = 2;
+    else if (surf->dev->deferredResolve) {
+        attachments[0]                        = attachments[2];
+        frameBufferCreateInfo.attachmentCount = 2;
+    }
+    VK_CHECK_RESULT(vkCreateFramebuffer(surf->dev->vkDev, &frameBufferCreateInfo, NULL, &surf->fb));
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_device_set_object_name((VkhDevice)surf->dev, VK_OBJECT_TYPE_FRAMEBUFFER, (uint64_t)surf->fb, "SURF FB");
 #endif
 }
-void _create_surface_images (VkvgSurface surf) {
+void _create_surface_images(VkvgSurface surf) {
 
-       _create_surface_main_image              (surf);
-       _create_surface_secondary_images(surf);
-       _create_framebuffer                             (surf);
+    _create_surface_main_image(surf);
+    _create_surface_secondary_images(surf);
+    _create_framebuffer(surf);
 
 #if defined(DEBUG) && defined(ENABLE_VALIDATION)
-       vkh_image_set_name(surf->img, "surfImg");
-       vkh_image_set_name(surf->imgMS, "surfImgMS");
-       vkh_image_set_name(surf->stencil, "surfStencil");
+    vkh_image_set_name(surf->img, "surfImg");
+    vkh_image_set_name(surf->imgMS, "surfImgMS");
+    vkh_image_set_name(surf->stencil, "surfStencil");
 #endif
 }
-VkvgSurface _create_surface (VkvgDevice dev, VkFormat format) {        
-       VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface));
-       if (!surf)
-               return (VkvgSurface)&_no_mem_status;
-
-       surf->references = 1;
-       if (dev->status != VKVG_STATUS_SUCCESS) {
-               surf->status = VKVG_STATUS_DEVICE_ERROR;
-               return surf;
-       }
-       surf->dev = dev;
-       surf->format = format;
-       if (dev->threadAware)
-               mtx_init (&surf->mutex, mtx_plain);
-       surf->cmdPool = vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
-       vkh_cmd_buffs_create((VkhDevice)dev, surf->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1, &surf->cmd);
+VkvgSurface _create_surface(VkvgDevice dev, VkFormat format) {
+    VkvgSurface surf = (vkvg_surface *)calloc(1, sizeof(vkvg_surface));
+    if (!surf)
+        return (VkvgSurface)&_no_mem_status;
+
+    surf->references = 1;
+    if (dev->status != VKVG_STATUS_SUCCESS) {
+        surf->status = VKVG_STATUS_DEVICE_ERROR;
+        return surf;
+    }
+    surf->dev    = dev;
+    surf->format = format;
+    if (dev->threadAware)
+        mtx_init(&surf->mutex, mtx_plain);
+    surf->cmdPool =
+        vkh_cmd_pool_create((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
+    vkh_cmd_buffs_create((VkhDevice)dev, surf->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1, &surf->cmd);
 
 #if VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       surf->timeline = vkh_timeline_create ((VkhDevice)dev, 0);
+    surf->timeline = vkh_timeline_create((VkhDevice)dev, 0);
 #else
-       surf->flushFence = vkh_fence_create ((VkhDevice)dev);
+    surf->flushFence = vkh_fence_create((VkhDevice)dev);
 #endif
 
 #if defined(DEBUG) && defined(VKVG_DBG_UTILS)
-       vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)surf->cmd, "vkvgSurfCmd");
+    vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)surf->cmd, "vkvgSurfCmd");
 #endif
 
-       return surf;
+    return surf;
 }
-//if fence sync, surf mutex must be locked.
+// if fence sync, surf mutex must be locked.
 /*bool _surface_wait_cmd (VkvgSurface surf) {
-       LOG(VKVG_LOG_INFO, "SURF: _surface__wait_flush_fence\n");
+    LOG(VKVG_LOG_INFO, "SURF: _surface__wait_flush_fence\n");
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       if (vkh_timeline_wait ((VkhDevice)surf->dev, surf->timeline, surf->timelineStep) == VK_SUCCESS)
-               return true;
+    if (vkh_timeline_wait ((VkhDevice)surf->dev, surf->timeline, surf->timelineStep) == VK_SUCCESS)
+        return true;
 #else
-       if (WaitForFences (surf->dev->vkDev, 1, &surf->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS) {
-               ResetFences (surf->dev->vkDev, 1, &surf->flushFence);
-               return true;
-       }
+    if (WaitForFences (surf->dev->vkDev, 1, &surf->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS) {
+        ResetFences (surf->dev->vkDev, 1, &surf->flushFence);
+        return true;
+    }
 #endif
-       LOG(VKVG_LOG_DEBUG, "CTX: _wait_flush_fence timeout\n");
-       surf->status = VKVG_STATUS_TIMEOUT;
-       return false;
+    LOG(VKVG_LOG_DEBUG, "CTX: _wait_flush_fence timeout\n");
+    surf->status = VKVG_STATUS_TIMEOUT;
+    return false;
 }*/
-//surface mutex must be locked to call this method, locking to guard also the surf->cmd local buffer usage.
-void _surface_submit_cmd (VkvgSurface surf) {
-       VkvgDevice dev = surf->dev;
+// surface mutex must be locked to call this method, locking to guard also the surf->cmd local buffer usage.
+void _surface_submit_cmd(VkvgSurface surf) {
+    VkvgDevice dev = surf->dev;
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       LOCK_DEVICE
-       vkh_cmd_submit_timelined (dev->gQueue, &surf->cmd, surf->timeline, surf->timelineStep, surf->timelineStep+1);
-       surf->timelineStep++;
-       UNLOCK_DEVICE
-       vkh_timeline_wait ((VkhDevice)dev, surf->timeline, surf->timelineStep);
+    LOCK_DEVICE
+    vkh_cmd_submit_timelined(dev->gQueue, &surf->cmd, surf->timeline, surf->timelineStep, surf->timelineStep + 1);
+    surf->timelineStep++;
+    UNLOCK_DEVICE
+    vkh_timeline_wait((VkhDevice)dev, surf->timeline, surf->timelineStep);
 #else
-       LOCK_DEVICE
-       vkh_cmd_submit (surf->dev->gQueue, &surf->cmd, surf->flushFence);
-       UNLOCK_DEVICE
-       WaitForFences (surf->dev->vkDev, 1, &surf->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT);
-       ResetFences (surf->dev->vkDev, 1, &surf->flushFence);
+    LOCK_DEVICE
+    vkh_cmd_submit(surf->dev->gQueue, &surf->cmd, surf->flushFence);
+    UNLOCK_DEVICE
+    WaitForFences(surf->dev->vkDev, 1, &surf->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT);
+    ResetFences(surf->dev->vkDev, 1, &surf->flushFence);
 #endif
 }
index 5cc47c670445d324940c5ad61f8574a3dee09a9a..085ce77b198766bb8e76aa9bfdd298b45f44e569 100644 (file)
 #include "vkh.h"
 
 typedef struct _vkvg_surface_t {
-       vkvg_status_t   status;                                 /**< Current status of surface, affected by last operation */
-       uint32_t                references;
-       VkvgDevice              dev;
-       uint32_t                width;
-       uint32_t                height;
-       VkFormat                format;
-       VkFramebuffer   fb;
-       VkhImage                img;
-       VkhImage                imgMS;
-       VkhImage                stencil;
-       VkCommandPool   cmdPool;                                //local pools ensure thread safety
-       VkCommandBuffer cmd;                                    //surface local command buffer.
-       bool                    newSurf;
-       mtx_t                   mutex;
+    vkvg_status_t   status; /**< Current status of surface, affected by last operation */
+    uint32_t        references;
+    VkvgDevice      dev;
+    uint32_t        width;
+    uint32_t        height;
+    VkFormat        format;
+    VkFramebuffer   fb;
+    VkhImage        img;
+    VkhImage        imgMS;
+    VkhImage        stencil;
+    VkCommandPool   cmdPool; // local pools ensure thread safety
+    VkCommandBuffer cmd;     // surface local command buffer.
+    bool            newSurf;
+    mtx_t           mutex;
 #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
-       VkSemaphore             timeline;                               /**< Timeline semaphore */
-       uint64_t                timelineStep;
+    VkSemaphore timeline; /**< Timeline semaphore */
+    uint64_t    timelineStep;
 #else
-       VkFence                 flushFence;                             //unsignaled idle.
+    VkFence flushFence; // unsignaled idle.
 #endif
 
-}vkvg_surface;
+} vkvg_surface;
 
-#define LOCK_SURFACE(surf) \
-       if (surf->dev->threadAware)\
-               mtx_lock (&surf->mutex);
-#define UNLOCK_SURFACE(surf) \
-       if (surf->dev->threadAware)\
-               mtx_unlock (&surf->mutex);
+#define LOCK_SURFACE(surf)                                                                                             \
+    if (surf->dev->threadAware)                                                                                        \
+        mtx_lock(&surf->mutex);
+#define UNLOCK_SURFACE(surf)                                                                                           \
+    if (surf->dev->threadAware)                                                                                        \
+        mtx_unlock(&surf->mutex);
 
-void _explicit_ms_resolve (VkvgSurface surf);
-void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect);
-void _create_surface_main_image (VkvgSurface surf);
-void _create_surface_secondary_images (VkvgSurface surf);
-void _create_framebuffer (VkvgSurface surf);
-void _create_surface_images (VkvgSurface surf);
-VkvgSurface _create_surface (VkvgDevice dev, VkFormat format);
+void        _explicit_ms_resolve(VkvgSurface surf);
+void        _clear_surface(VkvgSurface surf, VkImageAspectFlags aspect);
+void        _create_surface_main_image(VkvgSurface surf);
+void        _create_surface_secondary_images(VkvgSurface surf);
+void        _create_framebuffer(VkvgSurface surf);
+void        _create_surface_images(VkvgSurface surf);
+VkvgSurface _create_surface(VkvgDevice dev, VkFormat format);
 
-void _surface_submit_cmd (VkvgSurface surf);
-//bool _surface_wait_cmd (VkvgSurface surf);
+void _surface_submit_cmd(VkvgSurface surf);
+// bool _surface_wait_cmd (VkvgSurface surf);
 #endif
index 333fcdfabd331684556a56f536b07ef3e1f4cb91..6ac3390572cae85bfd6542628edb7bd61afbea8d 100644 (file)
@@ -4,13 +4,13 @@
 
 #include "test.h"
 
-void test_name(){
-       VkvgContext ctx = vkvg_create(surf);
+void test_name() {
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       PERFORM_TEST (test_name, argc, argv);
-       return 0;
+    PERFORM_TEST(test_name, argc, argv);
+    return 0;
 }
index cfeb131e664c520300906a14a119081f262da277..e711b41a766dca9b69ea23f5244e42b605b6a5ae 100644 (file)
@@ -1,92 +1,92 @@
 #include "test.h"
 
-void draw_growing_circles (VkvgContext ctx, float y, int count) {
-       float x = 2;
-       for (int i=1; i<count; i++) {
-               x += 0.5f*i;
-               //vkvg_set_source_rgb   (ctx, 1,0,1);
-               vkvg_arc(ctx, x + 2, y, 0.5f * i, 0, M_PIF*1.5f);
-               //vkvg_set_source_rgb   (ctx, 0,1,1);
-               //vkvg_arc_negative(ctx, x + 2, y, 0.5 * i, M_PI/2,0);
-               x += 0.5f*i + 5;
-       }
+void draw_growing_circles(VkvgContext ctx, float y, int count) {
+    float x = 2;
+    for (int i = 1; i < count; i++) {
+        x += 0.5f * i;
+        // vkvg_set_source_rgb   (ctx, 1,0,1);
+        vkvg_arc(ctx, x + 2, y, 0.5f * i, 0, M_PIF * 1.5f);
+        // vkvg_set_source_rgb   (ctx, 0,1,1);
+        // vkvg_arc_negative(ctx, x + 2, y, 0.5 * i, M_PI/2,0);
+        x += 0.5f * i + 5;
+    }
 }
 
 void scaled_up() {
-       VkvgContext ctx = vkvg_create(surf);
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_set_source_rgb   (ctx, 1,1,1);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgb   (ctx, 0,0,0);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 0, 0, 0);
 
-       vkvg_scale(ctx,10,10);
-       vkvg_arc(ctx, 20, 20, 2.0f, 0, M_PIF/2.f);
-       vkvg_stroke(ctx);
+    vkvg_scale(ctx, 10, 10);
+    vkvg_arc(ctx, 20, 20, 2.0f, 0, M_PIF / 2.f);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 void sizes() {
-       VkvgContext ctx = vkvg_create(surf);
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_set_source_rgb   (ctx, 1,1,1);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgb   (ctx, 0,0,0);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 0, 0, 0);
 
-       draw_growing_circles (ctx, 100, 40);
-       vkvg_stroke(ctx);
+    draw_growing_circles(ctx, 100, 40);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
-
-       vkvg_set_source_rgb   (ctx, 1,1,1);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgb   (ctx, 0,0,0);
-
-       vkvg_set_source_rgb   (ctx, 1,0,1);
-       vkvg_set_line_width(ctx, 5.0);
-       vkvg_arc(ctx, 100, 100, 20, 0, M_PIF/2);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgb   (ctx, 0,1,1);
-       vkvg_arc_negative(ctx, 100, 100, 20, 0, M_PIF/2);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgb   (ctx, 1,0,1);
-       vkvg_arc(ctx, 100, 200, 20, M_PIF/2, 0);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgb   (ctx, 0,1,1);
-       vkvg_arc_negative(ctx, 100, 200, 20, M_PIF/2, 0);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgb   (ctx, 0,0,1);
-       vkvg_set_line_width(ctx, 10.0);
-       vkvg_arc(ctx, 350, 100, 40, 0, M_PIF*2);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgb   (ctx, 0,1,0);
-       vkvg_set_line_width(ctx, 1.0);
-       vkvg_arc(ctx, 150, 100, 3.5, 0, M_PIF*2);
-       vkvg_stroke(ctx);
-       vkvg_arc(ctx, 200, 200, 10, 0, M_PIF*2);
-       vkvg_fill(ctx);
-
-       vkvg_set_source_rgb   (ctx, 1,0,0);
-       vkvg_scale(ctx,3,3);
-       vkvg_arc(ctx, 150, 100, 3.5, 0, M_PIF*2);
-       vkvg_stroke(ctx);
-       vkvg_arc(ctx, 200, 200, 10, 0, M_PIF*2);
-       vkvg_fill(ctx);
-
-       vkvg_destroy(ctx);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
+
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 0, 0, 0);
+
+    vkvg_set_source_rgb(ctx, 1, 0, 1);
+    vkvg_set_line_width(ctx, 5.0);
+    vkvg_arc(ctx, 100, 100, 20, 0, M_PIF / 2);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgb(ctx, 0, 1, 1);
+    vkvg_arc_negative(ctx, 100, 100, 20, 0, M_PIF / 2);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgb(ctx, 1, 0, 1);
+    vkvg_arc(ctx, 100, 200, 20, M_PIF / 2, 0);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgb(ctx, 0, 1, 1);
+    vkvg_arc_negative(ctx, 100, 200, 20, M_PIF / 2, 0);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgb(ctx, 0, 0, 1);
+    vkvg_set_line_width(ctx, 10.0);
+    vkvg_arc(ctx, 350, 100, 40, 0, M_PIF * 2);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_set_line_width(ctx, 1.0);
+    vkvg_arc(ctx, 150, 100, 3.5, 0, M_PIF * 2);
+    vkvg_stroke(ctx);
+    vkvg_arc(ctx, 200, 200, 10, 0, M_PIF * 2);
+    vkvg_fill(ctx);
+
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_scale(ctx, 3, 3);
+    vkvg_arc(ctx, 150, 100, 3.5, 0, M_PIF * 2);
+    vkvg_stroke(ctx);
+    vkvg_arc(ctx, 200, 200, 10, 0, M_PIF * 2);
+    vkvg_fill(ctx);
+
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (sizes, argc, argv);
-       PERFORM_TEST (scaled_up, argc, argv);
-       PERFORM_TEST (test, argc, argv);        
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(sizes, argc, argv);
+    PERFORM_TEST(scaled_up, argc, argv);
+    PERFORM_TEST(test, argc, argv);
+    return 0;
 }
index 0ac57d3198e9207d29e98ae0091570d1e2ddca31..a504722147bf8bf2647b9d753dc7ad0d15a1767f 100644 (file)
 #include "test.h"
 #include "vectors.h"
 
-vkvg_fill_rule_t fillrule = VKVG_FILL_RULE_NON_ZERO;
-static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT;
-float lineWidth = 10.0f;
-vkvg_line_join_t lineJoin = VKVG_LINE_JOIN_MITER;
-vkvg_line_cap_t lineCap = VKVG_LINE_CAP_BUTT;
-bool isClosed = false, isFilled = false;
-
-int ptsCount = 4;
-int initPtsCount = 4;
-vec2 pts[] = {
-       {150,150},
-       {500,340},
-       {470,150},
-       {160,350},
+vkvg_fill_rule_t          fillrule  = VKVG_FILL_RULE_NON_ZERO;
+static VkSampleCountFlags samples   = VK_SAMPLE_COUNT_8_BIT;
+float                     lineWidth = 10.0f;
+vkvg_line_join_t          lineJoin  = VKVG_LINE_JOIN_MITER;
+vkvg_line_cap_t           lineCap   = VKVG_LINE_CAP_BUTT;
+bool                      isClosed = false, isFilled = false;
+
+int  ptsCount     = 4;
+int  initPtsCount = 4;
+vec2 pts[]        = {
+    {150, 150},
+    {500, 340},
+    {470, 150},
+    {160, 350},
 };
 /*vec2 pts[] = {
-       {150,150},
-       {250,150},
-       {100,150},
-       {150,200},
+    {150,150},
+    {250,150},
+    {100,150},
+    {150,200},
 };*/
-int hoverPt = -1;
-double hoverPointSize = 7,
-               pointSize = 5;
+int    hoverPt        = -1;
+double hoverPointSize = 7, pointSize = 5;
 
 #ifdef VKVG_WIRED_DEBUG
 vkvg_wired_debug_mode _wired_debug = vkvg_wired_debug_mode_normal;
 #endif
 
-void draw (){
+void draw() {
 
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
 #ifdef VKVG_WIRED_DEBUG
-       vkvg_wired_debug = _wired_debug;
+    vkvg_wired_debug = _wired_debug;
 #endif
 
-       vkvg_set_line_width (ctx,lineWidth);
-       vkvg_set_line_join      (ctx, lineJoin);
-       vkvg_set_line_cap       (ctx, lineCap);
+    vkvg_set_line_width(ctx, lineWidth);
+    vkvg_set_line_join(ctx, lineJoin);
+    vkvg_set_line_cap(ctx, lineCap);
 
-       vkvg_move_to(ctx,pts[0].x,pts[0].y);
-       vkvg_curve_to(ctx, pts[1].x,pts[1].y, pts[2].x,pts[2].y, pts[3].x,pts[3].y);
+    vkvg_move_to(ctx, pts[0].x, pts[0].y);
+    vkvg_curve_to(ctx, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
 
-       if (isClosed)
-               vkvg_close_path(ctx);
+    if (isClosed)
+        vkvg_close_path(ctx);
 
-       if (isFilled) {
-               vkvg_set_source_rgba(ctx,0.4,0.6,0.4,1);
-               vkvg_fill_preserve (ctx);
-       }
+    if (isFilled) {
+        vkvg_set_source_rgba(ctx, 0.4, 0.6, 0.4, 1);
+        vkvg_fill_preserve(ctx);
+    }
 
-       vkvg_set_source_rgba(ctx,1,0,0,0.3f);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 0.3f);
 
-       vkvg_stroke (ctx);
-       vkvg_flush (ctx);
+    vkvg_stroke(ctx);
+    vkvg_flush(ctx);
 
 #ifdef VKVG_WIRED_DEBUG
-       vkvg_wired_debug = vkvg_wired_debug_mode_normal;
+    vkvg_wired_debug = vkvg_wired_debug_mode_normal;
 #endif
 
-       vkvg_set_line_width(ctx, 1);
-       vkvg_set_source_rgba(ctx,0.5,0.5,0.5,0.6);
-       for (int i=0; i<ptsCount; i++) {
-
-               if (i == hoverPt) {
-                       vkvg_arc (ctx, pts[i].x, pts[i].y, hoverPointSize, 0, M_PIF*2);
-                       vkvg_set_source_rgba (ctx, 0.5, 0.5, 1.0, 0.6);
-                       vkvg_fill_preserve (ctx);
-                       vkvg_set_source_rgba (ctx, 0.5 ,0.5 ,0.5 ,0.6);
-               } else {
-                       vkvg_arc (ctx, pts[i].x, pts[i].y, pointSize, 0, M_PIF*2);
-                       vkvg_fill_preserve (ctx);
-               }
-               vkvg_stroke (ctx);
-
-
-       }
-
-       if (hoverPt>=0) {
-               vkvg_stroke_preserve(ctx);
-               vkvg_set_dash(ctx, NULL, 0, 0);
-               vkvg_set_line_width(ctx,2);
-               vkvg_set_source_rgba(ctx,0,0,0,1);
-               vkvg_stroke(ctx);
-               vkvg_set_source_rgba(ctx,0.5f,0.5f,1.0f,0.7f);
-               vkvg_arc (ctx, pts[hoverPt].x, pts[hoverPt].y, pointSize, 0, M_PIF*2);
-               vkvg_fill_preserve(ctx);
-               vkvg_stroke(ctx);
-       } else
-               vkvg_stroke(ctx);
-
-       //draw_v(ctx, 200, 20, VKVG_LINE_JOIN_BEVEL);
-       //draw_v(ctx, 300, 80, VKVG_LINE_JOIN_ROUND);
-       vkvg_destroy(ctx);
+    vkvg_set_line_width(ctx, 1);
+    vkvg_set_source_rgba(ctx, 0.5, 0.5, 0.5, 0.6);
+    for (int i = 0; i < ptsCount; i++) {
+
+        if (i == hoverPt) {
+            vkvg_arc(ctx, pts[i].x, pts[i].y, hoverPointSize, 0, M_PIF * 2);
+            vkvg_set_source_rgba(ctx, 0.5, 0.5, 1.0, 0.6);
+            vkvg_fill_preserve(ctx);
+            vkvg_set_source_rgba(ctx, 0.5, 0.5, 0.5, 0.6);
+        } else {
+            vkvg_arc(ctx, pts[i].x, pts[i].y, pointSize, 0, M_PIF * 2);
+            vkvg_fill_preserve(ctx);
+        }
+        vkvg_stroke(ctx);
+    }
+
+    if (hoverPt >= 0) {
+        vkvg_stroke_preserve(ctx);
+        vkvg_set_dash(ctx, NULL, 0, 0);
+        vkvg_set_line_width(ctx, 2);
+        vkvg_set_source_rgba(ctx, 0, 0, 0, 1);
+        vkvg_stroke(ctx);
+        vkvg_set_source_rgba(ctx, 0.5f, 0.5f, 1.0f, 0.7f);
+        vkvg_arc(ctx, pts[hoverPt].x, pts[hoverPt].y, pointSize, 0, M_PIF * 2);
+        vkvg_fill_preserve(ctx);
+        vkvg_stroke(ctx);
+    } else
+        vkvg_stroke(ctx);
+
+    // draw_v(ctx, 200, 20, VKVG_LINE_JOIN_BEVEL);
+    // draw_v(ctx, 300, 80, VKVG_LINE_JOIN_ROUND);
+    vkvg_destroy(ctx);
 }
-static void key_callback(GLFWwindowwindow, int key, int scancode, int action, int mods) {
-       if (action == GLFW_RELEASE)
-               return;
-       switch (key) {
-       case GLFW_KEY_ESCAPE :
-               glfwSetWindowShouldClose(window, GLFW_TRUE);
-               break;
-       case GLFW_KEY_W :
-               isClosed ^= true;
-               break;
-       case GLFW_KEY_F :
-               isFilled ^= true;
-               break;
-       case GLFW_KEY_J :
-               lineJoin++;
-               if (lineJoin > 2)
-                       lineJoin = 0;
-               break;
-       case GLFW_KEY_C :
-               lineCap++;
-               if (lineCap > 2)
-                       lineCap = 0;
-               break;
-       case GLFW_KEY_KP_ADD :
-               lineWidth++;
-               break;
-       case GLFW_KEY_KP_SUBTRACT :
-               if (lineWidth > 1)
-                       lineWidth--;
-               break;
+static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
+    if (action == GLFW_RELEASE)
+        return;
+    switch (key) {
+    case GLFW_KEY_ESCAPE:
+        glfwSetWindowShouldClose(window, GLFW_TRUE);
+        break;
+    case GLFW_KEY_W:
+        isClosed ^= true;
+        break;
+    case GLFW_KEY_F:
+        isFilled ^= true;
+        break;
+    case GLFW_KEY_J:
+        lineJoin++;
+        if (lineJoin > 2)
+            lineJoin = 0;
+        break;
+    case GLFW_KEY_C:
+        lineCap++;
+        if (lineCap > 2)
+            lineCap = 0;
+        break;
+    case GLFW_KEY_KP_ADD:
+        lineWidth++;
+        break;
+    case GLFW_KEY_KP_SUBTRACT:
+        if (lineWidth > 1)
+            lineWidth--;
+        break;
 #ifdef VKVG_WIRED_DEBUG
-       case GLFW_KEY_F1:
-               _wired_debug ^= (1U << 0);
-               break;
-       case GLFW_KEY_F2:
-               _wired_debug ^= (1U << 1);
-               break;
-       case GLFW_KEY_F3:
-               _wired_debug ^= (1U << 2);
-               break;
+    case GLFW_KEY_F1:
+        _wired_debug ^= (1U << 0);
+        break;
+    case GLFW_KEY_F2:
+        _wired_debug ^= (1U << 1);
+        break;
+    case GLFW_KEY_F3:
+        _wired_debug ^= (1U << 2);
+        break;
 #endif
-       }
+    }
 }
-static void mouse_move_callback(GLFWwindow* window, double x, double y){
-       if (mouseDown) {
-               if (hoverPt < 0)
-                       return;
-               pts[hoverPt].x = x;
-               pts[hoverPt].y = y;
-       } else {
-               for (int i=0; i<ptsCount; i++) {
-                       if (x > pts[i].x - hoverPointSize &&
-                               x < pts[i].x + hoverPointSize &&
-                               y > pts[i].y - hoverPointSize &&
-                               y < pts[i].y + hoverPointSize) {
-                               hoverPt = i;
-                               return;
-                       }
-               }
-               hoverPt = -1;
-       }
+static void mouse_move_callback(GLFWwindow *window, double x, double y) {
+    if (mouseDown) {
+        if (hoverPt < 0)
+            return;
+        pts[hoverPt].x = x;
+        pts[hoverPt].y = y;
+    } else {
+        for (int i = 0; i < ptsCount; i++) {
+            if (x > pts[i].x - hoverPointSize && x < pts[i].x + hoverPointSize && y > pts[i].y - hoverPointSize &&
+                y < pts[i].y + hoverPointSize) {
+                hoverPt = i;
+                return;
+            }
+        }
+        hoverPt = -1;
+    }
 }
-static void scroll_callback(GLFWwindow* window, double x, double y){
-       if (y<0.f)
-               zoom *= 0.5f;
-       else
-               zoom *= 2.0f;
+static void scroll_callback(GLFWwindow *window, double x, double y) {
+    if (y < 0.f)
+        zoom *= 0.5f;
+    else
+        zoom *= 2.0f;
 }
-static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){
-       if (but != GLFW_MOUSE_BUTTON_1)
-               return;
-       if (state == GLFW_TRUE)
-               mouseDown = true;
-       else
-               mouseDown = false;
+static void mouse_button_callback(GLFWwindow *window, int but, int state, int modif) {
+    if (but != GLFW_MOUSE_BUTTON_1)
+        return;
+    if (state == GLFW_TRUE)
+        mouseDown = true;
+    else
+        mouseDown = false;
 }
 
+int main(int argc, char *argv[]) {
 
+    _parse_args(argc, argv);
+    VkEngine e;
+    e = vkengine_create(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
 
-int main(int argc, char* argv[]) {
+    VkhPresenter r = e->renderer;
+    vkengine_set_key_callback(e, key_callback);
+    vkengine_set_mouse_but_callback(e, mouse_button_callback);
+    vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+    vkengine_set_scroll_callback(e, scroll_callback);
 
-       _parse_args (argc, argv);
-       VkEngine e;
-       e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
+    vkvg_device_create_info_t info = {samples, false, vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0};
+    device                         = vkvg_device_create(&info);
 
-       VkhPresenter r = e->renderer;
-       vkengine_set_key_callback (e, key_callback);
-       vkengine_set_mouse_but_callback(e, mouse_button_callback);
-       vkengine_set_cursor_pos_callback(e, mouse_move_callback);
-       vkengine_set_scroll_callback(e, scroll_callback);
+    surf = vkvg_surface_create(device, test_width, test_height);
 
-    vkvg_device_create_info_t info = {
-        samples,
-        false,
-        vkh_app_get_inst(e->app),
-        r->dev->phy,
-        r->dev->dev,
-        r->qFam,
-        0
-    };
-    device = vkvg_device_create(&info);
+    vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
 
-       surf = vkvg_surface_create(device, test_width, test_height);
+    while (!vkengine_should_close(e)) {
+        glfwPollEvents();
 
-       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+        draw();
 
-       while (!vkengine_should_close (e)) {
-               glfwPollEvents();
+        if (!vkh_presenter_draw(r)) {
+            vkh_presenter_get_size(r, &test_width, &test_height);
+            vkvg_surface_destroy(surf);
+            surf = vkvg_surface_create(device, test_width, test_height);
+            vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+            vkDeviceWaitIdle(r->dev->dev);
+            continue;
+        }
+    }
+    vkDeviceWaitIdle(e->dev->dev);
 
-               draw ();
+    vkvg_surface_destroy(surf);
 
-               if (!vkh_presenter_draw (r)){
-                       vkh_presenter_get_size (r, &test_width, &test_height);
-                       vkvg_surface_destroy (surf);
-                       surf = vkvg_surface_create(device, test_width, test_height);
-                       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
-                       vkDeviceWaitIdle(r->dev->dev);
-                       continue;
-               }
-       }
-       vkDeviceWaitIdle(e->dev->dev);
+    vkvg_device_destroy(device);
 
-       vkvg_surface_destroy    (surf);
+    vkengine_destroy(e);
 
-       vkvg_device_destroy     (device);
-
-       vkengine_destroy (e);
-
-       return 0;
+    return 0;
 }
index 3a34d818329d61940a43efa7bf0c5cdbe27237d4..e8f88bac1a14e15a06cd6deebb7125737a16afa1 100644 (file)
@@ -1,63 +1,63 @@
 #include "test.h"
 
-void draw_growing_circles (VkvgContext ctx, float y, int count) {
-       float x = 2;
-       for (int i=1; i<count; i++) {
-               x += 0.5f*i;
-               vkvg_arc(ctx, x + 2, y, 0.5f * i, 0, M_PIF*2.f);
-               x += 0.5f*i + 5;
-       }
+void draw_growing_circles(VkvgContext ctx, float y, int count) {
+    float x = 2;
+    for (int i = 1; i < count; i++) {
+        x += 0.5f * i;
+        vkvg_arc(ctx, x + 2, y, 0.5f * i, 0, M_PIF * 2.f);
+        x += 0.5f * i + 5;
+    }
 }
 
 void scaled_up() {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
-       vkvg_set_source_rgb   (ctx, 1,1,1);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
 
-       vkvg_scale(ctx,100,100);
-       vkvg_arc(ctx, 2, 2, 0.5f, 0, M_PIF*2);
-       vkvg_stroke(ctx);
+    vkvg_scale(ctx, 100, 100);
+    vkvg_arc(ctx, 2, 2, 0.5f, 0, M_PIF * 2);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
-void fill_and_stroke () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-       vkvg_set_source_rgba   (ctx, 0,0.1f,0.8f, 0.5f);
-       vkvg_set_line_width(ctx,10);
+void fill_and_stroke() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    vkvg_set_source_rgba(ctx, 0, 0.1f, 0.8f, 0.5f);
+    vkvg_set_line_width(ctx, 10);
 
-       vkvg_arc(ctx, 300, 300, 150.f, 0, M_PIF*2);
-       vkvg_fill_preserve(ctx);
-       vkvg_stroke(ctx);
+    vkvg_arc(ctx, 300, 300, 150.f, 0, M_PIF * 2);
+    vkvg_fill_preserve(ctx);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 void sizes() {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
-       vkvg_set_source_rgb   (ctx, 1,1,1);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
 
-       draw_growing_circles (ctx, 100, 40);
-       vkvg_fill (ctx);
+    draw_growing_circles(ctx, 100, 40);
+    vkvg_fill(ctx);
 
-       draw_growing_circles (ctx, 200, 40);
-       vkvg_stroke(ctx);
+    draw_growing_circles(ctx, 200, 40);
+    vkvg_stroke(ctx);
 
-       vkvg_set_source_rgba  (ctx, 0,0,1,0.4F);
-       draw_growing_circles (ctx, 300, 40);
-       vkvg_fill_preserve (ctx);
-       vkvg_set_line_width(ctx,5);
-       vkvg_stroke(ctx);
+    vkvg_set_source_rgba(ctx, 0, 0, 1, 0.4F);
+    draw_growing_circles(ctx, 300, 40);
+    vkvg_fill_preserve(ctx);
+    vkvg_set_line_width(ctx, 5);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (fill_and_stroke, argc, argv);
-       PERFORM_TEST (sizes, argc, argv);
-       PERFORM_TEST (scaled_up, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(fill_and_stroke, argc, argv);
+    PERFORM_TEST(sizes, argc, argv);
+    PERFORM_TEST(scaled_up, argc, argv);
+    return 0;
 }
index e5c03a0a4682236d10e19a42f56d86f795339c23..5ae80266a75d388fa70ace888ec66c9dd25d2ef7 100644 (file)
 #include "test.h"
 
-void clipped_paint_ec () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_rectangle(ctx, 100,100,300,200);
-       vkvg_clip(ctx);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+void clipped_paint_ec() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_clip(ctx);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
-void clipped_paint_eo () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_rectangle(ctx, 100,100,300,200);
-       vkvg_clip(ctx);
-       vkvg_paint(ctx);
-
-       vkvg_destroy(ctx);
+void clipped_paint_eo() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_clip(ctx);
+    vkvg_paint(ctx);
+
+    vkvg_destroy(ctx);
 }
-void clipped_paint2_ec () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_rectangle(ctx, 100,100,300,200);
-       vkvg_clip(ctx);
-       vkvg_paint(ctx);
-
-       vkvg_reset_clip(ctx);
-       vkvg_rectangle(ctx, 200,200,300,200);
-       vkvg_set_source_rgb(ctx,0,0,1);
-       vkvg_paint(ctx);
-
-       vkvg_destroy(ctx);
+void clipped_paint2_ec() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_clip(ctx);
+    vkvg_paint(ctx);
+
+    vkvg_reset_clip(ctx);
+    vkvg_rectangle(ctx, 200, 200, 300, 200);
+    vkvg_set_source_rgb(ctx, 0, 0, 1);
+    vkvg_paint(ctx);
+
+    vkvg_destroy(ctx);
 }
-void clipped_paint2_eo () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_rectangle(ctx, 100,100,300,200);
-       vkvg_clip(ctx);
-       vkvg_paint(ctx);
-       vkvg_reset_clip(ctx);
-       vkvg_rectangle(ctx, 200,200,300,200);
-       vkvg_set_source_rgb(ctx,0,0,1);
-       vkvg_paint(ctx);
-
-       vkvg_destroy(ctx);
+void clipped_paint2_eo() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_clip(ctx);
+    vkvg_paint(ctx);
+    vkvg_reset_clip(ctx);
+    vkvg_rectangle(ctx, 200, 200, 300, 200);
+    vkvg_set_source_rgb(ctx, 0, 0, 1);
+    vkvg_paint(ctx);
+
+    vkvg_destroy(ctx);
 }
-void clipped_transformed_ec () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-       vkvg_rotate(ctx,0.2f);
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_rectangle(ctx, 100,100,300,200);
-       vkvg_clip(ctx);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+void clipped_transformed_ec() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_rotate(ctx, 0.2f);
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_clip(ctx);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
-void clip_transformed_ec () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-       vkvg_rotate(ctx,0.1f);
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_rectangle(ctx, 100,100,300,200);
-       vkvg_clip(ctx);
-       vkvg_paint(ctx);
-       vkvg_translate (ctx,200,100);
-       vkvg_set_source_rgb(ctx,0,0,1);
-       vkvg_paint(ctx);
-
-       vkvg_destroy(ctx);
+void clip_transformed_ec() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_rotate(ctx, 0.1f);
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_clip(ctx);
+    vkvg_paint(ctx);
+    vkvg_translate(ctx, 200, 100);
+    vkvg_set_source_rgb(ctx, 0, 0, 1);
+    vkvg_paint(ctx);
+
+    vkvg_destroy(ctx);
 }
-void clipped_transformed_eo () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-       vkvg_rotate(ctx,0.2f);
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_rectangle(ctx, 100,100,300,200);
-       vkvg_clip(ctx);
-       vkvg_paint(ctx);
-
-       vkvg_destroy(ctx);
+void clipped_transformed_eo() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_rotate(ctx, 0.2f);
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_clip(ctx);
+    vkvg_paint(ctx);
+
+    vkvg_destroy(ctx);
 }
 
-void test_clip(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_move_to(ctx,10,10);
-       vkvg_line_to(ctx,400,150);
-       vkvg_line_to(ctx,900,10);
-       vkvg_line_to(ctx,700,450);
-       vkvg_line_to(ctx,900,750);
-       vkvg_line_to(ctx,500,650);
-       vkvg_line_to(ctx,100,800);
-       vkvg_line_to(ctx,150,400);
-       vkvg_clip_preserve(ctx);
-       vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR);
-       vkvg_fill_preserve(ctx);
-       vkvg_clip(ctx);
-       vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);
-
-       vkvg_set_source_rgb(ctx,1,0,0);
-       //vkvg_set_line_width(ctx,10);
-       //vkvg_stroke(ctx);
-       vkvg_paint(ctx);
-
-       vkvg_destroy(ctx);
+void test_clip() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_move_to(ctx, 10, 10);
+    vkvg_line_to(ctx, 400, 150);
+    vkvg_line_to(ctx, 900, 10);
+    vkvg_line_to(ctx, 700, 450);
+    vkvg_line_to(ctx, 900, 750);
+    vkvg_line_to(ctx, 500, 650);
+    vkvg_line_to(ctx, 100, 800);
+    vkvg_line_to(ctx, 150, 400);
+    vkvg_clip_preserve(ctx);
+    vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR);
+    vkvg_fill_preserve(ctx);
+    vkvg_clip(ctx);
+    vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);
+
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    // vkvg_set_line_width(ctx,10);
+    // vkvg_stroke(ctx);
+    vkvg_paint(ctx);
+
+    vkvg_destroy(ctx);
 }
-void test_clip2(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
-       vkvg_rectangle(ctx, 50,50,500,500);
-       vkvg_clip(ctx);
-
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-
-       vkvg_save(ctx);
-       vkvg_rectangle(ctx, 100,100,350,350);
-       vkvg_clip(ctx);
-       vkvg_save(ctx);
-
-       vkvg_set_source_rgb(ctx,1,1,0);
-       vkvg_paint(ctx);
-
-       vkvg_rectangle(ctx, 200,200,200,200);
-       vkvg_clip(ctx);
-
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_paint(ctx);
-
-       vkvg_restore(ctx);
-
-       vkvg_rectangle(ctx, 350,350,420,420);
-       vkvg_set_source_rgb(ctx,0,0,1);
-       vkvg_fill(ctx);
-
-       vkvg_restore(ctx);
-
-       //vkvg_clip(ctx);
-       //
-       /*vkvg_clip_preserve(ctx);
-       vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR);
-       vkvg_fill_preserve(ctx);*/
-       //vkvg_clip(ctx);
-       //vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);
-       /*vkvg_rectangle(ctx, 200,200,220,220);
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);*/
-
-
-
-
-       vkvg_destroy(ctx);
+void test_clip2() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
+    vkvg_rectangle(ctx, 50, 50, 500, 500);
+    vkvg_clip(ctx);
+
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+
+    vkvg_save(ctx);
+    vkvg_rectangle(ctx, 100, 100, 350, 350);
+    vkvg_clip(ctx);
+    vkvg_save(ctx);
+
+    vkvg_set_source_rgb(ctx, 1, 1, 0);
+    vkvg_paint(ctx);
+
+    vkvg_rectangle(ctx, 200, 200, 200, 200);
+    vkvg_clip(ctx);
+
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_paint(ctx);
+
+    vkvg_restore(ctx);
+
+    vkvg_rectangle(ctx, 350, 350, 420, 420);
+    vkvg_set_source_rgb(ctx, 0, 0, 1);
+    vkvg_fill(ctx);
+
+    vkvg_restore(ctx);
+
+    // vkvg_clip(ctx);
+    //
+    /*vkvg_clip_preserve(ctx);
+    vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR);
+    vkvg_fill_preserve(ctx);*/
+    // vkvg_clip(ctx);
+    // vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);
+    /*vkvg_rectangle(ctx, 200,200,220,220);
+    vkvg_set_source_rgb(ctx,1,0,0);
+    vkvg_paint(ctx);*/
+
+    vkvg_destroy(ctx);
 }
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (clip_transformed_ec, argc, argv);
-       PERFORM_TEST (clipped_paint_ec, argc, argv);
-       PERFORM_TEST (clipped_paint_eo, argc, argv);
-       PERFORM_TEST (clipped_transformed_ec, argc, argv);
-       PERFORM_TEST (clipped_transformed_eo, argc, argv);
-       PERFORM_TEST (clipped_paint2_ec, argc, argv);
-       PERFORM_TEST (clipped_paint2_eo, argc, argv);
-       PERFORM_TEST (test_clip, argc, argv);
-       PERFORM_TEST (test_clip2, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(clip_transformed_ec, argc, argv);
+    PERFORM_TEST(clipped_paint_ec, argc, argv);
+    PERFORM_TEST(clipped_paint_eo, argc, argv);
+    PERFORM_TEST(clipped_transformed_ec, argc, argv);
+    PERFORM_TEST(clipped_transformed_eo, argc, argv);
+    PERFORM_TEST(clipped_paint2_ec, argc, argv);
+    PERFORM_TEST(clipped_paint2_eo, argc, argv);
+    PERFORM_TEST(test_clip, argc, argv);
+    PERFORM_TEST(test_clip2, argc, argv);
+    return 0;
 }
index 9e7d32e4edcc1420a3726b1616d4d72fc6047a0f..4a569d936219314c86bf2f1f5658f132df4b35e7 100644 (file)
@@ -1,25 +1,25 @@
 #include "test.h"
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_set_source_rgba(ctx,0.7f,0.7f,0.7f,1);
-       vkvg_paint(ctx);
+    vkvg_set_source_rgba(ctx, 0.7f, 0.7f, 0.7f, 1);
+    vkvg_paint(ctx);
 
-       vkvg_set_source_rgba(ctx,0,1,0,1);
-       vkvg_set_line_width(ctx,10);
+    vkvg_set_source_rgba(ctx, 0, 1, 0, 1);
+    vkvg_set_line_width(ctx, 10);
 
-       vkvg_move_to(ctx,100,100);
-       vkvg_line_to(ctx,100,200);
-       vkvg_line_to(ctx,100,300);
-       vkvg_stroke(ctx);
+    vkvg_move_to(ctx, 100, 100);
+    vkvg_line_to(ctx, 100, 200);
+    vkvg_line_to(ctx, 100, 300);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
 
-       return 0;
+    return 0;
 }
index 65ba2a7965c5a81abbbd0a61c8996ff954f1d2ff..3f50d45cc56dcc3cacd663b794c31dd86b45fe19 100644 (file)
@@ -50,125 +50,104 @@ extern "C" {
 //
 // If you don't know or care about the units stuff, "px" and 96 should get you going.
 
-
 /* Example Usage:
-       // Load
-       NSVGImage* image;
-       image = nsvgParseFromFile("test.svg", "px", 96);
-       printf("size: %f x %f\n", image->width, image->height);
-       // Use...
-       for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
-               for (NSVGpath *path = shape->paths; path != NULL; path = path->next) {
-                       for (int i = 0; i < path->npts-1; i += 3) {
-                               float* p = &path->pts[i*2];
-                               drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]);
-                       }
-               }
-       }
-       // Delete
-       nsvgDelete(image);
+    // Load
+    NSVGImage* image;
+    image = nsvgParseFromFile("test.svg", "px", 96);
+    printf("size: %f x %f\n", image->width, image->height);
+    // Use...
+    for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
+        for (NSVGpath *path = shape->paths; path != NULL; path = path->next) {
+            for (int i = 0; i < path->npts-1; i += 3) {
+                float* p = &path->pts[i*2];
+                drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]);
+            }
+        }
+    }
+    // Delete
+    nsvgDelete(image);
 */
 
 enum NSVGpaintType {
-       NSVG_PAINT_NONE = 0,
-       NSVG_PAINT_COLOR = 1,
-       NSVG_PAINT_LINEAR_GRADIENT = 2,
-       NSVG_PAINT_RADIAL_GRADIENT = 3
+    NSVG_PAINT_NONE            = 0,
+    NSVG_PAINT_COLOR           = 1,
+    NSVG_PAINT_LINEAR_GRADIENT = 2,
+    NSVG_PAINT_RADIAL_GRADIENT = 3
 };
 
-enum NSVGspreadType {
-       NSVG_SPREAD_PAD = 0,
-       NSVG_SPREAD_REFLECT = 1,
-       NSVG_SPREAD_REPEAT = 2
-};
+enum NSVGspreadType { NSVG_SPREAD_PAD = 0, NSVG_SPREAD_REFLECT = 1, NSVG_SPREAD_REPEAT = 2 };
 
-enum NSVGlineJoin {
-       NSVG_JOIN_MITER = 0,
-       NSVG_JOIN_ROUND = 1,
-       NSVG_JOIN_BEVEL = 2
-};
+enum NSVGlineJoin { NSVG_JOIN_MITER = 0, NSVG_JOIN_ROUND = 1, NSVG_JOIN_BEVEL = 2 };
 
-enum NSVGlineCap {
-       NSVG_CAP_BUTT = 0,
-       NSVG_CAP_ROUND = 1,
-       NSVG_CAP_SQUARE = 2
-};
+enum NSVGlineCap { NSVG_CAP_BUTT = 0, NSVG_CAP_ROUND = 1, NSVG_CAP_SQUARE = 2 };
 
-enum NSVGfillRule {
-       NSVG_FILLRULE_NONZERO = 0,
-       NSVG_FILLRULE_EVENODD = 1
-};
+enum NSVGfillRule { NSVG_FILLRULE_NONZERO = 0, NSVG_FILLRULE_EVENODD = 1 };
 
-enum NSVGflags {
-       NSVG_FLAGS_VISIBLE = 0x01
-};
+enum NSVGflags { NSVG_FLAGS_VISIBLE = 0x01 };
 
 typedef struct NSVGgradientStop {
-       unsigned int color;
-       float offset;
+    unsigned int color;
+    float        offset;
 } NSVGgradientStop;
 
 typedef struct NSVGgradient {
-       float xform[6];
-       char spread;
-       float fx, fy;
-       int nstops;
-       NSVGgradientStop stops[1];
+    float            xform[6];
+    char             spread;
+    float            fx, fy;
+    int              nstops;
+    NSVGgradientStop stops[1];
 } NSVGgradient;
 
 typedef struct NSVGpaint {
-       char type;
-       union {
-               unsigned int color;
-               NSVGgradient* gradient;
-       };
+    char type;
+    union {
+        unsigned int  color;
+        NSVGgradient *gradient;
+    };
 } NSVGpaint;
 
-typedef struct NSVGpath
-{
-       float* pts;                                     // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ...
-       int npts;                                       // Total number of bezier points.
-       char closed;                            // Flag indicating if shapes should be treated as closed.
-       float bounds[4];                        // Tight bounding box of the shape [minx,miny,maxx,maxy].
-       struct NSVGpath* next;          // Pointer to next path, or NULL if last element.
+typedef struct NSVGpath {
+    float           *pts;       // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ...
+    int              npts;      // Total number of bezier points.
+    char             closed;    // Flag indicating if shapes should be treated as closed.
+    float            bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy].
+    struct NSVGpath *next;      // Pointer to next path, or NULL if last element.
 } NSVGpath;
 
-typedef struct NSVGshape
-{
-       char id[64];                            // Optional 'id' attr of the shape or its group
-       NSVGpaint fill;                         // Fill paint
-       NSVGpaint stroke;                       // Stroke paint
-       float opacity;                          // Opacity of the shape.
-       float strokeWidth;                      // Stroke width (scaled).
-       float strokeDashOffset;         // Stroke dash offset (scaled).
-       float strokeDashArray[8];                       // Stroke dash array (scaled).
-       char strokeDashCount;                           // Number of dash values in dash array.
-       char strokeLineJoin;            // Stroke join type.
-       char strokeLineCap;                     // Stroke cap type.
-       float miterLimit;                       // Miter limit
-       char fillRule;                          // Fill rule, see NSVGfillRule.
-       unsigned char flags;            // Logical or of NSVG_FLAGS_* flags
-       float bounds[4];                        // Tight bounding box of the shape [minx,miny,maxx,maxy].
-       NSVGpath* paths;                        // Linked list of paths in the image.
-       struct NSVGshape* next;         // Pointer to next shape, or NULL if last element.
+typedef struct NSVGshape {
+    char              id[64];             // Optional 'id' attr of the shape or its group
+    NSVGpaint         fill;               // Fill paint
+    NSVGpaint         stroke;             // Stroke paint
+    float             opacity;            // Opacity of the shape.
+    float             strokeWidth;        // Stroke width (scaled).
+    float             strokeDashOffset;   // Stroke dash offset (scaled).
+    float             strokeDashArray[8]; // Stroke dash array (scaled).
+    char              strokeDashCount;    // Number of dash values in dash array.
+    char              strokeLineJoin;     // Stroke join type.
+    char              strokeLineCap;      // Stroke cap type.
+    float             miterLimit;         // Miter limit
+    char              fillRule;           // Fill rule, see NSVGfillRule.
+    unsigned char     flags;              // Logical or of NSVG_FLAGS_* flags
+    float             bounds[4];          // Tight bounding box of the shape [minx,miny,maxx,maxy].
+    NSVGpath         *paths;              // Linked list of paths in the image.
+    struct NSVGshape *next;               // Pointer to next shape, or NULL if last element.
 } NSVGshape;
 
-typedef struct NSVGimage
-{
-       float width;                            // Width of the image.
-       float height;                           // Height of the image.
-       NSVGshape* shapes;                      // Linked list of shapes in the image.
+typedef struct NSVGimage {
+    float      width;  // Width of the image.
+    float      height; // Height of the image.
+    NSVGshape *shapes; // Linked list of shapes in the image.
 } NSVGimage;
 
 // Parses SVG file from a file, returns SVG image as paths.
-NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi);
+NSVGimage *nsvgParseFromFile(const char *filename, const char *units, float dpi);
 
 // Parses SVG file from a null terminated string, returns SVG image as paths.
 // Important note: changes the string.
-NSVGimage* nsvgParse(char* input, const char* units, float dpi);
+NSVGimage *nsvgParse(char *input, const char *units, float dpi);
 
 // Deletes list of paths.
-void nsvgDelete(NSVGimageimage);
+void nsvgDelete(NSVGimage *image);
 
 #ifdef __cplusplus
 }
@@ -182,2744 +161,2747 @@ void nsvgDelete(NSVGimage* image);
 #include <stdlib.h>
 #include <math.h>
 
-#define NSVG_PI (3.14159265358979323846264338327f)
-#define NSVG_KAPPA90 (0.5522847493f)   // Length proportional to radius of a cubic bezier handle for 90deg arcs.
+#define NSVG_PI          (3.14159265358979323846264338327f)
+#define NSVG_KAPPA90     (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs.
 
-#define NSVG_ALIGN_MIN 0
-#define NSVG_ALIGN_MID 1
-#define NSVG_ALIGN_MAX 2
-#define NSVG_ALIGN_NONE 0
-#define NSVG_ALIGN_MEET 1
+#define NSVG_ALIGN_MIN   0
+#define NSVG_ALIGN_MID   1
+#define NSVG_ALIGN_MAX   2
+#define NSVG_ALIGN_NONE  0
+#define NSVG_ALIGN_MEET  1
 #define NSVG_ALIGN_SLICE 2
 
-#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
+#define NSVG_NOTUSED(v)                                                                                                \
+    do {                                                                                                               \
+        (void)(1 ? (void)0 : ((void)(v)));                                                                             \
+    } while (0)
 #define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))
 
 #ifdef _MSC_VER
-       #pragma warning (disable: 4996) // Switch off security warnings
-       #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
-       #ifdef __cplusplus
-       #define NSVG_INLINE inline
-       #else
-       #define NSVG_INLINE
-       #endif
+#pragma warning(disable : 4996) // Switch off security warnings
+#pragma warning(disable : 4100) // Switch off unreferenced formal parameter warnings
+#ifdef __cplusplus
+#define NSVG_INLINE inline
 #else
-       #define NSVG_INLINE inline
+#define NSVG_INLINE
+#endif
+#else
+#define NSVG_INLINE inline
 #endif
 
+static int nsvg__isspace(char c) { return strchr(" \t\n\v\f\r", c) != 0; }
 
-static int nsvg__isspace(char c)
-{
-       return strchr(" \t\n\v\f\r", c) != 0;
-}
+static int nsvg__isdigit(char c) { return c >= '0' && c <= '9'; }
 
-static int nsvg__isdigit(char c)
-{
-       return c >= '0' && c <= '9';
-}
-
-static int nsvg__isnum(char c)
-{
-       return strchr("0123456789+-.eE", c) != 0;
-}
+static int nsvg__isnum(char c) { return strchr("0123456789+-.eE", c) != 0; }
 
 static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
 static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }
 
-
 // Simple XML parser
 
-#define NSVG_XML_TAG 1
-#define NSVG_XML_CONTENT 2
+#define NSVG_XML_TAG         1
+#define NSVG_XML_CONTENT     2
 #define NSVG_XML_MAX_ATTRIBS 256
 
-static void nsvg__parseContent(char* s,
-                                                          void (*contentCb)(void* ud, const char* s),
-                                                          void* ud)
-{
-       // Trim start white spaces
-       while (*s && nsvg__isspace(*s)) s++;
-       if (!*s) return;
-
-       if (contentCb)
-               (*contentCb)(ud, s);
-}
-
-static void nsvg__parseElement(char* s,
-                                                          void (*startelCb)(void* ud, const char* el, const char** attr),
-                                                          void (*endelCb)(void* ud, const char* el),
-                                                          void* ud)
-{
-       const char* attr[NSVG_XML_MAX_ATTRIBS];
-       int nattr = 0;
-       char* name;
-       int start = 0;
-       int end = 0;
-       char quote;
-
-       // Skip white space after the '<'
-       while (*s && nsvg__isspace(*s)) s++;
-
-       // Check if the tag is end tag
-       if (*s == '/') {
-               s++;
-               end = 1;
-       } else {
-               start = 1;
-       }
-
-       // Skip comments, data and preprocessor stuff.
-       if (!*s || *s == '?' || *s == '!')
-               return;
-
-       // Get tag name
-       name = s;
-       while (*s && !nsvg__isspace(*s)) s++;
-       if (*s) { *s++ = '\0'; }
-
-       // Get attribs
-       while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) {
-               char* name = NULL;
-               char* value = NULL;
-
-               // Skip white space before the attrib name
-               while (*s && nsvg__isspace(*s)) s++;
-               if (!*s) break;
-               if (*s == '/') {
-                       end = 1;
-                       break;
-               }
-               name = s;
-               // Find end of the attrib name.
-               while (*s && !nsvg__isspace(*s) && *s != '=') s++;
-               if (*s) { *s++ = '\0'; }
-               // Skip until the beginning of the value.
-               while (*s && *s != '\"' && *s != '\'') s++;
-               if (!*s) break;
-               quote = *s;
-               s++;
-               // Store value and find the end of it.
-               value = s;
-               while (*s && *s != quote) s++;
-               if (*s) { *s++ = '\0'; }
-
-               // Store only well formed attributes
-               if (name && value) {
-                       attr[nattr++] = name;
-                       attr[nattr++] = value;
-               }
-       }
-
-       // List terminator
-       attr[nattr++] = 0;
-       attr[nattr++] = 0;
-
-       // Call callbacks.
-       if (start && startelCb)
-               (*startelCb)(ud, name, attr);
-       if (end && endelCb)
-               (*endelCb)(ud, name);
-}
-
-int nsvg__parseXML(char* input,
-                                  void (*startelCb)(void* ud, const char* el, const char** attr),
-                                  void (*endelCb)(void* ud, const char* el),
-                                  void (*contentCb)(void* ud, const char* s),
-                                  void* ud)
-{
-       char* s = input;
-       char* mark = s;
-       int state = NSVG_XML_CONTENT;
-       while (*s) {
-               if (*s == '<' && state == NSVG_XML_CONTENT) {
-                       // Start of a tag
-                       *s++ = '\0';
-                       nsvg__parseContent(mark, contentCb, ud);
-                       mark = s;
-                       state = NSVG_XML_TAG;
-               } else if (*s == '>' && state == NSVG_XML_TAG) {
-                       // Start of a content or new tag.
-                       *s++ = '\0';
-                       nsvg__parseElement(mark, startelCb, endelCb, ud);
-                       mark = s;
-                       state = NSVG_XML_CONTENT;
-               } else {
-                       s++;
-               }
-       }
-
-       return 1;
+static void nsvg__parseContent(char *s, void (*contentCb)(void *ud, const char *s), void *ud) {
+    // Trim start white spaces
+    while (*s && nsvg__isspace(*s))
+        s++;
+    if (!*s)
+        return;
+
+    if (contentCb)
+        (*contentCb)(ud, s);
+}
+
+static void nsvg__parseElement(char *s, void (*startelCb)(void *ud, const char *el, const char **attr),
+                               void (*endelCb)(void *ud, const char *el), void *ud) {
+    const char *attr[NSVG_XML_MAX_ATTRIBS];
+    int         nattr = 0;
+    char       *name;
+    int         start = 0;
+    int         end   = 0;
+    char        quote;
+
+    // Skip white space after the '<'
+    while (*s && nsvg__isspace(*s))
+        s++;
+
+    // Check if the tag is end tag
+    if (*s == '/') {
+        s++;
+        end = 1;
+    } else {
+        start = 1;
+    }
+
+    // Skip comments, data and preprocessor stuff.
+    if (!*s || *s == '?' || *s == '!')
+        return;
+
+    // Get tag name
+    name = s;
+    while (*s && !nsvg__isspace(*s))
+        s++;
+    if (*s) {
+        *s++ = '\0';
+    }
+
+    // Get attribs
+    while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS - 3) {
+        char *name  = NULL;
+        char *value = NULL;
+
+        // Skip white space before the attrib name
+        while (*s && nsvg__isspace(*s))
+            s++;
+        if (!*s)
+            break;
+        if (*s == '/') {
+            end = 1;
+            break;
+        }
+        name = s;
+        // Find end of the attrib name.
+        while (*s && !nsvg__isspace(*s) && *s != '=')
+            s++;
+        if (*s) {
+            *s++ = '\0';
+        }
+        // Skip until the beginning of the value.
+        while (*s && *s != '\"' && *s != '\'')
+            s++;
+        if (!*s)
+            break;
+        quote = *s;
+        s++;
+        // Store value and find the end of it.
+        value = s;
+        while (*s && *s != quote)
+            s++;
+        if (*s) {
+            *s++ = '\0';
+        }
+
+        // Store only well formed attributes
+        if (name && value) {
+            attr[nattr++] = name;
+            attr[nattr++] = value;
+        }
+    }
+
+    // List terminator
+    attr[nattr++] = 0;
+    attr[nattr++] = 0;
+
+    // Call callbacks.
+    if (start && startelCb)
+        (*startelCb)(ud, name, attr);
+    if (end && endelCb)
+        (*endelCb)(ud, name);
+}
+
+int nsvg__parseXML(char *input, void (*startelCb)(void *ud, const char *el, const char **attr),
+                   void (*endelCb)(void *ud, const char *el), void (*contentCb)(void *ud, const char *s), void *ud) {
+    char *s     = input;
+    char *mark  = s;
+    int   state = NSVG_XML_CONTENT;
+    while (*s) {
+        if (*s == '<' && state == NSVG_XML_CONTENT) {
+            // Start of a tag
+            *s++ = '\0';
+            nsvg__parseContent(mark, contentCb, ud);
+            mark  = s;
+            state = NSVG_XML_TAG;
+        } else if (*s == '>' && state == NSVG_XML_TAG) {
+            // Start of a content or new tag.
+            *s++ = '\0';
+            nsvg__parseElement(mark, startelCb, endelCb, ud);
+            mark  = s;
+            state = NSVG_XML_CONTENT;
+        } else {
+            s++;
+        }
+    }
+
+    return 1;
 }
 
-
 /* Simple SVG parser. */
 
 #define NSVG_MAX_ATTR 128
 
-enum NSVGgradientUnits {
-       NSVG_USER_SPACE = 0,
-       NSVG_OBJECT_SPACE = 1
-};
+enum NSVGgradientUnits { NSVG_USER_SPACE = 0, NSVG_OBJECT_SPACE = 1 };
 
 #define NSVG_MAX_DASHES 8
 
 enum NSVGunits {
-       NSVG_UNITS_USER,
-       NSVG_UNITS_PX,
-       NSVG_UNITS_PT,
-       NSVG_UNITS_PC,
-       NSVG_UNITS_MM,
-       NSVG_UNITS_CM,
-       NSVG_UNITS_IN,
-       NSVG_UNITS_PERCENT,
-       NSVG_UNITS_EM,
-       NSVG_UNITS_EX
+    NSVG_UNITS_USER,
+    NSVG_UNITS_PX,
+    NSVG_UNITS_PT,
+    NSVG_UNITS_PC,
+    NSVG_UNITS_MM,
+    NSVG_UNITS_CM,
+    NSVG_UNITS_IN,
+    NSVG_UNITS_PERCENT,
+    NSVG_UNITS_EM,
+    NSVG_UNITS_EX
 };
 
 typedef struct NSVGcoordinate {
-       float value;
-       int units;
+    float value;
+    int   units;
 } NSVGcoordinate;
 
 typedef struct NSVGlinearData {
-       NSVGcoordinate x1, y1, x2, y2;
+    NSVGcoordinate x1, y1, x2, y2;
 } NSVGlinearData;
 
 typedef struct NSVGradialData {
-       NSVGcoordinate cx, cy, r, fx, fy;
+    NSVGcoordinate cx, cy, r, fx, fy;
 } NSVGradialData;
 
-typedef struct NSVGgradientData
-{
-       char id[64];
-       char ref[64];
-       char type;
-       union {
-               NSVGlinearData linear;
-               NSVGradialData radial;
-       };
-       char spread;
-       char units;
-       float xform[6];
-       int nstops;
-       NSVGgradientStop* stops;
-       struct NSVGgradientData* next;
+typedef struct NSVGgradientData {
+    char id[64];
+    char ref[64];
+    char type;
+    union {
+        NSVGlinearData linear;
+        NSVGradialData radial;
+    };
+    char                     spread;
+    char                     units;
+    float                    xform[6];
+    int                      nstops;
+    NSVGgradientStop        *stops;
+    struct NSVGgradientData *next;
 } NSVGgradientData;
 
-typedef struct NSVGattrib
-{
-       char id[64];
-       float xform[6];
-       unsigned int fillColor;
-       unsigned int strokeColor;
-       float opacity;
-       float fillOpacity;
-       float strokeOpacity;
-       char fillGradient[64];
-       char strokeGradient[64];
-       float strokeWidth;
-       float strokeDashOffset;
-       float strokeDashArray[NSVG_MAX_DASHES];
-       int strokeDashCount;
-       char strokeLineJoin;
-       char strokeLineCap;
-       float miterLimit;
-       char fillRule;
-       float fontSize;
-       unsigned int stopColor;
-       float stopOpacity;
-       float stopOffset;
-       char hasFill;
-       char hasStroke;
-       char visible;
+typedef struct NSVGattrib {
+    char         id[64];
+    float        xform[6];
+    unsigned int fillColor;
+    unsigned int strokeColor;
+    float        opacity;
+    float        fillOpacity;
+    float        strokeOpacity;
+    char         fillGradient[64];
+    char         strokeGradient[64];
+    float        strokeWidth;
+    float        strokeDashOffset;
+    float        strokeDashArray[NSVG_MAX_DASHES];
+    int          strokeDashCount;
+    char         strokeLineJoin;
+    char         strokeLineCap;
+    float        miterLimit;
+    char         fillRule;
+    float        fontSize;
+    unsigned int stopColor;
+    float        stopOpacity;
+    float        stopOffset;
+    char         hasFill;
+    char         hasStroke;
+    char         visible;
 } NSVGattrib;
 
-typedef struct NSVGparser
-{
-       NSVGattrib attr[NSVG_MAX_ATTR];
-       int attrHead;
-       float* pts;
-       int npts;
-       int cpts;
-       NSVGpath* plist;
-       NSVGimage* image;
-       NSVGgradientData* gradients;
-       NSVGshape* shapesTail;
-       float viewMinx, viewMiny, viewWidth, viewHeight;
-       int alignX, alignY, alignType;
-       float dpi;
-       char pathFlag;
-       char defsFlag;
+typedef struct NSVGparser {
+    NSVGattrib        attr[NSVG_MAX_ATTR];
+    int               attrHead;
+    float            *pts;
+    int               npts;
+    int               cpts;
+    NSVGpath         *plist;
+    NSVGimage        *image;
+    NSVGgradientData *gradients;
+    NSVGshape        *shapesTail;
+    float             viewMinx, viewMiny, viewWidth, viewHeight;
+    int               alignX, alignY, alignType;
+    float             dpi;
+    char              pathFlag;
+    char              defsFlag;
 } NSVGparser;
 
-static void nsvg__xformIdentity(float* t)
-{
-       t[0] = 1.0f; t[1] = 0.0f;
-       t[2] = 0.0f; t[3] = 1.0f;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformSetTranslation(float* t, float tx, float ty)
-{
-       t[0] = 1.0f; t[1] = 0.0f;
-       t[2] = 0.0f; t[3] = 1.0f;
-       t[4] = tx; t[5] = ty;
-}
-
-static void nsvg__xformSetScale(float* t, float sx, float sy)
-{
-       t[0] = sx; t[1] = 0.0f;
-       t[2] = 0.0f; t[3] = sy;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformSetSkewX(float* t, float a)
-{
-       t[0] = 1.0f; t[1] = 0.0f;
-       t[2] = tanf(a); t[3] = 1.0f;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformSetSkewY(float* t, float a)
-{
-       t[0] = 1.0f; t[1] = tanf(a);
-       t[2] = 0.0f; t[3] = 1.0f;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformSetRotation(float* t, float a)
-{
-       float cs = cosf(a), sn = sinf(a);
-       t[0] = cs; t[1] = sn;
-       t[2] = -sn; t[3] = cs;
-       t[4] = 0.0f; t[5] = 0.0f;
-}
-
-static void nsvg__xformMultiply(float* t, float* s)
-{
-       float t0 = t[0] * s[0] + t[1] * s[2];
-       float t2 = t[2] * s[0] + t[3] * s[2];
-       float t4 = t[4] * s[0] + t[5] * s[2] + s[4];
-       t[1] = t[0] * s[1] + t[1] * s[3];
-       t[3] = t[2] * s[1] + t[3] * s[3];
-       t[5] = t[4] * s[1] + t[5] * s[3] + s[5];
-       t[0] = t0;
-       t[2] = t2;
-       t[4] = t4;
-}
-
-static void nsvg__xformInverse(float* inv, float* t)
-{
-       double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1];
-       if (det > -1e-6 && det < 1e-6) {
-               nsvg__xformIdentity(t);
-               return;
-       }
-       invdet = 1.0 / det;
-       inv[0] = (float)(t[3] * invdet);
-       inv[2] = (float)(-t[2] * invdet);
-       inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet);
-       inv[1] = (float)(-t[1] * invdet);
-       inv[3] = (float)(t[0] * invdet);
-       inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet);
-}
-
-static void nsvg__xformPremultiply(float* t, float* s)
-{
-       float s2[6];
-       memcpy(s2, s, sizeof(float)*6);
-       nsvg__xformMultiply(s2, t);
-       memcpy(t, s2, sizeof(float)*6);
-}
-
-static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t)
-{
-       *dx = x*t[0] + y*t[2] + t[4];
-       *dy = x*t[1] + y*t[3] + t[5];
-}
-
-static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t)
-{
-       *dx = x*t[0] + y*t[2];
-       *dy = x*t[1] + y*t[3];
+static void nsvg__xformIdentity(float *t) {
+    t[0] = 1.0f;
+    t[1] = 0.0f;
+    t[2] = 0.0f;
+    t[3] = 1.0f;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformSetTranslation(float *t, float tx, float ty) {
+    t[0] = 1.0f;
+    t[1] = 0.0f;
+    t[2] = 0.0f;
+    t[3] = 1.0f;
+    t[4] = tx;
+    t[5] = ty;
+}
+
+static void nsvg__xformSetScale(float *t, float sx, float sy) {
+    t[0] = sx;
+    t[1] = 0.0f;
+    t[2] = 0.0f;
+    t[3] = sy;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformSetSkewX(float *t, float a) {
+    t[0] = 1.0f;
+    t[1] = 0.0f;
+    t[2] = tanf(a);
+    t[3] = 1.0f;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformSetSkewY(float *t, float a) {
+    t[0] = 1.0f;
+    t[1] = tanf(a);
+    t[2] = 0.0f;
+    t[3] = 1.0f;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformSetRotation(float *t, float a) {
+    float cs = cosf(a), sn = sinf(a);
+    t[0] = cs;
+    t[1] = sn;
+    t[2] = -sn;
+    t[3] = cs;
+    t[4] = 0.0f;
+    t[5] = 0.0f;
+}
+
+static void nsvg__xformMultiply(float *t, float *s) {
+    float t0 = t[0] * s[0] + t[1] * s[2];
+    float t2 = t[2] * s[0] + t[3] * s[2];
+    float t4 = t[4] * s[0] + t[5] * s[2] + s[4];
+    t[1]     = t[0] * s[1] + t[1] * s[3];
+    t[3]     = t[2] * s[1] + t[3] * s[3];
+    t[5]     = t[4] * s[1] + t[5] * s[3] + s[5];
+    t[0]     = t0;
+    t[2]     = t2;
+    t[4]     = t4;
+}
+
+static void nsvg__xformInverse(float *inv, float *t) {
+    double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1];
+    if (det > -1e-6 && det < 1e-6) {
+        nsvg__xformIdentity(t);
+        return;
+    }
+    invdet = 1.0 / det;
+    inv[0] = (float)(t[3] * invdet);
+    inv[2] = (float)(-t[2] * invdet);
+    inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet);
+    inv[1] = (float)(-t[1] * invdet);
+    inv[3] = (float)(t[0] * invdet);
+    inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet);
+}
+
+static void nsvg__xformPremultiply(float *t, float *s) {
+    float s2[6];
+    memcpy(s2, s, sizeof(float) * 6);
+    nsvg__xformMultiply(s2, t);
+    memcpy(t, s2, sizeof(float) * 6);
+}
+
+static void nsvg__xformPoint(float *dx, float *dy, float x, float y, float *t) {
+    *dx = x * t[0] + y * t[2] + t[4];
+    *dy = x * t[1] + y * t[3] + t[5];
+}
+
+static void nsvg__xformVec(float *dx, float *dy, float x, float y, float *t) {
+    *dx = x * t[0] + y * t[2];
+    *dy = x * t[1] + y * t[3];
 }
 
 #define NSVG_EPSILON (1e-12)
 
-static int nsvg__ptInBounds(float* pt, float* bounds)
-{
-       return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3];
-}
-
-
-static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3)
-{
-       double it = 1.0-t;
-       return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3;
-}
-
-static void nsvg__curveBounds(float* bounds, float* curve)
-{
-       int i, j, count;
-       double roots[2], a, b, c, b2ac, t, v;
-       float* v0 = &curve[0];
-       float* v1 = &curve[2];
-       float* v2 = &curve[4];
-       float* v3 = &curve[6];
-
-       // Start the bounding box by end points
-       bounds[0] = nsvg__minf(v0[0], v3[0]);
-       bounds[1] = nsvg__minf(v0[1], v3[1]);
-       bounds[2] = nsvg__maxf(v0[0], v3[0]);
-       bounds[3] = nsvg__maxf(v0[1], v3[1]);
-
-       // Bezier curve fits inside the convex hull of it's control points.
-       // If control points are inside the bounds, we're done.
-       if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
-               return;
-
-       // Add bezier curve inflection points in X and Y.
-       for (i = 0; i < 2; i++) {
-               a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
-               b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
-               c = 3.0 * v1[i] - 3.0 * v0[i];
-               count = 0;
-               if (fabs(a) < NSVG_EPSILON) {
-                       if (fabs(b) > NSVG_EPSILON) {
-                               t = -c / b;
-                               if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
-                                       roots[count++] = t;
-                       }
-               } else {
-                       b2ac = b*b - 4.0*c*a;
-                       if (b2ac > NSVG_EPSILON) {
-                               t = (-b + sqrt(b2ac)) / (2.0 * a);
-                               if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
-                                       roots[count++] = t;
-                               t = (-b - sqrt(b2ac)) / (2.0 * a);
-                               if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
-                                       roots[count++] = t;
-                       }
-               }
-               for (j = 0; j < count; j++) {
-                       v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]);
-                       bounds[0+i] = nsvg__minf(bounds[0+i], (float)v);
-                       bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v);
-               }
-       }
-}
-
-static NSVGparser* nsvg__createParser()
-{
-       NSVGparser* p;
-       p = (NSVGparser*)malloc(sizeof(NSVGparser));
-       if (p == NULL) goto error;
-       memset(p, 0, sizeof(NSVGparser));
-
-       p->image = (NSVGimage*)malloc(sizeof(NSVGimage));
-       if (p->image == NULL) goto error;
-       memset(p->image, 0, sizeof(NSVGimage));
-
-       // Init style
-       nsvg__xformIdentity(p->attr[0].xform);
-       memset(p->attr[0].id, 0, sizeof p->attr[0].id);
-       p->attr[0].fillColor = NSVG_RGB(0,0,0);
-       p->attr[0].strokeColor = NSVG_RGB(0,0,0);
-       p->attr[0].opacity = 1;
-       p->attr[0].fillOpacity = 1;
-       p->attr[0].strokeOpacity = 1;
-       p->attr[0].stopOpacity = 1;
-       p->attr[0].strokeWidth = 1;
-       p->attr[0].strokeLineJoin = NSVG_JOIN_MITER;
-       p->attr[0].strokeLineCap = NSVG_CAP_BUTT;
-       p->attr[0].miterLimit = 4;
-       p->attr[0].fillRule = NSVG_FILLRULE_NONZERO;
-       p->attr[0].hasFill = 1;
-       p->attr[0].visible = 1;
-
-       return p;
+static int nsvg__ptInBounds(float *pt, float *bounds) {
+    return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3];
+}
+
+static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3) {
+    double it = 1.0 - t;
+    return it * it * it * p0 + 3.0 * it * it * t * p1 + 3.0 * it * t * t * p2 + t * t * t * p3;
+}
+
+static void nsvg__curveBounds(float *bounds, float *curve) {
+    int    i, j, count;
+    double roots[2], a, b, c, b2ac, t, v;
+    float *v0 = &curve[0];
+    float *v1 = &curve[2];
+    float *v2 = &curve[4];
+    float *v3 = &curve[6];
+
+    // Start the bounding box by end points
+    bounds[0] = nsvg__minf(v0[0], v3[0]);
+    bounds[1] = nsvg__minf(v0[1], v3[1]);
+    bounds[2] = nsvg__maxf(v0[0], v3[0]);
+    bounds[3] = nsvg__maxf(v0[1], v3[1]);
+
+    // Bezier curve fits inside the convex hull of it's control points.
+    // If control points are inside the bounds, we're done.
+    if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
+        return;
+
+    // Add bezier curve inflection points in X and Y.
+    for (i = 0; i < 2; i++) {
+        a     = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
+        b     = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
+        c     = 3.0 * v1[i] - 3.0 * v0[i];
+        count = 0;
+        if (fabs(a) < NSVG_EPSILON) {
+            if (fabs(b) > NSVG_EPSILON) {
+                t = -c / b;
+                if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON)
+                    roots[count++] = t;
+            }
+        } else {
+            b2ac = b * b - 4.0 * c * a;
+            if (b2ac > NSVG_EPSILON) {
+                t = (-b + sqrt(b2ac)) / (2.0 * a);
+                if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON)
+                    roots[count++] = t;
+                t = (-b - sqrt(b2ac)) / (2.0 * a);
+                if (t > NSVG_EPSILON && t < 1.0 - NSVG_EPSILON)
+                    roots[count++] = t;
+            }
+        }
+        for (j = 0; j < count; j++) {
+            v             = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]);
+            bounds[0 + i] = nsvg__minf(bounds[0 + i], (float)v);
+            bounds[2 + i] = nsvg__maxf(bounds[2 + i], (float)v);
+        }
+    }
+}
+
+static NSVGparser *nsvg__createParser() {
+    NSVGparser *p;
+    p = (NSVGparser *)malloc(sizeof(NSVGparser));
+    if (p == NULL)
+        goto error;
+    memset(p, 0, sizeof(NSVGparser));
+
+    p->image = (NSVGimage *)malloc(sizeof(NSVGimage));
+    if (p->image == NULL)
+        goto error;
+    memset(p->image, 0, sizeof(NSVGimage));
+
+    // Init style
+    nsvg__xformIdentity(p->attr[0].xform);
+    memset(p->attr[0].id, 0, sizeof p->attr[0].id);
+    p->attr[0].fillColor      = NSVG_RGB(0, 0, 0);
+    p->attr[0].strokeColor    = NSVG_RGB(0, 0, 0);
+    p->attr[0].opacity        = 1;
+    p->attr[0].fillOpacity    = 1;
+    p->attr[0].strokeOpacity  = 1;
+    p->attr[0].stopOpacity    = 1;
+    p->attr[0].strokeWidth    = 1;
+    p->attr[0].strokeLineJoin = NSVG_JOIN_MITER;
+    p->attr[0].strokeLineCap  = NSVG_CAP_BUTT;
+    p->attr[0].miterLimit     = 4;
+    p->attr[0].fillRule       = NSVG_FILLRULE_NONZERO;
+    p->attr[0].hasFill        = 1;
+    p->attr[0].visible        = 1;
+
+    return p;
 
 error:
-       if (p) {
-               if (p->image) free(p->image);
-               free(p);
-       }
-       return NULL;
-}
-
-static void nsvg__deletePaths(NSVGpath* path)
-{
-       while (path) {
-               NSVGpath *next = path->next;
-               if (path->pts != NULL)
-                       free(path->pts);
-               free(path);
-               path = next;
-       }
-}
-
-static void nsvg__deletePaint(NSVGpaint* paint)
-{
-       if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT)
-               free(paint->gradient);
+    if (p) {
+        if (p->image)
+            free(p->image);
+        free(p);
+    }
+    return NULL;
 }
-
-static void nsvg__deleteGradientData(NSVGgradientData* grad)
-{
-       NSVGgradientData* next;
-       while (grad != NULL) {
-               next = grad->next;
-               free(grad->stops);
-               free(grad);
-               grad = next;
-       }
+
+static void nsvg__deletePaths(NSVGpath *path) {
+    while (path) {
+        NSVGpath *next = path->next;
+        if (path->pts != NULL)
+            free(path->pts);
+        free(path);
+        path = next;
+    }
 }
 
-static void nsvg__deleteParser(NSVGparser* p)
-{
-       if (p != NULL) {
-               nsvg__deletePaths(p->plist);
-               nsvg__deleteGradientData(p->gradients);
-               nsvgDelete(p->image);
-               free(p->pts);
-               free(p);
-       }
+static void nsvg__deletePaint(NSVGpaint *paint) {
+    if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT)
+        free(paint->gradient);
 }
 
-static void nsvg__resetPath(NSVGparser* p)
-{
-       p->npts = 0;
-}
-
-static void nsvg__addPoint(NSVGparser* p, float x, float y)
-{
-       if (p->npts+1 > p->cpts) {
-               p->cpts = p->cpts ? p->cpts*2 : 8;
-               p->pts = (float*)realloc(p->pts, p->cpts*2*sizeof(float));
-               if (!p->pts) return;
-       }
-       p->pts[p->npts*2+0] = x;
-       p->pts[p->npts*2+1] = y;
-       p->npts++;
-}
-
-static void nsvg__moveTo(NSVGparser* p, float x, float y)
-{
-       if (p->npts > 0) {
-               p->pts[(p->npts-1)*2+0] = x;
-               p->pts[(p->npts-1)*2+1] = y;
-       } else {
-               nsvg__addPoint(p, x, y);
-       }
-}
-
-static void nsvg__lineTo(NSVGparser* p, float x, float y)
-{
-       float px,py, dx,dy;
-       if (p->npts > 0) {
-               px = p->pts[(p->npts-1)*2+0];
-               py = p->pts[(p->npts-1)*2+1];
-               dx = x - px;
-               dy = y - py;
-               nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f);
-               nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f);
-               nsvg__addPoint(p, x, y);
-       }
-}
-
-static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
-{
-       nsvg__addPoint(p, cpx1, cpy1);
-       nsvg__addPoint(p, cpx2, cpy2);
-       nsvg__addPoint(p, x, y);
-}
-
-static NSVGattrib* nsvg__getAttr(NSVGparser* p)
-{
-       return &p->attr[p->attrHead];
-}
-
-static void nsvg__pushAttr(NSVGparser* p)
-{
-       if (p->attrHead < NSVG_MAX_ATTR-1) {
-               p->attrHead++;
-               memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib));
-       }
-}
-
-static void nsvg__popAttr(NSVGparser* p)
-{
-       if (p->attrHead > 0)
-               p->attrHead--;
-}
-
-static float nsvg__actualOrigX(NSVGparser* p)
-{
-       return p->viewMinx;
-}
-
-static float nsvg__actualOrigY(NSVGparser* p)
-{
-       return p->viewMiny;
-}
-
-static float nsvg__actualWidth(NSVGparser* p)
-{
-       return p->viewWidth;
-}
-
-static float nsvg__actualHeight(NSVGparser* p)
-{
-       return p->viewHeight;
-}
-
-static float nsvg__actualLength(NSVGparser* p)
-{
-       float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p);
-       return sqrtf(w*w + h*h) / sqrtf(2.0f);
-}
-
-static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length)
-{
-       NSVGattrib* attr = nsvg__getAttr(p);
-       switch (c.units) {
-               case NSVG_UNITS_USER:           return c.value;
-               case NSVG_UNITS_PX:                     return c.value;
-               case NSVG_UNITS_PT:                     return c.value / 72.0f * p->dpi;
-               case NSVG_UNITS_PC:                     return c.value / 6.0f * p->dpi;
-               case NSVG_UNITS_MM:                     return c.value / 25.4f * p->dpi;
-               case NSVG_UNITS_CM:                     return c.value / 2.54f * p->dpi;
-               case NSVG_UNITS_IN:                     return c.value * p->dpi;
-               case NSVG_UNITS_EM:                     return c.value * attr->fontSize;
-               case NSVG_UNITS_EX:                     return c.value * attr->fontSize * 0.52f; // x-height of Helvetica.
-               case NSVG_UNITS_PERCENT:        return orig + c.value / 100.0f * length;
-               default:                                        return c.value;
-       }
-       return c.value;
-}
-
-static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
-{
-       NSVGgradientData* grad = p->gradients;
-       while (grad) {
-               if (strcmp(grad->id, id) == 0)
-                       return grad;
-               grad = grad->next;
-       }
-       return NULL;
-}
-
-static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType)
-{
-       NSVGattrib* attr = nsvg__getAttr(p);
-       NSVGgradientData* data = NULL;
-       NSVGgradientData* ref = NULL;
-       NSVGgradientStop* stops = NULL;
-       NSVGgradient* grad;
-       float ox, oy, sw, sh, sl;
-       int nstops = 0;
-
-       data = nsvg__findGradientData(p, id);
-       if (data == NULL) return NULL;
-
-       // TODO: use ref to fill in all unset values too.
-       ref = data;
-       while (ref != NULL) {
-               if (stops == NULL && ref->stops != NULL) {
-                       stops = ref->stops;
-                       nstops = ref->nstops;
-                       break;
-               }
-               ref = nsvg__findGradientData(p, ref->ref);
-       }
-       if (stops == NULL) return NULL;
-
-       grad = (NSVGgradient*)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1));
-       if (grad == NULL) return NULL;
-
-       // The shape width and height.
-       if (data->units == NSVG_OBJECT_SPACE) {
-               ox = localBounds[0];
-               oy = localBounds[1];
-               sw = localBounds[2] - localBounds[0];
-               sh = localBounds[3] - localBounds[1];
-       } else {
-               ox = nsvg__actualOrigX(p);
-               oy = nsvg__actualOrigY(p);
-               sw = nsvg__actualWidth(p);
-               sh = nsvg__actualHeight(p);
-       }
-       sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f);
-
-       if (data->type == NSVG_PAINT_LINEAR_GRADIENT) {
-               float x1, y1, x2, y2, dx, dy;
-               x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw);
-               y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh);
-               x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw);
-               y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh);
-               // Calculate transform aligned to the line
-               dx = x2 - x1;
-               dy = y2 - y1;
-               grad->xform[0] = dy; grad->xform[1] = -dx;
-               grad->xform[2] = dx; grad->xform[3] = dy;
-               grad->xform[4] = x1; grad->xform[5] = y1;
-       } else {
-               float cx, cy, fx, fy, r;
-               cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw);
-               cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh);
-               fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw);
-               fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh);
-               r = nsvg__convertToPixels(p, data->radial.r, 0, sl);
-               // Calculate transform aligned to the circle
-               grad->xform[0] = r; grad->xform[1] = 0;
-               grad->xform[2] = 0; grad->xform[3] = r;
-               grad->xform[4] = cx; grad->xform[5] = cy;
-               grad->fx = fx / r;
-               grad->fy = fy / r;
-       }
-
-       nsvg__xformMultiply(grad->xform, data->xform);
-       nsvg__xformMultiply(grad->xform, attr->xform);
-
-       grad->spread = data->spread;
-       memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop));
-       grad->nstops = nstops;
-
-       *paintType = data->type;
-
-       return grad;
-}
-
-static float nsvg__getAverageScale(float* t)
-{
-       float sx = sqrtf(t[0]*t[0] + t[2]*t[2]);
-       float sy = sqrtf(t[1]*t[1] + t[3]*t[3]);
-       return (sx + sy) * 0.5f;
-}
-
-static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform)
-{
-       NSVGpath* path;
-       float curve[4*2], curveBounds[4];
-       int i, first = 1;
-       for (path = shape->paths; path != NULL; path = path->next) {
-               nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform);
-               for (i = 0; i < path->npts-1; i += 3) {
-                       nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform);
-                       nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform);
-                       nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform);
-                       nsvg__curveBounds(curveBounds, curve);
-                       if (first) {
-                               bounds[0] = curveBounds[0];
-                               bounds[1] = curveBounds[1];
-                               bounds[2] = curveBounds[2];
-                               bounds[3] = curveBounds[3];
-                               first = 0;
-                       } else {
-                               bounds[0] = nsvg__minf(bounds[0], curveBounds[0]);
-                               bounds[1] = nsvg__minf(bounds[1], curveBounds[1]);
-                               bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]);
-                               bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]);
-                       }
-                       curve[0] = curve[6];
-                       curve[1] = curve[7];
-               }
-       }
-}
-
-static void nsvg__addShape(NSVGparser* p)
-{
-       NSVGattrib* attr = nsvg__getAttr(p);
-       float scale = 1.0f;
-       NSVGshape* shape;
-       NSVGpath* path;
-       int i;
-
-       if (p->plist == NULL)
-               return;
-
-       shape = (NSVGshape*)malloc(sizeof(NSVGshape));
-       if (shape == NULL) goto error;
-       memset(shape, 0, sizeof(NSVGshape));
-
-       memcpy(shape->id, attr->id, sizeof shape->id);
-       scale = nsvg__getAverageScale(attr->xform);
-       shape->strokeWidth = attr->strokeWidth * scale;
-       shape->strokeDashOffset = attr->strokeDashOffset * scale;
-       shape->strokeDashCount = (char)attr->strokeDashCount;
-       for (i = 0; i < attr->strokeDashCount; i++)
-               shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale;
-       shape->strokeLineJoin = attr->strokeLineJoin;
-       shape->strokeLineCap = attr->strokeLineCap;
-       shape->miterLimit = attr->miterLimit;
-       shape->fillRule = attr->fillRule;
-       shape->opacity = attr->opacity;
-
-       shape->paths = p->plist;
-       p->plist = NULL;
-
-       // Calculate shape bounds
-       shape->bounds[0] = shape->paths->bounds[0];
-       shape->bounds[1] = shape->paths->bounds[1];
-       shape->bounds[2] = shape->paths->bounds[2];
-       shape->bounds[3] = shape->paths->bounds[3];
-       for (path = shape->paths->next; path != NULL; path = path->next) {
-               shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]);
-               shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]);
-               shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]);
-               shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]);
-       }
-
-       // Set fill
-       if (attr->hasFill == 0) {
-               shape->fill.type = NSVG_PAINT_NONE;
-       } else if (attr->hasFill == 1) {
-               shape->fill.type = NSVG_PAINT_COLOR;
-               shape->fill.color = attr->fillColor;
-               shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24;
-       } else if (attr->hasFill == 2) {
-               float inv[6], localBounds[4];
-               nsvg__xformInverse(inv, attr->xform);
-               nsvg__getLocalBounds(localBounds, shape, inv);
-               shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type);
-               if (shape->fill.gradient == NULL) {
-                       shape->fill.type = NSVG_PAINT_NONE;
-               }
-       }
-
-       // Set stroke
-       if (attr->hasStroke == 0) {
-               shape->stroke.type = NSVG_PAINT_NONE;
-       } else if (attr->hasStroke == 1) {
-               shape->stroke.type = NSVG_PAINT_COLOR;
-               shape->stroke.color = attr->strokeColor;
-               shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24;
-       } else if (attr->hasStroke == 2) {
-               float inv[6], localBounds[4];
-               nsvg__xformInverse(inv, attr->xform);
-               nsvg__getLocalBounds(localBounds, shape, inv);
-               shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type);
-               if (shape->stroke.gradient == NULL)
-                       shape->stroke.type = NSVG_PAINT_NONE;
-       }
-
-       // Set flags
-       shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00);
-
-       // Add to tail
-       if (p->image->shapes == NULL)
-               p->image->shapes = shape;
-       else
-               p->shapesTail->next = shape;
-       p->shapesTail = shape;
-
-       return;
+static void nsvg__deleteGradientData(NSVGgradientData *grad) {
+    NSVGgradientData *next;
+    while (grad != NULL) {
+        next = grad->next;
+        free(grad->stops);
+        free(grad);
+        grad = next;
+    }
+}
+
+static void nsvg__deleteParser(NSVGparser *p) {
+    if (p != NULL) {
+        nsvg__deletePaths(p->plist);
+        nsvg__deleteGradientData(p->gradients);
+        nsvgDelete(p->image);
+        free(p->pts);
+        free(p);
+    }
+}
+
+static void nsvg__resetPath(NSVGparser *p) { p->npts = 0; }
+
+static void nsvg__addPoint(NSVGparser *p, float x, float y) {
+    if (p->npts + 1 > p->cpts) {
+        p->cpts = p->cpts ? p->cpts * 2 : 8;
+        p->pts  = (float *)realloc(p->pts, p->cpts * 2 * sizeof(float));
+        if (!p->pts)
+            return;
+    }
+    p->pts[p->npts * 2 + 0] = x;
+    p->pts[p->npts * 2 + 1] = y;
+    p->npts++;
+}
+
+static void nsvg__moveTo(NSVGparser *p, float x, float y) {
+    if (p->npts > 0) {
+        p->pts[(p->npts - 1) * 2 + 0] = x;
+        p->pts[(p->npts - 1) * 2 + 1] = y;
+    } else {
+        nsvg__addPoint(p, x, y);
+    }
+}
+
+static void nsvg__lineTo(NSVGparser *p, float x, float y) {
+    float px, py, dx, dy;
+    if (p->npts > 0) {
+        px = p->pts[(p->npts - 1) * 2 + 0];
+        py = p->pts[(p->npts - 1) * 2 + 1];
+        dx = x - px;
+        dy = y - py;
+        nsvg__addPoint(p, px + dx / 3.0f, py + dy / 3.0f);
+        nsvg__addPoint(p, x - dx / 3.0f, y - dy / 3.0f);
+        nsvg__addPoint(p, x, y);
+    }
+}
+
+static void nsvg__cubicBezTo(NSVGparser *p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) {
+    nsvg__addPoint(p, cpx1, cpy1);
+    nsvg__addPoint(p, cpx2, cpy2);
+    nsvg__addPoint(p, x, y);
+}
+
+static NSVGattrib *nsvg__getAttr(NSVGparser *p) { return &p->attr[p->attrHead]; }
+
+static void nsvg__pushAttr(NSVGparser *p) {
+    if (p->attrHead < NSVG_MAX_ATTR - 1) {
+        p->attrHead++;
+        memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead - 1], sizeof(NSVGattrib));
+    }
+}
+
+static void nsvg__popAttr(NSVGparser *p) {
+    if (p->attrHead > 0)
+        p->attrHead--;
+}
+
+static float nsvg__actualOrigX(NSVGparser *p) { return p->viewMinx; }
+
+static float nsvg__actualOrigY(NSVGparser *p) { return p->viewMiny; }
+
+static float nsvg__actualWidth(NSVGparser *p) { return p->viewWidth; }
+
+static float nsvg__actualHeight(NSVGparser *p) { return p->viewHeight; }
+
+static float nsvg__actualLength(NSVGparser *p) {
+    float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p);
+    return sqrtf(w * w + h * h) / sqrtf(2.0f);
+}
+
+static float nsvg__convertToPixels(NSVGparser *p, NSVGcoordinate c, float orig, float length) {
+    NSVGattrib *attr = nsvg__getAttr(p);
+    switch (c.units) {
+    case NSVG_UNITS_USER:
+        return c.value;
+    case NSVG_UNITS_PX:
+        return c.value;
+    case NSVG_UNITS_PT:
+        return c.value / 72.0f * p->dpi;
+    case NSVG_UNITS_PC:
+        return c.value / 6.0f * p->dpi;
+    case NSVG_UNITS_MM:
+        return c.value / 25.4f * p->dpi;
+    case NSVG_UNITS_CM:
+        return c.value / 2.54f * p->dpi;
+    case NSVG_UNITS_IN:
+        return c.value * p->dpi;
+    case NSVG_UNITS_EM:
+        return c.value * attr->fontSize;
+    case NSVG_UNITS_EX:
+        return c.value * attr->fontSize * 0.52f; // x-height of Helvetica.
+    case NSVG_UNITS_PERCENT:
+        return orig + c.value / 100.0f * length;
+    default:
+        return c.value;
+    }
+    return c.value;
+}
+
+static NSVGgradientData *nsvg__findGradientData(NSVGparser *p, const char *id) {
+    NSVGgradientData *grad = p->gradients;
+    while (grad) {
+        if (strcmp(grad->id, id) == 0)
+            return grad;
+        grad = grad->next;
+    }
+    return NULL;
+}
+
+static NSVGgradient *nsvg__createGradient(NSVGparser *p, const char *id, const float *localBounds, char *paintType) {
+    NSVGattrib       *attr  = nsvg__getAttr(p);
+    NSVGgradientData *data  = NULL;
+    NSVGgradientData *ref   = NULL;
+    NSVGgradientStop *stops = NULL;
+    NSVGgradient     *grad;
+    float             ox, oy, sw, sh, sl;
+    int               nstops = 0;
+
+    data = nsvg__findGradientData(p, id);
+    if (data == NULL)
+        return NULL;
+
+    // TODO: use ref to fill in all unset values too.
+    ref = data;
+    while (ref != NULL) {
+        if (stops == NULL && ref->stops != NULL) {
+            stops  = ref->stops;
+            nstops = ref->nstops;
+            break;
+        }
+        ref = nsvg__findGradientData(p, ref->ref);
+    }
+    if (stops == NULL)
+        return NULL;
+
+    grad = (NSVGgradient *)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop) * (nstops - 1));
+    if (grad == NULL)
+        return NULL;
+
+    // The shape width and height.
+    if (data->units == NSVG_OBJECT_SPACE) {
+        ox = localBounds[0];
+        oy = localBounds[1];
+        sw = localBounds[2] - localBounds[0];
+        sh = localBounds[3] - localBounds[1];
+    } else {
+        ox = nsvg__actualOrigX(p);
+        oy = nsvg__actualOrigY(p);
+        sw = nsvg__actualWidth(p);
+        sh = nsvg__actualHeight(p);
+    }
+    sl = sqrtf(sw * sw + sh * sh) / sqrtf(2.0f);
+
+    if (data->type == NSVG_PAINT_LINEAR_GRADIENT) {
+        float x1, y1, x2, y2, dx, dy;
+        x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw);
+        y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh);
+        x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw);
+        y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh);
+        // Calculate transform aligned to the line
+        dx             = x2 - x1;
+        dy             = y2 - y1;
+        grad->xform[0] = dy;
+        grad->xform[1] = -dx;
+        grad->xform[2] = dx;
+        grad->xform[3] = dy;
+        grad->xform[4] = x1;
+        grad->xform[5] = y1;
+    } else {
+        float cx, cy, fx, fy, r;
+        cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw);
+        cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh);
+        fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw);
+        fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh);
+        r  = nsvg__convertToPixels(p, data->radial.r, 0, sl);
+        // Calculate transform aligned to the circle
+        grad->xform[0] = r;
+        grad->xform[1] = 0;
+        grad->xform[2] = 0;
+        grad->xform[3] = r;
+        grad->xform[4] = cx;
+        grad->xform[5] = cy;
+        grad->fx       = fx / r;
+        grad->fy       = fy / r;
+    }
+
+    nsvg__xformMultiply(grad->xform, data->xform);
+    nsvg__xformMultiply(grad->xform, attr->xform);
+
+    grad->spread = data->spread;
+    memcpy(grad->stops, stops, nstops * sizeof(NSVGgradientStop));
+    grad->nstops = nstops;
+
+    *paintType = data->type;
+
+    return grad;
+}
+
+static float nsvg__getAverageScale(float *t) {
+    float sx = sqrtf(t[0] * t[0] + t[2] * t[2]);
+    float sy = sqrtf(t[1] * t[1] + t[3] * t[3]);
+    return (sx + sy) * 0.5f;
+}
+
+static void nsvg__getLocalBounds(float *bounds, NSVGshape *shape, float *xform) {
+    NSVGpath *path;
+    float     curve[4 * 2], curveBounds[4];
+    int       i, first = 1;
+    for (path = shape->paths; path != NULL; path = path->next) {
+        nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform);
+        for (i = 0; i < path->npts - 1; i += 3) {
+            nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i + 1) * 2], path->pts[(i + 1) * 2 + 1], xform);
+            nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i + 2) * 2], path->pts[(i + 2) * 2 + 1], xform);
+            nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i + 3) * 2], path->pts[(i + 3) * 2 + 1], xform);
+            nsvg__curveBounds(curveBounds, curve);
+            if (first) {
+                bounds[0] = curveBounds[0];
+                bounds[1] = curveBounds[1];
+                bounds[2] = curveBounds[2];
+                bounds[3] = curveBounds[3];
+                first     = 0;
+            } else {
+                bounds[0] = nsvg__minf(bounds[0], curveBounds[0]);
+                bounds[1] = nsvg__minf(bounds[1], curveBounds[1]);
+                bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]);
+                bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]);
+            }
+            curve[0] = curve[6];
+            curve[1] = curve[7];
+        }
+    }
+}
+
+static void nsvg__addShape(NSVGparser *p) {
+    NSVGattrib *attr  = nsvg__getAttr(p);
+    float       scale = 1.0f;
+    NSVGshape  *shape;
+    NSVGpath   *path;
+    int         i;
+
+    if (p->plist == NULL)
+        return;
+
+    shape = (NSVGshape *)malloc(sizeof(NSVGshape));
+    if (shape == NULL)
+        goto error;
+    memset(shape, 0, sizeof(NSVGshape));
+
+    memcpy(shape->id, attr->id, sizeof shape->id);
+    scale                   = nsvg__getAverageScale(attr->xform);
+    shape->strokeWidth      = attr->strokeWidth * scale;
+    shape->strokeDashOffset = attr->strokeDashOffset * scale;
+    shape->strokeDashCount  = (char)attr->strokeDashCount;
+    for (i = 0; i < attr->strokeDashCount; i++)
+        shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale;
+    shape->strokeLineJoin = attr->strokeLineJoin;
+    shape->strokeLineCap  = attr->strokeLineCap;
+    shape->miterLimit     = attr->miterLimit;
+    shape->fillRule       = attr->fillRule;
+    shape->opacity        = attr->opacity;
+
+    shape->paths = p->plist;
+    p->plist     = NULL;
+
+    // Calculate shape bounds
+    shape->bounds[0] = shape->paths->bounds[0];
+    shape->bounds[1] = shape->paths->bounds[1];
+    shape->bounds[2] = shape->paths->bounds[2];
+    shape->bounds[3] = shape->paths->bounds[3];
+    for (path = shape->paths->next; path != NULL; path = path->next) {
+        shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]);
+        shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]);
+        shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]);
+        shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]);
+    }
+
+    // Set fill
+    if (attr->hasFill == 0) {
+        shape->fill.type = NSVG_PAINT_NONE;
+    } else if (attr->hasFill == 1) {
+        shape->fill.type  = NSVG_PAINT_COLOR;
+        shape->fill.color = attr->fillColor;
+        shape->fill.color |= (unsigned int)(attr->fillOpacity * 255) << 24;
+    } else if (attr->hasFill == 2) {
+        float inv[6], localBounds[4];
+        nsvg__xformInverse(inv, attr->xform);
+        nsvg__getLocalBounds(localBounds, shape, inv);
+        shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type);
+        if (shape->fill.gradient == NULL) {
+            shape->fill.type = NSVG_PAINT_NONE;
+        }
+    }
+
+    // Set stroke
+    if (attr->hasStroke == 0) {
+        shape->stroke.type = NSVG_PAINT_NONE;
+    } else if (attr->hasStroke == 1) {
+        shape->stroke.type  = NSVG_PAINT_COLOR;
+        shape->stroke.color = attr->strokeColor;
+        shape->stroke.color |= (unsigned int)(attr->strokeOpacity * 255) << 24;
+    } else if (attr->hasStroke == 2) {
+        float inv[6], localBounds[4];
+        nsvg__xformInverse(inv, attr->xform);
+        nsvg__getLocalBounds(localBounds, shape, inv);
+        shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type);
+        if (shape->stroke.gradient == NULL)
+            shape->stroke.type = NSVG_PAINT_NONE;
+    }
+
+    // Set flags
+    shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00);
+
+    // Add to tail
+    if (p->image->shapes == NULL)
+        p->image->shapes = shape;
+    else
+        p->shapesTail->next = shape;
+    p->shapesTail = shape;
+
+    return;
 
 error:
-       if (shape) free(shape);
-}
-
-static void nsvg__addPath(NSVGparser* p, char closed)
-{
-       NSVGattrib* attr = nsvg__getAttr(p);
-       NSVGpath* path = NULL;
-       float bounds[4];
-       float* curve;
-       int i;
-
-       if (p->npts < 4)
-               return;
-
-       if (closed)
-               nsvg__lineTo(p, p->pts[0], p->pts[1]);
-
-       path = (NSVGpath*)malloc(sizeof(NSVGpath));
-       if (path == NULL) goto error;
-       memset(path, 0, sizeof(NSVGpath));
-
-       path->pts = (float*)malloc(p->npts*2*sizeof(float));
-       if (path->pts == NULL) goto error;
-       path->closed = closed;
-       path->npts = p->npts;
-
-       // Transform path.
-       for (i = 0; i < p->npts; ++i)
-               nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform);
-
-       // Find bounds
-       for (i = 0; i < path->npts-1; i += 3) {
-               curve = &path->pts[i*2];
-               nsvg__curveBounds(bounds, curve);
-               if (i == 0) {
-                       path->bounds[0] = bounds[0];
-                       path->bounds[1] = bounds[1];
-                       path->bounds[2] = bounds[2];
-                       path->bounds[3] = bounds[3];
-               } else {
-                       path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]);
-                       path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]);
-                       path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]);
-                       path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]);
-               }
-       }
-
-       path->next = p->plist;
-       p->plist = path;
-
-       return;
+    if (shape)
+        free(shape);
+}
+
+static void nsvg__addPath(NSVGparser *p, char closed) {
+    NSVGattrib *attr = nsvg__getAttr(p);
+    NSVGpath   *path = NULL;
+    float       bounds[4];
+    float      *curve;
+    int         i;
+
+    if (p->npts < 4)
+        return;
+
+    if (closed)
+        nsvg__lineTo(p, p->pts[0], p->pts[1]);
+
+    path = (NSVGpath *)malloc(sizeof(NSVGpath));
+    if (path == NULL)
+        goto error;
+    memset(path, 0, sizeof(NSVGpath));
+
+    path->pts = (float *)malloc(p->npts * 2 * sizeof(float));
+    if (path->pts == NULL)
+        goto error;
+    path->closed = closed;
+    path->npts   = p->npts;
+
+    // Transform path.
+    for (i = 0; i < p->npts; ++i)
+        nsvg__xformPoint(&path->pts[i * 2], &path->pts[i * 2 + 1], p->pts[i * 2], p->pts[i * 2 + 1], attr->xform);
+
+    // Find bounds
+    for (i = 0; i < path->npts - 1; i += 3) {
+        curve = &path->pts[i * 2];
+        nsvg__curveBounds(bounds, curve);
+        if (i == 0) {
+            path->bounds[0] = bounds[0];
+            path->bounds[1] = bounds[1];
+            path->bounds[2] = bounds[2];
+            path->bounds[3] = bounds[3];
+        } else {
+            path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]);
+            path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]);
+            path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]);
+            path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]);
+        }
+    }
+
+    path->next = p->plist;
+    p->plist   = path;
+
+    return;
 
 error:
-       if (path != NULL) {
-               if (path->pts != NULL) free(path->pts);
-               free(path);
-       }
+    if (path != NULL) {
+        if (path->pts != NULL)
+            free(path->pts);
+        free(path);
+    }
 }
 
 // We roll our own string to float because the std library one uses locale and messes things up.
-static double nsvg__atof(const char* s)
-{
-       char* cur = (char*)s;
-       char* end = NULL;
-       double res = 0.0, sign = 1.0;
-       long long intPart = 0, fracPart = 0;
-       char hasIntPart = 0, hasFracPart = 0;
-
-       // Parse optional sign
-       if (*cur == '+') {
-               cur++;
-       } else if (*cur == '-') {
-               sign = -1;
-               cur++;
-       }
-
-       // Parse integer part
-       if (nsvg__isdigit(*cur)) {
-               // Parse digit sequence
-               intPart = (double)strtoll(cur, &end, 10);
-               if (cur != end) {
-                       res = (double)intPart;
-                       hasIntPart = 1;
-                       cur = end;
-               }
-       }
-
-       // Parse fractional part.
-       if (*cur == '.') {
-               cur++; // Skip '.'
-               if (nsvg__isdigit(*cur)) {
-                       // Parse digit sequence
-                       fracPart = strtoll(cur, &end, 10);
-                       if (cur != end) {
-                               res += (double)fracPart / pow(10.0, (double)(end - cur));
-                               hasFracPart = 1;
-                               cur = end;
-                       }
-               }
-       }
-
-       // A valid number should have integer or fractional part.
-       if (!hasIntPart && !hasFracPart)
-               return 0.0;
-
-       // Parse optional exponent
-       if (*cur == 'e' || *cur == 'E') {
-               int expPart = 0;
-               cur++; // skip 'E'
-               expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
-               if (cur != end) {
-                       res *= pow(10.0, (double)expPart);
-               }
-       }
-
-       return res * sign;
-}
-
-
-static const char* nsvg__parseNumber(const char* s, char* it, const int size)
-{
-       const int last = size-1;
-       int i = 0;
-
-       // sign
-       if (*s == '-' || *s == '+') {
-               if (i < last) it[i++] = *s;
-               s++;
-       }
-       // integer part
-       while (*s && nsvg__isdigit(*s)) {
-               if (i < last) it[i++] = *s;
-               s++;
-       }
-       if (*s == '.') {
-               // decimal point
-               if (i < last) it[i++] = *s;
-               s++;
-               // fraction part
-               while (*s && nsvg__isdigit(*s)) {
-                       if (i < last) it[i++] = *s;
-                       s++;
-               }
-       }
-       // exponent
-       if (*s == 'e' || *s == 'E') {
-               if (i < last) it[i++] = *s;
-               s++;
-               if (*s == '-' || *s == '+') {
-                       if (i < last) it[i++] = *s;
-                       s++;
-               }
-               while (*s && nsvg__isdigit(*s)) {
-                       if (i < last) it[i++] = *s;
-                       s++;
-               }
-       }
-       it[i] = '\0';
-
-       return s;
-}
-
-static const char* nsvg__getNextPathItem(const char* s, char* it)
-{
-       it[0] = '\0';
-       // Skip white spaces and commas
-       while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
-       if (!*s) return s;
-       if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
-               s = nsvg__parseNumber(s, it, 64);
-       } else {
-               // Parse command
-               it[0] = *s++;
-               it[1] = '\0';
-               return s;
-       }
-
-       return s;
-}
-
-static unsigned int nsvg__parseColorHex(const char* str)
-{
-       unsigned int c = 0, r = 0, g = 0, b = 0;
-       int n = 0;
-       str++; // skip #
-       // Calculate number of characters.
-       while(str[n] && !nsvg__isspace(str[n]))
-               n++;
-       if (n == 6) {
-               sscanf(str, "%x", &c);
-       } else if (n == 3) {
-               sscanf(str, "%x", &c);
-               c = (c&0xf) | ((c&0xf0) << 4) | ((c&0xf00) << 8);
-               c |= c<<4;
-       }
-       r = (c >> 16) & 0xff;
-       g = (c >> 8) & 0xff;
-       b = c & 0xff;
-       return NSVG_RGB(r,g,b);
-}
-
-static unsigned int nsvg__parseColorRGB(const char* str)
-{
-       int r = -1, g = -1, b = -1;
-       char s1[32]="", s2[32]="";
-       sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);
-       if (strchr(s1, '%')) {
-               return NSVG_RGB((r*255)/100,(g*255)/100,(b*255)/100);
-       } else {
-               return NSVG_RGB(r,g,b);
-       }
+static double nsvg__atof(const char *s) {
+    char     *cur = (char *)s;
+    char     *end = NULL;
+    double    res = 0.0, sign = 1.0;
+    long long intPart = 0, fracPart = 0;
+    char      hasIntPart = 0, hasFracPart = 0;
+
+    // Parse optional sign
+    if (*cur == '+') {
+        cur++;
+    } else if (*cur == '-') {
+        sign = -1;
+        cur++;
+    }
+
+    // Parse integer part
+    if (nsvg__isdigit(*cur)) {
+        // Parse digit sequence
+        intPart = (double)strtoll(cur, &end, 10);
+        if (cur != end) {
+            res        = (double)intPart;
+            hasIntPart = 1;
+            cur        = end;
+        }
+    }
+
+    // Parse fractional part.
+    if (*cur == '.') {
+        cur++; // Skip '.'
+        if (nsvg__isdigit(*cur)) {
+            // Parse digit sequence
+            fracPart = strtoll(cur, &end, 10);
+            if (cur != end) {
+                res += (double)fracPart / pow(10.0, (double)(end - cur));
+                hasFracPart = 1;
+                cur         = end;
+            }
+        }
+    }
+
+    // A valid number should have integer or fractional part.
+    if (!hasIntPart && !hasFracPart)
+        return 0.0;
+
+    // Parse optional exponent
+    if (*cur == 'e' || *cur == 'E') {
+        int expPart = 0;
+        cur++;                           // skip 'E'
+        expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
+        if (cur != end) {
+            res *= pow(10.0, (double)expPart);
+        }
+    }
+
+    return res * sign;
+}
+
+static const char *nsvg__parseNumber(const char *s, char *it, const int size) {
+    const int last = size - 1;
+    int       i    = 0;
+
+    // sign
+    if (*s == '-' || *s == '+') {
+        if (i < last)
+            it[i++] = *s;
+        s++;
+    }
+    // integer part
+    while (*s && nsvg__isdigit(*s)) {
+        if (i < last)
+            it[i++] = *s;
+        s++;
+    }
+    if (*s == '.') {
+        // decimal point
+        if (i < last)
+            it[i++] = *s;
+        s++;
+        // fraction part
+        while (*s && nsvg__isdigit(*s)) {
+            if (i < last)
+                it[i++] = *s;
+            s++;
+        }
+    }
+    // exponent
+    if (*s == 'e' || *s == 'E') {
+        if (i < last)
+            it[i++] = *s;
+        s++;
+        if (*s == '-' || *s == '+') {
+            if (i < last)
+                it[i++] = *s;
+            s++;
+        }
+        while (*s && nsvg__isdigit(*s)) {
+            if (i < last)
+                it[i++] = *s;
+            s++;
+        }
+    }
+    it[i] = '\0';
+
+    return s;
+}
+
+static const char *nsvg__getNextPathItem(const char *s, char *it) {
+    it[0] = '\0';
+    // Skip white spaces and commas
+    while (*s && (nsvg__isspace(*s) || *s == ','))
+        s++;
+    if (!*s)
+        return s;
+    if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
+        s = nsvg__parseNumber(s, it, 64);
+    } else {
+        // Parse command
+        it[0] = *s++;
+        it[1] = '\0';
+        return s;
+    }
+
+    return s;
+}
+
+static unsigned int nsvg__parseColorHex(const char *str) {
+    unsigned int c = 0, r = 0, g = 0, b = 0;
+    int          n = 0;
+    str++; // skip #
+    // Calculate number of characters.
+    while (str[n] && !nsvg__isspace(str[n]))
+        n++;
+    if (n == 6) {
+        sscanf(str, "%x", &c);
+    } else if (n == 3) {
+        sscanf(str, "%x", &c);
+        c = (c & 0xf) | ((c & 0xf0) << 4) | ((c & 0xf00) << 8);
+        c |= c << 4;
+    }
+    r = (c >> 16) & 0xff;
+    g = (c >> 8) & 0xff;
+    b = c & 0xff;
+    return NSVG_RGB(r, g, b);
+}
+
+static unsigned int nsvg__parseColorRGB(const char *str) {
+    int  r = -1, g = -1, b = -1;
+    char s1[32] = "", s2[32] = "";
+    sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);
+    if (strchr(s1, '%')) {
+        return NSVG_RGB((r * 255) / 100, (g * 255) / 100, (b * 255) / 100);
+    } else {
+        return NSVG_RGB(r, g, b);
+    }
 }
 
 typedef struct NSVGNamedColor {
-       const char* name;
-       unsigned int color;
+    const char  *name;
+    unsigned int color;
 } NSVGNamedColor;
 
 NSVGNamedColor nsvg__colors[] = {
 
-       { "red", NSVG_RGB(255, 0, 0) },
-       { "green", NSVG_RGB( 0, 128, 0) },
-       { "blue", NSVG_RGB( 0, 0, 255) },
-       { "yellow", NSVG_RGB(255, 255, 0) },
-       { "cyan", NSVG_RGB( 0, 255, 255) },
-       { "magenta", NSVG_RGB(255, 0, 255) },
-       { "black", NSVG_RGB( 0, 0, 0) },
-       { "grey", NSVG_RGB(128, 128, 128) },
-       { "gray", NSVG_RGB(128, 128, 128) },
-       { "white", NSVG_RGB(255, 255, 255) },
+    {"red", NSVG_RGB(255, 0, 0)},
+    {"green", NSVG_RGB(0, 128, 0)},
+    {"blue", NSVG_RGB(0, 0, 255)},
+    {"yellow", NSVG_RGB(255, 255, 0)},
+    {"cyan", NSVG_RGB(0, 255, 255)},
+    {"magenta", NSVG_RGB(255, 0, 255)},
+    {"black", NSVG_RGB(0, 0, 0)},
+    {"grey", NSVG_RGB(128, 128, 128)},
+    {"gray", NSVG_RGB(128, 128, 128)},
+    {"white", NSVG_RGB(255, 255, 255)},
 
 #ifdef NANOSVG_ALL_COLOR_KEYWORDS
-       { "aliceblue", NSVG_RGB(240, 248, 255) },
-       { "antiquewhite", NSVG_RGB(250, 235, 215) },
-       { "aqua", NSVG_RGB( 0, 255, 255) },
-       { "aquamarine", NSVG_RGB(127, 255, 212) },
-       { "azure", NSVG_RGB(240, 255, 255) },
-       { "beige", NSVG_RGB(245, 245, 220) },
-       { "bisque", NSVG_RGB(255, 228, 196) },
-       { "blanchedalmond", NSVG_RGB(255, 235, 205) },
-       { "blueviolet", NSVG_RGB(138, 43, 226) },
-       { "brown", NSVG_RGB(165, 42, 42) },
-       { "burlywood", NSVG_RGB(222, 184, 135) },
-       { "cadetblue", NSVG_RGB( 95, 158, 160) },
-       { "chartreuse", NSVG_RGB(127, 255, 0) },
-       { "chocolate", NSVG_RGB(210, 105, 30) },
-       { "coral", NSVG_RGB(255, 127, 80) },
-       { "cornflowerblue", NSVG_RGB(100, 149, 237) },
-       { "cornsilk", NSVG_RGB(255, 248, 220) },
-       { "crimson", NSVG_RGB(220, 20, 60) },
-       { "darkblue", NSVG_RGB( 0, 0, 139) },
-       { "darkcyan", NSVG_RGB( 0, 139, 139) },
-       { "darkgoldenrod", NSVG_RGB(184, 134, 11) },
-       { "darkgray", NSVG_RGB(169, 169, 169) },
-       { "darkgreen", NSVG_RGB( 0, 100, 0) },
-       { "darkgrey", NSVG_RGB(169, 169, 169) },
-       { "darkkhaki", NSVG_RGB(189, 183, 107) },
-       { "darkmagenta", NSVG_RGB(139, 0, 139) },
-       { "darkolivegreen", NSVG_RGB( 85, 107, 47) },
-       { "darkorange", NSVG_RGB(255, 140, 0) },
-       { "darkorchid", NSVG_RGB(153, 50, 204) },
-       { "darkred", NSVG_RGB(139, 0, 0) },
-       { "darksalmon", NSVG_RGB(233, 150, 122) },
-       { "darkseagreen", NSVG_RGB(143, 188, 143) },
-       { "darkslateblue", NSVG_RGB( 72, 61, 139) },
-       { "darkslategray", NSVG_RGB( 47, 79, 79) },
-       { "darkslategrey", NSVG_RGB( 47, 79, 79) },
-       { "darkturquoise", NSVG_RGB( 0, 206, 209) },
-       { "darkviolet", NSVG_RGB(148, 0, 211) },
-       { "deeppink", NSVG_RGB(255, 20, 147) },
-       { "deepskyblue", NSVG_RGB( 0, 191, 255) },
-       { "dimgray", NSVG_RGB(105, 105, 105) },
-       { "dimgrey", NSVG_RGB(105, 105, 105) },
-       { "dodgerblue", NSVG_RGB( 30, 144, 255) },
-       { "firebrick", NSVG_RGB(178, 34, 34) },
-       { "floralwhite", NSVG_RGB(255, 250, 240) },
-       { "forestgreen", NSVG_RGB( 34, 139, 34) },
-       { "fuchsia", NSVG_RGB(255, 0, 255) },
-       { "gainsboro", NSVG_RGB(220, 220, 220) },
-       { "ghostwhite", NSVG_RGB(248, 248, 255) },
-       { "gold", NSVG_RGB(255, 215, 0) },
-       { "goldenrod", NSVG_RGB(218, 165, 32) },
-       { "greenyellow", NSVG_RGB(173, 255, 47) },
-       { "honeydew", NSVG_RGB(240, 255, 240) },
-       { "hotpink", NSVG_RGB(255, 105, 180) },
-       { "indianred", NSVG_RGB(205, 92, 92) },
-       { "indigo", NSVG_RGB( 75, 0, 130) },
-       { "ivory", NSVG_RGB(255, 255, 240) },
-       { "khaki", NSVG_RGB(240, 230, 140) },
-       { "lavender", NSVG_RGB(230, 230, 250) },
-       { "lavenderblush", NSVG_RGB(255, 240, 245) },
-       { "lawngreen", NSVG_RGB(124, 252, 0) },
-       { "lemonchiffon", NSVG_RGB(255, 250, 205) },
-       { "lightblue", NSVG_RGB(173, 216, 230) },
-       { "lightcoral", NSVG_RGB(240, 128, 128) },
-       { "lightcyan", NSVG_RGB(224, 255, 255) },
-       { "lightgoldenrodyellow", NSVG_RGB(250, 250, 210) },
-       { "lightgray", NSVG_RGB(211, 211, 211) },
-       { "lightgreen", NSVG_RGB(144, 238, 144) },
-       { "lightgrey", NSVG_RGB(211, 211, 211) },
-       { "lightpink", NSVG_RGB(255, 182, 193) },
-       { "lightsalmon", NSVG_RGB(255, 160, 122) },
-       { "lightseagreen", NSVG_RGB( 32, 178, 170) },
-       { "lightskyblue", NSVG_RGB(135, 206, 250) },
-       { "lightslategray", NSVG_RGB(119, 136, 153) },
-       { "lightslategrey", NSVG_RGB(119, 136, 153) },
-       { "lightsteelblue", NSVG_RGB(176, 196, 222) },
-       { "lightyellow", NSVG_RGB(255, 255, 224) },
-       { "lime", NSVG_RGB( 0, 255, 0) },
-       { "limegreen", NSVG_RGB( 50, 205, 50) },
-       { "linen", NSVG_RGB(250, 240, 230) },
-       { "maroon", NSVG_RGB(128, 0, 0) },
-       { "mediumaquamarine", NSVG_RGB(102, 205, 170) },
-       { "mediumblue", NSVG_RGB( 0, 0, 205) },
-       { "mediumorchid", NSVG_RGB(186, 85, 211) },
-       { "mediumpurple", NSVG_RGB(147, 112, 219) },
-       { "mediumseagreen", NSVG_RGB( 60, 179, 113) },
-       { "mediumslateblue", NSVG_RGB(123, 104, 238) },
-       { "mediumspringgreen", NSVG_RGB( 0, 250, 154) },
-       { "mediumturquoise", NSVG_RGB( 72, 209, 204) },
-       { "mediumvioletred", NSVG_RGB(199, 21, 133) },
-       { "midnightblue", NSVG_RGB( 25, 25, 112) },
-       { "mintcream", NSVG_RGB(245, 255, 250) },
-       { "mistyrose", NSVG_RGB(255, 228, 225) },
-       { "moccasin", NSVG_RGB(255, 228, 181) },
-       { "navajowhite", NSVG_RGB(255, 222, 173) },
-       { "navy", NSVG_RGB( 0, 0, 128) },
-       { "oldlace", NSVG_RGB(253, 245, 230) },
-       { "olive", NSVG_RGB(128, 128, 0) },
-       { "olivedrab", NSVG_RGB(107, 142, 35) },
-       { "orange", NSVG_RGB(255, 165, 0) },
-       { "orangered", NSVG_RGB(255, 69, 0) },
-       { "orchid", NSVG_RGB(218, 112, 214) },
-       { "palegoldenrod", NSVG_RGB(238, 232, 170) },
-       { "palegreen", NSVG_RGB(152, 251, 152) },
-       { "paleturquoise", NSVG_RGB(175, 238, 238) },
-       { "palevioletred", NSVG_RGB(219, 112, 147) },
-       { "papayawhip", NSVG_RGB(255, 239, 213) },
-       { "peachpuff", NSVG_RGB(255, 218, 185) },
-       { "peru", NSVG_RGB(205, 133, 63) },
-       { "pink", NSVG_RGB(255, 192, 203) },
-       { "plum", NSVG_RGB(221, 160, 221) },
-       { "powderblue", NSVG_RGB(176, 224, 230) },
-       { "purple", NSVG_RGB(128, 0, 128) },
-       { "rosybrown", NSVG_RGB(188, 143, 143) },
-       { "royalblue", NSVG_RGB( 65, 105, 225) },
-       { "saddlebrown", NSVG_RGB(139, 69, 19) },
-       { "salmon", NSVG_RGB(250, 128, 114) },
-       { "sandybrown", NSVG_RGB(244, 164, 96) },
-       { "seagreen", NSVG_RGB( 46, 139, 87) },
-       { "seashell", NSVG_RGB(255, 245, 238) },
-       { "sienna", NSVG_RGB(160, 82, 45) },
-       { "silver", NSVG_RGB(192, 192, 192) },
-       { "skyblue", NSVG_RGB(135, 206, 235) },
-       { "slateblue", NSVG_RGB(106, 90, 205) },
-       { "slategray", NSVG_RGB(112, 128, 144) },
-       { "slategrey", NSVG_RGB(112, 128, 144) },
-       { "snow", NSVG_RGB(255, 250, 250) },
-       { "springgreen", NSVG_RGB( 0, 255, 127) },
-       { "steelblue", NSVG_RGB( 70, 130, 180) },
-       { "tan", NSVG_RGB(210, 180, 140) },
-       { "teal", NSVG_RGB( 0, 128, 128) },
-       { "thistle", NSVG_RGB(216, 191, 216) },
-       { "tomato", NSVG_RGB(255, 99, 71) },
-       { "turquoise", NSVG_RGB( 64, 224, 208) },
-       { "violet", NSVG_RGB(238, 130, 238) },
-       { "wheat", NSVG_RGB(245, 222, 179) },
-       { "whitesmoke", NSVG_RGB(245, 245, 245) },
-       { "yellowgreen", NSVG_RGB(154, 205, 50) },
+    {"aliceblue", NSVG_RGB(240, 248, 255)},
+    {"antiquewhite", NSVG_RGB(250, 235, 215)},
+    {"aqua", NSVG_RGB(0, 255, 255)},
+    {"aquamarine", NSVG_RGB(127, 255, 212)},
+    {"azure", NSVG_RGB(240, 255, 255)},
+    {"beige", NSVG_RGB(245, 245, 220)},
+    {"bisque", NSVG_RGB(255, 228, 196)},
+    {"blanchedalmond", NSVG_RGB(255, 235, 205)},
+    {"blueviolet", NSVG_RGB(138, 43, 226)},
+    {"brown", NSVG_RGB(165, 42, 42)},
+    {"burlywood", NSVG_RGB(222, 184, 135)},
+    {"cadetblue", NSVG_RGB(95, 158, 160)},
+    {"chartreuse", NSVG_RGB(127, 255, 0)},
+    {"chocolate", NSVG_RGB(210, 105, 30)},
+    {"coral", NSVG_RGB(255, 127, 80)},
+    {"cornflowerblue", NSVG_RGB(100, 149, 237)},
+    {"cornsilk", NSVG_RGB(255, 248, 220)},
+    {"crimson", NSVG_RGB(220, 20, 60)},
+    {"darkblue", NSVG_RGB(0, 0, 139)},
+    {"darkcyan", NSVG_RGB(0, 139, 139)},
+    {"darkgoldenrod", NSVG_RGB(184, 134, 11)},
+    {"darkgray", NSVG_RGB(169, 169, 169)},
+    {"darkgreen", NSVG_RGB(0, 100, 0)},
+    {"darkgrey", NSVG_RGB(169, 169, 169)},
+    {"darkkhaki", NSVG_RGB(189, 183, 107)},
+    {"darkmagenta", NSVG_RGB(139, 0, 139)},
+    {"darkolivegreen", NSVG_RGB(85, 107, 47)},
+    {"darkorange", NSVG_RGB(255, 140, 0)},
+    {"darkorchid", NSVG_RGB(153, 50, 204)},
+    {"darkred", NSVG_RGB(139, 0, 0)},
+    {"darksalmon", NSVG_RGB(233, 150, 122)},
+    {"darkseagreen", NSVG_RGB(143, 188, 143)},
+    {"darkslateblue", NSVG_RGB(72, 61, 139)},
+    {"darkslategray", NSVG_RGB(47, 79, 79)},
+    {"darkslategrey", NSVG_RGB(47, 79, 79)},
+    {"darkturquoise", NSVG_RGB(0, 206, 209)},
+    {"darkviolet", NSVG_RGB(148, 0, 211)},
+    {"deeppink", NSVG_RGB(255, 20, 147)},
+    {"deepskyblue", NSVG_RGB(0, 191, 255)},
+    {"dimgray", NSVG_RGB(105, 105, 105)},
+    {"dimgrey", NSVG_RGB(105, 105, 105)},
+    {"dodgerblue", NSVG_RGB(30, 144, 255)},
+    {"firebrick", NSVG_RGB(178, 34, 34)},
+    {"floralwhite", NSVG_RGB(255, 250, 240)},
+    {"forestgreen", NSVG_RGB(34, 139, 34)},
+    {"fuchsia", NSVG_RGB(255, 0, 255)},
+    {"gainsboro", NSVG_RGB(220, 220, 220)},
+    {"ghostwhite", NSVG_RGB(248, 248, 255)},
+    {"gold", NSVG_RGB(255, 215, 0)},
+    {"goldenrod", NSVG_RGB(218, 165, 32)},
+    {"greenyellow", NSVG_RGB(173, 255, 47)},
+    {"honeydew", NSVG_RGB(240, 255, 240)},
+    {"hotpink", NSVG_RGB(255, 105, 180)},
+    {"indianred", NSVG_RGB(205, 92, 92)},
+    {"indigo", NSVG_RGB(75, 0, 130)},
+    {"ivory", NSVG_RGB(255, 255, 240)},
+    {"khaki", NSVG_RGB(240, 230, 140)},
+    {"lavender", NSVG_RGB(230, 230, 250)},
+    {"lavenderblush", NSVG_RGB(255, 240, 245)},
+    {"lawngreen", NSVG_RGB(124, 252, 0)},
+    {"lemonchiffon", NSVG_RGB(255, 250, 205)},
+    {"lightblue", NSVG_RGB(173, 216, 230)},
+    {"lightcoral", NSVG_RGB(240, 128, 128)},
+    {"lightcyan", NSVG_RGB(224, 255, 255)},
+    {"lightgoldenrodyellow", NSVG_RGB(250, 250, 210)},
+    {"lightgray", NSVG_RGB(211, 211, 211)},
+    {"lightgreen", NSVG_RGB(144, 238, 144)},
+    {"lightgrey", NSVG_RGB(211, 211, 211)},
+    {"lightpink", NSVG_RGB(255, 182, 193)},
+    {"lightsalmon", NSVG_RGB(255, 160, 122)},
+    {"lightseagreen", NSVG_RGB(32, 178, 170)},
+    {"lightskyblue", NSVG_RGB(135, 206, 250)},
+    {"lightslategray", NSVG_RGB(119, 136, 153)},
+    {"lightslategrey", NSVG_RGB(119, 136, 153)},
+    {"lightsteelblue", NSVG_RGB(176, 196, 222)},
+    {"lightyellow", NSVG_RGB(255, 255, 224)},
+    {"lime", NSVG_RGB(0, 255, 0)},
+    {"limegreen", NSVG_RGB(50, 205, 50)},
+    {"linen", NSVG_RGB(250, 240, 230)},
+    {"maroon", NSVG_RGB(128, 0, 0)},
+    {"mediumaquamarine", NSVG_RGB(102, 205, 170)},
+    {"mediumblue", NSVG_RGB(0, 0, 205)},
+    {"mediumorchid", NSVG_RGB(186, 85, 211)},
+    {"mediumpurple", NSVG_RGB(147, 112, 219)},
+    {"mediumseagreen", NSVG_RGB(60, 179, 113)},
+    {"mediumslateblue", NSVG_RGB(123, 104, 238)},
+    {"mediumspringgreen", NSVG_RGB(0, 250, 154)},
+    {"mediumturquoise", NSVG_RGB(72, 209, 204)},
+    {"mediumvioletred", NSVG_RGB(199, 21, 133)},
+    {"midnightblue", NSVG_RGB(25, 25, 112)},
+    {"mintcream", NSVG_RGB(245, 255, 250)},
+    {"mistyrose", NSVG_RGB(255, 228, 225)},
+    {"moccasin", NSVG_RGB(255, 228, 181)},
+    {"navajowhite", NSVG_RGB(255, 222, 173)},
+    {"navy", NSVG_RGB(0, 0, 128)},
+    {"oldlace", NSVG_RGB(253, 245, 230)},
+    {"olive", NSVG_RGB(128, 128, 0)},
+    {"olivedrab", NSVG_RGB(107, 142, 35)},
+    {"orange", NSVG_RGB(255, 165, 0)},
+    {"orangered", NSVG_RGB(255, 69, 0)},
+    {"orchid", NSVG_RGB(218, 112, 214)},
+    {"palegoldenrod", NSVG_RGB(238, 232, 170)},
+    {"palegreen", NSVG_RGB(152, 251, 152)},
+    {"paleturquoise", NSVG_RGB(175, 238, 238)},
+    {"palevioletred", NSVG_RGB(219, 112, 147)},
+    {"papayawhip", NSVG_RGB(255, 239, 213)},
+    {"peachpuff", NSVG_RGB(255, 218, 185)},
+    {"peru", NSVG_RGB(205, 133, 63)},
+    {"pink", NSVG_RGB(255, 192, 203)},
+    {"plum", NSVG_RGB(221, 160, 221)},
+    {"powderblue", NSVG_RGB(176, 224, 230)},
+    {"purple", NSVG_RGB(128, 0, 128)},
+    {"rosybrown", NSVG_RGB(188, 143, 143)},
+    {"royalblue", NSVG_RGB(65, 105, 225)},
+    {"saddlebrown", NSVG_RGB(139, 69, 19)},
+    {"salmon", NSVG_RGB(250, 128, 114)},
+    {"sandybrown", NSVG_RGB(244, 164, 96)},
+    {"seagreen", NSVG_RGB(46, 139, 87)},
+    {"seashell", NSVG_RGB(255, 245, 238)},
+    {"sienna", NSVG_RGB(160, 82, 45)},
+    {"silver", NSVG_RGB(192, 192, 192)},
+    {"skyblue", NSVG_RGB(135, 206, 235)},
+    {"slateblue", NSVG_RGB(106, 90, 205)},
+    {"slategray", NSVG_RGB(112, 128, 144)},
+    {"slategrey", NSVG_RGB(112, 128, 144)},
+    {"snow", NSVG_RGB(255, 250, 250)},
+    {"springgreen", NSVG_RGB(0, 255, 127)},
+    {"steelblue", NSVG_RGB(70, 130, 180)},
+    {"tan", NSVG_RGB(210, 180, 140)},
+    {"teal", NSVG_RGB(0, 128, 128)},
+    {"thistle", NSVG_RGB(216, 191, 216)},
+    {"tomato", NSVG_RGB(255, 99, 71)},
+    {"turquoise", NSVG_RGB(64, 224, 208)},
+    {"violet", NSVG_RGB(238, 130, 238)},
+    {"wheat", NSVG_RGB(245, 222, 179)},
+    {"whitesmoke", NSVG_RGB(245, 245, 245)},
+    {"yellowgreen", NSVG_RGB(154, 205, 50)},
 #endif
 };
 
-static unsigned int nsvg__parseColorName(const char* str)
-{
-       int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor);
-
-       for (i = 0; i < ncolors; i++) {
-               if (strcmp(nsvg__colors[i].name, str) == 0) {
-                       return nsvg__colors[i].color;
-               }
-       }
-
-       return NSVG_RGB(128, 128, 128);
-}
-
-static unsigned int nsvg__parseColor(const char* str)
-{
-       size_t len = 0;
-       while(*str == ' ') ++str;
-       len = strlen(str);
-       if (len >= 1 && *str == '#')
-               return nsvg__parseColorHex(str);
-       else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(')
-               return nsvg__parseColorRGB(str);
-       return nsvg__parseColorName(str);
-}
-
-static float nsvg__parseOpacity(const char* str)
-{
-       float val = 0;
-       sscanf(str, "%f", &val);
-       if (val < 0.0f) val = 0.0f;
-       if (val > 1.0f) val = 1.0f;
-       return val;
-}
-
-static float nsvg__parseMiterLimit(const char* str)
-{
-       float val = 0;
-       sscanf(str, "%f", &val);
-       if (val < 0.0f) val = 0.0f;
-       return val;
-}
-
-static int nsvg__parseUnits(const char* units)
-{
-       if (units[0] == 'p' && units[1] == 'x')
-               return NSVG_UNITS_PX;
-       else if (units[0] == 'p' && units[1] == 't')
-               return NSVG_UNITS_PT;
-       else if (units[0] == 'p' && units[1] == 'c')
-               return NSVG_UNITS_PC;
-       else if (units[0] == 'm' && units[1] == 'm')
-               return NSVG_UNITS_MM;
-       else if (units[0] == 'c' && units[1] == 'm')
-               return NSVG_UNITS_CM;
-       else if (units[0] == 'i' && units[1] == 'n')
-               return NSVG_UNITS_IN;
-       else if (units[0] == '%')
-               return NSVG_UNITS_PERCENT;
-       else if (units[0] == 'e' && units[1] == 'm')
-               return NSVG_UNITS_EM;
-       else if (units[0] == 'e' && units[1] == 'x')
-               return NSVG_UNITS_EX;
-       return NSVG_UNITS_USER;
-}
-
-static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
-{
-       NSVGcoordinate coord = {0, NSVG_UNITS_USER};
-       char units[32]="";
-       sscanf(str, "%f%31s", &coord.value, units);
-       coord.units = nsvg__parseUnits(units);
-       return coord;
-}
-
-static NSVGcoordinate nsvg__coord(float v, int units)
-{
-       NSVGcoordinate coord = {v, units};
-       return coord;
-}
-
-static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length)
-{
-       NSVGcoordinate coord = nsvg__parseCoordinateRaw(str);
-       return nsvg__convertToPixels(p, coord, orig, length);
-}
-
-static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int* na)
-{
-       const char* end;
-       const char* ptr;
-       char it[64];
-
-       *na = 0;
-       ptr = str;
-       while (*ptr && *ptr != '(') ++ptr;
-       if (*ptr == 0)
-               return 1;
-       end = ptr;
-       while (*end && *end != ')') ++end;
-       if (*end == 0)
-               return 1;
-
-       while (ptr < end) {
-               if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) {
-                       if (*na >= maxNa) return 0;
-                       ptr = nsvg__parseNumber(ptr, it, 64);
-                       args[(*na)++] = (float)nsvg__atof(it);
-               } else {
-                       ++ptr;
-               }
-       }
-       return (int)(end - str);
-}
-
-
-static int nsvg__parseMatrix(float* xform, const char* str)
-{
-       float t[6];
-       int na = 0;
-       int len = nsvg__parseTransformArgs(str, t, 6, &na);
-       if (na != 6) return len;
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseTranslate(float* xform, const char* str)
-{
-       float args[2];
-       float t[6];
-       int na = 0;
-       int len = nsvg__parseTransformArgs(str, args, 2, &na);
-       if (na == 1) args[1] = 0.0;
-
-       nsvg__xformSetTranslation(t, args[0], args[1]);
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseScale(float* xform, const char* str)
-{
-       float args[2];
-       int na = 0;
-       float t[6];
-       int len = nsvg__parseTransformArgs(str, args, 2, &na);
-       if (na == 1) args[1] = args[0];
-       nsvg__xformSetScale(t, args[0], args[1]);
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseSkewX(float* xform, const char* str)
-{
-       float args[1];
-       int na = 0;
-       float t[6];
-       int len = nsvg__parseTransformArgs(str, args, 1, &na);
-       nsvg__xformSetSkewX(t, args[0]/180.0f*NSVG_PI);
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseSkewY(float* xform, const char* str)
-{
-       float args[1];
-       int na = 0;
-       float t[6];
-       int len = nsvg__parseTransformArgs(str, args, 1, &na);
-       nsvg__xformSetSkewY(t, args[0]/180.0f*NSVG_PI);
-       memcpy(xform, t, sizeof(float)*6);
-       return len;
-}
-
-static int nsvg__parseRotate(float* xform, const char* str)
-{
-       float args[3];
-       int na = 0;
-       float m[6];
-       float t[6];
-       int len = nsvg__parseTransformArgs(str, args, 3, &na);
-       if (na == 1)
-               args[1] = args[2] = 0.0f;
-       nsvg__xformIdentity(m);
-
-       if (na > 1) {
-               nsvg__xformSetTranslation(t, -args[1], -args[2]);
-               nsvg__xformMultiply(m, t);
-       }
-
-       nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI);
-       nsvg__xformMultiply(m, t);
-
-       if (na > 1) {
-               nsvg__xformSetTranslation(t, args[1], args[2]);
-               nsvg__xformMultiply(m, t);
-       }
-
-       memcpy(xform, m, sizeof(float)*6);
-
-       return len;
-}
-
-static void nsvg__parseTransform(float* xform, const char* str)
-{
-       float t[6];
-       nsvg__xformIdentity(xform);
-       while (*str)
-       {
-               if (strncmp(str, "matrix", 6) == 0)
-                       str += nsvg__parseMatrix(t, str);
-               else if (strncmp(str, "translate", 9) == 0)
-                       str += nsvg__parseTranslate(t, str);
-               else if (strncmp(str, "scale", 5) == 0)
-                       str += nsvg__parseScale(t, str);
-               else if (strncmp(str, "rotate", 6) == 0)
-                       str += nsvg__parseRotate(t, str);
-               else if (strncmp(str, "skewX", 5) == 0)
-                       str += nsvg__parseSkewX(t, str);
-               else if (strncmp(str, "skewY", 5) == 0)
-                       str += nsvg__parseSkewY(t, str);
-               else{
-                       ++str;
-                       continue;
-               }
-
-               nsvg__xformPremultiply(xform, t);
-       }
-}
-
-static void nsvg__parseUrl(char* id, const char* str)
-{
-       int i = 0;
-       str += 4; // "url(";
-       if (*str == '#')
-               str++;
-       while (i < 63 && *str != ')') {
-               id[i] = *str++;
-               i++;
-       }
-       id[i] = '\0';
-}
-
-static char nsvg__parseLineCap(const char* str)
-{
-       if (strcmp(str, "butt") == 0)
-               return NSVG_CAP_BUTT;
-       else if (strcmp(str, "round") == 0)
-               return NSVG_CAP_ROUND;
-       else if (strcmp(str, "square") == 0)
-               return NSVG_CAP_SQUARE;
-       // TODO: handle inherit.
-       return NSVG_CAP_BUTT;
-}
-
-static char nsvg__parseLineJoin(const char* str)
-{
-       if (strcmp(str, "miter") == 0)
-               return NSVG_JOIN_MITER;
-       else if (strcmp(str, "round") == 0)
-               return NSVG_JOIN_ROUND;
-       else if (strcmp(str, "bevel") == 0)
-               return NSVG_JOIN_BEVEL;
-       // TODO: handle inherit.
-       return NSVG_JOIN_MITER;
-}
-
-static char nsvg__parseFillRule(const char* str)
-{
-       if (strcmp(str, "nonzero") == 0)
-               return NSVG_FILLRULE_NONZERO;
-       else if (strcmp(str, "evenodd") == 0)
-               return NSVG_FILLRULE_EVENODD;
-       // TODO: handle inherit.
-       return NSVG_FILLRULE_NONZERO;
-}
-
-static const char* nsvg__getNextDashItem(const char* s, char* it)
-{
-       int n = 0;
-       it[0] = '\0';
-       // Skip white spaces and commas
-       while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
-       // Advance until whitespace, comma or end.
-       while (*s && (!nsvg__isspace(*s) && *s != ',')) {
-               if (n < 63)
-                       it[n++] = *s;
-               s++;
-       }
-       it[n++] = '\0';
-       return s;
-}
-
-static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray)
-{
-       char item[64];
-       int count = 0, i;
-       float sum = 0.0f;
-
-       // Handle "none"
-       if (str[0] == 'n')
-               return 0;
-
-       // Parse dashes
-       while (*str) {
-               str = nsvg__getNextDashItem(str, item);
-               if (!*item) break;
-               if (count < NSVG_MAX_DASHES)
-                       strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
-       }
-
-       for (i = 0; i < count; i++)
-               sum += strokeDashArray[i];
-       if (sum <= 1e-6f)
-               count = 0;
-
-       return count;
-}
-
-static void nsvg__parseStyle(NSVGparser* p, const char* str);
-
-static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
-{
-       float xform[6];
-       NSVGattrib* attr = nsvg__getAttr(p);
-       if (!attr) return 0;
-
-       if (strcmp(name, "style") == 0) {
-               nsvg__parseStyle(p, value);
-       } else if (strcmp(name, "display") == 0) {
-               if (strcmp(value, "none") == 0)
-                       attr->visible = 0;
-               // Don't reset ->visible on display:inline, one display:none hides the whole subtree
-
-       } else if (strcmp(name, "fill") == 0) {
-               if (strcmp(value, "none") == 0) {
-                       attr->hasFill = 0;
-               } else if (strncmp(value, "url(", 4) == 0) {
-                       attr->hasFill = 2;
-                       nsvg__parseUrl(attr->fillGradient, value);
-               } else {
-                       attr->hasFill = 1;
-                       attr->fillColor = nsvg__parseColor(value);
-               }
-       } else if (strcmp(name, "opacity") == 0) {
-               attr->opacity = nsvg__parseOpacity(value);
-       } else if (strcmp(name, "fill-opacity") == 0) {
-               attr->fillOpacity = nsvg__parseOpacity(value);
-       } else if (strcmp(name, "stroke") == 0) {
-               if (strcmp(value, "none") == 0) {
-                       attr->hasStroke = 0;
-               } else if (strncmp(value, "url(", 4) == 0) {
-                       attr->hasStroke = 2;
-                       nsvg__parseUrl(attr->strokeGradient, value);
-               } else {
-                       attr->hasStroke = 1;
-                       attr->strokeColor = nsvg__parseColor(value);
-               }
-       } else if (strcmp(name, "stroke-width") == 0) {
-               attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
-       } else if (strcmp(name, "stroke-dasharray") == 0) {
-               attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray);
-       } else if (strcmp(name, "stroke-dashoffset") == 0) {
-               attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
-       } else if (strcmp(name, "stroke-opacity") == 0) {
-               attr->strokeOpacity = nsvg__parseOpacity(value);
-       } else if (strcmp(name, "stroke-linecap") == 0) {
-               attr->strokeLineCap = nsvg__parseLineCap(value);
-       } else if (strcmp(name, "stroke-linejoin") == 0) {
-               attr->strokeLineJoin = nsvg__parseLineJoin(value);
-       } else if (strcmp(name, "stroke-miterlimit") == 0) {
-               attr->miterLimit = nsvg__parseMiterLimit(value);
-       } else if (strcmp(name, "fill-rule") == 0) {
-               attr->fillRule = nsvg__parseFillRule(value);
-       } else if (strcmp(name, "font-size") == 0) {
-               attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
-       } else if (strcmp(name, "transform") == 0) {
-               nsvg__parseTransform(xform, value);
-               nsvg__xformPremultiply(attr->xform, xform);
-       } else if (strcmp(name, "stop-color") == 0) {
-               attr->stopColor = nsvg__parseColor(value);
-       } else if (strcmp(name, "stop-opacity") == 0) {
-               attr->stopOpacity = nsvg__parseOpacity(value);
-       } else if (strcmp(name, "offset") == 0) {
-               attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f);
-       } else if (strcmp(name, "id") == 0) {
-               strncpy(attr->id, value, 63);
-               attr->id[63] = '\0';
-       } else {
-               return 0;
-       }
-       return 1;
-}
-
-static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end)
-{
-       const char* str;
-       const char* val;
-       char name[512];
-       char value[512];
-       int n;
-
-       str = start;
-       while (str < end && *str != ':') ++str;
-
-       val = str;
-
-       // Right Trim
-       while (str > start &&  (*str == ':' || nsvg__isspace(*str))) --str;
-       ++str;
-
-       n = (int)(str - start);
-       if (n > 511) n = 511;
-       if (n) memcpy(name, start, n);
-       name[n] = 0;
-
-       while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val;
-
-       n = (int)(end - val);
-       if (n > 511) n = 511;
-       if (n) memcpy(value, val, n);
-       value[n] = 0;
-
-       return nsvg__parseAttr(p, name, value);
-}
-
-static void nsvg__parseStyle(NSVGparser* p, const char* str)
-{
-       const char* start;
-       const char* end;
-
-       while (*str) {
-               // Left Trim
-               while(*str && nsvg__isspace(*str)) ++str;
-               start = str;
-               while(*str && *str != ';') ++str;
-               end = str;
-
-               // Right Trim
-               while (end > start &&  (*end == ';' || nsvg__isspace(*end))) --end;
-               ++end;
-
-               nsvg__parseNameValue(p, start, end);
-               if (*str) ++str;
-       }
-}
-
-static void nsvg__parseAttribs(NSVGparser* p, const char** attr)
-{
-       int i;
-       for (i = 0; attr[i]; i += 2)
-       {
-               if (strcmp(attr[i], "style") == 0)
-                       nsvg__parseStyle(p, attr[i + 1]);
-               else
-                       nsvg__parseAttr(p, attr[i], attr[i + 1]);
-       }
-}
-
-static int nsvg__getArgsPerElement(char cmd)
-{
-       switch (cmd) {
-               case 'v':
-               case 'V':
-               case 'h':
-               case 'H':
-                       return 1;
-               case 'm':
-               case 'M':
-               case 'l':
-               case 'L':
-               case 't':
-               case 'T':
-                       return 2;
-               case 'q':
-               case 'Q':
-               case 's':
-               case 'S':
-                       return 4;
-               case 'c':
-               case 'C':
-                       return 6;
-               case 'a':
-               case 'A':
-                       return 7;
-       }
-       return 0;
-}
-
-static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       if (rel) {
-               *cpx += args[0];
-               *cpy += args[1];
-       } else {
-               *cpx = args[0];
-               *cpy = args[1];
-       }
-       nsvg__moveTo(p, *cpx, *cpy);
-}
-
-static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       if (rel) {
-               *cpx += args[0];
-               *cpy += args[1];
-       } else {
-               *cpx = args[0];
-               *cpy = args[1];
-       }
-       nsvg__lineTo(p, *cpx, *cpy);
-}
-
-static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       if (rel)
-               *cpx += args[0];
-       else
-               *cpx = args[0];
-       nsvg__lineTo(p, *cpx, *cpy);
-}
-
-static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       if (rel)
-               *cpy += args[0];
-       else
-               *cpy = args[0];
-       nsvg__lineTo(p, *cpx, *cpy);
-}
-
-static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy,
-                                                                float* cpx2, float* cpy2, float* args, int rel)
-{
-       float x2, y2, cx1, cy1, cx2, cy2;
-
-       if (rel) {
-               cx1 = *cpx + args[0];
-               cy1 = *cpy + args[1];
-               cx2 = *cpx + args[2];
-               cy2 = *cpy + args[3];
-               x2 = *cpx + args[4];
-               y2 = *cpy + args[5];
-       } else {
-               cx1 = args[0];
-               cy1 = args[1];
-               cx2 = args[2];
-               cy2 = args[3];
-               x2 = args[4];
-               y2 = args[5];
-       }
-
-       nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);
-
-       *cpx2 = cx2;
-       *cpy2 = cy2;
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy,
-                                                                         float* cpx2, float* cpy2, float* args, int rel)
-{
-       float x1, y1, x2, y2, cx1, cy1, cx2, cy2;
-
-       x1 = *cpx;
-       y1 = *cpy;
-       if (rel) {
-               cx2 = *cpx + args[0];
-               cy2 = *cpy + args[1];
-               x2 = *cpx + args[2];
-               y2 = *cpy + args[3];
-       } else {
-               cx2 = args[0];
-               cy2 = args[1];
-               x2 = args[2];
-               y2 = args[3];
-       }
-
-       cx1 = 2*x1 - *cpx2;
-       cy1 = 2*y1 - *cpy2;
-
-       nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);
-
-       *cpx2 = cx2;
-       *cpy2 = cy2;
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy,
-                                                               float* cpx2, float* cpy2, float* args, int rel)
-{
-       float x1, y1, x2, y2, cx, cy;
-       float cx1, cy1, cx2, cy2;
-
-       x1 = *cpx;
-       y1 = *cpy;
-       if (rel) {
-               cx = *cpx + args[0];
-               cy = *cpy + args[1];
-               x2 = *cpx + args[2];
-               y2 = *cpy + args[3];
-       } else {
-               cx = args[0];
-               cy = args[1];
-               x2 = args[2];
-               y2 = args[3];
-       }
-
-       // Convert to cubic bezier
-       cx1 = x1 + 2.0f/3.0f*(cx - x1);
-       cy1 = y1 + 2.0f/3.0f*(cy - y1);
-       cx2 = x2 + 2.0f/3.0f*(cx - x2);
-       cy2 = y2 + 2.0f/3.0f*(cy - y2);
-
-       nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);
-
-       *cpx2 = cx;
-       *cpy2 = cy;
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy,
-                                                                        float* cpx2, float* cpy2, float* args, int rel)
-{
-       float x1, y1, x2, y2, cx, cy;
-       float cx1, cy1, cx2, cy2;
-
-       x1 = *cpx;
-       y1 = *cpy;
-       if (rel) {
-               x2 = *cpx + args[0];
-               y2 = *cpy + args[1];
-       } else {
-               x2 = args[0];
-               y2 = args[1];
-       }
-
-       cx = 2*x1 - *cpx2;
-       cy = 2*y1 - *cpy2;
-
-       // Convert to cubix bezier
-       cx1 = x1 + 2.0f/3.0f*(cx - x1);
-       cy1 = y1 + 2.0f/3.0f*(cy - y1);
-       cx2 = x2 + 2.0f/3.0f*(cx - x2);
-       cy2 = y2 + 2.0f/3.0f*(cy - y2);
-
-       nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);
-
-       *cpx2 = cx;
-       *cpy2 = cy;
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static float nsvg__sqr(float x) { return x*x; }
-static float nsvg__vmag(float x, float y) { return sqrtf(x*x + y*y); }
-
-static float nsvg__vecrat(float ux, float uy, float vx, float vy)
-{
-       return (ux*vx + uy*vy) / (nsvg__vmag(ux,uy) * nsvg__vmag(vx,vy));
-}
-
-static float nsvg__vecang(float ux, float uy, float vx, float vy)
-{
-       float r = nsvg__vecrat(ux,uy, vx,vy);
-       if (r < -1.0f) r = -1.0f;
-       if (r > 1.0f) r = 1.0f;
-       return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r);
-}
-
-static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
-{
-       // Ported from canvg (https://code.google.com/p/canvg/)
-       float rx, ry, rotx;
-       float x1, y1, x2, y2, cx, cy, dx, dy, d;
-       float x1p, y1p, cxp, cyp, s, sa, sb;
-       float ux, uy, vx, vy, a1, da;
-       float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6];
-       float sinrx, cosrx;
-       int fa, fs;
-       int i, ndivs;
-       float hda, kappa;
-
-       rx = fabsf(args[0]);                            // y radius
-       ry = fabsf(args[1]);                            // x radius
-       rotx = args[2] / 180.0f * NSVG_PI;              // x rotation angle
-       fa = fabsf(args[3]) > 1e-6 ? 1 : 0;     // Large arc
-       fs = fabsf(args[4]) > 1e-6 ? 1 : 0;     // Sweep direction
-       x1 = *cpx;                                                      // start point
-       y1 = *cpy;
-       if (rel) {                                                      // end point
-               x2 = *cpx + args[5];
-               y2 = *cpy + args[6];
-       } else {
-               x2 = args[5];
-               y2 = args[6];
-       }
-
-       dx = x1 - x2;
-       dy = y1 - y2;
-       d = sqrtf(dx*dx + dy*dy);
-       if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
-               // The arc degenerates to a line
-               nsvg__lineTo(p, x2, y2);
-               *cpx = x2;
-               *cpy = y2;
-               return;
-       }
-
-       sinrx = sinf(rotx);
-       cosrx = cosf(rotx);
-
-       // Convert to center point parameterization.
-       // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
-       // 1) Compute x1', y1'
-       x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
-       y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
-       d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry);
-       if (d > 1) {
-               d = sqrtf(d);
-               rx *= d;
-               ry *= d;
-       }
-       // 2) Compute cx', cy'
-       s = 0.0f;
-       sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p);
-       sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p);
-       if (sa < 0.0f) sa = 0.0f;
-       if (sb > 0.0f)
-               s = sqrtf(sa / sb);
-       if (fa == fs)
-               s = -s;
-       cxp = s * rx * y1p / ry;
-       cyp = s * -ry * x1p / rx;
-
-       // 3) Compute cx,cy from cx',cy'
-       cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp;
-       cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp;
-
-       // 4) Calculate theta1, and delta theta.
-       ux = (x1p - cxp) / rx;
-       uy = (y1p - cyp) / ry;
-       vx = (-x1p - cxp) / rx;
-       vy = (-y1p - cyp) / ry;
-       a1 = nsvg__vecang(1.0f,0.0f, ux,uy);    // Initial angle
-       da = nsvg__vecang(ux,uy, vx,vy);                // Delta angle
-
-//     if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
-//     if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;
-
-       if (fs == 0 && da > 0)
-               da -= 2 * NSVG_PI;
-       else if (fs == 1 && da < 0)
-               da += 2 * NSVG_PI;
-
-       // Approximate the arc using cubic spline segments.
-       t[0] = cosrx; t[1] = sinrx;
-       t[2] = -sinrx; t[3] = cosrx;
-       t[4] = cx; t[5] = cy;
-
-       // Split arc into max 90 degree segments.
-       // The loop assumes an iteration per end point (including start and end), this +1.
-       ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f);
-       hda = (da / (float)ndivs) / 2.0f;
-       kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
-       if (da < 0.0f)
-               kappa = -kappa;
-
-       for (i = 0; i <= ndivs; i++) {
-               a = a1 + da * ((float)i/(float)ndivs);
-               dx = cosf(a);
-               dy = sinf(a);
-               nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position
-               nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent
-               if (i > 0)
-                       nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y);
-               px = x;
-               py = y;
-               ptanx = tanx;
-               ptany = tany;
-       }
-
-       *cpx = x2;
-       *cpy = y2;
-}
-
-static void nsvg__parsePath(NSVGparser* p, const char** attr)
-{
-       const char* s = NULL;
-       char cmd = '\0';
-       float args[10];
-       int nargs;
-       int rargs = 0;
-       float cpx, cpy, cpx2, cpy2;
-       const char* tmp[4];
-       char closedFlag;
-       int i;
-       char item[64];
-
-       for (i = 0; attr[i]; i += 2) {
-               if (strcmp(attr[i], "d") == 0) {
-                       s = attr[i + 1];
-               } else {
-                       tmp[0] = attr[i];
-                       tmp[1] = attr[i + 1];
-                       tmp[2] = 0;
-                       tmp[3] = 0;
-                       nsvg__parseAttribs(p, tmp);
-               }
-       }
-
-       if (s) {
-               nsvg__resetPath(p);
-               cpx = 0; cpy = 0;
-               cpx2 = 0; cpy2 = 0;
-               closedFlag = 0;
-               nargs = 0;
-
-               while (*s) {
-                       s = nsvg__getNextPathItem(s, item);
-                       if (!*item) break;
-                       if (nsvg__isnum(item[0])) {
-                               if (nargs < 10)
-                                       args[nargs++] = (float)nsvg__atof(item);
-                               if (nargs >= rargs) {
-                                       switch (cmd) {
-                                               case 'm':
-                                               case 'M':
-                                                       nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0);
-                                                       // Moveto can be followed by multiple coordinate pairs,
-                                                       // which should be treated as linetos.
-                                                       cmd = (cmd == 'm') ? 'l' : 'L';
-                                                       rargs = nsvg__getArgsPerElement(cmd);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               case 'l':
-                                               case 'L':
-                                                       nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               case 'H':
-                                               case 'h':
-                                                       nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               case 'V':
-                                               case 'v':
-                                                       nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               case 'C':
-                                               case 'c':
-                                                       nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0);
-                                                       break;
-                                               case 'S':
-                                               case 's':
-                                                       nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0);
-                                                       break;
-                                               case 'Q':
-                                               case 'q':
-                                                       nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0);
-                                                       break;
-                                               case 'T':
-                                               case 't':
-                                                       nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0);
-                                                       break;
-                                               case 'A':
-                                               case 'a':
-                                                       nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0);
-                                                       cpx2 = cpx; cpy2 = cpy;
-                                                       break;
-                                               default:
-                                                       if (nargs >= 2) {
-                                                               cpx = args[nargs-2];
-                                                               cpy = args[nargs-1];
-                                                               cpx2 = cpx; cpy2 = cpy;
-                                                       }
-                                                       break;
-                                       }
-                                       nargs = 0;
-                               }
-                       } else {
-                               cmd = item[0];
-                               rargs = nsvg__getArgsPerElement(cmd);
-                               if (cmd == 'M' || cmd == 'm') {
-                                       // Commit path.
-                                       if (p->npts > 0)
-                                               nsvg__addPath(p, closedFlag);
-                                       // Start new subpath.
-                                       nsvg__resetPath(p);
-                                       closedFlag = 0;
-                                       nargs = 0;
-                               } else if (cmd == 'Z' || cmd == 'z') {
-                                       closedFlag = 1;
-                                       // Commit path.
-                                       if (p->npts > 0) {
-                                               // Move current point to first point
-                                               cpx = p->pts[0];
-                                               cpy = p->pts[1];
-                                               cpx2 = cpx; cpy2 = cpy;
-                                               nsvg__addPath(p, closedFlag);
-                                       }
-                                       // Start new subpath.
-                                       nsvg__resetPath(p);
-                                       nsvg__moveTo(p, cpx, cpy);
-                                       closedFlag = 0;
-                                       nargs = 0;
-                               }
-                       }
-               }
-               // Commit path.
-               if (p->npts)
-                       nsvg__addPath(p, closedFlag);
-       }
-
-       nsvg__addShape(p);
-}
-
-static void nsvg__parseRect(NSVGparser* p, const char** attr)
-{
-       float x = 0.0f;
-       float y = 0.0f;
-       float w = 0.0f;
-       float h = 0.0f;
-       float rx = -1.0f; // marks not set
-       float ry = -1.0f;
-       int i;
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)));
-                       if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)));
-               }
-       }
-
-       if (rx < 0.0f && ry > 0.0f) rx = ry;
-       if (ry < 0.0f && rx > 0.0f) ry = rx;
-       if (rx < 0.0f) rx = 0.0f;
-       if (ry < 0.0f) ry = 0.0f;
-       if (rx > w/2.0f) rx = w/2.0f;
-       if (ry > h/2.0f) ry = h/2.0f;
-
-       if (w != 0.0f && h != 0.0f) {
-               nsvg__resetPath(p);
-
-               if (rx < 0.00001f || ry < 0.0001f) {
-                       nsvg__moveTo(p, x, y);
-                       nsvg__lineTo(p, x+w, y);
-                       nsvg__lineTo(p, x+w, y+h);
-                       nsvg__lineTo(p, x, y+h);
-               } else {
-                       // Rounded rectangle
-                       nsvg__moveTo(p, x+rx, y);
-                       nsvg__lineTo(p, x+w-rx, y);
-                       nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry);
-                       nsvg__lineTo(p, x+w, y+h-ry);
-                       nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h);
-                       nsvg__lineTo(p, x+rx, y+h);
-                       nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry);
-                       nsvg__lineTo(p, x, y+ry);
-                       nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y);
-               }
-
-               nsvg__addPath(p, 1);
-
-               nsvg__addShape(p);
-       }
-}
-
-static void nsvg__parseCircle(NSVGparser* p, const char** attr)
-{
-       float cx = 0.0f;
-       float cy = 0.0f;
-       float r = 0.0f;
-       int i;
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p)));
-               }
-       }
-
-       if (r > 0.0f) {
-               nsvg__resetPath(p);
-
-               nsvg__moveTo(p, cx+r, cy);
-               nsvg__cubicBezTo(p, cx+r, cy+r*NSVG_KAPPA90, cx+r*NSVG_KAPPA90, cy+r, cx, cy+r);
-               nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy);
-               nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r);
-               nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy);
-
-               nsvg__addPath(p, 1);
-
-               nsvg__addShape(p);
-       }
-}
-
-static void nsvg__parseEllipse(NSVGparser* p, const char** attr)
-{
-       float cx = 0.0f;
-       float cy = 0.0f;
-       float rx = 0.0f;
-       float ry = 0.0f;
-       int i;
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)));
-                       if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)));
-               }
-       }
-
-       if (rx > 0.0f && ry > 0.0f) {
-
-               nsvg__resetPath(p);
-
-               nsvg__moveTo(p, cx+rx, cy);
-               nsvg__cubicBezTo(p, cx+rx, cy+ry*NSVG_KAPPA90, cx+rx*NSVG_KAPPA90, cy+ry, cx, cy+ry);
-               nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy);
-               nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry);
-               nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy);
-
-               nsvg__addPath(p, 1);
-
-               nsvg__addShape(p);
-       }
-}
-
-static void nsvg__parseLine(NSVGparser* p, const char** attr)
-{
-       float x1 = 0.0;
-       float y1 = 0.0;
-       float x2 = 0.0;
-       float y2 = 0.0;
-       int i;
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-                       if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
-                       if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
-               }
-       }
-
-       nsvg__resetPath(p);
-
-       nsvg__moveTo(p, x1, y1);
-       nsvg__lineTo(p, x2, y2);
-
-       nsvg__addPath(p, 0);
-
-       nsvg__addShape(p);
-}
-
-static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag)
-{
-       int i;
-       const char* s;
-       float args[2];
-       int nargs, npts = 0;
-       char item[64];
-
-       nsvg__resetPath(p);
-
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "points") == 0) {
-                               s = attr[i + 1];
-                               nargs = 0;
-                               while (*s) {
-                                       s = nsvg__getNextPathItem(s, item);
-                                       args[nargs++] = (float)nsvg__atof(item);
-                                       if (nargs >= 2) {
-                                               if (npts == 0)
-                                                       nsvg__moveTo(p, args[0], args[1]);
-                                               else
-                                                       nsvg__lineTo(p, args[0], args[1]);
-                                               nargs = 0;
-                                               npts++;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       nsvg__addPath(p, (char)closeFlag);
-
-       nsvg__addShape(p);
-}
-
-static void nsvg__parseSVG(NSVGparser* p, const char** attr)
-{
-       int i;
-       for (i = 0; attr[i]; i += 2) {
-               if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "width") == 0) {
-                               p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
-                       } else if (strcmp(attr[i], "height") == 0) {
-                               p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
-                       } else if (strcmp(attr[i], "viewBox") == 0) {
-                               sscanf(attr[i + 1], "%f%*[%%, \t]%f%*[%%, \t]%f%*[%%, \t]%f", &p->viewMinx, &p->viewMiny, &p->viewWidth, &p->viewHeight);
-                       } else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
-                               if (strstr(attr[i + 1], "none") != 0) {
-                                       // No uniform scaling
-                                       p->alignType = NSVG_ALIGN_NONE;
-                               } else {
-                                       // Parse X align
-                                       if (strstr(attr[i + 1], "xMin") != 0)
-                                               p->alignX = NSVG_ALIGN_MIN;
-                                       else if (strstr(attr[i + 1], "xMid") != 0)
-                                               p->alignX = NSVG_ALIGN_MID;
-                                       else if (strstr(attr[i + 1], "xMax") != 0)
-                                               p->alignX = NSVG_ALIGN_MAX;
-                                       // Parse X align
-                                       if (strstr(attr[i + 1], "yMin") != 0)
-                                               p->alignY = NSVG_ALIGN_MIN;
-                                       else if (strstr(attr[i + 1], "yMid") != 0)
-                                               p->alignY = NSVG_ALIGN_MID;
-                                       else if (strstr(attr[i + 1], "yMax") != 0)
-                                               p->alignY = NSVG_ALIGN_MAX;
-                                       // Parse meet/slice
-                                       p->alignType = NSVG_ALIGN_MEET;
-                                       if (strstr(attr[i + 1], "slice") != 0)
-                                               p->alignType = NSVG_ALIGN_SLICE;
-                               }
-                       }
-               }
-       }
-}
-
-static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type)
-{
-       int i;
-       NSVGgradientData* grad = (NSVGgradientData*)malloc(sizeof(NSVGgradientData));
-       if (grad == NULL) return;
-       memset(grad, 0, sizeof(NSVGgradientData));
-       grad->units = NSVG_OBJECT_SPACE;
-       grad->type = type;
-       if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) {
-               grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
-               grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
-               grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT);
-               grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
-       } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) {
-               grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
-               grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
-               grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
-       }
-
-       nsvg__xformIdentity(grad->xform);
-
-       for (i = 0; attr[i]; i += 2) {
-               if (strcmp(attr[i], "id") == 0) {
-                       strncpy(grad->id, attr[i+1], 63);
-                       grad->id[63] = '\0';
-               } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
-                       if (strcmp(attr[i], "gradientUnits") == 0) {
-                               if (strcmp(attr[i+1], "objectBoundingBox") == 0)
-                                       grad->units = NSVG_OBJECT_SPACE;
-                               else
-                                       grad->units = NSVG_USER_SPACE;
-                       } else if (strcmp(attr[i], "gradientTransform") == 0) {
-                               nsvg__parseTransform(grad->xform, attr[i + 1]);
-                       } else if (strcmp(attr[i], "cx") == 0) {
-                               grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "cy") == 0) {
-                               grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "r") == 0) {
-                               grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "fx") == 0) {
-                               grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "fy") == 0) {
-                               grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "x1") == 0) {
-                               grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "y1") == 0) {
-                               grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "x2") == 0) {
-                               grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "y2") == 0) {
-                               grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]);
-                       } else if (strcmp(attr[i], "spreadMethod") == 0) {
-                               if (strcmp(attr[i+1], "pad") == 0)
-                                       grad->spread = NSVG_SPREAD_PAD;
-                               else if (strcmp(attr[i+1], "reflect") == 0)
-                                       grad->spread = NSVG_SPREAD_REFLECT;
-                               else if (strcmp(attr[i+1], "repeat") == 0)
-                                       grad->spread = NSVG_SPREAD_REPEAT;
-                       } else if (strcmp(attr[i], "xlink:href") == 0) {
-                               const char *href = attr[i+1];
-                               strncpy(grad->ref, href+1, 62);
-                               grad->ref[62] = '\0';
-                       }
-               }
-       }
-
-       grad->next = p->gradients;
-       p->gradients = grad;
-}
-
-static void nsvg__parseGradientStop(NSVGparser* p, const char** attr)
-{
-       NSVGattrib* curAttr = nsvg__getAttr(p);
-       NSVGgradientData* grad;
-       NSVGgradientStop* stop;
-       int i, idx;
-
-       curAttr->stopOffset = 0;
-       curAttr->stopColor = 0;
-       curAttr->stopOpacity = 1.0f;
-
-       for (i = 0; attr[i]; i += 2) {
-               nsvg__parseAttr(p, attr[i], attr[i + 1]);
-       }
-
-       // Add stop to the last gradient.
-       grad = p->gradients;
-       if (grad == NULL) return;
-
-       grad->nstops++;
-       grad->stops = (NSVGgradientStop*)realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops);
-       if (grad->stops == NULL) return;
-
-       // Insert
-       idx = grad->nstops-1;
-       for (i = 0; i < grad->nstops-1; i++) {
-               if (curAttr->stopOffset < grad->stops[i].offset) {
-                       idx = i;
-                       break;
-               }
-       }
-       if (idx != grad->nstops-1) {
-               for (i = grad->nstops-1; i > idx; i--)
-                       grad->stops[i] = grad->stops[i-1];
-       }
-
-       stop = &grad->stops[idx];
-       stop->color = curAttr->stopColor;
-       stop->color |= (unsigned int)(curAttr->stopOpacity*255) << 24;
-       stop->offset = curAttr->stopOffset;
-}
-
-static void nsvg__startElement(void* ud, const char* el, const char** attr)
-{
-       NSVGparser* p = (NSVGparser*)ud;
-
-       if (p->defsFlag) {
-               // Skip everything but gradients in defs
-               if (strcmp(el, "linearGradient") == 0) {
-                       nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
-               } else if (strcmp(el, "radialGradient") == 0) {
-                       nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
-               } else if (strcmp(el, "stop") == 0) {
-                       nsvg__parseGradientStop(p, attr);
-               }
-               return;
-       }
-
-       if (strcmp(el, "g") == 0) {
-               nsvg__pushAttr(p);
-               nsvg__parseAttribs(p, attr);
-       } else if (strcmp(el, "path") == 0) {
-               if (p->pathFlag)        // Do not allow nested paths.
-                       return;
-               nsvg__pushAttr(p);
-               nsvg__parsePath(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "rect") == 0) {
-               nsvg__pushAttr(p);
-               nsvg__parseRect(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "circle") == 0) {
-               nsvg__pushAttr(p);
-               nsvg__parseCircle(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "ellipse") == 0) {
-               nsvg__pushAttr(p);
-               nsvg__parseEllipse(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "line") == 0)  {
-               nsvg__pushAttr(p);
-               nsvg__parseLine(p, attr);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "polyline") == 0)  {
-               nsvg__pushAttr(p);
-               nsvg__parsePoly(p, attr, 0);
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "polygon") == 0)  {
-               nsvg__pushAttr(p);
-               nsvg__parsePoly(p, attr, 1);
-               nsvg__popAttr(p);
-       } else  if (strcmp(el, "linearGradient") == 0) {
-               nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
-       } else if (strcmp(el, "radialGradient") == 0) {
-               nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
-       } else if (strcmp(el, "stop") == 0) {
-               nsvg__parseGradientStop(p, attr);
-       } else if (strcmp(el, "defs") == 0) {
-               p->defsFlag = 1;
-       } else if (strcmp(el, "svg") == 0) {
-               nsvg__parseSVG(p, attr);
-       }
-}
-
-static void nsvg__endElement(void* ud, const char* el)
-{
-       NSVGparser* p = (NSVGparser*)ud;
-
-       if (strcmp(el, "g") == 0) {
-               nsvg__popAttr(p);
-       } else if (strcmp(el, "path") == 0) {
-               p->pathFlag = 0;
-       } else if (strcmp(el, "defs") == 0) {
-               p->defsFlag = 0;
-       }
-}
-
-static void nsvg__content(void* ud, const char* s)
-{
-       NSVG_NOTUSED(ud);
-       NSVG_NOTUSED(s);
-       // empty
-}
-
-static void nsvg__imageBounds(NSVGparser* p, float* bounds)
-{
-       NSVGshape* shape;
-       shape = p->image->shapes;
-       if (shape == NULL) {
-               bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0;
-               return;
-       }
-       bounds[0] = shape->bounds[0];
-       bounds[1] = shape->bounds[1];
-       bounds[2] = shape->bounds[2];
-       bounds[3] = shape->bounds[3];
-       for (shape = shape->next; shape != NULL; shape = shape->next) {
-               bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]);
-               bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]);
-               bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]);
-               bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]);
-       }
-}
-
-static float nsvg__viewAlign(float content, float container, int type)
-{
-       if (type == NSVG_ALIGN_MIN)
-               return 0;
-       else if (type == NSVG_ALIGN_MAX)
-               return container - content;
-       // mid
-       return (container - content) * 0.5f;
-}
-
-static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy)
-{
-       float t[6];
-       nsvg__xformSetTranslation(t, tx, ty);
-       nsvg__xformMultiply (grad->xform, t);
-
-       nsvg__xformSetScale(t, sx, sy);
-       nsvg__xformMultiply (grad->xform, t);
-}
-
-static void nsvg__scaleToViewbox(NSVGparser* p, const char* units)
-{
-       NSVGshape* shape;
-       NSVGpath* path;
-       float tx, ty, sx, sy, us, bounds[4], t[6], avgs;
-       int i;
-       float* pt;
-
-       // Guess image size if not set completely.
-       nsvg__imageBounds(p, bounds);
-
-       if (p->viewWidth == 0) {
-               if (p->image->width > 0) {
-                       p->viewWidth = p->image->width;
-               } else {
-                       p->viewMinx = bounds[0];
-                       p->viewWidth = bounds[2] - bounds[0];
-               }
-       }
-       if (p->viewHeight == 0) {
-               if (p->image->height > 0) {
-                       p->viewHeight = p->image->height;
-               } else {
-                       p->viewMiny = bounds[1];
-                       p->viewHeight = bounds[3] - bounds[1];
-               }
-       }
-       if (p->image->width == 0)
-               p->image->width = p->viewWidth;
-       if (p->image->height == 0)
-               p->image->height = p->viewHeight;
-
-       tx = -p->viewMinx;
-       ty = -p->viewMiny;
-       sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
-       sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
-       // Unit scaling
-       us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);
-
-       // Fix aspect ratio
-       if (p->alignType == NSVG_ALIGN_MEET) {
-               // fit whole image into viewbox
-               sx = sy = nsvg__minf(sx, sy);
-               tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
-               ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
-       } else if (p->alignType == NSVG_ALIGN_SLICE) {
-               // fill whole viewbox with image
-               sx = sy = nsvg__maxf(sx, sy);
-               tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
-               ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
-       }
-
-       // Transform
-       sx *= us;
-       sy *= us;
-       avgs = (sx+sy) / 2.0f;
-       for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
-               shape->bounds[0] = (shape->bounds[0] + tx) * sx;
-               shape->bounds[1] = (shape->bounds[1] + ty) * sy;
-               shape->bounds[2] = (shape->bounds[2] + tx) * sx;
-               shape->bounds[3] = (shape->bounds[3] + ty) * sy;
-               for (path = shape->paths; path != NULL; path = path->next) {
-                       path->bounds[0] = (path->bounds[0] + tx) * sx;
-                       path->bounds[1] = (path->bounds[1] + ty) * sy;
-                       path->bounds[2] = (path->bounds[2] + tx) * sx;
-                       path->bounds[3] = (path->bounds[3] + ty) * sy;
-                       for (i =0; i < path->npts; i++) {
-                               pt = &path->pts[i*2];
-                               pt[0] = (pt[0] + tx) * sx;
-                               pt[1] = (pt[1] + ty) * sy;
-                       }
-               }
-
-               if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) {
-                       nsvg__scaleGradient(shape->fill.gradient, tx,ty, sx,sy);
-                       memcpy(t, shape->fill.gradient->xform, sizeof(float)*6);
-                       nsvg__xformInverse(shape->fill.gradient->xform, t);
-               }
-               if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) {
-                       nsvg__scaleGradient(shape->stroke.gradient, tx,ty, sx,sy);
-                       memcpy(t, shape->stroke.gradient->xform, sizeof(float)*6);
-                       nsvg__xformInverse(shape->stroke.gradient->xform, t);
-               }
-
-               shape->strokeWidth *= avgs;
-               shape->strokeDashOffset *= avgs;
-               for (i = 0; i < shape->strokeDashCount; i++)
-                       shape->strokeDashArray[i] *= avgs;
-       }
-}
-
-NSVGimage* nsvgParse(char* input, const char* units, float dpi)
-{
-       NSVGparser* p;
-       NSVGimage* ret = 0;
-
-       p = nsvg__createParser();
-       if (p == NULL) {
-               return NULL;
-       }
-       p->dpi = dpi;
-
-       nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p);
-
-       // Scale to viewBox
-       nsvg__scaleToViewbox(p, units);
-
-       ret = p->image;
-       p->image = NULL;
-
-       nsvg__deleteParser(p);
-
-       return ret;
-}
-
-NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi)
-{
-       FILE* fp = NULL;
-       size_t size;
-       char* data = NULL;
-       NSVGimage* image = NULL;
-
-       fp = fopen(filename, "rb");
-       if (!fp) goto error;
-       fseek(fp, 0, SEEK_END);
-       size = ftell(fp);
-       fseek(fp, 0, SEEK_SET);
-       data = (char*)malloc(size+1);
-       if (data == NULL) goto error;
-       if (fread(data, 1, size, fp) != size) goto error;
-       data[size] = '\0';      // Must be null terminated.
-       fclose(fp);
-       image = nsvgParse(data, units, dpi);
-       free(data);
-
-       return image;
+static unsigned int nsvg__parseColorName(const char *str) {
+    int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor);
+
+    for (i = 0; i < ncolors; i++) {
+        if (strcmp(nsvg__colors[i].name, str) == 0) {
+            return nsvg__colors[i].color;
+        }
+    }
+
+    return NSVG_RGB(128, 128, 128);
+}
+
+static unsigned int nsvg__parseColor(const char *str) {
+    size_t len = 0;
+    while (*str == ' ')
+        ++str;
+    len = strlen(str);
+    if (len >= 1 && *str == '#')
+        return nsvg__parseColorHex(str);
+    else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(')
+        return nsvg__parseColorRGB(str);
+    return nsvg__parseColorName(str);
+}
+
+static float nsvg__parseOpacity(const char *str) {
+    float val = 0;
+    sscanf(str, "%f", &val);
+    if (val < 0.0f)
+        val = 0.0f;
+    if (val > 1.0f)
+        val = 1.0f;
+    return val;
+}
+
+static float nsvg__parseMiterLimit(const char *str) {
+    float val = 0;
+    sscanf(str, "%f", &val);
+    if (val < 0.0f)
+        val = 0.0f;
+    return val;
+}
+
+static int nsvg__parseUnits(const char *units) {
+    if (units[0] == 'p' && units[1] == 'x')
+        return NSVG_UNITS_PX;
+    else if (units[0] == 'p' && units[1] == 't')
+        return NSVG_UNITS_PT;
+    else if (units[0] == 'p' && units[1] == 'c')
+        return NSVG_UNITS_PC;
+    else if (units[0] == 'm' && units[1] == 'm')
+        return NSVG_UNITS_MM;
+    else if (units[0] == 'c' && units[1] == 'm')
+        return NSVG_UNITS_CM;
+    else if (units[0] == 'i' && units[1] == 'n')
+        return NSVG_UNITS_IN;
+    else if (units[0] == '%')
+        return NSVG_UNITS_PERCENT;
+    else if (units[0] == 'e' && units[1] == 'm')
+        return NSVG_UNITS_EM;
+    else if (units[0] == 'e' && units[1] == 'x')
+        return NSVG_UNITS_EX;
+    return NSVG_UNITS_USER;
+}
+
+static NSVGcoordinate nsvg__parseCoordinateRaw(const char *str) {
+    NSVGcoordinate coord     = {0, NSVG_UNITS_USER};
+    char           units[32] = "";
+    sscanf(str, "%f%31s", &coord.value, units);
+    coord.units = nsvg__parseUnits(units);
+    return coord;
+}
+
+static NSVGcoordinate nsvg__coord(float v, int units) {
+    NSVGcoordinate coord = {v, units};
+    return coord;
+}
+
+static float nsvg__parseCoordinate(NSVGparser *p, const char *str, float orig, float length) {
+    NSVGcoordinate coord = nsvg__parseCoordinateRaw(str);
+    return nsvg__convertToPixels(p, coord, orig, length);
+}
+
+static int nsvg__parseTransformArgs(const char *str, float *args, int maxNa, int *na) {
+    const char *end;
+    const char *ptr;
+    char        it[64];
+
+    *na = 0;
+    ptr = str;
+    while (*ptr && *ptr != '(')
+        ++ptr;
+    if (*ptr == 0)
+        return 1;
+    end = ptr;
+    while (*end && *end != ')')
+        ++end;
+    if (*end == 0)
+        return 1;
+
+    while (ptr < end) {
+        if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) {
+            if (*na >= maxNa)
+                return 0;
+            ptr           = nsvg__parseNumber(ptr, it, 64);
+            args[(*na)++] = (float)nsvg__atof(it);
+        } else {
+            ++ptr;
+        }
+    }
+    return (int)(end - str);
+}
+
+static int nsvg__parseMatrix(float *xform, const char *str) {
+    float t[6];
+    int   na  = 0;
+    int   len = nsvg__parseTransformArgs(str, t, 6, &na);
+    if (na != 6)
+        return len;
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseTranslate(float *xform, const char *str) {
+    float args[2];
+    float t[6];
+    int   na  = 0;
+    int   len = nsvg__parseTransformArgs(str, args, 2, &na);
+    if (na == 1)
+        args[1] = 0.0;
+
+    nsvg__xformSetTranslation(t, args[0], args[1]);
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseScale(float *xform, const char *str) {
+    float args[2];
+    int   na = 0;
+    float t[6];
+    int   len = nsvg__parseTransformArgs(str, args, 2, &na);
+    if (na == 1)
+        args[1] = args[0];
+    nsvg__xformSetScale(t, args[0], args[1]);
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseSkewX(float *xform, const char *str) {
+    float args[1];
+    int   na = 0;
+    float t[6];
+    int   len = nsvg__parseTransformArgs(str, args, 1, &na);
+    nsvg__xformSetSkewX(t, args[0] / 180.0f * NSVG_PI);
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseSkewY(float *xform, const char *str) {
+    float args[1];
+    int   na = 0;
+    float t[6];
+    int   len = nsvg__parseTransformArgs(str, args, 1, &na);
+    nsvg__xformSetSkewY(t, args[0] / 180.0f * NSVG_PI);
+    memcpy(xform, t, sizeof(float) * 6);
+    return len;
+}
+
+static int nsvg__parseRotate(float *xform, const char *str) {
+    float args[3];
+    int   na = 0;
+    float m[6];
+    float t[6];
+    int   len = nsvg__parseTransformArgs(str, args, 3, &na);
+    if (na == 1)
+        args[1] = args[2] = 0.0f;
+    nsvg__xformIdentity(m);
+
+    if (na > 1) {
+        nsvg__xformSetTranslation(t, -args[1], -args[2]);
+        nsvg__xformMultiply(m, t);
+    }
+
+    nsvg__xformSetRotation(t, args[0] / 180.0f * NSVG_PI);
+    nsvg__xformMultiply(m, t);
+
+    if (na > 1) {
+        nsvg__xformSetTranslation(t, args[1], args[2]);
+        nsvg__xformMultiply(m, t);
+    }
+
+    memcpy(xform, m, sizeof(float) * 6);
+
+    return len;
+}
+
+static void nsvg__parseTransform(float *xform, const char *str) {
+    float t[6];
+    nsvg__xformIdentity(xform);
+    while (*str) {
+        if (strncmp(str, "matrix", 6) == 0)
+            str += nsvg__parseMatrix(t, str);
+        else if (strncmp(str, "translate", 9) == 0)
+            str += nsvg__parseTranslate(t, str);
+        else if (strncmp(str, "scale", 5) == 0)
+            str += nsvg__parseScale(t, str);
+        else if (strncmp(str, "rotate", 6) == 0)
+            str += nsvg__parseRotate(t, str);
+        else if (strncmp(str, "skewX", 5) == 0)
+            str += nsvg__parseSkewX(t, str);
+        else if (strncmp(str, "skewY", 5) == 0)
+            str += nsvg__parseSkewY(t, str);
+        else {
+            ++str;
+            continue;
+        }
+
+        nsvg__xformPremultiply(xform, t);
+    }
+}
+
+static void nsvg__parseUrl(char *id, const char *str) {
+    int i = 0;
+    str += 4; // "url(";
+    if (*str == '#')
+        str++;
+    while (i < 63 && *str != ')') {
+        id[i] = *str++;
+        i++;
+    }
+    id[i] = '\0';
+}
+
+static char nsvg__parseLineCap(const char *str) {
+    if (strcmp(str, "butt") == 0)
+        return NSVG_CAP_BUTT;
+    else if (strcmp(str, "round") == 0)
+        return NSVG_CAP_ROUND;
+    else if (strcmp(str, "square") == 0)
+        return NSVG_CAP_SQUARE;
+    // TODO: handle inherit.
+    return NSVG_CAP_BUTT;
+}
+
+static char nsvg__parseLineJoin(const char *str) {
+    if (strcmp(str, "miter") == 0)
+        return NSVG_JOIN_MITER;
+    else if (strcmp(str, "round") == 0)
+        return NSVG_JOIN_ROUND;
+    else if (strcmp(str, "bevel") == 0)
+        return NSVG_JOIN_BEVEL;
+    // TODO: handle inherit.
+    return NSVG_JOIN_MITER;
+}
+
+static char nsvg__parseFillRule(const char *str) {
+    if (strcmp(str, "nonzero") == 0)
+        return NSVG_FILLRULE_NONZERO;
+    else if (strcmp(str, "evenodd") == 0)
+        return NSVG_FILLRULE_EVENODD;
+    // TODO: handle inherit.
+    return NSVG_FILLRULE_NONZERO;
+}
+
+static const char *nsvg__getNextDashItem(const char *s, char *it) {
+    int n = 0;
+    it[0] = '\0';
+    // Skip white spaces and commas
+    while (*s && (nsvg__isspace(*s) || *s == ','))
+        s++;
+    // Advance until whitespace, comma or end.
+    while (*s && (!nsvg__isspace(*s) && *s != ',')) {
+        if (n < 63)
+            it[n++] = *s;
+        s++;
+    }
+    it[n++] = '\0';
+    return s;
+}
+
+static int nsvg__parseStrokeDashArray(NSVGparser *p, const char *str, float *strokeDashArray) {
+    char  item[64];
+    int   count = 0, i;
+    float sum   = 0.0f;
+
+    // Handle "none"
+    if (str[0] == 'n')
+        return 0;
+
+    // Parse dashes
+    while (*str) {
+        str = nsvg__getNextDashItem(str, item);
+        if (!*item)
+            break;
+        if (count < NSVG_MAX_DASHES)
+            strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
+    }
+
+    for (i = 0; i < count; i++)
+        sum += strokeDashArray[i];
+    if (sum <= 1e-6f)
+        count = 0;
+
+    return count;
+}
+
+static void nsvg__parseStyle(NSVGparser *p, const char *str);
+
+static int nsvg__parseAttr(NSVGparser *p, const char *name, const char *value) {
+    float       xform[6];
+    NSVGattrib *attr = nsvg__getAttr(p);
+    if (!attr)
+        return 0;
+
+    if (strcmp(name, "style") == 0) {
+        nsvg__parseStyle(p, value);
+    } else if (strcmp(name, "display") == 0) {
+        if (strcmp(value, "none") == 0)
+            attr->visible = 0;
+        // Don't reset ->visible on display:inline, one display:none hides the whole subtree
+
+    } else if (strcmp(name, "fill") == 0) {
+        if (strcmp(value, "none") == 0) {
+            attr->hasFill = 0;
+        } else if (strncmp(value, "url(", 4) == 0) {
+            attr->hasFill = 2;
+            nsvg__parseUrl(attr->fillGradient, value);
+        } else {
+            attr->hasFill   = 1;
+            attr->fillColor = nsvg__parseColor(value);
+        }
+    } else if (strcmp(name, "opacity") == 0) {
+        attr->opacity = nsvg__parseOpacity(value);
+    } else if (strcmp(name, "fill-opacity") == 0) {
+        attr->fillOpacity = nsvg__parseOpacity(value);
+    } else if (strcmp(name, "stroke") == 0) {
+        if (strcmp(value, "none") == 0) {
+            attr->hasStroke = 0;
+        } else if (strncmp(value, "url(", 4) == 0) {
+            attr->hasStroke = 2;
+            nsvg__parseUrl(attr->strokeGradient, value);
+        } else {
+            attr->hasStroke   = 1;
+            attr->strokeColor = nsvg__parseColor(value);
+        }
+    } else if (strcmp(name, "stroke-width") == 0) {
+        attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
+    } else if (strcmp(name, "stroke-dasharray") == 0) {
+        attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray);
+    } else if (strcmp(name, "stroke-dashoffset") == 0) {
+        attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
+    } else if (strcmp(name, "stroke-opacity") == 0) {
+        attr->strokeOpacity = nsvg__parseOpacity(value);
+    } else if (strcmp(name, "stroke-linecap") == 0) {
+        attr->strokeLineCap = nsvg__parseLineCap(value);
+    } else if (strcmp(name, "stroke-linejoin") == 0) {
+        attr->strokeLineJoin = nsvg__parseLineJoin(value);
+    } else if (strcmp(name, "stroke-miterlimit") == 0) {
+        attr->miterLimit = nsvg__parseMiterLimit(value);
+    } else if (strcmp(name, "fill-rule") == 0) {
+        attr->fillRule = nsvg__parseFillRule(value);
+    } else if (strcmp(name, "font-size") == 0) {
+        attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
+    } else if (strcmp(name, "transform") == 0) {
+        nsvg__parseTransform(xform, value);
+        nsvg__xformPremultiply(attr->xform, xform);
+    } else if (strcmp(name, "stop-color") == 0) {
+        attr->stopColor = nsvg__parseColor(value);
+    } else if (strcmp(name, "stop-opacity") == 0) {
+        attr->stopOpacity = nsvg__parseOpacity(value);
+    } else if (strcmp(name, "offset") == 0) {
+        attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f);
+    } else if (strcmp(name, "id") == 0) {
+        strncpy(attr->id, value, 63);
+        attr->id[63] = '\0';
+    } else {
+        return 0;
+    }
+    return 1;
+}
+
+static int nsvg__parseNameValue(NSVGparser *p, const char *start, const char *end) {
+    const char *str;
+    const char *val;
+    char        name[512];
+    char        value[512];
+    int         n;
+
+    str = start;
+    while (str < end && *str != ':')
+        ++str;
+
+    val = str;
+
+    // Right Trim
+    while (str > start && (*str == ':' || nsvg__isspace(*str)))
+        --str;
+    ++str;
+
+    n = (int)(str - start);
+    if (n > 511)
+        n = 511;
+    if (n)
+        memcpy(name, start, n);
+    name[n] = 0;
+
+    while (val < end && (*val == ':' || nsvg__isspace(*val)))
+        ++val;
+
+    n = (int)(end - val);
+    if (n > 511)
+        n = 511;
+    if (n)
+        memcpy(value, val, n);
+    value[n] = 0;
+
+    return nsvg__parseAttr(p, name, value);
+}
+
+static void nsvg__parseStyle(NSVGparser *p, const char *str) {
+    const char *start;
+    const char *end;
+
+    while (*str) {
+        // Left Trim
+        while (*str && nsvg__isspace(*str))
+            ++str;
+        start = str;
+        while (*str && *str != ';')
+            ++str;
+        end = str;
+
+        // Right Trim
+        while (end > start && (*end == ';' || nsvg__isspace(*end)))
+            --end;
+        ++end;
+
+        nsvg__parseNameValue(p, start, end);
+        if (*str)
+            ++str;
+    }
+}
+
+static void nsvg__parseAttribs(NSVGparser *p, const char **attr) {
+    int i;
+    for (i = 0; attr[i]; i += 2) {
+        if (strcmp(attr[i], "style") == 0)
+            nsvg__parseStyle(p, attr[i + 1]);
+        else
+            nsvg__parseAttr(p, attr[i], attr[i + 1]);
+    }
+}
+
+static int nsvg__getArgsPerElement(char cmd) {
+    switch (cmd) {
+    case 'v':
+    case 'V':
+    case 'h':
+    case 'H':
+        return 1;
+    case 'm':
+    case 'M':
+    case 'l':
+    case 'L':
+    case 't':
+    case 'T':
+        return 2;
+    case 'q':
+    case 'Q':
+    case 's':
+    case 'S':
+        return 4;
+    case 'c':
+    case 'C':
+        return 6;
+    case 'a':
+    case 'A':
+        return 7;
+    }
+    return 0;
+}
+
+static void nsvg__pathMoveTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    if (rel) {
+        *cpx += args[0];
+        *cpy += args[1];
+    } else {
+        *cpx = args[0];
+        *cpy = args[1];
+    }
+    nsvg__moveTo(p, *cpx, *cpy);
+}
+
+static void nsvg__pathLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    if (rel) {
+        *cpx += args[0];
+        *cpy += args[1];
+    } else {
+        *cpx = args[0];
+        *cpy = args[1];
+    }
+    nsvg__lineTo(p, *cpx, *cpy);
+}
+
+static void nsvg__pathHLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    if (rel)
+        *cpx += args[0];
+    else
+        *cpx = args[0];
+    nsvg__lineTo(p, *cpx, *cpy);
+}
+
+static void nsvg__pathVLineTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    if (rel)
+        *cpy += args[0];
+    else
+        *cpy = args[0];
+    nsvg__lineTo(p, *cpx, *cpy);
+}
+
+static void nsvg__pathCubicBezTo(NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args,
+                                 int rel) {
+    float x2, y2, cx1, cy1, cx2, cy2;
+
+    if (rel) {
+        cx1 = *cpx + args[0];
+        cy1 = *cpy + args[1];
+        cx2 = *cpx + args[2];
+        cy2 = *cpy + args[3];
+        x2  = *cpx + args[4];
+        y2  = *cpy + args[5];
+    } else {
+        cx1 = args[0];
+        cy1 = args[1];
+        cx2 = args[2];
+        cy2 = args[3];
+        x2  = args[4];
+        y2  = args[5];
+    }
+
+    nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2);
+
+    *cpx2 = cx2;
+    *cpy2 = cy2;
+    *cpx  = x2;
+    *cpy  = y2;
+}
+
+static void nsvg__pathCubicBezShortTo(NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args,
+                                      int rel) {
+    float x1, y1, x2, y2, cx1, cy1, cx2, cy2;
+
+    x1 = *cpx;
+    y1 = *cpy;
+    if (rel) {
+        cx2 = *cpx + args[0];
+        cy2 = *cpy + args[1];
+        x2  = *cpx + args[2];
+        y2  = *cpy + args[3];
+    } else {
+        cx2 = args[0];
+        cy2 = args[1];
+        x2  = args[2];
+        y2  = args[3];
+    }
+
+    cx1 = 2 * x1 - *cpx2;
+    cy1 = 2 * y1 - *cpy2;
+
+    nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2);
+
+    *cpx2 = cx2;
+    *cpy2 = cy2;
+    *cpx  = x2;
+    *cpy  = y2;
+}
+
+static void nsvg__pathQuadBezTo(NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args, int rel) {
+    float x1, y1, x2, y2, cx, cy;
+    float cx1, cy1, cx2, cy2;
+
+    x1 = *cpx;
+    y1 = *cpy;
+    if (rel) {
+        cx = *cpx + args[0];
+        cy = *cpy + args[1];
+        x2 = *cpx + args[2];
+        y2 = *cpy + args[3];
+    } else {
+        cx = args[0];
+        cy = args[1];
+        x2 = args[2];
+        y2 = args[3];
+    }
+
+    // Convert to cubic bezier
+    cx1 = x1 + 2.0f / 3.0f * (cx - x1);
+    cy1 = y1 + 2.0f / 3.0f * (cy - y1);
+    cx2 = x2 + 2.0f / 3.0f * (cx - x2);
+    cy2 = y2 + 2.0f / 3.0f * (cy - y2);
+
+    nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2);
+
+    *cpx2 = cx;
+    *cpy2 = cy;
+    *cpx  = x2;
+    *cpy  = y2;
+}
+
+static void nsvg__pathQuadBezShortTo(NSVGparser *p, float *cpx, float *cpy, float *cpx2, float *cpy2, float *args,
+                                     int rel) {
+    float x1, y1, x2, y2, cx, cy;
+    float cx1, cy1, cx2, cy2;
+
+    x1 = *cpx;
+    y1 = *cpy;
+    if (rel) {
+        x2 = *cpx + args[0];
+        y2 = *cpy + args[1];
+    } else {
+        x2 = args[0];
+        y2 = args[1];
+    }
+
+    cx = 2 * x1 - *cpx2;
+    cy = 2 * y1 - *cpy2;
+
+    // Convert to cubix bezier
+    cx1 = x1 + 2.0f / 3.0f * (cx - x1);
+    cy1 = y1 + 2.0f / 3.0f * (cy - y1);
+    cx2 = x2 + 2.0f / 3.0f * (cx - x2);
+    cy2 = y2 + 2.0f / 3.0f * (cy - y2);
+
+    nsvg__cubicBezTo(p, cx1, cy1, cx2, cy2, x2, y2);
+
+    *cpx2 = cx;
+    *cpy2 = cy;
+    *cpx  = x2;
+    *cpy  = y2;
+}
+
+static float nsvg__sqr(float x) { return x * x; }
+static float nsvg__vmag(float x, float y) { return sqrtf(x * x + y * y); }
+
+static float nsvg__vecrat(float ux, float uy, float vx, float vy) {
+    return (ux * vx + uy * vy) / (nsvg__vmag(ux, uy) * nsvg__vmag(vx, vy));
+}
+
+static float nsvg__vecang(float ux, float uy, float vx, float vy) {
+    float r = nsvg__vecrat(ux, uy, vx, vy);
+    if (r < -1.0f)
+        r = -1.0f;
+    if (r > 1.0f)
+        r = 1.0f;
+    return ((ux * vy < uy * vx) ? -1.0f : 1.0f) * acosf(r);
+}
+
+static void nsvg__pathArcTo(NSVGparser *p, float *cpx, float *cpy, float *args, int rel) {
+    // Ported from canvg (https://code.google.com/p/canvg/)
+    float rx, ry, rotx;
+    float x1, y1, x2, y2, cx, cy, dx, dy, d;
+    float x1p, y1p, cxp, cyp, s, sa, sb;
+    float ux, uy, vx, vy, a1, da;
+    float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6];
+    float sinrx, cosrx;
+    int   fa, fs;
+    int   i, ndivs;
+    float hda, kappa;
+
+    rx   = fabsf(args[0]);                // y radius
+    ry   = fabsf(args[1]);                // x radius
+    rotx = args[2] / 180.0f * NSVG_PI;    // x rotation angle
+    fa   = fabsf(args[3]) > 1e-6 ? 1 : 0; // Large arc
+    fs   = fabsf(args[4]) > 1e-6 ? 1 : 0; // Sweep direction
+    x1   = *cpx;                          // start point
+    y1   = *cpy;
+    if (rel) { // end point
+        x2 = *cpx + args[5];
+        y2 = *cpy + args[6];
+    } else {
+        x2 = args[5];
+        y2 = args[6];
+    }
+
+    dx = x1 - x2;
+    dy = y1 - y2;
+    d  = sqrtf(dx * dx + dy * dy);
+    if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
+        // The arc degenerates to a line
+        nsvg__lineTo(p, x2, y2);
+        *cpx = x2;
+        *cpy = y2;
+        return;
+    }
+
+    sinrx = sinf(rotx);
+    cosrx = cosf(rotx);
+
+    // Convert to center point parameterization.
+    // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
+    // 1) Compute x1', y1'
+    x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
+    y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
+    d   = nsvg__sqr(x1p) / nsvg__sqr(rx) + nsvg__sqr(y1p) / nsvg__sqr(ry);
+    if (d > 1) {
+        d = sqrtf(d);
+        rx *= d;
+        ry *= d;
+    }
+    // 2) Compute cx', cy'
+    s  = 0.0f;
+    sa = nsvg__sqr(rx) * nsvg__sqr(ry) - nsvg__sqr(rx) * nsvg__sqr(y1p) - nsvg__sqr(ry) * nsvg__sqr(x1p);
+    sb = nsvg__sqr(rx) * nsvg__sqr(y1p) + nsvg__sqr(ry) * nsvg__sqr(x1p);
+    if (sa < 0.0f)
+        sa = 0.0f;
+    if (sb > 0.0f)
+        s = sqrtf(sa / sb);
+    if (fa == fs)
+        s = -s;
+    cxp = s * rx * y1p / ry;
+    cyp = s * -ry * x1p / rx;
+
+    // 3) Compute cx,cy from cx',cy'
+    cx = (x1 + x2) / 2.0f + cosrx * cxp - sinrx * cyp;
+    cy = (y1 + y2) / 2.0f + sinrx * cxp + cosrx * cyp;
+
+    // 4) Calculate theta1, and delta theta.
+    ux = (x1p - cxp) / rx;
+    uy = (y1p - cyp) / ry;
+    vx = (-x1p - cxp) / rx;
+    vy = (-y1p - cyp) / ry;
+    a1 = nsvg__vecang(1.0f, 0.0f, ux, uy); // Initial angle
+    da = nsvg__vecang(ux, uy, vx, vy);     // Delta angle
+
+    // if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
+    // if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;
+
+    if (fs == 0 && da > 0)
+        da -= 2 * NSVG_PI;
+    else if (fs == 1 && da < 0)
+        da += 2 * NSVG_PI;
+
+    // Approximate the arc using cubic spline segments.
+    t[0] = cosrx;
+    t[1] = sinrx;
+    t[2] = -sinrx;
+    t[3] = cosrx;
+    t[4] = cx;
+    t[5] = cy;
+
+    // Split arc into max 90 degree segments.
+    // The loop assumes an iteration per end point (including start and end), this +1.
+    ndivs = (int)(fabsf(da) / (NSVG_PI * 0.5f) + 1.0f);
+    hda   = (da / (float)ndivs) / 2.0f;
+    kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
+    if (da < 0.0f)
+        kappa = -kappa;
+
+    for (i = 0; i <= ndivs; i++) {
+        a  = a1 + da * ((float)i / (float)ndivs);
+        dx = cosf(a);
+        dy = sinf(a);
+        nsvg__xformPoint(&x, &y, dx * rx, dy * ry, t);                      // position
+        nsvg__xformVec(&tanx, &tany, -dy * rx * kappa, dx * ry * kappa, t); // tangent
+        if (i > 0)
+            nsvg__cubicBezTo(p, px + ptanx, py + ptany, x - tanx, y - tany, x, y);
+        px    = x;
+        py    = y;
+        ptanx = tanx;
+        ptany = tany;
+    }
+
+    *cpx = x2;
+    *cpy = y2;
+}
+
+static void nsvg__parsePath(NSVGparser *p, const char **attr) {
+    const char *s   = NULL;
+    char        cmd = '\0';
+    float       args[10];
+    int         nargs;
+    int         rargs = 0;
+    float       cpx, cpy, cpx2, cpy2;
+    const char *tmp[4];
+    char        closedFlag;
+    int         i;
+    char        item[64];
+
+    for (i = 0; attr[i]; i += 2) {
+        if (strcmp(attr[i], "d") == 0) {
+            s = attr[i + 1];
+        } else {
+            tmp[0] = attr[i];
+            tmp[1] = attr[i + 1];
+            tmp[2] = 0;
+            tmp[3] = 0;
+            nsvg__parseAttribs(p, tmp);
+        }
+    }
+
+    if (s) {
+        nsvg__resetPath(p);
+        cpx        = 0;
+        cpy        = 0;
+        cpx2       = 0;
+        cpy2       = 0;
+        closedFlag = 0;
+        nargs      = 0;
+
+        while (*s) {
+            s = nsvg__getNextPathItem(s, item);
+            if (!*item)
+                break;
+            if (nsvg__isnum(item[0])) {
+                if (nargs < 10)
+                    args[nargs++] = (float)nsvg__atof(item);
+                if (nargs >= rargs) {
+                    switch (cmd) {
+                    case 'm':
+                    case 'M':
+                        nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0);
+                        // Moveto can be followed by multiple coordinate pairs,
+                        // which should be treated as linetos.
+                        cmd   = (cmd == 'm') ? 'l' : 'L';
+                        rargs = nsvg__getArgsPerElement(cmd);
+                        cpx2  = cpx;
+                        cpy2  = cpy;
+                        break;
+                    case 'l':
+                    case 'L':
+                        nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0);
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        break;
+                    case 'H':
+                    case 'h':
+                        nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0);
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        break;
+                    case 'V':
+                    case 'v':
+                        nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0);
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        break;
+                    case 'C':
+                    case 'c':
+                        nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0);
+                        break;
+                    case 'S':
+                    case 's':
+                        nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0);
+                        break;
+                    case 'Q':
+                    case 'q':
+                        nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0);
+                        break;
+                    case 'T':
+                    case 't':
+                        nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0);
+                        break;
+                    case 'A':
+                    case 'a':
+                        nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0);
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        break;
+                    default:
+                        if (nargs >= 2) {
+                            cpx  = args[nargs - 2];
+                            cpy  = args[nargs - 1];
+                            cpx2 = cpx;
+                            cpy2 = cpy;
+                        }
+                        break;
+                    }
+                    nargs = 0;
+                }
+            } else {
+                cmd   = item[0];
+                rargs = nsvg__getArgsPerElement(cmd);
+                if (cmd == 'M' || cmd == 'm') {
+                    // Commit path.
+                    if (p->npts > 0)
+                        nsvg__addPath(p, closedFlag);
+                    // Start new subpath.
+                    nsvg__resetPath(p);
+                    closedFlag = 0;
+                    nargs      = 0;
+                } else if (cmd == 'Z' || cmd == 'z') {
+                    closedFlag = 1;
+                    // Commit path.
+                    if (p->npts > 0) {
+                        // Move current point to first point
+                        cpx  = p->pts[0];
+                        cpy  = p->pts[1];
+                        cpx2 = cpx;
+                        cpy2 = cpy;
+                        nsvg__addPath(p, closedFlag);
+                    }
+                    // Start new subpath.
+                    nsvg__resetPath(p);
+                    nsvg__moveTo(p, cpx, cpy);
+                    closedFlag = 0;
+                    nargs      = 0;
+                }
+            }
+        }
+        // Commit path.
+        if (p->npts)
+            nsvg__addPath(p, closedFlag);
+    }
+
+    nsvg__addShape(p);
+}
+
+static void nsvg__parseRect(NSVGparser *p, const char **attr) {
+    float x  = 0.0f;
+    float y  = 0.0f;
+    float w  = 0.0f;
+    float h  = 0.0f;
+    float rx = -1.0f; // marks not set
+    float ry = -1.0f;
+    int   i;
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "x") == 0)
+                x = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "y") == 0)
+                y = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+            if (strcmp(attr[i], "width") == 0)
+                w = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p));
+            if (strcmp(attr[i], "height") == 0)
+                h = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p));
+            if (strcmp(attr[i], "rx") == 0)
+                rx = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p)));
+            if (strcmp(attr[i], "ry") == 0)
+                ry = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p)));
+        }
+    }
+
+    if (rx < 0.0f && ry > 0.0f)
+        rx = ry;
+    if (ry < 0.0f && rx > 0.0f)
+        ry = rx;
+    if (rx < 0.0f)
+        rx = 0.0f;
+    if (ry < 0.0f)
+        ry = 0.0f;
+    if (rx > w / 2.0f)
+        rx = w / 2.0f;
+    if (ry > h / 2.0f)
+        ry = h / 2.0f;
+
+    if (w != 0.0f && h != 0.0f) {
+        nsvg__resetPath(p);
+
+        if (rx < 0.00001f || ry < 0.0001f) {
+            nsvg__moveTo(p, x, y);
+            nsvg__lineTo(p, x + w, y);
+            nsvg__lineTo(p, x + w, y + h);
+            nsvg__lineTo(p, x, y + h);
+        } else {
+            // Rounded rectangle
+            nsvg__moveTo(p, x + rx, y);
+            nsvg__lineTo(p, x + w - rx, y);
+            nsvg__cubicBezTo(p, x + w - rx * (1 - NSVG_KAPPA90), y, x + w, y + ry * (1 - NSVG_KAPPA90), x + w, y + ry);
+            nsvg__lineTo(p, x + w, y + h - ry);
+            nsvg__cubicBezTo(p, x + w, y + h - ry * (1 - NSVG_KAPPA90), x + w - rx * (1 - NSVG_KAPPA90), y + h,
+                             x + w - rx, y + h);
+            nsvg__lineTo(p, x + rx, y + h);
+            nsvg__cubicBezTo(p, x + rx * (1 - NSVG_KAPPA90), y + h, x, y + h - ry * (1 - NSVG_KAPPA90), x, y + h - ry);
+            nsvg__lineTo(p, x, y + ry);
+            nsvg__cubicBezTo(p, x, y + ry * (1 - NSVG_KAPPA90), x + rx * (1 - NSVG_KAPPA90), y, x + rx, y);
+        }
+
+        nsvg__addPath(p, 1);
+
+        nsvg__addShape(p);
+    }
+}
+
+static void nsvg__parseCircle(NSVGparser *p, const char **attr) {
+    float cx = 0.0f;
+    float cy = 0.0f;
+    float r  = 0.0f;
+    int   i;
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "cx") == 0)
+                cx = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "cy") == 0)
+                cy = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+            if (strcmp(attr[i], "r") == 0)
+                r = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualLength(p)));
+        }
+    }
+
+    if (r > 0.0f) {
+        nsvg__resetPath(p);
+
+        nsvg__moveTo(p, cx + r, cy);
+        nsvg__cubicBezTo(p, cx + r, cy + r * NSVG_KAPPA90, cx + r * NSVG_KAPPA90, cy + r, cx, cy + r);
+        nsvg__cubicBezTo(p, cx - r * NSVG_KAPPA90, cy + r, cx - r, cy + r * NSVG_KAPPA90, cx - r, cy);
+        nsvg__cubicBezTo(p, cx - r, cy - r * NSVG_KAPPA90, cx - r * NSVG_KAPPA90, cy - r, cx, cy - r);
+        nsvg__cubicBezTo(p, cx + r * NSVG_KAPPA90, cy - r, cx + r, cy - r * NSVG_KAPPA90, cx + r, cy);
+
+        nsvg__addPath(p, 1);
+
+        nsvg__addShape(p);
+    }
+}
+
+static void nsvg__parseEllipse(NSVGparser *p, const char **attr) {
+    float cx = 0.0f;
+    float cy = 0.0f;
+    float rx = 0.0f;
+    float ry = 0.0f;
+    int   i;
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "cx") == 0)
+                cx = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "cy") == 0)
+                cy = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+            if (strcmp(attr[i], "rx") == 0)
+                rx = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualWidth(p)));
+            if (strcmp(attr[i], "ry") == 0)
+                ry = fabsf(nsvg__parseCoordinate(p, attr[i + 1], 0.0f, nsvg__actualHeight(p)));
+        }
+    }
+
+    if (rx > 0.0f && ry > 0.0f) {
+
+        nsvg__resetPath(p);
+
+        nsvg__moveTo(p, cx + rx, cy);
+        nsvg__cubicBezTo(p, cx + rx, cy + ry * NSVG_KAPPA90, cx + rx * NSVG_KAPPA90, cy + ry, cx, cy + ry);
+        nsvg__cubicBezTo(p, cx - rx * NSVG_KAPPA90, cy + ry, cx - rx, cy + ry * NSVG_KAPPA90, cx - rx, cy);
+        nsvg__cubicBezTo(p, cx - rx, cy - ry * NSVG_KAPPA90, cx - rx * NSVG_KAPPA90, cy - ry, cx, cy - ry);
+        nsvg__cubicBezTo(p, cx + rx * NSVG_KAPPA90, cy - ry, cx + rx, cy - ry * NSVG_KAPPA90, cx + rx, cy);
+
+        nsvg__addPath(p, 1);
+
+        nsvg__addShape(p);
+    }
+}
+
+static void nsvg__parseLine(NSVGparser *p, const char **attr) {
+    float x1 = 0.0;
+    float y1 = 0.0;
+    float x2 = 0.0;
+    float y2 = 0.0;
+    int   i;
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "x1") == 0)
+                x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "y1") == 0)
+                y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+            if (strcmp(attr[i], "x2") == 0)
+                x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
+            if (strcmp(attr[i], "y2") == 0)
+                y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
+        }
+    }
+
+    nsvg__resetPath(p);
+
+    nsvg__moveTo(p, x1, y1);
+    nsvg__lineTo(p, x2, y2);
+
+    nsvg__addPath(p, 0);
+
+    nsvg__addShape(p);
+}
+
+static void nsvg__parsePoly(NSVGparser *p, const char **attr, int closeFlag) {
+    int         i;
+    const char *s;
+    float       args[2];
+    int         nargs, npts = 0;
+    char        item[64];
+
+    nsvg__resetPath(p);
+
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "points") == 0) {
+                s     = attr[i + 1];
+                nargs = 0;
+                while (*s) {
+                    s             = nsvg__getNextPathItem(s, item);
+                    args[nargs++] = (float)nsvg__atof(item);
+                    if (nargs >= 2) {
+                        if (npts == 0)
+                            nsvg__moveTo(p, args[0], args[1]);
+                        else
+                            nsvg__lineTo(p, args[0], args[1]);
+                        nargs = 0;
+                        npts++;
+                    }
+                }
+            }
+        }
+    }
+
+    nsvg__addPath(p, (char)closeFlag);
+
+    nsvg__addShape(p);
+}
+
+static void nsvg__parseSVG(NSVGparser *p, const char **attr) {
+    int i;
+    for (i = 0; attr[i]; i += 2) {
+        if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "width") == 0) {
+                p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
+            } else if (strcmp(attr[i], "height") == 0) {
+                p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
+            } else if (strcmp(attr[i], "viewBox") == 0) {
+                sscanf(attr[i + 1], "%f%*[%%, \t]%f%*[%%, \t]%f%*[%%, \t]%f", &p->viewMinx, &p->viewMiny, &p->viewWidth,
+                       &p->viewHeight);
+            } else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
+                if (strstr(attr[i + 1], "none") != 0) {
+                    // No uniform scaling
+                    p->alignType = NSVG_ALIGN_NONE;
+                } else {
+                    // Parse X align
+                    if (strstr(attr[i + 1], "xMin") != 0)
+                        p->alignX = NSVG_ALIGN_MIN;
+                    else if (strstr(attr[i + 1], "xMid") != 0)
+                        p->alignX = NSVG_ALIGN_MID;
+                    else if (strstr(attr[i + 1], "xMax") != 0)
+                        p->alignX = NSVG_ALIGN_MAX;
+                    // Parse X align
+                    if (strstr(attr[i + 1], "yMin") != 0)
+                        p->alignY = NSVG_ALIGN_MIN;
+                    else if (strstr(attr[i + 1], "yMid") != 0)
+                        p->alignY = NSVG_ALIGN_MID;
+                    else if (strstr(attr[i + 1], "yMax") != 0)
+                        p->alignY = NSVG_ALIGN_MAX;
+                    // Parse meet/slice
+                    p->alignType = NSVG_ALIGN_MEET;
+                    if (strstr(attr[i + 1], "slice") != 0)
+                        p->alignType = NSVG_ALIGN_SLICE;
+                }
+            }
+        }
+    }
+}
+
+static void nsvg__parseGradient(NSVGparser *p, const char **attr, char type) {
+    int               i;
+    NSVGgradientData *grad = (NSVGgradientData *)malloc(sizeof(NSVGgradientData));
+    if (grad == NULL)
+        return;
+    memset(grad, 0, sizeof(NSVGgradientData));
+    grad->units = NSVG_OBJECT_SPACE;
+    grad->type  = type;
+    if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) {
+        grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
+        grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
+        grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT);
+        grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
+    } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) {
+        grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
+        grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
+        grad->radial.r  = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
+    }
+
+    nsvg__xformIdentity(grad->xform);
+
+    for (i = 0; attr[i]; i += 2) {
+        if (strcmp(attr[i], "id") == 0) {
+            strncpy(grad->id, attr[i + 1], 63);
+            grad->id[63] = '\0';
+        } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
+            if (strcmp(attr[i], "gradientUnits") == 0) {
+                if (strcmp(attr[i + 1], "objectBoundingBox") == 0)
+                    grad->units = NSVG_OBJECT_SPACE;
+                else
+                    grad->units = NSVG_USER_SPACE;
+            } else if (strcmp(attr[i], "gradientTransform") == 0) {
+                nsvg__parseTransform(grad->xform, attr[i + 1]);
+            } else if (strcmp(attr[i], "cx") == 0) {
+                grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "cy") == 0) {
+                grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "r") == 0) {
+                grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "fx") == 0) {
+                grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "fy") == 0) {
+                grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "x1") == 0) {
+                grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "y1") == 0) {
+                grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "x2") == 0) {
+                grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "y2") == 0) {
+                grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]);
+            } else if (strcmp(attr[i], "spreadMethod") == 0) {
+                if (strcmp(attr[i + 1], "pad") == 0)
+                    grad->spread = NSVG_SPREAD_PAD;
+                else if (strcmp(attr[i + 1], "reflect") == 0)
+                    grad->spread = NSVG_SPREAD_REFLECT;
+                else if (strcmp(attr[i + 1], "repeat") == 0)
+                    grad->spread = NSVG_SPREAD_REPEAT;
+            } else if (strcmp(attr[i], "xlink:href") == 0) {
+                const char *href = attr[i + 1];
+                strncpy(grad->ref, href + 1, 62);
+                grad->ref[62] = '\0';
+            }
+        }
+    }
+
+    grad->next   = p->gradients;
+    p->gradients = grad;
+}
+
+static void nsvg__parseGradientStop(NSVGparser *p, const char **attr) {
+    NSVGattrib       *curAttr = nsvg__getAttr(p);
+    NSVGgradientData *grad;
+    NSVGgradientStop *stop;
+    int               i, idx;
+
+    curAttr->stopOffset  = 0;
+    curAttr->stopColor   = 0;
+    curAttr->stopOpacity = 1.0f;
+
+    for (i = 0; attr[i]; i += 2) {
+        nsvg__parseAttr(p, attr[i], attr[i + 1]);
+    }
+
+    // Add stop to the last gradient.
+    grad = p->gradients;
+    if (grad == NULL)
+        return;
+
+    grad->nstops++;
+    grad->stops = (NSVGgradientStop *)realloc(grad->stops, sizeof(NSVGgradientStop) * grad->nstops);
+    if (grad->stops == NULL)
+        return;
+
+    // Insert
+    idx = grad->nstops - 1;
+    for (i = 0; i < grad->nstops - 1; i++) {
+        if (curAttr->stopOffset < grad->stops[i].offset) {
+            idx = i;
+            break;
+        }
+    }
+    if (idx != grad->nstops - 1) {
+        for (i = grad->nstops - 1; i > idx; i--)
+            grad->stops[i] = grad->stops[i - 1];
+    }
+
+    stop        = &grad->stops[idx];
+    stop->color = curAttr->stopColor;
+    stop->color |= (unsigned int)(curAttr->stopOpacity * 255) << 24;
+    stop->offset = curAttr->stopOffset;
+}
+
+static void nsvg__startElement(void *ud, const char *el, const char **attr) {
+    NSVGparser *p = (NSVGparser *)ud;
+
+    if (p->defsFlag) {
+        // Skip everything but gradients in defs
+        if (strcmp(el, "linearGradient") == 0) {
+            nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
+        } else if (strcmp(el, "radialGradient") == 0) {
+            nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
+        } else if (strcmp(el, "stop") == 0) {
+            nsvg__parseGradientStop(p, attr);
+        }
+        return;
+    }
+
+    if (strcmp(el, "g") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseAttribs(p, attr);
+    } else if (strcmp(el, "path") == 0) {
+        if (p->pathFlag) // Do not allow nested paths.
+            return;
+        nsvg__pushAttr(p);
+        nsvg__parsePath(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "rect") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseRect(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "circle") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseCircle(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "ellipse") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseEllipse(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "line") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parseLine(p, attr);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "polyline") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parsePoly(p, attr, 0);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "polygon") == 0) {
+        nsvg__pushAttr(p);
+        nsvg__parsePoly(p, attr, 1);
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "linearGradient") == 0) {
+        nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
+    } else if (strcmp(el, "radialGradient") == 0) {
+        nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
+    } else if (strcmp(el, "stop") == 0) {
+        nsvg__parseGradientStop(p, attr);
+    } else if (strcmp(el, "defs") == 0) {
+        p->defsFlag = 1;
+    } else if (strcmp(el, "svg") == 0) {
+        nsvg__parseSVG(p, attr);
+    }
+}
+
+static void nsvg__endElement(void *ud, const char *el) {
+    NSVGparser *p = (NSVGparser *)ud;
+
+    if (strcmp(el, "g") == 0) {
+        nsvg__popAttr(p);
+    } else if (strcmp(el, "path") == 0) {
+        p->pathFlag = 0;
+    } else if (strcmp(el, "defs") == 0) {
+        p->defsFlag = 0;
+    }
+}
+
+static void nsvg__content(void *ud, const char *s) {
+    NSVG_NOTUSED(ud);
+    NSVG_NOTUSED(s);
+    // empty
+}
+
+static void nsvg__imageBounds(NSVGparser *p, float *bounds) {
+    NSVGshape *shape;
+    shape = p->image->shapes;
+    if (shape == NULL) {
+        bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0;
+        return;
+    }
+    bounds[0] = shape->bounds[0];
+    bounds[1] = shape->bounds[1];
+    bounds[2] = shape->bounds[2];
+    bounds[3] = shape->bounds[3];
+    for (shape = shape->next; shape != NULL; shape = shape->next) {
+        bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]);
+        bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]);
+        bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]);
+        bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]);
+    }
+}
+
+static float nsvg__viewAlign(float content, float container, int type) {
+    if (type == NSVG_ALIGN_MIN)
+        return 0;
+    else if (type == NSVG_ALIGN_MAX)
+        return container - content;
+    // mid
+    return (container - content) * 0.5f;
+}
+
+static void nsvg__scaleGradient(NSVGgradient *grad, float tx, float ty, float sx, float sy) {
+    float t[6];
+    nsvg__xformSetTranslation(t, tx, ty);
+    nsvg__xformMultiply(grad->xform, t);
+
+    nsvg__xformSetScale(t, sx, sy);
+    nsvg__xformMultiply(grad->xform, t);
+}
+
+static void nsvg__scaleToViewbox(NSVGparser *p, const char *units) {
+    NSVGshape *shape;
+    NSVGpath  *path;
+    float      tx, ty, sx, sy, us, bounds[4], t[6], avgs;
+    int        i;
+    float     *pt;
+
+    // Guess image size if not set completely.
+    nsvg__imageBounds(p, bounds);
+
+    if (p->viewWidth == 0) {
+        if (p->image->width > 0) {
+            p->viewWidth = p->image->width;
+        } else {
+            p->viewMinx  = bounds[0];
+            p->viewWidth = bounds[2] - bounds[0];
+        }
+    }
+    if (p->viewHeight == 0) {
+        if (p->image->height > 0) {
+            p->viewHeight = p->image->height;
+        } else {
+            p->viewMiny   = bounds[1];
+            p->viewHeight = bounds[3] - bounds[1];
+        }
+    }
+    if (p->image->width == 0)
+        p->image->width = p->viewWidth;
+    if (p->image->height == 0)
+        p->image->height = p->viewHeight;
+
+    tx = -p->viewMinx;
+    ty = -p->viewMiny;
+    sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
+    sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
+    // Unit scaling
+    us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);
+
+    // Fix aspect ratio
+    if (p->alignType == NSVG_ALIGN_MEET) {
+        // fit whole image into viewbox
+        sx = sy = nsvg__minf(sx, sy);
+        tx += nsvg__viewAlign(p->viewWidth * sx, p->image->width, p->alignX) / sx;
+        ty += nsvg__viewAlign(p->viewHeight * sy, p->image->height, p->alignY) / sy;
+    } else if (p->alignType == NSVG_ALIGN_SLICE) {
+        // fill whole viewbox with image
+        sx = sy = nsvg__maxf(sx, sy);
+        tx += nsvg__viewAlign(p->viewWidth * sx, p->image->width, p->alignX) / sx;
+        ty += nsvg__viewAlign(p->viewHeight * sy, p->image->height, p->alignY) / sy;
+    }
+
+    // Transform
+    sx *= us;
+    sy *= us;
+    avgs = (sx + sy) / 2.0f;
+    for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
+        shape->bounds[0] = (shape->bounds[0] + tx) * sx;
+        shape->bounds[1] = (shape->bounds[1] + ty) * sy;
+        shape->bounds[2] = (shape->bounds[2] + tx) * sx;
+        shape->bounds[3] = (shape->bounds[3] + ty) * sy;
+        for (path = shape->paths; path != NULL; path = path->next) {
+            path->bounds[0] = (path->bounds[0] + tx) * sx;
+            path->bounds[1] = (path->bounds[1] + ty) * sy;
+            path->bounds[2] = (path->bounds[2] + tx) * sx;
+            path->bounds[3] = (path->bounds[3] + ty) * sy;
+            for (i = 0; i < path->npts; i++) {
+                pt    = &path->pts[i * 2];
+                pt[0] = (pt[0] + tx) * sx;
+                pt[1] = (pt[1] + ty) * sy;
+            }
+        }
+
+        if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) {
+            nsvg__scaleGradient(shape->fill.gradient, tx, ty, sx, sy);
+            memcpy(t, shape->fill.gradient->xform, sizeof(float) * 6);
+            nsvg__xformInverse(shape->fill.gradient->xform, t);
+        }
+        if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) {
+            nsvg__scaleGradient(shape->stroke.gradient, tx, ty, sx, sy);
+            memcpy(t, shape->stroke.gradient->xform, sizeof(float) * 6);
+            nsvg__xformInverse(shape->stroke.gradient->xform, t);
+        }
+
+        shape->strokeWidth *= avgs;
+        shape->strokeDashOffset *= avgs;
+        for (i = 0; i < shape->strokeDashCount; i++)
+            shape->strokeDashArray[i] *= avgs;
+    }
+}
+
+NSVGimage *nsvgParse(char *input, const char *units, float dpi) {
+    NSVGparser *p;
+    NSVGimage  *ret = 0;
+
+    p = nsvg__createParser();
+    if (p == NULL) {
+        return NULL;
+    }
+    p->dpi = dpi;
+
+    nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p);
+
+    // Scale to viewBox
+    nsvg__scaleToViewbox(p, units);
+
+    ret      = p->image;
+    p->image = NULL;
+
+    nsvg__deleteParser(p);
+
+    return ret;
+}
+
+NSVGimage *nsvgParseFromFile(const char *filename, const char *units, float dpi) {
+    FILE      *fp = NULL;
+    size_t     size;
+    char      *data  = NULL;
+    NSVGimage *image = NULL;
+
+    fp = fopen(filename, "rb");
+    if (!fp)
+        goto error;
+    fseek(fp, 0, SEEK_END);
+    size = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    data = (char *)malloc(size + 1);
+    if (data == NULL)
+        goto error;
+    if (fread(data, 1, size, fp) != size)
+        goto error;
+    data[size] = '\0'; // Must be null terminated.
+    fclose(fp);
+    image = nsvgParse(data, units, dpi);
+    free(data);
+
+    return image;
 
 error:
-       if (fp) fclose(fp);
-       if (data) free(data);
-       if (image) nsvgDelete(image);
-       return NULL;
-}
-
-void nsvgDelete(NSVGimage* image)
-{
-       NSVGshape *snext, *shape;
-       if (image == NULL) return;
-       shape = image->shapes;
-       while (shape != NULL) {
-               snext = shape->next;
-               nsvg__deletePaths(shape->paths);
-               nsvg__deletePaint(&shape->fill);
-               nsvg__deletePaint(&shape->stroke);
-               free(shape);
-               shape = snext;
-       }
-       free(image);
+    if (fp)
+        fclose(fp);
+    if (data)
+        free(data);
+    if (image)
+        nsvgDelete(image);
+    return NULL;
+}
+
+void nsvgDelete(NSVGimage *image) {
+    NSVGshape *snext, *shape;
+    if (image == NULL)
+        return;
+    shape = image->shapes;
+    while (shape != NULL) {
+        snext = shape->next;
+        nsvg__deletePaths(shape->paths);
+        nsvg__deletePaint(&shape->fill);
+        nsvg__deletePaint(&shape->stroke);
+        free(shape);
+        shape = snext;
+    }
+    free(image);
 }
 
 #endif
index 410a1edc8bff40143e8b8c9bd36305d37abf9191..448bd0e05ec0ac8b7bbbbb053530642c4f37e948 100644 (file)
-static int _rnd_count = 9999;
-static float _rnd[] = { 0.39540747, 
-0.841546, 0.52073574, 0.80399257, 0.95868486, 0.46164507, 0.5644759, 0.50258803, 0.1953517, 0.40522006, 0.7953865, 
-0.7795385, 0.6009604, 0.03921096, 0.56872225, 0.93369347, 0.7019503, 0.5392296, 0.2671585, 0.87286836, 0.28110227, 
-0.41505373, 0.8609184, 0.65234584, 0.18079561, 0.1345461, 0.26905555, 0.97823226, 0.9349287, 0.37662244, 0.47883937, 
-0.1831086, 0.63446456, 0.2549137, 0.8205819, 0.44705132, 0.7044422, 0.36040744, 0.29616997, 0.60375917, 0.21973382, 
-0.094351165, 0.3769042, 0.9975177, 0.6133292, 0.3379986, 0.88620085, 0.83456165, 0.16677794, 0.2749627, 0.28938183, 
-0.6274365, 0.058304083, 0.97233975, 0.48520145, 0.9803537, 0.9806276, 0.8683899, 0.62319696, 0.82413876, 0.19258952, 
-0.5862436, 0.5676593, 0.8187293, 0.9263807, 0.6122779, 0.14507395, 0.34604672, 0.21862903, 0.121670924, 0.22925124, 
-0.34154287, 0.2430596, 0.66339934, 0.6531345, 0.1867511, 0.038149532, 0.8634007, 0.039016694, 0.84279704, 0.24834526, 
-0.4344939, 0.8114543, 0.65996605, 0.08724063, 0.8514029, 0.12480451, 0.6621248, 0.76971227, 0.8402282, 0.46642372, 
-0.83605236, 0.73721045, 0.47203118, 0.41116965, 0.6334902, 0.52669185, 0.55817497, 0.07113702, 0.0010512439, 0.19292463, 
-0.5401541, 0.61593264, 0.045107026, 0.04571145, 0.94783896, 0.3843769, 0.39490476, 0.3192052, 0.29845035, 0.9422042, 
-0.11722695, 0.8293732, 0.7804, 0.5757935, 0.7580956, 0.7747893, 0.90769327, 0.73148865, 0.074977815, 0.4874734, 
-0.48294914, 0.5763345, 0.37840083, 0.6552472, 0.39319888, 0.6043324, 0.77102846, 0.25222966, 0.019644327, 0.6600592, 
-0.4799746, 0.7922636, 0.03796545, 0.64987236, 0.70819116, 0.81856126, 0.7663473, 0.6142546, 0.13940167, 0.46702597, 
-0.72989976, 0.34291962, 0.47126192, 0.89802396, 0.34919676, 0.0066791615, 0.95681053, 0.8962376, 0.653074, 0.85870093, 
-0.6189986, 0.8266863, 0.9961592, 0.5135778, 0.7099755, 0.9638197, 0.2375318, 0.3898598, 0.65251255, 0.34350657, 
-0.6133485, 0.14267509, 0.29956087, 0.6383911, 0.4622296, 0.3249633, 0.79140776, 0.13052759, 0.8676024, 0.93953437, 
-0.008441999, 0.2934387, 0.592087, 0.6079518, 0.75757366, 0.14002953, 0.10507256, 0.48037684, 0.30605045, 0.38651973, 
-0.64752185, 0.8747908, 0.59915566, 0.1609434, 0.04106063, 0.65328825, 0.79610443, 0.5243876, 0.9398969, 0.7443715, 
-0.5810295, 0.3764875, 0.961742, 0.7958951, 0.8536775, 0.58722466, 0.043358732, 0.8328708, 0.43579438, 0.024233455, 
-0.21527143, 0.8262829, 0.028635254, 0.71353966, 0.85025895, 0.3255599, 0.23459937, 0.38820738, 0.7560042, 0.569946, 
-0.8587471, 0.75715494, 0.083809346, 0.26599285, 0.6959847, 0.73855764, 0.54351944, 0.13861747, 0.59733045, 0.80894136, 
-0.52885884, 0.26702014, 0.1906307, 0.123230904, 0.35850486, 0.6319545, 0.3316967, 0.7961919, 0.7542743, 0.17034897, 
-0.0966708, 0.27220175, 0.04458247, 0.28181702, 0.1712483, 0.82123893, 0.8461555, 0.88561594, 0.3106845, 0.7155007, 
-0.4186889, 0.40789708, 0.76838344, 0.36995092, 0.8856244, 0.82387453, 0.29267815, 0.69574916, 0.099910386, 0.11511985, 
-0.04370523, 0.9047413, 0.23554033, 0.62685305, 0.4953746, 0.9482513, 0.63565224, 0.9054043, 0.3550348, 0.21830441, 
-0.9938632, 0.4384075, 0.633933, 0.5856552, 0.47327515, 0.58654535, 0.71257246, 0.80199236, 0.09474454, 0.8747458, 
-0.8924021, 0.6579035, 0.82793295, 0.88182974, 0.39025244, 0.12096177, 0.4986367, 0.8206798, 0.23760653, 0.53463036, 
-0.33927637, 0.6359475, 0.6962815, 0.6391545, 0.12664375, 0.19192953, 0.036661416, 0.41772944, 0.7864424, 0.222997, 
-0.18558672, 0.9407512, 0.5305812, 0.092380084, 0.7216375, 0.9802814, 0.77396405, 0.18272822, 0.89667577, 0.29907903, 
-0.11130205, 0.4906858, 0.60100466, 0.22516462, 0.22271773, 0.38580173, 0.07680829, 0.3537106, 0.23660058, 0.37441283, 
-0.4496146, 0.81497246, 0.6677978, 0.82040447, 0.879028, 0.35791573, 0.742126, 0.9947786, 0.45901147, 0.28134564, 
-0.54988396, 0.29484302, 0.015549939, 0.87174755, 0.68915904, 0.9516509, 0.12732233, 0.7355529, 0.16019227, 0.40997103, 
-0.34699774, 0.31590846, 0.924004, 0.93852746, 0.4233283, 0.84859055, 0.034942873, 0.47111684, 0.41643673, 0.740842, 
-0.115121245, 0.68295085, 0.18112887, 0.41202956, 0.77338237, 0.3706143, 0.27295336, 0.7101767, 0.21335205, 0.36372176, 
-0.2381554, 0.7791855, 0.72371674, 0.6153301, 0.7491951, 0.816459, 0.47513586, 0.7292571, 0.5360056, 0.2710668, 
-0.25847942, 0.3412554, 0.19351831, 0.8266295, 0.0274151, 0.13370614, 0.8909684, 0.72927034, 0.39707616, 0.030437447, 
-0.32297286, 0.27100918, 0.57834184, 0.71816945, 0.16622439, 0.8669331, 0.11371415, 0.6035204, 0.09836516, 0.31854475, 
-0.6786976, 0.41714564, 0.5222008, 0.7964705, 0.17181565, 0.56781226, 0.5921917, 0.30867395, 0.1893324, 0.6068693, 
-0.37345472, 0.3056858, 0.9351113, 0.14536993, 0.4823626, 0.7738658, 0.4894325, 0.35449934, 0.38461447, 0.6396763, 
-0.4796459, 0.54368305, 0.31310055, 0.18291461, 0.040748898, 0.9671462, 0.20084366, 0.0055472897, 0.4491057, 0.882262, 
-0.7027449, 0.87161547, 0.6308919, 0.21746083, 0.59236926, 0.8413338, 0.81905454, 0.3970478, 0.6548139, 0.45960286, 
-0.5415144, 0.58229446, 0.539938, 0.7902069, 0.6569827, 0.017287076, 0.33589792, 0.4329719, 0.23580688, 0.39235854, 
-0.3775006, 0.7592148, 0.2189059, 0.45868888, 0.83889884, 0.13501453, 0.10404509, 0.3392862, 0.7557216, 0.20466943, 
-0.36696857, 0.5866444, 0.85956824, 0.3070704, 0.9041244, 0.5018392, 0.67479384, 0.7176504, 0.5530007, 0.6410288, 
-0.9548113, 0.092384726, 0.69968545, 0.92501163, 0.09816185, 0.89735144, 0.0037450776, 0.52289367, 0.5259319, 0.023461822, 
-0.6312483, 0.7678718, 0.7697404, 0.05674718, 0.5047614, 0.9435301, 0.6527096, 0.17220303, 0.37856197, 0.45735472, 
-0.7372887, 0.47976837, 0.6413262, 0.45014447, 0.09263428, 0.95487, 0.7227262, 0.23286755, 0.8860825, 0.15514348, 
-0.34249324, 0.61824745, 0.8799712, 0.59477806, 0.43754727, 0.28511587, 0.059529364, 0.2938943, 0.36052704, 0.9415474, 
-0.13126945, 0.5811514, 0.8133543, 0.7322598, 0.5734211, 0.5990968, 0.816904, 0.80282104, 0.802309, 0.96059436, 
-0.8491296, 0.50259084, 0.33908847, 0.09564596, 0.9037401, 0.4750429, 0.45105854, 0.24954097, 0.8323773, 0.14329186, 
-0.17462522, 0.77087754, 0.63681114, 0.3707884, 0.6809686, 0.013000839, 0.8879006, 0.17496233, 0.61919993, 0.21964556, 
-0.8840007, 0.3588153, 0.81167597, 0.43701455, 0.32608527, 0.15613726, 0.666414, 0.9090664, 0.87672335, 0.4935375, 
-0.13796596, 0.9199052, 0.43055856, 0.9254882, 0.30601385, 0.8399024, 0.279159, 0.78432524, 0.69103795, 0.9625043, 
-0.83405733, 0.8099884, 0.46151695, 0.2172352, 0.7669222, 0.3603919, 0.9443403, 0.44256592, 0.0512912, 0.5604203, 
-0.7111962, 0.64194167, 0.18362112, 0.5826634, 0.07659364, 0.49031433, 0.6909148, 0.9020739, 0.7695607, 0.7476028, 
-0.80862886, 0.5419922, 0.3728176, 0.33883983, 0.005325912, 0.25472003, 0.34031895, 0.711323, 0.064774565, 0.8410662, 
-0.73384184, 0.10357534, 0.48392436, 0.65669554, 0.38558826, 0.07401231, 0.8972984, 0.5944408, 0.67009234, 0.96569335, 
-0.21179698, 0.22384812, 0.8577752, 0.31630307, 0.7823413, 0.49602425, 0.7362841, 0.84789515, 0.84889454, 0.8156995, 
-0.14898759, 0.3770851, 0.01476456, 0.94343513, 0.15387547, 0.29206514, 0.43717077, 0.12267711, 0.21190928, 0.5122022, 
-0.020072967, 0.23301727, 0.37779135, 0.21022503, 0.82657844, 0.60762084, 0.15801735, 0.52692556, 0.19707517, 0.0025813282, 
-0.59301597, 0.09647403, 0.23198159, 0.80386734, 0.5358059, 0.58478075, 0.684217, 0.056514528, 0.5564985, 0.50930166, 
-0.51843596, 0.4924238, 0.8624285, 0.24907504, 0.6920786, 0.35675675, 0.08881078, 0.5404892, 0.5028201, 0.0935231, 
-0.63684154, 0.77462125, 0.38253152, 0.15789017, 0.94562036, 0.97877973, 0.84605676, 0.64755017, 0.48972467, 0.17472044, 
-0.3380069, 0.2093585, 0.65081996, 0.8463132, 0.22268358, 0.052513562, 0.1451035, 0.21089722, 0.40762928, 0.5690947, 
-0.60784817, 0.38065624, 0.56617856, 0.70260763, 0.99376625, 0.52764916, 0.37058878, 0.1287163, 0.51814646, 0.4698217, 
-0.5188101, 0.61752814, 0.024105478, 0.103552066, 0.3657398, 0.81839466, 0.7139425, 0.07409142, 0.858247, 0.55702615, 
-0.738724, 0.03666682, 0.56678987, 0.38177812, 0.17129473, 0.30907747, 0.8416038, 0.016115308, 0.02639147, 0.639565, 
-0.21165326, 0.87791353, 0.13285992, 0.9337254, 0.48567492, 0.2561853, 0.20844269, 0.6799239, 0.16412394, 0.41797122, 
-0.60819095, 0.71734047, 0.12940371, 0.019902974, 0.6559104, 0.7204788, 0.18525302, 0.5472679, 0.4805734, 0.4042889, 
-0.33857107, 0.07101207, 0.35265025, 0.85060316, 0.8303707, 0.57118136, 0.8138664, 0.18440045, 0.5313129, 0.68468875, 
-0.68604535, 0.35447347, 0.10232483, 0.8785814, 0.25816843, 0.6408965, 0.48466823, 0.09038009, 0.6178771, 0.10955451, 
-0.609952, 0.034018606, 0.9099675, 0.44027576, 0.9488352, 0.021383535, 0.9072631, 0.5468869, 0.72586775, 0.45081598, 
-0.12382444, 0.29433593, 0.5355419, 0.62210256, 0.30099395, 0.14064118, 0.5252633, 0.28225678, 0.10335469, 0.91449356, 
-0.44231892, 0.024042243, 0.14861101, 0.47943518, 0.7319259, 0.2537175, 0.6150156, 0.25082228, 0.76173455, 0.01501382, 
-0.23581055, 0.09487294, 0.9293908, 0.3710189, 0.7943369, 0.30455244, 0.1610446, 0.9123745, 0.90176797, 0.80898714, 
-0.66391826, 0.2669795, 0.4585327, 0.08049692, 0.5608643, 0.3917094, 0.8189315, 0.48022225, 0.5775875, 0.11752723, 
-0.11563321, 0.20241146, 0.9870254, 0.70338356, 0.6672356, 0.5859097, 0.88540757, 0.4305323, 0.7083498, 0.69511765, 
-0.4063679, 0.6564408, 0.7851523, 0.71085393, 0.21500541, 0.028951503, 0.36494514, 0.16452302, 0.8277657, 0.9964415, 
-0.9795966, 0.6128888, 0.38048878, 0.29436752, 0.25057533, 0.17533945, 0.56550956, 0.06811409, 0.9185709, 0.3402165, 
-0.43478596, 0.13479339, 0.6732348, 0.64420736, 0.8993806, 0.033399098, 0.10784754, 0.22600721, 0.7037833, 0.20842715, 
-0.41914487, 0.7305123, 0.20402466, 0.2066503, 0.40261927, 0.007477421, 0.48182714, 0.74767876, 0.8654915, 0.5319128, 
-0.026764244, 0.6544085, 0.6524566, 0.58114594, 0.13793063, 0.50274444, 0.82192266, 0.6926579, 0.45280823, 0.49189615, 
-0.020400187, 0.8172935, 0.51196146, 0.36813334, 0.26033172, 0.27157453, 0.983206, 0.140945, 0.81147337, 0.18160632, 
-0.92110395, 0.13893794, 0.46073973, 0.6193385, 0.5772967, 0.2490843, 0.40886414, 0.1738385, 0.89174825, 0.24309792, 
-0.6935123, 0.8178308, 0.20262258, 0.38665804, 0.31345224, 0.78037745, 0.48233682, 0.09208888, 0.50627667, 0.3966362, 
-0.21147643, 0.41518968, 0.77319896, 0.21188715, 0.18802696, 0.60185134, 0.21855086, 0.8358913, 0.94631857, 0.13104475, 
-0.024271427, 0.34088212, 0.9362054, 0.6838852, 0.61080885, 0.8878263, 0.1936688, 0.03311803, 0.0038492912, 0.88884634, 
-0.09388026, 0.64808416, 0.8009096, 0.2097103, 0.79838383, 0.20256937, 0.61467093, 0.1253034, 0.054681093, 0.47995427, 
-0.7892377, 0.8911171, 0.6346683, 0.41483715, 0.9701299, 0.5059143, 0.36573896, 0.24885257, 0.43131158, 0.97544533, 
-0.03053343, 0.57297283, 0.2275199, 0.7607035, 0.21882649, 0.3526302, 0.8816254, 0.5187374, 0.77584916, 0.42562595, 
-0.58670866, 0.44921878, 0.08823959, 0.6174303, 0.30275592, 0.5633923, 0.61428005, 0.56348866, 0.41350332, 0.9854576, 
-0.9871804, 0.093247466, 0.7812102, 0.4663643, 0.34180707, 0.13315432, 0.70621383, 0.52136827, 0.7137553, 0.10489457, 
-0.52208734, 0.94481623, 0.60180646, 0.028403986, 0.8583129, 0.5209074, 0.42056426, 0.04020609, 0.9908838, 0.44575363, 
-0.32094392, 0.09593353, 0.34945422, 0.62905514, 0.89324564, 0.3400189, 0.80287755, 0.017237967, 0.112081215, 0.40673763, 
-0.8916342, 0.80225027, 0.83534926, 0.44585398, 0.98826486, 0.93728596, 0.79176265, 0.7611556, 0.41889647, 0.08567218, 
-0.64641637, 0.3602572, 0.80498207, 0.6709546, 0.9035386, 0.64189243, 0.84741235, 0.0598356, 0.7591174, 0.7818485, 
-0.142828, 0.574074, 0.5726049, 0.96774966, 0.6645137, 0.8912469, 0.74379325, 0.15215507, 0.5731187, 0.0017881524, 
-0.3302768, 0.6889758, 0.40928704, 0.30701768, 0.21326037, 0.71983707, 0.10946698, 0.1559525, 0.040139113, 0.92102695, 
-0.7291448, 0.6594087, 0.62130964, 0.9052116, 0.79933727, 0.9606867, 0.29095143, 0.6784996, 0.72551656, 0.2513532, 
-0.49260658, 0.74304193, 0.25812054, 0.33023268, 0.2639096, 0.31756023, 0.22964539, 0.86759955, 0.7813403, 0.097017966, 
-0.19349271, 0.63960755, 0.18803692, 0.4171083, 0.7553954, 0.95744056, 0.9509702, 0.4979644, 0.45769426, 0.18370152, 
-0.53242546, 0.69145983, 0.019696489, 0.8380905, 0.052703734, 0.48341933, 0.95276433, 0.6673932, 0.16841243, 0.70382696, 
-0.6002955, 0.06529366, 0.42663854, 0.32176548, 0.50918156, 0.58723485, 0.4308553, 0.079054326, 0.04310807, 0.89570016, 
-0.4901917, 0.24186741, 0.3746122, 0.94312114, 0.72753423, 0.08953723, 0.47137174, 0.20420133, 0.14981624, 0.8418967, 
-0.009716521, 0.79298705, 0.22080535, 0.541815, 0.71892774, 0.80114675, 0.72334546, 0.42003006, 0.27752897, 0.7804903, 
-0.36479586, 0.56225216, 0.69918716, 0.07751329, 0.4967225, 0.12819904, 0.212969, 0.86627144, 0.90792674, 0.16816054, 
-0.5265852, 0.8719159, 0.45485634, 0.56199414, 0.6935098, 0.29055804, 0.31684762, 0.07657534, 0.11055623, 0.9631665, 
-0.012047576, 0.74856305, 0.517577, 0.32651573, 0.69411045, 0.80730844, 0.8444883, 0.88482356, 0.60283774, 0.7080349, 
-0.8638894, 0.010825248, 0.80152535, 0.26261777, 0.53090423, 0.92793953, 0.54268026, 0.29709893, 0.44639865, 0.5993352, 
-0.8765682, 0.6051003, 0.2962746, 0.9816557, 0.31531146, 0.13780066, 0.3381307, 0.6588112, 0.84830517, 0.4283697, 
-0.48429912, 0.6467701, 0.30947384, 0.31436247, 0.7684427, 0.6162329, 0.044675153, 0.3726714, 0.38340282, 0.689414, 
-0.28371072, 0.32814547, 0.26343372, 0.19989188, 0.30427113, 0.51576, 0.07039049, 0.19223855, 0.031089857, 0.7655703, 
-0.7478778, 0.019748688, 0.63017666, 0.511221, 0.08659828, 0.40694728, 0.45228842, 0.53592134, 0.011204251, 0.5563098, 
-0.46917772, 0.18567711, 0.036518365, 0.17446801, 0.22373573, 0.21711932, 0.7013514, 0.48716292, 0.49417505, 0.9146714, 
-0.88326436, 0.17000887, 0.9136961, 0.7569846, 0.3156245, 0.54842275, 0.34166658, 0.09638273, 0.67738456, 0.7995515, 
-0.06741016, 0.14589214, 0.62772137, 0.08273488, 0.680492, 0.46455044, 0.016593413, 0.7982528, 0.22776419, 0.36149544, 
-0.16394442, 0.50875384, 0.36146715, 0.827093, 0.22023632, 0.098033614, 0.2916271, 0.088965714, 0.9761561, 0.08715181, 
-0.8144086, 0.5832276, 0.6980635, 0.11641844, 0.8823059, 0.5778689, 0.106052585, 0.8731921, 0.19559653, 0.5381755, 
-0.06528069, 0.3559057, 0.8585367, 0.21165277, 0.48889965, 0.32328558, 0.55795574, 0.95378345, 0.49397606, 0.7591853, 
-0.20052591, 0.9030986, 0.25939873, 0.13267961, 0.750727, 0.37451053, 0.8085417, 0.086603075, 0.5367483, 0.21759088, 
-0.25679567, 0.25270087, 0.120226584, 0.59023273, 0.9851429, 0.48418257, 0.44782865, 0.51130295, 0.20042898, 0.102623075, 
-0.35849786, 0.14340132, 0.6026563, 0.68958867, 0.29621476, 0.8080387, 0.6502171, 0.14981438, 0.3381934, 0.8969507, 
-0.54007787, 0.33784363, 0.59498966, 0.21697083, 0.8866259, 0.91130996, 0.32382888, 0.5653839, 0.36569145, 0.5077954, 
-0.76932716, 0.01944951, 0.3364438, 0.97800565, 0.28137985, 0.8125798, 0.2356791, 0.268304, 0.22650987, 0.00471706, 
-0.8754569, 0.04665282, 0.7533545, 0.39135298, 0.40068746, 0.05712457, 0.3004423, 0.56981003, 0.8364648, 0.9426883, 
-0.7242934, 0.65872735, 0.7484097, 0.63979757, 0.677513, 0.91895205, 0.6577112, 0.90325576, 0.70360684, 0.07383294, 
-0.1603537, 0.88244474, 0.14561148, 0.6926336, 0.3332959, 0.33904833, 0.80695754, 0.62465066, 0.40820882, 0.48363495, 
-0.5723596, 0.38191313, 0.9233045, 0.33347633, 0.021493766, 0.49342504, 0.5844891, 0.20363668, 0.81628335, 0.82950133, 
-0.6108677, 0.75401884, 0.728919, 0.42300317, 0.7835019, 0.11059984, 0.2710398, 0.6966462, 0.30049264, 0.3624278, 
-0.1548686, 0.33242336, 0.56469715, 0.15267694, 0.84436333, 0.9930122, 0.9010413, 0.06072089, 0.058057077, 0.061639126, 
-0.25016704, 0.6757917, 0.16160122, 0.3528299, 0.37032866, 0.34238032, 0.7354228, 0.41493335, 0.6183038, 0.18408795, 
-0.3344629, 0.45407453, 0.08697238, 0.8741055, 0.46296528, 0.40633488, 0.1535257, 0.7226083, 0.90913165, 0.22269607, 
-0.068008505, 0.1103113, 0.32415798, 0.045781024, 0.32876635, 0.23993625, 0.817216, 0.77062756, 0.48911297, 0.028481547, 
-0.5923837, 0.52376825, 0.14557959, 0.7546443, 0.5793343, 0.935076, 0.5924176, 0.37608913, 0.05267449, 0.44112164, 
-0.37517703, 0.85610646, 0.078342445, 0.11640469, 0.02796489, 0.70079404, 0.24545097, 0.69059163, 0.68971163, 0.43802848, 
-0.83948654, 0.17843302, 0.15158923, 0.835361, 0.99363065, 0.13985574, 0.3516337, 0.115820184, 0.02406358, 0.13039242, 
-0.5251643, 0.96479523, 0.92582035, 0.58982223, 0.59170425, 0.8106947, 0.30849496, 0.33232814, 0.2947712, 0.5278893, 
-0.8139172, 0.77743655, 0.6699338, 0.46801004, 0.84751904, 0.21190204, 0.031968854, 0.2077533, 0.017816134, 0.62797225, 
-0.99448526, 0.12662433, 0.080915935, 0.05108449, 0.18899502, 0.41395068, 0.372179, 0.3102186, 0.7610136, 0.43947858, 
-0.5834423, 0.47659743, 0.35202554, 0.9222821, 0.9159573, 0.4103818, 0.9302861, 0.4885202, 0.52470046, 0.21727021, 
-0.39229912, 0.91312283, 0.39582044, 0.16182233, 0.62411124, 0.062049974, 0.5084992, 0.6835792, 0.98784196, 0.78172857, 
-0.10788689, 0.1438804, 0.09800406, 0.3960913, 0.13590716, 0.39854, 0.8838793, 0.8747359, 0.40082723, 0.17775355, 
-0.43851566, 0.99827635, 0.5713145, 0.8552926, 0.94444704, 0.33731982, 0.42541102, 0.74765176, 0.55205274, 0.43713725, 
-0.28161594, 0.5434486, 0.68305284, 0.80054593, 0.23567316, 0.08136242, 0.7308039, 0.9190936, 0.42697325, 0.12694505, 
-0.9054515, 0.6885998, 0.32237664, 0.97928506, 0.33159167, 0.43956187, 0.3785934, 0.9559342, 0.7863749, 0.5174173, 
-0.5265025, 0.05555021, 0.08769297, 0.3469469, 0.77875453, 0.39402276, 0.34180835, 0.5405278, 0.21737531, 0.2867914, 
-0.636639, 0.76084745, 0.13152646, 0.5507047, 0.50011265, 0.5644382, 0.46082756, 0.29745814, 0.16041815, 0.054544732, 
-0.6677361, 0.9647857, 0.44776264, 0.27388218, 0.27230206, 0.74991584, 0.67589974, 0.59202945, 0.52370095, 0.50488514, 
-0.9587264, 0.46947676, 0.9612768, 0.034635436, 0.91063476, 0.22606573, 0.45575568, 0.33610594, 0.02179139, 0.8416504, 
-0.7395541, 0.19027609, 0.7017183, 0.14018182, 0.49030608, 0.14460404, 0.55707335, 0.7716719, 0.47917238, 0.76715344, 
-0.9787343, 0.08113525, 0.7955161, 0.7318302, 0.8496812, 0.5617168, 0.60778755, 0.81381077, 0.07464484, 0.028838681, 
-0.718123, 0.74977887, 0.016826851, 0.71249014, 0.32806498, 0.16716221, 0.7995706, 0.096891016, 0.64007, 0.27404693, 
-0.10868255, 0.12472161, 0.27566674, 0.31876773, 0.31499064, 0.47746003, 0.2630674, 0.30758083, 0.78357613, 0.12769802, 
-0.1928425, 0.90422785, 0.112857096, 0.7565475, 0.5261508, 0.8775912, 0.6739607, 0.22944665, 0.18495426, 0.3489179, 
-0.61827815, 0.6419449, 0.2614611, 0.9929527, 0.12352738, 0.98977524, 0.17344923, 0.9892281, 0.81211686, 0.32314387, 
-0.34503344, 0.46018234, 0.13160191, 0.20512545, 0.65847087, 0.8540127, 0.8054685, 0.47674835, 0.41683954, 0.37222117, 
-0.29864943, 0.30020675, 0.03023468, 0.94694686, 0.8359962, 0.8138952, 0.63692176, 0.26027933, 0.18633933, 0.45047382, 
-0.49320155, 0.570124, 0.91193676, 0.2911521, 0.65576875, 0.46673766, 0.8632605, 0.28271404, 0.19524036, 0.32521543, 
-0.30401078, 0.27383924, 0.495464, 0.46043226, 0.7826646, 0.7326602, 0.7726259, 0.90773165, 0.09807661, 0.6721381, 
-0.07212267, 0.1972123, 0.8126071, 0.8127331, 0.05026847, 0.3180714, 0.6117102, 0.31451428, 0.15695652, 0.30963218, 
-0.35285345, 0.9131699, 0.8028888, 0.36164302, 0.8299423, 0.7749095, 0.54824555, 0.8404498, 0.5493567, 0.19173324, 
-0.9907522, 0.5227545, 0.281508, 0.091624096, 0.06821037, 0.024810186, 0.80474275, 0.5698024, 0.16428226, 0.10333604, 
-0.04126928, 0.7291901, 0.16220273, 0.5142012, 0.37835112, 0.29598927, 0.75751686, 0.09920368, 0.24088362, 0.33769736, 
-0.85502744, 0.5487462, 0.12575752, 0.8856082, 0.972362, 0.3908409, 0.47095042, 0.13382097, 0.63048995, 0.007755094, 
-0.18441458, 0.9321761, 0.35837498, 0.9063434, 0.6813859, 0.5493682, 0.9157043, 0.720983, 0.7445227, 0.025458287, 
-0.5133287, 0.041907787, 0.15023202, 0.053620476, 0.2683629, 0.6236633, 0.75096714, 0.28868756, 0.98329186, 0.5339531, 
-0.017392641, 0.4490419, 0.5995662, 0.21165931, 0.3367058, 0.44200596, 0.39699697, 0.39589983, 0.11926211, 0.6773695, 
-0.5538598, 0.6709218, 0.93931246, 0.15652716, 0.9189215, 0.10909318, 0.37081516, 0.25585935, 0.83281535, 0.82898295, 
-0.38028497, 0.03653382, 0.35468096, 0.21542533, 0.8243687, 0.81311965, 0.39851424, 0.07213704, 0.61724526, 0.34869868, 
-0.63987374, 0.18226288, 0.15052907, 0.096536905, 0.99036247, 0.73537266, 0.3326099, 0.14671567, 0.5696376, 0.2393799, 
-0.15237123, 0.5198045, 0.6017209, 0.067153245, 0.47159854, 0.84240687, 0.1025953, 0.99370486, 0.134699, 0.15926972, 
-0.25284818, 0.4951078, 0.45587218, 0.15430894, 0.15366808, 0.9808588, 0.094360925, 0.38414088, 0.3872906, 0.52358615, 
-0.043491747, 0.32485992, 0.7786546, 0.7705634, 0.037495736, 0.37159687, 0.5203927, 0.8427756, 0.16616471, 0.18354878, 
-0.7764833, 0.22409947, 0.6862218, 0.59343547, 0.6766117, 0.8604805, 0.4348129, 0.2875277, 0.7438268, 0.9819619, 
-0.7105244, 0.4048094, 0.937438, 0.45797554, 0.09585048, 0.14476593, 0.7263907, 0.9962201, 0.9428688, 0.009503636, 
-0.6410118, 0.94846904, 0.7594251, 0.04605143, 0.19588815, 0.8275113, 0.7411499, 0.83115745, 0.02965751, 0.10000168, 
-0.32201412, 0.25981972, 0.82754016, 0.95115024, 0.38278645, 0.02874871, 0.808886, 0.8624367, 0.47769725, 0.29318756, 
-0.5460459, 0.8068332, 0.6403141, 0.4053287, 0.8130618, 0.63868237, 0.3874219, 0.320679, 0.67471296, 0.8927298, 
-0.64520615, 0.5241726, 0.89990675, 0.15666108, 0.54253703, 0.82801425, 0.46467438, 0.64017034, 0.39754733, 0.8491004, 
-0.11933059, 0.60365546, 0.25787023, 0.6438251, 0.65994775, 0.45070463, 0.57726926, 0.98628783, 0.075189106, 0.06710178, 
-0.33587992, 0.863954, 0.51852286, 0.64968127, 0.46345773, 0.83417857, 0.30815494, 0.35409638, 0.23298964, 0.5572058, 
-0.4400894, 0.4204709, 0.1564445, 0.13692771, 0.4547955, 0.7978415, 0.35991296, 0.67087907, 0.4086132, 0.5547722, 
-0.56407434, 0.16871567, 0.46488938, 0.62859684, 0.17385697, 0.94239044, 0.548963, 0.996489, 0.74538094, 0.36235714, 
-0.061413143, 0.40113407, 0.24548991, 0.6076112, 0.5568499, 0.78125215, 0.005649717, 0.2502255, 0.69320333, 0.70835847, 
-0.5198593, 0.110578, 0.4071807, 0.84034157, 0.40901098, 0.6988597, 0.44721094, 0.12094251, 0.1890296, 0.86210626, 
-0.09079167, 0.90639013, 0.5776746, 0.5204169, 0.50302744, 0.16716424, 0.39906463, 0.8899261, 0.47582427, 0.52106726, 
-0.2852156, 0.31166598, 0.6087155, 0.87063247, 0.49579263, 0.03895533, 0.174981, 0.5488333, 0.5800778, 0.67354333, 
-0.7921918, 0.10968746, 0.97767574, 0.70025474, 0.034912895, 0.45349634, 0.761535, 0.6245478, 0.21958585, 0.47499728, 
-0.4951795, 0.42802048, 0.80745935, 0.8832747, 0.27156547, 0.15502298, 0.8234595, 0.725073, 0.10458374, 0.38968566, 
-0.38218752, 0.11572367, 0.77440125, 0.17213607, 0.42314288, 0.2081933, 0.5018625, 0.5365482, 0.3445489, 0.37005565, 
-0.5238787, 0.8983776, 0.5408647, 0.51548624, 0.06991447, 0.9811042, 0.9287144, 0.8774199, 0.48550403, 0.04953112, 
-0.40562928, 0.7745168, 0.6703402, 0.00082698837, 0.025887761, 0.8571951, 0.5042066, 0.7254408, 0.59906703, 0.34076965, 
-0.21549584, 0.449908, 0.44424957, 0.19039217, 0.29135585, 0.67646813, 0.33528623, 0.80553967, 0.27711186, 0.8267196, 
-0.95163375, 0.22498675, 0.2799989, 0.8495302, 0.9511186, 0.5968019, 0.8871558, 0.2919731, 0.8133602, 0.29046127, 
-0.22630857, 0.9460396, 0.23956898, 0.05505262, 0.98405635, 0.60767066, 0.4453835, 0.77357423, 0.14624831, 0.5659478, 
-0.7039867, 0.7764218, 0.9374812, 0.0037792725, 0.1545598, 0.073970705, 0.45412806, 0.35047254, 0.2241304, 0.39344636, 
-0.645818, 0.12317476, 0.600308, 0.65878445, 0.09789734, 0.18064253, 0.49451795, 0.82080996, 0.049708407, 0.42908588, 
-0.9700393, 0.2122335, 0.9120806, 0.30860576, 0.11446109, 0.26945624, 0.21033902, 0.38919696, 0.20633578, 0.6836851, 
-0.23108464, 0.56171197, 0.6592914, 0.7111641, 0.122732915, 0.175212, 0.28750554, 0.2762196, 0.69497037, 0.87714785, 
-0.14267384, 0.53668326, 0.06784272, 0.41991386, 0.6446433, 0.10313381, 0.34573162, 0.58078456, 0.9571553, 0.8034138, 
-0.11315275, 0.62457347, 0.7238658, 0.71716243, 0.59590846, 0.4917532, 0.8643412, 0.62887543, 0.88931817, 0.8851036, 
-0.86363167, 0.064931095, 0.14413676, 0.54044527, 0.16236171, 0.084106006, 0.4638834, 0.8891439, 0.5360515, 0.9226853, 
-0.893137, 0.21829833, 0.12583959, 0.17256053, 0.28641203, 0.4333561, 0.14439079, 0.49216673, 0.6639625, 0.011327274, 
-0.9237246, 0.62955445, 0.43204167, 0.40292194, 0.5705324, 0.6065112, 0.83784616, 0.94212896, 0.115255654, 0.6309797, 
-0.3108708, 0.6586301, 0.38690144, 0.8098668, 0.013516203, 0.07774274, 0.39254647, 0.52739745, 0.25755215, 0.5605373, 
-0.6392504, 0.4565877, 0.044733036, 0.034469932, 0.91027683, 0.8948544, 0.4987339, 0.5513053, 0.4307504, 0.16255233, 
-0.3473624, 0.3721745, 0.96491295, 0.8779909, 0.961379, 0.2340772, 0.6328894, 0.7412148, 0.9699129, 0.55585057, 
-0.24625985, 0.52175444, 0.77388823, 0.9050718, 0.61181456, 0.23450689, 0.8313969, 0.31597278, 0.15904433, 0.20866929, 
-0.04080962, 0.6169933, 0.23461457, 0.1034252, 0.37207687, 0.4671369, 0.58482146, 0.39757174, 0.4926451, 0.67567796, 
-0.107777245, 0.28654084, 0.5113785, 0.9527033, 0.28361735, 0.9386963, 0.6937171, 0.50891054, 0.84848785, 0.779439, 
-0.44485334, 0.65133166, 0.55748457, 0.7017016, 0.3142774, 0.11749596, 0.68269944, 0.13966125, 0.42265537, 0.6757699, 
-0.06345752, 0.18276113, 0.39226097, 0.2220811, 0.12174272, 0.7303691, 0.13755992, 0.8614878, 0.50591403, 0.4942421, 
-0.64925575, 0.23531766, 0.24856968, 0.29423487, 0.44807333, 0.959719, 0.010375906, 0.82118493, 0.6214544, 0.67311823, 
-0.5407898, 0.3224864, 0.46748495, 0.37960532, 0.76381594, 0.38947794, 0.05950873, 0.53291297, 0.7891478, 0.2545809, 
-0.7844374, 0.44516018, 0.97491634, 0.81687516, 0.61222047, 0.9250161, 0.89427984, 0.28929746, 0.83096063, 0.5532483, 
-0.8011364, 0.8322293, 0.0029964554, 0.35424575, 0.13018323, 0.20953566, 0.402762, 0.2632497, 0.25362825, 0.3545584, 
-0.10712006, 0.8615145, 0.51820683, 0.7495371, 0.13498017, 0.74097115, 0.7152762, 0.0126556605, 0.45826513, 0.73226476, 
-0.67086035, 0.6046469, 0.07234, 0.25133318, 0.70980465, 0.20409557, 0.2604013, 0.43169454, 0.6820144, 0.5230572, 
-0.065439165, 0.72107846, 0.99022436, 0.06820616, 0.87198186, 0.70856047, 0.31948993, 0.11323921, 0.24942209, 0.5542803, 
-0.9867159, 0.79625905, 0.27928472, 0.4345894, 0.14746083, 0.9229229, 0.9269534, 0.22537923, 0.681895, 0.8712493, 
-0.20973994, 0.8816242, 0.83103234, 0.098695815, 0.88238794, 0.19648944, 0.75988936, 0.75166327, 0.64444107, 0.9260877, 
-0.94913435, 0.9710675, 0.5812353, 0.7305711, 0.28911924, 0.3860416, 0.87129015, 0.45000067, 0.87755525, 0.42641973, 
-0.4214812, 0.60203695, 0.7632336, 0.90398484, 0.74554884, 0.8746013, 0.32536224, 0.6377506, 0.10387234, 0.7868817, 
-0.2771422, 0.035022065, 0.74979955, 0.8107651, 0.31331727, 0.18381497, 0.8900461, 0.89152855, 0.18581823, 0.6754924, 
-0.9486711, 0.5678266, 0.4687981, 0.32333443, 0.60514593, 0.015648454, 0.21502374, 0.5487136, 0.14547014, 0.76141924, 
-0.05163277, 0.4769527, 0.34782398, 0.25547525, 0.44976813, 0.607703, 0.11839061, 0.9270475, 0.35314697, 0.007786621, 
-0.8711272, 0.12213872, 0.64779097, 0.8575594, 0.64894545, 0.9141123, 0.22126794, 0.77047014, 0.4172538, 0.10530428, 
-0.4959955, 0.97976166, 0.26418245, 0.20206283, 0.47774863, 0.85365456, 0.13323887, 0.43989918, 0.29883888, 0.7299004, 
-0.65957755, 0.7766486, 0.49228048, 0.34245312, 0.7352489, 0.8001895, 0.6871981, 0.49432427, 0.360997, 0.70561427, 
-0.06542435, 0.96299857, 0.5383816, 0.1780316, 0.8043652, 0.82653236, 0.92003566, 0.6112387, 0.67438895, 0.6910336, 
-0.79438055, 0.44455358, 0.13145985, 0.04016586, 0.26542372, 0.07187113, 0.21277027, 0.14576113, 0.77772665, 0.59611356, 
-0.47446412, 0.6784915, 0.62820864, 0.62324655, 0.34820905, 0.094478644, 0.62985826, 0.30533785, 0.122310445, 0.84875596, 
-0.22691421, 0.7269437, 0.40947318, 0.7116395, 0.039879926, 0.5329969, 0.44138008, 0.08615084, 0.39769763, 0.65121627, 
-0.93361884, 0.52200013, 0.7655102, 0.60780525, 0.9355199, 0.21502401, 0.64518875, 0.45211464, 0.0770294, 0.6633778, 
-0.5874192, 0.541437, 0.7165977, 0.7648834, 0.2311502, 0.3869329, 0.33478996, 0.915135, 0.82982254, 0.70988655, 
-0.19667415, 0.6146979, 0.4889283, 0.825633, 0.46411943, 0.067436874, 0.035080392, 0.41982034, 0.0002859342, 0.7324268, 
-0.630491, 0.12661943, 0.7480635, 0.12651038, 0.6624947, 0.952464, 0.9129812, 0.020403363, 0.6877267, 0.13318504, 
-0.44928992, 0.1777436, 0.22830844, 0.45893264, 0.2613367, 0.68547726, 0.010346001, 0.6445898, 0.4804893, 0.652947, 
-0.19820693, 0.52624506, 0.25632828, 0.687811, 0.4545421, 0.31892103, 0.033071853, 0.9398772, 0.14368583, 0.868083, 
-0.17994362, 0.2253684, 0.4518287, 0.34460258, 0.032886766, 0.4607998, 0.7933734, 0.59008723, 0.10238874, 0.27868623, 
-0.47395167, 0.3143866, 0.22740832, 0.6966375, 0.26059666, 0.018930554, 0.3863894, 0.029995646, 0.5642963, 0.7786422, 
-0.05709087, 0.39049065, 0.939331, 0.3473389, 0.53421986, 0.10424597, 0.8702912, 0.060252476, 0.6719683, 0.34357366, 
-0.9193921, 0.97310406, 0.8767175, 0.8196437, 0.9532414, 0.22392152, 0.7259149, 0.88370585, 0.42604586, 0.80053693, 
-0.8921038, 0.42025873, 0.54220104, 0.2018031, 0.17899537, 0.8838203, 0.29883677, 0.5596908, 0.42721438, 0.43561155, 
-0.9325316, 0.0030762074, 0.37558094, 0.36504367, 0.8109921, 0.78945297, 0.2860374, 0.10448979, 0.8103827, 0.9286408, 
-0.59050864, 0.733121, 0.91811895, 0.75881505, 0.35929412, 0.50084764, 0.4376691, 0.40776464, 0.7433961, 0.036675144, 
-0.29301566, 0.5026836, 0.6039498, 0.7637594, 0.8865383, 0.6368321, 0.8482896, 0.7375279, 0.16834354, 0.65039957, 
-0.8054092, 0.31060037, 0.6330381, 0.23635677, 0.41104206, 0.9163159, 0.5975231, 0.51167387, 0.008651535, 0.16378845, 
-0.93788415, 0.62142515, 0.07332315, 0.49740508, 0.21002825, 0.15898286, 0.5021398, 0.78338593, 0.842509, 0.67814773, 
-0.44615123, 0.8910721, 0.81629467, 0.39053923, 0.14259589, 0.42984807, 0.39912644, 0.61182153, 0.47850534, 0.17416, 
-0.94116336, 0.5485095, 0.93614626, 0.15998314, 0.12323159, 0.27990827, 0.10008287, 0.6817622, 0.34777302, 0.4429782, 
-0.9033245, 0.92599523, 0.39911312, 0.57960767, 0.09879101, 0.6715905, 0.4293604, 0.1065447, 0.55373114, 0.72755545, 
-0.13469236, 0.06490368, 0.89501894, 0.4901958, 0.20424834, 0.9143371, 0.4943057, 0.24249884, 0.093760885, 0.98119396, 
-0.5171895, 0.98570156, 0.03316852, 0.83449155, 0.22262509, 0.38937467, 0.6852789, 0.91334003, 0.3741735, 0.93012, 
-0.05889999, 0.8203776, 0.43561292, 0.3995308, 0.77482325, 0.52015597, 0.491959, 0.23668702, 0.29174823, 0.47100535, 
-0.0004876647, 0.29258174, 0.058090426, 0.75094986, 0.039467655, 0.8762597, 0.65349054, 0.44595045, 0.9557348, 0.20889449, 
-0.78560257, 0.857584, 0.5880013, 0.36657903, 0.9257887, 0.917623, 0.89282674, 0.56462157, 0.35698256, 0.70941633, 
-0.9863116, 0.51602036, 0.7323712, 0.62361115, 0.6686555, 0.31431475, 0.62929076, 0.4954881, 0.71537256, 0.68409234, 
-0.4223781, 0.2576187, 0.9507506, 0.6227555, 0.98070633, 0.22460775, 0.9276111, 0.28221866, 0.79502386, 0.34636542, 
-0.73588413, 0.23932843, 0.95760524, 0.165279, 0.1445174, 0.20131597, 0.23237628, 0.069033906, 0.47374207, 0.85720026, 
-0.62732923, 0.9273374, 0.8797045, 0.5823319, 0.48469374, 0.48446727, 0.5602105, 0.43447927, 0.08229436, 0.7251529, 
-0.24696892, 0.15800244, 0.7305779, 0.27164242, 0.78651637, 0.52798384, 0.9068334, 0.9652458, 0.3858727, 0.701181, 
-0.9900118, 0.61060804, 0.7695977, 0.010617126, 0.97353226, 0.74698323, 0.5584152, 0.56709224, 0.47909376, 0.46733952, 
-0.08193848, 0.56025684, 0.021746036, 0.8581723, 0.056763105, 0.49504068, 0.37791422, 0.36841872, 0.13806179, 0.49623904, 
-0.66439724, 0.49313185, 0.19992432, 0.06987098, 0.09939649, 0.5778817, 0.50875056, 0.6859628, 0.3787626, 0.6165335, 
-0.29448256, 0.2671305, 0.6831612, 0.77256113, 0.86718845, 0.016721206, 0.1577397, 0.86908734, 0.60879964, 0.73771054, 
-0.9260521, 0.9931183, 0.9553855, 0.6149548, 0.6432144, 0.6867121, 0.1362564, 0.8724056, 0.21487932, 0.2914757, 
-0.15006965, 0.53841466, 0.827184, 0.88963366, 0.03678374, 0.49687997, 0.41068372, 0.69972676, 0.9112206, 0.39565054, 
-0.23823264, 0.8724524, 0.18832962, 0.8625602, 0.17285694, 0.814808, 0.87709564, 0.24918492, 0.99098384, 0.0400419, 
-0.337301, 0.50882685, 0.7596191, 0.4003513, 0.5701869, 0.67127895, 0.5377463, 0.58496946, 0.42665657, 0.4126844, 
-0.4416253, 0.63634497, 0.47108346, 0.08728689, 0.4664639, 0.75606793, 0.4399465, 0.79352754, 0.7357774, 0.3703085, 
-0.6060375, 0.45801297, 0.9578667, 0.2131491, 0.49947786, 0.05359975, 0.8047887, 0.092825316, 0.4420979, 0.82840645, 
-0.80961645, 0.8870715, 0.88142174, 0.17483743, 0.95417476, 0.6412428, 0.7787956, 0.4268327, 0.31944674, 0.3655048, 
-0.9591336, 0.82571423, 0.2730702, 0.49853623, 0.95402527, 0.6018877, 0.4013689, 0.10104273, 0.39609635, 0.41678905, 
-0.37486148, 0.083568096, 0.5134075, 0.6206753, 0.43400443, 0.879288, 0.5509602, 0.54647, 0.9008734, 0.5165872, 
-0.86649024, 0.44492102, 0.14287159, 0.59825015, 0.60306793, 0.5545538, 0.7549232, 0.29624605, 0.13311216, 0.8252211, 
-0.97727233, 0.013113789, 0.4740808, 0.37027258, 0.41117483, 0.7803232, 0.18494278, 0.45933047, 0.25912383, 0.89759016, 
-0.65223086, 0.70374596, 0.696729, 0.02530885, 0.45354494, 0.72604835, 0.37366393, 0.2607464, 0.740833, 0.07488672, 
-0.09028263, 0.23232558, 0.5259593, 0.80285954, 0.49901456, 0.5142126, 0.6828427, 0.67482007, 0.8954683, 0.39947143, 
-0.8469645, 0.10512285, 0.96793056, 0.5708752, 0.43951672, 0.3617477, 0.6094873, 0.14313498, 0.2095005, 0.6536812, 
-0.69434524, 0.09162968, 0.28734615, 0.0032832306, 0.86435634, 0.1627443, 0.748192, 0.11756273, 0.14470519, 0.8770196, 
-0.1808899, 0.49417683, 0.55541307, 0.05822544, 0.73493844, 0.7449467, 0.48715448, 0.67122126, 0.871258, 0.8969622, 
-0.097480536, 0.5101227, 0.5638622, 0.8596524, 0.050625734, 0.547108, 0.7358154, 0.12585375, 0.5857921, 0.09179724, 
-0.11656108, 0.23052894, 0.051245883, 0.08715177, 0.38054147, 0.99865294, 0.9449794, 0.52267605, 0.93850327, 0.33627024, 
-0.7660206, 0.56527996, 0.5301148, 0.018448701, 0.21858154, 0.3527876, 0.5497098, 0.90970516, 0.8359368, 0.69457, 
-0.8745932, 0.93826604, 0.27187696, 0.3125383, 0.5562007, 0.1842225, 0.5277675, 0.42769375, 0.9526575, 0.3172483, 
-0.42692894, 0.6223383, 0.5317706, 0.05290796, 0.7604585, 0.95036095, 0.44293094, 0.46826127, 0.67768395, 0.7362855, 
-0.7999673, 0.96447843, 0.732718, 0.53498775, 0.13094164, 0.5322006, 0.9800079, 0.5454135, 0.64107084, 0.6978381, 
-0.9973982, 0.82611024, 0.28991696, 0.8912221, 0.21720403, 0.17829505, 0.95865196, 0.7387076, 0.5309511, 0.19631897, 
-0.47088546, 0.5172857, 0.5700186, 0.6212549, 0.90934134, 0.14368229, 0.033509336, 0.4772069, 0.25799018, 0.26822057, 
-0.9098567, 0.08144851, 0.23202117, 0.09965124, 0.8946027, 0.91011477, 0.20554802, 0.7368892, 0.18159665, 0.024000084, 
-0.20421462, 0.982354, 0.7866229, 0.2548194, 0.31985012, 0.6008187, 0.33242133, 0.64054847, 0.8357039, 0.58216345, 
-0.991709, 0.70422333, 0.93731016, 0.481365, 0.26540005, 0.2826816, 0.39445987, 0.1114631, 0.6256465, 0.9872593, 
-0.49869126, 0.502801, 0.2874233, 0.37285027, 0.78798145, 0.9159497, 0.5940891, 0.19026573, 0.99661946, 0.30708927, 
-0.972747, 0.22176278, 0.55711097, 0.50695103, 0.99210435, 0.48853147, 0.73066276, 0.31519917, 0.3014048, 0.30852264, 
-0.81126094, 0.39296088, 0.641503, 0.6758267, 0.27651158, 0.20563333, 0.14413832, 0.7506562, 0.83425117, 0.6119211, 
-0.5156549, 0.094084926, 0.111242734, 0.1943373, 0.52530885, 0.70141363, 0.6949307, 0.41377264, 0.46683794, 0.4039004, 
-0.006729609, 0.14215559, 0.643929, 0.52861464, 0.6094164, 0.7699462, 0.1471124, 0.43035918, 0.4892606, 0.7768686, 
-0.5520188, 0.07926069, 0.8100583, 0.31712383, 0.17599839, 0.105730385, 0.861298, 0.6115966, 0.096338674, 0.5823481, 
-0.77181137, 0.8434329, 0.35601455, 0.38469836, 0.79143435, 0.8786621, 0.11052005, 0.36277366, 0.9816422, 0.29069075, 
-0.7936008, 0.31689015, 0.84836125, 0.8975044, 0.30179304, 0.66910535, 0.7490319, 0.1128883, 0.06641029, 0.5065654, 
-0.058520928, 0.71377915, 0.26139554, 0.057382602, 0.059902266, 0.4363942, 0.28402662, 0.7941189, 0.018338913, 0.41957843, 
-0.84011555, 0.083334126, 0.31743395, 0.88448983, 0.632089, 0.16329671, 0.78614104, 0.2592306, 0.7371803, 0.7307543, 
-0.65942615, 0.7843387, 0.448717, 0.19856988, 0.9832678, 0.23512867, 0.23089947, 0.9125539, 0.015330798, 0.50689304, 
-0.3566985, 0.74840975, 0.5451863, 0.5897733, 0.5238272, 0.05803223, 0.5820373, 0.29863194, 0.3247961, 0.35504016, 
-0.5946355, 0.31640115, 0.34443474, 0.56206375, 0.45057517, 0.71026665, 0.99945617, 0.9638714, 0.26541534, 0.13849631, 
-0.8829643, 0.48980126, 0.375708, 0.33565596, 0.84713924, 0.2741822, 0.26506215, 0.06282568, 0.07411481, 0.8247736, 
-0.20549475, 0.37147272, 0.7787881, 0.5114459, 0.06287994, 0.09170583, 0.53814787, 0.72766066, 0.36066267, 0.5740568, 
-0.58125937, 0.4875091, 0.93443453, 0.38214013, 0.13611887, 0.343025, 0.439904, 0.88665324, 0.7479947, 0.27300113, 
-0.23567249, 0.26702806, 0.64713854, 0.8768345, 0.62392867, 0.8668972, 0.37270173, 0.20953032, 0.74263406, 0.249645, 
-0.79297006, 0.51921165, 0.22451714, 0.50002253, 0.14954542, 0.22316273, 0.53761303, 0.83298886, 0.4991838, 0.35886934, 
-0.17211881, 0.2717955, 0.6032087, 0.6913585, 0.5572369, 0.3954552, 0.55536675, 0.9935679, 0.19953707, 0.5041142, 
-0.83427817, 0.3784089, 0.314831, 0.80111367, 0.58910114, 0.93846667, 0.7243342, 0.90195364, 0.8875172, 0.19598271, 
-0.7190041, 0.3286175, 0.9850266, 0.11101766, 0.78108674, 0.06204771, 0.26299196, 0.434412, 0.23259473, 0.9129562, 
-0.805412, 0.6069152, 0.38746944, 0.38912535, 0.10088234, 0.96387696, 0.6638193, 0.95578, 0.31959754, 0.22847345, 
-0.3115305, 0.37913388, 0.009993258, 0.23851983, 0.4153668, 0.41456118, 0.20438069, 0.42340347, 0.9109214, 0.21107873, 
-0.49882856, 0.6356594, 0.94547164, 0.3032011, 0.6398653, 0.84350127, 0.28676888, 0.49219108, 0.91027176, 0.49518922, 
-0.13246326, 0.120954745, 0.76097316, 0.28658092, 0.6987022, 0.22736304, 0.99093944, 0.9257056, 0.7002313, 0.6252242, 
-0.27464733, 0.76855415, 0.5823561, 0.6590438, 0.8844522, 0.3398702, 0.31862426, 0.7465068, 0.6956509, 0.36652556, 
-0.857667, 0.8395885, 0.5234906, 0.021515984, 0.4141276, 0.16975257, 0.66144353, 0.084268354, 0.74926007, 0.25738105, 
-0.67710805, 0.17162827, 0.045508236, 0.8244083, 0.0960102, 0.19057575, 0.6181607, 0.72341233, 0.5398176, 0.18800376, 
-0.4236217, 0.27867505, 0.7231721, 0.28569725, 0.9364314, 0.73027444, 0.05330333, 0.28642786, 0.4187489, 0.29999506, 
-0.524877, 0.5402621, 0.7965402, 0.54374623, 0.6375222, 0.29287475, 0.59746414, 0.73945713, 0.87245333, 0.5289497, 
-0.56591946, 0.9066711, 0.17644554, 0.4428503, 0.94811606, 0.10301907, 0.7230459, 0.75794774, 0.5630336, 0.69387645, 
-0.7217095, 0.5952119, 0.20668921, 0.5076471, 0.9429038, 0.57899195, 0.116416365, 0.23779334, 0.08508458, 0.6838532, 
-0.11644924, 0.3750157, 0.6655195, 0.44926503, 0.73250407, 0.13684598, 0.37508807, 0.50176203, 0.1868861, 0.80313545, 
-0.59311163, 0.8787036, 0.850959, 0.0108679095, 0.62208426, 0.5169506, 0.10222952, 0.28032187, 0.3375812, 0.83341235, 
-0.0072284974, 0.2953556, 0.7233943, 0.7248724, 0.5782856, 0.9296651, 0.3335729, 0.28889313, 0.6008424, 0.05853025, 
-0.17645839, 0.3596708, 0.6543726, 0.18860014, 0.41250044, 0.19090378, 0.24115163, 0.7271805, 0.7103462, 0.8112701, 
-0.727931, 0.22128391, 0.5710617, 0.7598981, 0.10076484, 0.8430059, 0.7442529, 0.1958213, 0.8855628, 0.4259532, 
-0.47676244, 0.8360945, 0.90021217, 0.25167224, 0.67662466, 0.8210937, 0.6516214, 0.940647, 0.8709795, 0.802839, 
-0.8032731, 0.08619493, 0.9009196, 0.12835586, 0.62667704, 0.2334408, 0.224331, 0.6623589, 0.59836745, 0.4311805, 
-0.27579898, 0.37504902, 0.5699756, 0.5263111, 0.10548131, 0.7859446, 0.72429395, 0.96349615, 0.6241076, 0.7352797, 
-0.18541217, 0.13775158, 0.40333033, 0.17488916, 0.5817678, 0.34036386, 0.45945865, 0.40270033, 0.51197547, 0.59140676, 
-0.5392824, 0.3005046, 0.85620105, 0.9075073, 0.007996995, 0.6417361, 0.3203643, 0.44270578, 0.13322107, 0.86732405, 
-0.6186749, 0.08189404, 0.59745383, 0.4543823, 0.15015423, 0.10171343, 0.2661189, 0.37390104, 0.14619094, 0.8906801, 
-0.096799746, 0.68812525, 0.31653944, 0.13569976, 0.6174268, 0.6655215, 0.6828646, 0.72603047, 0.54658806, 0.28631318, 
-0.77398217, 0.8216307, 0.15038341, 0.0069607063, 0.8918981, 0.97529435, 0.518848, 0.6624684, 0.5183141, 0.46374524, 
-0.4655803, 0.28158814, 0.83027506, 0.75678355, 0.11660483, 0.10351813, 0.54029775, 0.948948, 0.024734931, 0.48005438, 
-0.074244976, 0.0855576, 0.2565094, 0.62129533, 0.49460703, 0.85115707, 0.98396516, 0.7205013, 0.2900805, 0.34247547, 
-0.9588715, 0.5943338, 0.89611775, 0.8469079, 0.09334188, 0.79704416, 0.9315106, 0.59049314, 0.5624842, 0.17485987, 
-0.5828654, 0.60365057, 0.85558695, 0.6824457, 0.4250998, 0.8152116, 0.8578502, 0.55975586, 0.01909494, 0.5139087, 
-0.12522376, 0.73391664, 0.7012955, 0.06653367, 0.2120682, 0.6884245, 0.5651213, 0.5290881, 0.51235366, 0.040741026, 
-0.9913292, 0.7983467, 0.3723879, 0.17583862, 0.50487375, 0.87124646, 0.3854704, 0.9833672, 0.66344166, 0.31956065, 
-0.1720075, 0.94980466, 0.38646382, 0.8498751, 0.89718896, 0.4705944, 0.22997065, 0.57406366, 0.19619557, 0.67939544, 
-0.9933069, 0.4242093, 0.70140636, 0.7761718, 0.21725173, 0.22495484, 0.89303833, 0.82958406, 0.6348397, 0.40491733, 
-0.23192288, 0.40242258, 0.07813944, 0.5217432, 0.18353066, 0.7845187, 0.23126268, 0.6797483, 0.17757194, 0.55385333, 
-0.42974123, 0.874483, 0.8963142, 0.6995343, 0.34190118, 0.17541912, 0.34745282, 0.85142046, 0.16934472, 0.7414738, 
-0.4584539, 0.99105763, 0.33289248, 0.8329583, 0.04743413, 0.5671199, 0.09694037, 0.5962161, 0.9585869, 0.2799189, 
-0.9782081, 0.5558863, 0.3485275, 0.25852436, 0.08763776, 0.76958495, 0.8716652, 0.86472064, 0.6663444, 0.1126702, 
-0.23933174, 0.55022234, 0.39649174, 0.64234227, 0.24965419, 0.118823886, 0.5278951, 0.0018720366, 0.43427062, 0.04183261, 
-0.877502, 0.04161787, 0.66023934, 0.8933659, 0.9464634, 0.24086526, 0.069530085, 0.24518117, 0.47430903, 0.61641073, 
-0.6875784, 0.6350466, 0.7211614, 0.89765304, 0.5756452, 0.87385494, 0.5259555, 0.63778985, 0.6118965, 0.5723162, 
-0.3037539, 0.48273215, 0.18507604, 0.05667453, 0.5021421, 0.90823156, 0.59456587, 0.69055027, 0.5833041, 0.92861027, 
-0.039224792, 0.095068336, 0.16194543, 0.9167543, 0.40241688, 0.93659025, 0.895647, 0.4551616, 0.31206095, 0.8467725, 
-0.7000548, 0.62648404, 0.39041162, 0.049933646, 0.42509183, 0.6042851, 0.8290609, 0.49883872, 0.06669706, 0.37579927, 
-0.5928684, 0.89010525, 0.3899755, 0.8619544, 0.7380787, 0.39476988, 0.8565418, 0.6035648, 0.39122385, 0.038231853, 
-0.64629936, 0.37897983, 0.6618771, 0.54569876, 0.577186, 0.59251004, 0.47310117, 0.8044071, 0.49523613, 0.6390549, 
-0.97820795, 0.07079393, 0.3257289, 0.765124, 0.8722614, 0.6772699, 0.092320524, 0.1351424, 0.6315827, 0.89785695, 
-0.07917066, 0.09572715, 0.6238532, 0.20750481, 0.33574188, 0.14911953, 0.70509285, 0.29999104, 0.1786756, 0.0076469877, 
-0.08004845, 0.29208216, 0.063937746, 0.27382907, 0.20047311, 0.32107502, 0.96460694, 0.84471285, 0.47274768, 0.8325818, 
-0.13118395, 0.024653764, 0.0036025788, 0.42764217, 0.39759132, 0.52207446, 0.56437635, 0.62485147, 0.989693, 0.060808785, 
-0.30244938, 0.7213994, 0.9719821, 0.49336693, 0.9590612, 0.5505722, 0.75512666, 0.4543723, 0.2099569, 0.42806646, 
-0.8874172, 0.17311013, 0.6257315, 0.48758915, 0.55900645, 0.68612576, 0.0068561803, 0.051899806, 0.56465095, 0.5511864, 
-0.71266294, 0.2476077, 0.6623947, 0.7990009, 0.76667297, 0.054516893, 0.092124574, 0.19621104, 0.80991346, 0.8136675, 
-0.58474314, 0.08024137, 0.31029803, 0.117866814, 0.70519763, 0.35864902, 0.32010004, 0.5705708, 0.3147679, 0.64990085, 
-0.56594837, 0.51023465, 0.6347559, 0.044681232, 0.94516456, 0.9580738, 0.39892223, 0.51601344, 0.8686357, 0.71146554, 
-0.51521826, 0.51247656, 0.06020054, 0.43850663, 0.3481458, 0.054841675, 0.059004717, 0.1729812, 0.7266939, 0.9045443, 
-0.45844766, 0.5589156, 0.6444588, 0.39628944, 0.8433233, 0.8071758, 0.8628121, 0.5078647, 0.78239155, 0.20035744, 
-0.36602575, 0.43628535, 0.7371319, 0.91475004, 0.985238, 0.20242831, 0.61285174, 0.6177135, 0.8538363, 0.8085992, 
-0.65559465, 0.57611114, 0.32757533, 0.09844793, 0.2984492, 0.07226656, 0.020040827, 0.87179136, 0.769721, 0.65035594, 
-0.2996443, 0.14711884, 0.8438769, 0.4102236, 0.1914532, 0.007032739, 0.8657759, 0.23846649, 0.20135792, 0.13798875, 
-0.09526171, 0.8910575, 0.7336219, 0.6682783, 0.34543982, 0.078932896, 0.77534467, 0.14545049, 0.45326862, 0.14571752, 
-0.44198993, 0.44129124, 0.31914487, 0.9180948, 0.24894963, 0.8823365, 0.23134027, 0.54601085, 0.09784024, 0.7710568, 
-0.787135, 0.99102074, 0.73814374, 0.13203558, 0.90071315, 0.2189069, 0.5924085, 0.32690832, 0.7232968, 0.97820526, 
-0.33665246, 0.37438527, 0.41635555, 0.71584755, 0.7133375, 0.76453716, 0.84248924, 0.6592971, 0.7530081, 0.2195163, 
-0.29692188, 0.87459034, 0.41852275, 0.62400347, 0.20836602, 0.8583531, 0.82797396, 0.9257821, 0.16127396, 0.3091167, 
-0.77569246, 0.31976497, 0.14062625, 0.43030116, 0.35085374, 0.104240976, 0.15291376, 0.6015863, 0.76756513, 0.12653293, 
-0.48652443, 0.44843635, 0.42215365, 0.47506335, 0.80906504, 0.06760467, 0.02493567, 0.6032973, 0.20475733, 0.48441246, 
-0.039847255, 0.5720432, 0.7930028, 0.8783239, 0.47413486, 0.91254467, 0.57249796, 0.11414025, 0.9236696, 0.042360075, 
-0.39093295, 0.6666264, 0.16563436, 0.41418016, 0.20251282, 0.016887465, 0.23375902, 0.9860544, 0.36499384, 0.60909647, 
-0.6116234, 0.24090295, 0.891732, 0.6264752, 0.7329919, 0.8484855, 0.45243672, 0.9434594, 0.8149384, 0.14076136, 
-0.8334174, 0.22467664, 0.72102475, 0.6768615, 0.26926944, 0.20364925, 0.52676225, 0.2623023, 0.95616627, 0.43830907, 
-0.531743, 0.03877351, 0.67791677, 0.72520506, 0.7356, 0.81989807, 0.282802, 0.007973485, 0.27255052, 0.7921776, 
-0.8338457, 0.038881265, 0.23830348, 0.59566087, 0.872789, 0.7989443, 0.68031126, 0.16652757, 0.14533207, 0.62564933, 
-0.46010798, 0.6290386, 0.29920182, 0.7829082, 0.20894268, 0.16625631, 0.94560164, 0.48877287, 0.14491072, 0.9988636, 
-0.49012524, 0.9714567, 0.029888112, 0.92668474, 0.07735347, 0.5728499, 0.5629862, 0.16652691, 0.8908752, 0.91309386, 
-0.56568354, 0.44446322, 0.67090887, 0.022760825, 0.3069157, 0.7945361, 0.9863731, 0.12536389, 0.80407244, 0.47032514, 
-0.523338, 0.36023465, 0.11697024, 0.33051696, 0.9782011, 0.9027044, 0.7395717, 0.89500856, 0.51626235, 0.5693437, 
-0.8742964, 0.7940291, 0.86306274, 0.27368698, 0.30205235, 0.86238897, 0.008993154, 0.31161872, 0.5183074, 0.29993913, 
-0.2359581, 0.51378435, 0.27565238, 0.23223823, 0.059965752, 0.01564475, 0.9581297, 0.276441, 0.4759925, 0.41440654, 
-0.17988315, 0.82023776, 0.68470037, 0.6745856, 0.47552556, 0.12989059, 0.85448647, 0.69937116, 0.94848365, 0.17464903, 
-0.83327824, 0.6679777, 0.65026456, 0.32153153, 0.038797423, 0.7716544, 0.58140045, 0.3972219, 0.7207085, 0.44452676, 
-0.78554296, 0.67475444, 0.6070565, 0.50413334, 0.23436703, 0.009553685, 0.08458229, 0.884732, 0.27055123, 0.96255636, 
-0.9445748, 0.46313068, 0.41901603, 0.10185582, 0.38946053, 0.05405868, 0.10932874, 0.18847717, 0.79816145, 0.17216177, 
-0.007902476, 0.30962202, 0.36313507, 0.34365836, 0.46666092, 0.5679804, 0.8635198, 0.9541208, 0.19344081, 0.2883113, 
-0.4342443, 0.5609078, 0.55573255, 0.03146575, 0.6288636, 0.50512874, 0.21318124, 0.18056706, 0.44021857, 0.46597186, 
-0.045308296, 0.96975446, 0.42881992, 0.9859273, 0.23007429, 0.37014756, 0.24896163, 0.54840875, 0.932071, 0.98473877, 
-0.6623257, 0.39292327, 0.5990605, 0.5485467, 0.4366243, 0.47592095, 0.31161934, 0.26339814, 0.037472416, 0.6663866, 
-0.1460339, 0.13046144, 0.6912912, 0.9822399, 0.528312, 0.38366696, 0.90739816, 0.3875503, 0.47299224, 0.88433176, 
-0.8408774, 0.92876166, 0.7482586, 0.33218956, 0.12685347, 0.038148023, 0.8808021, 0.37720776, 0.11358407, 0.09651337, 
-0.3190188, 0.31511107, 0.022049852, 0.20870206, 0.6259856, 0.041321024, 0.9618473, 0.007185834, 0.5948415, 0.15294261, 
-0.19350938, 0.9497831, 0.14309464, 0.77383196, 0.31993797, 0.91484684, 0.27846324, 0.44658, 0.45761526, 0.8464073, 
-0.46274942, 0.86141133, 0.075416476, 0.0477392, 0.14386131, 0.733564, 0.64466465, 0.26687092, 0.42169324, 0.39847627, 
-0.5951189, 0.9344116, 0.14981407, 0.94095904, 0.3473678, 0.83092284, 0.108411595, 0.48258916, 0.3562543, 0.48699102, 
-0.42181966, 0.9002123, 0.7927088, 0.32004964, 0.6908224, 0.8910943, 0.78566706, 0.9744266, 0.012251603, 0.21200661, 
-0.7596848, 0.4342221, 0.9195925, 0.26717675, 0.63376397, 0.45760745, 0.2396946, 0.97431064, 0.06484076, 0.8924216, 
-0.39665636, 0.6949764, 0.5854926, 0.1963652, 0.5578238, 0.2590978, 0.799969, 0.2021356, 0.42646417, 0.48901513, 
-0.8064353, 0.7958741, 0.0903257, 0.9706242, 0.42458767, 0.56253713, 0.068702534, 0.75536686, 0.3569168, 0.25276697, 
-0.94789696, 0.670238, 0.2546193, 0.2096866, 0.6387915, 0.16089676, 0.01481907, 0.8826373, 0.3071951, 0.8897603, 
-0.59122825, 0.13410094, 0.4177484, 0.4638327, 0.09033466, 0.72684324, 0.3147197, 0.5963436, 0.76222587, 0.43172458, 
-0.091125324, 0.58353144, 0.5479625, 0.52323645, 0.40557137, 0.9638107, 0.3438964, 0.9489683, 0.8425891, 0.07122685, 
-0.38890493, 0.48432773, 0.61739385, 0.8120738, 0.9445246, 0.7264184, 0.4403571, 0.375806, 0.55757374, 0.396927, 
-0.24427874, 0.9173317, 0.8949405, 0.5367038, 0.8977869, 0.6723343, 0.3781257, 0.626493, 0.88028955, 0.6977444, 
-0.24781741, 0.4723589, 0.993141, 0.9251922, 0.16164163, 0.36436552, 0.12227554, 0.73138285, 0.80411524, 0.6749808, 
-0.8170004, 0.06585078, 0.040048227, 0.23596825, 0.5008554, 0.10690048, 0.51670706, 0.6056746, 0.5193081, 0.3639163, 
-0.28648618, 0.9389137, 0.03876988, 0.36529887, 0.18744585, 0.17379361, 0.68859094, 0.011258623, 0.62544954, 0.733237, 
-0.585685, 0.7174034, 0.06867873, 0.14484468, 0.82340944, 0.916546, 0.49118677, 0.6922017, 0.65043217, 0.58015907, 
-0.60414284, 0.70897424, 0.57169074, 0.8825929, 0.5799266, 0.17842796, 0.8772835, 0.65897226, 0.03584844, 0.7908864, 
-0.15562724, 0.7724511, 0.10718488, 0.5163733, 0.41125825, 0.3089037, 0.43358904, 0.62784207, 0.73774636, 0.98784804, 
-0.6757746, 0.111016914, 0.10593328, 0.07087821, 0.08929581, 0.09959695, 0.99717206, 0.89520353, 0.4125588, 0.5843094, 
-0.6157137, 0.82450545, 0.95524246, 0.939149, 0.7597735, 0.5775119, 0.36722296, 0.15617695, 0.78537226, 0.009017896, 
-0.29651013, 0.029618707, 0.97541016, 0.83456314, 0.5776098, 0.8132339, 0.6102185, 0.55230546, 0.73358643, 0.51450574, 
-0.48295695, 0.86334467, 0.9544553, 0.6625841, 0.90438455, 0.49312592, 0.603041, 0.50081253, 0.7932971, 0.4803297, 
-0.1812559, 0.9820799, 0.24641345, 0.45153904, 0.1751727, 0.3311218, 0.81720865, 0.16803588, 0.7565998, 0.8337463, 
-0.9416807, 0.2774121, 0.8424698, 0.7287285, 0.6913379, 0.64615583, 0.13560674, 0.27137014, 0.4932684, 0.27606192, 
-0.48937842, 0.4448666, 0.16161712, 0.89805305, 0.10135246, 0.75236905, 0.87005013, 0.29265827, 0.034764472, 0.26664755, 
-0.9744709, 0.86641043, 0.3628798, 0.30504256, 0.827762, 0.31443018, 0.7832053, 0.5238711, 0.65939045, 0.246488, 
-0.9960252, 0.44218266, 0.7957057, 0.8998401, 0.572825, 0.20554484, 0.020874852, 0.22572684, 0.97124624, 0.2582287, 
-0.35751918, 0.33167085, 0.007544129, 0.5172352, 0.99095124, 0.73638934, 0.8204628, 0.34836042, 0.3501866, 0.4228037, 
-0.46107167, 0.5245504, 0.1332714, 0.48995224, 0.8592754, 0.07527029, 0.91453224, 0.53742725, 0.90096647, 0.3769077, 
-0.8629506, 0.6117356, 0.61197966, 0.2467804, 0.2800367, 0.047195755, 0.6491609, 0.261777, 0.32522804, 0.8958076, 
-0.7314942, 0.6443233, 0.32141203, 0.7765358, 0.90912837, 0.6428001, 0.85886633, 0.8456446, 0.31409132, 0.09137268, 
-0.49396735, 0.43484485, 0.17368458, 0.23658675, 0.78541636, 0.47147486, 0.30891126, 0.30575344, 0.040564716, 0.49755472, 
-0.2910126, 0.48344758, 0.32476038, 0.59433854, 0.39527807, 0.7457836, 0.71969116, 0.76076376, 0.23719852, 0.9437555, 
-0.087228395, 0.55868584, 0.023132376, 0.45437896, 0.6913095, 0.8167484, 0.20313835, 0.35673562, 0.58082384, 0.2164753, 
-0.21640398, 0.06888765, 0.22333595, 0.8095938, 0.88294035, 0.42810574, 0.43805102, 0.37539294, 0.46136406, 0.80856186, 
-0.7382845, 0.34340748, 0.2212123, 0.8276733, 0.60479504, 0.24804658, 0.3195629, 0.7270735, 0.3812577, 0.16334477, 
-0.92310894, 0.09810257, 0.6084461, 0.37033582, 0.004144284, 0.9352815, 0.41171247, 0.71930563, 0.54527724, 0.968668, 
-0.2683365, 0.9521756, 0.7249296, 0.8240894, 0.28115076, 0.22212493, 0.26011166, 0.5151666, 0.71139824, 0.9671723, 
-0.3077326, 0.3442982, 0.29939967, 0.42863667, 0.20547101, 0.7438209, 0.33747354, 0.19545908, 0.8495839, 0.44326293, 
-0.49718547, 0.4760649, 0.97547793, 0.4174791, 0.29336637, 0.11830141, 0.46044156, 0.85300016, 0.8054495, 0.9476588, 
-0.016393282, 0.7187454, 0.8301157, 0.49269608, 0.5402253, 0.78610885, 0.6184779, 0.39712286, 0.54652256, 0.3826701, 
-0.98793495, 0.80439633, 0.015675247, 0.4140854, 0.85561216, 0.5788107, 0.7987029, 0.17980942, 0.16486481, 0.26032335, 
-0.597808, 0.2162534, 0.86972165, 0.102014296, 0.47148252, 0.7922716, 0.97669774, 0.3074505, 0.53072304, 0.16284934, 
-0.7616834, 0.40711153, 0.7097171, 0.7637394, 0.950779, 0.58898723, 0.5141825, 0.8067036, 0.88841134, 0.41936216, 
-0.12534304, 0.94035065, 0.6489365, 0.46691382, 0.45532802, 0.69278914, 0.46038964, 0.56139255, 0.56186694, 0.7145557, 
-0.31959853, 0.28063214, 0.6881353, 0.54512614, 0.3498508, 0.8001399, 0.8490237, 0.7281014, 0.021213572, 0.7479538, 
-0.8094111, 0.31102738, 0.8663998, 0.38367322, 0.6209867, 0.5808234, 0.09467922, 0.25193584, 0.46330634, 0.26662496, 
-0.06462818, 0.99199927, 0.29139808, 0.74550265, 0.13498032, 0.65745735, 0.5673169, 0.40280786, 0.64668626, 0.7786934, 
-0.33188194, 0.4153052, 0.7455836, 0.8161674, 0.8432508, 0.48105124, 0.7189762, 0.16459095, 0.41388863, 0.15063916, 
-0.73996353, 0.78608114, 0.78549004, 0.14045759, 0.609951, 0.8143157, 0.07395084, 0.26526332, 0.8459271, 0.8745046, 
-0.5981099, 0.20845382, 0.098086186, 0.29524195, 0.6499275, 0.32759923, 0.98923403, 0.9426327, 0.41014582, 0.6923934, 
-0.23282301, 0.44621587, 0.08141512, 0.24252021, 0.4160718, 0.3941059, 0.5654438, 0.050232418, 0.5404224, 0.13993548, 
-0.8618472, 0.9300883, 0.8380472, 0.31266716, 0.52666146, 0.27854705, 0.20650926, 0.1509405, 0.13555165, 0.32066464, 
-0.5835065, 0.30205357, 0.5568808, 0.7721817, 0.18058343, 0.123428136, 0.31721902, 0.45034164, 0.16623993, 0.5156516, 
-0.4918172, 0.7763435, 0.75444514, 0.7214952, 0.91781616, 0.29374766, 0.704666, 0.5429698, 0.7243858, 0.21584511, 
-0.24887188, 0.02371842, 0.7248409, 0.7059916, 0.012657363, 0.6680217, 0.37040663, 0.785419, 0.7685805, 0.37138042, 
-0.12108998, 0.83829355, 0.80708104, 0.08948117, 0.108886935, 0.93076944, 0.8893351, 0.30923343, 0.061936773, 0.29264367, 
-0.07688689, 0.11510216, 0.8839925, 0.02477082, 0.64811826, 0.08550372, 0.17564313, 0.11655201, 0.39485103, 0.23291379, 
-0.57388103, 0.6635394, 0.42655468, 0.9197065, 0.071792774, 0.5597881, 0.57721263, 0.8508891, 0.75952435, 0.5125618, 
-0.75302154, 0.53180003, 0.6817611, 0.79485947, 0.3945616, 0.6535236, 0.9692625, 0.66496396, 0.61260825, 0.98704666, 
-0.40441254, 0.3954326, 0.48103306, 0.43174213, 0.13895822, 0.13376972, 0.13972592, 0.7000701, 0.05787335, 0.92715365, 
-0.49237853, 0.2538546, 0.390568, 0.5356667, 0.7974994, 0.45755056, 0.41173887, 0.8873745, 0.017688395, 0.54909885, 
-0.3535568, 0.038445998, 0.54970914, 0.549375, 0.5396221, 0.54508686, 0.43334106, 0.089132994, 0.6302092, 0.99459463, 
-0.11624123, 0.5106792, 0.50394374, 0.40780434, 0.8285013, 0.17844845, 0.18250638, 0.99481255, 0.7807483, 0.93802303, 
-0.42006215, 0.87714255, 0.7930158, 0.8323707, 0.020183232, 0.4991669, 0.14123203, 0.1460944, 0.9973601, 0.93701106, 
-0.24178477, 0.081888, 0.64727557, 0.06350941, 0.6334899, 0.36596653, 0.84572345, 0.931658, 0.89212, 0.59387136, 
-0.70042866, 0.050592937, 0.06986087, 0.063278705, 0.81091243, 0.98169935, 0.74991083, 0.98276365, 0.7071655, 0.6190509, 
-0.27504414, 0.41692632, 0.106626175, 0.07966534, 0.12903668, 0.47641423, 0.24543023, 0.71733844, 0.5291918, 0.040455237, 
-0.40385485, 0.28724664, 0.091772884, 0.69319814, 0.7528099, 0.034353238, 0.8634036, 0.44043434, 0.77431446, 0.46253473, 
-0.332725, 0.25084835, 0.10269255, 0.18687698, 0.23759438, 0.36946923, 0.8072817, 0.72973704, 0.021458272, 0.038483858, 
-0.7492561, 0.1584684, 0.43892893, 0.37830916, 0.6619669, 0.8248584, 0.9752618, 0.5676102, 0.93447274, 0.15707563, 
-0.120536305, 0.12838502, 0.40246627, 0.8516648, 0.19001648, 0.41318202, 0.95882004, 0.3766627, 0.31046882, 0.7765592, 
-0.11829578, 0.3094765, 0.20844917, 0.24463072, 0.28632593, 0.024195805, 0.31423378, 0.9197492, 0.84207094, 0.75956744, 
-0.66913253, 0.5156932, 0.6958802, 0.4907079, 0.29119918, 0.24538647, 0.8483177, 0.7134637, 0.031231258, 0.92795146, 
-0.059091415, 0.29579335, 0.5059616, 0.6172388, 0.34199843, 0.20433997, 0.84838206, 0.2510278, 0.9968605, 0.82441235, 
-0.41064918, 0.43061897, 0.41926822, 0.2448991, 0.92018807, 0.43977955, 0.95001924, 0.19429821, 0.09198324, 0.63777107, 
-0.51062465, 0.055512622, 0.72553927, 0.17490527, 0.48794308, 0.60484314, 0.43250486, 0.91175836, 0.5604656, 0.94463, 
-0.56486434, 0.24535634, 0.34543145, 0.38251737, 0.7174677, 0.82250243, 0.8035149, 0.59121037, 0.9026323, 0.081985965, 
-0.17581372, 0.06320599, 0.9228887, 0.017658591, 0.3489183, 0.23851357, 0.096424945, 0.45098105, 0.57051986, 0.8514196, 
-0.29536724, 0.6540195, 0.62148046, 0.39346015, 0.41732678, 0.0035787956, 0.5702541, 0.33105636, 0.12929575, 0.7371553, 
-0.7718351, 0.93662375, 0.6905622, 0.052230474, 0.25954804, 0.16529284, 0.08518753, 0.03675085, 0.52743137, 0.097685665, 
-0.6362647, 0.35880888, 0.2916659, 0.009997273, 0.46195737, 0.4474187, 0.13262391, 0.7078807, 0.825987, 0.24942951, 
-0.5084182, 0.9815238, 0.3412385, 0.70904595, 0.6492628, 0.9108448, 0.62387586, 0.9519713, 0.9651906, 0.71388894, 
-0.25224832, 0.4724585, 0.4619146, 0.16547702, 0.31015086, 0.23919, 0.37264377, 0.8706582, 0.7581105, 0.18362544, 
-0.15332605, 0.05967409, 0.9235497, 0.47283417, 0.21515496, 0.93655837, 0.3623536, 0.6114832, 0.93150276, 0.9699081, 
-0.8709549, 0.8623734, 0.5050694, 0.87986624, 0.2287371, 0.7903113, 0.5953852, 0.98151624, 0.40296772, 0.34870324, 
-0.541417, 0.13321623, 0.07156025, 0.81354237, 0.84543735, 0.16380614, 0.8968943, 0.12618889, 0.6998464, 0.22276738, 
-0.07477489, 0.2619657, 0.94977015, 0.6423615, 0.09610346, 0.4487441, 0.05797409, 0.8684043, 0.49389097, 0.7127044, 
-0.54849124, 0.012392659, 0.020468513, 0.99528253, 0.8429341, 0.3898749, 0.96738917, 0.58204836, 0.9367399, 0.5198395, 
-0.6438048, 0.39112753, 0.46769053, 0.40940732, 0.64220846, 0.02010981, 0.9881138, 0.11000732, 0.6273968, 0.051348828, 
-0.039664086, 0.2361647, 0.91163677, 0.7087354, 0.8951332, 0.6089892, 0.91260326, 0.86270785, 0.7837628, 0.779993, 
-0.73233724, 0.72698087, 0.48762527, 0.69026333, 0.800212, 0.5290243, 0.11274772, 0.07627774, 0.9706083, 0.45556244, 
-0.19641699, 0.31484595, 0.18944897, 0.18000686, 0.5789626, 0.6836474, 0.79427516, 0.54036283, 0.00015307916, 0.07599365, 
-0.46063024, 0.94796675, 0.24100749, 0.44254217, 0.67304033, 0.31232652, 0.10075587, 0.31173313, 0.100149296, 0.23394488, 
-0.47727165, 0.10468131, 0.79828554, 0.1567469, 0.78750235, 0.9168239, 0.9035022, 0.7774272, 0.6091953, 0.11318414, 
-0.9073621, 0.9118361, 0.139399, 0.17183441, 0.85493183, 0.7248181, 0.04671574, 0.7316299, 0.1297728, 0.21148583, 
-0.814714, 0.37224042, 0.8625547, 0.70776916, 0.31936276, 0.7843705, 0.4859734, 0.04508312, 0.017223012, 0.4878855, 
-0.42826846, 0.8010146, 0.97612846, 0.73666346, 0.9782908, 0.09173568, 0.51656044, 0.032702066, 0.3925045, 0.6621387, 
-0.7801451, 0.01684795, 0.93116754, 0.886969, 0.16863157, 0.54879415, 0.80856776, 0.06917309, 0.5876103, 0.94822216, 
-0.26561078, 0.36912593, 0.18196031, 0.8886635, 0.41923082, 0.1050312, 0.24212655, 0.09051639, 0.8373841, 0.0031318855, 
-0.4308505, 0.8584191, 0.7602042, 0.121309794, 0.68491566, 0.10634747, 0.9357077, 0.4027356, 0.19354361, 0.7631962, 
-0.2082577, 0.014013676, 0.3391254, 0.46763408, 0.43134072, 0.7978661, 0.44107288, 0.9755858, 0.5391376, 0.7705686, 
-0.9758027, 0.4168003, 0.4574728, 0.06900084, 0.22227472, 0.059142508, 0.6190543, 0.08746498, 0.3174326, 0.8732596, 
-0.84960914, 0.42604402, 0.19531794, 0.38937265, 0.2312882, 0.921726, 0.25664374, 0.8098577, 0.20205325, 0.06228409, 
-0.61308646, 0.40583217, 0.8756295, 0.8244142, 0.7399645, 0.2515971, 0.030000538, 0.7143262, 0.45732272, 0.6213647, 
-0.6639583, 0.26654074, 0.5513788, 0.0668155, 0.02732918, 0.014050223, 0.40094635, 0.69120336, 0.8990351, 0.6257732, 
-0.48729318, 0.8482427, 0.08530297, 0.320284, 0.91358703, 0.7822137, 0.8186957, 0.94975275, 0.2363459, 0.50961477, 
-0.54122233, 0.63121516, 0.77353257, 0.4768535, 0.15748215, 0.56997055, 0.54117084, 0.6330586, 0.32903638, 0.9706776, 
-0.02914197, 0.90472806, 0.6301423, 0.69606787, 0.20930128, 0.5830684, 0.8746652, 0.12850243, 0.36204344, 0.21723796, 
-0.5207796, 0.5654404, 0.9108227, 0.57628006, 0.5749909, 0.7648438, 0.3205292, 0.5553455, 0.91082716, 0.9577508, 
-0.43290135, 0.08024777, 0.47798032, 0.94770795, 0.0801424, 0.03274318, 0.49300817, 0.07452531, 0.90933335, 0.45735866, 
-0.4728794, 0.7678877, 0.362167, 0.9283575, 0.5966312, 0.5825651, 0.21810043, 0.3892351, 0.11098274, 0.33051863, 
-0.9075484, 0.6901933, 0.5877093, 0.019107932, 0.9888351, 0.9757819, 0.72039247, 0.19725248, 0.90186256, 0.39263836, 
-0.24944134, 0.98582536, 0.72223145, 0.3712856, 0.5377763, 0.9488942, 0.42674774, 0.68243426, 0.6159255, 0.1765581, 
-0.09006023, 0.8001399, 0.21916907, 0.9046848, 0.74435854, 0.7528919, 0.20327342, 0.9824652, 0.9796489, 0.9924258, 
-0.5467434, 0.9312941, 0.44436273, 0.58030856, 0.05020233, 0.742708, 0.49253845, 0.4588724, 0.95887285, 0.10436046, 
-0.31235072, 0.29575568, 0.17266272, 0.516695, 0.20791732, 0.48705408, 0.045656245, 0.9908814, 0.3905812, 0.647737, 
-0.15581739, 0.5356661, 0.77330965, 0.93442464, 0.2404584, 0.10740854, 0.47102425, 0.6830245, 0.27474937, 0.2359432, 
-0.7725085, 0.73792726, 0.21760361, 0.9094368, 0.845895, 0.31814724, 0.5414626, 0.14192294, 0.32108325, 0.7950682, 
-0.45635575, 0.96787536, 0.72356147, 0.511565, 0.8642074, 0.79430455, 0.62747717, 0.70247406, 0.6967675, 0.2573045, 
-0.7072357, 0.212392, 0.591884, 0.33191186, 0.8366084, 0.01107724, 0.15798447, 0.5099381, 0.33985013, 0.9427938, 
-0.27168378, 0.8095139, 0.18412302, 0.72292966, 0.33185193, 0.5744235, 0.078152075, 0.2632259, 0.67080003, 0.8897701, 
-0.94559145, 0.9037333, 0.66979814, 0.595513, 0.19138126, 0.18794204, 0.8121047, 0.26174462, 0.07021725, 0.44615385, 
-0.47993135, 0.76855016, 0.986257, 0.017444894, 0.5287075, 0.5601165, 0.1460432, 0.88569176, 0.07282839, 0.8348177, 
-0.16016278, 0.031524524, 0.80207276, 0.37828946, 0.52338445, 0.6468418, 0.7837523, 0.00063179433, 0.17971309, 0.2897839, 
-0.7161524, 0.3642513, 0.031674027, 0.8069974, 0.31171304, 0.8035024, 0.54259384, 0.9963711, 0.14053062, 0.6486664, 
-0.19897254, 0.8962398, 0.43972084, 0.8936963, 0.46286246, 0.5031336, 0.8232569, 0.16667813, 0.19422211, 0.7717354, 
-0.42838028, 0.19246033, 0.19039753, 0.8359823, 0.7296073, 0.9140669, 0.10166052, 0.29150867, 0.07212853, 0.54453945, 
-0.40418974, 0.8114729, 0.08203155, 0.78043336, 0.7300014, 0.11568007, 0.73687613, 0.1792596, 0.70573187, 0.7252052, 
-0.017522655, 0.14967212, 0.7451611, 0.42416203, 0.6358452, 0.26392296, 0.59180367, 0.9083765, 0.915427, 0.020250821, 
-0.8235849, 0.6170742, 0.80640966, 0.40797767, 0.86140364, 0.52369213, 0.17385374, 0.19569172, 0.07739012, 0.3976461, 
-0.70184183, 0.2510852, 0.92424256, 0.59599113, 0.24447663, 0.38749963, 0.81420827, 0.6592875, 0.16369487, 0.34718236, 
-0.76625746, 0.6439973, 0.46094626, 0.46901694, 0.75421274, 0.27870816, 0.44729918, 0.76623553, 0.20013711, 0.46568435, 
-0.32226324, 0.193284, 0.37608168, 0.051877704, 0.72095454, 0.7871155, 0.0050632227, 0.6740539, 0.9190297, 0.20630927, 
-0.94182634, 0.5411844, 0.10186948, 0.30808574, 0.023363324, 0.7664375, 0.22542956, 0.14916998, 0.17968538, 0.24834555, 
-0.44971466, 0.93251616, 0.74468166, 0.56824464, 0.25399336, 0.17958756, 0.15612793, 0.33739275, 0.6537649, 0.5826955, 
-0.07639295, 0.40761822, 0.9955546, 0.6117058, 0.07538286, 0.50855786, 0.8750035, 0.8723649, 0.8750366, 0.4573611, 
-0.38243642, 0.1401544, 0.7402578, 0.9573856, 0.40535605, 0.22507304, 0.54212785, 0.1528605, 0.44565362, 0.98777527, 
-0.05327858, 0.2981292, 0.5865501, 0.9517916, 0.015969688, 0.38974705, 0.44860238, 0.807837, 0.79788435, 0.541367, 
-0.6309876, 0.6676705, 0.02028897, 0.33633423, 0.12991633, 0.5342081, 0.5456298, 0.4901637, 0.2327029, 0.5148055, 
-0.89143395, 0.35306472, 0.27413338, 0.7223243, 0.86590916, 0.30956024, 0.1922584, 0.787296, 0.1628886, 0.02892033, 
-0.6374597, 0.0032674163, 0.89173913, 0.66598964, 0.5294169, 0.77826375, 0.8210681, 0.043763056, 0.5957361, 0.6856358, 
-0.05995547, 0.06716649, 0.07448051, 0.3336696, 0.8263735, 0.7147659, 0.11986544, 0.40392354, 0.8274693, 0.87114793, 
-0.67944324, 0.051964145, 0.9201576, 0.9308481, 0.096341334, 0.70021385, 0.02399584, 0.8642258, 0.08588241, 0.70640945, 
-0.19748867, 0.6613063, 0.6449484, 0.768964, 0.9039073, 0.6277202, 0.77593136, 0.35429934, 0.8069173, 0.3516526, 
-0.71314, 0.50186676, 0.8944276, 0.5470671, 0.45485002, 0.82426745, 0.2785842, 0.9404638, 0.8959508, 0.15114321, 
-0.18969482, 0.78833485, 0.9598267, 0.29174066, 0.3494771, 0.5854956, 0.0831098, 0.960891, 0.56964827, 0.829203, 
-0.7542679, 0.9568423, 0.9578806, 0.88932663, 0.48814714, 0.39864913, 0.42221805, 0.3055165, 0.42976233, 0.19865331, 
-0.93883455, 0.7655661, 0.5970062, 0.4758167, 0.15800795, 0.17757647, 0.15753652, 0.3730905, 0.47599813, 0.27207386, 
-0.42162967, 0.08353208, 0.96827507, 0.9347392, 0.51671463, 0.40915382, 0.7014796, 0.35320777, 0.4194869, 0.3184117, 
-0.5446104, 0.81504035, 0.78465104, 0.9777143, 0.5973847, 0.7562977, 0.54398614, 0.0051009622, 0.05891997, 0.05620089, 
-0.4020494, 0.9730677, 0.5107014, 0.69729745, 0.21230865, 0.4241287, 0.19132863, 0.48401004, 0.1337327, 0.17190064, 
-0.42795905, 0.7100193, 0.48489287, 0.29757443, 0.40757337, 0.67073584, 0.98856723, 0.023141444, 0.37261203, 0.07899332, 
-0.6971695, 0.06901029, 0.8860296, 0.11135061, 0.65404296, 0.12379419, 0.98091507, 0.6192919, 0.878432, 0.40171024, 
-0.63359034, 0.15243557, 0.31417054, 0.41979724, 0.87002444, 0.44856197, 0.5728306, 0.2709776, 0.7224305, 0.09258589, 
-0.21782517, 0.21746957, 0.21947508, 0.24758625, 0.8904527, 0.8345911, 0.3301475, 0.48707664, 0.57014096, 0.92664886, 
-0.7677305, 0.5208447, 0.6324889, 0.97992665, 0.35903138, 0.3330391, 0.0870381, 0.39935082, 0.043254532, 0.08851445, 
-0.44321367, 0.57203674, 0.60557806, 0.73202246, 0.5383103, 0.27552348, 0.39584875, 0.06509563, 0.42754996, 0.95901144, 
-0.09790518, 0.7175897, 0.3007109, 0.28002614, 0.86116815, 0.47969994, 0.8495352, 0.63844335, 0.22089794, 0.8194518, 
-0.7936467, 0.4938384, 0.049150985, 0.9517831, 0.6339798, 0.11274567, 0.51994663, 0.3342439, 0.060765848, 0.53698534, 
-0.36152387, 0.17347981, 0.22772305, 0.6339161, 0.6493722, 0.64578843, 0.6118915, 0.48745263, 0.70927596, 0.6149292, 
-0.43874234, 0.26505187, 0.05952667, 0.6111295, 0.8287437, 0.050140806, 0.22013378, 0.35246277, 0.1187585, 0.87933147, 
-0.4835039, 0.44859475, 0.1784529, 0.2238027, 0.29486778, 0.9493753, 0.52288574, 0.65379494, 0.09804267, 0.42556462, 
-0.75557685, 0.061604857, 0.0043297815, 0.8905646, 0.59748757, 0.92442536, 0.4898666, 0.6667948, 0.6306539, 0.21537969, 
-0.8678084, 0.3620826, 0.9291674, 0.6059688, 0.3807095, 0.5285948, 0.43431175, 0.43802148, 0.123039424, 0.583839, 
-0.8926119, 0.16748385, 0.2154854, 0.18143441, 0.05348144, 0.9129291, 0.99502695, 0.003920352, 0.33904833, 0.69999695, 
-0.12290272, 0.9580966, 0.38940993, 0.2837113, 0.85935235, 0.37713748, 0.2607221, 0.16896206, 0.013641968, 0.90431833, 
-0.5602742, 0.553339, 0.72180885, 0.9033788, 0.011523027, 0.1214213, 0.51942736, 0.57248414, 0.8430932, 0.76627296, 
-0.5150635, 0.084864266, 0.5307555, 0.51420367, 0.5329527, 0.588093, 0.84611946, 0.82289535, 0.83708316, 0.68455845, 
-0.9293985, 0.48594627, 0.32774645, 0.930657, 0.092476964, 0.9097118, 0.97267264, 0.6454561, 0.74661636, 0.003572011, 
-0.2678727, 0.2653497, 0.4243795, 0.2187211, 0.023564778, 0.3392729, 0.44567502, 0.31210658, 0.16991138, 0.9320601, 
-0.39350176, 0.42254278, 0.16082714, 0.57277536, 0.18493341, 0.03803846, 0.4273411, 0.87520623, 0.7507586, 0.27125937, 
-0.531018, 0.43782672, 0.33187887, 0.32908353, 0.97491986, 0.07432794, 0.22559255, 0.7911518, 0.8109018, 0.10181122, 
-0.14874865, 0.8739713, 0.8258678, 0.83952117, 0.49840027, 0.24971384, 0.6604848, 0.3120344, 0.4906389, 0.19367984, 
-0.14241797, 0.5340129, 0.65298396, 0.90502304, 0.2910567, 0.50685567, 0.3251191, 0.7549711, 0.7457236, 0.054438505, 
-0.4823707, 0.09746641, 0.8946975, 0.47535703, 0.472554, 0.83004594, 0.9334708, 0.09529597, 0.24380124, 0.9492368, 
-0.11368034, 0.6545232, 0.5012047, 0.06810016, 0.7833115, 0.5195305, 0.59667504, 0.32130596, 0.07437508, 0.9352196, 
-0.3775537, 0.11530671, 0.38456735, 0.5570788, 0.12884142, 0.9970051, 0.7848427, 0.42685586, 0.03802683, 0.4680642, 
-0.7492088, 0.47062147, 0.045428254, 0.75646335, 0.6194405, 0.05128224, 0.9792738, 0.35051075, 0.3669672, 0.66835433, 
-0.31624305, 0.56518877, 0.06823316, 0.5414021, 0.0799995, 0.4878948, 0.032808155, 0.5848838, 0.12171154, 0.7715262, 
-0.9101807, 0.0038131434, 0.680596, 0.810504, 0.67688483, 0.36706397, 0.7128991, 0.3376187, 0.3465156, 0.47554886, 
-0.04520323, 0.5066149, 0.05726915, 0.77573705, 0.200028, 0.6430589, 0.6090949, 0.7447414, 0.44865963, 0.73202926, 
-0.5402566, 0.24616429, 0.9543388, 0.40602076, 0.61897653, 0.8123649, 0.047073558, 0.8431653, 0.47707924, 0.6409466, 
-0.964197, 0.1999589, 0.3051443, 0.2665006, 0.5578835, 0.7453957, 0.7900255, 0.23492423, 0.07957853, 0.25237653, 
-0.33838317, 0.6416551, 0.0039951354, 0.89141834, 0.62315106, 0.80962807, 0.50791967, 0.29249611, 0.34137407, 0.4369406, 
-0.8787999, 0.28806677, 0.1362242, 0.3896823, 0.23126958, 0.66401637, 0.049474377, 0.27457523, 0.19152752, 0.8645199, 
-0.31999043, 0.8697338, 0.8605395, 0.70556897, 0.5113519, 0.84524435, 0.20147063, 0.79076856, 0.21785353, 0.4546323, 
-0.8530334, 0.3741707, 0.66516286, 0.1962831, 0.3936461, 0.89860153, 0.24216916, 0.062920436, 0.7828697, 0.8093484, 
-0.30444527, 0.75457746, 0.5017912, 0.040138636, 0.7621467, 0.6761302, 0.06373471, 0.915462, 0.035231, 0.89386714, 
-0.6959213, 0.51545024, 0.04339671, 0.21505861, 0.9323861, 0.46864936, 0.7811156, 0.29842615, 0.38006642, 0.7779068, 
-0.60815746, 0.7171511, 0.07464257, 0.88674176, 0.5839072, 0.5046292, 0.6229039, 0.9399411, 0.9960362, 0.33266804, 
-0.42184722, 0.9865539, 0.49170554, 0.38217908, 0.5600747, 0.565413, 0.36794263, 0.82040083, 0.94342226, 0.8352217, 
-0.78150964, 0.2860086, 0.75553757, 0.32398638, 0.758711, 0.3375832, 0.33077398, 0.45010427, 0.26389697, 0.92499673, 
-0.11748593, 0.943743, 0.682854, 0.004962936, 0.20119096, 0.58729416, 0.67993486, 0.6150494, 0.45623145, 0.25751752, 
-0.053226303, 0.12379362, 0.91942585, 0.702563, 0.47201994, 0.7093674, 0.023744669, 0.66121763, 0.65498394, 0.36697313, 
-0.10070673, 0.96071476, 0.3550039, 0.54484475, 0.99639714, 0.32214886, 0.96161354, 0.7506562, 0.12803078, 0.24632397, 
-0.17385522, 0.17279965, 0.6760441, 0.071039446, 0.2151821, 0.4781042, 0.30369994, 0.48674262, 0.18098812, 0.97278047, 
-0.8854781, 0.7528932, 0.3641694, 0.68590474, 0.7819954, 0.657716, 0.36658275, 0.05297459, 0.85196644, 0.049343612, 
-0.31383854, 0.6695563, 0.7951203, 0.89692384, 0.82429004, 0.15677115, 0.5887391, 0.13800927, 0.0085657975, 0.8790421, 
-0.6256806, 0.9292787, 0.48701864, 0.20990747, 0.083662316, 0.88042665, 0.4477495, 0.8483864, 0.48738086, 0.99391574, 
-0.40566745, 0.537002, 0.4802295, 0.6822035, 0.48149505, 0.34781352, 0.5965454, 0.66909915, 0.76284933, 0.33868113, 
-0.9555661, 0.90863895, 0.89868975, 0.07868716, 0.93248546, 0.50429887, 0.37767935, 0.77912027, 0.24674945, 0.05841095, 
-0.8893651, 0.16569066, 0.4781768, 0.301946, 0.34709984, 0.9561994, 0.26587456, 0.15426192, 0.6022424, 0.9015687, 
-0.20996648, 0.51819634, 0.5655937, 0.8580507, 0.64367616, 0.7768365, 0.18932684, 0.11291685, 0.4154288, 0.4764765, 
-0.5602257, 0.91964, 0.37515992, 0.6698847, 0.923476, 0.7170417, 0.030588947, 0.40833148, 0.27742204, 0.57936347, 
-0.5027473, 0.6686292, 0.60163695, 0.42896992, 0.10455062, 0.2399768, 0.058825243, 0.17828348, 0.3351036, 0.5252956, 
-0.08193896, 0.44228348, 0.06685673, 0.8612806, 0.12871465, 0.43736976, 0.34304523, 0.040639006, 0.435011, 0.15564895, 
-0.314972, 0.2647625, 0.36369145, 0.770273, 0.4981852, 0.96972513, 0.79053074, 0.80829215, 0.37847006, 0.63005817, 
-0.9256105, 0.85754305, 0.8768399, 0.022878975, 0.3988214, 0.54133725, 0.9165594, 0.1366238, 0.7535001, 0.40369937, 
-0.71801126, 0.011043364, 0.77781326, 0.89013314, 0.39453754, 0.11794228, 0.85278326, 0.5138793, 0.54117, 0.4861062, 
-0.37399647, 0.98994994, 0.9733205, 0.12177309, 0.26439142, 0.23798482, 0.30493778, 0.83136404, 0.9307847, 0.13482551, 
-0.44944605, 0.25053307, 0.7998134, 0.70504546, 0.5996852, 0.22439589, 0.5654436, 0.043977752, 0.4624592, 0.5873774, 
-0.52081037, 0.20642142, 0.2871389, 0.031311635, 0.43763772, 0.30392867, 0.48694924, 0.4735583, 0.37573543, 0.3802429, 
-0.11694187, 0.27665144, 0.26712215, 0.89236385, 0.25606167, 0.93566054, 0.8842226, 0.7550668, 0.7584876, 0.16083659, 
-0.23639946, 0.08519537, 0.20583908, 0.6186746, 0.9542533, 0.46747816, 0.21122995, 0.07276781, 0.29044798, 0.17014165, 
-0.5524987, 0.8088055, 0.0514201, 0.9537926, 0.9652958, 0.16757506, 0.70281106, 0.94200885, 0.6841354, 0.96046275, 
-0.7510356, 0.8313795, 0.45562857, 0.5505418, 0.017883644, 0.17279461, 0.9834109, 0.90744954, 0.44898376, 0.66402465, 
-0.34017327, 0.81037676, 0.28549019, 0.3016226, 0.35097796, 0.43561503, 0.00058234343, 0.6684643, 0.07705832, 0.97015953, 
-0.092698716, 0.41418144, 0.18311031, 0.20559378, 0.82774425, 0.30813637, 0.22523133, 0.31332958, 0.92706805, 0.08848662, 
-0.23284948, 0.9422138, 0.07093142, 0.7980248, 0.409801, 0.40501997, 0.6295668, 0.6552973, 0.600791, 0.7814587, 
-0.48406723, 0.3037804, 0.62378407, 0.62642336, 0.82996833, 0.7421219, 0.5233153, 0.74979746, 0.6028146, 0.5296808, 
-0.16699271, 0.03434674, 0.86495054, 0.71397585, 0.86776406, 0.33685416, 0.6482692, 0.2500348, 0.7227976, 0.70974725, 
-0.9475633, 0.6700813, 0.9803815, 0.36049715, 0.43117517, 0.39795953, 0.7394454, 0.4874654, 0.8918216, 0.94595796, 
-0.8060482, 0.3452851, 0.06767335, 0.29559964, 0.4860923, 0.7889183, 0.7903974, 0.556687, 0.3756254, 0.08562232, 
-0.7848211, 0.47543386, 0.71051496, 0.3973873, 0.9214939, 0.19850273, 0.07726323, 0.3569556, 0.9302608, 0.072946854, 
-0.7567508, 0.37953198, 0.9324997, 0.89104366, 0.8338954, 0.8139859, 0.32339892, 0.2632869, 0.19524816, 0.43200883, 
-0.002676534, 0.035849903, 0.8579759, 0.65685666, 0.7236325, 0.82170767, 0.9666734, 0.5693509, 0.22788355, 0.07884572, 
-0.54645675, 0.09158218, 0.8744094, 0.63717526, 0.9249262, 0.47212943, 0.9595664, 0.58299416, 0.43900326, 0.23267244, 
-0.3206963, 0.3824898, 0.55720466, 0.8188748, 0.18920717, 0.42651626, 0.41278538, 0.17662966, 0.46170422, 0.6721064, 
-0.4655194, 0.5271105, 0.3614388, 0.94361657, 0.08294579, 0.74897116, 0.617458, 0.053658314, 0.67375475, 0.09978627, 
-0.23182935, 0.50791234, 0.12907204, 0.85141504, 0.5264901, 0.66516864, 0.50512254, 0.29532441, 0.9661175, 0.36176598, 
-0.8544195, 0.7404047, 0.82428366, 0.96257573, 0.11131253, 0.62018675, 0.47864527, 0.039101128, 0.46764946, 0.29711628, 
-0.40892226, 0.7900437, 0.10764668, 0.55577713, 0.6133263, 0.019346252, 0.73014337, 0.9307928, 0.5542295, 0.17595504, 
-0.8546715, 0.90590805, 0.9092394, 0.33921698, 0.0008430821, 0.81278396, 0.25341776, 0.7057896, 0.29238465, 0.52403855, 
-0.9213937, 0.11746097, 0.21051219, 0.09993823, 0.8176869, 0.72511464, 0.70282686, 0.3988631, 0.83230406, 0.46275905, 
-0.2703259, 0.57835686, 0.58600885, 0.3766385, 0.690864, 0.44178563, 0.40026566, 0.5732949, 0.23808873, 0.50714386, 
-0.9350253, 0.57432973, 0.74109495, 0.79016244, 0.5070945, 0.9485114, 0.8311653, 0.48506665, 0.9617326, 0.29852858, 
-0.366769, 0.77285564, 0.74671644, 0.94361097, 0.3757226, 0.29146126, 0.57953155, 0.007708449, 0.7380902, 0.88821167, 
-0.31651938, 0.33128026, 0.09848877, 0.09147043, 0.90562916, 0.27631462, 0.31989923, 0.53260094, 0.648353, 0.5590575, 
-0.4125183, 0.68012285, 0.4677009, 0.7852408, 0.5890133, 0.34706393, 0.37636602, 0.42034975, 0.5928437, 0.86917543, 
-0.89394933, 0.21776019, 0.43713045, 0.5337755, 0.09599007, 0.49747026, 0.83164036, 0.6423979, 0.00091591524, 0.39940274, 
-0.8622541, 0.3925572, 0.83520466, 0.3498771, 0.19062445, 0.603745, 0.475841, 0.6496245, 0.8845333, 0.2307799, 
-0.6286122, 0.29856437, 0.83671373, 0.40267518, 0.8860103, 0.6866461, 0.30515477, 0.9614757, 0.3545977, 0.028658632, 
-0.9150952, 0.15918177, 0.41486475, 0.8689148, 0.9942623, 0.0987592, 0.8941498, 0.5647133, 0.99548036, 0.40815887, 
-0.44467425, 0.6775013, 0.531685, 0.24895021, 0.69680333, 0.019961093, 0.8449182, 0.1178238, 0.59461635, 0.98526824, 
-0.871223, 0.7267415, 0.53581643, 0.3620638, 0.24056326, 0.59538496, 0.38104647, 0.034455262, 0.6477652, 0.40934396, 
-0.19231549, 0.8701647, 0.28780022, 0.97225726, 0.48430753, 0.7030723, 0.9776925, 0.9662899, 0.3556148, 0.09186526, 
-0.7095952, 0.9111277, 0.65414417, 0.47637445, 0.78610563, 0.9511109, 0.7668794, 0.5877635, 0.7058718, 0.8660492, 
-0.8417279, 0.18733096, 0.3668593, 0.36932942, 0.15743567, 0.18835372, 0.62336534, 0.05280094, 0.6283515, 0.3988773, 
-0.7177127, 0.85969454, 0.9169481, 0.5861364, 0.21584338, 0.5745095, 0.3897011, 0.55942774, 0.7646427, 0.993731, 
-0.042268623, 0.8786283, 0.762209, 0.5027511, 0.27567303, 0.9600953, 0.072597355, 0.059442017, 0.57595813, 0.2894524, 
-0.82850564, 0.793283, 0.32858342, 0.78171605, 0.56761605, 0.0049845274, 0.50330544, 0.9184708, 0.8148216, 0.29595378, 
-0.07970701, 0.92489153, 0.33793837, 0.9567375, 0.37415254, 0.84990066, 0.9941796, 0.06800775, 0.26053104, 0.21159613, 
-0.5614098, 0.20745164, 0.8231208, 0.7121408, 0.82378054, 0.9630996, 0.42512196, 0.8641082, 0.09365638, 0.19734041, 
-0.11575636, 0.5639233, 0.4768428, 0.33889914, 0.5703717, 0.9244297, 0.5311111, 0.13523202, 0.01852037, 0.21085885, 
-0.071204096, 0.4712303, 0.74460614, 0.4686889, 0.914024, 0.117377095, 0.54068995, 0.80547154, 0.12859856, 0.4257724, 
-0.9659156, 0.0045896024, 0.798911, 0.36436203, 0.7280426, 0.621054, 0.9701622, 0.6164426, 0.9579355, 0.6045164, 
-0.5798626, 0.63919723, 0.82481444, 0.61748123, 0.18019743, 0.5157837, 0.44804874, 0.99903923, 0.3863658, 0.44972283, 
-0.31878954, 0.85894763, 0.049487386, 0.04967219, 0.14039204, 0.09017946, 0.4628455, 0.3544319, 0.7981168, 0.70640343, 
-0.42240968, 0.6196504, 0.73550963, 0.667884, 0.23142478, 0.11116676, 0.7650123, 0.112480775, 0.6108565, 0.9493177, 
-0.9542675, 0.9146685, 0.17729652, 0.41400397, 0.6309963, 0.43200687, 0.6464159, 0.12712492, 0.2884915, 0.3982403, 
-0.66932833, 0.54165065, 0.4191057, 0.67887574, 0.10698286, 0.10696802, 0.9551022, 0.7492388, 0.22396998, 0.63786316, 
-0.15820846, 0.6157303, 0.8183258, 0.25153205, 0.18210672, 0.9602121, 0.9036876, 0.15693043, 0.38605642, 0.06903067, 
-0.7507714, 0.33556795, 0.38818276, 0.43704808, 0.4954553, 0.40412104, 0.6816511, 0.63548344, 0.4186759, 0.70838517, 
-0.44376358, 0.3357206, 0.06594042, 0.39987648, 0.037075095, 0.88075906, 0.20054473, 0.05663389, 0.5609011, 0.124456756, 
-0.15606454, 0.015773552, 0.88851076, 0.9729933, 0.79110926, 0.33853722, 0.09634267, 0.9257645, 0.23189723, 0.6707842, 
-0.52831924, 0.48948547, 0.7410685, 0.2194608, 0.6474689, 0.3337604, 0.15346791, 0.98205763, 0.18342042, 0.70286185, 
-0.42531693, 0.3196188, 0.3305629, 0.5155848, 0.19409959, 0.82248783, 0.5497899, 0.41844934, 0.21445695, 0.3013477, 
-0.7596674, 0.8470537, 0.5960293, 0.26159966, 0.91296613, 0.7349978, 0.44705716, 0.41518942, 0.6459388, 0.1569181, 
-0.30777836, 0.7558866, 0.4035862, 0.7478917, 0.18006596, 0.9542781, 0.5946521, 0.8464796, 0.75240755, 0.7033147, 
-0.7272911, 0.2184871, 0.87321347, 0.8580393, 0.69913983, 0.83644575, 0.68521065, 0.372926, 0.77889377, 0.96862143, 
-0.7887473, 0.67789334, 0.7113075, 0.93054956, 0.9111168, 0.6812655, 0.89345616, 0.47946882, 0.30649468, 0.9124711, 
-0.88670325, 0.7382785, 0.33611885, 0.026502334, 0.39508346, 0.6694303, 0.9160326, 0.5826711, 0.33551884, 0.23982148, 
-0.22783574, 0.70331025, 0.6660418, 0.51114225, 0.57405657, 0.5411803, 0.9738403, 0.73799, 0.5624598, 0.07652036, 
-0.04978715, 0.07413118, 0.6362957, 0.6773174, 0.36817077, 0.629885, 0.044579085, 0.47303665, 0.836775, 0.49880046, 
-0.06082195, 0.115183294, 0.53998494, 0.83993644, 0.81661147, 0.98901266, 0.88236827, 0.84671116, 0.46295583, 0.029709496, 
-0.9204132, 0.10253954, 0.03740714, 0.5390723, 0.74078566, 0.08543706, 0.011851499, 0.20016527, 0.356493, 0.36993647, 
-0.70742524, 0.15546617, 0.917009, 0.22997431, 0.86268395, 0.81257206, 0.1019828, 0.65880144, 0.6583316, 0.7651984, 
-0.6248512, 0.44299594, 0.74589616, 0.8367184, 0.17899951, 0.11265245, 0.16332534, 0.8261054, 0.6945308, 0.5850439, 
-0.65881205, 0.12712914, 0.27503416, 0.53275037, 0.15610719, 0.9472476, 0.036724042, 0.0972234, 0.9365317, 0.2827337, 
-0.6180335, 0.8444138, 0.116543666, 0.46683854, 0.7913752, 0.9053558, 0.19817433, 0.3100106, 0.9772525, 0.0040394296, 
-0.8870298, 0.22356682, 0.18837956, 0.6977574, 0.40485826, 0.47741726, 0.35664338, 0.20068875, 0.36007276, 0.62813324, 
-0.92211175, 0.1857461, 0.5056345, 0.7714491, 0.7111244, 0.5802961, 0.880432, 0.3842586, 0.07386713, 0.9154364, 
-0.775848, 0.0047594067, 0.7222697, 0.37559786, 0.14716488, 0.7804374, 0.32645226, 0.27905762, 0.04534316, 0.27364373, 
-0.9144781, 0.8533147, 0.84885293, 0.6904914, 0.6980141, 0.43524522, 0.93874955, 0.57727677, 0.1278921, 0.67868996, 
-0.5906042, 0.8360353, 0.73715067, 0.30839851, 0.360622, 0.43228745, 0.33877933, 0.3450946, 0.7557141, 0.21107915, 
-0.024923787, 0.8139157, 0.23614348, 0.061816096, 0.22819144, 0.88227046, 0.5012971, 0.8127817, 0.55059254, 0.6244208, 
-0.15096499, 0.07758577, 0.15534559, 0.08642902, 0.7136551, 0.068797, 0.33689317, 0.8151431, 0.073435, 0.27587917, 
-0.6415465, 0.30315524, 0.25636652, 0.3951772, 0.32483214, 0.9398127, 0.26760876, 0.41387123, 0.014975904, 0.7148774, 
-0.4416581, 0.9813577, 0.5233435, 0.83426404, 0.24871995, 0.100562416, 0.6171712, 0.78703684, 0.4622999, 0.8157436, 
-0.93394816, 0.1259679, 0.026684225, 0.50347126, 0.527725, 0.5130184, 0.6806897, 0.6507216, 0.59474343, 0.29182497, 
-0.09539426, 0.52363616, 0.27165958, 0.47983494, 0.56953263, 0.72176856, 0.5575492, 0.8409663, 0.73698395, 0.28837872, 
-0.6146617, 0.08742587, 0.7978058, 0.8357151, 0.18276273, 0.16960731, 0.55424225, 0.32108158, 0.83770907, 0.61309266, 
-0.45162576, 0.54985636, 0.35284323, 0.25769138, 0.34193105, 0.5155786, 0.27647102, 0.75289524, 0.86745226, 0.8118137, 
-0.259123, 0.61688715, 0.8191278, 0.7231509, 0.6194832, 0.9180219, 0.7096981, 0.043508567, 0.26473138, 0.5269514, 
-0.5430132, 0.77620494, 0.05005288, 0.1739212, 0.20108196, 0.8465223, 0.32816213, 0.19096912, 0.32070854, 0.35811764, 
-0.9587762, 0.3596081, 0.81301254, 0.9816507, 0.84019923, 0.54553795, 0.17079297, 0.013968218, 0.13790388, 0.053954035, 
-0.44529754, 0.80465394, 0.9735141, 0.92517024, 0.029255724, 0.99777454, 0.26829806, 0.07465485, 0.21623193, 0.2647408, 
-0.45990923, 0.5107337, 0.056350194, 0.31075767, 0.07007945, 0.6754208, 0.49980345, 0.17892201, 0.056609415, 0.4954088, 
-0.18741646, 0.08550189, 0.4321867, 0.5093346, 0.85303754, 0.89951485, 0.8038746, 0.8374771, 0.88295174, 0.073945254, 
-0.7472289, 0.69572985, 0.90560466, 0.21077734, 0.08165387, 0.7383593, 0.80269086, 0.12488264, 0.14466548, 0.20330743, 
-0.5782242, 0.2535073, 0.9747372, 0.055967752, 0.8982084, 0.44804245, 0.30325794, 0.50225484, 0.91157126, 0.16477837, 
-0.045734458, 0.99187094, 0.9573588, 0.6424951, 0.8665376, 0.35979563, 0.37246728, 0.46417946, 0.0721327, 0.12974085, 
-0.19389993, 0.430821, 0.19170313, 0.14228667, 0.51751184, 0.76417935, 0.605129, 0.8455728, 0.2291038, 0.3317202, 
-0.87272996, 0.37492082, 0.034256544, 0.853302, 0.9171846, 0.9339092, 0.11076469, 0.37621894, 0.6111262, 0.40499508, 
-0.5962569, 0.30161974, 0.92590576, 0.7181733, 0.028210793, 0.755358, 0.7383711, 0.2631096, 0.34423977, 0.7218582, 
-0.365892, 0.3385114, 0.05274994, 0.014924624, 0.0094075035, 0.1474032, 0.061804168, 0.8324505, 0.5384559, 0.13402902, 
-0.84291345, 0.45768508, 0.27315107, 0.5798511, 0.29204842, 0.6708136, 0.9576144, 0.10405682, 0.7253105, 0.9326284, 
-0.24903095, 0.99624836, 0.8530533, 0.6671376, 0.5334839, 0.8922802, 0.50491524, 0.47352976, 0.114075884, 0.76215386, 
-0.025808325, 0.34201944, 0.50133306, 0.5072456, 0.9658282, 0.53421855, 0.32217088, 0.019331919, 0.8438945, 0.7697814, 
-0.872105, 0.27831417, 0.837763, 0.47709718, 0.56208163, 0.13857186, 0.028468672, 0.34605467, 0.42612493, 0.35739717, 
-0.79774356, 0.63431424, 0.5377991, 0.4116114, 0.4728273, 0.36964366, 0.48545814, 0.3856123, 0.48144072, 0.11712731, 
-0.64248794, 0.5882744, 0.71837467, 0.77630204, 0.1082207, 0.500894, 0.956352, 0.7659055, 0.6140229, 0.75782984, 
-0.34864277, 0.9382825, 0.26016235, 0.9555291, 0.06052337, 0.9707168, 0.15848531, 0.3759561, 0.10505597, 0.39491206, 
-0.86381155, 0.15886053, 0.047404833, 0.7566787, 0.96441025, 0.3914941, 0.8042203, 0.08972167, 0.0344183, 0.59618455, 
-0.0487604, 0.93655854, 0.5378912, 0.7267672, 0.12729345, 0.2838306, 0.5599395, 0.06146098, 0.3688765, 0.061187647, 
-0.18221985, 0.2625632, 0.7320318, 0.6682951, 0.008754399, 0.85946107, 0.3741519, 0.58227, 0.35108802, 0.5021105, 
-0.21115834, 0.10950206, 0.28055635, 0.08652866, 0.25331578, 0.48362744, 0.5408696, 0.9616959, 0.8118918, 0.7167266, 
-0.6966737, 0.8666303, 0.73148715, 0.017838325, 0.7090695, 0.4120842, 0.40039128, 0.5333952, 0.8282356, 0.77669275, 
-0.41077727, 0.09702433, 0.007079605, 0.043868326, 0.21269222, 0.6012483, 0.42682874, 0.37910977, 0.7479243, 0.10494917, 
-0.01734221, 0.22195028, 0.73863363, 0.5323078, 0.38502622, 0.93925834, 0.6560022, 0.45136255, 0.47345138, 0.643666, 
-0.74296105, 0.5982436, 0.24956919, 0.65214986, 0.36451396, 0.31558952, 0.531076, 0.71419346, 0.9592256, 0.5966702, 
-0.45906982, 0.8407567, 0.7540344, 0.5743953, 0.09133322, 0.114134, 0.10242245, 0.23668802, 0.87383646, 0.6520674, 
-0.056798704, 0.16175981, 0.2137716, 0.7069426, 0.6993844, 0.4747234, 0.1279967, 0.19917937, 0.6328121, 0.76981115, 
-0.756082, 0.94902873, 0.059943788, 0.1845696, 0.03373171, 0.8125337, 0.84745514, 0.35492972, 0.67935437, 0.8971027, 
-0.07017233, 0.7126353, 0.41988418, 0.15125412, 0.6458793, 0.1765855, 0.46791586, 0.16423836, 0.4409746, 0.27089223, 
-0.83683586, 0.4193142, 0.5775261, 0.82138395, 0.58686733, 0.58120126, 0.384472, 0.54262656, 0.95276546, 0.8897906, 
-0.1875928, 0.33189663, 0.08138137, 0.18941447, 0.8405882, 0.51004106, 0.7808129, 0.5694648, 0.54066354, 0.27879953, 
-0.26667887, 0.74749273, 0.55733365, 0.97673374, 0.5818951, 0.34416345, 0.74187565, 0.06251747, 0.061063267, 0.5227989, 
-0.0068075284, 0.96375835, 0.75820476, 0.36191988, 0.93297523, 0.3367678, 0.37150264, 0.23855984, 0.5977023, 0.45253047, 
-0.42806166, 0.30482855, 0.40216422, 0.7895638, 0.7095099, 0.7382757, 0.6312539, 0.23046969, 0.3106659, 0.13583827, 
-0.39577258, 0.89845103, 0.6235748, 0.16217506, 0.004213362, 0.08934315, 0.86198056, 0.60079235, 0.23948883, 0.24270387, 
-0.8393256, 0.32195452, 0.4815633, 0.4299666, 0.8829831, 0.22383447, 0.57369184, 0.7194615, 0.2564392, 0.5038204, 
-0.13853844, 0.5422531, 0.97176254, 0.0881331, 0.85073787, 0.9618503, 0.3453285, 0.76776993, 0.26722383, 0.8436194, 
-0.7129096, 0.51140594, 0.75185156, 0.925225, 0.1270263, 0.10835649, 0.34018353, 0.5960297, 0.35770652, 0.8436321, 
-0.47478724, 0.7707103, 0.999071, 0.35499844, 0.6132049, 0.106107146, 0.82326525, 0.97219765, 0.9065807, 0.48567542, 
-0.16458383, 0.9117924, 0.9740305, 0.8068454, 0.99729985, 0.8535195, 0.9266885, 0.5354417, 0.3114372, 0.04236306, 
-0.7440147, 0.09421062, 0.3335685, 0.3958694, 0.52979434, 0.32791966, 0.57010293, 0.5563383, 0.30294028, 0.77462655, 
-0.88365096, 0.97766215, 0.36175498, 0.41280714, 0.029033197, 0.36782816, 0.5431821, 0.61676407, 0.47492823, 0.7446307, 
-0.13858505, 0.37313086, 0.86118925, 0.7815484, 0.6790356, 0.8011172, 0.53737545, 0.94500613, 0.92792517, 0.27350682, 
-0.18166798, 0.8047418, 0.2845925, 0.31534344, 0.09961744, 0.38057664, 0.43714178, 0.6032016, 0.82520413, 0.28528523, 
-0.5360042, 0.26692694, 0.66925734, 0.13195412, 0.6020245, 0.18692169, 0.5500374, 0.5612233, 0.77781224, 0.62947166, 
-0.31033742, 0.30992442, 0.060513485, 0.5668065, 0.903778, 0.3708838, 0.2330214, 0.55202013, 0.71683383, 0.72867715, 
-0.79054415, 0.6250968, 0.62841314, 0.029433481, 0.59295857, 0.07890911, 0.69306964, 0.046411548, 0.3131897, 0.6484566, 
-0.9306864, 0.93998045, 0.79156, 0.189643, 0.20862652, 0.8716581, 0.7038735, 0.7292351, 0.1795239, 0.49211392, 
-0.25107977, 0.9761521, 0.16719387, 0.29845348, 0.9631694, 0.87174356, 0.74422836, 0.7177861, 0.41156542, 0.72873366, 
-0.14755523, 0.88512164, 0.8863678, 0.096526965, 0.49474105, 0.9109074, 0.6385138, 0.63982385, 0.53899556, 0.5231154, 
-0.49385205, 0.5036258, 0.24803366, 0.12935568, 0.6987853, 0.37035698, 0.5183644, 0.8708705, 0.35817996, 0.032119915, 
-0.66701025, 0.5037863, 0.37249622, 0.22471993, 0.47759736, 0.81439203, 0.45790294, 0.32995966, 0.06626411, 0.721215, 
-0.33468077, 0.97528356, 0.6348461, 0.584456, 0.50090134, 0.04556473, 0.053612676, 0.695033, 0.69490194, 0.29771915, 
-0.23314431, 0.064049676, 0.19023955, 0.6564085, 0.99826187, 0.7474539, 0.7281185, 0.037838195, 0.5996682, 0.5928124, 
-0.35337916, 0.87335783, 0.3596061, 0.37944552, 0.06172341, 0.6437689, 0.51262546, 0.66164786, 0.6189296, 0.680349, 
-0.45300442, 0.3085541, 0.57355976, 0.81778055, 0.18843463, 0.51856846, 0.8687797, 0.6635776, 0.6284543, 0.6532206, 
-0.3167443, 0.8233314, 0.17596854, 0.06046078, 0.7989756, 0.6029606, 0.31354675, 0.7160877, 0.22645807, 0.7301434, 
-0.086273566, 0.42006475, 0.7302915, 0.4734517, 0.36783585, 0.4613229, 0.6156775, 0.2554006, 0.5227326, 0.8571324, 
-0.53293926, 0.39196482, 0.07610343, 0.014552955, 0.84471476, 0.9245902, 0.49048993, 0.37245902, 0.4679739, 0.47969338, 
-0.8786742, 0.06454086, 0.40938383, 0.9464476, 0.2760681, 0.5300478, 0.6973893, 0.2991453, 0.5804699, 0.45876285, 
-0.33022216, 0.79653776, 0.43518978, 0.8887862, 0.59407544, 0.032939672, 0.5782626, 0.10010804, 0.44994467, 0.7271117, 
-0.902891, 0.6133791, 0.140845, 0.77132195, 0.12028129, 0.9247795, 0.74722797, 0.16141559, 0.21574605, 0.8743854, 
-0.11247064, 0.9410877, 0.24811381, 0.74676466, 0.8514692, 0.021732707, 0.010680916, 0.7838439, 0.19738361, 0.8377881, 
-0.7639336, 0.31653216, 0.6749307, 0.06396978, 0.52691025, 0.7364015, 0.956775, 0.18731725, 0.42047754, 0.8117751, 
-0.34632754, 0.39038187, 0.9225143, 0.7408622, 0.57680243, 0.2652951, 0.92369586, 0.6380619, 0.82616633, 0.35128862, 
-0.7828198, 0.5359737, 0.08339928, 0.7060845, 0.3462922, 0.38913444, 0.54842395, 0.6884251, 0.037316978, 0.5723427, 
-0.022258755, 0.79441875, 0.90272444, 0.61215657, 0.9631781, 0.5863588, 0.9384484, 0.07687521, 0.24441172, 0.38387978, 
-0.96800447, 0.5599107, 0.74093807, 0.403971, 0.5280579, 0.72208875, 0.018573398, 0.5072516, 0.16996226, 0.58617413, 
-0.09803684, 0.37261903, 0.95767754, 0.84609497, 0.05496832, 0.22795987, 0.23313288, 0.9688462, 0.7176776, 0.1377758, 
-0.18797757, 0.26834992, 0.15000027, 0.8481348, 0.7895163, 0.5519088, 0.48765746, 0.31035778, 0.77768403, 0.9904436, 
-0.32684666, 0.84682065, 0.39365014, 0.44228655, 0.38328415, 0.22290905, 0.79503566, 0.6794283, 0.17802662, 0.62420344, 
-0.37056103, 0.041172326, 0.51846284, 0.45114288, 0.47430587, 0.6496397, 0.8367412, 0.05662944, 0.5571883, 0.7352182, 
-0.35322595, 0.9696022, 0.35919765, 0.10663593, 0.19590221, 0.6996546, 0.40991047, 0.89280325, 0.6144547, 0.9761491, 
-0.23443131, 0.70821565, 0.7295676, 0.17951865, 0.25932744, 0.25121617, 0.97896886, 0.515391, 0.46281084, 0.83205926, 
-0.4329242, 0.55370456, 0.7908196, 0.093474135, 0.7672148, 0.14680524, 0.74988705, 0.69885737, 0.37382892, 0.13987659, 
-0.7151676, 0.431028, 0.75316954, 0.04246583, 0.63721764, 0.35724443, 0.48762304, 0.28701422, 0.24638435, 0.6836296, 
-0.8129986, 0.9022324, 0.064973645, 0.20187753, 0.38977212, 0.6623454, 0.31160477, 0.3389442, 0.19181544, 0.2230897, 
-0.6706708, 0.32135025, 0.5938186, 0.725129, 0.30229402, 0.7995213, 0.17878264, 0.2657235, 0.33942115, 0.04909697, 
-0.94976753, 0.7110531, 0.5189743, 0.47457805, 0.2609815, 0.8034033, 0.9550461, 0.6871017, 0.542301, 0.90208304, 
-0.76359314, 0.6919547, 0.2690066, 0.77918124, 0.019060668, 0.5306918, 0.48873094, 0.58894205, 0.703702, 0.104869366, 
-0.8352005, 0.41094282, 0.507042, 0.15073924, 0.46920577, 0.3938173, 0.8372094, 0.028040525, 0.7401718, 0.8376963, 
-0.17846179, 0.22189952, 0.9475931, 0.19728738, 0.7338621, 0.101945534, 0.3832581, 0.59039557, 0.94089603, 0.5863688, 
-0.7072993, 0.624503, 0.7966432, 0.28973243, 0.45949653, 0.9787162, 0.052343633, 0.81463736, 0.70606834, 0.7716022, 
-0.31079042, 0.5898406, 0.5620215, 0.23455179, 0.21389648, 0.5388247, 0.2040111, 0.36823508, 0.0053723096, 0.8671642, 
-0.9661939, 0.9270056, 0.94692993, 0.7046047, 0.72362125, 0.5416936, 0.7443616, 0.07171923, 0.04531915, 0.91711515, 
-0.1474337, 0.89833534, 0.648046, 0.11733318, 0.39757007, 0.21069747, 0.6142996, 0.21730955, 0.6912427, 0.49048957, 
-0.34147367, 0.022572042, 0.3219722, 0.9685696, 0.5269059, 0.5886212, 0.659878, 0.7130413, 0.98339087, 0.19503741, 
-0.89793444, 0.015023004, 0.5850233, 0.07373183, 0.62017494, 0.7802937, 0.6775731, 0.09203854, 0.5661112, 0.9178029, 
-0.2343546, 0.9806244, 0.7693182, 0.7889532, 0.6241685, 0.41245508, 0.9417946, 0.44468832, 0.8369817, 0.0031990237, 
-0.9245251, 0.98670155, 0.6769924, 0.51488274, 0.5256905, 0.9436219, 0.6050334, 0.97836035, 0.17769879, 0.13500004, 
-0.8818156, 0.0313203, 0.08832834, 0.8502817, 0.019180698, 0.13241069, 0.31331208, 0.5743142, 0.49715826, 0.6172764, 
-0.5331244, 0.5222611, 0.6511984, 0.7734398, 0.256135, 0.3608493, 0.25325385, 0.533019, 0.34440103, 0.114450805, 
-0.6468266, 0.2151897, 0.8760596, 0.9801919, 0.27051234, 0.9112329, 0.3380306, 0.07014053, 0.54804134, 0.6765531, 
-0.1752603, 0.69921273, 0.9143398, 0.43111116, 0.035987273, 0.2030343, 0.8922961, 0.91903645, 0.76977247, 0.49175784, 
-0.099143006, 0.3674804, 0.94753003, 0.21970531, 0.47007462, 0.40226397, 0.3355032, 0.9035526, 0.25874776, 0.16484123, 
-0.69036806, 0.07201438, 0.63395935, 0.063247986, 0.48817343, 0.6666259, 0.15526073, 0.10813647, 0.5797694, 0.10794782, 
-0.79438007, 0.24317154, 0.026272861, 0.8206052, 0.4420161, 0.8339117, 0.6079213, 0.22008722, 0.73745257, 0.053100668, 
-0.46855322, 0.33421737, 0.76324654, 0.8526432, 0.015307797, 0.27934623, 0.26765963, 0.65635425, 0.51011723, 0.86824834, 
-0.57572967, 0.43447804, 0.8113928, 0.38320008, 0.986185, 0.10324592, 0.06525337, 0.85109174, 0.94293773, 0.36936134, 
-0.047773577, 0.7841596, 0.33926708, 0.66182464, 0.69737774, 0.85597146, 0.34120753, 0.12692484, 0.7776892, 0.63616294, 
-0.79434264, 0.11541597, 0.16610004, 0.2056471, 0.696288, 0.35615066, 0.30876786, 0.78131616, 0.04794019, 0.2088272, 
-0.39896628, 0.49890646, 0.59801924, 0.711521, 0.5322181, 0.35990205, 0.43177876, 0.6430728, 0.8344202, 0.33877015, 
-0.76865834, 0.75682956, 0.2771495, 0.3680912, 0.005327093, 0.68439364, 0.9949503, 0.10142185, 0.15526544, 0.15933633, 
-0.9381387, 0.14073479, 0.87866503, 0.8739543, 0.07390571, 0.46031374, 0.268378, 0.6057457, 0.68691206, 0.6300343, 
-0.79447806, 0.28393722, 0.80315155, 0.73411053, 0.9703951, 0.5488671, 0.18614037, 0.6277461, 0.12960654, 0.33747572, 
-0.4241927, 0.6981348, 0.29250467, 0.43891907, 0.8675046, 0.037513115, 0.8382665, 0.79800886, 0.20032, 0.011894401, 
-0.3612004, 0.207346, 0.6260507, 0.88860387, 0.27068847, 0.25823146, 0.62024146, 0.72406495, 0.6376153, 0.0719044, 
-0.09152406, 0.82603306, 0.9561607, 0.20438583, 0.5442921, 0.4847211, 0.95367795, 0.54303896, 0.3976961, 0.45646, 
-0.49825326, 0.3672042, 0.9718153, 0.81778973, 0.73514366, 0.24000394, 0.8482301, 0.43974596, 0.006449677, 0.036392592, 
-0.62204725, 0.47036913, 0.4054257, 0.67501765, 0.26883397, 0.58713204, 0.6578865, 0.91454774, 0.46342203, 0.7121636, 
-0.92862564, 0.46207544, 0.9901308, 0.057702154, 0.24595165, 0.5981596, 0.74197406, 0.08811883, 0.894627, 0.38278353, 
-0.08383514, 0.2952275, 0.40031275, 0.74386, 0.5136412, 0.9939962, 0.2355307, 0.808261, 0.15346022, 0.030684536, 
-0.41000134, 0.1804955, 0.71761525, 0.6012227, 0.44985715, 0.6211549, 0.4206074, 0.28114304, 0.9355519, 0.95716006, 
-0.82683456, 0.03913026, 0.07961693, 0.6855325, 0.52783436, 0.036177807, 0.3770734, 0.91411316, 0.5718381, 0.13698402, 
-0.4980299, 0.76011133, 0.545119, 0.62366617, 0.95255744, 0.32681978, 0.07005637, 0.66156566, 0.16137652, 0.27483776, 
-0.35160136, 0.8496255, 0.7610875, 0.4327375, 0.30216226, 0.74813014, 0.74446017, 0.38890806, 0.607845, 0.62479675, 
-0.17755221, 0.46083102, 0.15256695, 0.9374669, 0.5559489, 0.04470488, 0.21561056, 0.7147803, 0.21602567, 0.47746333, 
-0.6169228, 0.32141757, 0.23642296, 0.016476203, 0.53265464, 0.64989, 0.6353765, 0.0939491, 0.64866525, 0.12303737, 
-0.5510985, 0.7590417, 0.11976651, 0.6607141, 0.6055587, 0.9772091, 0.27804276, 0.64687943, 0.38337022, 0.7797042, 
-0.29171762, 0.9881654, 0.30626813, 0.94704133, 0.9594318, 0.037198868, 0.60754436, 0.60765207, 0.06771721, 0.9078526, 
-0.1112092, 0.3552761, 0.44554, 0.6839132, 0.657915, 0.030183792, 0.6132026, 0.74461126, 0.9000829, 0.6522722, 
-0.112753615, 0.6505111, 0.74024284, 0.48480767, 0.073698185, 0.4185105, 0.3410645, 0.49185285, 0.33190826, 0.5787399, 
-0.7666621, 0.5687311, 0.33141005, 0.43632144, 0.18574573, 0.6287574, 0.01514944, 0.28938162, 0.057044394, 0.49545577, 
-0.042345677, 0.027724478, 0.026231889, 0.74081266, 0.011828165, 0.19582245, 0.31350172, 0.43585333, 0.0027991086, 0.5753749, 
-0.36400652, 0.5334315, 0.74679655, 0.731098, 0.6669506, 0.6412065, 0.24792254, 0.8214605, 0.8733431, 0.54092133, 
-0.6961343, 0.115691505, 0.27574378, 0.48897734, 0.14119047, 0.5424781, 0.02386607, 0.009218562, 0.49816743, 0.029157575, 
-0.015034353, 0.32382092, 0.6875669, 0.40462708, 0.6099266, 0.08502913, 0.6242792, 0.9994301, 0.4729795, 0.87787575, 
-0.10500878, 0.90521115, 0.48905376, 0.7565334, 0.21473333, 0.23323065, 0.8219346, 0.60031205, 0.76937085, 0.5445392, 
-0.38083488, 0.19368897, 0.41603848, 0.51612306, 0.7993214, 0.92665416, 0.75198066, 0.5372545, 0.5996222, 0.4693501, 
-0.17195638, 0.30428314, 0.9376859, 0.9736415, 0.5603405, 0.040185597, 0.8458646, 0.34216946, 0.12117143, 0.58192146, 
-0.016927328, 0.24849239, 0.34848097, 0.99546736, 0.43591255, 0.7909232, 0.62663776, 0.51921046, 0.274244, 0.9079598, 
-0.72054344, 0.42355403, 0.2398477, 0.95362824, 0.6483227, 0.8213454, 0.90778244, 0.17144382, 0.6053057, 0.68327236, 
-0.33304846, 0.08702466, 0.39980793, 0.0036293846, 0.7059194, 0.80072564, 0.96752524, 0.5154122, 0.19619283, 0.17454775, 
-0.38736606, 0.47976512, 0.4791406, 0.1874494, 0.52761185, 0.13234249, 0.845208, 0.4205711, 0.08021053, 0.00839825, 
-0.3000164, 0.23277025, 0.26301053, 0.6916624, 0.74880666, 0.74840236, 0.064435445, 0.98405766, 0.32531884, 0.73899513, 
-0.13240317, 0.6744208, 0.7368638, 0.43789902, 0.24887301, 0.9299027, 0.8486845, 0.34485158, 0.289548, 0.6351869, 
-0.82339793, 0.11122555, 0.3230176, 0.09969627, 0.52059376, 0.24077836, 0.9444134, 0.05239831, 0.42601636, 0.5159802, 
-0.9761374, 0.48721132, 0.09123329, 0.59690744, 0.383256, 0.1002782, 0.8240141, 0.70814556, 0.25482276, 0.957517, 
-0.7362902, 0.9834676, 0.19009337, 0.45719767, 0.042144574, 0.71294534, 0.7429013, 0.041241586, 0.9385764, 0.59770924, 
-0.28365803, 0.50035644, 0.13102308, 0.44502363, 0.18500035, 0.18879086, 0.90975267, 0.16331425, 0.17106864, 0.50802827, 
-0.80398893, 0.012037134, 0.55804133, 0.8093386, 0.7628578, 0.64519185, 0.58318746, 0.1399564, 0.05464305, 0.14859481, 
-0.10588853, 0.14053893, 0.09002884, 0.332031, 0.89889675, 0.8399303, 0.9211322, 0.86581993, 0.057551697, 0.8076484, 
-0.49787706, 0.90317184, 0.113821924, 0.82830715, 0.23232217, 0.47578096, 0.35618824, 0.64620966, 0.41190708, 0.19446513, 
-0.19052555, 0.6606999, 0.5370769, 0.74679446, 0.15352806, 0.72425306, 0.42542627, 0.3807547, 0.6943399, 0.39695272, 
-0.12975785, 0.6029449, 0.98659855, 0.78998154, 0.4918207, 0.1431191, 0.41032755, 0.7989921, 0.5461269, 0.34507003, 
-0.26765865, 0.043932725, 0.105762556, 0.36342022, 0.010151213, 0.90081716, 0.89821523, 0.7297342, 0.5770165, 0.2870768, 
-0.28900358, 0.9369778, 0.72804934, 0.86017793, 0.95806926, 0.44518864, 0.60346204, 0.34323436, 0.17850293, 0.17464367, 
-0.41450405, 0.5403775, 0.17148003, 0.660599, 0.6778906, 0.89493215, 0.9165733, 0.32384035, 0.33648646, 0.08920308, 
-0.06545341, 0.5571962, 0.10008278, 0.06683705, 0.92680645, 0.14659283, 0.5549373, 0.17365667, 0.73664325, 0.25271094, 
-0.8260378, 0.69569206, 0.80373824, 0.4072631, 0.10794914, 0.19278006, 0.8748956, 0.12642062, 0.8319123, 0.04663203, 
-0.53965706, 0.06709321, 0.6204891, 0.37148324, 0.93056595, 0.7272812, 0.8724527, 0.44516358, 0.68552965, 0.11521906, 
-0.98424387, 0.57437485, 0.39324772, 0.48781338, 0.22162339, 0.7318074, 0.836895, 0.66121227, 0.9333714, 0.81147647, 
-0.89025134, 0.42980537, 0.6065911, 0.925792, 0.3486058, 0.718812, 0.7366392, 0.7642169, 0.55264986, 0.4851105, 
-0.02003657, 0.79015267, 0.49192804, 0.28985444, 0.54954606, 0.9983602, 0.936707, 0.72859955, 0.13627109, 0.1995253, 
-0.27414012, 0.10977373, 0.48812705, 0.6214242, 0.26846707, 0.251663, 0.30244434, 0.31592485, 0.18563971, 0.3761417, 
-0.35588506, 0.2136833, 0.19304918, 0.020435851, 0.1563807, 0.10985168, 0.46050212, 0.69469714, 0.022877397, 0.211754, 
-0.99064195, 0.10823577, 0.89251375, 0.20041913, 0.09518249, 0.19409119, 0.082446806, 0.1033933, 0.93826735, 0.22326319, 
-0.7951004, 0.108295456, 0.5249412, 0.7338461, 0.53733635, 0.7804776, 0.94167835, 0.9851669, 0.6573249, 0.09694284, 
-0.41636762, 0.42071435, 0.5785772, 0.17650813, 0.12922545, 0.8063533, 0.5971035, 0.4714922, 0.13347372, 0.43969434, 
-0.53785807, 0.2420099, 0.70572215, 0.9245171, 0.20888333, 0.16590436, 0.21725997, 0.2877079, 0.5262417, 0.07437589, 
-0.16921617, 0.19905105, 0.3776575, 0.96237653, 0.58104134, 0.2475896, 0.6887421, 0.459203, 0.48309952, 0.3759031, 
-0.16817336, 0.47533524, 0.037372224, 0.92593455, 0.7953864, 0.5699276, 0.52965856, 0.7160056, 0.07119369, 0.28882924, 
-0.5969877, 0.6109546, 0.96991956, 0.498573, 0.68540514, 0.5530905, 0.40257332, 0.6004241, 0.52496284, 0.37143198, 
-0.56321764, 0.6539704, 0.45892516, 0.58294904, 0.9277267, 0.21731657, 0.043056846, 0.6162007, 0.5954668, 0.88163584, 
-0.11761114, 0.13790047, 0.98839265, 0.7575706, 0.271521, 0.06252285, 0.20463766, 0.7797876, 0.1291307, 0.6389557, 
-0.6362458, 0.5012543, 0.21651421, 0.23741248, 0.4773882, 0.5582616, 0.22913149, 0.8790845, 0.27697143, 0.02795082, 
-0.8450163, 0.08831802, 0.9342402, 0.11166756, 0.8126855, 0.51420295, 0.016410068, 0.4544232, 0.99820787, 0.5780698, 
-0.5268707, 0.9134579, 0.12053883, 0.18955784, 0.1712181, 0.45908722, 0.62256193, 0.21234894, 0.227052, 0.62288225, 
-0.34845284, 0.6227857, 0.4712934, 0.8860071, 0.73518616, 0.06196327, 0.4374562, 0.22151268, 0.10556084, 0.3694651, 
-0.9881851, 0.16397232, 0.3392293, 0.56751597, 0.036619555, 0.029293122, 0.20366028, 0.87672514, 0.94488513, 0.757318, 
-0.04611278, 0.75021446, 0.78157973, 0.5510609, 0.112084985, 0.7227879, 0.38071552, 0.026956385, 0.0661944, 0.01830097, 
-0.93569964, 0.016782548, 0.6520325, 0.65408915, 0.67949796, 0.22223058, 0.6170246, 0.048233118, 0.37648138, 0.7507222, 
-0.07674675, 0.7948974, 0.34886235, 0.6287428, 0.5898847, 0.36289844, 0.5742286, 0.55302286, 0.15293828, 0.14192496, 
-0.25542694, 0.74583685, 0.26746377, 0.46973395, 0.5767695, 0.59823835, 0.841206, 0.9202325, 0.7739221, 0.012398226, 
-0.6812478, 0.4104998, 0.15531828, 0.087259874, 0.43376547, 0.9714025, 0.5119398, 0.68514013, 0.888018, 0.814389, 
-0.4122685, 0.15542716, 0.5002437, 0.19416295, 0.6805713, 0.2512154, 0.4013521, 0.15283692, 0.96117616, 0.7491866, 
-0.14855935, 0.8276927, 0.8740181, 0.92426944, 0.762874, 0.18986279, 0.7493188, 0.18229857, 0.07731968, 0.08125962, 
-0.3810246, 0.6967921, 0.27431104, 0.36408317, 0.06947445, 0.66624695, 0.6395791, 0.2616025, 0.19497731, 0.6184822, 
-0.85095865, 0.88908845, 0.66500485, 0.33854932, 0.72965646, 0.099999785, 0.24559312, 0.07330083, 0.78916264, 0.32555407, 
-0.19688624, 0.6883691, 0.9590563, 0.024735536, 0.86383885, 0.8535551, 0.53648174, 0.23104885, 0.32438585, 0.24390268, 
-0.22208378, 0.32964125, 0.60782045, 0.8067584, 0.4333644, 0.71547633, 0.88111615, 0.13616055, 0.1246885, 0.014324361, 
-0.6116363, 0.13974965, 0.9578596, 0.34269398, 0.89822793, 0.25947088, 0.16268782, 0.53546876, 0.19461296, 0.6628742, 
-0.94426966, 0.67601794, 0.3931359, 0.7517656, 0.88437337, 0.6926555, 0.7377358, 0.2495755, 0.50024426, 0.21591938, 
-0.12976523, 0.40853027, 0.93721664, 0.95107466, 0.39639843, 0.52131736, 0.28126806, 0.85824645, 0.9051849, 0.01418011, 
-0.21888365, 0.10943257, 0.94861233, 0.77483827, 0.7139178, 0.057136595, 0.73050946, 0.61636233, 0.1265076, 0.60436803, 
-0.69086725, 0.0010129241, 0.036435887, 0.6615116, 0.299633, 0.54606587, 0.9365053, 0.85605484, 0.922385, 0.7407089, 
-0.9777405, 0.63154066, 0.63591623, 0.90876913, 0.88455915, 0.20310602, 0.20253302, 0.0067849625, 0.94629556, 0.37691054, 
-0.9782028, 0.30444136, 0.63028383, 0.18043286, 0.4439906, 0.8348371, 0.7274056, 0.61829764, 0.037847787, 0.8272368, 
-0.96214604, 0.12137349, 0.123067886, 0.8958763, 0.52505213, 0.1287523, 0.3720944, 0.275705, 0.65144163, 0.85033256, 
-0.58481205, 0.42521322, 0.93586147, 0.16447607, 0.036439568, 0.58734304, 0.47351632, 0.039843205, 0.8902792, 0.5108118, 
-0.8546036, 0.72372454, 0.6700668, 0.7495971, 0.6261652, 0.3864259, 0.3707291, 0.85600305, 0.21752104, 0.4647959, 
-0.81866026, 0.3182077, 0.818207, 0.09514821, 0.77856284, 0.85636705, 0.50847274, 0.74004, 0.38371703, 0.7558068, 
-0.83101165, 0.926828, 0.35534334, 0.09596299, 0.7920985, 0.5529896, 0.36857986, 0.46580777, 0.14399329, 0.85664755, 
-0.3613208, 0.6875624, 0.72801846, 0.527036, 0.9726332, 0.23842148, 0.45130673, 0.37347084, 0.26971108, 0.1386262, 
-0.7580232, 0.51609135, 0.058183976, 0.18664573, 0.031672336, 0.26660433, 0.6070062, 0.84071326, 0.38591322, 0.18007252, 
-0.07887025, 0.73347634, 0.6561262, 0.13447234, 0.67980015, 0.92777556, 0.3683812, 0.5741038, 0.95749855, 0.07317559, 
-0.017846042, 0.9049213, 0.7120097, 0.36087346, 0.10347511, 0.13109785, 0.5901893, 0.29117107, 0.12251501, 0.54014134, 
-0.40506032, 0.13500193, 0.4703289, 0.24509083, 0.9977836, 0.3149203, 0.868644, 0.16869761, 0.06429065, 0.52549416, 
-0.94598347, 0.5278666, 0.079894565, 0.9639208, 0.7777773, 0.62784445, 0.0314362, 0.5935461, 0.8472358, 0.04485763, 
-0.8700403, 0.8772029, 0.4159723, 0.1965355, 0.120780155, 0.8531019, 0.80408156, 0.6973105, 0.08317062, 0.9005745, 
-0.6764151, 0.3158351, 0.71819824, 0.84577185, 0.7750122, 0.94386834, 0.26314744, 0.41103536, 0.13668874, 0.36487988, 
-0.059131548, 0.19968359, 0.50981313, 0.4320044, 0.12719214, 0.48997945, 0.82502675, 0.74808896, 0.58309615, 0.47563064, 
-0.09966165, 0.9966431, 0.44393525, 0.07765738, 0.67010105, 0.5278574, 0.71902966, 0.27379337, 0.12431067, 0.14468168, 
-0.5108387, 0.1713335, 0.08552699, 0.16371617, 0.8490791, 0.63014835, 0.80966836, 0.23412272, 0.18890859, 0.833909, 
-0.364697, 0.62040085, 0.45685738, 0.48235595, 0.98572606, 0.6703567, 0.3673898, 0.9839679, 0.06934336, 0.6308007, 
-0.02807519, 0.0559926, 0.11421437, 0.60753995, 0.80091286, 0.67977196, 0.87189984, 0.6405409, 0.17567077, 0.24715477, 
-0.22483869, 0.9893541, 0.2867247, 0.9920071, 0.85404116, 0.887798, 0.114156604, 0.34609696, 0.5829253, 0.49704382, 
-0.6803111, 0.590904, 0.5591804, 0.7491872, 0.110933654, 0.4792608, 0.53978574, 0.9615793, 0.091931306, 0.99974436, 
-0.1604676, 0.73506176, 0.20445003, 0.49350995, 0.11660648, 0.4548461, 0.057119142, 0.47798702, 0.36280334, 0.16930713, 
-0.7582485, 0.16912746, 0.058451943, 0.9417538, 0.6090703, 0.37534294, 0.33367616, 0.4648503, 0.6283148, 0.09792804, 
-0.5562001, 0.021292835, 0.40104258, 0.57229954, 0.95048964, 0.4371712, 0.49681222, 0.36502722, 0.49660632, 0.32165202, 
-0.13998619, 0.9103205, 0.54860955, 0.17592642, 0.086687185, 0.48977694, 0.78490406, 0.79321474, 0.8754006, 0.39919505, 
-0.8306789, 0.63616955, 0.98329365, 0.41361818, 0.73879534, 0.5111836, 0.53245205, 0.6174266, 0.14011684, 0.7355907, 
-0.14558467, 0.074935436, 0.33326453, 0.99400324, 0.44354424, 0.13917476, 0.33401918, 0.6321505, 0.5430203, 0.6794353, 
-0.9580339, 0.69209194, 0.9813807, 0.041151315, 0.029320937, 0.8479279, 0.6205179, 0.8825255, 0.85506666, 0.11929336, 
-0.5904389, 0.5404614, 0.58944976, 0.22911972, 0.26724914, 0.92003053, 0.037999198, 0.9874244, 0.83350426, 0.439306, 
-0.9047191, 0.87938565, 0.22491038, 0.7610156, 0.17606735, 0.06505076, 0.577056, 0.5546063, 0.7323822, 0.94751245, 
-0.15575777, 0.15275358, 0.2501944, 0.19596528, 0.44116116, 0.13858697, 0.65478885, 0.9421423, 0.38429725, 0.89086735, 
-0.8906657, 0.64992654, 0.7623599, 0.020823486, 0.14515182, 0.6051233, 0.4854857, 0.10414482, 0.7267541, 0.52351373, 
-0.10117556, 0.34659478, 0.7986462, 0.10371433, 0.7747162, 0.078648254, 0.46718153, 0.22036512, 0.86508393, 0.9642702, 
-0.27087194, 0.06591158, 0.15014334, 0.9075542, 0.9635356, 0.4376853, 0.290267, 0.39348447, 0.78795856, 0.12866218, 
-0.26524165, 0.095856875, 0.6031271, 0.94263685, 0.54864025, 0.25479257, 0.11702571, 0.20408688, 0.6158638, 0.5709441, 
-0.57956505, 0.47291118, 0.8278522, 0.20886846, 0.8463369, 0.809163, 0.35410735, 0.14648008, 0.4212491, 0.36251292, 
-0.67140543, 0.43442374, 0.07705836, 0.42002708, 0.6199954, 0.8247542, 0.4997832, 0.8548057, 0.057287898, 0.7074665, 
-0.31485626, 0.09200123, 0.31618625, 0.59809196, 0.25827205, 0.0053186826, 0.7434676, 0.85600936, 0.5550741, 0.5199236, 
-0.96162254, 0.26309466, 0.60450137, 0.29413986, 0.38470513, 0.79796076, 0.23805939, 0.9412749, 0.061217327, 0.15437259, 
-0.083577976, 0.14378692, 0.9722354, 0.42544565, 0.45725676, 0.8308179, 0.018798511, 0.18310007, 0.32264143, 0.72388613, 
-0.75500935, 0.26221997, 0.146799, 0.90839726, 0.25608784, 0.48756382, 0.15672493, 0.22976026, 0.9505964, 0.8410182, 
-0.06569535, 0.498098, 0.591406, 0.90132546, 0.40089035, 0.40831077, 0.82992244, 0.7829185, 0.03532195, 0.8220347, 
-0.5866948, 0.55850834, 0.7935884, 0.9029153, 0.62388855, 0.17106935, 0.11976584, 0.8907406, 0.14083518, 0.42745417, 
-0.9865202, 0.5603676, 0.53336793, 0.83118796, 0.7649143, 0.6994026, 0.116295666, 0.69610405, 0.03805204, 0.8971413, 
-0.6412358, 0.008299126, 0.9906785, 0.22019914, 0.08867724, 0.58548, 0.5523809, 0.07090994, 0.024555296, 0.048945986, 
-0.0008954834, 0.23588002, 0.14777812, 0.5006067, 0.13719136, 0.19650105, 0.46863157, 0.24388368, 0.28450873, 0.08501847, 
-0.367798, 0.26598433, 0.08892508, 0.5231422, 0.854498, 0.50532776, 0.96473, 0.760218, 0.13641119, 0.7014878, 
-0.2920151, 0.13381833, 0.74486643, 0.13818067, 0.18079887, 0.57839566, 0.56782985, 0.5733893, 0.8142381, 0.038408525, 
-0.61868846, 0.048855904, 0.8661853, 0.091889195, 0.42655867, 0.75064015, 0.41258946, 0.0327612, 0.6939966, 0.5684132, 
-0.230771, 0.87241197, 0.41159534, 0.95303357, 0.5293433, 0.37525147, 0.91937405, 0.46753627, 0.3657011, 0.58334947, 
-0.62074995, 0.79216284, 0.9344987, 0.32306752, 0.7569309, 0.8670772, 0.49101356, 0.0095974505, 0.31980786, 0.5587957, 
-0.6286712, 0.8952423, 0.42964563, 0.24610022, 0.46633002, 0.31894207, 0.39979902, 0.99703586, 0.09658354, 0.10385787, 
-0.092738345, 0.9319688, 0.066221446, 0.567998, 0.47071677, 0.41960314, 0.722223, 0.79183286, 0.60883737, 0.8055474, 
-0.6590216, 0.10029357, 0.20768817, 0.2308886, 0.41765857, 0.82652557, 0.11435715, 0.5431178, 0.3349583, 0.55948156, 
-0.2596266, 0.402992, 0.7129533, 0.13520089, 0.939742, 0.33552873, 0.44276634, 0.16549513, 0.48670354, 0.2104012, 
-0.9754525, 0.9223382, 0.37095273, 0.26184326, 0.4906111, 0.68878114, 0.7259414, 0.3665008, 0.8523507, 0.33732775, 
-0.14485414, 0.69918066, 0.40076008, 0.5142605, 0.89977413, 0.52837765, 0.6875541, 0.19875702, 0.8284416, 0.6398044, 
-0.20458493, 0.8566812, 0.66207755, 0.537102, 0.84423125, 0.6897463, 0.2190155, 0.93102056, 0.62825596, 0.13518804, 
-0.9768368, 0.5567279, 0.30512935, 0.39843616, 0.83009493, 0.7366834, 0.72934085, 0.9458449, 0.7402775, 0.7288774, 
-0.100584194, 0.7478564, 0.69076705, 0.99763054, 0.41462737, 0.5604459, 0.002231921, 0.19869287, 0.23542677, 0.41136438, 
-0.6479746, 0.24400933, 0.33705348, 0.8468991, 0.0058162767, 0.11877123, 0.26026058, 0.83385074, 0.417612, 0.80086476, 
-0.46976563, 0.79492086, 0.73824483, 0.71716267, 0.36049098, 0.58812624, 0.3940513, 0.0023239073, 0.68416554, 0.1630907, 
-0.7990368, 0.74170923, 0.45847952, 0.0995642, 0.5392202, 0.45672858, 0.16591415, 0.664447, 0.12247461, 0.28378534, 
-0.6875144, 0.020322617, 0.6955938, 0.21689159, 0.48721343, 0.7328274, 0.21967441, 0.45823023, 0.39261988, 0.7113237, 
-0.47642282, 0.8954901, 0.52823293, 0.9394127, 0.25911182, 0.30566335, 0.009611528, 0.9736044, 0.63713956, 0.82650113, 
-0.16639459, 0.99990803, 0.5145273, 0.07233607, 0.6123276, 0.9062654, 0.7855298, 0.23748927, 0.30767888, 0.5490877, 
-0.9528571, 0.5958136, 0.71137613, 0.13382663, 0.11335034, 0.449443, 0.09932706, 0.52135324, 0.22994924, 0.6276635, 
-0.36845186, 0.93582106, 0.609704, 0.9728418, 0.68666786, 0.9035467, 0.21347627, 0.51906675, 0.8404524, 0.2335569, 
-0.44711703, 0.19230975, 0.027307436, 0.29597348, 0.11739075, 0.6876064, 0.5057953, 0.6232577, 0.604564, 0.58094805, 
-0.94729763, 0.9821851, 0.15055138, 0.8435322, 0.7584666, 0.8806093, 0.18411398, 0.3944063, 0.8260624, 0.8096688, 
-0.20633629, 0.48825827, 0.74365515, 0.009476059, 0.45804924, 0.23057352, 0.39020398, 0.5416855, 0.3856682, 0.7087808, 
-0.69278914, 0.26646304, 0.39703688, 0.074121974, 0.10197067, 0.76054734, 0.5685061, 0.41540262, 0.016435882, 0.42574394, 
-0.94364774, 0.47606933, 0.91678923, 0.6490012, 0.68036586, 0.38626674, 0.78526974, 0.7661718, 0.2143752, 0.80605865, 
-0.7194327, 0.81907, 0.69300437, 0.030783592, 0.027220597, 0.9588587, 0.4486546, 0.017831376, 0.83792424, 0.8868172, 
-0.2974024, 0.9641097, 0.23758952, 0.8957832, 0.8881589, 0.6808346, 0.5851483, 0.0764294, 0.74156153, 0.9979193, 
-0.3121031, 0.7687113, 0.37797043, 0.40031847, 0.86602104, 0.730267, 0.57146907, 0.094653964, 0.32911018, 0.07178252, 
-0.4453038, 0.62403214, 0.32731032, 0.5796096, 0.9893481, 0.87371916, 0.5734587, 0.3662533, 0.046901383, 0.14311191, 
-0.31189272, 0.5506748, 0.5774784, 0.12961864, 0.12834151, 0.97953796, 0.23847981, 0.021006035, 0.76084226, 0.99953127, 
-0.8011185, 0.7088403, 0.024610326, 0.21645589, 0.49395552, 0.9507214, 0.44109955, 0.2926859, 0.16476253, 0.29695365, 
-0.3873897, 0.35400063, 0.6887212, 0.7661417, 0.44151342, 0.67337024, 0.6367994, 0.65797997, 0.906435, 0.014439769, 
-0.10737592, 0.21889497, 0.029528014, 0.5984496, 0.6860266, 0.76142836, 0.19123298, 0.24835177, 0.27197698, 0.8864831, 
-0.49178717, 0.550463, 0.3338117, 0.32957888, 0.27066407, 0.7364635, 0.59942186, 0.11085444, 0.08565405, 0.03862678, 
-0.4326196, 0.28077278, 0.20149076, 0.7499477, 0.7557222, 0.95789206, 0.86195356, 0.8113367, 0.6881052, 0.45497125, 
-0.34273857, 0.5804998, 0.11457099, 0.7464025, 0.8921554, 0.5822235, 0.6793123, 0.42616072, 0.5304293, 0.7325272, 
-0.7594884, 0.19274779, 0.02070892, 0.27827948, 0.8051665, 0.83692664, 0.020188946, 0.35914233, 0.49547768, 0.70504993, 
-0.07394841, 0.525945, 0.5723259, 0.8678083, 0.5818202, 0.8266031, 0.017404223, 0.27958027, 0.84272736, 0.7281345, 
-0.8994748, 0.3798963, 0.5602465, 0.8170057, 0.5437445, 0.9112873, 0.43589205, 0.5874092, 0.4374235, 0.68844056, 
-0.057151183, 0.1732611, 0.58042514, 0.35312688, 0.2791384, 0.23987181, 0.26006386, 0.9232113, 0.94478124, 0.9187956, 
-0.93770313, 0.50281125, 0.31585902, 0.9830553, 0.38102284, 0.8167936, 0.008173941, 0.24676272, 0.16458233, 0.06555225, 
-0.5648193, 0.39973202, 0.58343333, 0.8022948, 0.8330524, 0.3795921, 0.63250124, 0.20370321, 0.734535, 0.8938792, 
-0.40103462, 0.43277976, 0.92171884, 0.8070371, 0.64789873, 0.9006873, 0.94551986, 0.21919903, 0.5886699, 0.34194836, 
-0.5665393, 0.09419294, 0.33479902, 0.92393184, 0.7904314, 0.39666355, 0.0640373, 0.5771913, 0.43598288, 0.7269509, 
-0.90311337, 0.18912931, 0.42282686, 0.37187123, 0.12362129, 0.65741915, 0.5898278, 0.77813035, 0.5200745, 0.8995463, 
-0.6073706, 0.056360655, 0.18867631, 0.05090209, 0.51776093, 0.5049234, 0.5810924, 0.5088219, 0.3351565, 0.48033553, 
-0.87127376, 0.7889749, 0.65809286, 0.822634, 0.49901298, 0.47062632, 0.064933024, 0.65950155, 0.0118634105, 0.43638885, 
-0.3155548, 0.055309944, 0.76772034, 0.007584079, 0.9907658, 0.2119053, 0.0099529, 0.5498476, 0.68341583, 0.9904796, 
-0.31085956, 0.16738948, 0.6991246, 0.6891236, 0.7345778, 0.5101786, 0.9055166, 0.28389692, 0.40617087, 0.285508, 
-0.8155711, 0.5552154, 0.24203478, 0.95564735, 0.8556771, 0.11413846, 0.53103644, 0.6001929, 0.8728583, 0.652995, 
-0.59248614, 0.9303262, 0.76626694, 0.083685614, 0.5839915, 0.55206066, 0.28864032, 0.18109223, 0.06013629, 0.30585563, 
-0.49497047, 0.031244803, 0.8254061, 0.34467688, 0.16947599, 0.70388424, 0.089850344, 0.9689693, 0.088056214, 0.9888344, 
-0.56510967, 0.7810361, 0.25333068, 0.72635543, 0.6208177, 0.7603394, 0.81327516, 0.812073, 0.15190694, 0.8766273, 
-0.68086886, 0.40976003, 0.6769893, 0.03042084, 0.39799348, 0.38053334, 0.40112254, 0.61543894, 0.10513203, 0.18251711, 
-0.22153829, 0.7244244, 0.22376063, 0.10031522, 0.79053754, 0.7843263, 0.7298093, 0.8973579, 0.7861713, 0.15179288, 
-0.024288114, 0.56206715, 0.51213664, 0.8840239, 0.08788527, 0.81145, 0.6769955, 0.039911535, 0.4628679, 0.82365215, 
-0.7387855, 0.47656733, 0.029185295, 0.18350895, 0.62498677, 0.08521046, 0.35425547, 0.7949853, 0.9466834, 0.78894264, 
-0.30276173, 0.4744114, 0.86383724, 0.9055391, 0.7672961, 0.8406853, 0.5572755, 0.15301545, 0.9358179, 0.83649135, 
-0.030530108, 0.9159173, 0.025901658, 0.00011405395, 0.8523392, 0.1188017, 0.89762336, 0.7929654, 0.9425356, 0.58654344, 
-0.7035378, 0.361211, 0.15257105, 0.2814799, 0.44373164, 0.744971, 0.6952391, 0.040251687, 0.47532842, 0.70532703, 
-0.43007088, 0.93482405, 0.9506745, 0.9972287, 0.84903115, 0.5498767, 0.6982299, 0.60659754, 0.116727814, 0.24719998, 
-0.25417453, 0.5239801, 0.10409364, 0.6263765, 0.79312205, 0.82286817, 0.45066565, 0.02907124, 0.33116972, 0.5061851, 
-0.1875871, 0.56129, 0.8524497, 0.36013994, 0.085404865, 0.94155073, 0.32184035, 0.58235735, 0.46180746, 0.022325099, 
-0.14544618, 0.5170238, 0.67768705, 0.23049083, 0.4064205, 0.09570609, 0.9652428, 0.028672969, 0.1510829, 0.30246252, 
-0.4205718, 0.2910258, 0.67623764, 0.69533557, 0.33236894, 0.17955771, 0.25711736, 0.5261945, 0.48835787};
+static int   _rnd_count = 9999;
+static float _rnd[]     = {
+    0.39540747,   0.841546,     0.52073574,   0.80399257,   0.95868486,    0.46164507,   0.5644759,     0.50258803,
+    0.1953517,    0.40522006,   0.7953865,    0.7795385,    0.6009604,     0.03921096,   0.56872225,    0.93369347,
+    0.7019503,    0.5392296,    0.2671585,    0.87286836,   0.28110227,    0.41505373,   0.8609184,     0.65234584,
+    0.18079561,   0.1345461,    0.26905555,   0.97823226,   0.9349287,     0.37662244,   0.47883937,    0.1831086,
+    0.63446456,   0.2549137,    0.8205819,    0.44705132,   0.7044422,     0.36040744,   0.29616997,    0.60375917,
+    0.21973382,   0.094351165,  0.3769042,    0.9975177,    0.6133292,     0.3379986,    0.88620085,    0.83456165,
+    0.16677794,   0.2749627,    0.28938183,   0.6274365,    0.058304083,   0.97233975,   0.48520145,    0.9803537,
+    0.9806276,    0.8683899,    0.62319696,   0.82413876,   0.19258952,    0.5862436,    0.5676593,     0.8187293,
+    0.9263807,    0.6122779,    0.14507395,   0.34604672,   0.21862903,    0.121670924,  0.22925124,    0.34154287,
+    0.2430596,    0.66339934,   0.6531345,    0.1867511,    0.038149532,   0.8634007,    0.039016694,   0.84279704,
+    0.24834526,   0.4344939,    0.8114543,    0.65996605,   0.08724063,    0.8514029,    0.12480451,    0.6621248,
+    0.76971227,   0.8402282,    0.46642372,   0.83605236,   0.73721045,    0.47203118,   0.41116965,    0.6334902,
+    0.52669185,   0.55817497,   0.07113702,   0.0010512439, 0.19292463,    0.5401541,    0.61593264,    0.045107026,
+    0.04571145,   0.94783896,   0.3843769,    0.39490476,   0.3192052,     0.29845035,   0.9422042,     0.11722695,
+    0.8293732,    0.7804,       0.5757935,    0.7580956,    0.7747893,     0.90769327,   0.73148865,    0.074977815,
+    0.4874734,    0.48294914,   0.5763345,    0.37840083,   0.6552472,     0.39319888,   0.6043324,     0.77102846,
+    0.25222966,   0.019644327,  0.6600592,    0.4799746,    0.7922636,     0.03796545,   0.64987236,    0.70819116,
+    0.81856126,   0.7663473,    0.6142546,    0.13940167,   0.46702597,    0.72989976,   0.34291962,    0.47126192,
+    0.89802396,   0.34919676,   0.0066791615, 0.95681053,   0.8962376,     0.653074,     0.85870093,    0.6189986,
+    0.8266863,    0.9961592,    0.5135778,    0.7099755,    0.9638197,     0.2375318,    0.3898598,     0.65251255,
+    0.34350657,   0.6133485,    0.14267509,   0.29956087,   0.6383911,     0.4622296,    0.3249633,     0.79140776,
+    0.13052759,   0.8676024,    0.93953437,   0.008441999,  0.2934387,     0.592087,     0.6079518,     0.75757366,
+    0.14002953,   0.10507256,   0.48037684,   0.30605045,   0.38651973,    0.64752185,   0.8747908,     0.59915566,
+    0.1609434,    0.04106063,   0.65328825,   0.79610443,   0.5243876,     0.9398969,    0.7443715,     0.5810295,
+    0.3764875,    0.961742,     0.7958951,    0.8536775,    0.58722466,    0.043358732,  0.8328708,     0.43579438,
+    0.024233455,  0.21527143,   0.8262829,    0.028635254,  0.71353966,    0.85025895,   0.3255599,     0.23459937,
+    0.38820738,   0.7560042,    0.569946,     0.8587471,    0.75715494,    0.083809346,  0.26599285,    0.6959847,
+    0.73855764,   0.54351944,   0.13861747,   0.59733045,   0.80894136,    0.52885884,   0.26702014,    0.1906307,
+    0.123230904,  0.35850486,   0.6319545,    0.3316967,    0.7961919,     0.7542743,    0.17034897,    0.0966708,
+    0.27220175,   0.04458247,   0.28181702,   0.1712483,    0.82123893,    0.8461555,    0.88561594,    0.3106845,
+    0.7155007,    0.4186889,    0.40789708,   0.76838344,   0.36995092,    0.8856244,    0.82387453,    0.29267815,
+    0.69574916,   0.099910386,  0.11511985,   0.04370523,   0.9047413,     0.23554033,   0.62685305,    0.4953746,
+    0.9482513,    0.63565224,   0.9054043,    0.3550348,    0.21830441,    0.9938632,    0.4384075,     0.633933,
+    0.5856552,    0.47327515,   0.58654535,   0.71257246,   0.80199236,    0.09474454,   0.8747458,     0.8924021,
+    0.6579035,    0.82793295,   0.88182974,   0.39025244,   0.12096177,    0.4986367,    0.8206798,     0.23760653,
+    0.53463036,   0.33927637,   0.6359475,    0.6962815,    0.6391545,     0.12664375,   0.19192953,    0.036661416,
+    0.41772944,   0.7864424,    0.222997,     0.18558672,   0.9407512,     0.5305812,    0.092380084,   0.7216375,
+    0.9802814,    0.77396405,   0.18272822,   0.89667577,   0.29907903,    0.11130205,   0.4906858,     0.60100466,
+    0.22516462,   0.22271773,   0.38580173,   0.07680829,   0.3537106,     0.23660058,   0.37441283,    0.4496146,
+    0.81497246,   0.6677978,    0.82040447,   0.879028,     0.35791573,    0.742126,     0.9947786,     0.45901147,
+    0.28134564,   0.54988396,   0.29484302,   0.015549939,  0.87174755,    0.68915904,   0.9516509,     0.12732233,
+    0.7355529,    0.16019227,   0.40997103,   0.34699774,   0.31590846,    0.924004,     0.93852746,    0.4233283,
+    0.84859055,   0.034942873,  0.47111684,   0.41643673,   0.740842,      0.115121245,  0.68295085,    0.18112887,
+    0.41202956,   0.77338237,   0.3706143,    0.27295336,   0.7101767,     0.21335205,   0.36372176,    0.2381554,
+    0.7791855,    0.72371674,   0.6153301,    0.7491951,    0.816459,      0.47513586,   0.7292571,     0.5360056,
+    0.2710668,    0.25847942,   0.3412554,    0.19351831,   0.8266295,     0.0274151,    0.13370614,    0.8909684,
+    0.72927034,   0.39707616,   0.030437447,  0.32297286,   0.27100918,    0.57834184,   0.71816945,    0.16622439,
+    0.8669331,    0.11371415,   0.6035204,    0.09836516,   0.31854475,    0.6786976,    0.41714564,    0.5222008,
+    0.7964705,    0.17181565,   0.56781226,   0.5921917,    0.30867395,    0.1893324,    0.6068693,     0.37345472,
+    0.3056858,    0.9351113,    0.14536993,   0.4823626,    0.7738658,     0.4894325,    0.35449934,    0.38461447,
+    0.6396763,    0.4796459,    0.54368305,   0.31310055,   0.18291461,    0.040748898,  0.9671462,     0.20084366,
+    0.0055472897, 0.4491057,    0.882262,     0.7027449,    0.87161547,    0.6308919,    0.21746083,    0.59236926,
+    0.8413338,    0.81905454,   0.3970478,    0.6548139,    0.45960286,    0.5415144,    0.58229446,    0.539938,
+    0.7902069,    0.6569827,    0.017287076,  0.33589792,   0.4329719,     0.23580688,   0.39235854,    0.3775006,
+    0.7592148,    0.2189059,    0.45868888,   0.83889884,   0.13501453,    0.10404509,   0.3392862,     0.7557216,
+    0.20466943,   0.36696857,   0.5866444,    0.85956824,   0.3070704,     0.9041244,    0.5018392,     0.67479384,
+    0.7176504,    0.5530007,    0.6410288,    0.9548113,    0.092384726,   0.69968545,   0.92501163,    0.09816185,
+    0.89735144,   0.0037450776, 0.52289367,   0.5259319,    0.023461822,   0.6312483,    0.7678718,     0.7697404,
+    0.05674718,   0.5047614,    0.9435301,    0.6527096,    0.17220303,    0.37856197,   0.45735472,    0.7372887,
+    0.47976837,   0.6413262,    0.45014447,   0.09263428,   0.95487,       0.7227262,    0.23286755,    0.8860825,
+    0.15514348,   0.34249324,   0.61824745,   0.8799712,    0.59477806,    0.43754727,   0.28511587,    0.059529364,
+    0.2938943,    0.36052704,   0.9415474,    0.13126945,   0.5811514,     0.8133543,    0.7322598,     0.5734211,
+    0.5990968,    0.816904,     0.80282104,   0.802309,     0.96059436,    0.8491296,    0.50259084,    0.33908847,
+    0.09564596,   0.9037401,    0.4750429,    0.45105854,   0.24954097,    0.8323773,    0.14329186,    0.17462522,
+    0.77087754,   0.63681114,   0.3707884,    0.6809686,    0.013000839,   0.8879006,    0.17496233,    0.61919993,
+    0.21964556,   0.8840007,    0.3588153,    0.81167597,   0.43701455,    0.32608527,   0.15613726,    0.666414,
+    0.9090664,    0.87672335,   0.4935375,    0.13796596,   0.9199052,     0.43055856,   0.9254882,     0.30601385,
+    0.8399024,    0.279159,     0.78432524,   0.69103795,   0.9625043,     0.83405733,   0.8099884,     0.46151695,
+    0.2172352,    0.7669222,    0.3603919,    0.9443403,    0.44256592,    0.0512912,    0.5604203,     0.7111962,
+    0.64194167,   0.18362112,   0.5826634,    0.07659364,   0.49031433,    0.6909148,    0.9020739,     0.7695607,
+    0.7476028,    0.80862886,   0.5419922,    0.3728176,    0.33883983,    0.005325912,  0.25472003,    0.34031895,
+    0.711323,     0.064774565,  0.8410662,    0.73384184,   0.10357534,    0.48392436,   0.65669554,    0.38558826,
+    0.07401231,   0.8972984,    0.5944408,    0.67009234,   0.96569335,    0.21179698,   0.22384812,    0.8577752,
+    0.31630307,   0.7823413,    0.49602425,   0.7362841,    0.84789515,    0.84889454,   0.8156995,     0.14898759,
+    0.3770851,    0.01476456,   0.94343513,   0.15387547,   0.29206514,    0.43717077,   0.12267711,    0.21190928,
+    0.5122022,    0.020072967,  0.23301727,   0.37779135,   0.21022503,    0.82657844,   0.60762084,    0.15801735,
+    0.52692556,   0.19707517,   0.0025813282, 0.59301597,   0.09647403,    0.23198159,   0.80386734,    0.5358059,
+    0.58478075,   0.684217,     0.056514528,  0.5564985,    0.50930166,    0.51843596,   0.4924238,     0.8624285,
+    0.24907504,   0.6920786,    0.35675675,   0.08881078,   0.5404892,     0.5028201,    0.0935231,     0.63684154,
+    0.77462125,   0.38253152,   0.15789017,   0.94562036,   0.97877973,    0.84605676,   0.64755017,    0.48972467,
+    0.17472044,   0.3380069,    0.2093585,    0.65081996,   0.8463132,     0.22268358,   0.052513562,   0.1451035,
+    0.21089722,   0.40762928,   0.5690947,    0.60784817,   0.38065624,    0.56617856,   0.70260763,    0.99376625,
+    0.52764916,   0.37058878,   0.1287163,    0.51814646,   0.4698217,     0.5188101,    0.61752814,    0.024105478,
+    0.103552066,  0.3657398,    0.81839466,   0.7139425,    0.07409142,    0.858247,     0.55702615,    0.738724,
+    0.03666682,   0.56678987,   0.38177812,   0.17129473,   0.30907747,    0.8416038,    0.016115308,   0.02639147,
+    0.639565,     0.21165326,   0.87791353,   0.13285992,   0.9337254,     0.48567492,   0.2561853,     0.20844269,
+    0.6799239,    0.16412394,   0.41797122,   0.60819095,   0.71734047,    0.12940371,   0.019902974,   0.6559104,
+    0.7204788,    0.18525302,   0.5472679,    0.4805734,    0.4042889,     0.33857107,   0.07101207,    0.35265025,
+    0.85060316,   0.8303707,    0.57118136,   0.8138664,    0.18440045,    0.5313129,    0.68468875,    0.68604535,
+    0.35447347,   0.10232483,   0.8785814,    0.25816843,   0.6408965,     0.48466823,   0.09038009,    0.6178771,
+    0.10955451,   0.609952,     0.034018606,  0.9099675,    0.44027576,    0.9488352,    0.021383535,   0.9072631,
+    0.5468869,    0.72586775,   0.45081598,   0.12382444,   0.29433593,    0.5355419,    0.62210256,    0.30099395,
+    0.14064118,   0.5252633,    0.28225678,   0.10335469,   0.91449356,    0.44231892,   0.024042243,   0.14861101,
+    0.47943518,   0.7319259,    0.2537175,    0.6150156,    0.25082228,    0.76173455,   0.01501382,    0.23581055,
+    0.09487294,   0.9293908,    0.3710189,    0.7943369,    0.30455244,    0.1610446,    0.9123745,     0.90176797,
+    0.80898714,   0.66391826,   0.2669795,    0.4585327,    0.08049692,    0.5608643,    0.3917094,     0.8189315,
+    0.48022225,   0.5775875,    0.11752723,   0.11563321,   0.20241146,    0.9870254,    0.70338356,    0.6672356,
+    0.5859097,    0.88540757,   0.4305323,    0.7083498,    0.69511765,    0.4063679,    0.6564408,     0.7851523,
+    0.71085393,   0.21500541,   0.028951503,  0.36494514,   0.16452302,    0.8277657,    0.9964415,     0.9795966,
+    0.6128888,    0.38048878,   0.29436752,   0.25057533,   0.17533945,    0.56550956,   0.06811409,    0.9185709,
+    0.3402165,    0.43478596,   0.13479339,   0.6732348,    0.64420736,    0.8993806,    0.033399098,   0.10784754,
+    0.22600721,   0.7037833,    0.20842715,   0.41914487,   0.7305123,     0.20402466,   0.2066503,     0.40261927,
+    0.007477421,  0.48182714,   0.74767876,   0.8654915,    0.5319128,     0.026764244,  0.6544085,     0.6524566,
+    0.58114594,   0.13793063,   0.50274444,   0.82192266,   0.6926579,     0.45280823,   0.49189615,    0.020400187,
+    0.8172935,    0.51196146,   0.36813334,   0.26033172,   0.27157453,    0.983206,     0.140945,      0.81147337,
+    0.18160632,   0.92110395,   0.13893794,   0.46073973,   0.6193385,     0.5772967,    0.2490843,     0.40886414,
+    0.1738385,    0.89174825,   0.24309792,   0.6935123,    0.8178308,     0.20262258,   0.38665804,    0.31345224,
+    0.78037745,   0.48233682,   0.09208888,   0.50627667,   0.3966362,     0.21147643,   0.41518968,    0.77319896,
+    0.21188715,   0.18802696,   0.60185134,   0.21855086,   0.8358913,     0.94631857,   0.13104475,    0.024271427,
+    0.34088212,   0.9362054,    0.6838852,    0.61080885,   0.8878263,     0.1936688,    0.03311803,    0.0038492912,
+    0.88884634,   0.09388026,   0.64808416,   0.8009096,    0.2097103,     0.79838383,   0.20256937,    0.61467093,
+    0.1253034,    0.054681093,  0.47995427,   0.7892377,    0.8911171,     0.6346683,    0.41483715,    0.9701299,
+    0.5059143,    0.36573896,   0.24885257,   0.43131158,   0.97544533,    0.03053343,   0.57297283,    0.2275199,
+    0.7607035,    0.21882649,   0.3526302,    0.8816254,    0.5187374,     0.77584916,   0.42562595,    0.58670866,
+    0.44921878,   0.08823959,   0.6174303,    0.30275592,   0.5633923,     0.61428005,   0.56348866,    0.41350332,
+    0.9854576,    0.9871804,    0.093247466,  0.7812102,    0.4663643,     0.34180707,   0.13315432,    0.70621383,
+    0.52136827,   0.7137553,    0.10489457,   0.52208734,   0.94481623,    0.60180646,   0.028403986,   0.8583129,
+    0.5209074,    0.42056426,   0.04020609,   0.9908838,    0.44575363,    0.32094392,   0.09593353,    0.34945422,
+    0.62905514,   0.89324564,   0.3400189,    0.80287755,   0.017237967,   0.112081215,  0.40673763,    0.8916342,
+    0.80225027,   0.83534926,   0.44585398,   0.98826486,   0.93728596,    0.79176265,   0.7611556,     0.41889647,
+    0.08567218,   0.64641637,   0.3602572,    0.80498207,   0.6709546,     0.9035386,    0.64189243,    0.84741235,
+    0.0598356,    0.7591174,    0.7818485,    0.142828,     0.574074,      0.5726049,    0.96774966,    0.6645137,
+    0.8912469,    0.74379325,   0.15215507,   0.5731187,    0.0017881524,  0.3302768,    0.6889758,     0.40928704,
+    0.30701768,   0.21326037,   0.71983707,   0.10946698,   0.1559525,     0.040139113,  0.92102695,    0.7291448,
+    0.6594087,    0.62130964,   0.9052116,    0.79933727,   0.9606867,     0.29095143,   0.6784996,     0.72551656,
+    0.2513532,    0.49260658,   0.74304193,   0.25812054,   0.33023268,    0.2639096,    0.31756023,    0.22964539,
+    0.86759955,   0.7813403,    0.097017966,  0.19349271,   0.63960755,    0.18803692,   0.4171083,     0.7553954,
+    0.95744056,   0.9509702,    0.4979644,    0.45769426,   0.18370152,    0.53242546,   0.69145983,    0.019696489,
+    0.8380905,    0.052703734,  0.48341933,   0.95276433,   0.6673932,     0.16841243,   0.70382696,    0.6002955,
+    0.06529366,   0.42663854,   0.32176548,   0.50918156,   0.58723485,    0.4308553,    0.079054326,   0.04310807,
+    0.89570016,   0.4901917,    0.24186741,   0.3746122,    0.94312114,    0.72753423,   0.08953723,    0.47137174,
+    0.20420133,   0.14981624,   0.8418967,    0.009716521,  0.79298705,    0.22080535,   0.541815,      0.71892774,
+    0.80114675,   0.72334546,   0.42003006,   0.27752897,   0.7804903,     0.36479586,   0.56225216,    0.69918716,
+    0.07751329,   0.4967225,    0.12819904,   0.212969,     0.86627144,    0.90792674,   0.16816054,    0.5265852,
+    0.8719159,    0.45485634,   0.56199414,   0.6935098,    0.29055804,    0.31684762,   0.07657534,    0.11055623,
+    0.9631665,    0.012047576,  0.74856305,   0.517577,     0.32651573,    0.69411045,   0.80730844,    0.8444883,
+    0.88482356,   0.60283774,   0.7080349,    0.8638894,    0.010825248,   0.80152535,   0.26261777,    0.53090423,
+    0.92793953,   0.54268026,   0.29709893,   0.44639865,   0.5993352,     0.8765682,    0.6051003,     0.2962746,
+    0.9816557,    0.31531146,   0.13780066,   0.3381307,    0.6588112,     0.84830517,   0.4283697,     0.48429912,
+    0.6467701,    0.30947384,   0.31436247,   0.7684427,    0.6162329,     0.044675153,  0.3726714,     0.38340282,
+    0.689414,     0.28371072,   0.32814547,   0.26343372,   0.19989188,    0.30427113,   0.51576,       0.07039049,
+    0.19223855,   0.031089857,  0.7655703,    0.7478778,    0.019748688,   0.63017666,   0.511221,      0.08659828,
+    0.40694728,   0.45228842,   0.53592134,   0.011204251,  0.5563098,     0.46917772,   0.18567711,    0.036518365,
+    0.17446801,   0.22373573,   0.21711932,   0.7013514,    0.48716292,    0.49417505,   0.9146714,     0.88326436,
+    0.17000887,   0.9136961,    0.7569846,    0.3156245,    0.54842275,    0.34166658,   0.09638273,    0.67738456,
+    0.7995515,    0.06741016,   0.14589214,   0.62772137,   0.08273488,    0.680492,     0.46455044,    0.016593413,
+    0.7982528,    0.22776419,   0.36149544,   0.16394442,   0.50875384,    0.36146715,   0.827093,      0.22023632,
+    0.098033614,  0.2916271,    0.088965714,  0.9761561,    0.08715181,    0.8144086,    0.5832276,     0.6980635,
+    0.11641844,   0.8823059,    0.5778689,    0.106052585,  0.8731921,     0.19559653,   0.5381755,     0.06528069,
+    0.3559057,    0.8585367,    0.21165277,   0.48889965,   0.32328558,    0.55795574,   0.95378345,    0.49397606,
+    0.7591853,    0.20052591,   0.9030986,    0.25939873,   0.13267961,    0.750727,     0.37451053,    0.8085417,
+    0.086603075,  0.5367483,    0.21759088,   0.25679567,   0.25270087,    0.120226584,  0.59023273,    0.9851429,
+    0.48418257,   0.44782865,   0.51130295,   0.20042898,   0.102623075,   0.35849786,   0.14340132,    0.6026563,
+    0.68958867,   0.29621476,   0.8080387,    0.6502171,    0.14981438,    0.3381934,    0.8969507,     0.54007787,
+    0.33784363,   0.59498966,   0.21697083,   0.8866259,    0.91130996,    0.32382888,   0.5653839,     0.36569145,
+    0.5077954,    0.76932716,   0.01944951,   0.3364438,    0.97800565,    0.28137985,   0.8125798,     0.2356791,
+    0.268304,     0.22650987,   0.00471706,   0.8754569,    0.04665282,    0.7533545,    0.39135298,    0.40068746,
+    0.05712457,   0.3004423,    0.56981003,   0.8364648,    0.9426883,     0.7242934,    0.65872735,    0.7484097,
+    0.63979757,   0.677513,     0.91895205,   0.6577112,    0.90325576,    0.70360684,   0.07383294,    0.1603537,
+    0.88244474,   0.14561148,   0.6926336,    0.3332959,    0.33904833,    0.80695754,   0.62465066,    0.40820882,
+    0.48363495,   0.5723596,    0.38191313,   0.9233045,    0.33347633,    0.021493766,  0.49342504,    0.5844891,
+    0.20363668,   0.81628335,   0.82950133,   0.6108677,    0.75401884,    0.728919,     0.42300317,    0.7835019,
+    0.11059984,   0.2710398,    0.6966462,    0.30049264,   0.3624278,     0.1548686,    0.33242336,    0.56469715,
+    0.15267694,   0.84436333,   0.9930122,    0.9010413,    0.06072089,    0.058057077,  0.061639126,   0.25016704,
+    0.6757917,    0.16160122,   0.3528299,    0.37032866,   0.34238032,    0.7354228,    0.41493335,    0.6183038,
+    0.18408795,   0.3344629,    0.45407453,   0.08697238,   0.8741055,     0.46296528,   0.40633488,    0.1535257,
+    0.7226083,    0.90913165,   0.22269607,   0.068008505,  0.1103113,     0.32415798,   0.045781024,   0.32876635,
+    0.23993625,   0.817216,     0.77062756,   0.48911297,   0.028481547,   0.5923837,    0.52376825,    0.14557959,
+    0.7546443,    0.5793343,    0.935076,     0.5924176,    0.37608913,    0.05267449,   0.44112164,    0.37517703,
+    0.85610646,   0.078342445,  0.11640469,   0.02796489,   0.70079404,    0.24545097,   0.69059163,    0.68971163,
+    0.43802848,   0.83948654,   0.17843302,   0.15158923,   0.835361,      0.99363065,   0.13985574,    0.3516337,
+    0.115820184,  0.02406358,   0.13039242,   0.5251643,    0.96479523,    0.92582035,   0.58982223,    0.59170425,
+    0.8106947,    0.30849496,   0.33232814,   0.2947712,    0.5278893,     0.8139172,    0.77743655,    0.6699338,
+    0.46801004,   0.84751904,   0.21190204,   0.031968854,  0.2077533,     0.017816134,  0.62797225,    0.99448526,
+    0.12662433,   0.080915935,  0.05108449,   0.18899502,   0.41395068,    0.372179,     0.3102186,     0.7610136,
+    0.43947858,   0.5834423,    0.47659743,   0.35202554,   0.9222821,     0.9159573,    0.4103818,     0.9302861,
+    0.4885202,    0.52470046,   0.21727021,   0.39229912,   0.91312283,    0.39582044,   0.16182233,    0.62411124,
+    0.062049974,  0.5084992,    0.6835792,    0.98784196,   0.78172857,    0.10788689,   0.1438804,     0.09800406,
+    0.3960913,    0.13590716,   0.39854,      0.8838793,    0.8747359,     0.40082723,   0.17775355,    0.43851566,
+    0.99827635,   0.5713145,    0.8552926,    0.94444704,   0.33731982,    0.42541102,   0.74765176,    0.55205274,
+    0.43713725,   0.28161594,   0.5434486,    0.68305284,   0.80054593,    0.23567316,   0.08136242,    0.7308039,
+    0.9190936,    0.42697325,   0.12694505,   0.9054515,    0.6885998,     0.32237664,   0.97928506,    0.33159167,
+    0.43956187,   0.3785934,    0.9559342,    0.7863749,    0.5174173,     0.5265025,    0.05555021,    0.08769297,
+    0.3469469,    0.77875453,   0.39402276,   0.34180835,   0.5405278,     0.21737531,   0.2867914,     0.636639,
+    0.76084745,   0.13152646,   0.5507047,    0.50011265,   0.5644382,     0.46082756,   0.29745814,    0.16041815,
+    0.054544732,  0.6677361,    0.9647857,    0.44776264,   0.27388218,    0.27230206,   0.74991584,    0.67589974,
+    0.59202945,   0.52370095,   0.50488514,   0.9587264,    0.46947676,    0.9612768,    0.034635436,   0.91063476,
+    0.22606573,   0.45575568,   0.33610594,   0.02179139,   0.8416504,     0.7395541,    0.19027609,    0.7017183,
+    0.14018182,   0.49030608,   0.14460404,   0.55707335,   0.7716719,     0.47917238,   0.76715344,    0.9787343,
+    0.08113525,   0.7955161,    0.7318302,    0.8496812,    0.5617168,     0.60778755,   0.81381077,    0.07464484,
+    0.028838681,  0.718123,     0.74977887,   0.016826851,  0.71249014,    0.32806498,   0.16716221,    0.7995706,
+    0.096891016,  0.64007,      0.27404693,   0.10868255,   0.12472161,    0.27566674,   0.31876773,    0.31499064,
+    0.47746003,   0.2630674,    0.30758083,   0.78357613,   0.12769802,    0.1928425,    0.90422785,    0.112857096,
+    0.7565475,    0.5261508,    0.8775912,    0.6739607,    0.22944665,    0.18495426,   0.3489179,     0.61827815,
+    0.6419449,    0.2614611,    0.9929527,    0.12352738,   0.98977524,    0.17344923,   0.9892281,     0.81211686,
+    0.32314387,   0.34503344,   0.46018234,   0.13160191,   0.20512545,    0.65847087,   0.8540127,     0.8054685,
+    0.47674835,   0.41683954,   0.37222117,   0.29864943,   0.30020675,    0.03023468,   0.94694686,    0.8359962,
+    0.8138952,    0.63692176,   0.26027933,   0.18633933,   0.45047382,    0.49320155,   0.570124,      0.91193676,
+    0.2911521,    0.65576875,   0.46673766,   0.8632605,    0.28271404,    0.19524036,   0.32521543,    0.30401078,
+    0.27383924,   0.495464,     0.46043226,   0.7826646,    0.7326602,     0.7726259,    0.90773165,    0.09807661,
+    0.6721381,    0.07212267,   0.1972123,    0.8126071,    0.8127331,     0.05026847,   0.3180714,     0.6117102,
+    0.31451428,   0.15695652,   0.30963218,   0.35285345,   0.9131699,     0.8028888,    0.36164302,    0.8299423,
+    0.7749095,    0.54824555,   0.8404498,    0.5493567,    0.19173324,    0.9907522,    0.5227545,     0.281508,
+    0.091624096,  0.06821037,   0.024810186,  0.80474275,   0.5698024,     0.16428226,   0.10333604,    0.04126928,
+    0.7291901,    0.16220273,   0.5142012,    0.37835112,   0.29598927,    0.75751686,   0.09920368,    0.24088362,
+    0.33769736,   0.85502744,   0.5487462,    0.12575752,   0.8856082,     0.972362,     0.3908409,     0.47095042,
+    0.13382097,   0.63048995,   0.007755094,  0.18441458,   0.9321761,     0.35837498,   0.9063434,     0.6813859,
+    0.5493682,    0.9157043,    0.720983,     0.7445227,    0.025458287,   0.5133287,    0.041907787,   0.15023202,
+    0.053620476,  0.2683629,    0.6236633,    0.75096714,   0.28868756,    0.98329186,   0.5339531,     0.017392641,
+    0.4490419,    0.5995662,    0.21165931,   0.3367058,    0.44200596,    0.39699697,   0.39589983,    0.11926211,
+    0.6773695,    0.5538598,    0.6709218,    0.93931246,   0.15652716,    0.9189215,    0.10909318,    0.37081516,
+    0.25585935,   0.83281535,   0.82898295,   0.38028497,   0.03653382,    0.35468096,   0.21542533,    0.8243687,
+    0.81311965,   0.39851424,   0.07213704,   0.61724526,   0.34869868,    0.63987374,   0.18226288,    0.15052907,
+    0.096536905,  0.99036247,   0.73537266,   0.3326099,    0.14671567,    0.5696376,    0.2393799,     0.15237123,
+    0.5198045,    0.6017209,    0.067153245,  0.47159854,   0.84240687,    0.1025953,    0.99370486,    0.134699,
+    0.15926972,   0.25284818,   0.4951078,    0.45587218,   0.15430894,    0.15366808,   0.9808588,     0.094360925,
+    0.38414088,   0.3872906,    0.52358615,   0.043491747,  0.32485992,    0.7786546,    0.7705634,     0.037495736,
+    0.37159687,   0.5203927,    0.8427756,    0.16616471,   0.18354878,    0.7764833,    0.22409947,    0.6862218,
+    0.59343547,   0.6766117,    0.8604805,    0.4348129,    0.2875277,     0.7438268,    0.9819619,     0.7105244,
+    0.4048094,    0.937438,     0.45797554,   0.09585048,   0.14476593,    0.7263907,    0.9962201,     0.9428688,
+    0.009503636,  0.6410118,    0.94846904,   0.7594251,    0.04605143,    0.19588815,   0.8275113,     0.7411499,
+    0.83115745,   0.02965751,   0.10000168,   0.32201412,   0.25981972,    0.82754016,   0.95115024,    0.38278645,
+    0.02874871,   0.808886,     0.8624367,    0.47769725,   0.29318756,    0.5460459,    0.8068332,     0.6403141,
+    0.4053287,    0.8130618,    0.63868237,   0.3874219,    0.320679,      0.67471296,   0.8927298,     0.64520615,
+    0.5241726,    0.89990675,   0.15666108,   0.54253703,   0.82801425,    0.46467438,   0.64017034,    0.39754733,
+    0.8491004,    0.11933059,   0.60365546,   0.25787023,   0.6438251,     0.65994775,   0.45070463,    0.57726926,
+    0.98628783,   0.075189106,  0.06710178,   0.33587992,   0.863954,      0.51852286,   0.64968127,    0.46345773,
+    0.83417857,   0.30815494,   0.35409638,   0.23298964,   0.5572058,     0.4400894,    0.4204709,     0.1564445,
+    0.13692771,   0.4547955,    0.7978415,    0.35991296,   0.67087907,    0.4086132,    0.5547722,     0.56407434,
+    0.16871567,   0.46488938,   0.62859684,   0.17385697,   0.94239044,    0.548963,     0.996489,      0.74538094,
+    0.36235714,   0.061413143,  0.40113407,   0.24548991,   0.6076112,     0.5568499,    0.78125215,    0.005649717,
+    0.2502255,    0.69320333,   0.70835847,   0.5198593,    0.110578,      0.4071807,    0.84034157,    0.40901098,
+    0.6988597,    0.44721094,   0.12094251,   0.1890296,    0.86210626,    0.09079167,   0.90639013,    0.5776746,
+    0.5204169,    0.50302744,   0.16716424,   0.39906463,   0.8899261,     0.47582427,   0.52106726,    0.2852156,
+    0.31166598,   0.6087155,    0.87063247,   0.49579263,   0.03895533,    0.174981,     0.5488333,     0.5800778,
+    0.67354333,   0.7921918,    0.10968746,   0.97767574,   0.70025474,    0.034912895,  0.45349634,    0.761535,
+    0.6245478,    0.21958585,   0.47499728,   0.4951795,    0.42802048,    0.80745935,   0.8832747,     0.27156547,
+    0.15502298,   0.8234595,    0.725073,     0.10458374,   0.38968566,    0.38218752,   0.11572367,    0.77440125,
+    0.17213607,   0.42314288,   0.2081933,    0.5018625,    0.5365482,     0.3445489,    0.37005565,    0.5238787,
+    0.8983776,    0.5408647,    0.51548624,   0.06991447,   0.9811042,     0.9287144,    0.8774199,     0.48550403,
+    0.04953112,   0.40562928,   0.7745168,    0.6703402,    0.00082698837, 0.025887761,  0.8571951,     0.5042066,
+    0.7254408,    0.59906703,   0.34076965,   0.21549584,   0.449908,      0.44424957,   0.19039217,    0.29135585,
+    0.67646813,   0.33528623,   0.80553967,   0.27711186,   0.8267196,     0.95163375,   0.22498675,    0.2799989,
+    0.8495302,    0.9511186,    0.5968019,    0.8871558,    0.2919731,     0.8133602,    0.29046127,    0.22630857,
+    0.9460396,    0.23956898,   0.05505262,   0.98405635,   0.60767066,    0.4453835,    0.77357423,    0.14624831,
+    0.5659478,    0.7039867,    0.7764218,    0.9374812,    0.0037792725,  0.1545598,    0.073970705,   0.45412806,
+    0.35047254,   0.2241304,    0.39344636,   0.645818,     0.12317476,    0.600308,     0.65878445,    0.09789734,
+    0.18064253,   0.49451795,   0.82080996,   0.049708407,  0.42908588,    0.9700393,    0.2122335,     0.9120806,
+    0.30860576,   0.11446109,   0.26945624,   0.21033902,   0.38919696,    0.20633578,   0.6836851,     0.23108464,
+    0.56171197,   0.6592914,    0.7111641,    0.122732915,  0.175212,      0.28750554,   0.2762196,     0.69497037,
+    0.87714785,   0.14267384,   0.53668326,   0.06784272,   0.41991386,    0.6446433,    0.10313381,    0.34573162,
+    0.58078456,   0.9571553,    0.8034138,    0.11315275,   0.62457347,    0.7238658,    0.71716243,    0.59590846,
+    0.4917532,    0.8643412,    0.62887543,   0.88931817,   0.8851036,     0.86363167,   0.064931095,   0.14413676,
+    0.54044527,   0.16236171,   0.084106006,  0.4638834,    0.8891439,     0.5360515,    0.9226853,     0.893137,
+    0.21829833,   0.12583959,   0.17256053,   0.28641203,   0.4333561,     0.14439079,   0.49216673,    0.6639625,
+    0.011327274,  0.9237246,    0.62955445,   0.43204167,   0.40292194,    0.5705324,    0.6065112,     0.83784616,
+    0.94212896,   0.115255654,  0.6309797,    0.3108708,    0.6586301,     0.38690144,   0.8098668,     0.013516203,
+    0.07774274,   0.39254647,   0.52739745,   0.25755215,   0.5605373,     0.6392504,    0.4565877,     0.044733036,
+    0.034469932,  0.91027683,   0.8948544,    0.4987339,    0.5513053,     0.4307504,    0.16255233,    0.3473624,
+    0.3721745,    0.96491295,   0.8779909,    0.961379,     0.2340772,     0.6328894,    0.7412148,     0.9699129,
+    0.55585057,   0.24625985,   0.52175444,   0.77388823,   0.9050718,     0.61181456,   0.23450689,    0.8313969,
+    0.31597278,   0.15904433,   0.20866929,   0.04080962,   0.6169933,     0.23461457,   0.1034252,     0.37207687,
+    0.4671369,    0.58482146,   0.39757174,   0.4926451,    0.67567796,    0.107777245,  0.28654084,    0.5113785,
+    0.9527033,    0.28361735,   0.9386963,    0.6937171,    0.50891054,    0.84848785,   0.779439,      0.44485334,
+    0.65133166,   0.55748457,   0.7017016,    0.3142774,    0.11749596,    0.68269944,   0.13966125,    0.42265537,
+    0.6757699,    0.06345752,   0.18276113,   0.39226097,   0.2220811,     0.12174272,   0.7303691,     0.13755992,
+    0.8614878,    0.50591403,   0.4942421,    0.64925575,   0.23531766,    0.24856968,   0.29423487,    0.44807333,
+    0.959719,     0.010375906,  0.82118493,   0.6214544,    0.67311823,    0.5407898,    0.3224864,     0.46748495,
+    0.37960532,   0.76381594,   0.38947794,   0.05950873,   0.53291297,    0.7891478,    0.2545809,     0.7844374,
+    0.44516018,   0.97491634,   0.81687516,   0.61222047,   0.9250161,     0.89427984,   0.28929746,    0.83096063,
+    0.5532483,    0.8011364,    0.8322293,    0.0029964554, 0.35424575,    0.13018323,   0.20953566,    0.402762,
+    0.2632497,    0.25362825,   0.3545584,    0.10712006,   0.8615145,     0.51820683,   0.7495371,     0.13498017,
+    0.74097115,   0.7152762,    0.0126556605, 0.45826513,   0.73226476,    0.67086035,   0.6046469,     0.07234,
+    0.25133318,   0.70980465,   0.20409557,   0.2604013,    0.43169454,    0.6820144,    0.5230572,     0.065439165,
+    0.72107846,   0.99022436,   0.06820616,   0.87198186,   0.70856047,    0.31948993,   0.11323921,    0.24942209,
+    0.5542803,    0.9867159,    0.79625905,   0.27928472,   0.4345894,     0.14746083,   0.9229229,     0.9269534,
+    0.22537923,   0.681895,     0.8712493,    0.20973994,   0.8816242,     0.83103234,   0.098695815,   0.88238794,
+    0.19648944,   0.75988936,   0.75166327,   0.64444107,   0.9260877,     0.94913435,   0.9710675,     0.5812353,
+    0.7305711,    0.28911924,   0.3860416,    0.87129015,   0.45000067,    0.87755525,   0.42641973,    0.4214812,
+    0.60203695,   0.7632336,    0.90398484,   0.74554884,   0.8746013,     0.32536224,   0.6377506,     0.10387234,
+    0.7868817,    0.2771422,    0.035022065,  0.74979955,   0.8107651,     0.31331727,   0.18381497,    0.8900461,
+    0.89152855,   0.18581823,   0.6754924,    0.9486711,    0.5678266,     0.4687981,    0.32333443,    0.60514593,
+    0.015648454,  0.21502374,   0.5487136,    0.14547014,   0.76141924,    0.05163277,   0.4769527,     0.34782398,
+    0.25547525,   0.44976813,   0.607703,     0.11839061,   0.9270475,     0.35314697,   0.007786621,   0.8711272,
+    0.12213872,   0.64779097,   0.8575594,    0.64894545,   0.9141123,     0.22126794,   0.77047014,    0.4172538,
+    0.10530428,   0.4959955,    0.97976166,   0.26418245,   0.20206283,    0.47774863,   0.85365456,    0.13323887,
+    0.43989918,   0.29883888,   0.7299004,    0.65957755,   0.7766486,     0.49228048,   0.34245312,    0.7352489,
+    0.8001895,    0.6871981,    0.49432427,   0.360997,     0.70561427,    0.06542435,   0.96299857,    0.5383816,
+    0.1780316,    0.8043652,    0.82653236,   0.92003566,   0.6112387,     0.67438895,   0.6910336,     0.79438055,
+    0.44455358,   0.13145985,   0.04016586,   0.26542372,   0.07187113,    0.21277027,   0.14576113,    0.77772665,
+    0.59611356,   0.47446412,   0.6784915,    0.62820864,   0.62324655,    0.34820905,   0.094478644,   0.62985826,
+    0.30533785,   0.122310445,  0.84875596,   0.22691421,   0.7269437,     0.40947318,   0.7116395,     0.039879926,
+    0.5329969,    0.44138008,   0.08615084,   0.39769763,   0.65121627,    0.93361884,   0.52200013,    0.7655102,
+    0.60780525,   0.9355199,    0.21502401,   0.64518875,   0.45211464,    0.0770294,    0.6633778,     0.5874192,
+    0.541437,     0.7165977,    0.7648834,    0.2311502,    0.3869329,     0.33478996,   0.915135,      0.82982254,
+    0.70988655,   0.19667415,   0.6146979,    0.4889283,    0.825633,      0.46411943,   0.067436874,   0.035080392,
+    0.41982034,   0.0002859342, 0.7324268,    0.630491,     0.12661943,    0.7480635,    0.12651038,    0.6624947,
+    0.952464,     0.9129812,    0.020403363,  0.6877267,    0.13318504,    0.44928992,   0.1777436,     0.22830844,
+    0.45893264,   0.2613367,    0.68547726,   0.010346001,  0.6445898,     0.4804893,    0.652947,      0.19820693,
+    0.52624506,   0.25632828,   0.687811,     0.4545421,    0.31892103,    0.033071853,  0.9398772,     0.14368583,
+    0.868083,     0.17994362,   0.2253684,    0.4518287,    0.34460258,    0.032886766,  0.4607998,     0.7933734,
+    0.59008723,   0.10238874,   0.27868623,   0.47395167,   0.3143866,     0.22740832,   0.6966375,     0.26059666,
+    0.018930554,  0.3863894,    0.029995646,  0.5642963,    0.7786422,     0.05709087,   0.39049065,    0.939331,
+    0.3473389,    0.53421986,   0.10424597,   0.8702912,    0.060252476,   0.6719683,    0.34357366,    0.9193921,
+    0.97310406,   0.8767175,    0.8196437,    0.9532414,    0.22392152,    0.7259149,    0.88370585,    0.42604586,
+    0.80053693,   0.8921038,    0.42025873,   0.54220104,   0.2018031,     0.17899537,   0.8838203,     0.29883677,
+    0.5596908,    0.42721438,   0.43561155,   0.9325316,    0.0030762074,  0.37558094,   0.36504367,    0.8109921,
+    0.78945297,   0.2860374,    0.10448979,   0.8103827,    0.9286408,     0.59050864,   0.733121,      0.91811895,
+    0.75881505,   0.35929412,   0.50084764,   0.4376691,    0.40776464,    0.7433961,    0.036675144,   0.29301566,
+    0.5026836,    0.6039498,    0.7637594,    0.8865383,    0.6368321,     0.8482896,    0.7375279,     0.16834354,
+    0.65039957,   0.8054092,    0.31060037,   0.6330381,    0.23635677,    0.41104206,   0.9163159,     0.5975231,
+    0.51167387,   0.008651535,  0.16378845,   0.93788415,   0.62142515,    0.07332315,   0.49740508,    0.21002825,
+    0.15898286,   0.5021398,    0.78338593,   0.842509,     0.67814773,    0.44615123,   0.8910721,     0.81629467,
+    0.39053923,   0.14259589,   0.42984807,   0.39912644,   0.61182153,    0.47850534,   0.17416,       0.94116336,
+    0.5485095,    0.93614626,   0.15998314,   0.12323159,   0.27990827,    0.10008287,   0.6817622,     0.34777302,
+    0.4429782,    0.9033245,    0.92599523,   0.39911312,   0.57960767,    0.09879101,   0.6715905,     0.4293604,
+    0.1065447,    0.55373114,   0.72755545,   0.13469236,   0.06490368,    0.89501894,   0.4901958,     0.20424834,
+    0.9143371,    0.4943057,    0.24249884,   0.093760885,  0.98119396,    0.5171895,    0.98570156,    0.03316852,
+    0.83449155,   0.22262509,   0.38937467,   0.6852789,    0.91334003,    0.3741735,    0.93012,       0.05889999,
+    0.8203776,    0.43561292,   0.3995308,    0.77482325,   0.52015597,    0.491959,     0.23668702,    0.29174823,
+    0.47100535,   0.0004876647, 0.29258174,   0.058090426,  0.75094986,    0.039467655,  0.8762597,     0.65349054,
+    0.44595045,   0.9557348,    0.20889449,   0.78560257,   0.857584,      0.5880013,    0.36657903,    0.9257887,
+    0.917623,     0.89282674,   0.56462157,   0.35698256,   0.70941633,    0.9863116,    0.51602036,    0.7323712,
+    0.62361115,   0.6686555,    0.31431475,   0.62929076,   0.4954881,     0.71537256,   0.68409234,    0.4223781,
+    0.2576187,    0.9507506,    0.6227555,    0.98070633,   0.22460775,    0.9276111,    0.28221866,    0.79502386,
+    0.34636542,   0.73588413,   0.23932843,   0.95760524,   0.165279,      0.1445174,    0.20131597,    0.23237628,
+    0.069033906,  0.47374207,   0.85720026,   0.62732923,   0.9273374,     0.8797045,    0.5823319,     0.48469374,
+    0.48446727,   0.5602105,    0.43447927,   0.08229436,   0.7251529,     0.24696892,   0.15800244,    0.7305779,
+    0.27164242,   0.78651637,   0.52798384,   0.9068334,    0.9652458,     0.3858727,    0.701181,      0.9900118,
+    0.61060804,   0.7695977,    0.010617126,  0.97353226,   0.74698323,    0.5584152,    0.56709224,    0.47909376,
+    0.46733952,   0.08193848,   0.56025684,   0.021746036,  0.8581723,     0.056763105,  0.49504068,    0.37791422,
+    0.36841872,   0.13806179,   0.49623904,   0.66439724,   0.49313185,    0.19992432,   0.06987098,    0.09939649,
+    0.5778817,    0.50875056,   0.6859628,    0.3787626,    0.6165335,     0.29448256,   0.2671305,     0.6831612,
+    0.77256113,   0.86718845,   0.016721206,  0.1577397,    0.86908734,    0.60879964,   0.73771054,    0.9260521,
+    0.9931183,    0.9553855,    0.6149548,    0.6432144,    0.6867121,     0.1362564,    0.8724056,     0.21487932,
+    0.2914757,    0.15006965,   0.53841466,   0.827184,     0.88963366,    0.03678374,   0.49687997,    0.41068372,
+    0.69972676,   0.9112206,    0.39565054,   0.23823264,   0.8724524,     0.18832962,   0.8625602,     0.17285694,
+    0.814808,     0.87709564,   0.24918492,   0.99098384,   0.0400419,     0.337301,     0.50882685,    0.7596191,
+    0.4003513,    0.5701869,    0.67127895,   0.5377463,    0.58496946,    0.42665657,   0.4126844,     0.4416253,
+    0.63634497,   0.47108346,   0.08728689,   0.4664639,    0.75606793,    0.4399465,    0.79352754,    0.7357774,
+    0.3703085,    0.6060375,    0.45801297,   0.9578667,    0.2131491,     0.49947786,   0.05359975,    0.8047887,
+    0.092825316,  0.4420979,    0.82840645,   0.80961645,   0.8870715,     0.88142174,   0.17483743,    0.95417476,
+    0.6412428,    0.7787956,    0.4268327,    0.31944674,   0.3655048,     0.9591336,    0.82571423,    0.2730702,
+    0.49853623,   0.95402527,   0.6018877,    0.4013689,    0.10104273,    0.39609635,   0.41678905,    0.37486148,
+    0.083568096,  0.5134075,    0.6206753,    0.43400443,   0.879288,      0.5509602,    0.54647,       0.9008734,
+    0.5165872,    0.86649024,   0.44492102,   0.14287159,   0.59825015,    0.60306793,   0.5545538,     0.7549232,
+    0.29624605,   0.13311216,   0.8252211,    0.97727233,   0.013113789,   0.4740808,    0.37027258,    0.41117483,
+    0.7803232,    0.18494278,   0.45933047,   0.25912383,   0.89759016,    0.65223086,   0.70374596,    0.696729,
+    0.02530885,   0.45354494,   0.72604835,   0.37366393,   0.2607464,     0.740833,     0.07488672,    0.09028263,
+    0.23232558,   0.5259593,    0.80285954,   0.49901456,   0.5142126,     0.6828427,    0.67482007,    0.8954683,
+    0.39947143,   0.8469645,    0.10512285,   0.96793056,   0.5708752,     0.43951672,   0.3617477,     0.6094873,
+    0.14313498,   0.2095005,    0.6536812,    0.69434524,   0.09162968,    0.28734615,   0.0032832306,  0.86435634,
+    0.1627443,    0.748192,     0.11756273,   0.14470519,   0.8770196,     0.1808899,    0.49417683,    0.55541307,
+    0.05822544,   0.73493844,   0.7449467,    0.48715448,   0.67122126,    0.871258,     0.8969622,     0.097480536,
+    0.5101227,    0.5638622,    0.8596524,    0.050625734,  0.547108,      0.7358154,    0.12585375,    0.5857921,
+    0.09179724,   0.11656108,   0.23052894,   0.051245883,  0.08715177,    0.38054147,   0.99865294,    0.9449794,
+    0.52267605,   0.93850327,   0.33627024,   0.7660206,    0.56527996,    0.5301148,    0.018448701,   0.21858154,
+    0.3527876,    0.5497098,    0.90970516,   0.8359368,    0.69457,       0.8745932,    0.93826604,    0.27187696,
+    0.3125383,    0.5562007,    0.1842225,    0.5277675,    0.42769375,    0.9526575,    0.3172483,     0.42692894,
+    0.6223383,    0.5317706,    0.05290796,   0.7604585,    0.95036095,    0.44293094,   0.46826127,    0.67768395,
+    0.7362855,    0.7999673,    0.96447843,   0.732718,     0.53498775,    0.13094164,   0.5322006,     0.9800079,
+    0.5454135,    0.64107084,   0.6978381,    0.9973982,    0.82611024,    0.28991696,   0.8912221,     0.21720403,
+    0.17829505,   0.95865196,   0.7387076,    0.5309511,    0.19631897,    0.47088546,   0.5172857,     0.5700186,
+    0.6212549,    0.90934134,   0.14368229,   0.033509336,  0.4772069,     0.25799018,   0.26822057,    0.9098567,
+    0.08144851,   0.23202117,   0.09965124,   0.8946027,    0.91011477,    0.20554802,   0.7368892,     0.18159665,
+    0.024000084,  0.20421462,   0.982354,     0.7866229,    0.2548194,     0.31985012,   0.6008187,     0.33242133,
+    0.64054847,   0.8357039,    0.58216345,   0.991709,     0.70422333,    0.93731016,   0.481365,      0.26540005,
+    0.2826816,    0.39445987,   0.1114631,    0.6256465,    0.9872593,     0.49869126,   0.502801,      0.2874233,
+    0.37285027,   0.78798145,   0.9159497,    0.5940891,    0.19026573,    0.99661946,   0.30708927,    0.972747,
+    0.22176278,   0.55711097,   0.50695103,   0.99210435,   0.48853147,    0.73066276,   0.31519917,    0.3014048,
+    0.30852264,   0.81126094,   0.39296088,   0.641503,     0.6758267,     0.27651158,   0.20563333,    0.14413832,
+    0.7506562,    0.83425117,   0.6119211,    0.5156549,    0.094084926,   0.111242734,  0.1943373,     0.52530885,
+    0.70141363,   0.6949307,    0.41377264,   0.46683794,   0.4039004,     0.006729609,  0.14215559,    0.643929,
+    0.52861464,   0.6094164,    0.7699462,    0.1471124,    0.43035918,    0.4892606,    0.7768686,     0.5520188,
+    0.07926069,   0.8100583,    0.31712383,   0.17599839,   0.105730385,   0.861298,     0.6115966,     0.096338674,
+    0.5823481,    0.77181137,   0.8434329,    0.35601455,   0.38469836,    0.79143435,   0.8786621,     0.11052005,
+    0.36277366,   0.9816422,    0.29069075,   0.7936008,    0.31689015,    0.84836125,   0.8975044,     0.30179304,
+    0.66910535,   0.7490319,    0.1128883,    0.06641029,   0.5065654,     0.058520928,  0.71377915,    0.26139554,
+    0.057382602,  0.059902266,  0.4363942,    0.28402662,   0.7941189,     0.018338913,  0.41957843,    0.84011555,
+    0.083334126,  0.31743395,   0.88448983,   0.632089,     0.16329671,    0.78614104,   0.2592306,     0.7371803,
+    0.7307543,    0.65942615,   0.7843387,    0.448717,     0.19856988,    0.9832678,    0.23512867,    0.23089947,
+    0.9125539,    0.015330798,  0.50689304,   0.3566985,    0.74840975,    0.5451863,    0.5897733,     0.5238272,
+    0.05803223,   0.5820373,    0.29863194,   0.3247961,    0.35504016,    0.5946355,    0.31640115,    0.34443474,
+    0.56206375,   0.45057517,   0.71026665,   0.99945617,   0.9638714,     0.26541534,   0.13849631,    0.8829643,
+    0.48980126,   0.375708,     0.33565596,   0.84713924,   0.2741822,     0.26506215,   0.06282568,    0.07411481,
+    0.8247736,    0.20549475,   0.37147272,   0.7787881,    0.5114459,     0.06287994,   0.09170583,    0.53814787,
+    0.72766066,   0.36066267,   0.5740568,    0.58125937,   0.4875091,     0.93443453,   0.38214013,    0.13611887,
+    0.343025,     0.439904,     0.88665324,   0.7479947,    0.27300113,    0.23567249,   0.26702806,    0.64713854,
+    0.8768345,    0.62392867,   0.8668972,    0.37270173,   0.20953032,    0.74263406,   0.249645,      0.79297006,
+    0.51921165,   0.22451714,   0.50002253,   0.14954542,   0.22316273,    0.53761303,   0.83298886,    0.4991838,
+    0.35886934,   0.17211881,   0.2717955,    0.6032087,    0.6913585,     0.5572369,    0.3954552,     0.55536675,
+    0.9935679,    0.19953707,   0.5041142,    0.83427817,   0.3784089,     0.314831,     0.80111367,    0.58910114,
+    0.93846667,   0.7243342,    0.90195364,   0.8875172,    0.19598271,    0.7190041,    0.3286175,     0.9850266,
+    0.11101766,   0.78108674,   0.06204771,   0.26299196,   0.434412,      0.23259473,   0.9129562,     0.805412,
+    0.6069152,    0.38746944,   0.38912535,   0.10088234,   0.96387696,    0.6638193,    0.95578,       0.31959754,
+    0.22847345,   0.3115305,    0.37913388,   0.009993258,  0.23851983,    0.4153668,    0.41456118,    0.20438069,
+    0.42340347,   0.9109214,    0.21107873,   0.49882856,   0.6356594,     0.94547164,   0.3032011,     0.6398653,
+    0.84350127,   0.28676888,   0.49219108,   0.91027176,   0.49518922,    0.13246326,   0.120954745,   0.76097316,
+    0.28658092,   0.6987022,    0.22736304,   0.99093944,   0.9257056,     0.7002313,    0.6252242,     0.27464733,
+    0.76855415,   0.5823561,    0.6590438,    0.8844522,    0.3398702,     0.31862426,   0.7465068,     0.6956509,
+    0.36652556,   0.857667,     0.8395885,    0.5234906,    0.021515984,   0.4141276,    0.16975257,    0.66144353,
+    0.084268354,  0.74926007,   0.25738105,   0.67710805,   0.17162827,    0.045508236,  0.8244083,     0.0960102,
+    0.19057575,   0.6181607,    0.72341233,   0.5398176,    0.18800376,    0.4236217,    0.27867505,    0.7231721,
+    0.28569725,   0.9364314,    0.73027444,   0.05330333,   0.28642786,    0.4187489,    0.29999506,    0.524877,
+    0.5402621,    0.7965402,    0.54374623,   0.6375222,    0.29287475,    0.59746414,   0.73945713,    0.87245333,
+    0.5289497,    0.56591946,   0.9066711,    0.17644554,   0.4428503,     0.94811606,   0.10301907,    0.7230459,
+    0.75794774,   0.5630336,    0.69387645,   0.7217095,    0.5952119,     0.20668921,   0.5076471,     0.9429038,
+    0.57899195,   0.116416365,  0.23779334,   0.08508458,   0.6838532,     0.11644924,   0.3750157,     0.6655195,
+    0.44926503,   0.73250407,   0.13684598,   0.37508807,   0.50176203,    0.1868861,    0.80313545,    0.59311163,
+    0.8787036,    0.850959,     0.0108679095, 0.62208426,   0.5169506,     0.10222952,   0.28032187,    0.3375812,
+    0.83341235,   0.0072284974, 0.2953556,    0.7233943,    0.7248724,     0.5782856,    0.9296651,     0.3335729,
+    0.28889313,   0.6008424,    0.05853025,   0.17645839,   0.3596708,     0.6543726,    0.18860014,    0.41250044,
+    0.19090378,   0.24115163,   0.7271805,    0.7103462,    0.8112701,     0.727931,     0.22128391,    0.5710617,
+    0.7598981,    0.10076484,   0.8430059,    0.7442529,    0.1958213,     0.8855628,    0.4259532,     0.47676244,
+    0.8360945,    0.90021217,   0.25167224,   0.67662466,   0.8210937,     0.6516214,    0.940647,      0.8709795,
+    0.802839,     0.8032731,    0.08619493,   0.9009196,    0.12835586,    0.62667704,   0.2334408,     0.224331,
+    0.6623589,    0.59836745,   0.4311805,    0.27579898,   0.37504902,    0.5699756,    0.5263111,     0.10548131,
+    0.7859446,    0.72429395,   0.96349615,   0.6241076,    0.7352797,     0.18541217,   0.13775158,    0.40333033,
+    0.17488916,   0.5817678,    0.34036386,   0.45945865,   0.40270033,    0.51197547,   0.59140676,    0.5392824,
+    0.3005046,    0.85620105,   0.9075073,    0.007996995,  0.6417361,     0.3203643,    0.44270578,    0.13322107,
+    0.86732405,   0.6186749,    0.08189404,   0.59745383,   0.4543823,     0.15015423,   0.10171343,    0.2661189,
+    0.37390104,   0.14619094,   0.8906801,    0.096799746,  0.68812525,    0.31653944,   0.13569976,    0.6174268,
+    0.6655215,    0.6828646,    0.72603047,   0.54658806,   0.28631318,    0.77398217,   0.8216307,     0.15038341,
+    0.0069607063, 0.8918981,    0.97529435,   0.518848,     0.6624684,     0.5183141,    0.46374524,    0.4655803,
+    0.28158814,   0.83027506,   0.75678355,   0.11660483,   0.10351813,    0.54029775,   0.948948,      0.024734931,
+    0.48005438,   0.074244976,  0.0855576,    0.2565094,    0.62129533,    0.49460703,   0.85115707,    0.98396516,
+    0.7205013,    0.2900805,    0.34247547,   0.9588715,    0.5943338,     0.89611775,   0.8469079,     0.09334188,
+    0.79704416,   0.9315106,    0.59049314,   0.5624842,    0.17485987,    0.5828654,    0.60365057,    0.85558695,
+    0.6824457,    0.4250998,    0.8152116,    0.8578502,    0.55975586,    0.01909494,   0.5139087,     0.12522376,
+    0.73391664,   0.7012955,    0.06653367,   0.2120682,    0.6884245,     0.5651213,    0.5290881,     0.51235366,
+    0.040741026,  0.9913292,    0.7983467,    0.3723879,    0.17583862,    0.50487375,   0.87124646,    0.3854704,
+    0.9833672,    0.66344166,   0.31956065,   0.1720075,    0.94980466,    0.38646382,   0.8498751,     0.89718896,
+    0.4705944,    0.22997065,   0.57406366,   0.19619557,   0.67939544,    0.9933069,    0.4242093,     0.70140636,
+    0.7761718,    0.21725173,   0.22495484,   0.89303833,   0.82958406,    0.6348397,    0.40491733,    0.23192288,
+    0.40242258,   0.07813944,   0.5217432,    0.18353066,   0.7845187,     0.23126268,   0.6797483,     0.17757194,
+    0.55385333,   0.42974123,   0.874483,     0.8963142,    0.6995343,     0.34190118,   0.17541912,    0.34745282,
+    0.85142046,   0.16934472,   0.7414738,    0.4584539,    0.99105763,    0.33289248,   0.8329583,     0.04743413,
+    0.5671199,    0.09694037,   0.5962161,    0.9585869,    0.2799189,     0.9782081,    0.5558863,     0.3485275,
+    0.25852436,   0.08763776,   0.76958495,   0.8716652,    0.86472064,    0.6663444,    0.1126702,     0.23933174,
+    0.55022234,   0.39649174,   0.64234227,   0.24965419,   0.118823886,   0.5278951,    0.0018720366,  0.43427062,
+    0.04183261,   0.877502,     0.04161787,   0.66023934,   0.8933659,     0.9464634,    0.24086526,    0.069530085,
+    0.24518117,   0.47430903,   0.61641073,   0.6875784,    0.6350466,     0.7211614,    0.89765304,    0.5756452,
+    0.87385494,   0.5259555,    0.63778985,   0.6118965,    0.5723162,     0.3037539,    0.48273215,    0.18507604,
+    0.05667453,   0.5021421,    0.90823156,   0.59456587,   0.69055027,    0.5833041,    0.92861027,    0.039224792,
+    0.095068336,  0.16194543,   0.9167543,    0.40241688,   0.93659025,    0.895647,     0.4551616,     0.31206095,
+    0.8467725,    0.7000548,    0.62648404,   0.39041162,   0.049933646,   0.42509183,   0.6042851,     0.8290609,
+    0.49883872,   0.06669706,   0.37579927,   0.5928684,    0.89010525,    0.3899755,    0.8619544,     0.7380787,
+    0.39476988,   0.8565418,    0.6035648,    0.39122385,   0.038231853,   0.64629936,   0.37897983,    0.6618771,
+    0.54569876,   0.577186,     0.59251004,   0.47310117,   0.8044071,     0.49523613,   0.6390549,     0.97820795,
+    0.07079393,   0.3257289,    0.765124,     0.8722614,    0.6772699,     0.092320524,  0.1351424,     0.6315827,
+    0.89785695,   0.07917066,   0.09572715,   0.6238532,    0.20750481,    0.33574188,   0.14911953,    0.70509285,
+    0.29999104,   0.1786756,    0.0076469877, 0.08004845,   0.29208216,    0.063937746,  0.27382907,    0.20047311,
+    0.32107502,   0.96460694,   0.84471285,   0.47274768,   0.8325818,     0.13118395,   0.024653764,   0.0036025788,
+    0.42764217,   0.39759132,   0.52207446,   0.56437635,   0.62485147,    0.989693,     0.060808785,   0.30244938,
+    0.7213994,    0.9719821,    0.49336693,   0.9590612,    0.5505722,     0.75512666,   0.4543723,     0.2099569,
+    0.42806646,   0.8874172,    0.17311013,   0.6257315,    0.48758915,    0.55900645,   0.68612576,    0.0068561803,
+    0.051899806,  0.56465095,   0.5511864,    0.71266294,   0.2476077,     0.6623947,    0.7990009,     0.76667297,
+    0.054516893,  0.092124574,  0.19621104,   0.80991346,   0.8136675,     0.58474314,   0.08024137,    0.31029803,
+    0.117866814,  0.70519763,   0.35864902,   0.32010004,   0.5705708,     0.3147679,    0.64990085,    0.56594837,
+    0.51023465,   0.6347559,    0.044681232,  0.94516456,   0.9580738,     0.39892223,   0.51601344,    0.8686357,
+    0.71146554,   0.51521826,   0.51247656,   0.06020054,   0.43850663,    0.3481458,    0.054841675,   0.059004717,
+    0.1729812,    0.7266939,    0.9045443,    0.45844766,   0.5589156,     0.6444588,    0.39628944,    0.8433233,
+    0.8071758,    0.8628121,    0.5078647,    0.78239155,   0.20035744,    0.36602575,   0.43628535,    0.7371319,
+    0.91475004,   0.985238,     0.20242831,   0.61285174,   0.6177135,     0.8538363,    0.8085992,     0.65559465,
+    0.57611114,   0.32757533,   0.09844793,   0.2984492,    0.07226656,    0.020040827,  0.87179136,    0.769721,
+    0.65035594,   0.2996443,    0.14711884,   0.8438769,    0.4102236,     0.1914532,    0.007032739,   0.8657759,
+    0.23846649,   0.20135792,   0.13798875,   0.09526171,   0.8910575,     0.7336219,    0.6682783,     0.34543982,
+    0.078932896,  0.77534467,   0.14545049,   0.45326862,   0.14571752,    0.44198993,   0.44129124,    0.31914487,
+    0.9180948,    0.24894963,   0.8823365,    0.23134027,   0.54601085,    0.09784024,   0.7710568,     0.787135,
+    0.99102074,   0.73814374,   0.13203558,   0.90071315,   0.2189069,     0.5924085,    0.32690832,    0.7232968,
+    0.97820526,   0.33665246,   0.37438527,   0.41635555,   0.71584755,    0.7133375,    0.76453716,    0.84248924,
+    0.6592971,    0.7530081,    0.2195163,    0.29692188,   0.87459034,    0.41852275,   0.62400347,    0.20836602,
+    0.8583531,    0.82797396,   0.9257821,    0.16127396,   0.3091167,     0.77569246,   0.31976497,    0.14062625,
+    0.43030116,   0.35085374,   0.104240976,  0.15291376,   0.6015863,     0.76756513,   0.12653293,    0.48652443,
+    0.44843635,   0.42215365,   0.47506335,   0.80906504,   0.06760467,    0.02493567,   0.6032973,     0.20475733,
+    0.48441246,   0.039847255,  0.5720432,    0.7930028,    0.8783239,     0.47413486,   0.91254467,    0.57249796,
+    0.11414025,   0.9236696,    0.042360075,  0.39093295,   0.6666264,     0.16563436,   0.41418016,    0.20251282,
+    0.016887465,  0.23375902,   0.9860544,    0.36499384,   0.60909647,    0.6116234,    0.24090295,    0.891732,
+    0.6264752,    0.7329919,    0.8484855,    0.45243672,   0.9434594,     0.8149384,    0.14076136,    0.8334174,
+    0.22467664,   0.72102475,   0.6768615,    0.26926944,   0.20364925,    0.52676225,   0.2623023,     0.95616627,
+    0.43830907,   0.531743,     0.03877351,   0.67791677,   0.72520506,    0.7356,       0.81989807,    0.282802,
+    0.007973485,  0.27255052,   0.7921776,    0.8338457,    0.038881265,   0.23830348,   0.59566087,    0.872789,
+    0.7989443,    0.68031126,   0.16652757,   0.14533207,   0.62564933,    0.46010798,   0.6290386,     0.29920182,
+    0.7829082,    0.20894268,   0.16625631,   0.94560164,   0.48877287,    0.14491072,   0.9988636,     0.49012524,
+    0.9714567,    0.029888112,  0.92668474,   0.07735347,   0.5728499,     0.5629862,    0.16652691,    0.8908752,
+    0.91309386,   0.56568354,   0.44446322,   0.67090887,   0.022760825,   0.3069157,    0.7945361,     0.9863731,
+    0.12536389,   0.80407244,   0.47032514,   0.523338,     0.36023465,    0.11697024,   0.33051696,    0.9782011,
+    0.9027044,    0.7395717,    0.89500856,   0.51626235,   0.5693437,     0.8742964,    0.7940291,     0.86306274,
+    0.27368698,   0.30205235,   0.86238897,   0.008993154,  0.31161872,    0.5183074,    0.29993913,    0.2359581,
+    0.51378435,   0.27565238,   0.23223823,   0.059965752,  0.01564475,    0.9581297,    0.276441,      0.4759925,
+    0.41440654,   0.17988315,   0.82023776,   0.68470037,   0.6745856,     0.47552556,   0.12989059,    0.85448647,
+    0.69937116,   0.94848365,   0.17464903,   0.83327824,   0.6679777,     0.65026456,   0.32153153,    0.038797423,
+    0.7716544,    0.58140045,   0.3972219,    0.7207085,    0.44452676,    0.78554296,   0.67475444,    0.6070565,
+    0.50413334,   0.23436703,   0.009553685,  0.08458229,   0.884732,      0.27055123,   0.96255636,    0.9445748,
+    0.46313068,   0.41901603,   0.10185582,   0.38946053,   0.05405868,    0.10932874,   0.18847717,    0.79816145,
+    0.17216177,   0.007902476,  0.30962202,   0.36313507,   0.34365836,    0.46666092,   0.5679804,     0.8635198,
+    0.9541208,    0.19344081,   0.2883113,    0.4342443,    0.5609078,     0.55573255,   0.03146575,    0.6288636,
+    0.50512874,   0.21318124,   0.18056706,   0.44021857,   0.46597186,    0.045308296,  0.96975446,    0.42881992,
+    0.9859273,    0.23007429,   0.37014756,   0.24896163,   0.54840875,    0.932071,     0.98473877,    0.6623257,
+    0.39292327,   0.5990605,    0.5485467,    0.4366243,    0.47592095,    0.31161934,   0.26339814,    0.037472416,
+    0.6663866,    0.1460339,    0.13046144,   0.6912912,    0.9822399,     0.528312,     0.38366696,    0.90739816,
+    0.3875503,    0.47299224,   0.88433176,   0.8408774,    0.92876166,    0.7482586,    0.33218956,    0.12685347,
+    0.038148023,  0.8808021,    0.37720776,   0.11358407,   0.09651337,    0.3190188,    0.31511107,    0.022049852,
+    0.20870206,   0.6259856,    0.041321024,  0.9618473,    0.007185834,   0.5948415,    0.15294261,    0.19350938,
+    0.9497831,    0.14309464,   0.77383196,   0.31993797,   0.91484684,    0.27846324,   0.44658,       0.45761526,
+    0.8464073,    0.46274942,   0.86141133,   0.075416476,  0.0477392,     0.14386131,   0.733564,      0.64466465,
+    0.26687092,   0.42169324,   0.39847627,   0.5951189,    0.9344116,     0.14981407,   0.94095904,    0.3473678,
+    0.83092284,   0.108411595,  0.48258916,   0.3562543,    0.48699102,    0.42181966,   0.9002123,     0.7927088,
+    0.32004964,   0.6908224,    0.8910943,    0.78566706,   0.9744266,     0.012251603,  0.21200661,    0.7596848,
+    0.4342221,    0.9195925,    0.26717675,   0.63376397,   0.45760745,    0.2396946,    0.97431064,    0.06484076,
+    0.8924216,    0.39665636,   0.6949764,    0.5854926,    0.1963652,     0.5578238,    0.2590978,     0.799969,
+    0.2021356,    0.42646417,   0.48901513,   0.8064353,    0.7958741,     0.0903257,    0.9706242,     0.42458767,
+    0.56253713,   0.068702534,  0.75536686,   0.3569168,    0.25276697,    0.94789696,   0.670238,      0.2546193,
+    0.2096866,    0.6387915,    0.16089676,   0.01481907,   0.8826373,     0.3071951,    0.8897603,     0.59122825,
+    0.13410094,   0.4177484,    0.4638327,    0.09033466,   0.72684324,    0.3147197,    0.5963436,     0.76222587,
+    0.43172458,   0.091125324,  0.58353144,   0.5479625,    0.52323645,    0.40557137,   0.9638107,     0.3438964,
+    0.9489683,    0.8425891,    0.07122685,   0.38890493,   0.48432773,    0.61739385,   0.8120738,     0.9445246,
+    0.7264184,    0.4403571,    0.375806,     0.55757374,   0.396927,      0.24427874,   0.9173317,     0.8949405,
+    0.5367038,    0.8977869,    0.6723343,    0.3781257,    0.626493,      0.88028955,   0.6977444,     0.24781741,
+    0.4723589,    0.993141,     0.9251922,    0.16164163,   0.36436552,    0.12227554,   0.73138285,    0.80411524,
+    0.6749808,    0.8170004,    0.06585078,   0.040048227,  0.23596825,    0.5008554,    0.10690048,    0.51670706,
+    0.6056746,    0.5193081,    0.3639163,    0.28648618,   0.9389137,     0.03876988,   0.36529887,    0.18744585,
+    0.17379361,   0.68859094,   0.011258623,  0.62544954,   0.733237,      0.585685,     0.7174034,     0.06867873,
+    0.14484468,   0.82340944,   0.916546,     0.49118677,   0.6922017,     0.65043217,   0.58015907,    0.60414284,
+    0.70897424,   0.57169074,   0.8825929,    0.5799266,    0.17842796,    0.8772835,    0.65897226,    0.03584844,
+    0.7908864,    0.15562724,   0.7724511,    0.10718488,   0.5163733,     0.41125825,   0.3089037,     0.43358904,
+    0.62784207,   0.73774636,   0.98784804,   0.6757746,    0.111016914,   0.10593328,   0.07087821,    0.08929581,
+    0.09959695,   0.99717206,   0.89520353,   0.4125588,    0.5843094,     0.6157137,    0.82450545,    0.95524246,
+    0.939149,     0.7597735,    0.5775119,    0.36722296,   0.15617695,    0.78537226,   0.009017896,   0.29651013,
+    0.029618707,  0.97541016,   0.83456314,   0.5776098,    0.8132339,     0.6102185,    0.55230546,    0.73358643,
+    0.51450574,   0.48295695,   0.86334467,   0.9544553,    0.6625841,     0.90438455,   0.49312592,    0.603041,
+    0.50081253,   0.7932971,    0.4803297,    0.1812559,    0.9820799,     0.24641345,   0.45153904,    0.1751727,
+    0.3311218,    0.81720865,   0.16803588,   0.7565998,    0.8337463,     0.9416807,    0.2774121,     0.8424698,
+    0.7287285,    0.6913379,    0.64615583,   0.13560674,   0.27137014,    0.4932684,    0.27606192,    0.48937842,
+    0.4448666,    0.16161712,   0.89805305,   0.10135246,   0.75236905,    0.87005013,   0.29265827,    0.034764472,
+    0.26664755,   0.9744709,    0.86641043,   0.3628798,    0.30504256,    0.827762,     0.31443018,    0.7832053,
+    0.5238711,    0.65939045,   0.246488,     0.9960252,    0.44218266,    0.7957057,    0.8998401,     0.572825,
+    0.20554484,   0.020874852,  0.22572684,   0.97124624,   0.2582287,     0.35751918,   0.33167085,    0.007544129,
+    0.5172352,    0.99095124,   0.73638934,   0.8204628,    0.34836042,    0.3501866,    0.4228037,     0.46107167,
+    0.5245504,    0.1332714,    0.48995224,   0.8592754,    0.07527029,    0.91453224,   0.53742725,    0.90096647,
+    0.3769077,    0.8629506,    0.6117356,    0.61197966,   0.2467804,     0.2800367,    0.047195755,   0.6491609,
+    0.261777,     0.32522804,   0.8958076,    0.7314942,    0.6443233,     0.32141203,   0.7765358,     0.90912837,
+    0.6428001,    0.85886633,   0.8456446,    0.31409132,   0.09137268,    0.49396735,   0.43484485,    0.17368458,
+    0.23658675,   0.78541636,   0.47147486,   0.30891126,   0.30575344,    0.040564716,  0.49755472,    0.2910126,
+    0.48344758,   0.32476038,   0.59433854,   0.39527807,   0.7457836,     0.71969116,   0.76076376,    0.23719852,
+    0.9437555,    0.087228395,  0.55868584,   0.023132376,  0.45437896,    0.6913095,    0.8167484,     0.20313835,
+    0.35673562,   0.58082384,   0.2164753,    0.21640398,   0.06888765,    0.22333595,   0.8095938,     0.88294035,
+    0.42810574,   0.43805102,   0.37539294,   0.46136406,   0.80856186,    0.7382845,    0.34340748,    0.2212123,
+    0.8276733,    0.60479504,   0.24804658,   0.3195629,    0.7270735,     0.3812577,    0.16334477,    0.92310894,
+    0.09810257,   0.6084461,    0.37033582,   0.004144284,  0.9352815,     0.41171247,   0.71930563,    0.54527724,
+    0.968668,     0.2683365,    0.9521756,    0.7249296,    0.8240894,     0.28115076,   0.22212493,    0.26011166,
+    0.5151666,    0.71139824,   0.9671723,    0.3077326,    0.3442982,     0.29939967,   0.42863667,    0.20547101,
+    0.7438209,    0.33747354,   0.19545908,   0.8495839,    0.44326293,    0.49718547,   0.4760649,     0.97547793,
+    0.4174791,    0.29336637,   0.11830141,   0.46044156,   0.85300016,    0.8054495,    0.9476588,     0.016393282,
+    0.7187454,    0.8301157,    0.49269608,   0.5402253,    0.78610885,    0.6184779,    0.39712286,    0.54652256,
+    0.3826701,    0.98793495,   0.80439633,   0.015675247,  0.4140854,     0.85561216,   0.5788107,     0.7987029,
+    0.17980942,   0.16486481,   0.26032335,   0.597808,     0.2162534,     0.86972165,   0.102014296,   0.47148252,
+    0.7922716,    0.97669774,   0.3074505,    0.53072304,   0.16284934,    0.7616834,    0.40711153,    0.7097171,
+    0.7637394,    0.950779,     0.58898723,   0.5141825,    0.8067036,     0.88841134,   0.41936216,    0.12534304,
+    0.94035065,   0.6489365,    0.46691382,   0.45532802,   0.69278914,    0.46038964,   0.56139255,    0.56186694,
+    0.7145557,    0.31959853,   0.28063214,   0.6881353,    0.54512614,    0.3498508,    0.8001399,     0.8490237,
+    0.7281014,    0.021213572,  0.7479538,    0.8094111,    0.31102738,    0.8663998,    0.38367322,    0.6209867,
+    0.5808234,    0.09467922,   0.25193584,   0.46330634,   0.26662496,    0.06462818,   0.99199927,    0.29139808,
+    0.74550265,   0.13498032,   0.65745735,   0.5673169,    0.40280786,    0.64668626,   0.7786934,     0.33188194,
+    0.4153052,    0.7455836,    0.8161674,    0.8432508,    0.48105124,    0.7189762,    0.16459095,    0.41388863,
+    0.15063916,   0.73996353,   0.78608114,   0.78549004,   0.14045759,    0.609951,     0.8143157,     0.07395084,
+    0.26526332,   0.8459271,    0.8745046,    0.5981099,    0.20845382,    0.098086186,  0.29524195,    0.6499275,
+    0.32759923,   0.98923403,   0.9426327,    0.41014582,   0.6923934,     0.23282301,   0.44621587,    0.08141512,
+    0.24252021,   0.4160718,    0.3941059,    0.5654438,    0.050232418,   0.5404224,    0.13993548,    0.8618472,
+    0.9300883,    0.8380472,    0.31266716,   0.52666146,   0.27854705,    0.20650926,   0.1509405,     0.13555165,
+    0.32066464,   0.5835065,    0.30205357,   0.5568808,    0.7721817,     0.18058343,   0.123428136,   0.31721902,
+    0.45034164,   0.16623993,   0.5156516,    0.4918172,    0.7763435,     0.75444514,   0.7214952,     0.91781616,
+    0.29374766,   0.704666,     0.5429698,    0.7243858,    0.21584511,    0.24887188,   0.02371842,    0.7248409,
+    0.7059916,    0.012657363,  0.6680217,    0.37040663,   0.785419,      0.7685805,    0.37138042,    0.12108998,
+    0.83829355,   0.80708104,   0.08948117,   0.108886935,  0.93076944,    0.8893351,    0.30923343,    0.061936773,
+    0.29264367,   0.07688689,   0.11510216,   0.8839925,    0.02477082,    0.64811826,   0.08550372,    0.17564313,
+    0.11655201,   0.39485103,   0.23291379,   0.57388103,   0.6635394,     0.42655468,   0.9197065,     0.071792774,
+    0.5597881,    0.57721263,   0.8508891,    0.75952435,   0.5125618,     0.75302154,   0.53180003,    0.6817611,
+    0.79485947,   0.3945616,    0.6535236,    0.9692625,    0.66496396,    0.61260825,   0.98704666,    0.40441254,
+    0.3954326,    0.48103306,   0.43174213,   0.13895822,   0.13376972,    0.13972592,   0.7000701,     0.05787335,
+    0.92715365,   0.49237853,   0.2538546,    0.390568,     0.5356667,     0.7974994,    0.45755056,    0.41173887,
+    0.8873745,    0.017688395,  0.54909885,   0.3535568,    0.038445998,   0.54970914,   0.549375,      0.5396221,
+    0.54508686,   0.43334106,   0.089132994,  0.6302092,    0.99459463,    0.11624123,   0.5106792,     0.50394374,
+    0.40780434,   0.8285013,    0.17844845,   0.18250638,   0.99481255,    0.7807483,    0.93802303,    0.42006215,
+    0.87714255,   0.7930158,    0.8323707,    0.020183232,  0.4991669,     0.14123203,   0.1460944,     0.9973601,
+    0.93701106,   0.24178477,   0.081888,     0.64727557,   0.06350941,    0.6334899,    0.36596653,    0.84572345,
+    0.931658,     0.89212,      0.59387136,   0.70042866,   0.050592937,   0.06986087,   0.063278705,   0.81091243,
+    0.98169935,   0.74991083,   0.98276365,   0.7071655,    0.6190509,     0.27504414,   0.41692632,    0.106626175,
+    0.07966534,   0.12903668,   0.47641423,   0.24543023,   0.71733844,    0.5291918,    0.040455237,   0.40385485,
+    0.28724664,   0.091772884,  0.69319814,   0.7528099,    0.034353238,   0.8634036,    0.44043434,    0.77431446,
+    0.46253473,   0.332725,     0.25084835,   0.10269255,   0.18687698,    0.23759438,   0.36946923,    0.8072817,
+    0.72973704,   0.021458272,  0.038483858,  0.7492561,    0.1584684,     0.43892893,   0.37830916,    0.6619669,
+    0.8248584,    0.9752618,    0.5676102,    0.93447274,   0.15707563,    0.120536305,  0.12838502,    0.40246627,
+    0.8516648,    0.19001648,   0.41318202,   0.95882004,   0.3766627,     0.31046882,   0.7765592,     0.11829578,
+    0.3094765,    0.20844917,   0.24463072,   0.28632593,   0.024195805,   0.31423378,   0.9197492,     0.84207094,
+    0.75956744,   0.66913253,   0.5156932,    0.6958802,    0.4907079,     0.29119918,   0.24538647,    0.8483177,
+    0.7134637,    0.031231258,  0.92795146,   0.059091415,  0.29579335,    0.5059616,    0.6172388,     0.34199843,
+    0.20433997,   0.84838206,   0.2510278,    0.9968605,    0.82441235,    0.41064918,   0.43061897,    0.41926822,
+    0.2448991,    0.92018807,   0.43977955,   0.95001924,   0.19429821,    0.09198324,   0.63777107,    0.51062465,
+    0.055512622,  0.72553927,   0.17490527,   0.48794308,   0.60484314,    0.43250486,   0.91175836,    0.5604656,
+    0.94463,      0.56486434,   0.24535634,   0.34543145,   0.38251737,    0.7174677,    0.82250243,    0.8035149,
+    0.59121037,   0.9026323,    0.081985965,  0.17581372,   0.06320599,    0.9228887,    0.017658591,   0.3489183,
+    0.23851357,   0.096424945,  0.45098105,   0.57051986,   0.8514196,     0.29536724,   0.6540195,     0.62148046,
+    0.39346015,   0.41732678,   0.0035787956, 0.5702541,    0.33105636,    0.12929575,   0.7371553,     0.7718351,
+    0.93662375,   0.6905622,    0.052230474,  0.25954804,   0.16529284,    0.08518753,   0.03675085,    0.52743137,
+    0.097685665,  0.6362647,    0.35880888,   0.2916659,    0.009997273,   0.46195737,   0.4474187,     0.13262391,
+    0.7078807,    0.825987,     0.24942951,   0.5084182,    0.9815238,     0.3412385,    0.70904595,    0.6492628,
+    0.9108448,    0.62387586,   0.9519713,    0.9651906,    0.71388894,    0.25224832,   0.4724585,     0.4619146,
+    0.16547702,   0.31015086,   0.23919,      0.37264377,   0.8706582,     0.7581105,    0.18362544,    0.15332605,
+    0.05967409,   0.9235497,    0.47283417,   0.21515496,   0.93655837,    0.3623536,    0.6114832,     0.93150276,
+    0.9699081,    0.8709549,    0.8623734,    0.5050694,    0.87986624,    0.2287371,    0.7903113,     0.5953852,
+    0.98151624,   0.40296772,   0.34870324,   0.541417,     0.13321623,    0.07156025,   0.81354237,    0.84543735,
+    0.16380614,   0.8968943,    0.12618889,   0.6998464,    0.22276738,    0.07477489,   0.2619657,     0.94977015,
+    0.6423615,    0.09610346,   0.4487441,    0.05797409,   0.8684043,     0.49389097,   0.7127044,     0.54849124,
+    0.012392659,  0.020468513,  0.99528253,   0.8429341,    0.3898749,     0.96738917,   0.58204836,    0.9367399,
+    0.5198395,    0.6438048,    0.39112753,   0.46769053,   0.40940732,    0.64220846,   0.02010981,    0.9881138,
+    0.11000732,   0.6273968,    0.051348828,  0.039664086,  0.2361647,     0.91163677,   0.7087354,     0.8951332,
+    0.6089892,    0.91260326,   0.86270785,   0.7837628,    0.779993,      0.73233724,   0.72698087,    0.48762527,
+    0.69026333,   0.800212,     0.5290243,    0.11274772,   0.07627774,    0.9706083,    0.45556244,    0.19641699,
+    0.31484595,   0.18944897,   0.18000686,   0.5789626,    0.6836474,     0.79427516,   0.54036283,    0.00015307916,
+    0.07599365,   0.46063024,   0.94796675,   0.24100749,   0.44254217,    0.67304033,   0.31232652,    0.10075587,
+    0.31173313,   0.100149296,  0.23394488,   0.47727165,   0.10468131,    0.79828554,   0.1567469,     0.78750235,
+    0.9168239,    0.9035022,    0.7774272,    0.6091953,    0.11318414,    0.9073621,    0.9118361,     0.139399,
+    0.17183441,   0.85493183,   0.7248181,    0.04671574,   0.7316299,     0.1297728,    0.21148583,    0.814714,
+    0.37224042,   0.8625547,    0.70776916,   0.31936276,   0.7843705,     0.4859734,    0.04508312,    0.017223012,
+    0.4878855,    0.42826846,   0.8010146,    0.97612846,   0.73666346,    0.9782908,    0.09173568,    0.51656044,
+    0.032702066,  0.3925045,    0.6621387,    0.7801451,    0.01684795,    0.93116754,   0.886969,      0.16863157,
+    0.54879415,   0.80856776,   0.06917309,   0.5876103,    0.94822216,    0.26561078,   0.36912593,    0.18196031,
+    0.8886635,    0.41923082,   0.1050312,    0.24212655,   0.09051639,    0.8373841,    0.0031318855,  0.4308505,
+    0.8584191,    0.7602042,    0.121309794,  0.68491566,   0.10634747,    0.9357077,    0.4027356,     0.19354361,
+    0.7631962,    0.2082577,    0.014013676,  0.3391254,    0.46763408,    0.43134072,   0.7978661,     0.44107288,
+    0.9755858,    0.5391376,    0.7705686,    0.9758027,    0.4168003,     0.4574728,    0.06900084,    0.22227472,
+    0.059142508,  0.6190543,    0.08746498,   0.3174326,    0.8732596,     0.84960914,   0.42604402,    0.19531794,
+    0.38937265,   0.2312882,    0.921726,     0.25664374,   0.8098577,     0.20205325,   0.06228409,    0.61308646,
+    0.40583217,   0.8756295,    0.8244142,    0.7399645,    0.2515971,     0.030000538,  0.7143262,     0.45732272,
+    0.6213647,    0.6639583,    0.26654074,   0.5513788,    0.0668155,     0.02732918,   0.014050223,   0.40094635,
+    0.69120336,   0.8990351,    0.6257732,    0.48729318,   0.8482427,     0.08530297,   0.320284,      0.91358703,
+    0.7822137,    0.8186957,    0.94975275,   0.2363459,    0.50961477,    0.54122233,   0.63121516,    0.77353257,
+    0.4768535,    0.15748215,   0.56997055,   0.54117084,   0.6330586,     0.32903638,   0.9706776,     0.02914197,
+    0.90472806,   0.6301423,    0.69606787,   0.20930128,   0.5830684,     0.8746652,    0.12850243,    0.36204344,
+    0.21723796,   0.5207796,    0.5654404,    0.9108227,    0.57628006,    0.5749909,    0.7648438,     0.3205292,
+    0.5553455,    0.91082716,   0.9577508,    0.43290135,   0.08024777,    0.47798032,   0.94770795,    0.0801424,
+    0.03274318,   0.49300817,   0.07452531,   0.90933335,   0.45735866,    0.4728794,    0.7678877,     0.362167,
+    0.9283575,    0.5966312,    0.5825651,    0.21810043,   0.3892351,     0.11098274,   0.33051863,    0.9075484,
+    0.6901933,    0.5877093,    0.019107932,  0.9888351,    0.9757819,     0.72039247,   0.19725248,    0.90186256,
+    0.39263836,   0.24944134,   0.98582536,   0.72223145,   0.3712856,     0.5377763,    0.9488942,     0.42674774,
+    0.68243426,   0.6159255,    0.1765581,    0.09006023,   0.8001399,     0.21916907,   0.9046848,     0.74435854,
+    0.7528919,    0.20327342,   0.9824652,    0.9796489,    0.9924258,     0.5467434,    0.9312941,     0.44436273,
+    0.58030856,   0.05020233,   0.742708,     0.49253845,   0.4588724,     0.95887285,   0.10436046,    0.31235072,
+    0.29575568,   0.17266272,   0.516695,     0.20791732,   0.48705408,    0.045656245,  0.9908814,     0.3905812,
+    0.647737,     0.15581739,   0.5356661,    0.77330965,   0.93442464,    0.2404584,    0.10740854,    0.47102425,
+    0.6830245,    0.27474937,   0.2359432,    0.7725085,    0.73792726,    0.21760361,   0.9094368,     0.845895,
+    0.31814724,   0.5414626,    0.14192294,   0.32108325,   0.7950682,     0.45635575,   0.96787536,    0.72356147,
+    0.511565,     0.8642074,    0.79430455,   0.62747717,   0.70247406,    0.6967675,    0.2573045,     0.7072357,
+    0.212392,     0.591884,     0.33191186,   0.8366084,    0.01107724,    0.15798447,   0.5099381,     0.33985013,
+    0.9427938,    0.27168378,   0.8095139,    0.18412302,   0.72292966,    0.33185193,   0.5744235,     0.078152075,
+    0.2632259,    0.67080003,   0.8897701,    0.94559145,   0.9037333,     0.66979814,   0.595513,      0.19138126,
+    0.18794204,   0.8121047,    0.26174462,   0.07021725,   0.44615385,    0.47993135,   0.76855016,    0.986257,
+    0.017444894,  0.5287075,    0.5601165,    0.1460432,    0.88569176,    0.07282839,   0.8348177,     0.16016278,
+    0.031524524,  0.80207276,   0.37828946,   0.52338445,   0.6468418,     0.7837523,    0.00063179433, 0.17971309,
+    0.2897839,    0.7161524,    0.3642513,    0.031674027,  0.8069974,     0.31171304,   0.8035024,     0.54259384,
+    0.9963711,    0.14053062,   0.6486664,    0.19897254,   0.8962398,     0.43972084,   0.8936963,     0.46286246,
+    0.5031336,    0.8232569,    0.16667813,   0.19422211,   0.7717354,     0.42838028,   0.19246033,    0.19039753,
+    0.8359823,    0.7296073,    0.9140669,    0.10166052,   0.29150867,    0.07212853,   0.54453945,    0.40418974,
+    0.8114729,    0.08203155,   0.78043336,   0.7300014,    0.11568007,    0.73687613,   0.1792596,     0.70573187,
+    0.7252052,    0.017522655,  0.14967212,   0.7451611,    0.42416203,    0.6358452,    0.26392296,    0.59180367,
+    0.9083765,    0.915427,     0.020250821,  0.8235849,    0.6170742,     0.80640966,   0.40797767,    0.86140364,
+    0.52369213,   0.17385374,   0.19569172,   0.07739012,   0.3976461,     0.70184183,   0.2510852,     0.92424256,
+    0.59599113,   0.24447663,   0.38749963,   0.81420827,   0.6592875,     0.16369487,   0.34718236,    0.76625746,
+    0.6439973,    0.46094626,   0.46901694,   0.75421274,   0.27870816,    0.44729918,   0.76623553,    0.20013711,
+    0.46568435,   0.32226324,   0.193284,     0.37608168,   0.051877704,   0.72095454,   0.7871155,     0.0050632227,
+    0.6740539,    0.9190297,    0.20630927,   0.94182634,   0.5411844,     0.10186948,   0.30808574,    0.023363324,
+    0.7664375,    0.22542956,   0.14916998,   0.17968538,   0.24834555,    0.44971466,   0.93251616,    0.74468166,
+    0.56824464,   0.25399336,   0.17958756,   0.15612793,   0.33739275,    0.6537649,    0.5826955,     0.07639295,
+    0.40761822,   0.9955546,    0.6117058,    0.07538286,   0.50855786,    0.8750035,    0.8723649,     0.8750366,
+    0.4573611,    0.38243642,   0.1401544,    0.7402578,    0.9573856,     0.40535605,   0.22507304,    0.54212785,
+    0.1528605,    0.44565362,   0.98777527,   0.05327858,   0.2981292,     0.5865501,    0.9517916,     0.015969688,
+    0.38974705,   0.44860238,   0.807837,     0.79788435,   0.541367,      0.6309876,    0.6676705,     0.02028897,
+    0.33633423,   0.12991633,   0.5342081,    0.5456298,    0.4901637,     0.2327029,    0.5148055,     0.89143395,
+    0.35306472,   0.27413338,   0.7223243,    0.86590916,   0.30956024,    0.1922584,    0.787296,      0.1628886,
+    0.02892033,   0.6374597,    0.0032674163, 0.89173913,   0.66598964,    0.5294169,    0.77826375,    0.8210681,
+    0.043763056,  0.5957361,    0.6856358,    0.05995547,   0.06716649,    0.07448051,   0.3336696,     0.8263735,
+    0.7147659,    0.11986544,   0.40392354,   0.8274693,    0.87114793,    0.67944324,   0.051964145,   0.9201576,
+    0.9308481,    0.096341334,  0.70021385,   0.02399584,   0.8642258,     0.08588241,   0.70640945,    0.19748867,
+    0.6613063,    0.6449484,    0.768964,     0.9039073,    0.6277202,     0.77593136,   0.35429934,    0.8069173,
+    0.3516526,    0.71314,      0.50186676,   0.8944276,    0.5470671,     0.45485002,   0.82426745,    0.2785842,
+    0.9404638,    0.8959508,    0.15114321,   0.18969482,   0.78833485,    0.9598267,    0.29174066,    0.3494771,
+    0.5854956,    0.0831098,    0.960891,     0.56964827,   0.829203,      0.7542679,    0.9568423,     0.9578806,
+    0.88932663,   0.48814714,   0.39864913,   0.42221805,   0.3055165,     0.42976233,   0.19865331,    0.93883455,
+    0.7655661,    0.5970062,    0.4758167,    0.15800795,   0.17757647,    0.15753652,   0.3730905,     0.47599813,
+    0.27207386,   0.42162967,   0.08353208,   0.96827507,   0.9347392,     0.51671463,   0.40915382,    0.7014796,
+    0.35320777,   0.4194869,    0.3184117,    0.5446104,    0.81504035,    0.78465104,   0.9777143,     0.5973847,
+    0.7562977,    0.54398614,   0.0051009622, 0.05891997,   0.05620089,    0.4020494,    0.9730677,     0.5107014,
+    0.69729745,   0.21230865,   0.4241287,    0.19132863,   0.48401004,    0.1337327,    0.17190064,    0.42795905,
+    0.7100193,    0.48489287,   0.29757443,   0.40757337,   0.67073584,    0.98856723,   0.023141444,   0.37261203,
+    0.07899332,   0.6971695,    0.06901029,   0.8860296,    0.11135061,    0.65404296,   0.12379419,    0.98091507,
+    0.6192919,    0.878432,     0.40171024,   0.63359034,   0.15243557,    0.31417054,   0.41979724,    0.87002444,
+    0.44856197,   0.5728306,    0.2709776,    0.7224305,    0.09258589,    0.21782517,   0.21746957,    0.21947508,
+    0.24758625,   0.8904527,    0.8345911,    0.3301475,    0.48707664,    0.57014096,   0.92664886,    0.7677305,
+    0.5208447,    0.6324889,    0.97992665,   0.35903138,   0.3330391,     0.0870381,    0.39935082,    0.043254532,
+    0.08851445,   0.44321367,   0.57203674,   0.60557806,   0.73202246,    0.5383103,    0.27552348,    0.39584875,
+    0.06509563,   0.42754996,   0.95901144,   0.09790518,   0.7175897,     0.3007109,    0.28002614,    0.86116815,
+    0.47969994,   0.8495352,    0.63844335,   0.22089794,   0.8194518,     0.7936467,    0.4938384,     0.049150985,
+    0.9517831,    0.6339798,    0.11274567,   0.51994663,   0.3342439,     0.060765848,  0.53698534,    0.36152387,
+    0.17347981,   0.22772305,   0.6339161,    0.6493722,    0.64578843,    0.6118915,    0.48745263,    0.70927596,
+    0.6149292,    0.43874234,   0.26505187,   0.05952667,   0.6111295,     0.8287437,    0.050140806,   0.22013378,
+    0.35246277,   0.1187585,    0.87933147,   0.4835039,    0.44859475,    0.1784529,    0.2238027,     0.29486778,
+    0.9493753,    0.52288574,   0.65379494,   0.09804267,   0.42556462,    0.75557685,   0.061604857,   0.0043297815,
+    0.8905646,    0.59748757,   0.92442536,   0.4898666,    0.6667948,     0.6306539,    0.21537969,    0.8678084,
+    0.3620826,    0.9291674,    0.6059688,    0.3807095,    0.5285948,     0.43431175,   0.43802148,    0.123039424,
+    0.583839,     0.8926119,    0.16748385,   0.2154854,    0.18143441,    0.05348144,   0.9129291,     0.99502695,
+    0.003920352,  0.33904833,   0.69999695,   0.12290272,   0.9580966,     0.38940993,   0.2837113,     0.85935235,
+    0.37713748,   0.2607221,    0.16896206,   0.013641968,  0.90431833,    0.5602742,    0.553339,      0.72180885,
+    0.9033788,    0.011523027,  0.1214213,    0.51942736,   0.57248414,    0.8430932,    0.76627296,    0.5150635,
+    0.084864266,  0.5307555,    0.51420367,   0.5329527,    0.588093,      0.84611946,   0.82289535,    0.83708316,
+    0.68455845,   0.9293985,    0.48594627,   0.32774645,   0.930657,      0.092476964,  0.9097118,     0.97267264,
+    0.6454561,    0.74661636,   0.003572011,  0.2678727,    0.2653497,     0.4243795,    0.2187211,     0.023564778,
+    0.3392729,    0.44567502,   0.31210658,   0.16991138,   0.9320601,     0.39350176,   0.42254278,    0.16082714,
+    0.57277536,   0.18493341,   0.03803846,   0.4273411,    0.87520623,    0.7507586,    0.27125937,    0.531018,
+    0.43782672,   0.33187887,   0.32908353,   0.97491986,   0.07432794,    0.22559255,   0.7911518,     0.8109018,
+    0.10181122,   0.14874865,   0.8739713,    0.8258678,    0.83952117,    0.49840027,   0.24971384,    0.6604848,
+    0.3120344,    0.4906389,    0.19367984,   0.14241797,   0.5340129,     0.65298396,   0.90502304,    0.2910567,
+    0.50685567,   0.3251191,    0.7549711,    0.7457236,    0.054438505,   0.4823707,    0.09746641,    0.8946975,
+    0.47535703,   0.472554,     0.83004594,   0.9334708,    0.09529597,    0.24380124,   0.9492368,     0.11368034,
+    0.6545232,    0.5012047,    0.06810016,   0.7833115,    0.5195305,     0.59667504,   0.32130596,    0.07437508,
+    0.9352196,    0.3775537,    0.11530671,   0.38456735,   0.5570788,     0.12884142,   0.9970051,     0.7848427,
+    0.42685586,   0.03802683,   0.4680642,    0.7492088,    0.47062147,    0.045428254,  0.75646335,    0.6194405,
+    0.05128224,   0.9792738,    0.35051075,   0.3669672,    0.66835433,    0.31624305,   0.56518877,    0.06823316,
+    0.5414021,    0.0799995,    0.4878948,    0.032808155,  0.5848838,     0.12171154,   0.7715262,     0.9101807,
+    0.0038131434, 0.680596,     0.810504,     0.67688483,   0.36706397,    0.7128991,    0.3376187,     0.3465156,
+    0.47554886,   0.04520323,   0.5066149,    0.05726915,   0.77573705,    0.200028,     0.6430589,     0.6090949,
+    0.7447414,    0.44865963,   0.73202926,   0.5402566,    0.24616429,    0.9543388,    0.40602076,    0.61897653,
+    0.8123649,    0.047073558,  0.8431653,    0.47707924,   0.6409466,     0.964197,     0.1999589,     0.3051443,
+    0.2665006,    0.5578835,    0.7453957,    0.7900255,    0.23492423,    0.07957853,   0.25237653,    0.33838317,
+    0.6416551,    0.0039951354, 0.89141834,   0.62315106,   0.80962807,    0.50791967,   0.29249611,    0.34137407,
+    0.4369406,    0.8787999,    0.28806677,   0.1362242,    0.3896823,     0.23126958,   0.66401637,    0.049474377,
+    0.27457523,   0.19152752,   0.8645199,    0.31999043,   0.8697338,     0.8605395,    0.70556897,    0.5113519,
+    0.84524435,   0.20147063,   0.79076856,   0.21785353,   0.4546323,     0.8530334,    0.3741707,     0.66516286,
+    0.1962831,    0.3936461,    0.89860153,   0.24216916,   0.062920436,   0.7828697,    0.8093484,     0.30444527,
+    0.75457746,   0.5017912,    0.040138636,  0.7621467,    0.6761302,     0.06373471,   0.915462,      0.035231,
+    0.89386714,   0.6959213,    0.51545024,   0.04339671,   0.21505861,    0.9323861,    0.46864936,    0.7811156,
+    0.29842615,   0.38006642,   0.7779068,    0.60815746,   0.7171511,     0.07464257,   0.88674176,    0.5839072,
+    0.5046292,    0.6229039,    0.9399411,    0.9960362,    0.33266804,    0.42184722,   0.9865539,     0.49170554,
+    0.38217908,   0.5600747,    0.565413,     0.36794263,   0.82040083,    0.94342226,   0.8352217,     0.78150964,
+    0.2860086,    0.75553757,   0.32398638,   0.758711,     0.3375832,     0.33077398,   0.45010427,    0.26389697,
+    0.92499673,   0.11748593,   0.943743,     0.682854,     0.004962936,   0.20119096,   0.58729416,    0.67993486,
+    0.6150494,    0.45623145,   0.25751752,   0.053226303,  0.12379362,    0.91942585,   0.702563,      0.47201994,
+    0.7093674,    0.023744669,  0.66121763,   0.65498394,   0.36697313,    0.10070673,   0.96071476,    0.3550039,
+    0.54484475,   0.99639714,   0.32214886,   0.96161354,   0.7506562,     0.12803078,   0.24632397,    0.17385522,
+    0.17279965,   0.6760441,    0.071039446,  0.2151821,    0.4781042,     0.30369994,   0.48674262,    0.18098812,
+    0.97278047,   0.8854781,    0.7528932,    0.3641694,    0.68590474,    0.7819954,    0.657716,      0.36658275,
+    0.05297459,   0.85196644,   0.049343612,  0.31383854,   0.6695563,     0.7951203,    0.89692384,    0.82429004,
+    0.15677115,   0.5887391,    0.13800927,   0.0085657975, 0.8790421,     0.6256806,    0.9292787,     0.48701864,
+    0.20990747,   0.083662316,  0.88042665,   0.4477495,    0.8483864,     0.48738086,   0.99391574,    0.40566745,
+    0.537002,     0.4802295,    0.6822035,    0.48149505,   0.34781352,    0.5965454,    0.66909915,    0.76284933,
+    0.33868113,   0.9555661,    0.90863895,   0.89868975,   0.07868716,    0.93248546,   0.50429887,    0.37767935,
+    0.77912027,   0.24674945,   0.05841095,   0.8893651,    0.16569066,    0.4781768,    0.301946,      0.34709984,
+    0.9561994,    0.26587456,   0.15426192,   0.6022424,    0.9015687,     0.20996648,   0.51819634,    0.5655937,
+    0.8580507,    0.64367616,   0.7768365,    0.18932684,   0.11291685,    0.4154288,    0.4764765,     0.5602257,
+    0.91964,      0.37515992,   0.6698847,    0.923476,     0.7170417,     0.030588947,  0.40833148,    0.27742204,
+    0.57936347,   0.5027473,    0.6686292,    0.60163695,   0.42896992,    0.10455062,   0.2399768,     0.058825243,
+    0.17828348,   0.3351036,    0.5252956,    0.08193896,   0.44228348,    0.06685673,   0.8612806,     0.12871465,
+    0.43736976,   0.34304523,   0.040639006,  0.435011,     0.15564895,    0.314972,     0.2647625,     0.36369145,
+    0.770273,     0.4981852,    0.96972513,   0.79053074,   0.80829215,    0.37847006,   0.63005817,    0.9256105,
+    0.85754305,   0.8768399,    0.022878975,  0.3988214,    0.54133725,    0.9165594,    0.1366238,     0.7535001,
+    0.40369937,   0.71801126,   0.011043364,  0.77781326,   0.89013314,    0.39453754,   0.11794228,    0.85278326,
+    0.5138793,    0.54117,      0.4861062,    0.37399647,   0.98994994,    0.9733205,    0.12177309,    0.26439142,
+    0.23798482,   0.30493778,   0.83136404,   0.9307847,    0.13482551,    0.44944605,   0.25053307,    0.7998134,
+    0.70504546,   0.5996852,    0.22439589,   0.5654436,    0.043977752,   0.4624592,    0.5873774,     0.52081037,
+    0.20642142,   0.2871389,    0.031311635,  0.43763772,   0.30392867,    0.48694924,   0.4735583,     0.37573543,
+    0.3802429,    0.11694187,   0.27665144,   0.26712215,   0.89236385,    0.25606167,   0.93566054,    0.8842226,
+    0.7550668,    0.7584876,    0.16083659,   0.23639946,   0.08519537,    0.20583908,   0.6186746,     0.9542533,
+    0.46747816,   0.21122995,   0.07276781,   0.29044798,   0.17014165,    0.5524987,    0.8088055,     0.0514201,
+    0.9537926,    0.9652958,    0.16757506,   0.70281106,   0.94200885,    0.6841354,    0.96046275,    0.7510356,
+    0.8313795,    0.45562857,   0.5505418,    0.017883644,  0.17279461,    0.9834109,    0.90744954,    0.44898376,
+    0.66402465,   0.34017327,   0.81037676,   0.28549019,   0.3016226,     0.35097796,   0.43561503,    0.00058234343,
+    0.6684643,    0.07705832,   0.97015953,   0.092698716,  0.41418144,    0.18311031,   0.20559378,    0.82774425,
+    0.30813637,   0.22523133,   0.31332958,   0.92706805,   0.08848662,    0.23284948,   0.9422138,     0.07093142,
+    0.7980248,    0.409801,     0.40501997,   0.6295668,    0.6552973,     0.600791,     0.7814587,     0.48406723,
+    0.3037804,    0.62378407,   0.62642336,   0.82996833,   0.7421219,     0.5233153,    0.74979746,    0.6028146,
+    0.5296808,    0.16699271,   0.03434674,   0.86495054,   0.71397585,    0.86776406,   0.33685416,    0.6482692,
+    0.2500348,    0.7227976,    0.70974725,   0.9475633,    0.6700813,     0.9803815,    0.36049715,    0.43117517,
+    0.39795953,   0.7394454,    0.4874654,    0.8918216,    0.94595796,    0.8060482,    0.3452851,     0.06767335,
+    0.29559964,   0.4860923,    0.7889183,    0.7903974,    0.556687,      0.3756254,    0.08562232,    0.7848211,
+    0.47543386,   0.71051496,   0.3973873,    0.9214939,    0.19850273,    0.07726323,   0.3569556,     0.9302608,
+    0.072946854,  0.7567508,    0.37953198,   0.9324997,    0.89104366,    0.8338954,    0.8139859,     0.32339892,
+    0.2632869,    0.19524816,   0.43200883,   0.002676534,  0.035849903,   0.8579759,    0.65685666,    0.7236325,
+    0.82170767,   0.9666734,    0.5693509,    0.22788355,   0.07884572,    0.54645675,   0.09158218,    0.8744094,
+    0.63717526,   0.9249262,    0.47212943,   0.9595664,    0.58299416,    0.43900326,   0.23267244,    0.3206963,
+    0.3824898,    0.55720466,   0.8188748,    0.18920717,   0.42651626,    0.41278538,   0.17662966,    0.46170422,
+    0.6721064,    0.4655194,    0.5271105,    0.3614388,    0.94361657,    0.08294579,   0.74897116,    0.617458,
+    0.053658314,  0.67375475,   0.09978627,   0.23182935,   0.50791234,    0.12907204,   0.85141504,    0.5264901,
+    0.66516864,   0.50512254,   0.29532441,   0.9661175,    0.36176598,    0.8544195,    0.7404047,     0.82428366,
+    0.96257573,   0.11131253,   0.62018675,   0.47864527,   0.039101128,   0.46764946,   0.29711628,    0.40892226,
+    0.7900437,    0.10764668,   0.55577713,   0.6133263,    0.019346252,   0.73014337,   0.9307928,     0.5542295,
+    0.17595504,   0.8546715,    0.90590805,   0.9092394,    0.33921698,    0.0008430821, 0.81278396,    0.25341776,
+    0.7057896,    0.29238465,   0.52403855,   0.9213937,    0.11746097,    0.21051219,   0.09993823,    0.8176869,
+    0.72511464,   0.70282686,   0.3988631,    0.83230406,   0.46275905,    0.2703259,    0.57835686,    0.58600885,
+    0.3766385,    0.690864,     0.44178563,   0.40026566,   0.5732949,     0.23808873,   0.50714386,    0.9350253,
+    0.57432973,   0.74109495,   0.79016244,   0.5070945,    0.9485114,     0.8311653,    0.48506665,    0.9617326,
+    0.29852858,   0.366769,     0.77285564,   0.74671644,   0.94361097,    0.3757226,    0.29146126,    0.57953155,
+    0.007708449,  0.7380902,    0.88821167,   0.31651938,   0.33128026,    0.09848877,   0.09147043,    0.90562916,
+    0.27631462,   0.31989923,   0.53260094,   0.648353,     0.5590575,     0.4125183,    0.68012285,    0.4677009,
+    0.7852408,    0.5890133,    0.34706393,   0.37636602,   0.42034975,    0.5928437,    0.86917543,    0.89394933,
+    0.21776019,   0.43713045,   0.5337755,    0.09599007,   0.49747026,    0.83164036,   0.6423979,     0.00091591524,
+    0.39940274,   0.8622541,    0.3925572,    0.83520466,   0.3498771,     0.19062445,   0.603745,      0.475841,
+    0.6496245,    0.8845333,    0.2307799,    0.6286122,    0.29856437,    0.83671373,   0.40267518,    0.8860103,
+    0.6866461,    0.30515477,   0.9614757,    0.3545977,    0.028658632,   0.9150952,    0.15918177,    0.41486475,
+    0.8689148,    0.9942623,    0.0987592,    0.8941498,    0.5647133,     0.99548036,   0.40815887,    0.44467425,
+    0.6775013,    0.531685,     0.24895021,   0.69680333,   0.019961093,   0.8449182,    0.1178238,     0.59461635,
+    0.98526824,   0.871223,     0.7267415,    0.53581643,   0.3620638,     0.24056326,   0.59538496,    0.38104647,
+    0.034455262,  0.6477652,    0.40934396,   0.19231549,   0.8701647,     0.28780022,   0.97225726,    0.48430753,
+    0.7030723,    0.9776925,    0.9662899,    0.3556148,    0.09186526,    0.7095952,    0.9111277,     0.65414417,
+    0.47637445,   0.78610563,   0.9511109,    0.7668794,    0.5877635,     0.7058718,    0.8660492,     0.8417279,
+    0.18733096,   0.3668593,    0.36932942,   0.15743567,   0.18835372,    0.62336534,   0.05280094,    0.6283515,
+    0.3988773,    0.7177127,    0.85969454,   0.9169481,    0.5861364,     0.21584338,   0.5745095,     0.3897011,
+    0.55942774,   0.7646427,    0.993731,     0.042268623,  0.8786283,     0.762209,     0.5027511,     0.27567303,
+    0.9600953,    0.072597355,  0.059442017,  0.57595813,   0.2894524,     0.82850564,   0.793283,      0.32858342,
+    0.78171605,   0.56761605,   0.0049845274, 0.50330544,   0.9184708,     0.8148216,    0.29595378,    0.07970701,
+    0.92489153,   0.33793837,   0.9567375,    0.37415254,   0.84990066,    0.9941796,    0.06800775,    0.26053104,
+    0.21159613,   0.5614098,    0.20745164,   0.8231208,    0.7121408,     0.82378054,   0.9630996,     0.42512196,
+    0.8641082,    0.09365638,   0.19734041,   0.11575636,   0.5639233,     0.4768428,    0.33889914,    0.5703717,
+    0.9244297,    0.5311111,    0.13523202,   0.01852037,   0.21085885,    0.071204096,  0.4712303,     0.74460614,
+    0.4686889,    0.914024,     0.117377095,  0.54068995,   0.80547154,    0.12859856,   0.4257724,     0.9659156,
+    0.0045896024, 0.798911,     0.36436203,   0.7280426,    0.621054,      0.9701622,    0.6164426,     0.9579355,
+    0.6045164,    0.5798626,    0.63919723,   0.82481444,   0.61748123,    0.18019743,   0.5157837,     0.44804874,
+    0.99903923,   0.3863658,    0.44972283,   0.31878954,   0.85894763,    0.049487386,  0.04967219,    0.14039204,
+    0.09017946,   0.4628455,    0.3544319,    0.7981168,    0.70640343,    0.42240968,   0.6196504,     0.73550963,
+    0.667884,     0.23142478,   0.11116676,   0.7650123,    0.112480775,   0.6108565,    0.9493177,     0.9542675,
+    0.9146685,    0.17729652,   0.41400397,   0.6309963,    0.43200687,    0.6464159,    0.12712492,    0.2884915,
+    0.3982403,    0.66932833,   0.54165065,   0.4191057,    0.67887574,    0.10698286,   0.10696802,    0.9551022,
+    0.7492388,    0.22396998,   0.63786316,   0.15820846,   0.6157303,     0.8183258,    0.25153205,    0.18210672,
+    0.9602121,    0.9036876,    0.15693043,   0.38605642,   0.06903067,    0.7507714,    0.33556795,    0.38818276,
+    0.43704808,   0.4954553,    0.40412104,   0.6816511,    0.63548344,    0.4186759,    0.70838517,    0.44376358,
+    0.3357206,    0.06594042,   0.39987648,   0.037075095,  0.88075906,    0.20054473,   0.05663389,    0.5609011,
+    0.124456756,  0.15606454,   0.015773552,  0.88851076,   0.9729933,     0.79110926,   0.33853722,    0.09634267,
+    0.9257645,    0.23189723,   0.6707842,    0.52831924,   0.48948547,    0.7410685,    0.2194608,     0.6474689,
+    0.3337604,    0.15346791,   0.98205763,   0.18342042,   0.70286185,    0.42531693,   0.3196188,     0.3305629,
+    0.5155848,    0.19409959,   0.82248783,   0.5497899,    0.41844934,    0.21445695,   0.3013477,     0.7596674,
+    0.8470537,    0.5960293,    0.26159966,   0.91296613,   0.7349978,     0.44705716,   0.41518942,    0.6459388,
+    0.1569181,    0.30777836,   0.7558866,    0.4035862,    0.7478917,     0.18006596,   0.9542781,     0.5946521,
+    0.8464796,    0.75240755,   0.7033147,    0.7272911,    0.2184871,     0.87321347,   0.8580393,     0.69913983,
+    0.83644575,   0.68521065,   0.372926,     0.77889377,   0.96862143,    0.7887473,    0.67789334,    0.7113075,
+    0.93054956,   0.9111168,    0.6812655,    0.89345616,   0.47946882,    0.30649468,   0.9124711,     0.88670325,
+    0.7382785,    0.33611885,   0.026502334,  0.39508346,   0.6694303,     0.9160326,    0.5826711,     0.33551884,
+    0.23982148,   0.22783574,   0.70331025,   0.6660418,    0.51114225,    0.57405657,   0.5411803,     0.9738403,
+    0.73799,      0.5624598,    0.07652036,   0.04978715,   0.07413118,    0.6362957,    0.6773174,     0.36817077,
+    0.629885,     0.044579085,  0.47303665,   0.836775,     0.49880046,    0.06082195,   0.115183294,   0.53998494,
+    0.83993644,   0.81661147,   0.98901266,   0.88236827,   0.84671116,    0.46295583,   0.029709496,   0.9204132,
+    0.10253954,   0.03740714,   0.5390723,    0.74078566,   0.08543706,    0.011851499,  0.20016527,    0.356493,
+    0.36993647,   0.70742524,   0.15546617,   0.917009,     0.22997431,    0.86268395,   0.81257206,    0.1019828,
+    0.65880144,   0.6583316,    0.7651984,    0.6248512,    0.44299594,    0.74589616,   0.8367184,     0.17899951,
+    0.11265245,   0.16332534,   0.8261054,    0.6945308,    0.5850439,     0.65881205,   0.12712914,    0.27503416,
+    0.53275037,   0.15610719,   0.9472476,    0.036724042,  0.0972234,     0.9365317,    0.2827337,     0.6180335,
+    0.8444138,    0.116543666,  0.46683854,   0.7913752,    0.9053558,     0.19817433,   0.3100106,     0.9772525,
+    0.0040394296, 0.8870298,    0.22356682,   0.18837956,   0.6977574,     0.40485826,   0.47741726,    0.35664338,
+    0.20068875,   0.36007276,   0.62813324,   0.92211175,   0.1857461,     0.5056345,    0.7714491,     0.7111244,
+    0.5802961,    0.880432,     0.3842586,    0.07386713,   0.9154364,     0.775848,     0.0047594067,  0.7222697,
+    0.37559786,   0.14716488,   0.7804374,    0.32645226,   0.27905762,    0.04534316,   0.27364373,    0.9144781,
+    0.8533147,    0.84885293,   0.6904914,    0.6980141,    0.43524522,    0.93874955,   0.57727677,    0.1278921,
+    0.67868996,   0.5906042,    0.8360353,    0.73715067,   0.30839851,    0.360622,     0.43228745,    0.33877933,
+    0.3450946,    0.7557141,    0.21107915,   0.024923787,  0.8139157,     0.23614348,   0.061816096,   0.22819144,
+    0.88227046,   0.5012971,    0.8127817,    0.55059254,   0.6244208,     0.15096499,   0.07758577,    0.15534559,
+    0.08642902,   0.7136551,    0.068797,     0.33689317,   0.8151431,     0.073435,     0.27587917,    0.6415465,
+    0.30315524,   0.25636652,   0.3951772,    0.32483214,   0.9398127,     0.26760876,   0.41387123,    0.014975904,
+    0.7148774,    0.4416581,    0.9813577,    0.5233435,    0.83426404,    0.24871995,   0.100562416,   0.6171712,
+    0.78703684,   0.4622999,    0.8157436,    0.93394816,   0.1259679,     0.026684225,  0.50347126,    0.527725,
+    0.5130184,    0.6806897,    0.6507216,    0.59474343,   0.29182497,    0.09539426,   0.52363616,    0.27165958,
+    0.47983494,   0.56953263,   0.72176856,   0.5575492,    0.8409663,     0.73698395,   0.28837872,    0.6146617,
+    0.08742587,   0.7978058,    0.8357151,    0.18276273,   0.16960731,    0.55424225,   0.32108158,    0.83770907,
+    0.61309266,   0.45162576,   0.54985636,   0.35284323,   0.25769138,    0.34193105,   0.5155786,     0.27647102,
+    0.75289524,   0.86745226,   0.8118137,    0.259123,     0.61688715,    0.8191278,    0.7231509,     0.6194832,
+    0.9180219,    0.7096981,    0.043508567,  0.26473138,   0.5269514,     0.5430132,    0.77620494,    0.05005288,
+    0.1739212,    0.20108196,   0.8465223,    0.32816213,   0.19096912,    0.32070854,   0.35811764,    0.9587762,
+    0.3596081,    0.81301254,   0.9816507,    0.84019923,   0.54553795,    0.17079297,   0.013968218,   0.13790388,
+    0.053954035,  0.44529754,   0.80465394,   0.9735141,    0.92517024,    0.029255724,  0.99777454,    0.26829806,
+    0.07465485,   0.21623193,   0.2647408,    0.45990923,   0.5107337,     0.056350194,  0.31075767,    0.07007945,
+    0.6754208,    0.49980345,   0.17892201,   0.056609415,  0.4954088,     0.18741646,   0.08550189,    0.4321867,
+    0.5093346,    0.85303754,   0.89951485,   0.8038746,    0.8374771,     0.88295174,   0.073945254,   0.7472289,
+    0.69572985,   0.90560466,   0.21077734,   0.08165387,   0.7383593,     0.80269086,   0.12488264,    0.14466548,
+    0.20330743,   0.5782242,    0.2535073,    0.9747372,    0.055967752,   0.8982084,    0.44804245,    0.30325794,
+    0.50225484,   0.91157126,   0.16477837,   0.045734458,  0.99187094,    0.9573588,    0.6424951,     0.8665376,
+    0.35979563,   0.37246728,   0.46417946,   0.0721327,    0.12974085,    0.19389993,   0.430821,      0.19170313,
+    0.14228667,   0.51751184,   0.76417935,   0.605129,     0.8455728,     0.2291038,    0.3317202,     0.87272996,
+    0.37492082,   0.034256544,  0.853302,     0.9171846,    0.9339092,     0.11076469,   0.37621894,    0.6111262,
+    0.40499508,   0.5962569,    0.30161974,   0.92590576,   0.7181733,     0.028210793,  0.755358,      0.7383711,
+    0.2631096,    0.34423977,   0.7218582,    0.365892,     0.3385114,     0.05274994,   0.014924624,   0.0094075035,
+    0.1474032,    0.061804168,  0.8324505,    0.5384559,    0.13402902,    0.84291345,   0.45768508,    0.27315107,
+    0.5798511,    0.29204842,   0.6708136,    0.9576144,    0.10405682,    0.7253105,    0.9326284,     0.24903095,
+    0.99624836,   0.8530533,    0.6671376,    0.5334839,    0.8922802,     0.50491524,   0.47352976,    0.114075884,
+    0.76215386,   0.025808325,  0.34201944,   0.50133306,   0.5072456,     0.9658282,    0.53421855,    0.32217088,
+    0.019331919,  0.8438945,    0.7697814,    0.872105,     0.27831417,    0.837763,     0.47709718,    0.56208163,
+    0.13857186,   0.028468672,  0.34605467,   0.42612493,   0.35739717,    0.79774356,   0.63431424,    0.5377991,
+    0.4116114,    0.4728273,    0.36964366,   0.48545814,   0.3856123,     0.48144072,   0.11712731,    0.64248794,
+    0.5882744,    0.71837467,   0.77630204,   0.1082207,    0.500894,      0.956352,     0.7659055,     0.6140229,
+    0.75782984,   0.34864277,   0.9382825,    0.26016235,   0.9555291,     0.06052337,   0.9707168,     0.15848531,
+    0.3759561,    0.10505597,   0.39491206,   0.86381155,   0.15886053,    0.047404833,  0.7566787,     0.96441025,
+    0.3914941,    0.8042203,    0.08972167,   0.0344183,    0.59618455,    0.0487604,    0.93655854,    0.5378912,
+    0.7267672,    0.12729345,   0.2838306,    0.5599395,    0.06146098,    0.3688765,    0.061187647,   0.18221985,
+    0.2625632,    0.7320318,    0.6682951,    0.008754399,  0.85946107,    0.3741519,    0.58227,       0.35108802,
+    0.5021105,    0.21115834,   0.10950206,   0.28055635,   0.08652866,    0.25331578,   0.48362744,    0.5408696,
+    0.9616959,    0.8118918,    0.7167266,    0.6966737,    0.8666303,     0.73148715,   0.017838325,   0.7090695,
+    0.4120842,    0.40039128,   0.5333952,    0.8282356,    0.77669275,    0.41077727,   0.09702433,    0.007079605,
+    0.043868326,  0.21269222,   0.6012483,    0.42682874,   0.37910977,    0.7479243,    0.10494917,    0.01734221,
+    0.22195028,   0.73863363,   0.5323078,    0.38502622,   0.93925834,    0.6560022,    0.45136255,    0.47345138,
+    0.643666,     0.74296105,   0.5982436,    0.24956919,   0.65214986,    0.36451396,   0.31558952,    0.531076,
+    0.71419346,   0.9592256,    0.5966702,    0.45906982,   0.8407567,     0.7540344,    0.5743953,     0.09133322,
+    0.114134,     0.10242245,   0.23668802,   0.87383646,   0.6520674,     0.056798704,  0.16175981,    0.2137716,
+    0.7069426,    0.6993844,    0.4747234,    0.1279967,    0.19917937,    0.6328121,    0.76981115,    0.756082,
+    0.94902873,   0.059943788,  0.1845696,    0.03373171,   0.8125337,     0.84745514,   0.35492972,    0.67935437,
+    0.8971027,    0.07017233,   0.7126353,    0.41988418,   0.15125412,    0.6458793,    0.1765855,     0.46791586,
+    0.16423836,   0.4409746,    0.27089223,   0.83683586,   0.4193142,     0.5775261,    0.82138395,    0.58686733,
+    0.58120126,   0.384472,     0.54262656,   0.95276546,   0.8897906,     0.1875928,    0.33189663,    0.08138137,
+    0.18941447,   0.8405882,    0.51004106,   0.7808129,    0.5694648,     0.54066354,   0.27879953,    0.26667887,
+    0.74749273,   0.55733365,   0.97673374,   0.5818951,    0.34416345,    0.74187565,   0.06251747,    0.061063267,
+    0.5227989,    0.0068075284, 0.96375835,   0.75820476,   0.36191988,    0.93297523,   0.3367678,     0.37150264,
+    0.23855984,   0.5977023,    0.45253047,   0.42806166,   0.30482855,    0.40216422,   0.7895638,     0.7095099,
+    0.7382757,    0.6312539,    0.23046969,   0.3106659,    0.13583827,    0.39577258,   0.89845103,    0.6235748,
+    0.16217506,   0.004213362,  0.08934315,   0.86198056,   0.60079235,    0.23948883,   0.24270387,    0.8393256,
+    0.32195452,   0.4815633,    0.4299666,    0.8829831,    0.22383447,    0.57369184,   0.7194615,     0.2564392,
+    0.5038204,    0.13853844,   0.5422531,    0.97176254,   0.0881331,     0.85073787,   0.9618503,     0.3453285,
+    0.76776993,   0.26722383,   0.8436194,    0.7129096,    0.51140594,    0.75185156,   0.925225,      0.1270263,
+    0.10835649,   0.34018353,   0.5960297,    0.35770652,   0.8436321,     0.47478724,   0.7707103,     0.999071,
+    0.35499844,   0.6132049,    0.106107146,  0.82326525,   0.97219765,    0.9065807,    0.48567542,    0.16458383,
+    0.9117924,    0.9740305,    0.8068454,    0.99729985,   0.8535195,     0.9266885,    0.5354417,     0.3114372,
+    0.04236306,   0.7440147,    0.09421062,   0.3335685,    0.3958694,     0.52979434,   0.32791966,    0.57010293,
+    0.5563383,    0.30294028,   0.77462655,   0.88365096,   0.97766215,    0.36175498,   0.41280714,    0.029033197,
+    0.36782816,   0.5431821,    0.61676407,   0.47492823,   0.7446307,     0.13858505,   0.37313086,    0.86118925,
+    0.7815484,    0.6790356,    0.8011172,    0.53737545,   0.94500613,    0.92792517,   0.27350682,    0.18166798,
+    0.8047418,    0.2845925,    0.31534344,   0.09961744,   0.38057664,    0.43714178,   0.6032016,     0.82520413,
+    0.28528523,   0.5360042,    0.26692694,   0.66925734,   0.13195412,    0.6020245,    0.18692169,    0.5500374,
+    0.5612233,    0.77781224,   0.62947166,   0.31033742,   0.30992442,    0.060513485,  0.5668065,     0.903778,
+    0.3708838,    0.2330214,    0.55202013,   0.71683383,   0.72867715,    0.79054415,   0.6250968,     0.62841314,
+    0.029433481,  0.59295857,   0.07890911,   0.69306964,   0.046411548,   0.3131897,    0.6484566,     0.9306864,
+    0.93998045,   0.79156,      0.189643,     0.20862652,   0.8716581,     0.7038735,    0.7292351,     0.1795239,
+    0.49211392,   0.25107977,   0.9761521,    0.16719387,   0.29845348,    0.9631694,    0.87174356,    0.74422836,
+    0.7177861,    0.41156542,   0.72873366,   0.14755523,   0.88512164,    0.8863678,    0.096526965,   0.49474105,
+    0.9109074,    0.6385138,    0.63982385,   0.53899556,   0.5231154,     0.49385205,   0.5036258,     0.24803366,
+    0.12935568,   0.6987853,    0.37035698,   0.5183644,    0.8708705,     0.35817996,   0.032119915,   0.66701025,
+    0.5037863,    0.37249622,   0.22471993,   0.47759736,   0.81439203,    0.45790294,   0.32995966,    0.06626411,
+    0.721215,     0.33468077,   0.97528356,   0.6348461,    0.584456,      0.50090134,   0.04556473,    0.053612676,
+    0.695033,     0.69490194,   0.29771915,   0.23314431,   0.064049676,   0.19023955,   0.6564085,     0.99826187,
+    0.7474539,    0.7281185,    0.037838195,  0.5996682,    0.5928124,     0.35337916,   0.87335783,    0.3596061,
+    0.37944552,   0.06172341,   0.6437689,    0.51262546,   0.66164786,    0.6189296,    0.680349,      0.45300442,
+    0.3085541,    0.57355976,   0.81778055,   0.18843463,   0.51856846,    0.8687797,    0.6635776,     0.6284543,
+    0.6532206,    0.3167443,    0.8233314,    0.17596854,   0.06046078,    0.7989756,    0.6029606,     0.31354675,
+    0.7160877,    0.22645807,   0.7301434,    0.086273566,  0.42006475,    0.7302915,    0.4734517,     0.36783585,
+    0.4613229,    0.6156775,    0.2554006,    0.5227326,    0.8571324,     0.53293926,   0.39196482,    0.07610343,
+    0.014552955,  0.84471476,   0.9245902,    0.49048993,   0.37245902,    0.4679739,    0.47969338,    0.8786742,
+    0.06454086,   0.40938383,   0.9464476,    0.2760681,    0.5300478,     0.6973893,    0.2991453,     0.5804699,
+    0.45876285,   0.33022216,   0.79653776,   0.43518978,   0.8887862,     0.59407544,   0.032939672,   0.5782626,
+    0.10010804,   0.44994467,   0.7271117,    0.902891,     0.6133791,     0.140845,     0.77132195,    0.12028129,
+    0.9247795,    0.74722797,   0.16141559,   0.21574605,   0.8743854,     0.11247064,   0.9410877,     0.24811381,
+    0.74676466,   0.8514692,    0.021732707,  0.010680916,  0.7838439,     0.19738361,   0.8377881,     0.7639336,
+    0.31653216,   0.6749307,    0.06396978,   0.52691025,   0.7364015,     0.956775,     0.18731725,    0.42047754,
+    0.8117751,    0.34632754,   0.39038187,   0.9225143,    0.7408622,     0.57680243,   0.2652951,     0.92369586,
+    0.6380619,    0.82616633,   0.35128862,   0.7828198,    0.5359737,     0.08339928,   0.7060845,     0.3462922,
+    0.38913444,   0.54842395,   0.6884251,    0.037316978,  0.5723427,     0.022258755,  0.79441875,    0.90272444,
+    0.61215657,   0.9631781,    0.5863588,    0.9384484,    0.07687521,    0.24441172,   0.38387978,    0.96800447,
+    0.5599107,    0.74093807,   0.403971,     0.5280579,    0.72208875,    0.018573398,  0.5072516,     0.16996226,
+    0.58617413,   0.09803684,   0.37261903,   0.95767754,   0.84609497,    0.05496832,   0.22795987,    0.23313288,
+    0.9688462,    0.7176776,    0.1377758,    0.18797757,   0.26834992,    0.15000027,   0.8481348,     0.7895163,
+    0.5519088,    0.48765746,   0.31035778,   0.77768403,   0.9904436,     0.32684666,   0.84682065,    0.39365014,
+    0.44228655,   0.38328415,   0.22290905,   0.79503566,   0.6794283,     0.17802662,   0.62420344,    0.37056103,
+    0.041172326,  0.51846284,   0.45114288,   0.47430587,   0.6496397,     0.8367412,    0.05662944,    0.5571883,
+    0.7352182,    0.35322595,   0.9696022,    0.35919765,   0.10663593,    0.19590221,   0.6996546,     0.40991047,
+    0.89280325,   0.6144547,    0.9761491,    0.23443131,   0.70821565,    0.7295676,    0.17951865,    0.25932744,
+    0.25121617,   0.97896886,   0.515391,     0.46281084,   0.83205926,    0.4329242,    0.55370456,    0.7908196,
+    0.093474135,  0.7672148,    0.14680524,   0.74988705,   0.69885737,    0.37382892,   0.13987659,    0.7151676,
+    0.431028,     0.75316954,   0.04246583,   0.63721764,   0.35724443,    0.48762304,   0.28701422,    0.24638435,
+    0.6836296,    0.8129986,    0.9022324,    0.064973645,  0.20187753,    0.38977212,   0.6623454,     0.31160477,
+    0.3389442,    0.19181544,   0.2230897,    0.6706708,    0.32135025,    0.5938186,    0.725129,      0.30229402,
+    0.7995213,    0.17878264,   0.2657235,    0.33942115,   0.04909697,    0.94976753,   0.7110531,     0.5189743,
+    0.47457805,   0.2609815,    0.8034033,    0.9550461,    0.6871017,     0.542301,     0.90208304,    0.76359314,
+    0.6919547,    0.2690066,    0.77918124,   0.019060668,  0.5306918,     0.48873094,   0.58894205,    0.703702,
+    0.104869366,  0.8352005,    0.41094282,   0.507042,     0.15073924,    0.46920577,   0.3938173,     0.8372094,
+    0.028040525,  0.7401718,    0.8376963,    0.17846179,   0.22189952,    0.9475931,    0.19728738,    0.7338621,
+    0.101945534,  0.3832581,    0.59039557,   0.94089603,   0.5863688,     0.7072993,    0.624503,      0.7966432,
+    0.28973243,   0.45949653,   0.9787162,    0.052343633,  0.81463736,    0.70606834,   0.7716022,     0.31079042,
+    0.5898406,    0.5620215,    0.23455179,   0.21389648,   0.5388247,     0.2040111,    0.36823508,    0.0053723096,
+    0.8671642,    0.9661939,    0.9270056,    0.94692993,   0.7046047,     0.72362125,   0.5416936,     0.7443616,
+    0.07171923,   0.04531915,   0.91711515,   0.1474337,    0.89833534,    0.648046,     0.11733318,    0.39757007,
+    0.21069747,   0.6142996,    0.21730955,   0.6912427,    0.49048957,    0.34147367,   0.022572042,   0.3219722,
+    0.9685696,    0.5269059,    0.5886212,    0.659878,     0.7130413,     0.98339087,   0.19503741,    0.89793444,
+    0.015023004,  0.5850233,    0.07373183,   0.62017494,   0.7802937,     0.6775731,    0.09203854,    0.5661112,
+    0.9178029,    0.2343546,    0.9806244,    0.7693182,    0.7889532,     0.6241685,    0.41245508,    0.9417946,
+    0.44468832,   0.8369817,    0.0031990237, 0.9245251,    0.98670155,    0.6769924,    0.51488274,    0.5256905,
+    0.9436219,    0.6050334,    0.97836035,   0.17769879,   0.13500004,    0.8818156,    0.0313203,     0.08832834,
+    0.8502817,    0.019180698,  0.13241069,   0.31331208,   0.5743142,     0.49715826,   0.6172764,     0.5331244,
+    0.5222611,    0.6511984,    0.7734398,    0.256135,     0.3608493,     0.25325385,   0.533019,      0.34440103,
+    0.114450805,  0.6468266,    0.2151897,    0.8760596,    0.9801919,     0.27051234,   0.9112329,     0.3380306,
+    0.07014053,   0.54804134,   0.6765531,    0.1752603,    0.69921273,    0.9143398,    0.43111116,    0.035987273,
+    0.2030343,    0.8922961,    0.91903645,   0.76977247,   0.49175784,    0.099143006,  0.3674804,     0.94753003,
+    0.21970531,   0.47007462,   0.40226397,   0.3355032,    0.9035526,     0.25874776,   0.16484123,    0.69036806,
+    0.07201438,   0.63395935,   0.063247986,  0.48817343,   0.6666259,     0.15526073,   0.10813647,    0.5797694,
+    0.10794782,   0.79438007,   0.24317154,   0.026272861,  0.8206052,     0.4420161,    0.8339117,     0.6079213,
+    0.22008722,   0.73745257,   0.053100668,  0.46855322,   0.33421737,    0.76324654,   0.8526432,     0.015307797,
+    0.27934623,   0.26765963,   0.65635425,   0.51011723,   0.86824834,    0.57572967,   0.43447804,    0.8113928,
+    0.38320008,   0.986185,     0.10324592,   0.06525337,   0.85109174,    0.94293773,   0.36936134,    0.047773577,
+    0.7841596,    0.33926708,   0.66182464,   0.69737774,   0.85597146,    0.34120753,   0.12692484,    0.7776892,
+    0.63616294,   0.79434264,   0.11541597,   0.16610004,   0.2056471,     0.696288,     0.35615066,    0.30876786,
+    0.78131616,   0.04794019,   0.2088272,    0.39896628,   0.49890646,    0.59801924,   0.711521,      0.5322181,
+    0.35990205,   0.43177876,   0.6430728,    0.8344202,    0.33877015,    0.76865834,   0.75682956,    0.2771495,
+    0.3680912,    0.005327093,  0.68439364,   0.9949503,    0.10142185,    0.15526544,   0.15933633,    0.9381387,
+    0.14073479,   0.87866503,   0.8739543,    0.07390571,   0.46031374,    0.268378,     0.6057457,     0.68691206,
+    0.6300343,    0.79447806,   0.28393722,   0.80315155,   0.73411053,    0.9703951,    0.5488671,     0.18614037,
+    0.6277461,    0.12960654,   0.33747572,   0.4241927,    0.6981348,     0.29250467,   0.43891907,    0.8675046,
+    0.037513115,  0.8382665,    0.79800886,   0.20032,      0.011894401,   0.3612004,    0.207346,      0.6260507,
+    0.88860387,   0.27068847,   0.25823146,   0.62024146,   0.72406495,    0.6376153,    0.0719044,     0.09152406,
+    0.82603306,   0.9561607,    0.20438583,   0.5442921,    0.4847211,     0.95367795,   0.54303896,    0.3976961,
+    0.45646,      0.49825326,   0.3672042,    0.9718153,    0.81778973,    0.73514366,   0.24000394,    0.8482301,
+    0.43974596,   0.006449677,  0.036392592,  0.62204725,   0.47036913,    0.4054257,    0.67501765,    0.26883397,
+    0.58713204,   0.6578865,    0.91454774,   0.46342203,   0.7121636,     0.92862564,   0.46207544,    0.9901308,
+    0.057702154,  0.24595165,   0.5981596,    0.74197406,   0.08811883,    0.894627,     0.38278353,    0.08383514,
+    0.2952275,    0.40031275,   0.74386,      0.5136412,    0.9939962,     0.2355307,    0.808261,      0.15346022,
+    0.030684536,  0.41000134,   0.1804955,    0.71761525,   0.6012227,     0.44985715,   0.6211549,     0.4206074,
+    0.28114304,   0.9355519,    0.95716006,   0.82683456,   0.03913026,    0.07961693,   0.6855325,     0.52783436,
+    0.036177807,  0.3770734,    0.91411316,   0.5718381,    0.13698402,    0.4980299,    0.76011133,    0.545119,
+    0.62366617,   0.95255744,   0.32681978,   0.07005637,   0.66156566,    0.16137652,   0.27483776,    0.35160136,
+    0.8496255,    0.7610875,    0.4327375,    0.30216226,   0.74813014,    0.74446017,   0.38890806,    0.607845,
+    0.62479675,   0.17755221,   0.46083102,   0.15256695,   0.9374669,     0.5559489,    0.04470488,    0.21561056,
+    0.7147803,    0.21602567,   0.47746333,   0.6169228,    0.32141757,    0.23642296,   0.016476203,   0.53265464,
+    0.64989,      0.6353765,    0.0939491,    0.64866525,   0.12303737,    0.5510985,    0.7590417,     0.11976651,
+    0.6607141,    0.6055587,    0.9772091,    0.27804276,   0.64687943,    0.38337022,   0.7797042,     0.29171762,
+    0.9881654,    0.30626813,   0.94704133,   0.9594318,    0.037198868,   0.60754436,   0.60765207,    0.06771721,
+    0.9078526,    0.1112092,    0.3552761,    0.44554,      0.6839132,     0.657915,     0.030183792,   0.6132026,
+    0.74461126,   0.9000829,    0.6522722,    0.112753615,  0.6505111,     0.74024284,   0.48480767,    0.073698185,
+    0.4185105,    0.3410645,    0.49185285,   0.33190826,   0.5787399,     0.7666621,    0.5687311,     0.33141005,
+    0.43632144,   0.18574573,   0.6287574,    0.01514944,   0.28938162,    0.057044394,  0.49545577,    0.042345677,
+    0.027724478,  0.026231889,  0.74081266,   0.011828165,  0.19582245,    0.31350172,   0.43585333,    0.0027991086,
+    0.5753749,    0.36400652,   0.5334315,    0.74679655,   0.731098,      0.6669506,    0.6412065,     0.24792254,
+    0.8214605,    0.8733431,    0.54092133,   0.6961343,    0.115691505,   0.27574378,   0.48897734,    0.14119047,
+    0.5424781,    0.02386607,   0.009218562,  0.49816743,   0.029157575,   0.015034353,  0.32382092,    0.6875669,
+    0.40462708,   0.6099266,    0.08502913,   0.6242792,    0.9994301,     0.4729795,    0.87787575,    0.10500878,
+    0.90521115,   0.48905376,   0.7565334,    0.21473333,   0.23323065,    0.8219346,    0.60031205,    0.76937085,
+    0.5445392,    0.38083488,   0.19368897,   0.41603848,   0.51612306,    0.7993214,    0.92665416,    0.75198066,
+    0.5372545,    0.5996222,    0.4693501,    0.17195638,   0.30428314,    0.9376859,    0.9736415,     0.5603405,
+    0.040185597,  0.8458646,    0.34216946,   0.12117143,   0.58192146,    0.016927328,  0.24849239,    0.34848097,
+    0.99546736,   0.43591255,   0.7909232,    0.62663776,   0.51921046,    0.274244,     0.9079598,     0.72054344,
+    0.42355403,   0.2398477,    0.95362824,   0.6483227,    0.8213454,     0.90778244,   0.17144382,    0.6053057,
+    0.68327236,   0.33304846,   0.08702466,   0.39980793,   0.0036293846,  0.7059194,    0.80072564,    0.96752524,
+    0.5154122,    0.19619283,   0.17454775,   0.38736606,   0.47976512,    0.4791406,    0.1874494,     0.52761185,
+    0.13234249,   0.845208,     0.4205711,    0.08021053,   0.00839825,    0.3000164,    0.23277025,    0.26301053,
+    0.6916624,    0.74880666,   0.74840236,   0.064435445,  0.98405766,    0.32531884,   0.73899513,    0.13240317,
+    0.6744208,    0.7368638,    0.43789902,   0.24887301,   0.9299027,     0.8486845,    0.34485158,    0.289548,
+    0.6351869,    0.82339793,   0.11122555,   0.3230176,    0.09969627,    0.52059376,   0.24077836,    0.9444134,
+    0.05239831,   0.42601636,   0.5159802,    0.9761374,    0.48721132,    0.09123329,   0.59690744,    0.383256,
+    0.1002782,    0.8240141,    0.70814556,   0.25482276,   0.957517,      0.7362902,    0.9834676,     0.19009337,
+    0.45719767,   0.042144574,  0.71294534,   0.7429013,    0.041241586,   0.9385764,    0.59770924,    0.28365803,
+    0.50035644,   0.13102308,   0.44502363,   0.18500035,   0.18879086,    0.90975267,   0.16331425,    0.17106864,
+    0.50802827,   0.80398893,   0.012037134,  0.55804133,   0.8093386,     0.7628578,    0.64519185,    0.58318746,
+    0.1399564,    0.05464305,   0.14859481,   0.10588853,   0.14053893,    0.09002884,   0.332031,      0.89889675,
+    0.8399303,    0.9211322,    0.86581993,   0.057551697,  0.8076484,     0.49787706,   0.90317184,    0.113821924,
+    0.82830715,   0.23232217,   0.47578096,   0.35618824,   0.64620966,    0.41190708,   0.19446513,    0.19052555,
+    0.6606999,    0.5370769,    0.74679446,   0.15352806,   0.72425306,    0.42542627,   0.3807547,     0.6943399,
+    0.39695272,   0.12975785,   0.6029449,    0.98659855,   0.78998154,    0.4918207,    0.1431191,     0.41032755,
+    0.7989921,    0.5461269,    0.34507003,   0.26765865,   0.043932725,   0.105762556,  0.36342022,    0.010151213,
+    0.90081716,   0.89821523,   0.7297342,    0.5770165,    0.2870768,     0.28900358,   0.9369778,     0.72804934,
+    0.86017793,   0.95806926,   0.44518864,   0.60346204,   0.34323436,    0.17850293,   0.17464367,    0.41450405,
+    0.5403775,    0.17148003,   0.660599,     0.6778906,    0.89493215,    0.9165733,    0.32384035,    0.33648646,
+    0.08920308,   0.06545341,   0.5571962,    0.10008278,   0.06683705,    0.92680645,   0.14659283,    0.5549373,
+    0.17365667,   0.73664325,   0.25271094,   0.8260378,    0.69569206,    0.80373824,   0.4072631,     0.10794914,
+    0.19278006,   0.8748956,    0.12642062,   0.8319123,    0.04663203,    0.53965706,   0.06709321,    0.6204891,
+    0.37148324,   0.93056595,   0.7272812,    0.8724527,    0.44516358,    0.68552965,   0.11521906,    0.98424387,
+    0.57437485,   0.39324772,   0.48781338,   0.22162339,   0.7318074,     0.836895,     0.66121227,    0.9333714,
+    0.81147647,   0.89025134,   0.42980537,   0.6065911,    0.925792,      0.3486058,    0.718812,      0.7366392,
+    0.7642169,    0.55264986,   0.4851105,    0.02003657,   0.79015267,    0.49192804,   0.28985444,    0.54954606,
+    0.9983602,    0.936707,     0.72859955,   0.13627109,   0.1995253,     0.27414012,   0.10977373,    0.48812705,
+    0.6214242,    0.26846707,   0.251663,     0.30244434,   0.31592485,    0.18563971,   0.3761417,     0.35588506,
+    0.2136833,    0.19304918,   0.020435851,  0.1563807,    0.10985168,    0.46050212,   0.69469714,    0.022877397,
+    0.211754,     0.99064195,   0.10823577,   0.89251375,   0.20041913,    0.09518249,   0.19409119,    0.082446806,
+    0.1033933,    0.93826735,   0.22326319,   0.7951004,    0.108295456,   0.5249412,    0.7338461,     0.53733635,
+    0.7804776,    0.94167835,   0.9851669,    0.6573249,    0.09694284,    0.41636762,   0.42071435,    0.5785772,
+    0.17650813,   0.12922545,   0.8063533,    0.5971035,    0.4714922,     0.13347372,   0.43969434,    0.53785807,
+    0.2420099,    0.70572215,   0.9245171,    0.20888333,   0.16590436,    0.21725997,   0.2877079,     0.5262417,
+    0.07437589,   0.16921617,   0.19905105,   0.3776575,    0.96237653,    0.58104134,   0.2475896,     0.6887421,
+    0.459203,     0.48309952,   0.3759031,    0.16817336,   0.47533524,    0.037372224,  0.92593455,    0.7953864,
+    0.5699276,    0.52965856,   0.7160056,    0.07119369,   0.28882924,    0.5969877,    0.6109546,     0.96991956,
+    0.498573,     0.68540514,   0.5530905,    0.40257332,   0.6004241,     0.52496284,   0.37143198,    0.56321764,
+    0.6539704,    0.45892516,   0.58294904,   0.9277267,    0.21731657,    0.043056846,  0.6162007,     0.5954668,
+    0.88163584,   0.11761114,   0.13790047,   0.98839265,   0.7575706,     0.271521,     0.06252285,    0.20463766,
+    0.7797876,    0.1291307,    0.6389557,    0.6362458,    0.5012543,     0.21651421,   0.23741248,    0.4773882,
+    0.5582616,    0.22913149,   0.8790845,    0.27697143,   0.02795082,    0.8450163,    0.08831802,    0.9342402,
+    0.11166756,   0.8126855,    0.51420295,   0.016410068,  0.4544232,     0.99820787,   0.5780698,     0.5268707,
+    0.9134579,    0.12053883,   0.18955784,   0.1712181,    0.45908722,    0.62256193,   0.21234894,    0.227052,
+    0.62288225,   0.34845284,   0.6227857,    0.4712934,    0.8860071,     0.73518616,   0.06196327,    0.4374562,
+    0.22151268,   0.10556084,   0.3694651,    0.9881851,    0.16397232,    0.3392293,    0.56751597,    0.036619555,
+    0.029293122,  0.20366028,   0.87672514,   0.94488513,   0.757318,      0.04611278,   0.75021446,    0.78157973,
+    0.5510609,    0.112084985,  0.7227879,    0.38071552,   0.026956385,   0.0661944,    0.01830097,    0.93569964,
+    0.016782548,  0.6520325,    0.65408915,   0.67949796,   0.22223058,    0.6170246,    0.048233118,   0.37648138,
+    0.7507222,    0.07674675,   0.7948974,    0.34886235,   0.6287428,     0.5898847,    0.36289844,    0.5742286,
+    0.55302286,   0.15293828,   0.14192496,   0.25542694,   0.74583685,    0.26746377,   0.46973395,    0.5767695,
+    0.59823835,   0.841206,     0.9202325,    0.7739221,    0.012398226,   0.6812478,    0.4104998,     0.15531828,
+    0.087259874,  0.43376547,   0.9714025,    0.5119398,    0.68514013,    0.888018,     0.814389,      0.4122685,
+    0.15542716,   0.5002437,    0.19416295,   0.6805713,    0.2512154,     0.4013521,    0.15283692,    0.96117616,
+    0.7491866,    0.14855935,   0.8276927,    0.8740181,    0.92426944,    0.762874,     0.18986279,    0.7493188,
+    0.18229857,   0.07731968,   0.08125962,   0.3810246,    0.6967921,     0.27431104,   0.36408317,    0.06947445,
+    0.66624695,   0.6395791,    0.2616025,    0.19497731,   0.6184822,     0.85095865,   0.88908845,    0.66500485,
+    0.33854932,   0.72965646,   0.099999785,  0.24559312,   0.07330083,    0.78916264,   0.32555407,    0.19688624,
+    0.6883691,    0.9590563,    0.024735536,  0.86383885,   0.8535551,     0.53648174,   0.23104885,    0.32438585,
+    0.24390268,   0.22208378,   0.32964125,   0.60782045,   0.8067584,     0.4333644,    0.71547633,    0.88111615,
+    0.13616055,   0.1246885,    0.014324361,  0.6116363,    0.13974965,    0.9578596,    0.34269398,    0.89822793,
+    0.25947088,   0.16268782,   0.53546876,   0.19461296,   0.6628742,     0.94426966,   0.67601794,    0.3931359,
+    0.7517656,    0.88437337,   0.6926555,    0.7377358,    0.2495755,     0.50024426,   0.21591938,    0.12976523,
+    0.40853027,   0.93721664,   0.95107466,   0.39639843,   0.52131736,    0.28126806,   0.85824645,    0.9051849,
+    0.01418011,   0.21888365,   0.10943257,   0.94861233,   0.77483827,    0.7139178,    0.057136595,   0.73050946,
+    0.61636233,   0.1265076,    0.60436803,   0.69086725,   0.0010129241,  0.036435887,  0.6615116,     0.299633,
+    0.54606587,   0.9365053,    0.85605484,   0.922385,     0.7407089,     0.9777405,    0.63154066,    0.63591623,
+    0.90876913,   0.88455915,   0.20310602,   0.20253302,   0.0067849625,  0.94629556,   0.37691054,    0.9782028,
+    0.30444136,   0.63028383,   0.18043286,   0.4439906,    0.8348371,     0.7274056,    0.61829764,    0.037847787,
+    0.8272368,    0.96214604,   0.12137349,   0.123067886,  0.8958763,     0.52505213,   0.1287523,     0.3720944,
+    0.275705,     0.65144163,   0.85033256,   0.58481205,   0.42521322,    0.93586147,   0.16447607,    0.036439568,
+    0.58734304,   0.47351632,   0.039843205,  0.8902792,    0.5108118,     0.8546036,    0.72372454,    0.6700668,
+    0.7495971,    0.6261652,    0.3864259,    0.3707291,    0.85600305,    0.21752104,   0.4647959,     0.81866026,
+    0.3182077,    0.818207,     0.09514821,   0.77856284,   0.85636705,    0.50847274,   0.74004,       0.38371703,
+    0.7558068,    0.83101165,   0.926828,     0.35534334,   0.09596299,    0.7920985,    0.5529896,     0.36857986,
+    0.46580777,   0.14399329,   0.85664755,   0.3613208,    0.6875624,     0.72801846,   0.527036,      0.9726332,
+    0.23842148,   0.45130673,   0.37347084,   0.26971108,   0.1386262,     0.7580232,    0.51609135,    0.058183976,
+    0.18664573,   0.031672336,  0.26660433,   0.6070062,    0.84071326,    0.38591322,   0.18007252,    0.07887025,
+    0.73347634,   0.6561262,    0.13447234,   0.67980015,   0.92777556,    0.3683812,    0.5741038,     0.95749855,
+    0.07317559,   0.017846042,  0.9049213,    0.7120097,    0.36087346,    0.10347511,   0.13109785,    0.5901893,
+    0.29117107,   0.12251501,   0.54014134,   0.40506032,   0.13500193,    0.4703289,    0.24509083,    0.9977836,
+    0.3149203,    0.868644,     0.16869761,   0.06429065,   0.52549416,    0.94598347,   0.5278666,     0.079894565,
+    0.9639208,    0.7777773,    0.62784445,   0.0314362,    0.5935461,     0.8472358,    0.04485763,    0.8700403,
+    0.8772029,    0.4159723,    0.1965355,    0.120780155,  0.8531019,     0.80408156,   0.6973105,     0.08317062,
+    0.9005745,    0.6764151,    0.3158351,    0.71819824,   0.84577185,    0.7750122,    0.94386834,    0.26314744,
+    0.41103536,   0.13668874,   0.36487988,   0.059131548,  0.19968359,    0.50981313,   0.4320044,     0.12719214,
+    0.48997945,   0.82502675,   0.74808896,   0.58309615,   0.47563064,    0.09966165,   0.9966431,     0.44393525,
+    0.07765738,   0.67010105,   0.5278574,    0.71902966,   0.27379337,    0.12431067,   0.14468168,    0.5108387,
+    0.1713335,    0.08552699,   0.16371617,   0.8490791,    0.63014835,    0.80966836,   0.23412272,    0.18890859,
+    0.833909,     0.364697,     0.62040085,   0.45685738,   0.48235595,    0.98572606,   0.6703567,     0.3673898,
+    0.9839679,    0.06934336,   0.6308007,    0.02807519,   0.0559926,     0.11421437,   0.60753995,    0.80091286,
+    0.67977196,   0.87189984,   0.6405409,    0.17567077,   0.24715477,    0.22483869,   0.9893541,     0.2867247,
+    0.9920071,    0.85404116,   0.887798,     0.114156604,  0.34609696,    0.5829253,    0.49704382,    0.6803111,
+    0.590904,     0.5591804,    0.7491872,    0.110933654,  0.4792608,     0.53978574,   0.9615793,     0.091931306,
+    0.99974436,   0.1604676,    0.73506176,   0.20445003,   0.49350995,    0.11660648,   0.4548461,     0.057119142,
+    0.47798702,   0.36280334,   0.16930713,   0.7582485,    0.16912746,    0.058451943,  0.9417538,     0.6090703,
+    0.37534294,   0.33367616,   0.4648503,    0.6283148,    0.09792804,    0.5562001,    0.021292835,   0.40104258,
+    0.57229954,   0.95048964,   0.4371712,    0.49681222,   0.36502722,    0.49660632,   0.32165202,    0.13998619,
+    0.9103205,    0.54860955,   0.17592642,   0.086687185,  0.48977694,    0.78490406,   0.79321474,    0.8754006,
+    0.39919505,   0.8306789,    0.63616955,   0.98329365,   0.41361818,    0.73879534,   0.5111836,     0.53245205,
+    0.6174266,    0.14011684,   0.7355907,    0.14558467,   0.074935436,   0.33326453,   0.99400324,    0.44354424,
+    0.13917476,   0.33401918,   0.6321505,    0.5430203,    0.6794353,     0.9580339,    0.69209194,    0.9813807,
+    0.041151315,  0.029320937,  0.8479279,    0.6205179,    0.8825255,     0.85506666,   0.11929336,    0.5904389,
+    0.5404614,    0.58944976,   0.22911972,   0.26724914,   0.92003053,    0.037999198,  0.9874244,     0.83350426,
+    0.439306,     0.9047191,    0.87938565,   0.22491038,   0.7610156,     0.17606735,   0.06505076,    0.577056,
+    0.5546063,    0.7323822,    0.94751245,   0.15575777,   0.15275358,    0.2501944,    0.19596528,    0.44116116,
+    0.13858697,   0.65478885,   0.9421423,    0.38429725,   0.89086735,    0.8906657,    0.64992654,    0.7623599,
+    0.020823486,  0.14515182,   0.6051233,    0.4854857,    0.10414482,    0.7267541,    0.52351373,    0.10117556,
+    0.34659478,   0.7986462,    0.10371433,   0.7747162,    0.078648254,   0.46718153,   0.22036512,    0.86508393,
+    0.9642702,    0.27087194,   0.06591158,   0.15014334,   0.9075542,     0.9635356,    0.4376853,     0.290267,
+    0.39348447,   0.78795856,   0.12866218,   0.26524165,   0.095856875,   0.6031271,    0.94263685,    0.54864025,
+    0.25479257,   0.11702571,   0.20408688,   0.6158638,    0.5709441,     0.57956505,   0.47291118,    0.8278522,
+    0.20886846,   0.8463369,    0.809163,     0.35410735,   0.14648008,    0.4212491,    0.36251292,    0.67140543,
+    0.43442374,   0.07705836,   0.42002708,   0.6199954,    0.8247542,     0.4997832,    0.8548057,     0.057287898,
+    0.7074665,    0.31485626,   0.09200123,   0.31618625,   0.59809196,    0.25827205,   0.0053186826,  0.7434676,
+    0.85600936,   0.5550741,    0.5199236,    0.96162254,   0.26309466,    0.60450137,   0.29413986,    0.38470513,
+    0.79796076,   0.23805939,   0.9412749,    0.061217327,  0.15437259,    0.083577976,  0.14378692,    0.9722354,
+    0.42544565,   0.45725676,   0.8308179,    0.018798511,  0.18310007,    0.32264143,   0.72388613,    0.75500935,
+    0.26221997,   0.146799,     0.90839726,   0.25608784,   0.48756382,    0.15672493,   0.22976026,    0.9505964,
+    0.8410182,    0.06569535,   0.498098,     0.591406,     0.90132546,    0.40089035,   0.40831077,    0.82992244,
+    0.7829185,    0.03532195,   0.8220347,    0.5866948,    0.55850834,    0.7935884,    0.9029153,     0.62388855,
+    0.17106935,   0.11976584,   0.8907406,    0.14083518,   0.42745417,    0.9865202,    0.5603676,     0.53336793,
+    0.83118796,   0.7649143,    0.6994026,    0.116295666,  0.69610405,    0.03805204,   0.8971413,     0.6412358,
+    0.008299126,  0.9906785,    0.22019914,   0.08867724,   0.58548,       0.5523809,    0.07090994,    0.024555296,
+    0.048945986,  0.0008954834, 0.23588002,   0.14777812,   0.5006067,     0.13719136,   0.19650105,    0.46863157,
+    0.24388368,   0.28450873,   0.08501847,   0.367798,     0.26598433,    0.08892508,   0.5231422,     0.854498,
+    0.50532776,   0.96473,      0.760218,     0.13641119,   0.7014878,     0.2920151,    0.13381833,    0.74486643,
+    0.13818067,   0.18079887,   0.57839566,   0.56782985,   0.5733893,     0.8142381,    0.038408525,   0.61868846,
+    0.048855904,  0.8661853,    0.091889195,  0.42655867,   0.75064015,    0.41258946,   0.0327612,     0.6939966,
+    0.5684132,    0.230771,     0.87241197,   0.41159534,   0.95303357,    0.5293433,    0.37525147,    0.91937405,
+    0.46753627,   0.3657011,    0.58334947,   0.62074995,   0.79216284,    0.9344987,    0.32306752,    0.7569309,
+    0.8670772,    0.49101356,   0.0095974505, 0.31980786,   0.5587957,     0.6286712,    0.8952423,     0.42964563,
+    0.24610022,   0.46633002,   0.31894207,   0.39979902,   0.99703586,    0.09658354,   0.10385787,    0.092738345,
+    0.9319688,    0.066221446,  0.567998,     0.47071677,   0.41960314,    0.722223,     0.79183286,    0.60883737,
+    0.8055474,    0.6590216,    0.10029357,   0.20768817,   0.2308886,     0.41765857,   0.82652557,    0.11435715,
+    0.5431178,    0.3349583,    0.55948156,   0.2596266,    0.402992,      0.7129533,    0.13520089,    0.939742,
+    0.33552873,   0.44276634,   0.16549513,   0.48670354,   0.2104012,     0.9754525,    0.9223382,     0.37095273,
+    0.26184326,   0.4906111,    0.68878114,   0.7259414,    0.3665008,     0.8523507,    0.33732775,    0.14485414,
+    0.69918066,   0.40076008,   0.5142605,    0.89977413,   0.52837765,    0.6875541,    0.19875702,    0.8284416,
+    0.6398044,    0.20458493,   0.8566812,    0.66207755,   0.537102,      0.84423125,   0.6897463,     0.2190155,
+    0.93102056,   0.62825596,   0.13518804,   0.9768368,    0.5567279,     0.30512935,   0.39843616,    0.83009493,
+    0.7366834,    0.72934085,   0.9458449,    0.7402775,    0.7288774,     0.100584194,  0.7478564,     0.69076705,
+    0.99763054,   0.41462737,   0.5604459,    0.002231921,  0.19869287,    0.23542677,   0.41136438,    0.6479746,
+    0.24400933,   0.33705348,   0.8468991,    0.0058162767, 0.11877123,    0.26026058,   0.83385074,    0.417612,
+    0.80086476,   0.46976563,   0.79492086,   0.73824483,   0.71716267,    0.36049098,   0.58812624,    0.3940513,
+    0.0023239073, 0.68416554,   0.1630907,    0.7990368,    0.74170923,    0.45847952,   0.0995642,     0.5392202,
+    0.45672858,   0.16591415,   0.664447,     0.12247461,   0.28378534,    0.6875144,    0.020322617,   0.6955938,
+    0.21689159,   0.48721343,   0.7328274,    0.21967441,   0.45823023,    0.39261988,   0.7113237,     0.47642282,
+    0.8954901,    0.52823293,   0.9394127,    0.25911182,   0.30566335,    0.009611528,  0.9736044,     0.63713956,
+    0.82650113,   0.16639459,   0.99990803,   0.5145273,    0.07233607,    0.6123276,    0.9062654,     0.7855298,
+    0.23748927,   0.30767888,   0.5490877,    0.9528571,    0.5958136,     0.71137613,   0.13382663,    0.11335034,
+    0.449443,     0.09932706,   0.52135324,   0.22994924,   0.6276635,     0.36845186,   0.93582106,    0.609704,
+    0.9728418,    0.68666786,   0.9035467,    0.21347627,   0.51906675,    0.8404524,    0.2335569,     0.44711703,
+    0.19230975,   0.027307436,  0.29597348,   0.11739075,   0.6876064,     0.5057953,    0.6232577,     0.604564,
+    0.58094805,   0.94729763,   0.9821851,    0.15055138,   0.8435322,     0.7584666,    0.8806093,     0.18411398,
+    0.3944063,    0.8260624,    0.8096688,    0.20633629,   0.48825827,    0.74365515,   0.009476059,   0.45804924,
+    0.23057352,   0.39020398,   0.5416855,    0.3856682,    0.7087808,     0.69278914,   0.26646304,    0.39703688,
+    0.074121974,  0.10197067,   0.76054734,   0.5685061,    0.41540262,    0.016435882,  0.42574394,    0.94364774,
+    0.47606933,   0.91678923,   0.6490012,    0.68036586,   0.38626674,    0.78526974,   0.7661718,     0.2143752,
+    0.80605865,   0.7194327,    0.81907,      0.69300437,   0.030783592,   0.027220597,  0.9588587,     0.4486546,
+    0.017831376,  0.83792424,   0.8868172,    0.2974024,    0.9641097,     0.23758952,   0.8957832,     0.8881589,
+    0.6808346,    0.5851483,    0.0764294,    0.74156153,   0.9979193,     0.3121031,    0.7687113,     0.37797043,
+    0.40031847,   0.86602104,   0.730267,     0.57146907,   0.094653964,   0.32911018,   0.07178252,    0.4453038,
+    0.62403214,   0.32731032,   0.5796096,    0.9893481,    0.87371916,    0.5734587,    0.3662533,     0.046901383,
+    0.14311191,   0.31189272,   0.5506748,    0.5774784,    0.12961864,    0.12834151,   0.97953796,    0.23847981,
+    0.021006035,  0.76084226,   0.99953127,   0.8011185,    0.7088403,     0.024610326,  0.21645589,    0.49395552,
+    0.9507214,    0.44109955,   0.2926859,    0.16476253,   0.29695365,    0.3873897,    0.35400063,    0.6887212,
+    0.7661417,    0.44151342,   0.67337024,   0.6367994,    0.65797997,    0.906435,     0.014439769,   0.10737592,
+    0.21889497,   0.029528014,  0.5984496,    0.6860266,    0.76142836,    0.19123298,   0.24835177,    0.27197698,
+    0.8864831,    0.49178717,   0.550463,     0.3338117,    0.32957888,    0.27066407,   0.7364635,     0.59942186,
+    0.11085444,   0.08565405,   0.03862678,   0.4326196,    0.28077278,    0.20149076,   0.7499477,     0.7557222,
+    0.95789206,   0.86195356,   0.8113367,    0.6881052,    0.45497125,    0.34273857,   0.5804998,     0.11457099,
+    0.7464025,    0.8921554,    0.5822235,    0.6793123,    0.42616072,    0.5304293,    0.7325272,     0.7594884,
+    0.19274779,   0.02070892,   0.27827948,   0.8051665,    0.83692664,    0.020188946,  0.35914233,    0.49547768,
+    0.70504993,   0.07394841,   0.525945,     0.5723259,    0.8678083,     0.5818202,    0.8266031,     0.017404223,
+    0.27958027,   0.84272736,   0.7281345,    0.8994748,    0.3798963,     0.5602465,    0.8170057,     0.5437445,
+    0.9112873,    0.43589205,   0.5874092,    0.4374235,    0.68844056,    0.057151183,  0.1732611,     0.58042514,
+    0.35312688,   0.2791384,    0.23987181,   0.26006386,   0.9232113,     0.94478124,   0.9187956,     0.93770313,
+    0.50281125,   0.31585902,   0.9830553,    0.38102284,   0.8167936,     0.008173941,  0.24676272,    0.16458233,
+    0.06555225,   0.5648193,    0.39973202,   0.58343333,   0.8022948,     0.8330524,    0.3795921,     0.63250124,
+    0.20370321,   0.734535,     0.8938792,    0.40103462,   0.43277976,    0.92171884,   0.8070371,     0.64789873,
+    0.9006873,    0.94551986,   0.21919903,   0.5886699,    0.34194836,    0.5665393,    0.09419294,    0.33479902,
+    0.92393184,   0.7904314,    0.39666355,   0.0640373,    0.5771913,     0.43598288,   0.7269509,     0.90311337,
+    0.18912931,   0.42282686,   0.37187123,   0.12362129,   0.65741915,    0.5898278,    0.77813035,    0.5200745,
+    0.8995463,    0.6073706,    0.056360655,  0.18867631,   0.05090209,    0.51776093,   0.5049234,     0.5810924,
+    0.5088219,    0.3351565,    0.48033553,   0.87127376,   0.7889749,     0.65809286,   0.822634,      0.49901298,
+    0.47062632,   0.064933024,  0.65950155,   0.0118634105, 0.43638885,    0.3155548,    0.055309944,   0.76772034,
+    0.007584079,  0.9907658,    0.2119053,    0.0099529,    0.5498476,     0.68341583,   0.9904796,     0.31085956,
+    0.16738948,   0.6991246,    0.6891236,    0.7345778,    0.5101786,     0.9055166,    0.28389692,    0.40617087,
+    0.285508,     0.8155711,    0.5552154,    0.24203478,   0.95564735,    0.8556771,    0.11413846,    0.53103644,
+    0.6001929,    0.8728583,    0.652995,     0.59248614,   0.9303262,     0.76626694,   0.083685614,   0.5839915,
+    0.55206066,   0.28864032,   0.18109223,   0.06013629,   0.30585563,    0.49497047,   0.031244803,   0.8254061,
+    0.34467688,   0.16947599,   0.70388424,   0.089850344,  0.9689693,     0.088056214,  0.9888344,     0.56510967,
+    0.7810361,    0.25333068,   0.72635543,   0.6208177,    0.7603394,     0.81327516,   0.812073,      0.15190694,
+    0.8766273,    0.68086886,   0.40976003,   0.6769893,    0.03042084,    0.39799348,   0.38053334,    0.40112254,
+    0.61543894,   0.10513203,   0.18251711,   0.22153829,   0.7244244,     0.22376063,   0.10031522,    0.79053754,
+    0.7843263,    0.7298093,    0.8973579,    0.7861713,    0.15179288,    0.024288114,  0.56206715,    0.51213664,
+    0.8840239,    0.08788527,   0.81145,      0.6769955,    0.039911535,   0.4628679,    0.82365215,    0.7387855,
+    0.47656733,   0.029185295,  0.18350895,   0.62498677,   0.08521046,    0.35425547,   0.7949853,     0.9466834,
+    0.78894264,   0.30276173,   0.4744114,    0.86383724,   0.9055391,     0.7672961,    0.8406853,     0.5572755,
+    0.15301545,   0.9358179,    0.83649135,   0.030530108,  0.9159173,     0.025901658,  0.00011405395, 0.8523392,
+    0.1188017,    0.89762336,   0.7929654,    0.9425356,    0.58654344,    0.7035378,    0.361211,      0.15257105,
+    0.2814799,    0.44373164,   0.744971,     0.6952391,    0.040251687,   0.47532842,   0.70532703,    0.43007088,
+    0.93482405,   0.9506745,    0.9972287,    0.84903115,   0.5498767,     0.6982299,    0.60659754,    0.116727814,
+    0.24719998,   0.25417453,   0.5239801,    0.10409364,   0.6263765,     0.79312205,   0.82286817,    0.45066565,
+    0.02907124,   0.33116972,   0.5061851,    0.1875871,    0.56129,       0.8524497,    0.36013994,    0.085404865,
+    0.94155073,   0.32184035,   0.58235735,   0.46180746,   0.022325099,   0.14544618,   0.5170238,     0.67768705,
+    0.23049083,   0.4064205,    0.09570609,   0.9652428,    0.028672969,   0.1510829,    0.30246252,    0.4205718,
+    0.2910258,    0.67623764,   0.69533557,   0.33236894,   0.17955771,    0.25711736,   0.5261945,     0.48835787};
 
 float rndf() {
-       static int _cur_rnd = 0;
-       if (_cur_rnd > _rnd_count)
-               _cur_rnd = 0;
-       return _rnd[_cur_rnd++];
+    static int _cur_rnd = 0;
+    if (_cur_rnd > _rnd_count)
+        _cur_rnd = 0;
+    return _rnd[_cur_rnd++];
 }
index c583f8fbe396855369d08e7367148357b2cc2648..02959939efdd71465a05676ab1c48d30b9d94d2b 100644 (file)
 #include <string.h>
 
 #if defined(_WIN32) || defined(_WIN64)
-int gettimeofday(struct timeval * tp, void * tzp)
-{
-       // FILETIME Jan 1 1970 00:00:00
-       // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
-       static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
-
-       SYSTEMTIME  nSystemTime;
-       FILETIME    nFileTime;
-       uint64_t    nTime;
-
-       GetSystemTime( &nSystemTime );
-       SystemTimeToFileTime( &nSystemTime, &nFileTime );
-       nTime =  ((uint64_t)nFileTime.dwLowDateTime )      ;
-       nTime += ((uint64_t)nFileTime.dwHighDateTime) << 32;
-
-       tp->tv_sec  = (long) ((nTime - EPOCH) / 10000000L);
-       tp->tv_usec = (long) (nSystemTime.wMilliseconds * 1000);
-       return 0;
+int gettimeofday(struct timeval *tp, void *tzp) {
+    // FILETIME Jan 1 1970 00:00:00
+    // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+    static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);
+
+    SYSTEMTIME nSystemTime;
+    FILETIME   nFileTime;
+    uint64_t   nTime;
+
+    GetSystemTime(&nSystemTime);
+    SystemTimeToFileTime(&nSystemTime, &nFileTime);
+    nTime = ((uint64_t)nFileTime.dwLowDateTime);
+    nTime += ((uint64_t)nFileTime.dwHighDateTime) << 32;
+
+    tp->tv_sec  = (long)((nTime - EPOCH) / 10000000L);
+    tp->tv_usec = (long)(nSystemTime.wMilliseconds * 1000);
+    return 0;
 }
 #endif
 
-float panX     = 0.f;
-float panY     = 0.f;
-float lastX = 0.f;
-float lastY = 0.f;
-float zoom     = 1.0f;
-bool mouseDown = false;
-
-VkvgDevice device      = NULL;
-VkvgSurface surf       = NULL;
-
-uint32_t test_size     = 500;  // items drawn in one run, or complexity
-uint32_t iterations    = 500;  // repeat test n times
-uint32_t test_width    = 512;
-uint32_t test_height= 512;
-bool   test_vsync      = false;
-bool   quiet           = false;//if true, don't print details and head row
-bool   first_test      = true; //if multiple tests, dont print header row.
-bool   no_test_size= false;//several test consist of a single draw sequence without looping 'size' times
-                                                       //those test must be preceded by setting no_test_size to 'true'
-int    test_index      = 0;
-int            single_test = -1;       //if not < 0, contains the index of the single test to run
-
-
-static bool paused             = false;
-static bool offscreen  = false;
-static bool threadAware        = false;
-static VkSampleCountFlags samples = VK_SAMPLE_COUNT_1_BIT;
+float panX      = 0.f;
+float panY      = 0.f;
+float lastX     = 0.f;
+float lastY     = 0.f;
+float zoom      = 1.0f;
+bool  mouseDown = false;
+
+VkvgDevice  device = NULL;
+VkvgSurface surf   = NULL;
+
+uint32_t test_size    = 500; // items drawn in one run, or complexity
+uint32_t iterations   = 500; // repeat test n times
+uint32_t test_width   = 512;
+uint32_t test_height  = 512;
+bool     test_vsync   = false;
+bool     quiet        = false; // if true, don't print details and head row
+bool     first_test   = true;  // if multiple tests, dont print header row.
+bool     no_test_size = false; // several test consist of a single draw sequence without looping 'size' times
+                           // those test must be preceded by setting no_test_size to 'true'
+int test_index  = 0;
+int single_test = -1; // if not < 0, contains the index of the single test to run
+
+static bool                 paused                     = false;
+static bool                 offscreen                  = false;
+static bool                 threadAware                = false;
+static VkSampleCountFlags   samples                    = VK_SAMPLE_COUNT_1_BIT;
 static VkPhysicalDeviceType preferedPhysicalDeviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
-static vk_engine_te;
-static charsaveToPng = NULL;
-
-static void key_callback(GLFWwindowwindow, int key, int scancode, int action, int mods) {
-       if (action != GLFW_PRESS)
-               return;
-       switch (key) {
-       case GLFW_KEY_SPACE:
-                paused = !paused;
-               break;
-       case GLFW_KEY_ESCAPE :
-               glfwSetWindowShouldClose(window, GLFW_TRUE);
-               break;
+static vk_engine_t         *e;
+static char                *saveToPng = NULL;
+
+static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
+    if (action != GLFW_PRESS)
+        return;
+    switch (key) {
+    case GLFW_KEY_SPACE:
+        paused = !paused;
+        break;
+    case GLFW_KEY_ESCAPE:
+        glfwSetWindowShouldClose(window, GLFW_TRUE);
+        break;
 #ifdef VKVG_WIRED_DEBUG
-       case GLFW_KEY_F1:
-               vkvg_wired_debug ^= (1U << 0);
-               break;
-       case GLFW_KEY_F2:
-               vkvg_wired_debug ^= (1U << 1);
-               break;
-       case GLFW_KEY_F3:
-               vkvg_wired_debug ^= (1U << 2);
-               break;
+    case GLFW_KEY_F1:
+        vkvg_wired_debug ^= (1U << 0);
+        break;
+    case GLFW_KEY_F2:
+        vkvg_wired_debug ^= (1U << 1);
+        break;
+    case GLFW_KEY_F3:
+        vkvg_wired_debug ^= (1U << 2);
+        break;
 #endif
-       }
+    }
 }
-static void char_callback (GLFWwindow* window, uint32_t c){}
-static void mouse_move_callback(GLFWwindow* window, double x, double y){
-       if (mouseDown) {
-               panX += ((float)x-lastX);
-               panY += ((float)y-lastY);
-       }
-       lastX = (float)x;
-       lastY = (float)y;
+static void char_callback(GLFWwindow *window, uint32_t c) {}
+static void mouse_move_callback(GLFWwindow *window, double x, double y) {
+    if (mouseDown) {
+        panX += ((float)x - lastX);
+        panY += ((float)y - lastY);
+    }
+    lastX = (float)x;
+    lastY = (float)y;
 }
-static void scroll_callback(GLFWwindow* window, double x, double y){
-       if (y<0.f)
-               zoom *= 0.5f;
-       else
-               zoom *= 2.0f;
+static void scroll_callback(GLFWwindow *window, double x, double y) {
+    if (y < 0.f)
+        zoom *= 0.5f;
+    else
+        zoom *= 2.0f;
 }
-static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){
-       if (but != GLFW_MOUSE_BUTTON_1)
-               return;
-       if (state == GLFW_TRUE)
-               mouseDown = true;
-       else
-               mouseDown = false;
+static void mouse_button_callback(GLFWwindow *window, int but, int state, int modif) {
+    if (but != GLFW_MOUSE_BUTTON_1)
+        return;
+    if (state == GLFW_TRUE)
+        mouseDown = true;
+    else
+        mouseDown = false;
 }
 
-double time_diff(struct timeval x , struct timeval y)
-{
-       double x_ms , y_ms , diff;
+double time_diff(struct timeval x, struct timeval y) {
+    double x_ms, y_ms, diff;
 
-       x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec;
-       y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec;
+    x_ms = (double)x.tv_sec * 1000000 + (double)x.tv_usec;
+    y_ms = (double)y.tv_sec * 1000000 + (double)y.tv_usec;
 
-       diff = (double)y_ms - (double)x_ms;
+    diff = (double)y_ms - (double)x_ms;
 
-       return diff;
+    return diff;
 }
 
 /* from caskbench */
-double get_tick (void)
-{
-       struct timeval now;
-       gettimeofday (&now, NULL);
-       return (double)now.tv_sec + (double)now.tv_usec / 1000000.0;
+double get_tick(void) {
+    struct timeval now;
+    gettimeofday(&now, NULL);
+    return (double)now.tv_sec + (double)now.tv_usec / 1000000.0;
 }
-double median_run_time (double data[], int n)
-{
-       double temp;
-       int i, j;
-       for (i = 0; i < n; i++)
-               for (j = i+1; j < n; j++)
-               {
-                       if (data[i] > data[j])
-                       {
-                               temp = data[j];
-                               data[j] = data[i];
-                               data[i] = temp;
-                       }
-               }
-       if (n % 2 == 0)
-               return (data[n/2] + data[n/2-1])/2;
-       return data[n/2];
+double median_run_time(double data[], int n) {
+    double temp;
+    int    i, j;
+    for (i = 0; i < n; i++)
+        for (j = i + 1; j < n; j++) {
+            if (data[i] > data[j]) {
+                temp    = data[j];
+                data[j] = data[i];
+                data[i] = temp;
+            }
+        }
+    if (n % 2 == 0)
+        return (data[n / 2] + data[n / 2 - 1]) / 2;
+    return data[n / 2];
 }
-double standard_deviation (const double data[], int n, double mean)
-{
-       double sum_deviation = 0.0;
-       int i;
-       for (i = 0; i < n; ++i)
-       sum_deviation += (data[i]-mean) * (data[i]-mean);
-       return sqrt (sum_deviation / n);
+double standard_deviation(const double data[], int n, double mean) {
+    double sum_deviation = 0.0;
+    int    i;
+    for (i = 0; i < n; ++i)
+        sum_deviation += (data[i] - mean) * (data[i] - mean);
+    return sqrt(sum_deviation / n);
 }
 /***************/
 
-void init_test (uint32_t width, uint32_t height){
-       if (test_vsync)
-               e = vkengine_create (preferedPhysicalDeviceType, VK_PRESENT_MODE_FIFO_KHR, width, height);
-       else
-               e = vkengine_create (preferedPhysicalDeviceType, VK_PRESENT_MODE_MAILBOX_KHR, width, height);
+void init_test(uint32_t width, uint32_t height) {
+    if (test_vsync)
+        e = vkengine_create(preferedPhysicalDeviceType, VK_PRESENT_MODE_FIFO_KHR, width, height);
+    else
+        e = vkengine_create(preferedPhysicalDeviceType, VK_PRESENT_MODE_MAILBOX_KHR, width, height);
 
-       VkhPresenter r = e->renderer;
-       vkengine_set_key_callback (e, key_callback);
-       vkengine_set_mouse_but_callback(e, mouse_button_callback);
-       vkengine_set_cursor_pos_callback(e, mouse_move_callback);
-       vkengine_set_scroll_callback(e, scroll_callback);
+    VkhPresenter r = e->renderer;
+    vkengine_set_key_callback(e, key_callback);
+    vkengine_set_mouse_but_callback(e, mouse_button_callback);
+    vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+    vkengine_set_scroll_callback(e, scroll_callback);
 
-    vkvg_device_create_info_t info = {
-        samples,
-        false,
-        vkh_app_get_inst(e->app),
-        r->dev->phy,
-        r->dev->dev,
-        r->qFam,
-        0
-    };
+    vkvg_device_create_info_t info = {samples, false, vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0};
 
     device = vkvg_device_create(&info);
-       surf = vkvg_surface_create(device, width, height);
+    surf   = vkvg_surface_create(device, width, height);
 
-       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height);
+    vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), width, height);
 }
-void clear_test () {
-       vkDeviceWaitIdle(e->dev->dev);
+void clear_test() {
+    vkDeviceWaitIdle(e->dev->dev);
 
-       vkvg_surface_destroy    (surf);
-       vkvg_device_destroy     (device);
+    vkvg_surface_destroy(surf);
+    vkvg_device_destroy(device);
 
-       vkengine_destroy (e);
+    vkengine_destroy(e);
 }
 
 #ifdef VKVG_TEST_DIRECT_DRAW
-VkvgSurfacesurfaces;
+VkvgSurface *surfaces;
 #endif
-void _print_usage_and_exit () {
-       printf("\nUsage: test [options]\n\n");
-       printf("\t-i iterations:\tSpecify the repeat count for the test.\n");
-       printf("\t-s size:\tWhen applicable, specify the size of the test.\n");
-       printf("\t-x width:\tOutput surface width.\n");
-       printf("\t-y height:\tOutput surface height.\n");
-       printf("\t-S num samples:\tOutput surface filter, default is 1.\n");
+void _print_usage_and_exit() {
+    printf("\nUsage: test [options]\n\n");
+    printf("\t-i iterations:\tSpecify the repeat count for the test.\n");
+    printf("\t-s size:\tWhen applicable, specify the size of the test.\n");
+    printf("\t-x width:\tOutput surface width.\n");
+    printf("\t-y height:\tOutput surface height.\n");
+    printf("\t-S num samples:\tOutput surface filter, default is 1.\n");
     printf("\t-g gpu_type:\tSet prefered GPU type:\n");
-       printf("\t\t\t - 0: Other\n");
-       printf("\t\t\t - 1: Integrated (second choice)\n");
-       printf("\t\t\t - 2: Discrete (first choice)\n");
-       printf("\t\t\t - 3: Virtual\n");
-       printf("\t\t\t - 4: Cpu\n");
-       printf("\t-l line_width:\tset lines width for stokes.\n");
-       printf("\t-j line_join:\tset line joins for strokes:\n");
-       printf("\t\t\t - m: Mitter(default)\n");
-       printf("\t\t\t - r: Rount\n");
-       printf("\t\t\t - b: Bevel\n");
-       printf("\t-c line_cap:\tset line caps for strokes:\n");
-       printf("\t\t\t - b: Butt (default)\n");
-       printf("\t\t\t - r: Rount\n");
-       printf("\t\t\t - s: Square\n");
-       printf("\t-f fill_rule:\tset current fill rule:\n");
-       printf("\t\t\t - 0: Even Odd\n");
-       printf("\t\t\t - 1: Non Zero\n");
-       printf("\t-d:\t\tenable dashes.\n");
-       printf("\t-n index:\tRun only a single test, zero based index.\n");
-       printf("\t-q:\t\tQuiet, don't print measures table head row, usefull for batch tests.\n");
-       printf("\t-t:\t\tThread aware, set device in multithreading aware mode.\n");
-       printf("\t-p:\t\tPrint test details and exit without performing test, usefull to print details in logs.\n");
-       printf("\t-vsync:\t\tEnable VSync, disabled by default.\n");
-       printf("\t-o:\t\tPerform test offscreen.\n");
-       printf("\t-w filepath:\twrite last image to png.\n");
+    printf("\t\t\t - 0: Other\n");
+    printf("\t\t\t - 1: Integrated (second choice)\n");
+    printf("\t\t\t - 2: Discrete (first choice)\n");
+    printf("\t\t\t - 3: Virtual\n");
+    printf("\t\t\t - 4: Cpu\n");
+    printf("\t-l line_width:\tset lines width for stokes.\n");
+    printf("\t-j line_join:\tset line joins for strokes:\n");
+    printf("\t\t\t - m: Mitter(default)\n");
+    printf("\t\t\t - r: Rount\n");
+    printf("\t\t\t - b: Bevel\n");
+    printf("\t-c line_cap:\tset line caps for strokes:\n");
+    printf("\t\t\t - b: Butt (default)\n");
+    printf("\t\t\t - r: Rount\n");
+    printf("\t\t\t - s: Square\n");
+    printf("\t-f fill_rule:\tset current fill rule:\n");
+    printf("\t\t\t - 0: Even Odd\n");
+    printf("\t\t\t - 1: Non Zero\n");
+    printf("\t-d:\t\tenable dashes.\n");
+    printf("\t-n index:\tRun only a single test, zero based index.\n");
+    printf("\t-q:\t\tQuiet, don't print measures table head row, usefull for batch tests.\n");
+    printf("\t-t:\t\tThread aware, set device in multithreading aware mode.\n");
+    printf("\t-p:\t\tPrint test details and exit without performing test, usefull to print details in logs.\n");
+    printf("\t-vsync:\t\tEnable VSync, disabled by default.\n");
+    printf("\t-o:\t\tPerform test offscreen.\n");
+    printf("\t-w filepath:\twrite last image to png.\n");
 #ifdef DEBUG
-       printf("\t-L level:\tLog level in hexadecimal format (0xFF), 0 to disable.\n");
-       printf("\t\t\tsee vkvg.h for possible values.\n");
+    printf("\t-L level:\tLog level in hexadecimal format (0xFF), 0 to disable.\n");
+    printf("\t\t\tsee vkvg.h for possible values.\n");
 #endif
 
-       printf("\t-h:\t\tThis help message.\n");
-       printf("\n");
-       exit(-1);
+    printf("\t-h:\t\tThis help message.\n");
+    printf("\n");
+    exit(-1);
 }
-void _parse_args (int argc, char* argv[]) {
-       bool printTestDetailsAndExit = false;
-       for (int i = 1; i < argc; i++) {
-               if (strcmp (argv[i], "-h\0") == 0)
-                       _print_usage_and_exit ();
-               if (strcmp (argv[i], "-p\0") == 0)
-                       printTestDetailsAndExit = true;
-               else if (strcmp (argv[i], "-vsync\0") == 0)
-                       test_vsync = true;
-               else if (strcmp(argv[i], "-q\0") == 0)
-                       quiet = true;
-               else if (strcmp(argv[i], "-t\0") == 0)
-                       threadAware = true;
-               else if (strcmp (argv[i], "-i\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       iterations = atoi (argv[i]);
-               }else if (strcmp (argv[i], "-x\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       test_width = atoi (argv[i]);
-               }else if (strcmp (argv[i], "-y\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       test_height = atoi (argv[i]);
-               }else if (strcmp (argv[i], "-n\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       single_test = atoi (argv[i]);
-               }else if (strcmp (argv[i], "-s\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       test_size = atoi (argv[i]);
-               }else if (strcmp (argv[i], "-S\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       samples = (VkSampleCountFlags)atoi (argv[i]);
-               }else if (strcmp (argv[i], "-g\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       preferedPhysicalDeviceType = (VkPhysicalDeviceType)atoi (argv[i]);
-               }else if (strcmp (argv[i], "-l\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       line_width = atoi (argv[i]);
-               }else if (strcmp (argv[i], "-d\0") == 0) {
-                       dashes_count = 2;
-               }else if (strcmp (argv[i], "-f\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       fill_rule = atoi (argv[i]);
-               } else if (strcmp (argv[i], "-o\0") == 0) {
-                       offscreen = true;
-               }else if (strcmp (argv[i], "-j\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       switch (argv[i][0]) {
-                       case 'm':
-                               line_join = VKVG_LINE_JOIN_MITER;
-                               break;
-                       case 'r':
-                               line_join = VKVG_LINE_JOIN_ROUND;
-                               break;
-                       case 'b':
-                               line_join = VKVG_LINE_JOIN_BEVEL;
-                               break;
-                       default:
-                               _print_usage_and_exit();
-                       }
-               }else if (strcmp (argv[i], "-c\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       switch (argv[i][0]) {
-                       case 'b':
-                               line_cap = VKVG_LINE_CAP_BUTT;
-                               break;
-                       case 'r':
-                               line_cap = VKVG_LINE_CAP_ROUND;
-                               break;
-                       case 's':
-                               line_cap = VKVG_LINE_CAP_SQUARE;
-                               break;
-                       default:
-                               _print_usage_and_exit();
-                       }
-               }else if (strcmp (argv[i], "-w\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       saveToPng = argv[i];
+void _parse_args(int argc, char *argv[]) {
+    bool printTestDetailsAndExit = false;
+    for (int i = 1; i < argc; i++) {
+        if (strcmp(argv[i], "-h\0") == 0)
+            _print_usage_and_exit();
+        if (strcmp(argv[i], "-p\0") == 0)
+            printTestDetailsAndExit = true;
+        else if (strcmp(argv[i], "-vsync\0") == 0)
+            test_vsync = true;
+        else if (strcmp(argv[i], "-q\0") == 0)
+            quiet = true;
+        else if (strcmp(argv[i], "-t\0") == 0)
+            threadAware = true;
+        else if (strcmp(argv[i], "-i\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            iterations = atoi(argv[i]);
+        } else if (strcmp(argv[i], "-x\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            test_width = atoi(argv[i]);
+        } else if (strcmp(argv[i], "-y\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            test_height = atoi(argv[i]);
+        } else if (strcmp(argv[i], "-n\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            single_test = atoi(argv[i]);
+        } else if (strcmp(argv[i], "-s\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            test_size = atoi(argv[i]);
+        } else if (strcmp(argv[i], "-S\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            samples = (VkSampleCountFlags)atoi(argv[i]);
+        } else if (strcmp(argv[i], "-g\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            preferedPhysicalDeviceType = (VkPhysicalDeviceType)atoi(argv[i]);
+        } else if (strcmp(argv[i], "-l\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            line_width = atoi(argv[i]);
+        } else if (strcmp(argv[i], "-d\0") == 0) {
+            dashes_count = 2;
+        } else if (strcmp(argv[i], "-f\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            fill_rule = atoi(argv[i]);
+        } else if (strcmp(argv[i], "-o\0") == 0) {
+            offscreen = true;
+        } else if (strcmp(argv[i], "-j\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            switch (argv[i][0]) {
+            case 'm':
+                line_join = VKVG_LINE_JOIN_MITER;
+                break;
+            case 'r':
+                line_join = VKVG_LINE_JOIN_ROUND;
+                break;
+            case 'b':
+                line_join = VKVG_LINE_JOIN_BEVEL;
+                break;
+            default:
+                _print_usage_and_exit();
+            }
+        } else if (strcmp(argv[i], "-c\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            switch (argv[i][0]) {
+            case 'b':
+                line_cap = VKVG_LINE_CAP_BUTT;
+                break;
+            case 'r':
+                line_cap = VKVG_LINE_CAP_ROUND;
+                break;
+            case 's':
+                line_cap = VKVG_LINE_CAP_SQUARE;
+                break;
+            default:
+                _print_usage_and_exit();
+            }
+        } else if (strcmp(argv[i], "-w\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            saveToPng = argv[i];
 #ifdef DEBUG
-               }else if (strcmp (argv[i], "-L\0") == 0) {
-                       if (argc -1 < ++i)
-                               _print_usage_and_exit();
-                       sscanf(argv[i], "%x", &vkvg_log_level);
+        } else if (strcmp(argv[i], "-L\0") == 0) {
+            if (argc - 1 < ++i)
+                _print_usage_and_exit();
+            sscanf(argv[i], "%x", &vkvg_log_level);
 #endif
-               }else
-                       _print_usage_and_exit();
-       }
-       if (printTestDetailsAndExit) {
+        else
+            _print_usage_and_exit();
+    }
+    if (printTestDetailsAndExit) {
 #ifdef DEBUG
-               printf("Debug build\n");
+        printf("Debug build\n");
 #else
-               printf("Release build\n");
+        printf("Release build\n");
 #endif
 #ifdef VKVG_USE_RENDERDOC
-               printf("Render doc enabled\n");
+        printf("Render doc enabled\n");
 #endif
 #ifdef VKVG_USE_VALIDATION
-               printf("Validation:\tenabled\n");
+        printf("Validation:\tenabled\n");
 #else
-               printf("Validation:\no\n");
+        printf("Validation:\no\n");
 #endif
-               printf("surf dims:\t%d x %d\n", test_width, test_height);
-               printf("Samples:\t%d\n", samples);
-               printf("Gpu type:\t");
-               switch (preferedPhysicalDeviceType) {
-               case VK_PHYSICAL_DEVICE_TYPE_OTHER:
-                       printf("Other\n");
-                       break;
-               case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
-                       printf("Integrated\n");
-                       break;
-               case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
-                       printf("Discrete\n");
-                       break;
-               case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
-                       printf("Virtual\n");
-                       break;
-               case VK_PHYSICAL_DEVICE_TYPE_CPU:
-                       printf("CPU\n");
-                       break;
-               }
-
-               if (offscreen)
-                       printf("Offscreen:\ttrue\n");
-               else
-                       printf("Offscreen:\tfalse\n");
-
-               if (fill_rule == VKVG_FILL_RULE_EVEN_ODD)
-                       printf("Fillrule:\tEven/Odd\n");
-               else
-                       printf("Fillrule:\tNon zero\n");
-
-               printf("\n");
-               exit(0);
-       }
+        printf("surf dims:\t%d x %d\n", test_width, test_height);
+        printf("Samples:\t%d\n", samples);
+        printf("Gpu type:\t");
+        switch (preferedPhysicalDeviceType) {
+        case VK_PHYSICAL_DEVICE_TYPE_OTHER:
+            printf("Other\n");
+            break;
+        case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
+            printf("Integrated\n");
+            break;
+        case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
+            printf("Discrete\n");
+            break;
+        case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
+            printf("Virtual\n");
+            break;
+        case VK_PHYSICAL_DEVICE_TYPE_CPU:
+            printf("CPU\n");
+            break;
+        }
+
+        if (offscreen)
+            printf("Offscreen:\ttrue\n");
+        else
+            printf("Offscreen:\tfalse\n");
+
+        if (fill_rule == VKVG_FILL_RULE_EVEN_ODD)
+            printf("Fillrule:\tEven/Odd\n");
+        else
+            printf("Fillrule:\tNon zero\n");
+
+        printf("\n");
+        exit(0);
+    }
 }
 
-void _print_results (const char *testName, int argc, char* argv[], uint32_t i, double run_total, double* run_time_values) {
-       char* whoami;
-       (whoami = strrchr(argv[0], '/')) ? ++whoami : (whoami = argv[0]);
+void _print_results(const char *testName, int argc, char *argv[], uint32_t i, double run_total,
+                    double *run_time_values) {
+    char *whoami;
+    (whoami = strrchr(argv[0], '/')) ? ++whoami : (whoami = argv[0]);
 
-       double avg_run_time = run_total / (double)i;
-       double med_run_time = median_run_time (run_time_values, i);
-       double standard_dev = standard_deviation (run_time_values, i, avg_run_time);
-       double avg_frames_per_second = (1.0 / avg_run_time);
-       avg_frames_per_second = (avg_frames_per_second<9999) ? avg_frames_per_second:9999;
+    double avg_run_time          = run_total / (double)i;
+    double med_run_time          = median_run_time(run_time_values, i);
+    double standard_dev          = standard_deviation(run_time_values, i, avg_run_time);
+    double avg_frames_per_second = (1.0 / avg_run_time);
+    avg_frames_per_second        = (avg_frames_per_second < 9999) ? avg_frames_per_second : 9999;
 
-       if (!quiet && (test_index == 0 || test_index == single_test)) {
+    if (!quiet && (test_index == 0 || test_index == single_test)) {
 #if VKVG_DBG_STATS
-               printf ("_____________________________________________________________________________________________________________________________\n");
-               printf ("| N° | Test File Name  |       Sub Test            | Iter | Size |  Pts  |Pathes| Vx cache | Ix cache |   VBO    |   IBO    |\n");
-               printf ("|----|-----------------|---------------------------|------|------|-------|------|----------|----------|----------|----------|\n");
+        printf("_______________________________________________________________________________________________________"
+               "______________________\n");
+        printf("| N° | Test File Name  |       Sub Test            | Iter | Size |  Pts  |Pathes| Vx cache | Ix cache "
+               "|   VBO    |   IBO    |\n");
+        printf("|----|-----------------|---------------------------|------|------|-------|------|----------|----------|"
+               "----------|----------|\n");
 #else
-               printf ("__________________________________________________________________________________________________________\n");
-               printf ("| N° | Test File Name  |       Sub Test            | Iter | Size |   FPS   | Average | Median  | Sigma   |\n");
-               printf ("|----|-----------------|---------------------------|------|------|---------|---------|---------|---------|\n");
+        printf("_______________________________________________________________________________________________________"
+               "___\n");
+        printf("| N° | Test File Name  |       Sub Test            | Iter | Size |   FPS   | Average | Median  | Sigma "
+               "  |\n");
+        printf("|----|-----------------|---------------------------|------|------|---------|---------|---------|-------"
+               "--|\n");
 #endif
-       }
-       
-       printf ("| %2d | %-15s | %-25s | %4d | ", test_index, whoami, testName, i);
-       if (no_test_size)
-               printf ("%4d | ", 1);
-       else
-               printf ("%4d | ", test_size);
+    }
+
+    printf("| %2d | %-15s | %-25s | %4d | ", test_index, whoami, testName, i);
+    if (no_test_size)
+        printf("%4d | ", 1);
+    else
+        printf("%4d | ", test_size);
 
 #if VKVG_DBG_STATS
-       vkvg_debug_stats_t dbgStats = vkvg_device_get_stats (device);   
-       printf ("%5d | %4d | %8d | %8d | %8d | %8d |\n",
-                       dbgStats.sizePoints, dbgStats.sizePathes, dbgStats.sizeVertices,
-                       dbgStats.sizeIndices, dbgStats.sizeVBO, dbgStats.sizeIBO);
-#else  
-       printf ("%7.2f | %6.5f | %6.5f | %6.5f |\n",
-               avg_frames_per_second, avg_run_time, med_run_time, standard_dev);
-#endif 
+    vkvg_debug_stats_t dbgStats = vkvg_device_get_stats(device);
+    printf("%5d | %4d | %8d | %8d | %8d | %8d |\n", dbgStats.sizePoints, dbgStats.sizePathes, dbgStats.sizeVertices,
+           dbgStats.sizeIndices, dbgStats.sizeVBO, dbgStats.sizeIBO);
+#else
+    printf("%7.2f | %6.5f | %6.5f | %6.5f |\n", avg_frames_per_second, avg_run_time, med_run_time, standard_dev);
+#endif
 }
 
 #if VKVG_DBG_STATS
-void _print_debug_stats () {
+void _print_debug_stats() {
 
-       vkvg_debug_stats_t dbgStats = vkvg_device_get_stats (device);
-       printf ("| %8d | %8d | %8d | %8d | %8d | %8d |\n", dbgStats.sizePoints, dbgStats.sizePathes, dbgStats.sizeVertices,
-                       dbgStats.sizeIndices, dbgStats.sizeVBO, dbgStats.sizeIBO);
+    vkvg_debug_stats_t dbgStats = vkvg_device_get_stats(device);
+    printf("| %8d | %8d | %8d | %8d | %8d | %8d |\n", dbgStats.sizePoints, dbgStats.sizePathes, dbgStats.sizeVertices,
+           dbgStats.sizeIndices, dbgStats.sizeVBO, dbgStats.sizeIBO);
 }
 #endif
 
-void perform_test (void(*testfunc)(void), const char *testName, int argc, char* argv[]) {
-       setlocale(LC_ALL, "");
-       //dumpLayerExts();
-       _parse_args (argc, argv);
+void perform_test(void (*testfunc)(void), const char *testName, int argc, char *argv[]) {
+    setlocale(LC_ALL, "");
+    // dumpLayerExts();
+    _parse_args(argc, argv);
 
-       //init random gen
-       struct timeval currentTime;
-       gettimeofday(&currentTime, NULL);
-       srand((unsigned)currentTime.tv_usec);
+    // init random gen
+    struct timeval currentTime;
+    gettimeofday(&currentTime, NULL);
+    srand((unsigned)currentTime.tv_usec);
 
-       if (iterations == 0)
-               iterations = 9999;
+    if (iterations == 0)
+        iterations = 9999;
 
-       if (single_test >= 0 && test_index != single_test) {
-               test_index++;
-               return;
-       }
+    if (single_test >= 0 && test_index != single_test) {
+        test_index++;
+        return;
+    }
 
-       if (offscreen)
-               perform_test_offscreen(testfunc, testName, argc, argv);
-       else
-               perform_test_onscreen(testfunc, testName, argc, argv);
+    if (offscreen)
+        perform_test_offscreen(testfunc, testName, argc, argv);
+    else
+        perform_test_onscreen(testfunc, testName, argc, argv);
 }
 
-void perform_test_offscreen (void(*testfunc)(void), const char *testName, int argc, char* argv[]) {
-       uint32_t enabledExtsCount = 0, phyCount = 0;
-       const char* enabledExts [10];
+void perform_test_offscreen(void (*testfunc)(void), const char *testName, int argc, char *argv[]) {
+    uint32_t    enabledExtsCount = 0, phyCount = 0;
+    const char *enabledExts[10];
 #ifdef VKVG_USE_RENDERDOC
-       const uint32_t enabledLayersCount = 2;
-       const char* enabledLayers[] = {"VK_LAYER_KHRONOS_validation", "VK_LAYER_RENDERDOC_Capture"};
-#elif defined (VKVG_USE_VALIDATION)
-       const uint32_t enabledLayersCount = 1;
-       const char* enabledLayers[] = {"VK_LAYER_KHRONOS_validation"};
+    const uint32_t enabledLayersCount = 2;
+    const char    *enabledLayers[]    = {"VK_LAYER_KHRONOS_validation", "VK_LAYER_RENDERDOC_Capture"};
+#elif defined(VKVG_USE_VALIDATION)
+    const uint32_t enabledLayersCount = 1;
+    const char    *enabledLayers[]    = {"VK_LAYER_KHRONOS_validation"};
 #else
-       const uint32_t enabledLayersCount = 0;
-       const char* enabledLayers[] = {NULL};
+    const uint32_t enabledLayersCount = 0;
+    const char    *enabledLayers[]    = {NULL};
 #endif
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       enabledExts[enabledExtsCount] = "VK_EXT_debug_utils";
-       enabledExtsCount++;
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    enabledExts[enabledExtsCount] = "VK_EXT_debug_utils";
+    enabledExtsCount++;
 #endif
 
-       VkhApp app = vkh_app_create(1, 1, "vkvgTest", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_app_enable_debug_messenger(app
-                                                                  , VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
-                                                                  | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
-                                                                  | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
-                                                                  , VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
-                                                                  | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
-                                                                  //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
-                                                                  //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
-                                                                  , NULL);
+    VkhApp app = vkh_app_create(1, 1, "vkvgTest", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_app_enable_debug_messenger(
+        app,
+        VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
+            VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
+        VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
+        //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
+        //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
+        ,
+        NULL);
 #endif
-       bool deferredResolve = false;
-       VkhPhyInfo* phys = vkh_app_get_phyinfos (app, &phyCount, VK_NULL_HANDLE);
-       VkhPhyInfo pi = 0;
-       if (!vkengine_try_get_phyinfo(phys, phyCount, preferedPhysicalDeviceType, &pi))
-               if (!vkengine_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, &pi))
-                       if (!vkengine_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, &pi))
-                               pi = phys[0];
-
-       uint32_t qCount = 0;
-       float qPriorities[] = {0.0};
-       VkDeviceQueueCreateInfo pQueueInfos[] = { {0},{0},{0} };
-       if (vkh_phyinfo_create_queues (pi, pi->gQueue, 1, qPriorities, &pQueueInfos[qCount]))
-               qCount++;
-       VkPhysicalDeviceFeatures enabledFeatures = {
-               .fillModeNonSolid = true,
-       };
-
-       VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
-                                                                          .queueCreateInfoCount = qCount,
-                                                                          .pQueueCreateInfos = (VkDeviceQueueCreateInfo*)&pQueueInfos,
-                                                                          .pEnabledFeatures = &enabledFeatures};
-
-       VkhDevice dev = vkh_device_create(app, pi, &device_info);
+    bool        deferredResolve = false;
+    VkhPhyInfo *phys            = vkh_app_get_phyinfos(app, &phyCount, VK_NULL_HANDLE);
+    VkhPhyInfo  pi              = 0;
+    if (!vkengine_try_get_phyinfo(phys, phyCount, preferedPhysicalDeviceType, &pi))
+        if (!vkengine_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, &pi))
+            if (!vkengine_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, &pi))
+                pi = phys[0];
+
+    uint32_t                qCount        = 0;
+    float                   qPriorities[] = {0.0};
+    VkDeviceQueueCreateInfo pQueueInfos[] = {{0}, {0}, {0}};
+    if (vkh_phyinfo_create_queues(pi, pi->gQueue, 1, qPriorities, &pQueueInfos[qCount]))
+        qCount++;
+    VkPhysicalDeviceFeatures enabledFeatures = {
+        .fillModeNonSolid = true,
+    };
+
+    VkDeviceCreateInfo device_info = {.sType                = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+                                      .queueCreateInfoCount = qCount,
+                                      .pQueueCreateInfos    = (VkDeviceQueueCreateInfo *)&pQueueInfos,
+                                      .pEnabledFeatures     = &enabledFeatures};
+
+    VkhDevice dev = vkh_device_create(app, pi, &device_info);
 
     vkvg_device_create_info_t info = {
-        samples,
-        deferredResolve,
-        vkh_app_get_inst(e->app),
-        dev->phy,
-        dev->dev,
-        pi->gQueue,
-        0
-    };
+        samples, deferredResolve, vkh_app_get_inst(e->app), dev->phy, dev->dev, pi->gQueue, 0};
 
     device = vkvg_device_create(&info);
-       //vkvg_device_set_dpy(device, 96, 96);
+    // vkvg_device_set_dpy(device, 96, 96);
 
-       vkh_app_free_phyinfos (phyCount, phys);
+    vkh_app_free_phyinfos(phyCount, phys);
 
-       surf = vkvg_surface_create(device, test_width, test_height);
+    surf = vkvg_surface_create(device, test_width, test_height);
 
-       double start_time = 0.0, stop_time = 0.0, run_time = 0.0, run_total = 0.0, min_run_time = -1, max_run_time = 0.0;
-       double* run_time_values = (double*)malloc(iterations*sizeof(double));
+    double  start_time = 0.0, stop_time = 0.0, run_time = 0.0, run_total = 0.0, min_run_time = -1, max_run_time = 0.0;
+    double *run_time_values = (double *)malloc(iterations * sizeof(double));
 
-       uint32_t i = 0;
-       while (i < iterations) {
-               start_time = get_tick();
+    uint32_t i = 0;
+    while (i < iterations) {
+        start_time = get_tick();
 
-               testfunc();
+        testfunc();
 
-               if (deferredResolve)
-                       vkvg_surface_resolve(surf);
+        if (deferredResolve)
+            vkvg_surface_resolve(surf);
 
-               stop_time = get_tick();
-               run_time = stop_time - start_time;
-               run_time_values[i] = run_time;
+        stop_time          = get_tick();
+        run_time           = stop_time - start_time;
+        run_time_values[i] = run_time;
 
-               if (min_run_time < 0)
-                       min_run_time = run_time;
-               else
-                       min_run_time = MIN(run_time, min_run_time);
-               max_run_time = MAX(run_time, max_run_time);
-               run_total += run_time;
-               i++;
-       }
+        if (min_run_time < 0)
+            min_run_time = run_time;
+        else
+            min_run_time = MIN(run_time, min_run_time);
+        max_run_time = MAX(run_time, max_run_time);
+        run_total += run_time;
+        i++;
+    }
 
-       _print_results (testName, argc, argv, i, run_total, run_time_values);
+    _print_results(testName, argc, argv, i, run_total, run_time_values);
 
-       free (run_time_values); 
+    free(run_time_values);
 
-       vkDeviceWaitIdle(dev->dev);
+    vkDeviceWaitIdle(dev->dev);
 
-       if (saveToPng)
-               vkvg_surface_write_to_png (surf, saveToPng);
+    if (saveToPng)
+        vkvg_surface_write_to_png(surf, saveToPng);
 
-       vkvg_surface_destroy    (surf);
-       vkvg_device_destroy     (device);
+    vkvg_surface_destroy(surf);
+    vkvg_device_destroy(device);
 
-       vkh_device_destroy (dev);
-       vkh_app_destroy (app);
+    vkh_device_destroy(dev);
+    vkh_app_destroy(app);
 
-       test_index++;
+    test_index++;
 }
 
-void perform_test_onscreen (void(*testfunc)(void), const char *testName, int argc, char* argv[]) {
-       if (test_vsync)
-               e = vkengine_create (preferedPhysicalDeviceType, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
-       else
-               e = vkengine_create (preferedPhysicalDeviceType, VK_PRESENT_MODE_MAILBOX_KHR, test_width, test_height);
+void perform_test_onscreen(void (*testfunc)(void), const char *testName, int argc, char *argv[]) {
+    if (test_vsync)
+        e = vkengine_create(preferedPhysicalDeviceType, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
+    else
+        e = vkengine_create(preferedPhysicalDeviceType, VK_PRESENT_MODE_MAILBOX_KHR, test_width, test_height);
 
-       VkhPresenter r = e->renderer;
-       vkengine_set_key_callback (e, key_callback);
-       vkengine_set_mouse_but_callback (e, mouse_button_callback);
-       vkengine_set_cursor_pos_callback (e, mouse_move_callback);
-       vkengine_set_scroll_callback (e, scroll_callback);
+    VkhPresenter r = e->renderer;
+    vkengine_set_key_callback(e, key_callback);
+    vkengine_set_mouse_but_callback(e, mouse_button_callback);
+    vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+    vkengine_set_scroll_callback(e, scroll_callback);
 
-    vkvg_device_create_info_t info = {
-        samples,
-        false,
-        vkh_app_get_inst(e->app),
-        r->dev->phy,
-        r->dev->dev,
-        r->qFam,
-        0
-    };
-    device = vkvg_device_create(&info);
+    vkvg_device_create_info_t info = {samples, false, vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0};
+    device                         = vkvg_device_create(&info);
 
-       vkvg_device_set_dpy (device, 96, 96);
-       if (threadAware)
-               vkvg_device_set_thread_aware (device, 1);
+    vkvg_device_set_dpy(device, 96, 96);
+    if (threadAware)
+        vkvg_device_set_thread_aware(device, 1);
 
 #ifdef VKVG_TEST_DIRECT_DRAW
-       surfaces = (VkvgSurface*)malloc(r->imgCount * sizeof (VkvgSurface));
-       for (uint32_t i=0; i < r->imgCount;i++)
-               surfaces[i] = vkvg_surface_create_for_VkhImage (device, r->ScBuffers[i]);
+    surfaces = (VkvgSurface *)malloc(r->imgCount * sizeof(VkvgSurface));
+    for (uint32_t i = 0; i < r->imgCount; i++)
+        surfaces[i] = vkvg_surface_create_for_VkhImage(device, r->ScBuffers[i]);
 #else
-       surf = vkvg_surface_create (device, test_width, test_height);
-       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+    surf                              = vkvg_surface_create(device, test_width, test_height);
+    vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
 #endif
 
-       double start_time = 0.0, stop_time = 0.0, run_time = 0.0, run_total = 0.0, min_run_time = -1, max_run_time = 0.0;
-       double* run_time_values = (double*)malloc(iterations*sizeof(double));
+    double  start_time = 0.0, stop_time = 0.0, run_time = 0.0, run_total = 0.0, min_run_time = -1, max_run_time = 0.0;
+    double *run_time_values = (double *)malloc(iterations * sizeof(double));
 
-       uint32_t i = 0;
+    uint32_t i = 0;
 
-       vkengine_set_title (e, testName);
+    vkengine_set_title(e, testName);
 
-       while (!vkengine_should_close (e) && i < iterations) {
-               glfwPollEvents();
+    while (!vkengine_should_close(e) && i < iterations) {
+        glfwPollEvents();
 
-               start_time = get_tick();
+        start_time = get_tick();
 
 #ifdef VKVG_TEST_DIRECT_DRAW
 
-               if (!vkh_presenter_acquireNextImage(r, NULL, NULL)) {
-                       for (uint32_t i=0; i < r->imgCount;i++)
-                               vkvg_surface_destroy (surfaces[i]);
+        if (!vkh_presenter_acquireNextImage(r, NULL, NULL)) {
+            for (uint32_t i = 0; i < r->imgCount; i++)
+                vkvg_surface_destroy(surfaces[i]);
 
-                       vkh_presenter_create_swapchain (r);
+            vkh_presenter_create_swapchain(r);
 
-                       for (uint32_t i=0; i < r->imgCount;i++)
-                               surfaces[i] = vkvg_surface_create_for_VkhImage (device, r->ScBuffers[i]);
-               }else{
-                       surf = surfaces[r->currentScBufferIndex];
+            for (uint32_t i = 0; i < r->imgCount; i++)
+                surfaces[i] = vkvg_surface_create_for_VkhImage(device, r->ScBuffers[i]);
+        } else {
+            surf = surfaces[r->currentScBufferIndex];
 
-                       testfunc();
+            testfunc();
 
-                       if (deferredResolve)
-                               vkvg_multisample_surface_resolve(surf);
+            if (deferredResolve)
+                vkvg_multisample_surface_resolve(surf);
 
-                       VkPresentInfoKHR present = { .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
-                                                                                .swapchainCount = 1,
-                                                                                .pSwapchains = &r->swapChain,
-                                                                                .pImageIndices = &r->currentScBufferIndex };
+            VkPresentInfoKHR present = {.sType          = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+                                        .swapchainCount = 1,
+                                        .pSwapchains    = &r->swapChain,
+                                        .pImageIndices  = &r->currentScBufferIndex};
 
-                       vkQueuePresentKHR(r->queue, &present);
-               }
+            vkQueuePresentKHR(r->queue, &present);
+        }
 #else
-               if (paused)
-                       continue;
+        if (paused)
+            continue;
 
-               testfunc();
+        testfunc();
 
         if (info.deferredResolve)
-                       vkvg_surface_resolve(surf);
-               if (!vkh_presenter_draw (r)){
-                       vkh_presenter_get_size (r, &test_width, &test_height);
-                       vkvg_surface_destroy (surf);
-                       surf = vkvg_surface_create(device, test_width, test_height);
-                       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
-                       vkDeviceWaitIdle(r->dev->dev);
-                       continue;
-               }
+            vkvg_surface_resolve(surf);
+        if (!vkh_presenter_draw(r)) {
+            vkh_presenter_get_size(r, &test_width, &test_height);
+            vkvg_surface_destroy(surf);
+            surf = vkvg_surface_create(device, test_width, test_height);
+            vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+            vkDeviceWaitIdle(r->dev->dev);
+            continue;
+        }
 #endif
 
-               stop_time = get_tick();
-               run_time = stop_time - start_time;
-               run_time_values[i] = run_time;
+        stop_time          = get_tick();
+        run_time           = stop_time - start_time;
+        run_time_values[i] = run_time;
 
-               if (min_run_time < 0)
-                       min_run_time = run_time;
-               else
-                       min_run_time = MIN(run_time, min_run_time);
-               max_run_time = MAX(run_time, max_run_time);
-               run_total += run_time;
-               i++;
-       }
+        if (min_run_time < 0)
+            min_run_time = run_time;
+        else
+            min_run_time = MIN(run_time, min_run_time);
+        max_run_time = MAX(run_time, max_run_time);
+        run_total += run_time;
+        i++;
+    }
 
-       if (saveToPng)
-               vkvg_surface_write_to_png (surf, saveToPng);
+    if (saveToPng)
+        vkvg_surface_write_to_png(surf, saveToPng);
 
-       _print_results (testName, argc, argv, i, run_total, run_time_values);
+    _print_results(testName, argc, argv, i, run_total, run_time_values);
 
-       free (run_time_values);
+    free(run_time_values);
 
-       vkDeviceWaitIdle(e->dev->dev);
+    vkDeviceWaitIdle(e->dev->dev);
 
 #ifdef VKVG_TEST_DIRECT_DRAW
-       for (uint32_t i=0; i<r->imgCount;i++)
-               vkvg_surface_destroy (surfaces[i]);
+    for (uint32_t i = 0; i < r->imgCount; i++)
+        vkvg_surface_destroy(surfaces[i]);
 
-       free (surfaces);
+    free(surfaces);
 #else
-       vkvg_surface_destroy    (surf);
+    vkvg_surface_destroy(surf);
 #endif
-       
-       vkvg_device_destroy     (device);
 
-       vkengine_destroy (e);
-       
-       test_index++;
-}
+    vkvg_device_destroy(device);
 
+    vkengine_destroy(e);
+
+    test_index++;
+}
 
 /* common context init for several tests */
-vkvg_fill_rule_t       fill_rule       = VKVG_FILL_RULE_NON_ZERO;
-vkvg_line_cap_t                line_cap        = VKVG_LINE_CAP_BUTT;
-vkvg_line_join_t       line_join       = VKVG_LINE_JOIN_MITER;
-float          dashes[]        = {10.0f, 6.0f};
-//float                dashes[]        = {0.0f, 10.0f};
-uint32_t       dashes_count= 0;
-float          dash_offset     = 0;
-float          line_width      = 2.f;
+vkvg_fill_rule_t fill_rule = VKVG_FILL_RULE_NON_ZERO;
+vkvg_line_cap_t  line_cap  = VKVG_LINE_CAP_BUTT;
+vkvg_line_join_t line_join = VKVG_LINE_JOIN_MITER;
+float            dashes[]  = {10.0f, 6.0f};
+// float               dashes[]        = {0.0f, 10.0f};
+uint32_t dashes_count = 0;
+float    dash_offset  = 0;
+float    line_width   = 2.f;
 
 VkvgContext _initCtx() {
-       VkvgContext ctx = vkvg_create(surf);
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_set_line_width     (ctx,line_width);
-       vkvg_set_line_join      (ctx, line_join);
-       vkvg_set_line_cap       (ctx, line_cap);
-       vkvg_set_dash           (ctx, dashes, dashes_count, dash_offset);
-       vkvg_set_fill_rule      (ctx, fill_rule);
+    vkvg_set_line_width(ctx, line_width);
+    vkvg_set_line_join(ctx, line_join);
+    vkvg_set_line_cap(ctx, line_cap);
+    vkvg_set_dash(ctx, dashes, dashes_count, dash_offset);
+    vkvg_set_fill_rule(ctx, fill_rule);
 
-       vkvg_clear                      (ctx);
-       return ctx;
+    vkvg_clear(ctx);
+    return ctx;
 }
 
-
-
-const int star_points[11][2] = {
-       { 0, 85 },
-       { 75, 75 },
-       { 100, 10 },
-       { 125, 75 },
-       { 200, 85 },
-       { 150, 125 },
-       { 160, 190 },
-       { 100, 150 },
-       { 40, 190 },
-       { 50, 125 },
-       { 0, 85 }
-};
-void randomize_color(VkvgContext ctx) {
-       vkvg_set_source_rgba(ctx,
-               rndf(),
-               rndf(),
-               rndf(),
-               rndf()
-       );
-}
-void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact) {
-       float w = (float)test_width;
-       float h = (float)test_height;
-
-       float x, y, z, v, r;
-
-       randomize_color (ctx);
-
-       switch (shape) {
-       case SHAPE_LINE:
-               x = rndf() * w;
-               y = rndf() * h;
-               z = rndf() * w;
-               v = rndf() * h;
-
-               vkvg_move_to(ctx, x, y);
-               vkvg_line_to(ctx, z, v);
-               vkvg_stroke(ctx);
-               break;
-       case SHAPE_RECTANGLE:
-               z = truncf((sizeFact*w*rndf())+1.f);
-               v = truncf((sizeFact*h*rndf())+1.f);
-               x = truncf((w-z)*rndf());
-               y = truncf((h-v)*rndf());
-
-               vkvg_rectangle(ctx, x+1, y+1, z, v);
-               break;
-       case SHAPE_ROUNDED_RECTANGLE:
-               z = truncf((sizeFact*w*rndf())+1.f);
-               v = truncf((sizeFact*h*rndf())+1.f);
-               x = truncf((w-z)*rndf());
-               y = truncf((h-v)*rndf());
-               r = truncf((0.2f*z*rndf())+1.f);
-
-               if ((r > v / 2) || (r > z / 2))
-                       r = MIN(v / 2, z / 2);
-
-               vkvg_move_to(ctx, x, y + r);
-               vkvg_arc(ctx, x + r, y + r, r, (float)M_PI, (float)-M_PI_2);
-               vkvg_line_to(ctx, x + z - r, y);
-               vkvg_arc(ctx, x + z - r, y + r, r, (float)-M_PI_2, 0);
-               vkvg_line_to(ctx, x + z, y + v - r);
-               vkvg_arc(ctx, x + z - r, y + v - r, r, 0, (float)M_PI_2);
-               vkvg_line_to(ctx, x + r, y + v);
-               vkvg_arc(ctx, x + r, y + v - r, r, (float)M_PI_2, (float)M_PI);
-               vkvg_line_to(ctx, x, y + r);
-               vkvg_close_path(ctx);
-               break;
-       case SHAPE_CIRCLE:
-               /*x = truncf((float)w * rnd()/RAND_MAX);
-               y = truncf((float)h * rnd()/RAND_MAX);
-               v = truncf((float)w * rnd()/RAND_MAX * 0.2f);*/
-               x = rndf() * w;
-               y = rndf() * h;
-
-               r = truncf((sizeFact*MIN(w,h)*rndf())+1.f);
-
-               /*float r = 0.5f*w*rand()/RAND_MAX;
-               float x = truncf(0.5f * w*rand()/RAND_MAX + r);
-               float y = truncf(0.5f * w*rand()/RAND_MAX + r);*/
-
-               vkvg_arc(ctx, x, y, r, 0, (float)M_PI * 2.0f);
-               break;
-       case SHAPE_TRIANGLE:
-       case SHAPE_STAR:
-               x = rndf() * w;
-               y = rndf() * h;
-               z = rndf() * sizeFact + 0.15f; //scale
-
-               vkvg_move_to (ctx, x+star_points[0][0]*z, y+star_points[0][1]*z);
-               for (int s=1; s<11; s++)
-                       vkvg_line_to (ctx, x+star_points[s][0]*z, y+star_points[s][1]*z);
-               vkvg_close_path (ctx);
-               break;
-       case SHAPE_RANDOM:
-               draw_random_shape(ctx, 1 + (rndf() * 4), sizeFact);
-               break;
-       }
+const int star_points[11][2] = {{0, 85},    {75, 75},   {100, 10}, {125, 75}, {200, 85}, {150, 125},
+                                {160, 190}, {100, 150}, {40, 190}, {50, 125}, {0, 85}};
+void      randomize_color(VkvgContext ctx) { vkvg_set_source_rgba(ctx, rndf(), rndf(), rndf(), rndf()); }
+void      draw_random_shape(VkvgContext ctx, shape_t shape, float sizeFact) {
+    float w = (float)test_width;
+    float h = (float)test_height;
+
+    float x, y, z, v, r;
+
+    randomize_color(ctx);
+
+    switch (shape) {
+    case SHAPE_LINE:
+        x = rndf() * w;
+        y = rndf() * h;
+        z = rndf() * w;
+        v = rndf() * h;
+
+        vkvg_move_to(ctx, x, y);
+        vkvg_line_to(ctx, z, v);
+        vkvg_stroke(ctx);
+        break;
+    case SHAPE_RECTANGLE:
+        z = truncf((sizeFact * w * rndf()) + 1.f);
+        v = truncf((sizeFact * h * rndf()) + 1.f);
+        x = truncf((w - z) * rndf());
+        y = truncf((h - v) * rndf());
+
+        vkvg_rectangle(ctx, x + 1, y + 1, z, v);
+        break;
+    case SHAPE_ROUNDED_RECTANGLE:
+        z = truncf((sizeFact * w * rndf()) + 1.f);
+        v = truncf((sizeFact * h * rndf()) + 1.f);
+        x = truncf((w - z) * rndf());
+        y = truncf((h - v) * rndf());
+        r = truncf((0.2f * z * rndf()) + 1.f);
+
+        if ((r > v / 2) || (r > z / 2))
+            r = MIN(v / 2, z / 2);
+
+        vkvg_move_to(ctx, x, y + r);
+        vkvg_arc(ctx, x + r, y + r, r, (float)M_PI, (float)-M_PI_2);
+        vkvg_line_to(ctx, x + z - r, y);
+        vkvg_arc(ctx, x + z - r, y + r, r, (float)-M_PI_2, 0);
+        vkvg_line_to(ctx, x + z, y + v - r);
+        vkvg_arc(ctx, x + z - r, y + v - r, r, 0, (float)M_PI_2);
+        vkvg_line_to(ctx, x + r, y + v);
+        vkvg_arc(ctx, x + r, y + v - r, r, (float)M_PI_2, (float)M_PI);
+        vkvg_line_to(ctx, x, y + r);
+        vkvg_close_path(ctx);
+        break;
+    case SHAPE_CIRCLE:
+        /*x = truncf((float)w * rnd()/RAND_MAX);
+        y = truncf((float)h * rnd()/RAND_MAX);
+        v = truncf((float)w * rnd()/RAND_MAX * 0.2f);*/
+        x = rndf() * w;
+        y = rndf() * h;
+
+        r = truncf((sizeFact * MIN(w, h) * rndf()) + 1.f);
+
+        /*float r = 0.5f*w*rand()/RAND_MAX;
+        float x = truncf(0.5f * w*rand()/RAND_MAX + r);
+        float y = truncf(0.5f * w*rand()/RAND_MAX + r);*/
+
+        vkvg_arc(ctx, x, y, r, 0, (float)M_PI * 2.0f);
+        break;
+    case SHAPE_TRIANGLE:
+    case SHAPE_STAR:
+        x = rndf() * w;
+        y = rndf() * h;
+        z = rndf() * sizeFact + 0.15f; // scale
+
+        vkvg_move_to(ctx, x + star_points[0][0] * z, y + star_points[0][1] * z);
+        for (int s = 1; s < 11; s++)
+            vkvg_line_to(ctx, x + star_points[s][0] * z, y + star_points[s][1] * z);
+        vkvg_close_path(ctx);
+        break;
+    case SHAPE_RANDOM:
+        draw_random_shape(ctx, 1 + (rndf() * 4), sizeFact);
+        break;
+    }
 }
-void draw_random_curve (VkvgContext ctx) {
-       float w = (float)test_width;
-       float h = (float)test_height;
-
-       float x2 = w*rndf();
-       float y2 = h*rndf();
-       float cp_x1 = w*rndf();
-       float cp_y1 = h*rndf();
-       float cp_x2 = w*rndf();
-       float cp_y2 = h*rndf();
-
-       vkvg_curve_to(ctx, cp_x1, cp_y1, cp_x2, cp_y2, x2, y2);
+void draw_random_curve(VkvgContext ctx) {
+    float w = (float)test_width;
+    float h = (float)test_height;
+
+    float x2    = w * rndf();
+    float y2    = h * rndf();
+    float cp_x1 = w * rndf();
+    float cp_y1 = h * rndf();
+    float cp_x2 = w * rndf();
+    float cp_y2 = h * rndf();
+
+    vkvg_curve_to(ctx, cp_x1, cp_y1, cp_x2, cp_y2, x2, y2);
 }
 /*void draw_random_shape (VkvgContext ctx, shape_t shape) {
-       float w = (float)test_width;
-       float h = (float)test_height;
-       randomize_color(ctx);
-       float z = truncf((0.5f*w*rand()/RAND_MAX)+1.f);
-       float v = truncf((0.5f*w*rand()/RAND_MAX)+1.f);
-       float x = truncf((w-z)*rand()/RAND_MAX);
-       float y = truncf((h-v)*rand()/RAND_MAX);
-       vkvg_rectangle(ctx, x, y, z, v);
+    float w = (float)test_width;
+    float h = (float)test_height;
+    randomize_color(ctx);
+    float z = truncf((0.5f*w*rand()/RAND_MAX)+1.f);
+    float v = truncf((0.5f*w*rand()/RAND_MAX)+1.f);
+    float x = truncf((w-z)*rand()/RAND_MAX);
+    float y = truncf((h-v)*rand()/RAND_MAX);
+    vkvg_rectangle(ctx, x, y, z, v);
 }*/
index d61858e48ef9c56c87e1d544d5bcdd6f65e86ad9..8079cec252caceeafcc5056c54e45ca9db474876 100644 (file)
 #include "vkh_presenter.h"
 #include "vkh_phyinfo.h"
 
-#define M_PIF               3.14159265359f /* float pi */
-#define M_PIF_MULT_2        6.28318530718f
+#define M_PIF        3.14159265359f /* float pi */
+#define M_PIF_MULT_2 6.28318530718f
 #ifndef M_PI
-# define M_PI          3.14159265358979323846  /* pi */
+#define M_PI 3.14159265358979323846 /* pi */
 #endif
 #ifndef M_PI_2
-# define M_PI_2                1.57079632679489661923  /* pi/2 */
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
 #endif
 
 #ifndef MIN
-# define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
 #endif
 
 #ifndef MAX
-# define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
 #endif
 
 #define PERFORM_TEST(testName, argc, argv) perform_test(testName, #testName, argc, argv);
 
 #if defined(_WIN32) || defined(_WIN64)
-       #define WIN32_LEAN_AND_MEAN
-       #define NOMINMAX
-       #include <Windows.h> // Windows.h -> WinDef.h defines min() max()
-
-       /*
-               typedef uint16_t WORD ;
-               typedef uint32_t DWORD;
-
-               typedef struct _FILETIME {
-                       DWORD dwLowDateTime;
-                       DWORD dwHighDateTime;
-               } FILETIME;
-
-               typedef struct _SYSTEMTIME {
-                         WORD wYear;
-                         WORD wMonth;
-                         WORD wDayOfWeek;
-                         WORD wDay;
-                         WORD wHour;
-                         WORD wMinute;
-                         WORD wSecond;
-                         WORD wMilliseconds;
-               } SYSTEMTIME, *PSYSTEMTIME;
-       */
-
-       // *sigh* Microsoft has this in winsock2.h because they are too lazy to put it in the standard location ... !?!?
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <Windows.h> // Windows.h -> WinDef.h defines min() max()
+
+/*
+    typedef uint16_t WORD ;
+    typedef uint32_t DWORD;
+
+    typedef struct _FILETIME {
+        DWORD dwLowDateTime;
+        DWORD dwHighDateTime;
+    } FILETIME;
+
+    typedef struct _SYSTEMTIME {
+          WORD wYear;
+          WORD wMonth;
+          WORD wDayOfWeek;
+          WORD wDay;
+          WORD wHour;
+          WORD wMinute;
+          WORD wSecond;
+          WORD wMilliseconds;
+    } SYSTEMTIME, *PSYSTEMTIME;
+*/
+
+// *sigh* Microsoft has this in winsock2.h because they are too lazy to put it in the standard location ... !?!?
 #ifdef _MSC_VER
-       typedef struct timeval {
-               long tv_sec;
-               long tv_usec;
-       } timeval;
+typedef struct timeval {
+    long tv_sec;
+    long tv_usec;
+} timeval;
 #endif
 
-       // *sigh* no gettimeofday on Win32/Win64
-       int gettimeofday(struct timeval * tp, void * tzp);
+// *sigh* no gettimeofday on Win32/Win64
+int gettimeofday(struct timeval *tp, void *tzp);
 #else
-       #include <sys/time.h>
+#include <sys/time.h>
 #endif
 
 typedef enum _shape_t {
-       SHAPE_LINE,
-       SHAPE_RECTANGLE,
-       SHAPE_ROUNDED_RECTANGLE,
-       SHAPE_CIRCLE,
-       SHAPE_TRIANGLE,
-       SHAPE_STAR,
-       SHAPE_RANDOM,
+    SHAPE_LINE,
+    SHAPE_RECTANGLE,
+    SHAPE_ROUNDED_RECTANGLE,
+    SHAPE_CIRCLE,
+    SHAPE_TRIANGLE,
+    SHAPE_STAR,
+    SHAPE_RANDOM,
 } shape_t;
 
 extern uint32_t test_size;
 extern uint32_t iterations;
 extern uint32_t test_width;
 extern uint32_t test_height;
-extern bool no_test_size;
+extern bool     no_test_size;
 
 extern float panX;
 extern float panY;
 extern float lastX;
 extern float lastY;
 extern float zoom;
-extern bool mouseDown;
+extern bool  mouseDown;
 
-extern VkvgDevice device;
+extern VkvgDevice  device;
 extern VkvgSurface surf;
 
 /* common context init for several tests */
-extern float dash_offset;
-extern float line_width;
+extern float            dash_offset;
+extern float            line_width;
 extern vkvg_fill_rule_t fill_rule;
-extern vkvg_line_cap_t line_cap;
+extern vkvg_line_cap_t  line_cap;
 extern vkvg_line_join_t line_join;
-extern float dashes[];
-extern uint32_t dashes_count;
+extern float            dashes[];
+extern uint32_t         dashes_count;
 
 VkvgContext _initCtx();
-void _parse_args (int argc, char* argv[]);
+void        _parse_args(int argc, char *argv[]);
 /*******************************/
 
-//run test in one step
-void perform_test (void(*testfunc)(), const char* testName, int argc, char *argv[]);
-void perform_test_onscreen (void(*testfunc)(void), const char *testName, int argc, char* argv[]);
-void perform_test_offscreen (void(*testfunc)(void), const char *testName, int argc, char* argv[]);
+// run test in one step
+void perform_test(void (*testfunc)(), const char *testName, int argc, char *argv[]);
+void perform_test_onscreen(void (*testfunc)(void), const char *testName, int argc, char *argv[]);
+void perform_test_offscreen(void (*testfunc)(void), const char *testName, int argc, char *argv[]);
 
-void randomize_color   (VkvgContext ctx);
-void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact);
-void draw_random_curve (VkvgContext ctx);
+void randomize_color(VkvgContext ctx);
+void draw_random_shape(VkvgContext ctx, shape_t shape, float sizeFact);
+void draw_random_curve(VkvgContext ctx);
 
-//run test in 3 step: init, run, clear.
-void init_test (uint32_t width, uint32_t height);
-void clear_test ();
+// run test in 3 step: init, run, clear.
+void init_test(uint32_t width, uint32_t height);
+void clear_test();
index f9cea2ed8c8587b442bffb1167c672af62826dc4..5dcf01fd1a9ae5c422387a8a0084d95fc5eb405f 100644 (file)
@@ -32,103 +32,96 @@ freely, subject to the following restrictions:
 
 /* Platform specific includes */
 #if defined(_TTHREAD_POSIX_)
-  #include <signal.h>
-  #include <sched.h>
-  #include <unistd.h>
-  #include <sys/time.h>
-  #include <errno.h>
+#include <signal.h>
+#include <sched.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <errno.h>
 #elif defined(_TTHREAD_WIN32_)
-  #include <process.h>
-  #include <sys/timeb.h>
+#include <process.h>
+#include <sys/timeb.h>
 #endif
 
 /* Standard, good-to-have defines */
 #ifndef NULL
-  #define NULL (void*)0
+#define NULL (void *)0
 #endif
 #ifndef TRUE
-  #define TRUE 1
+#define TRUE 1
 #endif
 #ifndef FALSE
-  #define FALSE 0
+#define FALSE 0
 #endif
 
-int mtx_init(mtx_t *mtx, int type)
-{
+int mtx_init(mtx_t *mtx, int type) {
 #if defined(_TTHREAD_WIN32_)
-  mtx->mAlreadyLocked = FALSE;
-  mtx->mRecursive = type & mtx_recursive;
-  InitializeCriticalSection(&mtx->mHandle);
-  return thrd_success;
+    mtx->mAlreadyLocked = FALSE;
+    mtx->mRecursive     = type & mtx_recursive;
+    InitializeCriticalSection(&mtx->mHandle);
+    return thrd_success;
 #else
-  int ret;
-  pthread_mutexattr_t attr;
-  pthread_mutexattr_init(&attr);
-  if (type & mtx_recursive)
-  {
-    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-  }
-  ret = pthread_mutex_init(mtx, &attr);
-  pthread_mutexattr_destroy(&attr);
-  return ret == 0 ? thrd_success : thrd_error;
+    int                 ret;
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    if (type & mtx_recursive) {
+        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    }
+    ret = pthread_mutex_init(mtx, &attr);
+    pthread_mutexattr_destroy(&attr);
+    return ret == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-void mtx_destroy(mtx_t *mtx)
-{
+void mtx_destroy(mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  DeleteCriticalSection(&mtx->mHandle);
+    DeleteCriticalSection(&mtx->mHandle);
 #else
-  pthread_mutex_destroy(mtx);
+    pthread_mutex_destroy(mtx);
 #endif
 }
 
-int mtx_lock(mtx_t *mtx)
-{
+int mtx_lock(mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  EnterCriticalSection(&mtx->mHandle);
-  if (!mtx->mRecursive)
-  {
-    while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */
-    mtx->mAlreadyLocked = TRUE;
-  }
-  return thrd_success;
+    EnterCriticalSection(&mtx->mHandle);
+    if (!mtx->mRecursive) {
+        while (mtx->mAlreadyLocked)
+            Sleep(1000); /* Simulate deadlock... */
+        mtx->mAlreadyLocked = TRUE;
+    }
+    return thrd_success;
 #else
-  return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
+    return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
-{
-  /* FIXME! */
-  (void)mtx;
-  (void)ts;
-  return thrd_error;
+int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) {
+    /* FIXME! */
+    (void)mtx;
+    (void)ts;
+    return thrd_error;
 }
 
-int mtx_trylock(mtx_t *mtx)
-{
+int mtx_trylock(mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy;
-  if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked)
-  {
-    LeaveCriticalSection(&mtx->mHandle);
-    ret = thrd_busy;
-  }
-  return ret;
+    int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy;
+    if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked) {
+        LeaveCriticalSection(&mtx->mHandle);
+        ret = thrd_busy;
+    }
+    return ret;
 #else
-  return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
+    return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
 #endif
 }
 
-int mtx_unlock(mtx_t *mtx)
-{
+int mtx_unlock(mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  mtx->mAlreadyLocked = FALSE;
-  LeaveCriticalSection(&mtx->mHandle);
-  return thrd_success;
+    mtx->mAlreadyLocked = FALSE;
+    LeaveCriticalSection(&mtx->mHandle);
+    return thrd_success;
 #else
-  return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
+    return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;
+    ;
 #endif
 }
 
@@ -137,458 +130,397 @@ int mtx_unlock(mtx_t *mtx)
 #define _CONDITION_EVENT_ALL 1
 #endif
 
-int cnd_init(cnd_t *cond)
-{
+int cnd_init(cnd_t *cond) {
 #if defined(_TTHREAD_WIN32_)
-  cond->mWaitersCount = 0;
+    cond->mWaitersCount = 0;
 
-  /* Init critical section */
-  InitializeCriticalSection(&cond->mWaitersCountLock);
+    /* Init critical section */
+    InitializeCriticalSection(&cond->mWaitersCountLock);
 
-  /* Init events */
-  cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
-  if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL)
-  {
-    cond->mEvents[_CONDITION_EVENT_ALL] = NULL;
-    return thrd_error;
-  }
-  cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
-  if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
-    cond->mEvents[_CONDITION_EVENT_ONE] = NULL;
-    return thrd_error;
-  }
+    /* Init events */
+    cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL) {
+        cond->mEvents[_CONDITION_EVENT_ALL] = NULL;
+        return thrd_error;
+    }
+    cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
+    if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL) {
+        CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
+        cond->mEvents[_CONDITION_EVENT_ONE] = NULL;
+        return thrd_error;
+    }
 
-  return thrd_success;
+    return thrd_success;
 #else
-  return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
+    return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-void cnd_destroy(cnd_t *cond)
-{
+void cnd_destroy(cnd_t *cond) {
 #if defined(_TTHREAD_WIN32_)
-  if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
-  }
-  if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
-  }
-  DeleteCriticalSection(&cond->mWaitersCountLock);
+    if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL) {
+        CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
+    }
+    if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL) {
+        CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
+    }
+    DeleteCriticalSection(&cond->mWaitersCountLock);
 #else
-  pthread_cond_destroy(cond);
+    pthread_cond_destroy(cond);
 #endif
 }
 
-int cnd_signal(cnd_t *cond)
-{
+int cnd_signal(cnd_t *cond) {
 #if defined(_TTHREAD_WIN32_)
-  int haveWaiters;
-
-  /* Are there any waiters? */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  haveWaiters = (cond->mWaitersCount > 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we have any waiting threads, send them a signal */
-  if(haveWaiters)
-  {
-    if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0)
-    {
-      return thrd_error;
+    int haveWaiters;
+
+    /* Are there any waiters? */
+    EnterCriticalSection(&cond->mWaitersCountLock);
+    haveWaiters = (cond->mWaitersCount > 0);
+    LeaveCriticalSection(&cond->mWaitersCountLock);
+
+    /* If we have any waiting threads, send them a signal */
+    if (haveWaiters) {
+        if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0) {
+            return thrd_error;
+        }
     }
-  }
 
-  return thrd_success;
+    return thrd_success;
 #else
-  return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
+    return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-int cnd_broadcast(cnd_t *cond)
-{
+int cnd_broadcast(cnd_t *cond) {
 #if defined(_TTHREAD_WIN32_)
-  int haveWaiters;
-
-  /* Are there any waiters? */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  haveWaiters = (cond->mWaitersCount > 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we have any waiting threads, send them a signal */
-  if(haveWaiters)
-  {
-    if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
-    {
-      return thrd_error;
+    int haveWaiters;
+
+    /* Are there any waiters? */
+    EnterCriticalSection(&cond->mWaitersCountLock);
+    haveWaiters = (cond->mWaitersCount > 0);
+    LeaveCriticalSection(&cond->mWaitersCountLock);
+
+    /* If we have any waiting threads, send them a signal */
+    if (haveWaiters) {
+        if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) {
+            return thrd_error;
+        }
     }
-  }
 
-  return thrd_success;
+    return thrd_success;
 #else
-  return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
+    return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
 #if defined(_TTHREAD_WIN32_)
-static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout)
-{
-  int result, lastWaiter;
-
-  /* Increment number of waiters */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  ++ cond->mWaitersCount;
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* Release the mutex while waiting for the condition (will decrease
-     the number of waiters when done)... */
-  mtx_unlock(mtx);
-
-  /* Wait for either event to become signaled due to cnd_signal() or
-     cnd_broadcast() being called */
-  result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout);
-  if (result == WAIT_TIMEOUT)
-  {
-    return thrd_timeout;
-  }
-  else if (result == (int)WAIT_FAILED)
-  {
-    return thrd_error;
-  }
-
-  /* Check if we are the last waiter */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  -- cond->mWaitersCount;
-  lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
-               (cond->mWaitersCount == 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we are the last waiter to be notified to stop waiting, reset the event */
-  if (lastWaiter)
-  {
-    if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
-    {
-      return thrd_error;
+static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout) {
+    int result, lastWaiter;
+
+    /* Increment number of waiters */
+    EnterCriticalSection(&cond->mWaitersCountLock);
+    ++cond->mWaitersCount;
+    LeaveCriticalSection(&cond->mWaitersCountLock);
+
+    /* Release the mutex while waiting for the condition (will decrease
+       the number of waiters when done)... */
+    mtx_unlock(mtx);
+
+    /* Wait for either event to become signaled due to cnd_signal() or
+       cnd_broadcast() being called */
+    result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout);
+    if (result == WAIT_TIMEOUT) {
+        return thrd_timeout;
+    } else if (result == (int)WAIT_FAILED) {
+        return thrd_error;
+    }
+
+    /* Check if we are the last waiter */
+    EnterCriticalSection(&cond->mWaitersCountLock);
+    --cond->mWaitersCount;
+    lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && (cond->mWaitersCount == 0);
+    LeaveCriticalSection(&cond->mWaitersCountLock);
+
+    /* If we are the last waiter to be notified to stop waiting, reset the event */
+    if (lastWaiter) {
+        if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) {
+            return thrd_error;
+        }
     }
-  }
 
-  /* Re-acquire the mutex */
-  mtx_lock(mtx);
+    /* Re-acquire the mutex */
+    mtx_lock(mtx);
 
-  return thrd_success;
+    return thrd_success;
 }
 #endif
 
-int cnd_wait(cnd_t *cond, mtx_t *mtx)
-{
+int cnd_wait(cnd_t *cond, mtx_t *mtx) {
 #if defined(_TTHREAD_WIN32_)
-  return _cnd_timedwait_win32(cond, mtx, INFINITE);
+    return _cnd_timedwait_win32(cond, mtx, INFINITE);
 #else
-  return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
+    return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
-{
+int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts) {
 #if defined(_TTHREAD_WIN32_)
-  struct timespec now;
-  if (clock_gettime(CLOCK_REALTIME, &now) == 0)
-  {
-    DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 +
-                           (ts->tv_nsec - now.tv_nsec + 500000) / 1000000);
-    return _cnd_timedwait_win32(cond, mtx, delta);
-  }
-  else
-    return thrd_error;
+    struct timespec now;
+    if (clock_gettime(CLOCK_REALTIME, &now) == 0) {
+        DWORD delta = (DWORD)((ts->tv_sec - now.tv_sec) * 1000 + (ts->tv_nsec - now.tv_nsec + 500000) / 1000000);
+        return _cnd_timedwait_win32(cond, mtx, delta);
+    } else
+        return thrd_error;
 #else
-  int ret;
-  ret = pthread_cond_timedwait(cond, mtx, ts);
-  if (ret == ETIMEDOUT)
-  {
-    return thrd_timeout;
-  }
-  return ret == 0 ? thrd_success : thrd_error;
+    int ret;
+    ret = pthread_cond_timedwait(cond, mtx, ts);
+    if (ret == ETIMEDOUT) {
+        return thrd_timeout;
+    }
+    return ret == 0 ? thrd_success : thrd_error;
 #endif
 }
 
-
 /** Information to pass to the new thread (what to run). */
 typedef struct {
-  thrd_start_t mFunction; /**< Pointer to the function to be executed. */
-  void * mArg;            /**< Function argument for the thread function. */
+    thrd_start_t mFunction; /**< Pointer to the function to be executed. */
+    void        *mArg;      /**< Function argument for the thread function. */
 } _thread_start_info;
 
 /* Thread wrapper function. */
 #if defined(_TTHREAD_WIN32_)
-static unsigned WINAPI _thrd_wrapper_function(void * aArg)
+static unsigned WINAPI _thrd_wrapper_function(void *aArg)
 #elif defined(_TTHREAD_POSIX_)
-static void * _thrd_wrapper_function(void * aArg)
+static void *_thrd_wrapper_function(void *aArg)
 #endif
 {
-  thrd_start_t fun;
-  void *arg;
-  int  res;
+    thrd_start_t fun;
+    void        *arg;
+    int          res;
 #if defined(_TTHREAD_POSIX_)
-  void *pres;
+    void *pres;
 #endif
 
-  /* Get thread startup information */
-  _thread_start_info *ti = (_thread_start_info *) aArg;
-  fun = ti->mFunction;
-  arg = ti->mArg;
+    /* Get thread startup information */
+    _thread_start_info *ti = (_thread_start_info *)aArg;
+    fun                    = ti->mFunction;
+    arg                    = ti->mArg;
 
-  /* The thread is responsible for freeing the startup information */
-  free((void *)ti);
+    /* The thread is responsible for freeing the startup information */
+    free((void *)ti);
 
-  /* Call the actual client thread function */
-  res = fun(arg);
+    /* Call the actual client thread function */
+    res = fun(arg);
 
 #if defined(_TTHREAD_WIN32_)
-  return res;
+    return res;
 #else
-  pres = malloc(sizeof(int));
-  if (pres != NULL)
-  {
-    *(int*)pres = res;
-  }
-  return pres;
+    pres = malloc(sizeof(int));
+    if (pres != NULL) {
+        *(int *)pres = res;
+    }
+    return pres;
 #endif
 }
 
-int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
-{
-  /* Fill out the thread startup information (passed to the thread wrapper,
-     which will eventually free it) */
-  _thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info));
-  if (ti == NULL)
-  {
-    return thrd_nomem;
-  }
-  ti->mFunction = func;
-  ti->mArg = arg;
-
-  /* Create the thread */
+int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) {
+    /* Fill out the thread startup information (passed to the thread wrapper,
+       which will eventually free it) */
+    _thread_start_info *ti = (_thread_start_info *)malloc(sizeof(_thread_start_info));
+    if (ti == NULL) {
+        return thrd_nomem;
+    }
+    ti->mFunction = func;
+    ti->mArg      = arg;
+
+    /* Create the thread */
 #if defined(_TTHREAD_WIN32_)
-  *thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL);
+    *thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL);
 #elif defined(_TTHREAD_POSIX_)
-  if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0)
-  {
-    *thr = 0;
-  }
+    if (pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0) {
+        *thr = 0;
+    }
 #endif
 
-  /* Did we fail to create the thread? */
-  if(!*thr)
-  {
-    free(ti);
-    return thrd_error;
-  }
+    /* Did we fail to create the thread? */
+    if (!*thr) {
+        free(ti);
+        return thrd_error;
+    }
 
-  return thrd_success;
+    return thrd_success;
 }
 
-thrd_t thrd_current(void)
-{
+thrd_t thrd_current(void) {
 #if defined(_TTHREAD_WIN32_)
-  return GetCurrentThread();
+    return GetCurrentThread();
 #else
-  return pthread_self();
+    return pthread_self();
 #endif
 }
 
-int thrd_detach(thrd_t thr)
-{
-  /* FIXME! */
-  (void)thr;
-  return thrd_error;
+int thrd_detach(thrd_t thr) {
+    /* FIXME! */
+    (void)thr;
+    return thrd_error;
 }
 
-int thrd_equal(thrd_t thr0, thrd_t thr1)
-{
+int thrd_equal(thrd_t thr0, thrd_t thr1) {
 #if defined(_TTHREAD_WIN32_)
-  return thr0 == thr1;
+    return thr0 == thr1;
 #else
-  return pthread_equal(thr0, thr1);
+    return pthread_equal(thr0, thr1);
 #endif
 }
 
-void thrd_exit(int res)
-{
+void thrd_exit(int res) {
 #if defined(_TTHREAD_WIN32_)
-  ExitThread(res);
+    ExitThread(res);
 #else
-  void *pres = malloc(sizeof(int));
-  if (pres != NULL)
-  {
-    *(int*)pres = res;
-  }
-  pthread_exit(pres);
+    void *pres = malloc(sizeof(int));
+    if (pres != NULL) {
+        *(int *)pres = res;
+    }
+    pthread_exit(pres);
 #endif
 }
 
-int thrd_join(thrd_t thr, int *res)
-{
+int thrd_join(thrd_t thr, int *res) {
 #if defined(_TTHREAD_WIN32_)
-  if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED)
-  {
-    return thrd_error;
-  }
-  if (res != NULL)
-  {
-    DWORD dwRes;
-    GetExitCodeThread(thr, &dwRes);
-    *res = dwRes;
-  }
+    if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED) {
+        return thrd_error;
+    }
+    if (res != NULL) {
+        DWORD dwRes;
+        GetExitCodeThread(thr, &dwRes);
+        *res = dwRes;
+    }
 #elif defined(_TTHREAD_POSIX_)
-  void *pres;
-  int ires = 0;
-  if (pthread_join(thr, &pres) != 0)
-  {
-    return thrd_error;
-  }
-  if (pres != NULL)
-  {
-    ires = *(int*)pres;
-    free(pres);
-  }
-  if (res != NULL)
-  {
-    *res = ires;
-  }
-#endif
-  return thrd_success;
+    void *pres;
+    int   ires = 0;
+    if (pthread_join(thr, &pres) != 0) {
+        return thrd_error;
+    }
+    if (pres != NULL) {
+        ires = *(int *)pres;
+        free(pres);
+    }
+    if (res != NULL) {
+        *res = ires;
+    }
+#endif
+    return thrd_success;
 }
 
-int thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
-{
-  struct timespec now;
+int thrd_sleep(const struct timespec *time_point, struct timespec *remaining) {
+    struct timespec now;
 #if defined(_TTHREAD_WIN32_)
-  DWORD delta;
+    DWORD delta;
 #else
-  long delta;
+    long delta;
 #endif
 
-  /* Get the current time */
-  if (clock_gettime(CLOCK_REALTIME, &now) != 0)
-    return -2;  // FIXME: Some specific error code?
+    /* Get the current time */
+    if (clock_gettime(CLOCK_REALTIME, &now) != 0)
+        return -2; // FIXME: Some specific error code?
 
 #if defined(_TTHREAD_WIN32_)
-  /* Delta in milliseconds */
-  delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 +
-                   (time_point->tv_nsec - now.tv_nsec + 500000) / 1000000);
-  if (delta > 0)
-  {
-    Sleep(delta);
-  }
+    /* Delta in milliseconds */
+    delta = (DWORD)((time_point->tv_sec - now.tv_sec) * 1000 + (time_point->tv_nsec - now.tv_nsec + 500000) / 1000000);
+    if (delta > 0) {
+        Sleep(delta);
+    }
 #else
-  /* Delta in microseconds */
-  delta = (time_point->tv_sec - now.tv_sec) * 1000000L +
-          (time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
-
-  /* On some systems, the usleep argument must be < 1000000 */
-  while (delta > 999999L)
-  {
-    usleep(999999);
-    delta -= 999999L;
-  }
-  if (delta > 0L)
-  {
-    usleep((useconds_t)delta);
-  }
-#endif
-
-  /* We don't support waking up prematurely (yet) */
-  if (remaining)
-  {
-    remaining->tv_sec = 0;
-    remaining->tv_nsec = 0;
-  }
-  return 0;
+    /* Delta in microseconds */
+    delta = (time_point->tv_sec - now.tv_sec) * 1000000L + (time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
+
+    /* On some systems, the usleep argument must be < 1000000 */
+    while (delta > 999999L) {
+        usleep(999999);
+        delta -= 999999L;
+    }
+    if (delta > 0L) {
+        usleep((useconds_t)delta);
+    }
+#endif
+
+    /* We don't support waking up prematurely (yet) */
+    if (remaining) {
+        remaining->tv_sec  = 0;
+        remaining->tv_nsec = 0;
+    }
+    return 0;
 }
 
-void thrd_yield(void)
-{
+void thrd_yield(void) {
 #if defined(_TTHREAD_WIN32_)
-  Sleep(0);
+    Sleep(0);
 #else
-  sched_yield();
+    sched_yield();
 #endif
 }
 
-int tss_create(tss_t *key, tss_dtor_t dtor)
-{
+int tss_create(tss_t *key, tss_dtor_t dtor) {
 #if defined(_TTHREAD_WIN32_)
-  /* FIXME: The destructor function is not supported yet... */
-  if (dtor != NULL)
-  {
-    return thrd_error;
-  }
-  *key = TlsAlloc();
-  if (*key == TLS_OUT_OF_INDEXES)
-  {
-    return thrd_error;
-  }
+    /* FIXME: The destructor function is not supported yet... */
+    if (dtor != NULL) {
+        return thrd_error;
+    }
+    *key = TlsAlloc();
+    if (*key == TLS_OUT_OF_INDEXES) {
+        return thrd_error;
+    }
 #else
-  if (pthread_key_create(key, dtor) != 0)
-  {
-    return thrd_error;
-  }
+    if (pthread_key_create(key, dtor) != 0) {
+        return thrd_error;
+    }
 #endif
-  return thrd_success;
+    return thrd_success;
 }
 
-void tss_delete(tss_t key)
-{
+void tss_delete(tss_t key) {
 #if defined(_TTHREAD_WIN32_)
-  TlsFree(key);
+    TlsFree(key);
 #else
-  pthread_key_delete(key);
+    pthread_key_delete(key);
 #endif
 }
 
-void *tss_get(tss_t key)
-{
+void *tss_get(tss_t key) {
 #if defined(_TTHREAD_WIN32_)
-  return TlsGetValue(key);
+    return TlsGetValue(key);
 #else
-  return pthread_getspecific(key);
+    return pthread_getspecific(key);
 #endif
 }
 
-int tss_set(tss_t key, void *val)
-{
+int tss_set(tss_t key, void *val) {
 #if defined(_TTHREAD_WIN32_)
-  if (TlsSetValue(key, val) == 0)
-  {
-    return thrd_error;
-  }
+    if (TlsSetValue(key, val) == 0) {
+        return thrd_error;
+    }
 #else
-  if (pthread_setspecific(key, val) != 0)
-  {
-    return thrd_error;
-  }
+    if (pthread_setspecific(key, val) != 0) {
+        return thrd_error;
+    }
 #endif
-  return thrd_success;
+    return thrd_success;
 }
 
 #if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_)
-int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts)
-{
+int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts) {
 #if defined(_TTHREAD_WIN32_)
-  struct _timeb tb;
-  _ftime(&tb);
-  ts->tv_sec = (time_t)tb.time;
-  ts->tv_nsec = 1000000L * (long)tb.millitm;
+    struct _timeb tb;
+    _ftime(&tb);
+    ts->tv_sec  = (time_t)tb.time;
+    ts->tv_nsec = 1000000L * (long)tb.millitm;
 #else
-  struct timeval tv;
-  gettimeofday(&tv, NULL);
-  ts->tv_sec = (time_t)tv.tv_sec;
-  ts->tv_nsec = 1000L * (long)tv.tv_usec;
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    ts->tv_sec  = (time_t)tv.tv_sec;
+    ts->tv_nsec = 1000L * (long)tv.tv_usec;
 #endif
-  return 0;
+    return 0;
 }
 #endif // _TTHREAD_EMULATE_CLOCK_GETTIME_
-
index 42958c393e86ec8bc55ee10e150a02f243f71041..eaacfbe38683f7122380368dc16f2fa0ec0c2c35 100644 (file)
@@ -25,52 +25,52 @@ freely, subject to the following restrictions:
 #define _TINYCTHREAD_H_
 
 /**
-* @file
-* @mainpage TinyCThread API Reference
-*
-* @section intro_sec Introduction
-* TinyCThread is a minimal, portable implementation of basic threading
-* classes for C.
-*
-* They closely mimic the functionality and naming of the C11 standard, and
-* should be easily replaceable with the corresponding standard variants.
-*
-* @section port_sec Portability
-* The Win32 variant uses the native Win32 API for implementing the thread
-* classes, while for other systems, the POSIX threads API (pthread) is used.
-*
-* @section misc_sec Miscellaneous
-* The following special keywords are available: #_Thread_local.
-*
-* For more detailed information, browse the different sections of this
-* documentation. A good place to start is:
-* tinycthread.h.
-*/
+ * @file
+ * @mainpage TinyCThread API Reference
+ *
+ * @section intro_sec Introduction
+ * TinyCThread is a minimal, portable implementation of basic threading
+ * classes for C.
+ *
+ * They closely mimic the functionality and naming of the C11 standard, and
+ * should be easily replaceable with the corresponding standard variants.
+ *
+ * @section port_sec Portability
+ * The Win32 variant uses the native Win32 API for implementing the thread
+ * classes, while for other systems, the POSIX threads API (pthread) is used.
+ *
+ * @section misc_sec Miscellaneous
+ * The following special keywords are available: #_Thread_local.
+ *
+ * For more detailed information, browse the different sections of this
+ * documentation. A good place to start is:
+ * tinycthread.h.
+ */
 
 /* Which platform are we on? */
 #if !defined(_TTHREAD_PLATFORM_DEFINED_)
-  #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
-    #define _TTHREAD_WIN32_
-  #else
-    #define _TTHREAD_POSIX_
-  #endif
-  #define _TTHREAD_PLATFORM_DEFINED_
+#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
+#define _TTHREAD_WIN32_
+#else
+#define _TTHREAD_POSIX_
+#endif
+#define _TTHREAD_PLATFORM_DEFINED_
 #endif
 
 /* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */
 #if defined(_TTHREAD_POSIX_)
-  #undef _FEATURES_H
-  #if !defined(_GNU_SOURCE)
-    #define _GNU_SOURCE
-  #endif
-  #if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
-    #undef _POSIX_C_SOURCE
-    #define _POSIX_C_SOURCE 199309L
-  #endif
-  #if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
-    #undef _XOPEN_SOURCE
-    #define _XOPEN_SOURCE 500
-  #endif
+#undef _FEATURES_H
+#if !defined(_GNU_SOURCE)
+#define _GNU_SOURCE
+#endif
+#if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 199309L
+#endif
+#if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
+#undef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
 #endif
 
 /* Generic includes */
@@ -78,18 +78,18 @@ freely, subject to the following restrictions:
 
 /* Platform specific includes */
 #if defined(_TTHREAD_POSIX_)
-  #include <sys/time.h>
-  #include <pthread.h>
+#include <sys/time.h>
+#include <pthread.h>
 #elif defined(_TTHREAD_WIN32_)
-  #ifndef WIN32_LEAN_AND_MEAN
-    #define WIN32_LEAN_AND_MEAN
-    #define __UNDEF_LEAN_AND_MEAN
-  #endif
-  #include <windows.h>
-  #ifdef __UNDEF_LEAN_AND_MEAN
-    #undef WIN32_LEAN_AND_MEAN
-    #undef __UNDEF_LEAN_AND_MEAN
-  #endif
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#define __UNDEF_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#ifdef __UNDEF_LEAN_AND_MEAN
+#undef WIN32_LEAN_AND_MEAN
+#undef __UNDEF_LEAN_AND_MEAN
+#endif
 #endif
 
 /* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC,
@@ -97,11 +97,11 @@ freely, subject to the following restrictions:
    the only other supported time specifier: CLOCK_REALTIME (and if that fails,
    we're probably emulating clock_gettime anyway, so anything goes). */
 #ifndef TIME_UTC
-  #ifdef CLOCK_REALTIME
-    #define TIME_UTC CLOCK_REALTIME
-  #else
-    #define TIME_UTC 0
-  #endif
+#ifdef CLOCK_REALTIME
+#define TIME_UTC CLOCK_REALTIME
+#else
+#define TIME_UTC 0
+#endif
 #endif
 
 /* Workaround for missing clock_gettime (most Windows compilers, afaik) */
@@ -110,8 +110,8 @@ freely, subject to the following restrictions:
 /* Emulate struct timespec */
 #if defined(_TTHREAD_WIN32_)
 struct _ttherad_timespec {
-  time_t tv_sec;
-  long   tv_nsec;
+    time_t tv_sec;
+    long   tv_nsec;
 };
 #define timespec _ttherad_timespec
 #endif
@@ -124,11 +124,10 @@ typedef int _tthread_clockid_t;
 int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
 #define clock_gettime _tthread_clock_gettime
 #ifndef CLOCK_REALTIME
-  #define CLOCK_REALTIME 0
+#define CLOCK_REALTIME 0
 #endif
 #endif
 
-
 /** TinyCThread version (major number). */
 #define TINYCTHREAD_VERSION_MAJOR 1
 /** TinyCThread version (minor number). */
@@ -137,42 +136,44 @@ int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
 #define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
 
 /**
-* @def _Thread_local
-* Thread local storage keyword.
-* A variable that is declared with the @c _Thread_local keyword makes the
-* value of the variable local to each thread (known as thread-local storage,
-* or TLS). Example usage:
-* @code
-* // This variable is local to each thread.
-* _Thread_local int variable;
-* @endcode
-* @note The @c _Thread_local keyword is a macro that maps to the corresponding
-* compiler directive (e.g. @c __declspec(thread)).
-* @note This directive is currently not supported on Mac OS X (it will give
-* a compiler error), since compile-time TLS is not supported in the Mac OS X
-* executable format. Also, some older versions of MinGW (before GCC 4.x) do
-* not support this directive.
-* @hideinitializer
-*/
+ * @def _Thread_local
+ * Thread local storage keyword.
+ * A variable that is declared with the @c _Thread_local keyword makes the
+ * value of the variable local to each thread (known as thread-local storage,
+ * or TLS). Example usage:
+ * @code
+ * // This variable is local to each thread.
+ * _Thread_local int variable;
+ * @endcode
+ * @note The @c _Thread_local keyword is a macro that maps to the corresponding
+ * compiler directive (e.g. @c __declspec(thread)).
+ * @note This directive is currently not supported on Mac OS X (it will give
+ * a compiler error), since compile-time TLS is not supported in the Mac OS X
+ * executable format. Also, some older versions of MinGW (before GCC 4.x) do
+ * not support this directive.
+ * @hideinitializer
+ */
 
 /* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */
 #if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
- #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-  #define _Thread_local __thread
- #else
-  #define _Thread_local __declspec(thread)
- #endif
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
+#define _Thread_local __thread
+#else
+#define _Thread_local __declspec(thread)
+#endif
 #endif
 
 /* Macros */
 #define TSS_DTOR_ITERATIONS 0
 
 /* Function return values */
-#define thrd_error    0 /**< The requested operation failed */
-#define thrd_success  1 /**< The requested operation succeeded */
-#define thrd_timeout  2 /**< The time specified in the call was reached without acquiring the requested resource */
-#define thrd_busy     3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */
-#define thrd_nomem    4 /**< The requested operation failed because it was unable to allocate memory */
+#define thrd_error   0 /**< The requested operation failed */
+#define thrd_success 1 /**< The requested operation succeeded */
+#define thrd_timeout 2 /**< The time specified in the call was reached without acquiring the requested resource */
+#define thrd_busy                                                                                                      \
+    3 /**< The requested operation failed because a tesource requested by a test and return function is already in use \
+       */
+#define thrd_nomem 4 /**< The requested operation failed because it was unable to allocate memory */
 
 /* Mutex types */
 #define mtx_plain     1
@@ -183,261 +184,259 @@ int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
 /* Mutex */
 #if defined(_TTHREAD_WIN32_)
 typedef struct {
-  CRITICAL_SECTION mHandle;   /* Critical section handle */
-  int mAlreadyLocked;         /* TRUE if the mutex is already locked */
-  int mRecursive;             /* TRUE if the mutex is recursive */
+    CRITICAL_SECTION mHandle;        /* Critical section handle */
+    int              mAlreadyLocked; /* TRUE if the mutex is already locked */
+    int              mRecursive;     /* TRUE if the mutex is recursive */
 } mtx_t;
 #else
 typedef pthread_mutex_t mtx_t;
 #endif
 
 /** Create a mutex object.
-* @param mtx A mutex object.
-* @param type Bit-mask that must have one of the following six values:
-*   @li @c mtx_plain for a simple non-recursive mutex
-*   @li @c mtx_timed for a non-recursive mutex that supports timeout
-*   @li @c mtx_try for a non-recursive mutex that supports test and return
-*   @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive)
-*   @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive)
-*   @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive)
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * @param mtx A mutex object.
+ * @param type Bit-mask that must have one of the following six values:
+ *   @li @c mtx_plain for a simple non-recursive mutex
+ *   @li @c mtx_timed for a non-recursive mutex that supports timeout
+ *   @li @c mtx_try for a non-recursive mutex that supports test and return
+ *   @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive)
+ *   @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive)
+ *   @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive)
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int mtx_init(mtx_t *mtx, int type);
 
 /** Release any resources used by the given mutex.
-* @param mtx A mutex object.
-*/
+ * @param mtx A mutex object.
+ */
 void mtx_destroy(mtx_t *mtx);
 
 /** Lock the given mutex.
-* Blocks until the given mutex can be locked. If the mutex is non-recursive, and
-* the calling thread already has a lock on the mutex, this call will block
-* forever.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * Blocks until the given mutex can be locked. If the mutex is non-recursive, and
+ * the calling thread already has a lock on the mutex, this call will block
+ * forever.
+ * @param mtx A mutex object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int mtx_lock(mtx_t *mtx);
 
 /** NOT YET IMPLEMENTED.
-*/
+ */
 int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
 
 /** Try to lock the given mutex.
-* The specified mutex shall support either test and return or timeout. If the
-* mutex is already locked, the function returns without blocking.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_busy if the resource
-* requested is already in use, or @ref thrd_error if the request could not be
-* honored.
-*/
+ * The specified mutex shall support either test and return or timeout. If the
+ * mutex is already locked, the function returns without blocking.
+ * @param mtx A mutex object.
+ * @return @ref thrd_success on success, or @ref thrd_busy if the resource
+ * requested is already in use, or @ref thrd_error if the request could not be
+ * honored.
+ */
 int mtx_trylock(mtx_t *mtx);
 
 /** Unlock the given mutex.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * @param mtx A mutex object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int mtx_unlock(mtx_t *mtx);
 
 /* Condition variable */
 #if defined(_TTHREAD_WIN32_)
 typedef struct {
-  HANDLE mEvents[2];                  /* Signal and broadcast event HANDLEs. */
-  unsigned int mWaitersCount;         /* Count of the number of waiters. */
-  CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
+    HANDLE           mEvents[2];        /* Signal and broadcast event HANDLEs. */
+    unsigned int     mWaitersCount;     /* Count of the number of waiters. */
+    CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
 } cnd_t;
 #else
-typedef pthread_cond_t cnd_t;
+typedef pthread_cond_t  cnd_t;
 #endif
 
 /** Create a condition variable object.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * @param cond A condition variable object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int cnd_init(cnd_t *cond);
 
 /** Release any resources used by the given condition variable.
-* @param cond A condition variable object.
-*/
+ * @param cond A condition variable object.
+ */
 void cnd_destroy(cnd_t *cond);
 
 /** Signal a condition variable.
-* Unblocks one of the threads that are blocked on the given condition variable
-* at the time of the call. If no threads are blocked on the condition variable
-* at the time of the call, the function does nothing and return success.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * Unblocks one of the threads that are blocked on the given condition variable
+ * at the time of the call. If no threads are blocked on the condition variable
+ * at the time of the call, the function does nothing and return success.
+ * @param cond A condition variable object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int cnd_signal(cnd_t *cond);
 
 /** Broadcast a condition variable.
-* Unblocks all of the threads that are blocked on the given condition variable
-* at the time of the call. If no threads are blocked on the condition variable
-* at the time of the call, the function does nothing and return success.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * Unblocks all of the threads that are blocked on the given condition variable
+ * at the time of the call. If no threads are blocked on the condition variable
+ * at the time of the call, the function does nothing and return success.
+ * @param cond A condition variable object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int cnd_broadcast(cnd_t *cond);
 
 /** Wait for a condition variable to become signaled.
-* The function atomically unlocks the given mutex and endeavors to block until
-* the given condition variable is signaled by a call to cnd_signal or to
-* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex
-* before it returns.
-* @param cond A condition variable object.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * The function atomically unlocks the given mutex and endeavors to block until
+ * the given condition variable is signaled by a call to cnd_signal or to
+ * cnd_broadcast. When the calling thread becomes unblocked it locks the mutex
+ * before it returns.
+ * @param cond A condition variable object.
+ * @param mtx A mutex object.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int cnd_wait(cnd_t *cond, mtx_t *mtx);
 
 /** Wait for a condition variable to become signaled.
-* The function atomically unlocks the given mutex and endeavors to block until
-* the given condition variable is signaled by a call to cnd_signal or to
-* cnd_broadcast, or until after the specified time. When the calling thread
-* becomes unblocked it locks the mutex before it returns.
-* @param cond A condition variable object.
-* @param mtx A mutex object.
-* @param xt A point in time at which the request will time out (absolute time).
-* @return @ref thrd_success upon success, or @ref thrd_timeout if the time
-* specified in the call was reached without acquiring the requested resource, or
-* @ref thrd_error if the request could not be honored.
-*/
+ * The function atomically unlocks the given mutex and endeavors to block until
+ * the given condition variable is signaled by a call to cnd_signal or to
+ * cnd_broadcast, or until after the specified time. When the calling thread
+ * becomes unblocked it locks the mutex before it returns.
+ * @param cond A condition variable object.
+ * @param mtx A mutex object.
+ * @param xt A point in time at which the request will time out (absolute time).
+ * @return @ref thrd_success upon success, or @ref thrd_timeout if the time
+ * specified in the call was reached without acquiring the requested resource, or
+ * @ref thrd_error if the request could not be honored.
+ */
 int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
 
 /* Thread */
 #if defined(_TTHREAD_WIN32_)
 typedef HANDLE thrd_t;
 #else
-typedef pthread_t thrd_t;
+typedef pthread_t       thrd_t;
 #endif
 
 /** Thread start function.
-* Any thread that is started with the @ref thrd_create() function must be
-* started through a function of this type.
-* @param arg The thread argument (the @c arg argument of the corresponding
-*        @ref thrd_create() call).
-* @return The thread return value, which can be obtained by another thread
-* by using the @ref thrd_join() function.
-*/
+ * Any thread that is started with the @ref thrd_create() function must be
+ * started through a function of this type.
+ * @param arg The thread argument (the @c arg argument of the corresponding
+ *        @ref thrd_create() call).
+ * @return The thread return value, which can be obtained by another thread
+ * by using the @ref thrd_join() function.
+ */
 typedef int (*thrd_start_t)(void *arg);
 
 /** Create a new thread.
-* @param thr Identifier of the newly created thread.
-* @param func A function pointer to the function that will be executed in
-*        the new thread.
-* @param arg An argument to the thread function.
-* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could
-* be allocated for the thread requested, or @ref thrd_error if the request
-* could not be honored.
-* @note A thread’s identifier may be reused for a different thread once the
-* original thread has exited and either been detached or joined to another
-* thread.
-*/
+ * @param thr Identifier of the newly created thread.
+ * @param func A function pointer to the function that will be executed in
+ *        the new thread.
+ * @param arg An argument to the thread function.
+ * @return @ref thrd_success on success, or @ref thrd_nomem if no memory could
+ * be allocated for the thread requested, or @ref thrd_error if the request
+ * could not be honored.
+ * @note A thread’s identifier may be reused for a different thread once the
+ * original thread has exited and either been detached or joined to another
+ * thread.
+ */
 int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
 
 /** Identify the calling thread.
-* @return The identifier of the calling thread.
-*/
+ * @return The identifier of the calling thread.
+ */
 thrd_t thrd_current(void);
 
 /** NOT YET IMPLEMENTED.
-*/
+ */
 int thrd_detach(thrd_t thr);
 
 /** Compare two thread identifiers.
-* The function determines if two thread identifiers refer to the same thread.
-* @return Zero if the two thread identifiers refer to different threads.
-* Otherwise a nonzero value is returned.
-*/
+ * The function determines if two thread identifiers refer to the same thread.
+ * @return Zero if the two thread identifiers refer to different threads.
+ * Otherwise a nonzero value is returned.
+ */
 int thrd_equal(thrd_t thr0, thrd_t thr1);
 
 /** Terminate execution of the calling thread.
-* @param res Result code of the calling thread.
-*/
+ * @param res Result code of the calling thread.
+ */
 void thrd_exit(int res);
 
 /** Wait for a thread to terminate.
-* The function joins the given thread with the current thread by blocking
-* until the other thread has terminated.
-* @param thr The thread to join with.
-* @param res If this pointer is not NULL, the function will store the result
-*        code of the given thread in the integer pointed to by @c res.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * The function joins the given thread with the current thread by blocking
+ * until the other thread has terminated.
+ * @param thr The thread to join with.
+ * @param res If this pointer is not NULL, the function will store the result
+ *        code of the given thread in the integer pointed to by @c res.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int thrd_join(thrd_t thr, int *res);
 
 /** Put the calling thread to sleep.
-* Suspend execution of the calling thread.
-* @param time_point A point in time at which the thread will resume (absolute time).
-* @param remaining If non-NULL, this parameter will hold the remaining time until
-*                  time_point upon return. This will typically be zero, but if
-*                  the thread was woken up by a signal that is not ignored before
-*                  time_point was reached @c remaining will hold a positive
-*                  time.
-* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
-*/
+ * Suspend execution of the calling thread.
+ * @param time_point A point in time at which the thread will resume (absolute time).
+ * @param remaining If non-NULL, this parameter will hold the remaining time until
+ *                  time_point upon return. This will typically be zero, but if
+ *                  the thread was woken up by a signal that is not ignored before
+ *                  time_point was reached @c remaining will hold a positive
+ *                  time.
+ * @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
+ */
 int thrd_sleep(const struct timespec *time_point, struct timespec *remaining);
 
 /** Yield execution to another thread.
-* Permit other threads to run, even if the current thread would ordinarily
-* continue to run.
-*/
+ * Permit other threads to run, even if the current thread would ordinarily
+ * continue to run.
+ */
 void thrd_yield(void);
 
 /* Thread local storage */
 #if defined(_TTHREAD_WIN32_)
 typedef DWORD tss_t;
 #else
-typedef pthread_key_t tss_t;
+typedef pthread_key_t   tss_t;
 #endif
 
 /** Destructor function for a thread-specific storage.
-* @param val The value of the destructed thread-specific storage.
-*/
+ * @param val The value of the destructed thread-specific storage.
+ */
 typedef void (*tss_dtor_t)(void *val);
 
 /** Create a thread-specific storage.
-* @param key The unique key identifier that will be set if the function is
-*        successful.
-* @param dtor Destructor function. This can be NULL.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-* @note The destructor function is not supported under Windows. If @c dtor is
-* not NULL when calling this function under Windows, the function will fail
-* and return @ref thrd_error.
-*/
+ * @param key The unique key identifier that will be set if the function is
+ *        successful.
+ * @param dtor Destructor function. This can be NULL.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ * @note The destructor function is not supported under Windows. If @c dtor is
+ * not NULL when calling this function under Windows, the function will fail
+ * and return @ref thrd_error.
+ */
 int tss_create(tss_t *key, tss_dtor_t dtor);
 
 /** Delete a thread-specific storage.
-* The function releases any resources used by the given thread-specific
-* storage.
-* @param key The key that shall be deleted.
-*/
+ * The function releases any resources used by the given thread-specific
+ * storage.
+ * @param key The key that shall be deleted.
+ */
 void tss_delete(tss_t key);
 
 /** Get the value for a thread-specific storage.
-* @param key The thread-specific storage identifier.
-* @return The value for the current thread held in the given thread-specific
-* storage.
-*/
+ * @param key The thread-specific storage identifier.
+ * @return The value for the current thread held in the given thread-specific
+ * storage.
+ */
 void *tss_get(tss_t key);
 
 /** Set the value for a thread-specific storage.
-* @param key The thread-specific storage identifier.
-* @param val The value of the thread-specific storage to set for the current
-*        thread.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
+ * @param key The thread-specific storage identifier.
+ * @param val The value of the thread-specific storage to set for the current
+ *        thread.
+ * @return @ref thrd_success on success, or @ref thrd_error if the request could
+ * not be honored.
+ */
 int tss_set(tss_t key, void *val);
 
-
 #endif /* _TINYTHREAD_H_ */
-
index b1e8a9d7980ef0b0db4f0d5b6580ccdec2fca3aa..57307ff87b597ae1108cd82abe5ae35be1a910d3 100644 (file)
 
 #include "vkvg.h"
 
-#define TRY_LOAD_DEVICE_EXT(ext) {                                                             \
-if (vkh_phyinfo_try_get_extension_properties(pi, #ext, NULL))  \
-       enabledExts[enabledExtsCount++] = #ext;                                         \
-}
+#define TRY_LOAD_DEVICE_EXT(ext)                                                                                       \
+    {                                                                                                                  \
+        if (vkh_phyinfo_try_get_extension_properties(pi, #ext, NULL))                                                  \
+            enabledExts[enabledExtsCount++] = #ext;                                                                    \
+    }
 
 static void glfw_error_callback(int error, const char *description) {
-       fprintf(stderr, "vkengine: GLFW error %d: %s\n", error, description);
+    fprintf(stderr, "vkengine: GLFW error %d: %s\n", error, description);
 }
 
-VkSampleCountFlagBits getMaxUsableSampleCount(VkSampleCountFlags counts)
-{
-       if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; }
-       if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; }
-       if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; }
-       if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; }
-       if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; }
-       if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; }
-       return VK_SAMPLE_COUNT_1_BIT;
+VkSampleCountFlagBits getMaxUsableSampleCount(VkSampleCountFlags counts) {
+    if (counts & VK_SAMPLE_COUNT_64_BIT) {
+        return VK_SAMPLE_COUNT_64_BIT;
+    }
+    if (counts & VK_SAMPLE_COUNT_32_BIT) {
+        return VK_SAMPLE_COUNT_32_BIT;
+    }
+    if (counts & VK_SAMPLE_COUNT_16_BIT) {
+        return VK_SAMPLE_COUNT_16_BIT;
+    }
+    if (counts & VK_SAMPLE_COUNT_8_BIT) {
+        return VK_SAMPLE_COUNT_8_BIT;
+    }
+    if (counts & VK_SAMPLE_COUNT_4_BIT) {
+        return VK_SAMPLE_COUNT_4_BIT;
+    }
+    if (counts & VK_SAMPLE_COUNT_2_BIT) {
+        return VK_SAMPLE_COUNT_2_BIT;
+    }
+    return VK_SAMPLE_COUNT_1_BIT;
 }
 
-void vkengine_dump_Infos (VkEngine e){
-       printf("max samples = %d\n", getMaxUsableSampleCount(e->gpu_props.limits.framebufferColorSampleCounts));
-       printf("max tex2d size = %d\n", e->gpu_props.limits.maxImageDimension2D);
-       printf("max tex array layers = %d\n", e->gpu_props.limits.maxImageArrayLayers);
-       printf("max mem alloc count = %d\n", e->gpu_props.limits.maxMemoryAllocationCount);
-
-       for (uint32_t i = 0; i < e->memory_properties.memoryHeapCount; i++) {
-               printf("Mem Heap %d\n", i);
-               printf("\tflags= %d\n", e->memory_properties.memoryHeaps[i].flags);
-               printf("\tsize = %lu Mo\n", (unsigned long)e->memory_properties.memoryHeaps[i].size/ (uint32_t)(1024*1024));
-       }
-       for (uint32_t i = 0; i < e->memory_properties.memoryTypeCount; i++) {
-               printf("Mem type %d\n", i);
-               printf("\theap %d: ", e->memory_properties.memoryTypes[i].heapIndex);
-               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
-                       printf("VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|");
-               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
-                       printf("VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|");
-               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
-                       printf("VK_MEMORY_PROPERTY_HOST_COHERENT_BIT|");
-               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
-                       printf("VK_MEMORY_PROPERTY_HOST_CACHED_BIT|");
-               if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
-                       printf("VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT|");
-               printf("\n");
-       }
+void vkengine_dump_Infos(VkEngine e) {
+    printf("max samples = %d\n", getMaxUsableSampleCount(e->gpu_props.limits.framebufferColorSampleCounts));
+    printf("max tex2d size = %d\n", e->gpu_props.limits.maxImageDimension2D);
+    printf("max tex array layers = %d\n", e->gpu_props.limits.maxImageArrayLayers);
+    printf("max mem alloc count = %d\n", e->gpu_props.limits.maxMemoryAllocationCount);
+
+    for (uint32_t i = 0; i < e->memory_properties.memoryHeapCount; i++) {
+        printf("Mem Heap %d\n", i);
+        printf("\tflags= %d\n", e->memory_properties.memoryHeaps[i].flags);
+        printf("\tsize = %lu Mo\n", (unsigned long)e->memory_properties.memoryHeaps[i].size / (uint32_t)(1024 * 1024));
+    }
+    for (uint32_t i = 0; i < e->memory_properties.memoryTypeCount; i++) {
+        printf("Mem type %d\n", i);
+        printf("\theap %d: ", e->memory_properties.memoryTypes[i].heapIndex);
+        if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
+            printf("VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|");
+        if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
+            printf("VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|");
+        if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
+            printf("VK_MEMORY_PROPERTY_HOST_COHERENT_BIT|");
+        if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
+            printf("VK_MEMORY_PROPERTY_HOST_CACHED_BIT|");
+        if (e->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
+            printf("VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT|");
+        printf("\n");
+    }
 }
 
+void vkengine_dump_available_layers() {
+    uint32_t layerCount;
+    vkEnumerateInstanceLayerProperties(&layerCount, NULL);
 
+    VkLayerProperties *availableLayers = (VkLayerProperties *)malloc(layerCount * sizeof(VkLayerProperties));
+    vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);
 
-void vkengine_dump_available_layers () {
-       uint32_t layerCount;
-       vkEnumerateInstanceLayerProperties(&layerCount, NULL);
-
-       VkLayerProperties* availableLayers = (VkLayerProperties*)malloc(layerCount*sizeof(VkLayerProperties));
-       vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);
-
-       printf("Available Layers:\n");
-       printf("-----------------\n");
-       for (uint32_t i=0; i<layerCount; i++) {
-                printf ("\t - %s\n", availableLayers[i].layerName);
-       }
-       printf("-----------------\n\n");
-       free (availableLayers);
+    printf("Available Layers:\n");
+    printf("-----------------\n");
+    for (uint32_t i = 0; i < layerCount; i++) {
+        printf("\t - %s\n", availableLayers[i].layerName);
+    }
+    printf("-----------------\n\n");
+    free(availableLayers);
 }
-bool vkengine_try_get_phyinfo (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy) {
-       for (uint32_t i=0; i<phyCount; i++){
-               if (phys[i]->properties.deviceType == gpuType) {
-                        *phy = phys[i];
-                        return true;
-               }
-       }
-       return false;
+bool vkengine_try_get_phyinfo(VkhPhyInfo *phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo *phy) {
+    for (uint32_t i = 0; i < phyCount; i++) {
+        if (phys[i]->properties.deviceType == gpuType) {
+            *phy = phys[i];
+            return true;
+        }
+    }
+    return false;
 }
-bool instance_extension_supported (VkExtensionProperties* instanceExtProps, uint32_t extCount, const char* instanceName) {
-       for (uint32_t i=0; i<extCount; i++) {
-               if (!strcmp(instanceExtProps[i].extensionName, instanceName))
-                       return true;
-       }
-       return false;
+bool instance_extension_supported(VkExtensionProperties *instanceExtProps, uint32_t extCount,
+                                  const char *instanceName) {
+    for (uint32_t i = 0; i < extCount; i++) {
+        if (!strcmp(instanceExtProps[i].extensionName, instanceName))
+            return true;
+    }
+    return false;
 }
 
-vk_engine_t* vkengine_create (VkPhysicalDeviceType preferedGPU, VkPresentModeKHR presentMode, uint32_t width, uint32_t height) {
-       glfwSetErrorCallback(glfw_error_callback);
+vk_engine_t *vkengine_create(VkPhysicalDeviceType preferedGPU, VkPresentModeKHR presentMode, uint32_t width,
+                             uint32_t height) {
+    glfwSetErrorCallback(glfw_error_callback);
 
-       if (!glfwInit()) {
-               perror ("glfwInit failed");
-               exit(-1);
-       }
+    if (!glfwInit()) {
+        perror("glfwInit failed");
+        exit(-1);
+    }
 
-       if (!glfwVulkanSupported()) {
-               perror ("glfwVulkanSupported return false.");
-               exit(-1);
-       }
+    if (!glfwVulkanSupported()) {
+        perror("glfwVulkanSupported return false.");
+        exit(-1);
+    }
 
-       const char* enabledLayers[10];
-       const char* enabledExts [10];
-       uint32_t enabledExtsCount = 0, enabledLayersCount = 0, phyCount = 0;
+    const char *enabledLayers[10];
+    const char *enabledExts[10];
+    uint32_t    enabledExtsCount = 0, enabledLayersCount = 0, phyCount = 0;
 
-       vkh_layers_check_init();
+    vkh_layers_check_init();
 #ifdef VKVG_USE_VALIDATION
-       if (vkh_layer_is_present("VK_LAYER_KHRONOS_validation"))
-               enabledLayers[enabledLayersCount++] = "VK_LAYER_KHRONOS_validation";
+    if (vkh_layer_is_present("VK_LAYER_KHRONOS_validation"))
+        enabledLayers[enabledLayersCount++] = "VK_LAYER_KHRONOS_validation";
 #endif
 #ifdef VKVG_USE_MESA_OVERLAY
-       if (vkh_layer_is_present("VK_LAYER_MESA_overlay"))
-               enabledLayers[enabledLayersCount++] = "VK_LAYER_MESA_overlay";
+    if (vkh_layer_is_present("VK_LAYER_MESA_overlay"))
+        enabledLayers[enabledLayersCount++] = "VK_LAYER_MESA_overlay";
 #endif
 
 #ifdef VKVG_USE_RENDERDOC
-       if (vkh_layer_is_present("VK_LAYER_RENDERDOC_Capture"))
-               enabledLayers[enabledLayersCount++] = "VK_LAYER_RENDERDOC_Capture";
+    if (vkh_layer_is_present("VK_LAYER_RENDERDOC_Capture"))
+        enabledLayers[enabledLayersCount++] = "VK_LAYER_RENDERDOC_Capture";
 #endif
-       vkh_layers_check_release();
+    vkh_layers_check_release();
 
-       uint32_t glfwReqExtsCount = 0;
-       const char** gflwExts = glfwGetRequiredInstanceExtensions (&glfwReqExtsCount);
+    uint32_t     glfwReqExtsCount = 0;
+    const char **gflwExts         = glfwGetRequiredInstanceExtensions(&glfwReqExtsCount);
 
-       vkvg_get_required_instance_extensions (enabledExts, &enabledExtsCount);
+    vkvg_get_required_instance_extensions(enabledExts, &enabledExtsCount);
 
-       for (uint32_t i=0;i<glfwReqExtsCount;i++)
-               enabledExts[i+enabledExtsCount] = gflwExts[i];
+    for (uint32_t i = 0; i < glfwReqExtsCount; i++)
+        enabledExts[i + enabledExtsCount] = gflwExts[i];
 
-       enabledExtsCount += glfwReqExtsCount;
+    enabledExtsCount += glfwReqExtsCount;
 
-       vk_engine_t* e = (vk_engine_t*)calloc(1,sizeof(vk_engine_t));
+    vk_engine_t *e = (vk_engine_t *)calloc(1, sizeof(vk_engine_t));
 
 #ifdef VK_VERSION_1_2
-       e->app =  vkh_app_create(1, 2, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
+    e->app = vkh_app_create(1, 2, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
 #else
-       e->app =  vkh_app_create(1, 1, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
+    e->app = vkh_app_create(1, 1, "vkvg", enabledLayersCount, enabledLayers, enabledExtsCount, enabledExts);
 #endif
 
-
-#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
-       vkh_app_enable_debug_messenger(e->app
-                                                          , VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
-                                                          //| VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
-                                                          //| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
-                                                          , VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
-                                                          | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
-                                                          //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
-                                                          //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
-                                                          , NULL);
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+    vkh_app_enable_debug_messenger(e->app,
+                                   VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
+                                   //| VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
+                                   //| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
+                                   ,
+                                   VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
+                                       VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
+                                   //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
+                                   //| VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
+                                   ,
+                                   NULL);
 #endif
 
-       glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
-       glfwWindowHint(GLFW_RESIZABLE,  GLFW_TRUE);
-       glfwWindowHint(GLFW_FLOATING,   GLFW_FALSE);
-       glfwWindowHint(GLFW_DECORATED,  GLFW_TRUE);
+    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
+    glfwWindowHint(GLFW_FLOATING, GLFW_FALSE);
+    glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
 
-       e->window = glfwCreateWindow ((int)width, (int)height, "Window Title", NULL, NULL);
+    e->window = glfwCreateWindow((int)width, (int)height, "Window Title", NULL, NULL);
 
-       VkSurfaceKHR surf;
-       VK_CHECK_RESULT (glfwCreateWindowSurface(e->app->inst, e->window, NULL, &surf))
+    VkSurfaceKHR surf;
+    VK_CHECK_RESULT(glfwCreateWindowSurface(e->app->inst, e->window, NULL, &surf))
 
-       VkhPhyInfo* phys = vkh_app_get_phyinfos (e->app, &phyCount, surf);
+    VkhPhyInfo *phys = vkh_app_get_phyinfos(e->app, &phyCount, surf);
 
-       VkhPhyInfo pi = 0;
-       if (!vkengine_try_get_phyinfo(phys, phyCount, preferedGPU, &pi)
-       &&  !vkengine_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, &pi)
-       &&  !vkengine_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, &pi))
-               pi = phys[0];
-       assert(pi && "No vulkan physical device found.");
+    VkhPhyInfo pi = 0;
+    if (!vkengine_try_get_phyinfo(phys, phyCount, preferedGPU, &pi) &&
+        !vkengine_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, &pi) &&
+        !vkengine_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, &pi))
+        pi = phys[0];
+    assert(pi && "No vulkan physical device found.");
 
-       e->memory_properties = pi->memProps;
-       e->gpu_props = pi->properties;
+    e->memory_properties = pi->memProps;
+    e->gpu_props         = pi->properties;
 
-       uint32_t qCount = 0;
-       float qPriorities[] = {0.0};
+    uint32_t qCount        = 0;
+    float    qPriorities[] = {0.0};
 
-       VkDeviceQueueCreateInfo pQueueInfos[] = { {0},{0},{0} };
-       if (vkh_phyinfo_create_presentable_queues       (pi, 1, qPriorities, &pQueueInfos[qCount]))
-               qCount++;
-       /*if (vkh_phyinfo_create_compute_queues         (pi, 1, qPriorities, &pQueueInfos[qCount]))
-               qCount++;
-       if (vkh_phyinfo_create_transfer_queues          (pi, 1, qPriorities, &pQueueInfos[qCount]))
-               qCount++;*/
+    VkDeviceQueueCreateInfo pQueueInfos[] = {{0}, {0}, {0}};
+    if (vkh_phyinfo_create_presentable_queues(pi, 1, qPriorities, &pQueueInfos[qCount]))
+        qCount++;
+    /*if (vkh_phyinfo_create_compute_queues            (pi, 1, qPriorities, &pQueueInfos[qCount]))
+        qCount++;
+    if (vkh_phyinfo_create_transfer_queues             (pi, 1, qPriorities, &pQueueInfos[qCount]))
+        qCount++;*/
 
-       enabledExtsCount=0;
+    enabledExtsCount = 0;
 
-       if (vkvg_get_required_device_extensions (pi->phy, enabledExts, &enabledExtsCount) != VKVG_STATUS_SUCCESS) {
-               perror ("vkvg_get_required_device_extensions failed, enable log for details.\n");
-               exit(-1);
-       }
-       TRY_LOAD_DEVICE_EXT (VK_KHR_swapchain)
+    if (vkvg_get_required_device_extensions(pi->phy, enabledExts, &enabledExtsCount) != VKVG_STATUS_SUCCESS) {
+        perror("vkvg_get_required_device_extensions failed, enable log for details.\n");
+        exit(-1);
+    }
+    TRY_LOAD_DEVICE_EXT(VK_KHR_swapchain)
 
-       VkPhysicalDeviceFeatures enabledFeatures = {0};
-       const void* pNext = vkvg_get_device_requirements (&enabledFeatures);
+    VkPhysicalDeviceFeatures enabledFeatures = {0};
+    const void              *pNext           = vkvg_get_device_requirements(&enabledFeatures);
 
-       VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
-                                                                          .queueCreateInfoCount = qCount,
-                                                                          .pQueueCreateInfos = (VkDeviceQueueCreateInfo*)&pQueueInfos,
-                                                                          .enabledExtensionCount = enabledExtsCount,
-                                                                          .ppEnabledExtensionNames = enabledExts,
-                                                                          .pEnabledFeatures = &enabledFeatures,
-                                                                          .pNext = pNext};
+    VkDeviceCreateInfo device_info = {.sType                   = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+                                      .queueCreateInfoCount    = qCount,
+                                      .pQueueCreateInfos       = (VkDeviceQueueCreateInfo *)&pQueueInfos,
+                                      .enabledExtensionCount   = enabledExtsCount,
+                                      .ppEnabledExtensionNames = enabledExts,
+                                      .pEnabledFeatures        = &enabledFeatures,
+                                      .pNext                   = pNext};
 
-       e->dev = vkh_device_create(e->app, pi, &device_info);
+    e->dev = vkh_device_create(e->app, pi, &device_info);
 
-       e->renderer = vkh_presenter_create
-                       (e->dev, (uint32_t) pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, presentMode);
+    e->renderer =
+        vkh_presenter_create(e->dev, (uint32_t)pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, presentMode);
 
-       vkh_app_free_phyinfos (phyCount, phys);
+    vkh_app_free_phyinfos(phyCount, phys);
 
-       return e;
+    return e;
 }
 
-void vkengine_destroy (VkEngine e) {
-       //vkDeviceWaitIdle(e->dev->dev);
+void vkengine_destroy(VkEngine e) {
+    // vkDeviceWaitIdle(e->dev->dev);
 
-       VkSurfaceKHR surf = e->renderer->surface;
+    VkSurfaceKHR surf = e->renderer->surface;
 
-       vkh_presenter_destroy (e->renderer);
-       vkDestroySurfaceKHR (e->app->inst, surf, NULL);
+    vkh_presenter_destroy(e->renderer);
+    vkDestroySurfaceKHR(e->app->inst, surf, NULL);
 
-       vkh_device_destroy (e->dev);
+    vkh_device_destroy(e->dev);
 
-       glfwDestroyWindow (e->window);
-       vkh_app_destroy (e->app);
+    glfwDestroyWindow(e->window);
+    vkh_app_destroy(e->app);
 
-       glfwTerminate ();
+    glfwTerminate();
 
-       free(e);
-}
-void vkengine_close (VkEngine e) {
-       glfwSetWindowShouldClose(e->window, GLFW_TRUE);
-}
-void vkengine_blitter_run (VkEngine e, VkImage img, uint32_t width, uint32_t height) {
-       VkhPresenter p = e->renderer;
-       vkh_presenter_build_blit_cmd (p, img, width, height);
-
-       while (!vkengine_should_close (e)) {
-               glfwPollEvents();
-               if (!vkh_presenter_draw (p))
-                       vkh_presenter_build_blit_cmd (p, img, width, height);
-       }
-}
-bool vkengine_should_close (VkEngine e) {
-       return glfwWindowShouldClose (e->window);
-}
-void vkengine_set_title (VkEngine e, const char* title) {
-       glfwSetWindowTitle(e->window, title);
-}
-VkInstance vkengine_get_instance (VkEngine e){
-       return e->dev->instance;
-}
-VkDevice vkengine_get_device (VkEngine e){
-       return e->dev->dev;
-}
-VkPhysicalDevice vkengine_get_physical_device (VkEngine e){
-       return e->dev->phy;
-}
-VkQueue vkengine_get_queue (VkEngine e){
-       return e->renderer->queue;
-}
-uint32_t vkengine_get_queue_fam_idx (VkEngine e){
-       return e->renderer->qFam;
-}
-void vkengine_wait_idle (VkEngine e) {
-       vkDeviceWaitIdle(e->dev->dev);
-}
-
-void vkengine_set_key_callback (VkEngine e, GLFWkeyfun key_callback){
-       glfwSetKeyCallback (e->window, key_callback);
-}
-void vkengine_set_mouse_but_callback (VkEngine e, GLFWmousebuttonfun onMouseBut){
-       glfwSetMouseButtonCallback(e->window, onMouseBut);
+    free(e);
 }
-void vkengine_set_cursor_pos_callback (VkEngine e, GLFWcursorposfun onMouseMove){
-       glfwSetCursorPosCallback(e->window, onMouseMove);
+void vkengine_close(VkEngine e) { glfwSetWindowShouldClose(e->window, GLFW_TRUE); }
+void vkengine_blitter_run(VkEngine e, VkImage img, uint32_t width, uint32_t height) {
+    VkhPresenter p = e->renderer;
+    vkh_presenter_build_blit_cmd(p, img, width, height);
+
+    while (!vkengine_should_close(e)) {
+        glfwPollEvents();
+        if (!vkh_presenter_draw(p))
+            vkh_presenter_build_blit_cmd(p, img, width, height);
+    }
 }
-void vkengine_set_scroll_callback (VkEngine e, GLFWscrollfun onScroll){
-       glfwSetScrollCallback(e->window, onScroll);
+bool             vkengine_should_close(VkEngine e) { return glfwWindowShouldClose(e->window); }
+void             vkengine_set_title(VkEngine e, const char *title) { glfwSetWindowTitle(e->window, title); }
+VkInstance       vkengine_get_instance(VkEngine e) { return e->dev->instance; }
+VkDevice         vkengine_get_device(VkEngine e) { return e->dev->dev; }
+VkPhysicalDevice vkengine_get_physical_device(VkEngine e) { return e->dev->phy; }
+VkQueue          vkengine_get_queue(VkEngine e) { return e->renderer->queue; }
+uint32_t         vkengine_get_queue_fam_idx(VkEngine e) { return e->renderer->qFam; }
+void             vkengine_wait_idle(VkEngine e) { vkDeviceWaitIdle(e->dev->dev); }
+
+void vkengine_set_key_callback(VkEngine e, GLFWkeyfun key_callback) { glfwSetKeyCallback(e->window, key_callback); }
+void vkengine_set_mouse_but_callback(VkEngine e, GLFWmousebuttonfun onMouseBut) {
+    glfwSetMouseButtonCallback(e->window, onMouseBut);
 }
-void vkengine_set_char_callback (VkEngine e, GLFWcharfun onChar){
-       glfwSetCharCallback(e->window, onChar);
+void vkengine_set_cursor_pos_callback(VkEngine e, GLFWcursorposfun onMouseMove) {
+    glfwSetCursorPosCallback(e->window, onMouseMove);
 }
+void vkengine_set_scroll_callback(VkEngine e, GLFWscrollfun onScroll) { glfwSetScrollCallback(e->window, onScroll); }
+void vkengine_set_char_callback(VkEngine e, GLFWcharfun onChar) { glfwSetCharCallback(e->window, onChar); }
index ebed7727400119aae48dc29921ce59da7c117fb9..a8016ec8a37c9b0bfc8bd5668208462cf2dd33da 100644 (file)
 
 #define FENCE_TIMEOUT 100000000
 
-typedef struct _vk_engine_tVkEngine;
+typedef struct _vk_engine_t *VkEngine;
 
 typedef struct _vk_engine_t {
-       VkhApp                          app;
-       VkPhysicalDeviceMemoryProperties        memory_properties;
-       VkPhysicalDeviceProperties                      gpu_props;
-       VkhDevice                       dev;
-       GLFWwindow*                     window;
-       VkhPresenter            renderer;
-}vk_engine_t;
+    VkhApp                           app;
+    VkPhysicalDeviceMemoryProperties memory_properties;
+    VkPhysicalDeviceProperties       gpu_props;
+    VkhDevice                        dev;
+    GLFWwindow                      *window;
+    VkhPresenter                     renderer;
+} vk_engine_t;
 
-vk_engine_t*   vkengine_create  (VkPhysicalDeviceType preferedGPU, VkPresentModeKHR presentMode, uint32_t width, uint32_t height);
-void vkengine_dump_available_layers   ();
-bool vkengine_try_get_phyinfo (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy);
-void vkengine_destroy          (VkEngine e);
-bool vkengine_should_close     (VkEngine e);
-void vkengine_close                    (VkEngine e);
-void vkengine_dump_Infos       (VkEngine e);
-void vkengine_set_title                (VkEngine e, const char* title);
-VkInstance                     vkengine_get_instance           (VkEngine e);
-VkDevice                       vkengine_get_device                     (VkEngine e);
-VkPhysicalDevice       vkengine_get_physical_device(VkEngine e);
-VkQueue                                vkengine_get_queue                      (VkEngine e);
-uint32_t                       vkengine_get_queue_fam_idx      (VkEngine e);
+vk_engine_t *vkengine_create(VkPhysicalDeviceType preferedGPU, VkPresentModeKHR presentMode, uint32_t width,
+                             uint32_t height);
+void         vkengine_dump_available_layers();
+bool       vkengine_try_get_phyinfo(VkhPhyInfo *phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo *phy);
+void       vkengine_destroy(VkEngine e);
+bool       vkengine_should_close(VkEngine e);
+void       vkengine_close(VkEngine e);
+void       vkengine_dump_Infos(VkEngine e);
+void       vkengine_set_title(VkEngine e, const char *title);
+VkInstance vkengine_get_instance(VkEngine e);
+VkDevice   vkengine_get_device(VkEngine e);
+VkPhysicalDevice vkengine_get_physical_device(VkEngine e);
+VkQueue          vkengine_get_queue(VkEngine e);
+uint32_t         vkengine_get_queue_fam_idx(VkEngine e);
 
-void vkengine_get_queues_properties (vk_engine_t* e, VkQueueFamilyProperties** qFamProps, uint32_t* count);
+void vkengine_get_queues_properties(vk_engine_t *e, VkQueueFamilyProperties **qFamProps, uint32_t *count);
 
-void vkengine_set_key_callback                 (VkEngine e, GLFWkeyfun key_callback);
-void vkengine_set_mouse_but_callback   (VkEngine e, GLFWmousebuttonfun onMouseBut);
-void vkengine_set_cursor_pos_callback  (VkEngine e, GLFWcursorposfun onMouseMove);
-void vkengine_set_scroll_callback              (VkEngine e, GLFWscrollfun onScroll);
-void vkengine_set_char_callback                        (VkEngine e, GLFWcharfun onChar);
+void vkengine_set_key_callback(VkEngine e, GLFWkeyfun key_callback);
+void vkengine_set_mouse_but_callback(VkEngine e, GLFWmousebuttonfun onMouseBut);
+void vkengine_set_cursor_pos_callback(VkEngine e, GLFWcursorposfun onMouseMove);
+void vkengine_set_scroll_callback(VkEngine e, GLFWscrollfun onScroll);
+void vkengine_set_char_callback(VkEngine e, GLFWcharfun onChar);
 
-void vkengine_wait_idle                                        (VkEngine e);
+void vkengine_wait_idle(VkEngine e);
 #endif
index 54711b4bbb7a5d7156b4a78737b438221926228a..76e94905b6fe6c5e2aac3308c395ab16f777994c 100644 (file)
@@ -1,40 +1,39 @@
 #include "test.h"
 
-void compositing(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+void compositing() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
-       vkvg_set_source_rgba(ctx, 1,0,0,0.5f);
-       vkvg_rectangle(ctx,100,100,200,200);
-       vkvg_fill(ctx);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 0.5f);
+    vkvg_rectangle(ctx, 100, 100, 200, 200);
+    vkvg_fill(ctx);
 
-       vkvg_set_source_rgba(ctx, 0,0,1,0.5f);
-       vkvg_rectangle(ctx,200,200,200,200);
-       vkvg_fill(ctx);
+    vkvg_set_source_rgba(ctx, 0, 0, 1, 0.5f);
+    vkvg_rectangle(ctx, 200, 200, 200, 200);
+    vkvg_fill(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
-void opacity(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+void opacity() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
-       vkvg_set_source_rgba(ctx, 1,0,0,1.0f);
-       vkvg_rectangle(ctx,100,100,200,200);
-       vkvg_fill(ctx);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1.0f);
+    vkvg_rectangle(ctx, 100, 100, 200, 200);
+    vkvg_fill(ctx);
 
-       vkvg_set_opacity(ctx,0.5f);
+    vkvg_set_opacity(ctx, 0.5f);
 
-       vkvg_set_source_rgba(ctx, 0,0,1,1.0f);
-       vkvg_rectangle(ctx,200,200,200,200);
-       vkvg_fill(ctx);
+    vkvg_set_source_rgba(ctx, 0, 0, 1, 1.0f);
+    vkvg_rectangle(ctx, 200, 200, 200, 200);
+    vkvg_fill(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
-
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (compositing, argc, argv);
-       PERFORM_TEST (opacity, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(compositing, argc, argv);
+    PERFORM_TEST(opacity, argc, argv);
+    return 0;
 }
index b22da8ab2b4729d5ae8f4450d688b511210996c1..caf0a262aa24fbd28b901df66461b6ebd0db448c 100644 (file)
@@ -1,22 +1,22 @@
 #include "test.h"
 
-void create_destroy_multi(){
-       VkvgContext* ctxs = (VkvgContext*)malloc(sizeof(VkvgContext)*test_size);
-       for (uint32_t i = 0; i < test_size; i++)
-               ctxs[i] = vkvg_create(surf);
-       for (uint32_t i = 0; i < test_size; i++)
-               vkvg_destroy(ctxs[i]);
-       free(ctxs);
+void create_destroy_multi() {
+    VkvgContext *ctxs = (VkvgContext *)malloc(sizeof(VkvgContext) * test_size);
+    for (uint32_t i = 0; i < test_size; i++)
+        ctxs[i] = vkvg_create(surf);
+    for (uint32_t i = 0; i < test_size; i++)
+        vkvg_destroy(ctxs[i]);
+    free(ctxs);
 }
 
-void create_destroy_single(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_destroy(ctx);
+void create_destroy_single() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       PERFORM_TEST (create_destroy_multi, argc, argv);
-       no_test_size = true;
-       PERFORM_TEST (create_destroy_single, argc, argv);
-       return 0;
+    PERFORM_TEST(create_destroy_multi, argc, argv);
+    no_test_size = true;
+    PERFORM_TEST(create_destroy_single, argc, argv);
+    return 0;
 }
index ff78bc8b4e039916f63e21ad588d12200fc5abfa..d1bcfd1faf62a2d25294036af76fdc1326ac5cfd 100644 (file)
 
 //"M80 170   C100 170 160 170 180 170 lZ"
 void test3() {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear (ctx);
-       vkvg_set_line_width(ctx, 20);
-       vkvg_set_source_rgb (ctx,1,0,0);
-       vkvg_move_to (ctx,80,170);
-       vkvg_curve_to (ctx, 100,170,160,171,180,170);
-       //vkvg_rel_line_to (ctx, -30,100);
-       vkvg_close_path (ctx);
-       vkvg_stroke (ctx);
-       vkvg_destroy (ctx);
-
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    vkvg_set_line_width(ctx, 20);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_move_to(ctx, 80, 170);
+    vkvg_curve_to(ctx, 100, 170, 160, 171, 180, 170);
+    // vkvg_rel_line_to (ctx, -30,100);
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+    vkvg_destroy(ctx);
 }
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
-
-       vkvg_set_line_width(ctx, 20);
-
-       vkvg_scale(ctx,2,2);
-       vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL);
-
-       //vkvg_arc (ctx, 200, 500, 100, 0, M_PI);
-
-       vkvg_set_source_rgb   (ctx, 0.5f,0,0);
-
-
-       /*vkvg_move_to(ctx,100,100);
-       vkvg_line_to(ctx,300,100);
-       vkvg_line_to(ctx,500,300);
-       vkvg_line_to(ctx,300,500);
-       //vkvg_arc (ctx, 200, 500, 100, 0, M_PI);
-       vkvg_line_to(ctx,300,700);
-       vkvg_line_to(ctx,100,500);*/
-
-       /*vkvg_arc(ctx, 300, 300, 100, 0, M_PI);
-       vkvg_line_to(ctx,100,200);
-       vkvg_line_to(ctx,200,100);
-       vkvg_arc(ctx, 250, 100, 50, M_PI, M_PI * 1.5f);
-       vkvg_line_to(ctx,350,50);
-       vkvg_arc(ctx, 350, 100, 50, M_PI*1.5f, M_PI * 2.0f);
-
-       vkvg_stroke(ctx);
-       vkvg_translate(ctx,400,30);
-
-       */
-       //vkvg_set_fill_rule(ctx,VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_translate(ctx,200,30);
-       vkvg_arc(ctx, 200, 200, 20, 0, M_PIF*2);
-       //vkvg_stroke(ctx);
-
-       vkvg_set_source_rgba (ctx, 0.5f,0.0f,1.0f,0.5f);
-       vkvg_move_to(ctx,100,100);
-       vkvg_line_to(ctx,200,100);
-       //vkvg_move_to(ctx,200,100);
-       vkvg_curve_to(ctx,250,100,300,150,300,200);
-       vkvg_line_to(ctx,300,300);
-       vkvg_curve_to(ctx,300,350,250,400,200,400);
-       vkvg_line_to(ctx,100,400);
-       vkvg_curve_to(ctx,50,400,10,350,10,300);
-       vkvg_line_to(ctx,10,200);
-       vkvg_curve_to(ctx,10,150,50,100,100,100);
-       //vkvg_close_path(ctx);
-       vkvg_fill_preserve(ctx);
-       vkvg_set_source_rgba   (ctx, 0.1f,0.3f,0.7f,0.5f);
-       vkvg_stroke(ctx);
-
-
-       vkvg_destroy(ctx);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
+
+    vkvg_set_line_width(ctx, 20);
+
+    vkvg_scale(ctx, 2, 2);
+    vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL);
+
+    // vkvg_arc (ctx, 200, 500, 100, 0, M_PI);
+
+    vkvg_set_source_rgb(ctx, 0.5f, 0, 0);
+
+    /*vkvg_move_to(ctx,100,100);
+    vkvg_line_to(ctx,300,100);
+    vkvg_line_to(ctx,500,300);
+    vkvg_line_to(ctx,300,500);
+    //vkvg_arc (ctx, 200, 500, 100, 0, M_PI);
+    vkvg_line_to(ctx,300,700);
+    vkvg_line_to(ctx,100,500);*/
+
+    /*vkvg_arc(ctx, 300, 300, 100, 0, M_PI);
+    vkvg_line_to(ctx,100,200);
+    vkvg_line_to(ctx,200,100);
+    vkvg_arc(ctx, 250, 100, 50, M_PI, M_PI * 1.5f);
+    vkvg_line_to(ctx,350,50);
+    vkvg_arc(ctx, 350, 100, 50, M_PI*1.5f, M_PI * 2.0f);
+
+    vkvg_stroke(ctx);
+    vkvg_translate(ctx,400,30);
+
+    */
+    // vkvg_set_fill_rule(ctx,VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_translate(ctx, 200, 30);
+    vkvg_arc(ctx, 200, 200, 20, 0, M_PIF * 2);
+    // vkvg_stroke(ctx);
+
+    vkvg_set_source_rgba(ctx, 0.5f, 0.0f, 1.0f, 0.5f);
+    vkvg_move_to(ctx, 100, 100);
+    vkvg_line_to(ctx, 200, 100);
+    // vkvg_move_to(ctx,200,100);
+    vkvg_curve_to(ctx, 250, 100, 300, 150, 300, 200);
+    vkvg_line_to(ctx, 300, 300);
+    vkvg_curve_to(ctx, 300, 350, 250, 400, 200, 400);
+    vkvg_line_to(ctx, 100, 400);
+    vkvg_curve_to(ctx, 50, 400, 10, 350, 10, 300);
+    vkvg_line_to(ctx, 10, 200);
+    vkvg_curve_to(ctx, 10, 150, 50, 100, 100, 100);
+    // vkvg_close_path(ctx);
+    vkvg_fill_preserve(ctx);
+    vkvg_set_source_rgba(ctx, 0.1f, 0.3f, 0.7f, 0.5f);
+    vkvg_stroke(ctx);
+
+    vkvg_destroy(ctx);
 }
 
 void curved_rect() {
-       VkvgContext ctx = vkvg_create(surf);
-
-       float x = 50, y = 50, width = 150, height = 140, radius = 30;
-
-       vkvg_scale(ctx, 2, 2);
-       //vkvg_rotate(ctx,0.5f);
-
-       vkvg_set_line_width(ctx, 15);
-       vkvg_set_source_rgba(ctx, 0, 0.5f, 0.4f, 1);
-
-       if ((radius > height / 2) || (radius > width / 2))
-               radius = MIN(height / 2, width / 2);
-
-       vkvg_move_to(ctx, x, y + radius);
-       vkvg_arc(ctx, x + radius, y + radius, radius, M_PIF, (float)-M_PI_2);
-       vkvg_line_to(ctx, x + width - radius, y);
-       vkvg_arc(ctx, x + width - radius, y + radius, radius, (float)-M_PI_2, 0);
-       vkvg_line_to(ctx, x + width, y + height - radius);
-       vkvg_arc(ctx, x + width - radius, y + height - radius, radius, 0, (float)M_PI_2);
-       vkvg_line_to(ctx, x + radius, y + height);
-       vkvg_arc(ctx, x + radius, y + height - radius, radius, (float)M_PI_2, M_PIF);
-       vkvg_line_to(ctx, x, y + radius);
-       vkvg_close_path(ctx);
-       vkvg_fill_preserve(ctx);
-       vkvg_set_source_rgba(ctx, 0.5f, 0, 0, 0.5f);
-       vkvg_stroke(ctx);
-
-       vkvg_destroy(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+
+    float x = 50, y = 50, width = 150, height = 140, radius = 30;
+
+    vkvg_scale(ctx, 2, 2);
+    // vkvg_rotate(ctx,0.5f);
+
+    vkvg_set_line_width(ctx, 15);
+    vkvg_set_source_rgba(ctx, 0, 0.5f, 0.4f, 1);
+
+    if ((radius > height / 2) || (radius > width / 2))
+        radius = MIN(height / 2, width / 2);
+
+    vkvg_move_to(ctx, x, y + radius);
+    vkvg_arc(ctx, x + radius, y + radius, radius, M_PIF, (float)-M_PI_2);
+    vkvg_line_to(ctx, x + width - radius, y);
+    vkvg_arc(ctx, x + width - radius, y + radius, radius, (float)-M_PI_2, 0);
+    vkvg_line_to(ctx, x + width, y + height - radius);
+    vkvg_arc(ctx, x + width - radius, y + height - radius, radius, 0, (float)M_PI_2);
+    vkvg_line_to(ctx, x + radius, y + height);
+    vkvg_arc(ctx, x + radius, y + height - radius, radius, (float)M_PI_2, M_PIF);
+    vkvg_line_to(ctx, x, y + radius);
+    vkvg_close_path(ctx);
+    vkvg_fill_preserve(ctx);
+    vkvg_set_source_rgba(ctx, 0.5f, 0, 0, 0.5f);
+    vkvg_stroke(ctx);
+
+    vkvg_destroy(ctx);
 }
 
 void test2() {
-       VkvgContext ctx = vkvg_create(surf);
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_move_to(ctx, 100, 400);
-       vkvg_curve_to(ctx, 100, 100, 600, 700, 600, 400);
-       vkvg_curve_to(ctx, 1000, 100, 100, 800, 1000, 800);
-       vkvg_curve_to(ctx, 1000, 500, 700, 500, 700, 100);
-       vkvg_close_path(ctx);
+    vkvg_move_to(ctx, 100, 400);
+    vkvg_curve_to(ctx, 100, 100, 600, 700, 600, 400);
+    vkvg_curve_to(ctx, 1000, 100, 100, 800, 1000, 800);
+    vkvg_curve_to(ctx, 1000, 500, 700, 500, 700, 100);
+    vkvg_close_path(ctx);
 
-       //vkvg_set_source_rgba   (ctx, 0.5,0.0,1.0,0.5);
-       //vkvg_fill_preserve(ctx);
+    // vkvg_set_source_rgba   (ctx, 0.5,0.0,1.0,0.5);
+    // vkvg_fill_preserve(ctx);
 
-       vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
-       vkvg_set_line_width(ctx, 40);
-       vkvg_stroke(ctx);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_set_line_width(ctx, 40);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 static bool fillAndStroke = true;
 
-void random_curves_stroke () {
-       float w = (float)test_width;
-       float h = (float)test_height;
+void random_curves_stroke() {
+    float w = (float)test_width;
+    float h = (float)test_height;
 
-       VkvgContext ctx = _initCtx();
+    VkvgContext ctx = _initCtx();
 
-       for (uint32_t i=0; i<test_size; i++) {
-               randomize_color(ctx);
-               float x1 = rndf() * w;
-               float y1 = rndf() * h;
+    for (uint32_t i = 0; i < test_size; i++) {
+        randomize_color(ctx);
+        float x1 = rndf() * w;
+        float y1 = rndf() * h;
 
-               vkvg_move_to (ctx, x1, y1);
-               draw_random_curve(ctx);
+        vkvg_move_to(ctx, x1, y1);
+        draw_random_curve(ctx);
 
-               vkvg_stroke (ctx);
-       }
-       vkvg_destroy(ctx);
+        vkvg_stroke(ctx);
+    }
+    vkvg_destroy(ctx);
 }
 
-void _long_curv () {
-       float w = (float)test_width;
-       float h = (float)test_height;
+void _long_curv() {
+    float w = (float)test_width;
+    float h = (float)test_height;
 
-       VkvgContext ctx = _initCtx();
+    VkvgContext ctx = _initCtx();
 
-       randomize_color(ctx);
-       float x1 = rndf() * w;
-       float y1 = rndf() * h;
-       vkvg_move_to (ctx, x1, y1);
+    randomize_color(ctx);
+    float x1 = rndf() * w;
+    float y1 = rndf() * h;
+    vkvg_move_to(ctx, x1, y1);
 
-       for (uint32_t i=0; i<test_size; i++) {
-               draw_random_curve(ctx);
-       }
+    for (uint32_t i = 0; i < test_size; i++) {
+        draw_random_curve(ctx);
+    }
 
-       if (fillAndStroke) {
-               vkvg_fill_preserve(ctx);
-               randomize_color(ctx);
-               vkvg_stroke (ctx);
-       }else
-               vkvg_fill (ctx);
+    if (fillAndStroke) {
+        vkvg_fill_preserve(ctx);
+        randomize_color(ctx);
+        vkvg_stroke(ctx);
+    else
+        vkvg_fill(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
-void long_curv_fill_nz () {
-       fillAndStroke = false;
-       fill_rule = VKVG_FILL_RULE_NON_ZERO;
-       _long_curv ();
+void long_curv_fill_nz() {
+    fillAndStroke = false;
+    fill_rule     = VKVG_FILL_RULE_NON_ZERO;
+    _long_curv();
 }
-void long_curv_fill_eo () {
-       fillAndStroke = false;
-       fill_rule = VKVG_FILL_RULE_EVEN_ODD;
-       _long_curv ();
+void long_curv_fill_eo() {
+    fillAndStroke = false;
+    fill_rule     = VKVG_FILL_RULE_EVEN_ODD;
+    _long_curv();
 }
-void long_curv_fill_stroke_nz () {
-       fillAndStroke = true;
-       fill_rule = VKVG_FILL_RULE_NON_ZERO;
-       _long_curv ();
+void long_curv_fill_stroke_nz() {
+    fillAndStroke = true;
+    fill_rule     = VKVG_FILL_RULE_NON_ZERO;
+    _long_curv();
 }
-void long_curv_fill_stroke_eo () {
-       fillAndStroke = true;
-       fill_rule = VKVG_FILL_RULE_EVEN_ODD;
-       _long_curv ();
+void long_curv_fill_stroke_eo() {
+    fillAndStroke = true;
+    fill_rule     = VKVG_FILL_RULE_EVEN_ODD;
+    _long_curv();
 }
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST(test3, argc, argv);
-       //return 0;
-       PERFORM_TEST(test, argc, argv);
-       PERFORM_TEST(test2, argc, argv);
-       PERFORM_TEST(curved_rect, argc, argv);
-       //PERFORM_TEST(long_curv_fill_nz, argc, argv);
-       no_test_size = false;
-       PERFORM_TEST(long_curv_fill_eo, argc, argv);
-       //PERFORM_TEST(long_curv_fill_stroke_nz, argc, argv);
-       PERFORM_TEST(long_curv_fill_stroke_eo, argc, argv);
-       PERFORM_TEST(random_curves_stroke, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test3, argc, argv);
+    // return 0;
+    PERFORM_TEST(test, argc, argv);
+    PERFORM_TEST(test2, argc, argv);
+    PERFORM_TEST(curved_rect, argc, argv);
+    // PERFORM_TEST(long_curv_fill_nz, argc, argv);
+    no_test_size = false;
+    PERFORM_TEST(long_curv_fill_eo, argc, argv);
+    // PERFORM_TEST(long_curv_fill_stroke_nz, argc, argv);
+    PERFORM_TEST(long_curv_fill_stroke_eo, argc, argv);
+    PERFORM_TEST(random_curves_stroke, argc, argv);
+    return 0;
 }
index 3fc0734e6e344d2107ec318c2d877d052d5a9c64..1f2ade457afc6fd3a9ce77838509025b84f08191 100644 (file)
 #include "test.h"
 
-void test(){
-       dash_offset += 0.2f;
-
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-       vkvg_set_source_rgb(ctx, 1, 1, 1);
-       vkvg_paint(ctx);
-       //const float dashes[] = {160.0f, 80};
-       //float dashes[] = {7.0f, 3};
-       float dashes[] = {100, 20, 20, 20};
-       vkvg_set_line_cap(ctx, VKVG_LINE_CAP_ROUND);
-       vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND);
-       vkvg_set_dash(ctx, dashes, 4, dash_offset);
-       vkvg_set_line_width(ctx, 4);
-       vkvg_set_source_rgb(ctx, 0, 0, 1);
-
-       vkvg_move_to (ctx, 50, 50);
-       vkvg_rel_line_to (ctx, 500, 0);
-       vkvg_rel_line_to (ctx, 0, 200);
-       vkvg_rel_line_to (ctx, 200, 0);
-       vkvg_rel_line_to (ctx, 0, 500);
-       vkvg_rel_line_to (ctx, -700, 0);
-       vkvg_close_path(ctx);
-       vkvg_stroke (ctx);
-
-       dashes[0] = 0;
-       dashes[1] = 20;
-       vkvg_set_dash(ctx, dashes, 2, dash_offset);
-
-       vkvg_set_source_rgb(ctx, 0, 1, 0);
-
-       vkvg_move_to (ctx, 100, 100);
-       vkvg_rel_line_to (ctx, 400, 0);
-       vkvg_rel_line_to (ctx, 0, 200);
-       vkvg_rel_line_to (ctx, 200, 0);
-       vkvg_rel_line_to (ctx, 0, 400);
-       vkvg_rel_line_to (ctx, -600, 0);
-       vkvg_close_path(ctx);
-       vkvg_stroke (ctx);
-
-       dashes[0] = 80;
-       dashes[1] = 20;
-
-       vkvg_set_line_width(ctx, 10);
-       vkvg_set_source_rgb(ctx, 1, 0, 0);
-
-       vkvg_set_dash(ctx, dashes, 2, dash_offset);
-
-       vkvg_rectangle(ctx, 200,300,200,200);
-       /*vkvg_move_to(ctx, 200,300);
-       vkvg_rel_line_to(ctx,200,0);*/
-       vkvg_stroke (ctx);
-
-       vkvg_destroy(ctx);
+void test() {
+    dash_offset += 0.2f;
+
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
+    vkvg_paint(ctx);
+    // const float dashes[] = {160.0f, 80};
+    // float dashes[] = {7.0f, 3};
+    float dashes[] = {100, 20, 20, 20};
+    vkvg_set_line_cap(ctx, VKVG_LINE_CAP_ROUND);
+    vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND);
+    vkvg_set_dash(ctx, dashes, 4, dash_offset);
+    vkvg_set_line_width(ctx, 4);
+    vkvg_set_source_rgb(ctx, 0, 0, 1);
+
+    vkvg_move_to(ctx, 50, 50);
+    vkvg_rel_line_to(ctx, 500, 0);
+    vkvg_rel_line_to(ctx, 0, 200);
+    vkvg_rel_line_to(ctx, 200, 0);
+    vkvg_rel_line_to(ctx, 0, 500);
+    vkvg_rel_line_to(ctx, -700, 0);
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+
+    dashes[0] = 0;
+    dashes[1] = 20;
+    vkvg_set_dash(ctx, dashes, 2, dash_offset);
+
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+
+    vkvg_move_to(ctx, 100, 100);
+    vkvg_rel_line_to(ctx, 400, 0);
+    vkvg_rel_line_to(ctx, 0, 200);
+    vkvg_rel_line_to(ctx, 200, 0);
+    vkvg_rel_line_to(ctx, 0, 400);
+    vkvg_rel_line_to(ctx, -600, 0);
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+
+    dashes[0] = 80;
+    dashes[1] = 20;
+
+    vkvg_set_line_width(ctx, 10);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+
+    vkvg_set_dash(ctx, dashes, 2, dash_offset);
+
+    vkvg_rectangle(ctx, 200, 300, 200, 200);
+    /*vkvg_move_to(ctx, 200,300);
+    vkvg_rel_line_to(ctx,200,0);*/
+    vkvg_stroke(ctx);
+
+    vkvg_destroy(ctx);
 }
 
+void _long_curve() {
+    float w = (float)test_width;
+    float h = (float)test_height;
 
-void _long_curve () {
-       float w = (float)test_width;
-       float h = (float)test_height;
+    VkvgContext ctx = _initCtx();
 
-       VkvgContext ctx = _initCtx();
+    randomize_color(ctx);
+    float x1 = w * rand() / RAND_MAX;
+    float y1 = h * rand() / RAND_MAX;
+    vkvg_move_to(ctx, x1, y1);
 
-       randomize_color(ctx);
-       float x1 = w*rand()/RAND_MAX;
-       float y1 = h*rand()/RAND_MAX;
-       vkvg_move_to (ctx, x1, y1);
-
-       for (uint32_t i=0; i<test_size; i++)
-               draw_random_curve(ctx);
-
-       vkvg_stroke (ctx);
-       vkvg_destroy(ctx);
+    for (uint32_t i = 0; i < test_size; i++)
+        draw_random_curve(ctx);
 
+    vkvg_stroke(ctx);
+    vkvg_destroy(ctx);
 }
 void _long_path() {
-       float w = (float)test_width-10;
-       float h = (float)test_height-10;
-
-       VkvgContext ctx = _initCtx();
-
-       randomize_color(ctx);
-       float x1 = w*rndf();
-       float y1 = h*rndf();
-       vkvg_move_to (ctx, x1, y1);
-       for (uint32_t i=0; i<test_size; i++) {
-               x1 = w*rndf();
-               y1 = h*rndf();
-               vkvg_line_to (ctx, x1, y1);
-       }
-       vkvg_stroke (ctx);
-       vkvg_destroy(ctx);
-}
-
-void path () {
-       _long_path ();
-}
-void curve () {
-       _long_curve ();
+    float w = (float)test_width - 10;
+    float h = (float)test_height - 10;
+
+    VkvgContext ctx = _initCtx();
+
+    randomize_color(ctx);
+    float x1 = w * rndf();
+    float y1 = h * rndf();
+    vkvg_move_to(ctx, x1, y1);
+    for (uint32_t i = 0; i < test_size; i++) {
+        x1 = w * rndf();
+        y1 = h * rndf();
+        vkvg_line_to(ctx, x1, y1);
+    }
+    vkvg_stroke(ctx);
+    vkvg_destroy(ctx);
 }
 
-
-int main(int argc, char *argv[]) {     
-       dashes_count = 2;
-       dashes[0] = 0;
-       dashes[1] = 10;
-       line_width = 4;
-       //test_size = 50;
-       line_cap = VKVG_LINE_CAP_ROUND;
-       PERFORM_TEST(test, argc, argv);
-       PERFORM_TEST(path, argc, argv);
-       PERFORM_TEST(curve, argc, argv);
-       return 0;
+void path() { _long_path(); }
+void curve() { _long_curve(); }
+
+int main(int argc, char *argv[]) {
+    dashes_count = 2;
+    dashes[0]    = 0;
+    dashes[1]    = 10;
+    line_width   = 4;
+    // test_size = 50;
+    line_cap = VKVG_LINE_CAP_ROUND;
+    PERFORM_TEST(test, argc, argv);
+    PERFORM_TEST(path, argc, argv);
+    PERFORM_TEST(curve, argc, argv);
+    return 0;
 }
index 5c5223e9f124ac79075c0040d69823cfeb41f0f9..1da164e6f4ee3c5c34f087588e22e0de70528870 100644 (file)
@@ -1,25 +1,25 @@
 #include "test.h"
 
-void test(){
-       VkvgContext ctx = _initCtx(surf);
+void test() {
+    VkvgContext ctx = _initCtx(surf);
 
-       vkvg_set_source_rgba(ctx,0.1f,0.9f,0.1f,1.0f);
-       vkvg_move_to(ctx,100,100);
-       vkvg_rel_line_to(ctx,50,200);
-       vkvg_rel_line_to(ctx,150,-100);
-       vkvg_rel_line_to(ctx,100,200);
-       vkvg_rel_line_to(ctx,-100,100);
-       vkvg_rel_line_to(ctx,-10,-100);
-       vkvg_rel_line_to(ctx,-190,-50);
-       vkvg_close_path(ctx);
+    vkvg_set_source_rgba(ctx, 0.1f, 0.9f, 0.1f, 1.0f);
+    vkvg_move_to(ctx, 100, 100);
+    vkvg_rel_line_to(ctx, 50, 200);
+    vkvg_rel_line_to(ctx, 150, -100);
+    vkvg_rel_line_to(ctx, 100, 200);
+    vkvg_rel_line_to(ctx, -100, 100);
+    vkvg_rel_line_to(ctx, -10, -100);
+    vkvg_rel_line_to(ctx, -190, -50);
+    vkvg_close_path(ctx);
 
-       vkvg_fill(ctx);
+    vkvg_fill(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
+    return 0;
 }
index 6e3e21e7d1779fc1d51bf1900b48b69c0e7caa76..e051b26bad989a70f1f292367e3e12be5d15e603 100644 (file)
@@ -1,30 +1,30 @@
 #include "test.h"
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_move_to (ctx, 100, 100);
-       vkvg_rel_line_to (ctx, 50, -80);
-       vkvg_rel_line_to (ctx, 50, 80);
-       vkvg_close_path (ctx);
+    vkvg_move_to(ctx, 100, 100);
+    vkvg_rel_line_to(ctx, 50, -80);
+    vkvg_rel_line_to(ctx, 50, 80);
+    vkvg_close_path(ctx);
 
-       vkvg_move_to (ctx, 300, 100);
-       vkvg_rel_line_to (ctx, 50, -80);
-       vkvg_rel_line_to (ctx, 50, 80);
-       vkvg_close_path (ctx);
+    vkvg_move_to(ctx, 300, 100);
+    vkvg_rel_line_to(ctx, 50, -80);
+    vkvg_rel_line_to(ctx, 50, 80);
+    vkvg_close_path(ctx);
 
-       vkvg_set_line_width (ctx, 10.0);
-       vkvg_set_source_rgb (ctx, 0, 0, 1);
-       vkvg_fill_preserve (ctx);
-       //vkvg_fill(ctx);
-       vkvg_set_source_rgb (ctx, 1, 0, 0);
-       vkvg_stroke (ctx);
+    vkvg_set_line_width(ctx, 10.0);
+    vkvg_set_source_rgb(ctx, 0, 0, 1);
+    vkvg_fill_preserve(ctx);
+    // vkvg_fill(ctx);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
+    return 0;
 }
index b70c7eebe042b21edef6b79618be13d4bf600efc..9c6eb91270d15304f8998905ca5eba5592f7529d 100644 (file)
@@ -1,31 +1,31 @@
 #include "test.h"
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_save(ctx);
-       vkvg_set_line_width(ctx,30);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_save(ctx);
+    vkvg_set_line_width(ctx, 30);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
 
-       vkvg_set_source_rgba(ctx,0.1f,0.9f,0.1f,1.0f);
-       vkvg_move_to(ctx,100,100);
-       vkvg_rel_line_to(ctx,200,0);
-       vkvg_rel_line_to(ctx,0,150);
-       vkvg_rel_line_to(ctx,-200,0);
-       vkvg_close_path(ctx);
+    vkvg_set_source_rgba(ctx, 0.1f, 0.9f, 0.1f, 1.0f);
+    vkvg_move_to(ctx, 100, 100);
+    vkvg_rel_line_to(ctx, 200, 0);
+    vkvg_rel_line_to(ctx, 0, 150);
+    vkvg_rel_line_to(ctx, -200, 0);
+    vkvg_close_path(ctx);
 
-       vkvg_move_to(ctx,150,150);
-       vkvg_rel_line_to(ctx,0,50);
-       vkvg_rel_line_to(ctx,100,0);
-       vkvg_rel_line_to(ctx,0,-50);
-       vkvg_close_path(ctx);
+    vkvg_move_to(ctx, 150, 150);
+    vkvg_rel_line_to(ctx, 0, 50);
+    vkvg_rel_line_to(ctx, 100, 0);
+    vkvg_rel_line_to(ctx, 0, -50);
+    vkvg_close_path(ctx);
 
-       vkvg_fill(ctx);
+    vkvg_fill(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
+    return 0;
 }
index 9f40b62be97763cb5599c95d1de7ef36fc9ed757..e42882aeb9f61cc1dd702c516c5bbdee889ff376 100644 (file)
 #include "test.h"
 
-VkvgPattern create_grad (VkvgContext ctx, float x) {
-       VkvgPattern pat = vkvg_pattern_create_linear(x,0,300,0);
-       vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1);
-       vkvg_pattern_add_color_stop(pat, 0.5f, 0, 1, 0, 1);
-       vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1);
-       return pat;
+VkvgPattern create_grad(VkvgContext ctx, float x) {
+    VkvgPattern pat = vkvg_pattern_create_linear(x, 0, 300, 0);
+    vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1);
+    vkvg_pattern_add_color_stop(pat, 0.5f, 0, 1, 0, 1);
+    vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1);
+    return pat;
 }
 
-void paint(){
-       VkvgContext ctx = _initCtx (surf);
-       //vkvg_translate(ctx,100,100);
-       VkvgPattern pat = create_grad(ctx,0);
-       //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
-       vkvg_rectangle(ctx, 0,0,400,460);
-       vkvg_set_source (ctx, pat);
-       vkvg_pattern_destroy (pat);
-       vkvg_fill(ctx);
-
-       float x = 100;
-       pat = create_grad(ctx,x);
-       //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
-       vkvg_rectangle(ctx, x,200,50,50);
-       vkvg_set_source (ctx, pat);
-       vkvg_pattern_destroy (pat);
-       vkvg_fill(ctx);
-
-       x+=100;
-
-       pat = vkvg_pattern_create_linear(10,0,300,0);
-       vkvg_pattern_add_color_stop(pat, 0, 0, 0, 1, 0);
-       vkvg_pattern_add_color_stop(pat, 1, 1, 0, 0, 1);
-       //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
-       vkvg_rectangle(ctx, 10,10,300,50);
-       vkvg_set_source (ctx, pat);
-       vkvg_pattern_destroy (pat);
-       vkvg_fill(ctx);
-
-       x+=200;
-
-       pat = create_grad(ctx,x);
-       //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
-       vkvg_rectangle(ctx, x,200,50,50);
-       vkvg_set_source (ctx, pat);
-       vkvg_pattern_destroy (pat);
-       vkvg_fill(ctx);
-
-       x+=100;
-
-       pat = create_grad(ctx,x);
-       //vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
-       vkvg_rectangle(ctx, x,200,50,50);
-       vkvg_set_source (ctx, pat);
-       vkvg_pattern_destroy (pat);
-       vkvg_fill(ctx);
-
-       /*vkvg_set_source_rgb(ctx, 0,1,0);
-       vkvg_rectangle(ctx, 100,100,200,160);
-       vkvg_fill_preserve(ctx);
-       vkvg_set_source_rgb(ctx, 0,0,0);
-       vkvg_set_line_width(ctx,1.0f);
-       vkvg_stroke(ctx);*/
-
-
-       vkvg_destroy(ctx);
+void paint() {
+    VkvgContext ctx = _initCtx(surf);
+    // vkvg_translate(ctx,100,100);
+    VkvgPattern pat = create_grad(ctx, 0);
+    // vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
+    vkvg_rectangle(ctx, 0, 0, 400, 460);
+    vkvg_set_source(ctx, pat);
+    vkvg_pattern_destroy(pat);
+    vkvg_fill(ctx);
+
+    float x = 100;
+    pat     = create_grad(ctx, x);
+    // vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
+    vkvg_rectangle(ctx, x, 200, 50, 50);
+    vkvg_set_source(ctx, pat);
+    vkvg_pattern_destroy(pat);
+    vkvg_fill(ctx);
+
+    x += 100;
+
+    pat = vkvg_pattern_create_linear(10, 0, 300, 0);
+    vkvg_pattern_add_color_stop(pat, 0, 0, 0, 1, 0);
+    vkvg_pattern_add_color_stop(pat, 1, 1, 0, 0, 1);
+    // vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
+    vkvg_rectangle(ctx, 10, 10, 300, 50);
+    vkvg_set_source(ctx, pat);
+    vkvg_pattern_destroy(pat);
+    vkvg_fill(ctx);
+
+    x += 200;
+
+    pat = create_grad(ctx, x);
+    // vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
+    vkvg_rectangle(ctx, x, 200, 50, 50);
+    vkvg_set_source(ctx, pat);
+    vkvg_pattern_destroy(pat);
+    vkvg_fill(ctx);
+
+    x += 100;
+
+    pat = create_grad(ctx, x);
+    // vkvg_pattern_set_extend(pat,VKVG_EXTEND_NONE);
+    vkvg_rectangle(ctx, x, 200, 50, 50);
+    vkvg_set_source(ctx, pat);
+    vkvg_pattern_destroy(pat);
+    vkvg_fill(ctx);
+
+    /*vkvg_set_source_rgb(ctx, 0,1,0);
+    vkvg_rectangle(ctx, 100,100,200,160);
+    vkvg_fill_preserve(ctx);
+    vkvg_set_source_rgb(ctx, 0,0,0);
+    vkvg_set_line_width(ctx,1.0f);
+    vkvg_stroke(ctx);*/
+
+    vkvg_destroy(ctx);
 }
-void paint_repeat(){
-       VkvgContext ctx = _initCtx (surf);
-       VkvgPattern pat = create_grad(ctx,0);
-       vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT);
-       vkvg_set_source (ctx, pat);
-       vkvg_pattern_destroy (pat);
-       vkvg_paint(ctx);
-
-       vkvg_destroy(ctx);
+void paint_repeat() {
+    VkvgContext ctx = _initCtx(surf);
+    VkvgPattern pat = create_grad(ctx, 0);
+    vkvg_pattern_set_extend(pat, VKVG_EXTEND_REPEAT);
+    vkvg_set_source(ctx, pat);
+    vkvg_pattern_destroy(pat);
+    vkvg_paint(ctx);
+
+    vkvg_destroy(ctx);
 }
 
-void test(){
-       VkvgContext ctx = _initCtx (surf);
-       VkvgPattern pat = create_grad(ctx,0);
-       vkvg_set_source (ctx, pat);
-       vkvg_rectangle(ctx,100,100,200,200);
-       vkvg_set_line_width(ctx, 20);
-       //vkvg_fill (ctx);
-       //vkvg_paint(ctx);
-       vkvg_stroke (ctx);
-       vkvg_pattern_destroy (pat);
-
-       vkvg_destroy(ctx);
+void test() {
+    VkvgContext ctx = _initCtx(surf);
+    VkvgPattern pat = create_grad(ctx, 0);
+    vkvg_set_source(ctx, pat);
+    vkvg_rectangle(ctx, 100, 100, 200, 200);
+    vkvg_set_line_width(ctx, 20);
+    // vkvg_fill (ctx);
+    // vkvg_paint(ctx);
+    vkvg_stroke(ctx);
+    vkvg_pattern_destroy(pat);
+
+    vkvg_destroy(ctx);
 }
-void test2(){
-       VkvgContext ctx = _initCtx (surf);
-
-       vkvg_set_source_rgb(ctx,1,0,0);
-       vkvg_paint(ctx);
-
-       VkvgPattern pat = vkvg_pattern_create_linear(100,0,300,0);
-       vkvg_set_line_width(ctx, 20);
-       vkvg_pattern_add_color_stop(pat, 0, 1, 1, 1, 1);
-       vkvg_pattern_add_color_stop(pat, 1, 1, 1, 0, 0);
-       vkvg_set_source (ctx, pat);
-       vkvg_rectangle(ctx,100,100,200,200);
-       vkvg_fill (ctx);
-       //vkvg_stroke (ctx);
-       vkvg_pattern_destroy (pat);
-
-       vkvg_destroy(ctx);
+void test2() {
+    VkvgContext ctx = _initCtx(surf);
+
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_paint(ctx);
+
+    VkvgPattern pat = vkvg_pattern_create_linear(100, 0, 300, 0);
+    vkvg_set_line_width(ctx, 20);
+    vkvg_pattern_add_color_stop(pat, 0, 1, 1, 1, 1);
+    vkvg_pattern_add_color_stop(pat, 1, 1, 1, 0, 0);
+    vkvg_set_source(ctx, pat);
+    vkvg_rectangle(ctx, 100, 100, 200, 200);
+    vkvg_fill(ctx);
+    // vkvg_stroke (ctx);
+    vkvg_pattern_destroy(pat);
+
+    vkvg_destroy(ctx);
 }
 
 void gradient_transform() {
-       VkvgContext ctx = _initCtx (surf);
-
-       //vkvg_translate(ctx,-100,-100);
-
-       vkvg_translate(ctx, 200, 100);
-       vkvg_rotate(ctx, 0.5f);
-
-       //vkvg_scale(ctx,2,2);
-       VkvgPattern pat = vkvg_pattern_create_linear(0, 0, 400, 0);
-       vkvg_pattern_set_extend(pat, VKVG_EXTEND_NONE);
-       vkvg_set_line_width(ctx, 20);
-       vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1);
-       vkvg_pattern_add_color_stop(pat, 0.5f, 0, 1, 0, 1);
-       vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1);
-       vkvg_set_source(ctx, pat);
-       vkvg_rectangle(ctx, 0, 0, 400, 200);
-       //vkvg_fill (ctx);
-       vkvg_stroke(ctx);
-       //vkvg_paint(ctx);
-       vkvg_pattern_destroy(pat);
-
-       vkvg_destroy(ctx);
+    VkvgContext ctx = _initCtx(surf);
+
+    // vkvg_translate(ctx,-100,-100);
+
+    vkvg_translate(ctx, 200, 100);
+    vkvg_rotate(ctx, 0.5f);
+
+    // vkvg_scale(ctx,2,2);
+    VkvgPattern pat = vkvg_pattern_create_linear(0, 0, 400, 0);
+    vkvg_pattern_set_extend(pat, VKVG_EXTEND_NONE);
+    vkvg_set_line_width(ctx, 20);
+    vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1);
+    vkvg_pattern_add_color_stop(pat, 0.5f, 0, 1, 0, 1);
+    vkvg_pattern_add_color_stop(pat, 1, 0, 0, 1, 1);
+    vkvg_set_source(ctx, pat);
+    vkvg_rectangle(ctx, 0, 0, 400, 200);
+    // vkvg_fill (ctx);
+    vkvg_stroke(ctx);
+    // vkvg_paint(ctx);
+    vkvg_pattern_destroy(pat);
+
+    vkvg_destroy(ctx);
 }
 void gradient_alpha() {
-       VkvgContext ctx = _initCtx (surf);
-       vkvg_set_source_rgb(ctx,0,1,0);
-       vkvg_paint (ctx);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_paint(ctx);
 
-       VkvgPattern pat = vkvg_pattern_create_linear(10,0,300,0);
-       vkvg_pattern_add_color_stop(pat, 1, 1, 0, 0, 0.5);
-       vkvg_pattern_add_color_stop(pat, 1, 1, 0, 0, 0.5);
+    VkvgPattern pat = vkvg_pattern_create_linear(10, 0, 300, 0);
+    vkvg_pattern_add_color_stop(pat, 1, 1, 0, 0, 0.5);
+    vkvg_pattern_add_color_stop(pat, 1, 1, 0, 0, 0.5);
 
-       vkvg_set_source (ctx, pat);
-       vkvg_pattern_destroy (pat);
-       vkvg_rectangle (ctx, 10, 10, 300, 200);
-       vkvg_fill (ctx);
+    vkvg_set_source(ctx, pat);
+    vkvg_pattern_destroy(pat);
+    vkvg_rectangle(ctx, 10, 10, 300, 200);
+    vkvg_fill(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST(gradient_alpha, argc, argv);
-       PERFORM_TEST(paint, argc, argv);
-       PERFORM_TEST(paint_repeat, argc, argv);
-       PERFORM_TEST(gradient_transform, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(gradient_alpha, argc, argv);
+    PERFORM_TEST(paint, argc, argv);
+    PERFORM_TEST(paint_repeat, argc, argv);
+    PERFORM_TEST(gradient_transform, argc, argv);
+    return 0;
 }
index 1867f3b97bdb03e86bd9a049087eec13bcac0d1e..21ffbacbb2bd1502c605dc622ddc332199557cd6 100644 (file)
 #include "test.h"
 #include "vectors.h"
 
-vkvg_fill_rule_t fillrule = VKVG_FILL_RULE_NON_ZERO;
-static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT;
-float lineWidth = 50.0f;
-vkvg_line_join_t lineJoin = VKVG_LINE_JOIN_MITER;
-vkvg_line_cap_t lineCap = VKVG_LINE_CAP_BUTT;
-bool isClosed = false;
-
-int ptsCount = 2;
-int initPtsCount = 4;
-vec2 pts[] = {
-       {150,150},
-       {250,150},
-       {125,125},
-       {145,125},
+vkvg_fill_rule_t          fillrule  = VKVG_FILL_RULE_NON_ZERO;
+static VkSampleCountFlags samples   = VK_SAMPLE_COUNT_8_BIT;
+float                     lineWidth = 50.0f;
+vkvg_line_join_t          lineJoin  = VKVG_LINE_JOIN_MITER;
+vkvg_line_cap_t           lineCap   = VKVG_LINE_CAP_BUTT;
+bool                      isClosed  = false;
+
+int  ptsCount     = 2;
+int  initPtsCount = 4;
+vec2 pts[]        = {
+    {150, 150},
+    {250, 150},
+    {125, 125},
+    {145, 125},
 };
-int hoverPt = -1;
+int    hoverPt   = -1;
 double pointSize = 7;
 
 static vkvg_pattern_type_t patternType = VKVG_PATTERN_TYPE_LINEAR;
-static VkEngine e;
-
-void draw (){
-
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-
-       VkvgPattern pat;
-
-       switch (patternType) {
-       case VKVG_PATTERN_TYPE_LINEAR:
-               pat = vkvg_pattern_create_linear(pts[0].x,pts[0].y, pts[1].x,pts[1].y);
-               break;
-       case VKVG_PATTERN_TYPE_RADIAL:
-               pat = vkvg_pattern_create_radial(
-                                       pts[2].x,pts[2].y, vec2_length(vec2_sub(pts[3], pts[2])),
-                                       pts[0].x,pts[0].y, vec2_length(vec2_sub(pts[1], pts[0]))
-               );
-               break;
-       }
-
-       /**/
-
-       vkvg_pattern_add_color_stop(pat, 0.0, 1 ,0 ,0, 0.5);
-       vkvg_pattern_add_color_stop(pat, 0.3, 0 ,1 ,0, 0.5);
-       vkvg_pattern_add_color_stop(pat, 0.6, 0 ,0 ,1, 0.5);
-       vkvg_pattern_add_color_stop(pat, 1.0, 0 ,0 ,0, 0.5);
-
-       vkvg_set_source (ctx, pat);
-       vkvg_paint (ctx);
-
-       vkvg_set_dash(ctx, NULL, 0, 0);
-       vkvg_set_line_width(ctx,1);
-       for (int i=0; i<ptsCount; i++) {
-               if (hoverPt == i)
-                       vkvg_set_source_rgba(ctx,0.5f,0.5f,1.0f,0.7f);
-               else
-                       vkvg_set_source_rgba(ctx,1.0f,0.5f,0.5f,0.9f);
-               vkvg_arc(ctx, pts[i].x, pts[i].y, pointSize, 0, M_PIF*2);
-               vkvg_fill_preserve(ctx);
-               vkvg_stroke(ctx);
-       }
-
-
-       vkvg_pattern_destroy    (pat);
-       vkvg_destroy                    (ctx);
+static VkEngine            e;
+
+void draw() {
+
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+
+    VkvgPattern pat;
+
+    switch (patternType) {
+    case VKVG_PATTERN_TYPE_LINEAR:
+        pat = vkvg_pattern_create_linear(pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+        break;
+    case VKVG_PATTERN_TYPE_RADIAL:
+        pat = vkvg_pattern_create_radial(pts[2].x, pts[2].y, vec2_length(vec2_sub(pts[3], pts[2])), pts[0].x, pts[0].y,
+                                         vec2_length(vec2_sub(pts[1], pts[0])));
+        break;
+    }
+
+    /**/
+
+    vkvg_pattern_add_color_stop(pat, 0.0, 1, 0, 0, 0.5);
+    vkvg_pattern_add_color_stop(pat, 0.3, 0, 1, 0, 0.5);
+    vkvg_pattern_add_color_stop(pat, 0.6, 0, 0, 1, 0.5);
+    vkvg_pattern_add_color_stop(pat, 1.0, 0, 0, 0, 0.5);
+
+    vkvg_set_source(ctx, pat);
+    vkvg_paint(ctx);
+
+    vkvg_set_dash(ctx, NULL, 0, 0);
+    vkvg_set_line_width(ctx, 1);
+    for (int i = 0; i < ptsCount; i++) {
+        if (hoverPt == i)
+            vkvg_set_source_rgba(ctx, 0.5f, 0.5f, 1.0f, 0.7f);
+        else
+            vkvg_set_source_rgba(ctx, 1.0f, 0.5f, 0.5f, 0.9f);
+        vkvg_arc(ctx, pts[i].x, pts[i].y, pointSize, 0, M_PIF * 2);
+        vkvg_fill_preserve(ctx);
+        vkvg_stroke(ctx);
+    }
+
+    vkvg_pattern_destroy(pat);
+    vkvg_destroy(ctx);
 }
-static void key_callback(GLFWwindowwindow, int key, int scancode, int action, int mods) {
-       if (action != GLFW_PRESS)
-               return;
-       switch (key) {
-       case GLFW_KEY_ESCAPE :
-               glfwSetWindowShouldClose(window, GLFW_TRUE);
-               break;
-       case GLFW_KEY_P :
-               patternType++;
-               if (patternType > VKVG_PATTERN_TYPE_RADIAL)
-                       patternType = VKVG_PATTERN_TYPE_LINEAR;
-               break;
-       case GLFW_KEY_S :
-               vkengine_wait_idle(e);
-               vkvg_surface_write_to_png(surf, "/home/jp/test.png");
-               break;
-       case GLFW_KEY_KP_ADD :
-               if (ptsCount < initPtsCount)
-                       ptsCount++;
-               break;
-       case GLFW_KEY_KP_SUBTRACT :
-               if (ptsCount > 1)
-                       ptsCount--;
-               break;
-       }
+static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
+    if (action != GLFW_PRESS)
+        return;
+    switch (key) {
+    case GLFW_KEY_ESCAPE:
+        glfwSetWindowShouldClose(window, GLFW_TRUE);
+        break;
+    case GLFW_KEY_P:
+        patternType++;
+        if (patternType > VKVG_PATTERN_TYPE_RADIAL)
+            patternType = VKVG_PATTERN_TYPE_LINEAR;
+        break;
+    case GLFW_KEY_S:
+        vkengine_wait_idle(e);
+        vkvg_surface_write_to_png(surf, "/home/jp/test.png");
+        break;
+    case GLFW_KEY_KP_ADD:
+        if (ptsCount < initPtsCount)
+            ptsCount++;
+        break;
+    case GLFW_KEY_KP_SUBTRACT:
+        if (ptsCount > 1)
+            ptsCount--;
+        break;
+    }
 }
-static void mouse_move_callback(GLFWwindow* window, double x, double y){
-       if (mouseDown) {
-               if (hoverPt < 0)
-                       return;
-               pts[hoverPt].x = x;
-               pts[hoverPt].y = y;
-       } else {
-               for (int i=0; i<ptsCount; i++) {
-                       if (x > pts[i].x - pointSize &&
-                               x < pts[i].x + pointSize &&
-                               y > pts[i].y - pointSize &&
-                               y < pts[i].y + pointSize) {
-                               hoverPt = i;
-                               return;
-                       }
-               }
-               hoverPt = -1;
-       }
+static void mouse_move_callback(GLFWwindow *window, double x, double y) {
+    if (mouseDown) {
+        if (hoverPt < 0)
+            return;
+        pts[hoverPt].x = x;
+        pts[hoverPt].y = y;
+    } else {
+        for (int i = 0; i < ptsCount; i++) {
+            if (x > pts[i].x - pointSize && x < pts[i].x + pointSize && y > pts[i].y - pointSize &&
+                y < pts[i].y + pointSize) {
+                hoverPt = i;
+                return;
+            }
+        }
+        hoverPt = -1;
+    }
 }
-static void scroll_callback(GLFWwindow* window, double x, double y){
-       if (y<0.f)
-               zoom *= 0.5f;
-       else
-               zoom *= 2.0f;
+static void scroll_callback(GLFWwindow *window, double x, double y) {
+    if (y < 0.f)
+        zoom *= 0.5f;
+    else
+        zoom *= 2.0f;
 }
-static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){
-       if (but != GLFW_MOUSE_BUTTON_1)
-               return;
-       if (state == GLFW_TRUE)
-               mouseDown = true;
-       else
-               mouseDown = false;
+static void mouse_button_callback(GLFWwindow *window, int but, int state, int modif) {
+    if (but != GLFW_MOUSE_BUTTON_1)
+        return;
+    if (state == GLFW_TRUE)
+        mouseDown = true;
+    else
+        mouseDown = false;
 }
 
+int main(int argc, char *argv[]) {
 
+    _parse_args(argc, argv);
 
-int main(int argc, char* argv[]) {
+    e = vkengine_create(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
 
-       _parse_args (argc, argv);
+    VkhPresenter r = e->renderer;
+    vkengine_set_key_callback(e, key_callback);
+    vkengine_set_mouse_but_callback(e, mouse_button_callback);
+    vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+    vkengine_set_scroll_callback(e, scroll_callback);
 
-       e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
+    vkvg_device_create_info_t info = {samples, false, vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0};
+    device                         = vkvg_device_create(&info);
+    surf                           = vkvg_surface_create(device, test_width, test_height);
 
-       VkhPresenter r = e->renderer;
-       vkengine_set_key_callback (e, key_callback);
-       vkengine_set_mouse_but_callback(e, mouse_button_callback);
-       vkengine_set_cursor_pos_callback(e, mouse_move_callback);
-       vkengine_set_scroll_callback(e, scroll_callback);
+    vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
 
-    vkvg_device_create_info_t info = {
-        samples,
-        false,
-        vkh_app_get_inst(e->app),
-        r->dev->phy,
-        r->dev->dev,
-        r->qFam,
-        0
-    };
-    device = vkvg_device_create(&info);
-    surf = vkvg_surface_create(device, test_width, test_height);
+    while (!vkengine_should_close(e)) {
+        glfwPollEvents();
 
-       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+        draw();
 
-       while (!vkengine_should_close (e)) {
-               glfwPollEvents();
+        if (!vkh_presenter_draw(r)) {
+            vkh_presenter_get_size(r, &test_width, &test_height);
+            vkvg_surface_destroy(surf);
+            surf = vkvg_surface_create(device, test_width, test_height);
+            vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+            vkDeviceWaitIdle(r->dev->dev);
+            continue;
+        }
+    }
+    vkDeviceWaitIdle(e->dev->dev);
 
-               draw ();
+    vkvg_surface_destroy(surf);
 
-               if (!vkh_presenter_draw (r)){
-                       vkh_presenter_get_size (r, &test_width, &test_height);
-                       vkvg_surface_destroy (surf);
-                       surf = vkvg_surface_create(device, test_width, test_height);
-                       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
-                       vkDeviceWaitIdle(r->dev->dev);
-                       continue;
-               }
-       }
-       vkDeviceWaitIdle(e->dev->dev);
+    vkvg_device_destroy(device);
 
-       vkvg_surface_destroy    (surf);
+    vkengine_destroy(e);
 
-       vkvg_device_destroy     (device);
-
-       vkengine_destroy (e);
-
-       return 0;
+    return 0;
 }
index bffc65cc05981da43290c171602d956d0ca33acd..66d66b74c8e1c81aa3249518ad8871b661c1b16e 100644 (file)
 #include "test.h"
 
-const charimgPath = "data/miroir.jpg";
-void paint () {
-       VkvgContext ctx = vkvg_create(surf);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+const char *imgPath = "data/miroir.jpg";
+void        paint() {
+    VkvgContext ctx     = vkvg_create(surf);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
 
-       vkvg_set_source_surface(ctx, imgSurf, 0, 0);
-       vkvg_paint(ctx);
+    vkvg_set_source_surface(ctx, imgSurf, 0, 0);
+    vkvg_paint(ctx);
 
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
-void paint_offset () {
-       VkvgContext ctx = vkvg_create(surf);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+void paint_offset() {
+    VkvgContext ctx     = vkvg_create(surf);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
 
-       vkvg_set_source_surface(ctx, imgSurf, 100, 100);
-       vkvg_paint(ctx);
+    vkvg_set_source_surface(ctx, imgSurf, 100, 100);
+    vkvg_paint(ctx);
 
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
-void paint_with_scale(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_scale (ctx, 0.2f,0.2f);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       vkvg_set_source_surface(ctx, imgSurf, 0, 0);
+void paint_with_scale() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_scale(ctx, 0.2f, 0.2f);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    vkvg_set_source_surface(ctx, imgSurf, 0, 0);
 
-       vkvg_paint(ctx);
+    vkvg_paint(ctx);
 
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
-void translate(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_translate (ctx, 150,50);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       vkvg_set_source_surface(ctx, imgSurf, 0, 0);
+void translate() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_translate(ctx, 150, 50);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    vkvg_set_source_surface(ctx, imgSurf, 0, 0);
 
-       vkvg_paint(ctx);
+    vkvg_paint(ctx);
 
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
-void offset_and_scale(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_scale (ctx, 0.2f,0.2f);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       vkvg_set_source_surface(ctx, imgSurf, 100, 100);
+void offset_and_scale() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_scale(ctx, 0.2f, 0.2f);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    vkvg_set_source_surface(ctx, imgSurf, 100, 100);
 
-       vkvg_paint(ctx);
+    vkvg_paint(ctx);
 
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
 
 static float angle = 0;
-void paint_with_rot(){
-       angle += 0.005;
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+void         paint_with_rot() {
+    angle += 0.005;
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
-       vkvg_rotate (ctx, angle);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       vkvg_set_source_surface(ctx, imgSurf, 0, 0);
+    vkvg_rotate(ctx, angle);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    vkvg_set_source_surface(ctx, imgSurf, 0, 0);
 
-       vkvg_paint(ctx);
+    vkvg_paint(ctx);
 
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
-void offset_and_rot(){
-       angle += 0.005;
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+void offset_and_rot() {
+    angle += 0.005;
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
-       vkvg_rotate (ctx, angle);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       vkvg_set_source_surface(ctx, imgSurf, 100, 100);
+    vkvg_rotate(ctx, angle);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    vkvg_set_source_surface(ctx, imgSurf, 100, 100);
 
-       vkvg_paint(ctx);
+    vkvg_paint(ctx);
 
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
 
-void paint_pattern () {
-       VkvgContext ctx = vkvg_create(surf);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf);
-       vkvg_set_source(ctx, pat);
-       vkvg_paint(ctx);
-       vkvg_pattern_destroy(pat);
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+void paint_pattern() {
+    VkvgContext ctx     = vkvg_create(surf);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    VkvgPattern pat     = vkvg_pattern_create_for_surface(imgSurf);
+    vkvg_set_source(ctx, pat);
+    vkvg_paint(ctx);
+    vkvg_pattern_destroy(pat);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
-void paint_patt_repeat () {
-       VkvgContext ctx = vkvg_create(surf);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf);
-       vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT);
-       vkvg_set_source(ctx, pat);
-       vkvg_paint(ctx);
-       vkvg_pattern_destroy(pat);
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+void paint_patt_repeat() {
+    VkvgContext ctx     = vkvg_create(surf);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    VkvgPattern pat     = vkvg_pattern_create_for_surface(imgSurf);
+    vkvg_pattern_set_extend(pat, VKVG_EXTEND_REPEAT);
+    vkvg_set_source(ctx, pat);
+    vkvg_paint(ctx);
+    vkvg_pattern_destroy(pat);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
-void paint_patt_repeat_scalled () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_scale (ctx, 0.2f,0.2f);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf);
-       vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT);
-       vkvg_set_source(ctx, pat);
-       vkvg_paint(ctx);
-       vkvg_pattern_destroy(pat);
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+void paint_patt_repeat_scalled() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_scale(ctx, 0.2f, 0.2f);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    VkvgPattern pat     = vkvg_pattern_create_for_surface(imgSurf);
+    vkvg_pattern_set_extend(pat, VKVG_EXTEND_REPEAT);
+    vkvg_set_source(ctx, pat);
+    vkvg_paint(ctx);
+    vkvg_pattern_destroy(pat);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
-void paint_patt_pad () {
-       VkvgContext ctx = vkvg_create(surf);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf);
-       vkvg_pattern_set_extend(pat,VKVG_EXTEND_PAD);
-       vkvg_set_source(ctx, pat);
-       vkvg_paint(ctx);
-       vkvg_pattern_destroy(pat);
-       vkvg_surface_destroy(imgSurf);
-       vkvg_destroy(ctx);
+void paint_patt_pad() {
+    VkvgContext ctx     = vkvg_create(surf);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    VkvgPattern pat     = vkvg_pattern_create_for_surface(imgSurf);
+    vkvg_pattern_set_extend(pat, VKVG_EXTEND_PAD);
+    vkvg_set_source(ctx, pat);
+    vkvg_paint(ctx);
+    vkvg_pattern_destroy(pat);
+    vkvg_surface_destroy(imgSurf);
+    vkvg_destroy(ctx);
 }
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx,VKVG_FILL_RULE_EVEN_ODD);
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
 
-       vkvg_translate(ctx,200,200);
-       //vkvg_rotate(ctx,M_PI_4);
+    vkvg_translate(ctx, 200, 200);
+    // vkvg_rotate(ctx,M_PI_4);
 
-       vkvg_set_line_width(ctx,20.f);
-       //vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_arc(ctx,200,200,200,0,2.f*M_PIF);
-       vkvg_new_sub_path(ctx);
-       vkvg_arc(ctx,200,200,100,0,2.f*M_PIF);
+    vkvg_set_line_width(ctx, 20.f);
+    // vkvg_set_source_rgba(ctx,1,0,0,1);
+    vkvg_arc(ctx, 200, 200, 200, 0, 2.f * M_PIF);
+    vkvg_new_sub_path(ctx);
+    vkvg_arc(ctx, 200, 200, 100, 0, 2.f * M_PIF);
 
-       vkvg_set_source_surface(ctx, imgSurf, 0, 0);
-       vkvg_fill_preserve(ctx);
-       vkvg_set_source_rgba(ctx,0.2f,0.3f,0.8f,1);
+    vkvg_set_source_surface(ctx, imgSurf, 0, 0);
+    vkvg_fill_preserve(ctx);
+    vkvg_set_source_rgba(ctx, 0.2f, 0.3f, 0.8f, 1);
 
-       vkvg_stroke(ctx);
+    vkvg_stroke(ctx);
 
-       vkvg_surface_destroy(imgSurf);
+    vkvg_surface_destroy(imgSurf);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (paint, argc, argv);
-       PERFORM_TEST (paint_offset, argc, argv);
-       PERFORM_TEST (paint_with_scale, argc, argv);
-       PERFORM_TEST (offset_and_scale, argc, argv);
-       PERFORM_TEST (translate, argc, argv);
-       PERFORM_TEST (paint_with_rot, argc, argv);
-       PERFORM_TEST (offset_and_rot, argc, argv);
-       PERFORM_TEST (paint_pattern, argc, argv);
-       PERFORM_TEST (paint_patt_repeat, argc, argv);
-       PERFORM_TEST (paint_patt_repeat_scalled, argc, argv);
-       PERFORM_TEST (paint_patt_pad, argc, argv);
-       PERFORM_TEST (test, argc, argv);
-
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(paint, argc, argv);
+    PERFORM_TEST(paint_offset, argc, argv);
+    PERFORM_TEST(paint_with_scale, argc, argv);
+    PERFORM_TEST(offset_and_scale, argc, argv);
+    PERFORM_TEST(translate, argc, argv);
+    PERFORM_TEST(paint_with_rot, argc, argv);
+    PERFORM_TEST(offset_and_rot, argc, argv);
+    PERFORM_TEST(paint_pattern, argc, argv);
+    PERFORM_TEST(paint_patt_repeat, argc, argv);
+    PERFORM_TEST(paint_patt_repeat_scalled, argc, argv);
+    PERFORM_TEST(paint_patt_pad, argc, argv);
+    PERFORM_TEST(test, argc, argv);
+
+    return 0;
 }
index 38b4adc6b35ac294c27ebc6cb3f0359a6b97c418..2b5735cabda55898d08f530ab577c95d077263c7 100644 (file)
 #include "test.h"
 #include "vectors.h"
 
-vkvg_fill_rule_t fillrule = VKVG_FILL_RULE_NON_ZERO;
-static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT;
-float lineWidth = 50.0f;
-vkvg_line_join_t lineJoin = VKVG_LINE_JOIN_MITER;
-vkvg_line_cap_t lineCap = VKVG_LINE_CAP_BUTT;
-bool isClosed = false;
-bool startWithArc = false, endWithArc = false;
-
-int ptsCount = 4;
-int initPtsCount = 5;
-vec2 pts[] = {
-       {150,150},
-       {200,300},
-       {250,150},
-       {280,350},
-       {300,100},
+vkvg_fill_rule_t          fillrule     = VKVG_FILL_RULE_NON_ZERO;
+static VkSampleCountFlags samples      = VK_SAMPLE_COUNT_8_BIT;
+float                     lineWidth    = 50.0f;
+vkvg_line_join_t          lineJoin     = VKVG_LINE_JOIN_MITER;
+vkvg_line_cap_t           lineCap      = VKVG_LINE_CAP_BUTT;
+bool                      isClosed     = false;
+bool                      startWithArc = false, endWithArc = false;
+
+int  ptsCount     = 4;
+int  initPtsCount = 5;
+vec2 pts[]        = {
+    {150, 150}, {200, 300}, {250, 150}, {280, 350}, {300, 100},
 };
 /*vec2 pts[] = {
-       {150,150},
-       {250,150},
-       {100,150},
-       {150,200},
+    {150,150},
+    {250,150},
+    {100,150},
+    {150,200},
 };*/
-int hoverPt = -1;
+int    hoverPt   = -1;
 double pointSize = 7;
 
-float dash[] = {0, 60};
+float    dash[]        = {0, 60};
 uint32_t dashCountInit = 2;
-uint32_t dashCount = 0;
-float miterLimit = 10.0f;
-
-
-
-void draw (){
-
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-       if (dashCount > 0)
-               vkvg_set_dash(ctx, dash, dashCount,0);
-       vkvg_set_source_rgba    (ctx,1,0,0,0.3f);
-       vkvg_set_line_width             (ctx,lineWidth);
-       vkvg_set_line_join              (ctx, lineJoin);
-       vkvg_set_line_cap               (ctx, lineCap);
-       vkvg_set_miter_limit    (ctx, miterLimit);
-
-       if (startWithArc)
-               vkvg_arc_negative(ctx,pts[0].x,pts[0].y,200, M_PIF*1.5f, M_PIF);
-       else
-               vkvg_move_to(ctx,pts[0].x,pts[0].y);
-       for (int i=1; i<ptsCount-1; i++)
-               vkvg_line_to(ctx,pts[i].x,pts[i].y);
-       if (endWithArc)
-               vkvg_arc_negative(ctx,pts[ptsCount-1].x,pts[ptsCount-1].y,200, M_PIF*1.5f, M_PIF);
-       else
-               vkvg_line_to(ctx,pts[ptsCount-1].x,pts[ptsCount-1].y);
-
-       if (isClosed)
-               vkvg_close_path(ctx);
-
-       if (hoverPt>=0) {
-               vkvg_stroke_preserve(ctx);
-               vkvg_set_dash(ctx, NULL, 0, 0);
-               vkvg_set_line_width(ctx,2);
-               vkvg_set_source_rgba(ctx,0,0,0,1);
-               vkvg_stroke(ctx);
-               vkvg_set_source_rgba(ctx,0.5f,0.5f,1.0f,0.7f);
-               vkvg_arc (ctx, pts[hoverPt].x, pts[hoverPt].y, pointSize, 0, M_PIF*2);
-               vkvg_fill_preserve(ctx);
-               vkvg_stroke(ctx);
-       } else
-               vkvg_stroke(ctx);
-
-       //draw_v(ctx, 200, 20, VKVG_LINE_JOIN_BEVEL);
-       //draw_v(ctx, 300, 80, VKVG_LINE_JOIN_ROUND);
-       vkvg_destroy(ctx);
+uint32_t dashCount     = 0;
+float    miterLimit    = 10.0f;
+
+void draw() {
+
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    if (dashCount > 0)
+        vkvg_set_dash(ctx, dash, dashCount, 0);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 0.3f);
+    vkvg_set_line_width(ctx, lineWidth);
+    vkvg_set_line_join(ctx, lineJoin);
+    vkvg_set_line_cap(ctx, lineCap);
+    vkvg_set_miter_limit(ctx, miterLimit);
+
+    if (startWithArc)
+        vkvg_arc_negative(ctx, pts[0].x, pts[0].y, 200, M_PIF * 1.5f, M_PIF);
+    else
+        vkvg_move_to(ctx, pts[0].x, pts[0].y);
+    for (int i = 1; i < ptsCount - 1; i++)
+        vkvg_line_to(ctx, pts[i].x, pts[i].y);
+    if (endWithArc)
+        vkvg_arc_negative(ctx, pts[ptsCount - 1].x, pts[ptsCount - 1].y, 200, M_PIF * 1.5f, M_PIF);
+    else
+        vkvg_line_to(ctx, pts[ptsCount - 1].x, pts[ptsCount - 1].y);
+
+    if (isClosed)
+        vkvg_close_path(ctx);
+
+    if (hoverPt >= 0) {
+        vkvg_stroke_preserve(ctx);
+        vkvg_set_dash(ctx, NULL, 0, 0);
+        vkvg_set_line_width(ctx, 2);
+        vkvg_set_source_rgba(ctx, 0, 0, 0, 1);
+        vkvg_stroke(ctx);
+        vkvg_set_source_rgba(ctx, 0.5f, 0.5f, 1.0f, 0.7f);
+        vkvg_arc(ctx, pts[hoverPt].x, pts[hoverPt].y, pointSize, 0, M_PIF * 2);
+        vkvg_fill_preserve(ctx);
+        vkvg_stroke(ctx);
+    } else
+        vkvg_stroke(ctx);
+
+    // draw_v(ctx, 200, 20, VKVG_LINE_JOIN_BEVEL);
+    // draw_v(ctx, 300, 80, VKVG_LINE_JOIN_ROUND);
+    vkvg_destroy(ctx);
 }
-static void key_callback(GLFWwindowwindow, int key, int scancode, int action, int mods) {
-       if (action == GLFW_RELEASE)
-               return;
-       switch (key) {
-       case GLFW_KEY_ESCAPE :
-               glfwSetWindowShouldClose(window, GLFW_TRUE);
-               break;
-       case GLFW_KEY_W :
-               isClosed ^= true;
-               break;
-       case GLFW_KEY_Q :
-               startWithArc ^= true;
-               break;
-       case GLFW_KEY_A :
-               endWithArc ^= true;
-               break;
-       case GLFW_KEY_J :
-               lineJoin++;
-               if (lineJoin > 2)
-                       lineJoin = 0;
-               break;
-       case GLFW_KEY_C :
-               lineCap++;
-               if (lineCap > 2)
-                       lineCap = 0;
-               break;
-       case GLFW_KEY_D :
-               if (dashCount == 0)
-                       dashCount = dashCountInit;
-               else
-                       dashCount = 0;
-               break;
-       case GLFW_KEY_E :
-               if (dash[0] > 0)
-                       dash[0] = 0;
-               else
-                       dash[0] = 80;
-               break;
-       case GLFW_KEY_L :
-               if (mods & GLFW_MOD_SHIFT)
-                       miterLimit /= 2.0f;
-               else
-                       miterLimit *= 2.0f;
-               break;
-       case GLFW_KEY_P :
-               if (mods & GLFW_MOD_SHIFT) {
-                       if (ptsCount > 1)
-                               ptsCount--;
-               } else {
-                       if (ptsCount < initPtsCount)
-                               ptsCount++;
-               }
-               break;
-       case GLFW_KEY_KP_ADD :
-               lineWidth++;
-               break;
-       case GLFW_KEY_KP_SUBTRACT :
-               if (lineWidth > 1)
-                       lineWidth--;
-               break;
-       }
+static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
+    if (action == GLFW_RELEASE)
+        return;
+    switch (key) {
+    case GLFW_KEY_ESCAPE:
+        glfwSetWindowShouldClose(window, GLFW_TRUE);
+        break;
+    case GLFW_KEY_W:
+        isClosed ^= true;
+        break;
+    case GLFW_KEY_Q:
+        startWithArc ^= true;
+        break;
+    case GLFW_KEY_A:
+        endWithArc ^= true;
+        break;
+    case GLFW_KEY_J:
+        lineJoin++;
+        if (lineJoin > 2)
+            lineJoin = 0;
+        break;
+    case GLFW_KEY_C:
+        lineCap++;
+        if (lineCap > 2)
+            lineCap = 0;
+        break;
+    case GLFW_KEY_D:
+        if (dashCount == 0)
+            dashCount = dashCountInit;
+        else
+            dashCount = 0;
+        break;
+    case GLFW_KEY_E:
+        if (dash[0] > 0)
+            dash[0] = 0;
+        else
+            dash[0] = 80;
+        break;
+    case GLFW_KEY_L:
+        if (mods & GLFW_MOD_SHIFT)
+            miterLimit /= 2.0f;
+        else
+            miterLimit *= 2.0f;
+        break;
+    case GLFW_KEY_P:
+        if (mods & GLFW_MOD_SHIFT) {
+            if (ptsCount > 1)
+                ptsCount--;
+        } else {
+            if (ptsCount < initPtsCount)
+                ptsCount++;
+        }
+        break;
+    case GLFW_KEY_KP_ADD:
+        lineWidth++;
+        break;
+    case GLFW_KEY_KP_SUBTRACT:
+        if (lineWidth > 1)
+            lineWidth--;
+        break;
+    }
 }
-static void mouse_move_callback(GLFWwindow* window, double x, double y){
-       if (mouseDown) {
-               if (hoverPt < 0)
-                       return;
-               pts[hoverPt].x = x;
-               pts[hoverPt].y = y;
-       } else {
-               for (int i=0; i<ptsCount; i++) {
-                       if (x > pts[i].x - pointSize &&
-                               x < pts[i].x + pointSize &&
-                               y > pts[i].y - pointSize &&
-                               y < pts[i].y + pointSize) {
-                               hoverPt = i;
-                               return;
-                       }
-               }
-               hoverPt = -1;
-       }
+static void mouse_move_callback(GLFWwindow *window, double x, double y) {
+    if (mouseDown) {
+        if (hoverPt < 0)
+            return;
+        pts[hoverPt].x = x;
+        pts[hoverPt].y = y;
+    } else {
+        for (int i = 0; i < ptsCount; i++) {
+            if (x > pts[i].x - pointSize && x < pts[i].x + pointSize && y > pts[i].y - pointSize &&
+                y < pts[i].y + pointSize) {
+                hoverPt = i;
+                return;
+            }
+        }
+        hoverPt = -1;
+    }
 }
-static void scroll_callback(GLFWwindow* window, double x, double y){
-       if (y<0.f)
-               zoom *= 0.5f;
-       else
-               zoom *= 2.0f;
+static void scroll_callback(GLFWwindow *window, double x, double y) {
+    if (y < 0.f)
+        zoom *= 0.5f;
+    else
+        zoom *= 2.0f;
 }
-static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){
-       if (but != GLFW_MOUSE_BUTTON_1)
-               return;
-       if (state == GLFW_TRUE)
-               mouseDown = true;
-       else
-               mouseDown = false;
+static void mouse_button_callback(GLFWwindow *window, int but, int state, int modif) {
+    if (but != GLFW_MOUSE_BUTTON_1)
+        return;
+    if (state == GLFW_TRUE)
+        mouseDown = true;
+    else
+        mouseDown = false;
 }
 
+int main(int argc, char *argv[]) {
 
+    _parse_args(argc, argv);
+    VkEngine e;
+    e = vkengine_create(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
 
-int main(int argc, char* argv[]) {
+    VkhPresenter r = e->renderer;
+    vkengine_set_key_callback(e, key_callback);
+    vkengine_set_mouse_but_callback(e, mouse_button_callback);
+    vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+    vkengine_set_scroll_callback(e, scroll_callback);
 
-       _parse_args (argc, argv);
-       VkEngine e;
-       e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
+    vkvg_device_create_info_t info = {samples, false, vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0};
+    device                         = vkvg_device_create(&info);
+    surf                           = vkvg_surface_create(device, test_width, test_height);
 
-       VkhPresenter r = e->renderer;
-       vkengine_set_key_callback (e, key_callback);
-       vkengine_set_mouse_but_callback(e, mouse_button_callback);
-       vkengine_set_cursor_pos_callback(e, mouse_move_callback);
-       vkengine_set_scroll_callback(e, scroll_callback);
+    vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
 
-    vkvg_device_create_info_t info = {
-        samples,
-        false,
-        vkh_app_get_inst(e->app),
-        r->dev->phy,
-        r->dev->dev,
-        r->qFam,
-        0
-    };
-    device = vkvg_device_create(&info);
-    surf = vkvg_surface_create(device, test_width, test_height);
+    while (!vkengine_should_close(e)) {
+        glfwPollEvents();
 
-       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+        draw();
 
-       while (!vkengine_should_close (e)) {
-               glfwPollEvents();
+        if (!vkh_presenter_draw(r)) {
+            vkh_presenter_get_size(r, &test_width, &test_height);
+            vkvg_surface_destroy(surf);
+            surf = vkvg_surface_create(device, test_width, test_height);
+            vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+            vkDeviceWaitIdle(r->dev->dev);
+            continue;
+        }
+    }
+    vkDeviceWaitIdle(e->dev->dev);
 
-               draw ();
+    vkvg_surface_destroy(surf);
 
-               if (!vkh_presenter_draw (r)){
-                       vkh_presenter_get_size (r, &test_width, &test_height);
-                       vkvg_surface_destroy (surf);
-                       surf = vkvg_surface_create(device, test_width, test_height);
-                       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
-                       vkDeviceWaitIdle(r->dev->dev);
-                       continue;
-               }
-       }
-       vkDeviceWaitIdle(e->dev->dev);
+    vkvg_device_destroy(device);
 
-       vkvg_surface_destroy    (surf);
+    vkengine_destroy(e);
 
-       vkvg_device_destroy     (device);
-
-       vkengine_destroy (e);
-
-       return 0;
+    return 0;
 }
index 2ad012997dce1e7e379306d24192bc5d0cf1ab34..82a33dc1a8ada9c72b449ed072a684691d33bc1d 100644 (file)
@@ -1,58 +1,58 @@
 #include "test.h"
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_source_rgba(ctx,0.9f,0.9f,0.9f,1);
-       vkvg_paint(ctx);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_source_rgba(ctx, 0.9f, 0.9f, 0.9f, 1);
+    vkvg_paint(ctx);
 
-       float x = 20, y = 20, dx = 40, dy = 60;
+    float x = 20, y = 20, dx = 40, dy = 60;
 
-       //vkvg_scale(ctx,5,5);
-       vkvg_set_line_width(ctx,30);
-       vkvg_set_source_rgba(ctx,0.0,0.0,0,1);
-       vkvg_move_to(ctx,x,y);
-       vkvg_rel_line_to(ctx,0,dy);
-       vkvg_stroke(ctx);
-       vkvg_set_line_cap(ctx,VKVG_LINE_CAP_SQUARE);
-       vkvg_move_to(ctx,x+dx,y);
-       vkvg_rel_line_to(ctx,0,dy);
-       vkvg_stroke(ctx);
-       vkvg_set_line_cap(ctx,VKVG_LINE_CAP_ROUND);
-       vkvg_move_to(ctx,x+2*dx,y);
-       vkvg_rel_line_to(ctx,0,dy);
-       vkvg_rel_move_to(ctx,dx,-dy);
-       vkvg_rel_line_to(ctx,dx,dy);
-       vkvg_rel_move_to(ctx,dx,-dy/2.f);
-       vkvg_rel_line_to(ctx,dx,0);
-       vkvg_rel_move_to(ctx,dx,dy/2.f);
-       vkvg_rel_line_to(ctx,dx,-dy);
-       vkvg_rel_move_to(ctx,dx,dy);
-       vkvg_rel_line_to(ctx,0,-dy);
-       vkvg_rel_move_to(ctx,dx*2.f,dy);
-       vkvg_rel_line_to(ctx,-dx,-dy);
-       vkvg_rel_move_to(ctx,dx*3.f,dy/2.f);
-       vkvg_rel_line_to(ctx,-dx,0);
-       //vkvg_rel_line_to(ctx,0,-dy);
-       //vkvg_rel_move_to(ctx,dx,dy/2);
-       //vkvg_rel_line_to(ctx,dx,0);
-       vkvg_stroke(ctx);
+    // vkvg_scale(ctx,5,5);
+    vkvg_set_line_width(ctx, 30);
+    vkvg_set_source_rgba(ctx, 0.0, 0.0, 0, 1);
+    vkvg_move_to(ctx, x, y);
+    vkvg_rel_line_to(ctx, 0, dy);
+    vkvg_stroke(ctx);
+    vkvg_set_line_cap(ctx, VKVG_LINE_CAP_SQUARE);
+    vkvg_move_to(ctx, x + dx, y);
+    vkvg_rel_line_to(ctx, 0, dy);
+    vkvg_stroke(ctx);
+    vkvg_set_line_cap(ctx, VKVG_LINE_CAP_ROUND);
+    vkvg_move_to(ctx, x + 2 * dx, y);
+    vkvg_rel_line_to(ctx, 0, dy);
+    vkvg_rel_move_to(ctx, dx, -dy);
+    vkvg_rel_line_to(ctx, dx, dy);
+    vkvg_rel_move_to(ctx, dx, -dy / 2.f);
+    vkvg_rel_line_to(ctx, dx, 0);
+    vkvg_rel_move_to(ctx, dx, dy / 2.f);
+    vkvg_rel_line_to(ctx, dx, -dy);
+    vkvg_rel_move_to(ctx, dx, dy);
+    vkvg_rel_line_to(ctx, 0, -dy);
+    vkvg_rel_move_to(ctx, dx * 2.f, dy);
+    vkvg_rel_line_to(ctx, -dx, -dy);
+    vkvg_rel_move_to(ctx, dx * 3.f, dy / 2.f);
+    vkvg_rel_line_to(ctx, -dx, 0);
+    // vkvg_rel_line_to(ctx,0,-dy);
+    // vkvg_rel_move_to(ctx,dx,dy/2);
+    // vkvg_rel_line_to(ctx,dx,0);
+    vkvg_stroke(ctx);
 
-       vkvg_set_line_cap(ctx,VKVG_LINE_CAP_BUTT);
-       vkvg_set_line_width(ctx,1);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_move_to(ctx,x,y);
-       vkvg_rel_line_to(ctx,0,dy);
-       vkvg_rel_move_to(ctx,dx,-dy);
-       vkvg_rel_line_to(ctx,0,dy);
-       vkvg_rel_move_to(ctx,dx,-dy);
-       vkvg_rel_line_to(ctx,0,dy);
-       vkvg_stroke(ctx);
+    vkvg_set_line_cap(ctx, VKVG_LINE_CAP_BUTT);
+    vkvg_set_line_width(ctx, 1);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_move_to(ctx, x, y);
+    vkvg_rel_line_to(ctx, 0, dy);
+    vkvg_rel_move_to(ctx, dx, -dy);
+    vkvg_rel_line_to(ctx, 0, dy);
+    vkvg_rel_move_to(ctx, dx, -dy);
+    vkvg_rel_line_to(ctx, 0, dy);
+    vkvg_stroke(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
+    return 0;
 }
index 779b8cc3252d18f8bfaa13ab2b411b16e505eca9..f34ad70767e566c683eb63bdc91df0b43d0765a4 100644 (file)
 #include "test.h"
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
-
-       float x = 250, y = 150;
-
-       //vkvg_scale(ctx,2,2);
-
-       vkvg_set_line_width(ctx,100);
-       vkvg_set_source_rgba(ctx,0,1,0,1);
-
-
-       vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND);
-       //vkvg_rectangle(ctx,x,y,dx,dy);
-
-       vkvg_move_to(ctx,x,y);
-       vkvg_rel_line_to(ctx,-50,30);
-       vkvg_rel_line_to(ctx,0,60);
-       vkvg_rel_line_to(ctx,50,30);
-       /*
-       vkvg_rel_line_to(ctx,50,-30);
-       vkvg_rel_line_to(ctx,50,0);
-       vkvg_rel_line_to(ctx,50,30);
-       vkvg_rel_line_to(ctx,0,60);
-       vkvg_rel_line_to(ctx,-50,70);
-       vkvg_rel_line_to(ctx,-50,0);
-       vkvg_rel_line_to(ctx,-50,-70);
-       vkvg_close_path(ctx);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_move_to(ctx,x+200,y);
-       vkvg_rel_line_to(ctx,50,70);
-       vkvg_rel_line_to(ctx,50,0);
-       vkvg_rel_line_to(ctx,50,-70);
-       vkvg_rel_line_to(ctx,0,-60);
-       vkvg_rel_line_to(ctx,-50,-30);
-       vkvg_rel_line_to(ctx,-50,0);
-       vkvg_rel_line_to(ctx,-50,30);*/
-       vkvg_close_path(ctx);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgba(ctx,0,0,1,1);
-       vkvg_move_to(ctx,x+250,y);
-       vkvg_rel_line_to(ctx,50,-30);
-       vkvg_rel_line_to(ctx,50,0);
-       vkvg_rel_line_to(ctx,50,30);
-       vkvg_rel_line_to(ctx,0,60);
-       vkvg_rel_line_to(ctx,-50,70);
-       vkvg_rel_line_to(ctx,-50,0);
-       vkvg_rel_line_to(ctx,-50,-70);
-       vkvg_close_path(ctx);
-       vkvg_stroke(ctx);
-
-//    float dx = 150, dy = 140;
-//    vkvg_rel_line_to(ctx,dx,-dy);
-//    vkvg_rel_line_to(ctx,dx,dy);
-//    vkvg_stroke(ctx);
-//    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
-//    vkvg_rel_move_to(ctx,-dx*2,abs(dy*1.5));
-//    vkvg_rel_line_to(ctx,dx,-dy);
-//    vkvg_rel_line_to(ctx,dx,dy);
-//    vkvg_stroke(ctx);
-//    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND);
-//    vkvg_rel_move_to(ctx,-dx*2,abs(dy*1.5));
-//    vkvg_rel_line_to(ctx,dx,-dy);
-//    vkvg_rel_line_to(ctx,dx,dy);
-//    vkvg_stroke(ctx);
-//    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_MITER);
-
-       vkvg_destroy(ctx);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
+
+    float x = 250, y = 150;
+
+    // vkvg_scale(ctx,2,2);
+
+    vkvg_set_line_width(ctx, 100);
+    vkvg_set_source_rgba(ctx, 0, 1, 0, 1);
+
+    vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND);
+    // vkvg_rectangle(ctx,x,y,dx,dy);
+
+    vkvg_move_to(ctx, x, y);
+    vkvg_rel_line_to(ctx, -50, 30);
+    vkvg_rel_line_to(ctx, 0, 60);
+    vkvg_rel_line_to(ctx, 50, 30);
+    /*
+    vkvg_rel_line_to(ctx,50,-30);
+    vkvg_rel_line_to(ctx,50,0);
+    vkvg_rel_line_to(ctx,50,30);
+    vkvg_rel_line_to(ctx,0,60);
+    vkvg_rel_line_to(ctx,-50,70);
+    vkvg_rel_line_to(ctx,-50,0);
+    vkvg_rel_line_to(ctx,-50,-70);
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgba(ctx,1,0,0,1);
+    vkvg_move_to(ctx,x+200,y);
+    vkvg_rel_line_to(ctx,50,70);
+    vkvg_rel_line_to(ctx,50,0);
+    vkvg_rel_line_to(ctx,50,-70);
+    vkvg_rel_line_to(ctx,0,-60);
+    vkvg_rel_line_to(ctx,-50,-30);
+    vkvg_rel_line_to(ctx,-50,0);
+    vkvg_rel_line_to(ctx,-50,30);*/
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgba(ctx, 0, 0, 1, 1);
+    vkvg_move_to(ctx, x + 250, y);
+    vkvg_rel_line_to(ctx, 50, -30);
+    vkvg_rel_line_to(ctx, 50, 0);
+    vkvg_rel_line_to(ctx, 50, 30);
+    vkvg_rel_line_to(ctx, 0, 60);
+    vkvg_rel_line_to(ctx, -50, 70);
+    vkvg_rel_line_to(ctx, -50, 0);
+    vkvg_rel_line_to(ctx, -50, -70);
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+
+    //    float dx = 150, dy = 140;
+    //    vkvg_rel_line_to(ctx,dx,-dy);
+    //    vkvg_rel_line_to(ctx,dx,dy);
+    //    vkvg_stroke(ctx);
+    //    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
+    //    vkvg_rel_move_to(ctx,-dx*2,abs(dy*1.5));
+    //    vkvg_rel_line_to(ctx,dx,-dy);
+    //    vkvg_rel_line_to(ctx,dx,dy);
+    //    vkvg_stroke(ctx);
+    //    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND);
+    //    vkvg_rel_move_to(ctx,-dx*2,abs(dy*1.5));
+    //    vkvg_rel_line_to(ctx,dx,-dy);
+    //    vkvg_rel_line_to(ctx,dx,dy);
+    //    vkvg_stroke(ctx);
+    //    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_MITER);
+
+    vkvg_destroy(ctx);
 }
 
 void test2() {
-       VkvgContext ctx = vkvg_create(surf);
-
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_set_line_width(ctx, 30);
-
-       vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND);
-
-       //vkvg_arc (ctx, 200, 500, 100, 0, M_PI);
-
-       vkvg_translate(ctx, -50, -50);
-
-       vkvg_set_source_rgb(ctx, 0.5, 0, 0);
-
-       for (int j = 0; j < 2; j++) {
-               int i = 0;
-               vkvg_move_to(ctx, 100, 100);
-               for (i = 0; i < 5; i++) {
-                       vkvg_rel_line_to(ctx, 70, 50);
-                       vkvg_rel_line_to(ctx, -70, 50);
-               }
-               vkvg_stroke(ctx);
-
-               vkvg_move_to(ctx, 200, 600);
-               for (i = 0; i < 5; i++) {
-                       vkvg_rel_line_to(ctx, 70, -50);
-                       vkvg_rel_line_to(ctx, -70, -50);
-               }
-               vkvg_stroke(ctx);
-
-               vkvg_move_to(ctx, 400, 100);
-               for (i = 0; i < 5; i++) {
-                       vkvg_rel_line_to(ctx, -70, 50);
-                       vkvg_rel_line_to(ctx, 70, 50);
-               }
-               vkvg_stroke(ctx);
-
-               vkvg_move_to(ctx, 500, 600);
-               for (i = 0; i < 5; i++) {
-                       vkvg_rel_line_to(ctx, -70, -50);
-                       vkvg_rel_line_to(ctx, 70, -50);
-               }
-               vkvg_stroke(ctx);
-               vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL);
-               vkvg_translate(ctx, 500, 0);
-       }
-
-       vkvg_destroy(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_line_width(ctx, 30);
+
+    vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND);
+
+    // vkvg_arc (ctx, 200, 500, 100, 0, M_PI);
+
+    vkvg_translate(ctx, -50, -50);
+
+    vkvg_set_source_rgb(ctx, 0.5, 0, 0);
+
+    for (int j = 0; j < 2; j++) {
+        int i = 0;
+        vkvg_move_to(ctx, 100, 100);
+        for (i = 0; i < 5; i++) {
+            vkvg_rel_line_to(ctx, 70, 50);
+            vkvg_rel_line_to(ctx, -70, 50);
+        }
+        vkvg_stroke(ctx);
+
+        vkvg_move_to(ctx, 200, 600);
+        for (i = 0; i < 5; i++) {
+            vkvg_rel_line_to(ctx, 70, -50);
+            vkvg_rel_line_to(ctx, -70, -50);
+        }
+        vkvg_stroke(ctx);
+
+        vkvg_move_to(ctx, 400, 100);
+        for (i = 0; i < 5; i++) {
+            vkvg_rel_line_to(ctx, -70, 50);
+            vkvg_rel_line_to(ctx, 70, 50);
+        }
+        vkvg_stroke(ctx);
+
+        vkvg_move_to(ctx, 500, 600);
+        for (i = 0; i < 5; i++) {
+            vkvg_rel_line_to(ctx, -70, -50);
+            vkvg_rel_line_to(ctx, 70, -50);
+        }
+        vkvg_stroke(ctx);
+        vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL);
+        vkvg_translate(ctx, 500, 0);
+    }
+
+    vkvg_destroy(ctx);
 }
 
 void test3() {
-       VkvgContext ctx = vkvg_create(surf);
-
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_set_line_width(ctx, 30);
-
-       vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND);
-
-       //vkvg_arc (ctx, 200, 500, 100, 0, M_PI);
-
-       vkvg_translate(ctx, -50, -50);
-
-       vkvg_set_source_rgb(ctx, 0.5, 0, 0);
-
-       for (int j = 0; j < 2; j++) {
-               int i = 0;
-               vkvg_move_to(ctx, 100, 100);
-               for (i = 0; i < 4; i++) {
-                       vkvg_rel_line_to(ctx, 50, 70);
-                       vkvg_rel_line_to(ctx, 50, -70);
-               }
-               vkvg_stroke(ctx);
-
-               vkvg_move_to(ctx, 500, 200);
-               for (i = 0; i < 4; i++) {
-                       vkvg_rel_line_to(ctx, -50, 70);
-                       vkvg_rel_line_to(ctx, -50, -70);
-               }
-               vkvg_stroke(ctx);
-
-               vkvg_move_to(ctx, 100, 400);
-               for (i = 0; i < 4; i++) {
-                       vkvg_rel_line_to(ctx, 50, -70);
-                       vkvg_rel_line_to(ctx, 50, 70);
-               }
-               vkvg_stroke(ctx);
-
-               vkvg_move_to(ctx, 500, 500);
-               for (i = 0; i < 4; i++) {
-                       vkvg_rel_line_to(ctx, -50, -70);
-                       vkvg_rel_line_to(ctx, -50, 70);
-               }
-               vkvg_stroke(ctx);
-               vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL);
-               vkvg_translate(ctx, 450, 0);
-       }
-
-       vkvg_destroy(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_line_width(ctx, 30);
+
+    vkvg_set_line_join(ctx, VKVG_LINE_JOIN_ROUND);
+
+    // vkvg_arc (ctx, 200, 500, 100, 0, M_PI);
+
+    vkvg_translate(ctx, -50, -50);
+
+    vkvg_set_source_rgb(ctx, 0.5, 0, 0);
+
+    for (int j = 0; j < 2; j++) {
+        int i = 0;
+        vkvg_move_to(ctx, 100, 100);
+        for (i = 0; i < 4; i++) {
+            vkvg_rel_line_to(ctx, 50, 70);
+            vkvg_rel_line_to(ctx, 50, -70);
+        }
+        vkvg_stroke(ctx);
+
+        vkvg_move_to(ctx, 500, 200);
+        for (i = 0; i < 4; i++) {
+            vkvg_rel_line_to(ctx, -50, 70);
+            vkvg_rel_line_to(ctx, -50, -70);
+        }
+        vkvg_stroke(ctx);
+
+        vkvg_move_to(ctx, 100, 400);
+        for (i = 0; i < 4; i++) {
+            vkvg_rel_line_to(ctx, 50, -70);
+            vkvg_rel_line_to(ctx, 50, 70);
+        }
+        vkvg_stroke(ctx);
+
+        vkvg_move_to(ctx, 500, 500);
+        for (i = 0; i < 4; i++) {
+            vkvg_rel_line_to(ctx, -50, -70);
+            vkvg_rel_line_to(ctx, -50, 70);
+        }
+        vkvg_stroke(ctx);
+        vkvg_set_line_join(ctx, VKVG_LINE_JOIN_BEVEL);
+        vkvg_translate(ctx, 450, 0);
+    }
+
+    vkvg_destroy(ctx);
 }
 
-
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST(test, argc, argv);
-       PERFORM_TEST(test2, argc, argv);
-       PERFORM_TEST(test3, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
+    PERFORM_TEST(test2, argc, argv);
+    PERFORM_TEST(test3, argc, argv);
+    return 0;
 }
index ef26d85b0dde95144b712f1bca0638afaa20e7e7..efd7e3dc63e7cc54536bb34e3fb270321e564843 100644 (file)
 #include "test.h"
 
 void horizontal() {
-       float w = (float)test_width;
-       float h = (float)test_height;
-
-       VkvgContext ctx = _initCtx();
-
-       for (uint32_t i=0; i<test_size; i++) {
-               randomize_color(ctx);
-               float x1 = w*rndf();
-               float y1 = h*rndf();
-               float v = 500.f*rndf();
-
-               vkvg_move_to (ctx, x1, y1);
-               vkvg_line_to (ctx, x1 + v, y1);
-               vkvg_stroke (ctx);
-       }
-       vkvg_destroy(ctx);
+    float w = (float)test_width;
+    float h = (float)test_height;
+
+    VkvgContext ctx = _initCtx();
+
+    for (uint32_t i = 0; i < test_size; i++) {
+        randomize_color(ctx);
+        float x1 = w * rndf();
+        float y1 = h * rndf();
+        float v  = 500.f * rndf();
+
+        vkvg_move_to(ctx, x1, y1);
+        vkvg_line_to(ctx, x1 + v, y1);
+        vkvg_stroke(ctx);
+    }
+    vkvg_destroy(ctx);
 }
 void vertical() {
-       float w = (float)test_width;
-       float h = (float)test_height;
-
-       VkvgContext ctx = _initCtx();
-
-       for (uint32_t i=0; i<test_size; i++) {
-               randomize_color(ctx);
-               float x1 = w*rndf();
-               float y1 = h*rndf();
-               float v = 500.f*rndf();
-
-               vkvg_move_to (ctx, x1, y1);
-               vkvg_line_to (ctx, x1, y1 + v);
-               vkvg_stroke (ctx);
-       }
-       vkvg_destroy(ctx);
+    float w = (float)test_width;
+    float h = (float)test_height;
+
+    VkvgContext ctx = _initCtx();
+
+    for (uint32_t i = 0; i < test_size; i++) {
+        randomize_color(ctx);
+        float x1 = w * rndf();
+        float y1 = h * rndf();
+        float v  = 500.f * rndf();
+
+        vkvg_move_to(ctx, x1, y1);
+        vkvg_line_to(ctx, x1, y1 + v);
+        vkvg_stroke(ctx);
+    }
+    vkvg_destroy(ctx);
 }
-void horzAndVert(){
-       float w = (float)test_width;
-       float h = (float)test_height;
+void horzAndVert() {
+    float w = (float)test_width;
+    float h = (float)test_height;
 
-       VkvgContext ctx = _initCtx();
+    VkvgContext ctx = _initCtx();
 
-       for (uint32_t i=0; i<test_size; i++) {
-               randomize_color(ctx);
+    for (uint32_t i = 0; i < test_size; i++) {
+        randomize_color(ctx);
 
-               float x1 = w*rndf();
-               float y1 = h*rndf();
-               float x2 = (w*rndf()) + 1;
-               float y2 = (h*rndf()) + 1;
+        float x1 = w * rndf();
+        float y1 = h * rndf();
+        float x2 = (w * rndf()) + 1;
+        float y2 = (h * rndf()) + 1;
 
-               vkvg_move_to (ctx, x1, y1);
-               vkvg_line_to (ctx, x2, y2);
-               vkvg_stroke (ctx);
-       }
-       vkvg_destroy(ctx);
+        vkvg_move_to(ctx, x1, y1);
+        vkvg_line_to(ctx, x2, y2);
+        vkvg_stroke(ctx);
+    }
+    vkvg_destroy(ctx);
 }
-void multilines(){
-       float w = (float)test_width;
-       float h = (float)test_height;
+void multilines() {
+    float w = (float)test_width;
+    float h = (float)test_height;
 
-       VkvgContext ctx = _initCtx();
+    VkvgContext ctx = _initCtx();
 
-       randomize_color(ctx);
+    randomize_color(ctx);
 
-       for (uint32_t i=0; i<test_size; i++) {
+    for (uint32_t i = 0; i < test_size; i++) {
 
-               float x1 = w*rndf();
-               float y1 = h*rndf();
-               float x2 = (w*rndf()) + 1;
-               float y2 = (h*rndf()) + 1;
+        float x1 = w * rndf();
+        float y1 = h * rndf();
+        float x2 = (w * rndf()) + 1;
+        float y2 = (h * rndf()) + 1;
 
-               vkvg_move_to (ctx, x1, y1);
-               vkvg_line_to (ctx, x2, y2);
-       }
-       vkvg_stroke (ctx);
-       vkvg_destroy(ctx);
+        vkvg_move_to(ctx, x1, y1);
+        vkvg_line_to(ctx, x2, y2);
+    }
+    vkvg_stroke(ctx);
+    vkvg_destroy(ctx);
 }
 void multi_segments() {
-    float w = (float)test_width-10;
-    float h = (float)test_height-10;
+    float w = (float)test_width - 10;
+    float h = (float)test_height - 10;
 
     VkvgContext ctx = _initCtx();
 
     randomize_color(ctx);
-    float x1 = w*rndf();
-    float y1 = h*rndf();
-    vkvg_move_to (ctx, x1, y1);
-    for (uint32_t i=0; i<test_size; i++) {
-        x1 = w*rndf();
-        y1 = h*rndf();
-        vkvg_line_to (ctx, x1, y1);
+    float x1 = w * rndf();
+    float y1 = h * rndf();
+    vkvg_move_to(ctx, x1, y1);
+    for (uint32_t i = 0; i < test_size; i++) {
+        x1 = w * rndf();
+        y1 = h * rndf();
+        vkvg_line_to(ctx, x1, y1);
     }
-    vkvg_stroke (ctx);
+    vkvg_stroke(ctx);
     vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       struct timeval currentTime;
-       gettimeofday(&currentTime, NULL);
+    struct timeval currentTime;
+    gettimeofday(&currentTime, NULL);
 
-       srand((unsigned) currentTime.tv_usec);
+    srand((unsigned)currentTime.tv_usec);
 
     PERFORM_TEST(horizontal, argc, argv);
-       PERFORM_TEST(vertical, argc, argv);
-       PERFORM_TEST(horzAndVert, argc, argv);
+    PERFORM_TEST(vertical, argc, argv);
+    PERFORM_TEST(horzAndVert, argc, argv);
     PERFORM_TEST(multilines, argc, argv);
     PERFORM_TEST(multi_segments, argc, argv);
     return 0;
index 05ee0384a25af07a641df833df77c74575ef119b..280261de3d7809380b6dc35b3b12ed524a963f0b 100644 (file)
@@ -7,70 +7,69 @@
 
 #define THREAD_COUNT 32
 
+static int    finishedThreadCount = 0;
+static mtx_t *pmutex;
 
-static int finishedThreadCount = 0;
-static mtx_t* pmutex;
+void drawRandomRect(VkvgContext ctx, float s) {
+    float w = (float)test_width;
+    float h = (float)test_height;
+    randomize_color(ctx);
 
-void drawRandomRect (VkvgContext ctx, float s) {
-       float w = (float)test_width;
-       float h = (float)test_height;
-       randomize_color(ctx);
+    float x = truncf(w * rndf());
+    float y = truncf(h * rndf());
 
-       float x = truncf(w*rndf());
-       float y = truncf(h*rndf());
-
-       vkvg_rectangle(ctx, x, y, s, s);
+    vkvg_rectangle(ctx, x, y, s, s);
 }
 
-int drawRectsThread () {
+int drawRectsThread() {
 
-       VkvgSurface s = vkvg_surface_create(device, test_width, test_height);
-       VkvgContext ctx = vkvg_create(s);
-       for (uint32_t i=0; i<test_size; i++) {
-               drawRandomRect(ctx, 14.0f);
-               vkvg_fill (ctx);
-       }
-       vkvg_destroy(ctx);
+    VkvgSurface s   = vkvg_surface_create(device, test_width, test_height);
+    VkvgContext ctx = vkvg_create(s);
+    for (uint32_t i = 0; i < test_size; i++) {
+        drawRandomRect(ctx, 14.0f);
+        vkvg_fill(ctx);
+    }
+    vkvg_destroy(ctx);
 
-       mtx_lock(pmutex);
+    mtx_lock(pmutex);
 
-       ctx = vkvg_create(surf);
-               vkvg_set_source_surface (ctx, s, 0, 0);
-               vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+    ctx = vkvg_create(surf);
+    vkvg_set_source_surface(ctx, s, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 
-       finishedThreadCount++;
-       mtx_unlock(pmutex);
+    finishedThreadCount++;
+    mtx_unlock(pmutex);
 
-       vkvg_surface_destroy (s);
-       return 0;
+    vkvg_surface_destroy(s);
+    return 0;
 }
-void fixedSizeRects(){
-       mtx_t mutex;
-       pmutex = &mutex;
+void fixedSizeRects() {
+    mtx_t mutex;
+    pmutex = &mutex;
 
-       vkvg_device_set_thread_aware (device, 1);
+    vkvg_device_set_thread_aware(device, 1);
 
-       thrd_t threads[THREAD_COUNT];
+    thrd_t threads[THREAD_COUNT];
 
-       finishedThreadCount = 0;
-       mtx_init (pmutex, mtx_plain);
-       for (uint32_t i=0; i<THREAD_COUNT; i++)
-               thrd_create (&threads[i], drawRectsThread, NULL);
+    finishedThreadCount = 0;
+    mtx_init(pmutex, mtx_plain);
+    for (uint32_t i = 0; i < THREAD_COUNT; i++)
+        thrd_create(&threads[i], drawRectsThread, NULL);
 
-       const struct timespec ts = {1,0};
-       while (finishedThreadCount < THREAD_COUNT)
-               thrd_sleep(&ts, NULL);
+    const struct timespec ts = {1, 0};
+    while (finishedThreadCount < THREAD_COUNT)
+        thrd_sleep(&ts, NULL);
 
-       mtx_lock(pmutex);
-       mtx_unlock(pmutex);
-       mtx_destroy (pmutex);
-       pmutex = NULL;
+    mtx_lock(pmutex);
+    mtx_unlock(pmutex);
+    mtx_destroy(pmutex);
+    pmutex = NULL;
 
-       vkvg_device_set_thread_aware (device, 0);
+    vkvg_device_set_thread_aware(device, 0);
 }
 
 int main(int argc, char *argv[]) {
-       PERFORM_TEST (fixedSizeRects, argc, argv);
-       return 0;
+    PERFORM_TEST(fixedSizeRects, argc, argv);
+    return 0;
 }
index a29e0064b6289264415349439796925ec3e456b2..7eff7a0700a31023cd7593437541242a77b08923 100644 (file)
@@ -6,58 +6,57 @@
 
 #define THREAD_COUNT 32
 
+static int    finishedThreadCount = 0;
+static mtx_t *pmutex;
 
-static int finishedThreadCount = 0;
-static mtx_t* pmutex;
+void drawRandomRect(VkvgContext ctx, float s) {
+    float w = (float)test_width;
+    float h = (float)test_height;
+    randomize_color(ctx);
 
-void drawRandomRect (VkvgContext ctx, float s) {
-       float w = (float)test_width;
-       float h = (float)test_height;
-       randomize_color(ctx);
+    float x = truncf(w * rndf());
+    float y = truncf(h * rndf());
 
-       float x = truncf(w*rndf());
-       float y = truncf(h*rndf());
-
-       vkvg_rectangle(ctx, x, y, s, s);
+    vkvg_rectangle(ctx, x, y, s, s);
 }
-int drawRectsThread () {
-       VkvgContext ctx = vkvg_create(surf);
-       for (uint32_t i=0; i<test_size; i++) {
-               drawRandomRect(ctx, 14.0f);
-               vkvg_fill (ctx);
-       }
-       vkvg_destroy (ctx);
-       mtx_lock (pmutex);
-       finishedThreadCount++;
-       mtx_unlock (pmutex);
-       return 0;
+int drawRectsThread() {
+    VkvgContext ctx = vkvg_create(surf);
+    for (uint32_t i = 0; i < test_size; i++) {
+        drawRandomRect(ctx, 14.0f);
+        vkvg_fill(ctx);
+    }
+    vkvg_destroy(ctx);
+    mtx_lock(pmutex);
+    finishedThreadCount++;
+    mtx_unlock(pmutex);
+    return 0;
 }
-void fixedSizeRects(){
-       mtx_t mutex;
-       pmutex = &mutex;
+void fixedSizeRects() {
+    mtx_t mutex;
+    pmutex = &mutex;
 
-       vkvg_device_set_thread_aware (device, 1);
+    vkvg_device_set_thread_aware(device, 1);
 
-       thrd_t threads[THREAD_COUNT];
+    thrd_t threads[THREAD_COUNT];
 
-       finishedThreadCount = 0;
-       mtx_init (pmutex, mtx_plain);
-       for (uint32_t i=0; i<THREAD_COUNT; i++)
-               thrd_create (&threads[i], drawRectsThread, NULL);
+    finishedThreadCount = 0;
+    mtx_init(pmutex, mtx_plain);
+    for (uint32_t i = 0; i < THREAD_COUNT; i++)
+        thrd_create(&threads[i], drawRectsThread, NULL);
 
-       const struct timespec ts = {1,0};
-       while (finishedThreadCount < THREAD_COUNT)
-               thrd_sleep(&ts, NULL);
+    const struct timespec ts = {1, 0};
+    while (finishedThreadCount < THREAD_COUNT)
+        thrd_sleep(&ts, NULL);
 
-       mtx_lock(pmutex);
-       mtx_unlock(pmutex);
-       mtx_destroy (pmutex);
-       pmutex = NULL;
+    mtx_lock(pmutex);
+    mtx_unlock(pmutex);
+    mtx_destroy(pmutex);
+    pmutex = NULL;
 
-       vkvg_device_set_thread_aware (device, 0);
+    vkvg_device_set_thread_aware(device, 0);
 }
 
 int main(int argc, char *argv[]) {
-       PERFORM_TEST (fixedSizeRects, argc, argv);
-       return 0;
+    PERFORM_TEST(fixedSizeRects, argc, argv);
+    return 0;
 }
index 97895658deff538cbb4a4f81791393c042c8248f..f7e8d80b999fd514befbd682e6b0e27ca5ddde24 100644 (file)
@@ -3,48 +3,47 @@
 
 #define THREAD_COUNT 16
 
-
-static int finishedThreadCount = 0;
-static mtx_t* pmutex;
-
-int create_surfs () {
-       for (uint32_t i=0; i<test_size; i++) {
-               VkvgSurface s = vkvg_surface_create(device, test_width, test_height);
-               vkvg_surface_destroy (s);
-       }
-
-       mtx_lock(pmutex);
-       finishedThreadCount++;
-       mtx_unlock(pmutex);
-       return 0;
+static int    finishedThreadCount = 0;
+static mtx_t *pmutex;
+
+int create_surfs() {
+    for (uint32_t i = 0; i < test_size; i++) {
+        VkvgSurface s = vkvg_surface_create(device, test_width, test_height);
+        vkvg_surface_destroy(s);
+    }
+
+    mtx_lock(pmutex);
+    finishedThreadCount++;
+    mtx_unlock(pmutex);
+    return 0;
 }
 
-void fixedSizeRects(){
-       mtx_t mutex;
-       pmutex = &mutex;
+void fixedSizeRects() {
+    mtx_t mutex;
+    pmutex = &mutex;
 
-       vkvg_device_set_thread_aware (device, 1);
+    vkvg_device_set_thread_aware(device, 1);
 
-       thrd_t threads[THREAD_COUNT];
+    thrd_t threads[THREAD_COUNT];
 
-       finishedThreadCount = 0;
-       mtx_init (pmutex, mtx_plain);
-       for (uint32_t i=0; i<THREAD_COUNT; i++)
-               thrd_create (&threads[i], create_surfs, NULL);
+    finishedThreadCount = 0;
+    mtx_init(pmutex, mtx_plain);
+    for (uint32_t i = 0; i < THREAD_COUNT; i++)
+        thrd_create(&threads[i], create_surfs, NULL);
 
-       const struct timespec ts = {1,0};
-       while (finishedThreadCount < THREAD_COUNT)
-               thrd_sleep(&ts, NULL);
+    const struct timespec ts = {1, 0};
+    while (finishedThreadCount < THREAD_COUNT)
+        thrd_sleep(&ts, NULL);
 
-       mtx_lock(pmutex);
-       mtx_unlock(pmutex);
-       mtx_destroy (pmutex);
-       pmutex = NULL;
+    mtx_lock(pmutex);
+    mtx_unlock(pmutex);
+    mtx_destroy(pmutex);
+    pmutex = NULL;
 
-       vkvg_device_set_thread_aware (device, 0);
+    vkvg_device_set_thread_aware(device, 0);
 }
 
 int main(int argc, char *argv[]) {
-       PERFORM_TEST (fixedSizeRects, argc, argv);
-       return 0;
+    PERFORM_TEST(fixedSizeRects, argc, argv);
+    return 0;
 }
index bacf59759dcb5e08065adfc4f7e2327cc370f1d6..8ae18a9056c120055ef84e3aaecbd9f78dff851c 100644 (file)
@@ -7,77 +7,75 @@
 
 #define THREAD_COUNT 16
 
-static int finishedThreadCount = 0;
-static mtx_tpmutex;
+static int    finishedThreadCount = 0;
+static mtx_t *pmutex;
 
-void drawRandomRect (VkvgContext ctx, float s) {
-       float w = (float)test_width;
-       float h = (float)test_height;
-       randomize_color(ctx);
+void drawRandomRect(VkvgContext ctx, float s) {
+    float w = (float)test_width;
+    float h = (float)test_height;
+    randomize_color(ctx);
 
-       float x = truncf(w*rndf());
-       float y = truncf(h*rndf());
+    float x = truncf(w * rndf());
+    float y = truncf(h * rndf());
 
-       vkvg_rectangle(ctx, x, y, s, s);
+    vkvg_rectangle(ctx, x, y, s, s);
 }
 
-int _single_font_and_size () {
-       VkvgSurface s = vkvg_surface_create(device, test_width, test_height);
-       VkvgContext ctx = vkvg_create(s);
-       vkvg_clear(ctx);
-       for (uint32_t i=0; i<test_size/THREAD_COUNT; i++) {
-               randomize_color(ctx);
-               float x = rndf() * test_width;
-               float y = rndf() * test_height;
-               vkvg_select_font_face(ctx,"mono");
-               vkvg_set_font_size(ctx, 20);
-               vkvg_move_to(ctx,x,y);
-               vkvg_show_text(ctx,"This is a test string!");
-       }
-       vkvg_destroy(ctx);
-
-       mtx_lock(pmutex);
-
-       ctx = vkvg_create(surf);
-               vkvg_set_source_surface (ctx, s, 0, 0);
-               vkvg_paint(ctx);
-       vkvg_destroy(ctx);
-
-       finishedThreadCount++;
-       mtx_unlock(pmutex);
-
-       vkvg_surface_destroy (s);
-       return 0;
+int _single_font_and_size() {
+    VkvgSurface s   = vkvg_surface_create(device, test_width, test_height);
+    VkvgContext ctx = vkvg_create(s);
+    vkvg_clear(ctx);
+    for (uint32_t i = 0; i < test_size / THREAD_COUNT; i++) {
+        randomize_color(ctx);
+        float x = rndf() * test_width;
+        float y = rndf() * test_height;
+        vkvg_select_font_face(ctx, "mono");
+        vkvg_set_font_size(ctx, 20);
+        vkvg_move_to(ctx, x, y);
+        vkvg_show_text(ctx, "This is a test string!");
+    }
+    vkvg_destroy(ctx);
+
+    mtx_lock(pmutex);
+
+    ctx = vkvg_create(surf);
+    vkvg_set_source_surface(ctx, s, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
+
+    finishedThreadCount++;
+    mtx_unlock(pmutex);
+
+    vkvg_surface_destroy(s);
+    return 0;
 }
-void threaded_text(int(*testfunc)(void*)){
-       mtx_t mutex;
-       pmutex = &mutex;
+void threaded_text(int (*testfunc)(void *)) {
+    mtx_t mutex;
+    pmutex = &mutex;
 
-       vkvg_device_set_thread_aware (device, 1);
+    vkvg_device_set_thread_aware(device, 1);
 
-       thrd_t threads[THREAD_COUNT];
+    thrd_t threads[THREAD_COUNT];
 
-       finishedThreadCount = 0;
-       mtx_init (pmutex, mtx_plain);
-       for (uint32_t i=0; i<THREAD_COUNT; i++)
-               thrd_create (&threads[i], testfunc, NULL);
+    finishedThreadCount = 0;
+    mtx_init(pmutex, mtx_plain);
+    for (uint32_t i = 0; i < THREAD_COUNT; i++)
+        thrd_create(&threads[i], testfunc, NULL);
 
-       const struct timespec ts = {1,0};
-       while (finishedThreadCount < THREAD_COUNT)
-               thrd_sleep(&ts, NULL);
+    const struct timespec ts = {1, 0};
+    while (finishedThreadCount < THREAD_COUNT)
+        thrd_sleep(&ts, NULL);
 
-       mtx_lock(pmutex);
-       mtx_unlock(pmutex);
-       mtx_destroy (pmutex);
-       pmutex = NULL;
+    mtx_lock(pmutex);
+    mtx_unlock(pmutex);
+    mtx_destroy(pmutex);
+    pmutex = NULL;
 
-       vkvg_device_set_thread_aware (device, 0);
-}
-void single_font_and_size() {
-       threaded_text (_single_font_and_size);
+    vkvg_device_set_thread_aware(device, 0);
 }
+void single_font_and_size() { threaded_text(_single_font_and_size); }
 
 int main(int argc, char *argv[]) {
-       PERFORM_TEST (single_font_and_size, argc, argv);
-       return 0;
+    PERFORM_TEST(single_font_and_size, argc, argv);
+    return 0;
 }
index 895d1e0d4ab3f4f15c6a600d3d0af5ae1d6276aa..55fde1041acfa3fda65f8b3b82e152d01226ddfa 100644 (file)
@@ -1,23 +1,21 @@
 #include "vkvg.h"
 
 int main(int argc, char *argv[]) {
-    vkvg_device_create_info_t info = {
-        VK_SAMPLE_COUNT_1_BIT, false
-    };
-    VkvgDevice dev = vkvg_device_create(&info);
-       VkvgSurface surf = vkvg_surface_create(dev, 512,512);
-       VkvgContext ctx = vkvg_create(surf);
+    vkvg_device_create_info_t info = {VK_SAMPLE_COUNT_1_BIT, false};
+    VkvgDevice                dev  = vkvg_device_create(&info);
+    VkvgSurface               surf = vkvg_surface_create(dev, 512, 512);
+    VkvgContext               ctx  = vkvg_create(surf);
 
-       vkvg_clear(ctx);
-       vkvg_rectangle(ctx, 10, 10, 250, 200);
-       vkvg_set_source_rgb(ctx, 1, 0, 0);
-       vkvg_fill(ctx);
+    vkvg_clear(ctx);
+    vkvg_rectangle(ctx, 10, 10, 250, 200);
+    vkvg_set_source_rgb(ctx, 1, 0, 0);
+    vkvg_fill(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 
-       vkvg_surface_write_to_png(surf, "offscreen.png");
-       vkvg_surface_destroy(surf);
+    vkvg_surface_write_to_png(surf, "offscreen.png");
+    vkvg_surface_destroy(surf);
 
-       vkvg_device_destroy(dev);
-       return 0;
+    vkvg_device_destroy(dev);
+    return 0;
 }
index 996c4104034f3e66e4dd628ac8547cd72e6bc34c..211d1e62b2c7199b2097cd1cfc5a942797a6caaf 100644 (file)
 
 float lineWidth = 10.f;
 
-VkvgSurface createSurf (uint32_t width, uint32_t height) {
-       VkvgSurface s = vkvg_surface_create(device, width, height);
-       VkvgContext ctx = vkvg_create (s);
-       vkvg_set_line_width(ctx,lineWidth);
-       float hlw = lineWidth/2.f;
-       /*
-       vkvg_set_source_rgba(ctx,0,1,0,0.5);
-       vkvg_fill_preserve(ctx);*/
-       vkvg_set_source_rgba(ctx,1,0,0,0.5);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgba(ctx,0,0,1,0.5);
-       vkvg_rectangle(ctx,hlw,hlw,(float)width-lineWidth,(float)height-lineWidth);
-       vkvg_stroke(ctx);
-       vkvg_destroy(ctx);
-       return s;
+VkvgSurface createSurf(uint32_t width, uint32_t height) {
+    VkvgSurface s   = vkvg_surface_create(device, width, height);
+    VkvgContext ctx = vkvg_create(s);
+    vkvg_set_line_width(ctx, lineWidth);
+    float hlw = lineWidth / 2.f;
+    /*
+    vkvg_set_source_rgba(ctx,0,1,0,0.5);
+    vkvg_fill_preserve(ctx);*/
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 0.5);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgba(ctx, 0, 0, 1, 0.5);
+    vkvg_rectangle(ctx, hlw, hlw, (float)width - lineWidth, (float)height - lineWidth);
+    vkvg_stroke(ctx);
+    vkvg_destroy(ctx);
+    return s;
 }
 
-void paint(){
-       VkvgSurface src = createSurf(256,256);
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_set_source_surface(ctx, src, 0, 0);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
-       vkvg_surface_destroy(src);
+void paint() {
+    VkvgSurface src = createSurf(256, 256);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_source_surface(ctx, src, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
+    vkvg_surface_destroy(src);
 }
-void paint_with_offset(){
-       VkvgSurface src = createSurf(256,256);
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_set_source_rgba(ctx,0,1,0,0.5);
-       vkvg_paint(ctx);
-       vkvg_set_source_surface(ctx, src, 100, 100);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
-       vkvg_surface_destroy(src);
+void paint_with_offset() {
+    VkvgSurface src = createSurf(256, 256);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_source_rgba(ctx, 0, 1, 0, 0.5);
+    vkvg_paint(ctx);
+    vkvg_set_source_surface(ctx, src, 100, 100);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
+    vkvg_surface_destroy(src);
 }
-void paint_multiple(){
-       VkvgSurface src = createSurf(256,256);
-       VkvgContext ctx = _initCtx(surf);
-       for(int i=0;i<10;i++) {
-               vkvg_set_source_surface(ctx, src, i * 20, i * 20);
-               vkvg_paint(ctx);
-       }
-       vkvg_destroy(ctx);
-       vkvg_surface_destroy(src);
+void paint_multiple() {
+    VkvgSurface src = createSurf(256, 256);
+    VkvgContext ctx = _initCtx(surf);
+    for (int i = 0; i < 10; i++) {
+        vkvg_set_source_surface(ctx, src, i * 20, i * 20);
+        vkvg_paint(ctx);
+    }
+    vkvg_destroy(ctx);
+    vkvg_surface_destroy(src);
 }
-void paint_with_rotation(){
-       VkvgSurface src = createSurf(256,256);
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_set_source_surface(ctx, src, 0, 0);
-       vkvg_rotate(ctx, 45);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
-       vkvg_surface_destroy(src);
+void paint_with_rotation() {
+    VkvgSurface src = createSurf(256, 256);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_source_surface(ctx, src, 0, 0);
+    vkvg_rotate(ctx, 45);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
+    vkvg_surface_destroy(src);
 }
-void paint_with_scale(){
-       VkvgSurface src = createSurf(256,256);
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_set_source_surface(ctx, src, 0, 0);
-       vkvg_scale (ctx, 0.2f,0.2f);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
-       vkvg_surface_destroy(src);
+void paint_with_scale() {
+    VkvgSurface src = createSurf(256, 256);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_source_surface(ctx, src, 0, 0);
+    vkvg_scale(ctx, 0.2f, 0.2f);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
+    vkvg_surface_destroy(src);
 }
-void paint_rect(){
-       VkvgSurface src = createSurf(256,256);
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_set_source_surface(ctx, src, 0, 0);
-       vkvg_rectangle(ctx,100,100,300,200);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
-       vkvg_surface_destroy(src);
+void paint_rect() {
+    VkvgSurface src = createSurf(256, 256);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_source_surface(ctx, src, 0, 0);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
+    vkvg_surface_destroy(src);
 }
-//TODO:test failed: full screen paint instead of rotated rect
-void paint_rect_with_rotation(){
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_rotate(ctx, 45);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_rectangle(ctx,100,100,300,200);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+// TODO:test failed: full screen paint instead of rotated rect
+void paint_rect_with_rotation() {
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_rotate(ctx, 45);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
-void paint_rect_with_scale(){
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_scale (ctx, 0.2f,0.2f);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_rectangle(ctx,100,100,300,200);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+void paint_rect_with_scale() {
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_scale(ctx, 0.2f, 0.2f);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (paint, argc, argv);
-       PERFORM_TEST (paint_with_offset, argc, argv);
-       PERFORM_TEST (paint_multiple, argc, argv);
-       PERFORM_TEST (paint_with_rotation, argc, argv);
-       PERFORM_TEST (paint_with_scale, argc, argv);
-       PERFORM_TEST (paint_rect, argc, argv);
-       PERFORM_TEST (paint_rect_with_rotation, argc, argv);
-       PERFORM_TEST (paint_rect_with_scale, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(paint, argc, argv);
+    PERFORM_TEST(paint_with_offset, argc, argv);
+    PERFORM_TEST(paint_multiple, argc, argv);
+    PERFORM_TEST(paint_with_rotation, argc, argv);
+    PERFORM_TEST(paint_with_scale, argc, argv);
+    PERFORM_TEST(paint_rect, argc, argv);
+    PERFORM_TEST(paint_rect_with_rotation, argc, argv);
+    PERFORM_TEST(paint_rect_with_scale, argc, argv);
+    return 0;
 }
index 55c69de4db607ea668b47dde174bf5a28df3f639..8a31e01caecd5ca480d1d68215182107c233b29c 100644 (file)
 #include "test.h"
 #include "vectors.h"
 
-vkvg_fill_rule_t fillrule = VKVG_FILL_RULE_NON_ZERO;
-static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT;
-float lineWidth = 4.0f;
-vkvg_line_join_t lineJoin = VKVG_LINE_JOIN_MITER;
-vkvg_line_cap_t lineCap = VKVG_LINE_CAP_BUTT;
-bool isClosed = false, refresh = true;
-bool startWithArc = false, endWithArc = false;
-
-int ptsCount = 0;
-vec2 pts[1024];
-int hoverPt = -1;
+vkvg_fill_rule_t          fillrule  = VKVG_FILL_RULE_NON_ZERO;
+static VkSampleCountFlags samples   = VK_SAMPLE_COUNT_8_BIT;
+float                     lineWidth = 4.0f;
+vkvg_line_join_t          lineJoin  = VKVG_LINE_JOIN_MITER;
+vkvg_line_cap_t           lineCap   = VKVG_LINE_CAP_BUTT;
+bool                      isClosed = false, refresh = true;
+bool                      startWithArc = false, endWithArc = false;
+
+int    ptsCount = 0;
+vec2   pts[1024];
+int    hoverPt   = -1;
 double pointSize = 7;
-float _dashes[] = {5.0f,3.0f};
-int _ndashes = 2;
-
-void emit_path (VkvgContext ctx) {
-       vkvg_move_to(ctx,pts[0].x,pts[0].y);
-       for (int i=1; i<ptsCount; i++)
-               vkvg_line_to(ctx,pts[i].x,pts[i].y);
-       if (isClosed)
-               vkvg_close_path(ctx);
+float  _dashes[] = {5.0f, 3.0f};
+int    _ndashes  = 2;
+
+void emit_path(VkvgContext ctx) {
+    vkvg_move_to(ctx, pts[0].x, pts[0].y);
+    for (int i = 1; i < ptsCount; i++)
+        vkvg_line_to(ctx, pts[i].x, pts[i].y);
+    if (isClosed)
+        vkvg_close_path(ctx);
 }
 
-void draw (){
-       refresh = false;
-
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_set_line_width     (ctx,lineWidth);
-       vkvg_set_line_join      (ctx, lineJoin);
-       vkvg_set_line_cap       (ctx, lineCap);
-
-       emit_path(ctx);
-       float x1, y1, x2, y2;
-       vkvg_path_extents(ctx, &x1, &y1, &x2, &y2);
-       vkvg_set_source_rgba(ctx,0.2,0.2,1,0.5);
-       if (hoverPt>=0) {
-               if (isClosed)
-                       vkvg_fill_preserve(ctx);
-               vkvg_set_source_rgba(ctx,1,0.2,0.2,0.5);
-               vkvg_stroke_preserve(ctx);
-               vkvg_set_dash(ctx, NULL, 0, 0);
-               vkvg_set_line_width(ctx,1);
-               vkvg_set_source_rgba(ctx,0,0,0,1);
-               vkvg_stroke(ctx);
-               vkvg_set_source_rgba(ctx,0.5f,0.5f,1.0f,0.7f);
-               vkvg_arc (ctx, pts[hoverPt].x, pts[hoverPt].y, pointSize, 0, M_PIF*2);
-               vkvg_fill_preserve(ctx);
-               vkvg_stroke(ctx);
-       } else {
-               if (isClosed)
-                       vkvg_fill_preserve(ctx);
-               vkvg_set_source_rgba(ctx,1,0.2,0.2,0.5);
-               vkvg_stroke(ctx);
-       }
-
-       vkvg_rectangle(ctx, x1, y1, x2 - x1, y2 - y1);
-       vkvg_set_dash(ctx, _dashes, _ndashes, 0);
-       vkvg_set_line_width(ctx,1);
-       vkvg_set_source_rgba(ctx,0,1,0,1);
-       vkvg_stroke(ctx);
-
-       vkvg_destroy(ctx);
+void draw() {
+    refresh = false;
+
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_set_line_width(ctx, lineWidth);
+    vkvg_set_line_join(ctx, lineJoin);
+    vkvg_set_line_cap(ctx, lineCap);
+
+    emit_path(ctx);
+    float x1, y1, x2, y2;
+    vkvg_path_extents(ctx, &x1, &y1, &x2, &y2);
+    vkvg_set_source_rgba(ctx, 0.2, 0.2, 1, 0.5);
+    if (hoverPt >= 0) {
+        if (isClosed)
+            vkvg_fill_preserve(ctx);
+        vkvg_set_source_rgba(ctx, 1, 0.2, 0.2, 0.5);
+        vkvg_stroke_preserve(ctx);
+        vkvg_set_dash(ctx, NULL, 0, 0);
+        vkvg_set_line_width(ctx, 1);
+        vkvg_set_source_rgba(ctx, 0, 0, 0, 1);
+        vkvg_stroke(ctx);
+        vkvg_set_source_rgba(ctx, 0.5f, 0.5f, 1.0f, 0.7f);
+        vkvg_arc(ctx, pts[hoverPt].x, pts[hoverPt].y, pointSize, 0, M_PIF * 2);
+        vkvg_fill_preserve(ctx);
+        vkvg_stroke(ctx);
+    } else {
+        if (isClosed)
+            vkvg_fill_preserve(ctx);
+        vkvg_set_source_rgba(ctx, 1, 0.2, 0.2, 0.5);
+        vkvg_stroke(ctx);
+    }
+
+    vkvg_rectangle(ctx, x1, y1, x2 - x1, y2 - y1);
+    vkvg_set_dash(ctx, _dashes, _ndashes, 0);
+    vkvg_set_line_width(ctx, 1);
+    vkvg_set_source_rgba(ctx, 0, 1, 0, 1);
+    vkvg_stroke(ctx);
+
+    vkvg_destroy(ctx);
 }
-static void key_callback(GLFWwindowwindow, int key, int scancode, int action, int mods) {
-       if (action != GLFW_PRESS)
-               return;
-       switch (key) {
-       case GLFW_KEY_ESCAPE :
-               glfwSetWindowShouldClose(window, GLFW_TRUE);
-               break;
-       case GLFW_KEY_W :
-               isClosed ^= true;
-               break;
-       case GLFW_KEY_DELETE :
-               ptsCount = 0;
-               break;
-       case GLFW_KEY_J :
-               lineJoin++;
-               if (lineJoin > 2)
-                       lineJoin = 0;
-               break;
-       case GLFW_KEY_C :
-               lineCap++;
-               if (lineCap > 2)
-                       lineCap = 0;
-               break;
-       case GLFW_KEY_KP_SUBTRACT :
-               if (ptsCount > 1)
-                       ptsCount--;
-               break;
-       }
-       refresh = true;
+static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
+    if (action != GLFW_PRESS)
+        return;
+    switch (key) {
+    case GLFW_KEY_ESCAPE:
+        glfwSetWindowShouldClose(window, GLFW_TRUE);
+        break;
+    case GLFW_KEY_W:
+        isClosed ^= true;
+        break;
+    case GLFW_KEY_DELETE:
+        ptsCount = 0;
+        break;
+    case GLFW_KEY_J:
+        lineJoin++;
+        if (lineJoin > 2)
+            lineJoin = 0;
+        break;
+    case GLFW_KEY_C:
+        lineCap++;
+        if (lineCap > 2)
+            lineCap = 0;
+        break;
+    case GLFW_KEY_KP_SUBTRACT:
+        if (ptsCount > 1)
+            ptsCount--;
+        break;
+    }
+    refresh = true;
 }
 static vec2 mousePos;
-static void mouse_move_callback(GLFWwindow* window, double x, double y){
-       mousePos = (vec2) {x, y};
-       if (mouseDown) {
-               if (hoverPt < 0)
-                       return;
-               pts[hoverPt] = mousePos;
-               refresh = true;
-       } else {
-               for (int i=0; i<ptsCount; i++) {
-                       if (x > pts[i].x - pointSize &&
-                               x < pts[i].x + pointSize &&
-                               y > pts[i].y - pointSize &&
-                               y < pts[i].y + pointSize) {
-                               hoverPt = i;
-                               refresh = true;
-                               return;
-                       }
-               }
-               refresh = true;
-               hoverPt = -1;
-       }
+static void mouse_move_callback(GLFWwindow *window, double x, double y) {
+    mousePos = (vec2){x, y};
+    if (mouseDown) {
+        if (hoverPt < 0)
+            return;
+        pts[hoverPt] = mousePos;
+        refresh      = true;
+    } else {
+        for (int i = 0; i < ptsCount; i++) {
+            if (x > pts[i].x - pointSize && x < pts[i].x + pointSize && y > pts[i].y - pointSize &&
+                y < pts[i].y + pointSize) {
+                hoverPt = i;
+                refresh = true;
+                return;
+            }
+        }
+        refresh = true;
+        hoverPt = -1;
+    }
 }
-static void scroll_callback(GLFWwindow* window, double x, double y){
-       if (y<0.f)
-               zoom *= 0.5f;
-       else
-               zoom *= 2.0f;
+static void scroll_callback(GLFWwindow *window, double x, double y) {
+    if (y < 0.f)
+        zoom *= 0.5f;
+    else
+        zoom *= 2.0f;
 }
-static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){
-       if (but != GLFW_MOUSE_BUTTON_1)
-               return;
-       if (state == GLFW_TRUE)
-               mouseDown = true;
-       else
-               mouseDown = false;
-       if (state == GLFW_TRUE && hoverPt < 0)
-               pts[ptsCount++] = mousePos;
-       refresh = true;
+static void mouse_button_callback(GLFWwindow *window, int but, int state, int modif) {
+    if (but != GLFW_MOUSE_BUTTON_1)
+        return;
+    if (state == GLFW_TRUE)
+        mouseDown = true;
+    else
+        mouseDown = false;
+    if (state == GLFW_TRUE && hoverPt < 0)
+        pts[ptsCount++] = mousePos;
+    refresh = true;
 }
 
+int main(int argc, char *argv[]) {
 
+    _parse_args(argc, argv);
+    VkEngine e;
+    e = vkengine_create(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
 
-int main(int argc, char* argv[]) {
+    VkhPresenter r = e->renderer;
+    vkengine_set_key_callback(e, key_callback);
+    vkengine_set_mouse_but_callback(e, mouse_button_callback);
+    vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+    vkengine_set_scroll_callback(e, scroll_callback);
 
-       _parse_args (argc, argv);
-       VkEngine e;
-       e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
+    vkvg_device_create_info_t info = {samples, false, vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0};
+    device                         = vkvg_device_create(&info);
+    surf                           = vkvg_surface_create(device, test_width, test_height);
 
-       VkhPresenter r = e->renderer;
-       vkengine_set_key_callback (e, key_callback);
-       vkengine_set_mouse_but_callback(e, mouse_button_callback);
-       vkengine_set_cursor_pos_callback(e, mouse_move_callback);
-       vkengine_set_scroll_callback(e, scroll_callback);
+    vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
 
-    vkvg_device_create_info_t info = {
-        samples,
-        false,
-        vkh_app_get_inst(e->app),
-        r->dev->phy,
-        r->dev->dev,
-        r->qFam,
-        0
-    };
-    device = vkvg_device_create(&info);
-       surf = vkvg_surface_create(device, test_width, test_height);
+    while (!vkengine_should_close(e)) {
+        glfwPollEvents();
 
-       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+        if (refresh)
+            draw();
 
-       while (!vkengine_should_close (e)) {
-               glfwPollEvents();
+        if (!vkh_presenter_draw(r)) {
+            vkh_presenter_get_size(r, &test_width, &test_height);
+            vkvg_surface_destroy(surf);
+            surf = vkvg_surface_create(device, test_width, test_height);
+            vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+            vkDeviceWaitIdle(r->dev->dev);
+            continue;
+        }
+    }
+    vkDeviceWaitIdle(e->dev->dev);
 
-               if (refresh)
-                       draw ();
+    vkvg_surface_destroy(surf);
 
-               if (!vkh_presenter_draw (r)){
-                       vkh_presenter_get_size (r, &test_width, &test_height);
-                       vkvg_surface_destroy (surf);
-                       surf = vkvg_surface_create(device, test_width, test_height);
-                       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
-                       vkDeviceWaitIdle(r->dev->dev);
-                       continue;
-               }
-       }
-       vkDeviceWaitIdle(e->dev->dev);
+    vkvg_device_destroy(device);
 
-       vkvg_surface_destroy    (surf);
+    vkengine_destroy(e);
 
-       vkvg_device_destroy     (device);
-
-       vkengine_destroy (e);
-
-       return 0;
+    return 0;
 }
index 18e528af87aebd03f02f3f723061df3a58583b9d..58651c9517475497469a583427fffc6b1bcbb371 100644 (file)
@@ -1,93 +1,93 @@
 #include "test.h"
 
-float lineWidth = 10.f;
-const char* imgPath = "data/miroir.jpg";
-
-VkvgPattern create_grad (VkvgContext ctx) {
-       VkvgPattern pat = vkvg_pattern_create_linear(0,0,200,0);
-       vkvg_pattern_add_color_stop(pat,   0, 1, 0, 0, 1);
-       vkvg_pattern_add_color_stop(pat, 0.5, 0, 1, 0, 1);
-       vkvg_pattern_add_color_stop(pat, 1.0, 0, 0, 1, 1);
-       return pat;
+float       lineWidth = 10.f;
+const char *imgPath   = "data/miroir.jpg";
+
+VkvgPattern create_grad(VkvgContext ctx) {
+    VkvgPattern pat = vkvg_pattern_create_linear(0, 0, 200, 0);
+    vkvg_pattern_add_color_stop(pat, 0, 1, 0, 0, 1);
+    vkvg_pattern_add_color_stop(pat, 0.5, 0, 1, 0, 1);
+    vkvg_pattern_add_color_stop(pat, 1.0, 0, 0, 1, 1);
+    return pat;
 }
 
-VkvgSurface createSurf (uint32_t width, uint32_t height) {
-       VkvgSurface s = vkvg_surface_create(device, width, height);
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_set_line_width(ctx,lineWidth);
-       float hlw = lineWidth/2.f;
-       /*
-       vkvg_set_source_rgba(ctx,0,1,0,0.5);
-       vkvg_fill_preserve(ctx);*/
-       vkvg_set_source_rgba(ctx,1,0,0,0.5);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgba(ctx,0,0,1,0.5);
-       vkvg_rectangle(ctx,hlw,hlw,(float)width-lineWidth,(float)height-lineWidth);
-       vkvg_stroke(ctx);
-       vkvg_destroy(ctx);
-       return s;
+VkvgSurface createSurf(uint32_t width, uint32_t height) {
+    VkvgSurface s   = vkvg_surface_create(device, width, height);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_line_width(ctx, lineWidth);
+    float hlw = lineWidth / 2.f;
+    /*
+    vkvg_set_source_rgba(ctx,0,1,0,0.5);
+    vkvg_fill_preserve(ctx);*/
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 0.5);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgba(ctx, 0, 0, 1, 0.5);
+    vkvg_rectangle(ctx, hlw, hlw, (float)width - lineWidth, (float)height - lineWidth);
+    vkvg_stroke(ctx);
+    vkvg_destroy(ctx);
+    return s;
 }
 
 void img_scale() {
-       VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
-       VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf);
-       VkvgContext ctx = _initCtx(surf);
-
-       vkvg_translate(ctx, 100,100);
-
-       vkvg_matrix_t mat;
-       vkvg_matrix_init_scale(&mat, 2.0, 2.0);
-       vkvg_pattern_set_matrix (pat, &mat);
-
-       vkvg_set_source (ctx, pat);
-       vkvg_rectangle(ctx, 0 , 0, 200, 140);
-       vkvg_fill(ctx);
-       vkvg_destroy(ctx);
-       vkvg_pattern_destroy(pat);
-       vkvg_surface_destroy(imgSurf);
+    VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
+    VkvgPattern pat     = vkvg_pattern_create_for_surface(imgSurf);
+    VkvgContext ctx     = _initCtx(surf);
+
+    vkvg_translate(ctx, 100, 100);
+
+    vkvg_matrix_t mat;
+    vkvg_matrix_init_scale(&mat, 2.0, 2.0);
+    vkvg_pattern_set_matrix(pat, &mat);
+
+    vkvg_set_source(ctx, pat);
+    vkvg_rectangle(ctx, 0, 0, 200, 140);
+    vkvg_fill(ctx);
+    vkvg_destroy(ctx);
+    vkvg_pattern_destroy(pat);
+    vkvg_surface_destroy(imgSurf);
 }
 
-void pat_scale(){
+void pat_scale() {
 
-       VkvgContext ctx = _initCtx(surf);
-       VkvgPattern pat = create_grad(ctx);
+    VkvgContext ctx = _initCtx(surf);
+    VkvgPattern pat = create_grad(ctx);
 
-       vkvg_translate(ctx, 100,100);
+    vkvg_translate(ctx, 100, 100);
 
-       vkvg_matrix_t mat;
-       vkvg_matrix_init_scale(&mat, 0.5, 0.5);
-       vkvg_pattern_set_matrix (pat, &mat);
+    vkvg_matrix_t mat;
+    vkvg_matrix_init_scale(&mat, 0.5, 0.5);
+    vkvg_pattern_set_matrix(pat, &mat);
 
-       vkvg_set_source (ctx, pat);
-       vkvg_rectangle(ctx, 0 , 0, 200, 140);
-       vkvg_fill(ctx);
-       vkvg_destroy(ctx);
-       vkvg_pattern_destroy(pat);
+    vkvg_set_source(ctx, pat);
+    vkvg_rectangle(ctx, 0, 0, 200, 140);
+    vkvg_fill(ctx);
+    vkvg_destroy(ctx);
+    vkvg_pattern_destroy(pat);
 }
 static float angle = 0;
-void pat_rotate(){
-       angle += 0.001f;
+void         pat_rotate() {
+    angle += 0.001f;
 
-       VkvgContext ctx = _initCtx(surf);
-       VkvgPattern pat = create_grad(ctx);
+    VkvgContext ctx = _initCtx(surf);
+    VkvgPattern pat = create_grad(ctx);
 
-       //vkvg_translate(ctx, 100,100);
+    // vkvg_translate(ctx, 100,100);
 
-       vkvg_matrix_t mat;
-       vkvg_matrix_init_translate(&mat, 100, 70);
-       vkvg_matrix_rotate(&mat, angle);
-       vkvg_pattern_set_matrix (pat, &mat);
+    vkvg_matrix_t mat;
+    vkvg_matrix_init_translate(&mat, 100, 70);
+    vkvg_matrix_rotate(&mat, angle);
+    vkvg_pattern_set_matrix(pat, &mat);
 
-       vkvg_set_source (ctx, pat);
-       vkvg_rectangle(ctx, 0 , 0, 200, 140);
-       vkvg_fill(ctx);
-       vkvg_destroy(ctx);
-       vkvg_pattern_destroy(pat);
+    vkvg_set_source(ctx, pat);
+    vkvg_rectangle(ctx, 0, 0, 200, 140);
+    vkvg_fill(ctx);
+    vkvg_destroy(ctx);
+    vkvg_pattern_destroy(pat);
 }
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (pat_scale, argc, argv);
-       PERFORM_TEST (pat_rotate, argc, argv);
-       PERFORM_TEST (img_scale, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(pat_scale, argc, argv);
+    PERFORM_TEST(pat_rotate, argc, argv);
+    PERFORM_TEST(img_scale, argc, argv);
+    return 0;
 }
index e5b1dc4062dff8b058ef2fbe88b03efc7fab821b..4762b5efd97f71d1647c204e4e34ce3c66df2f4e 100644 (file)
@@ -1,25 +1,25 @@
 #include "test.h"
 
-void drawRandomRect (VkvgContext ctx, float s) {
-       float w = (float)test_width;
-       float h = (float)test_height;
-       randomize_color(ctx);
+void drawRandomRect(VkvgContext ctx, float s) {
+    float w = (float)test_width;
+    float h = (float)test_height;
+    randomize_color(ctx);
 
-       float x = truncf(w*rndf());
-       float y = truncf(h*rndf());
+    float x = truncf(w * rndf());
+    float y = truncf(h * rndf());
 
-       vkvg_rectangle(ctx, x, y, s, s);
+    vkvg_rectangle(ctx, x, y, s, s);
 }
-void fixedSizeRects(){
-       VkvgContext ctx = _initCtx ();
-       for (uint32_t i=0; i<test_size; i++) {
-               drawRandomRect(ctx, 50.0f);
-               vkvg_fill (ctx);
-       }
-       vkvg_destroy(ctx);
+void fixedSizeRects() {
+    VkvgContext ctx = _initCtx();
+    for (uint32_t i = 0; i < test_size; i++) {
+        drawRandomRect(ctx, 50.0f);
+        vkvg_fill(ctx);
+    }
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-    PERFORM_TEST (fixedSizeRects, argc, argv);
-       return 0;
+    PERFORM_TEST(fixedSizeRects, argc, argv);
+    return 0;
 }
index a20f360ea89363b04429691bbd8c657bcca4e8f3..b535b68ad1f27fb587daa8a7f0df5d691fb4f3a7 100644 (file)
 #include "test.h"
 
 /*void drawRandomRect (VkvgContext ctx) {
-       float w = (float)test_width;
-       float h = (float)test_height;
-       randomize_color(ctx);
+    float w = (float)test_width;
+    float h = (float)test_height;
+    randomize_color(ctx);
 
-       float z = truncf((0.5f*w*rand()/RAND_MAX)+1.f);
-       float v = truncf((0.5f*w*rand()/RAND_MAX)+1.f);
-       float x = truncf((w-z)*rand()/RAND_MAX);
-       float y = truncf((h-v)*rand()/RAND_MAX);
+    float z = truncf((0.5f*w*rand()/RAND_MAX)+1.f);
+    float v = truncf((0.5f*w*rand()/RAND_MAX)+1.f);
+    float x = truncf((w-z)*rand()/RAND_MAX);
+    float y = truncf((h-v)*rand()/RAND_MAX);
 
-       vkvg_rectangle(ctx, x, y, z, v);
+    vkvg_rectangle(ctx, x, y, z, v);
 }*/
 static float shape_size = 0.2f;
 
-void _shape_fill(shape_t shape){
-       VkvgContext ctx = _initCtx ();
-       for (uint32_t i=0; i<test_size; i++) {
-               draw_random_shape(ctx, shape, shape_size);
-               vkvg_fill(ctx);
-       }
-       vkvg_destroy(ctx);
-}
-void _shape_stroke(shape_t shape){
-       VkvgContext ctx = _initCtx ();
-       for (uint32_t i=0; i<test_size; i++) {
-               draw_random_shape(ctx, shape, shape_size);
-               vkvg_stroke (ctx);
-       }
-       vkvg_destroy(ctx);
-}
-void _shape_fill_stroke(shape_t shape){
-       VkvgContext ctx = _initCtx ();
+void _shape_fill(shape_t shape) {
+    VkvgContext ctx = _initCtx();
+    for (uint32_t i = 0; i < test_size; i++) {
+        draw_random_shape(ctx, shape, shape_size);
+        vkvg_fill(ctx);
+    }
+    vkvg_destroy(ctx);
+}
+void _shape_stroke(shape_t shape) {
+    VkvgContext ctx = _initCtx();
+    for (uint32_t i = 0; i < test_size; i++) {
+        draw_random_shape(ctx, shape, shape_size);
+        vkvg_stroke(ctx);
+    }
+    vkvg_destroy(ctx);
+}
+void _shape_fill_stroke(shape_t shape) {
+    VkvgContext ctx = _initCtx();
 
-       for (uint32_t i=0; i<test_size; i++) {
-               draw_random_shape(ctx, shape, shape_size);
-               vkvg_fill_preserve(ctx);
-               vkvg_stroke(ctx);
-       }
-       vkvg_destroy(ctx);
+    for (uint32_t i = 0; i < test_size; i++) {
+        draw_random_shape(ctx, shape, shape_size);
+        vkvg_fill_preserve(ctx);
+        vkvg_stroke(ctx);
+    }
+    vkvg_destroy(ctx);
 }
 
-void rectangles_fill () {
-       _shape_fill(SHAPE_RECTANGLE);
-}
-void rectangles_stroke () {
-       _shape_stroke(SHAPE_RECTANGLE);
-}
-void rectangles_fill_stroke () {
-       _shape_fill_stroke(SHAPE_RECTANGLE);
-}
-void rounded_rects_fill () {
-       _shape_fill(SHAPE_ROUNDED_RECTANGLE);
-}
-void rounded_rects_stroke () {
-       _shape_stroke(SHAPE_ROUNDED_RECTANGLE);
-}
-void rounded_rects_fill_stroke () {
-       _shape_fill_stroke(SHAPE_ROUNDED_RECTANGLE);
-}
-void circles_fill () {
-       _shape_fill(SHAPE_CIRCLE);
-}
-void circles_stroke () {
-       _shape_stroke(SHAPE_CIRCLE);
-}
-void circles_fill_stroke () {
-       _shape_fill_stroke(SHAPE_CIRCLE);
-}
-void stars_fill () {
-       _shape_fill(SHAPE_STAR);
-}
-void stars_stroke () {
-       _shape_stroke(SHAPE_STAR);
-}
-void stars_fill_stroke () {
-       _shape_fill_stroke(SHAPE_STAR);
-}
-void random_fill () {
-       _shape_fill(SHAPE_RANDOM);
-}
-void random_stroke () {
-       _shape_stroke(SHAPE_RANDOM);
-}
-void random_fill_stroke () {
-       _shape_fill_stroke(SHAPE_RANDOM);
-}
+void rectangles_fill() { _shape_fill(SHAPE_RECTANGLE); }
+void rectangles_stroke() { _shape_stroke(SHAPE_RECTANGLE); }
+void rectangles_fill_stroke() { _shape_fill_stroke(SHAPE_RECTANGLE); }
+void rounded_rects_fill() { _shape_fill(SHAPE_ROUNDED_RECTANGLE); }
+void rounded_rects_stroke() { _shape_stroke(SHAPE_ROUNDED_RECTANGLE); }
+void rounded_rects_fill_stroke() { _shape_fill_stroke(SHAPE_ROUNDED_RECTANGLE); }
+void circles_fill() { _shape_fill(SHAPE_CIRCLE); }
+void circles_stroke() { _shape_stroke(SHAPE_CIRCLE); }
+void circles_fill_stroke() { _shape_fill_stroke(SHAPE_CIRCLE); }
+void stars_fill() { _shape_fill(SHAPE_STAR); }
+void stars_stroke() { _shape_stroke(SHAPE_STAR); }
+void stars_fill_stroke() { _shape_fill_stroke(SHAPE_STAR); }
+void random_fill() { _shape_fill(SHAPE_RANDOM); }
+void random_stroke() { _shape_stroke(SHAPE_RANDOM); }
+void random_fill_stroke() { _shape_fill_stroke(SHAPE_RANDOM); }
 
 int main(int argc, char *argv[]) {
-       PERFORM_TEST (rectangles_fill, argc, argv);
-       PERFORM_TEST (rectangles_stroke, argc, argv);
-       PERFORM_TEST (rectangles_fill_stroke, argc, argv);
+    PERFORM_TEST(rectangles_fill, argc, argv);
+    PERFORM_TEST(rectangles_stroke, argc, argv);
+    PERFORM_TEST(rectangles_fill_stroke, argc, argv);
 
-       PERFORM_TEST (rounded_rects_fill, argc, argv);
-       PERFORM_TEST (rounded_rects_stroke, argc, argv);
-       PERFORM_TEST (rounded_rects_fill_stroke, argc, argv);
+    PERFORM_TEST(rounded_rects_fill, argc, argv);
+    PERFORM_TEST(rounded_rects_stroke, argc, argv);
+    PERFORM_TEST(rounded_rects_fill_stroke, argc, argv);
 
-       PERFORM_TEST (circles_fill, argc, argv);
-       PERFORM_TEST (circles_stroke, argc, argv);
-       PERFORM_TEST (circles_fill_stroke, argc, argv);
+    PERFORM_TEST(circles_fill, argc, argv);
+    PERFORM_TEST(circles_stroke, argc, argv);
+    PERFORM_TEST(circles_fill_stroke, argc, argv);
 
-       PERFORM_TEST (stars_fill, argc, argv);
-       PERFORM_TEST (stars_stroke, argc, argv);
-       PERFORM_TEST (stars_fill_stroke, argc, argv);
+    PERFORM_TEST(stars_fill, argc, argv);
+    PERFORM_TEST(stars_stroke, argc, argv);
+    PERFORM_TEST(stars_fill_stroke, argc, argv);
 
-       PERFORM_TEST (random_fill, argc, argv);
-       PERFORM_TEST (random_stroke, argc, argv);
-       PERFORM_TEST (random_fill_stroke, argc, argv);
+    PERFORM_TEST(random_fill, argc, argv);
+    PERFORM_TEST(random_stroke, argc, argv);
+    PERFORM_TEST(random_fill_stroke, argc, argv);
 
-       return 0;
+    return 0;
 }
index 1986f11ee68c9e8de62d22c30c2bb70289ef7856..deaec5e2e8cf69aadb8204285be1df4e1b44c6d5 100644 (file)
@@ -1,22 +1,22 @@
 #include "test.h"
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
 
-       VkvgPattern radial = vkvg_pattern_create_radial (250.0f,250.0f,0,300,300,260.0f);
-       vkvg_pattern_add_color_stop(radial, 0.0,1,0,0,1);
-       vkvg_pattern_add_color_stop(radial, 0.5,0,1,0,1);
-       vkvg_pattern_add_color_stop(radial, 1.0,0,0,0,1);
-       vkvg_set_source(ctx, radial);
-       vkvg_paint(ctx);
-       vkvg_pattern_destroy(radial);
+    VkvgPattern radial = vkvg_pattern_create_radial(250.0f, 250.0f, 0, 300, 300, 260.0f);
+    vkvg_pattern_add_color_stop(radial, 0.0, 1, 0, 0, 1);
+    vkvg_pattern_add_color_stop(radial, 0.5, 0, 1, 0, 1);
+    vkvg_pattern_add_color_stop(radial, 1.0, 0, 0, 0, 1);
+    vkvg_set_source(ctx, radial);
+    vkvg_paint(ctx);
+    vkvg_pattern_destroy(radial);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
 
-       return 0;
+    return 0;
 }
index 495ec4ac97a0439e3bec95fc60a7e7ae82152095..4fdf22379c33291802ea5af144c0891f16981f11 100644 (file)
@@ -1,48 +1,47 @@
 #include "test.h"
 
 #if VKVG_RECORDING
-void test(){
-       VkvgContext ctx = _initCtx(surf);
-
-       vkvg_scale(ctx,0.5,0.5);
-       vkvg_start_recording(ctx);
-
-       vkvg_set_source_rgba(ctx,0.1f,0.9f,0.1f,1.0f);
-       vkvg_move_to(ctx,100,100);
-       vkvg_rel_line_to(ctx,50,200);
-       vkvg_rel_line_to(ctx,150,-100);
-       vkvg_rel_line_to(ctx,100,200);
-       vkvg_rel_line_to(ctx,-100,100);
-       vkvg_rel_line_to(ctx,-10,-100);
-       vkvg_rel_line_to(ctx,-190,-50);
-       vkvg_rel_line_to(ctx,300,50);
-       vkvg_rel_line_to(ctx,50,0);
-       vkvg_rel_line_to(ctx,0, 50);
-       vkvg_rel_line_to(ctx,50,0);
-       vkvg_rel_line_to(ctx,0, 50);
-       vkvg_rel_line_to(ctx,50,0);
-       vkvg_rel_line_to(ctx,0, 50);
-       vkvg_rel_line_to(ctx,50,0);
-       vkvg_rel_line_to(ctx,0, 50);
-       vkvg_close_path(ctx);
-
-       vkvg_stroke_preserve(ctx);
-       vkvg_fill(ctx);
-
-       VkvgRecording rec = vkvg_stop_recording(ctx);
-
-       vkvg_translate(ctx,400,0);
-       vkvg_replay(ctx, rec);
-
-       vkvg_destroy(ctx);
-       vkvg_recording_destroy(rec);
+void test() {
+    VkvgContext ctx = _initCtx(surf);
+
+    vkvg_scale(ctx, 0.5, 0.5);
+    vkvg_start_recording(ctx);
+
+    vkvg_set_source_rgba(ctx, 0.1f, 0.9f, 0.1f, 1.0f);
+    vkvg_move_to(ctx, 100, 100);
+    vkvg_rel_line_to(ctx, 50, 200);
+    vkvg_rel_line_to(ctx, 150, -100);
+    vkvg_rel_line_to(ctx, 100, 200);
+    vkvg_rel_line_to(ctx, -100, 100);
+    vkvg_rel_line_to(ctx, -10, -100);
+    vkvg_rel_line_to(ctx, -190, -50);
+    vkvg_rel_line_to(ctx, 300, 50);
+    vkvg_rel_line_to(ctx, 50, 0);
+    vkvg_rel_line_to(ctx, 0, 50);
+    vkvg_rel_line_to(ctx, 50, 0);
+    vkvg_rel_line_to(ctx, 0, 50);
+    vkvg_rel_line_to(ctx, 50, 0);
+    vkvg_rel_line_to(ctx, 0, 50);
+    vkvg_rel_line_to(ctx, 50, 0);
+    vkvg_rel_line_to(ctx, 0, 50);
+    vkvg_close_path(ctx);
+
+    vkvg_stroke_preserve(ctx);
+    vkvg_fill(ctx);
+
+    VkvgRecording rec = vkvg_stop_recording(ctx);
+
+    vkvg_translate(ctx, 400, 0);
+    vkvg_replay(ctx, rec);
+
+    vkvg_destroy(ctx);
+    vkvg_recording_destroy(rec);
 }
 #endif
 int main(int argc, char *argv[]) {
-       no_test_size = true;
+    no_test_size = true;
 #if VKVG_RECORDING
-       PERFORM_TEST (test, argc, argv);
+    PERFORM_TEST(test, argc, argv);
 #endif
-       return 0;
+    return 0;
 }
-
index 7959d34b908719b3c1a34026aaf943c863431ee4..be5997639d5263185f9d3d1c4a0bb2da27fd27b0 100644 (file)
@@ -1,39 +1,39 @@
 #include "test.h"
 
 void draw(VkvgContext ctx) {
-       vkvg_set_source_rgba(ctx,0,0,1,0.5);
-       vkvg_rectangle(ctx,100,100,200,200);
-       vkvg_fill(ctx);
+    vkvg_set_source_rgba(ctx, 0, 0, 1, 0.5);
+    vkvg_rectangle(ctx, 100, 100, 200, 200);
+    vkvg_fill(ctx);
 
-       vkvg_rectangle(ctx,200,200,200,200);
-       vkvg_set_source_rgba(ctx,1,0,0,0.5);
-       vkvg_fill(ctx);
+    vkvg_rectangle(ctx, 200, 200, 200, 200);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 0.5);
+    vkvg_fill(ctx);
 }
-void test(){
+void test() {
 
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_NON_ZERO);
 
-       draw(ctx);
+    draw(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
-void test_evenodd(){
+void test_evenodd() {
 
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
 
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
 
-       draw(ctx);
+    draw(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
-       PERFORM_TEST (test_evenodd, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
+    PERFORM_TEST(test_evenodd, argc, argv);
+    return 0;
 }
index b50861b926060f7a3d2fe7930628f4a21b7ebec1..c51cf2c4fb97e5751055a7ac38df732c7a6718cb 100644 (file)
@@ -1,34 +1,33 @@
 #include "test.h"
 
 void recurse_draw(VkvgContext ctx, int depth) {
-       depth++;
-       vkvg_save(ctx);
+    depth++;
+    vkvg_save(ctx);
 
-       vkvg_translate (ctx, 5,5);
-       vkvg_rectangle(ctx, (float)depth,(float)depth,200,200);
-       /*vkvg_clip_preserve(ctx);
-       vkvg_set_source_rgb(ctx, 1.f/depth, 1.f / depth, 1.f / depth);
-       vkvg_fill_preserve(ctx);*/
-       vkvg_set_source_rgb(ctx, 0,1,0);
-       vkvg_stroke(ctx);
+    vkvg_translate(ctx, 5, 5);
+    vkvg_rectangle(ctx, (float)depth, (float)depth, 200, 200);
+    /*vkvg_clip_preserve(ctx);
+    vkvg_set_source_rgb(ctx, 1.f/depth, 1.f / depth, 1.f / depth);
+    vkvg_fill_preserve(ctx);*/
+    vkvg_set_source_rgb(ctx, 0, 1, 0);
+    vkvg_stroke(ctx);
 
-       if (depth < 20)
-               recurse_draw (ctx, depth);
+    if (depth < 20)
+        recurse_draw(ctx, depth);
 
-       vkvg_restore(ctx);
+    vkvg_restore(ctx);
 }
 
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
+    recurse_draw(ctx, 0);
 
-       recurse_draw(ctx, 0);
-
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
+    return 0;
 }
index 7dc47d19b860392c642d1f755c18e46794de0d3f..ac726b33f0d33b2faecbf3d85b0a5c886b7fc001 100644 (file)
@@ -1,56 +1,56 @@
 #include "test.h"
 
-void paint(){
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+void paint() {
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
-void paint_with_rotation(){
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_rotate(ctx, 45);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+void paint_with_rotation() {
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_rotate(ctx, 45);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
-void paint_with_scale(){
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_scale (ctx, 0.2f,0.2f);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+void paint_with_scale() {
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_scale(ctx, 0.2f, 0.2f);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
-void paint_rect(){
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_rectangle(ctx,100,100,300,200);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+void paint_rect() {
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
-//TODO:test failed: full screen paint instead of rotated rect
-void paint_rect_with_rotation(){
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_rotate(ctx, 45);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_rectangle(ctx,100,100,300,200);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+// TODO:test failed: full screen paint instead of rotated rect
+void paint_rect_with_rotation() {
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_rotate(ctx, 45);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
-void paint_rect_with_scale(){
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_scale (ctx, 0.2f,0.2f);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_rectangle(ctx,100,100,300,200);
-       vkvg_paint(ctx);
-       vkvg_destroy(ctx);
+void paint_rect_with_scale() {
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_scale(ctx, 0.2f, 0.2f);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_rectangle(ctx, 100, 100, 300, 200);
+    vkvg_paint(ctx);
+    vkvg_destroy(ctx);
 }
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (paint, argc, argv);
-       PERFORM_TEST (paint_with_rotation, argc, argv);
-       PERFORM_TEST (paint_with_scale, argc, argv);
-       PERFORM_TEST (paint_rect, argc, argv);
-       PERFORM_TEST (paint_rect_with_rotation, argc, argv);
-       PERFORM_TEST (paint_rect_with_scale, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(paint, argc, argv);
+    PERFORM_TEST(paint_with_rotation, argc, argv);
+    PERFORM_TEST(paint_with_scale, argc, argv);
+    PERFORM_TEST(paint_rect, argc, argv);
+    PERFORM_TEST(paint_rect_with_rotation, argc, argv);
+    PERFORM_TEST(paint_rect_with_scale, argc, argv);
+    return 0;
 }
index 5011881766278c7b65e5e4d945896a6fb7a6de26..09939cd885ea33c7a3b72827027255ef6f29887a 100644 (file)
@@ -1,60 +1,60 @@
 #include "test.h"
 
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
-
-       vkvg_set_line_width(ctx, 1);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_move_to(ctx,200.5f,200.5f);
-       vkvg_line_to(ctx,400.5f,200.5f);
-       vkvg_line_to(ctx,400.5f,400.5f);
-       vkvg_line_to(ctx,200.5f,400.5f);
-       vkvg_close_path(ctx);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgba(ctx,0,1,0,1);
-       vkvg_move_to(ctx,300.5f,300.5f);
-       vkvg_line_to(ctx,500.5f,300.5f);
-       vkvg_line_to(ctx,500.5f,500.5f);
-       vkvg_line_to(ctx,300.5f,500.5f);
-       vkvg_stroke(ctx);
-
-       //vkvg_set_source_rgba(ctx,0,0.2,0.35,1);
-       //vkvg_fill(ctx);
-
-       vkvg_set_source_rgba(ctx,0.5f,1,0,1);
-       vkvg_move_to(ctx,320.5f,320.5f);
-       vkvg_line_to(ctx,520.5f,320.5f);
-       vkvg_line_to(ctx,520.5f,520.5f);
-       vkvg_line_to(ctx,320.5f,520.5f);
-       //vkvg_close_path(ctx);
-       vkvg_stroke(ctx);
-       vkvg_set_line_width(ctx, 40);
-       vkvg_set_source_rgba(ctx,0.5f,0.6f,1,1.0f);
-       vkvg_move_to(ctx,700,475);
-       vkvg_line_to(ctx,400,475);
-       vkvg_stroke(ctx);
-       vkvg_set_source_rgba(ctx,0,0.5f,0.5f,0.5f);
-       vkvg_move_to(ctx,300,200);
-       vkvg_arc(ctx, 200,200,100,0, M_PIF);
-       vkvg_stroke(ctx);
-
-       vkvg_set_line_width(ctx, 20);
-       vkvg_set_source_rgba(ctx,0.1f,0.1f,0.1f,0.5f);
-       vkvg_move_to(ctx,100,60);
-       vkvg_line_to(ctx,400,600);
-       vkvg_stroke(ctx);
-
-       vkvg_set_source_rgba(ctx,1,1,1,1);
-       vkvg_set_line_width(ctx, 1);
-       vkvg_rectangle(ctx,600.5f,200.5f,100,60);
-       vkvg_stroke(ctx);
-
-       vkvg_destroy(ctx);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
+
+    vkvg_set_line_width(ctx, 1);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_move_to(ctx, 200.5f, 200.5f);
+    vkvg_line_to(ctx, 400.5f, 200.5f);
+    vkvg_line_to(ctx, 400.5f, 400.5f);
+    vkvg_line_to(ctx, 200.5f, 400.5f);
+    vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgba(ctx, 0, 1, 0, 1);
+    vkvg_move_to(ctx, 300.5f, 300.5f);
+    vkvg_line_to(ctx, 500.5f, 300.5f);
+    vkvg_line_to(ctx, 500.5f, 500.5f);
+    vkvg_line_to(ctx, 300.5f, 500.5f);
+    vkvg_stroke(ctx);
+
+    // vkvg_set_source_rgba(ctx,0,0.2,0.35,1);
+    // vkvg_fill(ctx);
+
+    vkvg_set_source_rgba(ctx, 0.5f, 1, 0, 1);
+    vkvg_move_to(ctx, 320.5f, 320.5f);
+    vkvg_line_to(ctx, 520.5f, 320.5f);
+    vkvg_line_to(ctx, 520.5f, 520.5f);
+    vkvg_line_to(ctx, 320.5f, 520.5f);
+    // vkvg_close_path(ctx);
+    vkvg_stroke(ctx);
+    vkvg_set_line_width(ctx, 40);
+    vkvg_set_source_rgba(ctx, 0.5f, 0.6f, 1, 1.0f);
+    vkvg_move_to(ctx, 700, 475);
+    vkvg_line_to(ctx, 400, 475);
+    vkvg_stroke(ctx);
+    vkvg_set_source_rgba(ctx, 0, 0.5f, 0.5f, 0.5f);
+    vkvg_move_to(ctx, 300, 200);
+    vkvg_arc(ctx, 200, 200, 100, 0, M_PIF);
+    vkvg_stroke(ctx);
+
+    vkvg_set_line_width(ctx, 20);
+    vkvg_set_source_rgba(ctx, 0.1f, 0.1f, 0.1f, 0.5f);
+    vkvg_move_to(ctx, 100, 60);
+    vkvg_line_to(ctx, 400, 600);
+    vkvg_stroke(ctx);
+
+    vkvg_set_source_rgba(ctx, 1, 1, 1, 1);
+    vkvg_set_line_width(ctx, 1);
+    vkvg_rectangle(ctx, 600.5f, 200.5f, 100, 60);
+    vkvg_stroke(ctx);
+
+    vkvg_destroy(ctx);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (test, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(test, argc, argv);
+    return 0;
 }
index 2438a44a3bd0d2de98adad3135b500ab1cb41d91..6aa910ccef55ea3c0d83ae1b7db601bdeb547f40 100644 (file)
@@ -1,22 +1,22 @@
 #include "test.h"
 
-void create_destroy_multi_512(){       
-       VkvgSurface* surfs = (VkvgSurface*)malloc(sizeof(VkvgSurface)*test_size);
-       for (uint32_t i = 0; i < test_size; i++)
-               surfs[i] = vkvg_surface_create (device, 512, 512);
-       for (uint32_t i = 0; i < test_size; i++)        
-               vkvg_surface_destroy(surfs[i]);
-       free(surfs);
+void create_destroy_multi_512() {
+    VkvgSurface *surfs = (VkvgSurface *)malloc(sizeof(VkvgSurface) * test_size);
+    for (uint32_t i = 0; i < test_size; i++)
+        surfs[i] = vkvg_surface_create(device, 512, 512);
+    for (uint32_t i = 0; i < test_size; i++)
+        vkvg_surface_destroy(surfs[i]);
+    free(surfs);
 }
 
-void create_destroy_single_512(){
-       VkvgSurface s = vkvg_surface_create (device, 512, 512);
-       vkvg_surface_destroy (s);
+void create_destroy_single_512() {
+    VkvgSurface s = vkvg_surface_create(device, 512, 512);
+    vkvg_surface_destroy(s);
 }
 
 int main(int argc, char *argv[]) {
-       PERFORM_TEST (create_destroy_multi_512, argc, argv);
-       no_test_size = true;
-       PERFORM_TEST (create_destroy_single_512, argc, argv);
-       return 0;
+    PERFORM_TEST(create_destroy_multi_512, argc, argv);
+    no_test_size = true;
+    PERFORM_TEST(create_destroy_single_512, argc, argv);
+    return 0;
 }
index f4f0569f57b64fa80ebae92f582f78641fd5b3c8..7a40026ab263b27b2cbd40a4e02e3be5c7f3e601 100644 (file)
@@ -2,57 +2,56 @@
 
 #include "vkvg-svg.h"
 
-static float rotation = 0.f;
-static const char* path = "data/tiger.svg";
-static const char* svgSubPath = "data/checkbox.svg";
-
+static float       rotation   = 0.f;
+static const char *path       = "data/tiger.svg";
+static const char *svgSubPath = "data/checkbox.svg";
 
 void svg_surface() {
-       VkvgSurface svgSurf = vkvg_surface_create_from_svg (device, test_width, test_height, path);
+    VkvgSurface svgSurf = vkvg_surface_create_from_svg(device, test_width, test_height, path);
 
-       VkvgContext ctx = _initCtx(surf);
+    VkvgContext ctx = _initCtx(surf);
 
-       vkvg_set_source_rgb(ctx,1,1,1);
-       vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
+    vkvg_paint(ctx);
 
-       vkvg_set_source_surface(ctx, svgSurf, 0,0);
-       vkvg_paint(ctx);
+    vkvg_set_source_surface(ctx, svgSurf, 0, 0);
+    vkvg_paint(ctx);
 
-       vkvg_destroy(ctx);
-       vkvg_surface_destroy(svgSurf);
+    vkvg_destroy(ctx);
+    vkvg_surface_destroy(svgSurf);
 }
-void vkvg_svg () {
-       VkvgSvg svg = vkvg_svg_load (path);
-       uint32_t w, h;
-       vkvg_svg_get_dimensions(svg, &w, &h);
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_clear(ctx);
+void vkvg_svg() {
+    VkvgSvg  svg = vkvg_svg_load(path);
+    uint32_t w, h;
+    vkvg_svg_get_dimensions(svg, &w, &h);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_clear(ctx);
 
-       vkvg_svg_render (svg, ctx, NULL);
+    vkvg_svg_render(svg, ctx, NULL);
 
-       vkvg_destroy(ctx);
-       vkvg_svg_destroy (svg);
+    vkvg_destroy(ctx);
+    vkvg_svg_destroy(svg);
 }
-void vkvg_svg_sub () {
-       VkvgSvg svg = vkvg_svg_load (svgSubPath);
-       uint32_t w, h;
-       vkvg_svg_get_dimensions(svg, &w, &h);
-       VkvgContext ctx = _initCtx(surf);
-       vkvg_clear(ctx);
-
-       vkvg_svg_render (svg, ctx, "#True");
-       vkvg_translate(ctx, 200, 0);
-       vkvg_svg_render (svg, ctx, "#False");
-
-       vkvg_destroy(ctx);
-       vkvg_svg_destroy (svg);
+void vkvg_svg_sub() {
+    VkvgSvg  svg = vkvg_svg_load(svgSubPath);
+    uint32_t w, h;
+    vkvg_svg_get_dimensions(svg, &w, &h);
+    VkvgContext ctx = _initCtx(surf);
+    vkvg_clear(ctx);
+
+    vkvg_svg_render(svg, ctx, "#True");
+    vkvg_translate(ctx, 200, 0);
+    vkvg_svg_render(svg, ctx, "#False");
+
+    vkvg_destroy(ctx);
+    vkvg_svg_destroy(svg);
 }
 
 int main(int argc, char *argv[]) {
-       no_test_size = true;
+    no_test_size = true;
 
-       PERFORM_TEST (svg_surface, argc, argv);
-       PERFORM_TEST (vkvg_svg, argc, argv);
-       PERFORM_TEST (vkvg_svg_sub, argc, argv);
-       return 0;
+    PERFORM_TEST(svg_surface, argc, argv);
+    PERFORM_TEST(vkvg_svg, argc, argv);
+    PERFORM_TEST(vkvg_svg_sub, argc, argv);
+    return 0;
 }
index 302f8a76740a59293f8e33f3872365fe01085511..60249aaa7664c46a3b583f286a06e6b69a62396a 100644 (file)
 
 #include "test.h"
 
-void cairo_test_fill_rule (VkvgContext cr){
-       vkvg_set_line_width (cr, 6);
-
-       //vkvg_scale(cr,3,3);
-       vkvg_set_source_rgba(cr,1,0,0,1);
-       vkvg_move_to(cr,50,150);
-       vkvg_rel_line_to(cr,50,70);
-       vkvg_rel_line_to(cr,50,0);
-       vkvg_rel_line_to(cr,50,-70);
-       vkvg_rel_line_to(cr,0,-60);
-       vkvg_rel_line_to(cr,-50,-30);
-       vkvg_rel_line_to(cr,-50,0);
-       vkvg_rel_line_to(cr,-50,30);
-       vkvg_close_path(cr);
-
-
-//    vkvg_set_line_join(cr,VKVG_LINE_JOIN_ROUND);
-       vkvg_set_source_rgb (cr, 0, 0.7f, 0);
-       vkvg_rectangle (cr, 12, 12, 232, 70);
-       //vkvg_stroke (cr);
-//    vkvg_new_sub_path (cr);
-       vkvg_arc (cr, 64, 64, 40, 0, M_PIF*2.f);
-       //vkvg_close_path(cr);
-
-       vkvg_new_sub_path (cr);
-       vkvg_arc_negative (cr, 192, 64, 40, M_PIF*2.f, 0);
-       //vkvg_close_path(cr);
-
-       //vkvg_rectangle (cr, 30, 30, 20, 200);
-       //vkvg_rectangle (cr, 130, 30, 20, 200);
-       //vkvg_set_fill_rule (cr, vkvg_FILL_RULE_EVEN_ODD);
-
-       vkvg_fill_preserve(cr);
-
-       vkvg_set_source_rgb (cr, 0, 0, 0);
-       vkvg_stroke (cr);
+void cairo_test_fill_rule(VkvgContext cr) {
+    vkvg_set_line_width(cr, 6);
+
+    // vkvg_scale(cr,3,3);
+    vkvg_set_source_rgba(cr, 1, 0, 0, 1);
+    vkvg_move_to(cr, 50, 150);
+    vkvg_rel_line_to(cr, 50, 70);
+    vkvg_rel_line_to(cr, 50, 0);
+    vkvg_rel_line_to(cr, 50, -70);
+    vkvg_rel_line_to(cr, 0, -60);
+    vkvg_rel_line_to(cr, -50, -30);
+    vkvg_rel_line_to(cr, -50, 0);
+    vkvg_rel_line_to(cr, -50, 30);
+    vkvg_close_path(cr);
+
+    //    vkvg_set_line_join(cr,VKVG_LINE_JOIN_ROUND);
+    vkvg_set_source_rgb(cr, 0, 0.7f, 0);
+    vkvg_rectangle(cr, 12, 12, 232, 70);
+    // vkvg_stroke (cr);
+    //    vkvg_new_sub_path (cr);
+    vkvg_arc(cr, 64, 64, 40, 0, M_PIF * 2.f);
+    // vkvg_close_path(cr);
+
+    vkvg_new_sub_path(cr);
+    vkvg_arc_negative(cr, 192, 64, 40, M_PIF * 2.f, 0);
+    // vkvg_close_path(cr);
+
+    // vkvg_rectangle (cr, 30, 30, 20, 200);
+    // vkvg_rectangle (cr, 130, 30, 20, 200);
+    // vkvg_set_fill_rule (cr, vkvg_FILL_RULE_EVEN_ODD);
+
+    vkvg_fill_preserve(cr);
+
+    vkvg_set_source_rgb(cr, 0, 0, 0);
+    vkvg_stroke(cr);
 }
-void cairo_test_text (VkvgContext cr) {
-       vkvg_text_extents_t extents;
-       vkvg_font_extents_t ft;
-
-       //vkvg_set_fill_rule(cr, VKVG_FILL_RULE_NON_ZERO);
-       const char *utf8 = "vkvg|Ãp";
-       float x,y;
-
-       //vkvg_select_font_face (cr, "times");
-       vkvg_select_font_face (cr, "linux biolinum keyboard");
-       vkvg_set_font_size (cr, 50);
-       vkvg_font_extents(cr, &ft);
-       vkvg_text_extents (cr, utf8, &extents);
-       vkvg_set_source_rgb(cr,0,0,0);
-
-       x=25.0f;
-       y=150.0f;
-
-       vkvg_move_to (cr, x,y);
-       vkvg_show_text (cr, utf8);
-
-       /* draw helping lines */
-       vkvg_set_source_rgba (cr, 0, 0.2f, 0.2f, 0.6f);
-       vkvg_set_line_width (cr, 1.0f);
-       vkvg_new_path(cr);
-       vkvg_arc (cr, x, y, 10.0f, 0, 2.f*M_PIF);
-       vkvg_fill (cr);
-       vkvg_move_to (cr, x,y);
-       //vkvg_rel_line_to (cr, 0, -30);
-       vkvg_rel_line_to (cr, 0, -ft.ascent);
-       vkvg_rel_line_to (cr, extents.width, 0);
-       vkvg_rel_line_to (cr, extents.x_bearing, -extents.y_bearing);
-
-       vkvg_stroke (cr);
-
-       vkvg_move_to (cr, x,y);
-       vkvg_rel_line_to (cr, extents.width, 0);
-       vkvg_set_source_rgba (cr, 0.0, 0.0, 0.9f, 0.6f);
-
-       vkvg_stroke (cr);
-
-       vkvg_move_to (cr, x,y);
-       vkvg_rel_line_to (cr, 0, ft.descent);
-       vkvg_rel_line_to (cr, extents.width, 0);
-       vkvg_set_source_rgba (cr, 0.9f, 0.0, 0.0, 0.6f);
-
-       vkvg_stroke (cr);
-
-       vkvg_move_to (cr, x-10,y-ft.ascent);
-       vkvg_rel_line_to (cr, 0, ft.height);
-       vkvg_set_source_rgba (cr, 0.0, 0.1f, 0.0, 0.6f);
-
-       vkvg_stroke (cr);
+void cairo_test_text(VkvgContext cr) {
+    vkvg_text_extents_t extents;
+    vkvg_font_extents_t ft;
+
+    // vkvg_set_fill_rule(cr, VKVG_FILL_RULE_NON_ZERO);
+    const char *utf8 = "vkvg|Ãp";
+    float       x, y;
+
+    // vkvg_select_font_face (cr, "times");
+    vkvg_select_font_face(cr, "linux biolinum keyboard");
+    vkvg_set_font_size(cr, 50);
+    vkvg_font_extents(cr, &ft);
+    vkvg_text_extents(cr, utf8, &extents);
+    vkvg_set_source_rgb(cr, 0, 0, 0);
+
+    x = 25.0f;
+    y = 150.0f;
+
+    vkvg_move_to(cr, x, y);
+    vkvg_show_text(cr, utf8);
+
+    /* draw helping lines */
+    vkvg_set_source_rgba(cr, 0, 0.2f, 0.2f, 0.6f);
+    vkvg_set_line_width(cr, 1.0f);
+    vkvg_new_path(cr);
+    vkvg_arc(cr, x, y, 10.0f, 0, 2.f * M_PIF);
+    vkvg_fill(cr);
+    vkvg_move_to(cr, x, y);
+    // vkvg_rel_line_to (cr, 0, -30);
+    vkvg_rel_line_to(cr, 0, -ft.ascent);
+    vkvg_rel_line_to(cr, extents.width, 0);
+    vkvg_rel_line_to(cr, extents.x_bearing, -extents.y_bearing);
+
+    vkvg_stroke(cr);
+
+    vkvg_move_to(cr, x, y);
+    vkvg_rel_line_to(cr, extents.width, 0);
+    vkvg_set_source_rgba(cr, 0.0, 0.0, 0.9f, 0.6f);
+
+    vkvg_stroke(cr);
+
+    vkvg_move_to(cr, x, y);
+    vkvg_rel_line_to(cr, 0, ft.descent);
+    vkvg_rel_line_to(cr, extents.width, 0);
+    vkvg_set_source_rgba(cr, 0.9f, 0.0, 0.0, 0.6f);
+
+    vkvg_stroke(cr);
+
+    vkvg_move_to(cr, x - 10, y - ft.ascent);
+    vkvg_rel_line_to(cr, 0, ft.height);
+    vkvg_set_source_rgba(cr, 0.0, 0.1f, 0.0, 0.6f);
+
+    vkvg_stroke(cr);
 }
-void cairo_test_clip (VkvgContext cr){
-       vkvg_arc (cr, 128.0f, 128.0f, 76.8f, 0, 2.f * M_PIF);
-       vkvg_clip (cr);
-       //vkvg_new_path (cr);  /* current path is not
-       //                         consumed by vkvg_clip() */
-       vkvg_set_source_rgba(cr, 0, 0, 0, 1);
-       vkvg_rectangle (cr, 0, 0, 256, 256);
-       vkvg_fill (cr);
-       vkvg_set_source_rgba (cr, 0, 1, 0, 1);
-       vkvg_move_to (cr, -100, -100);
-       vkvg_line_to (cr, 256, 256);
-       vkvg_move_to (cr, 356, -100);
-       vkvg_line_to (cr, 0, 256);
-       vkvg_set_line_width (cr, 10.0f);
-       vkvg_stroke (cr);
+void cairo_test_clip(VkvgContext cr) {
+    vkvg_arc(cr, 128.0f, 128.0f, 76.8f, 0, 2.f * M_PIF);
+    vkvg_clip(cr);
+    // vkvg_new_path (cr);  /* current path is not
+    //                          consumed by vkvg_clip() */
+    vkvg_set_source_rgba(cr, 0, 0, 0, 1);
+    vkvg_rectangle(cr, 0, 0, 256, 256);
+    vkvg_fill(cr);
+    vkvg_set_source_rgba(cr, 0, 1, 0, 1);
+    vkvg_move_to(cr, -100, -100);
+    vkvg_line_to(cr, 256, 256);
+    vkvg_move_to(cr, 356, -100);
+    vkvg_line_to(cr, 0, 256);
+    vkvg_set_line_width(cr, 10.0f);
+    vkvg_stroke(cr);
 }
-void cairo_test_curves (VkvgContext cr){
-       float x=25.6f,  y=128.0f;
-       float x1=102.4f, y1=230.4f,
-                  x2=153.6f, y2=25.6f,
-                  x3=230.4f, y3=128.0f;
-
-       vkvg_set_source_rgb (cr, 0, 0, 0);
-       vkvg_move_to (cr, x, y);
-       vkvg_curve_to (cr, x1, y1, x2, y2, x3, y3);
-
-       vkvg_set_line_width (cr, 10.0f);
-       vkvg_stroke (cr);
-
-       vkvg_set_source_rgba (cr, 1, 0.2f, 0.2f, 0.6f);
-       vkvg_set_line_width (cr, 6.0f);
-       vkvg_move_to (cr,x,y);   vkvg_line_to (cr,x1,y1);
-       vkvg_move_to (cr,x2,y2); vkvg_line_to (cr,x3,y3);
-       vkvg_stroke (cr);
+void cairo_test_curves(VkvgContext cr) {
+    float x = 25.6f, y = 128.0f;
+    float x1 = 102.4f, y1 = 230.4f, x2 = 153.6f, y2 = 25.6f, x3 = 230.4f, y3 = 128.0f;
+
+    vkvg_set_source_rgb(cr, 0, 0, 0);
+    vkvg_move_to(cr, x, y);
+    vkvg_curve_to(cr, x1, y1, x2, y2, x3, y3);
+
+    vkvg_set_line_width(cr, 10.0f);
+    vkvg_stroke(cr);
+
+    vkvg_set_source_rgba(cr, 1, 0.2f, 0.2f, 0.6f);
+    vkvg_set_line_width(cr, 6.0f);
+    vkvg_move_to(cr, x, y);
+    vkvg_line_to(cr, x1, y1);
+    vkvg_move_to(cr, x2, y2);
+    vkvg_line_to(cr, x3, y3);
+    vkvg_stroke(cr);
 }
-void cairo_test_rounded_rect (VkvgContext cr) {
-       /* a custom shape that could be wrapped in a function */
-       float x0      = 25.6f,   /* parameters like vkvg_rectangle */
-                  y0      = 25.6f,
-                  rect_width  = 204.8f,
-                  rect_height = 204.8f,
-                  radius = 102.4f;   /* and an approximate curvature radius */
-
-       float x1,y1;
-
-       x1=x0+rect_width;
-       y1=y0+rect_height;
-       if (!rect_width || !rect_height)
-               return;
-       if (rect_width/2<radius) {
-               if (rect_height/2<radius) {
-                       vkvg_move_to  (cr, x0, (y0 + y1)/2);
-                       vkvg_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
-                       vkvg_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
-                       vkvg_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
-                       vkvg_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
-               } else {
-                       vkvg_move_to  (cr, x0, y0 + radius);
-                       vkvg_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
-                       vkvg_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
-                       vkvg_line_to (cr, x1 , y1 - radius);
-                       vkvg_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
-                       vkvg_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
-               }
-       } else {
-               if (rect_height/2<radius) {
-                       vkvg_move_to  (cr, x0, (y0 + y1)/2);
-                       vkvg_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
-                       vkvg_line_to (cr, x1 - radius, y0);
-                       vkvg_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
-                       vkvg_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
-                       vkvg_line_to (cr, x0 + radius, y1);
-                       vkvg_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
-               } else {
-                       vkvg_move_to  (cr, x0, y0 + radius);
-                       vkvg_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
-                       vkvg_line_to (cr, x1 - radius, y0);
-                       vkvg_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
-                       vkvg_line_to (cr, x1 , y1 - radius);
-                       vkvg_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
-                       vkvg_line_to (cr, x0 + radius, y1);
-                       vkvg_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
-               }
-       }
-       vkvg_close_path (cr);
-
-       vkvg_set_source_rgb (cr, 0.5f, 0.5f, 1);
-       vkvg_fill_preserve (cr);
-       vkvg_set_source_rgba (cr, 0.5f, 0, 0, 0.5f);
-       vkvg_set_line_width (cr, 10.0f);
-       vkvg_stroke (cr);
+void cairo_test_rounded_rect(VkvgContext cr) {
+    /* a custom shape that could be wrapped in a function */
+    float x0 = 25.6f, /* parameters like vkvg_rectangle */
+        y0 = 25.6f, rect_width = 204.8f, rect_height = 204.8f,
+          radius = 102.4f; /* and an approximate curvature radius */
+
+    float x1, y1;
+
+    x1 = x0 + rect_width;
+    y1 = y0 + rect_height;
+    if (!rect_width || !rect_height)
+        return;
+    if (rect_width / 2 < radius) {
+        if (rect_height / 2 < radius) {
+            vkvg_move_to(cr, x0, (y0 + y1) / 2);
+            vkvg_curve_to(cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
+            vkvg_curve_to(cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
+            vkvg_curve_to(cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
+            vkvg_curve_to(cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
+        } else {
+            vkvg_move_to(cr, x0, y0 + radius);
+            vkvg_curve_to(cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
+            vkvg_curve_to(cr, x1, y0, x1, y0, x1, y0 + radius);
+            vkvg_line_to(cr, x1, y1 - radius);
+            vkvg_curve_to(cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
+            vkvg_curve_to(cr, x0, y1, x0, y1, x0, y1 - radius);
+        }
+    } else {
+        if (rect_height / 2 < radius) {
+            vkvg_move_to(cr, x0, (y0 + y1) / 2);
+            vkvg_curve_to(cr, x0, y0, x0, y0, x0 + radius, y0);
+            vkvg_line_to(cr, x1 - radius, y0);
+            vkvg_curve_to(cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
+            vkvg_curve_to(cr, x1, y1, x1, y1, x1 - radius, y1);
+            vkvg_line_to(cr, x0 + radius, y1);
+            vkvg_curve_to(cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
+        } else {
+            vkvg_move_to(cr, x0, y0 + radius);
+            vkvg_curve_to(cr, x0, y0, x0, y0, x0 + radius, y0);
+            vkvg_line_to(cr, x1 - radius, y0);
+            vkvg_curve_to(cr, x1, y0, x1, y0, x1, y0 + radius);
+            vkvg_line_to(cr, x1, y1 - radius);
+            vkvg_curve_to(cr, x1, y1, x1, y1, x1 - radius, y1);
+            vkvg_line_to(cr, x0 + radius, y1);
+            vkvg_curve_to(cr, x0, y1, x0, y1, x0, y1 - radius);
+        }
+    }
+    vkvg_close_path(cr);
+
+    vkvg_set_source_rgb(cr, 0.5f, 0.5f, 1);
+    vkvg_fill_preserve(cr);
+    vkvg_set_source_rgba(cr, 0.5f, 0, 0, 0.5f);
+    vkvg_set_line_width(cr, 10.0f);
+    vkvg_stroke(cr);
 }
-void cairo_test_fill_and_stroke2 (VkvgContext cr){
-       vkvg_move_to (cr, 128.0f, 25.6f);
-       vkvg_line_to (cr, 230.4f, 230.4f);
-       vkvg_rel_line_to (cr, -102.4f, 0.0);
-       vkvg_curve_to (cr, 51.2f, 230.4f, 51.2f, 128.0f, 128.0f, 128.0f);
-       vkvg_close_path (cr);
-
-       vkvg_move_to (cr, 64.0f, 25.6f);
-       vkvg_rel_line_to (cr, 51.2f, 51.2f);
-       vkvg_rel_line_to (cr, -51.2f, 51.2f);
-       vkvg_rel_line_to (cr, -51.2f, -51.2f);
-       vkvg_close_path (cr);
-
-       /*vkvg_translate(cr,100,100);
-       vkvg_move_to (cr, 100, 100);
-       vkvg_line_to(cr,300,300);
-       vkvg_line_to(cr,100,300);*/
-
-
-       vkvg_set_line_width (cr, 10.0f);
-       vkvg_set_source_rgb (cr, 0, 0, 1);
-       vkvg_fill_preserve (cr);
-       vkvg_set_source_rgb (cr, 0, 0, 0);
-       vkvg_stroke (cr);
+void cairo_test_fill_and_stroke2(VkvgContext cr) {
+    vkvg_move_to(cr, 128.0f, 25.6f);
+    vkvg_line_to(cr, 230.4f, 230.4f);
+    vkvg_rel_line_to(cr, -102.4f, 0.0);
+    vkvg_curve_to(cr, 51.2f, 230.4f, 51.2f, 128.0f, 128.0f, 128.0f);
+    vkvg_close_path(cr);
+
+    vkvg_move_to(cr, 64.0f, 25.6f);
+    vkvg_rel_line_to(cr, 51.2f, 51.2f);
+    vkvg_rel_line_to(cr, -51.2f, 51.2f);
+    vkvg_rel_line_to(cr, -51.2f, -51.2f);
+    vkvg_close_path(cr);
+
+    /*vkvg_translate(cr,100,100);
+    vkvg_move_to (cr, 100, 100);
+    vkvg_line_to(cr,300,300);
+    vkvg_line_to(cr,100,300);*/
+
+    vkvg_set_line_width(cr, 10.0f);
+    vkvg_set_source_rgb(cr, 0, 0, 1);
+    vkvg_fill_preserve(cr);
+    vkvg_set_source_rgb(cr, 0, 0, 0);
+    vkvg_stroke(cr);
 }
-void cairo_print_arc_neg (VkvgContext cr){
-       float xc = 128.0f;
-       float yc = 128.0f;
-       float radius = 100.0f;
-       float angle1 = 45.0f  * (M_PIF/180.0f);  /* angles are specified */
-       float angle2 = 180.0f * (M_PIF/180.0f);  /* in radians           */
-
-       vkvg_set_source_rgba(cr, 0, 0, 0, 1);
-       vkvg_set_line_width (cr, 10.0f);
-       vkvg_arc_negative (cr, xc, yc, radius, angle1, angle2);
-       vkvg_stroke (cr);
-
-       /* draw helping lines */
-       vkvg_set_source_rgba (cr, 1, 0.2f, 0.2f, 0.6f);
-       vkvg_set_line_width (cr, 6.0f);
-
-       vkvg_arc (cr, xc, yc, 10.0f, 0, 2.f*M_PIF);
-       vkvg_fill (cr);
-
-       vkvg_arc (cr, xc, yc, radius, angle1, angle1);
-       vkvg_line_to (cr, xc, yc);
-       vkvg_arc (cr, xc, yc, radius, angle2, angle2);
-       //vkvg_line_to (cr, xc, yc);
-       vkvg_stroke (cr);
-
+void cairo_print_arc_neg(VkvgContext cr) {
+    float xc     = 128.0f;
+    float yc     = 128.0f;
+    float radius = 100.0f;
+    float angle1 = 45.0f * (M_PIF / 180.0f);  /* angles are specified */
+    float angle2 = 180.0f * (M_PIF / 180.0f); /* in radians           */
+
+    vkvg_set_source_rgba(cr, 0, 0, 0, 1);
+    vkvg_set_line_width(cr, 10.0f);
+    vkvg_arc_negative(cr, xc, yc, radius, angle1, angle2);
+    vkvg_stroke(cr);
+
+    /* draw helping lines */
+    vkvg_set_source_rgba(cr, 1, 0.2f, 0.2f, 0.6f);
+    vkvg_set_line_width(cr, 6.0f);
+
+    vkvg_arc(cr, xc, yc, 10.0f, 0, 2.f * M_PIF);
+    vkvg_fill(cr);
+
+    vkvg_arc(cr, xc, yc, radius, angle1, angle1);
+    vkvg_line_to(cr, xc, yc);
+    vkvg_arc(cr, xc, yc, radius, angle2, angle2);
+    // vkvg_line_to (cr, xc, yc);
+    vkvg_stroke(cr);
 }
-void cairo_test_line_caps (VkvgContext cr) {
-       vkvg_set_source_rgb (cr, 0, 0, 0);
-       vkvg_set_line_width (cr, 30.0f);
-       vkvg_set_line_cap  (cr, VKVG_LINE_CAP_BUTT); /* default */
-       vkvg_move_to (cr, 64.0f, 50.0f); vkvg_line_to (cr, 64.0f, 200.0f);
-       vkvg_stroke (cr);
-       vkvg_set_line_cap  (cr, VKVG_LINE_CAP_ROUND);
-       vkvg_move_to (cr, 128.0f, 50.0f); vkvg_line_to (cr, 128.0f, 200.0f);
-       vkvg_stroke (cr);
-       vkvg_set_line_cap  (cr, VKVG_LINE_CAP_SQUARE);
-       vkvg_move_to (cr, 192.0f, 50.0f); vkvg_line_to (cr, 192.0f, 200.0f);
-       vkvg_stroke (cr);
-
-       /* draw helping lines */
-       vkvg_set_source_rgb (cr, 1, 0.2f, 0.2f);
-       vkvg_set_line_width (cr, 2.56f);
-       vkvg_move_to (cr, 64.0f, 50.0f); vkvg_line_to (cr, 64.0f, 200.0f);
-       vkvg_move_to (cr, 128.0f, 50.0f);  vkvg_line_to (cr, 128.0f, 200.0f);
-       vkvg_move_to (cr, 192.0f, 50.0f); vkvg_line_to (cr, 192.0f, 200.0f);
-       vkvg_stroke (cr);
+void cairo_test_line_caps(VkvgContext cr) {
+    vkvg_set_source_rgb(cr, 0, 0, 0);
+    vkvg_set_line_width(cr, 30.0f);
+    vkvg_set_line_cap(cr, VKVG_LINE_CAP_BUTT); /* default */
+    vkvg_move_to(cr, 64.0f, 50.0f);
+    vkvg_line_to(cr, 64.0f, 200.0f);
+    vkvg_stroke(cr);
+    vkvg_set_line_cap(cr, VKVG_LINE_CAP_ROUND);
+    vkvg_move_to(cr, 128.0f, 50.0f);
+    vkvg_line_to(cr, 128.0f, 200.0f);
+    vkvg_stroke(cr);
+    vkvg_set_line_cap(cr, VKVG_LINE_CAP_SQUARE);
+    vkvg_move_to(cr, 192.0f, 50.0f);
+    vkvg_line_to(cr, 192.0f, 200.0f);
+    vkvg_stroke(cr);
+
+    /* draw helping lines */
+    vkvg_set_source_rgb(cr, 1, 0.2f, 0.2f);
+    vkvg_set_line_width(cr, 2.56f);
+    vkvg_move_to(cr, 64.0f, 50.0f);
+    vkvg_line_to(cr, 64.0f, 200.0f);
+    vkvg_move_to(cr, 128.0f, 50.0f);
+    vkvg_line_to(cr, 128.0f, 200.0f);
+    vkvg_move_to(cr, 192.0f, 50.0f);
+    vkvg_line_to(cr, 192.0f, 200.0f);
+    vkvg_stroke(cr);
 }
-void cairo_test_line_joins (VkvgContext cr) {
-       vkvg_set_source_rgb (cr, 0, 0, 0);
-       vkvg_set_line_width (cr, 40.96f);
-       vkvg_move_to (cr, 76.8f, 84.48f);
-       vkvg_rel_line_to (cr, 51.2f, -51.2f);
-       vkvg_rel_line_to (cr, 51.2f, 51.2f);
-       vkvg_set_line_join (cr, VKVG_LINE_JOIN_MITER); /* default */
-       vkvg_stroke (cr);
-
-       vkvg_move_to (cr, 76.8f, 161.28f);
-       vkvg_rel_line_to (cr, 51.2f, -51.2f);
-       vkvg_rel_line_to (cr, 51.2f, 51.2f);
-       vkvg_set_line_join (cr, VKVG_LINE_JOIN_BEVEL);
-       vkvg_stroke (cr);
-
-       vkvg_move_to (cr, 76.8f, 238.08f);
-       vkvg_rel_line_to (cr, 51.2f, -51.2f);
-       vkvg_rel_line_to (cr, 51.2f, 51.2f);
-       vkvg_set_line_join (cr, VKVG_LINE_JOIN_ROUND);
-       vkvg_stroke (cr);
-
-               /* draw helping lines */
-       vkvg_set_source_rgb (cr, 1, 0.2f, 0.2f);
-       vkvg_set_line_width (cr, 2.56f);
-       vkvg_set_line_join (cr, VKVG_LINE_JOIN_MITER);
-       vkvg_move_to (cr, 76.8f, 84.48f);
-       vkvg_rel_line_to (cr, 51.2f, -51.2f);
-       vkvg_rel_line_to (cr, 51.2f, 51.2f);
-       vkvg_move_to (cr, 76.8f, 161.28f);
-       vkvg_rel_line_to (cr, 51.2f, -51.2f);
-       vkvg_rel_line_to (cr, 51.2f, 51.2f);
-       vkvg_move_to (cr, 76.8f, 238.08f);
-       vkvg_rel_line_to (cr, 51.2f, -51.2f);
-       vkvg_rel_line_to (cr, 51.2f, 51.2f);
-
-       vkvg_stroke (cr);
-
+void cairo_test_line_joins(VkvgContext cr) {
+    vkvg_set_source_rgb(cr, 0, 0, 0);
+    vkvg_set_line_width(cr, 40.96f);
+    vkvg_move_to(cr, 76.8f, 84.48f);
+    vkvg_rel_line_to(cr, 51.2f, -51.2f);
+    vkvg_rel_line_to(cr, 51.2f, 51.2f);
+    vkvg_set_line_join(cr, VKVG_LINE_JOIN_MITER); /* default */
+    vkvg_stroke(cr);
+
+    vkvg_move_to(cr, 76.8f, 161.28f);
+    vkvg_rel_line_to(cr, 51.2f, -51.2f);
+    vkvg_rel_line_to(cr, 51.2f, 51.2f);
+    vkvg_set_line_join(cr, VKVG_LINE_JOIN_BEVEL);
+    vkvg_stroke(cr);
+
+    vkvg_move_to(cr, 76.8f, 238.08f);
+    vkvg_rel_line_to(cr, 51.2f, -51.2f);
+    vkvg_rel_line_to(cr, 51.2f, 51.2f);
+    vkvg_set_line_join(cr, VKVG_LINE_JOIN_ROUND);
+    vkvg_stroke(cr);
+
+    /* draw helping lines */
+    vkvg_set_source_rgb(cr, 1, 0.2f, 0.2f);
+    vkvg_set_line_width(cr, 2.56f);
+    vkvg_set_line_join(cr, VKVG_LINE_JOIN_MITER);
+    vkvg_move_to(cr, 76.8f, 84.48f);
+    vkvg_rel_line_to(cr, 51.2f, -51.2f);
+    vkvg_rel_line_to(cr, 51.2f, 51.2f);
+    vkvg_move_to(cr, 76.8f, 161.28f);
+    vkvg_rel_line_to(cr, 51.2f, -51.2f);
+    vkvg_rel_line_to(cr, 51.2f, 51.2f);
+    vkvg_move_to(cr, 76.8f, 238.08f);
+    vkvg_rel_line_to(cr, 51.2f, -51.2f);
+    vkvg_rel_line_to(cr, 51.2f, 51.2f);
+
+    vkvg_stroke(cr);
 }
-void cairo_print_arc (VkvgContext cr) {
-       float xc = 128.0f;
-       float yc = 128.0f;
-       float radius = 100.0f;
-       float angle1 = 45.0f  * (M_PIF/180.0f);  /* angles are specified */
-       float angle2 = 180.0f * (M_PIF/180.0f);  /* in radians           */
-
-       vkvg_set_source_rgba(cr, 0, 0, 0, 1);
-       vkvg_set_line_width (cr, 10.0f);
-       vkvg_arc (cr, xc, yc, radius, angle1, angle2);
-       vkvg_stroke (cr);
-
-       /* draw helping lines */
-       vkvg_set_source_rgba(cr, 1, 0.2f, 0.2f, 0.6f);
-       vkvg_set_line_width (cr, 6.0f);
-
-       vkvg_arc (cr, xc, yc, 10.0f, 0, 2.f*M_PIF);
-       vkvg_fill (cr);
-
-       vkvg_arc (cr, xc, yc, radius, angle1, angle1);
-       vkvg_line_to (cr, xc, yc);
-       vkvg_arc (cr, xc, yc, radius, angle2, angle2);
-       vkvg_stroke (cr);
+void cairo_print_arc(VkvgContext cr) {
+    float xc     = 128.0f;
+    float yc     = 128.0f;
+    float radius = 100.0f;
+    float angle1 = 45.0f * (M_PIF / 180.0f);  /* angles are specified */
+    float angle2 = 180.0f * (M_PIF / 180.0f); /* in radians           */
+
+    vkvg_set_source_rgba(cr, 0, 0, 0, 1);
+    vkvg_set_line_width(cr, 10.0f);
+    vkvg_arc(cr, xc, yc, radius, angle1, angle2);
+    vkvg_stroke(cr);
+
+    /* draw helping lines */
+    vkvg_set_source_rgba(cr, 1, 0.2f, 0.2f, 0.6f);
+    vkvg_set_line_width(cr, 6.0f);
+
+    vkvg_arc(cr, xc, yc, 10.0f, 0, 2.f * M_PIF);
+    vkvg_fill(cr);
+
+    vkvg_arc(cr, xc, yc, radius, angle1, angle1);
+    vkvg_line_to(cr, xc, yc);
+    vkvg_arc(cr, xc, yc, radius, angle2, angle2);
+    vkvg_stroke(cr);
 }
 static float rotation = 0.f;
 
-void cairo_tests () {
-       rotation+=0.002f;
+void cairo_tests() {
+    rotation += 0.002f;
 
-       vkvg_matrix_t mat;
-       vkvg_matrix_init_translate (&mat, panX,panY);
-       vkvg_matrix_scale(&mat,zoom,zoom);
-       vkvg_matrix_translate (&mat, 400,400);
-       vkvg_matrix_rotate(&mat,rotation);
-       vkvg_matrix_translate(&mat,-400.f,-400.f);
+    vkvg_matrix_t mat;
+    vkvg_matrix_init_translate(&mat, panX, panY);
+    vkvg_matrix_scale(&mat, zoom, zoom);
+    vkvg_matrix_translate(&mat, 400, 400);
+    vkvg_matrix_rotate(&mat, rotation);
+    vkvg_matrix_translate(&mat, -400.f, -400.f);
 
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_source_rgba(ctx, 1.0f, 1.0f, 1.0f, 1);
+    vkvg_paint(ctx);
 
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_set_source_rgba(ctx,1.0f,1.0f,1.0f,1);
-       vkvg_paint(ctx);
+    // vkvg_set_matrix(ctx,&mat);
+    vkvg_translate(ctx, panX, panY);
+    vkvg_scale(ctx, zoom, zoom);
+    vkvg_translate(ctx, 400, 400);
+    vkvg_rotate(ctx, rotation);
+    vkvg_translate(ctx, -400.f, -400.f);
 
-       //vkvg_set_matrix(ctx,&mat);
-       vkvg_translate (ctx, panX,panY);
-       vkvg_scale(ctx,zoom,zoom);
-       vkvg_translate (ctx, 400,400);
-       vkvg_rotate(ctx,rotation);
-       vkvg_translate(ctx,-400.f,-400.f);
+    cairo_print_arc(ctx);
 
-       cairo_print_arc(ctx);
+    vkvg_translate(ctx, 200, 0);
+    cairo_test_fill_rule(ctx);
 
-       vkvg_translate(ctx,200,0);
-       cairo_test_fill_rule(ctx);
+    vkvg_translate(ctx, 250, 0);
+    cairo_test_rounded_rect(ctx);
 
-       vkvg_translate(ctx,250,0);
-       cairo_test_rounded_rect(ctx);
+    vkvg_translate(ctx, -450, 250);
+    cairo_test_fill_and_stroke2(ctx);
 
-       vkvg_translate(ctx,-450,250);
-       cairo_test_fill_and_stroke2(ctx);
+    vkvg_translate(ctx, 250, 0);
+    cairo_print_arc_neg(ctx);
 
-       vkvg_translate(ctx,250,0);
-       cairo_print_arc_neg(ctx);
+    vkvg_translate(ctx, 250, 0);
+    cairo_test_text(ctx);
 
-       vkvg_translate(ctx,250,0);
-       cairo_test_text(ctx);
+    vkvg_translate(ctx, -500, 250);
+    cairo_test_curves(ctx);
 
-       vkvg_translate(ctx,-500,250);
-       cairo_test_curves(ctx);
+    vkvg_translate(ctx, 250, 0);
+    cairo_test_line_joins(ctx);
 
-       vkvg_translate(ctx,250,0);
-       cairo_test_line_joins(ctx);
+    vkvg_translate(ctx, 250, 0);
+    cairo_test_line_caps(ctx);
 
-       vkvg_translate(ctx,250,0);
-       cairo_test_line_caps(ctx);
-
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
-
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (cairo_tests, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(cairo_tests, argc, argv);
+    return 0;
 }
index 51e5a9f5a2c59ff3841153af38c4b4afd99c0bc2..7087ba6981544142a93a142edcc1baa8c016f8de 100644 (file)
 #include "test.h"
 
-static const chartxt = "The quick brown fox jumps over the lazy dog";
+static const char *txt = "The quick brown fox jumps over the lazy dog";
 
 void print(VkvgContext ctx, float penY, uint32_t size) {
-       vkvg_set_font_size(ctx,size);
-       vkvg_move_to(ctx, 10, penY);
-       vkvg_show_text (ctx,txt);
+    vkvg_set_font_size(ctx, size);
+    vkvg_move_to(ctx, 10, penY);
+    vkvg_show_text(ctx, txt);
 }
-void print_boxed(VkvgContext ctx, const chartext, float penX, float penY, uint32_t size) {
-       vkvg_set_font_size(ctx,size);
-       vkvg_text_extents_t te = {0};
-       vkvg_text_extents(ctx,text,&te);
-       vkvg_font_extents_t fe = {0};
-       vkvg_font_extents(ctx, &fe);
-
-       vkvg_move_to(ctx, penX, penY);
-       vkvg_rectangle(ctx, penX, penY -fe.ascent, te.width, fe.height);
-       vkvg_set_source_rgb(ctx,0.2f,0.2f,0.7f);
-       vkvg_fill(ctx);
-
-       vkvg_move_to(ctx, penX, penY);
-       vkvg_set_source_rgb(ctx,1,1,1);
-       vkvg_show_text (ctx,text);
+void print_boxed(VkvgContext ctx, const char *text, float penX, float penY, uint32_t size) {
+    vkvg_set_font_size(ctx, size);
+    vkvg_text_extents_t te = {0};
+    vkvg_text_extents(ctx, text, &te);
+    vkvg_font_extents_t fe = {0};
+    vkvg_font_extents(ctx, &fe);
+
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_rectangle(ctx, penX, penY - fe.ascent, te.width, fe.height);
+    vkvg_set_source_rgb(ctx, 0.2f, 0.2f, 0.7f);
+    vkvg_fill(ctx);
+
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
+    vkvg_show_text(ctx, text);
 }
-void print_unboxed(VkvgContext ctx, const chartext, float penX, float penY, uint32_t size) {
-       vkvg_set_font_size(ctx,size);
-       vkvg_move_to(ctx, penX, penY);
-       vkvg_set_source_rgb(ctx,1,1,1);
-       vkvg_show_text (ctx,text);
+void print_unboxed(VkvgContext ctx, const char *text, float penX, float penY, uint32_t size) {
+    vkvg_set_font_size(ctx, size);
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
+    vkvg_show_text(ctx, text);
 }
 void test2() {
-       VkvgContext ctx = vkvg_create(surf);
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_color_t bg = {0.0,0.0,0.0,1};
-       vkvg_color_t fg = {1.0f,1.0f,1.0f,1};
+    vkvg_color_t bg = {0.0, 0.0, 0.0, 1};
+    vkvg_color_t fg = {1.0f, 1.0f, 1.0f, 1};
 
-       vkvg_set_source_rgba(ctx,bg.r,bg.g,bg.b,bg.a);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgba(ctx,fg.r,fg.g,fg.b,fg.a);
-       //vkvg_select_font_face(ctx, "droid");
-       vkvg_select_font_face(ctx, "times");
+    vkvg_set_source_rgba(ctx, bg.r, bg.g, bg.b, bg.a);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgba(ctx, fg.r, fg.g, fg.b, fg.a);
+    // vkvg_select_font_face(ctx, "droid");
+    vkvg_select_font_face(ctx, "times");
 
+    float penY = 10.f;
 
-       float penY = 10.f;
+    for (uint32_t size = 4; size < 39; size++) {
+        print(ctx, (float)penY, size);
+        penY += size;
+    }
 
-       for (uint32_t size = 4; size < 39; size++) {
-               print(ctx,(float)penY,size);
-               penY+=size;
-       }
-
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 void test1() {
-       VkvgContext ctx = vkvg_create(surf);
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_color_t fg = {0.0,0.0,0.0,1};
-       vkvg_color_t bg = {0.9f,0.9f,0.9f,1};
+    vkvg_color_t fg = {0.0, 0.0, 0.0, 1};
+    vkvg_color_t bg = {0.9f, 0.9f, 0.9f, 1};
 
-       vkvg_set_source_rgba(ctx,bg.r,bg.g,bg.b,bg.a);
-       vkvg_paint(ctx);
-       vkvg_set_source_rgba(ctx,fg.r,fg.g,fg.b,fg.a);
+    vkvg_set_source_rgba(ctx, bg.r, bg.g, bg.b, bg.a);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgba(ctx, fg.r, fg.g, fg.b, fg.a);
 
-       uint32_t size = 8;
-       float penY = 100.f;
+    uint32_t size = 8;
+    float    penY = 100.f;
 
-       vkvg_set_font_size(ctx,size);
+    vkvg_set_font_size(ctx, size);
 
-       vkvg_select_font_face(ctx, "mono");
-       vkvg_move_to(ctx, 100.f,penY);
-       vkvg_show_text (ctx,txt);
+    vkvg_select_font_face(ctx, "mono");
+    vkvg_move_to(ctx, 100.f, penY);
+    vkvg_show_text(ctx, txt);
 
-       penY += 1.2f * size;
+    penY += 1.2f * size;
 
-       vkvg_select_font_face(ctx, "times");
-       vkvg_move_to(ctx, 100.f, penY);
-       vkvg_show_text (ctx,txt);
+    vkvg_select_font_face(ctx, "times");
+    vkvg_move_to(ctx, 100.f, penY);
+    vkvg_show_text(ctx, txt);
 
-       penY += 1.2f * size;
+    penY += 1.2f * size;
 
-       vkvg_select_font_face(ctx, "arial:italic");
-       vkvg_move_to(ctx, 100.f, penY);
-       vkvg_show_text (ctx,txt);
+    vkvg_select_font_face(ctx, "arial:italic");
+    vkvg_move_to(ctx, 100.f, penY);
+    vkvg_show_text(ctx, txt);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
-void test(){
-       VkvgContext ctx = vkvg_create(surf);
-
-       //vkvg_color_t fg = {0.2,0.2,0.2,1};
-       vkvg_color_t fg = {0.0,0.0,0.0,1};
-       vkvg_color_t bg = {1.0f,1.0f,1.0f,1};
-       vkvg_set_source_rgba(ctx,bg.r,bg.g,bg.b,bg.a);
-       vkvg_paint(ctx);
-
-       float size = 19;
-       float penY = 50;
-       float penX = 10;
-
-       /*vkvg_rectangle(ctx,30,0,100,400);
-       vkvg_clip(ctx);*/
-
-       //vkvg_select_font_face(ctx, "/usr/local/share/fonts/DroidSansMono.ttf");
-       //vkvg_select_font_face(ctx, "/usr/share/fonts/truetype/unifont/unifont.ttf");
-
-       vkvg_set_font_size (ctx, 12);
-       vkvg_select_font_face (ctx, "droid");
-       vkvg_font_extents_t fe;
-       vkvg_font_extents (ctx, &fe);
-       vkvg_move_to (ctx, penX,penY);
-       vkvg_set_source_rgba (ctx, fg.r, fg.g, fg.b, fg.a);
-       vkvg_text_extents_t te;
-       vkvg_text_extents (ctx, "abcdefghijk", &te);
-       vkvg_show_text (ctx, "abcdefghijk");
-       penX += te.x_advance;
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"*abcdefghijk2");
-       penY += 2.f*size;
-
-       vkvg_select_font_face(ctx, "times");
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
-       penY+=size;
-
-       vkvg_select_font_face(ctx, "droid");
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"lmnopqrstuvwxyz123456789");
-       penY+=size;
-
-       vkvg_select_font_face(ctx, "times:bold");
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
-       penY+=size;
-
-       vkvg_select_font_face(ctx, "droid");
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
-       penY+=size;
-
-       vkvg_select_font_face(ctx, "arial:italic");
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
-       penY+=size;
-
-       vkvg_select_font_face(ctx, "arial");
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
-       penY+=size;
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"this is a test");
-       penY+=size;
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"this is another test to see if label is working");
-       penY+=size;
-
-       vkvg_select_font_face(ctx, "mono");
-       vkvg_move_to(ctx, penX,penY);
-       vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
-       penY+=size;
-
-       vkvg_move_to(ctx, 80,400);
-       vkvg_show_text (ctx,"Ленивый рыжий кот");
-
-       vkvg_move_to(ctx, 150,250);
-       vkvg_show_text (ctx,"test string é€");
-       vkvg_move_to(ctx, 150,300);
-       vkvg_show_text (ctx,"كسول الزنجبيل القط");
-       vkvg_move_to(ctx, 150,350);
-       vkvg_show_text (ctx,"懶惰的姜貓");
-
-       //vkvg_show_text (ctx,"ABCDABCD");
-       //vkvg_show_text (ctx,"j");
-
-       vkvg_destroy(ctx);
+void test() {
+    VkvgContext ctx = vkvg_create(surf);
+
+    // vkvg_color_t fg = {0.2,0.2,0.2,1};
+    vkvg_color_t fg = {0.0, 0.0, 0.0, 1};
+    vkvg_color_t bg = {1.0f, 1.0f, 1.0f, 1};
+    vkvg_set_source_rgba(ctx, bg.r, bg.g, bg.b, bg.a);
+    vkvg_paint(ctx);
+
+    float size = 19;
+    float penY = 50;
+    float penX = 10;
+
+    /*vkvg_rectangle(ctx,30,0,100,400);
+    vkvg_clip(ctx);*/
+
+    // vkvg_select_font_face(ctx, "/usr/local/share/fonts/DroidSansMono.ttf");
+    // vkvg_select_font_face(ctx, "/usr/share/fonts/truetype/unifont/unifont.ttf");
+
+    vkvg_set_font_size(ctx, 12);
+    vkvg_select_font_face(ctx, "droid");
+    vkvg_font_extents_t fe;
+    vkvg_font_extents(ctx, &fe);
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_set_source_rgba(ctx, fg.r, fg.g, fg.b, fg.a);
+    vkvg_text_extents_t te;
+    vkvg_text_extents(ctx, "abcdefghijk", &te);
+    vkvg_show_text(ctx, "abcdefghijk");
+    penX += te.x_advance;
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "*abcdefghijk2");
+    penY += 2.f * size;
+
+    vkvg_select_font_face(ctx, "times");
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "abcdefghijklmnopqrstuvwxyz");
+    penY += size;
+
+    vkvg_select_font_face(ctx, "droid");
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "lmnopqrstuvwxyz123456789");
+    penY += size;
+
+    vkvg_select_font_face(ctx, "times:bold");
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "abcdefghijklmnopqrstuvwxyz");
+    penY += size;
+
+    vkvg_select_font_face(ctx, "droid");
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    penY += size;
+
+    vkvg_select_font_face(ctx, "arial:italic");
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "abcdefghijklmnopqrstuvwxyz");
+    penY += size;
+
+    vkvg_select_font_face(ctx, "arial");
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    penY += size;
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "this is a test");
+    penY += size;
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "this is another test to see if label is working");
+    penY += size;
+
+    vkvg_select_font_face(ctx, "mono");
+    vkvg_move_to(ctx, penX, penY);
+    vkvg_show_text(ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    penY += size;
+
+    vkvg_move_to(ctx, 80, 400);
+    vkvg_show_text(ctx, "Ленивый рыжий кот");
+
+    vkvg_move_to(ctx, 150, 250);
+    vkvg_show_text(ctx, "test string é€");
+    vkvg_move_to(ctx, 150, 300);
+    vkvg_show_text(ctx, "كسول الزنجبيل القط");
+    vkvg_move_to(ctx, 150, 350);
+    vkvg_show_text(ctx, "懶惰的姜貓");
+
+    // vkvg_show_text (ctx,"ABCDABCD");
+    // vkvg_show_text (ctx,"j");
+
+    vkvg_destroy(ctx);
 }
-void single_font_and_size () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-       for (uint32_t i=0; i<test_size; i++) {
-               randomize_color(ctx);
-               float x = rndf() * test_width;
-               float y = rndf() * test_height;
-               vkvg_select_font_face(ctx,"mono");
-               vkvg_set_font_size(ctx, 20);
-               vkvg_move_to(ctx,x,y);
-               vkvg_show_text(ctx,"This is a test string!");
-       }
-       vkvg_destroy(ctx);
+void single_font_and_size() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    for (uint32_t i = 0; i < test_size; i++) {
+        randomize_color(ctx);
+        float x = rndf() * test_width;
+        float y = rndf() * test_height;
+        vkvg_select_font_face(ctx, "mono");
+        vkvg_set_font_size(ctx, 20);
+        vkvg_move_to(ctx, x, y);
+        vkvg_show_text(ctx, "This is a test string!");
+    }
+    vkvg_destroy(ctx);
 }
-void simple_text () {
-       VkvgContext ctx = vkvg_create(surf);
-
-       vkvg_set_source_rgb             (ctx, 0, 0, 0);
-       vkvg_paint                              (ctx);
-       vkvg_set_source_rgb             (ctx, 1, 1, 1);
+void simple_text() {
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_load_font_from_path (ctx, "data/DancingScript-Regular.ttf", "dancing");
-       print_boxed                             (ctx, "abcdefghijklmnopqrstuvwxyz", 20,60,20);
-       print_boxed                             (ctx, "ABC", 20,160,60);
-       vkvg_select_font_face   (ctx, "mono");
-       print_boxed                             (ctx, "This is a test string!", 20, 250, 20);
-       print_boxed                             (ctx, "ANOTHER ONE TO CHECK..", 20, 350, 20);
+    vkvg_set_source_rgb(ctx, 0, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
 
-       vkvg_destroy                    (ctx);
+    vkvg_load_font_from_path(ctx, "data/DancingScript-Regular.ttf", "dancing");
+    print_boxed(ctx, "abcdefghijklmnopqrstuvwxyz", 20, 60, 20);
+    print_boxed(ctx, "ABC", 20, 160, 60);
+    vkvg_select_font_face(ctx, "mono");
+    print_boxed(ctx, "This is a test string!", 20, 250, 20);
+    print_boxed(ctx, "ANOTHER ONE TO CHECK..", 20, 350, 20);
 
+    vkvg_destroy(ctx);
 }
-void font_file_path () {
-       VkvgContext ctx = vkvg_create(surf);
-
-       vkvg_set_source_rgb             (ctx, 0, 0, 0);
-       vkvg_paint                              (ctx);
-       vkvg_set_source_rgb             (ctx, 1, 1, 1);
-       vkvg_load_font_from_path (ctx, "data/DancingScript-Regular.ttf", "droid");
-       print_boxed                             (ctx, "This is a test string!", 50,20,12);
-       print_boxed                             (ctx, "This is a test string!", 50,50,20);
-       print_boxed                             (ctx, "ANOTHER ONE TO CHECK..", 50,80,20);
-       print_boxed                             (ctx, "this is another string to check if ligature are well set", 10,120,20);
-       vkvg_destroy                    (ctx);
+void font_file_path() {
+    VkvgContext ctx = vkvg_create(surf);
+
+    vkvg_set_source_rgb(ctx, 0, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
+    vkvg_load_font_from_path(ctx, "data/DancingScript-Regular.ttf", "droid");
+    print_boxed(ctx, "This is a test string!", 50, 20, 12);
+    print_boxed(ctx, "This is a test string!", 50, 50, 20);
+    print_boxed(ctx, "ANOTHER ONE TO CHECK..", 50, 80, 20);
+    print_boxed(ctx, "this is another string to check if ligature are well set", 10, 120, 20);
+    vkvg_destroy(ctx);
 }
 
-void random_size () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-       vkvg_select_font_face(ctx,"mono");
-       for (uint32_t i=0; i<test_size; i++) {
-               randomize_color(ctx);
-               float x = rndf() * test_width;
-               float y = rndf() * test_height;
-               uint32_t c = (uint32_t)(rndf() * 120)+1;
-
-               vkvg_set_font_size(ctx, c);
-               vkvg_move_to(ctx,x,y);
-               vkvg_show_text(ctx,"This is a test string!");
-       }
-       vkvg_destroy(ctx);
+void random_size() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+    vkvg_select_font_face(ctx, "mono");
+    for (uint32_t i = 0; i < test_size; i++) {
+        randomize_color(ctx);
+        float    x = rndf() * test_width;
+        float    y = rndf() * test_height;
+        uint32_t c = (uint32_t)(rndf() * 120) + 1;
+
+        vkvg_set_font_size(ctx, c);
+        vkvg_move_to(ctx, x, y);
+        vkvg_show_text(ctx, "This is a test string!");
+    }
+    vkvg_destroy(ctx);
 }
-const char* const fonts[] =
-       { "mono", "droid", "times", "arial", "times:bold"};
-
-void random_font_and_size () {
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-
-       for (uint32_t i=0; i<test_size; i++) {
-               randomize_color(ctx);
-               float x = rndf() * test_width;
-               float y = rndf() * test_height;
-               uint32_t c = (uint32_t)(rndf() * 80)+1;
-               uint32_t f = (uint32_t)(rndf() * 4);
-
-               vkvg_set_font_size(ctx, c);
-               vkvg_select_font_face(ctx, fonts[f]);
-               vkvg_move_to(ctx,x,y);
-               vkvg_show_text(ctx,"This is a test string!");
-       }
-       vkvg_destroy(ctx);
+const char *const fonts[] = {"mono", "droid", "times", "arial", "times:bold"};
+
+void random_font_and_size() {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+
+    for (uint32_t i = 0; i < test_size; i++) {
+        randomize_color(ctx);
+        float    x = rndf() * test_width;
+        float    y = rndf() * test_height;
+        uint32_t c = (uint32_t)(rndf() * 80) + 1;
+        uint32_t f = (uint32_t)(rndf() * 4);
+
+        vkvg_set_font_size(ctx, c);
+        vkvg_select_font_face(ctx, fonts[f]);
+        vkvg_move_to(ctx, x, y);
+        vkvg_show_text(ctx, "This is a test string!");
+    }
+    vkvg_destroy(ctx);
 }
-void proto_sinaitic () {
-       VkvgContext ctx = vkvg_create(surf);
+void proto_sinaitic() {
+    VkvgContext ctx = vkvg_create(surf);
 
-       vkvg_set_source_rgb             (ctx, 0, 0, 0);
-       vkvg_paint                              (ctx);
-       vkvg_set_source_rgb             (ctx, 1, 1, 1);
+    vkvg_set_source_rgb(ctx, 0, 0, 0);
+    vkvg_paint(ctx);
+    vkvg_set_source_rgb(ctx, 1, 1, 1);
 
-       vkvg_load_font_from_path (ctx, "data/Proto-Sinaitic15.ttf", "sinaitic");
-       print_boxed                             (ctx, "hwhy", 100, 150, 60);
+    vkvg_load_font_from_path(ctx, "data/Proto-Sinaitic15.ttf", "sinaitic");
+    print_boxed(ctx, "hwhy", 100, 150, 60);
 
-       vkvg_destroy                    (ctx);
+    vkvg_destroy(ctx);
 }
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (simple_text, argc, argv);
-       PERFORM_TEST (font_file_path, argc, argv);
-       PERFORM_TEST (single_font_and_size, argc, argv);
-       PERFORM_TEST (random_size, argc, argv);
-       PERFORM_TEST (random_font_and_size, argc, argv);
-       PERFORM_TEST (test, argc, argv);
-       PERFORM_TEST (test1, argc, argv);
-       PERFORM_TEST (test2, argc, argv);
-       PERFORM_TEST (proto_sinaitic, argc, argv);
-
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(simple_text, argc, argv);
+    PERFORM_TEST(font_file_path, argc, argv);
+    PERFORM_TEST(single_font_and_size, argc, argv);
+    PERFORM_TEST(random_size, argc, argv);
+    PERFORM_TEST(random_font_and_size, argc, argv);
+    PERFORM_TEST(test, argc, argv);
+    PERFORM_TEST(test1, argc, argv);
+    PERFORM_TEST(test2, argc, argv);
+    PERFORM_TEST(proto_sinaitic, argc, argv);
+
+    return 0;
 }
index dd47a247a275851777fa5f560e8575705afe96a1..2156a3ba6d7241bd99bfad1714bac3e5744f581b 100644 (file)
 #include "vectors.h"
 #include "vkvg_context_internal.h"
 
-vkvg_fill_rule_t fillrule = VKVG_FILL_RULE_NON_ZERO;
-static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT;
-float lineWidth = 3.0f;
-vkvg_line_join_t lineJoin = VKVG_LINE_JOIN_MITER;
-vkvg_line_cap_t lineCap = VKVG_LINE_CAP_BUTT;
-bool isClosed = false;
-bool startWithArc = false, endWithArc = false;
-float angle = 0;
-float r;
-vec2 mouse;
-
-void draw (){
-       angle += 0.001f;
-
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_clear(ctx);
-
-       float r = fabsf(test_width/2 - mouse.x)/zoom;
-
-       vkvg_new_path(ctx);
-       vkvg_set_source_rgba(ctx,1,0,0,1);
-       vkvg_set_line_width (ctx,lineWidth/zoom);
-
-       vkvg_translate(ctx, test_width/2, test_height/2);
-       vkvg_scale(ctx, zoom, zoom);
-       //vkvg_rotate (ctx, angle);
-
-       vkvg_matrix_t mat;
-       vkvg_get_matrix(ctx, &mat);
-       float sx, sy;
-       vkvg_matrix_get_scale(&mat, &sx, &sy);
-
-       vkvg_arc (ctx,0,0,r, 0, M_PIF*2);
-       vkvg_fill(ctx);
-
-       float steps = _get_arc_step(ctx, r);
-       vkvg_identity_matrix(ctx);
-
-       vkvg_set_source_rgba(ctx,1,1,1,1);
-       char txt[100];
-       sprintf(txt, "scale: %f, %f", sx, sy);
-       vkvg_move_to(ctx,10,10);
-       vkvg_show_text(ctx,txt);
-       sprintf(txt, "angle: %f", angle);
-       vkvg_move_to(ctx,10,25);
-       vkvg_show_text(ctx,txt);
-       sprintf(txt, "radius: %f", r);
-       vkvg_move_to(ctx,10,40);
-       vkvg_show_text(ctx,txt);
-       sprintf(txt, "zoom: %f", zoom);
-       vkvg_move_to(ctx,10,55);
-       vkvg_show_text(ctx,txt);
-       sprintf(txt, "arc step: %f", steps);
-       vkvg_move_to(ctx,10,70);
-       vkvg_show_text(ctx,txt);
-       sprintf(txt, "steps: %d", (int)roundf(2.0f*M_PI / steps));
-       vkvg_move_to(ctx,10,85);
-       vkvg_show_text(ctx,txt);
-
-       vkvg_destroy(ctx);
+vkvg_fill_rule_t          fillrule     = VKVG_FILL_RULE_NON_ZERO;
+static VkSampleCountFlags samples      = VK_SAMPLE_COUNT_8_BIT;
+float                     lineWidth    = 3.0f;
+vkvg_line_join_t          lineJoin     = VKVG_LINE_JOIN_MITER;
+vkvg_line_cap_t           lineCap      = VKVG_LINE_CAP_BUTT;
+bool                      isClosed     = false;
+bool                      startWithArc = false, endWithArc = false;
+float                     angle = 0;
+float                     r;
+vec2                      mouse;
+
+void draw() {
+    angle += 0.001f;
+
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_clear(ctx);
+
+    float r = fabsf(test_width / 2 - mouse.x) / zoom;
+
+    vkvg_new_path(ctx);
+    vkvg_set_source_rgba(ctx, 1, 0, 0, 1);
+    vkvg_set_line_width(ctx, lineWidth / zoom);
+
+    vkvg_translate(ctx, test_width / 2, test_height / 2);
+    vkvg_scale(ctx, zoom, zoom);
+    // vkvg_rotate (ctx, angle);
+
+    vkvg_matrix_t mat;
+    vkvg_get_matrix(ctx, &mat);
+    float sx, sy;
+    vkvg_matrix_get_scale(&mat, &sx, &sy);
+
+    vkvg_arc(ctx, 0, 0, r, 0, M_PIF * 2);
+    vkvg_fill(ctx);
+
+    float steps = _get_arc_step(ctx, r);
+    vkvg_identity_matrix(ctx);
+
+    vkvg_set_source_rgba(ctx, 1, 1, 1, 1);
+    char txt[100];
+    sprintf(txt, "scale: %f, %f", sx, sy);
+    vkvg_move_to(ctx, 10, 10);
+    vkvg_show_text(ctx, txt);
+    sprintf(txt, "angle: %f", angle);
+    vkvg_move_to(ctx, 10, 25);
+    vkvg_show_text(ctx, txt);
+    sprintf(txt, "radius: %f", r);
+    vkvg_move_to(ctx, 10, 40);
+    vkvg_show_text(ctx, txt);
+    sprintf(txt, "zoom: %f", zoom);
+    vkvg_move_to(ctx, 10, 55);
+    vkvg_show_text(ctx, txt);
+    sprintf(txt, "arc step: %f", steps);
+    vkvg_move_to(ctx, 10, 70);
+    vkvg_show_text(ctx, txt);
+    sprintf(txt, "steps: %d", (int)roundf(2.0f * M_PI / steps));
+    vkvg_move_to(ctx, 10, 85);
+    vkvg_show_text(ctx, txt);
+
+    vkvg_destroy(ctx);
 }
-static void key_callback(GLFWwindowwindow, int key, int scancode, int action, int mods) {
-       if (action != GLFW_PRESS)
-               return;
-       switch (key) {
-       case GLFW_KEY_ESCAPE :
-               glfwSetWindowShouldClose(window, GLFW_TRUE);
-               break;
-       case GLFW_KEY_KP_ADD :
-               zoom *= 2.0f;
-               break;
-       case GLFW_KEY_KP_SUBTRACT :
-               zoom *= 0.5f;
-               break;
+static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
+    if (action != GLFW_PRESS)
+        return;
+    switch (key) {
+    case GLFW_KEY_ESCAPE:
+        glfwSetWindowShouldClose(window, GLFW_TRUE);
+        break;
+    case GLFW_KEY_KP_ADD:
+        zoom *= 2.0f;
+        break;
+    case GLFW_KEY_KP_SUBTRACT:
+        zoom *= 0.5f;
+        break;
 #ifdef VKVG_WIRED_DEBUG
-       case GLFW_KEY_F1:
-               vkvg_wired_debug ^= (1U << 0);
-               break;
-       case GLFW_KEY_F2:
-               vkvg_wired_debug ^= (1U << 1);
-               break;
-       case GLFW_KEY_F3:
-               vkvg_wired_debug ^= (1U << 2);
-               break;
+    case GLFW_KEY_F1:
+        vkvg_wired_debug ^= (1U << 0);
+        break;
+    case GLFW_KEY_F2:
+        vkvg_wired_debug ^= (1U << 1);
+        break;
+    case GLFW_KEY_F3:
+        vkvg_wired_debug ^= (1U << 2);
+        break;
 #endif
-       }
+    }
 }
-static void mouse_move_callback(GLFWwindow* window, double x, double y){
-       if (mouseDown) {
-               mouse = (vec2) {x, y};
-       }
+static void mouse_move_callback(GLFWwindow *window, double x, double y) {
+    if (mouseDown) {
+        mouse = (vec2){x, y};
+    }
 }
-static void scroll_callback(GLFWwindow* window, double x, double y){
-       if (y<0.f)
-               zoom *= 0.5f;
-       else
-               zoom *= 2.0f;
+static void scroll_callback(GLFWwindow *window, double x, double y) {
+    if (y < 0.f)
+        zoom *= 0.5f;
+    else
+        zoom *= 2.0f;
 }
-static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){
-       if (but != GLFW_MOUSE_BUTTON_1)
-               return;
-       if (state == GLFW_TRUE)
-               mouseDown = true;
-       else
-               mouseDown = false;
+static void mouse_button_callback(GLFWwindow *window, int but, int state, int modif) {
+    if (but != GLFW_MOUSE_BUTTON_1)
+        return;
+    if (state == GLFW_TRUE)
+        mouseDown = true;
+    else
+        mouseDown = false;
 }
 
+int main(int argc, char *argv[]) {
 
+    _parse_args(argc, argv);
+    VkEngine e;
+    e = vkengine_create(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
 
-int main(int argc, char* argv[]) {
+    VkhPresenter r = e->renderer;
+    vkengine_set_key_callback(e, key_callback);
+    vkengine_set_mouse_but_callback(e, mouse_button_callback);
+    vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+    vkengine_set_scroll_callback(e, scroll_callback);
 
-       _parse_args (argc, argv);
-       VkEngine e;
-       e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
+    bool deferredResolve = false;
 
-       VkhPresenter r = e->renderer;
-       vkengine_set_key_callback (e, key_callback);
-       vkengine_set_mouse_but_callback(e, mouse_button_callback);
-       vkengine_set_cursor_pos_callback(e, mouse_move_callback);
-       vkengine_set_scroll_callback(e, scroll_callback);
+    device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0,
+                                                    samples, deferredResolve);
+    surf   = vkvg_surface_create(device, test_width, test_height);
 
-       bool deferredResolve = false;
+    vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
 
-       device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve);
-       surf = vkvg_surface_create(device, test_width, test_height);
+    mouse = (vec2){test_width * 0.75, test_height * 0.5f};
 
-       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+    while (!vkengine_should_close(e)) {
+        glfwPollEvents();
 
-       mouse = (vec2){test_width*0.75,test_height*0.5f};
+        draw();
 
-       while (!vkengine_should_close (e)) {
-               glfwPollEvents();
+        if (!vkh_presenter_draw(r)) {
+            vkh_presenter_get_size(r, &test_width, &test_height);
+            vkvg_surface_destroy(surf);
+            surf = vkvg_surface_create(device, test_width, test_height);
+            vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+            vkDeviceWaitIdle(r->dev->dev);
+            continue;
+        }
+    }
+    vkDeviceWaitIdle(e->dev->dev);
 
-               draw ();
+    vkvg_surface_destroy(surf);
 
-               if (!vkh_presenter_draw (r)){
-                       vkh_presenter_get_size (r, &test_width, &test_height);
-                       vkvg_surface_destroy (surf);
-                       surf = vkvg_surface_create(device, test_width, test_height);
-                       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
-                       vkDeviceWaitIdle(r->dev->dev);
-                       continue;
-               }
-       }
-       vkDeviceWaitIdle(e->dev->dev);
+    vkvg_device_destroy(device);
 
-       vkvg_surface_destroy    (surf);
+    vkengine_destroy(e);
 
-       vkvg_device_destroy     (device);
-
-       vkengine_destroy (e);
-
-       return 0;
+    return 0;
 }
index b89db50da962dfc120a78987cc707a4ba39dc5a3..cc282b01565c10a9975c02838f816e02face112c 100644 (file)
 
 #include "test.h"
 
-
-void _test_rounded_rect (VkvgContext cr) {
-       /* a custom shape that could be wrapped in a function */
-       float x0      = -100,   /* parameters like vkvg_rectangle */
-                  y0     = -100,
-                  rect_width  = 200,
-                  rect_height = 200,
-                  radius = 102.4f;   /* and an approximate curvature radius */
-
-       float x1,y1;
-
-       x1=x0+rect_width;
-       y1=y0+rect_height;
-       if (!rect_width || !rect_height)
-               return;
-       if (rect_width/2<radius) {
-               if (rect_height/2<radius) {
-                       vkvg_move_to  (cr, x0, (y0 + y1)/2);
-                       vkvg_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
-                       vkvg_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
-                       vkvg_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
-                       vkvg_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
-               } else {
-                       vkvg_move_to  (cr, x0, y0 + radius);
-                       vkvg_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
-                       vkvg_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
-                       vkvg_line_to (cr, x1 , y1 - radius);
-                       vkvg_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
-                       vkvg_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
-               }
-       } else {
-               if (rect_height/2<radius) {
-                       vkvg_move_to  (cr, x0, (y0 + y1)/2);
-                       vkvg_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
-                       vkvg_line_to (cr, x1 - radius, y0);
-                       vkvg_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
-                       vkvg_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
-                       vkvg_line_to (cr, x0 + radius, y1);
-                       vkvg_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
-               } else {
-                       vkvg_move_to  (cr, x0, y0 + radius);
-                       vkvg_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
-                       vkvg_line_to (cr, x1 - radius, y0);
-                       vkvg_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
-                       vkvg_line_to (cr, x1 , y1 - radius);
-                       vkvg_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
-                       vkvg_line_to (cr, x0 + radius, y1);
-                       vkvg_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
-               }
-       }
-       vkvg_close_path (cr);
-
-       vkvg_set_source_rgb (cr, 0.5f, 0.5f, 1);
-       vkvg_fill_preserve (cr);
-       vkvg_set_source_rgba (cr, 0.5f, 0, 0, 0.5f);
-       vkvg_set_line_width (cr, 10.0f);
-       vkvg_stroke (cr);
+void _test_rounded_rect(VkvgContext cr) {
+    /* a custom shape that could be wrapped in a function */
+    float x0 = -100,                                                     /* parameters like vkvg_rectangle */
+        y0 = -100, rect_width = 200, rect_height = 200, radius = 102.4f; /* and an approximate curvature radius */
+
+    float x1, y1;
+
+    x1 = x0 + rect_width;
+    y1 = y0 + rect_height;
+    if (!rect_width || !rect_height)
+        return;
+    if (rect_width / 2 < radius) {
+        if (rect_height / 2 < radius) {
+            vkvg_move_to(cr, x0, (y0 + y1) / 2);
+            vkvg_curve_to(cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
+            vkvg_curve_to(cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
+            vkvg_curve_to(cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
+            vkvg_curve_to(cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
+        } else {
+            vkvg_move_to(cr, x0, y0 + radius);
+            vkvg_curve_to(cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
+            vkvg_curve_to(cr, x1, y0, x1, y0, x1, y0 + radius);
+            vkvg_line_to(cr, x1, y1 - radius);
+            vkvg_curve_to(cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
+            vkvg_curve_to(cr, x0, y1, x0, y1, x0, y1 - radius);
+        }
+    } else {
+        if (rect_height / 2 < radius) {
+            vkvg_move_to(cr, x0, (y0 + y1) / 2);
+            vkvg_curve_to(cr, x0, y0, x0, y0, x0 + radius, y0);
+            vkvg_line_to(cr, x1 - radius, y0);
+            vkvg_curve_to(cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
+            vkvg_curve_to(cr, x1, y1, x1, y1, x1 - radius, y1);
+            vkvg_line_to(cr, x0 + radius, y1);
+            vkvg_curve_to(cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
+        } else {
+            vkvg_move_to(cr, x0, y0 + radius);
+            vkvg_curve_to(cr, x0, y0, x0, y0, x0 + radius, y0);
+            vkvg_line_to(cr, x1 - radius, y0);
+            vkvg_curve_to(cr, x1, y0, x1, y0, x1, y0 + radius);
+            vkvg_line_to(cr, x1, y1 - radius);
+            vkvg_curve_to(cr, x1, y1, x1, y1, x1 - radius, y1);
+            vkvg_line_to(cr, x0 + radius, y1);
+            vkvg_curve_to(cr, x0, y1, x0, y1, x0, y1 - radius);
+        }
+    }
+    vkvg_close_path(cr);
+
+    vkvg_set_source_rgb(cr, 0.5f, 0.5f, 1);
+    vkvg_fill_preserve(cr);
+    vkvg_set_source_rgba(cr, 0.5f, 0, 0, 0.5f);
+    vkvg_set_line_width(cr, 10.0f);
+    vkvg_stroke(cr);
 }
 
-
 static float rotation = 0.f;
 
-void cairo_tests () {
-       rotation+=0.002f;
+void cairo_tests() {
+    rotation += 0.002f;
 
-       VkvgContext ctx = vkvg_create(surf);
-       vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
-       vkvg_set_source_rgba(ctx,1.0f,1.0f,1.0f,1);
-       vkvg_paint(ctx);
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD);
+    vkvg_set_source_rgba(ctx, 1.0f, 1.0f, 1.0f, 1);
+    vkvg_paint(ctx);
 
-       vkvg_set_line_width(ctx,10);
+    vkvg_set_line_width(ctx, 10);
 
-       vkvg_set_source_rgb(ctx,0,0,1);
+    vkvg_set_source_rgb(ctx, 0, 0, 1);
 
-       vkvg_translate (ctx, test_width/2,test_height/2);
-       vkvg_rotate(ctx, rotation);
-       //vkvg_scale(ctx, 200,200);
+    vkvg_translate(ctx, test_width / 2, test_height / 2);
+    vkvg_rotate(ctx, rotation);
+    // vkvg_scale(ctx, 200,200);
 
-       vkvg_arc (ctx, 0, 0, 150, 0, M_PI*1.5);
-       vkvg_stroke(ctx);
+    vkvg_arc(ctx, 0, 0, 150, 0, M_PI * 1.5);
+    vkvg_stroke(ctx);
 
-       _test_rounded_rect(ctx);
+    _test_rounded_rect(ctx);
 
-       vkvg_destroy(ctx);
+    vkvg_destroy(ctx);
 }
 
-
 int main(int argc, char *argv[]) {
-       no_test_size = true;
-       PERFORM_TEST (cairo_tests, argc, argv);
-       return 0;
+    no_test_size = true;
+    PERFORM_TEST(cairo_tests, argc, argv);
+    return 0;
 }
index de18cde3776e5b93484771798e5891698bce05ed..e7bafbbc876deac94f8e3eaa2e8005d1a32f4ae7 100644 (file)
 #include <stdarg.h>
 #include <ctype.h>
 
-static VkvgDevice dev;
+static VkvgDevice  dev;
 static VkvgSurface svgSurf = NULL;
-static double scale = 1;
-
-
-static char* filename = NULL;
-static char* directory = NULL;
-static DIR * pCurrentDir = NULL;
-struct dirent *dir = NULL;
-static int iconSize = -1;
-static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT;
-static uint32_t width=512, height=512, margin = 10;
-static double scrollX, scrollY;
-static bool paused = false, repaintIconList = true;
-
+static double      scale   = 1;
+
+static char              *filename    = NULL;
+static char              *directory   = NULL;
+static DIR               *pCurrentDir = NULL;
+struct dirent            *dir         = NULL;
+static int                iconSize    = -1;
+static VkSampleCountFlags samples     = VK_SAMPLE_COUNT_8_BIT;
+static uint32_t           width = 512, height = 512, margin = 10;
+static double             scrollX, scrollY;
+static bool               paused = false, repaintIconList = true;
 
 struct stat file_stat;
 
-#define NORMAL_COLOR  "\x1B[0m"
-#define GREEN  "\x1B[32m"
-#define BLUE  "\x1B[34m"
+#define NORMAL_COLOR "\x1B[0m"
+#define GREEN        "\x1B[32m"
+#define BLUE         "\x1B[34m"
 
-static int svg_file_count;
+static int   svg_file_count;
 static float maxScroll;
 
 /* not defined in c11, ok to define here only for sample */
 #ifndef DT_DIR
-       # define DT_DIR 4
+#define DT_DIR 4
 #endif
 
-int _count_svg_files () {
-       struct dirent *de;
-       rewinddir (pCurrentDir);
-       int i = 0;
-       while ((de = readdir(pCurrentDir)) != NULL) {
-               if(de->d_type != DT_DIR && !strcasecmp(strrchr(de->d_name, '\0') - 4, ".svg"))
-                       i++;
-       }
-       return i;
+int _count_svg_files() {
+    struct dirent *de;
+    rewinddir(pCurrentDir);
+    int i = 0;
+    while ((de = readdir(pCurrentDir)) != NULL) {
+        if (de->d_type != DT_DIR && !strcasecmp(strrchr(de->d_name, '\0') - 4, ".svg"))
+            i++;
+    }
+    return i;
 }
-void readSVG (VkEngine e) {
-       struct stat sb;
-       VkvgSurface newSvgSurf = NULL;
-       if (iconSize > 0 && pCurrentDir) {
-               if (!repaintIconList)
-                       return;
-               char tmp[FILENAME_MAX];
-               double x = 0, y = 0;
-               int cellSize = iconSize + margin;
-               int iconPerLine = ceil((double)(width-iconSize) / cellSize);
-               int lineToSkip = floor(scrollY / cellSize);
-               int iconToSkip = lineToSkip * iconPerLine;
-
-               y = (lineToSkip * cellSize) - scrollY;
-
-               newSvgSurf = vkvg_surface_create(dev, width, height);
-               VkvgContext ctx = vkvg_create(newSvgSurf);
-
-               struct dirent *de;
-               rewinddir (pCurrentDir);
-               int i = 0;
-               while ((de = readdir(pCurrentDir)) != NULL) {
-                       if(de->d_type != DT_DIR) {
-                               if (!strcasecmp(strrchr(de->d_name, '\0') - 4, ".svg")) {
-                                       if (i >= iconToSkip) {
-                                               sprintf(tmp, "%s%s", directory, de->d_name);
-                                               VkvgSurface surf = vkvg_surface_create_from_svg (dev, iconSize, iconSize, tmp);
-
-                                               if (surf) {
-                                                       vkvg_set_source_surface(ctx, surf, x, y);
-                                                       vkvg_paint(ctx);
-                                                       vkvg_surface_destroy(surf);
-                                               }
-                                               x += iconSize + margin;
-                                               if (x > width - iconSize) {
-                                                       x = 0;
-                                                       y += iconSize + margin;
-                                                       if (y >= height)
-                                                               break;
-                                               }
-                                       }
-                                       i++;
-                               }
-                       }
-               }
-               vkvg_destroy(ctx);
-               repaintIconList = false;
-       }else if (filename) {
-               vkengine_set_title(e, filename);
-               if (stat(filename, &sb) == -1) {
-                       printf ("Unable to stat file: %s\n", filename);
-                       exit(EXIT_FAILURE);
-               }
-               if (sb.st_mtime == file_stat.st_mtime)
-                       return;
-               file_stat = sb;
-               newSvgSurf = vkvg_surface_create_from_svg(dev, width, height, filename);
-       } else if (dir) {
-               char tmp[FILENAME_MAX];
-               sprintf(tmp, "%s/%s", directory, dir->d_name);
-               vkengine_set_title(e, tmp);
-               if (stat(tmp, &sb) == -1) {
-                       printf ("Unable to stat file: %s\n", tmp);
-                       exit(EXIT_FAILURE);
-               }
-               if (sb.st_mtime == file_stat.st_mtime)
-                       return;
-               file_stat = sb;
-               newSvgSurf = vkvg_surface_create_from_svg(dev, width, height, tmp);
-       }
-
-       //vkengine_wait_idle(e);
-
-       if (svgSurf)
-               vkvg_surface_destroy(svgSurf);
-       svgSurf = newSvgSurf;
-
-       //vkengine_wait_idle(e);
+void readSVG(VkEngine e) {
+    struct stat sb;
+    VkvgSurface newSvgSurf = NULL;
+    if (iconSize > 0 && pCurrentDir) {
+        if (!repaintIconList)
+            return;
+        char   tmp[FILENAME_MAX];
+        double x = 0, y = 0;
+        int    cellSize    = iconSize + margin;
+        int    iconPerLine = ceil((double)(width - iconSize) / cellSize);
+        int    lineToSkip  = floor(scrollY / cellSize);
+        int    iconToSkip  = lineToSkip * iconPerLine;
+
+        y = (lineToSkip * cellSize) - scrollY;
+
+        newSvgSurf      = vkvg_surface_create(dev, width, height);
+        VkvgContext ctx = vkvg_create(newSvgSurf);
+
+        struct dirent *de;
+        rewinddir(pCurrentDir);
+        int i = 0;
+        while ((de = readdir(pCurrentDir)) != NULL) {
+            if (de->d_type != DT_DIR) {
+                if (!strcasecmp(strrchr(de->d_name, '\0') - 4, ".svg")) {
+                    if (i >= iconToSkip) {
+                        sprintf(tmp, "%s%s", directory, de->d_name);
+                        VkvgSurface surf = vkvg_surface_create_from_svg(dev, iconSize, iconSize, tmp);
+
+                        if (surf) {
+                            vkvg_set_source_surface(ctx, surf, x, y);
+                            vkvg_paint(ctx);
+                            vkvg_surface_destroy(surf);
+                        }
+                        x += iconSize + margin;
+                        if (x > width - iconSize) {
+                            x = 0;
+                            y += iconSize + margin;
+                            if (y >= height)
+                                break;
+                        }
+                    }
+                    i++;
+                }
+            }
+        }
+        vkvg_destroy(ctx);
+        repaintIconList = false;
+    else if (filename) {
+        vkengine_set_title(e, filename);
+        if (stat(filename, &sb) == -1) {
+            printf("Unable to stat file: %s\n", filename);
+            exit(EXIT_FAILURE);
+        }
+        if (sb.st_mtime == file_stat.st_mtime)
+            return;
+        file_stat  = sb;
+        newSvgSurf = vkvg_surface_create_from_svg(dev, width, height, filename);
+    } else if (dir) {
+        char tmp[FILENAME_MAX];
+        sprintf(tmp, "%s/%s", directory, dir->d_name);
+        vkengine_set_title(e, tmp);
+        if (stat(tmp, &sb) == -1) {
+            printf("Unable to stat file: %s\n", tmp);
+            exit(EXIT_FAILURE);
+        }
+        if (sb.st_mtime == file_stat.st_mtime)
+            return;
+        file_stat  = sb;
+        newSvgSurf = vkvg_surface_create_from_svg(dev, width, height, tmp);
+    }
+
+    // vkengine_wait_idle(e);
+
+    if (svgSurf)
+        vkvg_surface_destroy(svgSurf);
+    svgSurf = newSvgSurf;
+
+    // vkengine_wait_idle(e);
 #ifdef VKVG_DBG_STATS
-               vkvg_debug_stats_t dbgStats = vkvg_device_get_stats (dev);
-               vkvg_device_reset_stats (dev);
-               printf("maximum point array size                = %d\n", dbgStats.sizePoints);
-               printf("maximum path array size                 = %d\n", dbgStats.sizePathes);
-               printf("maximum size of host vertice cache      = %d\n", dbgStats.sizeVertices);
-               printf("maximum size of host index cache        = %d\n", dbgStats.sizeIndices);
-               printf("maximum size of vulkan vertex buffer    = %d\n", dbgStats.sizeVBO);
-               printf("maximum size of vulkan index buffer     = %d\n", dbgStats.sizeIBO);
+    vkvg_debug_stats_t dbgStats = vkvg_device_get_stats(dev);
+    vkvg_device_reset_stats(dev);
+    printf("maximum point array size           = %d\n", dbgStats.sizePoints);
+    printf("maximum path array size                    = %d\n", dbgStats.sizePathes);
+    printf("maximum size of host vertice cache = %d\n", dbgStats.sizeVertices);
+    printf("maximum size of host index cache   = %d\n", dbgStats.sizeIndices);
+    printf("maximum size of vulkan vertex buffer       = %d\n", dbgStats.sizeVBO);
+    printf("maximum size of vulkan index buffer        = %d\n", dbgStats.sizeIBO);
 #endif
-
 }
 
-struct dirent *get_next_svg_file_in_current_directory (bool cycle) {
-       struct dirent *de;
-       while ((de = readdir(pCurrentDir)) != NULL) {
-               if(de->d_type != DT_DIR) {
-                       if (!strcasecmp(strrchr(de->d_name, '\0') - 4, ".svg"))
-                               return de;
-               }
-       }
-       if (!cycle)
-               return NULL;
-       rewinddir (pCurrentDir);
-       return get_next_svg_file_in_current_directory (false);
+struct dirent *get_next_svg_file_in_current_directory(bool cycle) {
+    struct dirent *de;
+    while ((de = readdir(pCurrentDir)) != NULL) {
+        if (de->d_type != DT_DIR) {
+            if (!strcasecmp(strrchr(de->d_name, '\0') - 4, ".svg"))
+                return de;
+        }
+    }
+    if (!cycle)
+        return NULL;
+    rewinddir(pCurrentDir);
+    return get_next_svg_file_in_current_directory(false);
 }
 
-
-static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
-       if (action == GLFW_RELEASE)
-               return;
-       switch (key) {
-       case GLFW_KEY_SPACE:
-                paused = !paused;
-               break;
-       case GLFW_KEY_R:
-               //recording = !recording;
-               file_stat = (struct stat){0};
-               break;
-       case GLFW_KEY_ESCAPE :
-               glfwSetWindowShouldClose(window, GLFW_TRUE);
-               break;
-       case GLFW_KEY_ENTER :
-               if (!pCurrentDir)
-                       break;
-               dir = get_next_svg_file_in_current_directory(true);
-               file_stat = (struct stat){0};
-               break;
-       case GLFW_KEY_KP_ADD:
-               scale*=2.0;
-               file_stat = (struct stat){0};
-               break;
-       case GLFW_KEY_KP_SUBTRACT:
-               scale/=2.0;
-               file_stat = (struct stat){0};
-               break;
-       }
+static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
+    if (action == GLFW_RELEASE)
+        return;
+    switch (key) {
+    case GLFW_KEY_SPACE:
+        paused = !paused;
+        break;
+    case GLFW_KEY_R:
+        // recording = !recording;
+        file_stat = (struct stat){0};
+        break;
+    case GLFW_KEY_ESCAPE:
+        glfwSetWindowShouldClose(window, GLFW_TRUE);
+        break;
+    case GLFW_KEY_ENTER:
+        if (!pCurrentDir)
+            break;
+        dir       = get_next_svg_file_in_current_directory(true);
+        file_stat = (struct stat){0};
+        break;
+    case GLFW_KEY_KP_ADD:
+        scale *= 2.0;
+        file_stat = (struct stat){0};
+        break;
+    case GLFW_KEY_KP_SUBTRACT:
+        scale /= 2.0;
+        file_stat = (struct stat){0};
+        break;
+    }
 }
-static void scroll_callback(GLFWwindowwindow, double x, double y) {
-       if (iconSize == 0)
-               return;
-       scrollX -= x * 25;
-       scrollY -= y * 25;
-       if (scrollX < 0)
-               scrollX = 0;
-       if (scrollY < 0)
-               scrollY = 0;
-       else if (scrollY > maxScroll)
-               scrollY = maxScroll;
-       repaintIconList = true;
+static void scroll_callback(GLFWwindow *window, double x, double y) {
+    if (iconSize == 0)
+        return;
+    scrollX -= x * 25;
+    scrollY -= y * 25;
+    if (scrollX < 0)
+        scrollX = 0;
+    if (scrollY < 0)
+        scrollY = 0;
+    else if (scrollY > maxScroll)
+        scrollY = maxScroll;
+    repaintIconList = true;
 }
 
-void print_help_and_exit () {
-       printf("\nUsage: svgviewer [options] [svgfilepath]\n\n");
-       printf("\t-o file.png:\toutput result to file then exit.\n");
-       printf("\t-d directory:\tdirectory containing svg files, cycle pressing Enter.\n");
-       printf("\t\t\tif the -d option is not specified, svgfile path is mandatory.\n");
-       printf("\t-i size:\tif -d option is present, display all svg files as a list with the size specified.\n");
-       printf("\t-m margin:\tset margin for the -i option\n");
-       printf("\t-w width:\tset output surface width.\n");
-       printf("\t-h height:\tset output surface height.\n");
-       printf("\t-s samples:\tset sample count, set to 1 to disable multisampling.\n");
-       printf("\n");
-       exit(-1);
+void print_help_and_exit() {
+    printf("\nUsage: svgviewer [options] [svgfilepath]\n\n");
+    printf("\t-o file.png:\toutput result to file then exit.\n");
+    printf("\t-d directory:\tdirectory containing svg files, cycle pressing Enter.\n");
+    printf("\t\t\tif the -d option is not specified, svgfile path is mandatory.\n");
+    printf("\t-i size:\tif -d option is present, display all svg files as a list with the size specified.\n");
+    printf("\t-m margin:\tset margin for the -i option\n");
+    printf("\t-w width:\tset output surface width.\n");
+    printf("\t-h height:\tset output surface height.\n");
+    printf("\t-s samples:\tset sample count, set to 1 to disable multisampling.\n");
+    printf("\n");
+    exit(-1);
 }
 
-
-int main (int argc, char *argv[]){
-       int i = 1;
-       char* output = NULL;
-
-       while (i < argc) {
-               int argLen = strlen(argv[i]);
-               if (argv[i][0] == '-') {
-
-                       if (argLen < 2) print_help_and_exit ();
-
-                       switch (argv[i][1]) {
-                       case 'd':
-                               if (argc < ++i + 1) print_help_and_exit();
-                               directory = argv[i];
-                               break;
-                       case 'w':
-                               if (argc < ++i + 1) print_help_and_exit();
-                               width = atoi(argv[i]);
-                               break;
-                       case 'h':
-                               if (argc < ++i + 1) print_help_and_exit();
-                               height = atoi(argv[i]);
-                               break;
-                       case 's':
-                               if (argc < ++i + 1) print_help_and_exit();
-                               samples = (VkSampleCountFlags)atoi(argv[i]);
-                               break;
-                       case 'i':
-                               if (argc < ++i + 1) print_help_and_exit();
-                               iconSize = atoi(argv[i]);
-                               break;
-                       case 'm':
-                               if (argc < ++i + 1) print_help_and_exit();
-                               margin = atoi(argv[i]);
-                               break;
-                       case 'o':
-                               if (argc < ++i + 1) print_help_and_exit();
-                               output = argv[i];
-                               break;
-                       default:
-                               print_help_and_exit();
-                       }
-               } else
-                       filename = argv[i];
-               i++;
-       }
-       if (!filename && !directory)
-               print_help_and_exit();
-
-       VkEngine e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,VK_PRESENT_MODE_FIFO_KHR, width, height);
-       vkengine_set_key_callback (e, key_callback);
-       vkengine_set_scroll_callback(e, scroll_callback);
-    vkvg_device_create_info_t info = {
-        samples,
-        false,
-        vkh_app_get_inst(e->app),
-        vkengine_get_physical_device(e),
-        vkengine_get_device(e),
-        vkengine_get_queue_fam_idx(e),
-        0
-    };
-    dev = vkvg_device_create(&info);
-
-       VkvgSurface surf = NULL;
-
-       if (output) {
-               surf = vkvg_surface_create_from_svg(dev, width, height, filename);
-               vkvg_surface_write_to_png (surf, output);
-       } else {
-
-               surf = vkvg_surface_create(dev, width, height);
-
-               vkh_presenter_build_blit_cmd (e->renderer, vkvg_surface_get_vk_image(surf), width, height);
-
-               if (directory) {
-                       pCurrentDir = opendir(directory);
-                       if(!pCurrentDir) {
-                               printf ("Directory not found: %s\n", directory);
-                               exit(EXIT_FAILURE);
-                       }
-                       dir = get_next_svg_file_in_current_directory(false);
-                       if (!dir) {
-                               printf ("No .svg file found in %s\n", directory);
-                               closedir(pCurrentDir);
-                               exit(EXIT_FAILURE);
-                       }
-                       if (iconSize > 0) {
-                               svg_file_count = _count_svg_files();
-                               int cellSize = iconSize + margin;
-                               int iconPerLine = ceil((double)(width-iconSize) / cellSize);
-                               int visibleLines = ceil((double)(height) / cellSize);
-                               int totLines = ceil((double)svg_file_count / iconPerLine);
-                               maxScroll = (totLines-visibleLines) * cellSize;
-                       }
-               }
-
-
-
-               while (!vkengine_should_close (e)) {
-                       //vkvg_log_level = VKVG_LOG_INFO_CMD;
-                       readSVG (e);
-                       //vkvg_log_level = VKVG_LOG_ERR;
-
-                       VkvgContext ctx = vkvg_create(surf);
-                       vkvg_set_source_rgb(ctx,0.1,0.1,0.1);
-                       vkvg_paint(ctx);
-
-                       if (svgSurf) {
-                               vkvg_set_source_surface(ctx, svgSurf, 0, 0);
-                               vkvg_paint(ctx);
-                       } else {
-                               vkvg_set_line_width(ctx,10);
-                               vkvg_set_source_rgb(ctx,1,0,0);
-                               vkvg_move_to(ctx, 0,0);
-                               vkvg_line_to(ctx, 512,512);
-                               vkvg_move_to(ctx, 0,512);
-                               vkvg_line_to(ctx, 512,0);
-                               vkvg_stroke(ctx);
-
-                       }
-                       vkvg_destroy(ctx);
-
-                       glfwPollEvents();
-
-                       if (!vkh_presenter_draw (e->renderer)){
-                               vkh_presenter_get_size (e->renderer, &width, &height);
-                               vkvg_surface_destroy (surf);
-                               surf = vkvg_surface_create(dev, width, height);
-                               vkh_presenter_build_blit_cmd (e->renderer, vkvg_surface_get_vk_image(surf), width, height);
-                               vkengine_wait_idle(e);
-                               repaintIconList = true;
-                               continue;
-                       }
-
-               }
-
-               vkengine_wait_idle(e);
-
-       }
-
-       if (svgSurf)
-               vkvg_surface_destroy(svgSurf);
-       vkvg_surface_destroy(surf);
-       vkvg_device_destroy(dev);
-       vkengine_destroy(e);
-
-       if (pCurrentDir)
-               closedir(pCurrentDir);
+int main(int argc, char *argv[]) {
+    int   i      = 1;
+    char *output = NULL;
+
+    while (i < argc) {
+        int argLen = strlen(argv[i]);
+        if (argv[i][0] == '-') {
+
+            if (argLen < 2)
+                print_help_and_exit();
+
+            switch (argv[i][1]) {
+            case 'd':
+                if (argc < ++i + 1)
+                    print_help_and_exit();
+                directory = argv[i];
+                break;
+            case 'w':
+                if (argc < ++i + 1)
+                    print_help_and_exit();
+                width = atoi(argv[i]);
+                break;
+            case 'h':
+                if (argc < ++i + 1)
+                    print_help_and_exit();
+                height = atoi(argv[i]);
+                break;
+            case 's':
+                if (argc < ++i + 1)
+                    print_help_and_exit();
+                samples = (VkSampleCountFlags)atoi(argv[i]);
+                break;
+            case 'i':
+                if (argc < ++i + 1)
+                    print_help_and_exit();
+                iconSize = atoi(argv[i]);
+                break;
+            case 'm':
+                if (argc < ++i + 1)
+                    print_help_and_exit();
+                margin = atoi(argv[i]);
+                break;
+            case 'o':
+                if (argc < ++i + 1)
+                    print_help_and_exit();
+                output = argv[i];
+                break;
+            default:
+                print_help_and_exit();
+            }
+        } else
+            filename = argv[i];
+        i++;
+    }
+    if (!filename && !directory)
+        print_help_and_exit();
+
+    VkEngine e = vkengine_create(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, width, height);
+    vkengine_set_key_callback(e, key_callback);
+    vkengine_set_scroll_callback(e, scroll_callback);
+    vkvg_device_create_info_t info = {samples,
+                                      false,
+                                      vkh_app_get_inst(e->app),
+                                      vkengine_get_physical_device(e),
+                                      vkengine_get_device(e),
+                                      vkengine_get_queue_fam_idx(e),
+                                      0};
+    dev                            = vkvg_device_create(&info);
+
+    VkvgSurface surf = NULL;
+
+    if (output) {
+        surf = vkvg_surface_create_from_svg(dev, width, height, filename);
+        vkvg_surface_write_to_png(surf, output);
+    } else {
+
+        surf = vkvg_surface_create(dev, width, height);
+
+        vkh_presenter_build_blit_cmd(e->renderer, vkvg_surface_get_vk_image(surf), width, height);
+
+        if (directory) {
+            pCurrentDir = opendir(directory);
+            if (!pCurrentDir) {
+                printf("Directory not found: %s\n", directory);
+                exit(EXIT_FAILURE);
+            }
+            dir = get_next_svg_file_in_current_directory(false);
+            if (!dir) {
+                printf("No .svg file found in %s\n", directory);
+                closedir(pCurrentDir);
+                exit(EXIT_FAILURE);
+            }
+            if (iconSize > 0) {
+                svg_file_count   = _count_svg_files();
+                int cellSize     = iconSize + margin;
+                int iconPerLine  = ceil((double)(width - iconSize) / cellSize);
+                int visibleLines = ceil((double)(height) / cellSize);
+                int totLines     = ceil((double)svg_file_count / iconPerLine);
+                maxScroll        = (totLines - visibleLines) * cellSize;
+            }
+        }
+
+        while (!vkengine_should_close(e)) {
+            // vkvg_log_level = VKVG_LOG_INFO_CMD;
+            readSVG(e);
+            // vkvg_log_level = VKVG_LOG_ERR;
+
+            VkvgContext ctx = vkvg_create(surf);
+            vkvg_set_source_rgb(ctx, 0.1, 0.1, 0.1);
+            vkvg_paint(ctx);
+
+            if (svgSurf) {
+                vkvg_set_source_surface(ctx, svgSurf, 0, 0);
+                vkvg_paint(ctx);
+            } else {
+                vkvg_set_line_width(ctx, 10);
+                vkvg_set_source_rgb(ctx, 1, 0, 0);
+                vkvg_move_to(ctx, 0, 0);
+                vkvg_line_to(ctx, 512, 512);
+                vkvg_move_to(ctx, 0, 512);
+                vkvg_line_to(ctx, 512, 0);
+                vkvg_stroke(ctx);
+            }
+            vkvg_destroy(ctx);
+
+            glfwPollEvents();
+
+            if (!vkh_presenter_draw(e->renderer)) {
+                vkh_presenter_get_size(e->renderer, &width, &height);
+                vkvg_surface_destroy(surf);
+                surf = vkvg_surface_create(dev, width, height);
+                vkh_presenter_build_blit_cmd(e->renderer, vkvg_surface_get_vk_image(surf), width, height);
+                vkengine_wait_idle(e);
+                repaintIconList = true;
+                continue;
+            }
+        }
+
+        vkengine_wait_idle(e);
+    }
+
+    if (svgSurf)
+        vkvg_surface_destroy(svgSurf);
+    vkvg_surface_destroy(surf);
+    vkvg_device_destroy(dev);
+    vkengine_destroy(e);
+
+    if (pCurrentDir)
+        closedir(pCurrentDir);
 }