Skip to content

Commit cf95f30

Browse files
authored
Fix export scale precision issues (#1775)
1 parent 336cfe6 commit cf95f30

13 files changed

Lines changed: 60 additions & 56 deletions

src/data_classes/ElementLinearGradient.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func get_percentage_handling(attribute_name: String) -> DB.PercentageHandling:
2020
func generate_texture() -> DPITexture:
2121
var svg_texture_text := """<svg width="64" height="64" xmlns="http://www.w3.org/2000/svg"><linearGradient id="a" """
2222

23-
var scaling := Vector2(64.0, 64.0) / svg.get_size()
23+
var scaling := Vector2(64/svg.width, 64/svg.height)
2424
var is_user_space_on_use := (get_attribute_value("gradientUnits") == "userSpaceOnUse")
2525

2626
for attrib in ["x1", "x2"]:

src/data_classes/ElementRadialGradient.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func get_percentage_handling(attribute_name: String) -> DB.PercentageHandling:
2121
func generate_texture() -> DPITexture:
2222
var svg_texture_text := """<svg width="64" height="64" xmlns="http://www.w3.org/2000/svg"><radialGradient id="a" """
2323

24-
var scaling := Vector2(64.0, 64.0) / svg.get_size()
24+
var scaling := Vector2(64/svg.width, 64/svg.height)
2525
var is_user_space_on_use := (get_attribute_value("gradientUnits") == "userSpaceOnUse")
2626

2727
for attrib in ["cx", "fx"]:

src/data_classes/ElementSVG.gd

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## An <svg> element.
22
class_name ElementSVG extends Element
33

4+
# These are important to keep as 64-bit in some situations.
45
var width: float
56
var height: float
67
var precise_viewbox := PackedFloat64Array([0, 0, 0, 0])
@@ -91,9 +92,6 @@ func world_to_canvas(pos: Vector2) -> Vector2:
9192
func world_to_canvas_64_bit(pos: PackedFloat64Array) -> PackedFloat64Array:
9293
return Utils64Bit.transform_vector_mult(Utils64Bit.get_transform_affine_inverse(canvas_precise_transform), pos)
9394

94-
func get_size() -> Vector2:
95-
return Vector2(width, height)
96-
9795

9896
func _get_own_default(attribute_name: String) -> String:
9997
match attribute_name:

src/ui_parts/export_menu.gd

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ var export_data_resources: Dictionary[String, ImageExportData] = {
1717
"dds": ImageExportDataDDS.new(),
1818
}
1919
var current_format := ""
20-
var dimensions := Vector2.ZERO
20+
var svg_width := 0.0
21+
var svg_height := 0.0
2122

2223
@onready var dimensions_label: Label = %DimensionsLabel
2324
@onready var texture_preview: PreviewRect = %TexturePreview
@@ -47,14 +48,15 @@ func _ready() -> void:
4748
format_dropdown.value_changed.connect(_on_format_dropdown_value_changed)
4849

4950
# Update dimensions label.
50-
dimensions = State.root_element.get_size()
51-
dimensions_label.text = Translator.translate("Dimensions") + ": " + get_dimensions_text(dimensions)
51+
svg_width = State.root_element.width
52+
svg_height = State.root_element.height
53+
dimensions_label.text = Translator.translate("Dimensions") + ": " + get_dimensions_text(svg_width, svg_height)
5254
set_current_format("svg")
5355

5456
# Setup the warning for when the image is too big to have a preview.
55-
var scaling_factor := texture_preview.MAX_IMAGE_DIMENSION / maxf(dimensions.x, dimensions.y)
57+
var scaling_factor := texture_preview.MAX_IMAGE_DIMENSION / maxf(svg_width, svg_height)
5658
info_tooltip.tooltip_text = Translator.translate("Preview image size is limited to {dimensions}").format(
57-
{"dimensions": get_dimensions_text(Vector2(maxf(dimensions.x * scaling_factor, 1.0), maxf(dimensions.y * scaling_factor, 1.0)), true)})
59+
{"dimensions": get_dimensions_text(maxf(svg_width * scaling_factor, 1.0), maxf(svg_height * scaling_factor, 1.0), true)})
5860
info_tooltip.modulate = ThemeUtils.info_icon_color
5961

6062
if Configs.savedata.get_active_tab().svg_file_path.is_empty():
@@ -121,7 +123,7 @@ func set_current_format(new_format: String) -> void:
121123
if is_instance_valid(new_properties_scene_root):
122124
content_container.add_child(new_properties_scene_root)
123125
HandlerGUI.register_focus_sequence(content_container, [new_properties_scene_root])
124-
new_properties_scene_root.setup(get_edited_export_data(), undo_redo, dimensions)
126+
new_properties_scene_root.setup(get_edited_export_data(), undo_redo, svg_width, svg_height)
125127

126128
var file_name := Utils.get_file_name(Configs.savedata.get_active_tab().svg_file_path)
127129
if not file_name.is_empty():
@@ -139,21 +141,21 @@ func _on_edited_export_data_changed() -> void:
139141
var export_size: int
140142
if export_data is ImageExportDataRaster:
141143
texture_preview.setup_image(export_data)
142-
var export_size_factor := roundf(export_data.upscale_amount * maxf(dimensions.x, dimensions.y)) / texture_preview.MAX_IMAGE_DIMENSION
144+
var export_size_factor := roundf(export_data.upscale_amount * maxf(svg_width, svg_height)) / texture_preview.MAX_IMAGE_DIMENSION
143145
# Calculate or estimate size. WebP fares better when scaled.
144146
if not export_data is ImageExportDataWEBP:
145147
export_size_factor **= 2
146148
export_size = roundi(texture_preview.last_image_size * maxf(1.0, export_size_factor))
147149
final_size_label.text = Translator.translate("Size") if export_size_factor <= 1.0 else Translator.translate("Estimated size")
148150
else:
149-
texture_preview.setup_svg(State.get_export_text(), dimensions)
151+
texture_preview.setup_svg(State.get_export_text(), Vector2(svg_width, svg_height))
150152
export_size = State.get_export_text().length()
151153
final_size_label.text = Translator.translate("Size")
152154

153155
final_size_label.text += ": " + String.humanize_size(export_size)
154156
info_tooltip.visible = (export_data is ImageExportDataRaster and\
155-
roundi(export_data.upscale_amount * maxf(dimensions.x, dimensions.y)) > texture_preview.MAX_IMAGE_DIMENSION)
157+
roundi(export_data.upscale_amount * maxf(svg_width, svg_height)) > texture_preview.MAX_IMAGE_DIMENSION)
156158

157-
func get_dimensions_text(sides: Vector2, integer := false) -> String:
159+
func get_dimensions_text(width: float, height: float, integer := false) -> String:
158160
var precision := 0 if integer else 2
159-
return "%s×%s" % [Utils.num_simple(sides.x, precision), Utils.num_simple(sides.y, precision)]
161+
return "%s×%s" % [Utils.num_simple(width, precision), Utils.num_simple(height, precision)]

src/ui_parts/import_warning_menu.gd

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
extends PanelContainer
22

3+
const PreviewRect = preload("res://src/ui_widgets/preview_rect.gd")
4+
35
var import_success := false
46

57
signal imported
68
signal canceled
79

810
@onready var warnings_label: RichTextLabel = %WarningsLabel
9-
@onready var texture_preview: CenterContainer = %TexturePreview
11+
@onready var texture_preview: PreviewRect = %TexturePreview
1012
@onready var ok_button: Button = %ButtonContainer/OKButton
1113
@onready var margin_container: MarginContainer = %MarginContainer
1214
@onready var cancel_button: Button = $VBoxContainer/ButtonContainer/CancelButton
@@ -34,7 +36,7 @@ func _ready() -> void:
3436
var preview_parse_result := SVGParser.markup_to_root(preview_text)
3537
var preview := preview_parse_result.svg
3638
if is_instance_valid(preview):
37-
texture_preview.setup_svg(SVGParser.root_to_editor_markup(preview), preview.get_size())
39+
texture_preview.setup_svg(SVGParser.root_to_editor_markup(preview), Vector2(preview.width, preview.height))
3840

3941
if imported_text_parse_result.error != SVGParser.ParseError.OK:
4042
texture_preview.hide()

src/ui_parts/main_canvas.gd

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ func sync_camera_zoom_in_tab() -> void:
3434
Configs.savedata.get_active_tab().camera_zoom = camera_zoom
3535

3636
func sync_svg_size() -> void:
37-
if _current_svg_size != root_element.get_size():
38-
_current_svg_size = root_element.get_size()
37+
if _current_svg_width != root_element.width or _current_svg_height != root_element.height:
38+
_current_svg_width = root_element.width
39+
_current_svg_width = root_element.height
3940
sync_checkerboard()
4041
center_frame()
4142
queue_redraw()
4243

43-
var _current_svg_size: Vector2
44+
var _current_svg_width: float
45+
var _current_svg_height: float
4446

4547
func react_to_last_parsing() -> void:
4648
if State.last_parse_error == SVGParser.ParseError.OK:
@@ -53,7 +55,8 @@ func _on_svg_changed(is_edit: bool) -> void:
5355
if is_edit:
5456
sync_svg_size()
5557
else:
56-
_current_svg_size = root_element.get_size()
58+
_current_svg_width = root_element.width
59+
_current_svg_height = root_element.height
5760
queue_texture_update()
5861
handles_manager.queue_update_handles()
5962

src/ui_parts/previews.gd

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class IconPreviewTileData extends RefCounted:
4040
func _init(new_index: int) -> void:
4141
index = new_index
4242
bigger_dimension = Configs.savedata.preview_presentation_sizes[index]
43-
var svg_size := State.root_element.get_size()
43+
var svg_size := Vector2(State.root_element.width, State.root_element.height)
4444
var multiplier := bigger_dimension / maxf(svg_size.x, svg_size.y)
4545
svg_size *= multiplier
4646
var font := ThemeUtils.main_font
@@ -281,9 +281,8 @@ func _sync_texture() -> void:
281281
var tile := tiles[selected_tile_index]
282282
size_label.text = tile.dimensions_text + tile.additional_text
283283

284-
var svg_size := State.root_element.get_size()
285-
var multiplier := Configs.savedata.preview_presentation_sizes[selected_tile_index] / maxf(svg_size.x, svg_size.y)
286-
texture_rect.texture = Configs.savedata.preview_presentation.generate_texture(multiplier)
284+
texture_rect.texture = Configs.savedata.preview_presentation.generate_texture(
285+
Configs.savedata.preview_presentation_sizes[selected_tile_index] / maxf(State.root_element.width, State.root_element.height))
287286

288287

289288
func _generate_tile_popup(tile: IconPreviewTileData) -> ContextPopup:

src/ui_widgets/Canvas.gd

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,15 @@ func toggle_show_handles() -> void:
150150
handles_manager.update_show_handles()
151151

152152
func center_frame() -> void:
153-
var available_size := size * ZOOM_RESET_BUFFER
154-
var ratio := available_size / root_element.get_size()
155-
if ratio.is_finite():
156-
camera_zoom = nearest_po2(ceili(minf(ratio.x, ratio.y) * 32.0)) / 64.0
153+
var ratio_x := size.x * ZOOM_RESET_BUFFER / root_element.width
154+
var ratio_y := size.y * ZOOM_RESET_BUFFER / root_element.height
155+
if is_finite(ratio_x) and is_finite(ratio_y):
156+
camera_zoom = nearest_po2(ceili(minf(ratio_x, ratio_y) * 32.0)) / 64.0
157157
else:
158158
camera_zoom = 1.0
159159

160160
adjust_view()
161-
set_view(root_element.get_size() / 2.0)
161+
set_view(Vector2(root_element.width, root_element.height) / 2)
162162

163163
func sync_canvas_transform() -> void:
164164
viewport.canvas_transform = Transform2D(0.0, Vector2(camera_zoom, camera_zoom), 0.0, -get_camera_position() * camera_zoom)
@@ -212,9 +212,8 @@ func _texture_update() -> void:
212212

213213

214214
func sync_checkerboard() -> void:
215-
var root_element_size := root_element.get_size()
216-
if root_element_size.is_finite():
217-
checkerboard.size = root_element_size
215+
if is_finite(root_element.width) and is_finite(root_element.height):
216+
checkerboard.size = Vector2(root_element.width, root_element.height)
218217

219218

220219
func update_show_grid() -> void:

src/ui_widgets/export_properties_jpg.gd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func _ready() -> void:
1818
background_label.text = Translator.translate("Background") + ":"
1919
HandlerGUI.register_focus_sequence(self, [quality_edit, background_edit, export_scale_config])
2020

21-
func setup(new_export_data_object: ImageExportDataJPG, new_undo_redo: UndoRedoRef, dimensions: Vector2) -> void:
21+
func setup(new_export_data_object: ImageExportDataJPG, new_undo_redo: UndoRedoRef, new_width: float, new_height: float) -> void:
2222
export_data_object = new_export_data_object
2323
undo_redo = new_undo_redo
2424

@@ -46,7 +46,7 @@ func setup(new_export_data_object: ImageExportDataJPG, new_undo_redo: UndoRedoRe
4646
export_data_object.background_color = new_background_color
4747
)
4848

49-
export_scale_config.setup(dimensions, export_data_object.upscale_amount)
49+
export_scale_config.setup(new_width, new_height, export_data_object.upscale_amount)
5050
export_scale_config.scale_changed.connect(
5151
func(new_value: float) -> void:
5252
undo_redo.create_action()

src/ui_widgets/export_properties_raster_lossless.gd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func _ready() -> void:
1414
background_label.text = Translator.translate("Background") + ":"
1515
HandlerGUI.register_focus_sequence(self, [background_edit, export_scale_config])
1616

17-
func setup(new_export_data_object: ImageExportDataRaster, new_undo_redo: UndoRedoRef, dimensions: Vector2) -> void:
17+
func setup(new_export_data_object: ImageExportDataRaster, new_undo_redo: UndoRedoRef, new_width: float, new_height: float) -> void:
1818
export_data_object = new_export_data_object
1919
undo_redo = new_undo_redo
2020

@@ -31,7 +31,7 @@ func setup(new_export_data_object: ImageExportDataRaster, new_undo_redo: UndoRed
3131
export_data_object.background_color = new_background_color
3232
)
3333

34-
export_scale_config.setup(dimensions, export_data_object.upscale_amount)
34+
export_scale_config.setup(new_width, new_height, export_data_object.upscale_amount)
3535
# The actual limit is ~2 million pixels, but that doesn't seem relevant.
3636
if export_data_object is ImageExportDataPNG:
3737
export_scale_config.max_dimension = 65535

0 commit comments

Comments
 (0)