def _drawAssociation(self, linePositions: LinePositions): verticalGap: int = self._diagramPadding.verticalGap horizontalGap: int = self._diagramPadding.horizontalGap dpi: int = self._dpi docMaker: FPDF = self._docMaker numPositions: int = len(linePositions) for idx in range(numPositions): nextIdx: int = idx + 1 currentPos: Position = linePositions[idx] if nextIdx == numPositions: break nextPos: Position = linePositions[nextIdx] currentCoordinates: Coordinates = PdfCommon.convertPosition( pos=currentPos, dpi=dpi, verticalGap=verticalGap, horizontalGap=horizontalGap) nextCoordinates: Coordinates = PdfCommon.convertPosition( pos=nextPos, dpi=dpi, verticalGap=verticalGap, horizontalGap=horizontalGap) docMaker.line(x1=currentCoordinates.x, y1=currentCoordinates.y, x2=nextCoordinates.x, y2=nextCoordinates.y)
def __drawVerticalBoundaries(self, diagram: PdfDiagram): x1: int = PdfCommon.toPdfPoints( TestPdfLine.H_LEFT_X, diagram._dpi) + LEFT_MARGIN + diagram.verticalGap x2: int = x1 y1: int = PdfCommon.toPdfPoints( TestPdfLine.H_LEFT_TOP_Y, diagram._dpi) + TOP_MARGIN + diagram.horizontalGap y2: int = PdfCommon.toPdfPoints( TestPdfLine.H_LEFT_BOTTOM_Y, diagram._dpi) + TOP_MARGIN + diagram.horizontalGap diagram._pdf.dashed_line( x1=x1, y1=y1, x2=x2, y2=y2, space_length=TestPdfLine.DASH_LINE_SPACE_LENGTH) x1 = PdfCommon.toPdfPoints( TestPdfLine.H_RIGHT_X, diagram._dpi) + LEFT_MARGIN + diagram.verticalGap x2 = x1 diagram._pdf.dashed_line( x1=x1, y1=y1, x2=x2, y2=y2, space_length=TestPdfLine.DASH_LINE_SPACE_LENGTH)
def __finishDrawingLine(self, linePositions: LinePositions, newEndPoint: InternalPosition): linePositionsCopy: LinePositions = linePositions[: -1] # Makes a copy; remove last one verticalGap: int = self._diagramPadding.verticalGap horizontalGap: int = self._diagramPadding.horizontalGap dpi: int = self._dpi docMaker: FPDF = self._docMaker # # Ok, ok, I get it. This is not a Pythonic 'for' loop. But, I am not a purist # numPositions: int = len(linePositionsCopy) currentPos: Position = linePositionsCopy[0] for idx in range(numPositions): nextIdx: int = idx + 1 currentPos = linePositionsCopy[idx] if nextIdx == numPositions: break nextPos: Position = linePositionsCopy[nextIdx] currentCoordinates: Coordinates = PdfCommon.convertPosition( pos=currentPos, dpi=dpi, verticalGap=verticalGap, horizontalGap=horizontalGap) nextCoordinates: Coordinates = PdfCommon.convertPosition( pos=nextPos, dpi=dpi, verticalGap=verticalGap, horizontalGap=horizontalGap) docMaker.line(x1=currentCoordinates.x, y1=currentCoordinates.y, x2=nextCoordinates.x, y2=nextCoordinates.y) currentCoordinates = PdfCommon.convertPosition( pos=currentPos, dpi=dpi, verticalGap=verticalGap, horizontalGap=horizontalGap) docMaker.line(x1=currentCoordinates.x, y1=currentCoordinates.y, x2=newEndPoint.x, y2=newEndPoint.y)
def testPointLeftOfArrow(self): notInPolygon: InternalPosition = InternalPosition(0.0, 0.0) actualAns: bool = PdfCommon.pointInsidePolygon(pos=notInPolygon, polygon=self.arrow) self.assertFalse(actualAns, 'Arrow check is bad')
def testPointRightOfDiamond(self): notInPolygon: InternalPosition = InternalPosition(1122.0, 490.0) actualAns: bool = PdfCommon.pointInsidePolygon(pos=notInPolygon, polygon=self.diamond) self.assertFalse(actualAns, 'Diamond check is bad')
def testInCenterOfDiamond(self): inPolygon: InternalPosition = InternalPosition(1118.0, 470.0) actualAns: bool = PdfCommon.pointInsidePolygon(pos=inPolygon, polygon=self.diamond) self.assertTrue(actualAns, 'Diamond check in center of diamond is bad')
def testInCenterOfArrow(self): inPolygon: InternalPosition = InternalPosition(1118.0, 472.0) actualAns: bool = PdfCommon.pointInsidePolygon(pos=inPolygon, polygon=self.arrow) self.assertTrue(actualAns, 'Diamond check is bad')
def testBuildScanPointsForDiamond(self): scanPoints: ScanPoints = PdfCommon.buildScanPoints(points=self.diamond) self.assertEqual(1114.0, scanPoints.startScan.x, 'Minimum X not correct for diamond') self.assertEqual(460.0, scanPoints.startScan.y, 'Minimum Y not correct for diamond') self.assertEqual(1122.0, scanPoints.endScan.x, 'Max x is not correct for diamond') self.assertEqual(476.0, scanPoints.endScan.y, 'Max y is not correct for diamond')
def testBuildScanPointsForArrow(self): scanPoints: ScanPoints = PdfCommon.buildScanPoints(points=self.arrow) self.assertEqual(1114.0, scanPoints.startScan.x, 'Minimum X not correct for arrow') self.assertEqual(469.0717, scanPoints.startScan.y, 'Minimum Y not correct for arrow') self.assertEqual(1122.0, scanPoints.endScan.x, 'Max x is not correct for arrow') self.assertEqual(476.0, scanPoints.endScan.y, 'Max y is not correct for arrow')
def __fillInDiamond(self, points: DiamondPoints): """ Args: points: The polygon that defines the composition diamond """ scanPoints: ScanPoints = PdfCommon.buildScanPoints(points) startX: int = scanPoints.startScan.x startY: int = scanPoints.startScan.y endX: int = scanPoints.endScan.x endY: int = scanPoints.endScan.y x = startX while x <= endX: y = startY while y <= endY: if PdfCommon.pointInsidePolygon(pos=InternalPosition(x, y), polygon=points): self._docMaker.line(x1=x, y1=y, x2=x, y2=y) y += 1 x += 1
def __convertEndPoints( self, src: Position, dst: Position) -> Tuple[InternalPosition, InternalPosition]: verticalGap: int = self._diagramPadding.verticalGap horizontalGap: int = self._diagramPadding.horizontalGap sourceCoordinates: Coordinates = PdfCommon.convertPosition( pos=src, dpi=self._dpi, verticalGap=verticalGap, horizontalGap=horizontalGap) destinationCoordinates: Coordinates = PdfCommon.convertPosition( pos=dst, dpi=self._dpi, verticalGap=verticalGap, horizontalGap=horizontalGap) convertedSrc: InternalPosition = InternalPosition( sourceCoordinates.x, sourceCoordinates.y) convertedDst: InternalPosition = InternalPosition( destinationCoordinates.x, destinationCoordinates.y) return convertedSrc, convertedDst
def drawText(self, position: Position, text: str): """ Draw text at the input position. The method will appropriately convert the position to PDF points Args: position: The display's x, y position text: The text to display """ coordinates: Coordinates = PdfCommon.convertPosition( position, dpi=self._dpi, verticalGap=self.verticalGap, horizontalGap=self.horizontalGap) self._pdf.text(x=coordinates.x, y=coordinates.y, txt=text)
def __convertDefinition( self, definition: RectangleDefinition) -> PdfShapeDefinition: """ Args: definition: Returns: A description of the shape """ coordinates: Coordinates = PdfCommon.convertPosition( definition.position, dpi=self._dpi, verticalGap=self.verticalGap, horizontalGap=self.horizontalGap) dimensions: Dimensions = self.__convertSize(definition.size) return PdfShapeDefinition(coordinates=coordinates, dimensions=dimensions)
def drawClass(self, classDefinition: ClassDefinition): """ Draw the class diagram defined by the input Args: classDefinition: The class definition """ position: Position = classDefinition.position verticalGap: int = self._diagramPadding.verticalGap horizontalGap: int = self._diagramPadding.horizontalGap coordinates: Coordinates = PdfCommon.convertPosition( pos=position, dpi=self._dpi, verticalGap=verticalGap, horizontalGap=horizontalGap) x: int = coordinates.x y: int = coordinates.y self.logger.debug(f'x,y: ({x},{y})') methodReprs: BaseDiagram.MethodsRepr = self._buildMethods( classDefinition.methods, classDefinition.displayMethodParameters) fieldReprs: BaseDiagram.FieldsRepr = self._buildFields( classDefinition.fields) symbolWidth: int = self._drawClassSymbol(classDefinition, rectX=x, rectY=y) separatorPosition: SeparatorPosition = self._drawSeparator( rectX=x, rectY=y, shapeWidth=symbolWidth) fieldSeparatorPosition: SeparatorPosition = self._drawFields( fieldReprs=fieldReprs, separatorPosition=separatorPosition) methodSeparatorPosition: SeparatorPosition = self._drawSeparator( rectX=x, rectY=fieldSeparatorPosition.y, shapeWidth=symbolWidth) if classDefinition.displayMethods is True: self._drawMethods(methodReprs=methodReprs, separatorPosition=methodSeparatorPosition)
def __convertSize(self, size: Size) -> Dimensions: width: int = PdfCommon.toPdfPoints(size.width, self._dpi) height: int = PdfCommon.toPdfPoints(size.height, self._dpi) return Dimensions(width=width, height=height)