OOP question

BlitzMax Forums/BlitzMax Beginners Area/OOP question

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
Wend
The 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

I got ya.
Thanks