| ofs | hex dump | ascii |
|---|
| 0000 | 21 3c 61 72 63 68 3e 0a 2f 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 31 34 38 35 30 32 35 33 | !<arch>./...............14850253 |
| 0020 | 34 36 20 20 20 20 20 20 20 20 20 20 20 20 20 20 30 20 20 20 20 20 20 20 37 32 36 31 31 20 20 20 | 46..............0.......72611... |
| 0040 | 20 20 60 0a 00 00 03 36 00 02 39 dc 00 02 39 dc 00 02 39 dc 00 02 39 dc 00 02 39 dc 00 02 39 dc | ..`....6..9...9...9...9...9...9. |
| 0060 | 00 02 42 fc 00 02 42 fc 00 02 42 fc 00 02 42 fc 00 02 42 fc 00 02 42 fc 00 02 42 fc 00 02 42 fc | ..B...B...B...B...B...B...B...B. |
| 0080 | 00 02 42 fc 00 02 42 fc 00 02 42 fc 00 02 42 fc 00 02 5d 2a 00 02 5d 2a 00 02 5d 2a 00 02 5d 2a | ..B...B...B...B...]*..]*..]*..]* |
| 00a0 | 00 02 63 ee 00 02 63 ee 00 02 63 ee 00 02 63 ee 00 02 63 ee 00 02 63 ee 00 02 63 ee 00 02 63 ee | ..c...c...c...c...c...c...c...c. |
| 00c0 | 00 02 63 ee 00 02 63 ee 00 02 63 ee 00 02 63 ee 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..c...c...c...c...r...r...r...r. |
| 00e0 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0100 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0120 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0140 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0160 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0180 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 01a0 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 01c0 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 01e0 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0200 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0220 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0240 | 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 00 02 72 d2 | ..r...r...r...r...r...r...r...r. |
| 0260 | 00 03 01 8a 00 03 01 8a 00 03 01 8a 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 | ...............h...h...h...h...h |
| 0280 | 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 | ...h...h...h...h...h...h...h...h |
| 02a0 | 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 | ...h...h...h...h...h...h...h...h |
| 02c0 | 00 03 07 68 00 03 07 68 00 03 07 68 00 03 07 68 00 03 43 e0 00 03 43 e0 00 03 43 e0 00 03 43 e0 | ...h...h...h...h..C...C...C...C. |
| 02e0 | 00 03 4a fe 00 03 4a fe 00 03 4a fe 00 03 4a fe 00 03 4a fe 00 03 4a fe 00 03 4a fe 00 03 4a fe | ..J...J...J...J...J...J...J...J. |
| 0300 | 00 03 4a fe 00 03 4a fe 00 03 4a fe 00 03 5a 86 00 03 5a 86 00 03 5a 86 00 03 5a 86 00 03 5a 86 | ..J...J...J...Z...Z...Z...Z...Z. |
| 0320 | 00 03 5a 86 00 03 5a 86 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 | ..Z...Z...e...e...e...e...e...e. |
| 0340 | 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 | ..e...e...e...e...e...e...e...e. |
| 0360 | 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 | ..e...e...e...e...e...e...e...e. |
| 0380 | 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 00 03 65 e8 | ..e...e...e...e...e...e...e...e. |
| 03a0 | 00 03 65 e8 00 03 65 e8 00 03 a6 d4 00 03 a6 d4 00 03 a6 d4 00 03 a6 d4 00 03 a6 d4 00 03 a6 d4 | ..e...e......................... |
| 03c0 | 00 03 a6 d4 00 03 a6 d4 00 03 a6 d4 00 03 a6 d4 00 03 c1 ac 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 03e0 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0400 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0420 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0440 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0460 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0480 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 04a0 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 04c0 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 04e0 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0500 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0520 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0540 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0560 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 0580 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 05a0 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 05c0 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a | ................................ |
| 05e0 | 00 03 d3 8a 00 03 d3 8a 00 03 d3 8a 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 | ................................ |
| 0600 | 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 | ................................ |
| 0620 | 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 | ................................ |
| 0640 | 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 | ................................ |
| 0660 | 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 04 f6 08 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c | ..................>...>...>...>. |
| 0680 | 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c | ..>...>...>...>...>...>...>...>. |
| 06a0 | 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c | ..>...>...>...>...>...>...>...>. |
| 06c0 | 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c | ..>...>...>...>...>...>...>...>. |
| 06e0 | 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c | ..>...>...>...>...>...>...>...>. |
| 0700 | 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c | ..>...>...>...>...>...>...>...>. |
| 0720 | 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c | ..>...>...>...>...>...>...>...>. |
| 0740 | 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c | ..>...>...>...>...>...>...>...>. |
| 0760 | 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 3e 9c 00 05 d8 ec 00 05 d8 ec | ..>...>...>...>...>...>......... |
| 0780 | 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec | ................................ |
| 07a0 | 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 d8 ec 00 05 fe 28 00 05 fe 28 | ...........................(...( |
| 07c0 | 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 | ...(...(...(...(...(...(...(...( |
| 07e0 | 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 | ...(...(...(...(...(...(...(...( |
| 0800 | 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 05 fe 28 00 06 49 a6 00 06 49 a6 | ...(...(...(...(...(...(..I...I. |
| 0820 | 00 06 49 a6 00 06 49 a6 00 06 49 a6 00 06 49 a6 00 06 49 a6 00 06 49 a6 00 06 49 a6 00 06 49 a6 | ..I...I...I...I...I...I...I...I. |
| 0840 | 00 06 49 a6 00 06 49 a6 00 06 49 a6 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 | ..I...I...I...^0..^0..^0..^0..^0 |
| 0860 | 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 | ..^0..^0..^0..^0..^0..^0..^0..^0 |
| 0880 | 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 | ..^0..^0..^0..^0..^0..^0..^0..^0 |
| 08a0 | 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 00 06 5e 30 | ..^0..^0..^0..^0..^0..^0..^0..^0 |
| 08c0 | 00 06 5e 30 00 06 5e 30 00 06 96 00 00 06 96 00 00 06 96 00 00 06 96 00 00 06 96 00 00 06 96 00 | ..^0..^0........................ |
| 08e0 | 00 06 96 00 00 06 96 00 00 06 96 00 00 06 96 00 00 06 96 00 00 06 96 00 00 06 96 00 00 06 96 00 | ................................ |
| 0900 | 00 06 96 00 00 06 96 00 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 | ................................ |
| 0920 | 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 | ................................ |
| 0940 | 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 ac 16 00 06 d1 28 00 06 d1 28 | ...........................(...( |
| 0960 | 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 | ...(...(...(...(...(...(...(...( |
| 0980 | 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 | ...(...(...(...(...(...(...(...( |
| 09a0 | 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 | ...(...(...(...(...(...(...(...( |
| 09c0 | 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 | ...(...(...(...(...(...(...(...( |
| 09e0 | 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 06 d1 28 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ...(...(...(...(................ |
| 0a00 | 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ................................ |
| 0a20 | 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ................................ |
| 0a40 | 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ................................ |
| 0a60 | 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ................................ |
| 0a80 | 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ................................ |
| 0aa0 | 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ................................ |
| 0ac0 | 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ................................ |
| 0ae0 | 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa 00 07 0f aa | ................................ |
| 0b00 | 00 07 0f aa 00 07 92 76 00 07 92 76 00 07 92 76 00 07 92 76 00 07 92 76 00 07 92 76 00 07 92 76 | .......v...v...v...v...v...v...v |
| 0b20 | 00 07 92 76 00 07 92 76 00 07 92 76 00 07 92 76 00 07 a3 d8 00 07 a8 96 00 07 a8 96 00 07 a8 96 | ...v...v...v...v................ |
| 0b40 | 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 | ................................ |
| 0b60 | 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 00 07 a8 96 | ................................ |
| 0b80 | 00 07 a8 96 00 07 c4 ba 00 07 ca 66 00 07 ca 66 00 07 ca 66 00 07 ca 66 00 07 ca 66 00 07 ca 66 | ...........f...f...f...f...f...f |
| 0ba0 | 00 07 ca 66 00 07 e0 c8 00 07 e0 c8 00 07 e0 c8 00 07 e0 c8 00 07 e0 c8 00 07 e0 c8 00 07 e0 c8 | ...f............................ |
| 0bc0 | 00 07 e0 c8 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 | ................................ |
| 0be0 | 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 | ................................ |
| 0c00 | 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 07 eb 82 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa | ................................ |
| 0c20 | 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa | ................................ |
| 0c40 | 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa | ................................ |
| 0c60 | 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa 00 08 04 fa | ................................ |
| 0c80 | 00 08 04 fa 00 08 04 fa 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 | ..........'...'...'...'...'...'. |
| 0ca0 | 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 | ..'...'...'...'...'...'...'...'. |
| 0cc0 | 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 | ..'...'...'...'...'...'...'...'. |
| 0ce0 | 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 00 08 27 88 | ..'...'...'...'...'...'...'...'. |
| 0d00 | 00 08 27 88 00 08 4e 22 00 08 51 be 00 08 51 be 00 08 51 be 00 08 51 be 00 08 51 be 00 08 51 be | ..'...N"..Q...Q...Q...Q...Q...Q. |
| 0d20 | 3f 52 65 73 65 74 40 54 69 6d 65 73 74 61 6d 70 53 63 61 6c 65 72 40 77 65 62 72 74 63 40 40 55 | ?Reset@TimestampScaler@webrtc@@U |
| 0d40 | 41 45 58 58 5a 00 3f 53 61 6d 70 6c 65 52 61 74 65 48 7a 40 44 65 63 6f 64 65 72 49 6e 66 6f 40 | AEXXZ.?SampleRateHz@DecoderInfo@ |
| 0d60 | 44 65 63 6f 64 65 72 44 61 74 61 62 61 73 65 40 77 65 62 72 74 63 40 40 51 42 45 48 58 5a 00 3f | DecoderDatabase@webrtc@@QBEHXZ.? |
| 0d80 | 54 6f 45 78 74 65 72 6e 61 6c 40 54 69 6d 65 73 74 61 6d 70 53 63 61 6c 65 72 40 77 65 62 72 74 | ToExternal@TimestampScaler@webrt |
| 0da0 | 63 40 40 55 42 45 49 49 40 5a 00 3f 54 6f 49 6e 74 65 72 6e 61 6c 40 54 69 6d 65 73 74 61 6d 70 | c@@UBEII@Z.?ToInternal@Timestamp |
| 0dc0 | 53 63 61 6c 65 72 40 77 65 62 72 74 63 40 40 55 41 45 49 49 45 40 5a 00 3f 54 6f 49 6e 74 65 72 | Scaler@webrtc@@UAEIIE@Z.?ToInter |
| 0de0 | 6e 61 6c 40 54 69 6d 65 73 74 61 6d 70 53 63 61 6c 65 72 40 77 65 62 72 74 63 40 40 55 41 45 58 | nal@TimestampScaler@webrtc@@UAEX |
| 0e00 | 50 41 55 50 61 63 6b 65 74 40 32 40 40 5a 00 3f 54 6f 49 6e 74 65 72 6e 61 6c 40 54 69 6d 65 73 | PAUPacket@2@@Z.?ToInternal@Times |
| 0e20 | 74 61 6d 70 53 63 61 6c 65 72 40 77 65 62 72 74 63 40 40 55 41 45 58 50 41 56 3f 24 6c 69 73 74 | tampScaler@webrtc@@UAEXPAV?$list |
| 0e40 | 40 55 50 61 63 6b 65 74 40 77 65 62 72 74 63 40 40 56 3f 24 61 6c 6c 6f 63 61 74 6f 72 40 55 50 | @UPacket@webrtc@@V?$allocator@UP |
| 0e60 | 61 63 6b 65 74 40 77 65 62 72 74 63 40 40 40 73 74 64 40 40 40 73 74 64 40 40 40 5a 00 3f 3f 24 | acket@webrtc@@@std@@@std@@@Z.??$ |
| 0e80 | 3f 36 55 3f 24 63 68 61 72 5f 74 72 61 69 74 73 40 44 40 73 74 64 40 40 40 73 74 64 40 40 59 41 | ?6U?$char_traits@D@std@@@std@@YA |
| 0ea0 | 41 41 56 3f 24 62 61 73 69 63 5f 6f 73 74 72 65 61 6d 40 44 55 3f 24 63 68 61 72 5f 74 72 61 69 | AAV?$basic_ostream@DU?$char_trai |
| 0ec0 | 74 73 40 44 40 73 74 64 40 40 40 30 40 41 41 56 31 30 40 50 42 44 40 5a 00 3f 3f 24 63 68 65 63 | ts@D@std@@@0@AAV10@PBD@Z.??$chec |
| 0ee0 | 6b 65 64 5f 63 61 73 74 40 48 49 40 72 74 63 40 40 59 41 48 49 40 5a 00 3f 3f 24 65 6e 64 6c 40 | ked_cast@HI@rtc@@YAHI@Z.??$endl@ |
| 0f00 | 44 55 3f 24 63 68 61 72 5f 74 72 61 69 74 73 40 44 40 73 74 64 40 40 40 73 74 64 40 40 59 41 41 | DU?$char_traits@D@std@@@std@@YAA |
| 0f20 | 41 56 3f 24 62 61 73 69 63 5f 6f 73 74 72 65 61 6d 40 44 55 3f 24 63 68 61 72 5f 74 72 61 69 74 | AV?$basic_ostream@DU?$char_trait |
| 0f40 | 73 40 44 40 73 74 64 40 40 40 30 40 41 41 56 31 30 40 40 5a 00 3f 3f 30 5f 53 65 6e 74 72 79 5f | s@D@std@@@0@AAV10@@Z.??0_Sentry_ |
| 0f60 | 62 61 73 65 40 3f 24 62 61 73 69 63 5f 6f 73 74 72 65 61 6d 40 44 55 3f 24 63 68 61 72 5f 74 72 | base@?$basic_ostream@DU?$char_tr |
| 0f80 | 61 69 74 73 40 44 40 73 74 64 40 40 40 73 74 64 40 40 51 41 45 40 41 41 56 31 32 40 40 5a 00 3f | aits@D@std@@@std@@QAE@AAV12@@Z.? |
| 0fa0 | 3f 30 73 65 6e 74 72 79 40 3f 24 62 61 73 69 63 5f 6f 73 74 72 65 61 6d 40 44 55 3f 24 63 68 61 | ?0sentry@?$basic_ostream@DU?$cha |
| 0fc0 | 72 5f 74 72 61 69 74 73 40 44 40 73 74 64 40 40 40 73 74 64 40 40 51 41 45 40 41 41 56 31 32 40 | r_traits@D@std@@@std@@QAE@AAV12@ |
| 0fe0 | 40 5a 00 3f 3f 5f 43 40 5f 30 32 4b 50 44 42 50 4b 50 47 40 3f 24 43 44 3f 35 3f 24 41 41 40 00 | @Z.??_C@_02KPDBPKPG@?$CD?5?$AA@. |
| 1000 | 3f 3f 5f 43 40 5f 30 44 47 40 45 42 50 43 43 42 4f 4f 40 64 3f 33 3f 32 77 65 62 72 74 63 3f 39 | ??_C@_0DG@EBPCCBOO@d?3?2webrtc?9 |
| 1020 | 63 68 65 63 6b 6f 75 74 3f 32 73 72 63 3f 32 77 65 62 72 74 63 3f 32 62 61 40 00 3f 3f 5f 43 40 | checkout?2src?2webrtc?2ba@.??_C@ |
| 1040 | 5f 30 44 48 40 4c 46 4a 4e 48 49 4f 4c 40 43 68 65 63 6b 3f 35 66 61 69 6c 65 64 3f 33 3f 35 49 | _0DH@LFJNHIOL@Check?5failed?3?5I |
| 1060 | 73 56 61 6c 75 65 49 6e 52 61 6e 67 65 46 6f 72 4e 40 00 3f 41 75 74 6f 43 6f 72 72 65 6c 61 74 | sValueInRangeForN@.?AutoCorrelat |
| 1080 | 69 6f 6e 40 54 69 6d 65 53 74 72 65 74 63 68 40 77 65 62 72 74 63 40 40 41 41 45 58 58 5a 00 3f | ion@TimeStretch@webrtc@@AAEXXZ.? |
| 10a0 | 50 72 6f 63 65 73 73 40 54 69 6d 65 53 74 72 65 74 63 68 40 77 65 62 72 74 63 40 40 51 41 45 3f | Process@TimeStretch@webrtc@@QAE? |
| 10c0 | 41 57 34 52 65 74 75 72 6e 43 6f 64 65 73 40 31 32 40 50 42 46 49 5f 4e 50 41 56 41 75 64 69 6f | AW4ReturnCodes@12@PBFI_NPAVAudio |
| 10e0 | 4d 75 6c 74 69 56 65 63 74 6f 72 40 32 40 50 41 49 40 5a 00 3f 53 70 65 65 63 68 44 65 74 65 63 | MultiVector@2@PAI@Z.?SpeechDetec |
| 1100 | 74 69 6f 6e 40 54 69 6d 65 53 74 72 65 74 63 68 40 77 65 62 72 74 63 40 40 41 42 45 5f 4e 48 48 | tion@TimeStretch@webrtc@@ABE_NHH |
| 1120 | 49 48 40 5a 00 3f 6c 65 6e 67 74 68 40 3f 24 63 68 61 72 5f 74 72 61 69 74 73 40 44 40 73 74 64 | IH@Z.?length@?$char_traits@D@std |
| 1140 | 40 40 53 41 49 50 42 44 40 5a 00 3f 3f 30 43 6f 75 6e 74 64 6f 77 6e 40 54 69 63 6b 54 69 6d 65 | @@SAIPBD@Z.??0Countdown@TickTime |
| 1160 | 72 40 77 65 62 72 74 63 40 40 51 41 45 40 41 42 56 31 32 40 5f 4b 40 5a 00 3f 3f 30 53 74 6f 70 | r@webrtc@@QAE@ABV12@_K@Z.??0Stop |
| 1180 | 77 61 74 63 68 40 54 69 63 6b 54 69 6d 65 72 40 77 65 62 72 74 63 40 40 51 41 45 40 41 42 56 31 | watch@TickTimer@webrtc@@QAE@ABV1 |
| 11a0 | 32 40 40 5a 00 3f 3f 31 43 6f 75 6e 74 64 6f 77 6e 40 54 69 63 6b 54 69 6d 65 72 40 77 65 62 72 | 2@@Z.??1Countdown@TickTimer@webr |
| 11c0 | 74 63 40 40 51 41 45 40 58 5a 00 3f 47 65 74 4e 65 77 53 74 6f 70 77 61 74 63 68 40 54 69 63 6b | tc@@QAE@XZ.?GetNewStopwatch@Tick |
| 11e0 | 54 69 6d 65 72 40 77 65 62 72 74 63 40 40 51 42 45 3f 41 56 3f 24 75 6e 69 71 75 65 5f 70 74 72 | Timer@webrtc@@QBE?AV?$unique_ptr |
| 1200 | 40 56 53 74 6f 70 77 61 74 63 68 40 54 69 63 6b 54 69 6d 65 72 40 77 65 62 72 74 63 40 40 55 3f | @VStopwatch@TickTimer@webrtc@@U? |
| 1220 | 24 64 65 66 61 75 6c 74 5f 64 65 6c 65 74 65 40 56 53 74 6f 70 77 61 74 63 68 40 54 69 63 6b 54 | $default_delete@VStopwatch@TickT |
| 1240 | 69 6d 65 72 40 77 65 62 72 74 63 40 40 40 73 74 64 40 40 40 73 74 64 40 40 58 5a 00 3f 46 6c 75 | imer@webrtc@@@std@@@std@@XZ.?Flu |
| 1260 | 73 68 40 53 79 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 40 51 41 45 58 58 5a 00 3f 46 75 | sh@SyncBuffer@webrtc@@QAEXXZ.?Fu |
| 1280 | 74 75 72 65 4c 65 6e 67 74 68 40 53 79 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 40 51 42 | tureLength@SyncBuffer@webrtc@@QB |
| 12a0 | 45 49 58 5a 00 3f 47 65 74 4e 65 78 74 41 75 64 69 6f 49 6e 74 65 72 6c 65 61 76 65 64 40 53 79 | EIXZ.?GetNextAudioInterleaved@Sy |
| 12c0 | 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 40 51 41 45 58 49 50 41 56 41 75 64 69 6f 46 72 | ncBuffer@webrtc@@QAEXIPAVAudioFr |
| 12e0 | 61 6d 65 40 32 40 40 5a 00 3f 49 6e 63 72 65 61 73 65 45 6e 64 54 69 6d 65 73 74 61 6d 70 40 53 | ame@2@@Z.?IncreaseEndTimestamp@S |
| 1300 | 79 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 40 51 41 45 58 49 40 5a 00 3f 49 6e 73 65 72 | yncBuffer@webrtc@@QAEXI@Z.?Inser |
| 1320 | 74 5a 65 72 6f 73 41 74 49 6e 64 65 78 40 53 79 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 | tZerosAtIndex@SyncBuffer@webrtc@ |
| 1340 | 40 55 41 45 58 49 49 40 5a 00 3f 50 75 73 68 42 61 63 6b 40 53 79 6e 63 42 75 66 66 65 72 40 77 | @UAEXII@Z.?PushBack@SyncBuffer@w |
| 1360 | 65 62 72 74 63 40 40 55 41 45 58 41 42 56 41 75 64 69 6f 4d 75 6c 74 69 56 65 63 74 6f 72 40 32 | ebrtc@@UAEXABVAudioMultiVector@2 |
| 1380 | 40 40 5a 00 3f 50 75 73 68 46 72 6f 6e 74 5a 65 72 6f 73 40 53 79 6e 63 42 75 66 66 65 72 40 77 | @@Z.?PushFrontZeros@SyncBuffer@w |
| 13a0 | 65 62 72 74 63 40 40 51 41 45 58 49 40 5a 00 3f 52 65 70 6c 61 63 65 41 74 49 6e 64 65 78 40 53 | ebrtc@@QAEXI@Z.?ReplaceAtIndex@S |
| 13c0 | 79 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 40 55 41 45 58 41 42 56 41 75 64 69 6f 4d 75 | yncBuffer@webrtc@@UAEXABVAudioMu |
| 13e0 | 6c 74 69 56 65 63 74 6f 72 40 32 40 49 40 5a 00 3f 52 65 70 6c 61 63 65 41 74 49 6e 64 65 78 40 | ltiVector@2@I@Z.?ReplaceAtIndex@ |
| 1400 | 53 79 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 40 55 41 45 58 41 42 56 41 75 64 69 6f 4d | SyncBuffer@webrtc@@UAEXABVAudioM |
| 1420 | 75 6c 74 69 56 65 63 74 6f 72 40 32 40 49 49 40 5a 00 3f 52 65 73 65 74 40 41 75 64 69 6f 46 72 | ultiVector@2@II@Z.?Reset@AudioFr |
| 1440 | 61 6d 65 40 77 65 62 72 74 63 40 40 51 41 45 58 58 5a 00 3f 73 65 74 5f 64 74 6d 66 5f 69 6e 64 | ame@webrtc@@QAEXXZ.?set_dtmf_ind |
| 1460 | 65 78 40 53 79 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 40 51 41 45 58 49 40 5a 00 3f 73 | ex@SyncBuffer@webrtc@@QAEXI@Z.?s |
| 1480 | 65 74 5f 6e 65 78 74 5f 69 6e 64 65 78 40 53 79 6e 63 42 75 66 66 65 72 40 77 65 62 72 74 63 40 | et_next_index@SyncBuffer@webrtc@ |
| 14a0 | 40 51 41 45 58 49 40 5a 00 3f 3f 24 43 68 65 63 6b 65 64 44 69 76 45 78 61 63 74 40 48 40 72 74 | @QAEXI@Z.??$CheckedDivExact@H@rt |
| 14c0 | 63 40 40 59 41 48 48 48 40 5a 00 3f 3f 24 5f 43 6f 70 79 5f 6d 65 6d 6d 6f 76 65 40 50 41 50 41 | c@@YAHHH@Z.??$_Copy_memmove@PAPA |
| 14e0 | 48 50 41 50 41 48 40 73 74 64 40 40 59 41 50 41 50 41 48 50 41 50 41 48 30 30 40 5a 00 3f 3f 24 | HPAPAH@std@@YAPAPAHPAPAH00@Z.??$ |
| 1500 | 5f 47 75 65 73 73 5f 6d 65 64 69 61 6e 5f 75 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 | _Guess_median_unchecked@V?$_Dequ |
| 1520 | 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 | e_unchecked_iterator@V?$_Deque_v |
| 1540 | 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 | al@U?$_Deque_simple_types@H@std@ |
| 1560 | 40 40 73 74 64 40 40 40 73 74 64 40 40 55 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 | @@std@@@std@@U?$less@X@2@@std@@Y |
| 1580 | 41 58 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 | AXV?$_Deque_unchecked_iterator@V |
| 15a0 | 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 | ?$_Deque_val@U?$_Deque_simple_ty |
| 15c0 | 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 30 41 41 55 3f 24 6c 65 73 73 40 | pes@H@std@@@std@@@0@00AAU?$less@ |
| 15e0 | 58 40 30 40 40 5a 00 3f 3f 24 5f 49 6e 73 65 72 74 69 6f 6e 5f 73 6f 72 74 5f 75 6e 63 68 65 63 | X@0@@Z.??$_Insertion_sort_unchec |
| 1600 | 6b 65 64 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 | ked@V?$_Deque_unchecked_iterator |
| 1620 | 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f | @V?$_Deque_val@U?$_Deque_simple_ |
| 1640 | 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 55 3f 24 6c 65 73 73 | types@H@std@@@std@@@std@@U?$less |
| 1660 | 40 58 40 32 40 40 73 74 64 40 40 59 41 58 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 | @X@2@@std@@YAXV?$_Deque_unchecke |
| 1680 | 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 | d_iterator@V?$_Deque_val@U?$_Deq |
| 16a0 | 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 | ue_simple_types@H@std@@@std@@@0@ |
| 16c0 | 30 41 41 55 3f 24 6c 65 73 73 40 58 40 30 40 40 5a 00 3f 3f 24 5f 4d 61 6b 65 5f 68 65 61 70 5f | 0AAU?$less@X@0@@Z.??$_Make_heap_ |
| 16e0 | 75 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 | unchecked@V?$_Deque_unchecked_it |
| 1700 | 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 | erator@V?$_Deque_val@U?$_Deque_s |
| 1720 | 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 55 | imple_types@H@std@@@std@@@std@@U |
| 1740 | 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 41 58 56 3f 24 5f 44 65 71 75 65 5f 75 6e | ?$less@X@2@@std@@YAXV?$_Deque_un |
| 1760 | 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 | checked_iterator@V?$_Deque_val@U |
| 1780 | 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 | ?$_Deque_simple_types@H@std@@@st |
| 17a0 | 64 40 40 40 30 40 30 41 41 55 3f 24 6c 65 73 73 40 58 40 30 40 40 5a 00 3f 3f 24 5f 4d 65 64 33 | d@@@0@0AAU?$less@X@0@@Z.??$_Med3 |
| 17c0 | 5f 75 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 | _unchecked@V?$_Deque_unchecked_i |
| 17e0 | 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f | terator@V?$_Deque_val@U?$_Deque_ |
| 1800 | 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 | simple_types@H@std@@@std@@@std@@ |
| 1820 | 55 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 41 58 56 3f 24 5f 44 65 71 75 65 5f 75 | U?$less@X@2@@std@@YAXV?$_Deque_u |
| 1840 | 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 | nchecked_iterator@V?$_Deque_val@ |
| 1860 | 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 | U?$_Deque_simple_types@H@std@@@s |
| 1880 | 74 64 40 40 40 30 40 30 30 41 41 55 3f 24 6c 65 73 73 40 58 40 30 40 40 5a 00 3f 3f 24 5f 4d 6f | td@@@0@00AAU?$less@X@0@@Z.??$_Mo |
| 18a0 | 76 65 5f 62 61 63 6b 77 61 72 64 5f 75 6e 63 68 65 63 6b 65 64 31 40 56 3f 24 5f 44 65 71 75 65 | ve_backward_unchecked1@V?$_Deque |
| 18c0 | 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 | _unchecked_iterator@V?$_Deque_va |
| 18e0 | 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 | l@U?$_Deque_simple_types@H@std@@ |
| 1900 | 40 73 74 64 40 40 40 73 74 64 40 40 56 31 32 40 40 73 74 64 40 40 59 41 3f 41 56 3f 24 5f 44 65 | @std@@@std@@V12@@std@@YA?AV?$_De |
| 1920 | 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 | que_unchecked_iterator@V?$_Deque |
| 1940 | 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 | _val@U?$_Deque_simple_types@H@st |
| 1960 | 64 40 40 40 73 74 64 40 40 40 30 40 56 31 30 40 30 30 55 5f 47 65 6e 65 72 61 6c 5f 70 74 72 5f | d@@@std@@@0@V10@00U_General_ptr_ |
| 1980 | 69 74 65 72 61 74 6f 72 5f 74 61 67 40 30 40 40 5a 00 3f 3f 24 5f 4d 6f 76 65 5f 62 61 63 6b 77 | iterator_tag@0@@Z.??$_Move_backw |
| 19a0 | 61 72 64 5f 75 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 | ard_unchecked@V?$_Deque_unchecke |
| 19c0 | 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 | d_iterator@V?$_Deque_val@U?$_Deq |
| 19e0 | 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 | ue_simple_types@H@std@@@std@@@st |
| 1a00 | 64 40 40 56 31 32 40 40 73 74 64 40 40 59 41 3f 41 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 | d@@V12@@std@@YA?AV?$_Deque_unche |
| 1a20 | 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f | cked_iterator@V?$_Deque_val@U?$_ |
| 1a40 | 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 | Deque_simple_types@H@std@@@std@@ |
| 1a60 | 40 30 40 56 31 30 40 30 30 40 5a 00 3f 3f 24 5f 50 61 72 74 69 74 69 6f 6e 5f 62 79 5f 6d 65 64 | @0@V10@00@Z.??$_Partition_by_med |
| 1a80 | 69 61 6e 5f 67 75 65 73 73 5f 75 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e | ian_guess_unchecked@V?$_Deque_un |
| 1aa0 | 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 | checked_iterator@V?$_Deque_val@U |
| 1ac0 | 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 | ?$_Deque_simple_types@H@std@@@st |
| 1ae0 | 64 40 40 40 73 74 64 40 40 55 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 41 3f 41 55 | d@@@std@@U?$less@X@2@@std@@YA?AU |
| 1b00 | 3f 24 70 61 69 72 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 | ?$pair@V?$_Deque_unchecked_itera |
| 1b20 | 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 | tor@V?$_Deque_val@U?$_Deque_simp |
| 1b40 | 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 56 31 32 40 | le_types@H@std@@@std@@@std@@V12@ |
| 1b60 | 40 30 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 | @0@V?$_Deque_unchecked_iterator@ |
| 1b80 | 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 | V?$_Deque_val@U?$_Deque_simple_t |
| 1ba0 | 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 41 41 55 3f 24 6c 65 73 73 40 | ypes@H@std@@@std@@@0@0AAU?$less@ |
| 1bc0 | 58 40 30 40 40 5a 00 3f 3f 24 5f 50 6f 70 5f 68 65 61 70 5f 68 6f 6c 65 5f 62 79 5f 69 6e 64 65 | X@0@@Z.??$_Pop_heap_hole_by_inde |
| 1be0 | 78 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 | x@V?$_Deque_unchecked_iterator@V |
| 1c00 | 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 | ?$_Deque_val@U?$_Deque_simple_ty |
| 1c20 | 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 48 48 55 3f 24 6c 65 73 73 | pes@H@std@@@std@@@std@@HHU?$less |
| 1c40 | 40 58 40 32 40 40 73 74 64 40 40 59 41 58 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 | @X@2@@std@@YAXV?$_Deque_unchecke |
| 1c60 | 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 | d_iterator@V?$_Deque_val@U?$_Deq |
| 1c80 | 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 | ue_simple_types@H@std@@@std@@@0@ |
| 1ca0 | 48 48 24 24 51 41 48 41 41 55 3f 24 6c 65 73 73 40 58 40 30 40 40 5a 00 3f 3f 24 5f 50 6f 70 5f | HH$$QAHAAU?$less@X@0@@Z.??$_Pop_ |
| 1cc0 | 68 65 61 70 5f 68 6f 6c 65 5f 75 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e | heap_hole_unchecked@V?$_Deque_un |
| 1ce0 | 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 | checked_iterator@V?$_Deque_val@U |
| 1d00 | 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 | ?$_Deque_simple_types@H@std@@@st |
| 1d20 | 64 40 40 40 73 74 64 40 40 48 55 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 41 58 56 | d@@@std@@HU?$less@X@2@@std@@YAXV |
| 1d40 | 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f | ?$_Deque_unchecked_iterator@V?$_ |
| 1d60 | 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 | Deque_val@U?$_Deque_simple_types |
| 1d80 | 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 30 24 24 51 41 48 41 41 55 3f 24 6c 65 73 | @H@std@@@std@@@0@00$$QAHAAU?$les |
| 1da0 | 73 40 58 40 30 40 40 5a 00 3f 3f 24 5f 50 6f 70 5f 68 65 61 70 5f 75 6e 63 68 65 63 6b 65 64 40 | s@X@0@@Z.??$_Pop_heap_unchecked@ |
| 1dc0 | 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 | V?$_Deque_unchecked_iterator@V?$ |
| 1de0 | 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 | _Deque_val@U?$_Deque_simple_type |
| 1e00 | 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 55 3f 24 6c 65 73 73 40 58 40 32 | s@H@std@@@std@@@std@@U?$less@X@2 |
| 1e20 | 40 40 73 74 64 40 40 59 41 58 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 | @@std@@YAXV?$_Deque_unchecked_it |
| 1e40 | 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 | erator@V?$_Deque_val@U?$_Deque_s |
| 1e60 | 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 41 41 55 | imple_types@H@std@@@std@@@0@0AAU |
| 1e80 | 3f 24 6c 65 73 73 40 58 40 30 40 40 5a 00 3f 3f 24 5f 50 75 73 68 5f 68 65 61 70 5f 62 79 5f 69 | ?$less@X@0@@Z.??$_Push_heap_by_i |
| 1ea0 | 6e 64 65 78 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f | ndex@V?$_Deque_unchecked_iterato |
| 1ec0 | 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 | r@V?$_Deque_val@U?$_Deque_simple |
| 1ee0 | 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 48 48 55 3f 24 6c | _types@H@std@@@std@@@std@@HHU?$l |
| 1f00 | 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 41 58 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 | ess@X@2@@std@@YAXV?$_Deque_unche |
| 1f20 | 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f | cked_iterator@V?$_Deque_val@U?$_ |
| 1f40 | 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 | Deque_simple_types@H@std@@@std@@ |
| 1f60 | 40 30 40 48 48 24 24 51 41 48 41 41 55 3f 24 6c 65 73 73 40 58 40 30 40 40 5a 00 3f 3f 24 5f 53 | @0@HH$$QAHAAU?$less@X@0@@Z.??$_S |
| 1f80 | 6f 72 74 5f 68 65 61 70 5f 75 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 | ort_heap_unchecked@V?$_Deque_unc |
| 1fa0 | 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f | hecked_iterator@V?$_Deque_val@U? |
| 1fc0 | 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 | $_Deque_simple_types@H@std@@@std |
| 1fe0 | 40 40 40 73 74 64 40 40 55 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 41 58 56 3f 24 | @@@std@@U?$less@X@2@@std@@YAXV?$ |
| 2000 | 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 | _Deque_unchecked_iterator@V?$_De |
| 2020 | 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 | que_val@U?$_Deque_simple_types@H |
| 2040 | 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 41 41 55 3f 24 6c 65 73 73 40 58 40 30 40 40 5a | @std@@@std@@@0@0AAU?$less@X@0@@Z |
| 2060 | 00 3f 3f 24 5f 53 6f 72 74 5f 75 6e 63 68 65 63 6b 65 64 31 40 56 3f 24 5f 44 65 71 75 65 5f 75 | .??$_Sort_unchecked1@V?$_Deque_u |
| 2080 | 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 | nchecked_iterator@V?$_Deque_val@ |
| 20a0 | 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 | U?$_Deque_simple_types@H@std@@@s |
| 20c0 | 74 64 40 40 40 73 74 64 40 40 48 55 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 41 58 | td@@@std@@HU?$less@X@2@@std@@YAX |
| 20e0 | 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 | V?$_Deque_unchecked_iterator@V?$ |
| 2100 | 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 | _Deque_val@U?$_Deque_simple_type |
| 2120 | 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 48 41 41 55 3f 24 6c 65 73 73 40 58 40 | s@H@std@@@std@@@0@0HAAU?$less@X@ |
| 2140 | 30 40 40 5a 00 3f 3f 24 5f 53 6f 72 74 5f 75 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 | 0@@Z.??$_Sort_unchecked@V?$_Dequ |
| 2160 | 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 | e_unchecked_iterator@V?$_Deque_v |
| 2180 | 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 | al@U?$_Deque_simple_types@H@std@ |
| 21a0 | 40 40 73 74 64 40 40 40 73 74 64 40 40 55 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 59 | @@std@@@std@@U?$less@X@2@@std@@Y |
| 21c0 | 41 58 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 | AXV?$_Deque_unchecked_iterator@V |
| 21e0 | 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 | ?$_Deque_val@U?$_Deque_simple_ty |
| 2200 | 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 41 41 55 3f 24 6c 65 73 73 40 58 | pes@H@std@@@std@@@0@0AAU?$less@X |
| 2220 | 40 30 40 40 5a 00 3f 3f 24 5f 55 6e 63 68 65 63 6b 65 64 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 | @0@@Z.??$_Unchecked@V?$_Deque_va |
| 2240 | 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 | l@U?$_Deque_simple_types@H@std@@ |
| 2260 | 40 73 74 64 40 40 40 73 74 64 40 40 59 41 3f 41 56 3f 24 5f 44 65 71 75 65 5f 75 6e 63 68 65 63 | @std@@@std@@YA?AV?$_Deque_unchec |
| 2280 | 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 | ked_iterator@V?$_Deque_val@U?$_D |
| 22a0 | 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 | eque_simple_types@H@std@@@std@@@ |
| 22c0 | 30 40 56 3f 24 5f 44 65 71 75 65 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 | 0@V?$_Deque_iterator@V?$_Deque_v |
| 22e0 | 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 | al@U?$_Deque_simple_types@H@std@ |
| 2300 | 40 40 73 74 64 40 40 40 30 40 40 5a 00 3f 3f 24 69 74 65 72 5f 73 77 61 70 40 56 3f 24 5f 44 65 | @@std@@@0@@Z.??$iter_swap@V?$_De |
| 2320 | 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 | que_unchecked_iterator@V?$_Deque |
| 2340 | 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 | _val@U?$_Deque_simple_types@H@st |
| 2360 | 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 56 31 32 40 40 73 74 64 40 40 59 41 58 56 3f 24 5f | d@@@std@@@std@@V12@@std@@YAXV?$_ |
| 2380 | 44 65 71 75 65 5f 75 6e 63 68 65 63 6b 65 64 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 | Deque_unchecked_iterator@V?$_Deq |
| 23a0 | 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 | ue_val@U?$_Deque_simple_types@H@ |
| 23c0 | 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 40 5a 00 3f 3f 24 73 61 74 75 72 61 74 65 64 5f 63 | std@@@std@@@0@0@Z.??$saturated_c |
| 23e0 | 61 73 74 40 48 4e 40 72 74 63 40 40 59 41 48 4e 40 5a 00 3f 3f 24 73 6f 72 74 40 56 3f 24 5f 44 | ast@HN@rtc@@YAHN@Z.??$sort@V?$_D |
| 2400 | 65 71 75 65 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f | eque_iterator@V?$_Deque_val@U?$_ |
| 2420 | 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 | Deque_simple_types@H@std@@@std@@ |
| 2440 | 40 73 74 64 40 40 40 73 74 64 40 40 59 41 58 56 3f 24 5f 44 65 71 75 65 5f 69 74 65 72 61 74 6f | @std@@@std@@YAXV?$_Deque_iterato |
| 2460 | 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 | r@V?$_Deque_val@U?$_Deque_simple |
| 2480 | 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 30 40 30 40 5a 00 3f 3f 24 73 6f | _types@H@std@@@std@@@0@0@Z.??$so |
| 24a0 | 72 74 40 56 3f 24 5f 44 65 71 75 65 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f | rt@V?$_Deque_iterator@V?$_Deque_ |
| 24c0 | 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 | val@U?$_Deque_simple_types@H@std |
| 24e0 | 40 40 40 73 74 64 40 40 40 73 74 64 40 40 55 3f 24 6c 65 73 73 40 58 40 32 40 40 73 74 64 40 40 | @@@std@@@std@@U?$less@X@2@@std@@ |
| 2500 | 59 41 58 56 3f 24 5f 44 65 71 75 65 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f | YAXV?$_Deque_iterator@V?$_Deque_ |
| 2520 | 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 | val@U?$_Deque_simple_types@H@std |
| 2540 | 40 40 40 73 74 64 40 40 40 30 40 30 55 3f 24 6c 65 73 73 40 58 40 30 40 40 5a 00 3f 3f 30 3f 24 | @@@std@@@0@0U?$less@X@0@@Z.??0?$ |
| 2560 | 5f 44 65 71 75 65 5f 61 6c 6c 6f 63 40 55 3f 24 5f 44 65 71 75 65 5f 62 61 73 65 5f 74 79 70 65 | _Deque_alloc@U?$_Deque_base_type |
| 2580 | 73 40 48 56 3f 24 61 6c 6c 6f 63 61 74 6f 72 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 | s@HV?$allocator@H@std@@@std@@@st |
| 25a0 | 64 40 40 51 41 45 40 58 5a 00 3f 3f 30 3f 24 5f 44 65 71 75 65 5f 63 6f 6e 73 74 5f 69 74 65 72 | d@@QAE@XZ.??0?$_Deque_const_iter |
| 25c0 | 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d | ator@V?$_Deque_val@U?$_Deque_sim |
| 25e0 | 70 6c 65 5f 74 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 51 41 45 | ple_types@H@std@@@std@@@std@@QAE |
| 2600 | 40 49 50 42 55 5f 43 6f 6e 74 61 69 6e 65 72 5f 62 61 73 65 31 32 40 31 40 40 5a 00 3f 3f 30 3f | @IPBU_Container_base12@1@@Z.??0? |
| 2620 | 24 62 61 73 69 63 5f 73 74 72 69 6e 67 40 44 55 3f 24 63 68 61 72 5f 74 72 61 69 74 73 40 44 40 | $basic_string@DU?$char_traits@D@ |
| 2640 | 73 74 64 40 40 56 3f 24 61 6c 6c 6f 63 61 74 6f 72 40 44 40 32 40 40 73 74 64 40 40 51 41 45 40 | std@@V?$allocator@D@2@@std@@QAE@ |
| 2660 | 41 42 56 30 31 40 40 5a 00 3f 3f 30 3f 24 62 61 73 69 63 5f 73 74 72 69 6e 67 40 44 55 3f 24 63 | ABV01@@Z.??0?$basic_string@DU?$c |
| 2680 | 68 61 72 5f 74 72 61 69 74 73 40 44 40 73 74 64 40 40 56 3f 24 61 6c 6c 6f 63 61 74 6f 72 40 44 | har_traits@D@std@@V?$allocator@D |
| 26a0 | 40 32 40 40 73 74 64 40 40 51 41 45 40 50 42 44 40 5a 00 3f 3f 30 50 65 72 69 6f 64 69 63 55 6d | @2@@std@@QAE@PBD@Z.??0PeriodicUm |
| 26c0 | 61 41 76 65 72 61 67 65 40 53 74 61 74 69 73 74 69 63 73 43 61 6c 63 75 6c 61 74 6f 72 40 77 65 | aAverage@StatisticsCalculator@we |
| 26e0 | 62 72 74 63 40 40 51 41 45 40 41 42 56 3f 24 62 61 73 69 63 5f 73 74 72 69 6e 67 40 44 55 3f 24 | brtc@@QAE@ABV?$basic_string@DU?$ |
| 2700 | 63 68 61 72 5f 74 72 61 69 74 73 40 44 40 73 74 64 40 40 56 3f 24 61 6c 6c 6f 63 61 74 6f 72 40 | char_traits@D@std@@V?$allocator@ |
| 2720 | 44 40 32 40 40 73 74 64 40 40 48 48 40 5a 00 3f 3f 30 50 65 72 69 6f 64 69 63 55 6d 61 43 6f 75 | D@2@@std@@HH@Z.??0PeriodicUmaCou |
| 2740 | 6e 74 40 53 74 61 74 69 73 74 69 63 73 43 61 6c 63 75 6c 61 74 6f 72 40 77 65 62 72 74 63 40 40 | nt@StatisticsCalculator@webrtc@@ |
| 2760 | 51 41 45 40 41 42 56 3f 24 62 61 73 69 63 5f 73 74 72 69 6e 67 40 44 55 3f 24 63 68 61 72 5f 74 | QAE@ABV?$basic_string@DU?$char_t |
| 2780 | 72 61 69 74 73 40 44 40 73 74 64 40 40 56 3f 24 61 6c 6c 6f 63 61 74 6f 72 40 44 40 32 40 40 73 | raits@D@std@@V?$allocator@D@2@@s |
| 27a0 | 74 64 40 40 48 48 40 5a 00 3f 3f 30 50 65 72 69 6f 64 69 63 55 6d 61 4c 6f 67 67 65 72 40 53 74 | td@@HH@Z.??0PeriodicUmaLogger@St |
| 27c0 | 61 74 69 73 74 69 63 73 43 61 6c 63 75 6c 61 74 6f 72 40 77 65 62 72 74 63 40 40 51 41 45 40 41 | atisticsCalculator@webrtc@@QAE@A |
| 27e0 | 42 56 3f 24 62 61 73 69 63 5f 73 74 72 69 6e 67 40 44 55 3f 24 63 68 61 72 5f 74 72 61 69 74 73 | BV?$basic_string@DU?$char_traits |
| 2800 | 40 44 40 73 74 64 40 40 56 3f 24 61 6c 6c 6f 63 61 74 6f 72 40 44 40 32 40 40 73 74 64 40 40 48 | @D@std@@V?$allocator@D@2@@std@@H |
| 2820 | 48 40 5a 00 3f 3f 30 53 74 61 74 69 73 74 69 63 73 43 61 6c 63 75 6c 61 74 6f 72 40 77 65 62 72 | H@Z.??0StatisticsCalculator@webr |
| 2840 | 74 63 40 40 51 41 45 40 58 5a 00 3f 3f 31 3f 24 64 65 71 75 65 40 48 56 3f 24 61 6c 6c 6f 63 61 | tc@@QAE@XZ.??1?$deque@HV?$alloca |
| 2860 | 74 6f 72 40 48 40 73 74 64 40 40 40 73 74 64 40 40 51 41 45 40 58 5a 00 3f 3f 31 50 65 72 69 6f | tor@H@std@@@std@@QAE@XZ.??1Perio |
| 2880 | 64 69 63 55 6d 61 41 76 65 72 61 67 65 40 53 74 61 74 69 73 74 69 63 73 43 61 6c 63 75 6c 61 74 | dicUmaAverage@StatisticsCalculat |
| 28a0 | 6f 72 40 77 65 62 72 74 63 40 40 55 41 45 40 58 5a 00 3f 3f 31 50 65 72 69 6f 64 69 63 55 6d 61 | or@webrtc@@UAE@XZ.??1PeriodicUma |
| 28c0 | 43 6f 75 6e 74 40 53 74 61 74 69 73 74 69 63 73 43 61 6c 63 75 6c 61 74 6f 72 40 77 65 62 72 74 | Count@StatisticsCalculator@webrt |
| 28e0 | 63 40 40 55 41 45 40 58 5a 00 3f 3f 31 50 65 72 69 6f 64 69 63 55 6d 61 4c 6f 67 67 65 72 40 53 | c@@UAE@XZ.??1PeriodicUmaLogger@S |
| 2900 | 74 61 74 69 73 74 69 63 73 43 61 6c 63 75 6c 61 74 6f 72 40 77 65 62 72 74 63 40 40 55 41 45 40 | tatisticsCalculator@webrtc@@UAE@ |
| 2920 | 58 5a 00 3f 3f 31 53 74 61 74 69 73 74 69 63 73 43 61 6c 63 75 6c 61 74 6f 72 40 77 65 62 72 74 | XZ.??1StatisticsCalculator@webrt |
| 2940 | 63 40 40 55 41 45 40 58 5a 00 3f 3f 34 5f 49 74 65 72 61 74 6f 72 5f 62 61 73 65 31 32 40 73 74 | c@@UAE@XZ.??4_Iterator_base12@st |
| 2960 | 64 40 40 51 41 45 41 41 55 30 31 40 41 42 55 30 31 40 40 5a 00 3f 3f 41 3f 24 64 65 71 75 65 40 | d@@QAEAAU01@ABU01@@Z.??A?$deque@ |
| 2980 | 48 56 3f 24 61 6c 6c 6f 63 61 74 6f 72 40 48 40 73 74 64 40 40 40 73 74 64 40 40 51 41 45 41 41 | HV?$allocator@H@std@@@std@@QAEAA |
| 29a0 | 48 49 40 5a 00 3f 3f 44 3f 24 5f 44 65 71 75 65 5f 63 6f 6e 73 74 5f 69 74 65 72 61 74 6f 72 40 | HI@Z.??D?$_Deque_const_iterator@ |
| 29c0 | 56 3f 24 5f 44 65 71 75 65 5f 76 61 6c 40 55 3f 24 5f 44 65 71 75 65 5f 73 69 6d 70 6c 65 5f 74 | V?$_Deque_val@U?$_Deque_simple_t |
| 29e0 | 79 70 65 73 40 48 40 73 74 64 40 40 40 73 74 64 40 40 40 73 74 64 40 40 51 42 45 41 42 48 58 5a | ypes@H@std@@@std@@@std@@QBEABHXZ |
| 2a00 | 00 3f 3f 47 3f 24 5f 44 65 71 75 65 5f 69 74 65 72 61 74 6f 72 40 56 3f 24 5f 44 65 71 75 65 5f | .??G?$_Deque_iterator@V?$_Deque// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using System.Windows.Threading;
using Tango.Scripting.Editors.Document;
using Tango.Scripting.Editors.Editing;
using Tango.Scripting.Editors.Utils;
namespace Tango.Scripting.Editors.Rendering
{
/// <summary>
/// A virtualizing panel producing+showing <see cref="VisualLine"/>s for a <see cref="TextDocument"/>.
///
/// This is the heart of the text editor, this class controls the text rendering process.
///
/// Taken as a standalone control, it's a text viewer without any editing capability.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable",
Justification = "The user usually doesn't work with TextView but with TextEditor; and nulling the Document property is sufficient to dispose everything.")]
public class TextView : FrameworkElement, IScrollInfo, IWeakEventListener, ITextEditorComponent, IServiceProvider
{
#region Constructor
static TextView()
{
ClipToBoundsProperty.OverrideMetadata(typeof(TextView), new FrameworkPropertyMetadata(Boxes.True));
FocusableProperty.OverrideMetadata(typeof(TextView), new FrameworkPropertyMetadata(Boxes.False));
}
ColumnRulerRenderer columnRulerRenderer;
/// <summary>
/// Creates a new TextView instance.
/// </summary>
public TextView()
{
services.AddService(typeof(TextView), this);
textLayer = new TextLayer(this);
elementGenerators = new ObserveAddRemoveCollection<VisualLineElementGenerator>(ElementGenerator_Added, ElementGenerator_Removed);
lineTransformers = new ObserveAddRemoveCollection<IVisualLineTransformer>(LineTransformer_Added, LineTransformer_Removed);
backgroundRenderers = new ObserveAddRemoveCollection<IBackgroundRenderer>(BackgroundRenderer_Added, BackgroundRenderer_Removed);
columnRulerRenderer = new ColumnRulerRenderer(this);
this.Options = new TextEditorOptions();
Debug.Assert(singleCharacterElementGenerator != null); // assert that the option change created the builtin element generators
layers = new LayerCollection(this);
InsertLayer(textLayer, KnownLayer.Text, LayerInsertionPosition.Replace);
this.hoverLogic = new MouseHoverLogic(this);
this.hoverLogic.MouseHover += (sender, e) => RaiseHoverEventPair(e, PreviewMouseHoverEvent, MouseHoverEvent);
this.hoverLogic.MouseHoverStopped += (sender, e) => RaiseHoverEventPair(e, PreviewMouseHoverStoppedEvent, MouseHoverStoppedEvent);
}
#endregion
#region Document Property
/// <summary>
/// Document property.
/// </summary>
public static readonly DependencyProperty DocumentProperty =
DependencyProperty.Register("Document", typeof(TextDocument), typeof(TextView),
new FrameworkPropertyMetadata(OnDocumentChanged));
TextDocument document;
HeightTree heightTree;
/// <summary>
/// Gets/Sets the document displayed by the text editor.
/// </summary>
public TextDocument Document {
get { return (TextDocument)GetValue(DocumentProperty); }
set { SetValue(DocumentProperty, value); }
}
static void OnDocumentChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
((TextView)dp).OnDocumentChanged((TextDocument)e.OldValue, (TextDocument)e.NewValue);
}
internal double FontSize {
get {
return (double)GetValue(TextBlock.FontSizeProperty);
}
}
/// <summary>
/// Occurs when the document property has changed.
/// </summary>
public event EventHandler DocumentChanged;
void OnDocumentChanged(TextDocument oldValue, TextDocument newValue)
{
if (oldValue != null) {
heightTree.Dispose();
heightTree = null;
formatter.Dispose();
formatter = null;
cachedElements.Dispose();
cachedElements = null;
TextDocumentWeakEventManager.Changing.RemoveListener(oldValue, this);
}
this.document = newValue;
ClearScrollData();
ClearVisualLines();
if (newValue != null) {
TextDocumentWeakEventManager.Changing.AddListener(newValue, this);
formatter = TextFormatterFactory.Create(this);
InvalidateDefaultTextMetrics(); // measuring DefaultLineHeight depends on formatter
heightTree = new HeightTree(newValue, DefaultLineHeight);
cachedElements = new TextViewCachedElements();
}
InvalidateMeasure(DispatcherPriority.Normal);
if (DocumentChanged != null)
DocumentChanged(this, EventArgs.Empty);
}
/// <summary>
/// Recreates the text formatter that is used internally
/// by calling <see cref="TextFormatterFactory.Create"/>.
/// </summary>
void RecreateTextFormatter()
{
if (formatter != null) {
formatter.Dispose();
formatter = TextFormatterFactory.Create(this);
Redraw();
}
}
void RecreateCachedElements()
{
if (cachedElements != null) {
cachedElements.Dispose();
cachedElements = new TextViewCachedElements();
}
}
/// <inheritdoc cref="IWeakEventListener.ReceiveWeakEvent"/>
protected virtual bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
if (managerType == typeof(TextDocumentWeakEventManager.Changing)) {
// TODO: put redraw into background so that other input events can be handled before the redraw.
// Unfortunately the "easy" approach (just use DispatcherPriority.Background) here makes the editor twice as slow because
// the caret position change forces an immediate redraw, and the text input then forces a background redraw.
// When fixing this, make sure performance on the SharpDevelop "type text in C# comment" stress test doesn't get significantly worse.
DocumentChangeEventArgs change = (DocumentChangeEventArgs)e;
Redraw(change.Offset, change.RemovalLength, DispatcherPriority.Normal);
return true;
} else if (managerType == typeof(PropertyChangedWeakEventManager)) {
OnOptionChanged((PropertyChangedEventArgs)e);
return true;
}
return false;
}
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
return ReceiveWeakEvent(managerType, sender, e);
}
#endregion
#region Options property
/// <summary>
/// Options property.
/// </summary>
public static readonly DependencyProperty OptionsProperty =
DependencyProperty.Register("Options", typeof(TextEditorOptions), typeof(TextView),
new FrameworkPropertyMetadata(OnOptionsChanged));
/// <summary>
/// Gets/Sets the options used by the text editor.
/// </summary>
public TextEditorOptions Options {
get { return (TextEditorOptions)GetValue(OptionsProperty); }
set { SetValue(OptionsProperty, value); }
}
/// <summary>
/// Occurs when a text editor option has changed.
/// </summary>
public event PropertyChangedEventHandler OptionChanged;
/// <summary>
/// Raises the <see cref="OptionChanged"/> event.
/// </summary>
protected virtual void OnOptionChanged(PropertyChangedEventArgs e)
{
if (OptionChanged != null) {
OptionChanged(this, e);
}
if (Options.ShowColumnRuler)
columnRulerRenderer.SetRuler(Options.ColumnRulerPosition, ColumnRulerPen);
else
columnRulerRenderer.SetRuler(-1, ColumnRulerPen);
UpdateBuiltinElementGeneratorsFromOptions();
Redraw();
}
static void OnOptionsChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
((TextView)dp).OnOptionsChanged((TextEditorOptions)e.OldValue, (TextEditorOptions)e.NewValue);
}
void OnOptionsChanged(TextEditorOptions oldValue, TextEditorOptions newValue)
{
if (oldValue != null) {
PropertyChangedWeakEventManager.RemoveListener(oldValue, this);
}
if (newValue != null) {
PropertyChangedWeakEventManager.AddListener(newValue, this);
}
OnOptionChanged(new PropertyChangedEventArgs(null));
}
#endregion
#region ElementGenerators+LineTransformers Properties
readonly ObserveAddRemoveCollection<VisualLineElementGenerator> elementGenerators;
/// <summary>
/// Gets a collection where element generators can be registered.
/// </summary>
public IList<VisualLineElementGenerator> ElementGenerators {
get { return elementGenerators; }
}
void ElementGenerator_Added(VisualLineElementGenerator generator)
{
ConnectToTextView(generator);
Redraw();
}
void ElementGenerator_Removed(VisualLineElementGenerator generator)
{
DisconnectFromTextView(generator);
Redraw();
}
readonly ObserveAddRemoveCollection<IVisualLineTransformer> lineTransformers;
/// <summary>
/// Gets a collection where line transformers can be registered.
/// </summary>
public IList<IVisualLineTransformer> LineTransformers {
get { return lineTransformers; }
}
void LineTransformer_Added(IVisualLineTransformer lineTransformer)
{
ConnectToTextView(lineTransformer);
Redraw();
}
void LineTransformer_Removed(IVisualLineTransformer lineTransformer)
{
DisconnectFromTextView(lineTransformer);
Redraw();
}
#endregion
#region Builtin ElementGenerators
// NewLineElementGenerator newLineElementGenerator;
SingleCharacterElementGenerator singleCharacterElementGenerator;
LinkElementGenerator linkElementGenerator;
MailLinkElementGenerator mailLinkElementGenerator;
void UpdateBuiltinElementGeneratorsFromOptions()
{
TextEditorOptions options = this.Options;
// AddRemoveDefaultElementGeneratorOnDemand(ref newLineElementGenerator, options.ShowEndOfLine);
AddRemoveDefaultElementGeneratorOnDemand(ref singleCharacterElementGenerator, options.ShowBoxForControlCharacters || options.ShowSpaces || options.ShowTabs);
AddRemoveDefaultElementGeneratorOnDemand(ref linkElementGenerator, options.EnableHyperlinks);
AddRemoveDefaultElementGeneratorOnDemand(ref mailLinkElementGenerator, options.EnableEmailHyperlinks);
}
void AddRemoveDefaultElementGeneratorOnDemand<T>(ref T generator, bool demand)
where T : VisualLineElementGenerator, IBuiltinElementGenerator, new()
{
bool hasGenerator = generator != null;
if (hasGenerator != demand) {
if (demand) {
generator = new T();
this.ElementGenerators.Add(generator);
} else {
this.ElementGenerators.Remove(generator);
generator = null;
}
}
if (generator != null)
generator.FetchOptions(this.Options);
}
#endregion
#region Layers
internal readonly TextLayer textLayer;
readonly LayerCollection layers;
/// <summary>
/// Gets the list of layers displayed in the text view.
/// </summary>
public UIElementCollection Layers {
get { return layers; }
}
sealed class LayerCollection : UIElementCollection
{
readonly TextView textView;
public LayerCollection(TextView textView)
: base(textView, textView)
{
this.textView = textView;
}
public override void Clear()
{
base.Clear();
textView.LayersChanged();
}
public override int Add(UIElement element)
{
int r = base.Add(element);
textView.LayersChanged();
return r;
}
public override void RemoveAt(int index)
{
base.RemoveAt(index);
textView.LayersChanged();
}
public override void RemoveRange(int index, int count)
{
base.RemoveRange(index, count);
textView.LayersChanged();
}
}
void LayersChanged()
{
textLayer.index = layers.IndexOf(textLayer);
}
/// <summary>
/// Inserts a new layer at a position specified relative to an existing layer.
/// </summary>
/// <param name="layer">The new layer to insert.</param>
/// <param name="referencedLayer">The existing layer</param>
/// <param name="position">Specifies whether the layer is inserted above,below, or replaces the referenced layer</param>
public void InsertLayer(UIElement layer, KnownLayer referencedLayer, LayerInsertionPosition position)
{
if (layer == null)
throw new ArgumentNullException("layer");
if (!Enum.IsDefined(typeof(KnownLayer), referencedLayer))
throw new InvalidEnumArgumentException("referencedLayer", (int)referencedLayer, typeof(KnownLayer));
if (!Enum.IsDefined(typeof(LayerInsertionPosition), position))
throw new InvalidEnumArgumentException("position", (int)position, typeof(LayerInsertionPosition));
if (referencedLayer == KnownLayer.Background && position != LayerInsertionPosition.Above)
throw new InvalidOperationException("Cannot replace or insert below the background layer.");
LayerPosition newPosition = new LayerPosition(referencedLayer, position);
LayerPosition.SetLayerPosition(layer, newPosition);
for (int i = 0; i < layers.Count; i++) {
LayerPosition p = LayerPosition.GetLayerPosition(layers[i]);
if (p != null) {
if (p.KnownLayer == referencedLayer && p.Position == LayerInsertionPosition.Replace) {
// found the referenced layer
switch (position) {
case LayerInsertionPosition.Below:
layers.Insert(i, layer);
return;
case LayerInsertionPosition.Above:
layers.Insert(i + 1, layer);
return;
case LayerInsertionPosition.Replace:
layers[i] = layer;
return;
}
} else if (p.KnownLayer == referencedLayer && p.Position == LayerInsertionPosition.Above
|| p.KnownLayer > referencedLayer) {
// we skipped the insertion position (referenced layer does not exist?)
layers.Insert(i, layer);
return;
}
}
}
// inserting after all existing layers:
layers.Add(layer);
}
/// <inheritdoc/>
protected override int VisualChildrenCount {
get { return layers.Count + inlineObjects.Count; }
}
/// <inheritdoc/>
protected override Visual GetVisualChild(int index)
{
int cut = textLayer.index + 1;
if (index < cut)
return layers[index];
else if (index < cut + inlineObjects.Count)
return inlineObjects[index - cut].Element;
else
return layers[index - inlineObjects.Count];
}
/// <inheritdoc/>
protected override System.Collections.IEnumerator LogicalChildren {
get {
return inlineObjects.Select(io => io.Element).Concat(layers.Cast<UIElement>()).GetEnumerator();
}
}
#endregion
#region Inline object handling
List<InlineObjectRun> inlineObjects = new List<InlineObjectRun>();
/// <summary>
/// Adds a new inline object.
/// </summary>
internal void AddInlineObject(InlineObjectRun inlineObject)
{
Debug.Assert(inlineObject.VisualLine != null);
// Remove inline object if its already added, can happen e.g. when recreating textrun for word-wrapping
bool alreadyAdded = false;
for (int i = 0; i < inlineObjects.Count; i++) {
if (inlineObjects[i].Element == inlineObject.Element) {
RemoveInlineObjectRun(inlineObjects[i], true);
inlineObjects.RemoveAt(i);
alreadyAdded = true;
break;
}
}
inlineObjects.Add(inlineObject);
if (!alreadyAdded) {
AddVisualChild(inlineObject.Element);
}
inlineObject.Element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
inlineObject.desiredSize = inlineObject.Element.DesiredSize;
}
void MeasureInlineObjects()
{
// As part of MeasureOverride(), re-measure the inline objects
foreach (InlineObjectRun inlineObject in inlineObjects) {
if (inlineObject.VisualLine.IsDisposed) {
// Don't re-measure inline objects that are going to be removed anyways.
// If the inline object will be reused in a different VisualLine, we'll measure it in the AddInlineObject() call.
continue;
}
inlineObject.Element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
if (!inlineObject.Element.DesiredSize.IsClose(inlineObject.desiredSize)) {
// the element changed size -> recreate its parent visual line
inlineObject.desiredSize = inlineObject.Element.DesiredSize;
if (allVisualLines.Remove(inlineObject.VisualLine)) {
DisposeVisualLine(inlineObject.VisualLine);
}
}
}
}
List<VisualLine> visualLinesWithOutstandingInlineObjects = new List<VisualLine>();
void RemoveInlineObjects(VisualLine visualLine)
{
// Delay removing inline objects:
// A document change immediately invalidates affected visual lines, but it does not
// cause an immediate redraw.
// To prevent inline objects from flickering when they are recreated, we delay removing
// inline objects until the next redraw.
if (visualLine.hasInlineObjects) {
visualLinesWithOutstandingInlineObjects.Add(visualLine);
}
}
/// <summary>
/// Remove the inline objects that were marked for removal.
/// </summary>
void RemoveInlineObjectsNow()
{
if (visualLinesWithOutstandingInlineObjects.Count == 0)
return;
inlineObjects.RemoveAll(
ior => {
if (visualLinesWithOutstandingInlineObjects.Contains(ior.VisualLine)) {
RemoveInlineObjectRun(ior, false);
return true;
}
return false;
});
visualLinesWithOutstandingInlineObjects.Clear();
}
// Remove InlineObjectRun.Element from TextLayer.
// Caller of RemoveInlineObjectRun will remove it from inlineObjects collection.
void RemoveInlineObjectRun(InlineObjectRun ior, bool keepElement)
{
if (!keepElement && ior.Element.IsKeyboardFocusWithin) {
// When the inline element that has the focus is removed, WPF will reset the
// focus to the main window without raising appropriate LostKeyboardFocus events.
// To work around this, we manually set focus to the next focusable parent.
UIElement element = this;
while (element != null && !element.Focusable) {
element = VisualTreeHelper.GetParent(element) as UIElement;
}
if (element != null)
Keyboard.Focus(element);
}
ior.VisualLine = null;
if (!keepElement)
RemoveVisualChild(ior.Element);
}
#endregion
#region Brushes
/// <summary>
/// NonPrintableCharacterBrush dependency property.
/// </summary>
public static readonly DependencyProperty NonPrintableCharacterBrushProperty =
DependencyProperty.Register("NonPrintableCharacterBrush", typeof(Brush), typeof(TextView),
new FrameworkPropertyMetadata(Brushes.LightGray));
/// <summary>
/// Gets/sets the Brush used for displaying non-printable characters.
/// </summary>
public Brush NonPrintableCharacterBrush {
get { return (Brush)GetValue(NonPrintableCharacterBrushProperty); }
set { SetValue(NonPrintableCharacterBrushProperty, value); }
}
/// <summary>
/// LinkTextForegroundBrush dependency property.
/// </summary>
public static readonly DependencyProperty LinkTextForegroundBrushProperty =
DependencyProperty.Register("LinkTextForegroundBrush", typeof(Brush), typeof(TextView),
new FrameworkPropertyMetadata(Brushes.Blue));
/// <summary>
/// Gets/sets the Brush used for displaying link texts.
/// </summary>
public Brush LinkTextForegroundBrush {
get { return (Brush)GetValue(LinkTextForegroundBrushProperty); }
set { SetValue(LinkTextForegroundBrushProperty, value); }
}
/// <summary>
/// LinkTextBackgroundBrush dependency property.
/// </summary>
public static readonly DependencyProperty LinkTextBackgroundBrushProperty =
DependencyProperty.Register("LinkTextBackgroundBrush", typeof(Brush), typeof(TextView),
new FrameworkPropertyMetadata(Brushes.Transparent));
/// <summary>
/// Gets/sets the Brush used for the background of link texts.
/// </summary>
public Brush LinkTextBackgroundBrush {
get { return (Brush)GetValue(LinkTextBackgroundBrushProperty); }
set { SetValue(LinkTextBackgroundBrushProperty, value); }
}
#endregion
#region Redraw methods / VisualLine invalidation
/// <summary>
/// Causes the text editor to regenerate all visual lines.
/// </summary>
public void Redraw()
{
Redraw(DispatcherPriority.Normal);
}
/// <summary>
/// Causes the text editor to regenerate all visual lines.
/// </summary>
public void Redraw(DispatcherPriority redrawPriority)
{
VerifyAccess();
ClearVisualLines();
InvalidateMeasure(redrawPriority);
}
/// <summary>
/// Causes the text editor to regenerate the specified visual line.
/// </summary>
public void Redraw(VisualLine visualLine, DispatcherPriority redrawPriority = DispatcherPriority.Normal)
{
VerifyAccess();
if (allVisualLines.Remove(visualLine)) {
DisposeVisualLine(visualLine);
InvalidateMeasure(redrawPriority);
}
}
/// <summary>
/// Causes the text editor to redraw all lines overlapping with the specified segment.
/// </summary>
public void Redraw(int offset, int length, DispatcherPriority redrawPriority = DispatcherPriority.Normal)
{
VerifyAccess();
bool changedSomethingBeforeOrInLine = false;
for (int i = 0; i < allVisualLines.Count; i++) {
VisualLine visualLine = allVisualLines[i];
int lineStart = visualLine.FirstDocumentLine.Offset;
int lineEnd = visualLine.LastDocumentLine.Offset + visualLine.LastDocumentLine.TotalLength;
if (offset <= lineEnd) {
changedSomethingBeforeOrInLine = true;
if (offset + length >= lineStart) {
allVisualLines.RemoveAt(i--);
DisposeVisualLine(visualLine);
}
}
}
if (changedSomethingBeforeOrInLine) {
// Repaint not only when something in visible area was changed, but also when anything in front of it
// was changed. We might have to redraw the line number margin. Or the highlighting changed.
// However, we'll try to reuse the existing VisualLines.
InvalidateMeasure(redrawPriority);
}
}
/// <summary>
/// Causes a known layer to redraw.
/// This method does not invalidate visual lines;
/// use the <see cref="Redraw()"/> method to do that.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "knownLayer",
Justification="This method is meant to invalidate only a specific layer - I just haven't figured out how to do that, yet.")]
public void InvalidateLayer(KnownLayer knownLayer)
{
InvalidateMeasure(DispatcherPriority.Normal);
}
/// <summary>
/// Causes a known layer to redraw.
/// This method does not invalidate visual lines;
/// use the <see cref="Redraw()"/> method to do that.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "knownLayer",
Justification="This method is meant to invalidate only a specific layer - I just haven't figured out how to do that, yet.")]
public void InvalidateLayer(KnownLayer knownLayer, DispatcherPriority priority)
{
InvalidateMeasure(priority);
}
/// <summary>
/// Causes the text editor to redraw all lines overlapping with the specified segment.
/// Does nothing if segment is null.
/// </summary>
public void Redraw(ISegment segment, DispatcherPriority redrawPriority = DispatcherPriority.Normal)
{
if (segment != null) {
Redraw(segment.Offset, segment.Length, redrawPriority);
}
}
/// <summary>
/// Invalidates all visual lines.
/// The caller of ClearVisualLines() must also call InvalidateMeasure() to ensure
/// that the visual lines will be recreated.
/// </summary>
void ClearVisualLines()
{
visibleVisualLines = null;
if (allVisualLines.Count != 0) {
foreach (VisualLine visualLine in allVisualLines) {
DisposeVisualLine(visualLine);
}
allVisualLines.Clear();
}
}
void DisposeVisualLine(VisualLine visualLine)
{
if (newVisualLines != null && newVisualLines.Contains(visualLine)) {
throw new ArgumentException("Cannot dispose visual line because it is in construction!");
}
visibleVisualLines = null;
visualLine.Dispose();
RemoveInlineObjects(visualLine);
}
#endregion
#region InvalidateMeasure(DispatcherPriority)
DispatcherOperation invalidateMeasureOperation;
void InvalidateMeasure(DispatcherPriority priority)
{
if (priority >= DispatcherPriority.Render) {
if (invalidateMeasureOperation != null) {
invalidateMeasureOperation.Abort();
invalidateMeasureOperation = null;
}
base.InvalidateMeasure();
} else {
if (invalidateMeasureOperation != null) {
invalidateMeasureOperation.Priority = priority;
} else {
invalidateMeasureOperation = Dispatcher.BeginInvoke(
priority,
new Action(
delegate {
invalidateMeasureOperation = null;
base.InvalidateMeasure();
}
)
);
}
}
}
#endregion
#region Get(OrConstruct)VisualLine
/// <summary>
/// Gets the visual line that contains the document line with the specified number.
/// Returns null if the document line is outside the visible range.
/// </summary>
public VisualLine GetVisualLine(int documentLineNumber)
{
// TODO: EnsureVisualLines() ?
foreach (VisualLine visualLine in allVisualLines) {
Debug.Assert(visualLine.IsDisposed == false);
int start = visualLine.FirstDocumentLine.LineNumber;
int end = visualLine.LastDocumentLine.LineNumber;
if (documentLineNumber >= start && documentLineNumber <= end)
return visualLine;
}
return null;
}
/// <summary>
/// Gets the visual line that contains the document line with the specified number.
/// If that line is outside the visible range, a new VisualLine for that document line is constructed.
/// </summary>
public VisualLine GetOrConstructVisualLine(DocumentLine documentLine)
{
if (documentLine == null)
throw new ArgumentNullException("documentLine");
if (!this.Document.Lines.Contains(documentLine))
throw new InvalidOperationException("Line belongs to wrong document");
VerifyAccess();
VisualLine l = GetVisualLine(documentLine.LineNumber);
if (l == null) {
TextRunProperties globalTextRunProperties = CreateGlobalTextRunProperties();
VisualLineTextParagraphProperties paragraphProperties = CreateParagraphProperties(globalTextRunProperties);
while (heightTree.GetIsCollapsed(documentLine.LineNumber)) {
documentLine = documentLine.PreviousLine;
}
l = BuildVisualLine(documentLine,
globalTextRunProperties, paragraphProperties,
elementGenerators.ToArray(), lineTransformers.ToArray(),
lastAvailableSize);
allVisualLines.Add(l);
// update all visual top values (building the line might have changed visual top of other lines due to word wrapping)
foreach (var line in allVisualLines) {
line.VisualTop = heightTree.GetVisualPosition(line.FirstDocumentLine);
}
}
return l;
}
#endregion
#region Visual Lines (fields and properties)
List<VisualLine> allVisualLines = new List<VisualLine>();
ReadOnlyCollection<VisualLine> visibleVisualLines;
double clippedPixelsOnTop;
List<VisualLine> newVisualLines;
/// <summary>
/// Gets the currently visible visual lines.
/// </summary>
/// <exception cref="VisualLinesInvalidException">
/// Gets thrown if there are invalid visual lines when this property is accessed.
/// You can use the <see cref="VisualLinesValid"/> property to check for this case,
/// or use the <see cref="EnsureVisualLines()"/> method to force creating the visual lines
/// when they are invalid.
/// </exception>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
public ReadOnlyCollection<VisualLine> VisualLines {
get {
if (visibleVisualLines == null)
{
return new ReadOnlyCollection<VisualLine>(new List<VisualLine>());
}
else
{
return visibleVisualLines;
}
}
}
/// <summary>
/// Gets whether the visual lines are valid.
/// Will return false after a call to Redraw().
/// Accessing the visual lines property will cause a <see cref="VisualLinesInvalidException"/>
/// if this property is <c>false</c>.
/// </summary>
public bool VisualLinesValid {
get { return visibleVisualLines != null; }
}
/// <summary>
/// Occurs when the TextView is about to be measured and will regenerate its visual lines.
/// This event may be used to mark visual lines as invalid that would otherwise be reused.
/// </summary>
public event EventHandler<VisualLineConstructionStartEventArgs> VisualLineConstructionStarting;
/// <summary>
/// Occurs when the TextView was measured and changed its visual lines.
/// </summary>
public event EventHandler VisualLinesChanged;
/// <summary>
/// If the visual lines are invalid, creates new visual lines for the visible part
/// of the document.
/// If all visual lines are valid, this method does nothing.
/// </summary>
/// <exception cref="InvalidOperationException">The visual line build process is already running.
/// It is not allowed to call this method during the construction of a visual line.</exception>
public void EnsureVisualLines()
{
Dispatcher.VerifyAccess();
if (inMeasure)
throw new InvalidOperationException("The visual line build process is already running! Cannot EnsureVisualLines() during Measure!");
if (!VisualLinesValid) {
// increase priority for re-measure
InvalidateMeasure(DispatcherPriority.Normal);
// force immediate re-measure
UpdateLayout();
}
// Sometimes we still have invalid lines after UpdateLayout - work around the problem
// by calling MeasureOverride directly.
if (!VisualLinesValid) {
//Debug.WriteLine("UpdateLayout() failed in EnsureVisualLines");
//MeasureOverride(lastAvailableSize);
// UpdateLayout();
}
//if (!VisualLinesValid)
//throw new VisualLinesInvalidException("Internal error: visual lines invalid after EnsureVisualLines call");
}
#endregion
#region Measure
/// <summary>
/// Additonal amount that allows horizontal scrolling past the end of the longest line.
/// This is necessary to ensure the caret always is visible, even when it is at the end of the longest line.
/// </summary>
const double AdditionalHorizontalScrollAmount = 3;
Size lastAvailableSize;
bool inMeasure;
/// <inheritdoc/>
protected override Size MeasureOverride(Size availableSize)
{
// We don't support infinite available width, so we'll limit it to 32000 pixels.
if (availableSize.Width > 32000)
availableSize.Width = 32000;
if (!canHorizontallyScroll && !availableSize.Width.IsClose(lastAvailableSize.Width))
ClearVisualLines();
lastAvailableSize = availableSize;
foreach (UIElement layer in layers) {
layer.Measure(availableSize);
}
MeasureInlineObjects();
InvalidateVisual(); // = InvalidateArrange+InvalidateRender
double maxWidth;
if (document == null) {
// no document -> create empty list of lines
allVisualLines = new List<VisualLine>();
visibleVisualLines = allVisualLines.AsReadOnly();
maxWidth = 0;
} else {
inMeasure = true;
try {
maxWidth = CreateAndMeasureVisualLines(availableSize);
} finally {
inMeasure = false;
}
}
// remove inline objects only at the end, so that inline objects that were re-used are not removed from the editor
RemoveInlineObjectsNow();
maxWidth += AdditionalHorizontalScrollAmount;
double heightTreeHeight = this.DocumentHeight;
TextEditorOptions options = this.Options;
if (options.AllowScrollBelowDocument) {
if (!double.IsInfinity(scrollViewport.Height)) {
heightTreeHeight = Math.Max(heightTreeHeight, Math.Min(heightTreeHeight - 50, scrollOffset.Y) + scrollViewport.Height);
}
}
textLayer.SetVisualLines(visibleVisualLines);
SetScrollData(availableSize,
new Size(maxWidth, heightTreeHeight),
scrollOffset);
if (VisualLinesChanged != null)
VisualLinesChanged(this, EventArgs.Empty);
return new Size(Math.Min(availableSize.Width, maxWidth), Math.Min(availableSize.Height, heightTreeHeight));
}
/// <summary>
/// Build all VisualLines in the visible range.
/// </summary>
/// <returns>Width the longest line</returns>
double CreateAndMeasureVisualLines(Size availableSize)
{
TextRunProperties globalTextRunProperties = CreateGlobalTextRunProperties();
VisualLineTextParagraphProperties paragraphProperties = CreateParagraphProperties(globalTextRunProperties);
//Debug.WriteLine("Measure availableSize=" + availableSize + ", scrollOffset=" + scrollOffset);
var firstLineInView = heightTree.GetLineByVisualPosition(scrollOffset.Y);
// number of pixels clipped from the first visual line(s)
clippedPixelsOnTop = scrollOffset.Y - heightTree.GetVisualPosition(firstLineInView);
// clippedPixelsOnTop should be >= 0, except for floating point inaccurracy.
Debug.Assert(clippedPixelsOnTop >= -ExtensionMethods.Epsilon);
newVisualLines = new List<VisualLine>();
if (VisualLineConstructionStarting != null)
VisualLineConstructionStarting(this, new VisualLineConstructionStartEventArgs(firstLineInView));
var elementGeneratorsArray = elementGenerators.ToArray();
var lineTransformersArray = lineTransformers.ToArray();
var nextLine = firstLineInView;
double maxWidth = 0;
double yPos = -clippedPixelsOnTop;
while (yPos < availableSize.Height && nextLine != null) {
VisualLine visualLine = GetVisualLine(nextLine.LineNumber);
if (visualLine == null) {
visualLine = BuildVisualLine(nextLine,
globalTextRunProperties, paragraphProperties,
elementGeneratorsArray, lineTransformersArray,
availableSize);
}
visualLine.VisualTop = scrollOffset.Y + yPos;
nextLine = visualLine.LastDocumentLine.NextLine;
yPos += visualLine.Height;
foreach (TextLine textLine in visualLine.TextLines) {
if (textLine.WidthIncludingTrailingWhitespace > maxWidth)
maxWidth = textLine.WidthIncludingTrailingWhitespace;
}
newVisualLines.Add(visualLine);
}
foreach (VisualLine line in allVisualLines) {
Debug.Assert(line.IsDisposed == false);
if (!newVisualLines.Contains(line))
DisposeVisualLine(line);
}
allVisualLines = newVisualLines;
// visibleVisualLines = readonly copy of visual lines
visibleVisualLines = new ReadOnlyCollection<VisualLine>(newVisualLines.ToArray());
newVisualLines = null;
if (allVisualLines.Any(line => line.IsDisposed)) {
throw new InvalidOperationException("A visual line was disposed even though it is still in use.\n" +
"This can happen when Redraw() is called during measure for lines " +
"that are already constructed.");
}
return maxWidth;
}
#endregion
#region BuildVisualLine
TextFormatter formatter;
internal TextViewCachedElements cachedElements;
TextRunProperties CreateGlobalTextRunProperties()
{
var p = new GlobalTextRunProperties();
p.typeface = this.CreateTypeface();
p.fontRenderingEmSize = FontSize;
p.foregroundBrush = (Brush)GetValue(Control.ForegroundProperty);
ExtensionMethods.CheckIsFrozen(p.foregroundBrush);
p.cultureInfo = CultureInfo.CurrentCulture;
return p;
}
VisualLineTextParagraphProperties CreateParagraphProperties(TextRunProperties defaultTextRunProperties)
{
return new VisualLineTextParagraphProperties {
defaultTextRunProperties = defaultTextRunProperties,
textWrapping = canHorizontallyScroll ? TextWrapping.NoWrap : TextWrapping.Wrap,
tabSize = Options.IndentationSize * WideSpaceWidth
};
}
VisualLine BuildVisualLine(DocumentLine documentLine,
TextRunProperties globalTextRunProperties,
VisualLineTextParagraphProperties paragraphProperties,
VisualLineElementGenerator[] elementGeneratorsArray,
IVisualLineTransformer[] lineTransformersArray,
Size availableSize)
{
if (heightTree.GetIsCollapsed(documentLine.LineNumber))
throw new InvalidOperationException("Trying to build visual line from collapsed line");
//Debug.WriteLine("Building line " + documentLine.LineNumber);
VisualLine visualLine = new VisualLine(this, documentLine);
VisualLineTextSource textSource = new VisualLineTextSource(visualLine) {
Document = document,
GlobalTextRunProperties = globalTextRunProperties,
TextView = this
};
visualLine.ConstructVisualElements(textSource, elementGeneratorsArray);
if (visualLine.FirstDocumentLine != visualLine.LastDocumentLine) {
// Check whether the lines are collapsed correctly:
double firstLinePos = heightTree.GetVisualPosition(visualLine.FirstDocumentLine.NextLine);
double lastLinePos = heightTree.GetVisualPosition(visualLine.LastDocumentLine.NextLine ?? visualLine.LastDocumentLine);
if (!firstLinePos.IsClose(lastLinePos)) {
for (int i = visualLine.FirstDocumentLine.LineNumber + 1; i <= visualLine.LastDocumentLine.LineNumber; i++) {
if (!heightTree.GetIsCollapsed(i))
throw new InvalidOperationException("Line " + i + " was skipped by a VisualLineElementGenerator, but it is not collapsed.");
}
throw new InvalidOperationException("All lines collapsed but visual pos different - height tree inconsistency?");
}
}
visualLine.RunTransformers(textSource, lineTransformersArray);
// now construct textLines:
int textOffset = 0;
TextLineBreak lastLineBreak = null;
var textLines = new List<TextLine>();
paragraphProperties.indent = 0;
paragraphProperties.firstLineInParagraph = true;
while (textOffset <= visualLine.VisualLengthWithEndOfLineMarker) {
TextLine textLine = formatter.FormatLine(
textSource,
textOffset,
availableSize.Width,
paragraphProperties,
lastLineBreak
);
textLines.Add(textLine);
textOffset += textLine.Length;
// exit loop so that we don't do the indentation calculation if there's only a single line
if (textOffset >= visualLine.VisualLengthWithEndOfLineMarker)
break;
if (paragraphProperties.firstLineInParagraph) {
paragraphProperties.firstLineInParagraph = false;
TextEditorOptions options = this.Options;
double indentation = 0;
if (options.InheritWordWrapIndentation) {
// determine indentation for next line:
int indentVisualColumn = GetIndentationVisualColumn(visualLine);
if (indentVisualColumn > 0 && indentVisualColumn < textOffset) {
indentation = textLine.GetDistanceFromCharacterHit(new CharacterHit(indentVisualColumn, 0));
}
}
indentation += options.WordWrapIndentation;
// apply the calculated indentation unless it's more than half of the text editor size:
if (indentation > 0 && indentation * 2 < availableSize.Width)
paragraphProperties.indent = indentation;
}
lastLineBreak = textLine.GetTextLineBreak();
}
visualLine.SetTextLines(textLines);
heightTree.SetHeight(visualLine.FirstDocumentLine, visualLine.Height);
return visualLine;
}
static int GetIndentationVisualColumn(VisualLine visualLine)
{
if (visualLine.Elements.Count == 0)
return 0;
int column = 0;
int elementIndex = 0;
VisualLineElement element = visualLine.Elements[elementIndex];
while (element.IsWhitespace(column)) {
column++;
if (column == element.VisualColumn + element.VisualLength) {
elementIndex++;
if (elementIndex == visualLine.Elements.Count)
break;
element = visualLine.Elements[elementIndex];
}
}
return column;
}
#endregion
#region Arrange
/// <summary>
/// Arrange implementation.
/// </summary>
protected override Size ArrangeOverride(Size finalSize)
{
EnsureVisualLines();
foreach (UIElement layer in layers) {
layer.Arrange(new Rect(new Point(0, 0), finalSize));
}
if (document == null || allVisualLines.Count == 0)
return finalSize;
// validate scroll position
Vector newScrollOffset = scrollOffset;
if (scrollOffset.X + finalSize.Width > scrollExtent.Width) {
newScrollOffset.X = Math.Max(0, scrollExtent.Width - finalSize.Width);
}
if (scrollOffset.Y + finalSize.Height > scrollExtent.Height) {
newScrollOffset.Y = Math.Max(0, scrollExtent.Height - finalSize.Height);
}
if (SetScrollData(scrollViewport, scrollExtent, newScrollOffset))
InvalidateMeasure(DispatcherPriority.Normal);
//Debug.WriteLine("Arrange finalSize=" + finalSize + ", scrollOffset=" + scrollOffset);
// double maxWidth = 0;
if (visibleVisualLines != null) {
Point pos = new Point(-scrollOffset.X, -clippedPixelsOnTop);
foreach (VisualLine visualLine in visibleVisualLines) {
int offset = 0;
foreach (TextLine textLine in visualLine.TextLines) {
foreach (var span in textLine.GetTextRunSpans()) {
InlineObjectRun inline = span.Value as InlineObjectRun;
if (inline != null && inline.VisualLine != null) {
Debug.Assert(inlineObjects.Contains(inline));
double distance = textLine.GetDistanceFromCharacterHit(new CharacterHit(offset, 0));
inline.Element.Arrange(new Rect(new Point(pos.X + distance, pos.Y), inline.Element.DesiredSize));
}
offset += span.Length;
}
pos.Y += textLine.Height;
}
}
}
InvalidateCursor();
return finalSize;
}
#endregion
#region Render
readonly ObserveAddRemoveCollection<IBackgroundRenderer> backgroundRenderers;
/// <summary>
/// Gets the list of background renderers.
/// </summary>
public IList<IBackgroundRenderer> BackgroundRenderers {
get { return backgroundRenderers; }
}
void BackgroundRenderer_Added(IBackgroundRenderer renderer)
{
ConnectToTextView(renderer);
InvalidateLayer(renderer.Layer);
}
void BackgroundRenderer_Removed(IBackgroundRenderer renderer)
{
DisconnectFromTextView(renderer);
InvalidateLayer(renderer.Layer);
}
/// <inheritdoc/>
protected override void OnRender(DrawingContext drawingContext)
{
RenderBackground(drawingContext, KnownLayer.Background);
foreach (var line in visibleVisualLines) {
Brush currentBrush = null;
int startVC = 0;
int length = 0;
foreach (var element in line.Elements) {
if (currentBrush == null || !currentBrush.Equals(element.BackgroundBrush)) {
if (currentBrush != null) {
BackgroundGeometryBuilder builder = new BackgroundGeometryBuilder();
builder.AlignToWholePixels = true;
builder.CornerRadius = 3;
foreach (var rect in BackgroundGeometryBuilder.GetRectsFromVisualSegment(this, line, startVC, startVC + length))
builder.AddRectangle(this, rect);
Geometry geometry = builder.CreateGeometry();
if (geometry != null) {
drawingContext.DrawGeometry(currentBrush, null, geometry);
}
}
startVC = element.VisualColumn;
length = element.DocumentLength;
currentBrush = element.BackgroundBrush;
} else {
length += element.VisualLength;
}
}
if (currentBrush != null) {
BackgroundGeometryBuilder builder = new BackgroundGeometryBuilder();
builder.AlignToWholePixels = true;
builder.CornerRadius = 3;
foreach (var rect in BackgroundGeometryBuilder.GetRectsFromVisualSegment(this, line, startVC, startVC + length))
builder.AddRectangle(this, rect);
Geometry geometry = builder.CreateGeometry();
if (geometry != null) {
drawingContext.DrawGeometry(currentBrush, null, geometry);
}
}
}
}
internal void RenderBackground(DrawingContext drawingContext, KnownLayer layer)
{
foreach (IBackgroundRenderer bg in backgroundRenderers) {
if (bg.Layer == layer) {
bg.Draw(this, drawingContext);
}
}
}
internal void ArrangeTextLayer(IList<VisualLineDrawingVisual> visuals)
{
Point pos = new Point(-scrollOffset.X, -clippedPixelsOnTop);
foreach (VisualLineDrawingVisual visual in visuals) {
TranslateTransform t = visual.Transform as TranslateTransform;
if (t == null || t.X != pos.X || t.Y != pos.Y) {
visual.Transform = new TranslateTransform(pos.X, pos.Y);
visual.Transform.Freeze();
}
pos.Y += visual.Height;
}
}
#endregion
#region IScrollInfo implementation
/// <summary>
/// Size of the document, in pixels.
/// </summary>
Size scrollExtent;
/// <summary>
/// Offset of the scroll position.
/// </summary>
Vector scrollOffset;
/// <summary>
/// Size of the viewport.
/// </summary>
Size scrollViewport;
void ClearScrollData()
{
SetScrollData(new Size(), new Size(), new Vector());
}
bool SetScrollData(Size viewport, Size extent, Vector offset)
{
if (!(viewport.IsClose(this.scrollViewport)
&& extent.IsClose(this.scrollExtent)
&& offset.IsClose(this.scrollOffset)))
{
this.scrollViewport = viewport;
this.scrollExtent = extent;
SetScrollOffset(offset);
this.OnScrollChange();
return true;
}
return false;
}
void OnScrollChange()
{
ScrollViewer scrollOwner = ((IScrollInfo)this).ScrollOwner;
if (scrollOwner != null) {
scrollOwner.InvalidateScrollInfo();
}
}
bool canVerticallyScroll;
bool IScrollInfo.CanVerticallyScroll {
get { return canVerticallyScroll; }
set {
if (canVerticallyScroll != value) {
canVerticallyScroll = value;
InvalidateMeasure(DispatcherPriority.Normal);
}
}
}
bool canHorizontallyScroll;
bool IScrollInfo.CanHorizontallyScroll {
get { return canHorizontallyScroll; }
set {
if (canHorizontallyScroll != value) {
canHorizontallyScroll = value;
ClearVisualLines();
InvalidateMeasure(DispatcherPriority.Normal);
}
}
}
double IScrollInfo.ExtentWidth {
get { return scrollExtent.Width; }
}
double IScrollInfo.ExtentHeight {
get { return scrollExtent.Height; }
}
double IScrollInfo.ViewportWidth {
get { return scrollViewport.Width; }
}
double IScrollInfo.ViewportHeight {
get { return scrollViewport.Height; }
}
/// <summary>
/// Gets the horizontal scroll offset.
/// </summary>
public double HorizontalOffset {
get { return scrollOffset.X; }
}
/// <summary>
/// Gets the vertical scroll offset.
/// </summary>
public double VerticalOffset {
get { return scrollOffset.Y; }
}
/// <summary>
/// Gets the scroll offset;
/// </summary>
public Vector ScrollOffset {
get { return scrollOffset; }
}
/// <summary>
/// Occurs when the scroll offset has changed.
/// </summary>
public event EventHandler ScrollOffsetChanged;
void SetScrollOffset(Vector vector)
{
if (!canHorizontallyScroll)
vector.X = 0;
if (!canVerticallyScroll)
vector.Y = 0;
if (!scrollOffset.IsClose(vector)) {
scrollOffset = vector;
if (ScrollOffsetChanged != null)
ScrollOffsetChanged(this, EventArgs.Empty);
}
}
ScrollViewer IScrollInfo.ScrollOwner { get; set; }
void IScrollInfo.LineUp()
{
((IScrollInfo)this).SetVerticalOffset(scrollOffset.Y - DefaultLineHeight);
}
void IScrollInfo.LineDown()
{
((IScrollInfo)this).SetVerticalOffset(scrollOffset.Y + DefaultLineHeight);
}
void IScrollInfo.LineLeft()
{
((IScrollInfo)this).SetHorizontalOffset(scrollOffset.X - WideSpaceWidth);
}
void IScrollInfo.LineRight()
{
((IScrollInfo)this).SetHorizontalOffset(scrollOffset.X + WideSpaceWidth);
}
void IScrollInfo.PageUp()
{
((IScrollInfo)this).SetVerticalOffset(scrollOffset.Y - scrollViewport.Height);
}
void IScrollInfo.PageDown()
{
((IScrollInfo)this).SetVerticalOffset(scrollOffset.Y + scrollViewport.Height);
}
void IScrollInfo.PageLeft()
{
((IScrollInfo)this).SetHorizontalOffset(scrollOffset.X - scrollViewport.Width);
}
void IScrollInfo.PageRight()
{
((IScrollInfo)this).SetHorizontalOffset(scrollOffset.X + scrollViewport.Width);
}
void IScrollInfo.MouseWheelUp()
{
((IScrollInfo)this).SetVerticalOffset(
scrollOffset.Y - (SystemParameters.WheelScrollLines * DefaultLineHeight));
OnScrollChange();
}
void IScrollInfo.MouseWheelDown()
{
((IScrollInfo)this).SetVerticalOffset(
scrollOffset.Y + (SystemParameters.WheelScrollLines * DefaultLineHeight));
OnScrollChange();
}
void IScrollInfo.MouseWheelLeft()
{
((IScrollInfo)this).SetHorizontalOffset(
scrollOffset.X - (SystemParameters.WheelScrollLines * WideSpaceWidth));
OnScrollChange();
}
void IScrollInfo.MouseWheelRight()
{
((IScrollInfo)this).SetHorizontalOffset(
scrollOffset.X + (SystemParameters.WheelScrollLines * WideSpaceWidth));
OnScrollChange();
}
bool defaultTextMetricsValid;
double wideSpaceWidth; // Width of an 'x'. Used as basis for the tab width, and for scrolling.
double defaultLineHeight; // Height of a line containing 'x'. Used for scrolling.
double defaultBaseline; // Baseline of a line containing 'x'. Used for TextTop/TextBottom calculation.
/// <summary>
/// Gets the width of a 'wide space' (the space width used for calculating the tab size).
/// </summary>
/// <remarks>
/// This is the width of an 'x' in the current font.
/// We do not measure the width of an actual space as that would lead to tiny tabs in
/// some proportional fonts.
/// For monospaced fonts, this property will return the expected value, as 'x' and ' ' have the same width.
/// </remarks>
public double WideSpaceWidth {
get {
CalculateDefaultTextMetrics();
return wideSpaceWidth;
}
}
/// <summary>
/// Gets the default line height. This is the height of an empty line or a line containing regular text.
/// Lines that include formatted text or custom UI elements may have a different line height.
/// </summary>
public double DefaultLineHeight {
get {
CalculateDefaultTextMetrics();
return defaultLineHeight;
}
}
/// <summary>
/// Gets the default baseline position. This is the difference between <see cref="VisualYPosition.TextTop"/>
/// and <see cref="VisualYPosition.Baseline"/> for a line containing regular text.
/// Lines that include formatted text or custom UI elements may have a different baseline.
/// </summary>
public double DefaultBaseline {
get {
CalculateDefaultTextMetrics();
return defaultBaseline;
}
}
void InvalidateDefaultTextMetrics()
{
defaultTextMetricsValid = false;
if (heightTree != null) {
// calculate immediately so that height tree gets updated
CalculateDefaultTextMetrics();
}
}
void CalculateDefaultTextMetrics()
{
if (defaultTextMetricsValid)
return;
defaultTextMetricsValid = true;
if (formatter != null) {
var textRunProperties = CreateGlobalTextRunProperties();
using (var line = formatter.FormatLine(
new SimpleTextSource("x", textRunProperties),
0, 32000,
new VisualLineTextParagraphProperties { defaultTextRunProperties = textRunProperties },
null))
{
wideSpaceWidth = Math.Max(1, line.WidthIncludingTrailingWhitespace);
defaultBaseline = Math.Max(1, line.Baseline);
defaultLineHeight = Math.Max(1, line.Height);
}
} else {
wideSpaceWidth = FontSize / 2;
defaultBaseline = FontSize;
defaultLineHeight = FontSize + 3;
}
// Update heightTree.DefaultLineHeight, if a document is loaded.
if (heightTree != null)
heightTree.DefaultLineHeight = defaultLineHeight;
}
static double ValidateVisualOffset(double offset)
{
if (double.IsNaN(offset))
throw new ArgumentException("offset must not be NaN");
if (offset < 0)
return 0;
else
return offset;
}
void IScrollInfo.SetHorizontalOffset(double offset)
{
offset = ValidateVisualOffset(offset);
if (!scrollOffset.X.IsClose(offset)) {
SetScrollOffset(new Vector(offset, scrollOffset.Y));
InvalidateVisual();
textLayer.InvalidateVisual();
}
}
void IScrollInfo.SetVerticalOffset(double offset)
{
offset = ValidateVisualOffset(offset);
if (!scrollOffset.Y.IsClose(offset)) {
SetScrollOffset(new Vector(scrollOffset.X, offset));
InvalidateMeasure(DispatcherPriority.Normal);
}
}
Rect IScrollInfo.MakeVisible(Visual visual, Rect rectangle)
{
if (rectangle.IsEmpty || visual == null || visual == this || !this.IsAncestorOf(visual)) {
return Rect.Empty;
}
// Convert rectangle into our coordinate space.
GeneralTransform childTransform = visual.TransformToAncestor(this);
rectangle = childTransform.TransformBounds(rectangle);
MakeVisible(Rect.Offset(rectangle, scrollOffset));
return rectangle;
}
/// <summary>
/// Scrolls the text view so that the specified rectangle gets visible.
/// </summary>
public void MakeVisible(Rect rectangle)
{
Rect visibleRectangle = new Rect(scrollOffset.X, scrollOffset.Y,
scrollViewport.Width, scrollViewport.Height);
Vector newScrollOffset = scrollOffset;
if (rectangle.Left < visibleRectangle.Left) {
if (rectangle.Right > visibleRectangle.Right) {
newScrollOffset.X = rectangle.Left + rectangle.Width / 2;
} else {
newScrollOffset.X = rectangle.Left;
}
} else if (rectangle.Right > visibleRectangle.Right) {
newScrollOffset.X = rectangle.Right - scrollViewport.Width;
}
if (rectangle.Top < visibleRectangle.Top) {
if (rectangle.Bottom > visibleRectangle.Bottom) {
newScrollOffset.Y = rectangle.Top + rectangle.Height / 2;
} else {
newScrollOffset.Y = rectangle.Top;
}
} else if (rectangle.Bottom > visibleRectangle.Bottom) {
newScrollOffset.Y = rectangle.Bottom - scrollViewport.Height;
}
newScrollOffset.X = ValidateVisualOffset(newScrollOffset.X);
newScrollOffset.Y = ValidateVisualOffset(newScrollOffset.Y);
if (!scrollOffset.IsClose(newScrollOffset)) {
SetScrollOffset(newScrollOffset);
this.OnScrollChange();
InvalidateMeasure(DispatcherPriority.Normal);
}
}
#endregion
#region Visual element mouse handling
/// <inheritdoc/>
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
// accept clicks even where the text area draws no background
return new PointHitTestResult(this, hitTestParameters.HitPoint);
}
[ThreadStatic] static bool invalidCursor;
/// <summary>
/// Updates the mouse cursor by calling <see cref="Mouse.UpdateCursor"/>, but with input priority.
/// </summary>
public static void InvalidateCursor()
{
if (!invalidCursor) {
invalidCursor = true;
Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Input,
new Action(
delegate {
invalidCursor = false;
Mouse.UpdateCursor();
}));
}
}
/// <inheritdoc/>
protected override void OnQueryCursor(QueryCursorEventArgs e)
{
VisualLineElement element = GetVisualLineElementFromPosition(e.GetPosition(this) + scrollOffset);
if (element != null) {
element.OnQueryCursor(e);
}
}
/// <inheritdoc/>
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
if (!e.Handled) {
EnsureVisualLines();
VisualLineElement element = GetVisualLineElementFromPosition(e.GetPosition(this) + scrollOffset);
if (element != null) {
element.OnMouseDown(e);
}
}
}
/// <inheritdoc/>
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
if (!e.Handled) {
EnsureVisualLines();
VisualLineElement element = GetVisualLineElementFromPosition(e.GetPosition(this) + scrollOffset);
if (element != null) {
element.OnMouseUp(e);
}
}
}
#endregion
#region Getting elements from Visual Position
/// <summary>
/// Gets the visual line at the specified document position (relative to start of document).
/// Returns null if there is no visual line for the position (e.g. the position is outside the visible
/// text area).
/// </summary>
public VisualLine GetVisualLineFromVisualTop(double visualTop)
{
// TODO: change this method to also work outside the visible range -
// required to make GetPosition work as expected!
EnsureVisualLines();
foreach (VisualLine vl in this.VisualLines) {
if (visualTop < vl.VisualTop)
continue;
if (visualTop < vl.VisualTop + vl.Height)
return vl;
}
return null;
}
/// <summary>
/// Gets the visual top position (relative to start of document) from a document line number.
/// </summary>
public double GetVisualTopByDocumentLine(int line)
{
VerifyAccess();
if (heightTree == null)
throw ThrowUtil.NoDocumentAssigned();
return heightTree.GetVisualPosition(heightTree.GetLineByNumber(line));
}
VisualLineElement GetVisualLineElementFromPosition(Point visualPosition)
{
VisualLine vl = GetVisualLineFromVisualTop(visualPosition.Y);
if (vl != null) {
int column = vl.GetVisualColumnFloor(visualPosition);
// Debug.WriteLine(vl.FirstDocumentLine.LineNumber + " vc " + column);
foreach (VisualLineElement element in vl.Elements) {
if (element.VisualColumn + element.VisualLength <= column)
continue;
return element;
}
}
return null;
}
#endregion
#region Visual Position <-> TextViewPosition
/// <summary>
/// Gets the visual position from a text view position.
/// </summary>
/// <param name="position">The text view position.</param>
/// <param name="yPositionMode">The mode how to retrieve the Y position.</param>
/// <returns>The position in WPF device-independent pixels relative
/// to the top left corner of the document.</returns>
public Point GetVisualPosition(TextViewPosition position, VisualYPosition yPositionMode)
{
VerifyAccess();
if (this.Document == null)
throw ThrowUtil.NoDocumentAssigned();
DocumentLine documentLine = this.Document.GetLineByNumber(position.Line);
VisualLine visualLine = GetOrConstructVisualLine(documentLine);
int visualColumn = position.VisualColumn;
if (visualColumn < 0) {
int offset = documentLine.Offset + position.Column - 1;
visualColumn = visualLine.GetVisualColumn(offset - visualLine.FirstDocumentLine.Offset);
}
return visualLine.GetVisualPosition(visualColumn, yPositionMode);
}
/// <summary>
/// Gets the text view position from the specified visual position.
/// If the position is within a character, it is rounded to the next character boundary.
/// </summary>
/// <param name="visualPosition">The position in WPF device-independent pixels relative
/// to the top left corner of the document.</param>
/// <returns>The logical position, or null if the position is outside the document.</returns>
public TextViewPosition? GetPosition(Point visualPosition)
{
VerifyAccess();
if (this.Document == null)
throw ThrowUtil.NoDocumentAssigned();
VisualLine line = GetVisualLineFromVisualTop(visualPosition.Y);
if (line == null)
return null;
int visualColumn = line.GetVisualColumn(visualPosition);
int documentOffset = line.GetRelativeOffset(visualColumn) + line.FirstDocumentLine.Offset;
return new TextViewPosition(document.GetLocation(documentOffset), visualColumn);
}
/// <summary>
/// Gets the text view position from the specified visual position.
/// If the position is inside a character, the position in front of the character is returned.
/// </summary>
/// <param name="visualPosition">The position in WPF device-independent pixels relative
/// to the top left corner of the document.</param>
/// <returns>The logical position, or null if the position is outside the document.</returns>
public TextViewPosition? GetPositionFloor(Point visualPosition)
{
VerifyAccess();
if (this.Document == null)
throw ThrowUtil.NoDocumentAssigned();
VisualLine line = GetVisualLineFromVisualTop(visualPosition.Y);
if (line == null)
return null;
int visualColumn = line.GetVisualColumnFloor(visualPosition);
int documentOffset = line.GetRelativeOffset(visualColumn) + line.FirstDocumentLine.Offset;
return new TextViewPosition(document.GetLocation(documentOffset), visualColumn);
}
#endregion
#region Service Provider
readonly ServiceContainer services = new ServiceContainer();
/// <summary>
/// Gets a service container used to associate services with the text view.
/// </summary>
public ServiceContainer Services {
get { return services; }
}
object IServiceProvider.GetService(Type serviceType)
{
return services.GetService(serviceType);
}
void ConnectToTextView(object obj)
{
ITextViewConnect c = obj as ITextViewConnect;
if (c != null)
c.AddToTextView(this);
}
void DisconnectFromTextView(object obj)
{
ITextViewConnect c = obj as ITextViewConnect;
if (c != null)
c.RemoveFromTextView(this);
}
#endregion
#region MouseHover
/// <summary>
/// The PreviewMouseHover event.
/// </summary>
public static readonly RoutedEvent PreviewMouseHoverEvent =
EventManager.RegisterRoutedEvent("PreviewMouseHover", RoutingStrategy.Tunnel,
typeof(MouseEventHandler), typeof(TextView));
/// <summary>
/// The MouseHover event.
/// </summary>
public static readonly RoutedEvent MouseHoverEvent =
EventManager.RegisterRoutedEvent("MouseHover", RoutingStrategy.Bubble,
typeof(MouseEventHandler), typeof(TextView));
/// <summary>
/// The PreviewMouseHoverStopped event.
/// </summary>
public static readonly RoutedEvent PreviewMouseHoverStoppedEvent =
EventManager.RegisterRoutedEvent("PreviewMouseHoverStopped", RoutingStrategy.Tunnel,
typeof(MouseEventHandler), typeof(TextView));
/// <summary>
/// The MouseHoverStopped event.
/// </summary>
public static readonly RoutedEvent MouseHoverStoppedEvent =
EventManager.RegisterRoutedEvent("MouseHoverStopped", RoutingStrategy.Bubble,
typeof(MouseEventHandler), typeof(TextView));
/// <summary>
/// Occurs when the mouse has hovered over a fixed location for some time.
/// </summary>
public event MouseEventHandler PreviewMouseHover {
add { AddHandler(PreviewMouseHoverEvent, value); }
remove { RemoveHandler(PreviewMouseHoverEvent, value); }
}
/// <summary>
/// Occurs when the mouse has hovered over a fixed location for some time.
/// </summary>
public event MouseEventHandler MouseHover {
add { AddHandler(MouseHoverEvent, value); }
remove { RemoveHandler(MouseHoverEvent, value); }
}
/// <summary>
/// Occurs when the mouse had previously hovered but now started moving again.
/// </summary>
public event MouseEventHandler PreviewMouseHoverStopped {
add { AddHandler(PreviewMouseHoverStoppedEvent, value); }
remove { RemoveHandler(PreviewMouseHoverStoppedEvent, value); }
}
/// <summary>
/// Occurs when the mouse had previously hovered but now started moving again.
/// </summary>
public event MouseEventHandler MouseHoverStopped {
add { AddHandler(MouseHoverStoppedEvent, value); }
remove { RemoveHandler(MouseHoverStoppedEvent, value); }
}
MouseHoverLogic hoverLogic;
void RaiseHoverEventPair(MouseEventArgs e, RoutedEvent tunnelingEvent, RoutedEvent bubblingEvent)
{
var mouseDevice = e.MouseDevice;
var stylusDevice = e.StylusDevice;
int inputTime = Environment.TickCount;
var args1 = new MouseEventArgs(mouseDevice, inputTime, stylusDevice) {
RoutedEvent = tunnelingEvent,
Source = this
};
RaiseEvent(args1);
var args2 = new MouseEventArgs(mouseDevice, inputTime, stylusDevice) {
RoutedEvent = bubblingEvent,
Source = this,
Handled = args1.Handled
};
RaiseEvent(args2);
}
#endregion
/// <summary>
/// Collapses lines for the purpose of scrolling. <see cref="DocumentLine"/>s marked as collapsed will be hidden
/// and not used to start the generation of a <see cref="VisualLine"/>.
/// </summary>
/// <remarks>
/// This method is meant for <see cref="VisualLineElementGenerator"/>s that cause <see cref="VisualLine"/>s to span
/// multiple <see cref="DocumentLine"/>s. Do not call it without providing a corresponding
/// <see cref="VisualLineElementGenerator"/>.
/// If you want to create collapsible text sections, see <see cref="Folding.FoldingManager"/>.
///
/// Note that if you want a VisualLineElement to span from line N to line M, then you need to collapse only the lines
/// N+1 to M. Do not collapse line N itself.
///
/// When you no longer need the section to be collapsed, call <see cref="CollapsedLineSection.Uncollapse()"/> on the
/// <see cref="CollapsedLineSection"/> returned from this method.
/// </remarks>
public CollapsedLineSection CollapseLines(DocumentLine start, DocumentLine end)
{
VerifyAccess();
if (heightTree == null)
throw ThrowUtil.NoDocumentAssigned();
return heightTree.CollapseText(start, end);
}
/// <summary>
/// Gets the height of the document.
/// </summary>
public double DocumentHeight {
get {
// return 0 if there is no document = no heightTree
return heightTree != null ? heightTree.TotalHeight : 0;
}
}
/// <summary>
/// Gets the document line at the specified visual position.
/// </summary>
public DocumentLine GetDocumentLineByVisualTop(double visualTop)
{
VerifyAccess();
if (heightTree == null)
throw ThrowUtil.NoDocumentAssigned();
return heightTree.GetLineByVisualPosition(visualTop);
}
/// <inheritdoc/>
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (TextFormatterFactory.PropertyChangeAffectsTextFormatter(e.Property)) {
// first, create the new text formatter:
RecreateTextFormatter();
// changing text formatter requires recreating the cached elements
RecreateCachedElements();
// and we need to re-measure the font metrics:
InvalidateDefaultTextMetrics();
} else if (e.Property == Control.ForegroundProperty
|| e.Property == TextView.NonPrintableCharacterBrushProperty
|| e.Property == TextView.LinkTextBackgroundBrushProperty
|| e.Property == TextView.LinkTextForegroundBrushProperty)
{
// changing brushes requires recreating the cached elements
RecreateCachedElements();
Redraw();
}
if (e.Property == Control.FontFamilyProperty
|| e.Property == Control.FontSizeProperty
|| e.Property == Control.FontStretchProperty
|| e.Property == Control.FontStyleProperty
|| e.Property == Control.FontWeightProperty)
{
// changing font properties requires recreating cached elements
RecreateCachedElements();
// and we need to re-measure the font metrics:
InvalidateDefaultTextMetrics();
Redraw();
}
if (e.Property == ColumnRulerPenProperty) {
columnRulerRenderer.SetRuler(this.Options.ColumnRulerPosition, this.ColumnRulerPen);
}
}
/// <summary>
/// The pen used to draw the column ruler.
/// <seealso cref="TextEditorOptions.ShowColumnRuler"/>
/// </summary>
public static readonly DependencyProperty ColumnRulerPenProperty =
DependencyProperty.Register("ColumnRulerBrush", typeof(Pen), typeof(TextView),
new FrameworkPropertyMetadata(CreateFrozenPen(Brushes.LightGray)));
static Pen CreateFrozenPen(SolidColorBrush brush)
{
Pen pen = new Pen(brush, 1);
pen.Freeze();
return pen;
}
/// <summary>
/// Gets/Sets the pen used to draw the column ruler.
/// <seealso cref="TextEditorOptions.ShowColumnRuler"/>
/// </summary>
public Pen ColumnRulerPen {
get { return (Pen)GetValue(ColumnRulerPenProperty); }
set { SetValue(ColumnRulerPenProperty, value); }
}
}
}
|