Errors like this became more likely due to the 'optimized' memory usage.
Also, this prevents the WindowServer from being killed by a goofy program
sharing an incomplete bitmap, and likely some other scenarios.
Indexed bitmaps used to allocate four times the required amount of memory.
Also, we should acknowledge that the underlying data is not always RGBA32,
and instead cast it only when the true type is known.
In all circumstances, this returned exactly the same thing as scanline_u8(),
so let's just remove the silly detour.
This does not add any new dependency on Bitmap-internals, because that already existed.
DC and AC table IDs read in the scan header segment weren't validated
against the IDs of Huffman tables read in the DHT segment. This caused
an OOB read when a Huffman table was accessed using the ID read in the
scan header segment. Furthermore, the decoder now replaces the old DC
or AC table if a redefinition has been found prior to the scan header.
Fixes#3439.
GIFLoader now uses a single frame buffer to cache the last decoded
frame. This drastically reduces memory usage at the small expense of
re-decoding frames on each loop.
RestoreBackground disposal mode is now a transparent fill to allow
background to show through.
RestorePrevious disposal mode now restores the previous frame.
Before, we had about these occurrence counts:
COPY: 13 without, 33 with
MOVE: 12 without, 28 with
Clearly, 'with' was the preferred way. However, this introduced double-semicolons
all over the place, and caused some warnings to trigger.
This patch *forces* the usage of a semi-colon when calling the macro,
by removing the semi-colon within the macro. (And thus also gets rid
of the double-semicolon.)
GUI::TabWidget has long has a TabPosition::Bottom option, but we still
rendered the tab buttons the same as TabPosition::Top.
This patch implements a custom look for bottom-side tabs. I've done my
best to match the look of the top-side ones, but there might be some
improvements we can make here. :^)
This avoids a call to clone() which would be discarded immediately.
Also, avoid essentially cloning for each hammer rectangle unless
there is actually a need for it.
StylePainter's behavior is now handled by a static instance
of BaseStylePainter. The original static behavior of StylePainter
is left as-is for API compatibility.
The SI prefixes "k", "M", "G" mean "10^3", "10^6", "10^9".
The IEC prefixes "Ki", "Mi", "Gi" mean "2^10", "2^20", "2^30".
Let's use the correct name, at least in code.
Only changes the name of the constants, no other behavior change.
This fixes an issue where transparent pixels in GIF animation frames
have their alpha values incorrectly set to zero, allowing the
background behind the GIF to show through, instead of the previous
animation frame.
Additionally, transparent pixels are now correctly identified based on
their index matching the image transparency index, instead of their
color values.
This patch introduces the ClassicWindowTheme, which is our default
theme implemented as a Gfx::WindowTheme subclass.
In this initial cut, we move normal window frame painting and title
bar metrics helpers out of WindowServer and into LibGfx.
This will eventually allow us much greater flexibility with theming
windows, and also makes it easier to build applications that want to
render a window with a specific style for some reason. :^)
Right now we just guess that the x-height is glyph_height/2, which is
obviously not accurate. We currently don't store the x-height in fonts,
so that's something we'll need to fix.
This function did a const_cast internally which made the call side look
"safe". This method is removed completely and call sites are replaced
with ByteBuffer::wrap(const_cast<void*>(data), size) which makes the
behaviour obvious.
Change #2811 made window title stripes and window title shadow themable,
but it used the same stripe and shadow color for all window modes.
This is fine for the new 'basalt' theme which uses the same color
in all four window modes, but it changed the default theme so that
background windows had brown stripes and a brown shadow.
Instead, make the title stripe and title shadow themable per window mode,
and change the default theme to restore the colors it had before
change #2811: The title stripe color is the same as Border1 for all
window modes, and the title shadow is the same as the title stripe
darkened by 0.6.
This commit starts adding a basic SVG element. Currently, svg elements
have support for the width and height properties, as well as the stroke,
stroke-width, and fill properties. The only child element supported
is the path element, as most other graphical elements are just shorthand
for paths.
This API is not super perfect as it merely overrides the source alpha
on all source pixels instead of blending the alpha values. There is
room for improvement here for sure.
The theming system can now control title bar height, title button
size, title stripe color and the title text shadow color.
The implemented theme metrics system could be later extended to LibGUI
to allow themes to change widget padding, border width, etc.
This patch adds support for JPEG decoding. The JPEG decoder is capable
of handling standard 2x1 horizontal, 2x1 vertical and quartered chroma
subsampling. The implemented Inverse DCT performs with a decent speed.
As of interchange formats, since we tend to ignore the metadata in APPn
markers, the decoder can handle any format compatible with JFIF, which
includes EXIFs and sometimes WebMs too. The decoder does not support
progressive JPEGs yet.
The new ImageDecoder service (available for members of "image" via
/tmp/portal/image) allows you to decode images in a separate process.
This will allow programs to confidently load untrusted images, since
the bulk of the security concerns are sandboxed to a separate process.
The only API right now is a synchronous IPC DecodeImage() call that
takes a shbuf with encoded image data and returns a shared buffer and
metadata for the decoded image.
It also comes with a very simple library for interfacing with the
ImageDecoder service: LibImageDecoderClient. The name is a bit of a
mouthful but I guess we can rename it later if we think of something
nicer to call it.
There's obviously a bit of overhead to spawning a separate process
for every image decode, so this is mostly only appropriate for
untrusted images (e.g stuff downloaded from the web) and not necessary
for trusted local images (e.g stuff in /res)
Since the current image handling APIs don't provide a way to handle a
file which can contain multiple images, we just pick the largest one.
This gives the best chance of a good looking result.
This add support to the ICO file decoder for loading uncompressed bitmap icon files.
It is limited to 32-bit color icons, no 4/8/16 bit or paletted formats yet.
This is in addition to the PNG compressed ICO format support added previously.
With this we can now load the favicons for github, google and twitter.
This adds support for loading the first image from ICO format images only if they are PNG encoded.
This is useful for loading favicons, which are sometimes PNGs with an ICO extension and sometimes actual ICO files.
In particular we can now load the favicon from new.ycombinator.com
Adds an *almost fully featured BMP loader to process .bmp files.
Features:
- All header formats are supported
- Full RLE4/8/24 support
- Color scaling (e.g. distributing a 5-bit color throughout the 8-bit
color spectrum, so 5-bit white is still 0xffffff)
- Full BITMASK/ALPHABITMASK support
*Not included:
- 1D Huffman compression. Good luck actually finding a bmp in the wild
that uses this
- Use of any field in the V4/V5 header. Color spaces? Endpoints? No
thanks :)
This loader was tested with the images at
https://entropymine.com/jason/bmpsuite/bmpsuite/html/bmpsuite.html. This
loader correctly displays 81 out of the 90 total images (for reference,
firefox displays 64 correctly). Note that not rendering the images at
the bottom is counted as displaying correctly.
This adds support for decoding the Adam7 interlacing used in some PNGs.
Notably this includes many of the images (such as the eyes) used in the acid2 test :^)
Note that the HTML engine still doesn't understand the <object> tag well enough to show the eyes on the test.
If we can't decode the input data, just have a null decoder. In this
state we simply return a null bitmap and whatever empty values make
sense for each API.
This way, we don't try to decode the same thing over and over since
it's not gonna work anyway. :^)
Get rid of the weird old signature:
- int StringType::to_int(bool& ok) const
And replace it with sensible new signature:
- Optional<int> StringType::to_int() const
Return StylePainter::paint_button() before color initializations
when possible and replace an overdrawn rect in paint_button_new()
with more explicit shadow lines. Also standardize some comments.
This adds a "shine" effect to the bottom-right edges of pressed
and checked buttons, complementing the sunken shadow already
present at top-left and creating greater illusion of depth.
It is similar to the effect used in classic Windows and is
theme agnostic in Serenity, but produces the best result when
ThreedHighlight is a radiant color of Button.
It was really confusing that add_clip_rect() didn't apply transforms
to the new clip rect, but instead interpreted it as an absolute rect.
This makes web pages with <iframe> render correctly when scrolled.
Something might break from this, but we'll find it soon enough. :^)
.. and make travis run it.
I renamed check-license-headers.sh to check-style.sh and expanded it so
that it now also checks for the presence of "#pragma once" in .h files.
It also checks the presence of a (single) blank line above and below the
"#pragma once" line.
I also added "#pragma once" to all the files that need it: even the ones
we are not check.
I also added/removed blank lines in order to make the script not fail.
I also ran clang-format on the files I modified.
And move canonicalized_path() to a static method on LexicalPath.
This is to make it clear that FileSystemPath/canonicalized_path() only
perform *lexical* canonicalization.
Now most classes dictate how they are serialized and deserialized when
transmitted across LibIPC sockets. This also makes the IPC compiler
a bit simpler. :^)
If we just skip every second pixel, we still get a solid line if each
"pixel" is wider than 1!
Now we skip the same amount of pixels as the line is thick.
Various optimisations to speed up LZWDecoder
- Take advantage of the fact that we add new codes in the order they are
discovered so no need to store the code as part of a separate
CodeTableEntry structure. Instead we store directly store vectors of
colors and the code is the index into the vector.
- Cache current table capacity to avoid calling pow2 every time.
- Prevent some unnecessary vector copies by returning by reference from
get_output.
Adds methods to determine whether an image is animated, how many times
the animation loops, the number of frames, and to get individual frames.
Implements stubs of these methods for PNGImageDecoderPlugin and
GIFImageDecoderPlugin.
The existing scanline method works just fine, and only needs the points
to be available as floats.
This commit reverts the complex polygon mitigation, and instead fixes
the rasterization process to avoid generating complex polygons because
of precision issues.
This allows the painter to render filled complex shapes better, by
constructing a path graph for (interesting) intersecting lines and
omitting lines from the containing segments if they are detected
to take no part in defining the edges of a shape.
This approach would still fail if there are multiple logical shapes
that are confined to the collection of lines.
For instance, two polygons intersecting each other in a way that one
vertex of polygon A ends up inside polygon B.
we would detect that polygon A's edges are part of the shape
(technically correct) even though they are not a part of polygon B at
all.
There are some imperfections with intersecting edges (because the main
algorithm used is scanline, and that is not geared towards drawing
complex shapes), however, it behaves mostly fine for normal use :^)
When dealing with png data that has less than 8 bits per pixel, round
up to the next byte when allocating per row buffers and streamers. This
fixes decoding odd sized PNGs with less than 8 bits per pixel.
Also added a test page with some odd sized palleted PNGs.
The LZW decode step will now copy and pad LZW data out to 4 bytes if there are
less than 4 bytes remaining in the buffer. This means it will now also work when
the total size of the LZW image data is less than 4 bytes.
The sniff method is intended to be used for content sniffing. It should be a
cheap test to rapidly rule out whether a candidate image can be successfully
decoded. For the GIF and PNG implementations it simply attempts to decode the
image header, returning true if successful and false if not.
Also:
- Define the GIFLoadingContext structure.
- The load_gif_impl function now returns load operation success, and takes a
reference to a GIFLoadingContext as input.
- Implement GIFImageDecoderPlugin::bitmap which calls onto load_gif_impl.
This will be used to implement painting of 2D paths. This first patch
adds support for line_to(), move_to() and close().
It will try to have the same semantics as the HTML <canvas> element.
To stroke a Path, simply pass it to Painter::stroke_path().
If the area or size_in_bytes calculation for a Gfx::Bitmap would
overflow, we now refuse to create such a bitmap and return nullptr.
Thanks to @itamar8910 for finding this! :^)
blit_filtered() can be used to easily implement per-pixel filtered blit
functions. All you need to do is provide a callback that can compute
the Color for each pixel based on the original Color.
With this patch, it's now possible to pass a Gfx::ShareableBitmap in an
IPC message. As long as the message itself is synchronous, the bitmap
will be adopted by the receiving end, and disowned by the sender nicely
without any accounting effort like we've had to do in the past.
Use this in NotificationServer to allow sending arbitrary bitmaps as
icons instead of paths-to-icons.
Instead of passing the BufferStream, pass the Decoder. I'd like to stop
using BufferStream eventually anyway, so it's good to get it out of any
API's where it's in currently.
This feels a lot more consistent and Unixy:
create_shared_buffer() => shbuf_create()
share_buffer_with() => shbuf_allow_pid()
share_buffer_globally() => shbuf_allow_all()
get_shared_buffer() => shbuf_get()
release_shared_buffer() => shbuf_release()
seal_shared_buffer() => shbuf_seal()
get_shared_buffer_size() => shbuf_get_size()
Also, "shared_buffer_id" is shortened to "shbuf_id" all around.
SystemTheme.h:81:1: error: 'SystemTheme' defined as a struct here but previously declared as a class; this is valid, but may result in linker errors under the Microsoft C++ ABI
This shaves ~5 seconds off of a full build, not too bad. Also it just
seems nicer to push this logic out to classes. It could be better but
it's a start. :^)