This is a first (huge) step towards modernizing the layout architecture
and bringing it closer to spec language.
Layout is now performed by a stack of formatting contexts, operating on
the box tree (or layout tree, if you will.)
There are currently three types of formatting context:
- BlockFormattingContext (BFC)
- InlineFormattingContext (IFC)
- TableFormattingContext (TFC)
Document::layout() creates the initial BlockFormattingContext (BFC)
which lays out the initial containing block (ICB), and then we recurse
through the tree, creating BFC, IFC or TFC as appropriate and handing
over control at the context boundaries.
The majority of this patch is just refactoring the old logic spread out
in LayoutBlock and LayoutTableRowGroup, and turning into these context
classes instead. A lot more cleanup will be needed.
There are many architectural wins here, the main one being that layout
is no longer performed by boxes themselves, which gives us much greater
flexibility in the outer/inner layout of a given box.
Problem:
- Several files have missing includes. This results in complaints from
`clang-tidy`.
- `#ifdef` is followed by `#elif <value>` which evaluates to `0`.
Solution:
- Add missing includes.
- Change to `#elif defined(<value>)`.
Problem:
- It is difficult to refactor because there are no tests to bind the
functionality.
- Arguments are not forwarded correctly to the constructor.
Solution:
- Add tests.
- Change constructor to take forwarding references.
Problem:
- `is_zero()` is implemented by checking each value in the array by
hand. This is error-prone and less expressive than using an
algorithm.
Solution:
- Implement `is_zero()` in terms of `all_of`.
Problem:
- Raw loops are often written to validate that all values in a
container meet a predicate, but raw loops are not as expressive as
functions implementing well-named algorithms and are error-prone.
Solution:
- Implement a very generic form of `all_of`.
Problem:
- C-style arrays do not automatically provide bounds checking and are
less type safe overall.
- `__builtin_memcmp` is not a constant expression in the current gcc.
Solution:
- Change private m_data to be AK::Array.
- Eliminate constructor from C-style array.
- Change users of the C-style array constructor to use the default
constructor.
- Change `operator==()` to be a hand-written comparison loop and let
the optimizer figure out to use `memcmp`.
When clicking empty space (beneath any used lines) in the TextEditor,
the cursor would jump to the start of the last line, rather than the
correct column, or the end of the line where appropriate. This was
because in the for_each_visual_line callback would return
IterationDecision::Continue if the clicked point wasn't in the line's
rect. Thus the callback would continue on each iteration and at the
end, would set the cursor to the default column of 0. To fix this I
added a bool to the callback's signature which tells the callback if
the for_each_visual_line method is on the last visual line. The
callback now does not return IterationDecision:Continue if
for_each_visual_line method is on the last line and the correct column
is then calculated with the line passed.
This work is already done (and more correctly) by the parent class
(AbstractView) if we just let it take care of the event instead.
Fixes the root cause of #4096.
Switch over to gamma-aware interpolation. This causes color gradients
to not look so dark in the middle. SIMD optimized code is provided for
sse1 enabled builds.
Fixes#1342.
This doesn't fix all the issues found by the fuzzer, but it fixes
many of them. When running this
Meta/Lagom/Fuzzers/FuzzJPGLoader -jobs=24 -workers=24 \
../Base/res/html/misc/jpgsuite_files/
for 10 minutes on my machine, the fuzzer foudn 2 crashers, but after
this change it finds just ... 2. But with different stacks!
This just fixes ASSERT()s, so it's not security critical, but
ASSERT()s still crash the programs decoding JPGs, and crashing
less is nice even if it's not a security concern.
Problem:
- `MACAddress` class is not usable in a compile-time context.
- `__builtin_memcpy` is not constexpr in gcc.
Solution:
- Decorate functions with `constexpr` keyword.
- Use default constructors and destructors.
- Change `__builtin_memcpy` to a hand-written `for` loop and let the
compiler's optimizer take care of it.
- Add tests to ensure compile-time capabilities.
This patch shrinks X86::Instruction from 56 to 28 bytes by packing data
members more tightly and removing some entirely.
There is still some data duplication between Instruction and the
corresponding InstructionDescriptor but it will be a bit tricky to get
much more out of it.
This looks like a 1-2% improvement on general emulation speed. :^)
This fixes an OOB access when the last read/written chunk is empty (as we _just_
started on a new chunk).
Also adds a test case to TestMemoryStream.
Found via human fuzzing in the shell:
```sh
for $(cat /dev/urandom) {
clear
match $it {
?* as (x) {
echo $x
sleep 1
}
}
}
```
would assert at some point.
This adds a few macros used to determine the category of a floating
point number. This fixes a build error with the jq port due to the
previously missing isnormal() macro.
Co-authored-by: Lua MacDougall <luawhat@gmail.com>
Prevents the adding of items to the ClipboardHistoryModel if the raw
data and mime_type of the item being added is the same as another item
already in the list.
Personally I found this unintuitive at first, but it is in line with
strtol(), Python's int() or JavaScript's parseInt(), so I guess it makes
sense.
Fixes#4097.
Problem:
- Clang reports unused private member warning in the `Shell::Formatter`.
- Vector is not used in the `Shell::Formatter`.
Solution:
- Remove unused private member variable.
- Remove unused includes.
Problem:
- There are no unit tests for `MACAddress` class. This makes it
difficult to refactor and ensure the same behavior.
- `m_data` private member variable is uninitialized leading to undefined
behavior of `is_zero()`.
Solution:
- Add unit tests to cover basic functionality.
- Initialize `m_data`.
Instead of caching a raw pointer to the next instruction, cache the
region we're fetching instructions from, and a pointer to its base.
This way we don't need to keep invalidating and reloading the cache
whenever the CPU jumps.
By passing the Region& to the auditing functions, we know exactly which
block we are hitting. This allows us to track big mallocations the same
way we already do chunked ones.
This gets rid of the O(n) scan in find_mallocation() for allocations
larger than the maximum malloc chunk size. :^)
Problem:
- C++20 changes the way equality operators are generated. This results
in overload ambiguity as reported by clang.
Solution:
- Remove `AK::Vector::operator!=` because it will be automatically
generated in terms of `AK::Vector::operator==`.
- Change `AK::Vector::operator==` to be a function template so that
overload resolution is not confused about `a == b` vs `b == a`.
- Add tests to ensure the behavior works.
Notes:
- There is more info available at
https://brevzin.github.io/c++/2019/07/28/comparisons-cpp20/ for
deeper discussion about overload resolution, operator rewriting, and
generated functions.