Ejemplo n.º 1
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        siblings, shouldMoveAnyway = _getOffCurveSiblingPoints(contour, point)
        # if an onCurve is selected, the offCurve will move along with it
        if not (siblings or shouldMoveAnyway):
            return
        point.move(delta)
        for onCurve, otherPoint in siblings:
            if not onCurve.smooth or otherPoint.selected:
                continue
            # if the onCurve is smooth, we need to either...
            if otherPoint.segmentType is None:
                # keep the other offCurve inline
                rotateUIPointAroundRefLine(
                    point.x, point.y, onCurve.x, onCurve.y, otherPoint
                )
            else:
                # keep point in tangency with onCurve -> otherPoint segment,
                # i.e. do an orthogonal projection
                point.x, point.y, _ = bezierMath.lineProjection(
                    onCurve.x,
                    onCurve.y,
                    otherPoint.x,
                    otherPoint.y,
                    point.x,
                    point.y,
                    False,
                )
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                # avoid double move for qCurve with single offCurve
                if d > 0:
                    otherPt = contour.getPoint(index + 2 * d)
                    if (
                        otherPt.segmentType is not None
                        and otherPt.segmentType != "move"
                        and otherPt.selected
                    ):
                        continue
                pt.move(delta)
                maybeProjectUISmoothPointOffcurve(contour, index, delta)
    contour.dirty = True
Ejemplo n.º 2
0
 def _moveOnCurveAlongHandles(self, contour, pt, x, y):
     ret = False
     if pt.segmentType is not None:
         if pt.smooth and len(contour) >= 3:
             index = contour.index(pt)
             prevCP = contour.getPoint(index - 1)
             nextCP = contour.getPoint(index + 1)
             # we need at least one offCurve so that it makes sense
             # slide the onCurve around
             if prevCP.segmentType is None or nextCP.segmentType is None:
                 projX, projY, _ = bezierMath.lineProjection(
                     prevCP.x, prevCP.y, nextCP.x, nextCP.y, x, y, False)
                 # short-circuit UIMove because we're only moving this point
                 pt.x = projX
                 pt.y = projY
                 ret = True
         else:
             # non-smooth onCurve we just move, not moving any other point
             pt.x = x
             pt.y = y
             ret = True
     else:
         index = contour.index(pt)
         onCurve = None
         for delta in (-1, 1):
             pt_ = contour.getPoint(index + delta)
             if pt_.segmentType is not None:
                 onCurve = pt_
         if onCurve is not None:
             # keep new pt tangent to onCurve -> pt segment,
             # i.e. do an orthogonal projection
             pt.x, pt.y, _ = bezierMath.lineProjection(
                 onCurve.x, onCurve.y, pt.x, pt.y, x, y, False)
             ret = True
     if ret:
         contour.dirty = True
     return ret
Ejemplo n.º 3
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        siblings = _getOffCurveSiblingPoints(contour, point)
        # if an onCurve is selected, the offCurve will move along with it
        if not siblings:
            return
        point.move(delta)
        for onCurve, otherPoint in siblings:
            if not onCurve.smooth:
                continue
            # if the onCurve is smooth, we need to either...
            if otherPoint.segmentType is None and not otherPoint.selected:
                # keep the other offCurve inline
                line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
                otherLine = QLineF(
                    onCurve.x, onCurve.y, otherPoint.x, otherPoint.y)
                line.setLength(line.length() + otherLine.length())
                otherPoint.x = line.x2()
                otherPoint.y = line.y2()
            else:
                # keep point in tangency with onCurve -> otherPoint segment,
                # i.e. do an orthogonal projection
                point.x, point.y, _ = bezierMath.lineProjection(
                    onCurve.x, onCurve.y, otherPoint.x, otherPoint.y,
                    point.x, point.y, False)
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                # avoid double move for qCurve with single offCurve
                if d > 0:
                    otherPt = contour.getPoint(index + 2 * d)
                    if otherPt.segmentType is not None and \
                            otherPt.segmentType != "move" and otherPt.selected:
                        continue
                pt.move(delta)
                maybeProjectUISmoothPointOffcurve(contour, point)
    contour.dirty = True
Ejemplo n.º 4
0
 def _moveOnCurveAlongHandles(self, contour, pt, x, y):
     # TODO: offCurves
     if pt.segmentType is not None and pt.smooth and len(contour) >= 3:
         index = contour.index(pt)
         prevCP = contour.getPoint(index - 1)
         nextCP = contour.getPoint(index + 1)
         # we need at least one offCurve so that it makes sense
         # slide the onCurve around
         if prevCP.segmentType is None or nextCP.segmentType is None:
             projX, projY, _ = bezierMath.lineProjection(
                 prevCP.x, prevCP.y, nextCP.x, nextCP.y, x, y, False)
             # short-circuit UIMove because we're only moving this point
             pt.x = projX
             pt.y = projY
             contour.dirty = True
             return True
     return False
Ejemplo n.º 5
0
def projectUIPointOnRefLine(x1, y1, x2, y2, pt):
    x, y, t = bezierMath.lineProjection(x1, y1, x2, y2, pt.x, pt.y, False)
    # TODO: use grid precision ROUND
    pt.x = x  # round(x)
    pt.y = y  # round(y)