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/draw/make.py <port> <outdir> 22# Draw and Impress features the corpus lacks: animations, transitions, presentation settings, click actions, image maps, 23# 3D scenes, custom shapes, fontwork, connectors, glue points, measure, captions, plugin/applet/frame, page anchors. 24# Saves with the office's configured ODF version: run it against the strict and extended profiles. 25import sys, os, math, wave, struct, tempfile, threading, uno 26from unohelp import connect, desktop, pv, odf_version 27 28port, out = int(sys.argv[1]), os.path.abspath(sys.argv[2]) 29os.makedirs(out, exist_ok=True) 30ctx = connect(port) 31smgr = ctx.ServiceManager 32desk = desktop(ctx) 33failed = [] 34STEP_SECONDS = 90 35crashes = [] 36ONLY = set(sys.argv[3:]) | set(os.environ.get("DRAW_ONLY", "").split()) 37tmp = tempfile.mkdtemp(prefix="t12_draw_") 38SOUND = os.path.join(tmp, "beep.wav") 39w = wave.open(SOUND, "wb") 40w.setnchannels(1); w.setsampwidth(2); w.setframerate(8000) 41w.writeframes(b"".join(struct.pack("<h", int(8000 * math.sin(i / 5.0))) for i in range(4000))) 42w.close() 43SOUND_URL = uno.systemPathToFileUrl(SOUND) 44 45# online spelling runs on a timer and was seen crashing the office on closed documents (ImpEditEngine::DoOnlineSpelling) 46def quiet_spelling(): 47 try: 48 smgr.createInstanceWithContext("com.sun.star.linguistic2.LinguProperties", ctx).IsSpellAuto = False 49 except Exception as e: 50 print(" cannot disable online spelling", repr(e)[:100]) 51 52 53quiet_spelling() 54PROFILE = "t12_draw_" + ("strict" if odf_version(ctx) == 4 else "ext") 55 56CLIP = {"odp": "impress8", "odg": "draw8", "otp": "impress8_template", "otg": "draw8_template", 57 "odt": "writer8", "ods": "calc8"} 58FACTORY = {"odp": "simpress", "odg": "sdraw", "odt": "swriter", "ods": "scalc"} 59 60 61def new(kind): 62 return desk.loadComponentFromURL("private:factory/" + FACTORY[kind], "_blank", 0, (pv("Hidden", True),)) 63 64 65KEEP = [] 66 67 68def done(doc): 69 # closing documents or releasing annotation/table proxies after a close crashed the office (use after free); leak them and _exit 70 KEEP.append(doc) 71 72 73def save(doc, name): 74 try: 75 doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, name)), (pv("FilterName", CLIP[name.rsplit(".", 1)[1]]),)) 76 print("saved", name) 77 except Exception as e: 78 failed.append(name) 79 print("FAIL save", name, repr(e)[:300]) 80 81 82def step(label, fn, *a, **kw): 83 print(' step', label, flush=True) 84 try: 85 return fn(*a, **kw) 86 except Exception as e: 87 failed.append(label) 88 import traceback 89 print("FAIL", label, type(e).__name__, repr(e)[:300], traceback.format_exc().splitlines()[-3:-1]) 90 91 92def office_alive(): 93 try: 94 desk.getImplementationName() 95 return True 96 except Exception: 97 return False 98 99 100def kill_office(): 101 import subprocess 102 print("WATCHDOG: step exceeded %ds, killing the office" % STEP_SECONDS, flush=True) 103 subprocess.run(["pkill", "-f", "[p]rofile_" + PROFILE]) 104 105 106def restart_office(): 107 global ctx, smgr, desk 108 import subprocess 109 harness = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))) 110 prof = PROFILE 111 subprocess.run(["pkill", "-f", "[p]rofile_" + prof]) 112 subprocess.run([os.path.join(harness, "start.sh"), prof, str(port)], check=True) 113 ctx = connect(port) 114 smgr = ctx.ServiceManager 115 desk = desktop(ctx) 116 quiet_spelling() 117 118 119def top(label, fn, *a): 120 if ONLY and label not in ONLY: 121 return 122 print('step', label, flush=True) 123 for attempt in (1, 2): 124 nfailed = len(failed) 125 dog = threading.Timer(STEP_SECONDS, kill_office) 126 dog.start() 127 try: 128 fn(*a) 129 return 130 except Exception as e: 131 if office_alive(): 132 failed.append(label) 133 print("FAIL", label, type(e).__name__, repr(e)[:300]) 134 return 135 del failed[nfailed:] 136 crashes.append(label) 137 print("CRASH", label, "attempt", attempt, repr(e)[:150]) 138 restart_office() 139 finally: 140 dog.cancel() 141 failed.append(label) 142 143 144def struct_(name, *a): 145 return uno.createUnoStruct(name, *a) 146 147 148def pt(x, y): 149 return struct_("com.sun.star.awt.Point", x, y) 150 151 152def sz(w, h): 153 return struct_("com.sun.star.awt.Size", w, h) 154 155 156def mk(doc, page, service, x=1000, y=1000, w=3000, h=2000, text=None, **props): 157 s = doc.createInstance("com.sun.star.drawing." + service) 158 page.add(s) 159 if w is not None: 160 s.Position = pt(x, y) 161 s.Size = sz(w, h) 162 if text is not None: 163 s.String = text 164 for k, v in props.items(): 165 try: 166 setattr(s, k, v) 167 except Exception as e: 168 print(" prop", service, k, repr(e)[:120]) 169 return s 170 171 172def setp(obj, **props): 173 for k, v in props.items(): 174 try: 175 setattr(obj, k, v) 176 except Exception as e: 177 print(" prop", k, repr(e)[:120]) 178 179 180def spec(name): 181 return smgr.createInstanceWithContext("com.sun.star.animations." + name, ctx) 182 183 184def add_page(doc): 185 doc.DrawPages.insertNewByIndex(doc.DrawPages.Count) 186 return doc.DrawPages.getByIndex(doc.DrawPages.Count - 1) 187 188 189def presentation_settings(): 190 doc = new("odp") 191 pages = [doc.DrawPages.getByIndex(0)] + [add_page(doc) for _ in range(3)] 192 for i, p in enumerate(pages): 193 p.Name = "Slide%d" % (i + 1) 194 mk(doc, p, "RectangleShape", text="slide %d" % (i + 1)) 195 shows = doc.CustomPresentations 196 for nm, idx in (("ShowA", (0, 2)), ("ShowB", (1, 3, 0))): 197 show = shows.createInstance() 198 for i in idx: 199 show.insertByIndex(show.Count, pages[i]) 200 shows.insertByName(nm, show) 201 pres = doc.Presentation 202 pres.IsShowAll = False 203 pres.CustomShow = "ShowB" 204 pres.IsEndless = True 205 pres.Pause = 7 206 pres.AllowAnimations = False 207 pres.IsAlwaysOnTop = True 208 pres.IsAutomatic = True 209 pres.IsFullScreen = False 210 pres.IsMouseVisible = False 211 pres.StartWithNavigator = True 212 pres.UsePen = True 213 pres.IsTransitionOnClick = False 214 pres.IsShowLogo = True 215 save(doc, "pres-settings.odp") 216 pres.CustomShow = "" 217 pres.FirstPage = "Slide3" 218 save(doc, "pres-settings-start.odp") 219 done(doc) 220 221 222def header_footer(): 223 doc = new("odp") 224 p1 = doc.DrawPages.getByIndex(0) 225 p2 = add_page(doc) 226 for i, p in enumerate((p1, p2)): 227 mk(doc, p, "RectangleShape", text="hf %d" % i) 228 setp(p, IsFooterVisible=True, FooterText="footer %d" % i, IsPageNumberVisible=True, IsDateTimeVisible=True) 229 setp(p1, IsDateTimeFixed=True, DateTimeText="fixed date") 230 setp(p2, IsDateTimeFixed=False, DateTimeFormat=0x2002) 231 for p in (p1, p2): 232 setp(p.NotesPage, IsHeaderVisible=True, HeaderText="notes header", IsFooterVisible=True, FooterText="notes footer", 233 IsDateTimeVisible=True, IsDateTimeFixed=True, DateTimeText="notes date", IsPageNumberVisible=True) 234 setp(doc.MasterPages.getByIndex(0), IsFooterVisible=True, FooterText="master footer", IsPageNumberVisible=True) 235 try: 236 hm = doc.getHandoutMasterPage() 237 except Exception as e: 238 hm = None 239 print(" handout master", repr(e)[:100]) 240 hm is not None and setp(hm, IsHeaderVisible=True, HeaderText="handout header", IsFooterVisible=True, 241 FooterText="handout footer", IsDateTimeVisible=True, IsDateTimeFixed=True, DateTimeText="handout date") 242 save(doc, "header-footer.odp") 243 done(doc) 244 245 246def layouts(): 247 doc = new("odp") 248 first = True 249 for n in range(0, 40): 250 try: 251 p = doc.DrawPages.getByIndex(0) if first else add_page(doc) 252 first = False 253 p.Layout = n 254 except Exception as e: 255 print(" layout", n, repr(e)[:100]) 256 save(doc, "layouts.odp") 257 done(doc) 258 259 260def const(prefix, name): 261 mod = "presentation" if prefix in ("EffectNodeType", "EffectPresetClass", "ShapeAnimationSubType", "EffectCommands") else "animations" 262 return uno.getConstantByName("com.sun.star.%s.%s.%s" % (mod, prefix, name)) 263 264 265def transitions(): 266 doc = new("odp") 267 first = True 268 types = [uno.getConstantByName("com.sun.star.animations.TransitionType.BARWIPE") + i for i in range(43)] 269 subs = list(range(0, 120)) 270 combos = [(t, 0) for t in types] + [(1, st) for st in subs if st] 271 for i, (t, st) in enumerate(combos): 272 p = doc.DrawPages.getByIndex(0) if first else add_page(doc) 273 first = False 274 setp(p, TransitionType=t, TransitionSubtype=st, TransitionDuration=1.5 + (i % 3), TransitionDirection=bool(i % 2), 275 TransitionFadeColor=0x336699 + i) 276 p = add_page(doc) 277 setp(p, TransitionType=37, TransitionSubtype=const("TransitionSubType", "FADETOCOLOR"), TransitionDirection=False, 278 TransitionFadeColor=0xFF8800) 279 p = add_page(doc) 280 setp(p, TransitionType=37, TransitionSubtype=const("TransitionSubType", "FADEFROMCOLOR"), TransitionFadeColor=0x0088FF) 281 p = add_page(doc) 282 setp(p, TransitionType=0, Sound=SOUND_URL, LoopSound=True) 283 p = add_page(doc) 284 setp(p, TransitionType=4, TransitionSubtype=3, Sound=SOUND_URL) 285 p = add_page(doc) 286 setp(p, TransitionType=0, Sound=True) 287 p = add_page(doc) 288 setp(p, TransitionType=36, Sound=False, Change=1, Duration=5) 289 save(doc, "transitions.odp") 290 done(doc) 291 292 293def nv(name, value): 294 return struct_("com.sun.star.beans.NamedValue", name, value) 295 296 297def node(name, **props): 298 n = spec(name) 299 for k, v in props.items(): 300 setattr(n, k, v) 301 return n 302 303 304def userdata(**kw): 305 return tuple(nv(k.replace("_", "-"), v) for k, v in kw.items()) 306 307 308def event(trigger, source=None, offset=None): 309 e = struct_("com.sun.star.animations.Event") 310 e.Trigger = trigger 311 if source is not None: 312 e.Source = source 313 if offset is not None: 314 e.Offset = offset 315 return e 316 317 318def animations_one(doc, p, k): 319 sh = mk(doc, p, "RectangleShape", text="target one\ntwo\nthree") 320 sh2 = mk(doc, p, "EllipseShape", x=6000, y=1000, text="second") 321 sh3 = mk(doc, p, "RectangleShape", x=1000, y=5000, text="third") 322 root = p.AnimationNode 323 seq = node("SequenceTimeContainer", UserData=userdata(node_type=const("EffectNodeType", "MAIN_SEQUENCE"))) 324 root.appendChild(seq) 325 EN = lambda n: const("EffectNodeType", n) 326 327 def effect(nodetype, preset, cls, *children, **kw): 328 par = node("ParallelTimeContainer", Begin=kw.pop("Begin", 0.0), 329 UserData=userdata(node_type=EN(nodetype), preset_id=preset, preset_class=const("EffectPresetClass", cls), 330 preset_sub_type="", group_id=1)) 331 for c in children: 332 par.appendChild(c) 333 for a, b in kw.items(): 334 setattr(par, a, b) 335 return par 336 337 def click(*effects, trig=True): 338 outer = node("ParallelTimeContainer", Begin=event(const("EventTrigger", "ON_NEXT")) if trig else 0.0) 339 inner = node("ParallelTimeContainer", Begin=0.0) 340 for e in effects: 341 inner.appendChild(e) 342 outer.appendChild(inner) 343 seq.appendChild(outer) 344 345 st = node("AnimateSet", Target=sh, AttributeName="Visibility", To=True, Begin=0.0, Duration=0.001, Fill=const("AnimationFill", "HOLD")) 346 click(effect("ON_CLICK", "ooo-entrance-appear", "ENTRANCE", st)) 347 an = node("Animate", Target=sh2, AttributeName="X", Values=(0.0, 0.5), KeyTimes=(0.0, 1.0), Duration=2.0, 348 Formula="$X+#x", CalcMode=const("AnimationCalcMode", "DISCRETE"), Accumulate=True, 349 Additive=const("AnimationAdditiveMode", "SUM"), TimeFilter=(struct_("com.sun.star.animations.TimeFilterPair", 0.0, 0.0), struct_("com.sun.star.animations.TimeFilterPair", 1.0, 1.0))) 350 an2 = node("Animate", Target=sh2, AttributeName="Opacity", From=0.0, By=0.1, To=1.0, Duration=1.0, 351 CalcMode=const("AnimationCalcMode", "PACED"), Additive=const("AnimationAdditiveMode", "MULTIPLY")) 352 an3 = node("Animate", Target=sh2, AttributeName="Y", From=0.0, To=0.5, Duration=1.0, Additive=const("AnimationAdditiveMode", "BASE")) 353 an4 = node("Animate", Target=sh2, AttributeName="Height", From=0.0, To=0.5, Duration=1.0, Additive=const("AnimationAdditiveMode", "NONE")) 354 click(effect("WITH_PREVIOUS", "ooo-entrance-fly-in", "ENTRANCE", an, an2, an3, an4)) 355 ac = node("AnimateColor", Target=sh, AttributeName="FillColor", From=0xFF0000, To=0x00FF00, Duration=1.0, 356 ColorInterpolation=const("AnimationColorSpace", "HSL"), Direction=False) 357 ac2 = node("AnimateColor", Target=sh3, AttributeName="LineColor", By=0x101010, Duration=1.0, 358 ColorInterpolation=const("AnimationColorSpace", "RGB"), Direction=True) 359 click(effect("AFTER_PREVIOUS", "ooo-emphasis-change-fill-color", "EMPHASIS", ac, ac2)) 360 am = node("AnimateMotion", Target=sh3, Path="M 0 0 L 0.25 0.25 C 0.3 0.3 0.4 0.3 0.5 0.5", Duration=2.0, 361 CalcMode=const("AnimationCalcMode", "PACED")) 362 click(effect("ON_CLICK", "ooo-motionpath-user", "MOTIONPATH", am)) 363 ats = [node("AnimateTransform", Target=sh2, TransformType=tt, Values=("1", "2"), Duration=1.0, SubItem=sub) 364 for tt, sub in ((0, 0), (1, 1), (2, 2), (3, 0), (4, 1))] 365 click(effect("ON_CLICK", "ooo-emphasis-spin", "EMPHASIS", *ats)) 366 attrs = [("Width", "0", "width"), ("Height", "0", "height"), ("Y", "0", "y"), ("Rotate", 0.0, 90.0), ("SkewX", 0.0, 30.0), 367 ("CharColor", 0, 0xFF0000), ("CharRotation", 0, 90), ("CharWeight", 100.0, 150.0), ("CharUnderline", 0, 1), 368 ("CharFontName", "Arial", "Times"), ("CharHeight", 1.0, 2.0), ("CharPosture", 0, 2), 369 ("LineStyle", 0, 1), ("FillStyle", 0, 1), ("DimColor", 0, 0xAAAAAA), ("Visibility", False, True)] 370 kids = [] 371 for an_name, fr, to in attrs: 372 try: 373 kids.append(node("Animate", Target=sh3, AttributeName=an_name, From=fr, To=to, Duration=0.5, 374 Restart=const("AnimationRestart", "ALWAYS"), RestartDefault=const("AnimationRestart", "NEVER"), 375 FillDefault=const("AnimationFill", "FREEZE"), Acceleration=0.2, Decelerate=0.3, 376 AutoReverse=True, RepeatCount=3.0, RepeatDuration=9.0, EndSync=const("AnimationEndSync", "FIRST"), 377 End=5.0)) 378 except Exception as e: 379 print(" animate", an_name, repr(e)[:100]) 380 click(effect("ON_CLICK", "ooo-emphasis-custom", "CUSTOM", *kids)) 381 tf = node("TransitionFilter", Target=sh, Transition=1, Subtype=2, Mode=False, Direction=False, FadeColor=0x123456, Duration=1.0) 382 tf2 = node("TransitionFilter", Target=sh2, Transition=37, Subtype=const("TransitionSubType", "FADETOCOLOR"), Mode=True, 383 Direction=True, FadeColor=0x654321, Duration=1.0) 384 click(effect("ON_CLICK", "ooo-entrance-wipe", "ENTRANCE", tf, tf2)) 385 au = node("Audio", Source=SOUND_URL, Volume=0.5, Begin=0.0) 386 au2 = node("Audio", Source=SOUND_URL, Volume=1.0) 387 cm = [node("Command", Target=sh, Command=c, Parameter=None) for c in range(6)] 388 click(effect("ON_CLICK", "media-call", "MEDIACALL", au, au2, *cm)) 389 it = node("IterateContainer", Target=sh, SubItem=const("ShapeAnimationSubType", "ONLY_TEXT"), 390 IterateType=1, IterateInterval=0.25, 391 UserData=userdata(node_type=EN("ON_CLICK"), preset_id="ooo-entrance-fade-in", preset_class=const("EffectPresetClass", "ENTRANCE"))) 392 it.appendChild(node("AnimateSet", Target=sh, AttributeName="Visibility", To=True, Begin=0.0, Duration=0.001)) 393 click(it) 394 for sub, itype in ((1, 0), (0, 2)): 395 it2 = node("IterateContainer", Target=ParagraphTarget(sh, 1), SubItem=sub, IterateType=itype, IterateInterval=1.5) 396 it2.appendChild(node("AnimateSet", Target=ParagraphTarget(sh, 1), AttributeName="Visibility", To=True)) 397 click(it2) 398 seq2 = node("SequenceTimeContainer", UserData=userdata(node_type=EN("INTERACTIVE_SEQUENCE")), 399 Begin=event(const("EventTrigger", "ON_CLICK"), sh3), End=(event(const("EventTrigger", "ON_END"), sh), 5.0)) 400 seq2.appendChild(node("AnimateSet", Target=sh2, AttributeName="Visibility", To=False)) 401 root.appendChild(seq2) 402 for kind in range(12): 403 trig = kind + 1 404 e = event(trig, sh, 0.5 if kind % 2 else None) 405 seq3 = node("SequenceTimeContainer", UserData=userdata(node_type=EN("INTERACTIVE_SEQUENCE")), Begin=e) 406 seq3.appendChild(node("AnimateSet", Target=sh2, AttributeName="Visibility", To=True)) 407 root.appendChild(seq3) 408 for fill, rest in ((1, 1), (2, 2), (3, 3), (4, 0), (5, 1)): 409 par = node("ParallelTimeContainer", Fill=fill, Restart=rest, Begin=0.0) 410 par.appendChild(node("AnimateSet", Target=sh, AttributeName="Visibility", To=True)) 411 root.appendChild(par) 412 413 414def ParagraphTarget(shape, n): 415 return struct_("com.sun.star.presentation.ParagraphTarget", shape, n) 416 417 418def animations(): 419 doc = new("odp") 420 p = doc.DrawPages.getByIndex(0) 421 step("anim-tree", animations_one, doc, p, 0) 422 save(doc, "animations.odp") 423 done(doc) 424 425 426def enum(t, v): 427 return uno.Enum("com.sun.star.presentation." + t, v) 428 429 430ANIM_EFFECTS = """FADE_FROM_LEFT FADE_FROM_TOP FADE_FROM_RIGHT FADE_FROM_BOTTOM FADE_TO_CENTER FADE_FROM_CENTER MOVE_FROM_LEFT MOVE_FROM_TOP 431MOVE_FROM_RIGHT MOVE_FROM_BOTTOM VERTICAL_STRIPES HORIZONTAL_STRIPES CLOCKWISE COUNTERCLOCKWISE FADE_FROM_UPPERLEFT FADE_FROM_UPPERRIGHT 432FADE_FROM_LOWERLEFT FADE_FROM_LOWERRIGHT CLOSE_VERTICAL CLOSE_HORIZONTAL OPEN_VERTICAL OPEN_HORIZONTAL PATH MOVE_TO_LEFT MOVE_TO_TOP 433MOVE_TO_RIGHT MOVE_TO_BOTTOM SPIRALIN_LEFT SPIRALIN_RIGHT SPIRALOUT_LEFT SPIRALOUT_RIGHT DISSOLVE WAVYLINE_FROM_LEFT WAVYLINE_FROM_TOP 434WAVYLINE_FROM_RIGHT WAVYLINE_FROM_BOTTOM RANDOM VERTICAL_LINES HORIZONTAL_LINES LASER_FROM_LEFT LASER_FROM_TOP LASER_FROM_RIGHT 435LASER_FROM_BOTTOM LASER_FROM_UPPERLEFT LASER_FROM_UPPERRIGHT LASER_FROM_LOWERLEFT LASER_FROM_LOWERRIGHT APPEAR HIDE MOVE_FROM_UPPERLEFT 436MOVE_FROM_UPPERRIGHT MOVE_FROM_LOWERRIGHT MOVE_FROM_LOWERLEFT MOVE_TO_UPPERLEFT MOVE_TO_UPPERRIGHT MOVE_TO_LOWERRIGHT MOVE_TO_LOWERLEFT 437MOVE_SHORT_FROM_LEFT MOVE_SHORT_FROM_UPPERLEFT MOVE_SHORT_FROM_TOP MOVE_SHORT_FROM_UPPERRIGHT MOVE_SHORT_FROM_RIGHT 438MOVE_SHORT_FROM_LOWERRIGHT MOVE_SHORT_FROM_BOTTOM MOVE_SHORT_FROM_LOWERLEFT MOVE_SHORT_TO_LEFT MOVE_SHORT_TO_UPPERLEFT MOVE_SHORT_TO_TOP 439MOVE_SHORT_TO_UPPERRIGHT MOVE_SHORT_TO_RIGHT MOVE_SHORT_TO_LOWERRIGHT MOVE_SHORT_TO_BOTTOM MOVE_SHORT_TO_LOWERLEFT VERTICAL_CHECKERBOARD 440HORIZONTAL_CHECKERBOARD HORIZONTAL_ROTATE VERTICAL_ROTATE HORIZONTAL_STRETCH VERTICAL_STRETCH STRETCH_FROM_LEFT STRETCH_FROM_UPPERLEFT 441STRETCH_FROM_TOP STRETCH_FROM_UPPERRIGHT STRETCH_FROM_RIGHT STRETCH_FROM_LOWERRIGHT STRETCH_FROM_BOTTOM STRETCH_FROM_LOWERLEFT ZOOM_IN 442ZOOM_IN_SMALL ZOOM_IN_SPIRAL ZOOM_OUT ZOOM_OUT_SMALL ZOOM_OUT_SPIRAL ZOOM_IN_FROM_LEFT ZOOM_IN_FROM_UPPERLEFT ZOOM_IN_FROM_TOP 443ZOOM_IN_FROM_UPPERRIGHT ZOOM_IN_FROM_RIGHT ZOOM_IN_FROM_LOWERRIGHT ZOOM_IN_FROM_BOTTOM ZOOM_IN_FROM_LOWERLEFT ZOOM_IN_FROM_CENTER 444ZOOM_OUT_FROM_LEFT ZOOM_OUT_FROM_UPPERLEFT ZOOM_OUT_FROM_TOP ZOOM_OUT_FROM_UPPERRIGHT ZOOM_OUT_FROM_RIGHT ZOOM_OUT_FROM_LOWERRIGHT 445ZOOM_OUT_FROM_BOTTOM ZOOM_OUT_FROM_LOWERLEFT ZOOM_OUT_FROM_CENTER""".split() 446CLICK_ACTIONS = "NONE PREVPAGE NEXTPAGE FIRSTPAGE LASTPAGE BOOKMARK DOCUMENT INVISIBLE SOUND VERB VANISH PROGRAM MACRO STOPPRESENTATION".split() 447 448 449def png(path, w=8, h=8): 450 import zlib 451 raw = b"".join(b"\x00" + b"".join(bytes((x * 30 % 256, y * 30 % 256, 128)) for x in range(w)) for y in range(h)) 452 def chunk(t, d): 453 c = struct.pack(">I", len(d)) + t + d 454 return c + struct.pack(">I", zlib.crc32(t + d) & 0xffffffff) 455 data = b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 2, 0, 0, 0)) + chunk(b"IDAT", zlib.compress(raw)) + chunk(b"IEND", b"") 456 open(path, "wb").write(data) 457 458 459PNG = os.path.join(tmp, "pix.png") 460png(PNG) 461PNG_URL = uno.systemPathToFileUrl(PNG) 462 463 464def actions(): 465 doc = new("odp") 466 page = doc.DrawPages.getByIndex(0) 467 pg2 = add_page(doc) 468 pg2.Name = "Target" 469 x = 500 470 y = 500 471 for i, a in enumerate(CLICK_ACTIONS): 472 sh = mk(doc, page, "RectangleShape", x=x, y=y, w=2000, h=1000, text=a) 473 x += 2200 474 if x > 22000: 475 x = 500; y += 1200 476 props = dict(OnClick=enum("ClickAction", a)) 477 if a in ("BOOKMARK",): 478 props["Bookmark"] = "Target" 479 if a in ("DOCUMENT",): 480 props["Bookmark"] = "file:///tmp/other.odp#Slide1" 481 if a == "PROGRAM": 482 props["Bookmark"] = "file:///usr/bin/true" 483 if a == "SOUND": 484 props.update(Bookmark=SOUND_URL, PlayFull=True) 485 if a == "VERB": 486 props["Verb"] = 1 487 if a == "MACRO": 488 props["Bookmark"] = "macro:///Standard.Module1.Main" 489 setp(sh, **props) 490 for i, eff in enumerate(ANIM_EFFECTS): 491 sh = mk(doc, page, "RectangleShape", x=500 + (i % 10) * 2200, y=6000 + (i // 10) * 1100, w=2000, h=900, text=eff[:14]) 492 setp(sh, OnClick=enum("ClickAction", "VANISH"), Effect=enum("AnimationEffect", eff), 493 Speed=enum("AnimationSpeed", ("SLOW", "MEDIUM", "FAST")[i % 3]), SoundOn=bool(i % 2), Sound=SOUND_URL, PlayFull=bool(i % 3 == 0), 494 DimPrevious=False, DimHide=False) 495 save(doc, "click-actions.odp") 496 done(doc) 497 498 499def draw_links(): 500 doc = new("odg") 501 pages = [doc.DrawPages.getByIndex(0), add_page(doc)] 502 pages[1].Name = "Second" 503 for i, a in enumerate(("BOOKMARK", "DOCUMENT")): 504 sh = mk(doc, pages[0], "RectangleShape", x=500 + i * 3500, text=a) 505 setp(sh, OnClick=enum("ClickAction", a), Bookmark="Second" if i == 0 else "file:///tmp/other.odg#Page1") 506 save(doc, "draw-links.odg") 507 done(doc) 508 509 510def image_maps(): 511 doc = new("odg") 512 page = doc.DrawPages.getByIndex(0) 513 g = mk(doc, page, "GraphicObjectShape", x=1000, y=1000, w=8000, h=6000) 514 g.GraphicURL = PNG_URL 515 imap = g.ImageMap 516 r = doc.createInstance("com.sun.star.image.ImageMapRectangleObject") 517 r.Boundary = struct_("com.sun.star.awt.Rectangle", 0, 0, 3000, 2000) 518 r.URL = "http://example.org/rect" 519 r.Target = "_blank" 520 r.Description = "rect area" 521 r.IsActive = True 522 r.Name = "r1" 523 imap.insertByIndex(0, r) 524 c = doc.createInstance("com.sun.star.image.ImageMapCircleObject") 525 c.Center = pt(5000, 3000) 526 c.Radius = 1000 527 c.URL = "http://example.org/circle" 528 c.Title = "circle title" 529 c.IsActive = False 530 imap.insertByIndex(1, c) 531 po = doc.createInstance("com.sun.star.image.ImageMapPolygonObject") 532 po.Polygon = (pt(0, 0), pt(100, 0), pt(100, 100), pt(0, 100)) 533 po.URL = "#target" 534 po.Description = "poly area" 535 imap.insertByIndex(2, po) 536 g.ImageMap = imap 537 gr2 = mk(doc, page, "GraphicObjectShape", x=10000, y=1000, w=3000, h=3000) 538 gr2.GraphicURL = PNG_URL 539 setp(gr2, Title="a picture", Description="a described picture") 540 save(doc, "image-map.odg") 541 done(doc) 542 543 544def pts(*xy): 545 return tuple(pt(x, y) for x, y in xy) 546 547 548def poly(doc, page, service, points, **props): 549 s_ = doc.createInstance("com.sun.star.drawing." + service) 550 page.add(s_) 551 s_.PolyPolygon = (pts(*points),) 552 setp(s_, **props) 553 return s_ 554 555 556def bezier(doc, page, service, **props): 557 s_ = doc.createInstance("com.sun.star.drawing." + service) 558 page.add(s_) 559 C = uno.Enum("com.sun.star.drawing.PolygonFlags", "NORMAL") 560 K = uno.Enum("com.sun.star.drawing.PolygonFlags", "CONTROL") 561 coords = struct_("com.sun.star.drawing.PolyPolygonBezierCoords") 562 coords.Coordinates = (pts((1000, 1000), (2000, 0), (3000, 2000), (4000, 1000), (5000, 3000), (1000, 3000)),) 563 coords.Flags = ((C, K, K, C, C, C),) 564 s_.PolyPolygonBezier = coords 565 setp(s_, **props) 566 return s_ 567 568 569def shapes_core(doc, page): 570 mk(doc, page, "RectangleShape", x=500, y=500, text="plain", Name="rect1") 571 mk(doc, page, "RectangleShape", x=4000, y=500, text="round", CornerRadius=400, RotateAngle=3000, ShearAngle=500, Name="rect2") 572 mk(doc, page, "RectangleShape", x=8000, y=500, text="rot", RotateAngle=9000) 573 for i, kind in enumerate(("FULL", "CUT", "SECTION", "ARC")): 574 ck = uno.Enum("com.sun.star.drawing.CircleKind", kind) 575 mk(doc, page, "EllipseShape", x=500 + i * 2600, y=3500, w=2400, h=2400, CircleKind=ck, 576 CircleStartAngle=3000, CircleEndAngle=24000, Name="circle-" + kind) 577 mk(doc, page, "EllipseShape", x=500 + i * 3200, y=6500, w=3000, h=2000, CircleKind=ck, 578 CircleStartAngle=3000, CircleEndAngle=24000, Name="ellipse-" + kind) 579 mk(doc, page, "EllipseShape", x=500 + i * 3200, y=9000, w=2400, h=2400, CircleKind=ck, RotateAngle=4500, 580 CircleStartAngle=3000, CircleEndAngle=24000) 581 mk(doc, page, "EllipseShape", x=22000, y=9000, w=3000, h=2000, RotateAngle=2500, Name="ellipse-rot") 582 poly(doc, page, "LineShape", ((500, 12000), (4000, 13000)), Name="line1") 583 poly(doc, page, "LineShape", ((4500, 12000), (8000, 13000)), RotateAngle=2000) 584 poly(doc, page, "PolyLineShape", ((9000, 12000), (10000, 14000), (11000, 12000), (12000, 14000)), Name="polyline1") 585 poly(doc, page, "PolyLineShape", ((13000, 12000), (14000, 14000), (15000, 12000)), RotateAngle=3000) 586 poly(doc, page, "PolyPolygonShape", ((16000, 12000), (18000, 12000), (17000, 14000)), Name="polygon1") 587 poly(doc, page, "PolyPolygonShape", ((19000, 12000), (21000, 12000), (20000, 14000)), RotateAngle=1500) 588 bezier(doc, page, "ClosedBezierShape", Name="path-closed") 589 bezier(doc, page, "OpenBezierShape", RotateAngle=1000) 590 bezier(doc, page, "ClosedFreeHandShape") 591 bezier(doc, page, "OpenFreeHandShape") 592 poly(doc, page, "PolyLinePathShape", ((1000, 16000), (2000, 17000), (3000, 16000))) 593 poly(doc, page, "PolyPolygonPathShape", ((4000, 16000), (6000, 16000), (5000, 17500))) 594 mk(doc, page, "TextShape", x=7000, y=16000, w=4000, h=1000, text="text box", TextAutoGrowHeight=True, 595 TextMinimumFrameWidth=2000, TextMaximumFrameWidth=6000, TextMinimumFrameHeight=500, TextMaximumFrameHeight=3000, Name="text1") 596 t = mk(doc, page, "TextShape", x=12000, y=16000, w=4000, h=1000, text="titled") 597 setp(t, Title="text title", Description="text description") 598 g1 = mk(doc, page, "RectangleShape", x=500, y=18000, text="g1") 599 g2 = mk(doc, page, "EllipseShape", x=4000, y=18000, text="g2") 600 grp = doc.createInstance("com.sun.star.drawing.GroupShape") 601 page.add(grp) 602 grp.add(g1) 603 grp.add(g2) 604 setp(grp, Name="group1", Title="group title", Description="group desc") 605 inner = doc.createInstance("com.sun.star.drawing.GroupShape") 606 page.add(inner) 607 inner.add(mk(doc, page, "RectangleShape", x=8000, y=18000, text="n1")) 608 inner.add(mk(doc, page, "RectangleShape", x=11000, y=18000, text="n2")) 609 outer = doc.createInstance("com.sun.star.drawing.GroupShape") 610 page.add(outer) 611 outer.add(inner) 612 outer.add(mk(doc, page, "RectangleShape", x=14000, y=18000, text="n3")) 613 setp(outer, Name="group2") 614 615 616def connectors(doc, page): 617 r = [mk(doc, page, "RectangleShape", x=1000 + (i % 3) * 6000, y=1000 + (i // 3) * 5000, w=2500, h=1500, text="n%d" % i, Name="node%d" % i) 618 for i in range(9)] 619 for i in range(4): 620 gp = struct_("com.sun.star.drawing.GluePoint2") 621 gp.Position = pt(500 * i, 200 * i) 622 gp.IsRelative = bool(i % 2) 623 gp.PositionAlignment = uno.Enum("com.sun.star.drawing.Alignment", ("TOP_LEFT", "CENTER", "BOTTOM_RIGHT", "LEFT")[i]) 624 gp.Escape = uno.Enum("com.sun.star.drawing.EscapeDirection", ("SMART", "LEFT", "UP", "DOWN")[i]) 625 gp.IsUserDefined = True 626 r[0].GluePoints.insert(gp) 627 escs = ("SMART", "LEFT", "RIGHT", "UP", "DOWN", "HORIZONTAL", "VERTICAL") 628 for i, esc in enumerate(escs): 629 gp = struct_("com.sun.star.drawing.GluePoint2") 630 gp.Position = pt(100 * i, 100 * i) 631 gp.IsRelative = False 632 gp.PositionAlignment = uno.Enum("com.sun.star.drawing.Alignment", ("TOP_LEFT", "TOP", "TOP_RIGHT", "LEFT", "CENTER", "RIGHT", "BOTTOM_LEFT")[i]) 633 gp.Escape = uno.Enum("com.sun.star.drawing.EscapeDirection", esc) 634 gp.IsUserDefined = True 635 r[1].GluePoints.insert(gp) 636 kinds = ("STANDARD", "CURVE", "LINE", "LINES") 637 n = 0 638 for k in kinds: 639 c = doc.createInstance("com.sun.star.drawing.ConnectorShape") 640 page.add(c) 641 c.EdgeKind = uno.Enum("com.sun.star.drawing.ConnectorType", k) 642 c.StartShape = r[n % 9] 643 c.EndShape = r[(n + 4) % 9] 644 c.StartGluePointIndex = 0 if n % 2 else 4 645 c.EndGluePointIndex = 5 + n 646 setp(c, Title="conn " + k, Description="connector " + k, EdgeLine1Delta=300, EdgeLine2Delta=-300, EdgeNode1HorzDist=100, EdgeNode2VertDist=200) 647 n += 1 648 c2 = doc.createInstance("com.sun.star.drawing.ConnectorShape") 649 page.add(c2) 650 c2.EdgeKind = uno.Enum("com.sun.star.drawing.ConnectorType", k) 651 c2.StartPosition = pt(1000, 12000 + n * 700) 652 c2.EndPosition = pt(9000, 13000 + n * 900) 653 c2.String = "free " + k 654 655 656def measure_caption(doc, page): 657 for i, (a, b) in enumerate((((1000, 1000), (9000, 1000)), ((1000, 3000), (9000, 6000)), ((11000, 1000), (11000, 8000)))): 658 m = doc.createInstance("com.sun.star.drawing.MeasureShape") 659 page.add(m) 660 m.StartPosition = pt(*a) 661 m.EndPosition = pt(*b) 662 setp(m, Name="measure%d" % i, MeasureTextHorizontalPosition=i % 4, MeasureTextVerticalPosition=i % 4, 663 MeasureLineDistance=500, MeasureHelpLine1Length=200, MeasureHelpLine2Length=200, MeasureOverhang=100, 664 MeasureUnit=i, MeasureShowUnit=True, MeasureBelowReferenceEdge=bool(i % 2), MeasureTextRotate90=bool(i % 2), 665 MeasureTextIsFixedAngle=True, MeasureTextFixedAngle=1500 * i, MeasureDecimalPlaces=2, 666 MeasureTextAutoAngle=False, MeasureTextAutoAngleView=i, Title="m", Description="measure") 667 m.String = "measure %d" % i 668 for i in range(3): 669 c = doc.createInstance("com.sun.star.drawing.CaptionShape") 670 page.add(c) 671 c.Position = pt(1000 + i * 7000, 10000) 672 c.Size = sz(4000, 2000) 673 c.String = "caption %d" % i 674 setp(c, CaptionPoint=pt(500 + i * 7000, 14000), CaptionType=i, CaptionIsFitLineLength=bool(i % 2), CaptionIsEscapeRelative=bool(i % 2), 675 CaptionEscapeDirection=i, CaptionEscapeRelative=500, CaptionEscapeAbsolute=300, CaptionLineLength=700, 676 CaptionGap=100, CaptionAngle=300 * i, CornerRadius=300 * i, Name="caption%d" % i) 677 678 679def layers_doc(): 680 doc = new("odg") 681 page = doc.DrawPages.getByIndex(0) 682 lm = doc.LayerManager 683 for i, nm in enumerate(("layerA", "layerB")): 684 ly = lm.insertNewByIndex(lm.Count) 685 ly.Name = nm 686 setp(ly, IsVisible=bool(i % 2 == 0), IsPrintable=bool(i == 0), IsLocked=bool(i == 1), Title="t" + nm, Description="d" + nm) 687 sh = mk(doc, page, "RectangleShape", x=500 + 3000 * i, text=nm) 688 sh.LayerName = nm 689 for k, v in enumerate(("a", "b")): 690 sh = mk(doc, page, "EllipseShape", x=500 + 3000 * k, y=4000, text="nav%d" % k) 691 try: 692 order = smgr.createInstance("com.sun.star.drawing.ShapeCollection") 693 for i in reversed(range(page.Count)): 694 order.add(page.getByIndex(i)) 695 page.NavigationOrder = order 696 except Exception as e: 697 print(" navorder", repr(e)[:150]) 698 save(doc, "layers.odg") 699 done(doc) 700 701 702def shapes_docs(): 703 for kind in ("odg", "odp"): 704 for label, fn in (("core", shapes_core), ("connectors", connectors), ("measure", measure_caption)): 705 doc = new(kind) 706 page = doc.DrawPages.getByIndex(0) 707 step("%s-%s" % (label, kind), fn, doc, page) 708 save(doc, "%s.%s" % (label, kind)) 709 done(doc) 710 711 712def p3(x, y, z): 713 return struct_("com.sun.star.drawing.Position3D", x, y, z) 714 715 716def d3(x, y, z): 717 return struct_("com.sun.star.drawing.Direction3D", x, y, z) 718 719 720def scene_3d(doc, page, x, y, nm, mode="SMOOTH", proj="PERSPECTIVE", extra=None): 721 sc = doc.createInstance("com.sun.star.drawing.Shape3DSceneObject") 722 page.add(sc) 723 sc.Position = pt(x, y) 724 sc.Size = sz(5000, 5000) 725 cube = doc.createInstance("com.sun.star.drawing.Shape3DCubeObject") 726 sc.add(cube) 727 setp(cube, D3DPosition=p3(-1000, -1000, -1000), D3DSize=d3(2000, 3000, 2500)) 728 sph = doc.createInstance("com.sun.star.drawing.Shape3DSphereObject") 729 sc.add(sph) 730 setp(sph, D3DPosition=p3(500, 500, 0), D3DSize=d3(1500, 1500, 1500), D3DHorizontalSegments=12, D3DVerticalSegments=10) 731 ex = doc.createInstance("com.sun.star.drawing.Shape3DExtrudeObject") 732 sc.add(ex) 733 poly3 = struct_("com.sun.star.drawing.PolyPolygonShape3D") 734 poly3.SequenceX = ((0.0, 1000.0, 1000.0, 0.0),) 735 poly3.SequenceY = ((0.0, 0.0, 1000.0, 1000.0),) 736 poly3.SequenceZ = ((0.0, 0.0, 0.0, 0.0),) 737 setp(ex, D3DPolyPolygon3D=poly3, D3DDepth=700, D3DPercentDiagonal=5, D3DDoubleSided=True, 738 D3DCloseFront=True, D3DCloseBack=False, D3DNormalsKind=uno.Enum("com.sun.star.drawing.NormalsKind", "SPECIFIC"), 739 D3DNormalsInvert=True, D3DTextureProjectionX=uno.Enum("com.sun.star.drawing.TextureProjectionMode", "SPHERE"), 740 D3DTextureProjectionY=uno.Enum("com.sun.star.drawing.TextureProjectionMode", "OBJECTSPECIFIC"), 741 D3DTextureKind=uno.Enum("com.sun.star.drawing.TextureKind", "COLOR"), 742 D3DTextureMode=uno.Enum("com.sun.star.drawing.TextureMode", "BLEND"), D3DTextureFilter=True, 743 D3DMaterialColor=0x336699, D3DMaterialEmission=0x101010, D3DMaterialSpecular=0xAAAAAA, D3DMaterialSpecularIntensity=40, 744 D3DShadow3D=True) 745 la = doc.createInstance("com.sun.star.drawing.Shape3DLatheObject") 746 sc.add(la) 747 poly4 = struct_("com.sun.star.drawing.PolyPolygonShape3D") 748 poly4.SequenceX = ((500.0, 1500.0, 1000.0),) 749 poly4.SequenceY = ((0.0, 0.0, 1500.0),) 750 poly4.SequenceZ = ((0.0, 0.0, 0.0),) 751 setp(la, D3DPolyPolygon3D=poly4, D3DHorizontalSegments=16, D3DEndAngle=2700, D3DPercentDiagonal=10) 752 cg = struct_("com.sun.star.drawing.CameraGeometry") 753 cg.vrp = p3(0.0, 0.0, 6000.0) 754 cg.vpn = d3(1.0, 1.0, 5.0) 755 cg.vup = d3(0.0, 1.0, 0.2) 756 setp(sc, Name=nm, D3DCameraGeometry=cg, D3DScenePerspective=uno.Enum("com.sun.star.drawing.ProjectionMode", proj), 757 D3DSceneShadeMode=uno.Enum("com.sun.star.drawing.ShadeMode", mode), D3DSceneDistance=3000, D3DSceneFocalLength=40, 758 D3DSceneShadowSlant=15, D3DSceneAmbientColor=0x202040, D3DSceneTwoSidedLighting=True, 759 D3DSceneLightOn1=True, D3DSceneLightOn2=True, D3DSceneLightOn3=False, D3DSceneLightColor1=0xFFFFFF, 760 D3DSceneLightColor2=0xFF0000, D3DSceneLightColor5=0x00FF00, D3DSceneLightOn5=True, 761 D3DSceneLightDirection1=d3(1.0, 1.0, 1.0), D3DSceneLightDirection2=d3(-1.0, 0.0, 1.0), RotateAngle=1000 if extra else 0, 762 Title="3d scene", Description="a scene") 763 if extra: 764 setp(sc, **extra) 765 return sc 766 767 768def threed(kind): 769 doc = new(kind) 770 page = doc.DrawPages.getByIndex(0) 771 n = 0 772 for mode in ("FLAT", "PHONG", "SMOOTH", "DRAFT"): 773 for proj in ("PERSPECTIVE", "PARALLEL"): 774 step("scene-%s-%s" % (mode, proj), scene_3d, doc, page, 500 + (n % 4) * 5500, 500 + (n // 4) * 5500, "scene%d" % n, mode, proj) 775 n += 1 776 save(doc, "scenes.%s" % kind) 777 done(doc) 778 779 780def pv_(name, value): 781 return pv(name, value) 782 783 784def param(value, kind=0): 785 p_ = struct_("com.sun.star.drawing.EnhancedCustomShapeParameter") 786 p_.Value = value 787 p_.Type = kind 788 return p_ 789 790 791def pair(a, b, ka=0, kb=0): 792 pp = struct_("com.sun.star.drawing.EnhancedCustomShapeParameterPair") 793 pp.First = param(a, ka) 794 pp.Second = param(b, kb) 795 return pp 796 797 798def custom(doc, page, x, y, w, h, geometry, text=None, **props): 799 c = doc.createInstance("com.sun.star.drawing.CustomShape") 800 page.add(c) 801 c.Position = pt(x, y) 802 c.Size = sz(w, h) 803 if text: 804 c.String = text 805 c.CustomShapeGeometry = tuple(pv(k, v) for k, v in geometry) 806 setp(c, **props) 807 return c 808 809 810PRESETS = """rectangle round-rectangle ellipse diamond isosceles-triangle right-triangle parallelogram trapezoid octagon hexagon pentagon cross 811ring heart sun moon smiley-face lightning flower-1 cloud-callout star4 star5 star6 star8 star12 star24 right-arrow left-arrow up-arrow 812down-arrow left-right-arrow quad-arrow bent-arrow u-turn-arrow circular-arrow notched-right-arrow striped-right-arrow pentagon-right 813chevron flowchart-process flowchart-decision flowchart-terminator flowchart-document flowchart-data flowchart-connector 814flowchart-card flowchart-delay flowchart-sort mso-spt100 mso-spt21 round-callout rectangular-callout line-callout-1 bracket-pair 815brace-pair left-bracket right-brace wave double-wave horizontal-scroll vertical-scroll cube can bevel frame folded-corner 816block-arc forbidden down-ribbon up-ribbon quad-bevel octagon-bevel diamond-bevel left-right-up-arrow 817ellipse-ribbon ellipse-ribbon-2 irregular-seal1 irregular-seal2 doorplate 818fontwork-plain-text fontwork-slant-up fontwork-wave fontwork-fade-up-and-right fontwork-arch-up-curve fontwork-circle-curve 819fontwork-open-circle-curve fontwork-arch-up-pour fontwork-circle-pour fontwork-triangle-up fontwork-stop fontwork-inflate""".split() 820 821 822def custom_shapes(): 823 doc = new("odg") 824 page = doc.DrawPages.getByIndex(0) 825 for i, name in enumerate(PRESETS): 826 step("preset " + name, custom, doc, page, 500 + (i % 8) * 2700, 500 + (i // 8) * 2300, 2400, 2000, [("Type", name)], text=name[:8]) 827 save(doc, "custom-presets.odg") 828 done(doc) 829 830 831def custom_full(): 832 doc = new("odg") 833 page = doc.DrawPages.getByIndex(0) 834 PV = "[]com.sun.star.beans.PropertyValue" 835 ECS = "com.sun.star.drawing.EnhancedCustomShape" 836 pairs = lambda seq: uno.Any("[]" + ECS + "ParameterPair", tuple(seq)) 837 shade = lambda n: uno.Enum("com.sun.star.drawing.ShadeMode", n) 838 proj = lambda n: uno.Enum("com.sun.star.drawing.ProjectionMode", n) 839 for i, (sm, pm) in enumerate((("FLAT", "PARALLEL"), ("PHONG", "PERSPECTIVE"), ("SMOOTH", "PARALLEL"), ("DRAFT", "PERSPECTIVE"))): 840 ext = uno.Any(PV, (pv("Extrusion", True), pv("Brightness", 33.0), pv("Depth", pair(900.0, 0.5)), pv("Diffusion", 20.0), 841 pv("NumberOfLineSegments", 12), pv("LightFace", bool(i % 2)), pv("FirstLightHarsh", True), pv("SecondLightHarsh", False), 842 pv("FirstLightLevel", 60.0), pv("SecondLightLevel", 40.0), pv("FirstLightDirection", d3(10.0, 20.0, 30.0)), 843 pv("SecondLightDirection", d3(-1.0, 2.0, 3.0)), pv("Metal", bool(i % 2)), pv("ShadeMode", shade(sm)), 844 pv("RotateAngle", pair(10.0, 20.0)), pv("RotationCenter", d3(0.1, 0.2, 0.3)), pv("Shininess", 50.0), 845 pv("Skew", pair(50.0, 135.0)), pv("Specularity", 70.0), pv("ProjectionMode", proj(pm)), 846 pv("ViewPoint", p3(3500.0, -3500.0, 25000.0)), pv("Origin", pair(0.5, -0.5)), pv("Color", True))) 847 tp = uno.Any(PV, (pv("TextPath", True), pv("TextPathMode", uno.Enum("com.sun.star.drawing.EnhancedCustomShapeTextPathMode", ("NORMAL", "PATH", "SHAPE", "NORMAL")[i])), 848 pv("ScaleX", bool(i % 2)), pv("SameLetterHeights", bool(i // 2)))) 849 path = uno.Any(PV, (pv("ExtrusionAllowed", True), pv("ConcentricGradientFillAllowed", True), pv("TextPathAllowed", True), 850 pv("GluePointType", i % 3), pv("StretchX", 100 * i), pv("StretchY", 50 * i), 851 pv("GluePoints", pairs((pair(0, 0), pair(10800, 0), pair(21600, 21600)))), 852 pv("Coordinates", pairs((pair(0, 0), pair(21600, 0), pair(21600, 21600), pair(0, 21600)))), 853 pv("Segments", uno.Any("[]" + ECS + "Segment", (struct_(ECS + "Segment", 1, 1), struct_(ECS + "Segment", 2, 3), struct_(ECS + "Segment", 4, 1)))), 854 pv("TextFrames", uno.Any("[]" + ECS + "TextFrame", (struct_(ECS + "TextFrame", pair(0, 0), pair(21600, 21600)),))))) 855 h = uno.Any(PV, (pv("Position", pair(10800, 0)), pv("MirroredX", bool(i % 2)), pv("MirroredY", bool(i // 2)), pv("Switched", bool(i % 2)), 856 pv("RangeXMinimum", param(0)), pv("RangeXMaximum", param(21600)), pv("RangeYMinimum", param(0)), pv("RangeYMaximum", param(21600)))) 857 hp = uno.Any(PV, (pv("Position", pair(10800, 10800)), pv("Polar", pair(10800, 10800)), pv("RadiusRangeMinimum", param(0)), 858 pv("RadiusRangeMaximum", param(10800)))) 859 adj = struct_(ECS + "AdjustmentValue") 860 adj.Value = 5400 861 adj.State = uno.Enum("com.sun.star.beans.PropertyState", "DIRECT_VALUE") 862 geo = [("Type", "non-primitive"), ("MirroredX", bool(i % 2)), ("MirroredY", bool(i // 2)), 863 ("ViewBox", struct_("com.sun.star.awt.Rectangle", 0, 0, 21600, 21600)), ("TextRotateAngle", 15.0 * i), 864 ("Extrusion", ext), ("TextPath", tp), ("Path", path), ("Equations", uno.Any("[]string", ("x*2", "?0 -3", "$0 +1"))), 865 ("Handles", uno.Any("[][]com.sun.star.beans.PropertyValue", (h.value, hp.value))), 866 ("AdjustmentValues", uno.Any("[]" + ECS + "AdjustmentValue", (adj,)))] 867 step("custom-full-%d" % i, custom, doc, page, 500 + (i % 2) * 8000, 500 + (i // 2) * 7000, 7000, 6000, geo, text="fw%d" % i, 868 CustomShapeEngine="com.sun.star.drawing.EnhancedCustomShapeEngine", CustomShapeData="data%d" % i) 869 save(doc, "custom-full.odg") 870 done(doc) 871 872 873def fontwork(): 874 doc = new("odg") 875 page = doc.DrawPages.getByIndex(0) 876 for i, name in enumerate(("fontwork-plain-text", "fontwork-wave", "fontwork-slant-up", "fontwork-arch-up-curve", "fontwork-circle-pour")): 877 geo = [("Type", name), ("TextPath", uno.Any("[]com.sun.star.beans.PropertyValue", (pv("TextPath", True), pv("TextPathMode", uno.Enum("com.sun.star.drawing.EnhancedCustomShapeTextPathMode", "SHAPE")), 878 pv("ScaleX", False), pv("SameLetterHeights", bool(i % 2))))), 879 ("Path", uno.Any("[]com.sun.star.beans.PropertyValue", (pv("TextPathAllowed", True), pv("ExtrusionAllowed", True)))), 880 ("Extrusion", uno.Any("[]com.sun.star.beans.PropertyValue", (pv("Extrusion", bool(i % 2)),)))] 881 c = step("fw-" + name, custom, doc, page, 500, 500 + i * 3200, 12000, 3000, geo, text="Fontwork " + name[9:]) 882 if c is not None: 883 setp(c, TextAutoGrowHeight=False) 884 save(doc, "fontwork.odg") 885 done(doc) 886 887 888def cmds(**kw): 889 return uno.Any("[]com.sun.star.beans.PropertyValue", tuple(pv(k, v) for k, v in kw.items())) 890 891 892def special_shapes(doc, page, impress): 893 step("plugin", lambda: mk(doc, page, "PluginShape", x=500, y=500, w=4000, h=3000, PluginURL="file:///tmp/clip.mov", 894 PluginMimeType="video/quicktime", PluginCommands=cmds(autoplay="true", loop="false"))) 895 step("applet", lambda: mk(doc, page, "AppletShape", x=5000, y=500, w=4000, h=3000, AppletCodeBase="file:///tmp/", 896 AppletName="myapplet", AppletCode="Demo.class", AppletIsScript=True, 897 AppletCommands=cmds(speed="5", color="red"))) 898 step("frame", lambda: mk(doc, page, "FrameShape", x=10000, y=500, w=4000, h=3000, FrameURL="http://example.org/", 899 FrameName="myframe", FrameIsAutoScroll=True, FrameIsBorder=True, FrameMarginWidth=100, FrameMarginHeight=200)) 900 step("frame2", lambda: mk(doc, page, "FrameShape", x=15000, y=500, w=4000, h=3000, FrameURL="file:///tmp/x.html", FrameIsAutoScroll=False, 901 FrameIsBorder=False)) 902 903 def media(): 904 m = mk(doc, page, "MediaShape", x=500, y=4000, w=4000, h=3000) 905 setp(m, MediaURL=SOUND_URL, Loop=True, Mute=True, VolumeDB=-6, 906 Zoom=uno.Enum("com.sun.star.media.ZoomLevel", "FIT_TO_WINDOW")) 907 for i, z in enumerate(("ZOOM_1_TO_4", "ZOOM_1_TO_2", "ORIGINAL", "ZOOM_2_TO_1", "ZOOM_4_TO_1", "FIT_TO_WINDOW_FIXED_ASPECT", "FULLSCREEN")): 908 m2 = mk(doc, page, "MediaShape", x=5000 + i * 2000, y=4000, w=1800, h=1500) 909 setp(m2, MediaURL=SOUND_URL, Zoom=uno.Enum("com.sun.star.media.ZoomLevel", z)) 910 step("media", media) 911 step("page-thumb", lambda: mk(doc, page, "PageShape", x=500, y=8000, w=4000, h=3000, PageNumber=1, Name="thumb")) 912 step("page-thumb-rot", lambda: mk(doc, page, "PageShape", x=5000, y=8000, w=4000, h=3000, PageNumber=1, RotateAngle=2000, 913 Title="thumb title", Description="thumb desc")) 914 for i, (clsid, nm) in enumerate((("078B7ABA-54FC-457F-8551-6147E776A997", "math"), ("12DCAE26-281F-416F-A234-C3086127382E", "chart"), 915 ("47BBB4CB-CE4C-4E80-A591-42D9AE74950F", "calc"))): 916 def ole(clsid=clsid, nm=nm, i=i): 917 o = doc.createInstance("com.sun.star.drawing.OLE2Shape") 918 page.add(o) 919 o.CLSID = clsid 920 o.Position = pt(500 + i * 5000, 12000) 921 o.Size = sz(4000, 3000) 922 o.Name = "ole-" + nm 923 o.Title = "ole" 924 o.Description = nm 925 step("ole-" + nm, ole) 926 927 def control(): 928 form = doc.createInstance("com.sun.star.form.component.Form") 929 page.Forms.insertByIndex(0, form) 930 for i, svc in enumerate(("CommandButton", "TextField", "CheckBox")): 931 model = doc.createInstance("com.sun.star.form.component." + svc) 932 model.Name = "ctl%d" % i 933 form.insertByIndex(i, model) 934 cs = doc.createInstance("com.sun.star.drawing.ControlShape") 935 page.add(cs) 936 cs.Position = pt(500 + i * 4000, 16000) 937 cs.Size = sz(3000, 800) 938 cs.Control = model 939 setp(cs, Title="control", Description="ctl", Name="shape-ctl%d" % i, RotateAngle=0) 940 step("control", control) 941 942 943def special_docs(): 944 for kind in ("odg", "odp"): 945 doc = new(kind) 946 page = doc.DrawPages.getByIndex(0) 947 step("special-" + kind, special_shapes, doc, page, kind == "odp") 948 save(doc, "special.%s" % kind) 949 done(doc) 950 951 952def masters_and_notes(): 953 doc = new("odp") 954 mp = doc.MasterPages.getByIndex(0) 955 mp.Name = "MasterOne" 956 mk(doc, mp, "RectangleShape", x=500, y=500, text="on master") 957 mp2 = doc.MasterPages.insertNewByIndex(doc.MasterPages.Count) 958 mp2.Name = "MasterTwo" 959 mk(doc, mp2, "EllipseShape", x=500, y=500, text="master two") 960 pages = [doc.DrawPages.getByIndex(0), add_page(doc)] 961 pages[0].MasterPage = mp 962 pages[1].MasterPage = mp2 963 for i, p in enumerate(pages): 964 mk(doc, p, "RectangleShape", text="slide %d" % i) 965 np_ = p.NotesPage 966 mk(doc, np_, "RectangleShape", x=500, y=9000, text="note shape") 967 mk(doc, np_, "PageShape", x=500, y=500, w=4000, h=3000, PageNumber=i + 1) 968 try: 969 mk(doc, doc.getHandoutMasterPage(), "RectangleShape", x=500, y=500, text="handout") 970 except Exception as e: 971 print(" handout master", repr(e)[:100]) 972 save(doc, "masters-notes.odp") 973 doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, "masters-notes.otp")), (pv("FilterName", "impress8_template"),)) 974 done(doc) 975 doc = new("odg") 976 page = doc.DrawPages.getByIndex(0) 977 mp = doc.MasterPages.getByIndex(0) 978 mk(doc, mp, "RectangleShape", x=500, y=500, text="draw master") 979 page.MasterPage = mp 980 shapes_core(doc, page) 981 save(doc, "draw-master.odg") 982 doc.storeToURL(uno.systemPathToFileUrl(os.path.join(out, "draw-master.otg")), (pv("FilterName", "draw8_template"),)) 983 done(doc) 984 985 986ANCHORS = ("AS_CHARACTER", "AT_CHARACTER", "AT_PARAGRAPH", "AT_PAGE", "AT_FRAME") 987 988 989def anchor_enum(n): 990 return uno.Enum("com.sun.star.text.TextContentAnchorType", n) 991 992 993def writer_shapes(): 994 doc = new("odt") 995 text = doc.Text 996 cur = text.createTextCursor() 997 text.insertString(cur, "Anchoring test paragraph with some text to anchor to.", False) 998 text.insertControlCharacter(cur, uno.getConstantByName("com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK"), False) 999 frame = doc.createInstance("com.sun.star.text.TextFrame") 1000 frame.Size = sz(8000, 4000) 1001 frame.Name = "Host" 1002 frame.AnchorType = anchor_enum("AT_PARAGRAPH") 1003 text.insertTextContent(cur, frame, False) 1004 frame.Text.insertString(frame.Text.createTextCursor(), "frame text", False) 1005 services = ("RectangleShape", "EllipseShape", "LineShape", "PolyPolygonShape", "ClosedBezierShape", "CustomShape", "TextShape") 1006 for sv in services: 1007 for a in ANCHORS: 1008 def one(sv=sv, a=a): 1009 if sv in ("LineShape", "PolyPolygonShape"): 1010 sh = doc.createInstance("com.sun.star.drawing." + sv) 1011 sh.PolyPolygon = (pts((0, 0), (1500, 800)) if sv == "LineShape" else pts((0, 0), (1500, 0), (800, 1000)),) 1012 elif sv == "ClosedBezierShape": 1013 sh = doc.createInstance("com.sun.star.drawing.ClosedBezierShape") 1014 coords = struct_("com.sun.star.drawing.PolyPolygonBezierCoords") 1015 coords.Coordinates = (pts((0, 0), (1000, 0), (1000, 1000)),) 1016 N = uno.Enum("com.sun.star.drawing.PolygonFlags", "NORMAL") 1017 coords.Flags = ((N, N, N),) 1018 sh.PolyPolygonBezier = coords 1019 else: 1020 sh = doc.createInstance("com.sun.star.drawing." + sv) 1021 sh.Size = sz(1500, 1000) 1022 if sv == "CustomShape": 1023 sh.CustomShapeGeometry = (pv("Type", "diamond"),) 1024 sh.AnchorType = anchor_enum(a) 1025 if a == "AT_PAGE": 1026 sh.AnchorPageNo = 1 1027 cursor = text.createTextCursor() 1028 cursor.gotoStart(False) 1029 if a == "AT_FRAME": 1030 sh.AnchorFrame = frame 1031 frame.Text.insertTextContent(frame.Text.createTextCursor(), sh, False) 1032 else: 1033 text.insertTextContent(cursor, sh, False) 1034 setp(sh, Title="t " + sv, Description="d " + a) 1035 step("%s-%s" % (sv, a), one) 1036 def group(): 1037 for a in ANCHORS[:4]: 1038 g = doc.createInstance("com.sun.star.drawing.GroupShape") 1039 doc.DrawPage.add(g) 1040 for k in range(2): 1041 r = doc.createInstance("com.sun.star.drawing.RectangleShape") 1042 r.Size = sz(800, 800) 1043 r.Position = pt(k * 900, 0) 1044 g.add(r) 1045 g.AnchorType = anchor_enum(a) 1046 if a == "AT_PAGE": 1047 g.AnchorPageNo = 1 1048 step("groups", group) 1049 1050 def controls(): 1051 form = doc.createInstance("com.sun.star.form.component.Form") 1052 doc.DrawPage.Forms.insertByIndex(0, form) 1053 for i, a in enumerate(ANCHORS): 1054 model = doc.createInstance("com.sun.star.form.component.CommandButton") 1055 model.Name = "btn%d" % i 1056 form.insertByIndex(i, model) 1057 cs = doc.createInstance("com.sun.star.drawing.ControlShape") 1058 cs.Size = sz(2000, 700) 1059 cs.Control = model 1060 cs.AnchorType = anchor_enum(a) 1061 if a == "AT_PAGE": 1062 cs.AnchorPageNo = 1 1063 if a == "AT_FRAME": 1064 cs.AnchorFrame = frame 1065 cursor = text.createTextCursor() 1066 cursor.gotoStart(False) 1067 if a == "AT_FRAME": 1068 frame.Text.insertTextContent(frame.Text.createTextCursor(), cs, False) 1069 else: 1070 text.insertTextContent(cursor, cs, False) 1071 step("controls", controls) 1072 save(doc, "anchors.odt") 1073 done(doc) 1074 1075 1076def writer_group_frame(): 1077 doc = new("odt") 1078 text = doc.Text 1079 cur = text.createTextCursor() 1080 text.insertString(cur, "Group anchored to a frame.", False) 1081 frame = doc.createInstance("com.sun.star.text.TextFrame") 1082 frame.Size = sz(8000, 4000) 1083 frame.AnchorType = anchor_enum("AT_PARAGRAPH") 1084 text.insertTextContent(cur, frame, False) 1085 g = doc.createInstance("com.sun.star.drawing.GroupShape") 1086 r1 = doc.createInstance("com.sun.star.drawing.RectangleShape") 1087 r1.Size = sz(800, 800) 1088 g.AnchorType = anchor_enum("AT_FRAME") 1089 g.AnchorFrame = frame 1090 frame.Text.insertTextContent(frame.Text.createTextCursor(), g, False) 1091 g.add(r1) 1092 save(doc, "anchors-group-frame.odt") 1093 done(doc) 1094 1095 1096def writer_graphics(): 1097 doc = new("odt") 1098 text = doc.Text 1099 cur = text.createTextCursor() 1100 text.insertString(cur, "Graphics with contours, image maps and chained frames.", False) 1101 text.insertControlCharacter(cur, uno.getConstantByName("com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK"), False) 1102 for i, (name, contour) in enumerate((("single", (pts((0, 0), (100, 0), (100, 100), (0, 100)),)), 1103 ("multi", (pts((0, 0), (50, 0), (50, 50)), pts((60, 60), (100, 60), (100, 100)))), 1104 ("none", None))): 1105 def one(i=i, name=name, contour=contour): 1106 g = doc.createInstance("com.sun.star.text.TextGraphicObject") 1107 g.GraphicURL = PNG_URL 1108 g.AnchorType = anchor_enum(("AS_CHARACTER", "AT_PARAGRAPH", "AT_PAGE")[i]) 1109 g.Width = 3000 1110 g.Height = 2000 1111 g.Name = "grf-" + name 1112 if contour is not None: 1113 setp(g, ContourPolyPolygon=contour, SurroundContour=True, ContourOutside=bool(i % 2), IsPixelContour=bool(i // 1 % 2)) 1114 setp(g, GraphicFilter="png", Title="graphic " + name, Description="described", GraphicRotation=900 * i) 1115 cursor = text.createTextCursor() 1116 cursor.gotoEnd(False) 1117 text.insertTextContent(cursor, g, False) 1118 step("grf-" + name, one) 1119 def chain(): 1120 f1 = doc.createInstance("com.sun.star.text.TextFrame") 1121 f2 = doc.createInstance("com.sun.star.text.TextFrame") 1122 for f, nm in ((f1, "Chain1"), (f2, "Chain2")): 1123 f.Name = nm 1124 f.Size = sz(4000, 1500) 1125 f.AnchorType = anchor_enum("AT_PARAGRAPH") 1126 cursor = text.createTextCursor() 1127 cursor.gotoEnd(False) 1128 text.insertTextContent(cursor, f, False) 1129 f1.ChainNextName = "Chain2" 1130 f1.Text.insertString(f1.Text.createTextCursor(), "first frame of a chain " * 20, False) 1131 f3 = doc.createInstance("com.sun.star.text.TextFrame") 1132 f3.Name = "MinMax" 1133 f3.Width = 3000 1134 setp(f3, WidthType=uno.getConstantByName("com.sun.star.text.SizeType.MIN"), HeightType=uno.getConstantByName("com.sun.star.text.SizeType.MIN"), 1135 Height=800) 1136 f3.AnchorType = anchor_enum("AT_CHARACTER") 1137 cursor = text.createTextCursor() 1138 cursor.gotoEnd(False) 1139 text.insertTextContent(cursor, f3, False) 1140 step("chain", chain) 1141 save(doc, "graphics.odt") 1142 done(doc) 1143 1144 1145def calc_shapes(): 1146 doc = new("ods") 1147 sh = doc.Sheets.getByIndex(0) 1148 dp = sh.DrawPage 1149 for r in range(6): 1150 sh.getCellByPosition(0, r).String = "row %d" % r 1151 kinds = ("RectangleShape", "EllipseShape", "LineShape", "PolyPolygonShape", "PolyLineShape", "ClosedBezierShape", "CustomShape", 1152 "GraphicObjectShape", "TextShape", "ConnectorShape", "CaptionShape", "MeasureShape", "PageShape") 1153 for i, sv in enumerate(kinds): 1154 def one(i=i, sv=sv): 1155 o = doc.createInstance("com.sun.star.drawing." + sv) 1156 dp.add(o) 1157 if sv in ("LineShape", "PolyPolygonShape", "PolyLineShape"): 1158 o.PolyPolygon = (pts((0, 0), (1500, 0), (800, 1000)),) 1159 elif sv == "ClosedBezierShape": 1160 coords = struct_("com.sun.star.drawing.PolyPolygonBezierCoords") 1161 coords.Coordinates = (pts((0, 0), (1000, 0), (1000, 1000)),) 1162 N = uno.Enum("com.sun.star.drawing.PolygonFlags", "NORMAL") 1163 coords.Flags = ((N, N, N),) 1164 o.PolyPolygonBezier = coords 1165 else: 1166 o.Size = sz(2500, 1500) 1167 if sv == "CustomShape": 1168 o.CustomShapeGeometry = (pv("Type", "diamond"),) 1169 if sv == "GraphicObjectShape": 1170 o.GraphicURL = PNG_URL 1171 if sv not in ("LineShape", "PolyPolygonShape", "PolyLineShape", "ClosedBezierShape", "ConnectorShape", "MeasureShape"): 1172 o.Position = pt(500 + (i % 4) * 4000, 500 + (i // 4) * 3000) 1173 elif sv == "ConnectorShape": 1174 o.StartPosition = pt(500, 12000) 1175 o.EndPosition = pt(5000, 14000) 1176 elif sv == "MeasureShape": 1177 o.StartPosition = pt(6000, 12000) 1178 o.EndPosition = pt(10000, 12000) 1179 if i % 2 == 0: 1180 setp(o, Anchor=sh.getCellByPosition(1 + i % 3, i)) 1181 if i % 3 == 1: 1182 setp(o, LayerName="background") 1183 setp(o, Title="calc " + sv, Description="d") 1184 step("calc-" + sv, one) 1185 g = doc.createInstance("com.sun.star.drawing.GroupShape") 1186 dp.add(g) 1187 for k in range(2): 1188 r = doc.createInstance("com.sun.star.drawing.RectangleShape") 1189 r.Size = sz(800, 800) 1190 r.Position = pt(k * 900 + 15000, 1000) 1191 g.add(r) 1192 sh2 = doc.Sheets.getByIndex(0) 1193 save(doc, "shapes.ods") 1194 done(doc) 1195 1196 1197def annotations_docs(): 1198 for kind in ("odp", "odg"): 1199 doc = new(kind) 1200 for n in range(2): 1201 page = doc.DrawPages.getByIndex(0) if n == 0 else add_page(doc) 1202 mk(doc, page, "RectangleShape", text="annotated %d" % n) 1203 for k in range(2): 1204 ann = page.createAndInsertAnnotation() 1205 KEEP.append(ann) 1206 ann.Author = "Tester %d" % k 1207 ann.Position = struct_("com.sun.star.geometry.RealPoint2D", 3.0 + k, 4.0) 1208 ann.Size = struct_("com.sun.star.geometry.RealSize2D", 5.0, 6.0) 1209 ann.TextRange.String = "annotation %d.%d" % (n, k) 1210 ann.DateTime = struct_("com.sun.star.util.DateTime", 0, 12, 30, 10, 5, 6, 2025) 1211 save(doc, "annotations.%s" % kind) 1212 done(doc) 1213 1214 1215def fills(): 1216 doc = new("odg") 1217 page = doc.DrawPages.getByIndex(0) 1218 GS = lambda n: uno.Enum("com.sun.star.awt.GradientStyle", n) 1219 for i, gs in enumerate(("LINEAR", "AXIAL", "RADIAL", "ELLIPTICAL", "SQUARE", "RECT")): 1220 g = struct_("com.sun.star.awt.Gradient", GS(gs), 0xFF0000, 0x0000FF, 450 * i, 10 * i, 40 + i, 60 - i, 100, 80, 5) 1221 t = struct_("com.sun.star.awt.Gradient", GS(gs), 0x202020, 0xE0E0E0, 300 * i, 5 * i, 50, 50, 100, 100, 0) 1222 mk(doc, page, "RectangleShape", x=500 + i * 3000, y=500, w=2800, h=2000, FillStyle=uno.Enum("com.sun.star.drawing.FillStyle", "GRADIENT"), 1223 FillGradient=g) 1224 tt = doc.createInstance("com.sun.star.drawing.TransparencyGradientTable") 1225 tt.insertByName("trans-" + gs, t) 1226 mk(doc, page, "RectangleShape", x=500 + i * 3000, y=3000, w=2800, h=2000, FillStyle=uno.Enum("com.sun.star.drawing.FillStyle", "SOLID"), 1227 FillColor=0x3366CC, FillTransparenceGradientName="trans-" + gs) 1228 for i, hs in enumerate(("SINGLE", "DOUBLE", "TRIPLE")): 1229 h = struct_("com.sun.star.drawing.Hatch", uno.Enum("com.sun.star.drawing.HatchStyle", hs), 0x00AA00, 120 + 20 * i, 450 * i) 1230 mk(doc, page, "RectangleShape", x=500 + i * 3000, y=5500, w=2800, h=2000, FillStyle=uno.Enum("com.sun.star.drawing.FillStyle", "HATCH"), 1231 FillHatch=h, FillBackground=bool(i % 2), FillColor=0xFFEECC) 1232 for i, ds in enumerate(("RECT", "ROUND", "RECTRELATIVE", "ROUNDRELATIVE")): 1233 d = struct_("com.sun.star.drawing.LineDash", uno.Enum("com.sun.star.drawing.DashStyle", ds), 2, 100, 3, 300, 150) 1234 mk(doc, page, "LineShape" if False else "RectangleShape", x=500 + i * 3000, y=8000, w=2800, h=1500, 1235 LineStyle=uno.Enum("com.sun.star.drawing.LineStyle", "DASH"), LineDash=d, LineWidth=100) 1236 save(doc, "fills.odg") 1237 done(doc) 1238 1239 1240top("pres-settings", presentation_settings) 1241top("header-footer", header_footer) 1242top("layouts", layouts) 1243top("transitions", transitions) 1244top("animations", animations) 1245top("actions", actions) 1246top("draw-links", draw_links) 1247top("image-maps", image_maps) 1248top("shapes", shapes_docs) 1249top("layers", layers_doc) 1250top("special", special_docs) 1251top("annotations", annotations_docs) 1252top("fills", fills) 1253top("masters-notes", masters_and_notes) 1254top("writer-shapes", writer_shapes) 1255top("writer-group-frame", writer_group_frame) 1256top("writer-graphics", writer_graphics) 1257top("calc-shapes", calc_shapes) 1258top("custom-presets", custom_shapes) 1259top("custom-full", custom_full) 1260top("fontwork", fontwork) 1261top("3d-odg", threed, "odg") 1262top("3d-odp", threed, "odp") 1263 1264print("crashed steps (retried):", crashes) 1265print("failed:", failed) 1266sys.stdout.flush() 1267os._exit(1 if failed else 0) 1268