Skip to content

Commit e46fec0

Browse files
author
Anaminus
committed
Implement Font type for rbxl and rbxlx.
1 parent 88f86e6 commit e46fec0

File tree

5 files changed

+366
-1
lines changed

5 files changed

+366
-1
lines changed

rbxl/arrays.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ func newArray(t typeID, n int) array {
322322
}
323323
case typeUniqueId:
324324
return make(arrayUniqueId, n)
325+
case typeFont:
326+
return make(arrayFont, n)
325327
}
326328
return nil
327329
}
@@ -1528,3 +1530,39 @@ func (a arrayUniqueId) Bytes(b []byte) []byte {
15281530
func (a arrayUniqueId) Interleaved() {}
15291531

15301532
////////////////////////////////////////////////////////////////////////////////
1533+
1534+
type arrayFont []valueFont
1535+
1536+
func (arrayFont) Type() typeID {
1537+
return typeFont
1538+
}
1539+
1540+
func (a arrayFont) Len() int {
1541+
return len(a)
1542+
}
1543+
1544+
func (a arrayFont) Get(i int) value {
1545+
v := a[i]
1546+
return &v
1547+
}
1548+
1549+
func (a arrayFont) Set(i int, v value) {
1550+
a[i] = *v.(*valueFont)
1551+
}
1552+
1553+
func (a arrayFont) BytesLen() int {
1554+
var n int
1555+
for _, v := range a {
1556+
n += v.BytesLen()
1557+
}
1558+
return n
1559+
}
1560+
1561+
func (a arrayFont) Bytes(b []byte) []byte {
1562+
for _, v := range a {
1563+
b = v.Bytes(b)
1564+
}
1565+
return b
1566+
}
1567+
1568+
////////////////////////////////////////////////////////////////////////////////

rbxl/codec.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,14 @@ func decodeValue(val value) rbxfile.Value {
403403
Index: value.Index,
404404
}
405405

406+
case *valueFont:
407+
return rbxfile.ValueFont{
408+
Family: rbxfile.ValueContent(value.Family),
409+
Weight: rbxfile.FontWeight(value.Weight),
410+
Style: rbxfile.FontStyle(value.Style),
411+
CachedFaceId: rbxfile.ValueContent(value.CachedFaceId),
412+
}
413+
406414
default:
407415
return nil
408416
}
@@ -977,6 +985,14 @@ func encodeValue(val rbxfile.Value) value {
977985
Index: value.Index,
978986
}
979987

988+
case rbxfile.ValueFont:
989+
return &valueFont{
990+
Family: valueString(value.Family),
991+
Weight: uint16(value.Weight),
992+
Style: uint8(value.Style),
993+
CachedFaceId: valueString(value.CachedFaceId),
994+
}
995+
980996
default:
981997
return nil
982998
}

rbxl/values.go

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const (
3434
// Variable size, where the type is optional.
3535
zOpt = -3
3636

37+
// Variable size, custom implementation.
38+
zOther = -4
39+
3740
// Number of bytes used to contain length of a zArray type.
3841
zArrayLen = 4
3942

@@ -90,11 +93,12 @@ const (
9093
typeSignedString typeID = 0x1D //TODO
9194
typeOptional typeID = 0x1E
9295
typeUniqueId typeID = 0x1F
96+
typeFont typeID = 0x20
9397
)
9498

9599
// Valid returns whether the type has a valid value.
96100
func (t typeID) Valid() bool {
97-
return typeString <= t && t <= typeUniqueId && t != typeSignedString
101+
return typeString <= t && t <= typeFont && t != typeSignedString
98102
}
99103

100104
// Size returns the number of bytes required to hold a value of the type.
@@ -164,6 +168,8 @@ func (t typeID) Size() int {
164168
return zOptional
165169
case typeUniqueId:
166170
return zUniqueId
171+
case typeFont:
172+
return zFont
167173
default:
168174
return zInvalid
169175
}
@@ -273,6 +279,8 @@ func (t typeID) String() string {
273279
return "Optional"
274280
case typeUniqueId:
275281
return "UniqueId"
282+
case typeFont:
283+
return "Font"
276284
default:
277285
return "Invalid"
278286
}
@@ -341,6 +349,8 @@ func (t typeID) ValueType() rbxfile.Type {
341349
return rbxfile.TypeOptional
342350
case typeUniqueId:
343351
return rbxfile.TypeUniqueId
352+
case typeFont:
353+
return rbxfile.TypeFont
344354
default:
345355
return rbxfile.TypeInvalid
346356
}
@@ -413,6 +423,8 @@ func fromValueType(t rbxfile.Type) typeID {
413423
return typeOptional
414424
case rbxfile.TypeUniqueId:
415425
return typeUniqueId
426+
case rbxfile.TypeFont:
427+
return typeFont
416428
default:
417429
return typeInvalid
418430
}
@@ -501,6 +513,8 @@ func newValue(typ typeID) value {
501513
return nil
502514
case typeUniqueId:
503515
return new(valueUniqueId)
516+
case typeFont:
517+
return new(valueFont)
504518
}
505519
return nil
506520
}
@@ -2228,3 +2242,95 @@ func (v valueUniqueId) Dump(w *bufio.Writer, indent int) {
22282242
dumpNewline(w, indent)
22292243
w.WriteByte('}')
22302244
}
2245+
2246+
////////////////////////////////////////////////////////////////
2247+
2248+
const zFont = zOther // String + u16 + u8 + String
2249+
2250+
type valueFont struct {
2251+
Family valueString
2252+
Weight uint16
2253+
Style uint8
2254+
CachedFaceId valueString
2255+
}
2256+
2257+
func (valueFont) Type() typeID {
2258+
return typeFont
2259+
}
2260+
2261+
func (v valueFont) BytesLen() int {
2262+
return v.Family.BytesLen() + zu16 + zu8 + v.CachedFaceId.BytesLen()
2263+
}
2264+
2265+
func (v valueFont) Bytes(b []byte) []byte {
2266+
b = v.Family.Bytes(b)
2267+
b = appendUint16(b, le, v.Weight)
2268+
b = append(b, v.Style)
2269+
b = v.CachedFaceId.Bytes(b)
2270+
return b
2271+
}
2272+
2273+
func (v *valueFont) FromBytes(b []byte) (n int, err error) {
2274+
l := len(b)
2275+
2276+
nn, err := v.Family.FromBytes(b)
2277+
n += nn
2278+
if err != nil {
2279+
return n, err
2280+
}
2281+
b = b[nn:]
2282+
2283+
nn = zu16
2284+
n += nn
2285+
if len(b) < nn {
2286+
return n, buflenError{exp: uint64(n), got: l}
2287+
}
2288+
v.Weight = readUint16(&b, le)
2289+
2290+
nn = zu8
2291+
n += nn
2292+
if len(b) < nn {
2293+
return n, buflenError{exp: uint64(n), got: l}
2294+
}
2295+
v.Style = readUint8(&b)
2296+
2297+
nn, err = v.CachedFaceId.FromBytes(b)
2298+
n += nn
2299+
if err != nil {
2300+
return n, err
2301+
}
2302+
b = b[nn:]
2303+
2304+
return n, nil
2305+
}
2306+
2307+
func (v valueFont) Dump(w *bufio.Writer, indent int) {
2308+
w.WriteByte('{')
2309+
2310+
dumpNewline(w, indent+1)
2311+
w.WriteString("Family: ")
2312+
v.Family.Dump(w, indent+1)
2313+
2314+
dumpNewline(w, indent+1)
2315+
w.WriteString("Weight: ")
2316+
w.WriteString(rbxfile.FontWeight(v.Weight).String())
2317+
w.WriteString(" (")
2318+
w.Write(strconv.AppendInt(nil, int64(v.Weight), 10))
2319+
w.WriteString(")")
2320+
2321+
dumpNewline(w, indent+1)
2322+
w.WriteString("Style: ")
2323+
w.WriteString(rbxfile.FontStyle(v.Style).String())
2324+
w.WriteString(" (")
2325+
w.Write(strconv.AppendInt(nil, int64(v.Style), 10))
2326+
w.WriteString(")")
2327+
2328+
dumpNewline(w, indent+1)
2329+
w.WriteString("CachedFaceId: ")
2330+
v.CachedFaceId.Dump(w, indent+1)
2331+
2332+
dumpNewline(w, indent)
2333+
w.WriteByte('}')
2334+
}
2335+
2336+
////////////////////////////////////////////////////////////////

rbxlx/codec.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ func (robloxCodec) GetCanonTag(valueType rbxfile.Type, optional bool) (canonTag
314314
canonTag = "SharedString"
315315
case rbxfile.TypeUniqueId:
316316
canonTag = "UniqueId"
317+
case rbxfile.TypeFont:
318+
canonTag = "Font"
317319
}
318320
if optional {
319321
canonTag = "Optional" + canonTag
@@ -391,6 +393,8 @@ func (robloxCodec) GetCanonType(valueType string) (canonType rbxfile.Type, optio
391393
canonType = rbxfile.TypeSharedString
392394
case "uniqueid":
393395
canonType = rbxfile.TypeUniqueId
396+
case "font":
397+
canonType = rbxfile.TypeFont
394398
}
395399
return canonType, optional
396400
}
@@ -937,6 +941,39 @@ func (dec *rdecoder) getValue(tag *documentTag, valueType rbxfile.Type) (value r
937941
v.Time = binary.BigEndian.Uint32(b[8:12])
938942
v.Index = binary.BigEndian.Uint32(b[12:16])
939943
return v, true
944+
945+
case rbxfile.TypeFont:
946+
var v rbxfile.ValueFont
947+
var family *documentTag
948+
var cachedFaceId *documentTag
949+
ok := components{
950+
"Family": &family,
951+
"Weight": &v.Weight,
952+
"Style": &v.Style,
953+
}.getFrom(tag)
954+
if !ok {
955+
goto fontFailed
956+
}
957+
{
958+
vFamily, ok := dec.getValue(family, rbxfile.TypeContent)
959+
if !ok {
960+
goto fontFailed
961+
}
962+
v.Family = vFamily.(rbxfile.ValueContent)
963+
}
964+
if ok := (components{"CachedFaceId": &cachedFaceId}.getFrom(tag)); ok {
965+
vCachedFaceId, ok := dec.getValue(cachedFaceId, rbxfile.TypeContent)
966+
if !ok {
967+
goto fontFailed
968+
}
969+
v.CachedFaceId = vCachedFaceId.(rbxfile.ValueContent)
970+
}
971+
return v, true
972+
fontFailed:
973+
if dec.codec.DiscardInvalidProperties {
974+
return nil, false
975+
}
976+
return rbxfile.ValueFont{}, true
940977
}
941978
return nil, false
942979
}
@@ -1009,6 +1046,22 @@ func (c components) getFrom(tag *documentTag) (ok bool) {
10091046
if n, err := strconv.ParseFloat(getContent(subtag), 32); err == nil {
10101047
*v = float32(n)
10111048
}
1049+
case *rbxfile.FontStyle:
1050+
f, ok := rbxfile.FontStyleFromString(getContent(subtag))
1051+
if !ok {
1052+
return false
1053+
}
1054+
*v = f
1055+
case *rbxfile.FontWeight:
1056+
// Parse as uint16.
1057+
n, err := strconv.ParseInt(getContent(subtag), 10, 16)
1058+
*v = rbxfile.FontWeight(n)
1059+
if err != nil {
1060+
if errors.Is(err, strconv.ErrRange) {
1061+
return true
1062+
}
1063+
return false
1064+
}
10121065
case **documentTag:
10131066
*v = subtag
10141067
}
@@ -1596,6 +1649,24 @@ func (enc *rencoder) encodeProperty(value rbxfile.Value) *documentTag {
15961649
StartName: "UniqueId",
15971650
Text: hex.EncodeToString(b[:]),
15981651
}
1652+
1653+
case rbxfile.ValueFont:
1654+
family := enc.encodeProperty(value.Family)
1655+
family.StartName = "Family"
1656+
parent := &documentTag{
1657+
StartName: "Font",
1658+
Tags: []*documentTag{
1659+
family,
1660+
{StartName: "Weight", NoIndent: true, Text: strconv.FormatInt(int64(value.Weight), 10)},
1661+
{StartName: "Style", NoIndent: true, Text: value.Style.String()},
1662+
},
1663+
}
1664+
if len(value.CachedFaceId) > 0 {
1665+
cachedFaceId := enc.encodeProperty(value.CachedFaceId)
1666+
cachedFaceId.StartName = "CachedFaceId"
1667+
parent.Tags = append(parent.Tags, cachedFaceId)
1668+
}
1669+
return parent
15991670
}
16001671

16011672
return nil

0 commit comments

Comments
 (0)