Exemplo n.º 1
0
FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string)
{
    FBrokenLines lines[128];	// Support up to 128 lines (should be plenty)

    const BYTE *space = NULL, *start = string;
    size_t i, ii;
    int c, w, nw;
    FString lastcolor, linecolor;
    bool lastWasSpace = false;
    int kerning = font->GetDefaultKerning ();

    i = w = 0;

    while ( (c = *string++) && i < countof(lines) )
    {
        if (c == TEXTCOLOR_ESCAPE)
        {
            if (*string)
            {
                if (*string == '[')
                {
                    const BYTE *start = string;
                    while (*string != ']' && *string != '\0')
                    {
                        string++;
                    }
                    if (*string != '\0')
                    {
                        string++;
                    }
                    lastcolor = FString((const char *)start, string - start);
                }
                else
                {
                    lastcolor = *string++;
                }
            }
            continue;
        }

        if (isspace(c))
        {
            if (!lastWasSpace)
            {
                space = string - 1;
                lastWasSpace = true;
            }
        }
        else
        {
            lastWasSpace = false;
        }

        nw = font->GetCharWidth (c);

        if ((w > 0 && w + nw > maxwidth) || c == '\n')
        {   // Time to break the line
            if (!space)
                space = string - 1;

            breakit (&lines[i], font, start, space, linecolor);
            if (c == '\n')
            {
                lastcolor = "";		// Why, oh why, did I do it like this?
            }
            linecolor = lastcolor;

            i++;
            w = 0;
            lastWasSpace = false;
            start = space;
            space = NULL;

            while (*start && isspace (*start) && *start != '\n')
                start++;
            if (*start == '\n')
                start++;
            else
                while (*start && isspace (*start))
                    start++;
            string = start;
        }
        else
        {
            w += nw + kerning;
        }
    }

    // String here is pointing one character after the '\0'
    if (i < countof(lines) && --string - start >= 1)
    {
        const BYTE *s = start;

        while (s < string)
        {
            // If there is any non-white space in the remainder of the string, add it.
            if (!isspace (*s++))
            {
                breakit (&lines[i++], font, start, string, linecolor);
                break;
            }
        }
    }

    // Make a copy of the broken lines and return them
    FBrokenLines *broken = new FBrokenLines[i+1];

    for (ii = 0; ii < i; ++ii)
    {
        broken[ii] = lines[ii];
    }
    broken[ii].Width = -1;

    return broken;
}
Exemplo n.º 2
0
brokenlines_t* V_BreakLines(const OFont* font, int maxwidth, const byte* string)
{
	brokenlines_t lines[128];	// Support up to 128 lines (should be plenty)

	const byte* space = NULL;
	const byte* start = string;
	int c, i = 0;
	bool lastWasSpace = false;

	int width = 0;

	while ( (c = *string++) )
	{
		if (c == 0x8a)
		{
			if (*string)
				string++;
			continue;
		}

		if (isspace(c))
		{
			if (!lastWasSpace)
			{
				space = string - 1;
				lastWasSpace = true;
			}
		}
		else
			lastWasSpace = false;

		int charwidth = font->getTextWidth(c);
		
		// Time to break the line
		if (width + charwidth > maxwidth || c == '\n')
		{	
			if (!space)
				space = string - 1;

			breakit(&lines[i], start, space, font);

			i++;
			width = 0;
			lastWasSpace = false;
			start = space;
			space = NULL;

			while (*start && isspace(*start) && *start != '\n')
				start++;

			if (*start == '\n')
				start++;
			else
			{
				while (*start && isspace(*start))
					start++;
			}

			string = start;
		}
		else
		{
			width += charwidth;
		}
	}

	if (string - start > 1)
	{
		const byte* s = start;

		while (s < string)
		{
			if (!isspace(*s++))
			{
				breakit(&lines[i++], start, string, font);
				break;
			}
		}
	}

	// Make a copy of the broken lines and return them
	brokenlines_t *broken = new brokenlines_t[i+1];

	memcpy(broken, lines, sizeof(brokenlines_t) * i);
	broken[i].string = NULL;
	broken[i].width = -1;

	return broken;
}