Thread: Draw line with multicolor

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    4

    Draw line with multicolor

    Hello. I need draw many lines with multicolor (color is set bysome pixmap (xpm))
    on C++ with standart libs.

    Horizontal lines are drawing succsessfully with GC and XSetTile.
    But non-horizontal - no good. I rotate pixmap for all lines and then
    XSetTile for each line with own pixmap, but it's bad idea.

    How I can do this with standard libraries (xlib only. Without Qt, OpenGL etc.)?

  2. #2
    Registered User
    Join Date
    Jan 2013
    Posts
    4
    Done.
    For calculate lines used Bresenham's algorithm.

    Code:
    #include <math.h>
    #include <X11/Xlib.h>
    #include <X11/xpm.h>
    #include <stdlib.h>
    
    
    void XDrawLineFillXpm(XPoint start, XPoint end,
                   Display *disp, Drawable d, GC gc, Pixmap pmap, Pixmap mask)
    {    
        signed char dir[2];     // direction of the line ([0]:x; [1]:y)
        unsigned short delta[2];   // dx; dy
        unsigned char base = 0;   // base coord (that changed faster)
        short error;      // sum error
        short pos[2][2];  // curr & end positions
    
    
        static Pixmap currPmap = NULL;  // color of line
        static XpmImage xpmImage;       // xpm color of line
        unsigned short currColor = 0;
        unsigned short currLine = 0;
        static unsigned short currXInd = 0;
        char colorHex[6];
        static unsigned long *colorLong = NULL;
        unsigned int prevIndex = 0;
        unsigned short startCoord = 0;
        unsigned short val = 0;
        static XPoint prevEndPoint = {-1,-1};
    
    
        if (prevEndPoint.x != start.x
                || prevEndPoint.y != start.y)
            prevIndex = 0;
        else
            prevIndex = currXInd;
    
    
        // New pixmap? -> Read color & xpm
        if (currPmap != pmap)
        {
            currPmap = pmap;
            XpmCreateXpmImageFromPixmap(disp, pmap, mask, &xpmImage, NULL);
    
    
            if (colorLong != NULL)
                free(colorLong);
            colorLong = (unsigned long*)malloc(xpmImage.ncolors);
    
    
            for (currXInd = 0; currXInd < xpmImage.ncolors; currXInd++)
            {
                colorHex[0] = xpmImage.colorTable[currXInd].c_color[1];
                colorHex[1] = xpmImage.colorTable[currXInd].c_color[2];
                colorHex[2] = xpmImage.colorTable[currXInd].c_color[5];
                colorHex[3] = xpmImage.colorTable[currXInd].c_color[6];
                colorHex[4] = xpmImage.colorTable[currXInd].c_color[9];
                colorHex[5] = xpmImage.colorTable[currXInd].c_color[10];
    
    
                colorLong[currXInd] = strtol(colorHex, NULL, 16);
            }
            currXInd = 0;
        }
    
    
        // take direction
        delta[0] = (end.x > start.x ? (dir[0] = 1, end.x - start.x)
                                        : (dir[0] = -1, start.x - end.x)) << 1; //*2
        delta[1] = (end.y > start.y ? (dir[1] = 1, end.y - start.y)
                                        : (dir[1] = -1, start.y - end.y)) << 1;
    
    
        // If 'y' changed faster than 'x'
        if (delta[1] > delta[0])
            base = 1;
    
    
        XSetFillStyle(disp, gc, FillSolid);
    
    
        // Num of lines = Height
        for (currLine = 0; currLine < xpmImage.height; currLine++)
        {
            if (xpmImage.height > 1)
                startCoord = (xpmImage.height >> 1) - currLine;
            else
                startCoord = 0;
    
    
            // Fill all colors for each line
            for (currColor = 0; currColor < xpmImage.ncolors; currColor++)
            {
                pos[0][0] = start.x;
                pos[0][1] = start.y;
                pos[1][0] = end.x;
                pos[1][1] = end.y;
    
    
                // Recalculate start & end points
                if (base) // y is base coord
                {
                    val = startCoord*dir[base];
                    pos[0][1-base] += val;
                    pos[1][1-base] += val;
                }
                else // x is base coord
                {
                    val = startCoord*dir[base]*(-1);
                    pos[0][1-base] += val;
                    pos[1][1-base] += val;
                }
    
    
                // Set new color for points
                XSetForeground(disp, gc, colorLong[currColor]);
                currXInd = prevIndex; // load previous index for each color
    
    
                if (xpmImage.data[currLine*xpmImage.width + currXInd++] ==
                        currColor)
                    XDrawPoint(disp, d, gc, pos[0][0], pos[0][1]);
    
    
                if (currXInd >= xpmImage.width)
                    currXInd = 0;
    
    
                error = delta[1-base] - (delta[base] >> 1);
    
    
                while(pos[0][base] != pos[1][base])
                {
                    if (error >= 0)
                    {
                        if (error || dir[base] > 0)
                        {
                            pos[0][1-base] += dir[1-base]; //change pos by no-base
                            error -=delta[base];
                        }
                    }
    
    
                    pos[0][base] += dir[base];  // change pos by base coord
                    error += delta[1-base];
    
    
                    if (xpmImage.data[currLine*xpmImage.width + currXInd++] == currColor)
                        XDrawPoint(disp, d, gc, pos[0][0], pos[0][1]);
                    if (currXInd >= xpmImage.width)
                        currXInd = 0;
                }
            }
        }
    
    
        prevEndPoint = end;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How can i draw a line?
    By brack in forum C Programming
    Replies: 10
    Last Post: 10-20-2010, 12:20 PM
  2. multicolor dialog & multicolor text
    By lambs4 in forum Windows Programming
    Replies: 14
    Last Post: 12-16-2002, 01:40 PM
  3. draw line function
    By yakir in forum C Programming
    Replies: 5
    Last Post: 09-10-2002, 02:08 PM
  4. Draw Line Between Two Points
    By Shadow12345 in forum C++ Programming
    Replies: 4
    Last Post: 05-18-2002, 08:23 AM
  5. Draw a line...??
    By Gugge in forum C Programming
    Replies: 3
    Last Post: 04-07-2002, 07:15 AM