程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Mygui中文換行問題

Mygui中文換行問題

編輯:C++入門知識

相信大家解決了中文輸入後一定會遇到如何解決中文輸入的問題,中文輸入換行問題是很多gui框架都存在的一個問題,這裡不廢話了,大家打開mygui的引擎層中的widget的textview 的頭文件和源文件將其替換為:

[cpp] 
/*!
    @file
    @author     Albert Semenov
    @date       09/2009
*/ 
#ifndef __MYGUI_TEXT_VIEW_DATA_H__ 
#define __MYGUI_TEXT_VIEW_DATA_H__ 
 
#include "MyGUI_Prerequest.h" 
 
namespace MyGUI 

 
    class CharInfo 
    { 
    public: 
        CharInfo() : 
            mIsColour(false) 
        { 
            mMetrics.mWidth = 0.0f; 
            mMetrics.mHeight = 0.0f; 
            mMetrics.mAdvance = 0.0f; 
            mMetrics.mBearingX = 0.0f; 
            mMetrics.mBearingY = 0.0f; 
        } 
 
        CharInfo( 
            const FloatRect& _rect, 
            float _width, 
            float _height, 
            float _advance, 
            float _bearingX, 
            float _bearingY) : 
            mIsColour(false), 
            mUVRect(_rect) 
        {   www.2cto.com
            mMetrics.mWidth = _width; 
            mMetrics.mHeight = _height; 
            mMetrics.mAdvance = _advance; 
            mMetrics.mBearingX = _bearingX; 
            mMetrics.mBearingY = _bearingY; 
        } 
 
        CharInfo(uint32 _colour) : 
            mIsColour(true), 
            mColour(_colour) 
        { } 
 
        bool isColour() const 
        { 
            return mIsColour; 
        } 
 
        float getWidth() const 
        { 
            return mMetrics.mWidth; 
        } 
 
        float getHeight() const 
        { 
            return mMetrics.mHeight; 
        } 
 
        float getAdvance() const 
        { 
            return mMetrics.mAdvance; 
        } 
 
        float getBearingX() const 
        { 
            return mMetrics.mBearingX; 
        } 
 
        float getBearingY() const 
        { 
            return mMetrics.mBearingY; 
        } 
 
        const FloatRect& getUVRect() const 
        { 
            return mUVRect; 
        } 
 
        uint32 getColour() const 
        { 
            return mColour; 
        } 
 
    private: 
 
        bool mIsColour; 
        FloatRect mUVRect; 
 
        struct Metrics 
        { 
            float mWidth; 
            float mHeight; 
            float mAdvance; 
            float mBearingX; 
            float mBearingY; 
        }; 
 
        union 
        { 
            Metrics mMetrics; 
            uint32 mColour; 
        }; 
 
    }; 
 
    typedef std::vector<CharInfo> VectorCharInfo; 
 
    //struct LineInfo 
    //{ 
    //  LineInfo() : 
    //      width(0), 
    //      offset(0), 
    //      count(0) 
    //  { 
    //  } 
 
    //  void clear() 
    //  { 
    //      width = 0; 
    //      count = 0; 
    //      simbols.clear(); 
    //      offset = 0; 
    //  } 
 
    //  int width; 
    //  int offset; 
    //  size_t count; 
    //  VectorCharInfo simbols; 
    //}; 
 
    struct LineInfo 
    { 
        LineInfo() : 
    width(0), 
        offset(0), 
        count(0), 
        offcount(0) 
    { 
    } 
 
    void clear() 
    { 
        offcount = 0; 
        width = 0; 
        count = 0; 
        simbols.clear(); 
        offset = 0; 
    } 
 
    int offcount; 
    int width; 
    int offset; 
    size_t count; 
    VectorCharInfo simbols; 
    }; 
 
    typedef std::vector<LineInfo> VectorLineInfo; 
 
} // namespace MyGUI 
 
#endif // __MYGUI_TEXT_VIEW_DATA_H__ 

上面是頭文件,下面是源文件:
[cpp] view plaincopy
/*!
    @file
    @author     Albert Semenov
    @date       09/2010
*/ 
/*
    This file is part of MyGUI.
 
    MyGUI is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    MyGUI is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public License
    along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/ 
#include "MyGUI_Precompiled.h" 
#include "MyGUI_TextView.h" 
 
namespace MyGUI 

 
    namespace 
    { 
 
        template<typename T> 
        void setMin(T& _var, const T& _newValue) 
        { 
            if (_newValue < _var) 
                _var = _newValue; 
        } 
 
        template<typename T> 
        void setMax(T& _var, const T& _newValue) 
        { 
            if (_var < _newValue) 
                _var = _newValue; 
        } 
 
    } 
 
    class RollBackPoint 
    { 
    public: 
        RollBackPoint() : 
            position(0), 
            count(0), 
            width(0), 
            rollback(false) 
        { 
        } 
 
        void set(size_t _position, UString::const_iterator& _space_point, size_t _count, float _width) 
        { 
            position = _position; 
            space_point = _space_point; 
            count = _count; 
            width = _width; 
            rollback = true; 
        } 
 
        void clear() 
        { 
            rollback = false; 
        } 
 
        bool empty() const 
        { 
            return !rollback; 
        } 
 
        float getWidth() const 
        { 
            MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid"); 
            return width; 
        } 
 
        size_t getCount() const 
        { 
            MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid"); 
            return count; 
        } 
 
        size_t getPosition() const 
        { 
            MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid"); 
            return position; 
        } 
 
        UString::const_iterator getTextIter() const 
        { 
            MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid"); 
            return space_point; 
        } 
 
    private: 
        size_t position; 
        UString::const_iterator space_point; 
        size_t count; 
        float width; 
        bool rollback; 
    }; 
 
    TextView::TextView() : 
        mLength(0), 
        mFontHeight(0) 
    { 
    } 
 
    void TextView::update(const UString& _text, IFont* _font, int _height, Align _align, VertexColourType _format, int _maxWidth) 
    { 
        mFontHeight = _height; 
 
        // массив для быстрой конвертации цветов 
        static const char convert_colour[64] = 
        { 
            0,  1,  2,  3,  4,  5,  6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 
            0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
            0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
            0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 
        }; 
 
        mViewSize.clear(); 
 
        RollBackPoint roll_back; 
        IntSize result; 
        float width = 0.0f; 
        size_t count = 0; 
        mLength = 0; 
        mLineInfo.clear(); 
        LineInfo line_info; 
        int font_height = _font->getDefaultHeight(); 
 
        UString::const_iterator end = _text.end(); 
        UString::const_iterator index = _text.begin(); 
 
        /*if (index == end)
            return;*/ 
 
        result.height += _height; 
 
        for (; index != end; ++index) 
        { 
            Char character = *index; 
 
            // новая строка 
            if (character == FontCodeType::CR 
                || character == FontCodeType::NEL 
                || character == FontCodeType::LF) 
            { 
                if (character == FontCodeType::CR) 
                { 
                    UString::const_iterator peeki = index; 
                    ++peeki; 
                    if ((peeki != end) && (*peeki == FontCodeType::LF)) 
                        index = peeki; // skip both as one newline 
                } 
 
                line_info.width = (int)ceil(width); 
                line_info.count = count; 
                //mLength += line_info.count + 1; 
                mLength += line_info.offcount; 
                result.height += _height; 
                setMax(result.width, line_info.width); 
                width = 0; 
                count = 0; 
 
                mLineInfo.push_back(line_info); 
                line_info.clear(); 
 
                // отменяем откат 
                roll_back.clear(); 
 
                continue; 
            } 
            // тег 
            else if (character == L'#') 
            { 
                // берем следующий символ 
                ++ index; 
                if (index == end) 
                { 
                    --index;    // это защита 
                    continue; 
                } 
 
                character = *index; 
                // если два подряд, то рисуем один шарп, если нет то меняем цвет 
                if (character != L'#') 
                { 
                    // парсим первый символ 
                    uint32 colour = convert_colour[(character - 48) & 0x3F]; 
 
                    // и еще пять символов после шарпа 
                    for (char i = 0; i < 5; i++) 
                    { 
                        ++ index; 
                        if (index == end) 
                        { 
                            --index;    // это защита 
                            continue; 
                        } 
                        colour <<= 4; 
                        colour += convert_colour[ ((*index) - 48) & 0x3F ]; 
                    } 
 
                    // если нужно, то меняем красный и синий компоненты 
                    texture_utility::convertColour(colour, _format); 
 
                    line_info.simbols.push_back( CharInfo(colour) ); 
 
                    continue; 
                } 
            } 
 
            GlyphInfo* info = _font->getGlyphInfo(character); 
 
            if (info == nullptr) 
                continue; 
 
            if (FontCodeType::Space == character) 
            { 
                roll_back.set(line_info.simbols.size(), index, count, width); 
            } 
            else if (FontCodeType::Tab == character) 
            { 
                roll_back.set(line_info.simbols.size(), index, count, width); 
            } 
 
            float char_width = info->width; 
            float char_height = info->height; 
            float char_advance = info->advance; 
            float char_bearingX = info->bearingX; 
            float char_bearingY = info->bearingY; 
 
            if (_height != font_height) 
            { 
                float scale = (float)_height / font_height; 
 
                char_width *= scale; 
                char_height *= scale; 
                char_advance *= scale; 
                char_bearingX *= scale; 
                char_bearingY *= scale; 
            } 
 
            float char_fullAdvance = char_bearingX + char_advance; 
 
            // перенос слов 
            if (_maxWidth != -1 
                && (width + char_fullAdvance) > _maxWidth 
                /*&& !roll_back.empty()*/) 
            { 
                --index; 
                // откатываем до последнего пробела 
                /*width = roll_back.getWidth();
                count = roll_back.getCount();
                index = roll_back.getTextIter();
                line_info.simbols.erase(line_info.simbols.begin() + roll_back.getPosition(), line_info.simbols.end());*/ 
                 
                // запоминаем место отката, как полную строку 
                /*line_info.width = (int)ceil(width);
                line_info.count = count;
                mLength += line_info.count + 1;
 
                result.height += _height;
                setMax(result.width, line_info.width);
                width = 0;
                count = 0;
 
                mLineInfo.push_back(line_info);
                line_info.clear();*/ 
 
                // запоминаем место отката, как полную строку 
                line_info.width = (int)ceil(width); 
                line_info.count = count; 
                line_info.offcount = 0; 
                mLength += line_info.count;// + 1; 
 
                result.height += _height; 
                setMax(result.width, line_info.width); 
                width = 0; 
                count = 0; 
 
                mLineInfo.push_back(line_info); 
                line_info.clear(); 
 
 
                // отменяем откат 
                roll_back.clear(); 
 
                continue; 
            } 
 
            line_info.simbols.push_back(CharInfo(info->uvRect, char_width, char_height, char_advance, char_bearingX, char_bearingY)); 
            width += char_fullAdvance; 
            count ++; 
        } 
 
        line_info.width = (int)ceil(width); 
        line_info.count = count; 
        mLength += line_info.count; 
 
        mLineInfo.push_back(line_info); 
 
        setMax(result.width, line_info.width); 
 
        // теперь выравниванием строки 
        for (VectorLineInfo::iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line) 
        { 
            if (_align.isRight()) 
                line->offset = result.width - line->width; 
            else if (_align.isHCenter()) 
                line->offset = (result.width - line->width) / 2; 
        } 
 
        mViewSize = result; 
    } 
 
    size_t TextView::getCursorPosition(const IntPoint& _value) 
    { 
        const int height = mFontHeight; 
        size_t result = 0; 
        int top = 0; 
 
        for (VectorLineInfo::const_iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line) 
        { 
            // это последняя строка 
            bool lastline = !(line + 1 != mLineInfo.end()); 
 
            // наша строчка 
            if (top + height > _value.top || lastline) 
            { 
                top += height; 
                float left = (float)line->offset; 
                int count = 0; 
 
                // ищем символ 
                for (VectorCharInfo::const_iterator sim = line->simbols.begin(); sim != line->simbols.end(); ++sim) 
                { 
                    if (sim->isColour()) 
                        continue; 
 
                    float fullAdvance = sim->getAdvance() + sim->getBearingX(); 
                    if (left + fullAdvance / 2.0f > _value.left) 
                    { 
                        break; 
                    } 
                    left += fullAdvance; 
                    count ++; 
                } 
 
                result += count; 
                break; 
            } 
 
            if (!lastline) 
            { 
                top += height; 
                result += line->count + line->offcount; 
                 
            } 
        } 
 
        return result; 
    } 
 
    IntPoint TextView::getCursorPoint(size_t _position) 
    { 
        setMin(_position, mLength); 
 
        size_t position = 0; 
        int top = 0; 
        float left = 0.0f; 
        for (VectorLineInfo::const_iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line) 
        { 
            left = (float)line->offset; 
            if (position + line->count >= _position) 
            { 
                for (VectorCharInfo::const_iterator sim = line->simbols.begin(); sim != line->simbols.end(); ++sim) 
                { 
                    if (sim->isColour()) 
                        continue; 
 
                    if (position == _position) 
                        break; 
 
                    position ++; 
                    left += sim->getBearingX() + sim->getAdvance(); 
                } 
                break; 
            } 
            position += line->count + line->offcount; 
             
            top += mFontHeight; 
        } 
 
        return IntPoint((int)left, top); 
    } 
 
    const IntSize& TextView::getViewSize() const 
    { 
        return mViewSize; 
    } 
 
    size_t TextView::getTextLength() const 
    { 
        return mLength; 
    } 
 
    const VectorLineInfo& TextView::getData() const 
    { 
        return mLineInfo; 
    } 
 
} // namespace MyGUI 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved