첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ 회전 텍스트 그리기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


VerticalAlignment.cs

 

 

namespace TestProject

{

    /// <summary>

    /// 수직 정렬

    /// </summary>

    public enum VerticalAlignment

    {

        /// <summary>

        /// 상단

        /// </summary>

        Top,

 

        /// <summary>

        /// 중단

        /// </summary>

        Middle,

 

        /// <summary>

        /// 하단

        /// </summary>

        Bottom,

    }

}

 

 

DrawingContextExtension.cs

 

 

using System.Globalization;

using System.Linq;

using System.Windows;

using System.Windows.Media;

 

namespace TestProject

{

    /// <summary>

    /// 그리기 컨텍스트 확장

    /// </summary>

    public static class DrawingContextExtension

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 문자열 그리기 - DrawString(drawingContext, text, fontName, emSize, brush, originPoint, verticalAlignment,

            horizontalAlignment)

 

        /// <summary>

        /// 문자열 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="text">텍스트</param>

        /// <param name="fontName">폰트명</param>

        /// <param name="emSize">EM 크기</param>

        /// <param name="brush">브러시</param>

        /// <param name="originPoint">원점 포인트</param>

        /// <param name="verticalAlignment">수직 정렬</param>

        /// <param name="horizontalAlignment">수평 정렬</param>

        public static void DrawString(this DrawingContext drawingContext, string text, string fontName, double emSize, Brush brush,

            Point originPoint, VerticalAlignment verticalAlignment, TextAlignment horizontalAlignment)

        {

            Typeface typeface = new Typeface(fontName);

 

            FormattedText formattedText = new FormattedText

            (

                text,

                CultureInfo.CurrentUICulture,

                FlowDirection.LeftToRight,

                typeface,

                emSize,

                brush

            );

 

            formattedText.TextAlignment = horizontalAlignment;

 

            if(verticalAlignment == VerticalAlignment.Middle)

            {

                originPoint.Y -= formattedText.Height / 2;

            }

            else if(verticalAlignment == VerticalAlignment.Bottom)

            {

                originPoint.Y -= formattedText.Height;

            }

 

            drawingContext.DrawText(formattedText, originPoint);

        }

 

        #endregion

        #region 문자열 그리기 - DrawString(drawingContext, text, rotateAngle, fontName, emSize, brush, originPoint, textAlignment,

            verticalAlignment, horizontalAlignment)

 

        /// <summary>

        /// 문자열 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="text">텍스트</param>

        /// <param name="rotateAngle">회전 각도</param>

        /// <param name="fontName">폰트명</param>

        /// <param name="emSize">EM 크기</param>

        /// <param name="brush">브러시</param>

        /// <param name="originPoint">원점 포인트</param>

        /// <param name="textAlignment">텍스트 정렬</param>

        /// <param name="verticalAlignment">수직 정렬</param>

        /// <param name="horizontalAlignment">수평 정렬</param>

        public static void DrawString(this DrawingContext drawingContext, string text, double rotateAngle, string fontName,

            double emSize, Brush brush, Point originPoint, TextAlignment textAlignment, VerticalAlignment verticalAlignment,

            TextAlignment horizontalAlignment)

        {

            Typeface typeface = new Typeface(fontName);

 

            FormattedText formattedText = new FormattedText

            (

                text,

                CultureInfo.CurrentUICulture,

                FlowDirection.LeftToRight,

                typeface,

                emSize,

                brush

            );

 

            formattedText.TextAlignment = textAlignment;

 

            double width  = formattedText.Width - formattedText.OverhangLeading;

            double height = formattedText.Height;

 

            TranslateTransform translateTransform1 = new TranslateTransform();

 

            translateTransform1.Y = -height / 2;

 

            if((textAlignment == TextAlignment.Left) || (textAlignment == TextAlignment.Justify))

            {

                translateTransform1.X = -width / 2;

            }

            else if(textAlignment == TextAlignment.Right)

            {

                translateTransform1.X = width / 2;

            }

            else

            {

                translateTransform1.X = 0;

            }

 

            RotateTransform rotateTransform = new RotateTransform(rotateAngle);

 

            Rect rectangle = new Rect(0, 0, width, height);

 

            if(textAlignment == TextAlignment.Center)

            {

                rectangle.X -= width / 2;

            }

            else if(textAlignment == TextAlignment.Right)

            {

                rectangle.X -= width;

            }

 

            Rect rotateRectangle = rotateTransform.TransformBounds(rectangle);

 

            TranslateTransform translateTransform2 = new TranslateTransform(originPoint.X, originPoint.Y);

 

            if(horizontalAlignment == TextAlignment.Left)

            {

                translateTransform2.X += rotateRectangle.Width / 2;

            }

            else if(horizontalAlignment == TextAlignment.Right)

            {

                translateTransform2.X -= rotateRectangle.Width / 2;

            }

 

            if(verticalAlignment == VerticalAlignment.Top)

            {

                translateTransform2.Y += rotateRectangle.Height / 2;

            }

            else if(verticalAlignment == VerticalAlignment.Bottom)

            {

                translateTransform2.Y -= rotateRectangle.Height / 2;

            }

 

            drawingContext.PushTransform(translateTransform2);

            drawingContext.PushTransform(rotateTransform);

            drawingContext.PushTransform(translateTransform1);

 

            drawingContext.DrawText(formattedText, new Point(0, 0));

 

            drawingContext.DrawRectangle(null, new Pen(Brushes.Red, 1), rectangle);

 

            drawingContext.Pop();

            drawingContext.Pop();

            drawingContext.Pop();

 

            Rect transformRectangle = translateTransform2.TransformBounds

            (

                rotateTransform.TransformBounds

                (

                    translateTransform1.TransformBounds(rectangle)

                )

            );

 

            Pen customPen = new Pen(Brushes.Blue, 1);

 

            customPen.DashStyle = new DashStyle(new double[] { 5, 5 }, 0);

 

            drawingContext.DrawRectangle(null, customPen, transformRectangle);

        }

 

        #endregion

        #region 다각형 그리기 - DrawPolygon(drawingContext, brush, pen, pointArray, fillRule)

 

        /// <summary>

        /// 다각형 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="brush">브러시</param>

        /// <param name="pen"></param>

        /// <param name="pointArray">포인트 배열</param>

        /// <param name="fillRule">채우기 규칙</param>

        public static void DrawPolygon(this DrawingContext drawingContext, Brush brush, Pen pen, Point[] pointArray, FillRule fillRule)

        {

            drawingContext.DrawPolygonOrPolyline(brush, pen, pointArray, fillRule, true);

        }

 

        #endregion

        #region 다각선 그리기 - DrawPolyline(drawingContext, brush, pen, pointArray, fillRule)

 

        /// <summary>

        /// 다각선 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="brush">브러시</param>

        /// <param name="pen"></param>

        /// <param name="pointArray">포인트 배열</param>

        /// <param name="fillRule">채우기 규칙</param>

        public static void DrawPolyline(this DrawingContext drawingContext, Brush brush, Pen pen, Point[] pointArray, FillRule fillRule)

        {

            drawingContext.DrawPolygonOrPolyline(brush, pen, pointArray, fillRule, false);

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 다각형 또는 다각선 그리기 - DrawPolygonOrPolyline(drawingContext, brush, pen, pointArray, fillRule, drawPolygon)

 

        /// <summary>

        /// 다각형 또는 다각선 그리기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        /// <param name="brush">브러시</param>

        /// <param name="pen"></param>

        /// <param name="pointArray">포인트 배열</param>

        /// <param name="fillRule">채우기 규칙</param>

        /// <param name="drawPolygon">다각형 그리기 여부</param>

        private static void DrawPolygonOrPolyline(this DrawingContext drawingContext, Brush brush, Pen pen, Point[] pointArray,

            FillRule fillRule, bool drawPolygon)

        {

            StreamGeometry streamGeometry = new StreamGeometry();

 

            streamGeometry.FillRule = fillRule;

 

            using(StreamGeometryContext context = streamGeometry.Open())

            {

                context.BeginFigure(pointArray[0], true, drawPolygon);

 

                context.PolyLineTo(pointArray.Skip(1).ToArray(), true, false);

            }

 

            drawingContext.DrawGeometry(brush, pen, streamGeometry);

        }

 

        #endregion

    }

}

 

 

MainWindow.xaml

 

 

<Window x:Class="TestProject.MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Width="600"

    Height="450"

    Title="회전 텍스트 그리기"

    FontFamily="나눔고딕코딩"

    FontSize="16"

    Background="Transparent">

    <Grid>

        <StackPanel

            Orientation="Horizontal"

            Margin="5"

            VerticalAlignment="Top"

            Width="Auto"

            Height="Auto">

            <Label Content="텍스트 정렬"/>

            <ComboBox Name="textAlignmentComboBox"

                Width="80"

                VerticalContentAlignment="Center"

                SelectedIndex="1"

                SelectionChanged="textAlignmentComboBox_SelectionChanged">

                <ComboBox.Items>

                    <Label Content="Left"    />

                    <Label Content="Center" />

                    <Label Content="Right"   />

                    <Label Content="Justify" />

                </ComboBox.Items>

            </ComboBox>

            <Label

                Margin="20 0 0 0"

                Content="각도"/>

            <TextBox Name="angleTextBox"

                Width="40"

                TextAlignment="Right"

                VerticalContentAlignment="Center"

                TextChanged="angleTextBox_TextChanged">

                45

            </TextBox>

        </StackPanel>

    </Grid>

</Window>

 

 

MainWindow.xaml.cs

 

 

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media;

 

namespace TestProject

{

    /// <summary>

    /// 메인 윈도우

    /// </summary>

    public partial class MainWindow : Window

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainWindow()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainWindow()

        {

            InitializeComponent();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

        #region 렌더링시 처리하기 - OnRender(drawingContext)

 

        /// <summary>

        /// 렌더링시 처리하기

        /// </summary>

        /// <param name="drawingContext">그리기 컨텍스트</param>

        protected override void OnRender(DrawingContext drawingContext)

        {

            Rect backgroundRectangle = new Rect(0, 0, ActualWidth, ActualHeight);

 

            drawingContext.DrawRectangle(Brushes.White, null, backgroundRectangle);

 

            double angle;

 

            if(!double.TryParse(this.angleTextBox.Text, out angle))

            {

                return;

            }

 

            TextAlignment textAlign;

 

            if(this.textAlignmentComboBox.Text == "Left")

            {

                textAlign = TextAlignment.Left;

            }

            else if(this.textAlignmentComboBox.Text == "Right")

            {

                textAlign = TextAlignment.Right;

            }

            else if(this.textAlignmentComboBox.Text == "Center")

            {

                textAlign = TextAlignment.Center;

            }

            else

            {

                textAlign = TextAlignment.Justify;

            }

 

            const string FONT_NAME = "Times New Roman";

            const double EM_SIZE   = 14;

 

            Pen pen = new Pen(Brushes.Green, 1);

 

            Brush brush = Brushes.Lime;

 

            Point point;

 

            const double x0 = 50;

            const double y0 = 50;

            const double dy = 150;

            const double dx = 150;

 

            double x;

            double y;

 

            y = y0;

            x = x0;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "TOP\nLEFT",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Top,

                TextAlignment.Left

            );

 

            x += dx;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "TOP\nCENTER",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Top,

                TextAlignment.Center

            );

 

            x += dx;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "TOP\nRIGHT",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Top,

                TextAlignment.Right

            );

 

            y += dy;

 

            x = x0;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "MIDDLE\nLEFT",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Middle,

                TextAlignment.Left

            );

 

            x += dx;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "MIDDLE\nCENTER",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Middle,

                TextAlignment.Center

            );

 

            x += dx;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "MIDDLE\nRIGHT",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Middle,

                TextAlignment.Right

            );

 

            y += dy;

 

            x = x0;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "BOTTOM\nLEFT",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Bottom,

                TextAlignment.Left

            );

 

            x += dx;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "BOTTOM\nCENTER",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Bottom,

                TextAlignment.Center

            );

 

            x += dx;

 

            point = new Point(x, y);

 

            drawingContext.DrawEllipse(brush, pen, point, 3, 3);

 

            drawingContext.DrawString

            (

                "BOTTOM\nRIGHT",

                angle,

                FONT_NAME,

                EM_SIZE,

                Brushes.Black,

                point,

                textAlign,

                TestProject.VerticalAlignment.Bottom,

                TextAlignment.Right

            );

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region 텍스트 정렬 콤보 박스 선택 변경시 처리하기 - textAlignmentComboBox_SelectionChanged(sender, e)

 

        /// <summary>

        /// 텍스트 정렬 콤보 박스 선택 변경시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void textAlignmentComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)

        {

            InvalidateVisual();

        }

 

        #endregion

        #region 각도 텍스트 박스 텍스트 변경시 처리하기 - angleTextBox_TextChanged(sender, e)

 

        /// <summary>

        /// 각도 텍스트 박스 텍스트 변경시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void angleTextBox_TextChanged(object sender, TextChangedEventArgs e)

        {

            InvalidateVisual();

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker

댓글을 달아 주세요