void Graphics::drawMultiLineText (const String& text, const int startX, const int baselineY, const int maximumLineWidth) const { if (text.isNotEmpty() && startX < context->getClipBounds().getRight()) { GlyphArrangement arr; arr.addJustifiedText (context->getFont(), text, (float) startX, (float) baselineY, (float) maximumLineWidth, Justification::left); arr.draw (*this); } }
void GlyphArrangement::addLinesWithLineBreaks (const String& text, const Font& f, float x, float y, float width, float height, Justification layout) { GlyphArrangement ga; ga.addJustifiedText (f, text, x, y, width, layout); const Rectangle<float> bb (ga.getBoundingBox (0, -1, false)); float dy = y - bb.getY(); if (layout.testFlags (Justification::verticallyCentred)) dy += (height - bb.getHeight()) * 0.5f; else if (layout.testFlags (Justification::bottom)) dy += (height - bb.getHeight()); ga.moveRangeOfGlyphs (0, -1, 0.0f, dy); glyphs.addArray (ga.glyphs); }
void paint(Graphics& g) { // The following code is basically the same as // Graphics::drawMultiLineText but with centered text int startX = 20; int baselineY = getHeight() / 2; int maximumLineWidth = getWidth() - 40; LowLevelGraphicsContext& context = g.getInternalContext(); if (textToShow.isNotEmpty() && startX < context.getClipBounds().getRight()) { GlyphArrangement arr; arr.addJustifiedText(context.getFont(), textToShow, (float) startX, (float) baselineY, (float) maximumLineWidth, Justification::centred); arr.draw(g); } }
const int EdoChatWindowMessage::getMessageHeight(const int parentWidth, const Justification justification) { GlyphArrangement messageGlyphs; float top,left,right,bottom; applyOptions(); messageGlyphs.clear(); messageGlyphs.addJustifiedText ( EdoRestoreFont (getPropertyString(EWND_MESSAGE_FONT), Font(14)), messageLabel->getText(), 0, 0, (float)parentWidth, justification ); messageGlyphs.getBoundingBox (0, -1, left, top, right, bottom, true); messageHeight = roundFloatToInt ((bottom - top) + SPACER); // Log (String::formatted (T("EdoChatWindowMessage::getMessageHeight parentWidth: %d height: %d"), parentWidth, messageHeight)); if (avatar->isVisible()) { if (messageHeight < (avatar->getHeight()+16)) { messageHeight = avatar->getHeight()+16; return (messageHeight+SPACER); } else { return (messageHeight+SPACER); } } else { return (messageHeight+SPACER); } }
void GlyphArrangement::addFittedText (const Font& f, const String& text, const float x, const float y, const float width, const float height, const Justification& layout, int maximumLines, const float minimumHorizontalScale) { // doesn't make much sense if this is outside a sensible range of 0.5 to 1.0 jassert (minimumHorizontalScale > 0 && minimumHorizontalScale <= 1.0f); if (text.containsAnyOf ("\r\n")) { GlyphArrangement ga; ga.addJustifiedText (f, text, x, y, width, layout); const Rectangle<float> bb (ga.getBoundingBox (0, -1, false)); float dy = y - bb.getY(); if (layout.testFlags (Justification::verticallyCentred)) dy += (height - bb.getHeight()) * 0.5f; else if (layout.testFlags (Justification::bottom)) dy += height - bb.getHeight(); ga.moveRangeOfGlyphs (0, -1, 0.0f, dy); glyphs.ensureStorageAllocated (glyphs.size() + ga.glyphs.size()); for (int i = 0; i < ga.glyphs.size(); ++i) glyphs.add (ga.glyphs.getUnchecked (i)); ga.glyphs.clear (false); return; } int startIndex = glyphs.size(); addLineOfText (f, text.trim(), x, y); if (glyphs.size() > startIndex) { float lineWidth = glyphs.getUnchecked (glyphs.size() - 1)->getRight() - glyphs.getUnchecked (startIndex)->getLeft(); if (lineWidth <= 0) return; if (lineWidth * minimumHorizontalScale < width) { if (lineWidth > width) stretchRangeOfGlyphs (startIndex, glyphs.size() - startIndex, width / lineWidth); justifyGlyphs (startIndex, glyphs.size() - startIndex, x, y, width, height, layout); } else if (maximumLines <= 1) { fitLineIntoSpace (startIndex, glyphs.size() - startIndex, x, y, width, height, f, layout, minimumHorizontalScale); } else { Font font (f); String txt (text.trim()); const int length = txt.length(); const int originalStartIndex = startIndex; int numLines = 1; if (length <= 12 && ! txt.containsAnyOf (" -\t\r\n")) maximumLines = 1; maximumLines = jmin (maximumLines, length); while (numLines < maximumLines) { ++numLines; const float newFontHeight = height / (float) numLines; if (newFontHeight < font.getHeight()) { font.setHeight (jmax (8.0f, newFontHeight)); removeRangeOfGlyphs (startIndex, -1); addLineOfText (font, txt, x, y); lineWidth = glyphs.getUnchecked (glyphs.size() - 1)->getRight() - glyphs.getUnchecked (startIndex)->getLeft(); } if (numLines > lineWidth / width || newFontHeight < 8.0f) break; } if (numLines < 1) numLines = 1; float lineY = y; float widthPerLine = lineWidth / numLines; int lastLineStartIndex = 0; for (int line = 0; line < numLines; ++line) { int i = startIndex; lastLineStartIndex = i; float lineStartX = glyphs.getUnchecked (startIndex)->getLeft(); if (line == numLines - 1) { widthPerLine = width; i = glyphs.size(); } else { while (i < glyphs.size()) { lineWidth = (glyphs.getUnchecked (i)->getRight() - lineStartX); if (lineWidth > widthPerLine) { // got to a point where the line's too long, so skip forward to find a // good place to break it.. const int searchStartIndex = i; while (i < glyphs.size()) { if ((glyphs.getUnchecked (i)->getRight() - lineStartX) * minimumHorizontalScale < width) { if (glyphs.getUnchecked (i)->isWhitespace() || glyphs.getUnchecked (i)->getCharacter() == '-') { ++i; break; } } else { // can't find a suitable break, so try looking backwards.. i = searchStartIndex; for (int back = 1; back < jmin (5, i - startIndex - 1); ++back) { if (glyphs.getUnchecked (i - back)->isWhitespace() || glyphs.getUnchecked (i - back)->getCharacter() == '-') { i -= back - 1; break; } } break; } ++i; } break; } ++i; } int wsStart = i; while (wsStart > 0 && glyphs.getUnchecked (wsStart - 1)->isWhitespace()) --wsStart; int wsEnd = i; while (wsEnd < glyphs.size() && glyphs.getUnchecked (wsEnd)->isWhitespace()) ++wsEnd; removeRangeOfGlyphs (wsStart, wsEnd - wsStart); i = jmax (wsStart, startIndex + 1); } i -= fitLineIntoSpace (startIndex, i - startIndex, x, lineY, width, font.getHeight(), font, layout.getOnlyHorizontalFlags() | Justification::verticallyCentred, minimumHorizontalScale); startIndex = i; lineY += font.getHeight(); if (startIndex >= glyphs.size()) break; } justifyGlyphs (originalStartIndex, glyphs.size() - originalStartIndex, x, y, width, height, layout.getFlags() & ~Justification::horizontallyJustified); } } }