3939from qwt .scale_map import QwtScaleMap
4040from qwt .text import QwtText
4141
42+ # Plain-int aliases for Qt alignment flags. Qt6 exposes alignment flags as
43+ # IntEnum members and bitwise operations on them go through Python's
44+ # enum machinery (`__and__`/`__call__`), which is one of the dominant costs
45+ # of label layout. Casting to int once and using these constants makes the
46+ # bitwise tests in `labelTransformation` ~10x cheaper without changing
47+ # semantics.
48+ _ALIGN_LEFT = int (Qt .AlignLeft )
49+ _ALIGN_RIGHT = int (Qt .AlignRight )
50+ _ALIGN_TOP = int (Qt .AlignTop )
51+ _ALIGN_BOTTOM = int (Qt .AlignBottom )
52+
4253
4354class QwtAbstractScaleDraw_PrivateData (QObject ):
4455 def __init__ (self ):
@@ -568,9 +579,12 @@ def orientation(self):
568579
569580 :py:meth:`alignment()`
570581 """
571- if self .__data .alignment in (self .TopScale , self .BottomScale ):
582+ # Direct comparisons (no tuple ``in`` membership check) — this is
583+ # called per-tick in label layout and shows up in profiles.
584+ align = self .__data .alignment
585+ if align == self .BottomScale or align == self .TopScale :
572586 return Qt .Horizontal
573- elif self . __data . alignment in ( self .LeftScale , self .RightScale ) :
587+ if align == self .LeftScale or align == self .RightScale :
574588 return Qt .Vertical
575589
576590 def getBorderDistHint (self , font ):
@@ -597,34 +611,36 @@ def getBorderDistHint(self, font):
597611 if len (ticks ) == 0 :
598612 return start , end
599613
614+ scale_map = self .scaleMap ()
615+ transform = scale_map .transform
600616 minTick = ticks [0 ]
601- minPos = self . scaleMap (). transform (minTick )
617+ minPos = transform (minTick )
602618 maxTick = minTick
603619 maxPos = minPos
604620
605621 for tick in ticks :
606- tickPos = self . scaleMap (). transform (tick )
622+ tickPos = transform (tick )
607623 if tickPos < minPos :
608624 minTick = tick
609625 minPos = tickPos
610- if tickPos > self . scaleMap (). transform ( maxTick ) :
626+ if tickPos > maxPos :
611627 maxTick = tick
612628 maxPos = tickPos
613629
614630 s = 0.0
615631 e = 0.0
616632 if self .orientation () == Qt .Vertical :
617633 s = - self .labelRect (font , minTick ).top ()
618- s -= abs (minPos - round (self . scaleMap () .p2 ()))
634+ s -= abs (minPos - round (scale_map .p2 ()))
619635
620636 e = self .labelRect (font , maxTick ).bottom ()
621- e -= abs (maxPos - self . scaleMap () .p1 ())
637+ e -= abs (maxPos - scale_map .p1 ())
622638 else :
623639 s = - self .labelRect (font , minTick ).left ()
624- s -= abs (minPos - self . scaleMap () .p1 ())
640+ s -= abs (minPos - scale_map .p1 ())
625641
626642 e = self .labelRect (font , maxTick ).right ()
627- e -= abs (maxPos - self . scaleMap () .p2 ())
643+ e -= abs (maxPos - scale_map .p2 ())
628644
629645 return max (math .ceil (s ), 0 ), max (math .ceil (e ), 0 )
630646
@@ -763,27 +779,22 @@ def labelPosition(self, value):
763779 """
764780 tval = self .scaleMap ().transform (value )
765781 dist = self .spacing ()
766- if self .hasComponent (QwtAbstractScaleDraw .Backbone ):
767- dist += max ([1 , self .penWidth ()])
768- if self .hasComponent (QwtAbstractScaleDraw .Ticks ):
782+ hasComponent = self .hasComponent
783+ if hasComponent (QwtAbstractScaleDraw .Backbone ):
784+ dist += max (1 , self .penWidth ())
785+ if hasComponent (QwtAbstractScaleDraw .Ticks ):
769786 dist += self .tickLength (QwtScaleDiv .MajorTick )
770787
771- px = 0
772- py = 0
773- if self .alignment () == self .RightScale :
774- px = self .__data .pos .x () + dist
775- py = tval
776- elif self .alignment () == self .LeftScale :
777- px = self .__data .pos .x () - dist
778- py = tval
779- elif self .alignment () == self .BottomScale :
780- px = tval
781- py = self .__data .pos .y () + dist
782- elif self .alignment () == self .TopScale :
783- px = tval
784- py = self .__data .pos .y () - dist
785-
786- return QPointF (px , py )
788+ alignment = self .alignment ()
789+ pos = self .__data .pos
790+ if alignment == self .RightScale :
791+ return QPointF (pos .x () + dist , tval )
792+ if alignment == self .LeftScale :
793+ return QPointF (pos .x () - dist , tval )
794+ if alignment == self .BottomScale :
795+ return QPointF (tval , pos .y () + dist )
796+ # TopScale
797+ return QPointF (tval , pos .y () - dist )
787798
788799 def drawTick (self , painter , value , len_ ):
789800 """
@@ -1007,17 +1018,19 @@ def labelTransformation(self, pos, size):
10071018 flags = self .labelAlignment ()
10081019 if flags == 0 :
10091020 flags = self .Flags [self .alignment ()]
1021+ # Cast to plain int once to avoid the per-bit Qt6 enum overhead.
1022+ flags = int (flags )
10101023
1011- if flags & Qt . AlignLeft :
1024+ if flags & _ALIGN_LEFT :
10121025 x = - size .width ()
1013- elif flags & Qt . AlignRight :
1026+ elif flags & _ALIGN_RIGHT :
10141027 x = 0.0
10151028 else :
10161029 x = - (0.5 * size .width ())
10171030
1018- if flags & Qt . AlignTop :
1031+ if flags & _ALIGN_TOP :
10191032 y = - size .height ()
1020- elif flags & Qt . AlignBottom :
1033+ elif flags & _ALIGN_BOTTOM :
10211034 y = 0
10221035 else :
10231036 y = - (0.5 * size .height ())
@@ -1039,6 +1052,31 @@ def labelRect(self, font, value):
10391052 lbl , labelSize = self .tickLabel (font , value )
10401053 if not lbl or lbl .isEmpty ():
10411054 return QRectF (0.0 , 0.0 , 0.0 , 0.0 )
1055+ # Fast path: when the label is not rotated, the contribution of
1056+ # ``pos`` cancels out (transform.translate(pos) followed by
1057+ # br.translate(-pos)). This avoids ``labelPosition``,
1058+ # ``labelTransformation`` and ``QTransform.mapRect`` entirely - all
1059+ # of which are dominant costs in tick-heavy layouts.
1060+ if self .labelRotation () == 0.0 :
1061+ flags = self .labelAlignment ()
1062+ if flags == 0 :
1063+ flags = self .Flags [self .alignment ()]
1064+ flags = int (flags )
1065+ w = labelSize .width ()
1066+ h = labelSize .height ()
1067+ if flags & _ALIGN_LEFT :
1068+ x = - w
1069+ elif flags & _ALIGN_RIGHT :
1070+ x = 0.0
1071+ else :
1072+ x = - 0.5 * w
1073+ if flags & _ALIGN_TOP :
1074+ y = - h
1075+ elif flags & _ALIGN_BOTTOM :
1076+ y = 0.0
1077+ else :
1078+ y = - 0.5 * h
1079+ return QRectF (x , y , w , h )
10421080 pos = self .labelPosition (value )
10431081 transform = self .labelTransformation (pos , labelSize )
10441082 br = transform .mapRect (QRectF (QPointF (0 , 0 ), labelSize ))
0 commit comments