Пример #1
0
    else
    {
      m_staticCache.Lookup(staticPos,
                           colors, text,
                           rawAlignment, maxPixelWidth,
                           scrolling,
                           XbmcThreads::SystemClockMillis(),
                           dirtyCache) = *static_cast<CGUIFontCacheStaticValue *>(&tempVertices);
      /* Append the new vertices to the set collected since the first Begin() call */
      m_vertex.insert(m_vertex.end(), tempVertices->begin(), tempVertices->end());
    }
  }
  else
  {
    if (hardwareClipping)
      m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer, g_graphicsContext.GetClipRegion()));
    else
      /* Append the vertices from the cache to the set collected since the first Begin() call */
      m_vertex.insert(m_vertex.end(), vertices->begin(), vertices->end());
  }

  End();
}

// this routine assumes a single line (i.e. it was called from GUITextLayout)
float CGUIFontTTFBase::GetTextWidthInternal(vecText::const_iterator start, vecText::const_iterator end)
{
  float width = 0;
  while (start != end)
  {
    Character *c = GetCharacter(*start++);
Пример #2
0
void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors, const vecText &text, uint32_t alignment, float maxPixelWidth, bool scrolling)
{
  Begin();

  uint32_t rawAlignment = alignment;
  bool dirtyCache(false);
  bool hardwareClipping = g_Windowing.ScissorsCanEffectClipping();
  CGUIFontCacheStaticPosition staticPos(x, y);
  CGUIFontCacheDynamicPosition dynamicPos;
  if (hardwareClipping)
  {
    dynamicPos = CGUIFontCacheDynamicPosition(g_graphicsContext.ScaleFinalXCoord(x, y),
                                              g_graphicsContext.ScaleFinalYCoord(x, y),
                                              g_graphicsContext.ScaleFinalZCoord(x, y));
  }
  CVertexBuffer unusedVertexBuffer;
  CVertexBuffer &vertexBuffer = hardwareClipping ?
      m_dynamicCache.Lookup(dynamicPos,
                            colors, text,
                            alignment, maxPixelWidth,
                            scrolling,
                            XbmcThreads::SystemClockMillis(),
                            dirtyCache) :
      unusedVertexBuffer;
  std::shared_ptr<std::vector<SVertex> > tempVertices = std::make_shared<std::vector<SVertex> >();
  std::shared_ptr<std::vector<SVertex> > &vertices = hardwareClipping ?
      tempVertices :
      static_cast<std::shared_ptr<std::vector<SVertex> >&>(m_staticCache.Lookup(staticPos,
                           colors, text,
                           alignment, maxPixelWidth,
                           scrolling,
                           XbmcThreads::SystemClockMillis(),
                           dirtyCache));
  if (dirtyCache)
  {
    // save the origin, which is scaled separately
    m_originX = x;
    m_originY = y;

    // Check if we will really need to truncate or justify the text
    if ( alignment & XBFONT_TRUNCATED )
    {
      if ( maxPixelWidth <= 0.0f || GetTextWidthInternal(text.begin(), text.end()) <= maxPixelWidth)
        alignment &= ~XBFONT_TRUNCATED;
    }
    else if ( alignment & XBFONT_JUSTIFIED )
    {
      if ( maxPixelWidth <= 0.0f )
        alignment &= ~XBFONT_JUSTIFIED;
    }

    // calculate sizing information
    float startX = 0;
    float startY = (alignment & XBFONT_CENTER_Y) ? -0.5f*m_cellHeight : 0;  // vertical centering

    if ( alignment & (XBFONT_RIGHT | XBFONT_CENTER_X) )
    {
      // Get the extent of this line
      float w = GetTextWidthInternal( text.begin(), text.end() );

      if ( alignment & XBFONT_TRUNCATED && w > maxPixelWidth + 0.5f ) // + 0.5f due to rounding issues
        w = maxPixelWidth;

      if ( alignment & XBFONT_CENTER_X)
        w *= 0.5f;
      // Offset this line's starting position
      startX -= w;
    }

    float spacePerSpaceCharacter = 0; // for justification effects
    if ( alignment & XBFONT_JUSTIFIED )
    {
      // first compute the size of the text to render in both characters and pixels
      unsigned int numSpaces = 0;
      float linePixels = 0;
      for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos)
      {
        Character *ch = GetCharacter(*pos);
        if (ch)
        {
          if ((*pos & 0xffff) == L' ')
            numSpaces +=  1;
          linePixels += ch->advance;
        }
      }
      if (numSpaces > 0)
        spacePerSpaceCharacter = (maxPixelWidth - linePixels) / numSpaces;
    }

    float cursorX = 0; // current position along the line

    // Collect all the Character info in a first pass, in case any of them
    // are not currently cached and cause the texture to be enlarged, which
    // would invalidate the texture coordinates.
    std::queue<Character> characters;
    if (alignment & XBFONT_TRUNCATED)
      GetCharacter(L'.');
    for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos)
    {
      Character *ch = GetCharacter(*pos);
      if (!ch)
      {
        Character null = { 0 };
        characters.push(null);
        continue;
      }
      characters.push(*ch);

      if (maxPixelWidth > 0 &&
          cursorX + ((alignment & XBFONT_TRUNCATED) ? ch->advance + 3 * m_ellipsesWidth : 0) > maxPixelWidth)
        break;
      cursorX += ch->advance;
    }
    cursorX = 0;

    for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos)
    {
      // If starting text on a new line, determine justification effects
      // Get the current letter in the CStdString
      color_t color = (*pos & 0xff0000) >> 16;
      if (color >= colors.size())
        color = 0;
      color = colors[color];

      // grab the next character
      Character *ch = &characters.front();
      if (ch->letterAndStyle == 0)
      {
        characters.pop();
        continue;
      }

      if ( alignment & XBFONT_TRUNCATED )
      {
        // Check if we will be exceeded the max allowed width
        if ( cursorX + ch->advance + 3 * m_ellipsesWidth > maxPixelWidth )
        {
          // Yup. Let's draw the ellipses, then bail
          // Perhaps we should really bail to the next line in this case??
          Character *period = GetCharacter(L'.');
          if (!period)
            break;

          for (int i = 0; i < 3; i++)
          {
            RenderCharacter(startX + cursorX, startY, period, color, !scrolling, *tempVertices);
            cursorX += period->advance;
          }
          break;
        }
      }
      else if (maxPixelWidth > 0 && cursorX > maxPixelWidth)
        break;  // exceeded max allowed width - stop rendering

      RenderCharacter(startX + cursorX, startY, ch, color, !scrolling, *tempVertices);
      if ( alignment & XBFONT_JUSTIFIED )
      {
        if ((*pos & 0xffff) == L' ')
          cursorX += ch->advance + spacePerSpaceCharacter;
        else
          cursorX += ch->advance;
      }
      else
        cursorX += ch->advance;
      characters.pop();
    }
    if (hardwareClipping)
    {
      CVertexBuffer &vertexBuffer = m_dynamicCache.Lookup(dynamicPos,
                                                          colors, text,
                                                          rawAlignment, maxPixelWidth,
                                                          scrolling,
                                                          XbmcThreads::SystemClockMillis(),
                                                          dirtyCache);
      CVertexBuffer newVertexBuffer = CreateVertexBuffer(*tempVertices);
      vertexBuffer = newVertexBuffer;
      m_vertexTrans.push_back(CTranslatedVertices(0, 0, 0, &vertexBuffer, g_graphicsContext.GetClipRegion()));
    }
    else
    {
      m_staticCache.Lookup(staticPos,
                           colors, text,
                           rawAlignment, maxPixelWidth,
                           scrolling,
                           XbmcThreads::SystemClockMillis(),
                           dirtyCache) = *static_cast<CGUIFontCacheStaticValue *>(&tempVertices);
      /* Append the new vertices to the set collected since the first Begin() call */
      m_vertex.insert(m_vertex.end(), tempVertices->begin(), tempVertices->end());
    }
  }
  else
  {
    if (hardwareClipping)
Пример #3
0
    else
    {
      m_staticCache.Lookup(staticPos,
                           colors, text,
                           rawAlignment, maxPixelWidth,
                           scrolling,
                           XbmcThreads::SystemClockMillis(),
                           dirtyCache) = *static_cast<CGUIFontCacheStaticValue *>(&tempVertices);
      /* Append the new vertices to the set collected since the first Begin() call */
      m_vertex.insert(m_vertex.end(), tempVertices->begin(), tempVertices->end());
    }
  }
  else
  {
    if (hardwareClipping)
      m_vertexTrans.push_back(CTranslatedVertices(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer, CServiceBroker::GetWinSystem()->GetGfxContext().GetClipRegion()));
    else
      /* Append the vertices from the cache to the set collected since the first Begin() call */
      m_vertex.insert(m_vertex.end(), vertices->begin(), vertices->end());
  }

  End();
}

// this routine assumes a single line (i.e. it was called from GUITextLayout)
float CGUIFontTTFBase::GetTextWidthInternal(vecText::const_iterator start, vecText::const_iterator end)
{
  float width = 0;
  while (start != end)
  {
    Character *c = GetCharacter(*start++);