/*!*************************************************************************** @fn MeasureText @param[out] pfWidth Width of the string in pixels @param[out] pfHeight Height of the string in pixels @param[in] fFontSize Font size @param[in] sString String to take the size of @brief Returns the size of a string in pixels. *****************************************************************************/ void CPVRTPrint3D::MeasureText( float * const pfWidth, float * const pfHeight, float fScale, const CPVRTArray<PVRTuint32>& utf32) { #if !defined (DISABLE_PRINT3D) if(utf32.GetSize() == 0) { if(pfWidth) *pfWidth = 0; if(pfHeight) *pfHeight = 0; return; } float fLength = 0; float fMaxLength = -1.0f; float fMaxHeight = (float)m_uiNextLineH; PVRTuint32 txNextChar = 0; PVRTuint32 uiIdx; for(PVRTuint32 uiIndex = 0; uiIndex < utf32.GetSize(); uiIndex++) { if(utf32[uiIndex] == 0x0D || utf32[uiIndex] == 0x0A) { if(fLength > fMaxLength) fMaxLength = fLength; fLength = 0; fMaxHeight += (float)m_uiNextLineH; } uiIdx = FindCharacter(utf32[uiIndex]); if(uiIdx == PVRTPRINT3D_INVALID_CHAR) // No character found. Add a space. { fLength += m_uiSpaceWidth; continue; } float fKernOffset = 0; if ((uiIndex + 1) < utf32.GetSize()) { txNextChar = utf32[uiIndex + 1]; ApplyKerning(utf32[uiIndex], txNextChar, fKernOffset); } fLength += m_pCharMatrics[uiIdx].nAdv + fKernOffset; // Add on this characters width } if(fMaxLength < 0.0f) // Obviously no new line. fMaxLength = fLength; if(pfWidth) *pfWidth = fMaxLength * fScale; if(pfHeight) *pfHeight = fMaxHeight * fScale; #endif }
/*!*************************************************************************** @Function UpdateLine @Description *****************************************************************************/ unsigned int CPVRTPrint3D::UpdateLine(const float fZPos, float XPos, float YPos, const float fScale, const unsigned int Colour, const CPVRTArray<PVRTuint32>& Text, SPVRTPrint3DAPIVertex * const pVertices) { /* Nothing to update */ if (Text.GetSize() == 0) return 0; if(!m_bUsingProjection) { XPos *= m_fScreenScale[0]; YPos *= m_fScreenScale[1]; } YPos -= PVRTMakeWhole(m_uiAscent * fScale); float fPreXPos = XPos; // The original offset (after screen scale modification) of the X coordinate. float fKernOffset; float fAOff; float fYOffset; unsigned int VertexCount = 0; PVRTint32 NextChar; unsigned int uiNumCharsInString = Text.GetSize(); for(unsigned int uiIndex = 0; uiIndex < uiNumCharsInString; uiIndex++) { if(uiIndex > MAX_LETTERS) break; // Newline if(Text[uiIndex] == 0x0A) { XPos = fPreXPos; YPos -= PVRTMakeWhole(m_uiNextLineH * fScale); continue; } // Get the character PVRTuint32 uiIdx = FindCharacter(Text[uiIndex]); // Not found. Add a space. if(uiIdx == PVRTPRINT3D_INVALID_CHAR) // No character found. Add a space. { XPos += PVRTMakeWhole(m_uiSpaceWidth * fScale); continue; } fKernOffset = 0; fYOffset = PVRTMakeWhole(m_pYOffsets[uiIdx] * fScale); fAOff = PVRTMakeWhole(m_pCharMatrics[uiIdx].nXOff * fScale); // The A offset. Could include overhang or underhang. if(uiIndex < uiNumCharsInString - 1) { NextChar = Text[uiIndex + 1]; ApplyKerning(Text[uiIndex], NextChar, fKernOffset); } /* Filling vertex data */ pVertices[VertexCount+0].sx = f2vt(XPos + fAOff + 0.0f); pVertices[VertexCount+0].sy = f2vt(YPos + fYOffset + 0.0f); pVertices[VertexCount+0].sz = f2vt(fZPos); pVertices[VertexCount+0].rhw = f2vt(1.0f); pVertices[VertexCount+0].tu = f2vt(m_pUVs[uiIdx].fUL); pVertices[VertexCount+0].tv = f2vt(m_pUVs[uiIdx].fVT); pVertices[VertexCount+1].sx = f2vt(XPos + fAOff + PVRTMakeWhole(m_pRects[uiIdx].nW * fScale)); pVertices[VertexCount+1].sy = f2vt(YPos + fYOffset + 0.0f); pVertices[VertexCount+1].sz = f2vt(fZPos); pVertices[VertexCount+1].rhw = f2vt(1.0f); pVertices[VertexCount+1].tu = f2vt(m_pUVs[uiIdx].fUR); pVertices[VertexCount+1].tv = f2vt(m_pUVs[uiIdx].fVT); pVertices[VertexCount+2].sx = f2vt(XPos + fAOff + 0.0f); pVertices[VertexCount+2].sy = f2vt(YPos + fYOffset - PVRTMakeWhole(m_pRects[uiIdx].nH * fScale)); pVertices[VertexCount+2].sz = f2vt(fZPos); pVertices[VertexCount+2].rhw = f2vt(1.0f); pVertices[VertexCount+2].tu = f2vt(m_pUVs[uiIdx].fUL); pVertices[VertexCount+2].tv = f2vt(m_pUVs[uiIdx].fVB); pVertices[VertexCount+3].sx = f2vt(XPos + fAOff + PVRTMakeWhole(m_pRects[uiIdx].nW * fScale)); pVertices[VertexCount+3].sy = f2vt(YPos + fYOffset - PVRTMakeWhole(m_pRects[uiIdx].nH * fScale)); pVertices[VertexCount+3].sz = f2vt(fZPos); pVertices[VertexCount+3].rhw = f2vt(1.0f); pVertices[VertexCount+3].tu = f2vt(m_pUVs[uiIdx].fUR); pVertices[VertexCount+3].tv = f2vt(m_pUVs[uiIdx].fVB); pVertices[VertexCount+0].color = Colour; pVertices[VertexCount+1].color = Colour; pVertices[VertexCount+2].color = Colour; pVertices[VertexCount+3].color = Colour; XPos = XPos + PVRTMakeWhole((m_pCharMatrics[uiIdx].nAdv + fKernOffset) * fScale); // Add on this characters width VertexCount += 4; } return VertexCount; }