示例#1
0
bool CGUIFont::UpdateScrollInfo(const vecText &text, CScrollInfo &scrollInfo)
{
  // draw at our scroll position
  // we handle the scrolling as follows:
  //   We scroll on a per-pixel basis (eschewing the use of character indices
  //   which were also in use previously). The complete string, including suffix,
  //   is plotted to achieve the desired effect - normally just the one time, but
  //   if there is a wrap point within the viewport then it will be plotted twice.
  //   If the string is smaller than the viewport, then it may be plotted even
  //   more times than that.
  //
  if (g_application.ScreenSaverDisablesAutoScrolling())
    return false;

  if (scrollInfo.waitTime)
  {
    scrollInfo.waitTime--;
    return false;
  }

  if (text.empty())
    return false;

  CScrollInfo old(scrollInfo);

  // move along by the appropriate scroll amount
  float scrollAmount = fabs(scrollInfo.GetPixelsPerFrame() * g_graphicsContext.GetGUIScaleX());

  if (!scrollInfo.m_widthValid)
  {
    /* Calculate the pixel width of the complete string */
    scrollInfo.m_textWidth = GetTextWidth(text);
    scrollInfo.m_totalWidth = scrollInfo.m_textWidth + GetTextWidth(scrollInfo.suffix);
    scrollInfo.m_widthValid = true;
  }
  scrollInfo.pixelPos += scrollAmount;
  assert(scrollInfo.m_totalWidth != 0);
  while (scrollInfo.pixelPos >= scrollInfo.m_totalWidth)
    scrollInfo.pixelPos -= scrollInfo.m_totalWidth;

  if (scrollInfo.pixelPos != old.pixelPos)
    return true;
  else
    return false;
}
示例#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();
}