diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index 35e98b4..d725578 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -56,6 +56,8 @@ #include #include #include +#include +#include #include "goo/GooString.h" #include "goo/GooList.h" #include "UnicodeMap.h" @@ -466,34 +468,41 @@ void HtmlPage::endString() { curStr = NULL; } -static const char *strrstr( const char *s, const char *ss ) +static bool tag_exists( std::list tags, std::string tag ) { - const char *p = strstr( s, ss ); - for( const char *pp = p; pp != NULL; pp = strstr( p+1, ss ) ){ - p = pp; - } - return p; + for( std::list::iterator t = tags.begin(); t != tags.end(); ++t ) { + if( *t == tag ) { + return true; + } + } + return false; } -static void CloseTags( GooString *htext, GBool &finish_a, GBool &finish_italic, GBool &finish_bold ) +static void CloseTag(GooString *htext, std::list &tags, std::string tag) { - const char *last_italic = finish_italic && ( finish_bold || finish_a ) ? strrstr( htext->getCString(), "" ) : NULL; - const char *last_bold = finish_bold && ( finish_italic || finish_a ) ? strrstr( htext->getCString(), "" ) : NULL; - const char *last_a = finish_a && ( finish_italic || finish_bold ) ? strrstr( htext->getCString(), " ( last_italic > last_bold ? last_italic : last_bold ) ){ - htext->append("", 4); - finish_a = false; + while( !tags.empty() && tags.back() != tag ) { + std::string current_tag = tags.back(); + htext->append(current_tag.c_str(), current_tag.length()); + tags.pop_back(); + } + if( !tags.empty()) { + std::string current_tag = tags.back(); + htext->append(current_tag.c_str(), current_tag.length()); + tags.pop_back(); + } +} + +static void CloseTags( GooString *htext, GBool &finish_a, GBool &finish_italic, GBool &finish_bold, std::list &tags ) +{ + if( finish_a ) { + CloseTag(htext, tags, ""); + } + if( finish_italic ) { + CloseTag(htext, tags, ""); } - if( finish_italic && finish_bold && last_italic > last_bold ){ - htext->append("", 4); - finish_italic = false; + if( finish_bold ) { + CloseTag(htext, tags, ""); } - if( finish_bold ) - htext->append("", 4); - if( finish_italic ) - htext->append("", 4); - if( finish_a ) - htext->append(""); } // Strings are lines of text; @@ -520,6 +529,8 @@ void HtmlPage::coalesce() { printf("\n------------------------------------------------------------\n\n"); #endif str1 = yxStrings; + std::list tags; + int index = 0; if( !str1 ) return; @@ -564,15 +575,23 @@ void HtmlPage::coalesce() { str1 = yxStrings; hfont1 = getFont(str1); - if( hfont1->isBold() ) - str1->htext->insert(0,"",3); - if( hfont1->isItalic() ) - str1->htext->insert(0,"",3); if( str1->getLink() != NULL ) { + tags.push_back(""); GooString *ls = str1->getLink()->getLinkStart(); - str1->htext->insert(0, ls); + str1->htext->insert(index, ls); + index += ls->getLength(); delete ls; } + if( hfont1->isItalic() ) { + tags.push_back(""); + str1->htext->insert(index, "", 3); + index += 3; + } + if( hfont1->isBold() ) { + tags.push_back(""); + str1->htext->insert(index, "", 3); + index += 3; + } curX = str1->xMin; curY = str1->yMin; while (str1 && (str2 = str1->yxNext)) { @@ -675,19 +694,23 @@ void HtmlPage::coalesce() { HtmlLink *hlink2 = str2->getLink(); bool switch_links = !hlink1 || !hlink2 || !hlink1->isEqualDest(*hlink2); GBool finish_a = switch_links && hlink1 != NULL; - GBool finish_italic = hfont1->isItalic() && ( !hfont2->isItalic() || finish_a ); - GBool finish_bold = hfont1->isBold() && ( !hfont2->isBold() || finish_a || finish_italic ); - CloseTags( str1->htext, finish_a, finish_italic, finish_bold ); - if( switch_links && hlink2 != NULL ) { + GBool finish_italic = hfont1->isItalic() && !hfont2->isItalic(); + GBool finish_bold = hfont1->isBold() && !hfont2->isBold(); + CloseTags( str1->htext, finish_a, finish_italic, finish_bold, tags ); + if( switch_links && hlink2 != NULL && !tag_exists(tags, "") ) { + tags.push_back(""); GooString *ls = hlink2->getLinkStart(); str1->htext->append(ls); delete ls; } - if( ( !hfont1->isItalic() || finish_italic ) && hfont2->isItalic() ) - str1->htext->append("", 3); - if( ( !hfont1->isBold() || finish_bold ) && hfont2->isBold() ) - str1->htext->append("", 3); - + if( hfont2->isItalic() && !tag_exists(tags, "") ) { + tags.push_back(""); + str1->htext->append("", 3); + } + if( hfont2->isBold() && !tag_exists(tags, "") ) { + tags.push_back(""); + str1->htext->append("", 3); + } str1->htext->append(str2->htext); // str1 now contains href for link of str2 (if it is defined) @@ -706,20 +729,29 @@ void HtmlPage::coalesce() { GBool finish_a = str1->getLink() != NULL; GBool finish_bold = hfont1->isBold(); GBool finish_italic = hfont1->isItalic(); - CloseTags( str1->htext, finish_a, finish_italic, finish_bold ); + CloseTags( str1->htext, finish_a, finish_italic, finish_bold, tags ); str1->xMin = curX; str1->yMin = curY; str1 = str2; curX = str1->xMin; curY = str1->yMin; hfont1 = hfont2; - if( hfont1->isBold() ) - str1->htext->insert(0,"",3); - if( hfont1->isItalic() ) - str1->htext->insert(0,"",3); + index = 0; if( str1->getLink() != NULL ) { - GooString *ls = str1->getLink()->getLinkStart(); - str1->htext->insert(0, ls); - delete ls; + tags.push_back(""); + GooString *ls = str1->getLink()->getLinkStart(); + str1->htext->insert(index, ls); + index += ls->getLength(); + delete ls; + } + if( hfont1->isItalic() ) { + tags.push_back(""); + str1->htext->insert(index, "", 3); + index += 3; + } + if( hfont1->isBold() ) { + tags.push_back(""); + str1->htext->insert(index, "", 3); + index += 3; } } } @@ -728,7 +760,7 @@ void HtmlPage::coalesce() { GBool finish_bold = hfont1->isBold(); GBool finish_italic = hfont1->isItalic(); GBool finish_a = str1->getLink() != NULL; - CloseTags( str1->htext, finish_a, finish_italic, finish_bold ); + CloseTags( str1->htext, finish_a, finish_italic, finish_bold, tags ); #if 0 //~ for debugging for (str1 = yxStrings; str1; str1 = str1->yxNext) {