728x90
반응형
728x170
▶ FontHelper.cs
using System;
using System.Drawing;
namespace TestProject
{
/// <summary>
/// 폰트 헬퍼
/// </summary>
public class FontHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region EM 높이 (단위 : 픽셀) - EMHeight
/// <summary>
/// EM 높이 (단위 : 픽셀)
/// </summary>
public float EMHeight { get; protected set; }
#endregion
#region ASCENT (단위 : 픽셀) - Ascent
/// <summary>
/// ASCENT (단위 : 픽셀)
/// </summary>
public float Ascent { get; protected set; }
#endregion
#region DESCENT (단위 : 픽셀) - Descent
/// <summary>
/// DESCENT (단위 : 픽셀)
/// </summary>
public float Descent { get; protected set; }
#endregion
#region CELL 높이 (단위 : 픽셀) - CellHeight
/// <summary>
/// CELL 높이 (단위 : 픽셀)
/// </summary>
public float CellHeight { get; protected set; }
#endregion
#region INTERNAL LEADING (단위 : 픽셀) - InternalLeading
/// <summary>
/// INTERNAL LEADING (단위 : 픽셀)
/// </summary>
public float InternalLeading { get; protected set; }
#endregion
#region 줄 간격 (단위 : 픽셀) - LineSpacing
/// <summary>
/// 줄 간격 (단위 : 픽셀)
/// </summary>
public float LineSpacing { get; protected set; }
#endregion
#region EXTERNAL LEADING (단위 : 픽셀) - ExternalLeading
/// <summary>
/// EXTERNAL LEADING (단위 : 픽셀)
/// </summary>
public float ExternalLeading { get; protected set; }
#endregion
#region 폰트 위쪽 (단위 : 픽셀) - FontTop
/// <summary>
/// 폰트 위쪽 (단위 : 픽셀)
/// </summary>
public float FontTop { get; protected set; }
#endregion
#region 기준선 (단위 : 픽셀) - Baseline
/// <summary>
/// 기준선 (단위 : 픽셀)
/// </summary>
public float Baseline { get; protected set; }
#endregion
#region 폰트 아래쪽 (단위 : 픽셀) - FontBottom
/// <summary>
/// 폰트 아래쪽 (단위 : 픽셀)
/// </summary>
public float FontBottom { get; protected set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - FontHelper(graphics, font)
/// <summary>
/// 생성자
/// </summary>
/// <param name="graphics">그래픽스</param>
/// <param name="font">폰트</param>
public FontHelper(Graphics graphics, Font font)
{
float emHeightValue = font.FontFamily.GetEmHeight(font.Style);
EMHeight = ConvertValue(graphics, font.Size, font.Unit, GraphicsUnit.Pixel);
float designToPixelCount = EMHeight / emHeightValue;
Ascent = designToPixelCount * font.FontFamily.GetCellAscent(font.Style);
Descent = designToPixelCount * font.FontFamily.GetCellDescent(font.Style);
CellHeight = Ascent + Descent;
InternalLeading = CellHeight - EMHeight;
LineSpacing = designToPixelCount * font.FontFamily.GetLineSpacing(font.Style);
ExternalLeading = LineSpacing - CellHeight;
FontTop = InternalLeading;
Baseline = Ascent;
FontBottom = CellHeight;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 값 변환하기 - ConvertValue(Graphics graphics, float value, GraphicsUnit fromGraphicsUnit, GraphicsUnit toGraphicsUnit)
/// <summary>
/// 값 변환하기
/// </summary>
/// <param name="graphics">그래픽스</param>
/// <param name="value">값</param>
/// <param name="fromGraphicsUnit">FROM 그래픽스 단위</param>
/// <param name="toGraphicsUnit">TO 그래픽스 단위</param>
/// <returns>변환값</returns>
private float ConvertValue(Graphics graphics, float value, GraphicsUnit fromGraphicsUnit, GraphicsUnit toGraphicsUnit)
{
if(fromGraphicsUnit == toGraphicsUnit)
{
return value;
}
switch(fromGraphicsUnit)
{
case GraphicsUnit.Document : value *= graphics.DpiX / 300; break;
case GraphicsUnit.Inch : value *= graphics.DpiX; break;
case GraphicsUnit.Millimeter : value *= graphics.DpiX / 25.4f; break;
case GraphicsUnit.Pixel : break;
case GraphicsUnit.Point : value *= graphics.DpiX / 72; break;
default :
throw new Exception("알 수 없는 FROM 그래픽스 단위 입니다 : " + fromGraphicsUnit.ToString());
}
switch(toGraphicsUnit)
{
case GraphicsUnit.Document : value /= graphics.DpiX / 300; break;
case GraphicsUnit.Inch : value /= graphics.DpiX; break;
case GraphicsUnit.Millimeter : value /= graphics.DpiX / 25.4f; break;
case GraphicsUnit.Pixel : break;
case GraphicsUnit.Point : value /= graphics.DpiX / 72; break;
default :
throw new Exception("알 수 없는 TO 그래픽스 단위 입니다 : " + toGraphicsUnit.ToString());
}
return value;
}
#endregion
}
}
728x90
▶ MainForm.cs
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
ResizeRedraw = true;
#region 이벤트를 설정한다.
Paint += Form_Paint;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼 페인트시 처리하기 - Form_Paint(sender, e)
/// <summary>
/// 폼 페인트시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_Paint(object sender, PaintEventArgs e)
{
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
string text = "iyIg";
RectangleF layoutRectangle = new RectangleF(0, 0, this.ClientSize.Width / 3, this.ClientSize.Height);
using(StringFormat stringFormat = new StringFormat())
{
stringFormat.LineAlignment = StringAlignment.Center;
stringFormat.Alignment = StringAlignment.Center;
using(Font font = new Font("Times New Roman", 80, FontStyle.Bold, GraphicsUnit.Pixel))
{
MeasureText(e.Graphics, font, text, layoutRectangle, stringFormat);
}
layoutRectangle.X += this.ClientSize.Width / 3;
using(Font the_font = new Font("Comic Sans MS", 80, FontStyle.Bold, GraphicsUnit.Pixel))
{
MeasureText(e.Graphics, the_font, text, layoutRectangle, stringFormat);
}
layoutRectangle.X += this.ClientSize.Width / 3;
using(Font the_font = new Font("Courier New", 80, FontStyle.Bold, GraphicsUnit.Pixel))
{
MeasureText(e.Graphics, the_font, text, layoutRectangle, stringFormat);
}
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 텍스트 측정하기 - MeasureText(graphics, font, text, layoutRectangle , stringFormat)
/// <summary>
/// 텍스트 측정하기
/// </summary>
/// <param name="graphics">그래픽스</param>
/// <param name="font">폰트</param>
/// <param name="text">텍스트</param>
/// <param name="layoutRectangle">레이아웃 사각형</param>
/// <param name="stringFormat">문자열 포맷</param>
private void MeasureText(Graphics graphics, Font font, string text, RectangleF layoutRectangle , StringFormat stringFormat)
{
CharacterRange[] characterRangeArray = new CharacterRange[text.Length];
for(int i = 0; i < text.Length ; i++)
{
characterRangeArray[i] = new CharacterRange(i, 1);
}
stringFormat.SetMeasurableCharacterRanges(characterRangeArray);
Region[] characterRegionArray = graphics.MeasureCharacterRanges(text, font, layoutRectangle, stringFormat);
FontHelper fontHelper = new FontHelper(graphics, font);
foreach(Region characterRegion in characterRegionArray)
{
RectangleF characterRectangle = characterRegion.GetBounds(graphics);
Rectangle actualCharacterRectangle = Rectangle.Round(characterRectangle);
graphics.FillRectangle(Brushes.Pink, actualCharacterRectangle);
using(Pen pen = new Pen(Color.Black))
{
pen.DashStyle = DashStyle.Custom;
pen.DashPattern = new float[] { 3, 3 };
graphics.DrawLine
(
pen,
actualCharacterRectangle.X - 20,
actualCharacterRectangle.Y,
actualCharacterRectangle.Right,
actualCharacterRectangle.Y
);
}
// INTERNAL LEADING을 그린다.
graphics.DrawLine
(
Pens.Red,
actualCharacterRectangle.X - 3,
actualCharacterRectangle.Y + fontHelper.FontTop,
actualCharacterRectangle.Right + 3,
actualCharacterRectangle.Y + fontHelper.FontTop
);
// ASCENT를 그린다.
graphics.DrawLine
(
Pens.Green,
actualCharacterRectangle.X - 3,
actualCharacterRectangle.Y + fontHelper.Baseline,
actualCharacterRectangle.Right + 3,
actualCharacterRectangle.Y + fontHelper.Baseline
);
// DESCENT를 그린다.
graphics.DrawLine
(
Pens.Blue,
actualCharacterRectangle.X - 3,
actualCharacterRectangle.Y + fontHelper.FontBottom,
actualCharacterRectangle.Right + 3,
actualCharacterRectangle.Y + fontHelper.FontBottom
);
// 다음 라인을 그린다.
using(Pen pen = new Pen(Color.Blue))
{
pen.DashStyle = DashStyle.Custom;
pen.DashPattern = new float[] { 1, 2, 3, 2 };
graphics.DrawLine
(
pen,
actualCharacterRectangle.X,
actualCharacterRectangle.Y + fontHelper.LineSpacing,
actualCharacterRectangle.Right + 30,
actualCharacterRectangle.Y + fontHelper.LineSpacing
);
}
// EXTERNAL LEADING을 채운다.
graphics.FillRectangle
(
Brushes.Orange,
actualCharacterRectangle.X,
actualCharacterRectangle.Y + fontHelper.Ascent + fontHelper.Descent,
actualCharacterRectangle.Width,
fontHelper.ExternalLeading
);
}
// 텍스트를 그린다.
graphics.DrawString(text, font, Brushes.Black, layoutRectangle, stringFormat);
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] 임의의 선으로 채워진 텍스트 그리기 (0) | 2018.12.08 |
---|---|
[C#/WINFORM] 외곽선 텍스트 그리기 (0) | 2018.12.08 |
[C#/WINFORM] 부드러운 소용돌이 프랙탈(Smooth Vortex Fractal) 그리기 (0) | 2018.12.08 |
[C#/WINFORM] 소용돌이 프랙탈(Vortex Fractal) 그리기 (0) | 2018.12.08 |
[C#/WINFORM] 소용돌이 모양 프랙탈(Curlicue Fractal) 그리기 (0) | 2018.12.08 |
[C#/WINFORM] 폰트 메트릭(Font Metrics) 구하기 (0) | 2018.12.08 |
[C#/WINFORM] 문자 크기 측정하기 (0) | 2018.12.08 |
[C#/WINFORM] 마우스 드래그시 고무밴드 상자(Rubber Band Box) 표시하기 (0) | 2018.12.08 |
[C#/WINFORM] 포인트 리스트를 둘러싸는 원 구하기 (0) | 2018.12.05 |
[C#/WINFORM] 2개 직선 사이 최단거리 구하기 (0) | 2018.12.05 |
[C#/WINFORM] 2개 직선의 교차 여부 구하기 (0) | 2018.12.05 |
댓글을 달아 주세요