| 
13 | 13 | #### XCF ####  | 
14 | 14 | def openLayer_XCF(file: str) -> LayeredImage:  | 
15 | 15 | 	"""Open an .xcf file into a layered image."""  | 
16 |  | -	from gimpformats.gimpXcfDocument import GimpDocument  | 
 | 16 | +	from gimpformats.gimpXcfDocument import GimpDocument, GimpGroup  | 
17 | 17 | 
 
  | 
18 | 18 | 	blendLookup = {  | 
19 | 19 | 		0: BlendType.NORMAL,  | 
@@ -67,66 +67,44 @@ def openLayer_XCF(file: str) -> LayeredImage:  | 
67 | 67 | 	project = GimpDocument(file)  | 
68 | 68 | 	# Iterate the layers and create a list of layers for each group, then remove  | 
69 | 69 | 	# these from the project layers  | 
70 |  | -	layers = project.layers[::-1]  | 
71 |  | -	index = 0  | 
72 |  | -	groupIndex = 0  | 
73 |  | -	groupLayers = [[]]  | 
74 |  | -	while index < len(layers):  | 
75 |  | -		layerOrGroup = layers[index]  | 
76 |  | -		if layerOrGroup.isGroup:  | 
77 |  | -			index -= 1  | 
78 |  | -			while layers[index].itemPath is not None:  | 
79 |  | -				layer = layers[index]  | 
80 |  | -				groupLayers[groupIndex].append(  | 
 | 70 | + | 
 | 71 | +	root_group = project.walkTree()  | 
 | 72 | + | 
 | 73 | +	def rec_walk(group: GimpGroup) -> list[Group | Layer]:  | 
 | 74 | +		layers = []  | 
 | 75 | +		for child in group.children[::-1]:  | 
 | 76 | +			if isinstance(child, GimpGroup):  | 
 | 77 | +				info = child.layer_options  | 
 | 78 | +				if info is not None:  | 
 | 79 | +					layers.append(  | 
 | 80 | +						Group(  | 
 | 81 | +							name=str(info.name),  | 
 | 82 | +							layers=rec_walk(child),  | 
 | 83 | +							dimensions=(info.width, info.height),  | 
 | 84 | +							offsets=(0, 0),  | 
 | 85 | +							opacity=info.opacity,  | 
 | 86 | +							visible=info.visible,  | 
 | 87 | +							blendmode=blendModeLookup(info.blendMode, blendLookup),  | 
 | 88 | +						)  | 
 | 89 | +					)  | 
 | 90 | +			else:  | 
 | 91 | +				layers.append(  | 
81 | 92 | 					Layer(  | 
82 |  | -						name=layer.name,  | 
83 |  | -						image=layer.image,  | 
84 |  | -						dimensions=(layer.width, layer.height),  | 
 | 93 | +						name=str(child.name),  | 
 | 94 | +						image=child.image,  | 
 | 95 | +						dimensions=(child.width, child.height),  | 
85 | 96 | 						offsets=(  | 
86 |  | -							layer.xOffset - layerOrGroup.xOffset,  | 
87 |  | -							layer.yOffset - layerOrGroup.yOffset,  | 
 | 97 | +							child.xOffset,  | 
 | 98 | +							child.yOffset,  | 
88 | 99 | 						),  | 
89 |  | -						opacity=layer.opacity,  | 
90 |  | -						visible=layer.visible,  | 
91 |  | -						blendmode=blendModeLookup(layer.blendMode, blendLookup),  | 
 | 100 | +						opacity=child.opacity,  | 
 | 101 | +						visible=child.visible,  | 
 | 102 | +						blendmode=blendModeLookup(child.blendMode, blendLookup),  | 
92 | 103 | 					)  | 
93 | 104 | 				)  | 
94 |  | -				layers.pop(index)  | 
95 |  | -				index -= 1  | 
96 |  | -			index += 2  | 
97 |  | -			groupIndex += 1  | 
98 |  | -			groupLayers.append([])  | 
99 |  | -		else:  | 
100 |  | -			index += 1  | 
101 |  | -	# Iterate the clean project layers and add the group layers in  | 
102 |  | -	groupIndex = 0  | 
103 |  | -	layersAndGroups = []  | 
104 |  | -	for layerOrGroup in layers:  | 
105 |  | -		if layerOrGroup.isGroup:  | 
106 |  | -			layersAndGroups.append(  | 
107 |  | -				Group(  | 
108 |  | -					name=layerOrGroup.name,  | 
109 |  | -					layers=groupLayers[groupIndex][::-1],  | 
110 |  | -					dimensions=(layerOrGroup.width, layerOrGroup.height),  | 
111 |  | -					offsets=(layerOrGroup.xOffset, layerOrGroup.yOffset),  | 
112 |  | -					opacity=layerOrGroup.opacity,  | 
113 |  | -					visible=layerOrGroup.visible,  | 
114 |  | -					blendmode=blendModeLookup(layerOrGroup.blendMode, blendLookup),  | 
115 |  | -				)  | 
116 |  | -			)  | 
117 |  | -			groupIndex += 1  | 
118 |  | -		else:  | 
119 |  | -			layersAndGroups.append(  | 
120 |  | -				Layer(  | 
121 |  | -					name=layerOrGroup.name,  | 
122 |  | -					image=layerOrGroup.image,  | 
123 |  | -					dimensions=(layerOrGroup.width, layerOrGroup.height),  | 
124 |  | -					offsets=(layerOrGroup.xOffset, layerOrGroup.yOffset),  | 
125 |  | -					opacity=layerOrGroup.opacity,  | 
126 |  | -					visible=layerOrGroup.visible,  | 
127 |  | -					blendmode=blendModeLookup(layerOrGroup.blendMode, blendLookup),  | 
128 |  | -				)  | 
129 |  | -			)  | 
 | 105 | +		return layers  | 
 | 106 | + | 
 | 107 | +	layersAndGroups = rec_walk(root_group)  | 
130 | 108 | 
 
  | 
131 | 109 | 	return LayeredImage(layersAndGroups, (project.width, project.height))  | 
132 | 110 | 
 
  | 
 | 
0 commit comments