No announcement yet.

Using what GetGlyphOutline returns...

  • Filter
  • Time
  • Show
Clear All
new posts

  • Dominic Mitchell
    You both have the right idea but this is wrong
    pTTPC = @pTTPH.cpfx    ' address of first TTPOLYCURVE structure for this header
    The following shows how to access the data.
    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 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
                  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)
            INCR ihdr
            curPointer = curPointer + @PolygonHeader.cb
          CLOSE #1
        END IF
        HeapFree GetProcessHeap(), 0, bufferPointer
      END IF
      DeleteObject(SelectObject(hDC, hOldFont))
    Last edited by Dominic Mitchell; 29 Jan 2008, 06:41 AM. Reason: Conversion error

    Leave a comment:

  • Michael Mattias
    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.


    Leave a comment:

  • C.M. Rouleau

    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

    The following link shows you what I mean:

    Leave a comment:

  • Michael Mattias
    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
      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'


    Leave a comment:

  • C.M. Rouleau
    started a topic Using what GetGlyphOutline returns...

    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?