線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4775
推到 Plurk!
推到 Facebook!

如何將 UniCode 的字,在圖形中用 Canvas 產生 及 字形相關問題 ?

答題得分者是:shunchia63
小蚊子
中階會員


發表:55
回覆:267
積分:94
註冊:2002-06-08

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-10-18 15:06:42 IP:140.135.xxx.xxx 訂閱
如何將 UniCode 的字,在圖形中用 Canvas 產生 及 字形相關問題 ?
字串 : (wstr)南路6段7巷8號九樓B室 張国煊
(最後二字是 BIG5 沒有的)
問題
1. 用 image 的元件 或 TNT image 的元件, 不論 string / Widestring, 均無法 Canvas 相對的圖
2. 但將此字串貼於 Photoimpact 中,它會自動選用 simsun(GB312) 字形集,顯示均正常
若在 Photoimpact 中,改用選其它字形集(例如:新細明體 ),字串就會變成亂碼
可是同 一字串,貼上 WORD 中,選用新細明體 , 不會亂碼,且放大縮小均正常, 原因為何 ??
3. image (TNTimage) 的屬性 Canvas.Font.height 及Canvas.Font.size 的意義為何?
以下是將 size 的值改變, 但抓出來的 height 有自己的值,height 的正負值有何作用 , 不解 ?
軟體設定 size = 12 height = 0 取出 size=12 , height = -16
軟體設定size = 14 height = 0 取出 size=14 , height = -19
軟體設定size = 20 heigh t= 0 取出 size=20 , height = -27
謝謝您 !
附上測試程式 exe
(開發環境 : WIN XP delphi 2007 TNT 元件)

編輯記錄
小蚊子 重新編輯於 2007-10-18 15:07:21, 註解 無‧
小蚊子 重新編輯於 2007-10-18 15:25:44, 註解 無‧
小蚊子 重新編輯於 2007-10-18 15:27:46, 註解 附上 含 source 及 可執行的 exe ‧
小蚊子 重新編輯於 2007-10-20 17:11:24, 註解 實作範例‧
小蚊子 重新編輯於 2007-10-20 17:13:06, 註解 重傳 實作範例 !!‧
shunchia63
高階會員


發表:26
回覆:141
積分:198
註冊:2007-05-22

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-10-18 23:00:14 IP:61.64.xxx.xxx 訂閱
Hi :
你可以參考 unit TntGraphics WideCanvasTextOut 也許可以輸出


TTntImage = class(TImage{TNT-ALLOW TImage}) SO 應該無法有UniCode功能






{*****************************************************************************}
{ }
{ Tnt Delphi Unicode Controls }
{ http://www.tntware.com/delphicontrols/unicode/ }
{ Version: 2.2.1 }
{ }
{ Copyright (c) 2002-2005, Troy Wolbrink (troy.wolbrink@tntware.com) }
{ }
{*****************************************************************************}
unit TntGraphics;
{$INCLUDE TntCompilers.inc}
interface
uses
Classes, Graphics, Windows;
{TNT-WARN TextRect}
procedure WideCanvasTextRect(Canvas: TCanvas; Rect: TRect; X, Y: Integer; const Text: WideString);
{TNT-WARN TextOut}
procedure WideCanvasTextOut(Canvas: TCanvas; X, Y: Integer; const Text: WideString);
{TNT-WARN TextExtent}
function WideCanvasTextExtent(Canvas: TCanvas; const Text: WideString): TSize;
function WideDCTextExtent(hDC: THandle; const Text: WideString): TSize;
{TNT-WARN TextWidth}
function WideCanvasTextWidth(Canvas: TCanvas; const Text: WideString): Integer;
{TNT-WARN TextHeight}
function WideCanvasTextHeight(Canvas: TCanvas; const Text: WideString): Integer;
type
{TNT-WARN TPicture}
TTntPicture = class(TPicture{TNT-ALLOW TPicture})
public
procedure LoadFromFile(const Filename: WideString);
procedure SaveToFile(const Filename: WideString);
end;
implementation
uses
SysUtils, TntClasses, TntSysUtils;
type
TAccessCanvas = class(TCanvas);
procedure WideCanvasTextRect(Canvas: TCanvas; Rect: TRect; X, Y: Integer; const Text: WideString);
var
Options: Longint;
begin
with TAccessCanvas(Canvas) do begin
Changing;
RequiredState([csHandleValid, csFontValid, csBrushValid]);
Options := ETO_CLIPPED or TextFlags;
if Brush.Style <> bsClear then
Options := Options or ETO_OPAQUE;
if ((TextFlags and ETO_RTLREADING) <> 0) and
(CanvasOrientation = coRightToLeft) then Inc(X, WideCanvasTextWidth(Canvas, Text) 1);
Windows.ExtTextOutW(Handle, X, Y, Options, @Rect, PWideChar(Text),
Length(Text), nil);
Changed;
end;
end;
procedure WideCanvasTextOut(Canvas: TCanvas; X, Y: Integer; const Text: WideString);
begin
with TAccessCanvas(Canvas) do begin
Changing;
RequiredState([csHandleValid, csFontValid, csBrushValid]);
if CanvasOrientation = coRightToLeft then Inc(X, WideCanvasTextWidth(Canvas, Text) 1);
Windows.ExtTextOutW(Handle, X, Y, TextFlags, nil, PWideChar(Text),
Length(Text), nil);
MoveTo(X WideCanvasTextWidth(Canvas, Text), Y);
Changed;
end;
end;
function WideDCTextExtent(hDC: THandle; const Text: WideString): TSize;
begin
Result.cx := 0;
Result.cy := 0;
Windows.GetTextExtentPoint32W(hDC, PWideChar(Text), Length(Text), Result);
end;
function WideCanvasTextExtent(Canvas: TCanvas; const Text: WideString): TSize;
begin
with TAccessCanvas(Canvas) do begin
RequiredState([csHandleValid, csFontValid]);
Result := WideDCTextExtent(Handle, Text);
end;
end;
function WideCanvasTextWidth(Canvas: TCanvas; const Text: WideString): Integer;
begin
Result := WideCanvasTextExtent(Canvas, Text).cX;
end;
function WideCanvasTextHeight(Canvas: TCanvas; const Text: WideString): Integer;
begin
Result := WideCanvasTextExtent(Canvas, Text).cY;
end;
{ TTntPicture }
procedure TTntPicture.LoadFromFile(const Filename: WideString);
var
ShortName: WideString;
begin
ShortName := WideExtractShortPathName(Filename);
if WideSameText(WideExtractFileExt(FileName), '.jpeg') // the short name ends with ".JPE"!
or (ShortName = '') then // GetShortPathName failed
inherited LoadFromFile(FileName)
else
inherited LoadFromFile(WideExtractShortPathName(Filename));
end;
procedure TTntPicture.SaveToFile(const Filename: WideString);
var
TempFile: WideString;
begin
if Graphic <> nil then begin
// create to temp file (ansi safe file name)
repeat
TempFile := WideExtractFilePath(Filename) IntToStr(Random(MaxInt)) WideExtractFileExt(Filename);
until not WideFileExists(TempFile);
CloseHandle(WideFileCreate(TempFile)); // make it a real file so that it has a temp
try
// save
Graphic.SaveToFile(WideExtractShortPathName(TempFile));
// rename
WideDeleteFile(Filename);
if not WideRenameFile(TempFile, FileName) then
RaiseLastOSError;
finally
WideDeleteFile(TempFile);
end;
end;
end;
end.
小蚊子
中階會員


發表:55
回覆:267
積分:94
註冊:2002-06-08

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-10-19 13:54:33 IP:125.232.xxx.xxx 訂閱
再次 謝謝  Shunchia63 網友提供的方法,我剛實作一個範例
以下用初學者的角色,提供幾個重點供大家參考
1. UNICODE 字串,要用 widestring 來定義
2. 不論是 IMAGE 或 TNTIMAGE 元件,
均可以透過 Shunchia63 網友的方法,產生正確的字形圖片
3. 字形集似乎不影響 Unicode 取字的結果 (不缺字)
4. 記得 要 uses TntGraphics ( 要安裝 TNT 元件)
謝謝您

範例 請至作品分享區 下載
編輯記錄
小蚊子 重新編輯於 2007-10-20 17:10:05, 註解 測試完成 !!‧
小蚊子 重新編輯於 2007-10-20 17:25:50, 註解 無‧
系統時間:2017-11-20 17:15:56
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!