Using LineDDA to produce complex line styles

Environment: Windows NT 3.1-4.0, Windows 95/98 (not supported on CE)

Introduction:

A Very old method for generating complex line styles is the use of the Win32 API call "LineDDA". LineDDA can be used to create dashed or dotted lines, as well as more complex graphics such as wavy lines or "Railroad Tracks".

This method was first made available with Windows NT 3.1 and is currently supported by Windows 95/98. (Not Supported by Windows CE)

LineDDA is a GDI32 library call that takes a set of line coordinates, an address to a callback function and a pointer to some user data with the following signature: (Taken from the GDI: Platform SDK)


BOOL LineDDA(
             int nXStart,             // x-coordinate of line's starting point
             int nYStart,             // y-coordinate of line's starting point
             int nXEnd,               // x-coordinate of line's ending point
             int nYEnd,               // y-coordinate of line's ending point
             LINEDDAPROC lpLineFunc,  // pointer to callback function
             LPARAM lpData            // pointer to application-defined data
             );

The callback function has the signature: (Taken from the GDI: Platform SDK)


VOID CALLBACK LineDDAProc(
                          int X,          // x-coordinate of point being evaluated
                          int Y,          // y-coordinate of point being evaluated
                          LPARAM lpData   // pointer to application-defined data
                          );

Concept:

Basic use requires that LineDDA be called with the coordinates of the line segment, the address of the LineDDAProc and some User defined data and GDI will call the LineDDAProc for every calculated point on the line. (Excluding the Endpoint)

LineDDA is not a Graphics routine in that it does not draw anything, but rather is a support routine used to set up the callback stream. (DDA stands for Digital Differential Analyzer) Because of this, the line will always be calculated using default transformations and mapping modes applied to the current display resolution. Manual Transformation of the X and Y values passed to the LineDDAProc if other than the defaults are used.

Implementation:

A basic implementation would have a call to LinDDA in the "OnDraw" method passing in a static or global pointer to a function that would draw whatever interesting lines styles that the solution required:


void CSimpleView::OnDraw(CDC* pDC)
{
    //Implementation Note: it is safe to pass our local reference
    //of the pDC object because all of the callbacks will complete
    //before the pDC goes out of scope.
    
    CSimpleDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    
    //Draw a Line
    pDC->MoveTo(10,10);
    pDC->LineTo(300,300);
    
    //Use LineDDA to Draw 0's at intervals along the line.
    ::LineDDA(10,10,300,300,(LINEDDAPROC)DrawZero,(long)pDC);
    
}

VOID CALLBACK DrawZero(int X,int Y,LPARAM lpData)
{
    //This Callback routine will be called for every calculated
    //point in the line.
    
    //Implementation Note: Use lpData to pass a reference to a
    //CDC object for drawing.
    
    CDC* pDC;
    pDC = (CDC*)lpData;
    
    if( X % 20 ==0)
    {
        pDC->TextOut(X,Y,_T("0"));
    }
    
}

This treatment would have acceptable performance in very simple situations but under more rigorous application, would not be sufficient.

A better approach would be to use this method to precalculate points for later use in the OnDraw method. If the points are static, this would only be performed once.

Conclusion:

LineDDA can provide a solution to problems requiring more complex line styles. This is a Win32 solution and is currently not supported directly by MFC. (Probably because it is not used very much) As a general solution it may not prove to be very useful but it will solve some very unique problems for which no other direct solution exists.

Further Reading:

The Win32 SDK contains an average amount of documentation on this method. MSDN Knowledge Base contains several examples of how to use LineDDA to create some interesting affects. One sample actually used LineDDA to draw the cell lines for a simple spreadsheet program. (Article ID: Q68301)



Comments

  • Why aren't we using CPen to create textured lines?

    Posted by Legacy on 12/10/2002 12:00am

    Originally posted by: graber

    For all the searching that I have done I don't find anyone using CPen to Create textured lines. I have to ask why? Is it really that difficult to use? Are there no clear cut examples? For all my looking THERE AREN'T. Could someone shed some light on my Microsoft frustrations. How about you Bill Gates? Naw I didn't think so.

    Reply
  • LineDDA is too restrictive

    Posted by Legacy on 10/01/1999 12:00am

    Originally posted by: Feng Yuan

    1) LineDDA works only with straight lines
    2) LineDDA works in logical coordinate space, not device
    coordinate space
    3) LineDDA callback routine does not give you sense of
    line direction, so you can't draw something like
    a dash, although dots or any symmetric shapes are OK.

    Reply
  • SetPixel is slow!

    Posted by Legacy on 08/24/1999 12:00am

    Originally posted by: Niki Estner

    The problem with LineDDA isn't that the function itself is slow. It (probably) uses the bresenham-algorithm, which is considerably fast. (3 or 4 addition per pixel)
    The two reasons why this usage has poor performance is, that (1) a function call to the callback takes some time and (2) SetPixel does a multiplication (per pixel). (mapping modes, etc not included)
    So, saving the pixels in an array or something will not help.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • On-demand Event Event Date: September 17, 2014 Another day, another end-of-support deadline. You've heard enough about the hazards of not migrating to Windows Server 2008 or 2012. What you may not know is that there's plenty in it for you and your business, like increased automation and performance, time-saving technical features, and a lower total cost of ownership. Check out this webcast and join Rich Holmes, Pomeroy's practice director of virtualization, as he discusses the future state of your servers, …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds