You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by ji...@apache.org on 2026/10/23 18:26:05 UTC

(openoffice) branch odf-devel updated (7071125f70 -> d222476c5a)

This is an automated email from the ASF dual-hosted git repository.

jimjag pushed a change to branch odf-devel
in repository https://gitbox.apache.org/repos/asf/openoffice.git


    from 7071125f70 test/odf-validate: add fixtures for the default-mode gates
     new 3ac86099fe xmloff: import extension paragraph fill attributes
     new d222476c5a test/odf-validate: add fixtures for the extension paragraph fill import

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 main/xmloff/source/style/prstylei.cxx              | 118 ++++++
 .../fixtures/para-fill-foreign/aoo-form.odt        | Bin 0 -> 18940 bytes
 .../fixtures/para-fill-foreign/checks-angle.json   |  16 +
 .../para-fill-foreign/checks-aoo-form.json         | 378 +++++++++++++++++
 .../para-fill-foreign/checks-edge-both-forms.json  | 464 +++++++++++++++++++++
 .../checks-edge-duplicate-nested.json              | 464 +++++++++++++++++++++
 .../para-fill-foreign/checks-edge-empty.json       | 452 ++++++++++++++++++++
 .../checks-edge-nonparagraph.json                  | 464 +++++++++++++++++++++
 .../checks-edge-unknown-attr.json                  | 464 +++++++++++++++++++++
 .../checks-edge-unknown-name.json                  | 440 +++++++++++++++++++
 .../fixtures/para-fill-foreign/checks-frame.json   |  10 +
 .../para-fill-foreign/checks-unknown-attr.json     |  22 +
 .../fixtures/para-fill-foreign/checks-v13-v14.json | 464 +++++++++++++++++++++
 .../fixtures/para-fill-foreign/checks.json         | 464 +++++++++++++++++++++
 .../fixtures/para-fill-foreign/edge-both-forms.odt | Bin 0 -> 29275 bytes
 .../para-fill-foreign/edge-duplicate-nested.odt    | Bin 0 -> 29280 bytes
 .../fixtures/para-fill-foreign/edge-empty.odt      | Bin 0 -> 29265 bytes
 .../para-fill-foreign/edge-nonparagraph.odt        | Bin 0 -> 29312 bytes
 .../para-fill-foreign/edge-unknown-attr.odt        | Bin 0 -> 29286 bytes
 .../para-fill-foreign/edge-unknown-name.odt        | Bin 0 -> 29273 bytes
 .../fixtures/para-fill-foreign/foreign-v11.odt     | Bin 0 -> 29272 bytes
 .../fixtures/para-fill-foreign/foreign-v3.odt      | Bin 0 -> 29271 bytes
 .../fixtures/para-fill-foreign/foreign-v8.odt      | Bin 0 -> 29267 bytes
 .../fixtures/para-fill-foreign/gen.bas             |  95 +++++
 .../fixtures/para-fill-foreign/make-aoo.py         |  64 +++
 .../fixtures/para-fill-foreign/make.py             | 118 ++++++
 .../fixtures/para-fill-foreign/mkexpect.py         |  75 ++++
 .../fixtures/para-fill-foreign/tile.png            | Bin 0 -> 1795 bytes
 28 files changed, 4572 insertions(+)
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/aoo-form.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-angle.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-aoo-form.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-edge-both-forms.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-edge-duplicate-nested.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-edge-empty.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-edge-nonparagraph.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-edge-unknown-attr.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-edge-unknown-name.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-frame.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-unknown-attr.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks-v13-v14.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/checks.json
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/edge-both-forms.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/edge-duplicate-nested.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/edge-empty.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/edge-nonparagraph.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/edge-unknown-attr.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/edge-unknown-name.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/foreign-v11.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/foreign-v3.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/foreign-v8.odt
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/gen.bas
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/make-aoo.py
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/make.py
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/mkexpect.py
 create mode 100644 test/odf-validate/fixtures/para-fill-foreign/tile.png


(openoffice) 02/02: test/odf-validate: add fixtures for the extension paragraph fill import

Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jimjag pushed a commit to branch odf-devel
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit d222476c5abedf2c7c68174449c9e8de078e39ee
Author: Jim Jagielski <ji...@gmail.com>
AuthorDate: Fri Oct 23 14:25:57 2026 -0400

    test/odf-validate: add fixtures for the extension paragraph fill import
---
 .../fixtures/para-fill-foreign/aoo-form.odt        | Bin 0 -> 18940 bytes
 .../fixtures/para-fill-foreign/checks-angle.json   |  16 +
 .../para-fill-foreign/checks-aoo-form.json         | 378 +++++++++++++++++
 .../para-fill-foreign/checks-edge-both-forms.json  | 464 +++++++++++++++++++++
 .../checks-edge-duplicate-nested.json              | 464 +++++++++++++++++++++
 .../para-fill-foreign/checks-edge-empty.json       | 452 ++++++++++++++++++++
 .../checks-edge-nonparagraph.json                  | 464 +++++++++++++++++++++
 .../checks-edge-unknown-attr.json                  | 464 +++++++++++++++++++++
 .../checks-edge-unknown-name.json                  | 440 +++++++++++++++++++
 .../fixtures/para-fill-foreign/checks-frame.json   |  10 +
 .../para-fill-foreign/checks-unknown-attr.json     |  22 +
 .../fixtures/para-fill-foreign/checks-v13-v14.json | 464 +++++++++++++++++++++
 .../fixtures/para-fill-foreign/checks.json         | 464 +++++++++++++++++++++
 .../fixtures/para-fill-foreign/edge-both-forms.odt | Bin 0 -> 29275 bytes
 .../para-fill-foreign/edge-duplicate-nested.odt    | Bin 0 -> 29280 bytes
 .../fixtures/para-fill-foreign/edge-empty.odt      | Bin 0 -> 29265 bytes
 .../para-fill-foreign/edge-nonparagraph.odt        | Bin 0 -> 29312 bytes
 .../para-fill-foreign/edge-unknown-attr.odt        | Bin 0 -> 29286 bytes
 .../para-fill-foreign/edge-unknown-name.odt        | Bin 0 -> 29273 bytes
 .../fixtures/para-fill-foreign/foreign-v11.odt     | Bin 0 -> 29272 bytes
 .../fixtures/para-fill-foreign/foreign-v3.odt      | Bin 0 -> 29271 bytes
 .../fixtures/para-fill-foreign/foreign-v8.odt      | Bin 0 -> 29267 bytes
 .../fixtures/para-fill-foreign/gen.bas             |  95 +++++
 .../fixtures/para-fill-foreign/make-aoo.py         |  64 +++
 .../fixtures/para-fill-foreign/make.py             | 118 ++++++
 .../fixtures/para-fill-foreign/mkexpect.py         |  75 ++++
 .../fixtures/para-fill-foreign/tile.png            | Bin 0 -> 1795 bytes
 27 files changed, 4454 insertions(+)

diff --git a/test/odf-validate/fixtures/para-fill-foreign/aoo-form.odt b/test/odf-validate/fixtures/para-fill-foreign/aoo-form.odt
new file mode 100644
index 0000000000..a6d41ec52d
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/aoo-form.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-angle.json b/test/odf-validate/fixtures/para-fill-foreign/checks-angle.json
new file mode 100644
index 0000000000..560b31b64d
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-angle.json
@@ -0,0 +1,16 @@
+[
+ {
+  "name": "gradient_angle",
+  "expr": "[(n, doc.StyleFamilies.getByName('ParagraphStyles').getByName(n).FillGradient.Angle) for n in ('S_gradient','S_gradient_transp')]",
+  "expect": [
+   [
+    "S_gradient",
+    300
+   ],
+   [
+    "S_gradient_transp",
+    300
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-aoo-form.json b/test/odf-validate/fixtures/para-fill-foreign/checks-aoo-form.json
new file mode 100644
index 0000000000..c3ad2685a0
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-aoo-form.json
@@ -0,0 +1,378 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ],
+   [
+    "styled gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-edge-both-forms.json b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-both-forms.json
new file mode 100644
index 0000000000..0b59001281
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-both-forms.json
@@ -0,0 +1,464 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    16711680,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    16711680,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    16711680,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1711210496,
+    false
+   ],
+   [
+    "styled gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    16711680,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    16711680,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    16711680,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1711210496,
+    false
+   ]
+  ]
+ },
+ {
+  "name": "direct_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' else None),o.FillTransparence,(o.FillBitmapMode.value if o.FillStyle.value=='BITMAP' else None),('GraphicObject:' in o.FillBitmapURL and 'GraphicObject:0000' not in o.FillBitmapURL)))(p) for e in [doc.Text.createEnumeration()] for p in iter(lambda: e.nextElement() if e.hasMoreElements() else None, None) if p.String.startswith('direct')]",
+  "expect": [
+   [
+    "direct solid",
+    "SOLID",
+    3385941,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    null,
+    false
+   ],
+   [
+    "direct gradient",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch",
+    "SOLID",
+    16777164,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch_nobg",
+    "SOLID",
+    16755200,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    "STRETCH",
+    true
+   ],
+   [
+    "direct bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    "NO_REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_transp",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-edge-duplicate-nested.json b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-duplicate-nested.json
new file mode 100644
index 0000000000..0f88343021
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-duplicate-nested.json
@@ -0,0 +1,464 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ],
+   [
+    "styled gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ]
+  ]
+ },
+ {
+  "name": "direct_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' else None),o.FillTransparence,(o.FillBitmapMode.value if o.FillStyle.value=='BITMAP' else None),('GraphicObject:' in o.FillBitmapURL and 'GraphicObject:0000' not in o.FillBitmapURL)))(p) for e in [doc.Text.createEnumeration()] for p in iter(lambda: e.nextElement() if e.hasMoreElements() else None, None) if p.String.startswith('direct')]",
+  "expect": [
+   [
+    "direct solid",
+    "SOLID",
+    3385941,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    null,
+    false
+   ],
+   [
+    "direct gradient",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch",
+    "SOLID",
+    16777164,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch_nobg",
+    "SOLID",
+    16755200,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    "STRETCH",
+    true
+   ],
+   [
+    "direct bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    "NO_REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_transp",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-edge-empty.json b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-empty.json
new file mode 100644
index 0000000000..28146a9147
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-empty.json
@@ -0,0 +1,452 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ],
+   [
+    "styled gradient",
+    "SOLID",
+    8388736,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "SOLID",
+    8388736,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ]
+  ]
+ },
+ {
+  "name": "direct_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' else None),o.FillTransparence,(o.FillBitmapMode.value if o.FillStyle.value=='BITMAP' else None),('GraphicObject:' in o.FillBitmapURL and 'GraphicObject:0000' not in o.FillBitmapURL)))(p) for e in [doc.Text.createEnumeration()] for p in iter(lambda: e.nextElement() if e.hasMoreElements() else None, None) if p.String.startswith('direct')]",
+  "expect": [
+   [
+    "direct solid",
+    "SOLID",
+    3385941,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    null,
+    false
+   ],
+   [
+    "direct gradient",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch",
+    "SOLID",
+    16777164,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch_nobg",
+    "SOLID",
+    16755200,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    "STRETCH",
+    true
+   ],
+   [
+    "direct bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    "NO_REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_transp",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-edge-nonparagraph.json b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-nonparagraph.json
new file mode 100644
index 0000000000..0f88343021
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-nonparagraph.json
@@ -0,0 +1,464 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ],
+   [
+    "styled gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ]
+  ]
+ },
+ {
+  "name": "direct_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' else None),o.FillTransparence,(o.FillBitmapMode.value if o.FillStyle.value=='BITMAP' else None),('GraphicObject:' in o.FillBitmapURL and 'GraphicObject:0000' not in o.FillBitmapURL)))(p) for e in [doc.Text.createEnumeration()] for p in iter(lambda: e.nextElement() if e.hasMoreElements() else None, None) if p.String.startswith('direct')]",
+  "expect": [
+   [
+    "direct solid",
+    "SOLID",
+    3385941,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    null,
+    false
+   ],
+   [
+    "direct gradient",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch",
+    "SOLID",
+    16777164,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch_nobg",
+    "SOLID",
+    16755200,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    "STRETCH",
+    true
+   ],
+   [
+    "direct bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    "NO_REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_transp",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-edge-unknown-attr.json b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-unknown-attr.json
new file mode 100644
index 0000000000..0f88343021
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-unknown-attr.json
@@ -0,0 +1,464 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ],
+   [
+    "styled gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ]
+  ]
+ },
+ {
+  "name": "direct_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' else None),o.FillTransparence,(o.FillBitmapMode.value if o.FillStyle.value=='BITMAP' else None),('GraphicObject:' in o.FillBitmapURL and 'GraphicObject:0000' not in o.FillBitmapURL)))(p) for e in [doc.Text.createEnumeration()] for p in iter(lambda: e.nextElement() if e.hasMoreElements() else None, None) if p.String.startswith('direct')]",
+  "expect": [
+   [
+    "direct solid",
+    "SOLID",
+    3385941,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    null,
+    false
+   ],
+   [
+    "direct gradient",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch",
+    "SOLID",
+    16777164,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch_nobg",
+    "SOLID",
+    16755200,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    "STRETCH",
+    true
+   ],
+   [
+    "direct bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    "NO_REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_transp",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-edge-unknown-name.json b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-unknown-name.json
new file mode 100644
index 0000000000..513b57a113
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-edge-unknown-name.json
@@ -0,0 +1,440 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ],
+   [
+    "styled gradient",
+    "SOLID",
+    8388736,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "SOLID",
+    8388736,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ]
+  ]
+ },
+ {
+  "name": "direct_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' else None),o.FillTransparence,(o.FillBitmapMode.value if o.FillStyle.value=='BITMAP' else None),('GraphicObject:' in o.FillBitmapURL and 'GraphicObject:0000' not in o.FillBitmapURL)))(p) for e in [doc.Text.createEnumeration()] for p in iter(lambda: e.nextElement() if e.hasMoreElements() else None, None) if p.String.startswith('direct')]",
+  "expect": [
+   [
+    "direct solid",
+    "SOLID",
+    3385941,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    null,
+    false
+   ],
+   [
+    "direct gradient",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch",
+    "SOLID",
+    16777164,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch_nobg",
+    "SOLID",
+    16755200,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    "STRETCH",
+    true
+   ],
+   [
+    "direct bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    "NO_REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_transp",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-frame.json b/test/odf-validate/fixtures/para-fill-foreign/checks-frame.json
new file mode 100644
index 0000000000..fa221c56ab
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-frame.json
@@ -0,0 +1,10 @@
+[
+ {
+  "name": "frame_style_g9",
+  "expr": "[doc.StyleFamilies.getByName('FrameStyles').hasByName('G9')] + ([doc.StyleFamilies.getByName('FrameStyles').getByName('G9').FillStyle.value] if doc.StyleFamilies.getByName('FrameStyles').hasByName('G9') else [])",
+  "expect": [
+   true,
+   "NONE"
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-unknown-attr.json b/test/odf-validate/fixtures/para-fill-foreign/checks-unknown-attr.json
new file mode 100644
index 0000000000..0bb9c9a660
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-unknown-attr.json
@@ -0,0 +1,22 @@
+[
+ {
+  "name": "style_user_attributes",
+  "expr": "[(n, sorted(st.getByName(n).ParaUserDefinedAttributes.ElementNames)) for st in [doc.StyleFamilies.getByName('ParagraphStyles')] for n in ('S_solid', 'S_gradient')]",
+  "expect": [
+   [
+    "S_solid",
+    [
+     "loext:hyphenation-keep-line",
+     "loext:hyphenation-keep-type"
+    ]
+   ],
+   [
+    "S_gradient",
+    [
+     "loext:hyphenation-keep-line",
+     "loext:hyphenation-keep-type"
+    ]
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks-v13-v14.json b/test/odf-validate/fixtures/para-fill-foreign/checks-v13-v14.json
new file mode 100644
index 0000000000..077532e379
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks-v13-v14.json
@@ -0,0 +1,464 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ],
+   [
+    "styled gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     0,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     0,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     0,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     0,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ]
+  ]
+ },
+ {
+  "name": "direct_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' else None),o.FillTransparence,(o.FillBitmapMode.value if o.FillStyle.value=='BITMAP' else None),('GraphicObject:' in o.FillBitmapURL and 'GraphicObject:0000' not in o.FillBitmapURL)))(p) for e in [doc.Text.createEnumeration()] for p in iter(lambda: e.nextElement() if e.hasMoreElements() else None, None) if p.String.startswith('direct')]",
+  "expect": [
+   [
+    "direct solid",
+    "SOLID",
+    3385941,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    null,
+    false
+   ],
+   [
+    "direct gradient",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch",
+    "SOLID",
+    16777164,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch_nobg",
+    "SOLID",
+    16755200,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    "STRETCH",
+    true
+   ],
+   [
+    "direct bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    "NO_REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_transp",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/checks.json b/test/odf-validate/fixtures/para-fill-foreign/checks.json
new file mode 100644
index 0000000000..0f88343021
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/checks.json
@@ -0,0 +1,464 @@
+[
+ {
+  "name": "styled_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle. [...]
+  "expect": [
+   [
+    "styled solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "styled solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ],
+   [
+    "styled gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "styled gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "styled hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "styled hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "styled bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "styled bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ]
+  ]
+ },
+ {
+  "name": "para_styles",
+  "expr": "[(n,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' or (o.FillStyle.value=='HATCH' and o.FillBackground) else None),o.FillTransparence,bool(o.FillGradientName),(lambda g:(g.Style.value,g.StartColor,g.EndColor,g.Angle,g.Border))(o.FillGradient) if o.FillStyle.value=='GRADIENT' else None,bool(o.FillHatchName),(lambda h:(h.Style.value,h.Color,h.Distance,h.Angle))(o.FillHatch) if o.FillStyle.value=='HATCH' else None,o.FillBackground if o.FillStyle.value== [...]
+  "expect": [
+   [
+    "S_bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "NO_REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "STRETCH",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_bitmap_transp",
+    "BITMAP",
+    null,
+    50,
+    false,
+    null,
+    false,
+    null,
+    null,
+    true,
+    "REPEAT",
+    true,
+    -1,
+    true
+   ],
+   [
+    "S_gradient",
+    "GRADIENT",
+    null,
+    0,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    8388736,
+    false
+   ],
+   [
+    "S_gradient_transp",
+    "GRADIENT",
+    null,
+    30,
+    true,
+    [
+     "LINEAR",
+     16711680,
+     255,
+     300,
+     10
+    ],
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1283457152,
+    false
+   ],
+   [
+    "S_hatch",
+    "HATCH",
+    16777164,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    true,
+    false,
+    null,
+    false,
+    16777164,
+    false
+   ],
+   [
+    "S_hatch_nobg",
+    "HATCH",
+    null,
+    0,
+    false,
+    null,
+    true,
+    [
+     "SINGLE",
+     16755200,
+     200,
+     450
+    ],
+    false,
+    false,
+    null,
+    false,
+    2147461632,
+    false
+   ],
+   [
+    "S_solid",
+    "SOLID",
+    3385941,
+    0,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    3385941,
+    false
+   ],
+   [
+    "S_solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    false,
+    null,
+    false,
+    null,
+    null,
+    false,
+    null,
+    false,
+    1697863082,
+    false
+   ]
+  ]
+ },
+ {
+  "name": "direct_paragraphs",
+  "expr": "[(p.String,)+(lambda o:(o.FillStyle.value,(o.FillColor if o.FillStyle.value=='SOLID' else None),o.FillTransparence,(o.FillBitmapMode.value if o.FillStyle.value=='BITMAP' else None),('GraphicObject:' in o.FillBitmapURL and 'GraphicObject:0000' not in o.FillBitmapURL)))(p) for e in [doc.Text.createEnumeration()] for p in iter(lambda: e.nextElement() if e.hasMoreElements() else None, None) if p.String.startswith('direct')]",
+  "expect": [
+   [
+    "direct solid",
+    "SOLID",
+    3385941,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct solid_transp",
+    "SOLID",
+    3364266,
+    40,
+    null,
+    false
+   ],
+   [
+    "direct gradient",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct gradient_transp",
+    "SOLID",
+    8388736,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch",
+    "SOLID",
+    16777164,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct hatch_nobg",
+    "SOLID",
+    16755200,
+    0,
+    null,
+    false
+   ],
+   [
+    "direct bitmap_tile",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_stretch",
+    "BITMAP",
+    null,
+    0,
+    "STRETCH",
+    true
+   ],
+   [
+    "direct bitmap_once",
+    "BITMAP",
+    null,
+    0,
+    "NO_REPEAT",
+    true
+   ],
+   [
+    "direct bitmap_transp",
+    "BITMAP",
+    null,
+    0,
+    "REPEAT",
+    true
+   ]
+  ]
+ }
+]
diff --git a/test/odf-validate/fixtures/para-fill-foreign/edge-both-forms.odt b/test/odf-validate/fixtures/para-fill-foreign/edge-both-forms.odt
new file mode 100644
index 0000000000..173aef6dff
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/edge-both-forms.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/edge-duplicate-nested.odt b/test/odf-validate/fixtures/para-fill-foreign/edge-duplicate-nested.odt
new file mode 100644
index 0000000000..bb5336f422
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/edge-duplicate-nested.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/edge-empty.odt b/test/odf-validate/fixtures/para-fill-foreign/edge-empty.odt
new file mode 100644
index 0000000000..ae99d5f699
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/edge-empty.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/edge-nonparagraph.odt b/test/odf-validate/fixtures/para-fill-foreign/edge-nonparagraph.odt
new file mode 100644
index 0000000000..3f12742ca5
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/edge-nonparagraph.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/edge-unknown-attr.odt b/test/odf-validate/fixtures/para-fill-foreign/edge-unknown-attr.odt
new file mode 100644
index 0000000000..4f9cdfb1f1
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/edge-unknown-attr.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/edge-unknown-name.odt b/test/odf-validate/fixtures/para-fill-foreign/edge-unknown-name.odt
new file mode 100644
index 0000000000..365246ad94
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/edge-unknown-name.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/foreign-v11.odt b/test/odf-validate/fixtures/para-fill-foreign/foreign-v11.odt
new file mode 100644
index 0000000000..904a2da505
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/foreign-v11.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/foreign-v3.odt b/test/odf-validate/fixtures/para-fill-foreign/foreign-v3.odt
new file mode 100644
index 0000000000..ea95774b90
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/foreign-v3.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/foreign-v8.odt b/test/odf-validate/fixtures/para-fill-foreign/foreign-v8.odt
new file mode 100644
index 0000000000..f24676d614
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/foreign-v8.odt differ
diff --git a/test/odf-validate/fixtures/para-fill-foreign/gen.bas b/test/odf-validate/fixtures/para-fill-foreign/gen.bas
new file mode 100644
index 0000000000..f8a171dd49
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/gen.bas
@@ -0,0 +1,95 @@
+Function Gr(c1 As Long, c2 As Long, sty As Long, s As Long, e As Long)
+  Dim g As New com.sun.star.awt.Gradient
+  g.Style = sty : g.StartColor = c1 : g.EndColor = c2
+  g.Angle = 300 : g.Border = 10 : g.XOffset = 50 : g.YOffset = 50
+  g.StartIntensity = s : g.EndIntensity = e : g.StepCount = 0
+  Gr = g
+End Function
+
+Sub Fill(o As Object, kind As String, png As String)
+  Dim h As New com.sun.star.drawing.Hatch
+  Select Case kind
+  Case "solid"
+    o.FillStyle = com.sun.star.drawing.FillStyle.SOLID
+    o.FillColor = &H33AA55
+  Case "solid_transp"
+    o.FillStyle = com.sun.star.drawing.FillStyle.SOLID
+    o.FillColor = &H3355AA
+    o.FillTransparence = 40
+  Case "gradient"
+    o.FillStyle = com.sun.star.drawing.FillStyle.GRADIENT
+    o.FillGradient = Gr(&HFF0000, &H0000FF, 0, 100, 100)
+  Case "gradient_transp"
+    o.FillStyle = com.sun.star.drawing.FillStyle.GRADIENT
+    o.FillGradient = Gr(&HFF0000, &H0000FF, 0, 100, 100)
+    o.FillTransparence = 30
+  Case "gradient_tgrad"
+    o.FillStyle = com.sun.star.drawing.FillStyle.GRADIENT
+    o.FillGradient = Gr(&HFF0000, &H0000FF, 0, 100, 100)
+    o.FillTransparenceGradient = Gr(&H000000, &HFFFFFF, 0, 100, 100)
+  Case "hatch", "hatch_nobg"
+    h.Style = com.sun.star.drawing.HatchStyle.SINGLE : h.Color = &H00AA00 : h.Distance = 200 : h.Angle = 450
+    o.FillStyle = com.sun.star.drawing.FillStyle.HATCH
+    o.FillHatch = h
+    If kind = "hatch" Then
+      o.FillColor = &HFFFFCC
+      o.FillBackground = True
+    Else
+      o.FillBackground = False
+    End If
+  Case "bitmap_tile", "bitmap_stretch", "bitmap_once", "bitmap_transp"
+    o.FillStyle = com.sun.star.drawing.FillStyle.BITMAP
+    o.FillBitmapURL = png
+    If kind = "bitmap_stretch" Then
+      o.FillBitmapStretch = True
+      o.FillBitmapTile = False
+    ElseIf kind = "bitmap_once" Then
+      o.FillBitmapStretch = False
+      o.FillBitmapTile = False
+    Else
+      o.FillBitmapStretch = False
+      o.FillBitmapTile = True
+    End If
+    If kind = "bitmap_transp" Then o.FillTransparence = 50
+  End Select
+End Sub
+
+Sub Gen
+  Dim out As String, png As String
+  out = Environ("PFF_OUT") : png = Environ("PFF_PNG")
+  Dim a(0) As New com.sun.star.beans.PropertyValue
+  a(0).Name = "Hidden" : a(0).Value = True
+  Dim doc As Object
+  doc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, a())
+  Dim kinds
+  kinds = Split(Environ("PFF_KINDS"), ",")
+  Dim styles As Object, s As Object, i As Integer
+  styles = doc.StyleFamilies.getByName("ParagraphStyles")
+  For i = 0 To UBound(kinds)
+    s = doc.createInstance("com.sun.star.style.ParagraphStyle")
+    s.ParentStyle = "Standard"
+    styles.insertByName("S_" + kinds(i), s)
+    Fill s, kinds(i), png
+  Next
+  Dim cur As Object, k As Integer
+  cur = doc.Text.createTextCursor()
+  For i = 0 To UBound(kinds)
+    doc.Text.insertString(cur, "direct " + kinds(i), False)
+    doc.Text.insertControlCharacter(cur, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
+    doc.Text.insertString(cur, "styled " + kinds(i), False)
+    doc.Text.insertControlCharacter(cur, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
+  Next
+  Dim en As Object, p As Object
+  en = doc.Text.createEnumeration()
+  For i = 0 To UBound(kinds)
+    p = en.nextElement()
+    Fill p, kinds(i), png
+    p = en.nextElement()
+    p.ParaStyleName = "S_" + kinds(i)
+  Next
+  Dim b(0) As New com.sun.star.beans.PropertyValue
+  b(0).Name = "FilterName" : b(0).Value = "writer8"
+  doc.storeToURL(ConvertToURL(out), b())
+  doc.close(True)
+  StarDesktop.terminate()
+End Sub
diff --git a/test/odf-validate/fixtures/para-fill-foreign/make-aoo.py b/test/odf-validate/fixtures/para-fill-foreign/make-aoo.py
new file mode 100644
index 0000000000..6e7b52f2f2
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/make-aoo.py
@@ -0,0 +1,64 @@
+# usage: runpy.sh fixtures/para-fill-foreign/make-aoo.py <port> <out.odt> <tile.png>   (office saving ODF 1.2 Extended)
+# Builds the same paragraphs and paragraph styles as gen.bas, with AOO's own fill properties.
+import sys, uno
+from unohelp import connect, desktop, pv
+from com.sun.star.awt import Gradient
+from com.sun.star.awt.GradientStyle import LINEAR
+from com.sun.star.drawing import Hatch
+from com.sun.star.drawing.HatchStyle import SINGLE
+from com.sun.star.drawing.FillStyle import SOLID, GRADIENT, HATCH, BITMAP
+from com.sun.star.drawing.BitmapMode import REPEAT, STRETCH, NO_REPEAT
+
+port, out, png = int(sys.argv[1]), sys.argv[2], uno.systemPathToFileUrl(sys.argv[3])
+d = desktop(connect(port))
+doc = d.loadComponentFromURL("private:factory/swriter", "_blank", 0, (pv("Hidden", True),))
+
+def grad(c1, c2):
+    g = Gradient(); g.Style = LINEAR; g.StartColor = c1; g.EndColor = c2
+    g.Angle = 300; g.Border = 10; g.XOffset = 50; g.YOffset = 50
+    g.StartIntensity = 100; g.EndIntensity = 100; g.StepCount = 0
+    return g
+
+def hatch():
+    h = Hatch(); h.Style = SINGLE; h.Color = 0xFFAA00; h.Distance = 200; h.Angle = 450
+    return h
+
+def fill(o, kind):
+    if kind == "solid":
+        o.FillStyle = SOLID; o.FillColor = 0x33AA55
+    elif kind == "solid_transp":
+        o.FillStyle = SOLID; o.FillColor = 0x3355AA; o.FillTransparence = 40
+    elif kind == "gradient":
+        o.FillStyle = GRADIENT; o.FillGradient = grad(0xFF0000, 0x0000FF)
+    elif kind == "gradient_transp":
+        o.FillStyle = GRADIENT; o.FillGradient = grad(0xFF0000, 0x0000FF); o.FillTransparence = 30
+    elif kind == "hatch":
+        o.FillStyle = HATCH; o.FillHatch = hatch(); o.FillColor = 0xFFFFCC; o.FillBackground = True
+    elif kind == "hatch_nobg":
+        o.FillStyle = HATCH; o.FillHatch = hatch(); o.FillBackground = False
+    elif kind.startswith("bitmap"):
+        o.FillStyle = BITMAP; o.FillBitmapURL = png
+        o.FillBitmapMode = {"bitmap_stretch": STRETCH, "bitmap_once": NO_REPEAT}.get(kind, REPEAT)
+        if kind == "bitmap_transp":
+            o.FillTransparence = 50
+
+kinds = ["solid", "solid_transp", "gradient", "gradient_transp", "hatch", "hatch_nobg", "bitmap_tile", "bitmap_stretch", "bitmap_once", "bitmap_transp"]
+styles = doc.StyleFamilies.getByName("ParagraphStyles")
+for k in kinds:
+    s = doc.createInstance("com.sun.star.style.ParagraphStyle")
+    s.ParentStyle = "Standard"
+    styles.insertByName("S_" + k, s)
+    fill(s, k)
+PB = uno.getConstantByName("com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK")
+cur = doc.Text.createTextCursor()
+for k in kinds:
+    for kind in ("direct", "styled"):
+        doc.Text.insertString(cur, kind + " " + k, False)
+        doc.Text.insertControlCharacter(cur, PB, False)
+paras = doc.Text.createEnumeration()
+for k in kinds:
+    fill(paras.nextElement(), k)
+    paras.nextElement().ParaStyleName = "S_" + k
+doc.storeToURL(uno.systemPathToFileUrl(out), (pv("FilterName", "writer8"),))
+doc.close(True)
+print("saved", out)
diff --git a/test/odf-validate/fixtures/para-fill-foreign/make.py b/test/odf-validate/fixtures/para-fill-foreign/make.py
new file mode 100644
index 0000000000..fe51055b34
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/make.py
@@ -0,0 +1,118 @@
+# Known limitations of the import these documents exercise:
+#  - a fill is ignored when its gradient, hatch or bitmap definition comes after the style that uses it;
+#  - multi-stop gradients, unnamed direct gradients and hatches, and the opacity of a direct bitmap are not imported;
+#  - draw:angle with a unit suffix such as "30deg" is read as 0 (existing behaviour of the gradient import, unrelated to the fill element).
+# usage: python3 -I make.py <other-suite-soffice> <scratch-dir>
+# Writes foreign-v8.odt, foreign-v3.odt, foreign-v11.odt with the other suite saving at ODF version setting 8, 3, 11
+# (/org.openoffice.Office.Common/Save/ODF DefaultVersion), using gen.bas as macro Standard.Module1.Gen in a throw-away profile,
+# then derives the edge-*.odt variants by editing the XML text of foreign-v8.odt.
+import os, re, subprocess, sys, time, zipfile
+from xml.sax.saxutils import escape
+
+soffice, scratch = sys.argv[1], sys.argv[2]
+here = os.path.dirname(os.path.abspath(__file__))
+KINDS = "solid,solid_transp,gradient,gradient_transp,hatch,hatch_nobg,bitmap_tile,bitmap_stretch,bitmap_once,bitmap_transp"
+XCU = """<?xml version="1.0" encoding="UTF-8"?>
+<oor:items xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<item oor:path="/org.openoffice.Office.Common/Save/ODF"><prop oor:name="DefaultVersion" oor:op="fuse"><value>%d</value></prop></item>
+<item oor:path="/org.openoffice.Office.Common/Security/Scripting"><prop oor:name="MacroSecurityLevel" oor:op="fuse"><value>0</value></prop></item>
+</oor:items>
+"""
+MODULE = ('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">\n'
+          '<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic">%s</script:module>\n')
+OPTS = ["--headless", "--nofirststartwizard", "--norestore", "--nologo"]
+
+def wait_gone(prof):
+    while subprocess.run(["pgrep", "-f", prof], capture_output=True).returncode == 0:
+        time.sleep(1)
+
+for mode in (8, 3, 11):
+    prof = os.path.join(scratch, "profile_%d" % mode)
+    env = dict(os.environ, PFF_KINDS=KINDS, PFF_OUT=os.path.join(here, "foreign-v%d.odt" % mode), PFF_PNG="file://" + os.path.join(here, "tile.png"))
+    ui = "-env:UserInstallation=file://" + prof
+    os.makedirs(os.path.join(prof, "user"))
+    open(os.path.join(prof, "user", "registrymodifications.xcu"), "w").write(XCU % mode)
+    subprocess.run([soffice, *OPTS, ui, "macro:///Standard.Module1.Main"], env=env, timeout=300)  # creates the profile and its Standard library
+    wait_gone(prof)
+    open(os.path.join(prof, "user", "basic", "Standard", "Module1.xba"), "w").write(MODULE % escape(open(os.path.join(here, "gen.bas")).read()))
+    subprocess.run([soffice, *OPTS, ui, "macro:///Standard.Module1.Gen"], env=env, timeout=300)
+    wait_gone(prof)
+    assert os.path.getsize(env["PFF_OUT"]) > 0, "no output for mode %d" % mode
+
+def scrub(name):
+    """replaces the generator string in meta.xml and the colour theme name in styles.xml by neutral ones"""
+    path = os.path.join(here, name)
+    zi = zipfile.ZipFile(path); items = [(it, zi.read(it.filename)) for it in zi.infolist()]; zi.close()
+    zo = zipfile.ZipFile(path, "w")
+    for it, data in items:
+        if it.filename == "meta.xml":
+            data = re.sub(rb"<meta:generator>[^<]*</meta:generator>", b"<meta:generator>other suite</meta:generator>", data)
+        if it.filename == "styles.xml":
+            data = re.sub(rb'(<loext:theme-colors loext:name=")[^"]*"', rb'\1Other"', data)
+        zo.writestr(it, data, compress_type=zipfile.ZIP_STORED if it.filename == "mimetype" else zipfile.ZIP_DEFLATED)
+    zo.close()
+
+for mode in (8, 3, 11):
+    scrub("foreign-v%d.odt" % mode)
+
+def rewrite(src, dst, fn):
+    zi = zipfile.ZipFile(os.path.join(here, src)); zo = zipfile.ZipFile(os.path.join(here, dst), "w")
+    for it in zi.infolist():
+        data = zi.read(it.filename)
+        if it.filename in ("content.xml", "styles.xml"):
+            data = fn(it.filename, data.decode("utf-8")).encode("utf-8")
+        zo.writestr(it, data, compress_type=zipfile.ZIP_STORED if it.filename == "mimetype" else zipfile.ZIP_DEFLATED)
+    zo.close()
+
+def sub1(t, old, new):
+    assert t.count(old) == 1, (old, t.count(old))
+    return t.replace(old, new)
+
+def style_xml(t, name):
+    m = re.search(r'<style:style style:name="%s".*?</style:style>' % re.escape(name), t, re.S)
+    assert m, name
+    return m
+
+# named gradient reference that does not exist
+rewrite("foreign-v8.odt", "edge-unknown-name.odt", lambda n, t: t.replace('draw:fill-gradient-name="Gradient_20_1"', 'draw:fill-gradient-name="No_20_Such"') if n == "styles.xml" else t)
+# empty element in a paragraph style that has fo:background-color
+def empty(n, t):
+    if n != "styles.xml": return t
+    m = style_xml(t, "S_5f_gradient")
+    return t.replace(m.group(0), re.sub(r'<loext:graphic-properties[^>]*/>', '<loext:graphic-properties/>', m.group(0)))
+rewrite("foreign-v8.odt", "edge-empty.odt", empty)
+# same element in non-paragraph styles (text style, table cell style) plus a paragraph that uses them
+EXTRA_TEXT = '<style:style style:name="T9" style:family="text"><loext:graphic-properties draw:fill="solid" draw:fill-color="#ff0000"/></style:style>'
+EXTRA_CELL = '<style:style style:name="C9" style:family="table-cell"><loext:graphic-properties draw:fill="solid" draw:fill-color="#ff0000"/></style:style>'
+EXTRA_FRAME = '<style:style style:name="G9" style:family="graphic"><loext:graphic-properties draw:fill="solid" draw:fill-color="#ff0000"/></style:style>'
+def nonpara(n, t):
+    if n == "styles.xml":
+        return t.replace("</office:styles>", EXTRA_FRAME + "</office:styles>", 1)
+    return t.replace("</office:automatic-styles>", EXTRA_TEXT + EXTRA_CELL + "</office:automatic-styles>", 1)
+rewrite("foreign-v8.odt", "edge-nonparagraph.odt", nonpara)
+# duplicate element (second one must lose) and nested element
+def dup(n, t):
+    if n != "styles.xml": return t
+    m = style_xml(t, "S_5f_solid")
+    s = m.group(0).replace('<style:paragraph-properties', '<loext:graphic-properties draw:fill="solid" draw:fill-color="#ff0000"/><style:paragraph-properties', 1)
+    m2 = style_xml(t, "S_5f_hatch")
+    h = m2.group(0).replace('draw:fill-hatch-solid="true"/>', 'draw:fill-hatch-solid="true"><loext:graphic-properties draw:fill="solid" draw:fill-color="#ff0000"/></loext:graphic-properties>', 1)
+    return t.replace(m.group(0), s).replace(m2.group(0), h)
+rewrite("foreign-v8.odt", "edge-duplicate-nested.odt", dup)
+# the native form and the extension element in one style, both orders
+def both(n, t):
+    if n != "styles.xml": return t
+    m = style_xml(t, "S_5f_solid")
+    native = '<style:graphic-properties draw:fill="solid" draw:fill-color="#ff0000"/>'
+    s1 = m.group(0).replace('<loext:graphic-properties', native + '<loext:graphic-properties', 1)
+    m2 = style_xml(t, "S_5f_solid_5f_fill") if 'S_5f_solid_5f_fill' in t else style_xml(t, "S_5f_solid_5f_transp")
+    s2 = m2.group(0).replace('<style:paragraph-properties', native + '<style:paragraph-properties', 1)
+    return t.replace(m.group(0), s1).replace(m2.group(0), s2)
+rewrite("foreign-v8.odt", "edge-both-forms.odt", both)
+# an attribute of the extension element that no fill property maps to
+def unknown_attr(n, t):
+    if n != "styles.xml": return t
+    m = style_xml(t, "S_5f_solid")
+    return t.replace(m.group(0), m.group(0).replace('<loext:graphic-properties ', '<loext:graphic-properties loext:future-attribute="x" ', 1))
+rewrite("foreign-v8.odt", "edge-unknown-attr.odt", unknown_attr)
+print("done")
diff --git a/test/odf-validate/fixtures/para-fill-foreign/mkexpect.py b/test/odf-validate/fixtures/para-fill-foreign/mkexpect.py
new file mode 100644
index 0000000000..c66b9840a8
--- /dev/null
+++ b/test/odf-validate/fixtures/para-fill-foreign/mkexpect.py
@@ -0,0 +1,75 @@
+# usage: python3 -I mkexpect.py <cap-dir> <tag>
+# Writes the expect values of the checks-*.json files.
+#  - styled paragraphs and paragraph styles: what AOO's own form gives after a reload (<cap-dir>/<tag>_aoo-form.json,
+#    captured by roundtrip.py --capture from aoo-form.odt, written by make-aoo.py with the same fills);
+#  - direct paragraphs: derived from the XML text of foreign-v8.odt (an unnamed gradient or hatch cannot be restored, so
+#    fo:background-color is what remains; a bitmap comes from style:background-image);
+#  - edge documents: the same, except the styles an edge changes, which take <cap-dir>/<tag>_<edge>.json (captured with
+#    libraries without the import) or the value stated below.
+import copy, json, os, re, sys, zipfile
+cap, tag = sys.argv[1], sys.argv[2]
+here = os.path.dirname(os.path.abspath(__file__))
+C = lambda d: json.load(open(os.path.join(cap, "%s_%s.json" % (tag, d))))
+checks = json.load(open(os.path.join(here, "checks.json")))
+ref = C("aoo-form")
+
+def rgb(s): return int(s[1:], 16)
+z = zipfile.ZipFile(os.path.join(here, "foreign-v8.odt")); content = z.read("content.xml").decode()
+direct = {}
+for m in re.finditer(r'<text:p text:style-name="(P\d+)">direct (\w+)</text:p>', content):
+    sty = re.search(r'<style:style style:name="%s".*?</style:style>' % m.group(1), content, re.S).group(0)
+    kind = m.group(2)
+    fill = re.search(r'<loext:graphic-properties draw:fill="(\w+)"(?: draw:fill-color="(#\w+)")?(?: draw:opacity="(\d+)%")?', sty)
+    bg = re.search(r'fo:background-color="(#\w+)"', sty)
+    rep = re.search(r'<style:background-image [^>]*style:repeat="([\w-]+)"', sty)
+    if fill.group(1) == "solid":
+        direct[kind] = ["SOLID", rgb(fill.group(2)), 100 - int(fill.group(3) or 100) if fill.group(3) else 0, None, False]
+    elif fill.group(1) == "bitmap" and "<style:background-image " in sty:
+        direct[kind] = ["BITMAP", None, 0, {"stretch": "STRETCH", "no-repeat": "NO_REPEAT"}.get(rep.group(1) if rep else "", "REPEAT"), True]
+    else:
+        direct[kind] = ["SOLID", rgb(bg.group(1)), 0, None, False]
+direct_rows = [["direct " + k] + v for k, v in direct.items()]
+
+def build(styled, styles, direct_rows):
+    return {"styled_paragraphs": styled, "para_styles": styles, "direct_paragraphs": direct_rows}
+
+base = build(ref["styled_paragraphs"], ref["para_styles"], direct_rows)
+
+def write(name, exp, only=None, angle=None):
+    ck = copy.deepcopy(checks)
+    out = []
+    for c in ck:
+        if only and c["name"] not in only: continue
+        e = copy.deepcopy(exp[c["name"]])
+        if angle is not None:
+            for r in e:
+                if len(r) > 5 and r[5] is not None and r[1] == "GRADIENT": r[5][3] = angle
+        c["expect"] = e
+        out.append(c)
+    json.dump(out, open(os.path.join(here, name), "w"), indent=1); open(os.path.join(here, name), "a").write("\n")
+
+def swap(exp, edge, labels):
+    """replace the rows named in labels by the rows of the capture of <edge> taken without the import"""
+    red = C(edge); exp = copy.deepcopy(exp)
+    for k in ("styled_paragraphs", "para_styles"):
+        exp[k] = [next(r for r in red[k] if r[0] == row[0]) if row[0] in labels else row for row in exp[k]]
+    return exp
+
+write("checks.json", base)
+write("checks-v13-v14.json", base, angle=0)
+write("checks-aoo-form.json", base, only=("styled_paragraphs", "para_styles"))
+write("checks-edge-unknown-name.json", swap(base, "edge-unknown-name", ("styled gradient", "styled gradient_transp", "S_gradient", "S_gradient_transp")))
+write("checks-edge-empty.json", swap(base, "edge-empty", ("styled gradient", "S_gradient")))
+write("checks-edge-nonparagraph.json", base)
+write("checks-edge-duplicate-nested.json", base)
+both = swap(base, "edge-both-forms", ("styled solid", "S_solid"))
+for k in ("styled_paragraphs", "para_styles"):
+    for r in both[k]:
+        if r[0] in ("styled solid_transp", "S_solid_transp"):   # native element after the extension one: its colour wins, the extension's opacity survives
+            r[2] = 16711680; r[3] = 40; r[12] = 1711210496
+write("checks-edge-both-forms.json", both)
+write("checks-edge-unknown-attr.json", base)
+ua = json.load(open(os.path.join(here, "checks-unknown-attr.json")))
+ua[0]["expect"] = C("edge-unknown-attr_ua")["style_user_attributes"]   # what the styles carry without the import: the attribute must not be added
+json.dump(ua, open(os.path.join(here, "checks-unknown-attr.json"), "w"), indent=1); open(os.path.join(here, "checks-unknown-attr.json"), "a").write("\n")
+print("written; direct rows:", len(direct_rows))
diff --git a/test/odf-validate/fixtures/para-fill-foreign/tile.png b/test/odf-validate/fixtures/para-fill-foreign/tile.png
new file mode 100644
index 0000000000..9ac8fdd049
Binary files /dev/null and b/test/odf-validate/fixtures/para-fill-foreign/tile.png differ


(openoffice) 01/02: xmloff: import extension paragraph fill attributes

Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jimjag pushed a commit to branch odf-devel
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 3ac86099fecad6935c197722c6754cce2a5b7405
Author: Jim Jagielski <ji...@gmail.com>
AuthorDate: Fri Oct 23 14:25:57 2026 -0400

    xmloff: import extension paragraph fill attributes
    
    The extension namespace is matched by URI and is not registered.
---
 main/xmloff/source/style/prstylei.cxx | 118 ++++++++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/main/xmloff/source/style/prstylei.cxx b/main/xmloff/source/style/prstylei.cxx
index bbe3cab42d..945fa8d001 100644
--- a/main/xmloff/source/style/prstylei.cxx
+++ b/main/xmloff/source/style/prstylei.cxx
@@ -37,6 +37,7 @@
 #include <com/sun/star/beans/XMultiPropertyStates.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <xmloff/xmlimp.hxx>
+#include <xmloff/nmspmap.hxx>
 #include <xmloff/prstylei.hxx>
 #include <xmloff/attrlist.hxx>
 #include "xmloff/xmlerror.hxx"
@@ -169,6 +170,112 @@ const OldFillStyleDefinitionSet& XMLPropStyleContext::getParaSet()
     return maParaSet;
 }
 
+namespace
+{
+const sal_Char s_aExtGraphicNamespace[] = "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0";
+
+// Keeps the fill only if it is usable and no earlier fill exists; otherwise the fallback attributes apply.
+class XMLExtParaFillContext : public SvXMLPropertySetContext
+{
+    const size_t mnFirst;
+
+    bool Exists( const Reference< XNameContainer >& rTable, sal_uInt16 nStyleFamily, const OUString& rName ) const
+    {
+        return rName.getLength() && rTable.is() &&
+            rTable->hasByName( GetImport().GetStyleDisplayName( nStyleFamily, rName ) );
+    }
+
+public:
+    XMLExtParaFillContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
+        const Reference< XAttributeList >& xAttrList, std::vector< XMLPropertyState >& rProps,
+        const UniReference< SvXMLImportPropertyMapper >& rMap, size_t nFirst )
+    :   SvXMLPropertySetContext( rImport, nPrfx, rLName, xAttrList, XML_TYPE_PROP_GRAPHIC, rProps, rMap ),
+        mnFirst( nFirst )
+    {
+    }
+
+    virtual void EndElement();
+};
+
+void XMLExtParaFillContext::EndElement()
+{
+    const UniReference< XMLPropertySetMapper > xMap( mxMapper->getPropertySetMapper() );
+    bool bNativeFill = false, bColor = false;
+    sal_Int32 nStyle = -1, nTransName = -1;
+    OUString aGradient, aHatch, aBitmap, aTrans;
+
+    for( size_t i = 0; i < mrProperties.size(); ++i )
+    {
+        const XMLPropertyState& rState = mrProperties[i];
+        if( rState.mnIndex == -1 )
+            continue;
+        const OUString& rName = xMap->GetEntryAPIName( rState.mnIndex );
+        if( rName.equalsAscii( "FillStyle" ) )
+        {
+            if( i < mnFirst )
+                bNativeFill = true;
+            else
+                nStyle = static_cast< sal_Int32 >( i );
+        }
+        else if( i >= mnFirst )
+        {
+            if( rName.equalsAscii( "FillColor" ) )
+                bColor = true;
+            else if( rName.equalsAscii( "FillGradientName" ) )
+                rState.maValue >>= aGradient;
+            else if( rName.equalsAscii( "FillHatchName" ) )
+                rState.maValue >>= aHatch;
+            else if( rName.equalsAscii( "FillBitmapName" ) )
+                rState.maValue >>= aBitmap;
+            else if( rName.equalsAscii( "FillTransparenceGradientName" ) )
+            {
+                rState.maValue >>= aTrans;
+                nTransName = static_cast< sal_Int32 >( i );
+            }
+        }
+    }
+
+    bool bUsable = false;
+    if( nStyle != -1 && !bNativeFill )
+    {
+        FillStyle eStyle = FillStyle_NONE;
+        sal_Int32 nValue = 0;
+        const Any& rAny = mrProperties[nStyle].maValue;
+        if( !( rAny >>= eStyle ) && ( rAny >>= nValue ) )
+            eStyle = static_cast< FillStyle >( nValue );
+        SvXMLImport& rImport = GetImport();
+        switch( eStyle )
+        {
+            case FillStyle_SOLID:
+                bUsable = bColor;
+                break;
+            case FillStyle_GRADIENT:
+                bUsable = Exists( rImport.GetGradientHelper(), XML_STYLE_FAMILY_SD_GRADIENT_ID, aGradient );
+                break;
+            case FillStyle_HATCH:
+                bUsable = Exists( rImport.GetHatchHelper(), XML_STYLE_FAMILY_SD_HATCH_ID, aHatch );
+                break;
+            case FillStyle_BITMAP:
+                bUsable = Exists( rImport.GetBitmapHelper(), XML_STYLE_FAMILY_SD_FILL_IMAGE_ID, aBitmap );
+                break;
+            default:
+                break;
+        }
+    }
+
+    if( !bUsable )
+    {
+        for( size_t i = mnFirst; i < mrProperties.size(); ++i )
+            mrProperties[i].mnIndex = -1;
+    }
+    else if( nTransName != -1 &&
+        !Exists( GetImport().GetTransGradientHelper(), XML_STYLE_FAMILY_SD_GRADIENT_ID, aTrans ) )
+    {
+        mrProperties[nTransName].mnIndex = -1;
+    }
+}
+}
+
 SvXMLImportContext *XMLPropStyleContext::CreateChildContext(
 		sal_uInt16 nPrefix,
 		const OUString& rLocalName,
@@ -215,6 +322,17 @@ SvXMLImportContext *XMLPropStyleContext::CreateChildContext(
 													xImpPrMap );
 	}
 
+	if( !pContext && ( XML_NAMESPACE_UNKNOWN_FLAG & nPrefix ) && GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH &&
+		IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) &&
+		GetImport().GetNamespaceMap().GetNameByKey( nPrefix ).equalsAscii( s_aExtGraphicNamespace ) )
+	{
+		UniReference < SvXMLImportPropertyMapper > xImpPrMap =
+			((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper( GetFamily() );
+		if( xImpPrMap.is() )
+			pContext = new XMLExtParaFillContext( GetImport(), nPrefix, rLocalName, xAttrList,
+												  maProperties, xImpPrMap, maProperties.size() );
+	}
+
 	if( !pContext )
 		pContext = SvXMLStyleContext::CreateChildContext( nPrefix, rLocalName,
 														  xAttrList );