Exemple #1
0
 vector<string> fullJustify(vector<string> &words, int L) {
     vector<string> lines;
     vector<string> wordsInLine;
     int num = static_cast<int>(words.size());
     int wordCnt = 0;
     int wordLen = 0;
     for (int i = 0; i < num; ++i) {
         string word = words[i];
         //  could we add this word into the current line?
         if (wordLen + word.size() + wordCnt <= L) {
             wordLen += word.size();
             ++wordCnt;
             wordsInLine.push_back(word);
         } else {
             lines.push_back(justifyLine(wordsInLine, L, false));
             wordsInLine.clear();
             wordsInLine.push_back(word);
             wordLen = word.size();
             wordCnt = 1;
         }
     }
     lines.push_back(justifyLine(wordsInLine, L, true));
     return lines;
 }
 vector<string> fullJustify(vector<string>& words, int maxWidth) {
     if(words.size() == 0) return words;
     int left = 0, width = -1;
     vector<string> res;
     for(int i = 0; i < words.size(); ++i) {
     	width = width + 1 + words[i].size();
     	if(width <= maxWidth) continue;
     	justifyLine(res, words, left, i-1, width-1-words[i].size(), maxWidth);
     	left = i;
     	width = -1;
     	i--;
     }
     string out;
     while(left != words.size()) {
     	out += words[left];
     	if(out.size() < maxWidth) out += " ";
     	left++;
     }
     while(out.size() != maxWidth) {
     	out += " ";
     }
     res.push_back(out);
     return res;
 }
void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, const float maxWidth,
                         const float horizontalAlign, const float verticalAlign,
                         const float justify, const Point<float> &translate) const {
    uint32_t lastSafeBreak = 0;

    uint32_t lengthBeforeCurrentLine = 0;
    uint32_t lineStartIndex = 0;
    uint32_t line = 0;

    uint32_t maxLineLength = 0;

    std::vector<PositionedGlyph> &positionedGlyphs = shaping.positionedGlyphs;

    if (maxWidth) {
        for (uint32_t i = 0; i < positionedGlyphs.size(); i++) {
            PositionedGlyph &shape = positionedGlyphs[i];

            shape.x -= lengthBeforeCurrentLine;
            shape.y += lineHeight * line;

            if (shape.x > maxWidth && lastSafeBreak > 0) {

                uint32_t lineLength = positionedGlyphs[lastSafeBreak + 1].x;
                maxLineLength = util::max(lineLength, maxLineLength);

                for (uint32_t k = lastSafeBreak + 1; k <= i; k++) {
                    positionedGlyphs[k].y += lineHeight;
                    positionedGlyphs[k].x -= lineLength;
                }

                if (justify) {
                    // Collapse invisible characters.
                    uint32_t breakGlyph = positionedGlyphs[lastSafeBreak].glyph;
                    uint32_t lineEnd = lastSafeBreak;
                    if (breakGlyph == 0x20 /* space */
                        || breakGlyph == 0x200b /* zero-width space */) {
                        lineEnd--;
                    }

                    justifyLine(positionedGlyphs, sdfs, lineStartIndex, lineEnd, justify);
                }

                lineStartIndex = lastSafeBreak + 1;
                lastSafeBreak = 0;
                lengthBeforeCurrentLine += lineLength;
                line++;
            }

            // Spaces, plus word-breaking punctuation that often appears without surrounding spaces.
            if (shape.glyph == 0x20 /* space */
                || shape.glyph == 0x26 /* ampersand */
                || shape.glyph == 0x2b /* plus sign */
                || shape.glyph == 0x2d /* hyphen-minus */
                || shape.glyph == 0x2f /* solidus */
                || shape.glyph == 0xad /* soft hyphen */
                || shape.glyph == 0xb7 /* middle dot */
                || shape.glyph == 0x200b /* zero-width space */
                || shape.glyph == 0x2010 /* hyphen */
                || shape.glyph == 0x2013 /* en dash */) {
                lastSafeBreak = i;
            }
        }
    }

    const PositionedGlyph& lastPositionedGlyph = positionedGlyphs.back();
    const auto lastGlyphIt = sdfs.find(lastPositionedGlyph.glyph);
    assert(lastGlyphIt != sdfs.end());
    const uint32_t lastLineLength = lastPositionedGlyph.x + lastGlyphIt->second.metrics.advance;
    maxLineLength = std::max(maxLineLength, lastLineLength);

    const uint32_t height = (line + 1) * lineHeight;

    justifyLine(positionedGlyphs, sdfs, lineStartIndex, uint32_t(positionedGlyphs.size()) - 1, justify);
    align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line, translate);

    // Calculate the bounding box
    shaping.top += -verticalAlign * height;
    shaping.bottom = shaping.top + height;
    shaping.left += -horizontalAlign * maxLineLength;
    shaping.right = shaping.left + maxLineLength;
}
void FontStack::lineWrap(Shaping &shaping, const float lineHeight, const float maxWidth,
                         const float horizontalAlign, const float verticalAlign,
                         const float justify) const {
    uint32_t lastSafeBreak = 0;

    uint32_t lengthBeforeCurrentLine = 0;
    uint32_t lineStartIndex = 0;
    uint32_t line = 0;

    uint32_t maxLineLength = 0;

    std::vector<PositionedGlyph> &positionedGlyphs = shaping.positionedGlyphs;

    if (maxWidth) {
        for (uint32_t i = 0; i < positionedGlyphs.size(); i++) {
            PositionedGlyph &shape = positionedGlyphs[i];

            shape.x -= lengthBeforeCurrentLine;
            shape.y += lineHeight * line;

            if (shape.x > maxWidth && lastSafeBreak > 0) {

                uint32_t lineLength = positionedGlyphs[lastSafeBreak + 1].x;
                maxLineLength = util::max(lineLength, maxLineLength);

                for (uint32_t k = lastSafeBreak + 1; k <= i; k++) {
                    positionedGlyphs[k].y += lineHeight;
                    positionedGlyphs[k].x -= lineLength;
                }

                if (justify) {
                    justifyLine(positionedGlyphs, metrics, lineStartIndex, lastSafeBreak - 1, justify);
                }

                lineStartIndex = lastSafeBreak + 1;
                lastSafeBreak = 0;
                lengthBeforeCurrentLine += lineLength;
                line++;
            }

            if (shape.glyph == 32) {
                lastSafeBreak = i;
            }
        }
    }

    const PositionedGlyph& lastPositionedGlyph = positionedGlyphs.back();
    const auto lastGlyphMetric = metrics.find(lastPositionedGlyph.glyph);
    assert(lastGlyphMetric != metrics.end());
    const uint32_t lastLineLength = lastPositionedGlyph.x + lastGlyphMetric->second.advance;
    maxLineLength = std::max(maxLineLength, lastLineLength);

    const uint32_t height = (line + 1) * lineHeight;

    justifyLine(positionedGlyphs, metrics, lineStartIndex, uint32_t(positionedGlyphs.size()) - 1, justify);
    align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line);

    // Calculate the bounding box
    shaping.top += -verticalAlign * height;
    shaping.bottom = shaping.top + height;
    shaping.left += -horizontalAlign * maxLineLength;
    shaping.right = shaping.left + maxLineLength;
}