'CondensedTextBlock'에 해당되는 글 2건

  1. 2009/03/28 CondensedTextBlock #2 (2)
  2. 2008/12/12 Condensed TextBlock (5)
WPF2009/03/28 20:31
안녕하세요. 김대욱입니다. 현재 블로그에 포스팅되어있는 컨텐츠들을 모아서 UserControl LIbrary를 제작 하는 계획을 구상중에 있어서 포스팅이 늦었네요 ^^; 한번에 다 올리기에는 양도 너무 많고 아직 완성이 되질 않았기 때문에 중간중간 정리된 내용을 업로드하도록 하겠습니다. (기타 연재가 완료되지 않은 내용은 중간중간 포스팅 하겠습니다.)

이번시간에는 WPF상에서 텍스트의 자간을 조절하기 위한 CondensedTextblock(http://whatisthat.co.kr/127)의 몇가지 기능을 추가 & 개선한 내용에 대해 소개해 드리겠습니다. 아래는 샘플의 시연 동영상입니다.



기존 단순히 자간만을 조절할 수 있었던 기능에서 각 글자 단위로 Vertical, Horizontal Scale을 조절 가능할 수 있도록 추가 했습니다. 그리고 WPF상에서 작은 크기의 폰트를 사용할 경우 글자의 Antialising이 제대로 적용되지 않아 글자가 깨지는것처럼 보여지는 부분을 개선했습니다.

아래 그림은 기본적으로 WPF에서 제공해주는 TextBlock와 이번 포스팅에서 구현한 CondensedTextblock을 사용하여 각기 다른 크기의(12px ~ 30px까지) 텍스트를 출력했을 경우의 모양을 캡쳐한 화면입니다.



Textblock의 경우 폰트 크기가 작은 외각이 매끄럽지 못한 반면에 CondensedTextblock은 폰트 크기와 관계없이 Antialising이 적용되는 것을 확인 하실 수 있습니다.

아래 소스코드는 텍스트를 출력하는 핵심 코드입니다.

기존의 코드에서는 DrawingContext.DrawText 를 이용하여 FormattedText를 Drawing했지만, 이번 버전에서는 BuildGeometry를 사용하여 Text의 Geometry를 생성하고 DrawGeometry를 이용해 Drawing하도록 했습니다.


PS. 아직 최적화 작업은 진행되지 않은 내용입니다. 참고하시기 바랍니다. 아래는 소스코드입니다.






저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 곡스
WPF2008/12/12 02:49


WPF를 사용하면서 가장 아쉬웠던 점 중 하나를 꼽으라면 바로 Textblock 혹은 TextBox에서의 자간조절이 불가능하다는 점이였습니다. 디자인 작업을 할 때 보다 세련된 느낌을 표현하기 위해서 Font에 자간을 조절하여 느낌을 많이 개선하곤 하는데요, WPF에서는 기본적으로 자간을 조절을 지원하지 않아 지금까지는 해당 텍스트를 이미지로 만들어 표현하다가, 도서관리 프로그램을 만들면서 새로 자간을 지원하는 TextBlock를 구현 했습니다.


    
        
    

    
    
    
    
    
    
    
    
    
    
        




100을 기준으로 크기가 증가할 수록 자간이 넓어지게 됩니다. 아래는 CondensedTextBlock 클래스의 전체 소스코드입니다.

public class CondensedTextBlock : FrameworkElement
{

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text", typeof(String), typeof(CondensedTextBlock), new FrameworkPropertyMetadata(
             "", FrameworkPropertyMetadataOptions.AffectsRender));

    public String Text
    {
        get { return (String)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); InvalidateVisual(); }
    }

    public FontFamily FontFamily
    {
        get { return (FontFamily)GetValue(FontFamilyProperty); }
        set { SetValue(FontFamilyProperty, value); InvalidateVisual(); }
    }

    public static readonly DependencyProperty FontFamilyProperty =
        DependencyProperty.Register("FontFamily", typeof(FontFamily), 
        typeof(CondensedTextBlock), 
        new FrameworkPropertyMetadata(new FontFamily("NanumGothic"), FrameworkPropertyMetadataOptions.AffectsRender));


    public Double FontStretch
    {
        get { return (double)GetValue(FontStretchProperty); }
        set { SetValue(FontStretchProperty, value); InvalidateVisual(); }
    }

    public static readonly DependencyProperty FontStretchProperty =
        DependencyProperty.Register("FontStretch", typeof(Double), 
        typeof(CondensedTextBlock), 
        new FrameworkPropertyMetadata((double)1, FrameworkPropertyMetadataOptions.AffectsRender));


    public Brush Foreground
    {
        get { return (Brush)GetValue(ForegroundProperty); }
        set { SetValue(ForegroundProperty, value); InvalidateVisual(); }
    }

    public static readonly DependencyProperty ForegroundProperty =
        DependencyProperty.Register("Foreground", typeof(Brush), 
        typeof(CondensedTextBlock), 
        new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.AffectsRender));


    public double FontSize
    {
        get { return (double)GetValue(FontSizeProperty); }
        set { SetValue(FontSizeProperty, value); Height = value; }
    }

    public static readonly DependencyProperty FontSizeProperty =
        DependencyProperty.Register("FontSize", typeof(double), 
        typeof(CondensedTextBlock), 
        new FrameworkPropertyMetadata((double)11, FrameworkPropertyMetadataOptions.AffectsRender));


    
    protected override void OnRender(DrawingContext dc)
    {

        DrawingContext DrawingContext = dc;

        double XOffset = 0;
        if (Text == null) return;
        foreach (char Char in Text)
        {
            FormattedText FormattedText = new FormattedText(Char.ToString(), 
                CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                new Typeface(FontFamily, FontStyles.Normal, FontWeights.Normal, 
                FontStretches.Normal), FontSize, Foreground);

            DrawingContext.DrawText(FormattedText, new Point(XOffset, 0));
            XOffset += FormattedText.WidthIncludingTrailingWhitespace * FontStretch / 100;
        }

    }

    protected override Size MeasureOverride(Size availableSize)
    {
        availableSize.Height = FontSize * 1.2;
        return availableSize;
    }

}

아래는 전체 소스코드와 샘플 프로젝트입니다. 질문은 리플이나 이메일로 보내주세요~ !!


크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 곡스