| history | TOP |
2005/12/28:作成
| overview | TOP |
「フォントのアウトライン化」ってどういう意味か説明できませんが、Illustratorの「アウトライン化」のイメージです。
| コード | TOP |
無駄にクラスになってるんですが、GetMemory() と FreeMemory() がメインです。それ以外はおまけ。
//=============================================================================
// TFontOutLine
//=============================================================================
//-----------------------------------------------------------------------------
// これやっとかないと array[0..0] of に [1] でアクセスできない
{$RANGECHECKS OFF}
//-----------------------------------------------------------------------------
type
TPointsArray = array[0..0] of TPoint;
PPointsArray = ^TPointsArray;
TTypesArray = array[0..0] of Byte;
PTypesArray = ^TTypesArray;
//-----------------------------------------------------------------------------
type
TFontOutLine = class
private
FBitmap: TBitmap;
private
FText: string;
FRect: TRect;
procedure SetText(const Value: string);
private
FPtCount: Integer;
FPoints: PPointsArray;
FTypes: PTypesArray;
procedure GetMemory();
procedure FreeMemory();
public
constructor Create();
destructor Destroy(); override;
public
procedure SetCanvas(Source: TCanvas);
procedure SetFont(Source: TFont);
procedure SetBrush(Source: TBrush);
procedure SetPen(Source: TPen);
property Text: string read FText write SetText;
property Rect: TRect read FRect;
property PtCount: Integer read FPtCount;
property Points: PPointsArray read FPoints;
property Types: PTypesArray read FTypes;
end;
//-----------------------------------------------------------------------------
// コンストラクタ
constructor TFontOutLine.Create();
begin
inherited;
FText := '';
FPtCount := -1;
FPoints := nil;
FTypes := nil;
FRect := Classes.Rect(0, 0, 0, 0);
FBitmap := TBitmap.Create();
FBitmap.PixelFormat := pf24bit;
SetText(FText);
end;
//-----------------------------------------------------------------------------
// デストラクタ
destructor TFontOutLine.Destroy();
begin
FBitmap.Free;
FreeMemory();
inherited;
end;
//-----------------------------------------------------------------------------
// メモリ確保
procedure TFontOutLine.GetMemory();
begin
//-----------------------------------------------------
// パスを定義する点の個数取得
FPtCount := GetPath(FBitmap.Canvas.Handle, FPoints^, FTypes^, 0);
//-----------------------------------------------------
// 個数分のメモリ確保
GetMem(FPoints, SizeOf(TPoint) * FPtCount);
GetMem(FTypes, SizeOf(Byte) * FPtCount);
//-----------------------------------------------------
// 点を取得
GetPath(FBitmap.Canvas.Handle, FPoints^, FTypes^, FPtCount);
end;
//-----------------------------------------------------------------------------
// メモリ開放
procedure TFontOutLine.FreeMemory();
begin
if (FPtCount > 0) then
begin
FreeMem(FPoints);
FreeMem(FTypes);
end;
end;
//-----------------------------------------------------------------------------
// 内部キャンバスにフォントなどのプロパティをコピー
procedure TFontOutLine.SetCanvas(Source: TCanvas);
begin
SetFont(Source.Font);
SetBrush(Source.Brush);
SetPen(Source.Pen);
end;
//-----------------------------------------------------------------------------
// 内部キャンバスにフォントのプロパティをコピー
procedure TFontOutLine.SetFont(Source: TFont);
begin
FBitmap.Canvas.Font.Assign(Source);
SetText(FText);
end;
//-----------------------------------------------------------------------------
// 内部キャンバスにブラシのプロパティをコピー
procedure TFontOutLine.SetBrush(Source: TBrush);
begin
FBitmap.Canvas.Brush.Assign(Source);
SetText(FText);
end;
//-----------------------------------------------------------------------------
// 内部キャンバスにペンのプロパティをコピー
procedure TFontOutLine.SetPen(Source: TPen);
begin
FBitmap.Canvas.Pen.Assign(Source);
SetText(FText);
end;
//-----------------------------------------------------------------------------
// テキストを受け取ってアウトライン情報を作成
procedure TFontOutLine.SetText(const Value: string);
var
DtFormat: Cardinal;
DtParams: TDrawTextParams;
var
OldMode: Integer;
begin
FText := Value;
//-----------------------------------------------------
// パラメータ準備
FillChar(DtParams, SizeOf(DtParams), 0);
DtParams.cbSize := SizeOf(DtParams);
DtFormat := DT_LEFT or DT_TOP or DT_SINGLELINE or DT_CALCRECT;
FRect := Classes.Rect(0, 0, 0, 0);
//-----------------------------------------------------
// 描画領域決定
DrawTextEx(FBitmap.Canvas.Handle, PChar(FText), -1, FRect, DtFormat, @DtParams);
FBitmap.Width := FRect.Right - FRect.Left;
FBitmap.Height := FRect.Bottom - FRect.Top;
// 改めてパラメータ設定
DtFormat := DT_LEFT or DT_TOP or DT_SINGLELINE;
//-----------------------------------------------------
// パス作成
BeginPath(FBitmap.Canvas.Handle);
OldMode := SetBkMode(FBitmap.Canvas.Handle, TRANSPARENT);
DrawTextEx(FBitmap.Canvas.Handle, PChar(FText), -1, FRect, DtFormat, @DtParams);
SetBkMode(FBitmap.Canvas.Handle, OldMode);
EndPath(FBitmap.Canvas.Handle);
//-----------------------------------------------------
// アウトライン情報取得
FreeMemory();
GetMemory();
end;
| 実行結果・ダウンロード | TOP |
GetPath ってぇ API がキャンバスに書かれたテキストを元に、始点・終点・通過点・ベジェ曲線用の制御点にバキバキと分割してくれて、戻ってきた点の配列とそれぞれの点の種類を、そのまま PolyDraw っていう API に渡してやると、ベジェ曲線の処理も含めて綺麗に書き出してくれます。
下の図は、PolyDraw が書いたテキストに、赤色で始点・終点・通過点を、青色でベジェ曲線用の制御点を重ね書きしただけです。なにかに使えそうな予感がするんですが、何に使うんだろう...
20051228FontOutlineTest.zip(189,459bytes)
| EOF | TOP |