summaryrefslogtreecommitdiffstatsci
path: root/include/vkvg.h
blob: 790a62468b7398e1677dcae050448d7c6de9b8a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
/*
 * Copyright (c) 2018-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so, subject
 * to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#ifndef VKVG_H
#define VKVG_H

#ifdef __cplusplus
extern "C" {
#endif

/*************************************************************************
 * Doxygen documentation
 *************************************************************************/
/** @mainpage VKVG: vulkan vector graphics
 *
 * Documentation of all members: vkvg.h
 *
 * VKVG is an open source 2d vector drawing library written in @b c and using [vulkan](https://www.khronos.org/vulkan/) for hardware acceleration.
 * Its api is modeled on the [cairo graphic library](https://www.cairographics.org/) with the following software components:
 *
 * - @ref surface
 */

/*! @file vkvg.h
 *  @brief The header of the VKVG library.
 *
 *  This is the header file of the VKVG library.  It defines all its types and
 *  declares all its functions.
 *
 *  For more information about how to use this file, see @ref build_include.
 */
/*! @defgroup surface Surface
 *  @brief Functions and types related to VKVG surface.
 *
 *  This is the reference documentation for creating, using and destroying VKVG
 *  Surfaces used as backend for drawing operations.
 */
/*! @defgroup context Context
 *  @brief Functions and types related to VKVG contexts.
 *
 *  This is the reference documentation for VKVG contexts used to draw on @ref surface.
 */
/*! @defgroup path Path creation and manipulation reference.
 *  @brief Functions and types related to path edition.
 */

#include <vulkan/vulkan.h>
#include <math.h>
#include <stdbool.h>

#ifndef vkvg_public
	#if (defined(_WIN32) || defined(_WIN64)) && !defined (VKVG_STATIC_BUILD)
		#define vkvg_public __declspec(dllimport)
	#else
		#define vkvg_public __attribute__((visibility("default")))
	#endif
#endif


#define VKVG_LOG_ERR		0x10
#define VKVG_LOG_DEBUG		0x20
#define VKVG_LOG_INFO		0x40
#define VKVG_LOG_INFO_PTS	0x41
#define VKVG_LOG_INFO_PATH	0x42
#define VKVG_LOG_DBG_ARRAYS	0x80
#define VKVG_LOG_FULL		0xff

#ifdef DEBUG
extern uint8_t vkvg_log_level;
#endif

/**
 * @brief vkvg operation status.
 *
 * vkvg_status_t is used to indicates errors that can occur when using vkvg. Several vkvg function directely
 * return result, but when using a #VkvgContext, the last error is stored in the context and can be accessed
 * with #vkvg_status.
 */
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_NULL_POINTER,			/*!< NULL pointer*/
	VKVG_STATUS_INVALID_STRING,			/*!< */
	VKVG_STATUS_INVALID_PATH_DATA,		/*!< */
	VKVG_STATUS_READ_ERROR,				/*!< */
	VKVG_STATUS_WRITE_ERROR,			/*!< */
	VKVG_STATUS_SURFACE_FINISHED,		/*!< */
	VKVG_STATUS_SURFACE_TYPE_MISMATCH,	/*!< */
	VKVG_STATUS_PATTERN_TYPE_MISMATCH,	/*!< */
	VKVG_STATUS_INVALID_CONTENT,		/*!< */
	VKVG_STATUS_INVALID_FORMAT,			/*!< */
	VKVG_STATUS_INVALID_VISUAL,			/*!< */
	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_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;
/**
 * @brief pattern border policy
 *
 * when painting a pattern on a surface, if the input bounds are smaller than the target bounds,
 * 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_t;


typedef enum {
	VKVG_FILTER_FAST,
	VKVG_FILTER_GOOD,
	VKVG_FILTER_BEST,
	VKVG_FILTER_NEAREST,
	VKVG_FILTER_BILINEAR,
	VKVG_FILTER_GAUSSIAN,
} vkvg_filter_t;

/**
 * @brief pattern types
 *
 *
 */
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_t;

/**
 * @brief line caps
 *
 * define the path ends shapes which may be rounded or squared. The context hold the current line cap
 * 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_t;
/**
 * @brief lines articulations
 *
 * define the joins shape for the stroke command between consecutive lines or curves. This setting is holded
 * 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_t;

/**
 * @brief shape fill method
 *
 * define technique used to fill a path with the #vkvg_fill command. This setting can be accessed in the context
 * with #vkvg_set_fill_rule and #vkvg_get_fill_rule.
 */
typedef enum {
	VKVG_FILL_RULE_EVEN_ODD,	/*!< stencil even-odd technique */
	VKVG_FILL_RULE_NON_ZERO		/*!< ear clipping filling */
} vkvg_fill_rule_t;

typedef struct {
	float r;
	float g;
	float b;
	float a;
} vkvg_color_t;

typedef struct {
	float ascent;
	float descent;
	float height;
	float max_x_advance;
	float max_y_advance;
} vkvg_font_extents_t;

typedef struct {
	float x_bearing;
	float y_bearing;
	float width;
	float height;
	float x_advance;
	float y_advance;
} vkvg_text_extents_t;

/**
 * @brief Opaque pointer on a vkvg text run.
 *
 * A #VkvgText is an intermediate representation
 * of a text to be drawn on a #VkvgSurface.
 * It contains the measurments computed for character poisitioning.
 *
 * This object is used to speed up the rendering of the same text with the same font multiple times
 * by storing typographic computations.
 *
 * Drawing text with #vkvg_show_text() implicitly create such intermediate structure
 * that is destroyed imediatly after the function call.
 */
typedef struct _vkvg_text_run_t* VkvgText;

/**
 * @brief The Vkvg drawing Context.
 * @ingroup context
 *
 * A #VkvgContext is the central object for drawing operations.
 * #vkvg_context_t structure internals this pointer point to are
 * hidden to the client application.
 */
typedef struct _vkvg_context_t* VkvgContext;
/**
 * @brief Opaque pointer on a Vkvg Surface structure.
 * @ingroup surface
 *
 * A #VkvgSurface represents an image, either as the destination
 * of a drawing operation or as source when drawing onto another
 * surface.  To draw to a #VkvgSurface, create a vkvg context
 * with the surface as the target, using #vkvg_create().
 * hidden internals.
 *
 * #VkvgSurface are created with a @ref VkvgDevice which has to stay
 * active as long has the surface is in use.
 */
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_t*  VkvgDevice;
/**
 * @brief Opaque pointer on a Vkvg pattern structure.
 * @ingroup pattern
 *
 * Patterns are images to be drawn on surface with several
 * configurable parameters such as the wrap mode, the filtering, etc...
 */
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		*/
} vkvg_debug_stats_t;

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
 *
 * 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 {1,0,0,1,0,0}/*!< The identity matrix*/
/**
 * @xx: xx component of the affine transformation
 * @yx: yx component of the affine transformation
 * @xy: xy component of the affine transformation
 * @yy: yy component of the affine transformation
 * @x0: X translation component of the affine transformation
 * @y0: Y translation component of the affine transformation
 *
/**
 * @brief vkvg matrix structure
 *
 * A #vkvg_matrix_t holds an affine transformation, such as a scale,
 * rotation, shear, or a combination of those. The transformation of
 * a point (x, y) is given by:
 * @code
 * x_new = xx * x + xy * y + x0;
 * y_new = yx * x + yy * y + y0;
 * @endcode
 */
typedef struct {
	float xx; float yx;
	float xy; float yy;
	float x0; float y0;
} vkvg_matrix_t;
/**
 * @brief Set matrix to identity
 *
 * 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);
/**
 * @brief Matrix initialization.
 *
 * Initialize members of the supplied matrix to the values passed as arguments.
 * Resulting matrix will hold an affine transformation defined by the parameters.
 * @param matrix a valid #vkvg_matrix_t pointer
 * @param xx xx component of the affine transformation
 * @param yx yx component of the affine transformation
 * @param xy xy component of the affine transformation
 * @param yy yy component of the affine transformation
 * @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);
/**
 * @brief Rotation matrix initialization
 *
 * Initialize members of the supplied matrix to create a translation matrix.
 * @param matrix a valid #vkvg_matrix_t pointer
 * @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);
/**
 * @brief scaling matrix initialization
 *
 * Initialize members of the supplied matrix to create a new scaling matrix
 * @param matrix a valid #vkvg_matrix_t pointer
 * @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);
/**
 * @brief rotation matrix initialization
 *
 * Initialize members of the supplied matrix to create a new rotation matrix
 * @param matrix a valid #vkvg_matrix_t pointer
 * @param radians angle of rotation, in radians. The direction of rotation
 * is defined such that positive angles rotate in the direction from
 * the positive X axis toward the positive Y axis. With the default
 * axis orientation of vkvg, positive angles rotate in a clockwise
 * direction.
 */
vkvg_public
void vkvg_matrix_init_rotate (vkvg_matrix_t *matrix, float radians);
/**
 * @brief apply translation on matrix
 *
 * Apply the translation defined by tx and ty on the supplied matrix.
 * The effect of the new transformation is to first translate the coordinates by tx and ty,
 * then apply the original transformation to the coordinates.
 * @param matrix a valid #vkvg_matrix_t pointer
 * @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);
/**
 * @brief apply scale on matrix
 *
 * Apply scaling by sx and sy on the supplied transformation matrix.
 * The effect of the new transformation is to first scale the coordinates by sx and sy,
 * then apply the original transformation to the coordinates.
 * @param matrix a valid #vkvg_matrix_t pointer on which the scaling will be applied.
 * @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);
/**
 * @brief apply rotation on matrix
 *
 * Apply a rotation of radians on the supplied matrix.
 * The effect of the new transformation is to first rotate the coordinates by radians,
 * then apply the original transformation to the coordinates.
 * @param matrix a valid #vkvg_matrix_t pointer on which the rotation will be applied
 * @param radians angle of rotation in radians. The direction of rotation is defined such that positive angles
 * 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);
/**
 * @brief matrices multiplication
 *
 * compute the multiplication of two matrix.
 * @param result a valid #vkvg_matrix_t pointer to hold the resulting matrix
 * @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);
/**
 * @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:
 * @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 .
 * @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, double* dx, double* dy);
/**
 * @brief transform point
 *
 * Transforms the point (x , y ) by matrix .
 * @param matrix a valid #vkvg_matrix_t to use to transform point
 * @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, double* x, double* y);
/**
 * @brief invert matrix
 *
 * Changes matrix to be the inverse of its original value. Not all transformation matrices have inverses;
 * if the matrix collapses points together (it is degenerate), then it has no inverse and this function will fail.
 * @param matrix the matrix to invert
 * @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);
/** @}*/

/*!
 * @defgroup device Device
 * @brief bind vulkan context and vkvg.
 *
 * #VkvgDevice is the starting point of a vkvg rendering infrastructure. It connects an
 * existing vulkan context with vkvg.
 *
 * Most of the vulkan rendering component (pipelines, renderpass, ..) are part of the VkvgDevice,
 * their are shared among drawing contexts.
 *
 * Antialiasing level is configured when creating the device by selecting the sample count.
 * #vkvg_device_create will create a not antialiased by selecting VK_SAMPLE_COUNT_1_BIT as sample count.
 * To create antialiased rendering device, call #vkvg_device_create_multisample with VkSampleCountFlags
 * greater than one.
 *
 * vkvg use a single frame buffer format for now: VK_FORMAT_B8G8R8A8_UNORM.
 *
 * Device holds the font cache so that each time a context draws text, the same cache is used.
 *
 * @{ */

/**
 * @brief Create a new vkvg device.
 *
 * Create a new #VkvgDevice connected to the vulkan context define by an instance,
 * a physical device, a logical device, a graphical queue family index and an index
 *
 * On success, create a new vkvg device and set its reference count to 1.
 * On error, query the device status by calling #vkvg_device_status(). Error could be
 * one of the following:
 * - VKVG_STATUS_INVALID_FORMAT: the combination of image format and tiling is not supported
 * - VKVG_STATUS_NULL_POINTER: vulkan function pointer fetching failed.
 *
 * @param inst a valid Vulkan instance to create the device from.
 * @param phy Vulkan physical device used to create the vkvg device.
 * @param vkdev Vulkan logical device to create the vkvg device for.
 * @param qFamIdx Queue family Index of the graphic queue used for drawing operations.
 * @param qIndex Index of the queue into the choosen familly, 0 in general.
 * @return The handle of the created vkvg device, or null if an error occured.
 */
vkvg_public
VkvgDevice vkvg_device_create (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex);
/**
 * @brief Create a new multisampled vkvg device.
 *
 * This function allows to create vkvg device for working with multisampled surfaces.
 * Multisampling is used to smooth color transitions in drawings, making lines not pixelised and
 * diagonal edges not stepped. Multisampling has a performance cost.
 * The final image of the surface, accessible by the user will be a resolved single sampled image.
 *
 * @param inst Vulkan instance to create the device from.
 * @param phy Vulkan physical device used to create the vkvg device.
 * @param vkdev Vulkan logical device to create the vkvg device for.
 * @param qFamIdx Queue family Index of the graphic queue used for drawing operations.
 * @param qIndex Index of the queue into the choosen familly, 0 in general.
 * @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
 * when calling @ref vkvg_surface_get_vk_image or by explicitly calling @ref vkvg_multisample_surface_resolve. If false, multisampled image is resolved on each draw operation.
 * @return The handle of the created vkvg device, or null if an error occured.
 */
vkvg_public
VkvgDevice vkvg_device_create_multisample (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve);
/**
 * @brief Decrement the reference count of the device by 1. Release all it's ressources if count reach 0.
 *
 * If device is reference by several active surfaces, calling destroy will only decrement the reference count by 1.
 * When the reference count reach 0, the vkvg device is effectively destroyed, the device pointer is freed, and
 * vulkan objects are released.
 * 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);
/**
 * @brief Increment by one the reference count on the device.
 * @param The vkvg device pointer to increment reference for.
 * @return ?
 */
vkvg_public
VkvgDevice vkvg_device_reference (VkvgDevice dev);
/**
 * @brief Get the actual reference count on this device.
 * @param dev The vkvg device to get the reference of.
 * @return The reference count on this device.
 */
vkvg_public
uint32_t vkvg_device_get_reference_count (VkvgDevice dev);
/**
 * @brief Set the screen dot per inch for this device.
 *
 * Set the current values for horizontal and vertical dot per inch of the screen for this device.
 * @param dev The vkvg device to set the dpy for.
 * @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);
/**
 * @brief Get the current dpy values.
 *
 * Get the current values for horizontal and vertical dot per inch of the screen for this device.
 * The default values for horizontal and vertical dpy on device creation is 96.
 * @param dev The vkvg device to get the dpy configuration for.
 * @param hdpy[out] The current horizontal dot per inch.
 * @param vdpy[out] The current vertical dot per inch.
 */
vkvg_public
void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdpy);
/** @}*/

/** @addtogroup surface
 * @{ */
/**
 * @brief Create a new vkvg surface.
 * @param dev The vkvg device used for creating the surface.
 * @param width Width in pixel of the surface to create.
 * @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);
/**
 * @brief Create a new vkvg surface by loading an image file.
 * The resulting surface will have the same dimension as the supplied image.
 *
 * @param dev The vkvg device used for creating the surface.
 * @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);
/**
 * @brief Create a new vkvg surface that will used an existing vulkan texture as backend.
 * @param dev The vkvg device used for creating the surface.
 * @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);
// 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);
/**
 * @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);
/**
 * @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);
/**
 * @brief Clear the surface content, alpha is also set to 0 resulting in a transparent image.
 *
 * @remark Internaly, the vulkan method used to clear the surface is the slowest, prefer using the @ref vkvg_clear
 * 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);
/**
 * @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);
/**
 * @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);
/**
 * @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);
/**
 * @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);
/**
 * @brief Write surface content to a png file on disk.
 * @param The surface to save on disk.
 * @param The png file path.
 */
vkvg_public
void 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)
 */
vkvg_public
void vkvg_surface_write_to_memory (VkvgSurface surf, unsigned char* const bitmap);
/**
 * @brief Explicitly resolve a multisampled surface.
 *
 * When creating a multisampled vkvg device with deffered resolve set to true, this function has to be
 * called to have the multisampled texture used for drawing operations resolved on the single sampled accessible
 * texture. Note that a call to @ref vkvg_surface_get_vk_image will automaticaly call this method before returning
 * the backend image.
 *
 * @param The vkvg surface to resolve.
 */
vkvg_public
void vkvg_multisample_surface_resolve (VkvgSurface surf);
/** @}*/

//mimic from cairo, to facilitate usage of vkvg as cairo vulkan backend

/**
 * @brief compositing operators
 *
 * define the operation used to draw
 */
typedef enum _vkvg_operator {
	VKVG_OPERATOR_CLEAR,

	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_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_t;

/** @addtogroup context
 * @{ */

/**
 * @brief Create a new vkvg context used for drawing on surfaces.
 * @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);
/**
 * @brief 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);
/**
 * @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);
/**
 * @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);
/**
 * @brief Perform all the pending drawing operations on a context.
 *
 * Drawing operations by a context on a surface are delayed in several cases
 * for optimisation purpose. Calling #vkvg_flush on a context ensure that
 * all possibly delayed drawing command are executed.
 * The context is automatically flushed on destruction.
 * @param ctx The vkvg context to flush.
 */
vkvg_public
void vkvg_flush (VkvgContext ctx);
/**
 * @brief Start a new empty path.
 *
 * Calling #vkvg_new_path is equivalent to a clear of the current path stored in the context
 * without drawing anything on the target surface.
 * The current position is reseted to (0,0).
 * @param ctx The vkvg context pointer.
 */
vkvg_public
void vkvg_new_path (VkvgContext ctx);
/**
 * @brief Close the current path.
 *
 * Close the last path emited for this context if its point count is greater than 2.
 * This function has no effect if the current path is empty or if its point count is less
 * than 2.
 * This function is automatically call when you try to perform a filling operation on an unclosed path.
 * @param ctx The vkvg context pointer.
 */
vkvg_public
void vkvg_close_path (VkvgContext ctx);
/**
 * @brief Start new sub path, no current point is defined
 *
 * If the current path is empty, this function has no effect.
 * @param ctx The vkvg context pointer.
 */
vkvg_public
void vkvg_new_sub_path (VkvgContext ctx);
/**
 * @brief Add a line to the current path from the current point to the coordinate given in arguments.
 *
 * After this call, the current position will be (x,y).
 * If no current point is defined, this function call is equivalent to a
 * single #vkvg_move_to command.
 * @param ctx The vkvg context pointer.
 * @param x absolute x coordinate of second point
 * @param y aboslute y coordinate of second point
 */
vkvg_public
void vkvg_line_to (VkvgContext ctx, double x, double y);
/**
 * @brief Add a line to the current path from the current point to the coordinate relative to it.
 *
 * Given a current point of (x, y), after this call the current point will be  (x + dx, y + dy).
 * If no current point is defined, this function call is equivalent to a
 * single #move_to command to the absolute position given by the x and y arguments.
 * @param ctx The vkvg context pointer.
 * @param dx delta x
 * @param dy delta y
 */
vkvg_public
void vkvg_rel_line_to (VkvgContext ctx, double dx, double dy);
/**
 * @brief Move the context pen to the position given in argument.
 *
 * This command set the current pen position of the context to the coordinate
 * given by the x and y arguments.
 * If the current path is not empty, this command will start a new
 * subpath and set the current pen position to the coordinates given in
 * arguments.
 * @param ctx The vkvg context pointer.
 * @param x new x position of the pen
 * @param y new y position of the pen
 */
vkvg_public
void vkvg_move_to (VkvgContext ctx, double x, double y);
/**
 * @brief Move the context pen relative to the current point.
 *
 * This command will set the current pen position of the context to the
 * coordinate given by the x and y deltas in arguments.
 * If the current path is not empty, this command will start a new
 * subpath and set the current pen position.
 * @param ctx The vkvg context pointer.
 * @param x delta in the horizontal direction.
 * @param y delta in the vertical direction.
 */
vkvg_public
void vkvg_rel_move_to (VkvgContext ctx, double x, double 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.
 *
 * 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.
 *
 * @remark To convert from degrees to radians, use degrees * (PI/180).
 * @param ctx The vkvg context pointer.
 * @param xc center x coordinate
 * @param xy center y coordinate
 * @param radius The radius of the arc.
 * @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, double xc, double yc, double radius, double a1, double 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.
 * If a2 is greater than a1, it will be progressively decreased by 2*PI until it is less than a1.
 *
 * See @ref vkvg_arc for more details. This function differs only in the direction of the arc between the two angles.
 * @param ctx The vkvg context pointer.
 * @param xc center x coordinate
 * @param xy center y coordinate
 * @param radius The radius of the arc.
 * @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, double xc, double yc, double radius, double a1, double a2);
/**
 * @brief Adds a cubic Bézier spline to the current path.
 *
 * Adds a cubic Bézier 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).
 * @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.
 * @param x2 The X coordinate of the second control point.
 * @param y2 The Y coordinate of the second control point.
 * @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, double x1, double y1, double x2, double y2, double x3, double y3);
/**
 * @brief Add an axis aligned rectangle subpath 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.
 */
vkvg_public
void vkvg_rectangle(VkvgContext ctx, double x, double y, double w, double h);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param x
 * @param y
 * @param w
 * @param h
 */
vkvg_public
void vkvg_fill_rectangle (VkvgContext ctx, double x, double y, double w, double h);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_stroke (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_stroke_preserve (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_fill (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_fill_preserve (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_paint (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_clear (VkvgContext ctx);//use vkClearAttachment to speed up clearing surf
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_reset_clip (VkvgContext ctx);
/**
 * @brief reset clip
 *
 * Reset current context clip regions.
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_clip (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_clip_preserve (VkvgContext ctx);

/**
 * @brief set color with alpha.
 *
 * Set current source for drawing to the solid color defined by the rgba components with 'a' for transparency.
 * @param ctx a valid vkvg #context
 * @param r the red component of the color.
 * @param g the green component of the color.
 * @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);
/**
 * @brief set color as new source.
 *
 * Set current source to the solid color defined by the rgb components.
 *
 * @param ctx a valid vkvg @ref context
 * @param r the red component of the color.
 * @param g the green component of the color.
 * @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);
/**
 * @brief set line width.
 *
 * Set the current line width for the targeted context. All further calls to #vkvg_stroke on this context
 * will use this new width.
 *
 * @param ctx a valid vkvg #context
 * @param width new current line width for the context.
 */
vkvg_public
void vkvg_set_line_width (VkvgContext ctx, double width);
/**
 * @brief set line terminations
 *
 * Configure the line terminations to output for further path stroke commands.
 * @param ctx a valid vkvg #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);
/**
 * @brief set line joins
 *
 * Configure the line join to output for further path stroke commands.
 * @param ctx a valid vkvg #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);
/**
 * @brief use supplied surface as current pattern
 *
 * set #VkvgSurface as the current context source.
 * @param ctx a valid vkvg #context
 * @param surf the vkvg surface to use as source.
 * @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);
/**
 * @brief set supplied pattern as current source.
 *
 * set #VkvgPattern as the new source for the targeted context.
 * @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);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param op
 */
vkvg_public
void vkvg_set_operator (VkvgContext ctx, vkvg_operator_t op);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param fr
 */
vkvg_public
void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr);
/**
 * @brief set the dash configuration for strokes
 *
 * Sets the dash pattern to be used by the next #vkvg_stroke().
 * A dash pattern is specified by dashes, an array of positive values.
 * Each value provides the length of alternate "on" and "off" portions of the stroke.
 * The offset specifies an offset into the pattern at which the stroke begins.
 * @param ctx a valid vkvg #context
 * @param dashes a pointer on an array of float values defining alternate lengths of on and off stroke portions.
 * @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 double* dashes, uint32_t num_dashes, double offset);
/**
 * @brief get current dash settings.
 *
 * Get the current dash configuration for the supplied #context.
 * If dashes pointer is NULL, only count and offset are returned, useful to query dash array dimension first.
 * @param ctx a valid vkvg #context
 * @param dashes[out] return value for the dash array. If count is 0, this pointer stay untouched.
 * If NULL, only count and offset are returned.
 * @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 double* dashes, uint32_t* num_dashes, double* offset);

/**
 * @brief get current line width
 *
 * This function return the current line width to use by vkvg_stroke() as set by #vkvg_set_line_width().
 * @param ctx a valid vkvg #context
 * @return current line width.
 */
vkvg_public
float vkvg_get_line_width (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @return vkvg_line_cap_t
 */
vkvg_public
vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @return vkvg_line_join_t
 */
vkvg_public
vkvg_line_join_t vkvg_get_line_join (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @return vkvg_operator_t
 */
vkvg_public
vkvg_operator_t vkvg_get_operator (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @return vkvg_fill_rule_t
 */
vkvg_public
vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @return VkvgPattern
 */
vkvg_public
VkvgPattern vkvg_get_source (VkvgContext ctx);

/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_save (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_restore (VkvgContext ctx);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param dx
 * @param dy
 */
vkvg_public
void vkvg_translate (VkvgContext ctx, float dx, float dy);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param sx
 * @param sy
 */
vkvg_public
void vkvg_scale (VkvgContext ctx, float sx, float sy);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param radians
 */
vkvg_public
void vkvg_rotate (VkvgContext ctx, float radians);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param matrix
 */
vkvg_public
void vkvg_transform (VkvgContext ctx, const vkvg_matrix_t* matrix);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param matrix
 */
vkvg_public
void vkvg_set_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param matrix
 */
vkvg_public
void vkvg_get_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix);
/**
 * @brief Reset the current transformation matrix of the provided context to the identity matrix.
 *
 * @param ctx a valid vkvg #context
 */
vkvg_public
void vkvg_identity_matrix (VkvgContext ctx);

/**
 * @brief Try find font with the specified name using the FontConfig library.
 *
 * @param ctx a valid vkvg #context
 * @param name A name to be recognized by the FontConfig library
 */
vkvg_public
void vkvg_select_font_face (VkvgContext ctx, const char* name);
/**
 * @brief Select a new font by providing its file path.
 *
 * @param ctx a valid vkvg #context
 * @param name A valid font file path.
 */
vkvg_public
void vkvg_select_font_path (VkvgContext ctx, const char* path);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param size
 */
vkvg_public
void vkvg_set_font_size (VkvgContext ctx, uint32_t size);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param text
 */
vkvg_public
void vkvg_show_text (VkvgContext ctx, const char* text);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param text
 * @param extents
 */
vkvg_public
void vkvg_text_extents (VkvgContext ctx, const char* text, vkvg_text_extents_t* extents);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param 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.
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param text
 * @return VkvgText
 */
vkvg_public
VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text);
/**
 * @brief
 *
 * @param textRun
 */
vkvg_public
void vkvg_text_run_destroy (VkvgText textRun);
/**
 * @brief
 *
 * @param ctx a valid vkvg #context
 * @param 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);
/** @}*/

/**
 * @defgroup pattern Pattern
 * @brief special sources for drawing
 *
 * A Pattern is a special source for drawing operations that can be an image, a gradient
 * and which may have special configuration for filtering and border repeat.
 *
 * @{ */

/**
 * @brief add reference
 *
 * increment reference count by one for the supplied #VkvgPattern.
 * @param pat a valid #VkvgPattern pointer
 * @return VkvgPattern
 */
vkvg_public
VkvgPattern vkvg_pattern_reference (VkvgPattern pat);
/**
 * @brief get reference count
 *
 * return the current reference count for the supplied #VkvgPattern
 * @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);
/**
 * @brief create a surface pattern
 *
 * Create a new pattern from the supplied #surface. The advantage of having
 * a #VkvgPattern to paint an image resides in the hability to set filtering options
 * as well as repeat behaviour on borders. Reference count of the supplied surface will
 * be incremented so that it will not be destroyed before this pattern release it.
 * @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);
/**
 * @brief
 *
 * @param x0
 * @param y0
 * @param x1
 * @param y1
 * @return VkvgPattern
 */
vkvg_public
VkvgPattern vkvg_pattern_create_linear (float x0, float y0, float x1, float y1);
/**
 * @brief
 *
 * @param cx0
 * @param cy0
 * @param radius0
 * @param cx1
 * @param cy1
 * @param radius1
 * @return VkvgPattern
 */
vkvg_public
VkvgPattern vkvg_pattern_create_radial (float cx0, float cy0, float radius0,
											 float cx1, float cy1, float radius1);
/**
 * @brief
 *
 * @param pat
 */
vkvg_public
void vkvg_pattern_destroy (VkvgPattern pat);
/**
 * @brief
 *
 * @param pat
 * @param offset
 * @param r
 * @param g
 * @param b
 * @param a
 */
vkvg_public
void vkvg_pattern_add_color_stop (VkvgPattern pat, float offset, float r, float g, float b, float a);
/**
 * @brief
 *
 * @param pat
 * @param extend
 */
vkvg_public
void vkvg_pattern_set_extend (VkvgPattern pat, vkvg_extend_t extend);
/**
 * @brief
 *
 * @param pat
 * @param filter
 */
vkvg_public
void vkvg_pattern_set_filter (VkvgPattern pat, vkvg_filter_t filter);
/**
 * @brief
 *
 * @param pat
 * @return vkvg_extend_t
 */
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);
/** @}*/


#ifdef __cplusplus
}
#endif

#endif