Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement font attributes #299

Merged
merged 12 commits into from
Jun 28, 2023
1 change: 1 addition & 0 deletions rbx_binary/src/tests/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ binary_tests! {
text_label_with_font,
gui_inset_and_font_migration,
folder_with_cframe_attributes,
folder_with_font_attribute,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
source: rbx_binary/src/tests/util.rs
expression: decoded_viewed
---
- referent: referent-0
name: Folder
class: Folder
properties:
Attributes:
Attributes:
AFontAttribute:
Font:
family: "rbxasset://fonts/families/Creepster.json"
weight: Regular
style: Normal
cachedFaceId: ~
SourceAssetId:
Int64: -1
Tags:
Tags: []
children: []

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
source: rbx_binary/src/tests/util.rs
expression: text_roundtrip
---
num_types: 1
num_instances: 1
chunks:
- Inst:
type_id: 0
type_name: Folder
object_format: 0
referents:
- 0
- Prop:
type_id: 0
prop_name: AttributesSerialize
prop_type: String
values:
- 01 00 00 00 0e 00 00 00 41 46 6f 6e 74 41 74 74 72 69 62 75 74 65 21 90 01 00 28 00 00 00 72 62 78 61 73 73 65 74 3a 2f 2f 66 6f 6e 74 73 2f 66 61 6d 69 6c 69 65 73 2f 43 72 65 65 70 73 74 65 72 2e 6a 73 6f 6e 00 00 00 00
- Prop:
type_id: 0
prop_name: Name
prop_type: String
values:
- Folder
- Prop:
type_id: 0
prop_name: SourceAssetId
prop_type: Int64
values:
- -1
- Prop:
type_id: 0
prop_name: Tags
prop_type: String
values:
- ""
- Prnt:
version: 0
links:
- - 0
- -1
- End

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
source: rbx_binary/src/tests/util.rs
expression: text_decoded
---
num_types: 1
num_instances: 1
chunks:
- Meta:
entries:
- - ExplicitAutoJoints
- "true"
- Inst:
type_id: 0
type_name: Folder
object_format: 0
referents:
- 0
- Prop:
type_id: 0
prop_name: AttributesSerialize
prop_type: String
values:
- 01 00 00 00 0e 00 00 00 41 46 6f 6e 74 41 74 74 72 69 62 75 74 65 21 90 01 00 28 00 00 00 72 62 78 61 73 73 65 74 3a 2f 2f 66 6f 6e 74 73 2f 66 61 6d 69 6c 69 65 73 2f 43 72 65 65 70 73 74 65 72 2e 6a 73 6f 6e 00 00 00 00
- Prop:
type_id: 0
prop_name: Name
prop_type: String
values:
- Folder
- Prop:
type_id: 0
prop_name: SourceAssetId
prop_type: Int64
values:
- -1
- Prop:
type_id: 0
prop_name: Tags
prop_type: String
values:
- ""
- Prnt:
version: 0
links:
- - 0
- -1
- End

2 changes: 2 additions & 0 deletions rbx_types/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
* Changed `BinaryString`'s non-human readable serde implementation to be identical to `Vec<u8>`. ([#276])
* Added `Font::new` and `Font::regular` constructors. ([#283])
* Added support for `CFrame` values in attributes. ([#296])
* Added support for `Font` values in attributes. ([#299])

[#271]: https://github.com/rojo-rbx/rbx-dom/pull/271
[#276]: https://github.com/rojo-rbx/rbx-dom/pull/276
[#283]: https://github.com/rojo-rbx/rbx-dom/pull/283
[#296]: https://github.com/rojo-rbx/rbx-dom/pull/296
[#299]: https://github.com/rojo-rbx/rbx-dom/pull/299

## 1.5.0 (2023-04-22)
* Implemented `Font`. ([#248])
Expand Down
8 changes: 8 additions & 0 deletions rbx_types/src/attributes/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,12 @@ pub(crate) enum AttributeError {

#[error("couldn't read bytes to deserialize {0}")]
ReadType(&'static str),

#[error("font contained invalid UTF-8 in {field}")]
FontBadUnicode {
#[source]
source: FromUtf8Error,

field: String,
kennethloeffler marked this conversation as resolved.
Show resolved Hide resolved
},
}
49 changes: 46 additions & 3 deletions rbx_types/src/attributes/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use std::{
};

use crate::{
BinaryString, BrickColor, CFrame, Color3, ColorSequence, ColorSequenceKeypoint, Matrix3,
NumberRange, NumberSequence, NumberSequenceKeypoint, Rect, UDim, UDim2, Variant, VariantType,
Vector2, Vector3,
BinaryString, BrickColor, CFrame, Color3, ColorSequence, ColorSequenceKeypoint, Font,
FontStyle, FontWeight, Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint, Rect,
UDim, UDim2, Variant, VariantType, Vector2, Vector3,
};

use super::{type_id, AttributeError};
Expand Down Expand Up @@ -161,6 +161,43 @@ pub(crate) fn read_attributes<R: Read>(
}
.into(),

VariantType::Font => {
let weight = read_u16(&mut value)?;
let style = read_u8(&mut value)?;

let family = {
let buf = read_string(&mut value)?;

String::from_utf8(buf).map_err(|source| AttributeError::FontBadUnicode {
source,
field: "family".to_string(),
kennethloeffler marked this conversation as resolved.
Show resolved Hide resolved
})?
};

let cached_face_id = {
let buf = read_string(&mut value)?;

if buf.is_empty() {
None
} else {
Some(String::from_utf8(buf).map_err(|source| {
AttributeError::FontBadUnicode {
source,
field: "cached_face_id".to_string(),
kennethloeffler marked this conversation as resolved.
Show resolved Hide resolved
}
})?)
}
};

Font {
family,
weight: FontWeight::from_u16(weight).unwrap_or_default(),
style: FontStyle::from_u8(style).unwrap_or_default(),
cached_face_id,
}
}
.into(),

other => return Err(AttributeError::UnsupportedVariantType(other)),
};

Expand All @@ -176,6 +213,12 @@ fn read_u8<R: Read>(mut reader: R) -> io::Result<u8> {
Ok(bytes[0])
}

fn read_u16<R: Read>(mut reader: R) -> io::Result<u16> {
let mut bytes = [0u8; 2];
reader.read_exact(&mut bytes)?;
Ok(u16::from_le_bytes(bytes))
}

fn read_i32<R: Read>(mut reader: R) -> io::Result<i32> {
let mut bytes = [0u8; 4];
reader.read_exact(&mut bytes)?;
Expand Down
1 change: 1 addition & 0 deletions rbx_types/src/attributes/type_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,5 @@ type_ids! {
// ??? => 0x1A,
NumberRange => 0x1B,
Rect => 0x1C,
Font => 0x21,
}
13 changes: 13 additions & 0 deletions rbx_types/src/attributes/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ pub(crate) fn write_attributes<W: Write>(
write_vector3(&mut writer, matrix.z)?;
}
}
Variant::Font(font) => {
write_u16(&mut writer, font.weight.as_u16())?;
write_u8(&mut writer, font.style.as_u8())?;
write_string(&mut writer, &font.family)?;
write_string(
&mut writer,
&font.cached_face_id.clone().unwrap_or_default(),
)?;
}

other_variant => unreachable!("variant {:?} was not implemented", other_variant),
}
Expand All @@ -112,6 +121,10 @@ fn write_u32<W: Write>(mut writer: W, n: u32) -> io::Result<()> {
writer.write_all(&n.to_le_bytes()[..])
}

fn write_u16<W: Write>(mut writer: W, n: u16) -> io::Result<()> {
writer.write_all(&n.to_le_bytes()[..])
}

fn write_u8<W: Write>(mut writer: W, n: u8) -> io::Result<()> {
writer.write_all(&n.to_le_bytes()[..])
}
Expand Down
1 change: 1 addition & 0 deletions rbx_xml/src/tests/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,5 @@ model_tests! {
text_label_with_font,
gui_inset_and_font_migration,
folder_with_cframe_attributes,
folder_with_font_attribute,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
source: rbx_xml/src/tests/mod.rs
expression: "DomViewer::new().view_children(&decoded)"
---
- referent: referent-0
name: Folder
class: Folder
properties:
Attributes:
Attributes:
AFontAttribute:
Font:
family: "rbxasset://fonts/families/Creepster.json"
weight: Regular
style: Normal
cachedFaceId: ~
SourceAssetId:
Int64: -1
Tags:
Tags: []
children: []

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
source: rbx_xml/src/tests/mod.rs
expression: "DomViewer::new().view_children(&roundtrip)"
---
- referent: referent-0
name: Folder
class: Folder
properties:
Attributes:
Attributes:
AFontAttribute:
Font:
family: "rbxasset://fonts/families/Creepster.json"
weight: Regular
style: Normal
cachedFaceId: ~
SourceAssetId:
Int64: -1
Tags:
Tags: []
children: []