Esempio n. 1
0
    std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height)
    {
        using Ogre::UTFString;
        std::vector<std::string> result;

        MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
        utf8Text = Interpreter::fixDefinesBook(utf8Text, interpreterContext);

        boost::algorithm::replace_all(utf8Text, "\n", "");
        boost::algorithm::replace_all(utf8Text, "\r", "");
        boost::algorithm::replace_all(utf8Text, "<BR>", "\n");
        boost::algorithm::replace_all(utf8Text, "<P>", "\n\n");

        UTFString text(utf8Text);
        const int spacing = 48;

        const UTFString::unicode_char LEFT_ANGLE = unicodeCharFromChar('<');
        const UTFString::unicode_char NEWLINE = unicodeCharFromChar('\n');
        const UTFString::unicode_char SPACE = unicodeCharFromChar(' ');

        while (!text.empty())
        {
            // read in characters until we have exceeded the size, or run out of text
            int currentWidth = 0;
            int currentHeight = 0;

            size_t currentWordStart = 0;
            size_t index = 0;
            
            {
                std::string texToTrim = text.asUTF8();
                boost::algorithm::trim( texToTrim );
                text = UTFString(texToTrim);
            }
            
            
            while (currentHeight <= height - spacing && index < text.size())
            {
                const UTFString::unicode_char ch = text.getChar(index);
                if (ch == LEFT_ANGLE)
                {
                    const size_t tagStart = index + 1;
                    const size_t tagEnd = text.find('>', tagStart);
                    if (tagEnd == UTFString::npos)
                        throw std::runtime_error("BookTextParser Error: Tag is not terminated");
                    const std::string tag = text.substr(tagStart, tagEnd - tagStart).asUTF8();

                    if (boost::algorithm::starts_with(tag, "IMG"))
                    {
                        const int h = mHeight;
                        parseImage(tag, false);
                        currentHeight += (mHeight - h);
                        currentWidth = 0;
                    }
                    else if (boost::algorithm::starts_with(tag, "FONT"))
                    {
                        parseFont(tag);
                        if (currentWidth != 0) {
                            currentHeight += currentFontHeight();
                            currentWidth = 0;
                        }
                        currentWidth = 0;
                    }
                    else if (boost::algorithm::starts_with(tag, "DIV"))
                    {
                        parseDiv(tag);
                        if (currentWidth != 0) {
                            currentHeight += currentFontHeight();
                            currentWidth = 0;
                        }
                    }
                    index = tagEnd;
                }
                else if (ch == NEWLINE)
                {
                    currentHeight += currentFontHeight();
                    currentWidth = 0;
                    currentWordStart = index;
                }
                else if (ch == SPACE)
                {
                    currentWidth += 3; // keep this in sync with the font's SpaceWidth property
                    currentWordStart = index;
                }
                else
                {
                    currentWidth += widthForCharGlyph(ch);
                }

                if (currentWidth > width)
                {
                    currentHeight += currentFontHeight();
                    currentWidth = 0;
                    // add size of the current word
                    UTFString word = text.substr(currentWordStart, index - currentWordStart);
                    for (UTFString::const_iterator it = word.begin(), end = word.end(); it != end; ++it)
                        currentWidth += widthForCharGlyph(it.getCharacter());
                }
                index += UTFString::_utf16_char_length(ch);
            }
            const size_t pageEnd = (currentHeight > height - spacing && currentWordStart != 0)
                    ? currentWordStart : index;

            result.push_back(text.substr(0, pageEnd).asUTF8());
            text.erase(0, pageEnd);
        }
        
        std::vector<std::string> nonEmptyPages;
        boost::copy(result | boost::adaptors::filtered(is_not_empty), std::back_inserter(nonEmptyPages));
        return nonEmptyPages;
    }