AFsoft WebSite(エーエフソフト・ウェブサイト)
 

オペレーティング・システムについて

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
Delphi2010 Direct2D(9) 2010/12/15

今回ももう少し、Direct2Dについて見ていきます。
今回は文字の描画について見ていきます。WindowsGDIでの文字の描画は TextOutメソッドを利用しました。文字を回転させて描画させたい場合には LOGFONT型の文字情報を操作して行ったりしていました(※旧Borland社のホームページQ&A等で手法は記載されていました)。Direct2Dでも、これまで同様、GDIなTextOutメソッドはそのまま利用する事が出来ます。Fontプロパティ(TDirect2DFont型)も存在します。
まずは、ボタン Button13(Captionプロパティは「B13」)を追加して簡単なテスト描画をしてみます。
procedure TForm1.Button13Click(Sender: TObject);
begin
 if not(D2DCanvasFlag) then exit;
 with D2DCanvas do begin
  BeginDraw;
  RenderTarget.Clear (D2D1ColorF(clWhite)); // 背景:白色
  
  Font.Color := clBlue ;   // 文字色
  Font.Name := 'MS 明朝';  // フォント名
  Font.Size := 20 ;      // サイズをポイント指定
  TextOut(20,40,'これはテストです');
  
  EndDraw;
 end;
end;
これを保存・コンパイル(再構築)・実行してみます。

 
FontプロパティのBrushプロパティは、ヘルプには
テキストを描画するときに使用するブラシを示します。Brush は、テキストの背景を描画するために使われます。
とありますが、それは WindowsGDIの時の説明であって、Direct2Dでは異なります(この説明は誤りです)。Colorプロパティ同様、文字そのものをブラシで描画する、という事です。つまり、これまで同様の半透明やグラデーションが出来るという事です。
  ・・・
  Font.Brush.Handle := CreateBrush(clRed);
  Font.Name := 'MS 明朝';
  Font.Size := 10 ;
  TextOut(10,10,'これはテストです');
  
  Font.Brush.Handle := CreateBrush(clBlue);
  Font.Brush.Handle.SetOpacity(0.5);
  Font.Name := 'MS ゴシック';
  Font.Style := [fsBold] ;
  Font.Size := 14 ;
  TextOut(20,15,'これはテストです');
  
  Font.Brush.Handle := CreateBrush([clRed,clBlue],D2D1PointF(50,0),D2D1PointF(100,0));
  Font.Name := 'メイリオ';
  Font.Style := [fsItalic,fsUnderline] ;
  Font.Size := 18 ;
  TextOut(30,30,'これはテストです');
  
  EndDraw;
  ・・・
これを実行すると・・・

というように、なぜかメイリオに斜体指定が無効になっていますがそれは置いといて、文字描画で前に描画したものを文字背景で消してしまっています。これを消したくない場合は、「Font.Brush.Style := bsClear」ではなく、「Brush.Style := bsClear」を行います。
  ・・・
  Brush.Style := bsClear ;
  
  Font.Brush.Handle := CreateBrush(clRed);
  Font.Name := 'MS 明朝';
  Font.Size := 10 ;
  TextOut(10,10,'これはテストです');
  ・・・
とすれば・・・

となって、文字背景を指定する事が出来ます。という事は、
  ・・・
  Brush.COlor := clGray ;
  Brush.Style := bsSolid ;
  
  Font.Brush.Handle := CreateBrush(clRed);
  Font.Name := 'MS 明朝';
  Font.Size := 10 ;
  TextOut(10,10,'これはテストです');
  ・・・
とすれば・・・

 
  ・・・
  Brush.Handle := CreateBrush(clYellow);
  Brush.Handle.SetOpacity(0.5);
  
  Font.Brush.Handle := CreateBrush(clRed);
  Font.Name := 'MS 明朝';
  Font.Size := 10 ;
  TextOut(10,10,'これはテストです');
  ・・・
とすると・・・

 
  ・・・
  Brush.Handle := CreateBrush([clWhite,clAqua],D2D1PointF(0,0),D2D1PointF(300,0));
  
  Font.Brush.Handle := CreateBrush(clRed);
  Font.Name := 'MS 明朝';
  Font.Size := 10 ;
  TextOut(10,10,'これはテストです');
  ・・・
のようにすれば・・・

のようになる、という事です。
 
 
次に、文字を回転して描画したい場合、従来のGDIではLOGFONT型の lfOrientationフィールドを°の10倍単位(指定は 0.1°単位で可能)で行いましたが、Direct2Dではそれに相当する機能が Fontプロパティ内の Orientationプロパティとしてある、とヘルプには記載されています。
Orientation プロパティは、テキストの方向を指定します。
Orientation プロパティを使用して、テキスト文字の方向を指定します。これは、文字のベースラインとデバイスのX軸との間の角度を、10度単位で表したものです。これは、Windowsのフォント属性を定義するGDI LOGFONT 構造体の lfOrientation フィールドと同様です。
ですので
  ・・・
  Font.Brush.Handle := CreateBrush(clBlack);
  Font.Name := 'MS ゴシック';
  Font.Style := [] ;
  Font.Size := 20 ;
  Font.Orientation := 300 ;
  TextOut(30,80,'これはテストです');
  
  EndDraw;
  ・・・
としてみました。実行すると・・・

という事で・・・全く効果無し、ですね。フォントを変更しても、指定の順番を変えても同様です。ヘルプが実際と合致していないと、ちょっと困ってしまいます。
 
それでは前回のように、RenderTargetプロパティ内のGetTransformメソッドを利用してみます。
procedure TForm1.Button13Click(Sender: TObject);
var
 t : D2D_MATRIX_3X2_F ;
begin
  ・・・
  t._11 := cos(15/180*Pi) ;
  t._12 := sin(15/180*Pi) ;
  t._21 :=-sin(15/180*Pi) ;
  t._22 := cos(15/180*Pi) ;
  t._31 := 0.0 ;
  t._32 := 0.0 ;
  RenderTarget.SetTransform(t);
  
  Font.Brush.Handle := CreateBrush(clBlack);
  Font.Name := 'MS ゴシック';
  Font.Style := [] ;
  Font.Size := 20 ;
  TextOut(30,80,'これはテストです');
  
  EndDraw;
  ・・・
のようにしてみますと、

となります。回転の中心が原点(0,0)=左上ですので、文字開始位置はずれてしまいますが、この文字開始位置(文字の左上点)を上記のように(30,80)にしたい場合には
  ・・・
  t._11 := cos(15/180*Pi) ;
  t._12 := sin(15/180*Pi) ;
  t._21 :=-sin(15/180*Pi) ;
  t._22 := cos(15/180*Pi) ;
  t._31 := 30.0 ;
  t._32 := 80.0 ;
  RenderTarget.SetTransform(t);
  
  Font.Brush.Handle := CreateBrush(clBlack);
  Font.Name := 'MS ゴシック';
  Font.Style := [] ;
  Font.Size := 20 ;
  TextOut(0,0,'これはテストです');
  
  EndDraw;
  ・・・
とすれば

のようになります。
 
 
次に、アンチエイリアスについて描画の確認をしておきます。描画速度が必要な場合には、アンチエイリアスをしない状態にする事も有り得ますので。
  ・・・
  Font.Brush.Handle := CreateBrush(clBlack);
  Font.Name := 'MS ゴシック';
  Font.Style := [] ;
  Font.Size := 20 ;
  RenderTarget.SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_DEFAULT);
  TextOut(0,0,'これはテストです');
  
  RenderTarget.SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);
  TextOut(0,22,'これはテストです');
  
  RenderTarget.SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
  TextOut(0,44,'これはテストです');
  
  RenderTarget.SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
  TextOut(0,66,'これはテストです');
  
  EndDraw;
  ・・・
これを実行すると

となります。
アンチエイリアス無し(D2D1_TEXT_ANTIALIAS_MODE_ALIASED)の指定の場合は、明らかに他のものとは異なりますが、これを拡大すると、

というように、クリアタイプとグレースケールは若干違っている感じはあります(グレースケールはグレー色で処理されていますが、クリアタイプの場合は赤っぽい色や青っぽい色でも処理されています)。デフォルトの場合は、クリアタイプに近いですが、これは、フォントによって、クリアタイプかグレースケールかどちらがデフォルトか?という事なのかもしれません。
 
速度比較については・・・まぁいいでしょう。これまで同様、アンチエイリアス無しの方が有りに比較して高速になるのは想像できますし、それ以前に、綺麗さを取るのか、描画速度を取るのか、という方が問題になるであろうと思われますので。
 
 
また、DirectWriteという機能も追加されているとの事です。
ボタン Button14(Captionプロパティは「B14」)を追加して、「Delphi2010eHandbook.pdf」のテスト描画をしてみます。
procedure TForm1.Button14Click(Sender: TObject);
var
 idwtFormat: IDWriteTextFormat;
 //idwtLayout: IDWriteTextLayout;
 //matrix: DWRITE_MATRIX;
 strText: string ;
begin
 if not(D2DCanvasFlag) then exit;
 DWriteFactory.CreateTextFormat('Arial', nil,
  DWRITE_FONT_WEIGHT_LIGHT, DWRITE_FONT_STYLE_NORMAL,
  DWRITE_FONT_STRETCH_SEMI_CONDENSED,
  35, 'en-US', idwtFormat);
 
 with D2DCanvas do begin
  BeginDraw;
  RenderTarget.Clear (D2D1ColorF(clWhite)); // 背景:白色
  
  Brush.Handle := CreateBrush(clBlue);
  strText := 'Hello, Delphi';
  RenderTarget.DrawText(PChar(strText),
   Length(strText), idwtFormat,
   Rect(10,10, 500,200), Brush.Handle);
  
  Brush.Handle := CreateBrush(clGreen);
  strText := 'This is a DirectWrite oblique example';
  DWriteFactory.CreateTextFormat('Arial', nil,
   DWRITE_FONT_WEIGHT_EXTRA_BOLD, DWRITE_FONT_STYLE_OBLIQUE,
   DWRITE_FONT_STRETCH_EXTRA_EXPANDED, 35, 'en-US', idwtFormat);
  idwtFormat.SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
  idwtFormat.SetLineSpacing(
   DWRITE_LINE_SPACING_METHOD_UNIFORM, 28, 0);
  RenderTarget.DrawText (PChar(strText),
   Length(strText), idwtFormat,
   Rect(0,110, 250,200), Brush.Handle);
  
  EndDraw;
 end;
end;
「idwtLayout: IDWriteTextLayout;」と「matrix: DWRITE_MATRIX;」は未使用のようなのでコメント化しています。DWriteFactory関数は、TDirect2DCanvasのメソッドではありません(2回目は with内で書いてますが withの外側でも構いません)。RenderTargetプロパティ内のDrawTextメソッドを利用すれば、より細かい指定での文字描画が出来るようです。例によってヘルプに詳細説明がありませんのでよく分かりませんから、テキトウに類推するしかありませんが。。。このテストは都合上画面を小さくしていますので、2度目の文字描画のRect内の数値も小さくしています。取り合えずこれを保存・コンパイル(再構築)・実行してみます。

よく分かりませんが、サンプルがあれば取り合えずそのままプログラム入力してみて、その結果を見ながら類推することが出来ます。ですのでサンプルプログラムは、どんな簡単なものであっても(逆に大きすぎると正直しんどい)、あれば役に立ちますし、参考になります。しかし、Delphiのヘルプに記載されるサンプルは昔のバージョンから非常に少ないです。フォントを指定して、文字を描かせる、そしてその引数は?という事で調べていけばおそらく分かるのではないかと思います。単一の文字列の描画というよりは、文書の描画用という感覚でしょうか?
 
 
という訳で、このくらいにしておきます。
 
これで Direct2Dの話は終わりとします。
 
データベースやネット関連、Indy関連などはスルーしましたが、これでおおよそ、まぁ外観的な部分ではありますが、Delphi2010、ざっと見渡しましたでしょうか? という訳で、今回で、「Delphi2010触ってみたよ」話は<完>とします。ここまで長々と(約4ヶ月!)お付き合い下さいました皆様、御覧頂きありがとうございました。何かのお役に立てれば、と思います。
 
これらを通じて、WindowsVista/7 の特色・有効性、或いは、Windows9x/2000/Xpとの互換性、どちらを取るのか? どういうアプリケーションを作るのか?という所までに至るのか、などなど。ただ、少なくとも、Delphi2010を触っていなかった頃と比較すると、WindowsVista/7もなかなか面白いなぁ、と思えるようにはなりました。特に、マルチタッチ・ジェスチャ・Direct2Dは、色々と面白そうな事が出来そうだし、結構有効ではなかろうか?とも思いました。
 
そして、ヘルプや書籍等がもっと充実してくれればなぁ等と、改めて思ったりして。
 
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
>Delphi入門編
>Delphi2010
▲2010/12/14
 2010/12/15
 <完>
 
シェアウェア
Script!World
データベース
 
お問い合わせ
本サイトはリンクフリーです
リンクバナー
(C)Copyright 1999-2015. By AFsoft All Rights Reserved.