Hi there, a question on types and scope I guess. If I declare a type and in that type declare:
Field imgFont:TImage
Then in a method of the same type have the following:
imgFont= LoadAnimImage("font16p.png",16,16,0,..
126-32+1,DYNAMICIMAGE|MASKEDIMAGE)
will the contents of imgFont be available to other methods in that type? Doesnt seem to be...
Thanks for the help - a grateful newbie ;-)
will the contents of imgFont be available to other methods in that type?
Yes, but not to functions. Got code?
Here it is.....
Strict
Graphics 640,480,0
HideMouse
Type TFont
Field iLastASCII=126
Field iFirstASCII=32
Field iCellWidth=16
Field iCellHeight=16
Field imgFont: TImage
Field iWidthTable[iLastASCII-iFirstASCII+1]
Method CreateFont(sFontName$)
Local iMaxWidth=0
Local i,x,y,alpha=0
'Local imgfont
SetMaskColor (255,0,255)
imgFont= LoadAnimImage("font16p.png",16,16,0,..
126-32+1,DYNAMICIMAGE|MASKEDIMAGE)
If Not imgfont Print "cant fin font"
For i=1 To (iLastASCII-iFirstASCII)
Local img=LockImage(imgFont,i)
For x=(iCellWidth-1) To 0 Step -1
For y=0 Until iCellHeight
alpha=ReadPixel(img,x,y) & $ff000000
If alpha Then Exit
Next
If alpha Then Exit
Next
UnlockImage imgFont,i
iWidthTable[i]=x+1
If x>iMaxWidth Then iMaxWidth=x
Next
iWidthTable[0]=iMaxWidth*.3
EndMethod
Method DrawBmpFont(text$,x,y)
Local i=0
For i=0 Until text.length
DrawImage imgFont,x,y,Asc(text[i..i+1])-32
x:+iWidthTable[Asc(text[i..i+1])-32]
Next
EndMethod
EndType
Local ArialFont:TFont
ArialFont = New TFont
ArialFont.iFirstASCII = 32
ArialFont.iLastASCII = 126
ArialFont.iCellWidth = 16
ArialFont.iCellHeight = 16
ArialFont.CreateFont("font16p.png")
While Not KeyDown(key_escape)
ArialFont.DrawBmpFont("Hello",100,100)
Flip
Cls
Wend
...basically I want to know if the DrawBmpFont method can access imgFont.
Thanks
This works here (BlitzMAX 1.14), and isn't significantly different from your example:
Strict
Graphics 640,480,0
Type TFont
Field iLastASCII=126
Field iFirstASCII=32
Field iCellWidth=16
Field iCellHeight=16
Field imgFont:TImage
Field iWidthTable[iLastASCII-iFirstASCII+1]
Method CreateFont(sFontName$)
Local iMaxWidth=0
Local i,x,y,alpha=0
SetMaskColor (255,0,255)
imgFont= LoadAnimImage(sFontName,16,16,0,..
126-32+1,DYNAMICIMAGE|MASKEDIMAGE)
If Not imgfont Print "can't find font"
For i=1 To (iLastASCII-iFirstASCII)
Local img:TPixmap=LockImage(imgFont,i)
For x=(iCellWidth-1) To 0 Step -1
For y=0 Until iCellHeight
alpha=ReadPixel(img,x,y) & $ff000000
If alpha Then Exit
Next
If alpha Then Exit
Next
UnlockImage imgFont,i
iWidthTable[i]=x+1
If x>iMaxWidth Then iMaxWidth=x
Next
iWidthTable[0]=iMaxWidth*.3
EndMethod
Method DrawBmpFont(text$,x,y)
Local i=0
For i=0 Until text.length
DrawImage imgFont,x,y,Asc(text[i..i+1])-32
x:+iWidthTable[Asc(text[i..i+1])-32]
Next
EndMethod
EndType
Local ArialFont:TFont
ArialFont = New TFont
ArialFont.iFirstASCII = 32
ArialFont.iLastASCII = 126
ArialFont.iCellWidth = 16
ArialFont.iCellHeight = 16
ArialFont.CreateFont("font16p.png")
While Not KeyDown(key_escape)
ArialFont.DrawBmpFont("Hello",100,100)
Flip
Cls
WendThe DrawBmpFont method can access imgFont just fine. Maybe your PNG file is corrupted or something?
I've got it working at the expense of getting very confused. The following code works:
*****************************************
Strict
Graphics 640,480,0
HideMouse
Type TFont
Field iLastASCII=126 'Local as it may need to be different for each font object
Field iFirstASCII=32 'Local as it may need to be different for each font object
Field iCellWidth
Field iCellHeight
Field imgFont: TImage ' Local as it needs to specific to each instance (each font)
Field iWidthTable[iLastASCII-iFirstASCII+1] ' Again, local
Method CreateFont(sFontName$) 'try it without the $ if there's a problem - check later
Local iMaxWidth=0
Local i,x,y,alpha=0
SetMaskColor (255,0,255)
imgFont= LoadAnimImage("font16p.png",16,16,0,..
126-32+1,DYNAMICIMAGE|MASKEDIMAGE)
If Not imgfont Print "Cant find font to load"
For i=1 To (iLastASCII-iFirstASCII) ' step through each character
Local img=LockImage(imgFont,i) ' lock character image so we can read pixels - AL Lock image allows us to access image's pixels. Look at each frame of image
For x=(iCellWidth-1) To 0 Step -1 ' work from right to left
For y=0 Until iCellHeight ' check pixels from top to bottom
alpha=ReadPixel(img,x,y) & $ff000000 ' grab alpha ($00=background, $ff=foreground)
If alpha Then Exit ' if foreground then we have our width (in x)
Next
If alpha Then Exit ' if we have our width, no need to continue
Next
UnlockImage imgFont,i ' unlock this character
iWidthTable[i]=x+1 ' store width plus spacing
If x>iMaxWidth Then iMaxWidth=x ' check against widest character
Next
iWidthTable[0]=iMaxWidth*.3 ' calculate width of space
EndMethod
Method DrawBmpFont(text$,x,y)
Local i=0
For i=0 Until text.length
DrawImage imgFont,x,y,Asc(text[i..i+1])-32
x:+iWidthTable[Asc(text[i..i+1])-32]
Next
EndMethod
EndType
Global ArialFont:TFont
ArialFont = New TFont
ArialFont.iFirstASCII = 32
ArialFont.iLastASCII = 126
ArialFont.iCellWidth = 16
ArialFont.iCellHeight = 16
ArialFont.CreateFont("font16p.png")
While Not KeyDown(key_escape)
ArialFont.DrawBmpFont("1. Hello this is a font test",100,100)
ArialFont.DrawBmpFont("2. More text for you",100,200)
Flip
Cls
Wend
*****************************************
BUT...if you change the first 2 lines of the type to:
Field iLastASCII 'Local as it may need to be different for each font object
Field iFirstASCII
ie you remove the values within the type, the following line:
iWidthTable[i]=x+1
..produces the error 'Unhandled Exception: Attempt to index array element beyond array length'
So what is the difference? I understand the error but have no idea why this would happen. What have I missed? Thanks very much for all help.
use {codebox} ... {/codebox}
replace {} with []
- sorry, dont understand your last comment replace {} with [] ?
In terms of the code the problem I have found is that iWidthTable doesnt seem to have a size - yet its size seems to be initialised to iWidthTable[iLastASCII-iFirstASCII+1], with iLastASCII and iFirstASCII set when I create the instance...
When you want to post long code type "[" followed by "codebox" and a closing "]" on a line. Then type your code, and when you are done type "[" followed by "/" and "codebox" and a final "]".
Check out the forum codes
here