575
590
dp.ornaments.draw(path.circle_pt(x_pt, y_pt, r_pt), [filled])
576
591
x_pt, y_pt = normsubpathitem.atend_pt()
577
592
dp.ornaments.draw(path.circle_pt(x_pt, y_pt, r_pt), [filled])
595
class linehatched(deco, attr.exclusiveattr, attr.clearclass):
596
"""draws a pattern with explicit lines
598
This class acts as a drop-in replacement for postscript patterns
599
from the pattern module which are not understood by some printers"""
601
def __init__(self, dist, angle, strokestyles=[], cross=0):
602
attr.clearclass.__init__(self, _filled)
603
attr.exclusiveattr.__init__(self, linehatched)
606
self.strokestyles = attr.mergeattrs([style.linewidth.THIN] + strokestyles)
607
attr.checkattrs(self.strokestyles, [style.strokestyle])
610
def __call__(self, dist=None, angle=None, strokestyles=None, cross=None):
615
if strokestyles is None:
616
strokestyles = self.strokestyles
619
return linehatched(dist, angle, strokestyles, cross)
621
def _decocanvas(self, angle, dp, texrunner):
623
dist_pt = unit.topt(self.dist)
625
c = canvas.canvas([canvas.clip(dp.path)])
626
llx_pt, lly_pt, urx_pt, ury_pt = dp.path.bbox().highrestuple_pt()
627
center_pt = 0.5*(llx_pt+urx_pt), 0.5*(lly_pt+ury_pt)
628
radius_pt = 0.5*math.hypot(urx_pt-llx_pt, ury_pt-lly_pt) + dist_pt
629
n = int(2*radius_pt / dist_pt) + 1
631
x_pt = center_pt[0] - radius_pt + i*dist_pt
632
c.stroke(path.line_pt(x_pt, center_pt[1]-radius_pt, x_pt, center_pt[1]+radius_pt),
633
[trafo.rotate_pt(angle, center_pt[0], center_pt[1])] + self.strokestyles)
636
def decorate(self, dp, texrunner):
637
dp.ornaments.insert(self._decocanvas(self.angle, dp, texrunner))
639
dp.ornaments.insert(self._decocanvas(self.angle+90, dp, texrunner))
641
def merge(self, attrs):
642
# act as attr.clearclass and as attr.exclusiveattr at the same time
643
newattrs = attr.exclusiveattr.merge(self, attrs)
644
return attr.clearclass.merge(self, newattrs)
646
linehatched.clear = attr.clearclass(linehatched)
648
_hatch_base = 0.1 * unit.v_cm
650
linehatched0 = linehatched(_hatch_base, 0)
651
linehatched0.SMALL = linehatched0(_hatch_base/math.sqrt(64))
652
linehatched0.SMALL = linehatched0(_hatch_base/math.sqrt(64))
653
linehatched0.SMALl = linehatched0(_hatch_base/math.sqrt(32))
654
linehatched0.SMAll = linehatched0(_hatch_base/math.sqrt(16))
655
linehatched0.SMall = linehatched0(_hatch_base/math.sqrt(8))
656
linehatched0.Small = linehatched0(_hatch_base/math.sqrt(4))
657
linehatched0.small = linehatched0(_hatch_base/math.sqrt(2))
658
linehatched0.normal = linehatched0(_hatch_base)
659
linehatched0.large = linehatched0(_hatch_base*math.sqrt(2))
660
linehatched0.Large = linehatched0(_hatch_base*math.sqrt(4))
661
linehatched0.LArge = linehatched0(_hatch_base*math.sqrt(8))
662
linehatched0.LARge = linehatched0(_hatch_base*math.sqrt(16))
663
linehatched0.LARGe = linehatched0(_hatch_base*math.sqrt(32))
664
linehatched0.LARGE = linehatched0(_hatch_base*math.sqrt(64))
666
linehatched45 = linehatched(_hatch_base, 45)
667
linehatched45.SMALL = linehatched45(_hatch_base/math.sqrt(64))
668
linehatched45.SMALl = linehatched45(_hatch_base/math.sqrt(32))
669
linehatched45.SMAll = linehatched45(_hatch_base/math.sqrt(16))
670
linehatched45.SMall = linehatched45(_hatch_base/math.sqrt(8))
671
linehatched45.Small = linehatched45(_hatch_base/math.sqrt(4))
672
linehatched45.small = linehatched45(_hatch_base/math.sqrt(2))
673
linehatched45.normal = linehatched45(_hatch_base)
674
linehatched45.large = linehatched45(_hatch_base*math.sqrt(2))
675
linehatched45.Large = linehatched45(_hatch_base*math.sqrt(4))
676
linehatched45.LArge = linehatched45(_hatch_base*math.sqrt(8))
677
linehatched45.LARge = linehatched45(_hatch_base*math.sqrt(16))
678
linehatched45.LARGe = linehatched45(_hatch_base*math.sqrt(32))
679
linehatched45.LARGE = linehatched45(_hatch_base*math.sqrt(64))
681
linehatched90 = linehatched(_hatch_base, 90)
682
linehatched90.SMALL = linehatched90(_hatch_base/math.sqrt(64))
683
linehatched90.SMALl = linehatched90(_hatch_base/math.sqrt(32))
684
linehatched90.SMAll = linehatched90(_hatch_base/math.sqrt(16))
685
linehatched90.SMall = linehatched90(_hatch_base/math.sqrt(8))
686
linehatched90.Small = linehatched90(_hatch_base/math.sqrt(4))
687
linehatched90.small = linehatched90(_hatch_base/math.sqrt(2))
688
linehatched90.normal = linehatched90(_hatch_base)
689
linehatched90.large = linehatched90(_hatch_base*math.sqrt(2))
690
linehatched90.Large = linehatched90(_hatch_base*math.sqrt(4))
691
linehatched90.LArge = linehatched90(_hatch_base*math.sqrt(8))
692
linehatched90.LARge = linehatched90(_hatch_base*math.sqrt(16))
693
linehatched90.LARGe = linehatched90(_hatch_base*math.sqrt(32))
694
linehatched90.LARGE = linehatched90(_hatch_base*math.sqrt(64))
696
linehatched135 = linehatched(_hatch_base, 135)
697
linehatched135.SMALL = linehatched135(_hatch_base/math.sqrt(64))
698
linehatched135.SMALl = linehatched135(_hatch_base/math.sqrt(32))
699
linehatched135.SMAll = linehatched135(_hatch_base/math.sqrt(16))
700
linehatched135.SMall = linehatched135(_hatch_base/math.sqrt(8))
701
linehatched135.Small = linehatched135(_hatch_base/math.sqrt(4))
702
linehatched135.small = linehatched135(_hatch_base/math.sqrt(2))
703
linehatched135.normal = linehatched135(_hatch_base)
704
linehatched135.large = linehatched135(_hatch_base*math.sqrt(2))
705
linehatched135.Large = linehatched135(_hatch_base*math.sqrt(4))
706
linehatched135.LArge = linehatched135(_hatch_base*math.sqrt(8))
707
linehatched135.LARge = linehatched135(_hatch_base*math.sqrt(16))
708
linehatched135.LARGe = linehatched135(_hatch_base*math.sqrt(32))
709
linehatched135.LARGE = linehatched135(_hatch_base*math.sqrt(64))
711
crosslinehatched0 = linehatched(_hatch_base, 0, cross=1)
712
crosslinehatched0.SMALL = crosslinehatched0(_hatch_base/math.sqrt(64))
713
crosslinehatched0.SMALl = crosslinehatched0(_hatch_base/math.sqrt(32))
714
crosslinehatched0.SMAll = crosslinehatched0(_hatch_base/math.sqrt(16))
715
crosslinehatched0.SMall = crosslinehatched0(_hatch_base/math.sqrt(8))
716
crosslinehatched0.Small = crosslinehatched0(_hatch_base/math.sqrt(4))
717
crosslinehatched0.small = crosslinehatched0(_hatch_base/math.sqrt(2))
718
crosslinehatched0.normal = crosslinehatched0
719
crosslinehatched0.large = crosslinehatched0(_hatch_base*math.sqrt(2))
720
crosslinehatched0.Large = crosslinehatched0(_hatch_base*math.sqrt(4))
721
crosslinehatched0.LArge = crosslinehatched0(_hatch_base*math.sqrt(8))
722
crosslinehatched0.LARge = crosslinehatched0(_hatch_base*math.sqrt(16))
723
crosslinehatched0.LARGe = crosslinehatched0(_hatch_base*math.sqrt(32))
724
crosslinehatched0.LARGE = crosslinehatched0(_hatch_base*math.sqrt(64))
726
crosslinehatched45 = linehatched(_hatch_base, 45, cross=1)
727
crosslinehatched45.SMALL = crosslinehatched45(_hatch_base/math.sqrt(64))
728
crosslinehatched45.SMALl = crosslinehatched45(_hatch_base/math.sqrt(32))
729
crosslinehatched45.SMAll = crosslinehatched45(_hatch_base/math.sqrt(16))
730
crosslinehatched45.SMall = crosslinehatched45(_hatch_base/math.sqrt(8))
731
crosslinehatched45.Small = crosslinehatched45(_hatch_base/math.sqrt(4))
732
crosslinehatched45.small = crosslinehatched45(_hatch_base/math.sqrt(2))
733
crosslinehatched45.normal = crosslinehatched45
734
crosslinehatched45.large = crosslinehatched45(_hatch_base*math.sqrt(2))
735
crosslinehatched45.Large = crosslinehatched45(_hatch_base*math.sqrt(4))
736
crosslinehatched45.LArge = crosslinehatched45(_hatch_base*math.sqrt(8))
737
crosslinehatched45.LARge = crosslinehatched45(_hatch_base*math.sqrt(16))
738
crosslinehatched45.LARGe = crosslinehatched45(_hatch_base*math.sqrt(32))
739
crosslinehatched45.LARGE = crosslinehatched45(_hatch_base*math.sqrt(64))
742
class colorgradient(deco, attr.attr):
743
"""inserts pieces of the path in different colors"""
745
def __init__(self, grad, attrs=[], steps=20):
750
def decorate(self, dp, texrunner):
754
colors = [self.grad.select(n, self.steps) for n in range(self.steps)]
756
params = dp.path.arclentoparam([l*i/float(self.steps) for i in range(self.steps)])
760
# treat the end pieces separately
761
c.stroke(dp.path.split(params[1])[1], attr.mergeattrs([colors[0]] + self.attrs))
762
for n in range(1,self.steps-1):
763
c.stroke(dp.path.split([params[n-1],params[n+1]])[1], attr.mergeattrs([colors[n]] + self.attrs))
764
c.stroke(dp.path.split(params[-2])[0], attr.mergeattrs([colors[-1]] + self.attrs))
765
dp.ornaments.insert(c)
768
class brace(deco, attr.attr):
769
r"""draws a nicely curled brace
771
In most cases, the original line is not wanted use canvas.canvas.draw(..) for it
773
Geometrical parameters:
776
____________/ \__________
780
totalheight distance from the jaws to the middle cap
781
barthickness thickness of the main bars
782
innerstrokesthickness thickness of the two ending strokes
783
outerstrokesthickness thickness of the inner strokes at the middle cap
784
innerstrokesrelheight height of the inner/outer strokes, relative to the total height
785
outerstrokesrelheight this determines the angle of the main bars!
787
Note: if innerstrokesrelheight + outerstrokesrelheight == 1 then the main bars
788
will be aligned parallel to the connecting line between the endpoints
789
outerstrokesangle angle of the two ending strokes
790
innerstrokesangle angle between the inner strokes at the middle cap
791
slantstrokesangle extra slanting of the inner/outer strokes
792
innerstrokessmoothness smoothing parameter for the inner + outer strokes
793
outerstrokessmoothness should be around 1 (allowed: [0,infty))
794
middlerelpos position of the middle cap (0 == left, 1 == right)
796
# This code is experimental because it is unclear
797
# how the brace fits into the concepts of PyX
800
# - a brace needs to be decoratable with text
801
# it needs stroking and filling attributes
802
# - the brace is not really a box:
803
# it has two "anchor" points that are important for aligning it to other things
804
# and one "anchor" point (plus direction) for aligning other things
805
# - a brace is not a deformer:
806
# it does not look at anything else than begin/endpoint of a path
807
# - a brace might be a connector (which is to be dissolved into the box concept later?)
809
def __init__(self, reverse=1, stretch=None, dist=None, fillattrs=[],
810
totalheight=12*unit.x_pt,
811
barthickness=0.5*unit.x_pt, innerstrokesthickness=0.25*unit.x_pt, outerstrokesthickness=0.25*unit.x_pt,
812
innerstrokesrelheight=0.6, outerstrokesrelheight=0.7,
813
innerstrokesangle=30, outerstrokesangle=25, slantstrokesangle=5,
814
innerstrokessmoothness=2.0, outerstrokessmoothness=2.5,
816
self.fillattrs = fillattrs
817
self.reverse = reverse
818
self.stretch = stretch
820
self.totalheight = totalheight
821
self.barthickness = barthickness
822
self.innerstrokesthickness = innerstrokesthickness
823
self.outerstrokesthickness = outerstrokesthickness
824
self.innerstrokesrelheight = innerstrokesrelheight
825
self.outerstrokesrelheight = outerstrokesrelheight
826
self.innerstrokesangle = innerstrokesangle
827
self.outerstrokesangle = outerstrokesangle
828
self.slantstrokesangle = slantstrokesangle
829
self.innerstrokessmoothness = innerstrokessmoothness
830
self.outerstrokessmoothness = outerstrokessmoothness
831
self.middlerelpos = middlerelpos
833
def __call__(self, **kwargs):
834
for name in ["reverse", "stretch", "dist", "fillattrs",
835
"totalheight", "barthickness", "innerstrokesthickness", "outerstrokesthickness",
836
"innerstrokesrelheight", "outerstrokesrelheight", "innerstrokesangle", "outerstrokesangle", "slantstrokesangle",
837
"innerstrokessmoothness", "outerstrokessmoothness", "middlerelpos"]:
838
if not kwargs.has_key(name):
839
kwargs[name] = self.__dict__[name]
840
return brace(**kwargs)
842
def _halfbracepath_pt(self, length_pt, height_pt, ilength_pt, olength_pt, # <<<
843
ithick_pt, othick_pt, bthick_pt, cos_iangle, sin_iangle, cos_oangle,
844
sin_oangle, cos_slangle, sin_slangle):
846
ismooth = self.innerstrokessmoothness
847
osmooth = self.outerstrokessmoothness
849
# these two parameters are not important enough to be seen outside
850
inner_cap_param = 1.5
851
outer_cap_param = 2.5
852
outerextracurved = 0.6 # in (0, 1]
853
# 1.0 will lead to F=G, the outer strokes will not be curved at their ends.
854
# The smaller, the more curvature
856
# build an orientation path (three straight lines)
861
# _/ \______________________________________q5
867
# get the points for that:
868
q1 = (0, height_pt - inner_cap_param * ithick_pt + 0.5*ithick_pt/sin_iangle)
869
q2 = (q1[0] + ilength_pt * sin_iangle,
870
q1[1] - ilength_pt * cos_iangle)
872
q5 = (q6[0] - olength_pt * sin_oangle,
873
q6[1] + olength_pt * cos_oangle)
874
bardir = (q5[0] - q2[0], q5[1] - q2[1])
875
bardirnorm = math.hypot(*bardir)
876
bardir = (bardir[0]/bardirnorm, bardir[1]/bardirnorm)
877
ismoothlength_pt = ilength_pt * ismooth
878
osmoothlength_pt = olength_pt * osmooth
879
if bardirnorm < ismoothlength_pt + osmoothlength_pt:
880
ismoothlength_pt = bardirnorm * ismoothlength_pt / (ismoothlength_pt + osmoothlength_pt)
881
osmoothlength_pt = bardirnorm * osmoothlength_pt / (ismoothlength_pt + osmoothlength_pt)
882
q3 = (q2[0] + ismoothlength_pt * bardir[0],
883
q2[1] + ismoothlength_pt * bardir[1])
884
q4 = (q5[0] - osmoothlength_pt * bardir[0],
885
q5[1] - osmoothlength_pt * bardir[1])
891
# / \ B2C2________D2___________E2_______F2___G2
892
# \______________________________________ \
893
# B1,C1 D1 E1 F1 G1 \
899
# the halfbraces meet in P and A1:
901
A1 = (0, height_pt - inner_cap_param * ithick_pt)
902
# A2 is A1, shifted by the inner thickness
903
A2 = (A1[0] + ithick_pt * cos_iangle,
904
A1[1] + ithick_pt * sin_iangle)
905
s, t = deformer.intersection(P, A2, (cos_slangle, sin_slangle), (sin_iangle, -cos_iangle))
906
O = (P[0] + s * cos_slangle,
907
P[1] + s * sin_slangle)
909
# from D1 to E1 is the straight part of the brace
910
# also back from E2 to D1
911
D1 = (q3[0] + bthick_pt * bardir[1],
912
q3[1] - bthick_pt * bardir[0])
913
D2 = (q3[0] - bthick_pt * bardir[1],
914
q3[1] + bthick_pt * bardir[0])
915
E1 = (q4[0] + bthick_pt * bardir[1],
916
q4[1] - bthick_pt * bardir[0])
917
E2 = (q4[0] - bthick_pt * bardir[1],
918
q4[1] + bthick_pt * bardir[0])
919
# I1, I2 are the control points at the outer stroke
920
I1 = (q6[0] - 0.5 * othick_pt * cos_oangle,
921
q6[1] - 0.5 * othick_pt * sin_oangle)
922
I2 = (q6[0] + 0.5 * othick_pt * cos_oangle,
923
q6[1] + 0.5 * othick_pt * sin_oangle)
924
# get the control points for the curved parts of the brace
925
s, t = deformer.intersection(A1, D1, (sin_iangle, -cos_iangle), bardir)
926
B1 = (D1[0] + t * bardir[0],
927
D1[1] + t * bardir[1])
928
s, t = deformer.intersection(A2, D2, (sin_iangle, -cos_iangle), bardir)
929
B2 = (D2[0] + t * bardir[0],
930
D2[1] + t * bardir[1])
931
s, t = deformer.intersection(E1, I1, bardir, (-sin_oangle, cos_oangle))
932
G1 = (E1[0] + s * bardir[0],
933
E1[1] + s * bardir[1])
934
s, t = deformer.intersection(E2, I2, bardir, (-sin_oangle, cos_oangle))
935
G2 = (E2[0] + s * bardir[0],
936
E2[1] + s * bardir[1])
937
# at the inner strokes: use curvature zero at both ends
940
# at the outer strokes: use curvature zero only at the connection to
942
F1 = (outerextracurved * G1[0] + (1 - outerextracurved) * E1[0],
943
outerextracurved * G1[1] + (1 - outerextracurved) * E1[1])
944
F2 = (outerextracurved * G2[0] + (1 - outerextracurved) * E2[0],
945
outerextracurved * G2[1] + (1 - outerextracurved) * E2[1])
946
# the tip of the outer stroke, endpoints of the bezier curve
947
H1 = (I1[0] - outer_cap_param * othick_pt * sin_oangle,
948
I1[1] + outer_cap_param * othick_pt * cos_oangle)
949
H2 = (I2[0] - outer_cap_param * othick_pt * sin_oangle,
950
I2[1] + outer_cap_param * othick_pt * cos_oangle)
952
#for qq in [A1,B1,C1,D1,E1,F1,G1,H1,I1,
953
# A2,B2,C2,D2,E2,F2,G2,H2,I2,
956
# cc.fill(path.circle(qq[0], qq[1], 0.5), [color.rgb.green])
958
# now build the right halfbrace
959
bracepath = path.path(path.moveto_pt(*A1))
960
bracepath.append(path.curveto_pt(B1[0], B1[1], C1[0], C1[1], D1[0], D1[1]))
961
bracepath.append(path.lineto_pt(E1[0], E1[1]))
962
bracepath.append(path.curveto_pt(F1[0], F1[1], G1[0], G1[1], H1[0], H1[1]))
963
# the tip of the right halfbrace
964
bracepath.append(path.curveto_pt(I1[0], I1[1], I2[0], I2[1], H2[0], H2[1]))
965
# the rest of the right halfbrace
966
bracepath.append(path.curveto_pt(G2[0], G2[1], F2[0], F2[1], E2[0], E2[1]))
967
bracepath.append(path.lineto_pt(D2[0], D2[1]))
968
bracepath.append(path.curveto_pt(C2[0], C2[1], B2[0], B2[1], A2[0], A2[1]))
969
# the tip in the middle of the brace
970
bracepath.append(path.curveto_pt(O[0], O[1], O[0], O[1], P[0], P[1]))
975
def _bracepath(self, x0_pt, y0_pt, x1_pt, y1_pt): # <<<
976
height_pt = unit.topt(self.totalheight)
977
totallength_pt = math.hypot(x1_pt - x0_pt, y1_pt - y0_pt)
978
leftlength_pt = self.middlerelpos * totallength_pt
979
rightlength_pt = totallength_pt - leftlength_pt
980
ithick_pt = unit.topt(self.innerstrokesthickness)
981
othick_pt = unit.topt(self.outerstrokesthickness)
982
bthick_pt = unit.topt(self.barthickness)
984
# create the left halfbrace with positive slanting
985
# because we will mirror this part
986
cos_iangle = math.cos(math.radians(0.5*self.innerstrokesangle - self.slantstrokesangle))
987
sin_iangle = math.sin(math.radians(0.5*self.innerstrokesangle - self.slantstrokesangle))
988
cos_oangle = math.cos(math.radians(self.outerstrokesangle - self.slantstrokesangle))
989
sin_oangle = math.sin(math.radians(self.outerstrokesangle - self.slantstrokesangle))
990
cos_slangle = math.cos(math.radians(-self.slantstrokesangle))
991
sin_slangle = math.sin(math.radians(-self.slantstrokesangle))
992
ilength_pt = self.innerstrokesrelheight * height_pt / cos_iangle
993
olength_pt = self.outerstrokesrelheight * height_pt / cos_oangle
995
bracepath = self._halfbracepath_pt(leftlength_pt, height_pt,
996
ilength_pt, olength_pt, ithick_pt, othick_pt, bthick_pt, cos_iangle,
997
sin_iangle, cos_oangle, sin_oangle, cos_slangle,
998
sin_slangle).reversed().transformed(trafo.mirror(90))
1000
# create the right halfbrace with negative slanting
1001
cos_iangle = math.cos(math.radians(0.5*self.innerstrokesangle + self.slantstrokesangle))
1002
sin_iangle = math.sin(math.radians(0.5*self.innerstrokesangle + self.slantstrokesangle))
1003
cos_oangle = math.cos(math.radians(self.outerstrokesangle + self.slantstrokesangle))
1004
sin_oangle = math.sin(math.radians(self.outerstrokesangle + self.slantstrokesangle))
1005
cos_slangle = math.cos(math.radians(-self.slantstrokesangle))
1006
sin_slangle = math.sin(math.radians(-self.slantstrokesangle))
1007
ilength_pt = self.innerstrokesrelheight * height_pt / cos_iangle
1008
olength_pt = self.outerstrokesrelheight * height_pt / cos_oangle
1010
bracepath = bracepath << self._halfbracepath_pt(rightlength_pt, height_pt,
1011
ilength_pt, olength_pt, ithick_pt, othick_pt, bthick_pt, cos_iangle,
1012
sin_iangle, cos_oangle, sin_oangle, cos_slangle,
1015
return bracepath.transformed(
1016
# two trafos for matching the given endpoints
1017
trafo.translate_pt(x0_pt, y0_pt) *
1018
trafo.rotate_pt(math.degrees(math.atan2(y1_pt-y0_pt, x1_pt-x0_pt))) *
1019
# one trafo to move the brace's left outer stroke to zero
1020
trafo.translate_pt(leftlength_pt, 0))
1023
def decorate(self, dp, texrunner):
1025
x0_pt, y0_pt = dp.path.atbegin_pt()
1026
x1_pt, y1_pt = dp.path.atend_pt()
1028
x0_pt, y0_pt, x1_pt, y1_pt = x1_pt, y1_pt, x0_pt, y0_pt
1029
if self.stretch is not None:
1030
xm, ym = 0.5*(x0_pt+x1_pt), 0.5*(y0_pt+y1_pt)
1031
x0_pt, y0_pt = xm + self.stretch*(x0_pt-xm), ym + self.stretch*(y0_pt-ym)
1032
x1_pt, y1_pt = xm + self.stretch*(x1_pt-xm), ym + self.stretch*(y1_pt-ym)
1033
if self.dist is not None:
1034
d = unit.topt(self.dist)
1035
dx, dy = dp.path.rotation_pt(dp.path.begin()).apply_pt(0, 1)
1036
x0_pt += d*dx; y0_pt += d*dy
1037
dx, dy = dp.path.rotation_pt(dp.path.end()).apply_pt(0, 1)
1038
x1_pt += d*dx; y1_pt += d*dy
1039
dp.ornaments.fill(self._bracepath(x0_pt, y0_pt, x1_pt, y1_pt), self.fillattrs)
1041
brace.clear = attr.clearclass(brace)
1043
leftbrace = brace(reverse=0, middlerelpos=0.55, innerstrokesrelheight=0.6, outerstrokesrelheight=0.7, slantstrokesangle=-10)
1044
rightbrace = brace(reverse=1, middlerelpos=0.45, innerstrokesrelheight=0.6, outerstrokesrelheight=0.7, slantstrokesangle=10)
1045
belowbrace = brace(reverse=1, middlerelpos=0.55, innerstrokesrelheight=0.7, outerstrokesrelheight=0.9, slantstrokesangle=-10)
1046
abovebrace = brace(reverse=0, middlerelpos=0.45, innerstrokesrelheight=0.7, outerstrokesrelheight=0.9, slantstrokesangle=-10)
1047
straightbrace = brace(innerstrokesrelheight=0.5, outerstrokesrelheight=0.5,
1048
innerstrokesangle=30, outerstrokesangle=30, slantstrokesangle=0,
1049
innerstrokessmoothness=1.0, outerstrokessmoothness=1.0)