1. 程式人生 > >WPF文字描邊的解決方法(二)——支援文字豎排和字元間距調整

WPF文字描邊的解決方法(二)——支援文字豎排和字元間距調整

自前天格式化文字效果出來後,今天又新增文字豎排和調整字元間距的功能。另外,由於上次倉促,沒來得及做有些功能的設計時支援,這次也調整好了。

由於本人比較懶,沒有重新做,文字豎排和字元間距主要是通過新建繼承自StackPanel的FormatedText類逐字元新增StrokeableLabel做的,豎排是用的StackPanel.Orientation來設定的,字元間距主要用的StrokeableLabel.Margin。

FormatedText有如下新添屬性:

StretchSize:字元間距

TextOrientation:文字排版

下面是效果圖

XMAL配置:

<Window x:Class="StrokeableLabelTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpflib="clr-namespace:BLCTClassLibrary.WpfLib;assembly=BLCTClassLibrary.WpfLib"
        Title="MainWindow" Height="422" Width="579">
    <Grid ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <StackPanel Orientation="Vertical" >
            <Label Margin="10"  Content="以下是StrokeableLabel類(相對輕量級)"/>
            <wpflib:StrokeableLabel Text="測試文字" Fill="Yellow" Stroke="Black" StrokeThickness="0.3" FontWeight="Bold" FontSize="50"/>
            <wpflib:StrokeableLabel Text="測試文字" Fill="Yellow" Stroke="Red" StrokeThickness="0.7" FontWeight="DemiBold" FontSize="50">
                <wpflib:StrokeableLabel.Effect>
                    <DropShadowEffect Color="Black" BlurRadius="15" RenderingBias="Quality" Direction="290" ShadowDepth="5" Opacity="1"  />
                </wpflib:StrokeableLabel.Effect>
            </wpflib:StrokeableLabel>
            <wpflib:StrokeableLabel Text="測試文字" Fill="White" StrokeThickness="2" FontWeight="Bold" FontSize="50">
                <wpflib:StrokeableLabel.Stroke>
                    <LinearGradientBrush>
                        <LinearGradientBrush.GradientStops>
                            <GradientStop Color="Blue" Offset="0.2"/>
                            <GradientStop Color="Brown" Offset="0.3"/>
                            <GradientStop Color="PowderBlue" Offset="0.7"/>
                            <GradientStop Color="Red" Offset="1"/>
                        </LinearGradientBrush.GradientStops>
                    </LinearGradientBrush>
                </wpflib:StrokeableLabel.Stroke>
            </wpflib:StrokeableLabel>
            <wpflib:StrokeableLabel Text="測試文字" Stroke="red" StrokeThickness="2"  FontWeight="Bold" FontSize="50">
                <wpflib:StrokeableLabel.Fill>
                    <ImageBrush ImageSource="/StrokeableLabelTest;component/Images/20085385922474_2.jpg" />
                </wpflib:StrokeableLabel.Fill>
            </wpflib:StrokeableLabel>
            <wpflib:StrokeableLabel Fill="Transparent" FontSize="50" FontWeight="Light" StrokeThickness="8" Text="測試文字" >
                <wpflib:StrokeableLabel.Stroke>
                    <ImageBrush ImageSource="/StrokeableLabelTest;component/Images/05.jpg" />
                </wpflib:StrokeableLabel.Stroke>
            </wpflib:StrokeableLabel>
        </StackPanel>
        <StackPanel Grid.Column="1" Orientation="Vertical" >
            <TextBlock Margin="10"  Text="以下是FormatedText類(在StrokeableLabel的基礎上可以使文字豎排,可以控制字元間距)" TextWrapping="WrapWithOverflow" />
            <wpflib:FormatedText StretchSize="-5" TextOrientation="Vertical" HorizontalAlignment="Center" Text="測試文字" Fill="Yellow" Stroke="Black" StrokeThickness="0.3" FontWeight="Bold" FontSize="50"/>
            <wpflib:FormatedText StretchSize="-10" HorizontalAlignment="Center" Text="測試文字" Fill="Yellow" Stroke="Black" StrokeThickness="0.3" FontWeight="Bold" FontSize="50"/>
            <wpflib:FormatedText StretchSize="20" HorizontalAlignment="Center" Text="測試文字" Fill="Yellow" Stroke="Black" StrokeThickness="0.3" FontWeight="Bold" FontSize="50">
                <wpflib:FormatedText.Effect>
                    <DropShadowEffect Color="Black" BlurRadius="15" RenderingBias="Quality" Direction="290" ShadowDepth="5" Opacity="1"  />
                </wpflib:FormatedText.Effect>
            </wpflib:FormatedText>
        </StackPanel>
    </Grid>
</Window>


庫檔案僅貼關鍵程式碼,其餘請參考原始碼。庫檔案中利用StrokeableLabel進行排版以達到橫/豎排和字元間距的效果:

        private void CreateText(string newStr)
        {
            this.Children.Clear();
            if (newStr == null)
                return;
            this.Orientation = TextOrientation;

            for (int i = 0; i < newStr.Length; i++)
            {
                if (i < newStr.Length - 1)
                    addChar(newStr[i], false);
                else
                    addChar(newStr[i], true);
            }
        }

        /// <summary>
        /// 新增一個字元
        /// </summary>
        /// <param name="c"></param>
        private void addChar(char c, bool ignore)
        {
            StrokeableLabel label = new StrokeableLabel();
            label.Text = c + "";
            label.Fill = this.Fill;
            label.Stroke = this.Stroke;
            label.StrokeThickness = this.StrokeThickness;
            label.FontSize = this.FontSize;
            label.FontFamily = this.FontFamily;
            label.FontStyle = this.FontStyle;
            label.FontWeight = this.FontWeight;
            label.FontStretch = this.FontStretch;
            if (!ignore)
                switch (Orientation)
                {
                    case System.Windows.Controls.Orientation.Horizontal:
                        label.Margin = new Thickness(0, 0, StretchSize, 0);
                        break;
                    case System.Windows.Controls.Orientation.Vertical:
                        label.Margin = new Thickness(0, 0, 0, StretchSize);
                        break;
                }
            label.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            label.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            this.Children.Add(label);
        }

原始碼: