You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.8 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. //
  2. // Glyph.swift
  3. // lottie-swift
  4. //
  5. // Created by Brandon Withrow on 1/9/19.
  6. //
  7. import Foundation
  8. /// A model that holds a vector character
  9. final class Glyph: Codable, DictionaryInitializable {
  10. // MARK: Lifecycle
  11. required init(from decoder: Decoder) throws {
  12. let container = try decoder.container(keyedBy: Glyph.CodingKeys.self)
  13. character = try container.decode(String.self, forKey: .character)
  14. fontSize = try container.decode(Double.self, forKey: .fontSize)
  15. fontFamily = try container.decode(String.self, forKey: .fontFamily)
  16. fontStyle = try container.decode(String.self, forKey: .fontStyle)
  17. width = try container.decode(Double.self, forKey: .width)
  18. if
  19. container.contains(.shapeWrapper),
  20. let shapeContainer = try? container.nestedContainer(keyedBy: ShapeKey.self, forKey: .shapeWrapper),
  21. shapeContainer.contains(.shapes)
  22. {
  23. shapes = try shapeContainer.decode([ShapeItem].self, ofFamily: ShapeType.self, forKey: .shapes)
  24. } else {
  25. shapes = []
  26. }
  27. }
  28. init(dictionary: [String: Any]) throws {
  29. character = try dictionary.value(for: CodingKeys.character)
  30. fontSize = try dictionary.value(for: CodingKeys.fontSize)
  31. fontFamily = try dictionary.value(for: CodingKeys.fontFamily)
  32. fontStyle = try dictionary.value(for: CodingKeys.fontStyle)
  33. width = try dictionary.value(for: CodingKeys.width)
  34. if
  35. let shapes = dictionary[CodingKeys.shapeWrapper.rawValue] as? [String: Any],
  36. let shapeDictionaries = shapes[ShapeKey.shapes.rawValue] as? [[String: Any]]
  37. {
  38. self.shapes = try [ShapeItem].fromDictionaries(shapeDictionaries)
  39. } else {
  40. shapes = [ShapeItem]()
  41. }
  42. }
  43. // MARK: Internal
  44. /// The character
  45. let character: String
  46. /// The font size of the character
  47. let fontSize: Double
  48. /// The font family of the character
  49. let fontFamily: String
  50. /// The Style of the character
  51. let fontStyle: String
  52. /// The Width of the character
  53. let width: Double
  54. /// The Shape Data of the Character
  55. let shapes: [ShapeItem]
  56. func encode(to encoder: Encoder) throws {
  57. var container = encoder.container(keyedBy: CodingKeys.self)
  58. try container.encode(character, forKey: .character)
  59. try container.encode(fontSize, forKey: .fontSize)
  60. try container.encode(fontFamily, forKey: .fontFamily)
  61. try container.encode(fontStyle, forKey: .fontStyle)
  62. try container.encode(width, forKey: .width)
  63. var shapeContainer = container.nestedContainer(keyedBy: ShapeKey.self, forKey: .shapeWrapper)
  64. try shapeContainer.encode(shapes, forKey: .shapes)
  65. }
  66. // MARK: Private
  67. private enum CodingKeys: String, CodingKey {
  68. case character = "ch"
  69. case fontSize = "size"
  70. case fontFamily = "fFamily"
  71. case fontStyle = "style"
  72. case width = "w"
  73. case shapeWrapper = "data"
  74. }
  75. private enum ShapeKey: String, CodingKey {
  76. case shapes
  77. }
  78. }