using System;
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;
namespace Microsoft.Windows.Forms.Layout
{
///
/// 布局操作类
///
public static class LayoutOptions
{
private static TextImageRelation[] m_ImageAlignToRelation;//图片对齐方式转换为文本图片相对位置所需数组
private static ContentAlignment[][] m_RtlTranslateAlignment;//左右反转样式翻译对齐方式所需数组
///
/// 静态构造,初始化字段
///
static LayoutOptions()
{
TextImageRelation[] relationArray = new TextImageRelation[11];
relationArray[0] = TextImageRelation.ImageBeforeText | TextImageRelation.ImageAboveText;
relationArray[1] = TextImageRelation.ImageAboveText;
relationArray[2] = TextImageRelation.TextBeforeImage | TextImageRelation.ImageAboveText;
relationArray[4] = TextImageRelation.ImageBeforeText;
relationArray[6] = TextImageRelation.TextBeforeImage;
relationArray[8] = TextImageRelation.ImageBeforeText | TextImageRelation.TextAboveImage;
relationArray[9] = TextImageRelation.TextAboveImage;
relationArray[10] = TextImageRelation.TextBeforeImage | TextImageRelation.TextAboveImage;
m_ImageAlignToRelation = relationArray;
m_RtlTranslateAlignment = new ContentAlignment[][]
{
new ContentAlignment[] { ContentAlignment.TopLeft, ContentAlignment.TopRight },
new ContentAlignment[] { ContentAlignment.MiddleLeft, ContentAlignment.MiddleRight },
new ContentAlignment[] { ContentAlignment.BottomLeft, ContentAlignment.BottomRight }
};
}
///
/// Rtl翻译Align
///
/// 要被翻译的对齐方式
/// 左右反转样式
/// 翻译后的对齐方式
public static ContentAlignment RtlTranslateAlignment(ContentAlignment align, RightToLeft rtl)
{
if (rtl == RightToLeft.Yes)
{
for (int i = 0; i < 3; i++)
{
if (m_RtlTranslateAlignment[i][0] == align)
return m_RtlTranslateAlignment[i][1];
if (m_RtlTranslateAlignment[i][1] == align)
return m_RtlTranslateAlignment[i][0];
}
}
return align;
}
///
/// Rtl翻译Relation
///
/// 文本图片相对位置
/// 左右反转样式
/// 翻译后的文本图片相对位置
public static TextImageRelation RtlTranslateRelation(TextImageRelation relation, RightToLeft rtl)
{
if (rtl == RightToLeft.Yes)
{
if (relation == TextImageRelation.ImageBeforeText)
return TextImageRelation.TextBeforeImage;
if (relation == TextImageRelation.TextBeforeImage)
return TextImageRelation.ImageBeforeText;
}
return relation;
}
///
/// 图片对齐方式转换为文本图片相对位置
///
/// 图片对齐方式
/// 文本图片相对位置
public static TextImageRelation ImageAlignToRelation(ContentAlignment align)
{
return m_ImageAlignToRelation[LayoutUtils.ContentAlignmentToIndex(align)];
}
///
/// 文本对齐方式转换为文本图片相对位置
///
/// 文本对齐方式
/// 文本图片相对位置
public static TextImageRelation TextAlignToRelation(ContentAlignment align)
{
return LayoutUtils.GetOppositeTextImageRelation(ImageAlignToRelation(align));
}
///
/// 获取绘制格式
///
/// 对齐方式
/// 左右反转
/// 绘制格式
public static StringFormat GetStringFormat(ContentAlignment align, RightToLeft rtl)
{
StringFormat format = DefaultTheme.StringFormat;
switch (align)
{
case ContentAlignment.TopLeft:
format.LineAlignment = StringAlignment.Near;
format.Alignment = StringAlignment.Near;
break;
case ContentAlignment.TopCenter:
format.LineAlignment = StringAlignment.Near;
format.Alignment = StringAlignment.Center;
break;
case ContentAlignment.TopRight:
format.LineAlignment = StringAlignment.Near;
format.Alignment = StringAlignment.Far;
break;
case ContentAlignment.MiddleLeft:
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Near;
break;
case ContentAlignment.MiddleCenter:
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;
break;
case ContentAlignment.MiddleRight:
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Far;
break;
case ContentAlignment.BottomLeft:
format.LineAlignment = StringAlignment.Far;
format.Alignment = StringAlignment.Near;
break;
case ContentAlignment.BottomCenter:
format.LineAlignment = StringAlignment.Far;
format.Alignment = StringAlignment.Center;
break;
case ContentAlignment.BottomRight:
format.LineAlignment = StringAlignment.Far;
format.Alignment = StringAlignment.Far;
break;
default:
break;
}
if (rtl == RightToLeft.Yes)
format.FormatFlags = StringFormatFlags.DirectionRightToLeft;
format.HotkeyPrefix = HotkeyPrefix.Show;
return format;
}
///
/// 获取绘制格式
///
/// 对齐方式
/// 左右反转
/// 绘制格式
public static TextFormatFlags GetTextFormatFlags(ContentAlignment align, RightToLeft rtl)
{
TextFormatFlags flags = TextFormatFlags.WordBreak;
switch (align)
{
case ContentAlignment.TopLeft:
flags |= TextFormatFlags.Top | TextFormatFlags.Left;
break;
case ContentAlignment.TopCenter:
flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
break;
case ContentAlignment.TopRight:
flags |= TextFormatFlags.Top | TextFormatFlags.Right;
break;
case ContentAlignment.MiddleLeft:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
break;
case ContentAlignment.MiddleCenter:
flags |= TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter;
break;
case ContentAlignment.MiddleRight:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
break;
case ContentAlignment.BottomLeft:
flags |= TextFormatFlags.Bottom | TextFormatFlags.Left;
break;
case ContentAlignment.BottomCenter:
flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
break;
case ContentAlignment.BottomRight:
flags |= TextFormatFlags.Bottom | TextFormatFlags.Right;
break;
default:
break;
}
if (rtl == RightToLeft.Yes)
flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
return flags;
}
///
/// 测试文本大小
///
/// 布局对象
/// 可提供的大小
/// 文本大小
public static Size GetTextSize(LayoutData layout, Size proposedSize)
{
return Size.Ceiling(layout.Graphics.MeasureString(layout.Text, layout.Font, new SizeF((float)proposedSize.Width, (float)proposedSize.Height), layout.CurrentStringFormat));
}
///
/// 布局文本和图片,每调用一次,执行一次布局操作
///
/// 布局对象
public static void LayoutTextAndImage(LayoutData layout)
{
if (((layout.ImageSize == Size.Empty) || (layout.Text == null)) || ((layout.Text.Length == 0) || (layout.CurrentTextImageRelation == TextImageRelation.Overlay)))
{
Size imageSize = layout.ImageSize;
Size textSize = GetTextSize(layout, layout.CurrentClientRectangle.Size);
layout.OutImageBounds = LayoutUtils.Align(imageSize, layout.CurrentClientRectangle, layout.CurrentImageAlign);
layout.OutTextBounds = LayoutUtils.Align(textSize, layout.CurrentClientRectangle, layout.CurrentTextAlign);
}
else
{
Size proposedSize = LayoutUtils.SubAlignedRegion(layout.CurrentClientRectangle.Size, layout.ImageSize, layout.CurrentTextImageRelation);//减去图片空间后的大小
Size textSize = GetTextSize(layout, proposedSize);//文本大小
Size textImageSize = LayoutUtils.AddAlignedRegion(textSize, layout.ImageSize, layout.CurrentTextImageRelation);//两个大小相加
Rectangle containerRect = layout.CurrentClientRectangle;//能包含layout.CurrentClientRectangle,textImageSize的最小容器
containerRect.Size = LayoutUtils.UnionSizes(layout.CurrentClientRectangle.Size, textImageSize);//获取两个Size中的最大值(分别计算宽和高)
Rectangle textImageRect = LayoutUtils.Align(textImageSize, containerRect, ContentAlignment.MiddleCenter);//居中
bool imageNoOverlay = (ImageAlignToRelation(layout.CurrentImageAlign) & layout.CurrentTextImageRelation) != TextImageRelation.Overlay;
bool textNoOverlay = (TextAlignToRelation(layout.CurrentTextAlign) & layout.CurrentTextImageRelation) != TextImageRelation.Overlay;
Rectangle imageBounds;
Rectangle textBounds;
if (imageNoOverlay)
{
LayoutUtils.SplitRegion(containerRect, layout.ImageSize, (AnchorStyles)layout.CurrentTextImageRelation, out imageBounds, out textBounds);
}
else if (textNoOverlay)
{
LayoutUtils.SplitRegion(containerRect, textSize, (AnchorStyles)LayoutUtils.GetOppositeTextImageRelation(layout.CurrentTextImageRelation), out textBounds, out imageBounds);
}
else
{
LayoutUtils.SplitRegion(textImageRect, layout.ImageSize, (AnchorStyles)layout.CurrentTextImageRelation, out imageBounds, out textBounds);
LayoutUtils.ExpandRegionsToFillBounds(containerRect, (AnchorStyles)layout.CurrentTextImageRelation, ref imageBounds, ref textBounds);//扩展
}
layout.OutImageBounds = LayoutUtils.Align(layout.ImageSize, imageBounds, layout.CurrentImageAlign);
layout.OutTextBounds = LayoutUtils.Align(textSize, textBounds, layout.CurrentTextAlign);
}
//调整
switch (layout.CurrentTextImageRelation)
{
case TextImageRelation.TextBeforeImage:
case TextImageRelation.ImageBeforeText:
{
int num = Math.Min(layout.OutTextBounds.Bottom, layout.CurrentClientRectangle.Bottom);
layout.OutTextBounds.Y = Math.Max(Math.Min(layout.OutTextBounds.Y, layout.CurrentClientRectangle.Y + ((layout.CurrentClientRectangle.Height - layout.OutTextBounds.Height) / 2)), layout.CurrentClientRectangle.Y);
layout.OutTextBounds.Height = num - layout.OutTextBounds.Y;
break;
}
case TextImageRelation.TextAboveImage:
case TextImageRelation.ImageAboveText:
{
int num2 = Math.Min(layout.OutTextBounds.Right, layout.CurrentClientRectangle.Right);
layout.OutTextBounds.X = Math.Max(Math.Min(layout.OutTextBounds.X, layout.CurrentClientRectangle.X + ((layout.CurrentClientRectangle.Width - layout.OutTextBounds.Width) / 2)), layout.CurrentClientRectangle.X);
layout.OutTextBounds.Width = num2 - layout.OutTextBounds.X;
break;
}
default:
break;
}
if ((layout.CurrentTextImageRelation == TextImageRelation.ImageBeforeText) && (layout.OutImageBounds.Size.Width != 0))
{
layout.OutImageBounds.Width = Math.Max(0, Math.Min(layout.CurrentClientRectangle.Width - layout.OutTextBounds.Width, layout.OutImageBounds.Width));
layout.OutTextBounds.X = layout.OutImageBounds.X + layout.OutImageBounds.Width;
}
if ((layout.CurrentTextImageRelation == TextImageRelation.ImageAboveText) && (layout.OutImageBounds.Size.Height != 0))
{
layout.OutImageBounds.Height = Math.Max(0, Math.Min(layout.CurrentClientRectangle.Height - layout.OutTextBounds.Height, layout.OutImageBounds.Height));
layout.OutTextBounds.Y = layout.OutImageBounds.Y + layout.OutImageBounds.Height;
}
layout.OutTextBounds = Rectangle.Intersect(layout.OutTextBounds, layout.CurrentClientRectangle);
//
int num3 = Math.Min(layout.OutTextBounds.Bottom, layout.CurrentClientRectangle.Bottom);
layout.OutTextBounds.Y = Math.Max(layout.OutTextBounds.Y, layout.CurrentClientRectangle.Y);
layout.OutTextBounds.Height = num3 - layout.OutTextBounds.Y;
//偏移
layout.OutImageBounds.Offset(layout.ImageOffset);
layout.OutTextBounds.Offset(layout.TextOffset);
}
}
}