Page 1 of 1

static void displaySplitOrSpanText(uint8_t y, char *text)

Posted: Sat Apr 13, 2024 3:16 pm
by KA1CM
Hi all,

I'm very new to C programming, but trying to understand the part of OpenGD77 code that handle the display of DMRID database data.
The most complicated part of the function, and I can't wrap my head around it is the part where the data is more than 1 line (more than 21 character).

I can understand the first few conditions,
if there is no data then do nothing.
if the data length is less than 16 character, then display it on one line with big font.
if the data is more than 2 line (more than 42 character) then make it 42 character and treat it as 2 line
if the data is more than 1 line (meaning it is 2 line because we have just eliminated anything more than 2 line). now I'm confused.
I think I don't understand this line

char *p = buffer + 20;

What is it? how to add a string with number? there has to be something more than I can grasp.
I would be appreciated if someone can explain this to me, or point me to a link, so I can read.
Is it a pointer that point to the position of buffer[21]?


a full code of the function below

Code: Select all

static void displaySplitOrSpanText(uint8_t y, char *text)
{
	if (text != NULL)
	{
		uint8_t len = strlen(text);

		if (len == 0)           // no text, doing nothing
		{
			return;
		}
		else if (len <= 16)     // less than 16 characters, display 1 line big font
		{
			displayPrintCentered(y, text, FONT_SIZE_3);
		}
		else                    // more than 16 characters 
		{
			uint8_t nLines = len / 21 + (((len % 21) != 0) ? 1 : 0);

			if (nLines > 2)    // more than 2 line make it 2 line, chop out what excess 42 char
			{
				nLines = 2;
				len = 42; // 2 lines max.
			}

			if (nLines > 1)    // 2 line, now I'm confused???????
			{
				char buffer[MAX_DMR_ID_CONTACT_TEXT_LENGTH]; // to fit 2 * 21 chars + NULL, but needs larger

				memcpy(buffer, text, len + 1);
				buffer[len + 1] = 0;

				char *p = buffer + 20;        // I think it is this line that confused me

				// Find a space backward
				while ((*p != ' ') && (p > buffer))
				{
					p--;
				}

				uint8_t rest = (uint8_t)((buffer + strlen(buffer)) - p) - ((*p == ' ') ? 1 : 0);

				// rest is too long, just split the line in two chunks
				if (rest > 21)
				{
					char c = buffer[21];

					buffer[21] = 0;

					displayPrintCentered(y, chomp(buffer), FONT_SIZE_1); // 2 pixels are saved, could center

					buffer[21] = c;

					displayPrintCentered(y + 8, chomp(buffer + 21), FONT_SIZE_1);
				}
				else
				{
					*p = 0;

					displayPrintCentered(y, chomp(buffer), FONT_SIZE_1);
					displayPrintCentered(y + 8, chomp(p + 1), FONT_SIZE_1);
				}
			}
			else // One line of 21 chars max
			{
				displayPrintCentered(y
#if ! defined(PLATFORM_RD5R)
						+ 4
#endif
						, text, FONT_SIZE_1);
			}
		}
	}
}

Re: static void displaySplitOrSpanText(uint8_t y, char *text)

Posted: Sat Apr 13, 2024 3:54 pm
by F1RMB
The number is an offset to an address (buffer)

Re: static void displaySplitOrSpanText(uint8_t y, char *text)

Posted: Sat Apr 13, 2024 4:53 pm
by KA1CM
Thank you Daniel, one more question what is chomp(buffer);
Is it the same chomp as this https://gist.github.com/rocarvaj/3178214 ?

Re: static void displaySplitOrSpanText(uint8_t y, char *text)

Posted: Sat Apr 13, 2024 5:08 pm
by F1RMB
It's in the source, it's like trim(l, it removes spaces a both ends of an array of char.

Re: static void displaySplitOrSpanText(uint8_t y, char *text)

Posted: Sat Apr 13, 2024 5:49 pm
by KA1CM
F1RMB wrote:
Sat Apr 13, 2024 5:08 pm
It's in the source, it's like trim(l, it removes spaces a both ends of an array of char.
Thanks, I think I get it now.