Bounty proposal: Paint
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ... 27
Andy S (2979) 504 posts |
One downside of the way the spray can density feature works is that it’s never really been a true density. It’s a pixel count rate. Ideally, a density would scale up the number of pixels laid down (per second) in proportion to the area of the circle. Paint’s always worked like this though and I don’t think it can easily be changed as the redraw code would be much too slow and unresponsive then if you had, say, radius 300 with density 999 (whereas if you try this currently it takes a very long time to fill the circle). I’m thinking this is best left as it is for the time being. |
Andy S (2979) 504 posts |
I suppose the current model isn’t unrealistic. An adjustable nozzle on a paint gun or hose can’t increase the flow rate beyond a certain amount when you widen out the radius. On most of these devices, the spray does become less dense as the radius increases. Yep, I’m over-thinking this. |
Chris (121) 472 posts |
Yeah, I think so :) The spray can is a tool that I’m guessing gets rather limited use these days, so probably best to preserve the old behaviour and ensure it remains constant on newer hardware. If opacity ever gets added to the Brush tool, then this opens up the possibility of proper Photoshop-style airbrushing, which I think would supersede the spraycan for a lot of purposes. |
Andy S (2979) 504 posts |
If opacity ever gets added to the Brush tool Yeah. As some of you may have noticed, I’ve decided to push back my work on the Alpha and Opacity features now towards the end, on the basis that I believe I can get all the other tasks done more quickly – and most of the other tasks are a bit more self contained in terms of impact on the code base. The alpha and opacity stuff needs quite significant changes to the way Paint works in quite a few places, so unpicking those changes at a later date would be harder if they’re made too early on, I think. I know I already showed you a simple Edit Alpha feature, but I’ve shelved that for now while I work on the other tasks. The in-place editing of alpha values (including via opacity) still presents some difficulties that were touched on in my discussion with Jeffrey earlier in this thread. |
Chris (121) 472 posts |
Fair enough – that does sound like a huge bit of work. In the meantime, your other improvements are much appreciated :) |
Andy S (2979) 504 posts |
Jeffrey:
I think I have a solution to this. Please tell me if you can see a logical flaw. If the 4K colour sprite’s stored for editing by using an 8 bit alpha mask (as above), can’t I just scale the Opacity slider to a 4 bit value?1 My assumption is that whether the 4K alpha channel sprite was either newly created (so blank), or loaded from disc, by definition it cannot contain any 8 bit alpha data. Therefore if all the editing tools that allow alpha values to be added2 are locked in this mode to only allow 4 bit alpha values to be added to the sprite then, as I understand it, it cannot end up displaying anything other than 4 bits of alpha information (even though in memory, it’s really 8 bit). The only slight difficulty I can think of is the Use Sprite as Brush. The sprite’s alpha values would all have to be quantized to look like 4 bits when the brush was created. I guess the code would be something like: fakeFourBitAlpha = (eightBitAlpha >> 4) << 4; Please tell me if you see any flaw in this reasoning. 1When I’m talking about adding 4 bit alpha values to the sprite, I mean they will be converted back to 8 bit values first as per the above calculation. It’s just the 4 LSBs will be zero. In fact, a logical AND with 0xF0 would do it. 2I’m thinking, for the purposes of this Bounty, the only tools that manipulate alpha values will be tools with the Opacity slider, which will be Spray Can, Brush and probably Pencil (maybe flood fill), which is why I think the above approach could work. The “Transparent” colour will allow other tools to set pixels to 100% transparency but I’d imagine that’s very similar to the current Edit Mask code in that we’d just be writing direct to the Alpha Mask, with no pixel reads or changes in RGB. |
Jeffrey Lee (213) 6048 posts |
Yeah, manually quantising the alpha/opacity would work. I think there’d have to be two different approaches that are taken:
When expanding 4 bit alpha to 8 bit alpha you’d want both nibbles to be identical, so the post-processing step for fake 4 bit alpha would be: fakeFourBitAlpha = (eightBitAlpha >> 4) * 0x11 That way when the 8-bit version is rendered it will appear correct. If the lower nibble was just zero then it would appear more transparent then it should (notably, fully opaque areas would be partially transparent) |
Andy S (2979) 504 posts |
If the lower nibble was just zero then it would appear more transparent then it should (notably, fully opaque areas would be partially transparent) Argh. And there’s the flaw in my thinking, right there. Thanks Jeffrey. When in regular mode and using a tool which has opacity (spray can, brush with a custom alpha-masked sprite, etc.) you’d have to do the quantisation as a post-processing step […] Even if you restrict the input values to 4-bit quality you may get 8-bit quality output. : ( Yeah. I was thinking if the 4 LSBs were always zero then that could never happen. Damn. If the quantisation is over a large area of the sprite, that’s going to be slow. Plus ideally it would need to be done off-screen |
Jeffrey Lee (213) 6048 posts |
Paint does use OS_ChangedBox to track the bounding rectangle for each tool activation (e.g. for each individual plot of a brush sprite). So you should be able to use that to restrict which area of the mask is quantised, and it should be possible to make sure it gets done before Paint tells the Wimp to redraw that area of the sprite window. If you write a routine that modifies the mask memory directly then I wouldn’t expect performance to be a major issue. However, I have just remembered that OS_SpriteOp (and the VDU in general) doesn’t support proper alpha blending! The VDU plot operations have no concept of blending at all, they only support logical operations (aka GCOL actions). Meanwhile, OS_SpriteOp will do RGB blending (using the ARGB channels of the sprite and the RGB channel of the destination). But it completely ignores the alpha channel of the destination – when it blends it acts as if the destination has an alpha of 1, and when it writes pixels it always does so with an alpha of 1. (You can copy the sprite alpha channel to the destination by disabling the blending flag (bit 3), but that will obviously disable the RGB blending as well). I think the only bit of the OS which can blend properly with an alpha destination is the font manager (Font_Paint flag bit 14). Potentially it wouldn’t be too hard to add proper alpha blending to OS_SpriteOp. But supporting it in the VDU would be a lot more work. And we’d only be able to support it for alpha-channel formats; if the alpha is in a separate mask plane then there’s no way it can work (the screen alpha value is needed during the RGB blend stage, but the VDU has no concept of the framebuffer having a separate plane containing the alpha data) So I think the best course of action would be to design the feature set of Paint around the limitations of the current system. You can still have an opacity slider for the brush tool, and that will affect the blending of the RGB, but (outside of the special alpha/mask editing mode) the user will have little or no control over what the alpha/mask is set to. For most plot operations you could potentially allow the user to specify a custom alpha value to set, but that would only really work with non-blending operations, or with blending operations where the sprite being edited uses an alpha mask (since the mask update is a separate step, allowing you to use a blending op for the RGB update and non-blending op for the mask update) |
Andy S (2979) 504 posts |
Thanks Jeffrey. I think this reinforces my decision to make the alpha and opacity changes last in the bounty after the other tasks. That way, if we want to modify or completely redo how those features work at a later date, we can rollback if necessary without having a ton of other features to merge back in. |
Chris Evans (457) 1614 posts |
I like the sound of ‘a ton of other features’:-) Keep up the good work. |
Andy S (2979) 504 posts |
Hi all. A quick progress update. I’ve been working on the “Autoscroll with selection box drags” feature and annoyingly my progress with this had been stalling for quite some time. There’s a slightly complicated state machine that draws and erases the “rubber band” selection rectangles and this had broken horribly when I added the scrolling functionality. : ( Anyway, whenever I found a bit of time to work on Paint I kept looking in the wrong place, at this state machine, to try to fix the bug. At last, this evening, I found a couple of innocent looking lines of code I’d added that were causing the problem all along. The resulting code for this Autoscroll is a lot simpler than I originally expected, which is nice. Hopefully I can crack on with the rest of it now. Thanks for your patience and support everyone. |
Andy S (2979) 504 posts |
Right, I’m looking for some feedback on a design decision. The Autoscroll now works with the Camera, Scissor and Move Whole Sprite tools. This evening I added in the code that Draw uses that constrains the mouse pointer to the window bounds while the rubber band box is being dragged. It makes it a bit nicer when you are first defining the Copy or Cut box as otherwise it’s easy to move the mouse too far off screen while the window is scrolling, so it takes a while to get it back to stop the scrolling (if that makes sense ;-) ). The problem is on Copy or Scissor, after you release the mouse button, the second rectangle (paste box) is moved around freely with the mouse pointer and no button press, so constraining the mouse movement when that happens may frustrate some users who may feel their mouse is trapped! You can escape it by clicking adjust but then you lose your paste box and most users wouldn’t know that. Draw doesn’t have this problem because all selections and movements are done with mouse drags. This is how most modern graphics packages handle it as well. Where Paint is concerned though, I think I’ll have to throw away the idea of constraining the mouse to the window while scrolling altogether. Agreed? Having it do it just when dragging out the initial copy / scissor box but not when moving the paste box seems inconsistent to me. Having said that, the scroll bars are usable when moving the paste box around so Autoscroll is kind of redundant there as well. It’s a shame because it means Paint’s Autoscroll behaviour won’t be consistent with Draw’s. I have to wonder if that’s one of the reasons Acorn didn’t ship with such a feature. |
Martin Avison (27) 1491 posts |
When using AutoScroll the further the mouse is from the centre area the faster it scrolls, after the configured WimpAutoScrollDelay time. Limiting the mouse area would limit the maximum scroll speed. How this relates to Paint usage I am not sure. |
Rick Murray (539) 13806 posts |
Does that actually work with something other than the icon bar?
How about having this new behaviour as a toggle with Paint$Options? Then people can try either method and use the one they prefer? Just out of interest, something I tried the other day… Would it be feasible to have the camera icon (copy part of an image) be able to paste that copied part into a different image? |
Andy S (2979) 504 posts |
Does that actually work with something other than the icon bar? I don’t know, but I’m not using it and Draw doesn’t seem to pay any attention to it either. Strictly speaking I suppose both applications should probably honour the setting. How about having this new behaviour as a toggle with Paint$Options? Then people can try either method and use the one they prefer? That’s a possibility. If so it would probably be 2 options, one to enable restricting the mouse when dragging the selection box, and one to enable it when moving the paste boxes. It depends what everyone else, and ROOL, think. Just out of interest, something I tried the other day… Would it be feasible to have the camera icon (copy part of an image) be able to paste that copied part into a different image? That’s a neat idea Rick. However, I just tried it using 2 views of the same sprite, copying with the camera tool, moving the mouse pointer out of the first window, into the second window, pasting there, but when I moved the mouse back into the first window Paint crashed! :( “abort on data transfer at &00027D24”. I’ll have to see if the error is reproducible. |
Andy S (2979) 504 posts |
OK, it’s not obviously reproducible. I just tried again a couple of times and there was no error. |
Chris (121) 472 posts |
Not sure I do agree :) I think that auto-scrolling/constraining while dragging and not auto-scrolling/constraining while pasting are perfectly consistent. While dragging out to select an area, it’ll be really useful for the window to auto-scroll, and as a result a good idea to constrain the mouse pointer. While hovering over the image with a pasted ‘block’, it’s a different kind of activity – like hovering with a sprite using the Paint tool. There’s no dragging going on, so I can make use of the scrollbars, as you note, and so auto-scrolling is less important. If I’ve understood your description correctly, I’d be inclined to implement auto-scroll and window constraining for dragged operations (like selecting an area) and keep the current behaviour for paste operations with a floating object. That seems pretty logical to me – or have I missed something? |
Chris (121) 472 posts |
There’s already a roundabout way of doing this, by using the Export option on the Camera tool. That’ll allow you to drag the selection as a sprite to the Sprite window, after which you can use it with the Paint tool on any other sprite. A bit of a headache, though, I agree! For this kind of functionality, I’d be tempted to improve the interface for the Paint tool (not least prevent the crashes!) and make it a one-click operation to save the Camera selection to the pool of available sprites, not least because most of the code will presumably already be in place. |
Andy S (2979) 504 posts |
Not sure I do agree :) I think that auto-scrolling/constraining while dragging and not auto-scrolling/constraining while pasting are perfectly consistent. While dragging out to select an area, it’ll be really useful for the window to auto-scroll, and as a result a good idea to constrain the mouse pointer. While hovering over the image with a pasted ‘block’, it’s a different kind of activity – like hovering with a sprite using the Paint tool. There’s no dragging going on, so I can make use of the scrollbars, as you note, and so auto-scrolling is less important. Nope that’s logical enough and well defined. It also means I could check the mouse button state to make sure the pointer’s only constrained while the button is held down. |
Chris (121) 472 posts |
Just had a play with the new auto-scrolling Paint. Seems to work very well, and will be a useful addition. Great work! |
Andy S (2979) 504 posts |
Glad you like it, thanks :) |
Andy S (2979) 504 posts |
As it’s nearly two years since I started this Paint bounty (even though it might not feel like it!), I feel it’s time to say that whilst I have been and will continue to work on it as much as I can, if anybody else develops a desire to get involved or grows impatient with how long this is taking, I will gladly let them pick up some or all of the remaining tasks and allocation of the proceeds could then be discussed with ROOL. I’m not giving up now in any sense, nor have I stopped work. I just don’t like the thought of this dragging on for years, which was not my original intention. |
Jeffrey Lee (213) 6048 posts |
Maybe a summary of what has/hasn’t been done so far would be useful? (as long as you’re not too embarrassed!) |
Andy S (2979) 504 posts |
I suppose it is a little embarrassing but it’s unfortunately a case of there being far too many projects going on at once in my life combined with the complexity of each of these tasks seeming to expand the more I looked at them. Fully Completed: General Editing
Colour handling
Selection, zoom and resize
In Progress: General Editing
Selection, zoom and resize
UI / Templates Only Done: Sprite Formats
Selection, zoom and resize
Not Started: General Editing
Colour handling
Bug fixes
Notes I’m classifying all the tasks relating to creating and editing alpha channel / alpha mask sprites as Not Started or UI Only because I decided to scrap the initial code I wrote for them. It involved storing the greyscale representation of the alpha channel as an extra sprite within Paint’s existing data structures and some flags and logic to swap between that and the main sprite where necessary. On reflection I decided this was too clunky and error-prone because it needed code changes in too many places. I decided it should be rewritten so that the greyscale sprite is just a regular sprite in the sprite file, probably with logic to make it invisible so as not to confuse inexperienced users. Two of the “Colour handling” items are struck through because ROOL felt these could be dropped if necessary from the core bounty. “UI / Templates Only Done” means just what you would think, that I edited the window templates to create the user interface but have not yet written any code behind them. |
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ... 27