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 |