⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render_text.cpp

📁 monqueror一个很具有参考价值的源玛
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/** * This file is part of the DOM implementation for KDE. * * (C) 1999 Lars Knoll (knoll@kde.org) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * $Id: render_text.cpp,v 1.3 2003/04/22 09:34:24 weiym Exp $ *///#define DEBUG_LAYOUT//#define BIDI_DEBUG#if 0// #### for debugging Qt#define private public#include <qfontmetrics.h>#undef private#include <qtextcodec.h>#endif#include <assert.h>#include "render_interface.h"#include "mgcolor.h"#include "mgpen.h"#include "mgbrush.h"#include "mgsize.h"#include "mgrect.h"#include "mgpixmap.h"#include "mgfontmetrics.h"#include "mgfontinfo.h"#include "mgpainter.h"#include "mghtml_part.h"#include "render_text.h"#include "render_style.h"#include "kdebug.h"#define CODE_BY_YMWEI 1#define QT_ALLOC_QCHAR_VEC( N ) (QChar*) new char[ sizeof(QChar)*( N ) ]#define QT_DELETE_QCHAR_VEC( P ) delete[] ((char*)( P ))using namespace khtml;using namespace DOM;TextSlave::~TextSlave(){    if(deleteText)        QT_DELETE_QCHAR_VEC(m_text);}void TextSlave::print( MGPainter *p, int _tx, int _ty){    if (!m_text || len <= 0)        return;    QConstString s(m_text, len);    //kdDebug( 6040 ) << "textSlave::printing(" << s.string() << ") at(" << x+_tx << "/" << y+_ty << ")" << endl;    p->drawText(x + _tx, y + _ty, s.string());}void TextSlave::printSelection(MGPainter *p, RenderText* rt, int tx, int ty, int startPos, int endPos){    if(startPos > len) return;    if(startPos < 0) startPos = 0;    int _len = len;    int _width = m_width;    if(endPos > 0 && endPos < len) {        _len = endPos;    }    _len -= startPos;    QConstString s(m_text+startPos , _len);    if (_len != len)        _width = p->fontMetrics().width(s.string());    int _offset = 0;    if ( startPos > 0 ) {        QConstString aStr(m_text, startPos);        _offset = p->fontMetrics().width(aStr.string());    }    MGColor c = rt->style()->color();    p->setPen(MGColor(0xff-c.red(),0xff-c.green(),0xff-c.blue()));    p->fillRect(x + tx + _offset, y + ty, _width, m_height, c);    ty += m_baseline;    //kdDebug( 6040 ) << "textSlave::printing(" << s.string() << ") at(" << x+_tx << "/" << y+_ty << ")" << endl;    p->drawText(x + tx + _offset, y + ty, s.string());}// no blink at the moment...void TextSlave::printDecoration( MGPainter *p, int _tx, int _ty, int deco){    _tx += x;    _ty += y;/*     int underlineOffset = m_height/6 + m_baseline;	if( underlineOffset == m_baseline ) underlineOffset++;*/    int underlineOffset = m_baseline;    if(deco & UNDERLINE)        p->drawLine(_tx, _ty + underlineOffset, _tx + m_width, _ty + underlineOffset );    if(deco & OVERLINE)        p->drawLine(_tx, _ty, _tx + m_width, _ty );    if(deco & LINE_THROUGH)        p->drawLine(_tx, _ty + 2*m_baseline/3, _tx + m_width, _ty + 2*m_baseline/3 );// ### add BLINK}void TextSlave::printBoxDecorations(MGPainter *pt, RenderText *p, int _tx, int _ty, bool begin, bool end){    _tx += x;    _ty += y - p->paddingTop() - p->borderTop();    //kdDebug( 6040 ) << "renderBox::printDecorations()" << endl;    RenderStyle *style = p->style();    int width = m_width;    if(begin)        _tx -= p->paddingLeft() + p->borderLeft();    MGColor c = style->backgroundColor();    MGCachedImage *i = style->backgroundImage();    if(c.isValid() && (!i || i->tiled_pixmap(c).mask()))        pt->fillRect(_tx, _ty, width, m_height, c);    if(i)    {        // ### might need to add some correct offsets        // ### use paddingX/Y        pt->drawTiledPixmap(_tx + p->borderLeft(), _ty + p->borderTop(),                            m_width + p->paddingLeft() + p->paddingRight(),                            m_height + p->paddingTop() + p->paddingBottom(), i->tiled_pixmap(c));    }    if(style->hasBorder())    {        int h = m_height + p->paddingTop() + p->paddingBottom() + p->borderTop() + p->borderBottom();        if(style->borderTopStyle() != BNONE)        {            c = style->borderTopColor();            if(!c.isValid()) c = style->color();            p->drawBorder(pt, _tx, _ty, _tx + width, _ty, style->borderTopWidth(),                       RenderObject::BSTop, c, style->borderTopStyle());        }        if(style->borderBottomStyle() != BNONE)        {            c = style->borderBottomColor();            if(!c.isValid()) c = style->color();            p->drawBorder(pt, _tx, _ty + h, _tx + width, _ty + h, style->borderBottomWidth(),                       RenderObject::BSBottom, c, style->borderBottomStyle());        }        // ### has to be changed for RTL        if(style->borderLeftStyle() != BNONE && (begin))        {            c = style->borderLeftColor();            if(!c.isValid()) c = style->color();            p->drawBorder(pt, _tx, _ty, _tx, _ty + h, style->borderLeftWidth(),                       RenderObject::BSLeft, c, style->borderLeftStyle());        }        if(style->borderRightStyle() != BNONE && end)        {            c = style->borderRightColor();            if(!c.isValid()) c = style->color();            p->drawBorder(pt, _tx + width, _ty, _tx + width, _ty + h, style->borderRightWidth(),                       RenderObject::BSRight, c, style->borderRightStyle());        }    }#ifdef BIDI_DEBUG    int h = m_height + p->paddingTop() + p->paddingBottom() + p->borderTop() + p->borderBottom();    c = MGColor("#0000ff");    p->drawBorder(pt, _tx, _ty, _tx, _ty + h, 1,                  RenderObject::BSLeft, c, SOLID);    p->drawBorder(pt, _tx + width, _ty, _tx + width, _ty + h, style->borderRightWidth(),                  RenderObject::BSRight, c, SOLID);#endif}void TextSlave::printActivation( MGPainter *p, int _tx, int _ty){  p->drawRect(_tx+x-2,_ty+y, m_width+3, m_height+2);  p->drawRect(_tx+x-3,_ty+y+1, m_width+5, m_height);}bool TextSlave::checkPoint(int _x, int _y, int _tx, int _ty){    if((_ty + y > _y) || (_ty + y + m_height < _y) ||       (_tx + x > _x) || (_tx + x + m_width < _x))        return false;    return true;}// -------------------------------------------------------------------------------------RenderText::RenderText(DOMStringImpl *_str)    : RenderObject(){    // init RenderObject attributes    m_isText = true;   // our object inherits from RenderText    m_inline = true;   // our object is Inline    m_first = 0;    m_last = 0;    m_minWidth = -1;    m_maxWidth = -1;    str = _str;    if(str) str->ref();    fm = 0;    m_selectionState = SelectionNone;#ifdef DEBUG_LAYOUT    QConstString cstr(str->s, str->l);    kdDebug( 6040 ) << "RenderText::setText '" << (const char *)cstr.string().utf8() << "'" << endl;#endif}void RenderText::setStyle(RenderStyle *style){    RenderObject::setStyle(style);    delete fm;    fm = new MGFontMetrics(m_style->font(), m_part);    m_contentHeight = m_style->lineHeight().width(fm->height());}RenderText::~RenderText(){    deleteSlaves();    delete fm; fm = 0;    if(str) str->deref();}void RenderText::deleteSlaves(){    // delete all slaves    TextSlave *s = m_first;    while(s)    {        TextSlave *next = s->next();        delete s;        s = next;    }    m_first = m_last = 0;}bool RenderText::checkPoint(int _x, int _y, int _tx, int _ty, int &offset){    TextSlave *s = m_first;    while(s)    {        if( s->checkPoint(_x, _y, _tx, _ty) )        {            // now we need to get the exact position            int delta = _x - _tx - s->x;            int pos = 0;            while(pos < s->len)            {                // ### this will produce wrong results for RTL text!!!                int w = fm->width(*(s->m_text+pos));                int w2 = w/2;                w = w - w2;                delta -= w2;                if(delta <= 0) break;                pos++;                delta -= w;            }            offset = s->m_text - m_first->m_text + pos;            //kdDebug( 6040 ) << " Text  --> inside at position " << offset << endl;            return true;        }        // ### this might be wrong, if combining chars are used ( eg arabic )        s=s->next();    }    return false;}void RenderText::cursorPos(int offset, int &_x, int &_y, int &height){  if (!m_first) {    _x = _y = height = -1;    return;  }  _x = 0;  TextSlave *s = m_first;  int off = s->len;  while(offset > off && s->next())  {      s=s->next();      off = s->m_text - m_first->m_text + s->len;  }   // we are now in the correct text slave  int pos = (offset > off ? s->len : s->len - (off - offset ));  _y = s->y;  height = s->m_height;  QString tekst(s->m_text, s->len);  _x = s->x + (fm->boundingRect(tekst, pos)).right();  if(pos)      _x += fm->rightBearing( *(s->m_text + pos - 1 ) );  int absx, absy;  absolutePosition(absx,absy);  if (absx == -1) {    // we don't know out absolute position, and there is not point returning    // just a relative one    _x = _y = -1;  }  else {    _x += absx;    _y += absy;  }}void RenderText::absolutePosition(int &xPos, int &yPos, bool){    if(m_parent) {        m_parent->absolutePosition(xPos, yPos, false);        if ( m_first ) {            xPos += m_first->x;            yPos += m_first->y;        }    } else        xPos = yPos = -1;}void RenderText::posOfChar(int chr, int &x, int &y){    if (!m_parent)    {       x = -1;       y = -1;       return;    }    m_parent->absolutePosition( x, y, false );    if( chr > (int) str->l )	chr = str->l;    TextSlave *s = m_first;    TextSlave *last = s;    QChar *ch = str->s + chr;    while ( s && ch >= s->m_text )    {        last = s;	s = s->next();    }    x += last->x;    y += last->y;}void RenderText::printObject( MGPainter *p, int /*x*/, int y, int /*w*/, int h,                      int tx, int ty){    //kdDebug( 6040 ) << "Text::printObject(long)" << endl;    TextSlave *s = m_first;    //kdDebug( 6040 ) << "Text::printObject(2)" << endl;    bool start = true;#ifndef BIDI_DEBUG    if(m_printSpecial && m_parent->isInline())#endif    {        bool breakallowed = false;        while(s)        {            bool end = false;            if(!s->next()) end = true;            if(s->checkVerticalPoint(y, ty, h))            {                breakallowed = true;                s->printBoxDecorations(p, this, tx, ty, start, end);            }            else if (breakallowed)                break;            s=s->next();            start = false;        }        s = m_first;    }    p->setFont( m_style->font() );    //kdDebug( 6040 ) << "charset used: " << m_style->font().charSet() << endl;#if 0    kdDebug( 6040 ) << "charset used: " << m_style->font().charSet() << " mapper: " << fm->mapper()->name() << endl;#endif    // ### as QPainter::drawText only honors the pen color, we can avoid

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -