📄 bidi.cpp
字号:
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( status.eor != QChar::DirR && status.eor != QChar::DirAL ) { //last stuff takes embedding dir if(context->dir == QChar::DirR || status.lastStrong == QChar::DirR) { appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON; dir = QChar::DirR; eor = current; } else { eor = last; appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON; dir = QChar::DirR; } } else { eor = current; status.eor = QChar::DirR; } default: break; } status.lastStrong = dirCurrent; break; // weak types: case QChar::DirNSM: // ### if @sor, set dir to dirSor break; case QChar::DirEN: if(status.lastStrong != QChar::DirAL) { // if last strong was AL change EN to AN if(dir == QChar::DirON) { if(status.lastStrong == QChar::DirAL) dir = QChar::DirAN; else dir = QChar::DirL; } switch(status.last) { case QChar::DirET: if ( status.lastStrong == QChar::DirR || status.lastStrong == QChar::DirAL ) { appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirAN; } // fall through case QChar::DirEN: case QChar::DirL: eor = current; status.eor = dirCurrent; break; case QChar::DirR: case QChar::DirAL: case QChar::DirAN: appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; status.eor = QChar::DirEN; dir = QChar::DirAN; break; case QChar::DirES: case QChar::DirCS: if(status.eor == QChar::DirEN) { eor = current; break; } case QChar::DirBN: case QChar::DirB: case QChar::DirS: case QChar::DirWS: case QChar::DirON: if(status.eor == QChar::DirR) { // neutrals go to R eor = last; appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirEN; dir = QChar::DirAN; } else if( status.eor == QChar::DirL || (status.eor == QChar::DirEN && status.lastStrong == QChar::DirL)) { eor = current; status.eor = dirCurrent; } else { // numbers on both sides, neutrals get right to left direction if(dir != QChar::DirL) { appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON; eor = last; dir = QChar::DirR; appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON; dir = QChar::DirAN; } else { eor = current; status.eor = dirCurrent; } } default: break; } break; } case QChar::DirAN: dirCurrent = QChar::DirAN; if(dir == QChar::DirON) dir = QChar::DirAN; switch(status.last) { case QChar::DirL: case QChar::DirAN: eor = current; status.eor = QChar::DirAN; break; case QChar::DirR: case QChar::DirAL: case QChar::DirEN: appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON; break; case QChar::DirCS: if(status.eor == QChar::DirAN) { eor = current; 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(status.eor == QChar::DirR) { // neutrals go to R eor = last; appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON; dir = QChar::DirAN; } else if( status.eor == QChar::DirL || (status.eor == QChar::DirEN && status.lastStrong == QChar::DirL)) { eor = current; status.eor = dirCurrent; } else { // numbers on both sides, neutrals get right to left direction if(dir != QChar::DirL) { appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON; eor = last; dir = QChar::DirR; appendRun(runs, sor, eor, context, dir); ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON; dir = QChar::DirAN; } else { eor = current; status.eor = dirCurrent; } } default: break; } break; case QChar::DirES: case QChar::DirCS: break; case QChar::DirET: if(status.last == QChar::DirEN) { dirCurrent = QChar::DirEN; eor = current; status.eor = dirCurrent; break; } break; // boundary neutrals should be ignored case QChar::DirBN: break; // neutrals case QChar::DirB: // ### what do we do with newline and paragraph seperators that come to here? break; case QChar::DirS: // ### implement rule L1 break; case QChar::DirWS: case QChar::DirON: break; default: break; } //cout << " after: dir=" << // dir << " current=" << dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << context->dir << endl; if(current.atEnd()) break; // set status.last as needed. switch(dirCurrent) { case QChar::DirET: case QChar::DirES: case QChar::DirCS: case QChar::DirS: case QChar::DirWS: case QChar::DirON: switch(status.last) { case QChar::DirL: case QChar::DirR: case QChar::DirAL: case QChar::DirEN: case QChar::DirAN: status.last = dirCurrent; break; default: status.last = QChar::DirON; } break; case QChar::DirNSM: case QChar::DirBN: // ignore these break; default: status.last = dirCurrent; } last = current; ++current; }#if BIDI_DEBUG > 0 kdDebug(6041) << "reached end of line current=" << current.pos << ", eor=" << eor.pos << endl;#endif eor = last;#else eor = end;#endif appendRun(runs, sor, eor, context, dir); BidiContext *endEmbed = context; // both commands below together give a noop... //endEmbed->ref(); //context->deref(); // reorder line according to run structure... // first find highest and lowest levels uchar levelLow = 128; uchar levelHigh = 0; BidiRun *r = runs.first(); while ( r ) { //printf("level = %d\n", r->level); if ( r->level > levelHigh ) levelHigh = r->level; if ( r->level < levelLow ) levelLow = r->level; r = runs.next(); } // implements reordering of the line (L2 according to Bidi spec): // L2. From the highest level found in the text to the lowest odd level on each line, // reverse any contiguous sequence of characters that are at that level or higher. // reversing is only done up to the lowest odd level if(!levelLow%2) levelLow++;#if BIDI_DEBUG > 0 kdDebug(6041) << "reorderLine: lineLow = " << (uint)levelLow << ", lineHigh = " << (uint)levelHigh << endl; kdDebug(6041) << "logical order is:" << endl; QListIterator<BidiRun> it2(runs); BidiRun *r2; for ( ; (r2 = it2.current()); ++it2 ) kdDebug(6041) << " " << r2 << " start=" << r2->start << " stop=" << r2->stop << " level=" << (uint)r2->level << endl;#endif int count = runs.count() - 1; // do not reverse for visually ordered web sites if(!style()->visuallyOrdered()) { while(levelHigh >= levelLow) { int i = 0; while ( i < count ) { while(i < count && runs.at(i)->level < levelHigh) i++; int start = i; while(i <= count && runs.at(i)->level >= levelHigh) i++; int end = i-1; if(start != end) { //kdDebug(6041) << "reversing from " << start << " to " << end << endl; for(int j = 0; j < (end-start+1)/2; j++) { BidiRun *first = runs.take(start+j); BidiRun *last = runs.take(end-j-1); runs.insert(start+j, last); runs.insert(end-j, first); } } i++; if(i >= count) break; } levelHigh--; } }#if BIDI_DEBUG > 0 kdDebug(6041) << "visual order is:" << endl; QListIterator<BidiRun> it3(runs); BidiRun *r3; for ( ; (r3 = it3.current()); ++it3 ) { kdDebug(6041) << " " << r3 << endl; }#endif int maxPositionTop = 0; int maxPositionBottom = 0; int maxAscent = 0; int maxDescent = 0; r = runs.first(); while ( r ) { r->height = r->obj->lineHeight( firstLine ); r->baseline = r->obj->baselinePosition( firstLine ); if ( r->baseline > r->height ) r->baseline = r->height; r->vertical = r->obj->verticalPositionHint( firstLine ); //kdDebug(6041) << "object="<< r->obj << " height="<<r->height<<" baseline="<< r->baseline << " vertical=" << r->vertical <<endl; //int ascent; if ( r->vertical == PositionTop ) { if ( maxPositionTop < r->height ) maxPositionTop = r->height; } else if ( r->vertical == PositionBottom ) { if ( maxPositionBottom < r->height ) maxPositionBottom = r->height; } else { int ascent = r->baseline - r->vertical; int descent = r->height - ascent; if(maxAscent < ascent) maxAscent = ascent; if(maxDescent < descent) maxDescent = descent; } r = runs.next(); } if ( maxAscent+maxDescent < QMAX( maxPositionTop, maxPositionBottom ) ) { // now the computed lineheight needs to be extended for the // positioned elements // see khtmltests/rendering/html_align.html // ### only iterate over the positioned ones! for ( r = runs.first(); r; r = runs.next() ) { if ( r->vertical == PositionTop ) { if ( maxAscent + maxDescent < r->height ) maxDescent = r->height - maxAscent; } else if ( r->vertical == PositionBottom ) { if ( maxAscent + maxDescent < r->height ) maxAscent = r->height - maxDescent; } else continue; if ( maxAscent + maxDescent >= QMAX( maxPositionTop, maxPositionBottom ) ) break; } } int maxHeight = maxAscent + maxDescent; r = runs.first(); int totWidth = 0; while ( r ) { if(r->vertical == PositionTop) r->vertical = m_height; else if(r->vertical == PositionBottom) r->vertical = m_height + maxHeight - r->height; else r->vertical += m_height + maxAscent - r->baseline; //kdDebug(6041) << "object="<< r->obj << " placing at vertical=" << r->vertical <<endl; if(r->obj->isText()) r->width = static_cast<RenderText *>(r->obj)->width(r->start, r->stop-r->start); else { r->obj->calcWidth(); r->width = r->obj->width()+r->obj->marginLeft()+r->obj->marginRight(); } totWidth += r->width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -