Windows ストアアプリで合字処理回避を美しく処理する

#win8dev_jp

■ シリーズになっちゃいました。

■ さて本題

Windows ストアアプリで合字処理が出た場合 の記事で Windows ストアアプリで、標準のスタイルがかかっているTextBlockなどでフォントを変更し他場合、合字処理が発生してしまうことを記述した。

image

この図で言うと マイクロや株式会社が一文字になってしまっているところと、Office の ff がつながっているところです。記事では、該当するTextBlockに対して、2つのプロパティを設定して回避する方法を紹介してます。

が、例えば、これって前ページにやるの?XAMLに書くの?って疑問がわきます。

もちろん、ここは Visual Studio 2013 ですから、よりスマートな方法があるのでご紹介します。

プロジェクト内でスタイルを再定義する

簡単にいうと、同じスタイルをプロジェクト内でスタイルとして再定義して問題の箇所だけ変えてしまうのです。じゃぁ定義を探してこないといけないと思うかもしれませんが、スタイルを定義する際に Visual Studio が持ってきてくれるんですよ。ホントいいツールです。

■準備

まずは、TextBlock を配置して、スタイル適応&フォント設定の2つをかけます。下のXAMLをコピペするのが速いかも。

<TextBlock Text="マイクロソフト株式会社 Office 2013" FontFamily="Yu Gothic" FontSize="48" Style="{StaticResource HeaderTextBlockStyle}" />

image

手順

  1. 該当のTextBlock を右クリックして「スタイルの編集」→「コピーして編集」を選びます。(このコピーによって元のスタイルを読み込んでくれるのです。)

    image

  2. ダイアログが表示されたら、

    1. スタイルの名前を同じ名前「HeaderTextBlockStyle」にします。こうすれば作ったスタイルを適応する手間が省けます。

    2. そして設定場所をアプリケーションに変更します。こうすることで各ページごとに設定する必要がなくなります。

      image

  3. App.xaml を開いて Typography.DiscretionaryLigatures="True" を削除して と Typography.StandardLigatures="False" の行を追加します。

    image      

  4. App.xaml を保存します。

  5. MainPage.xaml を開いて確認してみましょう。合字処理がなくなっていることがわかります。     
         
    image

■いちばん簡単な手順

上に手順を書いたわけですが、要はApp.xaml に定義を書いちゃえばいいわけです。その方法。

標準で定義されているスタイルはだいたい7個くらいあるので、7個分の定義がApp.xaml にあれば、この問題はほぼ解決できます。

image

※ もし、元の定義のXAMLを直接見たい場合は、XAMLの HeaderTextBlockStyle をクリックして F12を押しましょう。定義が見えます。 image 要はこの部分を、そのままApp.xaml に持って行っちゃってもいいんですよね。そうすると1発解決。

では実際にやる方法。

  1. App.xaml を開いて以下のXAMLを貼り付ける

    <Application.Resources>
    <Style x:Key="BaseTextBlockStyle" TargetType="TextBlock">
    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
    <Setter Property="SelectionHighlightColor" Value="{ThemeResource TextSelectionHighlightColorThemeBrush}" />
    <Setter Property="TextTrimming" Value="CharacterEllipsis"/>
    <Setter Property="TextWrapping" Value="Wrap"/>
    <Setter Property="Typography.StylisticSet20" Value="True"/>

    <!--<Setter Property="Typography.DiscretionaryLigatures" Value="True"/>-->
    <Setter Property="Typography.StandardLigatures" Value="False"/>

    <Setter Property="Typography.CaseSensitiveForms" Value="True"/>
    <Setter Property="LineHeight" Value="20"/>
    <Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
    <Setter Property="TextLineBounds" Value="TrimToBaseline"/>
    <Setter Property="OpticalMarginAlignment" Value="TrimSideBearings"/>
    </Style>

        <Style x:Key="HeaderTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
    <Setter Property="FontSize" Value="56"/>
    <Setter Property="FontWeight" Value="Light"/>
    <Setter Property="LineHeight" Value="40"/>
    </Style>

        <Style x:Key="SubheaderTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
    <Setter Property="FontSize" Value="26.667"/>
    <Setter Property="FontWeight" Value="Light"/>
    <Setter Property="LineHeight" Value="30"/>
    </Style>

        <Style x:Key="TitleTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
    <Setter Property="FontWeight" Value="SemiBold"/>
    </Style>

        <Style x:Key="SubtitleTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
    <Setter Property="FontWeight" Value="Normal"/>
    </Style>

        <Style x:Key="BodyTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
    <Setter Property="FontWeight" Value="SemiLight"/>
    </Style>

        <Style x:Key="CaptionTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="FontWeight" Value="Normal"/>
    </Style>
    < /Application.Resources>

  2. App.xaml を保存して終了。

そんだけです。あとは、どんなページを作ろうが、どのスタイルを設定しようが、どのフォントを設定しようが、合字は回避できるはず。

■App.xaml に入れておくのは美しくない?

いいんですけど、これだけ大きくて変更のないものをApp.xaml に入れておくのはちょっと美しくないですよね。

なので、リソースディクショナリを作ってそこに入れちゃいましょ。

  1. 「プロジェクト」「新しい項目の追加」「リソースディクショナリ」でリソースディクショナリを追加します。名前は FontStyleDictionary.xaml とでもしておきましょうか。

  2. そこに、先ほどのスタイルをそのままコピペします。スタイルだけです。<Application.Resources></Application.Resources> は不要です。

  3. で、これをApp.xaml から参照します。

    <Application.Resources>
       
        <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="FontStyleDictionary.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>

    </Application.Resources>

美しいね。

でも手順が美しくない。なぜってリソースをコピペしてるから。まとめて持ってくるのは仕方がないとして。もっと美しくやるならBlendを使ってやる。そう、Blen道。続きはそちらで。

応用

応用ってわけではないですが、定義したものを次のプロジェクトからはそのまま App.xaml にコピペしてしまえば、この合字処理の問題は回避できるわけです。ってことはこれが入った プロジェクトをテンプレート化して...

ま、そんな感じです。

Windows Phone の中華フォント問題を思い出しちゃいます。