KColor is coming this Monday...

Zack Rusin zack at kde.org
Sat May 26 08:54:38 BST 2007


On Friday 25 May 2007 02:49:24 pm Matthew Woehlke wrote:
> > The differences between HSL and HSV colorspaces are
> > pretty minuscule from the point of view of applications, almost
> > non-existant.
>
> Um... no, there is actually quite a big difference between HSV and
> HS[LY]. In the former, you cannot make Qt::red any brighter. In the
> latter you can make anything except Qt::white brighter. That's pretty
> much the main point; lighten() and darken() do not really work correctly
> in HSV color space which is why QColor::lighten() and QColor::darken()
> are broken IMO.

I'm not sure where you got that, but luckily in the last email I've sent out 
that example that proves this is absolutely not the case. (you can see QColor 
lightning Qt::red, Qt::blue and Qt::green producing identical results to 
KColor).

> > Now moving forward to the blend method. I think it's a neat addition.
> > What I think is pretty silly is introducing another API and another
> > implementation on top of what Qt already does and provides.
>
> I've been asking for months where to find blend() in Qt. No one has told
> me, and I haven't found one. Therefore I fail to see how you can say
> that Qt already provides this. In fact, since you subsequently give an
> example of how to implement blend() anyway, rather than referring me to
> an existing function in Qt, I can only assume that as far as you know,
> there is no such function in Qt.

I'm talking about blending in general. Implementing a blendColors method in Qt 
just hasn't been a high priority for any of us given that you can trivially 
do it in about 10 lines of code. 

> > What I think would be a lot better idea is introducing a class/namespace
> > called KGraphicsUtils or similar and adding blendColor method to it.
>
> If Qt supported HSL and HSY color spaces I would probably do that, or at
> minimum I would not be making KColor as complex as it is. I wouldn't
> need to.

Why would it? Really. We have a very long list of things we have to do, every 
feature I implemented comes with an obvious benefits to the users of Qt.
"Support HSL colorspace" is not a feature request. It's not a feature requests 
because it doesn't come with any obvious benefits. "Make darken/lighten 
methods work in foo scenario", is a feature requests (that possibly can be 
implemented by adding HSL support). 
The only problem is that, again, as the example showed QColor's darken/lighten 
methods work. They work very well in fact. So yeah, there's simply not enough 
reason to justify that new code in Qt.

> Ok, so you addressed the horrible performance profile, thanks for making
> me feel more complicated about all the heavy math KColor is doing ;-).

What was it on your machine? 10000 calls in 670ms? So 100 calls (the amount I 
don't see any application realisitically making) would take ~6ms... And 
you're saying applications don't have 6ms to spare? (That is a rhetorical 
question, please don't feel the need to follow with a long response :) ).

> You didn't address that this also suffers the same *limits* as Qt, nor
> is it able to operate in color spaces other than RGB.

You want to be doing composition in other colorspaces than *RGB? There's so 
many sarcastic jokes I could say about that =) It's a bad, bad idea. Those 
operators will not be closed. In the same way that operator Over (which you 
called BlendAlpha) is not closed on non-premultiplied alpha.

> > It's a really bad idea because it means that KDE
> > developers will by default use this class and when they do they introduce
> > losy conversions all the time. The bottom line is that to paint KDE
> > applications need to convert to QColor at some point anyway. So the usage
> > of KColor in most cases will be.
> > 1) Convert QColor to KColor (due to differences in the way these classes
> > internally store colors, that's already one lossy conversion)
>
> If you looked at the code for KColor and QColor you would know that this
> is actually totally untrue. QColor uses 16 bits to store color
> information (and frequently only 8 are set), whereas KColor uses
> something like 48*. Funny, that doesn't /sound/ lossy :-).

It doesn't matter how many bits you have. You're going from exact 
representation to a finite-mentissa double by dividing by 255 (or USHRT_MAX). 
Of course you loose precisiion, the only question is whether it's enough to 
affect the transition back. And yes, assuming you haven't been fiddling too 
much with it you should end up with the same 16bit integer after converting 
back.

> This is the only truly "lossy" conversion... except that last I checked
> X is 8bpp anyway, so you're being reduced to 8bpp no matter what. This
> entire 'loss of precision' argument is just FUD.

No, it points out very important aspect of this discussion. You're arguing for 
HSL based on the fact that it is mathematically correct, I'm showing you that 
by sheer introduction of a new color class nothing is perfectly correct. 
This is the bottom line, in computer graphics, things are never perfectly 
correct, they just need to be visually close enough. 
I think it's beyond a shadow of doubt that QColor lighten/darken are good 
enough and introduction of a new color class just for that doesn't make any 
sense.

> > - If there are applications that would really like to see darkening of
> > colors producing shades of gray instead of deep color then addition of
> > QColor KGraphicsUtils::darkenInHsl(const QColor &clr, qreal val);
> > QColor KGraphicsUtils::lightenInHsl(const QColor &clr, qreal val);
> > would make some sene. It wouldn't make any real difference in terms of
> > speed because the to-from QColor rgb conversion has to apply in any case
> > anyway and it wouldn't introduce a very prominently named class that
> > would make the transition to a lot more interesting addition, like
> > Pigment, a lot more confusing in the future)
>
> So in short, you would like to name KColor something else. :-) Any
> suggestions?

Oh, yeah, personally I'd love to see:
QColor KGraphicsUtils::blendColors(const QColor &one,
             const QColor &two,
            QPainter::CompositionMode mode =    
                  QPainter::CompositionMode_SourceOver);
and possibly (maybe initially somewhere outside kdelibs until it's actually 
proven without a doubt that it's useful for anyone)
QColor KGraphicsUtils::darkenInHls(cons QColor &, qreal scale);
QColor KGraphicsUtils::lighteninHls(const QColor &, qreal scale);

That's because, like I mentioned none of the things you mentioned requires a 
whole new color class. And again, that's kind of my bottom line. 

Zack




More information about the kde-core-devel mailing list