[futurebasic] [FB] Print Question / Bug

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : January 2006 : Group Archive : Group : All Groups

From: Stu Cram <stu@...>
Date: Wed, 11 Jan 2006 09:53:30 -0600
On Jan 8, Douglas Stemen asked about this program ...
> 	DIM t%
> 	DEF LPRINT
> 	ROUTE _toPrinter
> 	FOR t% = 1 TO 100
> 	PRINT t%
> 	NEXT t%
> 	CLOSE LPRINT

and why it would crash now but not in earlier systems of FB.
The suggestion was to have a window on the screen
and add ROUTE _toScreen just before CLOSE LPRINT, as follows...

	WINDOW 1, "x-test-1"
	DIM t%
	DEF LPRINT
	ROUTE _toPrinter
	FOR t% = 1 TO 100
	  PRINT t%
	NEXT t%
	ROUTE _toScreen
	CLOSE LPRINT

Now that stopped the problem of it crashing BUT he also mentioned...
> If the PRINT statement causes the pen to move below the bottom of the
> printer page, the page is supposed to be automatically ejected and
> printing continued at the top of the next page. This is how it is
> described in the FB reference manual. FB used to work this way.

In particular, this only prints numbers up to 60 on the first page and 
not beyond. The additional numbers are not printed on an additional 
page as the manual says they should be.

While not elegant, here is a work-around to test when printing is near 
the page bottom and to start a new page. FutureBasic's built in 
function WINDOW(_height) returns the height of the output window which 
in this case is the print area (not the full page, that's bigger with 
margins) after a route _toPrinter.

	WINDOW 1, "x-test-2"
	DIM t%
	DEF LPRINT
	ROUTE _toPrinter
	FOR t% = 1 TO 100
	  PRINT t%
	  LONG IF WINDOW(_penV) >= WINDOW(_height) - 1.25*(USR FontHeight)
	    ROUTE _toScreen
		CLEAR LPRINT
		ROUTE _toPrinter
	  END IF
	NEXT t%
	ROUTE _toScreen
	CLOSE LPRINT

This now starts the new page and continues printing up to value 100 on 
the 2nd page.

However, only 59 numbers are printed, not 60 on page 1 as in the 
earlier example.

If I use this version:
     LONG IF WINDOW(_penV) >= WINDOW(_height) - (USR FontHeight)
then 60 numbers appear on page 1, but page 2 doesn't show up.
As Doug suggested, there is evidence of a bug in the FB print routine.

More evidence of a printing bug appears when you set the text to 
another font, size and/or style initially. The first page uses that 
text type but the second page reverts back to Monaco, size 12, plain. 
The only solution for now is to reset the text properties every time a 
new page is started as if it were a new window. However, one would 
expect from the documentation that each successive page in a job would 
'carry over' its text properties, etc. This example shows the problem 
with text formatting...

	WINDOW 1,"x-test-3"
	DIM t%
	DEF LPRINT
	ROUTE _toPrinter
	TEXT _Times, 20, 1
	FOR t% = 1 TO 100
	  PRINT t%
	  LONG IF WINDOW(_penV) > WINDOW(_height) - 1.25*(USR FontHeight)
	    ROUTE _toScreen
		CLEAR LPRINT
		ROUTE _toPrinter
	  END IF
	NEXT t%
	ROUTE _toScreen
	CLOSE LPRINT

To fix the above problem, add another 'TEXT _Times, 20, 1' just after 
ROUTE _toPrinter in the LONG IF structure.

The point of this discussion is that FutureBasic -- supposedly for 
beginners as well a pros -- is becoming more and more complex in simple 
tasks like printing a list of numbers and frustrating beginners, 
perhaps not to continue.

I hope the next revision of FB will make PRINT work the way it is 
described in the manual, and apparently as Douglas mentioned, the way 
it used too.

=============================================================

Addendum:  I gave up long ago trying to figure out the bottom of the 
page with WINDOW(_penv) and would probably print the numbers from 1 to 
100 using a routine something like this...

------------------------------------------
	BEGIN GLOBALS
	  DIM gPageNum
	  DIM gVertPos
	  DIM gLineSpacing
	END GLOBALS
	'~'1

	LOCAL FN StartNewPage
	  gPageNum ++
	  LONG IF gPageNum > 1
	    ROUTE _toScreen
	    CLEAR _LPRINT
	  END IF
	  ROUTE _toPrinter
	  TEXT _Courier, 10, 0
	  PRINT %(WINDOW(_width)-30,12) "Page:"; gPageNum;  // heading line
	  TEXT _Courier, 14, 1
	  gVertPos = 30
	  gLineSpacing = 20
	END FN
	'~'1

	// Main routine

	WINDOW 1, "xx-test5"
	DIM t%
	gPageNum = 0

	DEF PAGE
	IF prCancel THEN END
	DEF LPRINT
	IF prCancel THEN END

	FN StartNewPage

	FOR t% = 1 TO 100
	  gVertPos += gLineSpacing
	  LONG IF gVertPos > WINDOW(_height)
	    FN StartNewPage
	  END IF
	  PRINT %(30, gVertPos) USING "####"; t% ;
	NEXT t%

	ROUTE _toScreen
	CLOSE LPRINT
------------------------------------------

As someone mentioned, use the PRINT %(h,v) option to specify the exact 
position on the page and finish each PRINT instruction with a 
semi-colon to suppress any extra returns that would start a new line, 
possibly below the page bottom. That works for total control of 
printing but it's much more work than a raw beginner should be expected 
to deal with.

PS The manual also states that a space is output after each number but 
that doesn't happen either - see previous post on Jan 7.

BOTTOM LINE - K.I.S.S. and make FutureBasic 4.3 or 5.0 work AS THE 
MANUAL SAYS.

My $0,02 rant; comments welcome.
-Stu