xref: /trunk/test/odf-validate/fixtures/styles-gfx/verify.py (revision 0e16a31d78a652c56c5c0fc79c752f48b9048df9)
1#**************************************************************
2#
3#  Licensed to the Apache Software Foundation (ASF) under one
4#  or more contributor license agreements.  See the NOTICE file
5#  distributed with this work for additional information
6#  regarding copyright ownership.  The ASF licenses this file
7#  to you under the Apache License, Version 2.0 (the
8#  "License"); you may not use this file except in compliance
9#  with the License.  You may obtain a copy of the License at
10#
11#    http://www.apache.org/licenses/LICENSE-2.0
12#
13#  Unless required by applicable law or agreed to in writing,
14#  software distributed under the License is distributed on an
15#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16#  KIND, either express or implied.  See the License for the
17#  specific language governing permissions and limitations
18#  under the License.
19#
20#
21# usage: runpy.sh fixtures/styles-gfx/verify.py <port> <outdir>
22# Reloads the packages written by make.py and compares the properties of shapes and styles with the values make.py set.
23import sys, os
24import tempfile
25OUT = os.path.abspath(sys.argv[2])
26sys.argv = [sys.argv[0], sys.argv[1], tempfile.mkdtemp(prefix="styles-gfx-verify-")]
27exec(open("fixtures/styles-gfx/make.py").read().split("\nDOCS = [")[0])
28bad, checked = [], [0]
29
30
31def same(a, b, k=""):
32    if k.endswith("Color") or k.endswith("Color2"):
33        return (a & 0xffffff) == (b & 0xffffff)
34    if isinstance(b, uno.Enum):
35        return isinstance(a, uno.Enum) and a.value == b.value
36    if isinstance(b, float):
37        return abs(a - b) < 1e-3 * max(1.0, abs(b))
38    if hasattr(b, "OuterLineWidth"):
39        return (a.Color & 0xffffff) == (b.Color & 0xffffff) and (a.InnerLineWidth > 0) == (b.InnerLineWidth > 0) and \
40            abs(a.OuterLineWidth + a.InnerLineWidth + a.LineDistance - b.OuterLineWidth - b.InnerLineWidth - b.LineDistance) <= 8
41    if hasattr(b, "ShadowWidth"):
42        return a.Location.value == b.Location.value
43    if isinstance(b, bool):
44        return bool(a) == b
45    if isinstance(b, int) and isinstance(a, int) and abs(b) >= 50:
46        return abs(a - b) <= 2
47    return a == b
48
49
50def cmp(tag, obj, props):
51    for k, v in props.items():
52        try:
53            a = obj.getPropertyValue(k)
54        except Exception:
55            continue
56        checked[0] += 1
57        try:
58            ok = same(a, v, k)
59        except Exception as e:
60            ok = False
61        if not ok:
62            bad.append((tag, k, v.value if isinstance(v, uno.Enum) else v, a.value if isinstance(a, uno.Enum) else a))
63
64
65def loaddoc(name):
66    return desk.loadComponentFromURL(uno.systemPathToFileUrl(os.path.join(OUT, name)), "_blank", 0,
67                                     (pv("Hidden", True), pv("ReadOnly", True)))
68
69
70def shapes(page):
71    return [page.getByIndex(i) for i in range(page.Count)]
72
73
74def draw_check():
75    d = loaddoc("draw-fill-line.odg")
76    sh = shapes(d.DrawPages.getByIndex(0))
77    cases = fillprops() + linecases()
78    for s, (n, p) in zip(sh, cases):
79        cmp("draw-fill-line " + n, s, {k: v for k, v in p.items() if not k.endswith("Name") and k not in ("FillBitmapOffsetX", "FillBitmapOffsetY")})
80    print("draw-fill-line shapes", len(sh), "cases", len(cases))
81    d.close(True)
82
83
84def style_check(doc_name, fam, prefix, cases):
85    d = loaddoc(doc_name)
86    st_ = d.StyleFamilies.getByName(fam)
87    for n, p in cases:
88        nm = prefix + n
89        if st_.hasByName(nm):
90            cmp(doc_name + " " + nm, st_.getByName(nm), p)
91        else:
92            bad.append((doc_name, nm, "style missing", ""))
93    d.close(True)
94
95
96def writer_pagestyle_check():
97    d = loaddoc("writer-pagestyles.odt")
98    fam = d.StyleFamilies.getByName("PageStyles")
99    for wm in range(5):
100        cmp("ps-wm-%d" % wm, fam.getByName("ps-wm-%d" % wm), dict(WritingMode=wm))
101    for lay in ("ALL", "LEFT", "RIGHT", "MIRRORED"):
102        cmp("ps-layout-" + lay, fam.getByName("ps-layout-" + lay), dict(PageStyleLayout=E("com.sun.star.style.PageStyleLayout", lay)))
103    for nt in (0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 20, 30, 40):
104        cmp("ps-num-%d" % nt, fam.getByName("ps-num-%d" % nt), dict(NumberingType=nt))
105    for gm in (0, 1, 2):
106        for std in (True, False):
107            cmp("ps-grid-%d-%d" % (gm, std), fam.getByName("ps-grid-%s-%d" % (gm, std)), dict(GridMode=gm, RubyBelow=not std, GridPrint=not std, GridDisplay=bool(std)))
108    for i in range(6):
109        cmp("ps-hf-%d" % i, fam.getByName("ps-hf-%d" % i), dict(page_common(i), **hf_props("Header", i)))
110    d.close(True)
111
112
113def impress_check():
114    d = loaddoc("impress-effects.odp")
115    pages = d.DrawPages
116    spd = ("SLOW", "MEDIUM", "FAST")
117    effects = enum_names("com.sun.star.presentation.FadeEffect")
118    for i in range(pages.Count):
119        pg = pages.getByIndex(i)
120        cmp("slide %d" % i, pg, dict(Speed=E("com.sun.star.presentation.AnimationSpeed", spd[i % 3]), Change=i % 3, Duration=1 + i % 5,
121            Visible=bool(i % 4), IsBackgroundVisible=bool(i % 3), IsBackgroundObjectsVisible=bool(i % 5), IsFooterVisible=bool(i % 3),
122            IsPageNumberVisible=bool(i % 4), IsDateTimeVisible=bool(i % 5)))
123    print("impress-effects slides", pages.Count)
124    d.close(True)
125    d = loaddoc("impress-transitions.odp")
126    pages = d.DrawPages
127    print("impress-transitions slides", pages.Count)
128    for i in range(pages.Count):
129        pg = pages.getByIndex(i)
130        try:
131            checked[0] += 1
132            if pg.getPropertyValue("TransitionType") == 0 and i < 38:
133                bad.append(("impress-transitions", "slide %d" % i, "TransitionType>0", 0))
134        except Exception:
135            pass
136    d.close(True)
137
138
139def calc_check():
140    cases = []
141    d = loaddoc("calc-cells.ods")
142    fam = d.StyleFamilies.getByName("CellStyles")
143    names = [n for n in fam.ElementNames if n.startswith("cs-")]
144    print("calc cell styles", len(names))
145    d.close(True)
146
147
148for fn in (draw_check, writer_pagestyle_check, impress_check, calc_check):
149    try:
150        fn()
151    except Exception as e:
152        print("FAIL", fn.__name__, type(e).__name__, str(e)[:120])
153shutil.rmtree(work, ignore_errors=True)
154shutil.rmtree(out, ignore_errors=True)
155print("checked", checked[0], "mismatches", len(bad))
156for b in bad:
157    print("MISMATCH", *b)
158