Commit Graph
127 Commits
Author SHA1 Message Date
bflatastic f22caa6108 Fix #4938: Dynamic symbols keep per-instance appearance linked to the symbol 2026-11-01 04:53:38 +07:00
bflatastic ea0539976e Fix #4937: document artboard fills in exports, print and Export for Screens 2026-11-01 04:13:58 +07:00
dotCooCoo 777ad6765c File formats: JPEG 2000 images open and place
File › Open and File › Place read JP2 files and raw JPEG 2000
codestreams (.jpf, .jpx, .jp2, .j2k, .j2c, .jpc) through hayro-jpeg2000,
and store the pixels as PNG. Gray, RGB, CMYK and ICC-tagged images, with
or without alpha, are converted to RGBA. Several codestreams, JPX
composition or layers, other color spaces, inconsistent or oversize
palettes, inconsistent channel definitions, oversize tile grids and
images past the pixel allowance are refused with a message before the
pixels are decoded.

The capture and display resolution boxes size the image: the box that
comes last sets each axis, and an axis without a usable value uses
72 ppi.

IccProfile::to_srgb_into converts a pixel with the cached transform and
no heap allocation.
2026-11-01 01:22:05 +07:00
dotCooCoo d6297dbfb9 .ai import: type comes from the text document alone when every shown story reads
Squashed from #4865 onto main.
2026-11-01 00:35:35 +07:00
Don Omondi 1883e5342d PDF import: find installed fonts named with hyphens or a composite font's CMap
- A composite (Type 0) font is noted by its descendant CIDFont's BaseFont
  (ISO 32000-1 9.7.4.1), not its own BaseFont, which ends in "-" and the
  CMap name (9.7.6.1, e.g. Name-Identity-H); without one, the CMap name is
  taken off the end of the BaseFont.
- A font name's family is the longest part before a hyphen (or the comma of
  Arial,Bold) that names an available family, so Noto-Sans-Bold is Noto
  Sans, Bold and Noto-Sans-CJK-JP is Noto Sans CJK JP; a shorter family
  still matches when no longer one is available.
- A missing font is split only at a comma or before the first part that is a
  style word (Helvetica-BoldOblique); otherwise the whole name is its family
  (MS-PGothic is reported as MS PGothic, not MS).

Synthetic tests (no host fonts): Families::of builds the family list.

# Conflicts:
#	docs/file-format-parity.md
#	docs/gaps.md
#	docs/type-parity.md
2026-10-31 19:43:17 +07:00
Don Omondi 22b1c6bc2e Fix #3085: DXF LAYOUT objects write only the group codes the DXF Reference defines
The PLOTSETTINGS part of each LAYOUT wrote the paper image origin as a point
(148 and 158), but the origin is two values at 148 (x) and 149 (y), and 158 is
not a PLOTSETTINGS code. Strict readers such as Autodesk Fusion can reject the
file. The ezdxf re-save the reporter found Fusion accepts differs from our export in
these objects, not in the geometry.

- 148/149 for the paper image origin
- shade plot mode, resolution level and DPI (76/77/78) from DXF 2004
- plot flag 1024 (model type) on the Model layout
- the plot style ACDBPLACEHOLDER without a subclass marker

Test r2000_and_later_files_have_the_structure_cad_apps_require checks the
required sections and table entries, handles below $HANDSEED, references
that resolve, and LAYOUT group codes.

# Conflicts:
#	docs/file-format-parity.md
2026-10-31 19:43:17 +07:00
Don Omondi 7403003fb1 fix(eps): an envelope's contents being edited aren't read as art
An envelope whose contents are being edited is written the other way
round from one that isn't: its contents, a group on `%_` lines, then
its dictionary, which holds the mesh that shapes them. Only a group of
meshes was left out before an envelope's dictionary, so those contents
were read as art and their undistorted shapes drew over the distorted
art that follows on plain lines (and that the page draws).

The group on `%_` lines before an envelope's dictionary is now left
out whatever it holds; text in it stays as hidden text, as the
dictionary's own source text does.

# Conflicts:
#	docs/file-format-parity.md
2026-10-31 19:43:17 +07:00
Don Omondi 5b15b3f56b fix(eps): a transparency set in a dictionary's art stays after it
Art inside a dictionary in the editing data, such as an area text's
frame (`/ConfiningPath`) or a mask's art, can set a transparency
(`Xy`). The writer goes on from it: the objects after an area text
whose frame sets one have no `Xy` of their own. The reader dropped
that state when the dictionary closed, so those objects took the
transparency before the dictionary instead; in a user's file a Lighten
glow before an area text made everything after it fade into the light
background.

The last transparency the art inside a dictionary sets is now the
current one after it (and the enclosing dictionary's). Dictionaries
outside the layers (the setup's styles) are left as they were.

# Conflicts:
#	docs/file-format-parity.md
2026-10-31 19:43:17 +07:00
Don Omondi 75d2736a2a fix(eps): area type's first line goes where the file lays it out
Area type made from the editing data's text document was laid out with
its first baseline the font's ascent below the frame's top. The text
document keeps where each of its lines starts, and the file's page draws
them there: for some fonts the first line sits well above the font's
ascent (Oswald's at about its cap height), so headings came in lower
than on the page and the layers were taken to differ from it.

When the file's first line is more than half a point from where it is
laid out here, the first baseline is now fixed where the file has it
(First Baseline: Fixed), measured in the text document's own frame so a
copied object's type moves with its frame.

# Conflicts:
#	docs/file-format-parity.md
2026-10-31 19:43:17 +07:00
Don Omondi 3602bd6ea3 fix(ai-import): type from the text document takes its character style's attributes
Type made from an Illustrator file's text document took each character
attribute its run doesn't set from the document's base attributes, not
from the character style the run names ([Normal Character Style] or
another of the file's). Where the two differ the type came in wrong: a
file whose base fill is white and whose Normal Character Style is black
came in with its text white, invisible, so the layers differed from the
page wherever the page's own type didn't stand in for it.

A run now takes its own attributes, then its character style's (and the
styles that one is based on, up to 16), then the document's.
2026-10-31 19:43:17 +07:00
Don Omondi 9259434a89 SVG export: a gradient mesh patch is cut no finer than its colour changes
Each patch of a gradient mesh was cut into 8 x 8 flat quads for SVG export,
Object > Expand and the other outputs that cannot shade a mesh, whatever its
colours, so a patch of one colour became 64 identical pieces. Neighbouring
quads are now joined into square blocks wherever the colour changes by no
more than about one 8-bit step across the block; the block's outline runs
through its quads' corners, and a patch that folds over itself is not joined.
2026-10-31 19:43:16 +07:00
dotCooCoo b493e601a9 Docs: leave the DXF row of file-format-parity.md to #4796
The ELLIPSE note stays in docs/gaps.md; the open #4796 rewrites the same file-format-parity.md row.
2026-10-31 19:43:15 +07:00
dotCooCoo d0a903d5d7 DXF export: ellipses and unevenly scaled circles are written as ELLIPSE
A closed path of four cubics that is the four-cubic circle under an
affine map (an ellipse, or a circle scaled out of proportion) is written
as a native ELLIPSE in R13 and later, with its center, major axis and
minor to major ratio. The check maps the path back onto the unit circle
and runs the existing circle recognition on it. R12 keeps the existing
fallback, and ellipses with a ratio under 1e-6 stay splines. The ratio
and end parameter are written in full so that a thin ellipse keeps its
size and a whole turn reads back closed.

Part of #1299.
2026-10-31 19:43:15 +07:00
Don Omondi b0cc17343e fix(pdf-import): take a group's knockout and isolate flags from the interpreter
The import read each form's /Group /I and /K from the file in order and
matched them to the transparency groups the interpreter pushed. The
interpreter draws a group that adds nothing (full opacity, Normal, no
mask, neither flag) straight onto its parent without pushing it, so every
group after one took another group's flags. Blend steps written as a
knockout group of falling opacity then painted over each other and drew
as solid dark shapes instead of light rings.

The interpreter already reports the flags right after pushing a group
(set_knockout, set_isolated); the import now uses those and drops the
file-order list. That list was capped at 10,000 entries, past which a page
failed to import; that limit goes with it.
2026-10-31 05:27:13 +07:00
Don Omondi d4745fe046 fix(eps): a layer's state after its last blend stays the layer's
#4757 gives a blend the Xy written after its record. When the blend is a
layer's last object, the layer's own state block (Xy, Xd, 7 () XW, LB)
went to the blend instead, and the layer stayed opaque. The blend's state
is now tentative like a mesh's (#4748): its own 6 () XW confirms it, the
layer's LB gives it to the layer and the blend keeps what it had.

Also records the .ai/EPS audit fixes under G9, the File formats row and M4.
2026-10-31 05:11:04 +07:00
Don Omondi aa6a960062 fix(ai-import): compare a PDF of some artboards on the artboard its page shows
A PDF saved with Illustrator editing data for only some of its artboards
has pages for those artboards, while the editing data keeps them all. The
layers were compared with the first page on the first artboard, so a page
showing a later artboard never matched and the file came in as its PDF
part, without its layers.

With fewer pages than artboards, the first page is now taken to be the
artboard of its size whose art draws most like it (up to 16 weighed), and
the pages' type goes to that artboard and the ones after it. All the
artboards still come in, and the comparison still decides whether the
layers are used.
2026-10-31 04:55:14 +07:00
Don Omondi c4d2480132 .ai/EPS import: a blend takes the transparency written after its record
Squashed from #4757 onto main.
2026-10-31 04:39:05 +07:00
Don Omondi a1fc3cfdb1 fix(eps): a masked gradient mesh takes the transparency after its mask
A gradient mesh with an opacity mask has its own state (`Xy`) after the
mask's dictionary, not right after its `/End X!`. The operators of the
mask's art, on `%_` lines, cleared the flag that says a mesh just ended,
so the state was read as the next object's and each masked mesh in a
run drew with the blend mode of the one before it.

The flag now goes back to what it was when a dictionary opened once it
closes, as `after_object` does.
2026-10-31 04:21:56 +07:00
Don Omondi ff1f721013 fix(eps-import): keep a layer's opacity when its state block has the stroke style
A layer's own state block (Xy, Xd, 7 () XW before LB) can have the
stroke style (J j w M d XR) between its Xy and Xd. Read as the art moving
on, it dropped the layer's opacity, so a layer at 17% drew opaque and the
file came in as its page. The stroke style now keeps the pending layer
state, and the state a mesh before it had; an object's own 6 () XW block
still isn't the layer's.
2026-10-31 04:02:35 +07:00
Don Omondi bfe509bb38 fix(eps-import): read layers whose type is in the legacy format beside a page with text
An EPS saved for Illustrator 10 keeps its type in the editing data as
legacy text objects (`To` ... `TO`), with no `/AI11Text` slot for the
page's type to go in, so a file whose page had text came in as its page.
Those text objects are now the layers' own: the page's type isn't put
anywhere, and the comparison with the page decides as before. Type the
editing data keeps only as outlines stays outlines, with a note counting
the page's text objects that are.
2026-10-31 03:34:40 +07:00
Don Omondi ef3b5b0c95 fix(eps): a layer's state after its last mesh stays the layer's
An Xy right after a gradient mesh's /End X! is the mesh's only when the
mesh's own 6 () XW follows. When the layer's LB follows (directly or
after the layer's Xd and 7 () XW) it is the layer's, as before, and the
mesh keeps the state it had. Also corrects the revision-history row that
still said meshes with handle weights of 0 aren't read.
2026-10-31 02:52:13 +07:00
Don Omondi 1a5f0fb099 fix(ai-import): space type on a path round curves as the file lays it out
Type on a path from the editing data's text document came in at the
font's advances, while the file's own layout (and its page) closes the
glyphs up round the outside of a curve and opens them up round the
inside, even where the frame keeps no spacing. Round a circle the type
ran on past where the page ends it.

The spacing (Type on a Path Options > Spacing) that reproduces the
layout is now fitted from the layout's glyph positions, advances and
turns, using the text engine's own model, and set on the imported text
object. Corners and straight runs are left out of the fit.
2026-10-31 02:05:52 +07:00
Don Omondi 7b4a65e231 fix(ai-import): put placed files where they draw closer to the page
The corner placement of placed files was tried only when the first
placement failed the comparison with the page. A small logo in the wrong
place differs too little to fail, so it stayed there. When the corner
placement draws closer to the page and still matches it, use it.
2026-10-31 02:05:48 +07:00
Don Omondi 67c8d86c6f .ai import: a page's type inside placed files needs no text object
A .ai whose layers hold placed (linked) PDFs and no text object came in as
its PDF part, saying its layers had no text objects for its page's text.
The PDF part draws each placed file, type and all, where the layers show
its preview, so type that lies inside the placed files (at either of their
placements) is theirs and needs no text object. Type outside them still
does.
2026-10-31 02:05:43 +07:00
Don Omondi e5481bda98 fix(eps): a gradient mesh takes the transparency written after it
In the editing data of a .ai or EPS file, a gradient mesh's own state
(`Xy`) comes right after its `/End X!`, before its `Xd` and `XW`, as a
group's comes after its `U`. The reader took it as the next object's, so
a Multiply shadow mesh came in as Normal and painted opaque white over
the art under it, while the file's page shows the shadow.

An `Xy` read straight after a mesh ends now also applies to that mesh.
An `Xy` after the mesh's `Xd` and `XW` stays the next object's.
2026-10-31 02:05:39 +07:00
Don Omondi dc6af04dcc fix(ai-import): read mesh corners whose handle weights are 0
Some files write a handle weight of 0 on some gradient mesh corners. The
reader took only weights of 1, so the mesh and the whole file's layers
were unread. A weight of 0 draws as the same cubic edge against the files'
pages; other weights still leave the mesh unread.
2026-10-31 02:05:35 +07:00
Don Omondi 66c797a59b .ai import: outlines from the editing data keep their look and threads; mesh corners with non-numbers are unread
Follow-ups to the review of #4697 and #4698:

- With textAs: outlines, a .ai saved without PDF compatibility, read
  from its editing data alone, has its type outlined too, as an empty
  page or a text-only placeholder already did.
- Threaded type read from the editing data holds its story in its first
  frame: it now flows through its frames before it is outlined, so each
  frame's outlines show the text it holds, and the outlined frames
  leave their threads.
- Each outline group keeps its type's opacity, blend mode, isolation,
  opacity mask and effects (the same carry-over the flattener uses).
- A gradient-mesh corner (/N) holding anything but numbers is unread,
  instead of being read with the numbers after it shifted into its
  colour and opacity.
2026-10-30 23:55:32 +07:00
Don Omondi 1d58ea947d fix(ai-import): pages cropped to the art in UserUnit units, and their copies' type
A page cropped to the art is recognised in a UserUnit page's units too,
when the art's box is the page in those units and the artboard isn't the
page in points. Such pages are taken only when every page is the art's
box, and only the first page's type is read: the later pages are copies
whose type was moved by the first page's offset and could fill the
layers' text objects twice.
2026-10-30 23:55:28 +07:00
Don Omondi 75958ce7da fix(ai-import): weigh unseen text again at the placed files' other placement
prune_unseen ran before the retry that moves placed files to their box's
corner, and that retry cloned the pruned layers: text an image covered
only at its first placement was already gone, so the file came in without
it or as its PDF part. Clone the layers before pruning and prune each
placement on its own.
2026-10-30 23:55:22 +07:00
Don Omondi 530605d4fc fix(ai-import): keep All Caps and Small Caps on type from the text document
Character attribute 12 of the editing data's text document is the case
(1 Small Caps, 2 All Caps). The reader skipped it, so type set in All Caps
came in as typed, in lower or mixed case where the page draws capitals.
Map it onto CharStyle::all_caps and CharStyle::small_caps.
2026-10-30 23:55:16 +07:00
Don Omondi 75e8f69734 PDF import: large mesh shadings and mesh-painted strokes come in as gradient meshes
Patch and triangle mesh shadings of more than 4,096 patches, and strokes
painted with a mesh shading, came in as a flat grey. Illustrator writes
meshes of up to 14,355 patches, and writes a freeform gradient on a
stroke as a stroke painted with a type 7 shading.

- MAX_PATCHES is 16,384, as in the .ai editing-data reader.
- A stroke painted with a mesh shading is the meshes clipped to the area
  the stroke paints (stroke_outline: width, caps, joins, miter limit and
  dashes, built in the path's space and then transformed); draw_meshes
  always clips a stroke's meshes.
2026-10-30 19:44:50 +07:00
Don Omondi 4f5d270ae9 .ai import: an empty page with skipped content isn't empty; outlines asked for are given
Two follow-ups to the empty-page fallback:

- A page counts as empty only when nothing on it was skipped: its only
  notes are the page's own (art off the artboards, art past the page). A
  page whose only content couldn't be read, such as an image that can't
  be decoded, keeps its notes and goes through the usual check against
  the editing data, instead of being replaced by it unchecked.
- With textAs: outlines, the document read from the editing data alone
  has its type outlined. The usual path takes outlines from the page,
  but an empty page (or a text-only placeholder, #1387) has none to give.
2026-10-30 19:44:45 +07:00
Don Omondi c0ee9c1986 .ai/EPS import: read gradient meshes in named colours, mixed colour spaces and large grids
A mesh in the editing data that the reader couldn't read made the whole
file come in as its page or PDF part, without its layers. Three cases
were rejected that files write routinely:

- A mesh starts grey, and `/CS` is written only where the colour space
  changes, before the corner it applies to, even within a patch. Meshes
  with no `/CS`, or one that changed between corners, were unread.
- Named colours (`[c m y k /DeviceCMYK (name) /Process]` or `/Spot`) and
  `/NChannel` inks: each corner gives the tint, 1 being the full colour.
- Grids over 64 patches a side or 4,096 patches (files have 97 x 72).

Each corner now takes the colour space last set before it; named
colours paint at their tint and inks overprint at theirs; the limits
are 128 a side and 16,384 patches.
2026-10-30 19:44:41 +07:00
Don Omondi b8886d3da4 .ai import: try a placed file at its box's corner when the layers differ
A placed (linked) file is put where its matrix takes the canvas point of
art space's origin (the centre of %AI3_TemplateBox). In many files the
matrix takes the corner of the box the file is written with instead, so
the image landed far off its artboard, the layers differed from the
page, and the file came in as its PDF part.

The reader keeps that second placement for each placed file where the
two differ. When the layers don't draw as the page, they are compared
again with those files at their box's corner, and used if that draws
as the page. Files whose layers already match keep their placement.
2026-10-30 09:46:56 +07:00
bflatastic beb0ae6515 SVG export: rectangles, circles, ellipses, lines and straight paths as SVG shape elements (#4652) 2026-10-30 09:45:59 +07:00
Don Omondi 380a3cfcff .ai import: a placed file on %_ lines no longer drops the layers
A placed (linked) file written as an object's editable copy, on %_
lines after its drawn look, has its %AI5_BeginPlace and %AI5_EndPlace
markers on those lines too. The lexer dropped comments after %_ that
don't start a section, so the placed file never began, the ~ that ends
it was an operator the reader didn't know, and the whole file came in
as its PDF part. The lexer now returns those two markers from %_ lines,
and the preview reader skips the %_ its header line starts with.
2026-10-30 09:01:24 +07:00
Don Omondi 43db0c00bc PDF export: gradient meshes as smooth Type 6 patch shadings
PDF export (and the PDF-compatible .ai it writes) cut each gradient mesh
patch into 8 x 8 flat-coloured quads. Viewers showed colour bands and
hairline seams between them, and files with many meshes became very
large and slow to write.

An opaque mesh is now written as one Type 6 (Coons patch) shading
(ISO 32000-1, 8.7.4.5.7) filling its outline, through the PDF writer's
MeshGradient: each patch blends its corner colours bilinearly, as the
canvas draws it. Colours go through page_color as other fills do, and a
mesh mixing RGB with other models goes through RGB. A mesh with
see-through points, an invalid one, or one past the coordinate range
keeps the quads.
2026-10-30 08:15:20 +07:00
Don Omondi 87cb19c589 .ai import: a file whose PDF part is an empty page opens from its editing data
Squashed from #4651 onto main.
2026-10-30 08:15:16 +07:00
Don Omondi 0f1b70f8b1 .ai import: a PDF part cropped to the art no longer hides the layers
A PDF-compatible .ai whose PDF part's pages are cropped to its art (each
page the box of all the art, the editing data's bounding box) rather
than to its artboards came in as that PDF part: the editing data's
artboard wasn't the page's size, so its layers were refused. With
several artboards every page held all the art, so the document had a
copy of everything per page.

When the artboard isn't the page's size but the editing data's bounding
box is, the layers are compared with the page on that box and keep
their artboards. The comparison of their art with the page still
decides whether they are used.
2026-10-30 08:15:04 +07:00
Don Omondi 2e3a4ec604 Fix #3911: EMF export writes a pattern fill as one shape per part of its tile
A pattern fill was written to EMF as every tile's art, each tile in a clip
of its own, with the brush made again for each part: a rotated two-colour
stripe fill of a 360 x 260 pt rectangle took 473 fills, 246 clips and
122 KB.

When the tiles can't overlap (a grid or brick tiling whose art stays in its
tile), each tile's clip is left out where what it clips lies inside it
already (a convex clip holding every control point of the fills), and the
n-th fill of every tile becomes one path. The picture is the same: the
tiles don't overlap, and the fill's own clip still trims them. That fill
is now 2 fills and 1 clip, 61 KB; unrotated, 99 KB becomes 33 KB.

Tiles that overlap, hex tilings, and tiles holding strokes, images or
clips that cut are written as before, their parts off the page left out.
2026-10-30 05:52:37 +07:00
Don Omondi 68ad249efd Fix #3510: editing data past 512 MiB opens with its layers where memory allows
A layered .ai or Illustrator EPS whose editing data (embedded rasters,
mostly) unpacks past 512 MiB opened as its PDF part or printed page, in
one layer, with "it decompresses to more than 512 MB" (#4628 on 0.17.0
hit the older 256 MiB limit the same way).

The limit is now an eighth of installed memory, from 512 MiB (what every
64-bit build read before) to 2 GiB: 1 GiB on an 8 GiB machine, 2 GiB on
16 GiB or more. Reading takes about as much memory again as the data
(1.1 GB of data with 24 embedded 4096 x 4096 images peaked 1.1 GB above
the start), so the ceiling keeps a small file that unpacks without end
from taking a large machine's memory. 32-bit and web builds keep 256 MiB.
vectorcraft_render::installed_memory exposes the reading the image cache
already sizes itself from.
2026-10-30 05:07:58 +07:00
bflatastic c0bd20b6a2 Docs: cut the progress docs' status lines back to their latest change
Merges kept prepending each side's whole summary as "previously: …", so
target-app-parity.md's status line had grown to 66 MB (839 copies of its
Target clause), gaps.md's and ui-parity.md's to over 1 MB. Each status
line now names its latest change only, as the progress-docs standard has
it; the revision histories keep the earlier ones.
2026-10-30 01:46:33 +07:00
Taha-Mahmoodi 887328db03 Fix #4420: import attached recolor adjustment layers as color overlays
In Affinity Designer, Recolor Adjustment layers (RcRA) can be attached to
vector groups/shapes via AdCh. Lightness 1.0 recolors target elements to
white. Import visible RcRA layers as ColorOverlay effects and apply them
during node appearance evaluation.
2026-10-30 00:15:58 +07:00
dotCooCoo f32699bea7 File formats: PCX (.pcx) files open and place
A new reader, written from the ZSoft PCX Technical Reference Manual, decodes
the run-length encoded scan lines of 1-bit images in the header palette's
first two colors (black and white when the version has no palette or the two
colors are the same), 1-bit images in two to four planes and 4-bit images
with the header's palette (the EGA colors for versions 0 and 3), 2-bit CGA
images in the colors that the header's CGA background and palette settings
pick, 8-bit images with the 256-color palette after the image data (gray
levels without one) and 24-bit images in three planes. The image is stored as PNG at the resolution of the header's HDpi and
VDpi fields.

Open and Place list PCX, and pasting a copied .pcx file and Glass's Load
Texture… read it by its header. A file of another depth or plane count, one
cut short and one whose pixels as RGBA pass the pixel allowance are refused
with a message before its pixels are decoded. The desktop packaging does not
associate .pcx files, and no export writes them.

Docs: docs/file-format-parity.md, docs/target-app-parity.md, docs/mcp.md,
docs/releasing.md.
2026-10-30 00:15:56 +07:00
Don Omondi 88cf3c817c Docs: record EPS Save in status lines and revision histories
CodeRabbit follow-up for #4293. Add 2026-10-26 revision-history rows and
status-line updates for EPS Save and Save As in file-format-parity, gaps
(G9), roadmap and target-app-parity; move the completed EPS Save note in
roadmap's M4 row out of "Left:". Save-back is recorded as done; G9 import
fidelity and Illustrator editing-data writing (#868) are unchanged. Scores
and estimates unchanged. Docs only.
2026-10-29 13:00:48 +07:00
Don Omondi c6070f633e Support original-format EPS Save and Save As 2026-10-29 13:00:47 +07:00
aiongg e724228e25 docs: update source paths for the moved files 2026-10-26 22:01:25 +00:00
YOU WISH! GAMES aa7f6bb31d .ai import: editing data up to 512 MiB opens on 64-bit builds, so a card file with embedded rasters keeps its layers and text (part of #3510)
Squashed from #4177 onto main.
2026-10-26 08:18:31 +07:00
YOU WISH! GAMESandClaude Sonnet 5.5 9af023b084 .ai import: the -- placeholder in a gradient highlight and the XC operator no longer send the file to its PDF part (fixes #4176)
An undefined number (--) in `-- -- angle length Bh` is read as a radial
gradient with no highlight, and XC (a color space name after a linked
image's file name) is ignored like its neighbours. Either one used to make
the whole editing data unreadable, so the file opened as its PDF part and
lost its layers and live text. A -- anywhere else is still an operator the
reader doesn't know.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 08:18:25 +07:00
Taha-Mahmoodi cab62cbb18 Fix #3964: Create Outlines, EPS, EMF/WMF and legacy .ai keep the ruby where the canvas draws it 2026-10-24 17:29:32 +07:00