godot-xterm/addons/godot_xterm/renderer/renderer.gd

119 lines
3.4 KiB
GDScript3
Raw Normal View History

2020-05-10 12:56:49 +02:00
# Copyright (c) 2017 The xterm.js authors. All rights reserved.
# Ported to GDScript by the GodotXterm authors.
# License MIT
extends Reference
const CharacterJoinerRegistry = preload("res://addons/godot_xterm/renderer/character_joiner_registry.gd")
const TextRenderLayer = preload("res://addons/godot_xterm/renderer/text_render_layer.gd")
signal redraw_requested
signal options_changed
signal grid_changed(start, end)
var _id: int
var _render_layers: Array
var _device_pixel_ratio: float
var _character_joiner_registry
var _colors
var _container
var _buffer_service
var _options_service
var _char_size_service
var dimensions
func _init(colors, container: Node, buffer_service, options_service):
_id = get_instance_id()
_colors = colors
_container = container
_buffer_service = buffer_service
_options_service = options_service
var allow_transparency = _options_service.options.allow_transparency
_character_joiner_registry = CharacterJoinerRegistry.new(_buffer_service)
_render_layers = [
TextRenderLayer.new(_container, 0, _colors, _character_joiner_registry,
allow_transparency, _id, _buffer_service, _options_service)
]
# Connect render layers to our signals.
for layer in _render_layers:
self.connect("options_changed", layer, "on_options_changed")
self.connect("grid_changed", layer, "on_grid_changed")
dimensions = {
"scaled_char_width": 0,
"scaled_char_height": 0,
"scaled_cell_width": 0,
"scaled_cell_height": 0,
"scaled_char_left": 0,
"scaled_char_top": 0,
"scaled_canvas_width": 0,
"scaled_canvas_height": 0,
"canvas_width": 0,
"canvas_height": 0,
"actual_cell_width": 0,
"actual_cell_height": 0,
}
_device_pixel_ratio = OS.get_screen_dpi()
_update_dimensions()
emit_signal("options_changed")
func on_resize(cols, rows):
# Update character and canvas dimensions
_update_dimensions()
# Resize all render layers
for layer in _render_layers:
layer.resize(dimensions)
func refresh_rows(start: int, end: int) -> void:
emit_signal("grid_changed", start, end)
# Recalculates the character and canvas dimensions.
func _update_dimensions():
var char_width = 0
var char_height = 0
for font in _options_service.options.font_family.values():
var size = font.get_string_size("W")
char_width = max(char_width, size.x)
char_height = max(char_height, size.y)
dimensions.scaled_char_width = char_width
dimensions.scaled_char_height = char_height
# Calculate the scaled cell height, if line_height is not 1 then the value
# will be floored because since line_height can never be lower then 1, there
# is a guarantee that the scaled line height will always be larger than
# scaled char height.
dimensions.scaled_cell_height = floor(dimensions.scaled_char_height * _options_service.options.line_height)
# Calculate the y coordinate within a cell that text should draw from in
# order to draw in the center of a cell.
dimensions.scaled_char_top = 0 if _options_service.options.line_height == 1 else \
round((dimensions.scaled_cell_height - dimensions.scaled_char_height) / 2)
# Calculate the scaled cell width, taking the letter_spacing into account.
dimensions.scaled_cell_width = dimensions.scaled_char_width + round(_options_service.options.letter_spacing)
# Calculate the x coordinate with a cell that text should draw from in
# order to draw in the center of a cell.
dimensions.scaled_char_left = floor(_options_service.options.letter_spacing / 2)