Announcement

Collapse
No announcement yet.

Using what GetGlyphOutline returns...

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

  • Using what GetGlyphOutline returns...

    Ok, with Dominic's help, my call to GetGlyphOutline is now returning a filled buffer and pointer to that buffer. From what I understand, this buffer is made up of a series of TTPOLYGONHEADER data structures, which are followed by as many TTPOLYCURVE data structures as required to describe the particular contour. In order to use the data in the buffer, my guess is I need to DIM a TTPOLYGONHEADER starting at the pointer, and then use information in this header to determine where I should DIM the next header, and so on. So, assuming I have this right, how does one go about overlaying structures onto this buffer?

    -CMR

  • #2
    From what I understand, this buffer is made up of a series of TTPOLYGONHEADER data structures, which are followed by as many TTPOLYCURVE data structures
    ??

    My SDK doc for GetGlyphOutline does not show that at all. Show the call with all values used .

    Well, I found this..
    The native buffer returned by GetGlyphOutline when GGO_NATIVE is specified is a glyph outline. A glyph outline is returned as a series of one or more contours defined by a TTPOLYGONHEADER structure followed by one or more curves. Each curve in the contour is defined by a TTPOLYCURVE structure followed by a number of POINTFX data points. POINTFX points are absolute positions, not relative moves. The starting point of a contour is given by the pfxStart member of the TTPOLYGONHEADER structure. The starting point of each curve is the last point of the previous curve or the starting point of the contour. The count of data points in a curve is stored in the cpfx member of TTPOLYCURVE structure. The size of each contour in the buffer, in bytes, is stored in the cb member of TTPOLYGONHEADER structure. Additional curve definitions are packed into the buffer following preceding curves and additional contours are packed into the buffer following preceding contours. The buffer contains as many contours as fit within the buffer returned by GetGlyphOutline.
    .. so you must be using GGO_NATIVE in your call.

    Meaning, you are on the correct track re your proposed access method.

    Pointer variables are used to overlay structures on a memory block
    Code:
     LOCAL pTTPH AS TTPOLYGONHEADER PTR, pTTPC as TTPOLYCURVE PTR
    
      pTTPH = Address of Header
      AnyValue =  @pTTPH.membername 
      pTTPC = @pTTPH.cpfx    ' address of first TTPOLYCURVE structure for this header
      ....
    Then you just INCR your pointer variables to 'walk the list'

    MCM
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Michael,

      What if the headers change size? This would seem to make walking quite difficult. What I mean is TTPOLYGONHEADER always seems to be the same size, but the TTPOLYCURVE structures that follow change size, depending on how many points are contained. So, the actual buffer could look like:

      TTPOLYGONHEADER <--16 bytes
      TTPOLYCURVE <--# of bytes depends on points involved
      TTPOLYCURVE <--# of bytes depends on points involved
      TTPOLYCURVE <--# of bytes depends on points involved
      TTPOLYGONHEADER <--16 bytes
      TTPOLYCURVE <--# of bytes depends on points involved
      blah
      blah
      blah

      The following link shows you what I mean: http://support.microsoft.com/kb/q87115/

      Comment


      • #4
        It's almost like a treasure hunt: Start at the big oak tree; walk six paces west. There you will find the instructions for your next move... which will get you to the next set of instructions. Follow those to the next set of instructions, and so on.

        True, walking a list of variable length elements or elements which aren't defined until you get there is more difficult than walking a list of a known qauntity of same-sized elements. But that's why programmers get the big bucks.

        BTW.. using pointer variables is now essential to your task.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          You both have the right idea but this is wrong
          Code:
          pTTPC = @pTTPH.cpfx    ' address of first TTPOLYCURVE structure for this header
          The following shows how to access the data.
          Code:
           
          FUNCTION Form1_TextBtn1_Clicked _
            ( _
            BYVAL hWndParent  AS DWORD, _ ' handle of parent window
            BYVAL hWndCtrl    AS DWORD _  ' handle of control
            ) AS LONG
          
            LOCAL szOut           AS ASCIIZ * 32768
            LOCAL GlyphMets       AS GLYPHMETRICS
            LOCAL xformation      AS MAT2
            LOCAL PolygonHeader   AS TTPOLYGONHEADER PTR
            LOCAL PolyCurve       AS TTPOLYCURVE PTR
            LOCAL PtFx            AS POINTFX PTR
            LOCAL bufferPointer   AS DWORD
            LOCAL curPointer      AS DWORD
            LOCAL endPointer      AS DWORD
            LOCAL curPoly         AS DWORD
            LOCAL endPoly         AS DWORD
            LOCAL ipfx            AS LONG
            LOCAL ihdr            AS LONG
            LOCAL ipoly           AS LONG
            LOCAL hDC             AS DWORD
            LOCAL hFont           AS DWORD
            LOCAL hOldFont        AS DWORD
            LOCAL point_size      AS LONG
            LOCAL points_per_inch AS LONG
            LOCAL pixels_per_inch AS LONG
            LOCAL logical_height  AS LONG
            LOCAL bufferSize      AS DWORD
          
            hDC = GetDC(hWndParent)
          
            point_size      =24 '30
            points_per_inch =72
            pixels_per_inch =GetDeviceCaps(hDC, %LOGPIXELSY)
          
            logical_height = -MulDiv(point_size, pixels_per_inch, points_per_inch)
          
            hFont = CreateFont(logical_height,0,0,0,0,%TRUE,0,0,%ANSI_CHARSET,0,0,0,0,"Arial")
            hOldFont=SelectObject(hDC, hFont)
          
            xformation.eM11.value   =1
            xformation.eM11.fract   =0
            xformation.eM12.value   =0
            xformation.eM12.fract   =0
            xformation.eM21.value   =0
            xformation.eM21.fract   =0
            xformation.eM22.value   =1
            xformation.eM22.fract   =0
          
            bufferSize=GetGlyphOutline(hDC, ASC("j"), %GGO_NATIVE, GlyphMets, 0, BYVAL %NULL, xformation)
            MSGBOX FORMAT$(bufferSize)
            bufferPointer = HeapAlloc(GetProcessHeap(), %HEAP_ZERO_MEMORY, bufferSize)
            IF bufferPointer THEN
              IF GetGlyphOutline(hDC, ASC("j"), %GGO_NATIVE, GlyphMets, bufferSize, BYVAL bufferPointer, xformation) <> %GDI_ERROR THEN
                OPEN "Glyph.txt" FOR OUTPUT AS #1      
                curPointer = bufferPointer
                endPointer = curPointer + bufferSize
                
                ' Walk PolygonHeader structs 
                WHILE curPointer < endPointer
                  ' Get PolygonHeader at current address
                  PolygonHeader = curPointer
                  endPoly = curPointer + @PolygonHeader.cb
                  ' Get first PolyCurve associated with current PolygonHeader
                  curPoly = curPointer + SIZEOF(@PolygonHeader)
                  
                  szOut = "TTPOLYGONHEADER #" + FORMAT$(ihdr + 1) + $CRLF + _
                          "cb      " + $TAB + "= " + FORMAT$(@PolygonHeader.cb) + $CRLF + _
                          "dwType  " + $TAB + "= " + FORMAT$(@PolygonHeader.dwType) + $CRLF + _
                          "pfxStart" + $TAB + "= " + FORMAT$(@PolygonHeader.pfxStart.x.value) + "." + FORMAT$(@PolygonHeader.pfxStart.x.fract * 100 \ 65536) + "," + _
                                                    FORMAT$(@PolygonHeader.pfxStart.y.value) + "." + FORMAT$(@PolygonHeader.pfxStart.y.fract * 100 \ 65536) + $CRLF
                  PRINT #1, szOut
                  
                  ' Walk PolyCurve structs
                  WHILE curPoly < endPoly
                    PolyCurve = curPoly
          
                    szOut = "TTPOLYCURVE #" + FORMAT$(ipoly + 1) + $CRLF + _
                            "wType" + $TAB + "= " + FORMAT$(@PolyCurve.wType) + $CRLF + _
                            "cpfx " + $TAB + "= " + FORMAT$(@PolyCurve.cpfx) 
                    PRINT #1, szOut
                  
                    SELECT CASE @PolyCurve.wType
                      CASE %TT_PRIM_LINE
                        PtFx = curPoly + 4
                        ipfx = 0
                        
                        ' Walk POINTFX structs
                        WHILE ipfx < @PolyCurve.cpfx
                          szOut = "apfx[" + FORMAT$(ipfx) + "]" + $TAB + "= " + _
                                            FORMAT$(@PtFx[ipfx].x.value) + "." + FORMAT$(@PtFx[ipfx].x.fract * 100 \ 65536) + "," + _
                                            FORMAT$(@PtFx[ipfx].y.value) + "." + FORMAT$(@PtFx[ipfx].y.fract * 100 \ 65536) 
                          PRINT #1, szOut
                          INCR ipfx
                        WEND
                        
                        PRINT #1, $CRLF
                        
                      CASE %TT_PRIM_QSPLINE : PRINT #1, $CRLF
                      CASE %TT_PRIM_CSPLINE : PRINT #1, $CRLF
                    END SELECT
          
                    INCR ipoly
                    curPoly = curPoly + 4 + @PolyCurve.cpfx * SIZEOF(@PtFx)
                  WEND
          
                  INCR ihdr
                  curPointer = curPointer + @PolygonHeader.cb
                WEND
                
                CLOSE #1
              END IF
              HeapFree GetProcessHeap(), 0, bufferPointer
            END IF
          
            DeleteObject(SelectObject(hDC, hOldFont))
            ReleaseDC(hWndParent,hDC)
          
          END FUNCTION
          Last edited by Dominic Mitchell; 29 Jan 2008, 06:41 AM. Reason: Conversion error
          Dominic Mitchell
          Phoenix Visual Designer
          http://www.phnxthunder.com

          Comment

          Working...
          X
          😀
          🥰
          🤢
          😎
          😡
          👍
          👎