📄 html.cpp
字号:
f.setStrikeOut( strikeOut ); f.setTextColor( *(colorStack.top()) ); const HTMLFont *fp = pFontManager->getFont( f ); font_stack.push( fp ); painter->setFont( *(font_stack.top()) );}void KHTMLWidget::popFont(){ font_stack.pop(); if ( font_stack.isEmpty() ) { HTMLFont f( settings->fontBaseFace, settings->fontBaseSize, settings->fontSizes ); f.setCharset(settings->charset); const HTMLFont *fp = pFontManager->getFont( f ); font_stack.push( fp ); } // we keep the current font color font_stack.top()->setTextColor( *(colorStack.top()) ); painter->setFont( *(font_stack.top()) ); weight = font_stack.top()->weight(); italic = font_stack.top()->italic(); underline = font_stack.top()->underline(); strikeOut = font_stack.top()->strikeOut();}void KHTMLWidget::popColor(){ colorStack.remove(); if ( colorStack.isEmpty() ) colorStack.push( new QColor( settings->fontBaseColor ) );}void KHTMLWidget::pushBlock(int _id, int _level, blockFunc _exitFunc, int _miscData1, int _miscData2){ HTMLStackElem *Elem = new HTMLStackElem(_id, _level, _exitFunc, _miscData1, _miscData2, blockStack); blockStack = Elem;} void KHTMLWidget::popBlock( int _id, HTMLClueV *_clue){ HTMLStackElem *Elem = blockStack; int maxLevel = 0; while( (Elem != 0) && (Elem->id != _id)) { if (maxLevel < Elem->level) { maxLevel = Elem->level; } Elem = Elem->next; } if (Elem == 0) { return; } if (maxLevel > Elem->level) { return; } Elem = blockStack; while (Elem) { HTMLStackElem *tmp = Elem; if (Elem->exitFunc != 0) (this->*(Elem->exitFunc))( _clue, Elem ); if (Elem->id == _id) { blockStack = Elem->next; Elem = 0; } else { Elem = Elem->next; } delete tmp; } } void KHTMLWidget::freeBlock(){ HTMLStackElem *Elem = blockStack; while (Elem != 0) { HTMLStackElem *tmp = Elem; Elem = Elem->next; delete tmp; } blockStack = 0;}void KHTMLWidget::blockEndFont( HTMLClueV *_clue, HTMLStackElem *Elem){ popFont(); if (Elem->miscData1) { vspace_inserted = insertVSpace( _clue, vspace_inserted ); flow = 0; }}void KHTMLWidget::blockEndPre( HTMLClueV *_clue, HTMLStackElem *Elem){ // We add a hidden space to get the height // If there is no flow box, we add one. if (!flow) newFlow( _clue ); flow->append(new HTMLHSpace( currentFont(), painter, true )); popFont(); vspace_inserted = insertVSpace( _clue, vspace_inserted ); flow = 0; inPre = false;}void KHTMLWidget::blockEndColorFont( HTMLClueV *_clue, HTMLStackElem *Elem){ popColor(); popFont();}void KHTMLWidget::blockEndIndent( HTMLClueV *_clue, HTMLStackElem *Elem){ indent = Elem->miscData1; flow = 0;}void KHTMLWidget::blockEndList( HTMLClueV *_clue, HTMLStackElem *Elem){ if (Elem->miscData2) { vspace_inserted = insertVSpace( _clue, vspace_inserted ); } if ( !listStack.remove() ) { fprintf(stderr, "%s : List stack corrupt!\n", __FILE__); } indent = Elem->miscData1; flow = 0;}void KHTMLWidget::blockEndDiv( HTMLClueV *_clue, HTMLStackElem *Elem){ divAlign = (HTMLClue::HAlign)Elem->miscData1; flow = 0;}void KHTMLWidget::parse(){// emit documentStarted(); // Dont parse an existing framed document twice. // If parse is called two times after begin() then // the second call is ususally done because the widget // has been resized./* if ( bIsFrameSet && frameSet ) { frameSet->resize( width(), height() ); return; }*/ // if there is no tokenizer then no html has been added if ( !ht ) return; if ( !bgPixmapURL.isEmpty() ) emit cancelFileRequest( bgPixmapURL ); findTextEnd(); stopParser(); if ( painter ) { painter->end(); delete painter; } painter = new QPainter(); painter->begin( this ); tempStrings.clear(); char *str; for ( str = parsedURLs.first(); str; str = parsedURLs.next() ) { delete [] str; } parsedURLs.clear(); for ( str = parsedTargets.first(); str; str = parsedTargets.next() ) delete [] str; parsedTargets.clear();#ifdef EXEC_EXTENSIONS for ( str = parsedExecs.first(); str; str = parsedExecs.next() ) { delete [] str; } parsedExecs.clear();#endif // Initialize the font stack with the default font. italic = false; underline = false; strikeOut = false; weight = QFont::Normal; *settings = *defaultSettings; colorStack.clear(); colorStack.push( new QColor( settings->fontBaseColor ) ); font_stack.clear(); HTMLFont f( settings->fontBaseFace, settings->fontBaseSize, settings->fontSizes ); // set the initial charset if(!overrideCharset.isEmpty()) f.setCharset(overrideCharset); else f.setCharset(kapp->getCharsets()->defaultCharset().name()); //f.setCharset(settings->charset); f.setTextColor( settings->fontBaseColor ); const HTMLFont *fp = pFontManager->getFont( f ); font_stack.push( fp ); if(!overrideCharset.isEmpty()) setCharset(overrideCharset); else setCharset(kapp->getCharsets()->defaultCharset().name()); // reset form related stuff formList.clear(); form = 0; formSelect = 0; inOption = false; inTextArea = false; inPre = false; inTitle = false; bodyParsed = false; target = 0; url = 0; listStack.clear(); glossaryStack.clear(); mapList.clear(); parsing = true; indent = 0; vspace_inserted = true; divAlign = HTMLClue::Left; // move to the first token ht->first(); if ( !bgPixmap.isNull() ) bgPixmap.resize( -1, -1 ); // clear page bDrawBackground = true; drawBackground( x_offset, y_offset, 0, 0, width(), height() );/* if ( colorContext ) { QColor::leaveAllocContext(); QColor::destroyAllocContext( colorContext ); } colorContext = QColor::enterAllocContext();*/ if (clue) delete clue; clue = new HTMLClueV( 0, 0, width() - leftBorder - rightBorder ); clue->setVAlign( HTMLClue::Top ); clue->setHAlign( HTMLClue::Left ); flow = 0; // this will call timerEvent which in turn calls parseBody timerId = startTimer( TIMER_INTERVAL );/* char * __end[] = { "</body>",0 }; while(parseBody(clue,__end,false));*/}void KHTMLWidget::stopParser(){ if ( !parsing ) return; if ( timerId != 0 ) killTimer( timerId ); parsing = false;}void KHTMLWidget::timerEvent( QTimerEvent * ){ debugM("Timer event\n"); static const char *end[] = { "</body>", 0 }; if ( !painter ) return; debugM("Killing timer\n"); killTimer( timerId ); timerId = 0; debugM("Has more tokens?\n"); if ( !ht->hasMoreTokens() && writing ) return; debugM("Storing font info\n"); const QFont &oldFont = painter->font(); debugM("Setting font\n"); painter->setFont( *font_stack.top() ); debugM("Getting height\n"); int lastHeight = docHeight(); parseCount = granularity; debugM("Parsing body height\n"); if ( parseBody( clue, end, TRUE ) ) stopParser(); calcSize(); calcAbsolutePos(); debugM("Restoring font\n"); painter->setFont( oldFont ); debugM("Synchronizing painter's background\n"); // FE: synchronize painter's backgroundColor painter->setBackgroundColor( settings->bgColor ); // If the visible rectangle was not filled before the parsing and // if we have something to display in the visible area now then repaint. if ( lastHeight - y_offset < height() * 2 && docHeight() - y_offset > 0 ) scheduleUpdate( false ); if (!reference.isNull()) { if (gotoAnchor()) { reference = 0; } } debugM("Parsin is over?\n"); // Parsing is over ? if ( !parsing ) { debugM("Yes\n"); debugM( "Parsing done" ); // Is y_offset too big ? if ( docHeight() - y_offset < height() ) { //printf("isFrameSet=%d, docHeight=%d\n",bIsFrameSet, docHeight()); y_offset = docHeight() - height(); if ( y_offset < 0 ) y_offset = 0; } // Adjust the scrollbar emit scrollVert( y_offset ); // Is x_offset too big ? if ( docWidth() - x_offset < width() ) { x_offset = docWidth() - width(); if ( x_offset < 0 ) x_offset = 0; } // Adjust the scrollbar emit scrollHorz( x_offset ); initialXPos = initialYPos = 0; painter->end(); delete painter; painter = 0; // Did we finish the job or are still pictures missing ? // XXXX if ( waitingFileList.count() == 0 && bgPixmapURL.isEmpty() ) if ( mapPendingFiles.isEmpty() && bgPixmapURL.isEmpty() ) { emit documentDone(); } // Now it is time to tell all frames what they should do KHTMLView *v; KHTMLWidget *w; for ( w = frameList.first(); w != 0; w = frameList.next() ) { v = w->getView(); if ( v->getCookie() ) { v->openURL( v->getCookie() ); } v->show(); } HTMLFrameSet *s; for ( s = framesetList.first(); s != 0; s = framesetList.next() ) { s->show(); } if ( ( s = framesetList.getFirst() ) ) s->setGeometry( 0, 0, width(), height() ); bDrawBackground = true; } else{ debugM("No\n"); timerId = startTimer( TIMER_INTERVAL ); } }void KHTMLWidget::calcSize(){ if ( clue == 0 ) return; clue->reset(); int _max_width = width() - leftBorder - rightBorder; int _min_width = clue->calcMinWidth(); if (_min_width > _max_width) { _max_width = _min_width; } clue->setMaxWidth( _max_width ); clue->calcSize(); clue->setPos( 0, clue->getAscent() ); emit documentChanged();}bool KHTMLWidget::insertVSpace( HTMLClueV *_clue, bool _vspace_inserted ){ if ( !_vspace_inserted ) { HTMLClueFlow *f = new HTMLClueFlow( 0, 0, _clue->getMaxWidth() ); _clue->append( f ); HTMLVSpace *t = new HTMLVSpace( settings->fontSizes[settings->fontBaseSize] ); f->append( t ); flow = 0; } return true;}void KHTMLWidget::newFlow(HTMLClue * _clue){ if (inPre) flow = new HTMLClueH( 0, 0, _clue->getMaxWidth() ); else flow = new HTMLClueFlow( 0, 0, _clue->getMaxWidth() ); flow->setIndent( indent ); flow->setHAlign( divAlign ); _clue->append( flow );}// Function insertText// ====// This function inserts text in the flow. It decides whether to use// HTMLText or HTMLTextMaster objects for the text.// // HTMLText is used if the text may not be broken.// HTMLTextMaster is used if the text contains (breaking) spaces.//// This function converts non-breaking spaces to normal spaces since// non-breaking spaces aren't shown correctly for all fonts.//// The hard part is to make several objects if the text contains both// normal spaces and non-breaking spaces.void KHTMLWidget::insertText(char *str, const HTMLFont * fp){ enum { unknown, fixed, variable} textType = unknown; // Flag, indicating whether text may be broken int i = 0; char *remainingStr = 0; bool insertSpace = false; bool insertNBSP = false; bool insertBlock = false; for(;;) { if (((unsigned char *)str)[i] == 0xa0) { // Non-breaking space if (textType == variable) { // We have a non-breaking space in a block of variable text // We need to split the text and insert a seperate // non-breaking space object str[i] = 0x00; // End of string remainingStr = &(str[i+1]); insertBlock = true; insertNBSP = true; } else { // We have a non-breaking space: this makes the block fixed. str[i] = 0x20; // Normal space textType = fixed; } } else if (str[i] == 0x20) { // Normal space if (textType == fixed) { // We have a normal space in a block of fixed text. // We need to split the text and insert a seperate normal // space. str[i] = 0x00; // End of string remainingStr = &(str[i+1]); insertBlock = true; insertSpace = true; } else { // We have a normal space: if this is the first character // we insert a normal space and continue if (i == 0) { if (str[i+1] == 0x00) { str++; remainingStr = 0; } else { str[i] = 0x00; // End of string remainingStr = str+1; } insertBlock = true; // Block is zero-length, no actual insertion insertSpace = true; } else if (str[i+1] == 0x00) { // Last character is a space: Insert the block and // a normal space str[i] = 0x00; // End of string remainingStr = 0; insertBlock = true; insertSpace = true; } else { textType = variable; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -