Avoiding line cut-off in a multipage printout

André.Bisseret Andre.Bisseret at inria.fr
Tue Mar 28 08:22:25 EST 2006


Hi Graham,

I had recently a lot of problem about printing (actually mainly with  
Windows, not with Mac).
with Mac a number of differents procedure worked.
I give you here the one which eventually worked with Windows too.
I don’t claim that it is the best possible one ; likely it should be  
optimized, simplified etc. but currently it is working on Windows as  
well as on Mac.
I hope it will help you (could be some others) :-)))

I wrote this post a bit quicky ( and my english is not so good)  
so,don’t hesitate to ask me questions about anything that would not be  
clear. (I hope I will remember why I put such or such line ;-))). Some  
line could be useless but for the moment I don't change anything !!!!

My stack has about 300 cards. Each card presents a text (analysis of  
scientific articles) in aVscrolling field. Often the text exceeds the  
visible par of the field.  On each card there are also other (non  
scrolling) fields containing « name of the author », a code of the  
text, the title of the text, the reference of the article the text is  
about etc.

Sorry, I keep naming my objects as it is, often in French ; It would be  
too long to change them in the script ; I will tried to translate when  
necessary. I hope that wont be too disturbing.
I don't use "formatForPrinting" ; I tried it with a printingStack (not  
a substack) without success.
I don't use either the scrolling  technique.

best regards from Grenoble
André

1 – I have a hidden field in my stack named « PourImprimer » (ToPrint)
In this fld I format a report composed from several fields on the  
cards. (author, code of the text ; title and the text itself (in a fld  
name « LeTexte ».
Below, a part of the script I am using : (concerns the installation of  
the fld «LeTexte »
on formatPourImprimer
   put empty into fld "pourImprimer"
   put fld "leTexte" into fld "pourImprimer"
   set the HTMLText of fld "pourImprimer" to the HTMLText of fld  
"leTexte"
   put the number of lines of fld "pourImprimer" into truc
   repeat with x = 1 to truc
     if line x of fld "pourImprimer" is empty then next repeat
     if line x of fld "pourImprimer" is not empty then
       get the effective textSize of line x of fld "pourImprimer"
       set the effective textSize of line x of fld "pourImprimer" to it  
–2 -- that’s because otherwise the printed characters were too large.
     end if
   end repeat
-- actually I continue here to install the content of others field but  
it is the same way.
end formatPourImprimer


2 – Moreover I created a subStack named « StackDImpression » (means  
PrintingStack) with two fields :
one is named « tamponAImprimer » (means « bufferField)
the other is name « champDImpression » (means « FieldToBePrinted »).
This two fields have no border shown.
  These two fields on it, have the same size. This size is calculated so  
that it corresponds to the size of  A4 page minus the margins.
A page A4 is in points (inches * 72) : 595 * 842
As I set the margins to : 72,50,50,72, the resulting size for my  
subStack and its 2 flds is 473*720.
Actually, he subStack is a bit highter than its two flds, because at  
the bottom of the substack I have a small field where I can put the  
page number.
This substack remains not visible.

When the user click on a button « Print the text » on a card, then :
Here is the handler which is called :
5 – Finally I print
on Imprimer (means « print »)
   FormaterLaFiche --  SEE BELOW ALL THE (EMBEDDED) HANDLERS
   go to stack "stackDImpression"
     set the printmargins to 72,50,50,72
   put the cardNames of stack "stackDImpression" into cardsToPrint
   answer printer
   open printing with dialog
   if the result is "Cancel" then exit Imprimer
   repeat for each line tCd in cardsToPrint
     print tCd
   end repeat
   close printing
end Imprimer

NOW WHAT IS UNDER « FORMATERLAFICHE» AND THE HANDLERS IT IS CALLING.
1-  I format the document (translation from the fld « LeTexte » to the  
fld « pourImprimer » with new formating) as above.

2.– Then I put the fld « pourImprimer » into the fld « tamponAImprimer  
» of the subStack ; and then I fill in the field « champDImpression »  
from fld « tamponAImprimer », line after line (put one first line into  
fld « champDimpression » delete this line in fld « tamponAImprimer »  
etc until a page of field « champDImpression » be full. Then I continue
the same process on a new card filling in a new page for fld «  
ChampDImpression ».

Below the handlers :
on FormaterLaFiche -- (means « format the text (in stackDImpression)
   set the cursor to watch
   GLOBAL lineToAdd
   GLOBAL cardNum
   GLOBAL gPrintHeight
   formatPourImprimer
   miseAZéroStackDImpression -- see below the handler
   set the printMargins to 72,50,50,72 -- likely not necessary here
   put field "pourImprimer" into field "tamponAImprimer" of card 1 of  
stack "StackDImpression"
   set the htmlText of fld "tamponAImprimer" of cd 1 of stack  
"stackDImpression" to\
   the htmlText of fld "pourImprimer"
   go to stack "stackDImpression" –which remains invisible
   put the height of field "champDImpression" of stack  
"StackDImpression" - 26 into gPrintHeight -- « -26 »
   put empty into fld "champDImpression"
   put empty into cardNum
   repeat until fld "tamponAImprimer" is empty
     -- if the mouseClick then exit repeat
     put cardNum + 1 into cardNum
     remplirUnePage -- see the handler below
     put "Page" && cardNum into fld "champNoPage"
   end repeat
   go to last card of stack "stackDImpression"
if fld "champDImpression" is empty then delete this cd
   reset cursors
end FormaterLaFiche

on miseAZéroStackDImpression -- simple but just to be complete ; it is  
to delete the cards of the previous printing
   put the number of cds of stack "stackDImpression" - 1 into NbrDeCartes
   repeat NbrDeCartes
     delete cd 2 of stack "stackDImpression"
   end repeat
end miseAZéroStackDImpression

on remplirUnePage (means « fillinOnePage »)
GLOBAL CARDNUM
   GLOBAL LINETOADD
   GLOBAL GPRINTHEIGHT
   go to Card CardNum
   put the number of lines of fld "champDImpression" + 1 into lineToAdd
   create card
   go previous
   repeat UNTIL the formattedHeight of fld "champDImpression" of cd  
cardNum >= gPrintHeight
if the number of lines of fld "tamponAImprimer" = 0 then exit repeat
     if line 1 of fld "tamponAImprimer" is empty then put cr after fld  
"champDImpression" of cd cardNum
     copy line 1 of fld "tamponAImprimer" – copy and paste is the easier  
way I found (that keeps html format and is particularly efficient if  
you have images embedded in the text
     select line lineToAdd of fld "champDImpression" of cd cardNum –the  
first empty line
     paste
     set the clipboardData to empty
     delete line 1 of fld "tamponAImprimer"
     put lineToAdd + 1 into lineToAdd
   end repeat
   reformaterPage – see the handler below
   replacerLesLignesIsoléesEnBas – see the handler below
end remplirUnePage

3 – When fld « tamponAImprimer » is empty then fld « champDImpression »  
may be display on several cards (= several pages to print).
BUT, often, last line on a card is not entirely visible because it is  
too long. Thus, I need to test this and if true then, : copy this last  
line, delete it, and  paste it at the top of the next card.
  Below the handler :
on reformaterPage – means formatAgainPage
   if the formattedHeight of fld "champDImpression" >= the height of  
field "champDImpression" then
     repeat until the formattedHeight of fld "ChampDImpression" < the  
height of fld "champDImpression"
       if the mouseClick then exit repeat
       copy last line of fld "champDImpression"
       go next
       if the clipboardData is empty then
         put cr before fld "champDImpression"
       else
         select before fld "champDImpression"
         paste
         set the clipboardData to empty
         go previous
         delete last line of fld "champDImpression"
       end if
     end repeat
   end if
end ReformaterPage

4 – But it remains one problem :  last line of fld « champAImprimer »  
can be an « isolated line », in French « une ligne orpheline » ( an  
orphan line). Often it is a title which remains isolated as a last line  
while the content of the passsage has been put on the next page.
So, I have another handler trying to solve as many such problems as  
possible (depending on how easy it is to detect theses sort of cases).
Below the handler I am using  (well, only to get the idea ; depends a  
lot of your texts) :

on replacerLesLignesIsoléesEnBas --(means something like «put back the  
isolated last lines)
   switch
   case the textStyle of last line of fld "champDImpression" is "bold"\
     and the foregroundColor of last line of fld "champDImpression" is  
"0,0,0" –for me small sub-titles
     copy last line of fld "champDImpression"
     go next
     select before fld "champDImpression"
     paste
     set the clipboardData to empty
     go previous
     delete last line of fld "champDImpression"
     break
   case the foregroundColor of last line of fld "champDImpression" is  
"0,0,255" – I have titles in blue
     copy last line of fld "champDImpression"
     go next
     put cr before fld "champDImpression"
     select before fld "champDImpression"
     paste
     go previous
     delete last line of fld "champDImpression"
     break
   case first char of last line of fld "champDImpression" is "*" and\
     the number of chars of last line of fld "champDImpression" < 50 --  
small lines in lists
     copy last line of fld "champDImpression"
     go next
     put cr before fld "champDImpression"
     select before fld "champDImpression"
     paste
     go previous
     delete last line of fld "champDImpression"
     break
   end switch
end replacerLesLignesIsoléesEnBas

Le Monday, 27 Mar 2006, à 19:38 Europe/Paris, Graham Samuel a écrit :

> Well, so far my experiments have been somewhat unsatisfactory. My  
> surmise that you can't scroll beyond the bottom of the last page was  
> correct: if say 60 lines fit on the first page and you have a total of  
> 80 lines, scrolling the pixel equivalent of 60 lines won't make line  
> 61 come to the top of the field: in fact AFAIK line 21 or thereabouts  
> will come to the top of the field, so I will have to deal with the  
> last page in a different way (for example by deleting all the lines  
> except the ones that are meant to be on the last page, and printing  
> what remains). The other odd thing that happened is that when I  
> scrolled by the amount suggested in the pageHeights, the last line of  
> page n was repeated at the top of page n+1. Probably my error, but so  
> far I don't see how. A further point is that the RR docs (dictionary)  
> suggests you print the field the text is in, but actually you can't  
> print a field, only a card: so first you have to get the field to be  
> the right size to fill the printable area on the page (to which there  
> is no general solution) and then you have to print the card.
>
> I'll carry on experimenting. Haven't tried it on the PC yet (with the  
> stack opened in FormatForPrinting mode). But it all seems a lot more  
> complicated than I had hoped. I'd really like to save a text file and  
> get the user to print it using the local text editor, but I don't  
> think that's in the spec...
>
> Graham
>
> I wrote:
>> Thanks to Ken Ray and Dave Cragg for pointing out the existence 'the  
>> pageHeights'. I had missed this. Although somewhat eccentric, i.e.
>>
>>> Comments:
>>> The value reported by the pageHeights property is a list of numbers  
>>> separated by returns. Each number is the height in pixels of a page  
>>> full of text.
>>>
>>> You can use the pageHeights property to print the entire contents of  
>>> a field by printing the field, setting the field's scroll to the  
>>> first line of the pageHeights, printing the field again, setting the  
>>> scroll to the current scroll plus line 2 of the pageHeights, and so  
>>> on.
>>>
>>> The computations used by the pageHeights property assume the field's  
>>> borderWidth property is set to zero and its margins is set to 6.
>>
>> it does look like the answer. Thanks to you both. There does at first  
>> sight seem to be one problem, which is that if the last page isn't  
>> full of text, then AFAIK scrolling won't work, because the scroll  
>> will include stuff from the previous page... but as I've been wrong  
>> about everything else I'm probably wrong about this too. Also I'm not  
>> sure what the implications of the margins being set to 6 are... nor  
>> if this works when the formatForPrinting is set (I suppose so,  
>> otherwise what would be the use of it?). I'll experiment.
>>
>>> On 3/27/06 12:36 AM, "Graham Samuel" <livfoss at mac.com> wrote:
>>>
>>>
>>>> It gets worse! I see now that the script can't know the exact number
>>>> of lines that will be printed without clipping on a properly
>>>> formatted page under Windows! What I can't understand (as with other
>>>> aspects of printing) is why so few developers seem to care about
>>>> this. Not everybody reads stuff on the screen: for example teachers,
>>>> I find, want to carry bits of paper away with them (such as student
>>>> reports) even if the actual app is a highly interactive screen-based
>>>> thing.
>
>
> ----------------------------------------
> Graham Samuel / The Living Fossil Co. / UK and France
>
> _______________________________________________
> use-revolution mailing list
> use-revolution at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your  
> subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-revolution
>
>
------------------------------------------------------------------------ 
--------------------------
André Bisseret
Directeur de recherche émérite
Adresse : 140 rue E. Béthoux - 38220 Vizille
Tél. : 04 76 68 15 24
Courriel : Andre.Bisseret at inria.fr
            et : bisseret at andre-bisseret.com
site Multifiches  
:http://www-clips.imag.fr/multicom/web_site_multicom/Multifiches/
site peinture : http://www.andre-bisseret.com/





More information about the Use-livecode mailing list