aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/obm/ObmW/inkstore.h
blob: 147e7d529f504c2fcfd9c204bc00a5617172a87d (plain) (blame)
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
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
/*--------------------------------------------------------------------------
** File: inkstore.h
**
** Copyright 1993, Slate Corporation, All Rights Reserved.
**
** This document is part of the Jot specification for the storage and
** interchange of electronic ink data.  This specification is the joint work
** of representatives of Slate Corporation, Lotus Development Corporation,
** GO, Microsoft, Apple, General Magic, and others.
**
** This document and the accompanying code samples on disk comprise Version 
** 1.0 of the Jot specification for the storage and interchange of electronic 
** ink data.  Permission is granted to incorporate and otherwise use any 
** portion of the specification.  You may make copies of the specification 
** for distribution to others, provided you include the notice "Copyright 
** 1993, Slate Corporation.  All Rights Reserved" on both the document and
** the disk label.  You may not modify this specification without written 
** permission from Slate Corporation.
**
** The specification is provided "as is" without warranty of any kind.  Slate 
** further disclaims all implied warranties of merchantability or of fitness 
** for a particular purpose.  The entire risk arising out of the use or 
** performance of the specification remains with you.
**
**--------------------------------------------------------------------------
**
** This is the main body of definitions for the ink storage specification.
** See reference section 1.0 for revision history.
**
**------------------------------------------------------------------------*/

#ifndef INKSTORE_INCLUDED
#define INKSTORE_INCLUDED




/*************************/
/* REFERENCE SECTION 0.0 */
/*************************/

/*--------------------------------------------------------------------------
** "Rationale for the ink specification"
**
** This document defines a storage and interchange format for embedded ink
** data.  The format is device- and platform-independent.  The goal is to
** provide application programs on the same and different platforms and
** operating systems a way to store and exchange ink data.  Thus a PenPoint
** user might scribble a note and send the untranslated ink as part of an
** e-mail message to a colleague's pen computer running Windows for Pen
** Computing using Magic Mail.
**
** This specification is for a publicly-defined, external format for
** electronic ink data interchange, and neither assumes nor dictates the
** nature of how the application deals with ink data internally.  The format
** is not intended to be the "internal" ink format of an application, though
** there is no reason why it could not serve such a purpose. 
**
** The scope and goals of this format design are limited to the represent-
** ation of electronic ink data embedded in some other electronic document, 
** not to the larger document itself (such as an e-mail or enhanced word-
** processing data file).
**
** The approach taken is to capture the complete user input for the
** electronic ink, including not just X/Y coordinates, but also a large set
** of current drawing attributes such as nib type and ink color.  This
** differs from other possible approaches, such as those based on certain
** recognition models for handwritten text, which require decomposing the
** handwritten ink data first into a set of pre-defined approximation curves
** or sub-strokes, and then storing a list of encodings of these sub-strokes.
** In other words, Jot preserves all information about the original input as
** opposed attempting any sort of abstract characterization of the input.
** 
** The storage format has a number of properties:
** 
** * Simple.  Typical operations on the ink data are easy.  If you only wish
**   to read stroke coordinates and bounding information from the data,
**   complex information that might be present will not hinder the process.
**   Likewise, it is easy to write out just simple information.  The
**   complex information is all optional.
** 
** * Compact.  The storage format is intended to be as compact as possible 
**   without sacrificing simplicity or fidelity.  Optional information such
**   as time stamps or color specifications occupy space only when they are
**   present.  Specifications that apply to many strokes (such as line width
**   or color) are represented just once.
** 
** * Compression.  The stroke information that describes the ink can
**   optionally be represented in a compressed format.  Compression
**   techniques include both compression and reduction of the ink data.
** 
** * Inclusive.  The format is capable of storing every property of ink
**   conceivable as of today.  
** 
** * Expandable and Compatible.  The format is expandable, so as developers
**   discover new information that should be recorded in an ink storage
**   format, these new features can be added without changing the behavior of
**   existing application programs working with an older version of the
**   format.  In general, new features can generally be ignored by
**   applications reading older versions of the format.  Likewise, new
**   application programs can handle previous versions of the format without
**   special work.
** 
** The format is not designed to easily support lots of in-memory
** manipulation of the ink data, such as deleting strokes, changing line
** widths, and so on.  A format supporting these types of manipulations would
** be at odds with the above goals.  All the information needed to perform
** these manipulations is present in this data format, so an application
** might augment this format to facilitate manipulation of the ink data.
** 
** Applications are likely to use some other format internally for real-time
** ink manipulation.  Many operating environments provide some internal means
** for storing and manipulating ink data, the details of which may be hidden
** to some extent from the application designer.  Many such real-time data
** structures store fewer types of and/or less information (such as not
** preserving information about the tablet point data rate) than are covered
** in this definition.  
**
**------------------------------------------------------------------------*/




/*************************/
/* REFERENCE SECTION 1.0 */
/*************************/

/*-------------------------------------------------------------------------
** Jot Ink Specification
** ---------------------
**
** Revision History:
**
** March    16, 1992 - First public draft.
** July     13, 1992 - Major rewrite to put data into a series of records.
** July     19, 1992 - Inclusion of ink-compacting definitions.
** July     30, 1992 - Change of target rect to offset.
** December 28, 1992 - Changes incorporated from August 1992 review meeting.
** February 12, 1993 - Incremental fixes due to coding experience.
** March    13, 1993 - Revised definition of a "group".
** April    12, 1993 - Release of version 0.99 of the specification.  Moved
**                     reference sections 28 and 29 to a separate file called
**                     sample.h
** May      01, 1993 - Release of version 1.00 of the specification.  
**                     Changed INK_OFFSET_RECORD units from twips to pen 
**                     units for consistency and ease of implementation.
**                     Fixed a typo in reference section 26.0 in the diagram.
**                     The text accompanying the diagram was correct.
**                     Fixed a typo in reference section 27.0.  The old text
**                     "delta-X == 0 or 1" was replaced with the correct text
**                     "delta-X == 2".  The accompanying diagram was correct.
**                     Removed all sizeof() constructs and replaced with 
**                     appropriate #defines to reduce compiler dependencies.
**                     Tagged all struct definitions with tag_ prefix.
**                     Added comments and reordered some existing comments.
** May      17, 1993 - Added a few more _SIZE #defines, clarified reserved
**                     values.
**
**
** GENERAL NOTES
** -------------
**
**
** Record Structure
** ----------------
**
** If not otherwise specified, all words are stored in Intel order: low-order
** word first, then high-order word, and inside of a word,  low-order byte,
** then high-order byte.  For example, a 32 bit quantity 0x12345678 would be
** written to the file as 0x78 0x56 0x34 0x12.  The notable exception is the
** storage of point data in "standard compression" format.  Sign bits are
** used to indicate item types, so the bytes are stored high-order to low-
** order (exactly opposite).  See the sample code and reference section 23.0
** for more information on the compressed format.  Uncompressed data is 
** written in Intel order.
**
** All structures are packed for the purposes of writing to a stream.
** 
** Signed integer values are two's-complement.  Rectangles are stored 
** x,y,w,h.
**
** These definitions are intended to insulate the sample ink compaction and
** storage code from any possible variation in item alignment or structure
** packing across architectures.  The only possible area of portability
** concern lies in the use of unions in colors (see 11.0) and pen tips (see
** 14.0).
**
** Any use of units of mass to denote units of force ("grams of force"), or
** similar common misuses of physical units, are noted here with an apology
** to any purists, and should be interpreted in the common way by assuming
** one standard gravity.
**
** Record Sequence
** ---------------
**
** In this document, one piece of ink data is called an ink bundle. 
** Typically this might correspond to the strokes that make up the ink from
** the time when the pen touches down until the user finishes writing
** (usually determined by a timeout or the pen leaving proximity).  Thus an
** ink bundle usually contains many ink strokes, and the strokes do not have
** to describe a continuous line of ink.
** 
** As stated in reference section 5.0, all data conforming to this
** specification appears as a stream of ink bundles each of which must begin
** with an INK_BUNDLE_RECORD and end with an INK_END_RECORD.  There may be
** more than one INK_BUNDLE_RECORD/INK_END_RECORD pair in a given stream.
** A record stream might look something like this:
**
** INK_BUNDLE_RECORD       required    // for bundle number one
** INK_SCALE_RECORD        optional    // sets the scale for rendering
** INK_OFFSET_RECORD       optional    // sets the offset for rendering
** INK_COLOR_RECORD        optional    // sets the color for rendering
** INK_START_TIME_RECORD   optional    // sets the relative start time
** INK_PENTIP_RECORD       optional    // sets the pentip for rendering
** INK_GROUP_RECORD        optional    // tags the following PENDATA
** INK_PENDATA_RECORD      recommended // actual points
** INK_GROUP_RECORD        optional    // tags the following PENDATA
** INK_PENDATA_RECORD      recommended // actual points 
** INK_PENDATA_RECORD      recommended // more points in same group
** INK_SCALE_RESET_RECORD  optional    // resets to default scaling/offset
** INK_PENDATA_RECORD      recommended // actual points
** INK_END_TIME_RECORD     optional    // relative time inking ended
** INK_END_RECORD          required    // end of bundle number one
**
** It is perfectly reasonable to write out only the following (though doing
** so will cause the ink to be rendered in a completely default manner -- 
** black hairline width at 1:1 scaling with offset 0):
**
** INK_BUNDLE_RECORD
** INK_PENDATA_RECORD
** INK_END_RECORD
** 
**
** Specification Revisions
** -----------------------
** 
** Future enhancements to this specification may modify certain record types.
** It is guaranteed that any record modified in a subsequent revision of the 
** specification will be a strict superset of that record's definition in any
** previous revision of the specification.  That is, modified record types 
** will only be lengthened, not shortened.  If a particular record type must
** be extended such that it would not be a superset of the original, a new 
** record type would be added to cover that particular extension.
** 
** This extension strategy has two important ramifications: 
**
** 1) A reading application should *ALWAYS* use the size of a record as 
**    recorded in the record structure itself (i.e., the recordLength field
**    of the INK_RECORD_HEADERx structure) rather than the sizeof() or any
**    other size determined at compile time to determine how may bytes to 
**    read as the data structures are parsed.  This is due to the fact that 
**    a record may grow in a future revision of the standard.  The only
**    exception to this rule is the INK_BUNDLE_RECORD which contains a
**    version number that will be modified with each change to that record.
**    If an INK_BUNDLE_RECORD is encountered and its version matches the
**    version used at compile time, the size of the record should exactly
**    match the #define of inkRecordBundleSize.
**
** 2) Any particular record may be read into a target data structure up to 
**    the size of the target data structure and the rest may be ignored.  
**    This is due to the 'strict superset' rule which means that any 
**    extension of any record type must leave the meaning, content, and size
**    of any existing fields as is.  So, for example, if an INK_SCALE_RECORD
**    was modified by adding 2 bytes, the reading application can safely read
**    the data into the INK_SCALE_RECORD known at compile time and throw
**    away the extra two bytes: the header, x, and y will be in the same 
**    place and will have the same meaning.
**
** 
** Files of Ink
** ------------
**
** It is a recommended practice on DOS and UNIX style file systems to use the
** extension ".JOT" for files consisting solely of ink recorded according to
** this specification.  The specification is designed such that ink data can
** be embedded inside any file format and if such a file contains more than
** strictly ink data, it should not use the .JOT extension.
**
**------------------------------------------------------------------------*/




/*************************/
/* REFERENCE SECTION 2.0 */
/*************************/

/*-------------------------------------------------------------------------
** Definitions used in this header.
**
** These definitions must be defined appropriately to the target environment
** and compiler.
**
** For example, on some compilers for environments using segmented addressing
** and 64K segments sizes, the correct definition of FAR would be "_huge",
** rather than "_far", because the objects pointed to may be larger than 64K.
**
** In particular, check the definitions of FAR, U32, and S32 for
** compatibility with your compiler, environment, and memory model.
**
**------------------------------------------------------------------------*/

#ifndef FAR
#define FAR
#endif

/* useful constants */

#define flag0           (0x0001)
#define flag1           (0x0002)
#define flag2           (0x0004)
#define flag3           (0x0008)
#define flag4           (0x0010)
#define flag5           (0x0020)
#define flag6           (0x0040)
#define flag7           (0x0080)
#define flag8           (0x0100)
#define flag9           (0x0200)
#define flag10          (0x0400)
#define flag11          (0x0800)
#define flag12          (0x1000)
#define flag13          (0x2000)
#define flag14          (0x4000)
#define flag15          (0x8000)

#define flag16          (0x00010000L)
#define flag17          (0x00020000L)
#define flag18          (0x00040000L)
#define flag19          (0x00080000L)
#define flag20          (0x00100000L)
#define flag21          (0x00200000L)
#define flag22          (0x00400000L)
#define flag23          (0x00800000L)
#define flag24          (0x01000000L)
#define flag25          (0x02000000L)
#define flag26          (0x04000000L)
#define flag27          (0x08000000L)
#define flag28          (0x10000000L)
#define flag29          (0x20000000L)
#define flag30          (0x40000000L)
#define flag31          (0x80000000L)

#define TRUE    1
#define FALSE   0

/* void pointers */
typedef void        FAR *P_UNKNOWN;
typedef P_UNKNOWN   FAR *PP_UNKNOWN;

#define pNull       ((P_UNKNOWN)0)

/*  Unsigned integers */
typedef unsigned char   U8,  FAR *P_U8;
#define U8_SIZE         1
typedef unsigned short  U16, FAR *P_U16;
#define U16_SIZE        2
typedef unsigned long   U32, FAR *P_U32;
#define U32_SIZE        4

/*  Signed integers */
/*
typedef signed char     S8,  FAR *P_S8;
#define S8_SIZE         1
typedef signed short    S16, FAR *P_S16;
#define S16_SIZE        2
typedef signed long     S32, FAR *P_S32;
#define S32_SIZE        4
 */
typedef char     	S8,  FAR *P_S8;
#define S8_SIZE         1
typedef short   	 S16, FAR *P_S16;
#define S16_SIZE        2
typedef long    	 S32, FAR *P_S32;
#define S32_SIZE        4

/* geometry structures */
typedef struct tag_XY32 {
    S32     x;
    S32     y;
} XY32, FAR *P_XY32;
#define XY32_SIZE (S32_SIZE+S32_SIZE)

typedef struct tag_XY16 {
    S16     x;
    S16     y;
} XY16, FAR *P_XY16;

/*-------------------------------------------------------------------------
** Note: 
** Angles from vertical can exceed +-90 degrees: in this case, the "back" end
** of the stylus is nearer the tablet surface than the "front" end.
**-------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------
** Note: 
** Standard compaction will normally store angles in nibbles, or single 
** bytes, rather than in four-byte records.
**-------------------------------------------------------------------------*/

typedef struct tag_ANGLE16 {
    S16     theta;  /* "X" angle of the stylus, degrees from vertical, */
                    /* increasing in the positive "X" direction. */
    S16     phi;    /* "Y" angle of the stylus. */
} ANGLE16, FAR *P_ANGLE16;
#define ANGLE16_SIZE (S16_SIZE+S16_SIZE)

typedef struct tag_SIZE32 {
    S32     w;
    S32     h;
} SIZE32, FAR *P_SIZE32;
#define SIZE32_SIZE (S32_SIZE+S32_SIZE)

typedef struct tag_SIZE16 {
    S16     w;
    S16     h;
} SIZE16, FAR *P_SIZE16;
#define SIZE16_SIZE (S16_SIZE+S16_SIZE)

/*-------------------------------------------------------------------------
** Note:
** A rect where xmin==xmax and ymin==ymax has a size of zero:
** size.w and size.h are both zero.
**-------------------------------------------------------------------------*/

typedef struct tag_RECT32 {
    XY32    origin;
    SIZE32  size;
} RECT32, FAR *P_RECT32;
#define RECT32_SIZE (XY32_SIZE+SIZE32_SIZE)

typedef U32 FIXED_FRACTION; /* fixed point value, unity = 0x00010000 */
#define FIXED_FRACTION_SIZE U32_SIZE

#define INK_UNITY_SCALE ((U32) 0x00010000L)




/*************************/
/* REFERENCE SECTION 3.0 */
/*************************/

/*-------------------------------------------------------------------------
** A block of ink data is called an ink bundle.  Each ink bundle consists of
** a series of n records.  Each record has a common header that indicates the
** record type and the record length.  An ink bundle always starts with an
** INK_BUNDLE_RECORD and always ends with an INK_END_RECORD.
**
** Any records of unknown type can be skipped by simply reading the length of
** the record.
**
** Note:
** Within an ink bundle, time increases.  This implies a drawing order of
** back-to-front.  Between adjacent sequential bundles, the implicit drawing
** is also back-to-front.
**
** A number of record types are defined.  The most common is the
** inkRecordPenData which contains the actual pen data.  Other records are
** mostly attributes of the pen data and are optional.  They will, in
** general, only be present when a given attribute changes to something
** different than the default value for that attribute.
**
** In order to have the most compact format and also allow large records,
** several different record headers are defined, each with a different
** length.
**
** The top two bits of the record type indicate what kind of record length
** follows:
**
** The record length can be:
**
**  -   non-existent (the entire record consists of just the recordType)
**  -   An 8 bit length (one byte) for records up to 255 bytes
**  -   A 16 bit length (two bytes) for records up to 64k
**  -   A 32 bit length (four bytes) for really big records
**
**------------------------------------------------------------------------*/

#define inkRecordNoLength                  0    /* no length, just recordType */
#define inkRecordLength8              flag14    /* 8 bit length */
#define inkRecordLength16    flag15             /* 16 bit length */
#define inkRecordLength32   (flag15 | flag14)   /* 32 bit length */

/* useful defines for isolating or clearing the length type bits */
#define inkRecordLengthMask (flag15 | flag14)   /* mask for length bits */
#define inkRecordLengthClearMask (~inkRecordLengthMask)

/* some useful macros for declaring the various types of record types */
#define MakeRec0(recType)   (recType | inkRecordNoLength)   /* no rec length */
#define MakeRec8(recType)   (recType | inkRecordLength8)    /* 8 bit length */
#define MakeRec16(recType)  (recType | inkRecordLength16)   /* 16 bit length */
#define MakeRec32(recType)  (recType | inkRecordLength32)   /* 32 bit length */

typedef U16 INK_RECORD_TYPE, FAR *P_INK_RECORD_TYPE;
#define INK_RECORD_TYPE_SIZE U16_SIZE

#define inkRecordHeaderLength(record_type)  \
    (   (((record_type) & inkRecordLength32) == inkRecordNoLength) ?\
                    INK_RECORD_TYPE_SIZE                            \
     :  (((record_type) & inkRecordLength32) == inkRecordLength8)  ?\
                    INK_RECORD_TYPE_SIZE+U8_SIZE                    \
     :  (((record_type) & inkRecordLength32) == inkRecordLength16) ?\
                    INK_RECORD_TYPE_SIZE+U16_SIZE                   \
     :              INK_RECORD_TYPE_SIZE+U32_SIZE                   \
    )

/*-------------------------------------------------------------------------
** Note: most compilers will not generate code for the above macro but will 
** determine the proper value at compile time.
**-------------------------------------------------------------------------*/


/*************************/
/* REFERENCE SECTION 4.0 */
/*************************/

/*-------------------------------------------------------------------------
** These are all the currently defined record types.  The macro MakeRecX()
** encodes the right bits in with the record Id to define its recordLength.
**
** For simplicity, recType values may not be repeated for different
** INK_RECORD_TYPEs.  Use of a record type defined as MakeRec32(63) thus
** forbids the use of a record type defined as MakeRec16(63), MakeRec8(63),
** or MakeRec0(63).
**
** Record type 63 is reserved explicitly for possible future extension beyond
** 63 record types.
**
**------------------------------------------------------------------------*/

#define inkRecordEnd             MakeRec0(  0) /* end of bundle */
#define inkRecordBundle          MakeRec8(  1)
#define inkRecordPenData         MakeRec32( 2)
#define inkRecordScale           MakeRec8(  3)
#define inkRecordScaleReset      MakeRec0(  4)
#define inkRecordColor           MakeRec8(  5)
#define inkRecordTip             MakeRec8(  6)
#define inkRecordGroup           MakeRec8(  7)
#define inkRecordOffset          MakeRec8(  8)
#define inkRecordStartTime       MakeRec8(  9)
#define inkRecordEndTime         MakeRec8( 10)
#define inkRecordPointsPerSecond MakeRec8( 11)
#define inkRecordUnitsPerZ       MakeRec8( 12)
#define inkRecordUnitsPerForce   MakeRec8( 13)

/* Record types 14 .. 61 are reserved for future definition. */

#define inkRecordApp             MakeRec32(62) /* application-specific records*/
#define inkRecordExt             MakeRec32(63) /* reserved for extension */

/*-------------------------------------------------------------------------
** Every record starts with a header that contains the recordType and the
** recordLength.  The recordType indicates the type of data here.  The
** recordLength indicates the total length of all the data for the record
** (including the size of the header).
**-------------------------------------------------------------------------*/

/* no recordLength */
typedef struct tag_INK_RECORD_HEADER0 {
    INK_RECORD_TYPE     recordType;
} INK_RECORD_HEADER0, FAR *P_INK_RECORD_HEADER0;

/* 8 bit recordLength */
typedef struct tag_INK_RECORD_HEADER8 {
    INK_RECORD_TYPE     recordType;
    U8                  recordLength;
} INK_RECORD_HEADER8, FAR *P_INK_RECORD_HEADER8;

/* 16 bit recordLength */
typedef struct tag_INK_RECORD_HEADER16 {
    INK_RECORD_TYPE     recordType;
    U16                 recordLength;
} INK_RECORD_HEADER16, FAR *P_INK_RECORD_HEADER16;

/* 32 bit recordLength */
typedef struct tag_INK_RECORD_HEADER32 {
    INK_RECORD_TYPE     recordType;
    U32                 recordLength;
} INK_RECORD_HEADER32, FAR *P_INK_RECORD_HEADER32;




/*************************/
/* REFERENCE SECTION 5.0 */
/*************************/

/*-------------------------------------------------------------------------
** A bundle of ink consists of an INK_BUNDLE_RECORD, a series of records,
** terminated with an INK_END_RECORD.
**
** An INK_BUNDLE_RECORD, along with a matching INK_END_RECORD, are the
** mandatory records in the format.  The ink data must start with an
** INK_BUNDLE_RECORD.
**
** It is suggested that anyone reading this format do a number of validity
** checks on the first record in any ink data.  The first record should meet
** the following minimum requirements:
**
** 1)   header.recordType == INK_RECORD_BUNDLE
** 2)   header.recordLength >= inkRecordBundleSize (See general notes in 
**      reference section 1.0 for important information about record sizes.)
** 3)   compactionType is an expected and supported value
** 4)   penUnitsPerX and penUnitsPerY seem reasonable and expected:
**      greater than, say, 1000 units per meter (25.4/inch), less than, say,
**      400,000 (~10,000 units per inch)
**
**------------------------------------------------------------------------*/

typedef struct tag_INK_END_RECORD {
    INK_RECORD_HEADER0  header;         /* value is inkRecordEnd */
} INK_END_RECORD, FAR *P_INK_END_RECORD;
#define inkRecordEndSize     (inkRecordHeaderLength(inkRecordEnd))




/*************************/
/* REFERENCE SECTION 6.0 */
/*************************/

/*-------------------------------------------------------------------------
** The terms compression and compaction are used somewhat interchangeably
** in this specification but they actually have slightly different meanings
** and are both supported to a certain extent by Jot.
**
** Compression refers to a technique of encoding data such that the resuling
** data, while smaller, is still whole.  That is, compression under Jot is
** loss-less.  Compaction refers to a process where certain pieces of less
** important data are actually omitted from the stream and are possibly
** reconstructed by the reader of the data.  
**
** Using Jot, a writing application may choose to compress only, compact only
** or use some combination.  The standard compression mechanism defined here
** and implemented in the sample code supports both notions.
**
**------------------------------------------------------------------------*/

typedef U8 INK_COMPACTION_TYPE, FAR *P_INK_COMPACTION_TYPE;
#define INK_COMPACTION_TYPE_SIZE U8_SIZE
#define inkNoCompression            (0)
#define inkStdCompression           (1)

/*-------------------------------------------------------------------------
** Other compression schemes may be adopted in future revisions of this
** specification.
**-------------------------------------------------------------------------*/




/*************************/
/* REFERENCE SECTION 7.0 */
/*************************/

/*-------------------------------------------------------------------------
** The INK_BUNDLE_FLAGS contain some flags that apply to an entire bundle. 
** If you wanted to store several pieces of ink that had different
** INK_BUNDLE_FLAGS, you would do it by storing several different bundles.
**
** Advisory flags:
**
** inkPointsRemoved         
**      Indicates whether all original points are still present or whether
**      some points were removed to save space.  For applications that are
**      only interested in the visual aspects of ink, many points can be
**      removed that do not affect the appearance (i.e. duplicate points,
**      collinear points, points which deviate less than some screen
**      resolution, etc..).  Some other types of applications must know that
**      points are present at some consistent sampling rate (i.e. some forms
**      of handwriting translation).  This flag indicates whether all
**      original points are still there.
**
**      Note:
**      The purpose of "inkPointsRemoved" is to indicate that the timing
**      information cannot be accurately derived by counting points:
**      replacing individual points with an "elided point" item does not
**      constitute removing points. ("Elided" means omitted or skipped).
**
** inkProxDataRemoved   
**      Indicates that the original points between strokes (proximity) were
**      removed to save space.  An out-of-prox point should be stored between
**      strokes to delimit them.  Some applications depend on knowing the
**      time between strokes or at the ends of strokes for certain
**      functions. 
**
**      Note:
**      "Proximity" is defined as the stylus being close enough to the tablet
**      for the tablet to report the stylus position, although perhaps at
**      lower accuracy and perhaps at a lower number of points per second.  A
**      recommended practice is to include "out of proximity" points in the
**      recorded ink data when they are used as part of determining the
**      amount of time a stylus was out of contact with the tablet, or for
**      triggering the completion of an action such as a "gesture". 
**
** inkStrokeLimitsPresent   
**      Indicates that INK_BUTTONS items are also present, and that they
**      indicate what the storing app decided the stroke start/end points
**      were. (Note: the reading application may otherwise use a different
**      algorithm for using tip force values to delimit strokes.) 
**
**      Note:
**      If inkStrokeLimitsPresent is set, then inkButtonDataPresent must also
**      be set. 
**
** Data flags:
**
**  inkAngleDataPresent     indicates angle data is present.
**  inkForceDataPresent     indicates force data is present.
**  inkProxDataPresent      indicates points are present when pen is lifted
**                          up (i.e. the force drops below some threshold).
**  inkRotationDataPresent  indicates pen rotation data is present.
**  inkHeightDataPresent    indicates pen height data is present.
**  inkButtonDataPresent    indicates "button state" information is present.
**  inkPreMultiplyScale     indicates that scaling should be applied before
**                          the offset value is added ("pre-multiply")
**                          rather than after ("post-multiply")
**
** Note: 
** A previous draft version included a provision for compacting data to an
** approximation based on Bezier curves.  Initial results did not show
** promise in terms of efficiency and performance.
**
** "inkBezierRepresentation" would have indicated that the X/Y ordinates
** reflected a Bezier approximation to the original tablet data.  This would
** have meant that the ordinate data represented aggregates of anchor points
** and control points for each piece wise approximation, and therefore could
** not be used directly to render the data.  The definition of these anchor
** and control points, and the example code for the approximation and
** regeneration of the "true" coordinates could not be worked out at this
** time. 
**
** Some standard values for pen units per meter follow:
**
** 1000 points per inch digitizer == 39370 pen units per meter
**  500 points per inch digitizer == 19685 pen units per meter
**  200 points per inch digitizer ==  7874 pen units per meter
**  254 points per inch (1/10 mm) == 10000 pen units per meter
**
** 1000 pen units per meter is a reasonable minimum; 400,000 is a reasonable
** maximum value.
**
** The specific format for each of these types of data is described in the
** INK_PENDATA_RECORD documentation (reference section 8.0).
** 
** Note:
** The order in which these flags are defined has nothing to do with the
** order in which the data appears in the INK_POINT structure when reading
** or writing point data.  For more information, see reference section 21.0.
**
**------------------------------------------------------------------------*/

typedef U16 INK_BUNDLE_FLAGS, FAR *P_INK_BUNDLE_FLAGS;
#define INK_BUNDLE_FLAGS_SIZE U16_SIZE
#define inkPointsRemoved            (flag0)
#define inkProxDataRemoved          (flag1)
#define inkAngleDataPresent         (flag2)
#define inkForceDataPresent         (flag3)
#define inkRotationDataPresent      (flag4)
#define inkHeightDataPresent        (flag5)
#define inkButtonDataPresent        (flag6)
#define inkStrokeLimitsPresent      (flag7)
#define inkPreMultiplyScale         (flag8)

/*-------------------------------------------------------------------------
** Reserved: flag9, flag10, flag11, flag12, flag13, flag14, flag15.
** More flags beyond flag15 can be added in a new record type
** in a later revision to this specification.
**-------------------------------------------------------------------------*/


typedef struct tag_INK_BUNDLE_RECORD {
    INK_RECORD_HEADER8      header;         /* value is inkRecordBundle */
    U8                      version;        /* Value for release 1.0 is 1 */
    INK_COMPACTION_TYPE     compactionType;
    INK_BUNDLE_FLAGS        flags;          /* flags for the whole bundle */
    U32                     penUnitsPerX;   /* pen units per meter (x dir) */
    U32                     penUnitsPerY;   /* pen units per meter (y dir) */
} INK_BUNDLE_RECORD, FAR *P_INK_BUNDLE_RECORD;

#define inkPointDefaultVersion          (1)
#define inkPointDefaultCompactionType   (inkStdCompression)
#define inkPointDefaultBundleFlags      (0)
#define inkPointDefaultPenUnitsPerX     (1000)
#define inkPointDefaultPenUnitsPerY     (1000)

#define inkRecordBundleSize \
    (inkRecordHeaderLength(inkRecordBundle) +  U8_SIZE + \
     INK_COMPACTION_TYPE_SIZE + INK_BUNDLE_FLAGS_SIZE +       \
     U32_SIZE + U32_SIZE)




/*************************/
/* REFERENCE SECTION 8.0 */
/*************************/

/*-------------------------------------------------------------------------
** A penData record contains the actual pen data for one or more pen strokes.
** The bounds applies to all the strokes contained within this record. 
** Multiple strokes are typically grouped into one record to increase the
** efficiency of the compression algorithm, though strokes may be stored
** individually, if desired.
**
** The bounds is the pure mathematical bounds of the raw pen points and does
** not take into account any rendering information such as the pen tip or the
** line width.  All points in the INK_PENDATA have been normalized relative
** to the lower bounds in the INK_PENDATA header.
**
** Some applications will prefer to know the bounds of individual strokes.
** This can be accomplished in two ways.
**
** 1) The bounds for a given stroke can be computed when reading the file
**    by decompressing an INK_PENDATA_RECORD into its strokes and then
**    traversing the points in each stroke to build the bounds for each
**    stroke.
**
** 2) An application can decide to store only one stroke per
**    INK_PENDATA_RECORD (and thus the bounds of the PENDATA_RECORD is
**    already the bounds of one stroke).  The sacrifice here is in
**    compression efficiency and the need to still support reading files
**    written by other applications that might group multiple strokes
**    into a single INK_PENDATA_RECORD.
**
** Note: 
** In practice, our experience is that unpacking the data in order to compute
** the bounds for each stroke to check for strokes that intrude into a given
** region is not an excessive burden.  The checks that would have been done
** on the bounds of each stroke can be done on the builds for each penData
** group, and not all strokes must be checked individually.
**
** The format of the pen data is determined by the settings for
** compactionType and flags in the INK_BUNDLE_RECORD structure, and
** is described later in this file.  Two formats are currently defined:
** an uncompacted format and a delta-encoded compacted format, both with
** optional components present or absent depending on the state of the flags
** in the INK_BUNDLE_RECORD.
**
**------------------------------------------------------------------------*/

typedef struct tag_INK_PENDATA_RECORD {
    INK_RECORD_HEADER32 header;     /* value is inkRecordPenData */
    RECT32              bounds;
    U8                  inkData[1]; /* ink data goes here: definitions */
                                    /* follow later in this file. */
} INK_PENDATA_RECORD, FAR *P_INK_PENDATA_RECORD;
#define inkRecordPenDataSize(data_length)   \
   (inkRecordHeaderLength(inkRecordPenData) +  RECT32_SIZE + (data_length))




/*************************/
/* REFERENCE SECTION 9.0 */
/*************************/

/*-------------------------------------------------------------------------
** Ink scale is recorded in two fixed point values.  A unity scale (scale
** of one) is represented as 0x00010000, a scale of 0.5 as 0x00008000.
**
** Note:
** All ink is located relative to the lower-left (0,0) corner of a logical 
** page or window.  Scale and offset operations are cumulative, much in the 
** same way as in PostScript.  One begins with a normalized graphics state
** and sequentially applies the scale and offset operations to that matrix. 
** The INK_SCALE_RESET record returns the graphics state to its default state
** (i.e., the transformation matrix is set to an identity matrix and the
** offset is reset to the default of 0).  By default, scaling is applied
** after adding in any offset specified in an INK_OFFSET_RECORD.  If the ink
** bundle has the inkPreMultiplyScale bit set, for all ink in that bundle
** scaling is applied before adding in any offset.
** 
** As used in this format, ink scale and offset values are set by the storing
** application, to be applied by the rendering application.  If the storing
** application collected the ink at scales of (2.0,2.0), the storing
** application should insert an INK_SCALE_RECORD with a scale of (0.5,0.5)
** for the rendering application to multiply all ink X and Y coordinates by.
**
** It is the responsibility of the storing application to deal with any 
** effects from round-off or truncation error due to the limits of precision
** in the FIXED_FRACTION values used in INK_SCALE_RECORDs.
**
** An ink scale record indicates a scale change that stays in effect until
** another ink scale record is encountered.  Ink scale values compound: if
** the current scale is (2.0,2.0) and an INK_SCALE_RECORD is encountered with
** scale of (2.0,3.0), the scale to be applied to ink then becomes(4.0,6.0). 
** In absence of any ink scale record, the default ink scale is unity.  In
** general, a typical usage pattern for an application that supports drawing
** ink while zoomed at scale is to record a number of strokes at a given
** scale, reset the scale with an INK_SCALE_RESET_RECORD (which resets both
** the scale and the offset to the default values), then switch to another
** scale, then record a number more strokes, and so on.
**
** Note:
** The extension scaling and offset to the Z ordinate value is not defined in
** this version of the specification.  The extension to Z scaling and offset
** in a "standard" record type (i.e. not an application-specific record) may
** be addressed in the future.
**
**------------------------------------------------------------------------*/

typedef struct tag_INK_SCALE {
    FIXED_FRACTION      x;      /* scale in the x direction */
    FIXED_FRACTION      y;      /* scale in the y direction */
} INK_SCALE, FAR *P_INK_SCALE;
#define INK_SCALE_SIZE (FIXED_FRACTION_SIZE+FIXED_FRACTION_SIZE)

#define inkPointDefaultScale    (INK_UNITY_SCALE)       /* Unity. */

typedef struct tag_INK_SCALE_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordScale */
    INK_SCALE           scale;
} INK_SCALE_RECORD, FAR *P_INK_SCALE_RECORD;
#define inkRecordScaleSize  \
       (inkRecordHeaderLength(inkRecordScale) + \
        FIXED_FRACTION_SIZE + FIXED_FRACTION_SIZE)




/**************************/
/* REFERENCE SECTION 10.0 */
/**************************/

/*-------------------------------------------------------------------------
** The offset position is used to relocate ink data, after scaling.  For
** example, in a forms application, ink in a sketch field is drawn relative
** to a given sketch field in the form.  The location of this original field
** is important to know so we know how the ink in this bundle relates to its
** original field.  If we wanted to move this ink to another field (i.e.
** cut/paste or move), we would need to know the location of the original
** field so we could render the ink in the new field in a manner consistent
** with how it was drawn relative to its original field (i.e. a similar
** baseline for a hand-written signature).
**
** This record is optional.  If it exists, it will then apply to all
** following pen data in the file.  If it is not present it is assumed that
** no information of this type is relevant.  For example, while field ink
** would have an offset position, markup ink over an entire form would not
** have a offset position (or would have an offset position of (0,0) and a
** scale of (1,1)) because it is relative to the entire form coordinate
** system, not relative to some piece in the form. 
**
** Note:
** This approach allows a reader to "blindly" apply the scale and offset 
** values specified to ink data, and puts the burden for computing
** compounding of multiple zoom levels, etc., on the writing application.
**
**------------------------------------------------------------------------*/

typedef struct tag_INK_OFFSET_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordOffset */
    XY32                positionOffset; /* values are in pen units */
} INK_OFFSET_RECORD, FAR *P_INK_OFFSET_RECORD;

#define inkRecordOffsetSize \
       (inkRecordHeaderLength(inkRecordOffset) + XY32_SIZE)

#define inkPointDefaultOffset   ((S32) 0)   /* No offset. */


typedef struct tag_INK_SCALE_RESET_RECORD {
    INK_RECORD_HEADER0  header;         /* value is inkRecordScaleReset */
} INK_SCALE_RESET_RECORD, FAR *P_INK_SCALE_RESET_RECORD;

#define inkRecordScaleResetSize  (inkRecordHeaderLength(inkRecordScaleReset))




/**************************/
/* REFERENCE SECTION 11.0 */
/**************************/

/*-------------------------------------------------------------------------
** Ink color is represented as an rgb value, plus opacity.
**
** The default color is black (r,g,b,o) = (0,0,0,255).  A color change
** present in the file remains in effect until another color change.
** Typically, the color will stay the same for many ink strokes and thus
** a color record will only be used occasionally when the color changes.
**
** "Opacity" is rather vaguely understood, especially in color environments.
** In this context, opacity means the degree to which the display underneath
** the ink shows through.  An opacity value of 255 means that nothing under
** the ink shows through; 0 means that everything shows through (the ink
** is transparent).  It is up to the reading application to define the
** implementation of opacity on the reading platform.
**
** The color/opacity value of (255,255,255,0), or "transparent white" is
** defined as an "erase" color.  In inking applications that support a true
** "erase" function, such as the ability to erase annotation ink on an
** "original" document (perhaps a FAX image) the "erase" color restores the
** background image where painted.  The "background image" is defined by the
** rendering application.  
**
** Applications which do not support a true "erase" function may interpret
** this as some other drawing function, such as drawing the "background"      
** color.
**
**------------------------------------------------------------------------*/

typedef union {
  U32    all;
  struct {
    U8   red,
         green,
         blue,
         opacity;   /* opaqueness: see defines below */
  } rgb;
} INK_COLOR, FAR *P_INK_COLOR;
#define INK_COLOR_SIZE (U32_SIZE)

typedef struct tag_INK_COLOR_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordColor */
    INK_COLOR           color;
} INK_COLOR_RECORD, FAR *P_INK_COLOR_RECORD;
#define inkRecordColorSize  \
       (inkRecordHeaderLength(inkRecordColor) + U32_SIZE)

/*-------------------------------------------------------------------------
** Standardized opacity values:
** A recommended practice is that an opacity value of 128 (midway between
** 0 and 255) be used for "highlighter" colors.  A recommended practice is 
** that grey values as defined below be used for "standard grey" 
** highlighters.
**-------------------------------------------------------------------------*/

#define inkOpacityTransparent   0x00
#define inkOpacityHighlight     0x80
#define inkOpacityOpaque        0xFF

/* Standard solid colors: */

#define inkColorErase           {0xFF,0xFF,0xFF,0x00}
#define inkColorWhite           {0xFF,0xFF,0xFF,0xFF}
#define inkColorLtGrey          {0x80,0x80,0x80,0xFF}
#define inkColorDkGrey          {0x40,0x40,0x40,0xFF}
#define inkColorBlack           {0x00,0x00,0x00,0xFF}

/* Standard highlighter (transparent) colors: */

#define inkColorLtGreyHighlight {0x80,0x80,0x80,0x80}
#define inkColorDkGreyHighlight {0x40,0x40,0x40,0x80}

#define inkDefaultColor ((INK_COLOR) inkColorBlack)




/**************************/
/* REFERENCE SECTION 12.0 */
/**************************/

/*-------------------------------------------------------------------------
** Time is measured in milliseconds.
** 
** Note:
** Because of the difficulty synchronizing clocks on different machines
** at the time granularity of digitizing tablets, and because the "editing"
** of ink at a later time makes the definition of the absolute time for each
** ink point ambiguous, the base for the time is arbitrary.  All times in
** strokes are just relative to each other with no absolute time
** relationship.
**
** These records, when encountered in the file, apply to the next stroke data
** in the file (so this record comes before the penData that it applies to).
** End time records are not required.  The interpretation of an end time
** which is in conflict with the end time inferred from the assumed data rate
** of points and the number of points (including elided points) is not
** defined.  
**
** Start time is the time for the first point in the following penData record
** and end time is the time of the last point in the following penData
** record, because if you are recording tip force, the exact definition of
** pen up and pen down may be fuzzy and/or application dependent.  
**
**------------------------------------------------------------------------*/

typedef U32 INK_TIME, FAR *P_INK_TIME;      /* milliseconds */
#define INK_TIME_SIZE U32_SIZE

#define inkDefaultTime      ((INK_TIME) 0)

typedef struct tag_INK_START_TIME_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordStartTime */
    INK_TIME            startTime;
} INK_START_TIME_RECORD, FAR *P_INK_START_TIME_RECORD;
#define inkRecordStartTimeSize  \
       (inkRecordHeaderLength(inkRecordStartTime) + INK_TIME_SIZE)

typedef struct tag_INK_END_TIME_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordEndTime */
    INK_TIME            endTime;
} INK_END_TIME_RECORD, FAR *P_INK_END_TIME_RECORD;
#define inkRecordEndTimeSize    \
       (inkRecordHeaderLength(inkRecordEndTime) + INK_TIME_SIZE)




/**************************/
/* REFERENCE SECTION 13.0 */
/**************************/

/*-------------------------------------------------------------------------
** INK_PENDATA_RECORDs can be grouped.  If they are grouped, each
** INK_PENDATA_RECORD can be assigned a group number.  All
** INK_PENDATA_RECORDs with the same group number belong to the same group. 
**
** The exact interpretation of grouping is up the applications involved.
** Writing applications may group ink data, but not all reading applications
** that read the data may interpret grouping in the same way.
**
** For example, grouping could be used in the traditional fashion as in
** drawing programs so the user moves or copies an entire group of
** INK_PENDATA_RECORDs together.  A group could also be used to signify a
** series of INK_PENDATA_RECORDs entered by the user all within some criteria
** (i.e. all during one proximity session or all within some time frame).
**
** Group numbers are simply signed 16 bit values and can be anything.  They
** do not need to be contiguous (i.e. they do not need to be 0,1,2).  They
** can be 12,49,-12345 if that is useful.
**
** This record can also be used as a simple marker for starting a new group
** when the groupId is not really used: Group numbers of 0,0,0,0 ... are
** thus permitted.
**
** INK_GROUPs are nestable.  Group 0 is reserved as the end-of-group marker
** for disjoint groups.  If no end-of-group marker is encountered before the
** end of the file or the end of all ink data (as indicated by an
** INK_END_RECORD), all current (and possibly nested) groups are terminated
** as if end-of-groups markers for them had been encountered.
**
**------------------------------------------------------------------------*/

typedef S32 INK_GROUP, FAR *P_INK_GROUP;
#define INK_GROUP_SIZE S32_SIZE

typedef struct tag_INK_GROUP_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordGroup */
    INK_GROUP           groupId;    /* application-specific interpretation */
} INK_GROUP_RECORD, FAR *P_INK_GROUP_RECORD;

#define inkDefaultGroup ((INK_GROUP) 0)

#define inkRecordGroupSize  \
       (inkRecordHeaderLength(inkRecordGroup) + INK_GROUP_SIZE)




/**************************/
/* REFERENCE SECTION 14.0 */
/**************************/

/*-------------------------------------------------------------------------
** Some applications may support the idea of rendering ink as if it were 
** drawn by a certain shaped pen tip.  The most common pen tips would be
** round or rectangular.  The exact details of how to render a given pen
** tip will be application specific, but this record states what pen tip
** parameters were used by the storing app.
**
** Pen tips determine, in part, how ink is rendered.  For pen tip types
** defined in future versions of this format which require additional
** parameters (such as the X and Y rectangle for a simulated nib pen, or
** brush dimensions for a simulated brush), additional data is included
** at the end of the structure.
**
** The writing application should be aware that the reading application will
** only do "the best possible" job of rendering and that fully compliant 
** reading applications may not be able to render certain nib types and/or
** colors.  Both reading and writing applications should pay particular
** attention to the following notes regarding defaults and ink drawn at a
** width of zero.
** 
** A pen tip which is drawing ink in zero width renders at the minimum
** visible width the reading application will support.
** 
** A recommended practice is that ink which should not render (should this
** be called for) be drawn with a color value of (0,0,0, 0), i.e., black,
** completely transparent.
**
** Pen tip size should scale when an INK_SCALE_RECORD is encountered.  The
** writing application should write a new INK_PENTIP_RECORD after an
** INK_SCALE_RECORD if the writing application does not want the pen tip
** size to scale along with the ink.  If the pen tip scales to zero width, 
** it should be rendered by the reading application according to the comment
** above.
**
** The default pen tip if no pentip record exists is INK_PENTIP_ROUND, with a
** width of one twip.  The dimensions of a round nib specify diameter, not
** radius: the X/Y coordinate is the center of this diameter.  Similarly, for
** for rectangular nibs, the X/Y coordinate is the center of the rectangle.  
**
** Note:
** This specification does not specify information for an algorithmic
** variation in nib width, ink color, or other "brush" effects as a function
** of tip force, speed or any other factor.  An example would be for an
** application to draw wider ink as the user presses down harder with the
** stylus.  Applications wishing to implement such features may do so using
** application-specific record types for this revision of the specification.
** 
**------------------------------------------------------------------------*/

typedef S16 INK_PENTIP, FAR *P_INK_PENTIP;
#define INK_PENTIP_SIZE S16_SIZE
#define INK_PENTIP_ROUND            (0) /* Diameter in twips */
#define INK_PENTIP_RECTANGLE        (1) /* Dimensions in twips */
#define INK_PENTIP_SLANT_RECTANGLE  (2)
#define INK_PENTIP_ROUND_FLAT_END   (3)
/* ... more to be filled in here if needed */

#define inkDefaultPentip        INK_PENTIP_ROUND
#define inkDefaultPentipData    ((U16) 1)

typedef struct tag_INK_PENTIP_SLANT {
    SIZE16  rectangle_size; /* INK_PENTIP_SLANTRECTANGLE */
    U16     angle;          /* Whole degrees from vertical, counter-clockwise */
} INK_PENTIP_SLANT, FAR *P_INK_PENTIP_SLANT;

typedef union {
  U16               round_width;        /* INK_PENTIP_ROUND */
  SIZE16            rectangle_size;     /* INK_PENTIP_RECTANGLE */
  INK_PENTIP_SLANT  slant;              /* INK_PENTIP_SLANT_RECTANGLE */
  U16               round_flat_width;   /* INK_PENTIP_ROUND_FLAT_END */
} INK_PENTIP_DATA, FAR *P_INK_PENTIP_DATA;

/* Size of the union is determined by INK_PENTIP_SLANT */
#define INK_PENTIP_DATA_SIZE (SIZE16_SIZE+U16_SIZE)

typedef struct tag_INK_PENTIP_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordTip */
    INK_PENTIP          tip;
    INK_PENTIP_DATA     tip_data;
} INK_PENTIP_RECORD, FAR *P_INK_PENTIP_RECORD;
#define inkRecordTipSize    \
       (inkRecordHeaderLength(inkRecordTip) + INK_PENTIP_SIZE + \
        SIZE16_SIZE + U16_SIZE)




/**************************/
/* REFERENCE SECTION 15.0 */
/**************************/

/*-------------------------------------------------------------------------
** For some applications, it will be important to know the sampling rate of
** the pen digitizer. 
**
** This record would likely be present once in a bundle and would typically
** be after the INK_BUNDLE_RECORD, but before the first pen data.
**
** Note:
** Writing applications are not required to report the "true" sampling rate
** of the digitizer, nor are rendering applications required to play back the
** ink at the specified rate.  It is likely that most types of rendering
** applications will render ink as rapidly as possible to construct a display
** in minimum time, and that some types of animation applications will
** intentionally set an arbitrary sampling rate to vary the display rate.  
**
** Note:
** For hardware which supports a highly variable sampling rate, the writing
** application can simulate a very high sampling rate (say, 1000 points/
** second), and use skip records for "elided" points to achieve an exact time
** value (at 1-millisecond resolution) for each point.
**
** A default value for sampling rate has been arbitrarily defined below.
**
**------------------------------------------------------------------------*/

typedef struct tag_INK_POINTS_PER_SECOND_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordPointsPerSecond */
    U16                 pointsPerSecond;
} INK_POINTS_PER_SECOND_RECORD, FAR *P_INK_POINTS_PER_SECOND_RECORD;

#define inkPointDefaultPointsPerSecond  (100)

#define inkRecordPointsPerSecondSize    \
       (inkRecordHeaderLength(inkRecordPointsPerSecond) + U16_SIZE)




/**************************/
/* REFERENCE SECTION 16.0 */
/**************************/

/*-------------------------------------------------------------------------
** Units for Z height of stylus above the tablet.
**
** This record would only be present once in a bundle and would typically be
** after the INK_BUNDLE_RECORD, but before the first pen data.
**
**------------------------------------------------------------------------*/

typedef struct tag_INK_UNITS_PER_Z_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordUnitsPerZ */
    U32                 unitsPerZ;      /* pen units per meter (Z height) */
} INK_UNITS_PER_Z_RECORD, FAR *P_INK_UNITS_PER_Z_RECORD;

#define inkPointDefaultUnitsPerZ  (10000)   /* 0.1 mm units */

#define inkRecordUnitsPerZSize  \
       (inkRecordHeaderLength(inkRecordUnitsPerZ) + U32_SIZE)




/**************************/
/* REFERENCE SECTION 17.0 */
/**************************/

/*-------------------------------------------------------------------------
** Units for stylus tip force.
**
** This record would only be present once in a bundle and would typically be
** after the INK_BUNDLE_RECORD, but before the first pen data.
**
** Note:
** This specification assumes some level of accuracy and linearity for tip
** force data, if such data is present.  However, since tip force sensors in
** current digitizer tablet and stylus designs may well vary in accuracy and
** linearity from one unit to the next even for hardware of the same design
** and model, and since algorithms for using tip force to determine stroke
** start and end are likely to differ, a recommended practice for writing
** applications that use the tip force value to determine the "touch" points
** in a stroke is to mark those points using the touch bit in the INK_BUTTONS
** structure.  
**
** It is also recommended that vendors supporting tip force sensing in their
** hardware linearize their transducers to the greatest extent possible.  
**
** Because of the likelihood that tip force transducers may not be accurately
** linearized, negative tip force values, while perhaps somewhat absurd
** are possible and are permitted in this specification.  
** 
**------------------------------------------------------------------------*/

typedef struct tag_INK_UNITS_PER_FORCE_RECORD {
    INK_RECORD_HEADER8  header;         /* value is inkRecordUnitsPerForce */
    U32                 unitsPerForce;  /* tip-force units per k-gram of force*/
} INK_UNITS_PER_FORCE_RECORD, FAR *P_INK_UNITS_PER_FORCE_RECORD;

#define inkPointDefaultUnitsPerForce  (1000)    /* grams of force */

#define inkRecordUnitsPerForceSize  \
       (inkRecordHeaderLength(inkRecordUnitsPerForce) + U32_SIZE)




/**************************/
/* REFERENCE SECTION 18.0 */
/**************************/

/*-------------------------------------------------------------------------
** The INK_APP_RECORD record is a universal record to be used by individual
** applications to put data into the file that is not supported by an
** additional publicly defined record type.  The basic idea is that an
** application puts its own unique application signature into the appData
** bytes in the INK_APP_RECORD.  This identifies the data as originating with
** a particular application.  Then, an application defines a set of
** subRecordTypes that they wish to use.  Then, using these subRecordTypes
** they can put a wide variety of information into the file.  By examining
** the appData signature and comparing it to theirs, an application can
** decide whether it knows how to interpret the various subRecordtypes.  
** 
**------------------------------------------------------------------------*/

typedef struct tag_INK_APP_RECORD {
    INK_RECORD_HEADER32 header;         /* value is inkRecordApp */
    U8                  appSignature[8];/* reserved for possible unique */
                                        /* application signature */
    U16                 subRecordType;
    /* data here appropriate to the subRecordType and appData signature */
} INK_APP_RECORD, FAR *P_INK_APP_RECORD;
#define inkRecordAppSize(data_length)   \
    (inkRecordHeaderLength(inkRecordApp) + 8 + U16_SIZE + (data_length))




/**************************/
/* REFERENCE SECTION 19.0 */
/**************************/

/*-------------------------------------------------------------------------
** Definition of the inkData components of an INK_PENDATA_RECORD:
**
** Uncompacted point format:
** -------------------------
**
** This structure immediately follows the rest of the INK_PENDATA_RECORD. 
** The structure has several optional components, present or not present as
** indicated by the INK_BUNDLE_FLAGS in the INK_BUNDLE_RECORD.  The format is
** a sequence of "point values", each containing all the scalar data for each
** sampled tablet point.  
** 
** In the uncompacted format, there is a single structure that contains all
** of the state information for each point from the tablet.  Components not
** present (as indicated by the INK_BUNDLE_FLAGS) are just that: not present,
** do not exist, do not occupy space.  
**
** Compacted point format:
** -----------------------
**
** In the compacted format, "State values", such as the stylus state of
** touch/no-touch/out-of-prox or the on/off state of the barrel switches, are
** stored in a compacted "INK_BUTTONS" item (represented using reserved
** encodings in the INK_POINT coordinate values) interjected when their state
** changes.  The initial state is assumed to be "not touching", "out of
** proximity", all barrel switches "off".  It is possible to have both tip
** force data, and explicit starts and ends of strokes: the starts and ends
** of the strokes are then points that were considered to be such by the
** original application storing the data.    The INK_BUTTONS record reflects
** the state of the next X/Y point following.  
**
**------------------------------------------------------------------------*/




/**************************/
/* REFERENCE SECTION 20.0 */
/**************************/

/*-------------------------------------------------------------------------
** "INK_BUTTONS" items may most often be used only to indicate stylus touch
** and out-of-prox state, and perhaps a single barrel button.  The format is
** optimized for this case.  The format extends to a total of 28 stylus/puck
** buttons.
**
**------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------
** The lowest-order bit (flag0) is "0" when the stylus is out of
**   proximity, "1" when it is in proximity.
** Second lowest-order bit (flag1) is "1" to indicate the next inkPoints are
**   when the stylus is touching (the start of a stroke: tip-switch "on"),
**   "0" to indicate that the stylus is not touching (end of a stroke).
** Third bit (flag2) indicates state of first (or only) barrel switch,
**   etc.
** 31'st bit (flag30) is normally "0", "1" is indicates there are more
**   than 29 barrel/puck buttons with state, and the rest are in the next
**   four-byte word.
**-------------------------------------------------------------------------*/

typedef U32 INK_BUTTONS, FAR * P_INK_BUTTONS;

/*-------------------------------------------------------------------------
** These definitions hold the maximum and minimum values that
** can be used with the S15 and S31 representations described in
** this document:
**-------------------------------------------------------------------------*/

#define MAX_S31 ((S32) 0x3FFFFFFF)
#define MIN_S31 ((S32) 0xC0000000)

#define MAX_S15 ((S16) 0x3FFF)
#define MIN_S15 ((S16) 0xC000)

#define MAX_S7 ((S16) 0x003F)
#define MIN_S7 ((S16) 0xFFC0)

#define MAX_S3 ((S16) 0x0003)
#define MIN_S3 ((S16) 0xFFFC)

/* SignExtend4/8/16/32: Sign-extend an S3, S7, S15, S31 to an S32: */

#define SignExtend4(value)  ((S32)                      \
    (((value)&0x00000004l)== 0 ?  ((value)&0x00000007l)     \
                               : (((value)&0x00000007l) | 0xFFFFFFF8l)))

#define SignExtend8(value)  ((S32)                      \
    (((value)&0x00000040l)== 0 ?  ((value)&0x0000007Fl)     \
                               : (((value)&0x0000007Fl) | 0xFFFFFF80l)))

#define SignExtend16(value) ((S32)                      \
    (((value)&0x00004000l)== 0 ?  ((value)&0x00007FFFl)     \
                               : (((value)&0x00007FFFl) | 0xFFFF8000l)))

#define SignExtend32(value) ((S32)                      \
    (((value)&0x40000000l)== 0 ?  ((value)&0x7FFFFFFFl) \
                               : (((value)&0x7FFFFFFFl) | 0x80000000l)))



/**************************/
/* REFERENCE SECTION 21.0 */
/**************************/

/*-------------------------------------------------------------------------
** INK_POINT data.  The INK_POINT structure varies in size depending on 
** flags set in the bundle header.  The XY32 position is always present, but
** the force, rho, height, angle, and buttons members are only present when
** indicated by the corresponding flag in the bundle header.  When optional
** data is present, it is present in the order defined by this structure;
** that is, position, force, height, rho, angle, and finally buttons.  
**
** The INK_POINT structure has the following elements:
**
** position - required and always present
**    Positions are measured with (0,0) at the lower-left, X increasing to
**    the right, Y increasing upwards.  Values are actually S31, not S32.
**    The high bit in X and Y must be zero.
** force    - optional, present if inkForceDataPresent is asserted
**    Units are in pen force units, zero is no contact.
** height   - optional, present if inkHeightDataPresent is asserted
**    Units are in pen unitsPerZ as specified by inkPointDefaultUnitsPerZ or
**    by an INK_UNITS_PER_Z_RECORD, whichever is appropriate.  Units increase
**    as the stylus is taken away from the tablet.  Zero means "just in 
**    contact".  Negative values could possibly result from spring action if
**    the stylus is pressed hard, or if the tablet is not perfectly accurate.
** rho      - optional, present if inkRotationDataPresent is asserted
**    Angles are measured in degrees from some nominal orientation of 
**    "stylus button on top" (somewhat arbitrary).  Angles increase with 
**    clockwise rotation as seen from the rear end of the stylus.
** angle    - optional, present if inkAngleDataPresent is asserted
**    Angles are measured in pen angle units from the vertical.  Theta 
**    increases in the positive-X direction, phi in the positive-Y.
** buttons  - optional, present if inkButtonDataPresent is asserted
**    
** When the INK_BUNDLE_RECORD member compactionType is inkStdCompression,
** all data in this structure is compressed according to the methods 
** described in reference section 23.0.  For more details on how to interpret
** the compressed data stream, see the sample code.  The bundle flags which
** indicate whether a particular piece of data is present are used regardless
** of whether the data is compressed or not.  Note that when data is written
** in compressed format, it is NOT written in Intel order but rather most
** significant byte first.  In compressed form, some of the eight bit delta
** values are reserved for button data and elided (skipped) point counts.
** This has two important ramifications.  1) When expecting a point, 
** compacted button data or elided point data may be encountered instead, and
** 2) when the inkButtonDataPresent flag is asserted in the bundle header,
** button data will appear in the place of a point and not in addition to a
** point.  If inkButtonDataPresent is not asserted, the reader need not check
** the point data for the special case of button data; however, the point 
** data must still be checked to see if it is a count of elided points rather
** than an actual point.
**
**------------------------------------------------------------------------*/

typedef struct tag_INK_POINT {
    XY32        position;  /* required x/y point data */
    S16         force;     /* optional force data */
    S16         height;    /* optional z height data */
    S16         rho;       /* optional rotational data */
    ANGLE16     angle;     /* optional theta and phi data */
    INK_BUTTONS buttons;   /* optional proximity, contact, button data */
} INK_POINT, FAR *P_INK_POINT;




/**************************/
/* REFERENCE SECTION 22.0 */
/**************************/


/*-------------------------------------------------------------------------
** The following default values are assumed before the start of any 
** INK_BUNDLE:
**
**------------------------------------------------------------------------*/


#define inkPointDefaultXYPosition   ((S32) 0)
#define inkPointDefaultForce        ((S16) 0)
#define inkPointDefaultHeight       ((S16) 0)
#define inkPointDefaultRho          ((S16) 0)
#define inkPointDefaultAngle        ((S16) 0)
#define inkPointDefaultButtons      ((U32) 0)




/**************************/
/* REFERENCE SECTION 23.0 */
/**************************/

/*-------------------------------------------------------------------------
** Compacted point format:
** ---------------------
**
** A recommended practice is always to use the compacted point format, not
** the uncompacted point format.  Sample code for reading and writing the
** compacted format is included in an appendix.  
**
** This structure also immediately follows the rest of the
** INK_PENDATA_RECORD.
**
** The uncompacted values above are stored in sequential bytes in a more
** compact, delta-oriented format.  Deltas are all signed values, a value to
** add to the previous value.  The first point in an INK_PENDATA_RECORD is
** always relative to the defined default values for each component of the
** point.
**
** The storing application, as an alternative to eliminating points, can
** specify a "skip" record for elided points.  The skipRecord indicates that
** a number of points were skipped, and the reading application is free to
** insert values for the elided points (interpolating where appropriate). 
** The intent is to allow for accurate time information to be maintained
** between time stamps for synchronization with recorded voice, press-hold
** gesture recognition, etc.  
**
** Compacted data is written most significant byte first so that reading
** applications can read the first byte and determine (from the top two bits)
** how large the encoded delta is.
**
** Note:
** "Reserved encodings" are those encodings that, if real points, would fit
** into the next smaller delta size.  16 bit deltas and 8 bit deltas have
** reserved encodings.  The reserved encodings for 16 bit deltas are all 16
** bit delta pairs where both X and Y are within the inclusive range MIN_S7
** and MAX_S7.  Similarly, the reserved encoding for 8 bit deltas are all 8
** bit delta pairs where both X and Y are within the inclusive range MIN_S3
** and MAX_S3.  In revision 1.0 of Jot, three of the reserved encodings for 8
** bit deltas are used for special cases: skip counts (reference section 
** 27.0) and button changes (reference section 26.0).
** 
** x/y position:
** ------------
**
** 32-bit absolute X/Y:
**
**      Two 32 bit long words: Data is actually two S31s:
**
**      |0|0|     (30 low-order bits of X)                             |
**              ... Sign bit is taken from first bit of next word.
**      ----------------------------------------------------------------
**      |X|       (sign bit of X plus 31 bits of Y)                     |
**      ----------------------------------------------------------------
**
** 16-bit short delta X/Y:
**
**      Short words: two 16 bit words: Deltas are actually two S15s:
**      Values that would fit into an 8-bit byte delta are reserved.
**
**      |0|1|     (14 low-order bits of delta-X)         |
**              ... Sign bit is taken from first bit of next word.
**      --------------------------------------------------
**      |X|       (sign bit of X plus 15 bits of delta Y |
**      --------------------------------------------------
**
** 8-bit byte delta X/Y:
**
**      Bytes: two bytes: Deltas are actually two S7s:
**      Values that would fit into a 4-bit nibble delta are reserved.
**
**      |1|0|     (6 low-order bits of delta-X)  |
**              ... Sign bit is taken from first bit of next word.
**      ------------------------------------------
**      |X|       (7 bits of delta-Y)            |
**      ------------------------------------------
**
** 4-bit nibble delta X/Y:
**
**      Nibbles: one byte: Deltas are actually S3:
**
**      |1|1| (S3 delta-X) | (S3 delta-Y) |
**      -----------------------------------
**
**------------------------------------------------------------------------*/




/**************************/
/* REFERENCE SECTION 24.0 */
/**************************/

/*-------------------------------------------------------------------------
** Tip force:
** ----------
**
** 16-bit absolute force:
**
**      Short word: one word: Value is actually S15:
**      Values that would fit into an 8-bit byte delta are reserved.
**
**      |0|       (15 bits of force)                |
**      ---------------------------------------------
**
** 8-bit byte delta force:
**
**      Byte: one byte: Deltas are actually S7:
**
**      |1|  (S7 delta-force)    |
**      --------------------------
**
**
** Height:
** ------
**
** (Same encoding as tip force)
**
** Rho:
** ---
**
** (Same encoding as tip force)
**
**
** Stylus theta-phi:
** ----------------
**
** 16-bit absolute theta-phi:
**
**      Short words: two words: Data is actually S15:
**
**      |0|0|     (14 low-order bits of theta)    |
**      -------------------------------------------
**              ... Sign bit is taken from first bit of next word.
**      |X|       (15 bits of phi)                |
**      -------------------------------------------
**
**------------------------------------------------------------------------*/




/**************************/
/* REFERENCE SECTION 25.0 */
/**************************/

/*-------------------------------------------------------------------------
** 8-bit byte delta theta-phi
**
**      Bytes: two bytes: Deltas are actually S7:
**      Values that would fit into a 4-bit nibble delta are reserved.
**
**      |0|1|     (6 low-order bits of delta-theta)|
**      --------------------------------------------
**              ... Sign bit is taken from first bit of next word.
**      |X|       (7 bits of delta-phi)            |
**      --------------------------------------------
**
** 4-bit nibble delta theta-phi
**
**      Nibbles: one byte: Deltas are actually S3:
**
**      |1|0|(S3 delta-theta)|(S3 delta-phi)|
**      -------------------------------------
**
** Note: 
** Leading bit values of |1|1| are reserved
**
**------------------------------------------------------------------------*/




/**************************/
/* REFERENCE SECTION 26.0 */
/**************************/

/*-------------------------------------------------------------------------
** Since the X/Y data is always present, we use some of the reserved delta
** encodings to encode button states and elided (skipped) points.  We use the
** 8-bit delta encodings that are unused: the values that can fit into the
** smaller 4-bit delta encodings. 
**
** Button/tip records:
** ------------------
**
** It is assumed that the state of barrel buttons and the touching sensor on
** the stylus change infrequently.  A compacted button/tip record is only
** included when the state changes in one of the switches.  The button state 
** value applies to the X/Y point immediately following the button state 
** record. 
**
**
** (Taken from 8-bit byte delta X/Y: two bytes total)
**
**      |1|0| 0|0|0|0|0|0/1|   0|X|.|.|.|.|X|X|
**      ---------------------------------------
**              (delta-X)           (delta-Y)
**
** An eight-bit delta with delta-X == 0 or 1, and delta-Y in the range
** (-4..3) indicates a button state encoding. 
**
** It is likely to be the case that many hardware platforms have only one
** barrel button.
**
** The three delta-Y bits indicate the "touch", "out-of-prox", and "first
** barrel button" state as follows:
**
** low-order         delta-Y bit: 1 --> in proximity,    0 --> out of prox
** next              delta-Y bit: 1 --> touching tablet, 0 --> not touching
** high-order (sign) delta-Y bit: 1 --> first button closed, 0 --> open
**
**
** The lowest order bit of the delta-X bits is used to indicate that
** additional bytes follow: "1" indicates that the next byte is used for the
** next 7 barrel buttons with state.  The high order bit of each sequential 
** byte in the series is "1" if an additional byte must be fetched, "0"
** otherwise.  In these additional bytes, the additional buttons are 
** associated in order starting with the low-order bit.   
**
**------------------------------------------------------------------------*/



/**************************/
/* REFERENCE SECTION 27.0 */
/**************************/

/*-------------------------------------------------------------------------
** Skipped-point records:
** ---------------------
**
** (Taken from 8-bit byte delta X/Y: two bytes total)
**
**
**      |1|0| 0|0|0|0|1|0|   0|X|.|.|.|.|X|X|
**      -------------------------------------
**              (delta-X)           (delta-Y)
**
** An eight-bit delta with delta-X == 2, and delta-Y in the range
** (-4..3) indicates a count of elided points.  The delta-Y values in the
** range (-4..-1) are used to represent skip counts of (4..7).  If the
** delta-Y value is zero "0", the next two bytes are fetched to get a U16
** skip count value.
**
** The elided points are points removed between the point immediately prior
** to the skipped-point record and the point immediately afterward.  This 
** implies that at least one point must follow every skip record (though 
** the point may not appear next in the stream if there are intervening
** button state transitions).  Reading applications that are interested in 
** recovering elided points will typically interpolate.  Skip counts of zero
** are meaningless and not permitted.
**
** Reserved:
** --------
**
** The remaining encodings from the 8-bit byte delta X/Y are reserved:
**
** delta-X of -4, -3, -2, -1, 3 AND ((delta-Y >= -4) & ((delta-Y <= 3))
**
**------------------------------------------------------------------------*/

#endif      /* end of INKSTORE_INCLUDED */