|
736 | 736 | ///
|
737 | 737 | /// ## Anchors
|
738 | 738 | /// Supports border anchors.
|
| 739 | +/// - **mid**: Content center, from baseline to top bounds |
| 740 | +/// - **mid-east**: Content center extended to the east |
| 741 | +/// - **mid-west**: Content center extended to the west |
| 742 | +/// - **base**: Horizontally centered baseline of the content |
| 743 | +/// - **base-east**: Baseline height extended to the east |
| 744 | +/// - **base-west**: Baseline height extended to the west |
739 | 745 | #let content(
|
740 | 746 | ..args-style,
|
741 | 747 | angle: 0deg,
|
|
788 | 794 | // Typst's `rotate` function is clockwise relative to x-axis, which is backwards from us
|
789 | 795 | angle = angle * -1
|
790 | 796 |
|
| 797 | + // Height from the baseline to content-north |
| 798 | + let (_, baseline-height) = util.measure(ctx, text(top-edge: "bounds", bottom-edge: "baseline", body)) |
| 799 | + |
| 800 | + // Size of the bounding box |
791 | 801 | let (width, height, ..) = if auto-size {
|
792 |
| - util.measure(ctx, body) |
| 802 | + util.measure(ctx, text(top-edge: "bounds", bottom-edge: "bounds", body)) |
793 | 803 | } else {
|
794 | 804 | vector.sub(b, a)
|
795 | 805 | }
|
796 | 806 |
|
797 |
| - width = (calc.abs(width) |
798 |
| - + padding.at("left", default: 0) |
799 |
| - + padding.at("right", default: 0)) |
800 |
| - height = (calc.abs(height) |
801 |
| - + padding.at("top", default: 0) |
802 |
| - + padding.at("bottom", default: 0)) |
| 807 | + let bounds-width = calc.abs(width) |
| 808 | + let bounds-height = calc.abs(height) |
| 809 | + baseline-height = bounds-height - baseline-height |
| 810 | + |
| 811 | + width = bounds-width + padding.left + padding.right |
| 812 | + height = bounds-height + padding.top + padding.bottom |
803 | 813 |
|
804 | 814 | let anchors = {
|
805 |
| - let w = width/2 |
806 |
| - let h = height/2 |
807 |
| - let center = if auto-size { |
| 815 | + let w = width / 2 |
| 816 | + let h = height / 2 |
| 817 | + let bh = (baseline-height - padding.top - padding.bottom) / 2 |
| 818 | + |
| 819 | + let bounds-center = if auto-size { |
808 | 820 | a
|
809 | 821 | } else {
|
810 | 822 | vector.lerp(a, b, .5)
|
811 | 823 | }
|
812 | 824 |
|
813 | 825 | // Only the center anchor gets transformed. All other anchors
|
814 | 826 | // must be calculated relative to the transformed center!
|
815 |
| - center = matrix.mul4x4-vec3(ctx.transform, |
816 |
| - vector.as-vec(center, init: (0,0,0))) |
| 827 | + bounds-center = matrix.mul4x4-vec3(ctx.transform, |
| 828 | + vector.as-vec(bounds-center, init: (0,0,0))) |
| 829 | + |
| 830 | + let east-dir = vector.rotate-z((1, 0, 0), angle) |
| 831 | + let north-dir = vector.rotate-z((-1, 0, 0), angle + 90deg) |
| 832 | + let east-scaled = vector.scale(east-dir, +w) |
| 833 | + let west-scaled = vector.scale(east-dir, -w) |
| 834 | + let north-scaled = vector.scale(north-dir, +h) |
| 835 | + let south-scaled = vector.scale(north-dir, -h) |
| 836 | + |
| 837 | + let north = vector.add(bounds-center, north-scaled) |
| 838 | + let south = vector.add(bounds-center, south-scaled) |
| 839 | + let east = vector.add(bounds-center, east-scaled) |
| 840 | + let west = vector.add(bounds-center, west-scaled) |
| 841 | + let north-east = vector.add(bounds-center, vector.add(north-scaled, east-scaled)) |
| 842 | + let north-west = vector.sub(bounds-center, vector.add(south-scaled, east-scaled)) |
| 843 | + let south-east = vector.add(bounds-center, vector.add(south-scaled, east-scaled)) |
| 844 | + let south-west = vector.sub(bounds-center, vector.add(north-scaled, east-scaled)) |
| 845 | + |
| 846 | + let base = vector.add(south, |
| 847 | + vector.scale(north-dir, padding.bottom + baseline-height)) |
| 848 | + let mid = vector.lerp( |
| 849 | + vector.sub(north, vector.scale(north-dir, padding.top)), |
| 850 | + base, |
| 851 | + 0.5) |
| 852 | + let base-east = vector.add(base, east-scaled) |
| 853 | + let base-west = vector.add(base, west-scaled) |
| 854 | + let mid-east = vector.add(mid, east-scaled) |
| 855 | + let mid-west = vector.add(mid, west-scaled) |
817 | 856 |
|
818 |
| - let north = (calc.sin(angle)*h, -calc.cos(angle)*h,0) |
819 |
| - let east = (calc.cos(-angle)*w, -calc.sin(-angle)*w,0) |
820 |
| - let south = vector.scale(north, -1) |
821 |
| - let west = vector.scale(east, -1) |
822 | 857 | (
|
823 |
| - center: center, |
824 |
| - north: vector.add(center, north), |
825 |
| - north-east: vector.add(center, vector.add(north, east)), |
826 |
| - east: vector.add(center, east), |
827 |
| - south-east: vector.add(center, vector.add(south, east)), |
828 |
| - south: vector.add(center, south), |
829 |
| - south-west: vector.add(center, vector.add(south, west)), |
830 |
| - west: vector.add(center, west), |
831 |
| - north-west: vector.add(center, vector.add(north, west)), |
| 858 | + center: bounds-center, |
| 859 | + mid: mid, |
| 860 | + mid-east: mid-east, |
| 861 | + mid-west: mid-west, |
| 862 | + base: base, |
| 863 | + base-east: base-east, |
| 864 | + base-west: base-west, |
| 865 | + north: north, |
| 866 | + north-east: north-east, |
| 867 | + north-west: north-west, |
| 868 | + south: south, |
| 869 | + south-east: south-east, |
| 870 | + south-west: south-west, |
| 871 | + east: east, |
| 872 | + west: west, |
832 | 873 | )
|
833 | 874 | }
|
834 | 875 |
|
|
858 | 899 | (anchors.north-west, anchors.north-east,
|
859 | 900 | anchors.south-west, anchors.south-east)))
|
860 | 901 |
|
861 |
| - let corners = (anchors.north-east, anchors.north-west, |
862 |
| - anchors.south-west, anchors.south-east) |
863 |
| - |
864 | 902 | let drawables = ()
|
865 | 903 | if style.frame != none {
|
866 | 904 | drawables.push(border)
|
|
0 commit comments