📄 bidi.cpp
字号:
// now construct the reordered string out of the runs... r = runs.first(); int x = leftOffset(m_height); int availableWidth = lineWidth(m_height); switch(m_style->textAlign()) { case LEFT: break; case JUSTIFY: if(endEmbed->basicDir == QChar::DirL) break; // for right to left fall through to right aligned case RIGHT: x += availableWidth - totWidth; break; case CENTER: case KONQ_CENTER: x += (availableWidth - totWidth)/2; break; } while ( r ) { r->obj->position(x, r->yOffset, r->start, r->stop - r->start, r->width, r->level%2); x += r->width; r = runs.next(); } m_height += maxHeight; return endEmbed;}void RenderFlow::layoutInlineChildren(){#ifdef DEBUG_LAYOUT //kdDebug( 6040 ) << "layoutInlineChildren" << endl;#endif int toAdd = 0; m_height = 0; if(m_style->hasBorder()) { m_height = borderTop(); toAdd = borderBottom(); } if(m_style->hasPadding()) { m_height += paddingTop(); toAdd += paddingBottom(); } if(m_first) { // layout replaced elements RenderObject *o = first(); while ( o ) { //kdDebug() << "In function: RenderFlow::layoutInlineChildren" << endl; //kdDebug() << "child name is " << o->renderName() << endl; if(o->isReplaced() || o->isFloating() || o->isPositioned()) { //kdDebug(6041) << "layouting replaced or floating child" << endl; o->layout(); if(o->isPositioned()) static_cast<RenderFlow*>(o->containingBlock())->insertPositioned(o); } else if(o->isText()) static_cast<RenderText *>(o)->deleteSlaves(); o = next(o); } BidiContext *startEmbed; BidiStatus status; if( style()->direction() == LTR ) { startEmbed = new BidiContext( 0, QChar::DirL ); status.eor = QChar::DirL; } else { startEmbed = new BidiContext( 1, QChar::DirR ); status.eor = QChar::DirR; } startEmbed->ref(); BidiIterator start(this); BidiIterator end(this); BidiContext *embed = startEmbed; firstLine = true; while( !end.atEnd() ) { start = end; if(m_pre && start.current() == QChar('\n') ) { ++start; if( start.atEnd() ) break; } if(!m_pre) { // remove leading spaces while(!start.atEnd() && start.direction() == QChar::DirWS ) ++start; } if( start.atEnd() ) break; end = findNextLineBreak(start); if(end == start && start.obj && start.obj->isText() && start.current() == '\n') { // empty line, somthing like <br><br> m_height += start.obj->style()->font().pointSize(); } else embed = bidiReorderLine(status, start, end, embed); if( end == start ) ++end; newLine(); firstLine = false; } startEmbed->deref(); //embed->deref(); } m_height += toAdd; //kdDebug(6040) << "height = " << m_height <<endl;}BidiIterator RenderFlow::findNextLineBreak(const BidiIterator &start){ BidiIterator lBreak = start; int width = lineWidth(m_height); int w = 0; int tmpW = 0;#ifdef DEBUG_LINEBREAKS kdDebug(6041) << "findNextLineBreak: line at " << m_height << " line width " << width << endl; kdDebug(6041) << "sol: " << start.obj << " " << start.pos << endl;#endif RenderObject *o = start.obj; RenderObject *last = o; unsigned int pos = start.pos; while( o ) {#ifdef DEBUG_LINEBREAKS kdDebug(6041) << "new object "<< o <<" width = " << w <<" tmpw = " << tmpW << endl;#endif if(o->isBR()) { if( w + tmpW <= width ) { lBreak.obj = o; lBreak.pos = 0; //check the clear status EClear clear = o->style()->clear(); if(clear != CNONE) { m_clearStatus = (EClear) (m_clearStatus | clear); } } goto end; } if( o->isSpecial() ) { // add to special objects... specialHandler(o); // check if it fits in the current line. // If it does, position it now, otherwise, position // it after moving to next line (in newLine() func) if (o->width()+o->marginLeft()+o->marginRight()+w+tmpW <= width) { positionNewFloats(); width = lineWidth(m_height); } } else if ( o->isReplaced() ) { tmpW += o->width(); } else if ( o->isText() ) { RenderText *t = static_cast<RenderText *>(o); QChar *ch = t->text() + pos; int len = t->length() - pos; const MGFontMetrics *fm = t->metrics();#if CODE_BY_YMWEI { QChar *lastSpace = ch; while (len) { int char_len; char_len = fm->getFirstCharLen (QConstString(ch, len).string(), len); if (char_len > 1 || isBreakable (ch)) { tmpW += fm->width (QConstString(lastSpace, ch - lastSpace).string()); if ( w + tmpW > width ) goto end; lBreak.obj = o; lBreak.pos = pos; if( *ch == '\n' ) { return lBreak; } w += tmpW; tmpW = 0; lastSpace = ch; } ch += char_len; pos += char_len; len -= char_len; } if (ch - lastSpace > 1) tmpW += fm->width(QConstString(lastSpace, ch - lastSpace).string()); else tmpW += fm->width(*lastSpace); }#else#if 0 if(t->isFixedWidthFont()) { int chWidth = fm->width(*ch); while(len) { if( ch->direction() == QChar::DirWS || *ch == '\n' ) { if ( w + tmpW > width ) goto end; lBreak.obj = o; lBreak.pos = pos; if( *ch == '\n' ) { return lBreak; } w += tmpW; tmpW = 0; } tmpW += chWidth; ch++; pos++; len--; } } else#endif { // proportional font, needs a bit more work. QChar *lastSpace = ch; while(len) { if( isBreakable( ch ) ) { tmpW += fm->width(QConstString(lastSpace, ch - lastSpace).string()); if ( w + tmpW > width ) goto end; lBreak.obj = o; lBreak.pos = pos; if( *ch == '\n' ) { return lBreak; } w += tmpW; tmpW = 0; lastSpace = ch; } ch++; pos++; len--; } if(ch-lastSpace > 1) tmpW += fm->width(QConstString(lastSpace, ch - lastSpace).string()); else tmpW += fm->width(*lastSpace); }#endif } else assert( false ); if( w + tmpW > width+1 ) { int fb = floatBottom(); if(!w && m_height < fb && width < lineWidth(fb)) { m_height = fb; width = lineWidth(m_height); } if (!w && ((w + tmpW) > (width + 1)) && (o != start.obj || pos != start.pos) ) { // getting below floats wasn't enough... lBreak.obj = o; if(last != o) { //lBreak.obj = last; lBreak.pos = 0;//last->length() - 1; } else { lBreak.pos = pos; } return lBreak; } else { return lBreak; } } last = o; o = start.par->next(o); pos = 0; } if( w + tmpW <= width ) { lBreak.obj = 0; lBreak.pos = 0; } end: if( lBreak == start && !lBreak.obj->isBR() ) { // we just add as much as possible if ( m_pre ) { if(pos != 0) { lBreak.obj = o; lBreak.pos = pos - 1; } else { lBreak.obj = last; lBreak.pos = last->length(); } } else if( lBreak.obj ) { if( last != o ) { // better break between object boundaries than in the middle of a word lBreak.obj = o; lBreak.pos = 0; } else { int w = 0; if( lBreak.obj->isText() ) w += static_cast<RenderText *>(lBreak.obj)->width(lBreak.pos, 1); else w += lBreak.obj->width(); while( lBreak.obj && w < width ) { ++lBreak; if( !lBreak.obj ) break; if( lBreak.obj->isText() ) w += static_cast<RenderText *>(lBreak.obj)->width(lBreak.pos, 1); else w += lBreak.obj->width(); } } } } // make sure we consume at least one char/object. if( lBreak == start ) ++lBreak; return lBreak;}RenderObject *RenderFlow::first(){ if(!m_first) return 0; RenderObject *o = m_first; if(!o->isText() && !o->isBR() && !o->isReplaced() && !o->isFloating() && !o->isPositioned()) o = next(o) ; return o;}RenderObject *RenderFlow::next(RenderObject *current){ if(!current) return 0; while(current != 0) { //kdDebug( 6040 ) << "current = " << current << endl; RenderObject *next = nextObject(current); if(!next) return 0; if(next->isText() || next->isBR() || next->isFloating() || next->isReplaced() || next->isPositioned()) return next; current = next; } return 0;}RenderObject *RenderFlow::nextObject(RenderObject *current){ RenderObject *next = 0; if(!current->isFloating() && !current->isReplaced() && !current->isPositioned()) next = current->firstChild(); if(next) return next; while(current && current != this) { next = current->nextSibling(); if(next) return next; current = current->parent(); } return 0;}// For --enable-final#undef BIDI_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -