Example #1
0
void CGUIFont::DrawScrollingText(float x, float y, const vector<DWORD> &colors, DWORD shadowColor,
                const vector<DWORD> &text, DWORD alignment, float maxWidth, CScrollInfo &scrollInfo)
{
  if (!m_font) return;
  if (!shadowColor) shadowColor = m_shadowColor;

  float spaceWidth = GetCharWidth(L' ');
  unsigned int maxChars = min((long unsigned int)(text.size() + scrollInfo.suffix.size()), (long unsigned int)((maxWidth*1.05f)/spaceWidth)); //max chars on screen + extra marginchars

  if (!text.size() || ClippedRegionIsEmpty(x, y, maxWidth, alignment))
    return; // nothing to render

  maxWidth = ROUND(maxWidth / g_graphicsContext.GetGUIScaleX());

  // draw at our scroll position
  // we handle the scrolling as follows:
  //   We scroll on a per-pixel basis up until we have scrolled the first character outside
  //   of our viewport, whereby we cycle the string around, and reset the scroll position.
  //
  //   m_PixelScroll is the amount in pixels to move the string by.
  //   m_CharacterScroll is the amount in characters to rotate the string by.
  //
  if (!scrollInfo.waitTime)
  {
    // First update our m_PixelScroll...
    DWORD ch;
    if (scrollInfo.characterPos < text.size())
      ch = text[scrollInfo.characterPos];
    else if (scrollInfo.characterPos < text.size() + scrollInfo.suffix.size())
      ch = scrollInfo.suffix[scrollInfo.characterPos - text.size()];
    else
      ch = text[0];
    float charWidth = GetCharWidth(ch);
    float scrollAmount = scrollInfo.pixelSpeed * g_graphicsContext.GetGUIScaleX();
    if (scrollInfo.pixelPos < charWidth - scrollAmount)
      scrollInfo.pixelPos += scrollAmount;
    else
    {
      scrollInfo.pixelPos -= (charWidth - scrollAmount);
      scrollInfo.characterPos++;
      if (scrollInfo.characterPos >= text.size() + scrollInfo.suffix.size())
        scrollInfo.Reset();
    }
  }
  else
    scrollInfo.waitTime--;

  // Now rotate our string as needed, only take a slightly larger then visible part of the text.
  unsigned int pos = scrollInfo.characterPos;
  vector<DWORD> renderText;
  renderText.reserve(maxChars);
  for (unsigned int i = 0; i < maxChars; i++)
  {
    if (pos >= text.size() + scrollInfo.suffix.size())
      pos = 0;
    if (pos < text.size())
      renderText.push_back(text[pos]);
    else
      renderText.push_back(scrollInfo.suffix[pos - text.size()]);
    pos++;
  }

  vector<DWORD> renderColors;
  for (unsigned int i = 0; i < colors.size(); i++)
    renderColors.push_back(g_graphicsContext.MergeAlpha(colors[i] ? colors[i] : m_textColor));

  if (shadowColor)
    m_font->DrawTextInternal(x - scrollInfo.pixelPos + 1, y + 1, g_graphicsContext.MergeAlpha(shadowColor), renderText, alignment, maxWidth + scrollInfo.pixelPos + m_font->GetLineHeight(2.0f));

  m_font->DrawTextInternal(x - scrollInfo.pixelPos, y, renderColors, renderText, alignment, maxWidth + scrollInfo.pixelPos + m_font->GetLineHeight(2.0f));

  g_graphicsContext.RestoreClipRegion();
}
Example #2
0
void CGUIFont::DrawScrollingText(float x, float y, const vecColors &colors, color_t shadowColor,
                                 const vecText &text, uint32_t alignment, float maxWidth, CScrollInfo &scrollInfo)
{
    if (!m_font) return;
    if (!shadowColor) shadowColor = m_shadowColor;

    float spaceWidth = GetCharWidth(L' ');
    // max chars on screen + extra margin chars
    vecText::size_type maxChars =
        std::min<vecText::size_type>(
            (text.size() + (vecText::size_type)scrollInfo.suffix.size()),
            (vecText::size_type)((maxWidth * 1.05f) / spaceWidth));

    if (!text.size() || ClippedRegionIsEmpty(x, y, maxWidth, alignment))
        return; // nothing to render

    maxWidth = ROUND(maxWidth / g_graphicsContext.GetGUIScaleX());

    // draw at our scroll position
    // we handle the scrolling as follows:
    //   We scroll on a per-pixel basis up until we have scrolled the first character outside
    //   of our viewport, whereby we cycle the string around, and reset the scroll position.
    //
    //   pixelPos is the amount in pixels to move the string by.
    //   characterPos is the amount in characters to rotate the string by.
    //
    float offset = scrollInfo.pixelPos;
    if (!scrollInfo.waitTime)
    {
        // move along by the appropriate scroll amount
        float scrollAmount = fabs(scrollInfo.GetPixelsPerFrame() * g_graphicsContext.GetGUIScaleX());

        if (scrollInfo.pixelSpeed > 0)
        {
            // we want to move scrollAmount, grab the next character
            float charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
            if (scrollInfo.pixelPos + scrollAmount < charWidth)
                scrollInfo.pixelPos += scrollAmount;  // within the current character
            else
            {   // past the current character, decrement scrollAmount by the charWidth and move to the next character
                while (scrollInfo.pixelPos + scrollAmount >= charWidth)
                {
                    scrollAmount -= (charWidth - scrollInfo.pixelPos);
                    scrollInfo.pixelPos = 0;
                    scrollInfo.characterPos++;
                    if (scrollInfo.characterPos >= text.size() + scrollInfo.suffix.size())
                    {
                        scrollInfo.Reset();
                        break;
                    }
                    charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
                }
            }
            offset = scrollInfo.pixelPos;
        }
        else if (scrollInfo.pixelSpeed < 0)
        {   // scrolling backwards
            // we want to move scrollAmount, grab the next character
            float charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
            if (scrollInfo.pixelPos + scrollAmount < charWidth)
                scrollInfo.pixelPos += scrollAmount;  // within the current character
            else
            {   // past the current character, decrement scrollAmount by the charWidth and move to the next character
                while (scrollInfo.pixelPos + scrollAmount >= charWidth)
                {
                    scrollAmount -= (charWidth - scrollInfo.pixelPos);
                    scrollInfo.pixelPos = 0;
                    if (scrollInfo.characterPos == 0)
                    {
                        scrollInfo.Reset();
                        scrollInfo.characterPos = text.size() + scrollInfo.suffix.size() - 1;
                        break;
                    }
                    scrollInfo.characterPos--;
                    charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
                }
            }
            offset = charWidth - scrollInfo.pixelPos;
        }
    }
    else
        scrollInfo.waitTime--;

    // Now rotate our string as needed, only take a slightly larger then visible part of the text.
    unsigned int pos = scrollInfo.characterPos;
    vecText renderText;
    renderText.reserve(maxChars);
    for (vecText::size_type i = 0; i < maxChars; i++)
    {
        if (pos >= text.size() + scrollInfo.suffix.size())
            pos = 0;
        if (pos < text.size())
            renderText.push_back(text[pos]);
        else
            renderText.push_back(scrollInfo.suffix[pos - text.size()]);
        pos++;
    }

    vecColors renderColors;
    for (unsigned int i = 0; i < colors.size(); i++)
        renderColors.push_back(g_graphicsContext.MergeAlpha(colors[i] ? colors[i] : m_textColor));

    bool scroll =  !scrollInfo.waitTime && scrollInfo.pixelSpeed;
    if (shadowColor)
    {
        shadowColor = g_graphicsContext.MergeAlpha(shadowColor);
        vecColors shadowColors;
        for (unsigned int i = 0; i < renderColors.size(); i++)
            shadowColors.push_back((renderColors[i] & 0xff000000) != 0 ? shadowColor : 0);
        m_font->DrawTextInternal(x - offset + 1, y + 1, shadowColors, renderText, alignment, maxWidth + scrollInfo.pixelPos + m_font->GetLineHeight(2.0f), scroll);
    }
    m_font->DrawTextInternal(x - offset, y, renderColors, renderText, alignment, maxWidth + scrollInfo.pixelPos + m_font->GetLineHeight(2.0f), scroll);

    g_graphicsContext.RestoreClipRegion();
}