📄 htmlclue.cpp
字号:
for ( obj = head; obj != 0; obj = obj->next() ) { obj->getSelectedText( _str ); } if ( tail && tail->isSelected() ) _str += '\n';}void HTMLClueH::setMaxWidth( int _w ){ HTMLObject *obj; max_width = _w; // first calculate width minus fixed width objects for ( obj = head; obj != 0; obj = obj->next() ) { if ( obj->getPercent() <= 0 ) // i.e. fixed width objects _w -= obj->getWidth(); } // now call setMaxWidth for variable objects for ( obj = head; obj != 0; obj = obj->next() ) if ( obj->getPercent() > 0 ) obj->setMaxWidth( _w - indent );}void HTMLClueH::calcSize( HTMLClue *parent ){ // make sure children are properly sized setMaxWidth( max_width ); HTMLClue::calcSize( parent ); HTMLObject *obj; int lmargin = 0; if ( parent ) lmargin = parent->getLeftMargin( getYPos() ); width = lmargin + indent; descent = 0; ascent = 0; int a = 0; int d = 0; for ( obj = head; obj != 0; obj = obj->next() ) { obj->fitLine( (obj == head), true, -1); obj->setXPos( width ); width += obj->getWidth(); if ( obj->getAscent() > a ) a = obj->getAscent(); if ( obj->getDescent() > d ) d = obj->getDescent(); } ascent = a+d; switch ( valign ) { case Top: for ( obj = head; obj != 0; obj = obj->next() ) obj->setYPos( obj->getAscent() ); break; case VCenter: for ( obj = head; obj != 0; obj = obj->next() ) obj->setYPos( ascent/2 ); break; default: for ( obj = head; obj != 0; obj = obj->next() ) obj->setYPos( ascent - d ); }}int HTMLClueH::calcMinWidth(){ HTMLObject *obj; int minWidth = 0; for ( obj = head; obj != 0; obj = obj->next() ) minWidth += obj->calcMinWidth(); return minWidth + indent;} int HTMLClueH::calcPreferredWidth(){ HTMLObject *obj; int prefWidth = 0; for ( obj = head; obj != 0; obj = obj->next() ) prefWidth += obj->calcPreferredWidth(); return prefWidth + indent;} //-----------------------------------------------------------------------------// process one line at a time, making sure that all objects on a line// are able to be selected if the cursor is within the maximum// ascent and descent of the line.//bool HTMLClueFlow::selectText( KHTMLWidget *_htmlw, HTMLChain *_chain, int _x1, int _y1, int _x2, int _y2, int _tx, int _ty ){ HTMLObject *lineEnd = head, *obj = head; bool isSel = false; int ypos, a, d, rely1, rely2; _tx += x; _ty += y - ascent; _chain->push( this ); while ( lineEnd ) { ypos = lineEnd->getYPos(); a = lineEnd->getAscent(); d = lineEnd->getDescent(); while ( lineEnd && lineEnd->getYPos() == ypos ) { if ( lineEnd->getAscent() > a ) a = lineEnd->getAscent(); if ( lineEnd->getDescent() > d ) d = lineEnd->getDescent(); lineEnd = lineEnd->next(); } rely1 = _y1 - ( y - ascent ); rely2 = _y2 - ( y - ascent ); if ( rely1 > ypos - a && rely1 < ypos + d ) rely1 = ypos-1; if ( rely2 > ypos - a && rely2 < ypos + d ) rely2 = ypos; while ( obj != lineEnd ) { if ( obj->getObjectType() == Clue ) isSel = obj->selectText(_htmlw,_chain,_x1 - x, _y1 - (y-ascent), _x2 - x, _y2 - ( y - ascent ), _tx, _ty ) || isSel; else isSel = obj->selectText(_htmlw,_chain,_x1 - x, rely1, _x2 - x, rely2, _tx, _ty ) || isSel; obj = obj->next(); } } _chain->pop(); return isSel;}void HTMLClueFlow::getSelectedText( QString &_str ){ HTMLObject *obj; for ( obj = head; obj != 0; obj = obj->next() ) { if ( obj != head || !obj->isSeparator() ) obj->getSelectedText( _str ); } if ( tail && tail->isSelected() && !tail->isNewline() ) _str += '\n';}// MRJ - 26/10/97: I've given this a rewrite so that its layout is done// correctly, i.e. break ONLY on separators and newlines instead of breaking// after any object. This is much nicer and smaller code now also. Sorry// if I broke something.// void HTMLClueFlow::calcSize( HTMLClue *parent ){// HTMLClue::calcSize( parent ); HTMLObject *obj = head; HTMLObject *line = head; HTMLVSpace::Clear clear = HTMLVSpace::CNone;; int lmargin, rmargin; ascent = 0; descent = 0; width = 0; lmargin = parent->getLeftMargin( getYPos() ); if ( indent > lmargin ) lmargin = indent; rmargin = parent->getRightMargin( getYPos() ); int w = lmargin; int a = 0; int d = 0; bool newLine = false; while ( obj != 0 ) { // If we get a newline object, set newLine=true so that the current // line will be aligned, and the next line prepared. if ( obj->isNewline() ) {// WABA: Only update the height if this line has no height already if ( !a ) a = obj->getAscent(); if ( !a && (obj->getDescent() > d) ) d = obj->getDescent(); newLine = true; HTMLVSpace *vs = (HTMLVSpace *)obj; clear = vs->clear(); obj = obj->next(); } // add a separator else if ( obj->isSeparator() ) { obj->setXPos( w ); // skip a space at the start of a line if ( w != lmargin ) { w += obj->getWidth(); if ( obj->getAscent() > a ) a = obj->getAscent(); if ( obj->getDescent() > d ) d = obj->getDescent(); } obj = obj->next(); } // a left or right aligned object is not added in this line. It // is added to our parent's list of aligned objects and will be // taken into account in subsequent get*Margin() calls. else if ( obj->isAligned() ) { HTMLClueAligned *c = (HTMLClueAligned *)obj; if ( !parent->appended( c ) ) { obj->calcSize(); if ( c->getHAlign() == Left ) { c->setPos( lmargin, ascent + c->getAscent() ); parent->appendLeftAligned( c ); } else { c->setPos( rmargin - c->getWidth(), ascent + c->getAscent() ); parent->appendRightAligned( c ); } } obj = obj->next(); } // This is a normal object. We must add all objects upto the next // separator/newline/aligned object. else { // By setting "newLine = true" we move the complete run to // a new line. // We shouldn't set newLine if we are at the start of a line. int runWidth = 0; HTMLObject *run = obj; while ( run && !run->isSeparator() && !run->isNewline() && !run->isAligned() ) { HTMLFitType fit; run->setMaxWidth( rmargin - lmargin ); fit = run->fitLine( (w+runWidth == lmargin), // Start of line (obj == line), // first run rmargin-runWidth-w); if ( fit == HTMLNoFit) { newLine = true; break; } //run->calcSize(parent); // Lars: the above gives wrong lmargins, since run // run->setSize() usually calls // parent->getLeftMargin( getYSize() ) to determine the // left margin. But y is relative to the clues parent, // not absolute... So this should fix it. run->calcSize(this); runWidth += run->getWidth(); // If this run cannot fit in the allowed area, break it // on a non-seperator. // Don't break here, if it is the first object. if (( run != obj) && (runWidth > rmargin - lmargin )) { break; } if ( run->getAscent() > a ) a = run->getAscent(); if ( run->getDescent() > d ) d = run->getDescent(); run = run->next(); if (fit == HTMLPartialFit) { // We encountered an implicit separator break; } // If this is the first object but it doesn't fit the // allowed area, break directly after it. if (runWidth > rmargin - lmargin) { break; } } // if these objects do not fit in the current line and we are // not at the start of a line then end the current line in // preparation to add this run in the next pass. if ( w > lmargin && w + runWidth > rmargin ) { newLine = true; } if (!newLine) { int new_y, new_lmargin, new_rmargin; // Check whether this run still fits the current flow area, // especially with respect to its height. // If not, find a rectangle with height a+b. The size of // the rectangle will be rmargin-lmargin. parent->findFreeArea(y, line->getWidth(), a+d, indent, &new_y, &new_lmargin, &new_rmargin); if ( (new_y != y) || (new_lmargin > lmargin) || (new_rmargin < rmargin) ) { // We did not get the location we expected. // We start building our current line again // We got shifted downwards by "new_y - y" // add this to both "y" and "ascent" new_y -= y; y += new_y; ascent += new_y; lmargin = new_lmargin; if ( indent > lmargin ) lmargin = indent; rmargin = new_rmargin; obj = line; // Reset this line w = lmargin; d = 0; a = 0; newLine = false; clear = HTMLVSpace::CNone; } else { while ( obj != run ) { obj->setXPos( w ); w += obj->getWidth(); obj = obj->next(); } } } } // if we need a new line, or all objects have been processed // and need to be aligned. if ( newLine || !obj ) { int extra = 0; ascent += a + d; y += a + d; if ( w > width ) width = w; if ( halign == HCenter ) { extra = ( rmargin - w ) / 2; if ( extra < 0 ) extra = 0; } else if ( halign == Right ) { extra = rmargin - w; if ( extra < 0 ) extra = 0; } while ( line != obj ) { if ( !line->isAligned() ) { line->setYPos( ascent - d ); line->setMaxAscent( a ); line->setMaxDescent( d ); if ( halign == HCenter || halign == Right ) { line->setXPos( line->getXPos() + extra ); } } line = line->next(); } int oldy = y; if ( clear == HTMLVSpace::All ) { int new_lmargin, new_rmargin; parent->findFreeArea(oldy, max_width, 1, 0, &y, &new_lmargin, &new_rmargin); } else if ( clear == HTMLVSpace::Left) { y = parent->getLeftClear( oldy ); } else if ( clear == HTMLVSpace::Right) { y = parent->getRightClear( oldy ); } ascent += y-oldy; lmargin = parent->getLeftMargin( y ); if ( indent > lmargin ) lmargin = indent; rmargin = parent->getRightMargin( y ); w = lmargin; d = 0; a = 0; newLine = false; clear = HTMLVSpace::CNone; } } if ( width < max_width ) width = max_width;}int HTMLClueFlow::findPageBreak( int _y ){ if ( _y > y ) return -1; HTMLObject *obj; int pos, minpos, yp; for ( obj = head; obj != 0; obj = obj->next() ) { yp = obj->getYPos(); minpos = yp; while ( obj && obj->getYPos() == yp ) { if ( !obj->isAligned() ) { pos = obj->findPageBreak( _y - ( y - ascent ) ); if ( pos >= 0 && pos < minpos ) minpos = pos; } obj = obj->next(); } if ( minpos != yp ) return ( minpos + y - ascent ); if (!obj) return -1; } return -1;}int HTMLClueFlow::calcMinWidth(){#if 1 HTMLObject *obj; int minWidth = 0; for ( obj = head; obj != 0; obj = obj->next() ) { int w = obj->calcMinWidth(); if ( w > minWidth ) minWidth = w; } minWidth += indent; if ( isFixedWidth() ) { if (width > minWidth) minWidth = width; } return minWidth;#else HTMLObject *obj = head; int minWidth = 0; int ow, runWidth = 0; while ( obj ) { if ( obj->isSeparator() || obj->isNewline() ) { ow = obj->calcMinWidth(); runWidth += ow; if ( runWidth > minWidth ) minWidth = runWidth; runWidth = 0; } else { ow = obj->calcMinWidth(); // we try not to grow larger than max_width by breaking at // object boundaries if necessary. if ( runWidth + ow > max_width ) runWidth = 0; runWidth += ow; if ( runWidth > minWidth ) minWidth = runWidth; } obj = obj->next(); } if ( isFixedWidth() ) { if (width > minWidth) minWidth = width; } return minWidth + indent;#endif}int HTMLClueFlow::calcPreferredWidth(){ HTMLObject *obj; int maxw = 0, w = 0; for ( obj = head; obj != 0; obj = obj->next() ) { if ( !obj->isNewline() ) { w += obj->calcPreferredWidth(); } else { if ( w > maxw ) maxw = w; w = 0; } } if ( w > maxw ) maxw = w; return maxw + indent;}void HTMLClueFlow::setMaxWidth( int _max_width ){ max_width = _max_width; HTMLObject *obj; for ( obj = head; obj != 0; obj = obj->next() ) obj->setMaxWidth( max_width - indent );}//-----------------------------------------------------------------------------void HTMLClueAligned::setMaxWidth( int _max_width ){ max_width = _max_width; HTMLObject *obj; for ( obj = head; obj != 0; obj = obj->next() ) obj->setMaxWidth( max_width );}// HTMLClueAligned behaves like a HTMLClueV//void HTMLClueAligned::calcSize( HTMLClue *parent ){ HTMLClue::calcSize( parent ); HTMLObject *obj; width = 0; ascent = ALIGN_BORDER; descent = 0; for ( obj = head; obj != 0; obj = obj->next() ) { if ( obj->getWidth() > width ) width = obj->getWidth(); ascent += obj->getHeight(); obj->setPos( ALIGN_BORDER, ascent - obj->getDescent() ); } ascent += ALIGN_BORDER; width += (ALIGN_BORDER*2);}//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -