Exemplo n.º 1
0
bool nuiTextLayout::PrintGlyphs(nuiDrawContext *pContext, float X, float Y, const std::map<nuiTexture*, std::vector<nuiTextGlyph*> >& rGlyphs, bool AlignGlyphPixels) const
{
  std::map<nuiTexture*, std::vector<nuiTextGlyph*> >::const_iterator it = rGlyphs.begin();
  std::map<nuiTexture*, std::vector<nuiTextGlyph*> >::const_iterator end = rGlyphs.end();
  
  bool texturing = pContext->GetState().mTexturing;
  nuiTexture* pOldTexture = pContext->GetTexture();
  if (pOldTexture)
    pOldTexture->Acquire();
  
  pContext->EnableTexturing(true);

  const float f = nuiGetScaleFactor();
  const float i_f = nuiGetInvScaleFactor();
  
  while (it != end)
  {
    nuiTexture* pTexture = it->first;
    pContext->SetTexture(pTexture);
    int size = (int)it->second.size();
    int i;
    
    nuiRenderArray* pArray = new nuiRenderArray(GL_TRIANGLES);
    pArray->EnableArray(nuiRenderArray::eVertex);
    pArray->EnableArray(nuiRenderArray::eTexCoord);
    pArray->EnableArray(nuiRenderArray::eColor);
    pArray->Reserve(6 * size);

    nuiColor textcolor = pContext->GetTextColor();
    
    for (i = 0; i < size; i++)
    {
      auto& run = *it;
      auto& glyph = *run.second[i];
      const nuiRect& rDest = glyph.mDestRect;
      const nuiRect& rSource = glyph.mSourceRect;

      if (glyph.mUseColor)
        pArray->SetColor(glyph.mColor);
      else
        pArray->SetColor(textcolor);

      nuiSize x1,y1,x2,y2;
      nuiSize tx,ty,tw,th;
      
      x1 = rDest.mLeft + X;
      y1 = rDest.mTop + Y;
      x2 = rDest.mRight + X;
      y2 = rDest.mBottom + Y;

      if (AlignGlyphPixels)
      {
        x1 = ToNearest(x1 * f) * i_f;
        y1 = ToNearest(y1 * f) * i_f;
        x2 = ToNearest(x2 * f) * i_f;
        y2 = ToNearest(y2 * f) * i_f;
      }
      
      tx = rSource.mLeft;
      ty = rSource.mTop;
      tw = rSource.mRight;
      th = rSource.mBottom;
      
      pTexture->ImageToTextureCoord(tx, ty);
      pTexture->ImageToTextureCoord(tw,th);
      
      ///////////////////////////////////////////
      pArray->SetVertex(x1, y1);
      pArray->SetTexCoords(tx, ty);
      pArray->PushVertex();
      
      pArray->SetVertex(x2, y1);
      pArray->SetTexCoords(tw, ty);
      pArray->PushVertex();
      
      pArray->SetVertex(x2, y2);
      pArray->SetTexCoords(tw, th);
      pArray->PushVertex();
      
      ///////////////////////////////////////////
      pArray->SetVertex(x1, y1);
      pArray->SetTexCoords(tx, ty);
      pArray->PushVertex();
      
      pArray->SetVertex(x2, y2);
      pArray->SetTexCoords(tw, th);
      pArray->PushVertex();
      
      pArray->SetVertex(x1, y2);
      pArray->SetTexCoords(tx, th);
      pArray->PushVertex();
    }
    
    //nglString str = pArray->Dump();
    //NGL_OUT("%s", str.GetChars());
    pContext->DrawArray(pArray);
    
    ++it;
  }
  
  pContext->EnableTexturing(texturing);
  pContext->SetTexture(pOldTexture);
  if (pOldTexture)
    pOldTexture->Release();
  
  return true;
}
Exemplo n.º 2
0
void nuiDrawContext::DrawRect(const nuiRect& rRect, nuiShapeMode Mode)
{

  if (Mode == eStrokeAndFillShape || Mode == eStrokeShape)
  {
    nuiRect rect(rRect);

    GLenum mode = GL_LINE_LOOP;

    if (rect.mRight - rect.mLeft <= 1.0f)
    {
      mode = GL_TRIANGLE_STRIP;
    }
    else
    {
      rect.mRight -= 1.0f;
    }
    
    if (rect.mBottom - rect.mTop <= 1.0f)
    {
      mode = GL_TRIANGLE_STRIP;
    }
    else
    {
      rect.mBottom -= 1.0f;
    }

    // Draw the stroke in all cases:
    if (mode == GL_TRIANGLE_STRIP)
    {
      nuiRenderArray* pStrokeArray = new nuiRenderArray(mode);
      pStrokeArray->EnableArray(nuiRenderArray::eVertex, true);
      pStrokeArray->EnableArray(nuiRenderArray::eColor, true);
      pStrokeArray->Reserve(4);
      
      pStrokeArray->SetColor(mCurrentState.mStrokeColor);
      pStrokeArray->SetVertex(rect.mLeft, rect.mTop);
      pStrokeArray->PushVertex();
      pStrokeArray->SetVertex(rect.mRight, rect.mTop);
      pStrokeArray->PushVertex();
      pStrokeArray->SetVertex(rect.mLeft, rect.mBottom);
      pStrokeArray->PushVertex();

      pStrokeArray->SetVertex(rect.mRight, rect.mBottom);
      pStrokeArray->PushVertex();

      DrawArray(pStrokeArray);
    }
    else
    {
      nuiRenderArray* pStrokeArray = new nuiRenderArray(mode);
      if (nuiGetScaleFactor() != 1.0f)
      {
        nuiDrawRect(rRect, *pStrokeArray);
      }
      else
      {
        pStrokeArray->EnableArray(nuiRenderArray::eVertex, true);
        pStrokeArray->EnableArray(nuiRenderArray::eColor, true);
        pStrokeArray->Reserve(4);
        
        pStrokeArray->SetColor(mCurrentState.mStrokeColor);
        pStrokeArray->SetVertex(rect.mLeft, rect.mTop);
        pStrokeArray->PushVertex();
        
        pStrokeArray->SetVertex(rect.mRight, rect.mTop);
        pStrokeArray->PushVertex();
        
        pStrokeArray->SetVertex(rect.mRight, rect.mBottom);
        pStrokeArray->PushVertex();
        
        pStrokeArray->SetVertex(rect.mLeft, rect.mBottom);
        pStrokeArray->PushVertex();
      }

      DrawArray(pStrokeArray);
    }
  }

  if (Mode == eStrokeAndFillShape)
  {
    if ((rRect.mRight - rRect.mLeft <= 2.0f) || (rRect.mBottom - rRect.mTop <= 2.0f))
      return;

    nuiRect rect(rRect);
    // Draw the filled part:
    nuiRenderArray* pFillArray = new nuiRenderArray(GL_TRIANGLE_STRIP);
    pFillArray->EnableArray(nuiRenderArray::eVertex, true);
    pFillArray->EnableArray(nuiRenderArray::eColor, true);
    pFillArray->Reserve(4);
    
    pFillArray->SetColor(mCurrentState.mFillColor);
    pFillArray->SetVertex(rect.mLeft+1, rect.mTop+1);
    pFillArray->PushVertex();

    pFillArray->SetVertex(rect.mRight-1, rect.mTop+1);
    pFillArray->PushVertex();

    pFillArray->SetVertex(rect.mLeft+1, rect.mBottom-1);
    pFillArray->PushVertex();
    
    pFillArray->SetVertex(rect.mRight-1, rect.mBottom-1);
    pFillArray->PushVertex();
    
    DrawArray(pFillArray);
  }
  else if (Mode == eFillShape)
  {
    nuiRect rect(rRect);
    //rect.Move(0,-.5); // Adjust to have a correct position on ATI cards, this should work on nvidia too
    // Draw the filled rectangle:
    nuiRenderArray* pFillArray = new nuiRenderArray(GL_TRIANGLE_STRIP);
    pFillArray->EnableArray(nuiRenderArray::eVertex, true);
    pFillArray->EnableArray(nuiRenderArray::eColor, true);
    pFillArray->Reserve(4);

    pFillArray->SetColor(mCurrentState.mFillColor);
    pFillArray->SetVertex(rect.mLeft, rect.mTop);
    pFillArray->PushVertex();

    pFillArray->SetVertex(rect.mRight, rect.mTop);
    pFillArray->PushVertex();

    pFillArray->SetVertex(rect.mLeft, rect.mBottom);
    pFillArray->PushVertex();
    
    pFillArray->SetVertex(rect.mRight, rect.mBottom);
    pFillArray->PushVertex();

    DrawArray(pFillArray);
  }
}