Note that there are some explanatory texts on larger screens.

plurals
  1. POBetter, or advantages in different ways of coding similar functions
    text
    copied!<p>I'm writing the code for a GUI (in C++), and right now I'm concerned with the organisation of text in lines. One of the problems I'm having is that the code is getting very long and confusing, and I'm starting to get into a n^2 scenario where for every option I add in for the texts presentation, the number of functions I have to write is the square of that. In trying to deal with this, A particular design choice has come up, and I don't know the better method, or the extent of the advantages or disadvantages between them:</p> <p>I have two methods which are very similar in flow, i.e, iterate through the same objects, taking into account the same constraints, but ultimately perform different operations between this flow. For anyones interest, the methods render the text, and determine if any text overflows the line due to wrapping the text around other objects or simply the end of the line respectively.</p> <p>These functions need to be copied and rewritten for left, right or centred text, which have different flow, so whatever design choice I make would be repeated three times.</p> <p>Basically, I could continue what I have now, which is two separate methods to handle these different actions, or I could merge them into one function, which has if statements within it to determine whether or not to render the text or figure out if any text overflows.</p> <p>Is there a generally accepted right way to going about this? Otherwise, what are the tradeoffs concerned, what are the signs that might indicate one way should be used over the other? Is there some other way of doing things I've missed?</p> <p>I've edited through this a few times to try and make it more understandable, but if it isn't please ask me some questions so I can edit and explain. I can also post the source code of the two different methods, but they use a lot of functions and objects that would take too long to explain.</p> <p>// EDIT: Source Code //</p> <p>Function 1:</p> <blockquote> <p>void GUITextLine::renderLeftShifted(const GUIRenderInfo&amp; renderInfo) { if(m_renderLines.empty()) return;</p> <pre><code>Uint iL = 0; Array2t&lt;float&gt; renderCoords; renderCoords.s_x = renderInfo.s_offset.s_x + m_renderLines[0].s_x; renderCoords.s_y = renderInfo.s_offset.s_y + m_y; float remainingPixelsInLine = m_renderLines[0].s_y; for (Uint iTO= 0;iTO != m_text.size();++iTO) { if(m_text[iTO].s_pixelWidth &lt;= remainingPixelsInLine) { string preview = m_text[iTO].s_string; m_text[iTO].render(&amp;renderCoords); remainingPixelsInLine -= m_text[iTO].s_pixelWidth; } else { FSInternalGlyphData intData = m_text[iTO].stealFSFastFontInternalData(); float characterWidth = 0; Uint iFirstCharacterOfRenderLine = 0; for(Uint iC = 0;;++iC) { if(iC == m_text[iTO].s_string.size()) { // wrap up string renderPart = m_text[iTO].s_string; renderPart.erase(iC, renderPart.size()); renderPart.erase(0, iFirstCharacterOfRenderLine); m_text[iTO].s_font-&gt;renderString(renderPart.c_str(), intData, &amp;renderCoords); break; } characterWidth += m_text[iTO].s_font-&gt;getWidthOfGlyph(intData, m_text[iTO].s_string[iC]); if(characterWidth &gt; remainingPixelsInLine) { // Can't push in the last character // No more space in this line // First though, render what we already have: string renderPart = m_text[iTO].s_string; renderPart.erase(iC, renderPart.size()); renderPart.erase(0, iFirstCharacterOfRenderLine); m_text[iTO].s_font-&gt;renderString(renderPart.c_str(), intData, &amp;renderCoords); if(++iL != m_renderLines.size()) { remainingPixelsInLine = m_renderLines[iL].s_y; renderCoords.s_x = renderInfo.s_offset.s_x + m_renderLines[iL].s_x; // Cool, so now try rendering this character again --iC; iFirstCharacterOfRenderLine = iC; characterWidth = 0; } else { // Quit break; } } } } } // Done! } </code></pre> </blockquote> <p>Function 2:</p> <blockquote> <p>vector GUITextLine::recalculateWrappingContraints_LeftShift() { m_pixelsOfCharacters = 0;</p> <pre><code>float pixelsRemaining = m_renderLines[0].s_y; Uint iRL = 0; // Go through every text object, fiting them into render lines for(Uint iTO = 0;iTO != m_text.size();++iTO) { // If an entire text object fits in a single line if(pixelsRemaining &gt;= m_text[iTO].s_pixelWidth) { pixelsRemaining -= m_text[iTO].s_pixelWidth; m_pixelsOfCharacters += m_text[iTO].s_pixelWidth; } // Otherwise, character by character else { // Get some data now we don't get it every function call FSInternalGlyphData intData = m_text[iTO].stealFSFastFontInternalData(); for(Uint iC = 0; iC != m_text[iTO].s_string.size();++iC) { float characterWidth = m_text[iTO].s_font-&gt;getWidthOfGlyph(intData, '-'); if(characterWidth &lt; pixelsRemaining) { pixelsRemaining -= characterWidth; m_pixelsOfCharacters += characterWidth; } else // End of render line! { m_pixelsOfWrapperCharacters += pixelsRemaining; // we might track how much wrapping px we use // If this is true, then we ran out of render lines before we ran out of text. Means we have some overflow to return if(++iRL == m_renderLines.size()) { return harvestOverflowFrom(iTO, iC); } else { pixelsRemaining = m_renderLines[iRL].s_y; } } } } } vector&lt;GUIText&gt; emptyOverflow; return emptyOverflow; } </code></pre> </blockquote> <p>So basically, render() takes renderCoordinates as a parameter and gets from it the global position of where it needs to render from. calcWrappingConstraints figures out how much text in the object goes over the allocated space, and returns that text as a function.</p> <p>m_renderLines is an std::vector of a two float structure, where .s_x = where rendering can start and .s_y = how large the space for rendering is - not, its essentially width of the 'renderLine', not where it ends.</p> <p>m_text is an std::vector of GUIText objects, which contain a string of text, and some data, like style, colour, size ect. It also contains under s_font, a reference to a font object, which performs rendering, calculating the width of a glyph, ect.</p> <p>Hopefully this clears things up.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload