diff --git a/src/common/StringMap.h b/src/common/StringMap.h index 682626519..7fa1f9b54 100644 --- a/src/common/StringMap.h +++ b/src/common/StringMap.h @@ -70,7 +70,7 @@ public: for (unsigned i = 0; i < MAX; ++i) { - unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? + unsigned str_i = (str_hash + i) % MAX; if (!records[str_i].set) return false; diff --git a/src/modules/graphics/opengl/Font.cpp b/src/modules/graphics/opengl/Font.cpp index 0fb3cb3cb..c6280471e 100644 --- a/src/modules/graphics/opengl/Font.cpp +++ b/src/modules/graphics/opengl/Font.cpp @@ -258,7 +258,7 @@ float Font::getHeight() const return static_cast(height); } -void Font::print(const std::string &text, float x, float y, float letter_spacing, float angle, float sx, float sy, float ox, float oy, float kx, float ky) +void Font::print(const std::string &text, float x, float y, float extra_spacing, float angle, float sx, float sy, float ox, float oy, float kx, float ky) { // Spacing counter and newline handling. float dx = 0.0f; @@ -320,7 +320,11 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing } // Advance the x position for the next glyph. - dx += glyph->spacing + letter_spacing; + dx += glyph->spacing; + + // Account for extra spacing given to space characters. + if (g == ' ' && extra_spacing != 0.0f) + dx = floorf(dx + extra_spacing); } } catch (utf8::exception &e) @@ -403,7 +407,7 @@ int Font::getWidth(char character) return g->spacing; } -std::vector Font::getWrap(const std::string &text, float wrap, int *max_width) +std::vector Font::getWrap(const std::string &text, float wrap, int *max_width, std::vector *wrappedlines) { using namespace std; const float width_space = static_cast(getWidth(' ')); @@ -445,6 +449,10 @@ std::vector Font::getWrap(const std::string &text, float wrap, int realw -= (int) width; if (realw > maxw) maxw = realw; + + // Indicate that this line was automatically wrapped. + if (wrappedlines) + wrappedlines->push_back(true); } string_builder << word << " "; width += width_space; @@ -455,6 +463,10 @@ std::vector Font::getWrap(const std::string &text, float wrap, int maxw = (int) width; string tmp = string_builder.str(); lines_to_draw.push_back(tmp.substr(0,tmp.size()-1)); + + // Indicate that this line was not automatically wrapped. + if (wrappedlines) + wrappedlines->push_back(false); } if (max_width) diff --git a/src/modules/graphics/opengl/Font.h b/src/modules/graphics/opengl/Font.h index 207f94071..c8715cd44 100644 --- a/src/modules/graphics/opengl/Font.h +++ b/src/modules/graphics/opengl/Font.h @@ -59,7 +59,7 @@ public: * @param text A string. * @param x The x-coordinate. * @param y The y-coordinate. - * @param letter_spacing Additional spacing between letters. + * @param extra_spacing Additional spacing added to spaces (" "). * @param angle The amount of rotation. * @param sx Scale along the x axis. * @param sy Scale along the y axis. @@ -68,7 +68,7 @@ public: * @param kx Shear along the x axis. * @param ky Shear along the y axis. **/ - void print(const std::string &text, float x, float y, float letter_spacing = 0.0f, float angle = 0.0f, float sx = 1.0f, float sy = 1.0f, float ox = 0.0f, float oy = 0.0f, float kx = 0.0f, float ky = 0.0f); + void print(const std::string &text, float x, float y, float extra_spacing = 0.0f, float angle = 0.0f, float sx = 1.0f, float sy = 1.0f, float ox = 0.0f, float oy = 0.0f, float kx = 0.0f, float ky = 0.0f); /** * Returns the height of the font. @@ -96,9 +96,11 @@ public: * @param text The input text * @param wrap The number of pixels to wrap at * @param max_width Optional output of the maximum width + * @param wrapped_lines Optional output indicating which lines were + * auto-wrapped. Indices correspond to indices of the returned value. * Returns a vector with the lines. **/ - std::vector getWrap(const std::string &text, float wrap, int *max_width = 0); + std::vector getWrap(const std::string &text, float wrap, int *max_width = 0, std::vector *wrapped_lines = 0); /** * Sets the line height (which should be a number to multiply the font size by, diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 3352a769a..a08921eba 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -791,7 +791,10 @@ void Graphics::printf(const std::string &str, float x, float y, float wrap, Alig using std::string; using std::vector; - vector lines_to_draw = currentFont->getWrap(str, wrap); + // wrappedlines indicates which lines were automatically wrapped. It's + // guaranteed to have the same number of elements as lines_to_draw. + vector wrappedlines; + vector lines_to_draw = currentFont->getWrap(str, wrap, 0, &wrappedlines); glPushMatrix(); @@ -805,7 +808,10 @@ void Graphics::printf(const std::string &str, float x, float y, float wrap, Alig { // now for the actual printing vector::const_iterator line_iter, line_end = lines_to_draw.end(); - float letter_spacing = 0.0f; + float extra_spacing = 0.0f; + int num_spaces = 0; + int i = 0; + for (line_iter = lines_to_draw.begin(); line_iter != line_end; ++line_iter) { float width = static_cast(currentFont->getWidth(*line_iter)); @@ -818,11 +824,12 @@ void Graphics::printf(const std::string &str, float x, float y, float wrap, Alig currentFont->print(*line_iter, ceil(x + (wrap - width) / 2), ceil(y), 0.0f); break; case ALIGN_JUSTIFY: - if (line_iter->length() > 1) - letter_spacing = (wrap - width) / float(line_iter->length() - 1); + num_spaces = std::count(line_iter->begin(), line_iter->end(), ' '); + if (wrappedlines[i] && num_spaces >= 1) + extra_spacing = (wrap - width) / float(num_spaces); else - letter_spacing = 0.0f; - currentFont->print(*line_iter, ceil(x), ceil(y), letter_spacing); + extra_spacing = 0.0f; + currentFont->print(*line_iter, ceil(x), ceil(y), extra_spacing); break; case ALIGN_LEFT: default: @@ -830,6 +837,7 @@ void Graphics::printf(const std::string &str, float x, float y, float wrap, Alig break; } y += currentFont->getHeight() * currentFont->getLineHeight(); + i++; } } catch (love::Exception &)