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.
This commit is contained in:
Alx Sa 2025-06-01 15:25:43 +00:00
parent ede910abce
commit 9ab17bf034

View file

@ -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)