This allows `file` to correctly print the dimensions of a .jbig2 file,
and it allows us to write a test that covers much of all the code
written so far.
Several ramifications:
* /JBIG2Globals is an indirect reference, which means we now need
a Document for unfiltering. (Technically, other decode parameters
can also be indirect objects and we should use the Document to
resolve() those too, but in practice it only seems to be needed
for /JBIG2Globals.)
* Since /JBIG2Globals are so rare, we just parse once for each
image that use them, and decode_embedded() now receives a
Vector<ReadonlyBytes> with all sections of sequences of
segments.
* Internally, decode_segment_headers() is now called several times
for embedded JBIG2s with multiple such sections (e.g. PDFs with
/JBIG2Globals).
* That means `data` is now no longer part of JBIG2LoadingContext
and things get slightly reshuffled due to this.
This completes the LibPDF part of JBIG2 support. Once LibGfx
implements actual decoding of JBIG2s, things should start to
Just Work in PDFs.
They're in different places for Sequential/Embedded (right after
the header) and RandomAccess (which has all headers first, followed
by all data bits next).
We don't do anything with the data yet, but now everything's in
place to actually process segment data.
Except for /JBIG2Globals, which we bail out on for now. In my 1000
files, 13 use JBIG2, and of those, 2 use JBIG2Globals (0000372.pdf e.g.
page 11 and 0000857.pdf e.g. page 1), and only one (the latter) of the
two uses the same JBIG2Globals stream for more than a single image.
JBIG2ImageDecoderPlugin cannot decode the data yet, so no behavior
change, but with `#define JBIG2_DEBUG 1` at the top of that file,
it now prints segment header info for PDFs containing JBIG2 data :^)
I created this by running
jbig2 -i Tests/LibGfx/test-inputs/bmp/bitmap -f bmp -o bitmap -F jb2
using the `jbig2` tool whose source code is in the zip file here:
https://www.itu.int/rec/T-REC-T.88-201808-I
(Just `make jbig2` in Software/JBIG2_SampleSoftware-A20180829/source
was enough to build it.)
As far as I can tell (cf `JBIG2_EncMain()` which always writes `1`
to the flags byte in the file header), this tool always writes files
in the sequential organization.
With `#define JBIG2_DEBUG 1` at the top of the file:
% Build/lagom/bin/image --no-output \
.../JBIG2_ConformanceData-A20180829/F01_200_TT10.jb2
JBIG2LoadingContext: Organization: 0 (Sequential)
JBIG2LoadingContext: Number of pages: 1
Segment number: 0
Segment type: 48
Referred to segment count: 0
Segment page association: 1
Segment data length: 19
Segment number: 1
Segment type: 39
Referred to segment count: 0
Segment page association: 1
Segment data length: 12666
Segment number: 2
Segment type: 49
Referred to segment count: 0
Segment page association: 1
Segment data length: 0
Runtime error: JBIG2ImageDecoderPlugin: Draw the rest of the owl
With `#define JBIG2_DEBUG 1` at the top of the file:
% Build/lagom/bin/image --no-output \
.../JBIG2_ConformanceData-A20180829/F01_200_TT10.jb2
JBIG2LoadingContext: Organization: 0 (Sequential)
JBIG2LoadingContext: Number of pages: 1
Segment number: 0
Segment type: 48
Referred to segment count: 0
Segment page association: 1
Segment data length: 19
Runtime error: JBIG2ImageDecoderPlugin: Draw the rest of the owl
This is closer to what the spec instructs us to do, and matches how
associations are maintained in the timelines. Also note that the removed
destructor logic is not necessary since we visit the associated
animations anyways.
We create labels in the Browser from text on web documents, which may
use carriage returns. LibGfx will split lines on CR already, but LibGUI
would not consider CRs when computing the height of the containing
widget. The result was text that would not fit in the label's box.
We already have a helper to split a StringView by line while considering
"\n", "\r", and "\r\n". Add an analagous method to just count the number
of lines in the same manner.
Fixes pages 17-19 on
https://www.iro.umontreal.ca/~feeley/papers/ChevalierBoisvertFeeleyECOOP15.pdf
Calling the fill handler after painting the stroke as previously doesn't
work, since we need to set up the clip before both stroke and fill, and
unset it after both. The duplication is a bit unfortunate, but also
minor.
ObservableArray inherits from JS::Array and overrides `internal_set`
and `internal_delete` to run an interceptor callback when an indexed
item is added or deleted.
This is for validating that a decoder with a weak or nonexistent
sniff() method thinks it can decode an image. This should not be
treated as an error.
No behavior change.
We are currently using Core::DateTime, which is meant to represent local
time. However, we are doing no conversion between the parsed time in UTC
and local time, so we end up comparing time stamps from different time
zones.
Instead, store the parsed times as UnixDateTime, which is UTC. Then we
can always compare the parsed times against the current UTC time.
This also lets us store parsed milliseconds.
Displaying a GML preview in HackStudio seems to be broken at the moment,
but this change will be needed once it does work again, so might as well
make it now, while I'm aware of the issue.
When in permissive mode, the ConfigServer will not treat reads and
writes to non-pledged domains as errors, but instead turns them into
no-ops: Reads will act as if the key was not found, and writes will do
nothing. Permissive mode must be enabled before pledging any domains.
This is needed to make GUI Widgets nicer to work with in GML Playground:
a few Widgets include reads and writes to LibConfig in order to load
system settings (eg, GUI::Calendar) or to save and restore state
(eg, GUI::DynamicWidgetContainer). Without this change, editing a
layout that includes one of these Widgets will cause GML Playground to
crash when they try to access config domains that are not pledged.
The solution used previously is to make Playground pledge more domains,
but not only does this mean Playground has to know about these cases,
but also that working on a layout file can alter the user's settings in
other arbitrary apps, which is not something we want.
By simply ignoring these config accesses, we avoid those downsides, and
Widgets will simply use the fallback values they already have to provide
to Config::read_foo_value().
Turns out the spec didn't mean that the whole range is populated,
but that one of these ranges is populated. So take the argmax.
As fallout, explicitly mark the Liberation fonts as nonsymbolic
when we use them for the 14 standard fonts. Else, we'd regress
"PostScrõpt", since the Liberation fonts would otherwise go down
the "is symbolic or doesn't have explicit encoding" codepath,
since the standard fonts usually don't have an explicit encoding.
As a fallout from _that_, since the 14 standard fonts now go down
the regular truetype rendering path, and since we don't implement
lookup by postscript name yet, glyphs not present in Liberation
now cause text to stop rendering with a diag, instead of rendering
a "glyph not found" symbol. That isn't super common, only an
additional 4 files appear for the "'post' table not yet implemented"
diag. Since we'll implement that soon, this seems fine until then.
...from try_create_for_raw_bytes().
If a plugin returns `true` from sniff but then fails when calling
its `create()` method, we now no longer swallow that error.
Allows `image` (and other places in the system) to print a more
actionable error if early image headers are invalid.
(We now no longer try to find another plugin that can also handle
the image.)
Fixes a regression from #20063 / #19893 -- before then, we didn't
do fallible work this early.
When placement position is found we always want to do following:
- Mark the occupied cells in the occupation grid
- Add the item to the list of placed items
Therefore, having helper that does both is useful
With this change we use the same code to resolve (start, end, span)
based on computed values in all cases:
- When only column is definite
- When only row is definite
- When both are definite
Moves the code that identifies (start, end, span) for a grid item into
a separate function. By doing so, we can eliminate the duplicated code
between the placement of grid items with definite columns and those
with definite rows.
This change omits some of the comments that reference the spec, as they
were largely irrelevant and unhelpful for making changes or diagnosing
issues.
Table wrappers don't quite behave the same as most elements, in that
their computed height and width are not meant to be used for layout.
Instead, we now calculate suitable widths and heights based on the
contents of the table wrapper when performing absolute layout.
Fixes the layout of
http://wpt.live/css/css-position/position-absolute-center-007.html