示例#1
0
float TEXT_DRAW::RenderText(
	const FONT & font, const std::string & text,
	float x, float y, float scalex, float scaley,
	VERTEXARRAY & output_array)
{
	output_array.Clear();
	float cursorx = x;
	float cursory = y  + scaley / 4;
	for (unsigned int i = 0; i < text.size(); ++i)
	{
		if (text[i] == '\n')
		{
			cursorx = x;
			cursory += scaley;
		}
		else
		{
			cursorx += RenderCharacter(font, text[i], cursorx, cursory, scalex, scaley, output_array);
		}
	}
	return cursorx;
}
示例#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
void CGControlSys::Render( dword dwOption)
{
//	CanDrawTerrain(false);
	
	if( !m_bReadyForRender ) return;
	
//	DLogWriteSystem( "in GControl::Render()" );

	static time_t timePrev = timeGetTime();
	time_t timeProgress = timeGetTime()-timePrev;
	float fRatio = (float)((timeProgress)%1000)/1000.0f;
	float fFrameMorphing = (float)(timeGetTime()%1000)/1000.0f*30.0f;
	static time_t timePrevSky = timePrev;
	static time_t timeNowSky = timePrev;
	timeNowSky+=timeProgress;

	// ::
	// Sky and Environment
	// ::
	DRenderUtil().UpdateRenderState( DRenderUtility::SblkEnvironment, DRenderBatch::s_bForceWireFrame, 0x01 );

//	m_NeoEnvironment.Render( m_Timer.fProgressRatio );
	m_Environment.Render();

	DLightActor::s_bDay = m_NeoEnvironment.IsDay();

	// Light Off
	Scud::ClearLightList();
	
	// Apply Environmental Global Light (single)
	//m_Environment.ApplyLightState( m_Environment.GetLightState( true ) );
	Scud::PushLight( m_NeoEnvironment.GlobalLightInstance() );
	Scud::UpdateLightOnDevice();

	Scud::SetAmbientLight( m_NeoEnvironment.Ambient() );

	m_aVisibleDynamicActorList.Initialize();

	DRenderUtil().UpdateRenderState( DRenderUtility::SblkNormal, false, m_NeoEnvironment.AlphaRef() ); //B4=180
	GSmallActor::s_dwAlphaRef = 0x96;
	
	// ::
	// Render All Visible Actor
	// ::
	BuildVisibleList();
	
	// 2004/03/23 by impurity
	DRenderUtil().UpdateRenderState( DRenderUtility::SblkNormal, false, m_NeoEnvironment.AlphaRef() ); //B4=180
	
	RenderMapObject();

	if( 1 ) //m_bRenderEnable ) // added by findfun. [Full]
		RenderCharacter();

	RenderMapAlpha();

	RenderEffect();
	
	// ::
	// Character Extra
	// ::
	GDynamicActor::GrpRenderExtra();
	
	// 2004/02/24 by impurity
	m_mngTransition.Render();
}