Alaska Software Inc. - Cutting Off Text When Printing
Username: Password:
AuthorTopic: Cutting Off Text When Printing
Richard L. Hankins, Jr.
Cutting Off Text When Printing
on Wed, 02 Nov 2005 12:54:35 -0600
I am wanting to try something new (to me) with a report that I am
printing.  I would like to print some information at a given point,
however I cannot let the text step out of a given size.  For example,
I want to print "Ed. Lasker wrote several good books on chess" but I
have to crop the text at all points where it steps out of the {300,20}
bounding rect on the form.  I have been doing it using the average
width of the characters and then spliting it using Left() but I need
something with more control.

I have been looking at trying to do this using a viewport but that
does not work, and I didn't see much else that would appear to work in
the help file and examples.  How would you all recommend accomplishing
this task, is it possible in Xb++, what did I overlook? 

Thanks in advance,


- richard hankins

"All programmers are optimists. -- Frederick P. Brooks, Jr."
James Loughner Re: Cutting Off Text When Printing
on Wed, 02 Nov 2005 14:20:16 -0500
Well you can scan the text one character at a time and add up the total 
width of all the characters. When you reach the max exit the loop.

ie
FUNCTION TruncateStr(oPS,cStr,nMaxWidth)
LOCAL nWidth := 0, cResult := ""
FOR I = 1 TO LEN(cStr)
    nWidth += GraQueryTextBox( oPS, cStr[I])
    IF nWidth > nMaxWidth
       EXIT
    ENDIF
    cResult += cSr[I]
NEXT I
RETURN cResult

Jim

Richard L. Hankins, Jr. wrote:

> I am wanting to try something new (to me) with a report that I am
> printing.  I would like to print some information at a given point,
> however I cannot let the text step out of a given size.  For example,
> I want to print "Ed. Lasker wrote several good books on chess" but I
> have to crop the text at all points where it steps out of the {300,20}
> bounding rect on the form.  I have been doing it using the average
> width of the characters and then spliting it using Left() but I need
> something with more control.
> 
> I have been looking at trying to do this using a viewport but that
> does not work, and I didn't see much else that would appear to work in
> the help file and examples.  How would you all recommend accomplishing
> this task, is it possible in Xb++, what did I overlook? 
> 
> Thanks in advance,
> 
>
Richard L. Hankins, Jr.
Re: Cutting Off Text When Printing
on Wed, 02 Nov 2005 13:24:20 -0600
On Wed, 02 Nov 2005 14:20:16 -0500, James Loughner wrote:

> Well you can scan the text one character at a time and add up the total 
> width of all the characters. When you reach the max exit the loop.
> 
> ...(compacted)
> 
> Jim
> 

Jim,
   I have thought about doing this, but have not tried it.  I was
afraid of the time it may involve when having to do the calculation on
large reports (12 columns, 50 lines per page, 100 pages).
   I will try it though to see what the time loss is compared to
winging it and see if that is an option.  I appreciate your help and
welcome any other ideas as well.

Thanks Again,

- richard hankins

"Flon's Law: There is not now, and never will be, a language in which
it is the least bit difficult to write bad programs"
James Loughner Re: Cutting Off Text When Printing
on Wed, 02 Nov 2005 19:11:29 -0500
It's going to eat up time GraQueryBox is slow with most print drivers!!! 
It has to query the print driver and it returns the array. SO do you 
want fine control or speed you can't have both.

Jim
Richard L. Hankins, Jr. wrote:

> On Wed, 02 Nov 2005 14:20:16 -0500, James Loughner wrote:
> 
> 
>>Well you can scan the text one character at a time and add up the total 
>>width of all the characters. When you reach the max exit the loop.
>>
>>...(compacted)
>>
>>Jim
>>
> 
> 
> Jim,
>    I have thought about doing this, but have not tried it.  I was
> afraid of the time it may involve when having to do the calculation on
> large reports (12 columns, 50 lines per page, 100 pages).
>    I will try it though to see what the time loss is compared to
> winging it and see if that is an option.  I appreciate your help and
> welcome any other ideas as well.
> 
> Thanks Again,
>
Eric BreddamRe: Cutting Off Text When Printing
on Wed, 02 Nov 2005 17:40:56 -0800
>
> > Well you can scan the text one character at a time and add up the total
> > width of all the characters. When you reach the max exit the loop.
> >

you'll get some speed improvements if you simply print each character, check
the current GraPos() after that, and only invoke GraQueryTextBox() when you
get to within one "W" of the far right... then you only GraQuery about three
times, usually only two... but this depends on the text usually fitting into
the space and I'm assuming you're just wanting to cut it off at the end, not
go to 2nd/3rd etc lines.
Roger DonnayRe: Cutting Off Text When Printing
on Thu, 03 Nov 2005 08:51:35 -0700
In eXpress++ I use a function named DC_FormatMemoToWidth().  See below.

This accepts the string that you want to print, the width (in pixels) and
the printer presentation space object or a font.
It returns a string that has a CR embedded at the end of each line.

You can then parse out each line with MemoLine() for printing.

* -------------

FUNCTION DC_FormatMemoToWidth( cString, nWidth, oPS )

LOCAL aTokens, cOutString, cLine, i, cFont, nLineWidth, aRect, cCaption

DEFAULT cString := '', ;
        nWidth := 200

aTokens := DC_TokenArray( cString, ' '+Chr(10) )

cOutString := ''
cLine := ''

FOR i := 1 TO Len(aTokens)
  IF aTokens[i] == Chr(13)
    cLine += aTokens[i]
    cOutString += cLine
    cLine := ''
    LOOP
  ENDIF
  cCaption := cLine + ' ' + aTokens[i]
  IF Valtype( oPS ) == 'C'  It's a font
    cFont := Alltrim(oPS)
    nLineWidth := DC_GraQueryTextBox(cCaption,cFont)[1]
  ELSE  It's a presentation space
    aRect := GraQueryTextBox(oPS, cCaption )
    nLineWidth := aRect[3,1] - aRect[1,1]
  ENDIF
  IF nLineWidth <= nWidth
    cLine += ' ' + aTokens[i]
  ELSE
    cOutString += cLine + Chr(13)
    cLine := aTokens[i]
  ENDIF
NEXT
IF !Empty(cLine)
  cOutString += cLine
ENDIF

cOutString := Strtran(cOutString,Chr(13)+' ',Chr(13))
cOutString := Strtran(cOutString,Chr(13),Chr(13)+Chr(10))

RETURN LTrim(cOutString)





"Richard L. Hankins, Jr." <RHankins@ContactASI.com> wrote in message
news:jb2px0ptv2t9.c0lvxk98xagj.dlg@40tude.net...
> I am wanting to try something new (to me) with a report that I am
> printing.  I would like to print some information at a given point,
> however I cannot let the text step out of a given size.  For example,
> I want to print "Ed. Lasker wrote several good books on chess" but I
> have to crop the text at all points where it steps out of the {300,20}
> bounding rect on the form.  I have been doing it using the average
> width of the characters and then spliting it using Left() but I need
> something with more control.
>
> I have been looking at trying to do this using a viewport but that
> does not work, and I didn't see much else that would appear to work in
> the help file and examples.  How would you all recommend accomplishing
> this task, is it possible in Xb++, what did I overlook?
>
> Thanks in advance,
>
>
> -- 
> - richard hankins
>
> "All programmers are optimists. -- Frederick P. Brooks, Jr."
Anand GuptaRe: Cutting Off Text When Printing
on Tue, 08 Nov 2005 14:31:01 +0530
Richard L. Hankins, Jr.
Re: Cutting Off Text When Printing
on Wed, 09 Nov 2005 14:50:55 -0600
I came up with something that works for me, I also use topdown, but
what I did is duplicate and modify prPt (to prClip) and use it to call
the following code... the only problem is that there may be part of a
letter or number shown that is not completed.  Note however that this
is till beta code as I have not written a full report using it yet,
just doing single columns using it or the like.  I am still going to
try it against the other ideas that were posted and try to see which
one is faster for me.

Thanks again!

- richard hankins

"If it keeps up, man will atrophy all his limbs but the push-button
finger." (Frank Lloyd Wright)

<---- Code Insert Below ---->

/*
** prClip - prints a clipped region of a specified width
**
** oPs            - the presentation space
** aPos           - the X,Y coords for the text
** cText          - the text that will be printed
** nMaxW          - the max width the text can be
** [lShowClipBox] - show the bounding rect
*/
Function PrClip(oPS,aPos,cText,nMaxW,lShowClipBox)
  Local aPnts, nDiff, nMaxH, nCX, nCY, nW, nH, nX, nY

  Local aTmp

  //** split our points
  nX := aPos[1]
  nY := aPos[2]

  //** now figure out the size of the 
  //** string we are printing
  aPnts := GraQueryTextBox(oPS,cText)

  //** this will be the extent of the 
  //** text beneath the pos
  nDiff := aPnts[2,2]

  //** this will be the actual height of 
  //** the text we are going to print
  nMaxH := aPnts[1,2] + Abs(nDiff)

  //** the X Coord Position of the clipping 
  //** region, it doesn't change with all the 
  //** fonts I have looked at thus far, it seems 
  //** to be correct
  nCX := nX + aPnts[2,1]

  //** the Y Coord position of the clipping region, 
  //** this has to be the negative extent plus the 
  //** positive extent
  nCY := nY + aPnts[2,2]

  //** now get the actual width of the box (using 
  //** what the user passes)
  nW := nX + nMaxW

  //** this is the actual height of the box, 
  //** I gathered this information earlier
  nH := nY + aPnts[3,2]

  //** now we will define the path that we will 
  //** be using to crop the text
  GraPathBegin(oPS)
  GraBox(oPs,{nCX,nCY},{nW,nH})
  GraPathEnd(oPS)

  //** tell it we will being clipping using 
  //** the predefined path
  GraPathClip(oPS,.T.)

  //** now we will write our string within the box
  GraStringAt(oPS,{nX,nY},cText)

  //** now turn the clipping path off
  GraPathClip(oPS,.F.)

  //** for testing
  If lShowClipBox
    GraBox(oPs,{nCX,nCY},{nW,nH})
  EndIf

  Return nil