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; }
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); } }