我已经在Delphi中编写了一个Windows程序,它使用GetCharWidth和Em-Square非常精确地放置和包装文本到屏幕和打印机。这与ANSI文本很好地协作,你只需要检索和计算255个字符的宽度,但是当你使用65535个字符的Unicode时,它太慢了。由于必须创建两个宽度数组,一个用于正常,一个用于粗体,问题变得更糟。所见即所得编码
//Setup a reference canvas for measuring purposes
RefDC := CreateCompatibleDC (FCanvas.Handle) ;
DPI := GetDeviceCaps (RefDC , LOGPIXELSY) ;
//find EmSquare
GetOutlineTextMetrics (RefDC , sizeof(otm) , @otm[0]) ;
EmSq := otm[0].otmEmSquare ;
//calc NORMAL char sizes
GetObject (FCanvas.Font.Handle , SizeOf (lf) , @lf) ;
lf.lfHeight := -EmSq ;
lf.lfWidth := 0 ;
lf.lfWeight := FW_NORMAL ;
hf := CreateFontIndirect (lf) ;
hold := SelectObject (RefDC , hf) ;
GetCharWidth (RefDC , 0 , $FFFF , nCharWidth) ;
for a := 0 to $FFFF do
fCharWidth[a] := nCharWidth[a]* PixelSize/EmSq ;
SelectObject (RefDC , hold) ;
DeleteObject (hf) ;
//calculate line height
PixelSize := abs (fCanvas.Font.Size * DPI/72) ;
GetOutlineTextMetrics (RefDC , sizeof(otm) , @otm[0]) ;
LineHt := round ((otm[0].otmTextMetrics.tmHeight +
otm[0].otmTextMetrics.tmExternalLeading) *
PixelSize/EmSq) ;
//calculate Bold char sizes
lf.lfWeight := FW_BOLD ;
hf := CreateFontIndirect (lf) ;
hold := SelectObject (RefDC , hf) ;
GetCharWidth (RefDC , 0 , $FFFF , nCharWidth) ;
for a := 0 to $FFFF do
fBoldWidth[a] := nCharWidth[a] * PixelSize/EmSq ;
SelectObject (RefDC , hold) ;
DeleteObject (hf) ;
DeleteDC (RefDC) ;`
Unicode没有65,535个字符。它通过分配码点来定义(撰写本文时)约107,000个字符。你可能在谈论UTF-16,这是一种以16位单位明确表示所有这些代码点的方法(http://en.wikipedia.org/wiki/UTF-16)。它是一种可变长度编码,因为某些字符可能占用多个16位单元,但其设计使基本多语言平面中的所有代码点都“适合”在一个16位单元中。 – 2010-08-16 21:29:34
那么你的问题是什么? – 2010-08-16 21:40:39
我需要更快的方式来做到这一点。必须有其他所见即所得的策略可以更有效地处理UNICODE。 – Mitch 2010-08-16 21:46:50