SvgGraphicsArch.cs
//
// このコードは、DioDocs for Imaging のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;
using GrapeCity.Documents.Svg;
using DsImagingWeb.Demos.Common;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
namespace DsImagingWeb.Demos
{
// このサンプルでは、グラフィックスパスを使用して
// GcSvgGraphics 上にアーチを描画する方法を示します。
// アーチは、グラフィックス変換行列を使用して
// 生成される画像の中央に配置されます。
public class SvgGraphicsArch
{
public string DefaultMime { get => Common.Util.MimeTypes.SVG; }
public Stream GenerateImageStream(string targetMime, Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
{
if (targetMime != Common.Util.MimeTypes.SVG)
throw new Exception("This sample only supports SVG output format.");
Color background = Color.PaleGoldenrod,
line = Color.FromArgb(11, 83, 69),
arc = Color.FromArgb(22, 160, 133),
fill = Color.FromArgb(255, 171, 145),
marks = Color.DarkGray,
text = Color.Black,
textBack = Color.Cornsilk;
var Inch = dpi;
var ms = new MemoryStream();
using var g = new GcSvgGraphics(pixelSize.Width, pixelSize.Height);
if (opaque)
g.FillRectangle(new RectangleF(0, 0, g.Width, g.Height), background);
// アーチの境界長方形です。
var rc = new RectangleF(0, 0, Inch * 4, Inch * 4.8f);
// 変形を使用して、すべての描画を中央に配置します。
var t = g.Transform;
g.Transform = Matrix3x2.CreateTranslation(g.Width / 2 - rc.Width / 2, g.Height / 2 - rc.Height / 2);
// アーチを描画します。
DrawArch(g, rc, rc.Height * 0.3f, rc.Width * 0.08f, line, arc, fill);
// ラベルを追加します。
var tf = new TextFormat()
{
Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSerif.ttf")),
FontSize = Inch / 6,
ForeColor = text,
};
g.DrawString("ARCH", tf, rc, TextAlignment.Center, ParagraphAlignment.Center, false);
// 計測線(寸法線)を描画します。
var w = Inch / 8;
var pen = new GCDRAW.Pen(marks);
var txt = $"{(rc.Width / Inch):F}\"";
var s = g.MeasureString(txt, tf);
var d = s.Height * 1.5f;
g.DrawLine(rc.Left, rc.Top - d, rc.Right, rc.Top - d, pen);
g.DrawLine(rc.Left, rc.Top - d, rc.Left + w, rc.Top - d - w, pen);
g.DrawLine(rc.Left, rc.Top - d, rc.Left + w, rc.Top - d + w, pen);
g.DrawLine(rc.Right, rc.Top - d, rc.Right - w, rc.Top - d - w, pen);
g.DrawLine(rc.Right, rc.Top - d, rc.Right - w, rc.Top - d + w, pen);
var rcTxt = new RectangleF(rc.Left + rc.Width / 2 - s.Width / 2, rc.Top - d - s.Height / 2, s.Width, s.Height);
rcTxt.Inflate(2, 2);
g.FillRectangle(rcTxt, textBack);
g.DrawString(txt, tf, rcTxt, TextAlignment.Center, ParagraphAlignment.Center, false);
txt = $"{(rc.Height / Inch):F}\"";
s = g.MeasureString(txt, tf);
d = s.Width;
g.DrawLine(rc.Left - d, rc.Top, rc.Left - d, rc.Bottom, pen);
g.DrawLine(rc.Left - d, rc.Top, rc.Left - d - w, rc.Top + w, pen);
g.DrawLine(rc.Left - d, rc.Top, rc.Left - d + w, rc.Top + w, pen);
g.DrawLine(rc.Left - d, rc.Bottom, rc.Left - d - w, rc.Bottom - w, pen);
g.DrawLine(rc.Left - d, rc.Bottom, rc.Left - d + w, rc.Bottom - w, pen);
rcTxt = new RectangleF(rc.Left - d - s.Width / 2, rc.Top + rc.Height / 2 - s.Height / 2, s.Width, s.Height);
rcTxt.Inflate(2, 2);
g.FillRectangle(rcTxt, textBack);
g.DrawString(txt, tf, rcTxt, TextAlignment.Center, ParagraphAlignment.Center, false);
// 変形を元に戻します。
g.Transform = t;
// 画像ファイルを保存します。
var svg = g.ToSvgDocument();
svg.Save(ms);
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
private void DrawArch(GcGraphics g, RectangleF rc, float harc, float wd, Color line, Color arch, Color fill)
{
var path = g.CreatePath();
// 内部の塗りつぶしです(左下から始めて時計回りに描画します)。
path.BeginFigure(rc.Left + wd, rc.Bottom - wd);
path.AddLine(rc.Left + wd, rc.Top + harc);
path.AddArc(new ArcSegment()
{
ArcSize = ArcSize.Small,
Point = new PointF(rc.Right - wd, rc.Top + harc),
RotationAngle = 0,
Size = new SizeF(rc.Width / 2f - wd, harc - wd),
SweepDirection = SweepDirection.Clockwise
});
path.AddLine(rc.Right - wd, rc.Bottom - wd);
path.EndFigure(FigureEnd.Closed);
g.FillPath(path, fill);
path.Dispose();
// アーチの外形線です(左下から始めて時計回りに描画します)。
path = g.CreatePath();
path.BeginFigure(rc.Left, rc.Bottom);
path.AddLine(rc.Left, rc.Top + harc);
path.AddLine(rc.Left + wd, rc.Top + harc);
path.AddLine(rc.Left + wd, rc.Bottom - wd);
path.EndFigure(FigureEnd.Closed);
path.BeginFigure(rc.Left, rc.Top + harc);
path.AddArc(new ArcSegment()
{
ArcSize = ArcSize.Small,
Point = new PointF(rc.Right, rc.Top + harc),
RotationAngle = 0,
Size = new SizeF(rc.Width / 2f, harc),
SweepDirection = SweepDirection.Clockwise
});
path.AddLine(rc.Right - wd, rc.Top + harc);
path.AddArc(new ArcSegment()
{
ArcSize = ArcSize.Small,
Point = new PointF(rc.Left + wd, rc.Top + harc),
RotationAngle = 0,
Size = new SizeF(rc.Width / 2f - wd, harc - wd),
SweepDirection = SweepDirection.CounterClockwise
});
path.EndFigure(FigureEnd.Closed);
path.BeginFigure(rc.Right, rc.Top + harc);
path.AddLine(rc.Right, rc.Bottom);
path.AddLine(rc.Right - wd, rc.Bottom - wd);
path.AddLine(rc.Right - wd, rc.Top + harc);
path.EndFigure(FigureEnd.Closed);
path.BeginFigure(rc.Right, rc.Bottom);
path.AddLine(rc.Left, rc.Bottom);
path.AddLine(rc.Left + wd, rc.Bottom - wd);
path.AddLine(rc.Right - wd, rc.Bottom - wd);
path.EndFigure(FigureEnd.Closed);
g.FillPath(path, arch);
g.DrawPath(path, new GCDRAW.Pen(line, 2));
path.Dispose();
}
}
}