📄 bidi.cpp
字号:
int x = leftOffset(m_height); int availableWidth = lineWidth(m_height); switch(style()->textAlign()) { case LEFT: case KHTML_LEFT: numSpaces = 0; break; case JUSTIFY: if (numSpaces != 0 && !bidi.current.atEnd() && !lineBox->endsWithBreak()) break; // fall through case TAAUTO: numSpaces = 0; // for right to left fall through to right aligned if (bidi.context->basicDir == QChar::DirL) break; case RIGHT: case KHTML_RIGHT: x += availableWidth - totWidth; numSpaces = 0; break; case CENTER: case KHTML_CENTER: int xd = (availableWidth - totWidth)/2; x += xd >0 ? xd : 0; numSpaces = 0; break; } if (numSpaces > 0) { for (r = sFirstBidiRun; r; r = r->nextRun) { if (!r->box) continue; int spaceAdd = 0; if (numSpaces > 0 && r->obj->isText() && !r->compact) { // get the number of spaces in the run int spaces = 0; for ( int i = r->start; i < r->stop; i++ ) { const QChar c = static_cast<RenderText *>(r->obj)->text()[i]; if (c == ' ' || c == '\n') spaces++; } KHTMLAssert(spaces <= numSpaces); // Only justify text with white-space: normal. if (r->obj->style()->whiteSpace() != PRE) { spaceAdd = (availableWidth - totWidth)*spaces/numSpaces; static_cast<InlineTextBox*>(r->box)->setSpaceAdd(spaceAdd); totWidth += spaceAdd; } numSpaces -= spaces; } } } // The widths of all runs are now known. We can now place every inline box (and // compute accurate widths for the inline flow boxes). int rightPos = lineBox->placeBoxesHorizontally(x); if (rightPos > m_overflowWidth) m_overflowWidth = rightPos; // FIXME: Work for rtl overflow also.}void RenderBlock::computeVerticalPositionsForLine(RootInlineBox* lineBox){ lineBox->verticallyAlignBoxes(m_height); lineBox->setBlockHeight(m_height); // See if the line spilled out. If so set overflow height accordingly. int bottomOfLine = lineBox->bottomOverflow(); if (bottomOfLine > m_height && bottomOfLine > m_overflowHeight) m_overflowHeight = bottomOfLine; // Now make sure we place replaced render objects correctly. for (BidiRun* r = sFirstBidiRun; r; r = r->nextRun) { if (!r->box) continue; // Skip runs with no line boxes. // Align positioned boxes with the top of the line box. This is // a reasonable approximation of an appropriate y position. if (r->obj->isPositioned()) r->box->setYPos(m_height); // Position is used to properly position both replaced elements and // to update the static normal flow x/y of positioned elements. r->obj->position(r->box, r->start, r->stop - r->start, r->level%2); }}// collects one line of the paragraph and transforms it to visual ordervoid RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator &end, BidiState &bidi){ if ( start == end ) { if ( start.current() == '\n' ) { m_height += lineHeight( m_firstLine, true ); } return; }#if BIDI_DEBUG > 1 kdDebug(6041) << "reordering Line from " << start.obj << "/" << start.pos << " to " << end.obj << "/" << end.pos << endl;#endif sFirstBidiRun = 0; sLastBidiRun = 0; sBidiRunCount = 0; // context->ref(); dir = QChar::DirON; emptyRun = true; numSpaces = 0; bidi.current = start; bidi.last = bidi.current; bool atEnd = false; while( 1 ) { QChar::Direction dirCurrent; if (atEnd) { //kdDebug(6041) << "atEnd" << endl; BidiContext *c = bidi.context; if ( bidi.current.atEnd()) while ( c->parent ) c = c->parent; dirCurrent = c->dir; } else { dirCurrent = bidi.current.direction(); }#ifndef QT_NO_UNICODETABLES#if BIDI_DEBUG > 1 kdDebug(6041) << "directions: dir=" << (int)dir << " current=" << (int)dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << (int)context->dir << " level =" << (int)context->level << endl;#endif switch(dirCurrent) { // embedding and overrides (X1-X9 in the Bidi specs) case QChar::DirRLE: case QChar::DirLRE: case QChar::DirRLO: case QChar::DirLRO: case QChar::DirPDF: bidi.eor = bidi.last; embed( dirCurrent, bidi ); break; // strong types case QChar::DirL: if(dir == QChar::DirON) dir = QChar::DirL; switch(bidi.status.last) { case QChar::DirL: bidi.eor = bidi.current; bidi.status.eor = QChar::DirL; break; case QChar::DirR: case QChar::DirAL: case QChar::DirEN: case QChar::DirAN: appendRun( bidi ); break; case QChar::DirES: case QChar::DirET: case QChar::DirCS: case QChar::DirBN: case QChar::DirB: case QChar::DirS: case QChar::DirWS: case QChar::DirON: if(dir != QChar::DirL) { //last stuff takes embedding dir if( bidi.context->dir == QChar::DirR ) { if(!(bidi.status.eor == QChar::DirR)) { // AN or EN appendRun( bidi ); dir = QChar::DirR; } else bidi.eor = bidi.last; appendRun( bidi ); dir = QChar::DirL; bidi.status.eor = QChar::DirL; } else { if(bidi.status.eor == QChar::DirR) { appendRun( bidi ); dir = QChar::DirL; } else { bidi.eor = bidi.current; bidi.status.eor = QChar::DirL; break; } } } else { bidi.eor = bidi.current; bidi.status.eor = QChar::DirL; } default: break; } bidi.status.lastStrong = QChar::DirL; break; case QChar::DirAL: case QChar::DirR: if(dir == QChar::DirON) dir = QChar::DirR; switch(bidi.status.last) { case QChar::DirR: case QChar::DirAL: bidi.eor = bidi.current; bidi.status.eor = QChar::DirR; break; case QChar::DirL: case QChar::DirEN: case QChar::DirAN: appendRun( bidi ); dir = QChar::DirR; bidi.eor = bidi.current; bidi.status.eor = QChar::DirR; break; case QChar::DirES: case QChar::DirET: case QChar::DirCS: case QChar::DirBN: case QChar::DirB: case QChar::DirS: case QChar::DirWS: case QChar::DirON: if( !(bidi.status.eor == QChar::DirR) && !(bidi.status.eor == QChar::DirAL) ) { //last stuff takes embedding dir if(bidi.context->dir == QChar::DirR || bidi.status.lastStrong == QChar::DirR) { appendRun( bidi ); dir = QChar::DirR; bidi.eor = bidi.current; bidi.status.eor = QChar::DirR; } else { bidi.eor = bidi.last; appendRun( bidi ); dir = QChar::DirR; bidi.status.eor = QChar::DirR; } } else { bidi.eor = bidi.current; bidi.status.eor = QChar::DirR; } default: break; } bidi.status.lastStrong = dirCurrent; break; // weak types: case QChar::DirNSM: // ### if @sor, set dir to dirSor break; case QChar::DirEN: if(!(bidi.status.lastStrong == QChar::DirAL)) { // if last strong was AL change EN to AN if(dir == QChar::DirON) { if(bidi.status.lastStrong == QChar::DirAL) dir = QChar::DirAN; else dir = QChar::DirL; } switch(bidi.status.last) { case QChar::DirET: if ( bidi.status.lastStrong == QChar::DirR || bidi.status.lastStrong == QChar::DirAL ) { appendRun( bidi ); dir = QChar::DirEN; bidi.status.eor = QChar::DirEN; } // fall through case QChar::DirEN: case QChar::DirL: bidi.eor = bidi.current; bidi.status.eor = dirCurrent; break; case QChar::DirR: case QChar::DirAL: case QChar::DirAN: appendRun( bidi ); bidi.status.eor = QChar::DirEN; dir = QChar::DirEN; break; case QChar::DirES: case QChar::DirCS: if(bidi.status.eor == QChar::DirEN) { bidi.eor = bidi.current; break; } case QChar::DirBN: case QChar::DirB: case QChar::DirS: case QChar::DirWS: case QChar::DirON: if(bidi.status.eor == QChar::DirR) { // neutrals go to R bidi.eor = bidi.last; appendRun( bidi ); dir = QChar::DirEN; bidi.status.eor = QChar::DirEN; } else if( bidi.status.eor == QChar::DirL || (bidi.status.eor == QChar::DirEN && bidi.status.lastStrong == QChar::DirL)) { bidi.eor = bidi.current; bidi.status.eor = dirCurrent; } else { // numbers on both sides, neutrals get right to left direction if(dir != QChar::DirL) { appendRun( bidi ); bidi.eor = bidi.last; dir = QChar::DirR; appendRun( bidi ); dir = QChar::DirEN; bidi.status.eor = QChar::DirEN; } else { bidi.eor = bidi.current; bidi.status.eor = dirCurrent; } } default: break; } break; } case QChar::DirAN: dirCurrent = QChar::DirAN; if(dir == QChar::DirON) dir = QChar::DirAN; switch(bidi.status.last) { case QChar::DirL: case QChar::DirAN: bidi.eor = bidi.current; bidi.status.eor = QChar::DirAN; break; case QChar::DirR: case QChar::DirAL: case QChar::DirEN: appendRun( bidi ); dir = QChar::DirAN; bidi.status.eor = QChar::DirAN; break; case QChar::DirCS: if(bidi.status.eor == QChar::DirAN) { bidi.eor = bidi.current; bidi.status.eor = QChar::DirR; break; } case QChar::DirES: case QChar::DirET: case QChar::DirBN: case QChar::DirB: case QChar::DirS: case QChar::DirWS: case QChar::DirON: if(bidi.status.eor == QChar::DirR) { // neutrals go to R bidi.eor = bidi.last; appendRun( bidi ); dir = QChar::DirAN; bidi.status.eor = QChar::DirAN; } else if( bidi.status.eor == QChar::DirL || (bidi.status.eor == QChar::DirEN && bidi.status.lastStrong == QChar::DirL)) { bidi.eor = bidi.current; bidi.status.eor = dirCurrent; } else { // numbers on both sides, neutrals get right to left direction if(dir != QChar::DirL) { appendRun( bidi ); bidi.eor = bidi.last; dir = QChar::DirR; appendRun( bidi ); dir = QChar::DirAN; bidi.status.eor = QChar::DirAN; } else { bidi.eor = bidi.current; bidi.status.eor = dirCurrent; } } default: break; } break; case QChar::DirES:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -