Draw multicolor line


 
Thread Tools Search this Thread
Top Forums Programming Draw multicolor line
# 1  
Old 01-10-2013
Draw multicolor line

Hello. I need to draw many lines with multicolor (color is set by some 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  
Old 01-11-2013
Done.
For calculate lines used Bresenham's algorithm.

Code:
#include <math.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <stdlib.h>
#include "bresDraw.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;
}

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. What is on Your Mind?

Football / Soccer World Cup 2018 draw.

What is on Your Mind? 2018 FIFA World Cup - Wikipedia I'm hoping that England are drawn into positions B2, D3, G3 or G4 so that all their games will be outside usual UK office hours and people will not desert the office with mystery illnesses to watch the games. Expecting failure, so I... (1 Reply)
Discussion started by: rbatte1
1 Replies

2. Shell Programming and Scripting

How can draw line on Ubuntu, shell programming?

https://www.unix.com/attachment.php?attachmentid=6304&d=1432179166 how can draw line like this? on ubuntu, shell programming. i tried "-" , " l " but it's failed.. (2 Replies)
Discussion started by: gotit
2 Replies

3. Programming

Draw Bar Graph for GNUPLOT

For example, I have a file called data.txt. And the content is: Iker_Casillas 181 Raphael_Varane 182 Sergio_Ramos 182May I know how to write a script for gnuplot, so I can have a bar graph as the column 1 will be the x and column 2 will be the y? And I hope that the x value can be seen clearly.... (0 Replies)
Discussion started by: Tzeronone
0 Replies

4. What is on Your Mind?

Do you draw flowcharts

Do you draw flowcharts while you do the programming , design new network or simmilar ? (8 Replies)
Discussion started by: solaris_user
8 Replies

5. Programming

Draw a 3D cylinder using openGL.

Hi, please give me, how to code to draw 3D cylinder in openGL, that should be rotated in x-direction. waiting for your reply .. (2 Replies)
Discussion started by: Ravikishore
2 Replies

6. Ubuntu

How to draw cylinder using openGL

Hi Sir, i am new to openGL, i want to know how to draw cylinder using openGL code in C or C++.. And i have to insert bitmap images on cylinder.. How to do this .. please guide me ... Thanking You in advance .. (0 Replies)
Discussion started by: Ravikishore
0 Replies

7. UNIX and Linux Applications

Corel Draw like software for Ubuntu

Hi guys, I need a software for Ubuntu *which has the capabilities of Corel Draw *which can open/import and use a .cdr template, i.e., template created by Corel Draw. *which has the same color codes, i.e., names for colors I have looked through Google, some suggested ones are Inkscape,... (7 Replies)
Discussion started by: apprentice
7 Replies

8. Shell Programming and Scripting

Is it possible to draw table/matrix using shell script?

Hi all, I need to create a matrix of variable rows and columns. Right now i have 3 rows and two columns and following values. Output something like TypeA TypeB TestCase1 Pass Fail TestCase2 Pass ... (2 Replies)
Discussion started by: jakSun8
2 Replies

9. Shell Programming and Scripting

Draw a Horizontal and Vertical line on UNIX

I want to draw a horizontal and vertical line on Unix. Please suggest some solution. (11 Replies)
Discussion started by: allways4u21
11 Replies

10. Solaris

draw graphics to stdout in solaris

Hi all.. I am trying to draw a line on the monitor on sun platform machine. I tried a simple program. #include<stdio.h> #include<plot.h> int main() { openpl(); linemod("dotted"); line(1000,1000,2000,2000); closepl(); return 0; } It doesn't produce the desired result. If one... (0 Replies)
Discussion started by: shivamasam
0 Replies
Login or Register to Ask a Question