📄 bidi.cpp
字号:
r = runs.next(); } //kdDebug(6040) << "yPos of line=" << m_height << " lineHeight=" << maxHeight << endl; // now construct the reordered string out of the runs... r = runs.first(); int x = leftOffset(m_height); int availableWidth = lineWidth(m_height); switch(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: int xd = (availableWidth - totWidth)/2; x += xd>0?xd:0; break; } while ( r ) { //kdDebug(6040) << "positioning " << r->obj << " start=" << r->start << " stop=" << r->stop << " yPos=" << r->vertical << endl; r->obj->position(x, r->vertical, r->start, r->stop - r->start, r->width, r->level%2, firstLine); x += r->width; r = runs.next(); } m_height += maxHeight; return endEmbed;}void RenderFlow::layoutInlineChildren(){ invalidateVerticalPositions();#ifdef DEBUG_LAYOUT QTime qt; qt.start(); kdDebug( 6040 ) << renderName() << " layoutInlineChildren( " << this <<" )" << endl;#endif int toAdd = style()->borderBottomWidth(); m_height = style()->borderTopWidth(); if(style()->hasPadding()) { m_height += paddingTop(); toAdd += paddingBottom(); } if(firstChild()) { // layout replaced elements RenderObject *o = first(); while ( o ) { 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#ifndef QT_NO_UNICODETABLES while(!start.atEnd() && start.direction() == QChar::DirWS )#else while(!start.atEnd() && start.current() == ' ' )#endif ++start; } if( start.atEnd() ) break; end = findNextLineBreak(start); embed = bidiReorderLine(status, start, end, embed); if( end == start || (end.obj && end.obj->isBR() ) ) ++end; newLine(); firstLine = false; } startEmbed->deref(); //embed->deref(); } m_height += toAdd; //kdDebug() << "RenderFlow::layoutInlineChildren time used " << qt.elapsed() << endl; //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; 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()+o->marginLeft()+o->marginRight(); } else if ( o->isText() ) { RenderText *t = static_cast<RenderText *>(o); int strlen = t->length(); int len = strlen - pos; QChar *str = t->text();#if 0 if ( ( !firstLine || !t->firstLine() ) && !t->hasReturn() && t->maxWidth() + w + tmpW < width ) { // the rest of the object fits completely// kdDebug() << "RenderFlow::findNextLineBreak object fits completely, max=" << t->maxWidth()// << " width =" << w << " avail = " << width <<" tmp=" << tmpW << endl; //search backwards for last possible linebreak int lastSpace = strlen-1; while( lastSpace >= pos && !isBreakable( str, lastSpace, strlen ) ) lastSpace--; lastSpace++; if ( lastSpace > pos ) { w += tmpW + t->width( pos, lastSpace-pos, firstLine); tmpW = 0; lBreak.obj = o; lBreak.pos = lastSpace; } tmpW += t->width( lastSpace, strlen-lastSpace, firstLine);// kdDebug() << "--> width=" << t->width( pos, strlen-pos, firstLine)// <<" first=" << t->width( pos, lastSpace-pos, firstLine)// <<" end=" << t->width( lastSpace, strlen-lastSpace, firstLine)// << endl; } else {#endif QFontMetrics fm = t->metrics( firstLine ); // proportional font, needs a bit more work. int lastSpace = pos; while(len) { if( isBreakable( str, pos, strlen ) ) { tmpW += t->width(lastSpace, pos - lastSpace, &fm);#ifdef DEBUG_LINEBREAKS kdDebug(6041) << "found space at " << pos << " in string '" << QString( str, strlen ).latin1() << "' adding " << tmpW << " new width = " << w << endl;#endif if ( w + tmpW > width && w == 0 ) { int fb = floatBottom(); if(!w && m_height < fb && width < lineWidth(fb)) { m_height = fb; width = lineWidth(m_height);#ifdef DEBUG_LINEBREAKS kdDebug() << "RenderFlow::findNextLineBreak new position at " << m_height << " newWidth " << width << endl;#endif } } if ( w + tmpW > width ) goto end; lBreak.obj = o; lBreak.pos = pos; if( *(str+pos) == '\n' ) {#ifdef DEBUG_LINEBREAKS kdDebug(6041) << "forced break sol: " << start.obj << " " << start.pos << " end: " << lBreak.obj << " " << lBreak.pos << " width=" << w << endl;#endif return lBreak; } w += tmpW; tmpW = 0; lastSpace = pos; } pos++; len--; } // IMPORTANT: pos is > length here! tmpW += t->width(lastSpace, pos - lastSpace, &fm); } else assert( false ); if( w + tmpW > width+1 ) { //kdDebug() << " too wide w=" << w << " tmpW = " << tmpW << " width = " << width << endl; //kdDebug() << "start=" << start.obj << " current=" << o << endl; // if we have floats, try to get below them. int fb = floatBottom(); if(!w && m_height < fb && width < lineWidth(fb)) { m_height = fb; width = lineWidth(m_height); //kdDebug() << "RenderFlow::findNextLineBreak new position at " << m_height << " newWidth " << width << endl; } if( !w && w + tmpW > width+1 && (o != start.obj || (unsigned) pos != start.pos) ) { // getting below floats wasn't enough... //kdDebug() << "still too wide w=" << w << " tmpW = " << tmpW << " width = " << width << endl; lBreak.obj = o; if(last != o) { //kdDebug() << " using last " << last << endl; //lBreak.obj = last; lBreak.pos = 0;//last->length() - 1; } else if ( unsigned ( pos ) >= o->length() ) { lBreak.obj = start.par->next(o); lBreak.pos = 0; } else lBreak.pos = pos; } return lBreak; } last = o; o = start.par->next(o); pos = 0; }#if 0 kdDebug( 6041 ) << "end of par, width = " << width << " linewidth = " << w + tmpW << endl;#endif if( w + tmpW <= width ) { lBreak.obj = 0; lBreak.pos = 0; } end: if( lBreak == start && !lBreak.obj->isBR() ) { //kdDebug( 6041 ) << "lBreak == start, adding...." << endl; // 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;#ifdef DEBUG_LINEBREAKS kdDebug(6041) << "regular break sol: " << start.obj << " " << start.pos << " end: " << lBreak.obj << " " << lBreak.pos << " width=" << w << endl;#endif return lBreak;}RenderObject *RenderFlow::first(){ if(!firstChild()) return 0; RenderObject *o = firstChild(); 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#undef DEBUG_LINEBREAKS#undef DEBUG_LAYOUT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -