Polygonal selection tool allows for the drawing of any arbitrary
polygonal shape. It tracks clicked points in a vector, upon double
clicking we finalize the polygon and generate the selection mask. The
user can press the escape key during selection to cancel.
The mask is generated as follows:
- First we calculate the size of the bounding rect needed to hold the
polygon
- We add 2 pixels to height/width to allow us a 1 pixel border, the
polygon will be centered in this bitmap
- Draw the polygon into the bitmap via Gfx::Painter, making sure to
connect final polygon point to the first to ensure an enclosed shape
- Generate a selection mask the size of the bitmap, with all pixels
initially selected
- Perform a flood fill from (0,0) which is guaranteed to be outside the
polygon
- For every pixel reached by the flood fill, we clear the selected pixel
from the selection mask
- Finally we merge the selection mask like other selection tools.
This fixes a bug which shows up when a layer is offset and the selection
range includes pixels that are outside the current layer bitmap rect. We
would still try to delete that pixel from the bitmap since there was no
contains() check.
Before this commit, when the wand select tool was used on a layer that
was moved, it would make the selection relative to the image, and not
relative to the layer. This commit fixes that issue.
Refactored PickerTool functionality to the ImageEditor level and added a
flag to Tool Base Class to allow for tools to override Alt+Click
ColorPicker functionality
Commit #3197c17 introduced a session based clipboard portal.
This made pixel-paint fail to launch, because it had an unveil that
used the old path to the clipboard. This commit fixes that and now
unveils the new session based clipboard portal.
We previously put the generated headers in SOURCES, which did not mark
them as GENERATED (and did not produce a proper dependency).
This commit moves all generated headers into GENERATED_SOURCES, and
removes useless header SOURCES.
This filter mimics the functionality from Photoshop and other image
editors, allowing you to adjust the hue, saturation, and lightness of
an image. I always found this a very handy feature :^)
This is a partial revert of commit 7af5eef. After 97d15e9, the 'proc'
promise is not needed for operations using getsid().
This also fixes launching several applications in which 7af5eef added
the 'proc' promise only in the second call to pledge().
This commit does three things atomically:
- switch over Core::Account+SystemServer+LoginServer to sid based socket
names.
- change socket names with %uid to %sid.
- add/update necessary pledges and unveils.
Userland: Switch over servers to sid based sockets
Userland: Properly pledge and unveil for sid based sockets
New actions in the Layer Menu allows for the creation of a new layer
from the current selection. Layers can be made by copying the
selection or cutting it from the current layer. The new layer will be
sized to the bounding box of the selection. The newly produced layer
will be added to the layer stack.
URL had properly named replacements for protocol(), set_protocol() and
create_with_file_protocol() already. This patch removes these function
and updates all call sites to use the functions named according to the
specification.
See https://url.spec.whatwg.org/#concept-url-scheme
The main advantage of this change is that heavy-weight filters do not
lock up the GUI anymore.
This first cut has several flaws:
- We do not account for modification of the referenced images while the
filter is running. Depending on the exact filter behavior this might
have all sorts of weird effects. A simple fix would be to show a
progress dialog to the user, preventing them from performing other
modifications in the meantime.
- We do not use the image processor for previews. Preview behavior has a
couple of other considerations that are intentionally not addressed in
this commit or pull request.
The ImageProcessor singleton is intended to be used by all sorts of
image processing which might take some time to complete; or other
background actions. We're not using BackgroundTask here because this
system is specifically designed to work with task queues and PixelPaint
interaction; e.g. it provides common image processing tasks such as
filter application.
This patch adds scaling function to the move tool.
When the cursor is over the lower right corner of the layer, it changes.
This is to signify that the layer can be scaled by dragging the mouse.
There is currently no preview of the scaling.
Doing a resize every time the mouse moves leads to unexpected behavior.
Vectorscopes are a standard tool in professional video/film color
grading. *Very* simply, the Vectorscope shows image colors with hue as
the angle and saturation as the radius; brightness for each point in the
scope is determined by the number of "color vectors" at that point. More
specifically, the Vectorscope shows a 2D UV histogram of the image,
where U and V are the chroma ("color") channels of the image.
Co-authored-by: MacDue <macdue@dueutil.tech>
The histogram is perfectly fine with being drawn at any size, but the
code currently fixes its height to 65. Once the histogram is in a
subclass and several GML things around it change, the fixed height
breaks, so we move the height specification to GML. Additionally, the
container is specified to shrink as much as possible, alleviating a
hard-coded UI size. The user can now change histogram height in GML,
which is a lot more obvious.
Layer::erase_selection used to erase the entire bounding box of the
selection. With the add/subtract merge modes for the selection tool it
is possible to create selections which are not rectangular. This leads
to deleting pixels that were not selected.
This change adjusts the erase behavior to walk the selection rect and
check if a pixel is selected or not before deleting.
Wand Selection tool uses similar logic to the Bucket Tool. Flood filling
and threshold calculations to determine the affected area just in this
case we do not set the pixels of the selected area, instead we use
those pixels to alter the selection mask.
In the future we can probably abstract out the shared flood logic so
both tools can share the code.
Specializing point_position_to_preferred_cell for the
RectangleSelectTool as it selects a new cells with a rounding
behavior instead of a flooring behavior
This is done to allow querying the current active tool inside the
event_with_pan_and_scale_applied and event_adjusted_for_layer
functions without risking a null pointer dereference
This method is used to point a position at the preferred pixel of
the image. Certain tools may want to specify a different preferred
pixel for the same input position.
When cropping to content with a layer not positioned at 0,0 the moved
layers content disappeared and the layers position was not updated
according to the crop offset.
There's probably an easier/more efficient way, but for my testcase this
improves the behavior.
This adds menu item icons for Add Mask, Flatten Image, Fit Image To
View, and Generic 5x5 Convolution.
This modifies the menu item icon for Swap Colors to make the action more
obvious and improve accessibility.
This command finds the smallest non-empty content bounding rect
by looking for the outermost non-transparent pixels in the image,
and then crops the image to that rect.
It's implemented in a pretty naive way, but it's a start. :^)