| // SPDX-License-Identifier: Apache-2.0 OR MIT OR Unlicense |
| |
| // Common data structures and functions for the path tag stream. |
| |
| // This is the layout for tag bytes in the path stream. See |
| // doc/pathseg.md for an explanation. |
| |
| #define PATH_TAG_PATHSEG_BITS 0xf |
| #define PATH_TAG_PATH 0x10 |
| #define PATH_TAG_TRANSFORM 0x20 |
| #define PATH_TAG_LINEWIDTH 0x40 |
| |
| struct TagMonoid { |
| uint trans_ix; |
| uint linewidth_ix; |
| uint pathseg_ix; |
| uint path_ix; |
| uint pathseg_offset; |
| }; |
| |
| TagMonoid tag_monoid_identity() { |
| return TagMonoid(0, 0, 0, 0, 0); |
| } |
| |
| TagMonoid combine_tag_monoid(TagMonoid a, TagMonoid b) { |
| TagMonoid c; |
| c.trans_ix = a.trans_ix + b.trans_ix; |
| c.linewidth_ix = a.linewidth_ix + b.linewidth_ix; |
| c.pathseg_ix = a.pathseg_ix + b.pathseg_ix; |
| c.path_ix = a.path_ix + b.path_ix; |
| c.pathseg_offset = a.pathseg_offset + b.pathseg_offset; |
| return c; |
| } |
| |
| TagMonoid reduce_tag(uint tag_word) { |
| TagMonoid c; |
| // Some fun bit magic here, see doc/pathseg.md for explanation. |
| uint point_count = tag_word & 0x3030303; |
| c.pathseg_ix = bitCount((point_count * 7) & 0x4040404); |
| c.linewidth_ix = bitCount(tag_word & (PATH_TAG_LINEWIDTH * 0x1010101)); |
| c.path_ix = bitCount(tag_word & (PATH_TAG_PATH * 0x1010101)); |
| c.trans_ix = bitCount(tag_word & (PATH_TAG_TRANSFORM * 0x1010101)); |
| uint n_points = point_count + ((tag_word >> 2) & 0x1010101); |
| uint a = n_points + (n_points & (((tag_word >> 3) & 0x1010101) * 15)); |
| a += a >> 8; |
| a += a >> 16; |
| c.pathseg_offset = a & 0xff; |
| return c; |
| } |