SpeedText ( Beta )

Blitz3D Forums/Blitz3D Userlibs/SpeedText ( Beta )

What is SpeedText?

SpeedText is a function library which allows loading fonts in Blitz3D and rendering them with maximum speed. The functions provided by SpeedText are much faster than the text functions of Blitz3D. Furthermore SpeedText offers many options for text alignment and formatting.

Features

• Very fast rendering
• Many alignment and formatting options
• Antialiasing ( Standard and ClearType )
• Unicode support ( UTF-8 )
• Render text into any buffer ( BackBuffer, TextureBuffer, ImageBuffer )
• Lock buffers for even more speed

Samples and Documentation

You can find 4 examples in the "samples" folder. The "docs" folder contains a documentation ( English and German ).

Beta-Version

This is a beta version, so there may be still bugs. Additional speed optimizations may also be possible. :)


Download

Nice!

Note, these also exist in fastText, which is pretty popular:

TextRect%(x%,y%,w%,h%,text$,format%,encoding%)
TextBackground(r%,g%,b%)

I removed them and it works fine. The 3 declarations on the blank lib name are more trouble to me than not having them.

I found that rendering direct to the texdture buffer is the nicest feature here. I copied the portion where it render the text to the texture buffer in the main loop, and I still had 60 fps! Nice!

; SpeedText - Sample 2
; Rendering To Buffers

Include "include/SpeedText.bb"

Graphics3D 800, 600, 0, 2
ST_Initialize( BackBuffer( ) )

Local font = LoadFont( "media/bolton sans.ttf", 22 )
SetFont font

Local cam = CreateCamera( )
	CameraClsColor cam, 30, 35, 35
	PositionEntity cam, 0, 0, -3

Local light = CreateLight( )
	LightColor light, 50, 50, 50

Local cube = CreateCube( )

Local tex = CreateTexture( 256, 256 )
	EntityTexture cube, tex
	
	SetBuffer TextureBuffer( tex )
		ClsColor 30, 60, 100 : Cls
	SetBuffer BackBuffer( )
	
	ST_SetBuffer TextureBuffer( tex )
		Text 10, 10, "This text was rendered"
		Text 10, 40, "directly to the"
		Text 10, 70, "texture's buffer."
		
		Text 10, 120, "Thank you,"
		Text 10, 150, "SpeedText!"		
	ST_SetBuffer BackBuffer( )
	
	a = 0
While Not KeyDown( 1 )
	TurnEntity cube, 1, 1, 1

	RenderWorld
	Flip
	SetBuffer TextureBuffer( tex )
		ClsColor 30, 60, 100 : Cls
	SetBuffer BackBuffer( )
	
	ST_SetBuffer TextureBuffer( tex )
		Text 10, 10, "This text was rendered"
		Text 10, 40, "directly to the"
		Text 10, 70, "texture's buffer."
		
		Text 10, 120, "Thank you,"
		Text 10, 150, "SpeedText! " + Str$(a)
	ST_SetBuffer BackBuffer( )
a = a + 1
Wend


Sometimes MAV. Seldom, do not know why...
Can't load my font - see source file

_33,
Thanks. I will rename the two functions in the next version.

MikhailV,
the filename of the font must be [real name].ttf -> "memory lapses.ttf". I know that you solved it better, but I'm still working on that. ;)
Can you tell me, where the MAV occurs?

MAV after Graphics3D command (on my worker computer. On home comp. all well) :(

>> [real name].ttf
He he :) Take name of the font from TTF-file! Example (PureBasic syntax):


;//This is TTF file header
Structure TT_OFFSET_TABLE
     uMajorVersion.w
     uMinorVersion.w
     uNumOfTables.w
     uSearchRange.w
     uEntrySelector.w
     uRangeShift.w
EndStructure


; //Tables in TTF file And there placement And name (tag)
Structure TT_TABLE_DIRECTORY
     szTag.s{4}		; //table name
     uCheckSum.l		; //Check sum
     uOffset.l			; //Offset from beginning of file
     uLength.l			; //length of the table in bytes
EndStructure


; //Header of names table
Structure TT_NAME_TABLE_HEADER
    uFSelector.w		; //format selector. Always 0
    uNRCount.w			; //Name Records count
    uStorageOffset.w	; //Offset for strings storage, from start of the table
EndStructure


; //Record in names table
Structure TT_NAME_RECORD
    uPlatformID.w
    uEncodingID.w
    uLanguageID.w
    uNameID.w
    uStringLength.w
    uStringOffset.w		; //from start of storage area
EndStructure


Procedure.l SWAPWORD(x.w)
	Protected b0.l, b1.l
	b0 = ( x >> 8 ) & $000000FF
	b1 = ( x << 8 ) & $0000FF00 
	ProcedureReturn ( b0 | b1 )
EndProcedure


Procedure.l SWAPLONG (x.l)
	Protected b0.l, b1.l, b2.l, b3.l
	b0 = (x >> 24 ) & $000000FF
	b1 = (x >> 8 ) & $0000FF00 
	b2 = (x << 8 ) & $00FF0000
	b3 = (x << 24 ) & $FF000000
	ProcedureReturn ( b0 | b1 | b2 | b3 )
EndProcedure


Procedure.s GetFontNameFromFileEx(path.s, id.l)
	Protected csRetVal.s
	Protected s.s
	Protected i.l, iq.l
	Protected ttOffsetTable.TT_OFFSET_TABLE
	Protected tblDir.TT_TABLE_DIRECTORY
	Protected ttNTHeader.TT_NAME_TABLE_HEADER
	Protected bFound.l, nPos.l


	If ReadFile(0,path)
		; //Define And Read file header
		ReadData(0,@ttOffsetTable,SizeOf(TT_OFFSET_TABLE))
		
		; //remember To rearrange bytes in the field you gonna use
	    ttOffsetTable\uNumOfTables = SWAPWORD(ttOffsetTable\uNumOfTables);
	    ttOffsetTable\uMajorVersion = SWAPWORD(ttOffsetTable\uMajorVersion);
	    ttOffsetTable\uMinorVersion = SWAPWORD(ttOffsetTable\uMinorVersion);

		; TTF(TrueType) or OTF(OpenType)
		If ((ttOffsetTable\uMajorVersion & $FFFF)=1 And (ttOffsetTable\uMinorVersion & $FFFF)=0) Or ((ttOffsetTable\uMajorVersion & $FFFF)=$4F54 And (ttOffsetTable\uMinorVersion & $FFFF)=$544F)	; //check is this is a true type font And the version is 1.0
	
			bFound = #False
			
			iq = (ttOffsetTable\uNumOfTables & $FFFF)-1
			For i=0 To iq
				ReadData(0,@tblDir, SizeOf(TT_TABLE_DIRECTORY))
				If LCase(tblDir\szTag)="name"
					bFound = #True
					tblDir\uLength = SWAPLONG(tblDir\uLength)
					tblDir\uOffset = SWAPLONG(tblDir\uOffset)
					Break
				EndIf
			Next
	
			If bFound
				FileSeek(0,tblDir\uOffset )
				ReadData(0,@ttNTHeader, SizeOf(TT_NAME_TABLE_HEADER))
			
	
	 			ttNTHeader\uNRCount = SWAPWORD(ttNTHeader\uNRCount);
	 			ttNTHeader\uStorageOffset = SWAPWORD(ttNTHeader\uStorageOffset);
	 			ttRecord.TT_NAME_RECORD
	 			bFound = #False;
	
	
				iq = (ttNTHeader\uNRCount & $FFFF) - 1
				For i=0 To iq
					ReadData(0,@ttRecord, SizeOf(TT_NAME_RECORD))
					ttRecord\uNameID = SWAPWORD(ttRecord\uNameID)
	
					If (ttRecord\uNameID & $FFFF) = id
	
	 					ttRecord\uStringLength = SWAPWORD(ttRecord\uStringLength);
	 					ttRecord\uStringOffset = SWAPWORD(ttRecord\uStringOffset);
	 					
	 					nPos = Loc(0)	
	 					FileSeek(0, tblDir\uOffset + (ttRecord\uStringOffset & $FFFF) + (ttNTHeader\uStorageOffset & $FFFF) )
	 							
	 					s.s = Space( ttRecord\uStringLength & $FFFF )		
						ReadData(0,@s, (ttRecord\uStringLength & $FFFF) )
						s=Trim(s)
						
						If Len(s)>0
							csRetVal=s
							Break					
						EndIf					
						
						FileSeek(0, nPos) 
					EndIf
							
				Next
	
			EndIf
			
		EndIf

		CloseFile(0)
	EndIf
	
	ProcedureReturn csRetVal
EndProcedure


Procedure.s GetFontNameFromFile(path.s)

	;USE ID = 1	  ==  family name

	; id:
	; 0 - Copyright
	; 1 - Family Name
	; 2 - Style
	; 3 - ? Name Full
	; 4 - Name (Full)
	; 5 - Version
	; 6 - PostScript Name
	; 7 - Trademark

	ProcedureReturn GetFontNameFromFileEx(path,1)
EndProcedure



See my FastText library, there no such problem.

Wow. That's it.
Thanks a lot, Mikhail. :)

> MAV after Graphics3D command
SpeedText does not do anything before ST_Initialize ... strange.

Very strange. I was too surprised... Check your source-code!

Sorry, I checked the code again, but returning 1 is the only thing that is done when loading the DLL. What B3D-Version do you use?

Hmm... 1.99