Short: Calculating width of textdraws -
Alcatrik - 10.10.2016
Hi all,
This is a super short one - I wanted to chronicle my research somewhere to save someone the hassle of spending however long I have trying to tackle this problem: working out how wide a textdraw
actually is based on its text content.
In my case, I have a UI system with textboxes and the likes - and I wanted to shorten the string down if it was longer then the textbox, so using the below, if the text width is greater than the width of the textbox, I cut off the remainder, the size of three .'s and some padding, resulting in:
Another use case would be if you wanted to put "hyperlinks" in your textdraw contents - so that you can trigger things once a certain word is pressed without having to manually work out and hard code position.
Solution:
1. The GTA San Andreas\data\fonts.dat file contains (in cleartext) the
baseline widths of each character in rows of 8 - where the 1st digit on the left reflects the first character after the # and the first number. For example, ! is 15 pixels wide.
Code:
15 9 17 27 20 34 23 12 # 0 ! " Ј $ % & '
12 12 21 20 12 14 12 15 # 8 ( ) * + , - . /
23 15 21 21 21 21 21 21 # 16 0 1 2 3 4 5 6 7
20 21 12 12 24 24 24 19 # 24 8 9 : ; < = > ?
10 22 19 19 22 16 19 24 # 32 tmA B C D E F G
22 11 16 21 15 28 24 27 # 40 H I J K L M N O
20 25 19 19 18 23 23 31 # 48 P Q R S T U V W
23 19 21 21 13 35 11 21 # 56 X Y Z ! _
10 19 20 14 20 19 13 20 # 64 ! a b c d e f g
19 9 9 19 9 29 19 21 # 72 h i j k l m n o
19 19 15 15 14 18 19 27 # 80 p q r s t u v w
20 20 17 21 17 20 15 15 # 88 x y z $ [ ]
22 22 22 22 29 19 16 16 # 96 А Б В Г Ж З И Й
16 16 11 11 11 11 27 27 # 104 К Л М Н О П Т У
27 27 23 23 23 23 20 19 # 112 Ф Ц Щ Ъ Ы Ь Я а
19 19 19 30 14 19 19 19 # 120 б в г ж з и й к
19 9 9 9 9 21 21 21 # 128 л м н о п т у ф
21 18 18 18 18 24 19 19 # 136 ц щ ъ ы ь С с ї
20 18 19 19 21 19 19 19 # 144 0 1 2 3 4 5 6 7
19 19 16 19 19 19 20 19 # 152 8 9 : A B C D E
16 19 19 9 19 20 14 29 # 160 F G H I J K L M
19 19 19 19 19 19 21 19 # 168 N O P Q R S T U
20 32 21 19 19 19 19 19 # 176 V W X Y Z А Б В
19 29 19 19 19 19 19 9 # 184 Г Ж З И Й К Л М
9 9 9 19 19 19 19 19 # 192 Н О П Т У Ф Ц Щ
19 19 19 19 21 19 10 9 # 200 Ъ Ы Ь Я С ї ' .
2. There are however two things to note:
- These are multiplied against the textdraw width - for example, at 0.5 the actual width of the ! character is 7.5 - not 15.
- These also work off the basis of the virtual 640x480 textdraw canvas which applies regardless of resolution. For example, at 1280x1024, the letter ! at 1.0 letter width will ACTUALLY be 30 pixels wide
on your screen. However most of the time this shouldn't matter because all other textdraws will also be drawn on the 640x480 grid; I include this only so that you all have a proper understanding of why this is.
3. The default unproportional letter width is 20 pixels.
Re: Short: Calculating width of textdraws -
Crayder - 10.10.2016
Very useful. This could even be used for properly splitting chat lines!
Put it in an include. A VERY simple include:
pawn Code:
#define IsTextdrawChar(%0) \
(!!(0 <= %0 < 224))
#define GetCharLength(%0) \
(IsTextdrawChar(%0) ? _letterSizes[%0] : 0)
new Float:_letterSizes[224] = {
15.0, 9.0, 17.0, 27.0, 20.0, 34.0, 23.0, 12.0, // ! " Ј $ % & '
12.0, 12.0, 21.0, 20.0, 12.0, 14.0, 12.0, 15.0, // ( ) * + , - . /
23.0, 15.0, 21.0, 21.0, 21.0, 21.0, 21.0, 21.0, // 0 1 2 3 4 5 6 7
20.0, 21.0, 12.0, 12.0, 24.0, 24.0, 24.0, 19.0, // 8 9 : ; < = > ?
10.0, 22.0, 19.0, 19.0, 22.0, 16.0, 19.0, 24.0, // tmA B C D E F G
22.0, 11.0, 16.0, 21.0, 15.0, 28.0, 24.0, 27.0, // H I J K L M N O
20.0, 25.0, 19.0, 19.0, 18.0, 23.0, 23.0, 31.0, // P Q R S T U V W
23.0, 19.0, 21.0, 21.0, 13.0, 35.0, 11.0, 21.0, // X Y Z ! _
10.0, 19.0, 20.0, 14.0, 20.0, 19.0, 13.0, 20.0, // ! a b c d e f g
19.0, 9.0, 9.0, 19.0, 9.0, 29.0, 19.0, 21.0, // h i j k l m n o
19.0, 19.0, 15.0, 15.0, 14.0, 18.0, 19.0, 27.0, // p q r s t u v w
20.0, 20.0, 17.0, 21.0, 17.0, 20.0, 15.0, 15.0, // x y z $ [ ]
22.0, 22.0, 22.0, 22.0, 29.0, 19.0, 16.0, 16.0, // А Б В Г Ж З И Й
16.0, 16.0, 11.0, 11.0, 11.0, 11.0, 27.0, 27.0, // К Л М Н О П Т У
27.0, 27.0, 23.0, 23.0, 23.0, 23.0, 20.0, 19.0, // Ф Ц Щ Ъ Ы Ь Я а
19.0, 19.0, 19.0, 30.0, 14.0, 19.0, 19.0, 19.0, // б в г ж з и й к
19.0, 9.0, 9.0, 9.0, 9.0, 21.0, 21.0, 21.0, // л м н о п т у ф
21.0, 18.0, 18.0, 18.0, 18.0, 24.0, 19.0, 19.0, // ц щ ъ ы ь С с ї
20.0, 18.0, 19.0, 19.0, 21.0, 19.0, 19.0, 19.0, // 0 1 2 3 4 5 6 7
19.0, 19.0, 16.0, 19.0, 19.0, 19.0, 20.0, 19.0, // 8 9 : A B C D E
16.0, 19.0, 19.0, 9.0, 19.0, 20.0, 14.0, 29.0, // F G H I J K L M
19.0, 19.0, 19.0, 19.0, 19.0, 19.0, 21.0, 19.0, // N O P Q R S T U
20.0, 32.0, 21.0, 19.0, 19.0, 19.0, 19.0, 19.0, // V W X Y Z А Б В
19.0, 29.0, 19.0, 19.0, 19.0, 19.0, 19.0, 9.0, // Г Ж З И Й К Л М
9.0, 9.0, 9.0, 19.0, 19.0, 19.0, 19.0, 19.0, // Н О П Т У Ф Ц Щ
19.0, 19.0, 19.0, 19.0, 21.0, 19.0, 10.0, 9.0 // Ъ Ы Ь Я С ї ' .
};
Re: Short: Calculating width of textdraws -
Dutheil - 11.10.2016
Oh god, so useful
Re: Short: Calculating width of textdraws -
Eoussama - 11.10.2016
Yep, usefull
Re: Short: Calculating width of textdraws -
Crayder - 02.01.2017
Someone extract the sizes for the dialog font...
Re: Short: Calculating width of textdraws -
Ivan_Ino - 06.01.2017
Uh i didn't saw this before, but i made include for dialog center text with smilar way.. i made all letters width..
https://sampforum.blast.hk/showthread.php?tid=625090
Re: Short: Calculating width of textdraws -
Freaksken - 18.09.2017
This works for ASCII:
Code:
new const characterWidths[] = {
//Data taken from singleplayer fonts.dat file
0, 15, 15, 15, 15, 15, 15, 15, //NULL is not displayable because it breaks off the string, others display as a space
15, 15, 15, 15, 15, 15, 15, 15, //Display as a space
15, 15, 15, 15, 15, 15, 15, 15, //Display as a space
15, 15, 15, 15, 15, 15, 15, 15, //Display as a space
15, 9, 17, 27, 20, 34, 23, 12, // ! " Ј $ % & '
12, 12, 21, 20, 12, 14, 12, 15, //( ) * + , - . /
23, 15, 21, 21, 21, 21, 21, 21, //0 1 2 3 4 5 6 7
20, 21, 12, 12, 24, 24, 24, 19, //8 9 : ; < = > ?
10, 22, 19, 19, 22, 16, 19, 24, //tmA B C D E F G
22, 11, 16, 21, 15, 28, 24, 27, //H I J K L M N O
20, 25, 19, 19, 18, 23, 23, 31, //P Q R S T U V W
23, 19, 21, 21, 13, 35, 11, 21, //X Y Z ! _
10, 19, 20, 14, 20, 19, 13, 20, //! a b c d e f g
19, 9, 9, 19, 9, 29, 19, 21, //h i j k l m n o
19, 19, 15, 15, 14, 18, 19, 27, //p q r s t u v w
20, 20, 17, 21, 17, 20, 15, 15, //x y z $ [ ]
22, 22, 22, 22, 29, 19, 16, 16, //А Б В Г Ж З И Й
16, 16, 11, 11, 11, 11, 27, 27, //К Л М Н О П Т У
27, 27, 23, 23, 23, 23, 20, 19, //Ф Ц Щ Ъ Ы Ь Я а
19, 19, 19, 30, 14, 19, 19, 19, //б в г ж з и й к
19, 9, 9, 9, 9, 21, 21, 21, //л м н о п т у ф
21, 18, 18, 18, 18, 24, 19, 19, //ц щ ъ ы ь С с ї
20, 18, 19, 19, 21, 19, 19, 19, //0 1 2 3 4 5 6 7
19, 19, 16, 19, 19, 19, 20, 19, //8 9 : A B C D E
16, 19, 19, 9, 19, 20, 14, 29, //F G H I J K L M
19, 19, 19, 19, 19, 19, 21, 19, //N O P Q R S T U
20, 32, 21, 19, 19, 19, 19, 19, //V W X Y Z А Б В
19, 29, 19, 19, 19, 19, 19, 9, //Г Ж З И Й К Л М
9, 9, 9, 19, 19, 19, 19, 19, //Н О П Т У Ф Ц Щ
19, 19, 19, 19, 21, 19, 10, 9 //Ъ Ы Ь Я С ї ' .
};
stock GetCharacterWidth© {
if(c < 0) {
return 0;
}
if(c >= sizeof(characterWidths)) {
return 20; //Default width, also taken from singleplayer fonts.dat file
}
return characterWidths[c];
}
stock GetStringWidth(const string[]) {
new width = 0;
for(new i = 0, size = strlen(string); i < size; i++) {
width += GetCharacterWidth(string[i]);
}
return width;
}
Btw, ! is not 15, but space is. ! is 9.
And the widths should be multiplied by the texdraw letter size, not the texdraw width.
EDIT:
Usage for a single character is:
Code:
printf("%d", GetCharacterWidth('a'));
Usage for a string is:
Code:
printf("%d", GetStringWidth("abc"));
EDIT2:
Keep in mind that the final values depend on TextDrawLetterSize and TextDrawSetOutline.
Also don't forget to set TextDrawSetProportional to 1.
Re: Short: Calculating width of textdraws -
kristo - 23.10.2018
I took some time to create a proper implementation of this concept. The ones posted here don't take into account that there are four different fonts, etc. I explained this further in my thread:
https://sampforum.blast.hk/showthread.php?tid=660047