Skip to content

Commit

Permalink
Implement Font type (#248)
Browse files Browse the repository at this point in the history
* Implement Font type

* Error when not impl future FontStyles

* Add docs

* Delete old tests

* Add new test

* Fix formatting consistency issues in spec file

Co-authored-by: Micah <dekkonot@rocketmail.com>

* Address PR comments
* Use explicit from_x and to_x
* Derive and use Copy
* Nicer default when writing cached_face_id

* IgnoreGuiInset no longer saves
(replaced by ScreenInsets)

* Fix typo in binary.md

Co-authored-by: Lucien Greathouse <me@lpghatguy.com>

* Fix font weight casing

* Remove unused constructor

* Fix snapshot tests for PascalCase fonts

* Don't cast around u16 for xml

* Remote Other for Font Weight and Style

* Fix camelCase attribute on FontStyle

* Add PR changes to CHANGELOG files

* Fix Font types from being excluded

* Update database to reflect Font inclusion

* Use if...else

* Fix minor formatting

* to_x -> as_x

---------

Co-authored-by: set <set>
Co-authored-by: Micah <dekkonot@rocketmail.com>
Co-authored-by: Lucien Greathouse <me@lpghatguy.com>
  • Loading branch information
3 people authored Mar 12, 2023
1 parent a878a1f commit 1227bfd
Show file tree
Hide file tree
Showing 28 changed files with 1,286 additions and 31 deletions.
16 changes: 16 additions & 0 deletions docs/binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ This document is based on:
- [SharedString](#sharedstring)
- [OptionalCoordinateFrame](#optionalcoordinateframe)
- [UniqueId](#uniqueid)
- [Font](#font)
- [Data Storage Notes](#data-storage-notes)
- [Integer Transformations](#integer-transformations)
- [Byte Interleaving](#byte-interleaving)
Expand Down Expand Up @@ -639,6 +640,21 @@ When interacting with the XML format, care must be taken because `UniqueId` is s

When an array of `UniqueId` values is present, the bytes are subject to [byte interleaving](#byte-interleaving).

### Font
**Type ID `0x20`**

The `Font` type is a struct composed of two `String` values, a `u8`, and a `u16`:

| Field Name | Format | Value |
|:-------------|:--------------------|:---------------------------------------|
| Family | [`String`](#string) | The font family content URI |
| Weight | `u16` | The weight of the font |
| Style | `u8` | The style of the font |
| CachedFaceId | [`String`](#string) | The cached content URI of the TTF file |

The `Weight` and `Style` fields are stored as little-endian unsigned integers. These are usually treated like enums, and to assign them in Roblox Studio an Enum is used. Interestingly, the `Weight` is *always* stored as a number in binary and XML, but `Style` is stored as a number in binary and as text in XML.

The `CachedFaceId` field is always present, but is allowed to be an empty string (a string of length `0`). When represented in XML, this property will be omitted if it is an empty string. This property is not visible via any user APIs in Roblox Studio.

## Data Storage Notes

Expand Down
4 changes: 1 addition & 3 deletions generate_reflection/src/api_dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ fn variant_type_from_str(value: &str) -> Option<VariantType> {
"ColorSequence" => VariantType::ColorSequence,
"Content" => VariantType::Content,
"Faces" => VariantType::Faces,
"Font" => VariantType::Font,
"Instance" => VariantType::Ref,
"NumberRange" => VariantType::NumberRange,
"NumberSequence" => VariantType::NumberSequence,
Expand Down Expand Up @@ -296,9 +297,6 @@ fn variant_type_from_str(value: &str) -> Option<VariantType> {
// TweenInfo is not supported by rbx_types yet
"TweenInfo" => return None,

// Font is not supported by rbx_types yet
"Font" => return None,

// While DateTime is possible to Serialize, the only use it has as a
// DataType is for the TextChatMessage class, which cannot be serialized
// (at least not saved to file as it is locked to nil parent)
Expand Down
8 changes: 5 additions & 3 deletions generate_reflection/src/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use std::collections::BTreeMap;

use rbx_dom_weak::types::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, Faces, Matrix3, NumberRange,
NumberSequence, NumberSequenceKeypoint, PhysicalProperties, Ray, Rect, Region3int16, Tags,
UDim, UDim2, Variant, VariantType, Vector2, Vector2int16, Vector3, Vector3int16,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, Faces, Font, Matrix3,
NumberRange, NumberSequence, NumberSequenceKeypoint, PhysicalProperties, Ray, Rect,
Region3int16, Tags, UDim, UDim2, Variant, VariantType, Vector2, Vector2int16, Vector3,
Vector3int16,
};
use serde::Serialize;

Expand Down Expand Up @@ -77,6 +78,7 @@ pub fn encode() -> anyhow::Result<String> {
values.insert("Faces", Faces::all().into());
values.insert("Float32", 15.0f32.into());
values.insert("Float64", 15123.0f64.into());
values.insert("Font", Font::default().into());
values.insert("Int32", 6014i32.into());
values.insert("Int64", 23491023i64.into());
values.insert("NumberRange", NumberRange::new(-36.0, 94.0).into());
Expand Down
3 changes: 3 additions & 0 deletions rbx_binary/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# rbx_binary Changelog

## Unreleased
* Added support for `Font` values. ([#248])

[#248]: https://github.com/rojo-rbx/rbx-dom/pull/248

## 0.6.6 (2022-06-29)
* Fixed unserialized properties getting deserialized, like `BasePart.MaterialVariant`. ([#230])
Expand Down
43 changes: 40 additions & 3 deletions rbx_binary/src/deserializer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ use std::{
use rbx_dom_weak::{
types::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, Faces, Matrix3,
NumberRange, NumberSequence, NumberSequenceKeypoint, PhysicalProperties, Ray, Rect, Ref,
SharedString, Tags, UDim, UDim2, Variant, VariantType, Vector2, Vector3, Vector3int16,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, Faces, Font, FontStyle,
FontWeight, Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint,
PhysicalProperties, Ray, Rect, Ref, SharedString, Tags, UDim, UDim2, Variant, VariantType,
Vector2, Vector3, Vector3int16,
},
InstanceBuilder, WeakDom,
};
Expand Down Expand Up @@ -863,6 +864,42 @@ impl<'a, R: Read> DeserializerState<'a, R> {
});
}
},
Type::Font => match canonical_type {
VariantType::Font => {
for referent in &type_info.referents {
let instance = self.instances_by_ref.get_mut(referent).unwrap();

let family = chunk.read_string()?;
let weight = FontWeight::from_u16(chunk.read_le_u16()?);
let style = FontStyle::from_u8(chunk.read_u8()?);
let cached_face_id = chunk.read_string()?;

let cached_face_id = if cached_face_id.is_empty() {
None
} else {
Some(cached_face_id)
};

instance.builder.add_property(
&canonical_name,
Font {
family,
weight,
style,
cached_face_id,
},
);
}
}
invalid_type => {
return Err(InnerError::PropTypeMismatch {
type_name: type_info.type_name.clone(),
prop_name,
valid_type_names: "Font",
actual_type_name: format!("{:?}", invalid_type),
});
}
},
Type::NumberSequence => match canonical_type {
VariantType::NumberSequence => {
for referent in &type_info.referents {
Expand Down
17 changes: 16 additions & 1 deletion rbx_binary/src/serializer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{
use rbx_dom_weak::{
types::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
ColorSequenceKeypoint, Content, Enum, Faces, Matrix3, NumberRange, NumberSequence,
ColorSequenceKeypoint, Content, Enum, Faces, Font, Matrix3, NumberRange, NumberSequence,
NumberSequenceKeypoint, PhysicalProperties, Ray, Rect, Ref, SharedString, Tags, UDim,
UDim2, Variant, VariantType, Vector2, Vector3, Vector3int16,
},
Expand Down Expand Up @@ -709,6 +709,20 @@ impl<'dom, W: Write> SerializerState<'dom, W> {
chunk.write_interleaved_i32_array(offset_x.into_iter())?;
chunk.write_interleaved_i32_array(offset_y.into_iter())?;
}
Type::Font => {
for (i, rbx_value) in values {
if let Variant::Font(value) = rbx_value.as_ref() {
chunk.write_string(&value.family)?;
chunk.write_le_u16(value.weight.as_u16())?;
chunk.write_u8(value.style.as_u8())?;
chunk.write_string(
&value.cached_face_id.clone().unwrap_or_default(),
)?;
} else {
return type_mismatch(i, &rbx_value, "Font");
}
}
}
Type::Ray => {
for (i, rbx_value) in values {
if let Variant::Ray(value) = rbx_value.as_ref() {
Expand Down Expand Up @@ -1229,6 +1243,7 @@ impl<'dom, W: Write> SerializerState<'dom, W> {
VariantType::Tags => Variant::Tags(Tags::new()),
VariantType::Content => Variant::Content(Content::new()),
VariantType::Attributes => Variant::Attributes(Attributes::new()),
VariantType::Font => Variant::Font(Font::default()),
_ => return None,
})
}
Expand Down
1 change: 1 addition & 0 deletions rbx_binary/src/tests/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ binary_tests! {
two_terrainregions,
weldconstraint,
package_link,
text_label_with_font,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
source: rbx_binary/src/tests/util.rs
assertion_line: 33
expression: decoded_viewed
---
- referent: referent-0
name: TextLabel
class: TextLabel
properties:
Active:
Bool: false
AnchorPoint:
Vector2:
- 0
- 0
Attributes:
Attributes: {}
AutoLocalize:
Bool: true
AutomaticSize:
Enum: 0
BackgroundColor3:
Color3:
- 1
- 1
- 1
BackgroundTransparency:
Float32: 0
BorderColor3:
Color3:
- 0.10588236
- 0.16470589
- 0.20784315
BorderMode:
Enum: 0
BorderSizePixel:
Int32: 1
ClipsDescendants:
Bool: false
Draggable:
Bool: false
FontFace:
Font:
family: "rbxasset://fonts/families/RobotoMono.json"
weight: Bold
style: Italic
cachedFaceId: ~
LayoutOrder:
Int32: 0
LineHeight:
Float32: 1
MaxVisibleGraphemes:
Int32: -1
NextSelectionDown: "null"
NextSelectionLeft: "null"
NextSelectionRight: "null"
NextSelectionUp: "null"
Position:
UDim2:
- - 0
- 0
- - 0
- 0
RichText:
Bool: false
RootLocalizationTable: "null"
Rotation:
Float32: 0
Selectable:
Bool: false
SelectionBehaviorDown:
Enum: 0
SelectionBehaviorLeft:
Enum: 0
SelectionBehaviorRight:
Enum: 0
SelectionBehaviorUp:
Enum: 0
SelectionGroup:
Bool: false
SelectionImageObject: "null"
SelectionOrder:
Int32: 0
Size:
UDim2:
- - 0
- 200
- - 0
- 50
SizeConstraint:
Enum: 0
SourceAssetId:
Int64: -1
Tags:
Tags: []
Text:
String: My Text
TextColor3:
Color3:
- 0
- 0
- 0
TextScaled:
Bool: false
TextSize:
Float32: 14
TextStrokeColor3:
Color3:
- 0
- 0
- 0
TextStrokeTransparency:
Float32: 1
TextTransparency:
Float32: 0
TextTruncate:
Enum: 0
TextWrapped:
Bool: false
TextXAlignment:
Enum: 2
TextYAlignment:
Enum: 1
Visible:
Bool: true
ZIndex:
Int32: 1
children: []

Loading

0 comments on commit 1227bfd

Please sign in to comment.