On Friday 22 February 2002 10:56 am, Jean-Marc Lasgouttes wrote:
> >>>>> "Angus" == Angus Leeming <[EMAIL PROTECTED]> writes:
> 
> >>  Another question: why do we need grayscale/mono rendering?
> >> Shouldn't we just display the figure as well as the display
> >> permits? This seems very complicated for a small gain...
> 
> Angus> Because people ask for it? Anyway, it's about 40 lines of code.
> 
> OK, if it is so short, we can handle that. And how do you make sure
> that we limit the number of colors on 8bits display? Do the xpms have
> a common palette?

No, I have done nothing like that. I suspect that is what John was talking 
about with XpmAllocCloseCloseColors, but I'm not going to investigate further 
as all woks fine on my TrueColor display.

I have simply given the pixmap an m_color and g_color array to go with it's 
c_color one.

        if (attrib.color_key == XPM_MONO) {
                XpmColor * table = xpm_image_->colorTable;

                for (int i = 0; i < xpm_image_->ncolors; ++i) {
                        // If the c_color is defined and the equivalent
                        // monochrome one is not, then define it.
                        if (table[i].c_color && !table[i].m_color) {
                                table[i].m_color =
                                        mapcolor(table[i].c_color, false);
                        }
                }
        }

where 

// Given a string of the form #ff0571 create a string for the appropriate
// grayscale or monochrome color.
char * mapcolor(char * color, bool toGray)
{
        if (!color)
                return 0;
        
        Display * display = GUIRunTime::x11Display();
        Colormap cmap     = GUIRunTime::x11Colormap();
        XColor xcol, ccol;
        if (XLookupColor(display, cmap, color, &xcol, &ccol) == 0)
                // Fail gracefully in the color is called "none".
                return 0;

        // Note that X stores the RGB values in the range 0 - 65535
        // whilst we require them in the range 0 - 255.
        int const r = xcol.red   / 256;
        int const g = xcol.green / 256;
        int const b = xcol.blue  / 256;

        // This gives a good match to a human's RGB to luminance conversion.
        // (From xv's Postscript code --- Mike Ressler.)
        int mapped_color = (0.32 * r) + (0.5 * g) + (0.18 * b);
        if (!toGray) // monochrome
                mapped_color = (mapped_color < 128) ? 0 : 255;

        ostringstream ostr;

        ostr << "#" << std::setbase(16) << std::setfill('0')
             << std::setw(2) << mapped_color
             << std::setw(2) << mapped_color
             << std::setw(2) << mapped_color;

        // This string is going into an XpmImage struct, so create a copy that
        // libXPM can free successfully.
        string str = ostr.str();
        char * result = (char *)malloc(str.size()+1); // don't forget '\0'
        strcpy(result, str.c_str());
        return result;
}

Reply via email to