#14,#15,#29,#31: Added qr, added more settings, added keymap, changed about page.
Build / build (push) Successful in 1m10s
Build / build (push) Successful in 1m10s
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
Copyright 2022-present Iceflower S (iceflower@gmx.de)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,75 @@
|
||||
extends RefCounted
|
||||
|
||||
var _data: PackedByteArray = []
|
||||
|
||||
func duplicate():
|
||||
var dup = new()
|
||||
dup._data = self._data.duplicate()
|
||||
return dup
|
||||
|
||||
func resize(size: int) -> void:
|
||||
self._data.resize(size)
|
||||
|
||||
func size() -> int:
|
||||
return self._data.size()
|
||||
|
||||
func clear() -> void:
|
||||
return self._data.clear()
|
||||
|
||||
func get_array() -> PackedByteArray:
|
||||
return self._data
|
||||
|
||||
func to_byte_array() -> PackedByteArray:
|
||||
var byte_arr: PackedByteArray = []
|
||||
|
||||
var cur_byte: int = 0
|
||||
for idx: int in range(self._data.size()):
|
||||
var byte_idx: int = 7 - idx & 7
|
||||
if self._data[idx]:
|
||||
cur_byte |= (1 << byte_idx)
|
||||
if (idx != 0 && byte_idx == 0) || idx == self._data.size() - 1:
|
||||
byte_arr.append(cur_byte)
|
||||
cur_byte = 0
|
||||
return byte_arr
|
||||
|
||||
func prepend_bit(bit: bool) -> void:
|
||||
self._data.insert(0, int(bit))
|
||||
|
||||
func append_bit(bit: bool) -> void:
|
||||
self._data.append(int(bit))
|
||||
|
||||
func append_stream(stream) -> void:
|
||||
self._data.append_array(stream.get_array())
|
||||
|
||||
func append_byte_array(arr: PackedByteArray) -> void:
|
||||
for val: int in arr:
|
||||
self.append(val, 8)
|
||||
|
||||
func prepend(value: int, total_bits: int) -> void:
|
||||
for idx: int in range(total_bits - 1, -1, -1):
|
||||
self._data.insert(0, int((value & (1 << idx)) != 0))
|
||||
|
||||
func append(value: int, total_bits: int) -> void:
|
||||
for idx: int in range(total_bits - 1, -1, -1):
|
||||
self._data.append(int((value & (1 << idx)) != 0))
|
||||
|
||||
func set_bit(idx: int, bit: bool) -> void:
|
||||
self._data[idx] = int(bit)
|
||||
|
||||
func get_bit(idx: int) -> bool:
|
||||
return bool(self._data[idx])
|
||||
|
||||
func _to_string() -> String:
|
||||
var val: String = ""
|
||||
for idx: int in range(self._data.size()):
|
||||
if (idx + 1) & 7 == 1:
|
||||
val += "["
|
||||
val += str(self._data[idx])
|
||||
if (idx + 1) & 7 == 0:
|
||||
val += "]"
|
||||
if (idx + 1) & 3 == 0:
|
||||
val += " "
|
||||
val = val.strip_edges()
|
||||
if val[-1] != "]":
|
||||
val += "]"
|
||||
return val
|
||||
@@ -0,0 +1 @@
|
||||
uid://dyt1tls86b518
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
version="1.1"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<defs
|
||||
id="defs4" />
|
||||
<path
|
||||
id="rect4"
|
||||
style="fill:#8eef97;fill-opacity:1;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="M 0,0 V 6 H 6 V 0 Z M 1,1 H 5 V 5 H 1 Z" />
|
||||
<path
|
||||
id="rect4-4-4"
|
||||
style="fill:#8eef97;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
transform="rotate(90)"
|
||||
d="m 2,-4 h 2 v 2 H 2 Z" />
|
||||
<path
|
||||
id="rect4-9"
|
||||
style="fill:#8eef97;fill-opacity:1;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="m 10,0 v 6 h 6 V 0 Z m 1,1 h 4 v 4 h -4 z" />
|
||||
<path
|
||||
id="rect4-4-4-7"
|
||||
style="fill:#8eef97;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
transform="rotate(90)"
|
||||
d="m 2,-14 h 2 v 2 H 2 Z" />
|
||||
<path
|
||||
id="rect4-90"
|
||||
style="fill:#8eef97;fill-opacity:1;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="m 0,10 v 6 h 6 v -6 z m 1,1 h 4 v 4 H 1 Z" />
|
||||
<path
|
||||
id="rect4-4-4-8"
|
||||
style="fill:#8eef97;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
transform="rotate(90)"
|
||||
d="m 12,-4 h 2 v 2 h -2 z" />
|
||||
<path
|
||||
id="rect5"
|
||||
style="fill:#8eef97;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="m 10,12 h 2 v 2 h -2 z" />
|
||||
<path
|
||||
id="rect5-31"
|
||||
style="fill:#8eef97;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="m 14,8 h 2 v 2 h -2 z" />
|
||||
<path
|
||||
id="rect5-3"
|
||||
style="fill:#8eef97;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="m 8,14 h 2 v 2 H 8 Z" />
|
||||
<path
|
||||
id="rect5-0"
|
||||
style="fill:#8eef97;fill-opacity:1;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="m 14,12 v 2 h -2 v 2 h 4 v -4 z" />
|
||||
<path
|
||||
id="rect5-0-2-7"
|
||||
style="fill:#8eef97;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="m 12,10 h 2 v 2 h -2 z" />
|
||||
<path
|
||||
id="rect5-5"
|
||||
style="fill:#8eef97;fill-opacity:1;fill-rule:evenodd;stroke-width:32;paint-order:fill markers stroke"
|
||||
d="m 8,8 v 4 h 2 v -2 h 2 V 8 Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,43 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cn383mw8drmm5"
|
||||
path="res://.godot/imported/icon.svg-f2b8283af99fea807d6be2c96605b944.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/kenyoni/qr_code/icon.svg"
|
||||
dest_files=["res://.godot/imported/icon.svg-f2b8283af99fea807d6be2c96605b944.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
@@ -0,0 +1,20 @@
|
||||
[plugin]
|
||||
|
||||
name="QR Code"
|
||||
description="QR Code generator."
|
||||
author="Kenyoni Software"
|
||||
version="2.0.0"
|
||||
script="plugin.gd"
|
||||
license="MIT"
|
||||
repository="https://github.com/kenyoni-software/godot-addons"
|
||||
keywords=[
|
||||
"node",
|
||||
"tool"
|
||||
]
|
||||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"License :: OSI Approved :: MIT License"
|
||||
]
|
||||
|
||||
[plugin.dependencies]
|
||||
godot=">=4.4"
|
||||
@@ -0,0 +1,10 @@
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
const QrCodeRect := preload("res://addons/kenyoni/qr_code/qr_code_rect.gd")
|
||||
|
||||
func _enter_tree() -> void:
|
||||
self.add_custom_type("QRCodeRect", "TextureRect", QrCodeRect, preload("res://addons/kenyoni/qr_code/icon.svg"))
|
||||
|
||||
func _exit_tree() -> void:
|
||||
self.remove_custom_type("QRCodeRect")
|
||||
@@ -0,0 +1 @@
|
||||
uid://bepdve2jn8q0i
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
uid://c7aw4f3o7g8sc
|
||||
@@ -0,0 +1,415 @@
|
||||
@tool
|
||||
@icon("res://addons/kenyoni/qr_code/icon.svg")
|
||||
extends TextureRect
|
||||
class_name QRCodeRect
|
||||
|
||||
const QRCode := preload("res://addons/kenyoni/qr_code/qr_code.gd")
|
||||
const ShiftJIS := preload("res://addons/kenyoni/qr_code/shift_jis.gd")
|
||||
|
||||
var mode: QRCode.Mode:
|
||||
set = set_mode,
|
||||
get = get_mode
|
||||
var error_correction: QRCode.ErrorCorrection:
|
||||
set = set_error_correction,
|
||||
get = get_error_correction
|
||||
## Use Extended Channel Interpretation (ECI).
|
||||
var use_eci: bool:
|
||||
set = set_use_eci,
|
||||
get = get_use_eci
|
||||
## Extended Channel Interpretation (ECI) Value.
|
||||
var eci_value: int:
|
||||
set = set_eci_value,
|
||||
get = get_eci_value
|
||||
var data: Variant = "":
|
||||
set = set_data,
|
||||
get = get_data
|
||||
## Automatically update the QR Code when a property changes.
|
||||
var auto_update: bool = true:
|
||||
set = set_auto_update
|
||||
## Use automatically the smallest version possible.
|
||||
var auto_version: bool = true:
|
||||
set = set_auto_version,
|
||||
get = get_auto_version
|
||||
var version: int = 1:
|
||||
set = set_version,
|
||||
get = get_version
|
||||
## Use automatically the best mask pattern.
|
||||
var auto_mask_pattern: bool = true:
|
||||
set = set_auto_mask_pattern,
|
||||
get = get_auto_mask_pattern
|
||||
## Used mask pattern.
|
||||
var mask_pattern: int = 0:
|
||||
set = set_mask_pattern,
|
||||
get = get_mask_pattern
|
||||
var light_module_color: Color = Color.WHITE:
|
||||
set = set_light_module_color
|
||||
var dark_module_color: Color = Color.BLACK:
|
||||
set = set_dark_module_color
|
||||
## Automatically set the module pixel size based on the size.
|
||||
## Do not use expand mode KEEP_SIZE when using it.
|
||||
## Turn this off when the QR Code is resized often, as it impacts the performance quite heavily.
|
||||
var auto_module_size: bool = true:
|
||||
set = set_auto_module_size
|
||||
## Use that many pixel for one module.
|
||||
## If auto_module_size is set, this value might by only occasionally updated. In this case do not rely on it.
|
||||
var module_size: int = 1:
|
||||
set = set_module_size
|
||||
## Use that many modules for the quiet zone. A value of 4 is recommended.
|
||||
var quiet_zone_size: int = 4:
|
||||
set = set_quiet_zone_size
|
||||
|
||||
var _qr: QRCode = QRCode.new()
|
||||
var _update_fn: Callable = self.update
|
||||
var _cached_data: PackedByteArray = PackedByteArray()
|
||||
|
||||
func set_mode(new_mode: QRCode.Mode) -> void:
|
||||
self._qr.mode = new_mode
|
||||
self.notify_property_list_changed()
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_mode() -> QRCode.Mode:
|
||||
return self._qr.mode
|
||||
|
||||
func set_error_correction(new_error_correction: QRCode.ErrorCorrection) -> void:
|
||||
self._qr.error_correction = new_error_correction
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_error_correction() -> QRCode.ErrorCorrection:
|
||||
return self._qr.error_correction
|
||||
|
||||
func set_use_eci(new_use_eci: bool) -> void:
|
||||
self._qr.use_eci = new_use_eci
|
||||
self.notify_property_list_changed()
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_use_eci() -> bool:
|
||||
return self._qr.use_eci
|
||||
|
||||
func set_eci_value(new_eci_value: int) -> void:
|
||||
if self._qr.eci_value == new_eci_value:
|
||||
return
|
||||
self._qr.eci_value = new_eci_value
|
||||
self.notify_property_list_changed()
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_eci_value() -> int:
|
||||
return self._qr.eci_value
|
||||
|
||||
func set_data(new_data: Variant) -> void:
|
||||
match self._qr.mode:
|
||||
QRCode.Mode.NUMERIC:
|
||||
self._qr.put_numeric(new_data)
|
||||
QRCode.Mode.ALPHANUMERIC:
|
||||
self._qr.put_alphanumeric(new_data)
|
||||
QRCode.Mode.BYTE:
|
||||
if typeof(new_data) == TYPE_PACKED_BYTE_ARRAY || ! self.use_eci:
|
||||
self._qr.put_byte(new_data)
|
||||
return
|
||||
match self.eci_value:
|
||||
QRCode.ECI.ISO_8859_1:
|
||||
self._qr.put_byte(new_data.to_ascii_buffer())
|
||||
QRCode.ECI.SHIFT_JIS:
|
||||
self._qr.put_byte(ShiftJIS.to_shift_jis_2004_buffer(new_data))
|
||||
QRCode.ECI.UTF_8:
|
||||
self._qr.put_byte(new_data.to_utf8_buffer())
|
||||
QRCode.ECI.UTF_16:
|
||||
self._qr.put_byte(new_data.to_utf16_buffer())
|
||||
QRCode.ECI.US_ASCII:
|
||||
self._qr.put_byte(new_data.to_ascii_buffer())
|
||||
_:
|
||||
self._qr.put_byte(new_data)
|
||||
QRCode.Mode.KANJI:
|
||||
self._qr.put_kanji(new_data)
|
||||
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_data() -> Variant:
|
||||
var input_data: Variant = self._qr.get_input_data()
|
||||
if self.mode == QRCode.Mode.BYTE && self.use_eci:
|
||||
match self.eci_value:
|
||||
QRCode.ECI.ISO_8859_1:
|
||||
return input_data.get_string_from_ascii()
|
||||
QRCode.ECI.SHIFT_JIS:
|
||||
return ShiftJIS.get_string_from_shift_jis_2004(input_data)
|
||||
QRCode.ECI.UTF_8:
|
||||
return input_data.get_string_from_utf8()
|
||||
QRCode.ECI.UTF_16:
|
||||
return input_data.get_string_from_utf16()
|
||||
QRCode.ECI.US_ASCII:
|
||||
return input_data.get_string_from_ascii()
|
||||
|
||||
return self._qr.get_input_data()
|
||||
|
||||
func set_auto_update(new_auto_update: bool) -> void:
|
||||
if auto_update == new_auto_update:
|
||||
return
|
||||
auto_update = new_auto_update
|
||||
self.notify_property_list_changed()
|
||||
if auto_update:
|
||||
self.update()
|
||||
|
||||
func set_auto_version(new_auto_version: bool) -> void:
|
||||
if self._qr.auto_version == new_auto_version:
|
||||
return
|
||||
self._qr.auto_version = new_auto_version
|
||||
self.notify_property_list_changed()
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_auto_version() -> bool:
|
||||
return self._qr.auto_version
|
||||
|
||||
func set_version(new_version: int) -> void:
|
||||
if self.auto_version || self._qr.version == new_version:
|
||||
return
|
||||
self._qr.version = new_version
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_version() -> int:
|
||||
return self._qr.version
|
||||
|
||||
func set_auto_mask_pattern(new_auto_mask_pattern: bool) -> void:
|
||||
if self._qr.auto_mask_pattern == new_auto_mask_pattern:
|
||||
return
|
||||
self._qr.auto_mask_pattern = new_auto_mask_pattern
|
||||
self.notify_property_list_changed()
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_auto_mask_pattern() -> bool:
|
||||
return self._qr.auto_mask_pattern
|
||||
|
||||
func set_mask_pattern(new_mask_pattern: int) -> void:
|
||||
if self.auto_mask_pattern || self._qr.mask_pattern == new_mask_pattern:
|
||||
return
|
||||
self._qr.mask_pattern = new_mask_pattern
|
||||
if self.auto_update:
|
||||
self.update()
|
||||
|
||||
func get_mask_pattern() -> int:
|
||||
return self._qr.mask_pattern
|
||||
|
||||
func set_light_module_color(new_light_module_color: Color) -> void:
|
||||
if light_module_color == new_light_module_color:
|
||||
return
|
||||
light_module_color = new_light_module_color
|
||||
if self.auto_update:
|
||||
self._update_texture()
|
||||
|
||||
func set_dark_module_color(new_dark_module_color: Color) -> void:
|
||||
if dark_module_color == new_dark_module_color:
|
||||
return
|
||||
dark_module_color = new_dark_module_color
|
||||
if self.auto_update:
|
||||
self._update_texture()
|
||||
|
||||
func set_auto_module_size(new_auto_module_size: bool) -> void:
|
||||
if auto_module_size == new_auto_module_size:
|
||||
return
|
||||
auto_module_size = new_auto_module_size
|
||||
self.notify_property_list_changed()
|
||||
self.update_configuration_warnings()
|
||||
if self.auto_update:
|
||||
self._update_texture()
|
||||
|
||||
func set_module_size(new_module_size: int) -> void:
|
||||
if module_size == new_module_size:
|
||||
return
|
||||
module_size = new_module_size
|
||||
# if not auto it was set directly
|
||||
if ! self.auto_module_size && self.auto_update:
|
||||
self._update_texture()
|
||||
|
||||
func set_quiet_zone_size(new_quiet_zone_size: int) -> void:
|
||||
if quiet_zone_size == new_quiet_zone_size:
|
||||
return
|
||||
quiet_zone_size = maxi(0, new_quiet_zone_size)
|
||||
if self.auto_module_size && self.auto_update:
|
||||
self._update_texture()
|
||||
elif self.auto_module_size:
|
||||
self._update_module_size()
|
||||
|
||||
func _ready() -> void:
|
||||
if self.texture != null && self.auto_update:
|
||||
self.update()
|
||||
|
||||
func update() -> void:
|
||||
self._cached_data = self._qr.encode()
|
||||
self._update_texture()
|
||||
|
||||
func _set(property: StringName, value: Variant) -> bool:
|
||||
if property == "expand_mode":
|
||||
self.update_configuration_warnings()
|
||||
|
||||
return false
|
||||
|
||||
func _get_property_list() -> Array[Dictionary]:
|
||||
var data_prop: Dictionary = {
|
||||
"name": "data",
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
}
|
||||
match self.mode:
|
||||
QRCode.Mode.NUMERIC:
|
||||
data_prop["type"] = TYPE_STRING
|
||||
QRCode.Mode.ALPHANUMERIC, QRCode.Mode.KANJI:
|
||||
data_prop["type"] = TYPE_STRING
|
||||
data_prop["hint"] = PROPERTY_HINT_MULTILINE_TEXT
|
||||
QRCode.Mode.BYTE:
|
||||
# these encoding is natively supported
|
||||
if self.use_eci && self.eci_value in [QRCode.ECI.ISO_8859_1, QRCode.ECI.SHIFT_JIS, QRCode.ECI.UTF_8, QRCode.ECI.UTF_16, QRCode.ECI.US_ASCII]:
|
||||
data_prop["type"] = TYPE_STRING
|
||||
data_prop["hint"] = PROPERTY_HINT_MULTILINE_TEXT
|
||||
else:
|
||||
data_prop["type"] = TYPE_PACKED_BYTE_ARRAY
|
||||
|
||||
return [
|
||||
{
|
||||
"name": "_update_fn",
|
||||
"type": TYPE_CALLABLE,
|
||||
"usage": PROPERTY_USAGE_NONE if self.auto_update else PROPERTY_USAGE_EDITOR,
|
||||
"hint": PROPERTY_HINT_TOOL_BUTTON,
|
||||
"hint_string": "Update"
|
||||
},
|
||||
{
|
||||
"name": "auto_update",
|
||||
"type": TYPE_BOOL,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
},
|
||||
{
|
||||
"name": "mode",
|
||||
"type": TYPE_INT,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
"hint": PROPERTY_HINT_ENUM,
|
||||
"hint_string": "Numeric:1,Alphanumeric:2,Byte:4,Kanji:8"
|
||||
},
|
||||
{
|
||||
"name": "error_correction",
|
||||
"type": TYPE_INT,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
"hint": PROPERTY_HINT_ENUM,
|
||||
"hint_string": "Low:1,Medium:0,Quartile:3,High:2"
|
||||
},
|
||||
{
|
||||
"name": "use_eci",
|
||||
"type": TYPE_BOOL,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
},
|
||||
{
|
||||
"name": "eci_value",
|
||||
"type": TYPE_INT,
|
||||
"usage": (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE) if self.use_eci else (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY),
|
||||
"hint": PROPERTY_HINT_ENUM,
|
||||
"hint_string": "Code Page 437:2,ISO 8859-1:3,ISO 8859-2:4,ISO 8859-3:5,ISO 8859-4:6,ISO 8859-5:7,ISO 8859-6:8,ISO 8859-7:9,ISO 8859-8:10,ISO 8859-9:11,ISO 8859-10:12,ISO 8859-11:13,ISO 8859-12:14,ISO 8859-13:15,ISO 8859-14:16,ISO 8859-15:17,ISO 8859-16:18,Shift JIS:20,Windows 1250:21,Windows 1251:22,Windows 1252:23,Windows 1256:24,UTF-16:25,UTF-8:26,US ASCII:27,BIG 5:28,GB 18030:29,EUC KR:30"
|
||||
},
|
||||
data_prop,
|
||||
{
|
||||
"name": "auto_version",
|
||||
"type": TYPE_BOOL,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
},
|
||||
{
|
||||
"name": "version",
|
||||
"type": TYPE_INT,
|
||||
"usage": (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY) if self.auto_version else (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE),
|
||||
"hint": PROPERTY_HINT_RANGE,
|
||||
"hint_string": "1,40"
|
||||
},
|
||||
{
|
||||
"name": "auto_mask_pattern",
|
||||
"type": TYPE_BOOL,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
},
|
||||
{
|
||||
"name": "mask_pattern",
|
||||
"type": TYPE_INT,
|
||||
"usage": (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY) if self.auto_mask_pattern else (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE),
|
||||
"hint": PROPERTY_HINT_RANGE,
|
||||
"hint_string": "0,7"
|
||||
},
|
||||
{
|
||||
"name": "Appearance",
|
||||
"type": TYPE_NIL,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_GROUP,
|
||||
},
|
||||
{
|
||||
"name": "light_module_color",
|
||||
"type": TYPE_COLOR,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
},
|
||||
{
|
||||
"name": "dark_module_color",
|
||||
"type": TYPE_COLOR,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
},
|
||||
{
|
||||
"name": "auto_module_size",
|
||||
"type": TYPE_BOOL,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
},
|
||||
{
|
||||
"name": "module_size",
|
||||
"type": TYPE_INT,
|
||||
"usage": (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY) if self.auto_module_size else (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE),
|
||||
"hint": PROPERTY_HINT_RANGE,
|
||||
"hint_string": "1,1,or_greater"
|
||||
},
|
||||
{
|
||||
"name": "quiet_zone_size",
|
||||
"type": TYPE_INT,
|
||||
"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE,
|
||||
"hint_string": "0,1,or_greater",
|
||||
},
|
||||
]
|
||||
|
||||
func _validate_property(property: Dictionary) -> void:
|
||||
if property.name == "texture":
|
||||
property.usage &= ~(PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE)
|
||||
|
||||
func _property_can_revert(property: StringName) -> bool:
|
||||
return property in ["eci_value", "auto_version", "auto_mask_pattern", "light_module_color", "dark_module_color", "auto_module_size", "quiet_zone_size"]
|
||||
|
||||
func _property_get_revert(property: StringName) -> Variant:
|
||||
match property:
|
||||
"eci_value":
|
||||
return QRCode.ECI.ISO_8859_1
|
||||
"auto_version":
|
||||
return true
|
||||
"auto_mask_pattern":
|
||||
return true
|
||||
"light_module_color":
|
||||
return Color.WHITE
|
||||
"dark_module_color":
|
||||
return Color.BLACK
|
||||
"auto_module_size":
|
||||
return true
|
||||
"quiet_zone_size":
|
||||
return 4
|
||||
_:
|
||||
return null
|
||||
|
||||
func _get_configuration_warnings() -> PackedStringArray:
|
||||
if self.auto_module_size && self.expand_mode == EXPAND_KEEP_SIZE:
|
||||
return ["Do not use auto module px size AND keep size expand mode."]
|
||||
return []
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
match what:
|
||||
NOTIFICATION_RESIZED:
|
||||
if self.auto_module_size && self.auto_update:
|
||||
self._update_texture()
|
||||
elif self.auto_module_size:
|
||||
self._update_module_size()
|
||||
|
||||
func _update_module_size() -> void:
|
||||
self.module_size = mini(self.size.x, self.size.y) / (self._qr.get_dimension() + 2 * self.quiet_zone_size)
|
||||
|
||||
func _update_texture() -> void:
|
||||
if self.auto_module_size:
|
||||
self._update_module_size()
|
||||
self.texture = ImageTexture.create_from_image(QRCode.generate_image(self._cached_data, self.module_size, self.light_module_color, self.dark_module_color, self.quiet_zone_size))
|
||||
@@ -0,0 +1 @@
|
||||
uid://dynulhnyq5hpq
|
||||
@@ -0,0 +1,76 @@
|
||||
# log -> exponent/antilog
|
||||
static var _anti_log_table: PackedByteArray = []
|
||||
# exponent/antilog -> log
|
||||
static var _log_table: PackedByteArray = []
|
||||
|
||||
static func _static_init() -> void:
|
||||
_create_log_anti_log_tables()
|
||||
|
||||
static func _anti_log(degree: int) -> int:
|
||||
var res: int = 1
|
||||
var alpha: int = 2
|
||||
|
||||
while degree != 0:
|
||||
if degree & 1 == 1:
|
||||
res = mul(res, alpha)
|
||||
degree = degree >> 1
|
||||
alpha = mul(alpha, alpha)
|
||||
|
||||
return res
|
||||
|
||||
static func _create_log_anti_log_tables() -> void:
|
||||
_anti_log_table.resize(256)
|
||||
_anti_log_table.fill(0)
|
||||
_log_table.resize(256)
|
||||
_log_table.fill(0)
|
||||
for degree: int in range(0, 256):
|
||||
var value: int = _anti_log(degree)
|
||||
_anti_log_table[degree] = value
|
||||
_log_table[value] = degree % 255
|
||||
|
||||
# Russian Peasant Multiplication algorithm, adapted to reed solomon
|
||||
static func mul(lhs: int, rhs: int) -> int:
|
||||
var res: int = 0
|
||||
while rhs > 0:
|
||||
if rhs & 1:
|
||||
res = res ^ lhs
|
||||
lhs = lhs << 1 # lhs * 2
|
||||
rhs = rhs >> 1 # rhs / 2
|
||||
if lhs & 256:
|
||||
lhs = lhs ^ 0x11D
|
||||
return res
|
||||
|
||||
static func generator_polynom(size: int) -> PackedByteArray:
|
||||
var res: PackedByteArray = []
|
||||
res.resize(size + 1)
|
||||
res.fill(0)
|
||||
res[0] = 1
|
||||
|
||||
var a_j: int = 1
|
||||
for exp: int in range(0, size):
|
||||
var cur_val: int = a_j
|
||||
for cur_exp: int in range(1, exp + 1):
|
||||
var old_res: int = res[cur_exp]
|
||||
res[cur_exp] = cur_val ^ old_res
|
||||
cur_val = mul(old_res, a_j)
|
||||
res[exp + 1] = cur_val
|
||||
|
||||
a_j = mul(a_j, 0x02)
|
||||
return res
|
||||
|
||||
static func encode(data: PackedByteArray, code_words: int) -> PackedByteArray:
|
||||
assert(len(data) + code_words <= 255, "message to encode is to long")
|
||||
var gen_poly: PackedByteArray = generator_polynom(code_words)
|
||||
var enc_msg: PackedByteArray = []
|
||||
enc_msg.resize(len(data) + len(gen_poly) - 1)
|
||||
enc_msg.fill(0)
|
||||
|
||||
for idx: int in range(len(data)):
|
||||
enc_msg[idx] = data[idx]
|
||||
|
||||
for idx: int in range(len(data)):
|
||||
var coef: int = enc_msg[idx]
|
||||
for p_idx: int in range(1, len(gen_poly)):
|
||||
enc_msg[idx+p_idx] ^= mul(gen_poly[p_idx], coef)
|
||||
|
||||
return enc_msg.slice(len(data))
|
||||
@@ -0,0 +1 @@
|
||||
uid://g8jskaqqsmlg
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
uid://8yd22fd2gbxt
|
||||
Reference in New Issue
Block a user