Re: [Development] Proposal: Make QPen non-cosmetic by default
On 10/11/2012 02:22 PM, Sorvig Morten wrote: On Oct 11, 2012, at 10:58 AM, Bache-Wiig Jens jens.bache-w...@digia.com wrote: I have personally never seen an actual use case where a cosmetic pen makes sense, but I assume there are reasons for having i so anyone creating an explicit QPen(Qt::black, 0.0) should get a 1.0 pixel thick line regardless of scaling. I agree in general. I'm wondering if a 2 pixel-wide line for QPen(Qt::black, 0.0) would be a better option in high-dpi mode - the user is expecting to fill one point. The result will look like a scaled pixmap, but won't have gaps. Morten You mean a 1 logical pixel-wide line? ;) But yeah, agreed, for high-dpi mode it will make sense that everything gets scaled by 2x2, both cosmetic and geometric lines, for the sake of consistency. The result will look like a scaled pixmap - well, an antialiased non axis aligned line will still look sharp, unlike a scaled pixmap. but won't have gaps, that depends, if you're mixing line drawing and rectangle filling you might have gaps. Example: painter-setPen(Qt::black); painter-drawLine(0, 0, 10, 0); painter-fillRect(0, 1, 10, 1, Qt::black); Since lines and other outlines are centered on the pixel grid lines instead of in the pixel centers, if you scale this by 2x2 you will get the line filling the device rectangle starting at QPoint(0, -1) with a size QSize(20, 2), whereas the rect fills the device rectangle starting at QPoint(0, 2) with a size QSize(20, 2). Thus, there would be a one pixel horizontal gap starting at QPoint(0, 1) with size QSize(20, 1). If the line is clipped by the widget it will visibly only be one pixel high, whereas the rectangle will be two pixels high. This way of mixing line drawing and filling in style code is therefore pretty evil, but unfortunately we do it in a lot of places. Most drawLine() calls in the style should really be replaced with calls to fillRect(). That's the curse of the 0.5 pixel offset between fills and strokes, and not writing the style code with scalability in mind. -- Samuel ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Wed, 17 Oct 2012 16:47:00 +0200, Samuel Rødal wrote: Seems to me to be the best compromise to avoid completely breaking too much existing code. I don't agree - it is going to break many applications doing graphics and PDF export for a micro modification that isn't much better than the existing API. Is this really worth the incompatibility ? Please have in mind that for Qwt I will have the problem that all pens are created in application code, while the painter ( and its render hints ) is usually created inside of the Qwt library. An exception are f.e. report generators: here the exported plot is part of a document and the application creates the painter passing it together with a target rectangle to Qwt. I have no idea how to hide the incompatibility inside of the Qwt library. I'm afraid in the end it will be something every Qwt application has to handle manually. Uwe ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Oct 12, 2012, at 6:31 PM, Tony Van Eerd tvane...@rim.com wrote: I think Windows also uses 0-width to mean the same thing. On the other hand, I worked on a drawing library that used sub-pixel lines. Via good anti-aliasing, A 0.5 width line, even if vertical/horizontal, would be drawn semi-transparent. A 0-width line would thus be invisible. Qt 4.8 and 5.0 are actually doing this when using the raster paint engine. The exception is that 0 jumps back to 1 due to the definition of QPen. Cheers, Lars -Original Message- From: development-bounces+tvaneerd=rim@qt-project.org [mailto:development-bounces+tvaneerd=rim@qt-project.org] On Behalf Of Samuel Rødal Sent: Friday, October 12, 2012 11:02 AM To: development@qt-project.org Subject: Re: [Development] Proposal: Make QPen non-cosmetic by default On 10/12/2012 03:17 PM, Uwe Rathmann wrote: On Fri, 12 Oct 2012 12:21:30 +, Bache-Wiig Jens wrote: After all what is the point of doing a major version unless we don't even allow ourselves to change broken defaults. There is nothing broken: it's a well defined API that behaves exactly like it is documented. Your suggestion is about modifying an illogical API. I don't know the reasons why the API was decided once the way it is - but it is so confusing, that I can't believe that it happened by accident ( being documented later ). My guess is that it was following some other system that did it this way. Originally a 0-width pen was the only way to get the cosmetic pen behavior. Later on setCosmetic() was added to be able to have any pen width be cosmetic. I guess the whole 0-width thing comes from X11, where 0 is a special value with the following documentation: Thin lines (zero line-width) are one-pixel-wide lines drawn using an unspecified, device-dependent algorithm. http://tronche.com/gui/x/xlib/GC/manipulating.html also contains this bit of documentation: A line-width of zero may differ from a line-width of one in which pixels are drawn. This permits the use of many manufacturers' line drawing hardware, which may run many times faster than the more precisely specified wide lines. In general, drawing a thin line will be faster than drawing a wide line of width one. However, because of their different drawing algorithms, thin lines may not mix well aesthetically with wide lines. If it is desirable to obtain precise and uniform results across all displays, a client should always use a line-width of one rather than a line-width of zero. So 0-width lines in X11 are not only implicitly cosmetic, but also have less strict guarantees when it comes to correctness, so that they can be optimized by custom hardware. I guess originally QPen simply mirrored this behavior, which is probably why as you noted 0-width pens are faster than 1-width pens with the X11 paint engine in 4.x. Still, I agree with Jens that the API of having 0-width pens and cosmetic pens as separate concepts is confusing. If we wanted something akin to the 0-width concept of X11 it should rather have been a render hint saying that it's acceptable for the application to get less accurate line drawing in exchange for better performance. I'm not sure how valid that use case is these days though. -- Samuel ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development - This transmission (including any attachments) may contain confidential information, privileged material (including material protected by the solicitor-client or other applicable privileges), or constitute non-public information. Any use of this information by anyone other than the intended recipient is prohibited. If you have received this transmission in error, please immediately reply to the sender and delete this information from your system. Use, dissemination, distribution, or reproduction of this transmission by unintended recipients is not authorized and may be unlawful. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Oct 12, 2012, at 3:17 PM, Uwe Rathmann uwe.rathm...@tigertal.de wrote: On Fri, 12 Oct 2012 12:21:30 +, Bache-Wiig Jens wrote: After all what is the point of doing a major version unless we don't even allow ourselves to change broken defaults. There is nothing broken: it's a well defined API that behaves exactly like it is documented. Your suggestion is about modifying an illogical API. I don't know the reasons why the API was decided once the way it is - but it is so confusing, that I can't believe that it happened by accident ( being documented later ). My guess is that it was following some other system that did it this way. In the end it is about to decide if the improvement is it worth to introduce a hard to find incompatibility to the application world. As far as I understood Jens, the reason to change this would be to avoid lots of drawing issues with High-DPI support (for e.g. the new Macs). If this is the case, we'll get into some problems whether we change the default or not. If we don't change it, the developers will likely run into issues on computers with High-DPI displays. If we change it plotting apps such as Qwt will have different issues. Both types of problems are unfortunately difficult to find when testing (as you might not test all use cases). Changing this in a minor release is obviously not going to happen so its either now or never. Thought Qt 5.0 API is already frozen - but if you really want to do it now is indeed by far the best moment for changes like this one. It's now or never really. To collect pros and cons that I've heard so far: + Logical API (to make it really logical would probably also require to make 0 width pens invisible) + Better compatibility on High-DPI displays - Breaks plotting/graphing apps/libraries (Qwt) Do we have any other arguments? Cheers, Lars ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On 10/12/2012 08:18 PM, Uwe Rathmann wrote: Qt/Embedded is the platform where you find this type of widget most what usually means a combination of the weakest hardware and the slowest graphic path. Unfortunately the implementation of the subsurfaces concept is so very broken, that embedding OpenGL is no option. Hope that using QPainter in combination with the scene graph opens a way to a faster implementation with Qt 5. Could you elaborate on what you mean regarding the implementation of the subsurfaces concept? -- Samuel ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Fri, 12 Oct 2012 10:10:59 +, Bache-Wiig Jens wrote: True. There are certainly plenty of valid use cases out there and some of those would require a minor change in Qt5 if we go ahead with this change. Basically it is about if you want to have a pen width in model or paint device coordinates. Both use cases exist and IMHO none of them is more important than the other. Most likely no more than setRenderHint(Qt::CosmeticDefaultPen, true). As long as you don't eliminate this flag I agree for Qwt. But I would have to write a lot of documentation, that pens set from the application code will be handled in Qwt differently than the user is used from other parts of the application. In fact all non-0 values for pen width are non-cosmetic by default so making only the default constructor a special case with a cosmetic pen of size 1 is arbitrary and confusing regardless if you are using a cosmetic pen or not in your application. Yes it is and I've seen several situations where this leaded to irritations - but this is how it is like many versions of Qt. If it were about introducing a new API I would completely agree, but your suggestion breaks many applications doing graphics. And worst of all it is about introducing a type of bug QA departments usually never finds ( not very likely than someone loads and zooms the exported PDF document in a PDF viewer ). Uwe By the way: in earlier versions of Qt ( didn't test it myself quite some time ) drawing with a pen width of 0 was faster than using a pen of 1 - even if it had the same result. In case of drawing a curve with many lines it was a significant effect. I never spent time on further explorations, but if it is still this way and the cosmetic attribute was the reason you might introduce a performance issues with changing the default setting as well. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
Basically it is about if you want to have a pen width in model or paint device coordinates. Both use cases exist and IMHO none of them is more important than the other. Agree on the importance on both but the inconsistency applies in both use cases. Most likely no more than setRenderHint(Qt::CosmeticDefaultPen, true). As long as you don't eliminate this flag I agree for Qwt. Yes the flag is essential to the change. But I think it is debatable if we should maintain compatibility with explicit pen size of 0. On the other hand any app that explicitly set size 0 is deliberately asking for a cosmetic pen since otherwise it would seem pretty silly. But the current behaviour makes it impossible to animate pen thickness from 1 to 0 right now. But I would have to write a lot of documentation, that pens set from the application code will be handled in Qwt differently than the user is used from other parts of the application. Right now we actually have this situation: QPen pen; // cosmetic, black 1 pixel pen.setWith(2); // magically makes it non cosmetic, black 2 pixel pen.setCosmetic(true); // back to cosmetic for real now So with introducing the explicit flag we mentioned above, you wouldn't have to deal with this inconsistency in Qwt any more. Right we we don't have this option at all when dealing with cosmetic pens so from a documentation perspective I think it would be easier than the current solution. In fact all non-0 values for pen width are non-cosmetic by default so making only the default constructor a special case with a cosmetic pen of size 1 is arbitrary and confusing regardless if you are using a cosmetic pen or not in your application. Yes it is and I've seen several situations where this leaded to irritations - but this is how it is like many versions of Qt. If it were about introducing a new API I would completely agree, but your suggestion breaks many applications doing graphics. And worst of all it is about introducing a type of bug QA departments usually never finds ( not very likely than someone loads and zooms the exported PDF document in a PDF viewer ). We will certainly not introduce a new QPainter-like API again, that is pretty certain so we are stuck with improving on what we have. (unless you count the canvas API in qt5) I still think it is worth updating the few issues that are broken when we are doing a new major version of Qt and we are already looking into changing some of the other inconsistencies in QPainter. After all what is the point of doing a major version unless we don't even allow ourselves to change broken defaults. Changing this in a minor release is obviously not going to happen so its either now or never. If the change is documented properly I think it is worth it. But this it is obviously still up for discussion. I never spent time on further explorations, but if it is still this way and the cosmetic attribute was the reason you might introduce a performance issues with changing the default setting as well. I will leave that question for the graphics guys. I find it really strange that the performance impact of this would be significant and doubt that this is currently the case but I could easily be mistaking. Jens ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Fri, 12 Oct 2012 12:21:30 +, Bache-Wiig Jens wrote: I will leave that question for the graphics guys. I find it really strange that the performance impact of this would be significant and doubt that this is currently the case but I could easily be mistaking. In Qwt I have an example called refreshtest that simply draws a curve as often as possible counting how many repaint events can be processed - nothing high sophisticated. I did a quick test with Qt 4.8.1 on my linux box with a curve of 1000 points: X11/pen width 0: ~480 fps X11/pen width 1: ~215 fps Raster/pen width 0/1: ~100 fps Sorry I don't have a Qt5 installation here - and yes I'm not happy that raster has become the default setting on X11. Uwe ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Fri, 12 Oct 2012 12:21:30 +, Bache-Wiig Jens wrote: After all what is the point of doing a major version unless we don't even allow ourselves to change broken defaults. There is nothing broken: it's a well defined API that behaves exactly like it is documented. Your suggestion is about modifying an illogical API. I don't know the reasons why the API was decided once the way it is - but it is so confusing, that I can't believe that it happened by accident ( being documented later ). My guess is that it was following some other system that did it this way. In the end it is about to decide if the improvement is it worth to introduce a hard to find incompatibility to the application world. Changing this in a minor release is obviously not going to happen so its either now or never. Thought Qt 5.0 API is already frozen - but if you really want to do it now is indeed by far the best moment for changes like this one. Uwe ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On 10/12/2012 03:17 PM, Uwe Rathmann wrote: On Fri, 12 Oct 2012 12:21:30 +, Bache-Wiig Jens wrote: After all what is the point of doing a major version unless we don't even allow ourselves to change broken defaults. There is nothing broken: it's a well defined API that behaves exactly like it is documented. Your suggestion is about modifying an illogical API. I don't know the reasons why the API was decided once the way it is - but it is so confusing, that I can't believe that it happened by accident ( being documented later ). My guess is that it was following some other system that did it this way. Originally a 0-width pen was the only way to get the cosmetic pen behavior. Later on setCosmetic() was added to be able to have any pen width be cosmetic. I guess the whole 0-width thing comes from X11, where 0 is a special value with the following documentation: Thin lines (zero line-width) are one-pixel-wide lines drawn using an unspecified, device-dependent algorithm. http://tronche.com/gui/x/xlib/GC/manipulating.html also contains this bit of documentation: A line-width of zero may differ from a line-width of one in which pixels are drawn. This permits the use of many manufacturers' line drawing hardware, which may run many times faster than the more precisely specified wide lines. In general, drawing a thin line will be faster than drawing a wide line of width one. However, because of their different drawing algorithms, thin lines may not mix well aesthetically with wide lines. If it is desirable to obtain precise and uniform results across all displays, a client should always use a line-width of one rather than a line-width of zero. So 0-width lines in X11 are not only implicitly cosmetic, but also have less strict guarantees when it comes to correctness, so that they can be optimized by custom hardware. I guess originally QPen simply mirrored this behavior, which is probably why as you noted 0-width pens are faster than 1-width pens with the X11 paint engine in 4.x. Still, I agree with Jens that the API of having 0-width pens and cosmetic pens as separate concepts is confusing. If we wanted something akin to the 0-width concept of X11 it should rather have been a render hint saying that it's acceptable for the application to get less accurate line drawing in exchange for better performance. I'm not sure how valid that use case is these days though. -- Samuel ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
I think Windows also uses 0-width to mean the same thing. On the other hand, I worked on a drawing library that used sub-pixel lines. Via good anti-aliasing, A 0.5 width line, even if vertical/horizontal, would be drawn semi-transparent. A 0-width line would thus be invisible. -Original Message- From: development-bounces+tvaneerd=rim@qt-project.org [mailto:development-bounces+tvaneerd=rim@qt-project.org] On Behalf Of Samuel Rødal Sent: Friday, October 12, 2012 11:02 AM To: development@qt-project.org Subject: Re: [Development] Proposal: Make QPen non-cosmetic by default On 10/12/2012 03:17 PM, Uwe Rathmann wrote: On Fri, 12 Oct 2012 12:21:30 +, Bache-Wiig Jens wrote: After all what is the point of doing a major version unless we don't even allow ourselves to change broken defaults. There is nothing broken: it's a well defined API that behaves exactly like it is documented. Your suggestion is about modifying an illogical API. I don't know the reasons why the API was decided once the way it is - but it is so confusing, that I can't believe that it happened by accident ( being documented later ). My guess is that it was following some other system that did it this way. Originally a 0-width pen was the only way to get the cosmetic pen behavior. Later on setCosmetic() was added to be able to have any pen width be cosmetic. I guess the whole 0-width thing comes from X11, where 0 is a special value with the following documentation: Thin lines (zero line-width) are one-pixel-wide lines drawn using an unspecified, device-dependent algorithm. http://tronche.com/gui/x/xlib/GC/manipulating.html also contains this bit of documentation: A line-width of zero may differ from a line-width of one in which pixels are drawn. This permits the use of many manufacturers' line drawing hardware, which may run many times faster than the more precisely specified wide lines. In general, drawing a thin line will be faster than drawing a wide line of width one. However, because of their different drawing algorithms, thin lines may not mix well aesthetically with wide lines. If it is desirable to obtain precise and uniform results across all displays, a client should always use a line-width of one rather than a line-width of zero. So 0-width lines in X11 are not only implicitly cosmetic, but also have less strict guarantees when it comes to correctness, so that they can be optimized by custom hardware. I guess originally QPen simply mirrored this behavior, which is probably why as you noted 0-width pens are faster than 1-width pens with the X11 paint engine in 4.x. Still, I agree with Jens that the API of having 0-width pens and cosmetic pens as separate concepts is confusing. If we wanted something akin to the 0-width concept of X11 it should rather have been a render hint saying that it's acceptable for the application to get less accurate line drawing in exchange for better performance. I'm not sure how valid that use case is these days though. -- Samuel ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development - This transmission (including any attachments) may contain confidential information, privileged material (including material protected by the solicitor-client or other applicable privileges), or constitute non-public information. Any use of this information by anyone other than the intended recipient is prohibited. If you have received this transmission in error, please immediately reply to the sender and delete this information from your system. Use, dissemination, distribution, or reproduction of this transmission by unintended recipients is not authorized and may be unlawful. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
[Development] Proposal: Make QPen non-cosmetic by default
This issue came up while preparing some code to be High-dpi aware but it is really a completely separate issue. While I previously supported the idea that cosmetic pens should be two pixels wide by default on HDPI screens, I think we should take it one step further as the real issue is caused by the default values of QPen. QPen defaults to a pen width of 0, which might or might not be an intentional behaviour. This is interpreted as a Cosmetic pen which will have 1 pixel thickness regardless of the scale on the scene. Any code that simply does painter-setPen(someColor) will have this behaviour. The only way to avoid it is to explicitly create a QPen(Qt::Black, 1.0). Since normally there would be no difference between these behaviours, I assume that the majority of code will simply ignore the pen with altogether. Most existing styles certainly does this and mostly break with HDPI set unless every pen is explicitly set to 1.0. I have personally never seen an actual use case where a cosmetic pen makes sense, but I assume there are reasons for having i so anyone creating an explicit QPen(Qt::black, 0.0) should get a 1.0 pixel thick line regardless of scaling. With this in mind, I would propose that we change the initialisation value of QPen to be 1.0 for pen width by default in Qt5, and invert the name and behaviour of the QPainter::NonCosmeticDefaultPen render hint. Most code should not be affected by it and code that depends on this really needs cosmetic pen should already be initialising their QPen explicitly. Regards, Jens ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Oct 11, 2012, at 10:58 AM, Bache-Wiig Jens jens.bache-w...@digia.com wrote: I have personally never seen an actual use case where a cosmetic pen makes sense, but I assume there are reasons for having i so anyone creating an explicit QPen(Qt::black, 0.0) should get a 1.0 pixel thick line regardless of scaling. I agree in general. I'm wondering if a 2 pixel-wide line for QPen(Qt::black, 0.0) would be a better option in high-dpi mode - the user is expecting to fill one point. The result will look like a scaled pixmap, but won't have gaps. Morten ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Oct 11, 2012, at 10:58, Bache-Wiig Jens jens.bache-w...@digia.com wrote: This issue came up while preparing some code to be High-dpi aware but it is really a completely separate issue. While I previously supported the idea that cosmetic pens should be two pixels wide by default on HDPI screens, I think we should take it one step further as the real issue is caused by the default values of QPen. QPen defaults to a pen width of 0, which might or might not be an intentional behaviour. This is interpreted as a Cosmetic pen which will have 1 pixel thickness regardless of the scale on the scene. Any code that simply does painter-setPen(someColor) will have this behaviour. The only way to avoid it is to explicitly create a QPen(Qt::Black, 1.0). Since normally there would be no difference between these behaviours, I assume that the majority of code will simply ignore the pen with altogether. Most existing styles certainly does this and mostly break with HDPI set unless every pen is explicitly set to 1.0. I have personally never seen an actual use case where a cosmetic pen makes sense, but I assume there are reasons for having i so anyone creating an explicit QPen(Qt::black, 0.0) should get a 1.0 pixel thick line regardless of scaling. PDF/PS define it this way, and is used when writing that kind of output. With this in mind, I would propose that we change the initialisation value of QPen to be 1.0 for pen width by default in Qt5, and invert the name and behaviour of the QPainter::NonCosmeticDefaultPen render hint. Most code should not be affected by it and code that depends on this really needs cosmetic pen should already be initialising their QPen explicitly. Agreed, I only ever used it when I knew I was painting to PDF. So +1 from me. -- Erik. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Proposal: Make QPen non-cosmetic by default
On Thu, 11 Oct 2012 14:33:30 +, Verbruggen Erik wrote: I have personally never seen an actual use case where a cosmetic pen makes sense, but I assume there are reasons for having i so anyone creating an explicit QPen(Qt::black, 0.0) should get a 1.0 pixel thick line regardless of scaling. Think about a scatter plot with many points displayed as crosses. On a large zoom level you only see a cloud but when zooming in you can see each cross and its position in detail. When the pen for the crosses would have been scaled you would end with huge fat symbols - each probably larger than the plot widget itself. Or think about a grid ( or ticks on an axis ), where each line indicates a position according to scale. This line has to be one pixel regardless of the scaling. PDF/PS define it this way, and is used when writing that kind of output. The important part with PDF and cosmetic pens is when you zoom in the generated document later in a PDF viewer. The cosmetic attribute used in the Qt application code decided if the line gets scaled in the viewer or not. Please note that when you change the default setting to non-cosmetic almost all applications using Qwt for generating PDF documents will be broken ( zooming itself is not a problem for Qwt as it is not implemented using painter transformations, but I know other packages doing it ). And as f.e curve pens are set in the application code I can't fix it with a new version of the Qwt library. I bet you will cause similar issues with any type of application that implements zooming ( in the application itself or via PDF ). Uwe ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development