QRLabelで上付文字を表示するには?


ほたる  2008-01-23 19:36:47  No: 29443

数式をQuickReportで印刷しようとしています。
㎡のような文字は入力できますが、2を3にしたい場合があります。
QRLabelを一文字ずつ並べれば良いかと思っていたのですが、
印刷機によって同じ文字でも文字幅が違うのかズレて、文字が重なったりします。
例えば、QRLabelのCaptionにm^2と入力すれば、㎡と表示できる方法はありますでしょうか?
そのような事ができるコンポーネントも探しています。
宜しくお願いします。


DEKO  2008-01-25 13:55:44  No: 29444

数式であればTMetafileを用意して、そこへ文字を描画し、
TQRImageへ読み込ませるのが一番簡単な方法だと思います。

TMetafileではなくTBitmapでやると、文字をキレイに印刷できないハズです。


ofZ  2008-01-25 17:58:42  No: 29445

上付き、下付き、中央小文字等のできるTQRLabelを継承したコンポ作ったけど、
Canvasに直書きしないと、実現できませんでした。
このこんぽは、ちょっと出しにくいので、グラフとか印刷したいときに
つくった、Metafileを印刷できるQRコンポーネントを暴露します。

QR2で使っているので、QR3以降で使えるか不明。

Scaleは、縮尺(%)で、縦横 50×100のコントロールのとき、
100×200のサイズのCanvasを使うことができる。
大きく書いて、小さく印刷させるためのもの。
細かい図を書くときに使えると思う。
文字は、縮尺を考えて書かないといけないけど、放物線とかが滑らかに描ける。

type
  TQRMetafileImage = class(TQRPrintable)
  private
    FMetaFile: TMetaFile;
    FMetaCanvas: TMetafileCanvas;
    FScale: Word;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  protected
    function GetCanvas: TCanvas;
    procedure SetMetaFile(aMetaFile: TMetaFile);
    procedure SetScale(aScale: Word);
    procedure Paint; override;
    procedure Print(OfsX, OfsY : Integer); override;
    function GetCanvasSize(aIndex: Integer): Integer;
  public
    property Canvas: TCanvas read GetCanvas;
  published
    property Metafile: TMetaFile read FMetaFile write SetMetaFile;
    property Scale: Word read FScale write SetScale default 100;
    property CanvasHeight: Integer index 1 read GetCanvasSize;
    property CanvasWidth : Integer index 2 read GetCanvasSize;
  end;


ofZ  2008-01-25 17:59:05  No: 29446

実装部

constructor TQRMetafileImage.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMetaFile := TMetafile.Create;
  FMetaCanvas := nil;
  Height := 80;
  Width := 80;
  FScale := 100;
end;

destructor TQRMetafileImage.Destroy;
begin
  if FMetaCanvas <> nil then FreeAndNil(FMetaCanvas);
  FMetaFile.Free;
  inherited Destroy;
end;

function TQRMetafileImage.GetCanvas: TCanvas;
begin
  if FMetaCanvas = nil then begin
    FMetaFile.Width  := Round(Width  * FScale / 100);
    FMetaFile.Height := Round(Height * FScale / 100);
    FMetaCanvas := TMetafileCanvas.Create(FMetaFile, 0);
  end;
  Result := FMetaCanvas;
end;

procedure TQRMetafileImage.SetMetaFile(aMetaFile: TMetaFile);
begin
  FMetaFile.Assign(aMetaFile);
end;

procedure TQRMetafileImage.SetScale(aScale: Word);
begin
  if aScale < 10 then aScale := 10;
  if FScale <> aScale then begin
    FScale := aScale;
    if FMetaCanvas = nil then FreeAndNil(FMetaCanvas);
  end;
end;

procedure TQRMetafileImage.Paint;
var
  dest  :TRect;
begin
  if csDesigning in ComponentState then begin
    with inherited Canvas do begin
      Pen.Style := psDash;
      Brush.Style := bsClear;
      Rectangle(0, 0, Width, Height);
    end;
  end;
  if Zoom <> 100 then begin
    dest.Right  := dest.Left + (dest.Right - dest.Left) * Zoom div 100;
    dest.Bottom := dest.Top + (dest.Bottom - dest.Top) * Zoom div 100;
  end;
  inherited Canvas.StretchDraw(dest, FMetaFile);
  Inherited Paint;
end;

procedure TQRMetafileImage.Print(OfsX,OfsY : Integer);
var
  dest :TRect;
  printDC, savedDC: THandle;
begin
  if FMetaCanvas <> nil then FreeAndNil(FMetaCanvas);

  dest := Rect(QRPrinter.XPos(OfsX + Size.Left),
    QRPrinter.YPos(OfsY + Size.Top),
    QRPrinter.XPos(OfsX + Size.Width + Size.Left),
    QRPrinter.YPos(OfsY + Size.Height + Size.Top));

  IntersectClipRect(QRPrinter.Canvas.Handle, dest.Left,
        dest.Top, dest.Right, dest.Bottom);

  printDC := GetDC(QRPrinter.Canvas.Handle);
  savedDC := SaveDC(printDC);

  QRPrinter.Canvas.StretchDraw(dest, FMetaFile);

  RestoreDC(printDC, savedDC);

  SelectClipRgn(QRPrinter.Canvas.Handle, 0);

  Transparent := True;
  inherited Print(OfsX,OfsY);
end;

function TQRMetafileImage.GetCanvasSize(aIndex: Integer): Integer;
begin
  if aIndex = 1 then
    Result := Height * FScale Div 100
  else
    Result := Width  * FScale Div 100;
end;


ほたる  2008-01-25 23:34:40  No: 29447

DEKO様ofZ様とても親切な回答ありがとうございます。
TQRLabelでは難しそうなので諦めます。
Metafileと言うのがあるんですね。初心者ですいません。
本来ここに記述すべきでは無いと思いますが、 
ofZ様のQRコンポーネントをC++Builder6でも同様に活用するにはどのようにすれば良いのでしょうか?
ご存知の方いらっしゃいましたら、宜しくお願いします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加