2 using System.Collections.Generic;
3 using System.Diagnostics;
8 /// DirectWrite を使った Direct2D1ビットマップ。
11 /// 「表示文字列」メンバを設定/更新すれば、次回の描画時にビットマップが生成される。
13 public class 文字列画像 : FDK.Activity
16 /// このメンバを set すれば、次回の進行描画時に画像が更新される。
18 public string 表示文字列 { get; set; } = null;
19 public string フォント名 { get; set; } = "メイリオ";
20 public float フォントサイズpt { get; set; } = 20.0f;
21 public SharpDX.Direct2D1.InterpolationMode 補正モード { get; set; } = SharpDX.Direct2D1.InterpolationMode.Linear;
22 public SharpDX.RectangleF? 転送元矩形dpx { get; set; } = null;
23 public bool 加算合成 { get; set; } = false;
24 public SharpDX.Size2F レイアウトサイズdpx { get; set; } = new SharpDX.Size2F( -1f, -1f );
25 public bool 下詰め { get; set; } = false;
30 public 文字列画像( string 文字列, float フォントサイズpt = 20.0f, string フォント名 = "メイリオ" )
34 this.フォントサイズpt = フォントサイズpt;
36 protected override void Onデバイス依存リソースの作成( デバイスリソース dr )
40 if( this.表示文字列.Nullでも空でもない() )
42 this.ビットマップを生成する( dr );
43 this.前回の表示文字列 = this.表示文字列; // 最初の構築完了。
46 protected override void Onデバイス依存リソースの解放( デバイスリソース dr )
48 FDK.Utilities.解放する( ref this.黒ブラシ );
49 FDK.Utilities.解放する( ref this.白ブラシ );
50 FDK.Utilities.解放する( ref this.ビットマップレンダーターゲット );
51 FDK.Utilities.解放する( ref this.テキストレイアウト );
52 FDK.Utilities.解放する( ref this.テキストフォーマット );
58 float 不透明度0to1 = 1.0f,
61 SharpDX.Matrix? 変換行列3Dpx = null )
64 dr.拡大行列DPXtoPX // スケーリング(1) DPX → PX
65 * SharpDX.Matrix3x2.Scaling( X方向拡大率, Y方向拡大率 ) // スケーリング(2)
66 * SharpDX.Matrix3x2.Translation( 左位置dpx * dr.拡大率DPXtoPX横方向, 上位置dpx * dr.拡大率DPXtoPX縦方向 ); // 平行移動(物理単位)。
68 this.進行描画する( dr, 変換行列2Dpx, 変換行列3Dpx, 不透明度0to1 );
73 SharpDX.Matrix3x2? 変換行列2Dpx = null,
74 SharpDX.Matrix? 変換行列3Dpx = null,
75 float 不透明度0to1 = 1.0f )
77 Debug.Assert( this.活性化している );
79 if( this.表示文字列.Nullまたは空である() )
82 // 表示文字列が変更されているなら、ここで表示ビットマップの再構築を行う。
83 if( false == string.Equals( this.表示文字列, this.前回の表示文字列 ) )
84 this.ビットマップを生成する( dr );
86 if( null == this.ビットマップレンダーターゲット )
89 Utilities.D2DBatchDraw( dr.D2DContext1, () => {
91 dr.D2DContextの設定をリセットする( dr.D2DContext1 );
93 // 変換行列とブレンドモードをD2Dレンダーターゲットに設定する。
94 dr.D2DContext1.Transform = 変換行列2Dpx ?? SharpDX.Matrix3x2.Identity;
95 dr.D2DContext1.PrimitiveBlend = ( 加算合成 ) ? SharpDX.Direct2D1.PrimitiveBlend.Add : SharpDX.Direct2D1.PrimitiveBlend.SourceOver;
97 // D2Dレンダーターゲットに this.Bitmap を描画する。
98 using( var bmp = this.ビットマップレンダーターゲット.Bitmap )
100 dr.D2DContext1.DrawBitmap(
102 destinationRectangle: null,
104 interpolationMode: this.補正モード,
105 sourceRectangle: this.転送元矩形dpx,
106 erspectiveTransformRef: 変換行列3Dpx );
111 protected string 前回の表示文字列 = null;
112 protected SharpDX.Direct2D1.BitmapRenderTarget ビットマップレンダーターゲット = null;
113 protected SharpDX.DirectWrite.TextFormat テキストフォーマット = null;
114 protected SharpDX.DirectWrite.TextLayout テキストレイアウト = null;
115 protected SharpDX.Direct2D1.SolidColorBrush 白ブラシ = null;
116 protected SharpDX.Direct2D1.SolidColorBrush 黒ブラシ = null;
118 protected void ビットマップを生成する( デバイスリソース dr )
120 this.前回の表示文字列 = this.表示文字列;
122 // テキストフォーマット/レイアウトを作成し、表示ビットマップのサイズを計算する。
123 if( null == this.テキストフォーマット )
125 this.テキストフォーマット = new SharpDX.DirectWrite.TextFormat( dr.DWriteFactory, this.フォント名, this.フォントサイズpt ) {
126 TextAlignment = SharpDX.DirectWrite.TextAlignment.Leading,
130 if( ( 0.0f >= this.レイアウトサイズdpx.Width ) || ( 0.0f >= this.レイアウトサイズdpx.Height ) )
131 this.レイアウトサイズdpx = new SharpDX.Size2F( dr.設計画面サイズdpx.Width, dr.設計画面サイズdpx.Height );
133 this.テキストレイアウト?.Dispose();
134 this.テキストレイアウト = new SharpDX.DirectWrite.TextLayout(
138 this.レイアウトサイズdpx.Width,
139 this.レイアウトサイズdpx.Height );
141 var 表示ビットマップのサイズdpx = new SharpDX.Size2F();
145 表示ビットマップのサイズdpx = new SharpDX.Size2F(
146 this.テキストレイアウト.Metrics.WidthIncludingTrailingWhitespace,
147 this.レイアウトサイズdpx.Height ); // レイアウトの最大高
149 上マージン = this.レイアウトサイズdpx.Height - this.テキストレイアウト.Metrics.Height;
153 表示ビットマップのサイズdpx = new SharpDX.Size2F(
154 this.テキストレイアウト.Metrics.WidthIncludingTrailingWhitespace,
155 this.テキストレイアウト.Metrics.Height );
158 // ビットマップレンダーターゲットを生成する。
159 using( var target = dr.D2DContext1.Target ) // Target を get すると COM参照カウンタが増えるので注意。
161 // D2DContext1.Target が設定済みであること。さもなきゃ例外も出さずに落ちる。
162 Debug.Assert( null != target );
164 this.ビットマップレンダーターゲット?.Dispose();
165 this.ビットマップレンダーターゲット = new SharpDX.Direct2D1.BitmapRenderTarget(
167 SharpDX.Direct2D1.CompatibleRenderTargetOptions.None,
171 if( null == this.白ブラシ )
172 this.白ブラシ = new SharpDX.Direct2D1.SolidColorBrush( this.ビットマップレンダーターゲット, SharpDX.Color.LightGray );
173 if( null == this.黒ブラシ )
174 this.黒ブラシ = new SharpDX.Direct2D1.SolidColorBrush( this.ビットマップレンダーターゲット, SharpDX.Color.Black );
176 // ビットマップレンダーターゲットにテキストを描画する。
177 Utilities.D2DBatchDraw( this.ビットマップレンダーターゲット, () => {
179 this.ビットマップレンダーターゲット.Clear( SharpDX.Color.Transparent );
181 this.ビットマップレンダーターゲット.DrawTextLayout( // ドロップシャドウ
182 new SharpDX.Vector2( 1.0f, 上マージン + 1.0f ),
185 SharpDX.Direct2D1.DrawTextOptions.Clip );
187 this.ビットマップレンダーターゲット.DrawTextLayout( // 本体
188 new SharpDX.Vector2( 0.0f, 上マージン ),
191 SharpDX.Direct2D1.DrawTextOptions.Clip );