Announcement

Collapse
No announcement yet.

Truncate text to pixel length

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Truncate text to pixel length

    I have a sinking feeling that I already know how to do this, but does anyone have a more efficient method than using a binary chop on the text string until the legth of the result is just less than the desired pixel length?

  • #2
    Chris,
    If you use a fixed font then perhaps GRAPHIC TEXT SIZE txt$ TO nWidth!, nHeight!
    will help.

    Paul.

    Comment


    • #3
      DrawText with DT_MODIFYSTRING is useful for text or path truncation
      kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

      Comment


      • #4
        Originally posted by Paul Dixon View Post
        Chris,
        If you use a fixed font then perhaps GRAPHIC TEXT SIZE txt$ TO nWidth!, nHeight!
        will help.
        Paul, I only wish I could use a fixed font, but the design subcommittee have ruled it out except in prototyping.

        Comment


        • #5
          Originally posted by Kev Peel View Post
          DrawText with DT_MODIFYSTRING is useful for text or path truncation
          That's the one! Thanks!

          Comment


          • #6
            I still have not mastered this drawtext API.

            It seems to map the string at 0,0 in the GW then display just as much as coincides with the given rect - or maybe I got the options wrong.

            Any experts out there?

            ******* ADDED **********
            Sorry, what I should have said is that I want to constrain a string to a certain number of pixels in width, so the leftmost character is always displayed, and the right hand end of the string is truncated.

            Code:
            ' to investigate DrawText on a GW
            #compile exe
            #dim all
            #include once "WIN32API.inc"
            function pbmain () as long
                local hgw as dword
                local skey as string
                local i as long
                    local x, y as long
                    local tempr as rect
                    local hDC as dword
                    local sztitle as asciz * 512
            
                graphic window "DrawText (ESC to end)", 100, 100, 280, 200 to hgw
                graphic attach hgw, 0, redraw
            
            
                sztitle = "HELLO MOTHER"
                graphic color %white,%blue
                graphic get dc to hdc
                setrect tempr, 30, 5, 130, 20
                drawtext hdc, byval varptr(sztitle), len(sztitle), tempr, _
                         %DT_END_ELLIPSIS or %DT_LEFT or %DT_MODIFYSTRING or %DT_SINGLELINE
                '? hdc, tempr.nleft, tempr.ntop, tempr.nright, tempr.nbottom
                graphic color %black, %white
                graphic redraw
                graphic waitkey$ to skey
                graphic window end
            end function
            Last edited by Chris Holbrook; 18 Nov 2008, 11:14 AM. Reason: see ADDED

            Comment


            • #7
              Unless the point is to get a modified string which WILL fit into the rect supplied - in which case one would also need %DT_CALCRECT to prevent anything being displayed:

              Code:
              ' to investigate DrawText on a GW
              #compile exe
              #dim all
              #include "WIN32API.inc"
              function pbmain () as long
                  local hgw as dword
                  local skey as string
                  local i as long
                      local x, y as long
                      local tempr as rect
                      local hDC as dword
                      local sztitle as asciz * 512
              
                  graphic window "DrawText (ESC to end)", 100, 100, 280, 200 to hgw
                  graphic attach hgw, 0, redraw
              
              
                  sztitle = "HELLO MOTHER"
                  graphic color %white,%blue
                  graphic get dc to hdc
                  setrect tempr, 30, 5, 90, 20
                  drawtext hdc, byval varptr(sztitle), len(sztitle), tempr, _
                           %DT_LEFT or %DT_SINGLELINE or %DT_END_ELLIPSIS or %DT_MODIFYSTRING or %DT_CALCRECT
              
                  graphic set pos ( 0, 40):graphic print sztitle
                  '? hdc, tempr.nleft, tempr.ntop, tempr.nright, tempr.nbottom
                  graphic color %black, %white
                  graphic redraw
                  graphic waitkey$ to skey
                  graphic window end
              end function

              Comment


              • #8
                I don't see how graphic redraw can work, since it has no buffered GRAPHIC statements.

                DrawText is coming from "outside the reservation"
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  This looks promising...
                  GetTextExtentExPoint
                  The GetTextExtentExPoint function retrieves the number of characters in a specified string that will fit within a specified space and fills an array with the text extent for each of those characters. (A text extent is the distance between the beginning of the space and a character that will fit in the space.) This information is useful for word-wrapping calculations.
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    Originally posted by Michael Mattias View Post
                    I don't see how graphic redraw can work
                    yes, it's completely irrelevoneous.

                    GetTextExtentExPoint loks promising for when I graduate to PS fonts, though.

                    The technique in my code above does actually seem to work, though it looks rather clumsy.

                    Comment


                    • #11
                      Chris,

                      Q. What do you want to do?

                      A. Modify the text in the string and truncate to a specific pixel width
                      B. Just display the text truncated to a pixel width, without modifying the string
                      C. Something else entirely
                      kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                      Comment


                      • #12
                        Hello Kev, I was hoping you would chip in!

                        "B"

                        Comment


                        • #13
                          Leave out DT_MODIFYSTRING and DT_CALCRECT and the text will be clipped exactly to the rectangle you specify. If you need some aspect of the text size before output then you can use GetTextExtentPoint32 or DrawText with DT_CALCRECT.

                          Note: If you want multiple text outputs clipped in a specific area, then a region is what you need.
                          kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                          Comment


                          • #14
                            Originally posted by Kev Peel View Post
                            Leave out DT_MODIFYSTRING and DT_CALCRECT and the text will be clipped exactly to the rectangle you specify.
                            If only - see compileable code below:

                            Code:
                            ' to investigate DrawText on a GW
                            #compile exe
                            #dim all
                            #include "WIN32API.inc"
                            function pbmain () as long
                                local hgw as dword
                                local skey as string
                                local i as long
                                    local x, y as long
                                    local tempr as rect
                                    local hDC as dword
                                    local sztitle as asciz * 512
                            
                                graphic window "DrawText (ESC to end)", 100, 100, 280, 200 to hgw
                                graphic attach hgw, 0, redraw
                            
                            
                                sztitle = "HELLO MOTHER"
                                graphic color %white,%blue
                                graphic get dc to hdc
                                setrect tempr, 30, 5, 90, 20
                                drawtext hdc, byval varptr(sztitle), len(sztitle), tempr, _
                                         %DT_LEFT or %DT_SINGLELINE or %DT_END_ELLIPSIS 'or %DT_MODIFYSTRING or %DT_CALCRECT
                                graphic waitkey$ to skey
                                graphic window end
                            end function

                            Comment


                            • #15
                              I don't have any experience (at all) with PB graphics commands, but your earlier example worked, so I added the GRAPHIC REDRAW from that into your latest code and it does work. So I would put a GRAPHIC REDRAW statement after any (or batch of) drawing operations direct to the DC.

                              If this behaviour is by design then ideally it should be noted in the help file under GRAPHIC GET DC.
                              kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                              Comment


                              • #16
                                Kev, maybe I just don't understand what to expect! Is this what you see?
                                Attached Files

                                Comment


                                • #17
                                  I see what you mean. The problem was the default text alignment was not TA_LEFT. Have a gander at this:

                                  Code:
                                  #Compile Exe
                                  #Dim All
                                  #Include Once "WIN32API.inc"
                                   
                                  Function PBMain () As Long
                                   
                                      Local hgw As Dword
                                      Local skey As String
                                      Local i As Long
                                      Local x, y As Long
                                      Local tempr As rect
                                      Local hDC As Dword
                                      Local sztitle As Asciz * 512
                                   
                                      Graphic Window "DrawText (ESC to end)", 100, 100, 280, 200 To hgw
                                      Graphic Attach hgw, 0, ReDraw
                                   
                                      sztitle = "HELLO MOTHER"
                                      Graphic Color %white,%blue
                                      Graphic Get DC To hdc
                                   
                                      ' ----Start of GDI code----------------------------------------------
                                      SaveDC(hDC)
                                      SetTextAlign(hDC, %TA_LEFT)
                                      setrect tempr, 30, 10, 100, 40
                                      drawtext hdc, ByVal VarPtr(sztitle), Len(sztitle), tempr, _
                                               %DT_LEFT Or %DT_SINGLELINE Or %DT_END_ELLIPSIS
                                      RestoreDC(hDC, -1)
                                      ' ----End of GDI code----------------------------------------------
                                   
                                      Graphic ReDraw
                                      Graphic Waitkey$ To skey
                                      Graphic Window End
                                   
                                  End Function
                                  PS. Remember that SetRect and other GDI functions use pixels.

                                  PPS. You might need to restore the DC after the GDI calls, in which case a couple calls to SaveDC/RestoreDC have been added. These stack-like functions will save and restore the exact state of the DC before any changes were made, such as with SetTextAlign, SelectObject, and the like.
                                  Last edited by Kev Peel; 18 Nov 2008, 04:55 PM.
                                  kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                                  Comment


                                  • #18
                                    Originally posted by Kev Peel View Post
                                    The problem was the default text alignment was not TA_LEFT.
                                    Now you're talking. That does exactly what I want.

                                    I will drop support a line re the need for save/restoreDC.

                                    Thanks Kev!

                                    Comment


                                    • #19
                                      Originally posted by Chris Holbrook View Post
                                      I will drop support a line re the need for save/restoreDC.
                                      My question:
                                      is the saveDC/restoreDC necessary?
                                      PowerBasic's reply:

                                      If you will be changing any of the DC's state then yes.
                                      So, fellow PBCCers, now we know how to truncate text to a pixel length.

                                      Just don't tell me you knew all along!

                                      Comment


                                      • #20
                                        >Just don't tell me you knew all along!

                                        I did not know but I and found an answer in about five minutes.

                                        However, I would not have even tried to use a WinApi draw technique on the proprietary GRAPHIC window/control. I would have measured the text character by character using the provided intrinsic text measurement functions until "it don't fit no more" and printed a substring which did fit.

                                        Yes, your ultimate solution is more elegant, and it just might work with future versions of the compiler, but my client was back in production yesterday.
                                        Michael Mattias
                                        Tal Systems (retired)
                                        Port Washington WI USA
                                        [email protected]
                                        http://www.talsystems.com

                                        Comment

                                        Working...
                                        X