喫茶XRAYトップページ

[スレッド全体
]

[2134] 印刷プレビュー制御コンポーネントのテキスト表示について返信 削除
2009/2/3 (火) 19:48:06 KSC 〔HomePage
ご無沙汰しております。
最近、やっとサイトのリニューアルを開始したKSCです。
(「Joomla」って、なかなか良いですよ...。)

印刷プレビュー制御コンポーネントのテキスト表示についてですが、
矩形テキスト(TextRect**)で向きが反転したテキスト(TextSpecialの「R=180」)
表示をする方法は、ありませんか?

当然、通常のテキストはTextSpecialメゾットで実現させています。

[2147] Re:印刷プレビュー制御コンポーネントのテキスト表示について返信 削除
2009/2/13 (金) 20:26:48 Mr.XRAY
▼ KSCさん

> 矩形テキスト(TextRect**)で向きが反転したテキスト(TextSpecialの「R=180」)
> 表示をする方法は、ありませんか?


大変遅くなりましたが,こんな方法はどうでしょう.
メタファイルで描画するやり方です.

ところで,印刷プレビューコンポって,プレビューフォーム関係がバグ
だらけなんですね.ハハハッ.

http://mrxray.on.coocan.jp/counter/DLCounterEx/lime.cgi?plPrev001
(665 kB Zipファイル)


[2162] Re2:印刷プレビュー制御コンポーネントのテキスト表示について返信 削除
2009/2/19 (木) 13:02:51 KSCHomePage
▼ Mr.XRAYさん
> ▼ KSCさん
>
> > 矩形テキスト(TextRect**)で向きが反転したテキスト(TextSpecialの「R=180」)
> > 表示をする方法は、ありませんか?
>
> 大変遅くなりましたが,こんな方法はどうでしょう.
> メタファイルで描画するやり方です.
>
> ところで,印刷プレビューコンポって,プレビューフォーム関係がバグ
> だらけなんですね.ハハハッ.
>
> http://mrxray.on.coocan.jp/counter/DLCounterEx/lime.cgi?plPrev001
> (665 kB Zipファイル)


色々と有難うございます。

ソースを参考にしてやってみたいと思います。

[2171] やってみて、質問です?返信 削除
2009/2/26 (木) 19:31:42 KSCHomePage
▼ KSCさん
> ▼ Mr.XRAYさん
> > ▼ KSCさん
> >
> > > 矩形テキスト(TextRect**)で向きが反転したテキスト(TextSpecialの「R=180」)
> > > 表示をする方法は、ありませんか?
> >
> > 大変遅くなりましたが,こんな方法はどうでしょう.
> > メタファイルで描画するやり方です.
> >
> > ところで,印刷プレビューコンポって,プレビューフォーム関係がバグ
> > だらけなんですね.ハハハッ.
> >
> > http://mrxray.on.coocan.jp/counter/DLCounterEx/lime.cgi?plPrev001
> > (665 kB Zipファイル)
>
> 色々と有難うございます。
>
> ソースを参考にしてやってみたいと思います。


「反転文字作成メソッド」をソースを参考して実装してみたのですが、

plPrev1.StretchDrawMetaFileのARectの座標値をちゃんと設定しているにも
関わらず、
 x方向の表示位置 → ○。
 x方向の表示幅  → ×。(狭い)
 y方向の表示位置 → ○。
 y方向の表示高さ → ○。

表示した状態を画像を見て見て下さい。

ACanvasとFPrev.FCanvasの解像度などが違うのでしょうか?

何が原因なのでしょうか?

[2172] Re:やってみて、質問です?返信 削除
2009/2/26 (木) 21:51:39 Mr.XRAY
▼ KSCさん

ありゃ.ハハハッって,人が困っているのに笑ってはいけませんね.
調べてみます.

[2173] Re3:やってみて、質問です?返信 削除
2009/2/27 (金) 12:06:47 KSCHomePage
▼ Mr.XRAYさん
> ▼ KSCさん
>
> ありゃ.ハハハッって,人が困っているのに笑ってはいけませんね.
> 調べてみます.


わっ、わっ、わっ、笑われた〜!
って、私も最初は笑いましたけどね...。

すいませんが、宜しくお願い致します。

それとこれなら
「右90度」とか「左90度」もARectにしている座標値の計算だけで対応
出来そうですね。
ただ、フォントサイズの計算が面倒かも...。

それとこの件とは無関係ですが、
最近「Wink」で動画マニュアル作成にハマッテイマス!

Wink
 http://www.debugmode.com/wink/

[2175] Re3:やってみて、質問です?返信 削除
2009/2/27 (金) 18:55:15 Mr.XRAY
▼ KSCさん

> ただ、フォントサイズの計算が面倒かも...。

そうなんですよね.これが難問です.
そう言えば,前にDelphi-MLだった思うんですが,この反転文字列,
ミラー文字列というらしいです.質問があったような気がします.
質問された方は,確か? 型抜きだったか,とにかくミラー文字が必要な理由を
書いていました.その時は,「なるほどこんな必要性もあるんだ」と
納得した記憶があります.

少し考えながら,Q and A にカキコしながら,また考えたんですが,
もしかしたら,こういうことではないのかと.

1. TextOutで描画した場合
   描画開始始点は(X1,Y1)であるが,終点は文字列の長さとサイズに
   によって違ってくる
2. StretchDrawMetaFileの場合
   (X1,Y1)と(X2,Y2)で設定した範囲内にStretchDrawされている

の違いかも知れません.
以下コードです.KSCさんの画像を参考に,少し修正しました.
でも,こうやって,動作内容の画像を添付していただけると嬉しいです.
理解しやすいです.
作成する方は大変でしょうけど.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  plPrev, StdCtrls, plSetPrinter,ExtCtrls,Printers;

type
  TForm1 = class(TForm)
    Button1: TButton;
    plPrev1: TplPrev;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    procedure InverseString(X1,Y1,X2,Y2: Integer; Text : String; AFont: TFont);
    procedure AdjustFont(Canvas : TCanvas);
    procedure SwapIntValue(var A: Integer; var B: Integer);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

//====================================================================
//  先読み方式のコード
//  ミラー文字列(反転文字列)のテスト1
//
//  TPrinerによる印刷同様,BeginDoc〜EndDocメソッドを使用する.
//  (必要に応じてNewPageメソッドを使用)
//  印刷(描画)コードは本コンポーネントのCanvasを使用する.
//
//  2009年02月27日版
//  前版からの変更
//  ・InverseStringの引数に座標値を追加
//  ・変数の交換(入替え)関数を追加
//  ・描画文字列を変数に格納
//  ・TextOutで描画した文字列を追加
//  ・描画文字列を囲む枠を描画
//====================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
     AFont : TFont;
     X1    : Integer;
     X2    : Integer;
     Y1    : Integer;
     Y2    : Integer;
     L     : Integer;
     TestText : String;
begin
     TestText := 'テストデータ';

     plPrev1.plSetPrinter.Orientation:=poLandscape;
     plPrev1.BeginDoc;
     try
       AFont := TFont.Create;
       try
         X1 := 200;
         X2 := 2200;
         Y1 := 300;
         Y2 := Y1+500;

         //通常の文字の描画
         plPrev1.Canvas.Font.Height := Y2-Y1;
         plPrev1.TextOut(X1,Y1,TestText);
         //文字列の長さを求める
         L := plPrev1.Canvas.TextWidth(TestText);
         //文字列を囲む枠を描画
         plPrev1.Rectangle(X1,X1+L,Y1,Y2);

         //反転文字の描画
         AFont.Assign(plPrev1.Canvas.Font);
         AFont.Color := clGreen;
         plPrev1.Canvas.Pen.Color := clRed;
         Y1 := Y2+400;
         Y2 := Y1+500;
         InverseString(X1,Y1,X2,Y2,TestText,AFont);
         //文字列を囲む枠を描画
         plPrev1.Rectangle(X1,X2,Y1,Y2);
       finally
         FreeAndNil(AFont);
       end;
     finally
       plPrev1.EndDoc;
     end;
     plPrev1.ShowModal;
end;
//=============================================================================
//  左右の反転文字(ミラー文字列)作成メソッド
//  メタファイルに描画して,それを印刷プレビュー制御コンポーネントのCanvasに
//  描画する
//============================================================================
procedure TForm1.InverseString(X1,Y1,X2,Y2: Integer; Text: String; AFont: TFont);
var
    AMetaFile : TMetafile;
    ACanvas   : TMetaFileCanvas;
    AWidth    : Integer;
    AHeight   : Integer;
    ARect     : TRect;
begin
    AMetaFile      := TMetafile.Create;
    AMetaFile.Inch := 0;

    try
      ACanvas:=TMetafileCanvas.Create(AMetaFile,0);
      try
        //メタファイルに必要なサイズを求める
        ACanvas.Font.Assign(AFont);
        AWidth :=ACanvas.TextWidth(Text);
        AHeight:=ACanvas.TextHeight(Text);
        //一旦描画を終了してメタファイルのサイズを設定
        ACanvas.Free;
        AMetaFile.Width :=AWidth;
        AMetaFile.Height:=AHeight;
        //メタファイルCanvasを再生成
        ACanvas  :=TMetafileCanvas.Create(AMetaFile,0);
        ACanvas.Font.Assign(AFont);
        //フォントを正しく設定
        AdjustFont(ACanvas);

        ACanvas.Brush.Style:=bsClear;
        ACanvas.TextOut(0,0,Text);
      finally
        ACanvas.Free;
      end;

      //左右を反転させるために右と左の座標を入替える
      SwapIntValue(X1,X2);
      ARect.Left   := X1;
      ARect.Right  := X2;
      ARect.Top    := Y1;
      ARect.Bottom := Y2;
      plPrev1.StretchDrawMetaFile(ARect,AMetaFile);
    finally
      AMetaFile.Free;
    end;
end;
//=============================================================================
//  フォントの縦横サイズが正確に取得できない現象の回避関数
//  フォント幅が0の時に文字幅を設定する
//  中村拓男著「Delphi Graphic Secrets」P141のコードそのまま
//============================================================================
procedure TForm1.AdjustFont(Canvas: TCanvas);
var
    tm : TTextMetric;
    lf : TLogFont;
begin
    GetObject(Canvas.Font.Handle, SizeOf(lf), @lf);
    if lf.lfWidth=0 then begin
      GetTextMetrics(Canvas.Handle, tm);
      lf.lfWidth := -lf.lfHeight * tm.tmAveCharWidth div tm.tmHeight;
      Canvas.Font.Handle := CreateFontIndirect(lf);
    end;
end;
//=============================================================================
//  変数の交換(入替え)関数
//============================================================================
procedure TForm1.SwapIntValue(var A: Integer; var B: Integer);
var
    Temp : Integer;
begin
    Temp := A;
    A := B;
    B := Temp;
end;

end.

EXEファイルのダウンロードの内容も変更しておきました.
http://mrxray.on.coocan.jp/counter/DLCounterEx/lime.cgi?plPrev001


[2179] Re4:やってみて、質問です?返信 削除
2009/3/1 (日) 18:24:42 KSC 〔HomePage
▼ Mr.XRAYさん
> 少し考えながら,Q and A にカキコしながら,また考えたんですが,
> もしかしたら,こういうことではないのかと.
>
> 1. TextOutで描画した場合
>    描画開始始点は(X1,Y1)であるが,終点は文字列の長さとサイズに
>    によって違ってくる
> 2. StretchDrawMetaFileの場合
>    (X1,Y1)と(X2,Y2)で設定した範囲内にStretchDrawされている
>
> の違いかも知れません.


Mr.XRAYさんのソースより
>          X1 := 200;
>          X2 := 2200;(A)
>          Y1 := 300;
>          Y2 := Y1+500;
>
> ・
> ・
> ・
>          //文字列の長さを求める
>          L := plPrev1.Canvas.TextWidth(TestText);
>          //文字列を囲む枠を描画
>          plPrev1.Rectangle(X1,X1+L,Y1,Y2);(B)
>
> ・
> ・
> ・
> ・

この時、
 InverseString(X1,Y1,X2,Y2,TestText,AFont);
「X2」と「X1+L」が同一値なら表示は同一幅にならなければ理屈が合わないのですが?

前回、イメージ画像を送った際も上記で言う「X2」と「X1+L」は同一値になるように
計算して描画してもイメージ画像ような結果でした。

なぜなのでしょうか?


[2183] Re5:やってみて、質問です?(追記)返信 削除
2009/3/1 (日) 23:21:03 KSCHomePage
▼ Mr.XRAYさん
> ・
> ・
> ・
> ・
> この時、
>  InverseString(X1,Y1,X2,Y2,TestText,AFont);
> 「X2」と「X1+L」が同一値なら表示は同一幅にならなければ理屈が合わないのですが?
>
> 前回、イメージ画像を送った際も上記で言う「X2」と「X1+L」は同一値になるように
> 計算して描画してもイメージ画像ような結果でした。
>
> なぜなのでしょうか?


アプリ用のコンポにデバックモードを追加し、デバックモード時に矩形テキストを表示した際の
・「ARect」を二点鎖線の直線表示。
・左上と右下の座標値表示。
させるようにしました。

そのついでに上記の「X2」と「X1+L」が同一値なら...イメージできる画像を添付します。

何かの参考になりますか?

[2185] ミラー文字テスト返信 削除
2009/3/1 (日) 23:34:29 Mr.XRAY
▼ KSCさん
[2183]の添付図は,左右と上下のミラーなんですね.
で,InverseStringの引数のY1とY2を入れ換えてやってみました.

  InverseString(X1,Y1,X2,Y2,TestText,AFont);
        ↓
  InverseString(X1,Y2,X2,Y1,TestText,AFont);

図のようになりました.
私,何か勘違いしているのな?


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82