Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions isobus/include/isobus/isobus/isobus_virtual_terminal_objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4529,6 +4529,149 @@ namespace isobus
std::uint8_t pointerType = 0; ///< The pointer type, defines how this should be rendered
};

/// @brief Defines an Scaled Graphic object.
/// The Scaled Graphic object, available in VT version 6 and later, displays a scaled representation of a
/// referenced graphic object. The VT shall scale the raw data from the referenced graphic object from the
/// actual width and height to the target width and height. See Table B.75 and Table B.76. Therefore the
/// target width attribute in the Picture Graphic object shall be ignored when referenced from the Scaled
/// Graphic object.
class ScaledGraphicObject : public VTObject
{
public:
/// @brief Enumerates this object's attributes that have Attribute IDs (AID)
enum class AttributeName : std::uint8_t
{
Width = 1,
Height = 2,
ScaleType = 3,
Options = 4,

NumberOfAttributes = 5
};

/// @brief Enumerates the option bits in the options bitfield for a Scaled graphics object
enum class Options
{
Flashing = 0, // Flashing. Flash style and rate determined by VT design.
};

/// @brief Enumerates the scaling value bits in the scale type attribute of a Scaled graphics object
enum class ScalingValue : std::uint8_t
{
NotScaled = 0,
ScaleToWidthMaintainAspectRatio = 1,
ScaleToHeightMaintainAspectRatio = 2,
ScaleToWidthAndHeight = 3,
ScaleToWidthAndHeightMaintainAspectRatio = 4,
};

/// @brief Enumerates the horizontal justification bits in the scale type attribute of a Scaled graphics object
enum class HorizontalJustification : std::uint8_t
{
PositionLeft = 0,
PositionMiddle = 1,
PositionRight = 2,
};

/// @brief Enumerates the vertical justification bits in the scale type attribute of a Scaled graphics object
enum class VerticalJustification : std::uint8_t
{
PositionTop = 0,
PositionMiddle = 1,
PositionBottom = 2,
};

/// @brief Bitmask of the horizontal justification bits in the scale type attribute of a Scaled graphics object
static constexpr std::uint8_t HORIZONTAL_JUSTIFICATION_MASK = 0x18;

/// @brief Bitmask of the vertical justification bits in the scale type attribute of a Scaled graphics object
static constexpr std::uint8_t VERTICAL_JUSTIFICATION_MASK = 0x60;

ScaledGraphicObject() = default;
~ScaledGraphicObject() override = default;

/// @brief Returns the VT object type of the underlying derived object
/// @returns The VT object type of the underlying derived objec
VirtualTerminalObjectType get_object_type() const override;

/// @brief Returns the minimum binary serialized length of the associated object
/// @returns The minimum binary serialized length of the associated object
std::uint32_t get_minumum_object_length() const override;

/// @brief Performs basic error checking on the object and returns if the object is valid
/// @param[in] objectPool The object pool to use when validating the object
/// @returns `true` if the object passed basic error checks
bool get_is_valid(const std::map<std::uint16_t, std::shared_ptr<VTObject>> &objectPool) const override;

/// @brief Sets an attribute and optionally returns an error code in the last parameter
/// @param[in] attributeID The ID of the attribute to change
/// @param[in] rawData The raw data to change the attribute to, as decoded in little endian format with unused
/// bytes/bits set to zero.
/// @param[in] objectPool The object pool to use when validating the objects affected by setting this attribute
/// @param[out] returnedError If this function returns false, this will be the error code. If the function
/// returns true, this value is undefined.
/// @returns True if the attribute was changed, otherwise false (check the returnedError in this case to know why).
bool set_attribute(std::uint8_t attributeID, std::uint32_t rawData, const std::map<std::uint16_t, std::shared_ptr<VTObject>> &objectPool, AttributeError &returnedError) override;

/// @brief Gets an attribute and returns the raw data in the last parameter
/// @param[in] attributeID The ID of the attribute to get
/// @param[out] returnedAttributeData The raw data of the attribute, as decoded in little endian format with unused
/// bytes/bits set to zero. You may need to cast this to the correct type. If this function
/// returns false, this value is undefined.
/// @returns True if the attribute was retrieved, otherwise false (the attribute ID was invalid)
bool get_attribute(std::uint8_t attributeID, std::uint32_t &returnedAttributeData) const override;

/// @brief Returns the state of a single option in the object's option bitfield
/// @param[in] option The option to check the value of in the object's option bitfield
/// @returns The state of the associated option bit
bool get_option(Options option) const;

/// @brief Sets a single option in the options bitfield to the specified value
/// @param[in] option The option to set
/// @param[in] value The new value of the option bit
void set_option(Options option, bool value);

/// @brief Sets the options bitfield for this object to a new value
/// @param[in] options The new value for the options bitfield
void set_options(std::uint8_t options);

/// @brief Returns the scale type of the scaled graphic object
/// @returns Scaling type value
std::uint8_t get_scale_type() const;

/// @brief Sets the scaling type of the scaled graphic object
/// @param[in] scale_type The scale type to set
void set_scale_type(std::uint8_t scale_type);

/// @brief Helper method the query the vertical and horizontal justification with a single call
/// @param[in] vjust reference parameter for the vertical justification
/// @param[in] hjust reference parameter for the horizontal justification
void get_justification(VerticalJustification &vjust, HorizontalJustification &hjust) const;

/// @brief Returns the object ID of the referenced Graphics Data, Picture Graphic or object pointer
/// @returns The object ID of the referenced Graphics Data, Picture Graphic or object pointer or the null object ID
std::uint16_t get_graphic_id() const;

/// @brief Sets the object ID of the referenced Graphics Data, Picture Graphic or object pointer
/// @param[in] newGraphicID The object ID of the referenced Graphics Data, Picture Graphic or object pointer or the null object ID
void set_graphic_id(std::uint16_t newGraphicID);

private:
/// ScaleType bit-field
/// Bits 0-2 : scaling type
/// Bits 3-4 : horizontal justification
/// Bits 5-6 : vertical justification
/// Bit 7 : reserved
std::uint8_t scaleType = 0;

/// Options bit-field
/// Bit 0 = Flashing
/// Bits 1–7 = reserved
std::uint8_t optionsBitfield = 0;

std::uint16_t graphicID = NULL_OBJECT_ID; ///< Object ID of a referenced Graphics Data, Picture Graphic or object pointer or NULL_OBJECT_ID
};

template<typename T>
/// @brief A specialized replacement for std::to_string
/// @param object_id An ID of an IsoBus object
Expand Down
161 changes: 161 additions & 0 deletions isobus/src/isobus_virtual_terminal_objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8612,4 +8612,165 @@ namespace isobus
pointerType = type;
}

VirtualTerminalObjectType ScaledGraphicObject::get_object_type() const
{
return VirtualTerminalObjectType::ScaledGraphic;
}

bool ScaledGraphicObject::get_attribute(std::uint8_t attributeID, std::uint32_t &returnedAttributeData) const
{
switch (static_cast<AttributeName>(attributeID))
{
case AttributeName::Width:
returnedAttributeData = width;
return true;

case AttributeName::Height:
returnedAttributeData = height;
return true;

case AttributeName::ScaleType:
returnedAttributeData = scaleType;
return true;

case AttributeName::Options:
returnedAttributeData = optionsBitfield;
return true;

default:
return false;
}
}

bool ScaledGraphicObject::get_option(Options option) const
{
return (0 != ((1 << static_cast<std::uint8_t>(option)) & optionsBitfield));
}

void ScaledGraphicObject::set_option(Options option, bool value)
{
if (value)
{
optionsBitfield |= (1 << static_cast<std::uint8_t>(option));
}
else
{
optionsBitfield &= ~(1 << static_cast<std::uint8_t>(option));
}
}

void ScaledGraphicObject::set_options(std::uint8_t options)
{
optionsBitfield = options;
}

void ScaledGraphicObject::set_scale_type(std::uint8_t scale_type)
{
scaleType = scale_type;
}

void ScaledGraphicObject::get_justification(VerticalJustification &vjust, HorizontalJustification &hjust) const
{
hjust = static_cast<HorizontalJustification>((scaleType & HORIZONTAL_JUSTIFICATION_MASK) >> 3);
vjust = static_cast<VerticalJustification>((scaleType & VERTICAL_JUSTIFICATION_MASK) >> 5);
}

std::uint16_t ScaledGraphicObject::get_graphic_id() const
{
return graphicID;
}

void ScaledGraphicObject::set_graphic_id(std::uint16_t newGraphicID)
{
graphicID = newGraphicID;
}

std::uint8_t ScaledGraphicObject::get_scale_type() const
{
return scaleType;
}

bool ScaledGraphicObject::set_attribute(std::uint8_t attributeID, std::uint32_t rawData, const std::map<std::uint16_t, std::shared_ptr<VTObject>> &, AttributeError &returnedError)
{
switch (static_cast<AttributeName>(attributeID))
{
case AttributeName::Width:
set_width(static_cast<std::uint16_t>(rawData));
return true;

case AttributeName::Height:
set_height(static_cast<std::uint16_t>(rawData));
return true;

case AttributeName::ScaleType:
if (((rawData & 0x07) >= 5) ||
((rawData & VERTICAL_JUSTIFICATION_MASK) == VERTICAL_JUSTIFICATION_MASK) ||
((rawData & HORIZONTAL_JUSTIFICATION_MASK) == HORIZONTAL_JUSTIFICATION_MASK) ||
((rawData & 0x80) == 0x80))
{
returnedError = AttributeError::InvalidValue;
return false;
}
scaleType = static_cast<std::uint8_t>(rawData);
return true;

case AttributeName::Options:
optionsBitfield = static_cast<std::uint8_t>(rawData & 0xFF);
return true;
default:
returnedError = AttributeError::InvalidAttributeID;
return false;
}
}

bool ScaledGraphicObject::get_is_valid(const std::map<std::uint16_t, std::shared_ptr<VTObject>> &objectPool) const
{
if (((scaleType & 0x07) >= 5) ||
((scaleType & VERTICAL_JUSTIFICATION_MASK) == VERTICAL_JUSTIFICATION_MASK) ||
((scaleType & HORIZONTAL_JUSTIFICATION_MASK) == HORIZONTAL_JUSTIFICATION_MASK) ||
((scaleType & 0x80) == 0x80))
{
return false;
}

if (NULL_OBJECT_ID != graphicID)
{
// Object identifier of a graphic object, or an Object Pointer object.
// Graphic objects include:
// —   Graphic Data object;
// —   Picture Graphic object.
// An Object Pointer object shall point only to one of the above listed graphic objects,
// another Object Pointer object, or the NULL object.
auto object = get_object_by_id(graphicID, objectPool);

if (object && (VirtualTerminalObjectType::ObjectPointer == object->get_object_type()))
{
auto objectPointer = std::static_pointer_cast<ObjectPointer>(object);
if (NULL_OBJECT_ID != objectPointer->get_value())
{
object = get_object_by_id(objectPointer->get_value(), objectPool);
if (object &&
(VirtualTerminalObjectType::PictureGraphic != object->get_object_type()) &&
(VirtualTerminalObjectType::GraphicData != object->get_object_type()))
{
return false;
}
}
}

if (object &&
(VirtualTerminalObjectType::PictureGraphic != object->get_object_type()) &&
(VirtualTerminalObjectType::GraphicData != object->get_object_type()))
{
return false;
}
}
return true;
}

std::uint32_t ScaledGraphicObject::get_minumum_object_length() const
{
return 12;
}

} // namespace isobus
Loading
Loading