📄 udiagram.pas
字号:
procedure TCanvasDiagramDrawer.DrawModule(Left, Top, Right, Bottom: Integer;
Rounding: Integer;
const ModuleName: String;
TextOffset: Integer;
Monochrome: Boolean);
begin
if not Monochrome then
FCanvas.Brush.Color := clSilver;
//draw the rectangle around the boxes of the module
FCanvas.RoundRect(Left, Top, Right, Bottom, Rounding, Rounding);
//and its name inside the rectangle
FCanvas.TextOut(Left + TextOffset, Top + TextOffset, ModuleName);
if not Monochrome then
FCanvas.Brush.Color := clWhite;
end;
{Draws a box of a file or class in the diagram.
~param Left, Top, Right, Bottom the sides of the rectangle of the box
~param Rounding by how much the rectangle should be rounded }
procedure TCanvasDiagramDrawer.DrawBox(Left, Top, Right, Bottom: Integer;
Rounding: Integer);
begin
//draw the rectangle around the box
FCanvas.RoundRect(Left, Top, Right, Bottom, Rounding, Rounding);
end;
{Draws selection markers at a box of a file or class in the diagram.
~param Left, Top, Right, Bottom the sides of the rectangle of the box
~param HalfSize the half size of the selection markers }
procedure TCanvasDiagramDrawer.DrawBoxSelection(Left, Top,
Right, Bottom: Integer;
HalfSize: Integer);
begin
//draw black small boxes at the four corners of the box
FCanvas.Brush.Color := clBlack;
FCanvas.FillRect(Rect(Left - HalfSize, Top - HalfSize,
Left + HalfSize, Top + HalfSize));
FCanvas.FillRect(Rect(Right - HalfSize, Top - HalfSize,
Right + HalfSize, Top + HalfSize));
FCanvas.FillRect(Rect(Left - HalfSize, Bottom - HalfSize,
Left + HalfSize, Bottom + HalfSize));
FCanvas.FillRect(Rect(Right - HalfSize, Bottom - HalfSize,
Right + HalfSize, Bottom + HalfSize));
FCanvas.Brush.Color := clWhite;
end;
{Draws some text.
~param Top the vertical position where the text should be drawn
~param Left the horizontal position where the text should be drawn, or if
Center is true the left position where to center it in
~param Right only relevant if Center is true, the right position to center the
text in
~param Text the text to be drawn
~param Center whether the text should be centered between the left and right
margin, of not it is drawn at the left position
~param Style the font style to use, one or more of fsBold, fsItalic and
fsUnderline is possible
~param Color the color to draw the text in, clBlack is the default }
procedure TCanvasDiagramDrawer.DrawText(Top, Left, Right: Integer;
const Text: String; Center: Boolean;
Style: TFontStyles; Color: TColor);
begin
//font and color has already been set for the canvas
if Center then //if the text should be drawn centered
//calculate its starting point
Left := (Left + Right - FCanvas.TextWidth(Text)) div 2;
FCanvas.TextOut(Left, Top, Text); //draw the text
end;
{Draws a line.
~param Xs, Ys the starting point of the line
~param Xe, Ye the end point of the line }
procedure TCanvasDiagramDrawer.DrawLine(Xs, Ys, Xe, Ye: Integer);
begin
FCanvas.MoveTo(Xs, Ys); //draw the line
FCanvas.LineTo(Xe, Ye);
end;
{Draws an icon representing a scope of a member of a record-like type.
~param X, Y the position where to draw the icon
~param Scope the scope, whose icon should be drawn }
procedure TCanvasDiagramDrawer.DrawScopeIcon(X, Y: Integer; Scope: TScope);
begin
FCanvas.Draw(X, Y, FDiagram.MemberScopeIcons[Scope]); //draw the scope icon
end;
{ * * * *** * * * *** TSVGDiagramDrawer *** * * * *** * * * }
{Draws an arrow.
~param Src the start point of the arrow
~param Dest the end point of the arrow
~param Arr1, Arr2 the end points of the arrow head
~param FilledArrowHead whether the arrow head should be filled
~param ThickLine whether the arrow should be painted thickly
~param LineStyle the style of the line, either psSolid, psDash or
psDashDot }
procedure TSVGDiagramDrawer.DrawArrow(Src, Dest, Arr1, Arr2: TPoint;
FilledArrowHead: Boolean;
ThickLine: Boolean;
LineStyle: TPenStyle);
begin
FSVGFile.WriteString(' <g>'); //group line and head of arrow together
FSVGFile.WriteString(XMLNewLine);
//draw arrow (main line)
FSVGFile.WriteFormatted(' <line x1="%d" y1="%d" x2="%d" y2="%d" stroke="black" stroke-width="%d" ',
[Src.x, Src.y, Dest.x, Dest.y,
2 * Succ(Ord(ThickLine))]);
if LineStyle <> psSolid then
if LineStyle = psDash then
FSVGFile.WriteString('stroke-dasharray="2,2" ')
else
FSVGFile.WriteString('stroke-dasharray="2,2,1,2" ');
FSVGFile.WriteString('/>');
FSVGFile.WriteString(XMLNewLine);
if FilledArrowHead then //if a arrow head should be filled
//fill arrowhead
SVGFile.WriteFormatted(' <polygon points="%d,%d %d,%d %d,%d" stroke="black" fill="black" />',
[Arr1.x, Arr1.y, Dest.x, Dest.y, Arr2.x, Arr2.y])
else
//just draw both sides of the arrow head
FSVGFile.WriteFormatted(' <polyline points="%d,%d %d,%d %d,%d" stroke="black" stroke-width="2" fill="none" />',
[Arr1.x, Arr1.y, Dest.x, Dest.y,
Arr2.x, Arr2.y]);
FSVGFile.WriteString(XMLNewLine);
FSVGFile.WriteString(' </g>'); //end the group
FSVGFile.WriteString(XMLNewLine);
FSVGFile.WriteString(XMLNewLine);
end;
{Draws the rectangle of a module and its name.
~param Left, Top, Right, Bottom the sides of the rectangle of the module
~param Rounding by how much the rectangle should be rounded
~param ModuleName the name of the module to be drawn
~param TextOffset the offset of the text from the upper left
corner
~param Monochrome whether the diagram is drawn monochrome }
procedure TSVGDiagramDrawer.DrawModule(Left, Top, Right, Bottom: Integer;
Rounding: Integer;
const ModuleName: String;
TextOffset: Integer;
Monochrome: Boolean);
begin
FSVGFile.WriteString(' <g>'); //group box and name together
FSVGFile.WriteString(XMLNewLine);
//draw box of the module
FSVGFile.WriteFormatted(' <rect x="%d" y="%d" width="%d" height="%d" rx="%d" fill="#C0C0C0" stroke="black" stroke-width="2" />',
[Left, Top, Right - Left, Bottom - Top, Rounding]);
FSVGFile.WriteString(XMLNewLine);
//draw the name
FSVGFile.WriteFormatted(' <text x="%d" y="%d">%s</text>',
[Left + TextOffset,
Top + TextOffset + FBaseLineOffset, ModuleName]);
FSVGFile.WriteString(XMLNewLine);
FSVGFile.WriteString(' </g>');
FSVGFile.WriteString(XMLNewLine);
FSVGFile.WriteString(XMLNewLine);
end;
{Draws a box of a file or class in the diagram.
~param Left, Top, Right, Bottom the sides of the rectangle of the box
~param Rounding by how much the rectangle should be rounded }
procedure TSVGDiagramDrawer.DrawBox(Left, Top, Right, Bottom: Integer;
Rounding: Integer);
begin
//draw the rectangle around the box
FSVGFile.WriteFormatted(' <rect x="%d" y="%d" width="%d" height="%d" rx="%d" fill="white" stroke="black" stroke-width="2" />',
[Left, Top, Right - Left, Bottom - Top, Rounding]);
end;
{Draws selection markers at a box of a file or class in the diagram.
~param Left, Top, Right, Bottom the sides of the rectangle of the box
~param HalfSize the half size of the selection markers }
procedure TSVGDiagramDrawer.DrawBoxSelection(Left, Top, Right, Bottom: Integer;
HalfSize: Integer);
begin
Assert(False); //should never be drawn while exporting
end;
{Draws some text.
~param Top the vertical position where the text should be drawn
~param Left the horizontal position where the text should be drawn, or if
Center is true the left position where to center it in
~param Right only relevant if Center is true, the right position to center the
text in
~param Text the text to be drawn
~param Center whether the text should be centered between the left and right
margin, of not it is drawn at the left position
~param Style the font style to use, one or more of fsBold, fsItalic and
fsUnderline is possible
~param Color the color to draw the text in, clBlack is the default }
procedure TSVGDiagramDrawer.DrawText(Top, Left, Right: Integer;
const Text: String; Center: Boolean;
Style: TFontStyles; Color: TColor);
{Writes the text into the XML file while encoding special characters. This is
neede because the values of default-parameters may contain the special
characters.
~param SVGFile the stream to write the text into
~param Text the text to be written }
procedure WriteEncodedString(SVGFile: TBufferStream; const Text: String);
var p :PChar; //runner through the text
StartP :PChar; //start of normal text (no need to quote)
begin
p := Pointer(Text);
while p^ <> #0 do //for each character in the text
begin
case p^ of //needs to be quoted?
'<': SVGFile.WriteString('<');
'>': SVGFile.WriteString('>');
'&': SVGFile.WriteString('&');
// '"': FHTMLFile.WriteString('"');
else
StartP := p; //get start position of normal text
repeat
Inc(p); //skip all characters that don't need
until p^ in [#0, '<', '>', '&'{, '"'}]; //to be quoted
//decrement now, will be incremented again after the case-statement
Dec(p);
if StartP = p then //was only one character?
SVGFile.WriteCharacter(p^) //write the character
else //or write all characters
SVGFile.WriteBuffer(StartP^, p - StartP + 1);
end;
Inc(p); //next character
end;
end;
begin
//font and color has already been set for the SVG
if Center then //if the text should be drawn centered
Left := (Right + Left) div 2; //calculate middle of region
FSVGFile.WriteFormatted(' <text x="%d" y="%d"',
[Left, Top + FBaseLineOffset]);
if Center then //if the text should be drawn centered
FSVGFile.WriteString(' text-anchor="middle"'); //center it
if Color <> clBlack then //if color is not black, set it
FSVGFile.WriteFormatted(' color="#%.2X%.2X%.2X"',
[Color and $FF, Color shr 8 and $FF,
Color shr 16 and $FF]);
if fsItalic in Style then //if not normal font style set style
FSVGFile.WriteString(' font-style="italic"');
if fsBold in Style then
FSVGFile.WriteString(' font-weight="bold"');
if fsUnderline in Style then
FSVGFile.WriteString(' text-decoration="underline"');
FSVGFile.WriteCharacter('>');
if Text <> '' then
WriteEncodedString(FSVGFile, Text); //write the text
FSVGFile.WriteString('</text>');
FSVGFile.WriteString(XMLNewLine);
end;
{Draws a line.
~param Xs, Ys the starting point of the line
~param Xe, Ye the end point of the line }
procedure TSVGDiagramDrawer.DrawLine(Xs, Ys, Xe, Ye: Integer);
begin
SVGFile.WriteFormatted(' <line x1="%d" y1="%d" x2="%d" y2="%d" stroke="black" stroke-width="2" />',
[Xs, Ys, Xe, Ye]);
SVGFile.WriteString(XMLNewLine);
SVGFile.WriteString(XMLNewLine);
end;
{Draws an icon representing a scope of a member of a record-like type.
~param X, Y the position where to draw the icon
~param Scope the scope, whose icon should be drawn }
procedure TSVGDiagramDrawer.DrawScopeIcon(X, Y: Integer; Scope: TScope);
begin
//draw the rectangle around the character and the character inside
FSVGFile.WriteFormatted(' <rect x="%f" y="%f" width="%f" height="%f" rx="%f" fill="#C0C0C0" />',
[X - 0.15 * FBaseLineOffset, Y - 0.1 * FBaseLineOffset,
1.4 * FBaseLineOffset, 1.4 * FBaseLineOffset,
0.3 * FBaseLineOffset]);
FSVGFile.WriteFormatted(' <text x="%f" y="%d">%s</text>',
[X + 0.2 * FBaseLineOffset, Y + FBaseLineOffset,
MemberScopeCharacters[Scope]]);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -