GDI 繪製自定義行距的文字(續)

2022-01-28 17:23:43 字數 3240 閱讀 4028

在上文「gdi+繪製自定義行距的文字的三種方法。」中,介紹了繪製自定義行間距的多行文字的方法。

在第三種的方法中,啟用了gdipdrawdriverstring這個函式。這個函式可以定義每個字元的位置,這是它的優點。不過它的缺點也比較明顯。一是它定義的字元位置是以字元的左下角為基準的,和一般的概念是兩樣的。二是他對font要求比較高,據說如果採用的是英文本型,在顯示中文時會顯示成乙個個小方塊。

再翻翻gdip中的其他函式,發現graphics的drawstring的方法都是呼叫gdipdrawstring這個函式。如果我們能跳過graphics直接呼叫gdipdrawstring這個函式,是不是能提高效率呢?我們試試看。

gdiplus.dll", charset:=charset.unicode, setlasterror:=true, exactspelling:=true)> _

friend shared function gdipdrawstring(byval graphics as intptr, _

byval textstring as string, _

byval length as integer, _

byval font as intptr, _

byref layoutrect as gprectf, _

byval stringformat as intptr, _

byval brush as intptr) as integer

end function

_friend structure gprectf

friend x as single

friend y as single

friend width as single

friend height as single

friend sub new(byval x as single, byval y as single, byval width as single, byval height as single)

me.x = x

me.y = y

me.width = width

me.height = height

end sub

friend sub new(byval rect as rectanglef)

me.x = rect.x

me.y = rect.y

me.width = rect.width

me.height = rect.height

end sub

friend readonly property sizef() as sizef

getreturn new sizef(me.width, me.height)

end get

end property

friend function torectanglef() as rectanglef

return new rectanglef(me.x, me.y, me.width, me.height)

end function

end structure

public sub draw4(byval text as string)

clear()

dim i as integer, j as integer, ts() as string

j = int(text.length / 52)

redim ts(j - 1)

for i = 0 to j - 1

ts(i) = text.substring(i * 52, 52)

next

if text.length - j * 52 <> 0 then

redim preserve ts(j+1)

ts(j+1) = text.substring(j * 52)

end if

drawlinetext(mg, ts, mfont, new solidbrush(mforecolor))

end sub

private sub drawlinetext(byval g as graphics, byval t() as string, byval f as font, byval b as brush)

if (g is nothing)then throw new argumentnullexception("graphics")

if (t is nothing) then throw new argumentnullexception("text")

if (f is nothing) then throw new argumentnullexception("font")

if (b is nothing) then throw new argumentnullexception("brush")

dim fieldas fieldinfo

field = gettype(graphics).getfield("nativegraphics", bindingflags.instance or bindingflags.nonpublic)

dim hgraphics as intptr = field.getvalue(g)

field = gettype(font).getfield("nativefont", bindingflags.instance or bindingflags.nonpublic)

dim hfont as intptr = field.getvalue(f)

field = gettype(brush).getfield("nativebrush", bindingflags.instance or bindingflags.nonpublic)

dim hbrush as intptr = field.getvalue(b)

dim i as integer, tr as gprectf

tr =new gprectf(0, 0, mbmp.width, mbmp.height)

for i = 0 to 17

tr.x = 3

tr.y = 3 + i * mlineheight

gdipdrawstring(hgraphics, t(i), t(i).length, hfont, tr, intptr.zero, hbrush)

next

end sub

經測試,方法四和方法三的效率不相上下。但是,方法四更接近我們直觀的想法,而且對font的要求也不是很高。

可能還有更好的方法,歡迎各位網友交流。

GDI 繪製自定義製表位位數的文字。

先上圖 2,使用 stringformat中的settabstops來設定製表位所佔的空間 stringformat sf new stringformat sf.sttabstops 5f,ff 如下 private void form1 paint object sender,painteven...

自定義View之繪製文字

在初始化方法裡建立畫筆,設定畫筆顏色,不設定預設黑色 mtextpaint new paint mtextpaint.setcolor color.white 在ondraw方法裡繪製文字 canvas.drawtext text,float x,float y offset,mtextpaint ...

對話方塊上自定義繪製文字

以下 放置在onpaint 的else中,刪除原來else中的內容 文字 int itheight 200 文字高度 int itwidth 200 文字寬度 int ix 640 繪製區域的開始位置x int iy 150 繪製區域的開始位置y int icx ix itwidth 繪製區域的寬度...