GetWidthFromCodepointSequence
Short summary
This function returns the width of a given unicode string.
A width of -1 means the string contains control characters, e.g. line feed or carriage return. If a string has for example a line break, the width cannot be calculated. A width 0 means the string is either empty or consists only of combining marks.
Attention: The actual width a character needs for displaying is always dependent on the used font, the fontsize and the rendering! The width this function returns is actually an estimation.
- Return type:
DINT
Parameters
| Name | Type | Comment | Kind |
|---|---|---|---|
| codepoints | POINTER TO UnicodeCodePoint | pointer to the codepoint sequence | input |
| codepointCount | UDINT | number of codepoints in the sequence | input |
| width | DINT | width of the given string | output |
| visibleCharacters | UDINT | count of visible characters | output |
Code
Declaration
FUNCTION GetWidthFromCodepointSequence :DINT
VAR_INPUT
(* pointer to the codepoint sequence *)
codepoints :POINTER TO UnicodeCodePoint;
(* number of codepoints in the sequence *)
codepointCount :UDINT;
END_VAR
VAR_OUTPUT
(* width of the given string *)
width :DINT := 0;
(* count of visible characters *)
visibleCharacters :UDINT := 0;
END_VAR
VAR
index :UDINT;
currentCodepoint :UnicodeCodePoint;
characterWidth: DINT;
END_VAR
Implementation
GetWidthFromCodepointSequence := 0;
WHILE index < codepointCount DO
CASE codepoints[index] OF
16#200D: // zero width joiner, ignore next sign
index := index + 2;
16#FE0F: // Variant Selector 16, it can in some cases make the previous codepoint displayed as emoji, which will consume +1 additional width
IF (index>0) THEN
characterWidth := GetVS16Width(ADR(codepoints[index-1]));
width := width + characterWidth;
visibleCharacters := visibleCharacters + SEL(characterWidth > 0, 0, 1);
END_IF
index := index + 1;
ELSE
characterWidth := GetWidthFromCodepoint(ADR(codepoints[index]));
IF (characterWidth < 0) THEN
// control sign found, size cannot be calculated correctly (e.g. linefeed or carriage return)
width := -1;
RETURN;
END_IF
width := width + characterWidth;
visibleCharacters := visibleCharacters + SEL(characterWidth > 0, 0, 1);
index := index + 1;
END_CASE
END_WHILE
GetWidthFromCodepointSequence := width;