From 9ab17bf0348cabe7a258a328327c4fa95a536521 Mon Sep 17 00:00:00 2001 From: Alx Sa Date: Sun, 1 Jun 2025 15:25:43 +0000 Subject: [PATCH] python: Add import/export support for ORA extensions The OpenRaster specification has two official extensions for layers - storing if they are pixel locked, and if they are selected. Krita and MyPaint already support these extensions on import and export. This patch adds that support to GIMP as well. --- plug-ins/python/file-openraster.py | 32 ++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/plug-ins/python/file-openraster.py b/plug-ins/python/file-openraster.py index 1baed1e4a7..9f3abc2700 100755 --- a/plug-ins/python/file-openraster.py +++ b/plug-ins/python/file-openraster.py @@ -141,8 +141,10 @@ def get_layer_attributes(layer): visible = a.get('visibility', 'visible') != 'hidden' m = a.get('composite-op', 'svg:src-over') layer_mode = layermodes_map.get(m, Gimp.LayerMode.NORMAL) + selected = a.get('selected', 'false') == 'true' + locked = a.get('edit-locked', 'false') == 'true' - return path, name, x, y, opac, visible, layer_mode + return path, name, x, y, opac, visible, layer_mode, selected, locked def get_group_layer_attributes(layer): a = layer.attrib @@ -151,8 +153,10 @@ def get_group_layer_attributes(layer): visible = a.get('visibility', 'visible') != 'hidden' m = a.get('composite-op', 'svg:src-over') layer_mode = layermodes_map.get(m, Gimp.LayerMode.NORMAL) + selected = a.get('selected', 'false') == 'true' + locked = a.get('edit-locked', 'false') == 'true' - return name, 0, 0, opac, visible, layer_mode + return name, 0, 0, opac, visible, layer_mode, selected, locked def thumbnail_ora(procedure, file, thumb_size, args, data): tempdir = tempfile.mkdtemp('gimp-plugin-file-openraster') @@ -222,6 +226,7 @@ def export_ora(procedure, run_mode, image, file, options, metadata, config, data tmp_img.set_palette(image.get_palette()) tmp_layer = Gimp.Layer.new_from_drawable (drawable, tmp_img) + tmp_layer.set_visible (False) tmp_img.insert_layer (tmp_layer, None, 0) pdb_proc = Gimp.get_pdb().lookup_procedure('file-png-export') @@ -260,6 +265,12 @@ def export_ora(procedure, run_mode, image, file, options, metadata, config, data a['opacity'] = str(opac) a['visibility'] = 'visible' if visible else 'hidden' a['composite-op'] = gimp_layermodes_map.get(gimp_layer.get_mode(), 'svg:src-over') + + # ORA Specification extensions + if gimp_layer in image.get_selected_layers(): + a['selected'] = "true" + if gimp_layer.get_lock_content(): + a['edit-locked'] = "true" return layer def add_group_layer(parent, opac, gimp_layer, visible=True): @@ -271,6 +282,12 @@ def export_ora(procedure, run_mode, image, file, options, metadata, config, data a['opacity'] = str(opac) a['visibility'] = 'visible' if visible else 'hidden' a['composite-op'] = gimp_layermodes_map.get(gimp_layer.get_mode(), 'svg:src-over') + + # ORA Specification extensions + if gimp_layer in image.get_selected_layers(): + a['selected'] = "true" + if gimp_layer.get_lock_content(): + a['edit-locked'] = "true" return group_layer @@ -383,6 +400,7 @@ def load_ora(procedure, run_mode, file, metadata, flags, config, data): lay_cnt = len(stack) layer_no = 0 + selected_layers = [] for item in get_layers(stack): prev_lay = layer_no @@ -391,11 +409,11 @@ def load_ora(procedure, run_mode, file, metadata, flags, config, data): continue if item.tag == 'stack': - name, x, y, opac, visible, layer_mode = get_group_layer_attributes(item) + name, x, y, opac, visible, layer_mode, selected, locked = get_group_layer_attributes(item) gimp_layer = Gimp.GroupLayer.new(img, name) else: - path, name, x, y, opac, visible, layer_mode = get_layer_attributes(item) + path, name, x, y, opac, visible, layer_mode, selected, locked = get_layer_attributes(item) if not path.lower().endswith('.png'): continue @@ -433,6 +451,9 @@ def load_ora(procedure, run_mode, file, metadata, flags, config, data): gimp_layer.set_offsets(x, y) # move to correct position gimp_layer.set_opacity(opac * 100) # a float between 0 and 100 gimp_layer.set_visible(visible) + gimp_layer.set_lock_content(locked) + if selected: + selected_layers.append(gimp_layer) img.insert_layer(gimp_layer, parent_groups[-1][0] if parent_groups else None, @@ -448,6 +469,9 @@ def load_ora(procedure, run_mode, file, metadata, flags, config, data): if (layer_no > prev_lay): Gimp.progress_update(layer_no/lay_cnt) + if len(selected_layers) > 0: + img.set_selected_layers(selected_layers) + Gimp.progress_end() os.rmdir(tempdir)