namespace DemosCommonCode.Annotation
{
/// <summary>
/// Specifies the available types of mark annotation.
/// </summary>
public enum MarkAnnotationType : int
{
/// <summary>
/// The rectangle.
/// </summary>
Rectangle = 0,
/// <summary>
/// The tick.
/// </summary>
Tick = 1,
/// <summary>
/// The star.
/// </summary>
Star = 2,
/// <summary>
/// The cross.
/// </summary>
Cross = 3,
}
}
Namespace DemosCommonCode.Annotation
''' <summary>
''' Specifies the available types of mark annotation.
''' </summary>
Public Enum MarkAnnotationType As Integer
''' <summary>
''' The rectangle.
''' </summary>
Rectangle = 0
''' <summary>
''' The tick.
''' </summary>
Tick = 1
''' <summary>
''' The star.
''' </summary>
Star = 2
''' <summary>
''' The cross.
''' </summary>
Cross = 3
End Enum
End Namespace
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
using System.Security.Permissions;
using Vintasoft.Imaging;
using Vintasoft.Imaging.Annotation;
using Vintasoft.Imaging.Annotation.Rendering;
namespace DemosCommonCode.Annotation
{
/// <summary>
/// Class that holds information about the annotation that displays a mark.
/// </summary>
[Serializable]
public class MarkAnnotationData : AnnotationData
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="MarkAnnotationData"/> class.
/// </summary>
public MarkAnnotationData()
: base()
{
FillBrush = new AnnotationSolidBrush(Color.Black);
}
/// <summary>
/// Initializes a new instance of the <see cref="AnnotationData"/> class.
/// </summary>
/// <param name="info">The SerializationInfo to populate with data.</param>
/// <param name="context">The destination for this serialization.</param>
public MarkAnnotationData(SerializationInfo info, StreamingContext context)
: base(info, context)
{
_markType = (MarkAnnotationType)info.GetValue("MarkType", typeof(int));
}
/// <summary>
/// Initializes the <see cref="MarkAnnotationData"/> class.
/// </summary>
static MarkAnnotationData()
{
// register renderer form this annotation
AnnotationRendererFactory.RegisterRendererForAnnotationData(typeof(MarkAnnotationData), typeof(MarkAnnotationRenderer));
}
#endregion
#region Properties
MarkAnnotationType _markType = MarkAnnotationType.Tick;
/// <summary>
/// Gets or sets a mark type.
/// </summary>
[Description("The mark type.")]
[DefaultValue(MarkAnnotationType.Tick)]
public MarkAnnotationType MarkType
{
get
{
return _markType;
}
set
{
if (_markType != value)
{
ObjectPropertyChangingEventArgs changingArgs =
new ObjectPropertyChangingEventArgs("MarkType", _markType, value);
if (OnPropertyChanging(changingArgs))
{
_markType = (MarkAnnotationType)changingArgs.NewValue;
OnPropertyChanged(changingArgs.ToChangedEventArgs());
}
}
}
}
#endregion
#region Methods
/// <summary>
/// Returns the bounding box of annotation if annotation will have specified location,
/// size and rotation.
/// </summary>
/// <param name="location">Location, in device-independent pixels (1/96th inch),
/// of annotation.</param>
/// <param name="size">Size, in device-independent pixels (1/96th inch),
/// of annotation</param>
/// <param name="rotation">Rotation, in degrees, of annotation.</param>
/// <returns>Bounding box of annotation.</returns>
public override RectangleF GetBoundingBox(PointF location, SizeF size, float rotation)
{
PointF[] points = GetReferencePointsInContentSpace();
// rotate
AnnotationsMath.RotatePointsAt(points, PointF.Empty, Rotation);
// scale
AnnotationsMath.ScalePoints(points, size.Width / this.Size.Width, size.Height / this.Size.Height);
// translate
AnnotationsMath.TranslatePoints(points, location.X, location.Y);
return AnnotationsMath.GetBoundingBox(points);
}
/// <summary>
/// Gets an array that contains reference points in content space of this annotation.
/// </summary>
/// <returns></returns>
public virtual PointF[] GetReferencePointsInContentSpace()
{
float width = Size.Width;
float height = Size.Height;
float w = Math.Min(width / 10, height / 10);
PointF[] points;
switch (MarkType)
{
case MarkAnnotationType.Rectangle:
points = new PointF[]{
new PointF(-width / 2, -height/2),
new PointF(width / 2, -height/2),
new PointF(width / 2, height/2),
new PointF(-width / 2, height/2)};
break;
case MarkAnnotationType.Tick:
points = new PointF[]{
new PointF(-width / 2, 0),
new PointF(0, height / 4),
new PointF(width / 2, -height / 2),
new PointF(0, height / 2),
new PointF(-width / 2, 0)};
break;
case MarkAnnotationType.Cross:
points = new PointF[]{
new PointF(-width / 2, -w),
new PointF(-w, -w),
new PointF(-w, -height/2),
new PointF(w, -height/2),
new PointF(w, -w),
new PointF(width/2, -w),
new PointF(width/2, w),
new PointF(w, w),
new PointF(w, height/2),
new PointF(-w, height/2),
new PointF(-w, w),
new PointF(-width/2, w)};
break;
case MarkAnnotationType.Star:
points = new PointF[]{
new PointF(-width / 2, 0),
new PointF(-w, -w),
new PointF(0, -height/2),
new PointF(w, -w),
new PointF(width/2, 0),
new PointF(w, w),
new PointF(0, height/2),
new PointF(-w, w),
new PointF(-width/2, 0)};
break;
default:
throw new NotImplementedException();
}
AffineMatrix matrix = new AffineMatrix();
if (HorizontalMirrored)
matrix.ScalePrepend(-1, 1);
if (VerticalMirrored)
matrix.ScalePrepend(1, -1);
PointFAffineTransform.TransformPoints(matrix, points);
return points;
}
/// <summary>
/// Populates a SerializationInfo with the data needed to serialize the target object.
/// </summary>
/// <param name="info">The SerializationInfo to populate with data.</param>
/// <param name="context">The destination for this serialization.</param>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("MarkType", (int)MarkType);
}
/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
/// <returns>A new object that is a copy of this instance.</returns>
public override object Clone()
{
MarkAnnotationData data = new MarkAnnotationData();
CopyTo(data);
return data;
}
/// <summary>
/// Copies the state of the current object to the target object.
/// </summary>
/// <param name="target">Object to copy the state of the current object to.</param>
public override void CopyTo(AnnotationData target)
{
base.CopyTo(target);
if (target is MarkAnnotationData)
{
((MarkAnnotationData)target).MarkType = MarkType;
}
}
#endregion
}
}
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Runtime.Serialization
Imports System.Security.Permissions
Imports Vintasoft.Imaging
Imports Vintasoft.Imaging.Annotation
Imports Vintasoft.Imaging.Annotation.Rendering
Namespace DemosCommonCode.Annotation
''' <summary>
''' Class that holds information about the annotation that displays a mark.
''' </summary>
<Serializable> _
Public Class MarkAnnotationData
Inherits AnnotationData
#Region "Constructors"
''' <summary>
''' Initializes a new instance of the <see cref="MarkAnnotationData"/> class.
''' </summary>
Public Sub New()
MyBase.New()
FillBrush = New AnnotationSolidBrush(Color.Black)
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="AnnotationData"/> class.
''' </summary>
''' <param name="info">The SerializationInfo to populate with data.</param>
''' <param name="context">The destination for this serialization.</param>
Public Sub New(info As SerializationInfo, context As StreamingContext)
MyBase.New(info, context)
_markType = CType(info.GetValue("MarkType", GetType(Integer)), MarkAnnotationType)
End Sub
''' <summary>
''' Initializes the <see cref="MarkAnnotationData"/> class.
''' </summary>
Shared Sub New()
' register renderer form this annotation
AnnotationRendererFactory.RegisterRendererForAnnotationData(GetType(MarkAnnotationData), GetType(MarkAnnotationRenderer))
End Sub
#End Region
#Region "Properties"
Private _markType As MarkAnnotationType = MarkAnnotationType.Tick
''' <summary>
''' Gets or sets a mark type.
''' </summary>
<Description("The mark type.")> _
<DefaultValue(MarkAnnotationType.Tick)> _
Public Property MarkType() As MarkAnnotationType
Get
Return _markType
End Get
Set
If _markType <> value Then
Dim changingArgs As New ObjectPropertyChangingEventArgs("MarkType", _markType, value)
If OnPropertyChanging(changingArgs) Then
_markType = CType(changingArgs.NewValue, MarkAnnotationType)
OnPropertyChanged(changingArgs.ToChangedEventArgs())
End If
End If
End Set
End Property
#End Region
#Region "Methods"
''' <summary>
''' Returns the bounding box of annotation if annotation will have specified location,
''' size and rotation.
''' </summary>
''' <param name="location">Location, in device-independent pixels (1/96th inch),
''' of annotation.</param>
''' <param name="size">Size, in device-independent pixels (1/96th inch),
''' of annotation</param>
''' <param name="rotation">Rotation, in degrees, of annotation.</param>
''' <returns>Bounding box of annotation.</returns>
Public Overrides Function GetBoundingBox(location As PointF, size As SizeF, rotation__1 As Single) As RectangleF
Dim points As PointF() = GetReferencePointsInContentSpace()
' rotate
AnnotationsMath.RotatePointsAt(points, PointF.Empty, Rotation)
' scale
AnnotationsMath.ScalePoints(points, size.Width / Me.Size.Width, size.Height / Me.Size.Height)
' translate
AnnotationsMath.TranslatePoints(points, location.X, location.Y)
Return AnnotationsMath.GetBoundingBox(points)
End Function
''' <summary>
''' Gets an array that contains reference points in content space of this annotation.
''' </summary>
''' <returns></returns>
Public Overridable Function GetReferencePointsInContentSpace() As PointF()
Dim width As Single = Size.Width
Dim height As Single = Size.Height
Dim w As Single = Math.Min(width / 10, height / 10)
Dim points As PointF()
Select Case MarkType
Case MarkAnnotationType.Rectangle
points = New PointF() {New PointF(-width / 2, -height / 2), New PointF(width / 2, -height / 2), New PointF(width / 2, height / 2), New PointF(-width / 2, height / 2)}
Exit Select
Case MarkAnnotationType.Tick
points = New PointF() {New PointF(-width / 2, 0), New PointF(0, height / 4), New PointF(width / 2, -height / 2), New PointF(0, height / 2), New PointF(-width / 2, 0)}
Exit Select
Case MarkAnnotationType.Cross
points = New PointF() {New PointF(-width / 2, -w), New PointF(-w, -w), New PointF(-w, -height / 2), New PointF(w, -height / 2), New PointF(w, -w), New PointF(width / 2, -w), _
New PointF(width / 2, w), New PointF(w, w), New PointF(w, height / 2), New PointF(-w, height / 2), New PointF(-w, w), New PointF(-width / 2, w)}
Exit Select
Case MarkAnnotationType.Star
points = New PointF() {New PointF(-width / 2, 0), New PointF(-w, -w), New PointF(0, -height / 2), New PointF(w, -w), New PointF(width / 2, 0), New PointF(w, w), _
New PointF(0, height / 2), New PointF(-w, w), New PointF(-width / 2, 0)}
Exit Select
Case Else
Throw New NotImplementedException()
End Select
Dim matrix As New AffineMatrix()
If HorizontalMirrored Then
matrix.ScalePrepend(-1, 1)
End If
If VerticalMirrored Then
matrix.ScalePrepend(1, -1)
End If
PointFAffineTransform.TransformPoints(matrix, points)
Return points
End Function
''' <summary>
''' Populates a SerializationInfo with the data needed to serialize the target object.
''' </summary>
''' <param name="info">The SerializationInfo to populate with data.</param>
''' <param name="context">The destination for this serialization.</param>
<SecurityPermission(SecurityAction.LinkDemand, Flags := SecurityPermissionFlag.SerializationFormatter)> _
Public Overrides Sub GetObjectData(info As SerializationInfo, context As StreamingContext)
MyBase.GetObjectData(info, context)
info.AddValue("MarkType", CInt(MarkType))
End Sub
''' <summary>
''' Creates a new object that is a copy of the current instance.
''' </summary>
''' <returns>A new object that is a copy of this instance.</returns>
Public Overrides Function Clone() As Object
Dim data As New MarkAnnotationData()
CopyTo(data)
Return data
End Function
''' <summary>
''' Copies the state of the current object to the target object.
''' </summary>
''' <param name="target">Object to copy the state of the current object to.</param>
Public Overrides Sub CopyTo(target As AnnotationData)
MyBase.CopyTo(target)
If TypeOf target Is MarkAnnotationData Then
DirectCast(target, MarkAnnotationData).MarkType = MarkType
End If
End Sub
#End Region
End Class
End Namespace
using System.Drawing;
using Vintasoft.Imaging.UI.VisualTools.UserInteraction;
namespace DemosCommonCode.Annotation
{
/// <summary>
/// Interaction controller that builds a mark annotation.
/// </summary>
public class MarkAnnotationBuilder : InteractionControllerBase<IRectangularInteractiveObject>
{
#region Contructors
/// <summary>
/// Initializes a new instance of the <see cref="MarkAnnotationBuilder"/> class.
/// </summary>
/// <param name="view">The mark annotation.</param>
public MarkAnnotationBuilder(MarkAnnotationView view)
: base(view)
{
// create an interaction area that can be moved, hovered and clicked
ImageViewerArea buildArea = new ImageViewerArea(
InteractionAreaType.Hover | InteractionAreaType.Movable | InteractionAreaType.Clickable);
// mark that any mouse button can interact with interaction area
buildArea.AnyActionMouseButton = true;
// add the interacton area to a list of interaction areas of the interaction controller
InteractionAreaList.Add(buildArea);
// set initial size of annotation
_initialSize = view.Size;
}
#endregion
#region Properties
SizeF _initialSize;
/// <summary>
/// Gets or sets an annotation initial size.
/// </summary>
public SizeF InitialSize
{
get
{
return _initialSize;
}
set
{
_initialSize = value;
}
}
#endregion
#region Methods
/// <summary>
/// Performs an interaction between user and interaction area.
/// </summary>
/// <param name="args">An interaction event args.</param>
protected override void PerformInteraction(InteractionEventArgs args)
{
// set rectangle of annotation
InteractiveObject.SetRectangle(
args.Location.X - _initialSize.Width / 2, args.Location.Y - _initialSize.Height / 2,
args.Location.X + _initialSize.Width / 2, args.Location.Y + _initialSize.Height / 2);
// mark that the user interacted with annotation
args.InteractionOccured(true);
// if any mouse button is clicked
if (args.Action == InteractionAreaAction.Click)
// finish building of annotation
args.InteractionFinished = true;
}
#endregion
}
}
Imports System.Drawing
Imports Vintasoft.Imaging.UI.VisualTools.UserInteraction
Namespace DemosCommonCode.Annotation
''' <summary>
''' Interaction controller that builds a mark annotation.
''' </summary>
Public Class MarkAnnotationBuilder
Inherits InteractionControllerBase(Of IRectangularInteractiveObject)
#Region "Contructors"
''' <summary>
''' Initializes a new instance of the <see cref="MarkAnnotationBuilder"/> class.
''' </summary>
''' <param name="view">The mark annotation.</param>
Public Sub New(view As MarkAnnotationView)
MyBase.New(view)
' create an interaction area that can be moved, hovered and clicked
Dim buildArea As New ImageViewerArea(InteractionAreaType.Hover Or InteractionAreaType.Movable Or InteractionAreaType.Clickable)
' mark that any mouse button can interact with interaction area
buildArea.AnyActionMouseButton = True
' add the interacton area to a list of interaction areas of the interaction controller
InteractionAreaList.Add(buildArea)
' set initial size of annotation
_initialSize = view.Size
End Sub
#End Region
#Region "Properties"
Private _initialSize As SizeF
''' <summary>
''' Gets or sets an annotation initial size.
''' </summary>
Public Property InitialSize() As SizeF
Get
Return _initialSize
End Get
Set
_initialSize = value
End Set
End Property
#End Region
#Region "Methods"
''' <summary>
''' Performs an interaction between user and interaction area.
''' </summary>
''' <param name="args">An interaction event args.</param>
Protected Overrides Sub PerformInteraction(args As InteractionEventArgs)
' set rectangle of annotation
InteractiveObject.SetRectangle(args.Location.X - _initialSize.Width / 2, args.Location.Y - _initialSize.Height / 2, args.Location.X + _initialSize.Width / 2, args.Location.Y + _initialSize.Height / 2)
' mark that the user interacted with annotation
args.InteractionOccured(True)
' if any mouse button is clicked
If args.Action = InteractionAreaAction.Click Then
' finish building of annotation
args.InteractionFinished = True
End If
End Sub
#End Region
End Class
End Namespace
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using Vintasoft.Imaging;
using Vintasoft.Imaging.Annotation;
using Vintasoft.Imaging.Annotation.UI;
using Vintasoft.Imaging.Annotation.UI.VisualTools.UserInteraction;
using Vintasoft.Imaging.Drawing;
using Vintasoft.Imaging.UI.VisualTools.UserInteraction;
namespace DemosCommonCode.Annotation
{
/// <summary>
/// Class that determines how to display the annotation that displays a mark
/// and how user can interact with annotation.
/// </summary>
public class MarkAnnotationView : AnnotationView, IRectangularInteractiveObject
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="MarkAnnotationView"/> class.
/// </summary>
/// <param name="annotationData">Object that stores the annotation data.</param>
public MarkAnnotationView(MarkAnnotationData annotationData)
: base(annotationData)
{
SizeF initialSize = Size;
if (initialSize.IsEmpty)
{
initialSize = new Size(64, 64);
Size = initialSize;
}
Builder = new MarkAnnotationBuilder(this);
RectangularAnnotationTransformer transformer = new RectangularAnnotationTransformer(this);
transformer.HideInteractionPointsWhenMoving = true;
foreach (InteractionPoint point in transformer.ResizePoints)
point.FillColor = Color.FromArgb(100, Color.Red);
Transformer = transformer;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets a mark type.
/// </summary>
[Description("The mark type.")]
[DefaultValue(MarkAnnotationType.Tick)]
public MarkAnnotationType MarkType
{
get
{
return MarkAnnoData.MarkType;
}
set
{
MarkAnnoData.MarkType = value;
}
}
/// <summary>
/// Gets an annotation data.
/// </summary>
MarkAnnotationData MarkAnnoData
{
get
{
return (MarkAnnotationData)Data;
}
}
/// <summary>
/// Gets or sets the rotation angle of interactive object.
/// </summary>
double IRectangularInteractiveObject.RotationAngle
{
get
{
return Rotation;
}
set
{
Rotation = (float)value;
}
}
#endregion
#region Methods
#region PUBLIC
/// <summary>
/// Indicates whether the specified point is contained within the annotation.
/// </summary>
/// <param name="point">Point in image space.</param>
/// <param name="ignoreContainmentCheckDistance">A value indicating whether value of <see cref="AnnotationView.ContainmentCheckDistance"/> property must be ignored.</param>
/// <returns><b>true</b> if the specified point is contained within the annotation;
/// otherwise, <b>false</b>.</returns>
public override bool IsPointOnFigure(PointF point, bool ignoreContainmentCheckDistance)
{
using (IGraphicsPath path = ((MarkAnnotationRenderer)Renderer).GetAsGraphicsPath(DrawingFactory.Default))
{
path.Transform(GetTransformFromContentToImageSpace());
using (IDrawingPen pen = DrawingFactory.Default.CreatePen(Outline))
{
return path.Contains(point) || path.OutlineContains(point, pen);
}
}
}
/// <summary>
/// Creates a new object that is a copy of the current
/// <see cref="MarkAnnotationView"/> instance.
/// </summary>
/// <returns>A new object that is a copy of this <see cref="MarkAnnotationView"/>
/// instance.</returns>
public override object Clone()
{
return new MarkAnnotationView((MarkAnnotationData)this.Data.Clone());
}
/// <summary>
/// Returns an annotation selection as <see cref="GraphicsPath"/> in annotation content space.
/// </summary>
public override GraphicsPath GetSelectionAsGraphicsPath()
{
GraphicsPath path = new GraphicsPath();
SizeF size = Size;
path.AddRectangle(new RectangleF(-size.Width / 2, -size.Height / 2, size.Width, size.Height));
using (Matrix transform = GdiConverter.Convert(GetTransformFromContentToImageSpace()))
path.Transform(transform);
return path;
}
#endregion
#region PROTECTED
/// <summary>
/// Sets the properties of interaction controller according to the properties of annotation.
/// </summary>
/// <param name="controller">The interaction controller.</param>
protected override void SetInteractionControllerProperties(IInteractionController controller)
{
base.SetInteractionControllerProperties(controller);
RectangularObjectTransformer rectangularTransformer = controller as RectangularObjectTransformer;
if (rectangularTransformer != null)
{
rectangularTransformer.CanMove = Data.CanMove;
rectangularTransformer.CanResize = Data.CanResize;
rectangularTransformer.CanRotate = Data.CanRotate;
return;
}
}
/// <summary>
/// Raises the <see cref="AnnotationView.StateChanged" /> event.
/// Invoked when the property of annotation is changed.
/// </summary>
/// <param name="e">An <see cref="ObjectPropertyChangedEventArgs" />
/// that contains the event data.</param>
protected override void OnDataPropertyChanged(ObjectPropertyChangedEventArgs e)
{
base.OnDataPropertyChanged(e);
if (e.PropertyName == "Size")
{
if (Builder is MarkAnnotationBuilder)
((MarkAnnotationBuilder)Builder).InitialSize = (SizeF)e.NewValue;
}
}
#endregion
#region IRectangularInteractiveObject
/// <summary>
/// Returns a rectangle of interactive object.
/// </summary>
/// <param name="x0">Left-top X coordinate of rectangle.</param>
/// <param name="y0">Left-top Y coordinate of rectangle.</param>
/// <param name="x1">Right-bottom X coordinate of rectangle.</param>
/// <param name="y1">Right-bottom Y coordinate of rectangle.</param>
void IRectangularInteractiveObject.GetRectangle(
out double x0,
out double y0,
out double x1,
out double y1)
{
PointF location = Location;
SizeF size = Size;
x0 = location.X - size.Width / 2;
y0 = location.Y - size.Height / 2;
x1 = location.X + size.Width / 2;
y1 = location.Y + size.Height / 2;
if (Data.HorizontalMirrored)
{
double tmp = x0;
x0 = x1;
x1 = tmp;
}
if (Data.VerticalMirrored)
{
double tmp = y0;
y0 = y1;
y1 = tmp;
}
}
/// <summary>
/// Sets a rectangle of interactive object.
/// </summary>
/// <param name="x0">Left-top X coordinate of rectangle.</param>
/// <param name="y0">Left-top Y coordinate of rectangle.</param>
/// <param name="x1">Right-bottom X coordinate of rectangle.</param>
/// <param name="y1">Right-bottom Y coordinate of rectangle.</param>
void IRectangularInteractiveObject.SetRectangle(double x0, double y0, double x1, double y1)
{
Size = new SizeF((float)Math.Abs(x0 - x1), (float)Math.Abs(y0 - y1));
Location = new PointF((float)(x0 + x1) / 2, (float)(y0 + y1) / 2);
HorizontalMirrored = x0 > x1;
VerticalMirrored = y0 > y1;
if (Data.IsInitializing)
OnStateChanged();
}
#endregion
#endregion
}
}
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports Vintasoft.Imaging
Imports Vintasoft.Imaging.Annotation
Imports Vintasoft.Imaging.Annotation.UI
Imports Vintasoft.Imaging.Annotation.UI.VisualTools.UserInteraction
Imports Vintasoft.Imaging.Drawing
Imports Vintasoft.Imaging.UI.VisualTools.UserInteraction
Namespace DemosCommonCode.Annotation
''' <summary>
''' Class that determines how to display the annotation that displays a mark
''' and how user can interact with annotation.
''' </summary>
Public Class MarkAnnotationView
Inherits AnnotationView
Implements IRectangularInteractiveObject
#Region "Constructors"
''' <summary>
''' Initializes a new instance of the <see cref="MarkAnnotationView"/> class.
''' </summary>
''' <param name="annotationData">Object that stores the annotation data.</param>
Public Sub New(annotationData As MarkAnnotationData)
MyBase.New(annotationData)
Dim initialSize As SizeF = Size
If initialSize.IsEmpty Then
initialSize = New Size(64, 64)
Size = initialSize
End If
Builder = New MarkAnnotationBuilder(Me)
Dim transformer__1 As New RectangularAnnotationTransformer(Me)
transformer__1.HideInteractionPointsWhenMoving = True
For Each point As InteractionPoint In transformer__1.ResizePoints
point.FillColor = Color.FromArgb(100, Color.Red)
Next
Transformer = transformer__1
End Sub
#End Region
#Region "Properties"
''' <summary>
''' Gets or sets a mark type.
''' </summary>
<Description("The mark type.")> _
<DefaultValue(MarkAnnotationType.Tick)> _
Public Property MarkType() As MarkAnnotationType
Get
Return MarkAnnoData.MarkType
End Get
Set
MarkAnnoData.MarkType = value
End Set
End Property
''' <summary>
''' Gets an annotation data.
''' </summary>
Private ReadOnly Property MarkAnnoData() As MarkAnnotationData
Get
Return DirectCast(Data, MarkAnnotationData)
End Get
End Property
''' <summary>
''' Gets or sets the rotation angle of interactive object.
''' </summary>
Private Property IRectangularInteractiveObject_RotationAngle() As Double Implements IRectangularInteractiveObject.RotationAngle
Get
Return Rotation
End Get
Set
Rotation = CSng(value)
End Set
End Property
#End Region
#Region "Methods"
#Region "PUBLIC"
''' <summary>
''' Indicates whether the specified point is contained within the annotation.
''' </summary>
''' <param name="point">Point in image space.</param>
''' <param name="ignoreContainmentCheckDistance">A value indicating whether value of <see cref="AnnotationView.ContainmentCheckDistance"/> property must be ignored.</param>
''' <returns><b>true</b> if the specified point is contained within the annotation;
''' otherwise, <b>false</b>.</returns>
Public Overrides Function IsPointOnFigure(point As PointF, ignoreContainmentCheckDistance As Boolean) As Boolean
Using path As IGraphicsPath = DirectCast(Renderer, MarkAnnotationRenderer).GetAsGraphicsPath(DrawingFactory.[Default])
path.Transform(GetTransformFromContentToImageSpace())
Using pen As IDrawingPen = DrawingFactory.[Default].CreatePen(Outline)
Return path.Contains(point) OrElse path.OutlineContains(point, pen)
End Using
End Using
End Function
''' <summary>
''' Creates a new object that is a copy of the current
''' <see cref="MarkAnnotationView"/> instance.
''' </summary>
''' <returns>A new object that is a copy of this <see cref="MarkAnnotationView"/>
''' instance.</returns>
Public Overrides Function Clone() As Object
Return New MarkAnnotationView(DirectCast(Me.Data.Clone(), MarkAnnotationData))
End Function
''' <summary>
''' Returns an annotation selection as <see cref="GraphicsPath"/> in annotation content space.
''' </summary>
Public Overrides Function GetSelectionAsGraphicsPath() As GraphicsPath
Dim path As New GraphicsPath()
Dim size__1 As SizeF = Size
path.AddRectangle(New RectangleF(-size__1.Width / 2, -size__1.Height / 2, size__1.Width, size__1.Height))
Using transform As Matrix = GdiConverter.Convert(GetTransformFromContentToImageSpace())
path.Transform(transform)
End Using
Return path
End Function
#End Region
#Region "PROTECTED"
''' <summary>
''' Sets the properties of interaction controller according to the properties of annotation.
''' </summary>
''' <param name="controller">The interaction controller.</param>
Protected Overrides Sub SetInteractionControllerProperties(controller As IInteractionController)
MyBase.SetInteractionControllerProperties(controller)
Dim rectangularTransformer As RectangularObjectTransformer = TryCast(controller, RectangularObjectTransformer)
If rectangularTransformer IsNot Nothing Then
rectangularTransformer.CanMove = Data.CanMove
rectangularTransformer.CanResize = Data.CanResize
rectangularTransformer.CanRotate = Data.CanRotate
Return
End If
End Sub
''' <summary>
''' Raises the <see cref="AnnotationView.StateChanged" /> event.
''' Invoked when the property of annotation is changed.
''' </summary>
''' <param name="e">An <see cref="ObjectPropertyChangedEventArgs" />
''' that contains the event data.</param>
Protected Overrides Sub OnDataPropertyChanged(e As ObjectPropertyChangedEventArgs)
MyBase.OnDataPropertyChanged(e)
If e.PropertyName = "Size" Then
If TypeOf Builder Is MarkAnnotationBuilder Then
DirectCast(Builder, MarkAnnotationBuilder).InitialSize = CType(e.NewValue, SizeF)
End If
End If
End Sub
#End Region
#Region "IRectangularInteractiveObject"
''' <summary>
''' Returns a rectangle of interactive object.
''' </summary>
''' <param name="x0">Left-top X coordinate of rectangle.</param>
''' <param name="y0">Left-top Y coordinate of rectangle.</param>
''' <param name="x1">Right-bottom X coordinate of rectangle.</param>
''' <param name="y1">Right-bottom Y coordinate of rectangle.</param>
Private Sub IRectangularInteractiveObject_GetRectangle(ByRef x0 As Double, ByRef y0 As Double, ByRef x1 As Double, ByRef y1 As Double) Implements IRectangularInteractiveObject.GetRectangle
Dim location__1 As PointF = Location
Dim size__2 As SizeF = Size
x0 = location__1.X - size__2.Width / 2
y0 = location__1.Y - size__2.Height / 2
x1 = location__1.X + size__2.Width / 2
y1 = location__1.Y + size__2.Height / 2
If Data.HorizontalMirrored Then
Dim tmp As Double = x0
x0 = x1
x1 = tmp
End If
If Data.VerticalMirrored Then
Dim tmp As Double = y0
y0 = y1
y1 = tmp
End If
End Sub
''' <summary>
''' Sets a rectangle of interactive object.
''' </summary>
''' <param name="x0">Left-top X coordinate of rectangle.</param>
''' <param name="y0">Left-top Y coordinate of rectangle.</param>
''' <param name="x1">Right-bottom X coordinate of rectangle.</param>
''' <param name="y1">Right-bottom Y coordinate of rectangle.</param>
Private Sub IRectangularInteractiveObject_SetRectangle(x0 As Double, y0 As Double, x1 As Double, y1 As Double) Implements IRectangularInteractiveObject.SetRectangle
Size = New SizeF(CSng(Math.Abs(x0 - x1)), CSng(Math.Abs(y0 - y1)))
Location = New PointF(CSng(x0 + x1) / 2, CSng(y0 + y1) / 2)
HorizontalMirrored = x0 > x1
VerticalMirrored = y0 > y1
If Data.IsInitializing Then
OnStateChanged()
End If
End Sub
#End Region
#End Region
End Class
End Namespace
using System.Drawing;
using Vintasoft.Imaging;
using Vintasoft.Imaging.Annotation;
using Vintasoft.Imaging.Annotation.Rendering;
using Vintasoft.Imaging.Drawing;
namespace DemosCommonCode.Annotation
{
/// <summary>
/// Determines how to render the mark annotation.
/// </summary>
public class MarkAnnotationRenderer : AnnotationRenderer
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="MarkAnnotationRenderer"/> class.
/// </summary>
/// <param name="annotationData">Object that stores the annotation data.</param>
public MarkAnnotationRenderer(MarkAnnotationData annotationData)
: base(annotationData)
{
}
#endregion
#region Properties
/// <summary>
/// Gets an annotation data.
/// </summary>
MarkAnnotationData MarkAnnoData
{
get
{
return (MarkAnnotationData)Data;
}
}
#endregion
#region Methods
/// <summary>
/// Returns a drawing box of annotation, in the image space.
/// </summary>
/// <param name="drawingSurface">The object that provides information about drawing surface.</param>
/// <returns>Drawing box of annotation, in the image space.</returns>
public override RectangleF GetDrawingBox(DrawingSurface drawingSurface)
{
using (IGraphicsPath path = GetAsGraphicsPath(DrawingFactory.Default))
{
using (IDrawingPen pen = DrawingFactory.Default.CreatePen(Data.Outline))
{
// create transformation that allows to get correct bounding box
AffineMatrix transform = AffineMatrix.CreateRotation(MarkAnnoData.Rotation);
transform.Translate(MarkAnnoData.Location.X, MarkAnnoData.Location.Y);
return path.GetBounds(pen, transform);
}
}
}
/// <summary>
/// Returns a mark annotation as <see cref="IGraphicsPath"/> in content space.
/// </summary>
public virtual IGraphicsPath GetAsGraphicsPath(DrawingFactory drawingFactory)
{
IGraphicsPath path = drawingFactory.CreateGraphicsPath();
PointF[] referencePoints = MarkAnnoData.GetReferencePointsInContentSpace();
switch (MarkAnnoData.MarkType)
{
case MarkAnnotationType.Tick:
path.AddCurve(referencePoints);
break;
default:
path.AddPolygon(referencePoints);
break;
}
return path;
}
/// <summary>
/// Renders the annotation on the <see cref="T:Vintasoft.Imaging.Drawing.DrawingEngine" />
/// in the coordinate space of annotation.
/// </summary>
/// <param name="drawingEngine">The <see cref="T:Vintasoft.Imaging.Drawing.DrawingEngine" /> to render on.</param>
/// <param name="drawingSurface">The object that provides information about drawing surface.</param>
protected override void RenderInContentSpace(DrawingEngine drawingEngine, DrawingSurface drawingSurface)
{
using (IGraphicsPath path = GetAsGraphicsPath(drawingEngine.DrawingFactory))
{
if (Data.FillBrush != null)
{
using (IDrawingBrush brush = drawingEngine.DrawingFactory.CreateBrush(Data.FillBrush))
drawingEngine.FillPath(brush, path);
}
if (Data.Border)
{
using (IDrawingPen pen = drawingEngine.DrawingFactory.CreatePen(Data.Outline))
drawingEngine.DrawPath(pen, path);
}
}
}
#endregion
}
}
Imports System.Drawing
Imports Vintasoft.Imaging
Imports Vintasoft.Imaging.Annotation
Imports Vintasoft.Imaging.Annotation.Rendering
Imports Vintasoft.Imaging.Drawing
Namespace DemosCommonCode.Annotation
''' <summary>
''' Determines how to render the mark annotation.
''' </summary>
Public Class MarkAnnotationRenderer
Inherits AnnotationRenderer
#Region "Constructors"
''' <summary>
''' Initializes a new instance of the <see cref="MarkAnnotationRenderer"/> class.
''' </summary>
''' <param name="annotationData">Object that stores the annotation data.</param>
Public Sub New(annotationData As MarkAnnotationData)
MyBase.New(annotationData)
End Sub
#End Region
#Region "Properties"
''' <summary>
''' Gets an annotation data.
''' </summary>
Private ReadOnly Property MarkAnnoData() As MarkAnnotationData
Get
Return DirectCast(Data, MarkAnnotationData)
End Get
End Property
#End Region
#Region "Methods"
''' <summary>
''' Returns a drawing box of annotation, in the image space.
''' </summary>
''' <param name="drawingSurface">The object that provides information about drawing surface.</param>
''' <returns>Drawing box of annotation, in the image space.</returns>
Public Overrides Function GetDrawingBox(drawingSurface As DrawingSurface) As RectangleF
Using path As IGraphicsPath = GetAsGraphicsPath(DrawingFactory.[Default])
Using pen As IDrawingPen = DrawingFactory.[Default].CreatePen(Data.Outline)
' create transformation that allows to get correct bounding box
Dim transform As AffineMatrix = AffineMatrix.CreateRotation(MarkAnnoData.Rotation)
transform.Translate(MarkAnnoData.Location.X, MarkAnnoData.Location.Y)
Return path.GetBounds(pen, transform)
End Using
End Using
End Function
''' <summary>
''' Returns a mark annotation as <see cref="IGraphicsPath"/> in content space.
''' </summary>
Public Overridable Function GetAsGraphicsPath(drawingFactory As DrawingFactory) As IGraphicsPath
Dim path As IGraphicsPath = drawingFactory.CreateGraphicsPath()
Dim referencePoints As PointF() = MarkAnnoData.GetReferencePointsInContentSpace()
Select Case MarkAnnoData.MarkType
Case MarkAnnotationType.Tick
path.AddCurve(referencePoints)
Exit Select
Case Else
path.AddPolygon(referencePoints)
Exit Select
End Select
Return path
End Function
''' <summary>
''' Renders the annotation on the <see cref="T:Vintasoft.Imaging.Drawing.DrawingEngine" />
''' in the coordinate space of annotation.
''' </summary>
''' <param name="drawingEngine">The <see cref="T:Vintasoft.Imaging.Drawing.DrawingEngine" /> to render on.</param>
''' <param name="drawingSurface">The object that provides information about drawing surface.</param>
Protected Overrides Sub RenderInContentSpace(drawingEngine As DrawingEngine, drawingSurface As DrawingSurface)
Using path As IGraphicsPath = GetAsGraphicsPath(drawingEngine.DrawingFactory)
If Data.FillBrush IsNot Nothing Then
Using brush As IDrawingBrush = drawingEngine.DrawingFactory.CreateBrush(Data.FillBrush)
drawingEngine.FillPath(brush, path)
End Using
End If
If Data.Border Then
Using pen As IDrawingPen = drawingEngine.DrawingFactory.CreatePen(Data.Outline)
drawingEngine.DrawPath(pen, path)
End Using
End If
End Using
End Sub
#End Region
End Class
End Namespace