include/svtools/HtmlWriter.hxx | 31 + include/svtools/htmlout.hxx | 1 include/vcl/gdimtf.hxx | 6 include/vcl/graphicfilter.hxx | 2 sfx2/source/doc/graphhelp.cxx | 38 +- svtools/qa/unit/testHtmlWriter.cxx | 124 +++++++ svtools/source/svhtml/HtmlWriter.cxx | 49 ++ svtools/source/svhtml/htmlout.cxx | 25 + sw/qa/extras/htmlexport/data/HTMLImage.odt |binary sw/qa/extras/htmlexport/htmlexport.cxx | 30 + sw/source/filter/html/htmlatr.cxx | 3 sw/source/filter/html/htmlflywriter.cxx | 505 +++++++++++++++++++++-------- sw/source/filter/html/wrthtml.cxx | 62 +-- sw/source/filter/html/wrthtml.hxx | 7 vcl/source/filter/graphicfilter.cxx | 12 vcl/source/gdi/gdimtf.cxx | 21 - 16 files changed, 712 insertions(+), 204 deletions(-)
New commits: commit 935e8fc98c033680029e4531747a2f680f50d5ca Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Mon Sep 22 00:09:22 2014 +0200 werror: ânDirectionâ shadows a member of 'this' Change-Id: Idb56ef8327164f22379b732f9507e0b255b0998c diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx index b64f9aa..5cc182f 100644 --- a/sw/source/filter/html/wrthtml.cxx +++ b/sw/source/filter/html/wrthtml.cxx @@ -1307,10 +1307,10 @@ void SwHTMLWriter::OutDirection( sal_uInt16 nDir ) } } -OString SwHTMLWriter::convertDirection(sal_uInt16 nDirection) +OString SwHTMLWriter::convertDirection(sal_uInt16 nDir) { OString sConverted; - switch (nDirection) + switch (nDir) { case FRMDIR_HORI_LEFT_TOP: case FRMDIR_VERT_TOP_LEFT: commit 2113c50b455ae67874eb61ff0dcd75c766b17002 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sun Sep 21 21:34:01 2014 +0200 fdo#62104 Optimize thumbnail size by using PNG8 and other tricks Change-Id: I54ece4a1977fe93c0e7bbb11774bd8657912c6bb diff --git a/include/vcl/gdimtf.hxx b/include/vcl/gdimtf.hxx index 4d863aa..414f430 100644 --- a/include/vcl/gdimtf.hxx +++ b/include/vcl/gdimtf.hxx @@ -24,6 +24,7 @@ #include <tools/gen.hxx> #include <tools/link.hxx> #include <vcl/mapmod.hxx> +#include <vcl/bitmap.hxx> #include <vector> class OutputDevice; @@ -214,7 +215,10 @@ public: friend VCL_DLLPUBLIC SvStream& WriteGDIMetaFile( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile ); /// Creates an antialiased thumbnail, with maximum width or height of nMaximumExtent. - bool CreateThumbnail(BitmapEx& rBmpEx, sal_uInt32 nMaximumSize = 256) const; + bool CreateThumbnail(BitmapEx& rBitmapEx, + sal_uInt32 nMaximumExtent = 256, + BmpConversion nColorConversion = BMP_CONVERSION_24BIT, + long nScaleFlag = BMP_SCALE_BESTQUALITY) const; void UseCanvas( bool _bUseCanvas ); bool GetUseCanvas() const { return bUseCanvas; } diff --git a/sfx2/source/doc/graphhelp.cxx b/sfx2/source/doc/graphhelp.cxx index f1d0bc5..2741131 100644 --- a/sfx2/source/doc/graphhelp.cxx +++ b/sfx2/source/doc/graphhelp.cxx @@ -39,6 +39,7 @@ #include <vcl/outdev.hxx> #include <vcl/virdev.hxx> #include <vcl/bitmapex.hxx> +#include <vcl/graphicfilter.hxx> #include <tools/stream.hxx> #include <tools/helpers.hxx> @@ -52,7 +53,7 @@ #include "graphhelp.hxx" #include "doc.hrc" -using namespace ::com::sun::star; +using namespace css; SvMemoryStream* GraphicHelper::getFormatStrFromGDI_Impl( const GDIMetaFile* pGDIMeta, sal_uInt32 nFormat ) { @@ -192,30 +193,33 @@ bool GraphicHelper::supportsMetaFileHandle_Impl() // static -bool GraphicHelper::getThumbnailFormatFromGDI_Impl( GDIMetaFile* pMetaFile, - const uno::Reference< io::XStream >& xStream ) +bool GraphicHelper::getThumbnailFormatFromGDI_Impl(GDIMetaFile* pMetaFile, const uno::Reference<io::XStream>& xStream) { bool bResult = false; - SvStream* pStream = NULL; - if ( xStream.is() ) - pStream = ::utl::UcbStreamHelper::CreateStream( xStream ); + if (!pMetaFile || !xStream.is()) + return false; - if ( pMetaFile && pStream && !pStream->GetError() ) - { - BitmapEx aResultBitmap; + boost::scoped_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xStream)); - bResult = pMetaFile->CreateThumbnail(aResultBitmap); + if (pStream->GetError()) + return false; - if ( bResult ) - bResult = ( !aResultBitmap.IsEmpty() - && GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0 - && ( pStream->Flush(), !pStream->GetError() ) ); + BitmapEx aResultBitmap; - delete pStream; - } + bResult = pMetaFile->CreateThumbnail(aResultBitmap, 256, BMP_CONVERSION_8BIT_COLORS, BMP_SCALE_DEFAULT); - return bResult; + if (!bResult || aResultBitmap.IsEmpty()) + return false; + + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + + if (rFilter.compressAsPNG(aResultBitmap, *pStream.get(), 9) != GRFILTER_OK) + return false; + + pStream->Flush(); + + return !pStream->GetError(); } // static diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx index 3bd6eb2..3b0d9d0 100644 --- a/vcl/source/gdi/gdimtf.cxx +++ b/vcl/source/gdi/gdimtf.cxx @@ -2879,7 +2879,7 @@ SvStream& GDIMetaFile::Write( SvStream& rOStm ) return rOStm; } -bool GDIMetaFile::CreateThumbnail(BitmapEx& rBmpEx, sal_uInt32 nMaximumExtent) const +bool GDIMetaFile::CreateThumbnail(BitmapEx& rBitmapEx, sal_uInt32 nMaximumExtent, BmpConversion eColorConversion, long nScaleFlag) const { // initialization seems to be complicated but is used to avoid rounding errors VirtualDevice aVDev; @@ -2889,8 +2889,8 @@ bool GDIMetaFile::CreateThumbnail(BitmapEx& rBmpEx, sal_uInt32 nMaximumExtent) c Size aDrawSize( aVDev.LogicToPixel( GetPrefSize(), GetPrefMapMode() ) ); Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 ); - if ( !rBmpEx.IsEmpty() ) - rBmpEx.SetEmpty(); + if (!rBitmapEx.IsEmpty()) + rBitmapEx.SetEmpty(); // determine size that has the same aspect ratio as image size and // fits into the rectangle determined by nMaximumExtent @@ -2932,19 +2932,18 @@ bool GDIMetaFile::CreateThumbnail(BitmapEx& rBmpEx, sal_uInt32 nMaximumExtent) c const_cast<GDIMetaFile *>(this)->Play(&aVDev, aBackPosPix, aAntialias); // get paint bitmap - Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) ); + Bitmap aBitmap( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) ); - // assure that we have a true color image - if ( aBmp.GetBitCount() != 24 ) - aBmp.Convert( BMP_CONVERSION_24BIT ); + // scale down the image to the desired size - use the input scaler for the scaling operation + aBitmap.Scale(aDrawSize, nScaleFlag); - // downsize, to get the antialiased picture - aBmp.Scale(aDrawSize, BMP_SCALE_BESTQUALITY); + // convert to desired bitmap color format + aBitmap.Convert(eColorConversion); - rBmpEx = BitmapEx(aBmp); + rBitmapEx = BitmapEx(aBitmap); } - return !rBmpEx.IsEmpty(); + return !rBitmapEx.IsEmpty(); } void GDIMetaFile::UseCanvas( bool _bUseCanvas ) commit 3a7e54f5d2020ea1f6f2b27a51f5ca065844837f Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sun Sep 21 21:29:19 2014 +0200 Convenient function to compress a Graphic to PNG image Change-Id: I3d30dd4337b6bd3b5b0c7cdf97a8787c4bc37fa3 diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx index 1579845..313ee02 100644 --- a/include/vcl/graphicfilter.hxx +++ b/include/vcl/graphicfilter.hxx @@ -320,6 +320,8 @@ public: Graphic& rGraphic, GraphicFilter* pFilter = NULL, sal_uInt16* pDeterminedFormat = NULL ); + + sal_uInt16 compressAsPNG(const Graphic& rGraphic, SvStream& rOutputStream, sal_uInt32 nCompression = 5); }; #endif // INCLUDED_VCL_GRAPHICFILTER_HXX diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 9c69d98..2f38fbf 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -2302,4 +2302,16 @@ int GraphicFilter::LoadGraphic( const OUString &rPath, const OUString &rFilterNa return nRes; } +sal_uInt16 GraphicFilter::compressAsPNG(const Graphic& rGraphic, SvStream& rOutputStream, sal_uInt32 nCompression) +{ + nCompression = MinMax(nCompression, 0, 100); + + uno::Sequence<beans::PropertyValue> aFilterData(1); + aFilterData[0].Name = "Compression"; + aFilterData[0].Value <<= nCompression; + + sal_uInt16 nFilterFormat = GetExportFormatNumberForShortName("PNG"); + return ExportGraphic(rGraphic, OUString(), rOutputStream, nFilterFormat, &aFilterData); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 6b894d17ef1ca50b5326290d691635fbfbbdd864 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Sep 20 15:44:40 2014 +0200 Test HTML export of images & image properties. Change-Id: Ib0bffab0e653dc9ad0cc5367fdbc6bdee02181d2 diff --git a/sw/qa/extras/htmlexport/data/HTMLImage.odt b/sw/qa/extras/htmlexport/data/HTMLImage.odt new file mode 100644 index 0000000..c938c3f Binary files /dev/null and b/sw/qa/extras/htmlexport/data/HTMLImage.odt differ diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx index f59b09b..5c655bf 100644 --- a/sw/qa/extras/htmlexport/htmlexport.cxx +++ b/sw/qa/extras/htmlexport/htmlexport.cxx @@ -162,6 +162,36 @@ DECLARE_HTMLEXPORT_TEST(testSkipImageEmbeddedDocument, "skipimage-embedded-docum assertXPathContent(pDoc, "/html/body/p/span/p/span", "Inner."); } +DECLARE_HTMLEXPORT_TEST(testExportImageProperties, "HTMLImage.odt") +{ + htmlDocPtr pDoc = parseHtml(maTempFile); + CPPUNIT_ASSERT(pDoc); + + assertXPath(pDoc, "/html/body", 1); + + assertXPath(pDoc, "/html/body/p/map/area", "shape", "poly"); + assertXPath(pDoc, "/html/body/p/map/area", "href", "http://www.microsoft.com/"); + assertXPath(pDoc, "/html/body/p/map/area", "target", "_self"); + assertXPath(pDoc, "/html/body/p/map/area", "alt", "microsoft"); + + assertXPath(pDoc, "/html/body/p/a", 1); + assertXPath(pDoc, "/html/body/p/a", "href", "http://www.google.com/"); + + assertXPath(pDoc, "/html/body/p/a/font", 1); + assertXPath(pDoc, "/html/body/p/a/font", "color", "#ff0000"); + + assertXPath(pDoc, "/html/body/p/a/font/img", 1); + assertXPath(pDoc, "/html/body/p/a/font/img", "name", "Text"); + assertXPath(pDoc, "/html/body/p/a/font/img", "alt", "Four colors"); + assertXPath(pDoc, "/html/body/p/a/font/img", "align", "middle"); + assertXPath(pDoc, "/html/body/p/a/font/img", "hspace", "38"); + assertXPath(pDoc, "/html/body/p/a/font/img", "vspace", "19"); + assertXPath(pDoc, "/html/body/p/a/font/img", "width", "222"); + assertXPath(pDoc, "/html/body/p/a/font/img", "height", "222"); + assertXPath(pDoc, "/html/body/p/a/font/img", "border", "3"); + assertXPath(pDoc, "/html/body/p/a/font/img", "usemap", "#map1"); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 03fe839d6e76ed8b1dfb65093ab59a8904852ff6 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Sep 20 15:41:13 2014 +0200 html export: rework image output to use HTML writer Change-Id: Iead3f0f49b93453bd45f07f047978cb92d279d21 diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx index 725ba97..a96b261 100644 --- a/sw/source/filter/html/htmlflywriter.cxx +++ b/sw/source/filter/html/htmlflywriter.cxx @@ -803,115 +803,360 @@ OString SwHTMLWriter::OutFrmFmtOptions( const SwFrmFmt &rFrmFmt, return sRetEndTags; } -Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt, - Graphic& rGraphic, const OUString& rAlternateTxt, - const Size &rRealSize, sal_uInt32 nFrmOpts, - const sal_Char *pMarkType, - const ImageMap *pAltImgMap ) +void SwHTMLWriter::writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrmFmt& rFrmFmt, const OUString& rAlternateText, sal_uInt32 nFrameOptions) { - SwHTMLWriter &rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); + OStringBuffer sOut; - if (rHTMLWrt.mbSkipImages) - return rHTMLWrt; + const SfxPoolItem* pItem; + const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet(); - // ggf. ein noch offenes Attribut voruebergehend beenden - if( !rHTMLWrt.aINetFmts.empty() ) + // Name + if( (nFrameOptions & (HTML_FRMOPT_ID|HTML_FRMOPT_NAME)) && + !rFrmFmt.GetName().isEmpty() ) { - SwFmtINetFmt *pINetFmt = rHTMLWrt.aINetFmts.back(); - OutHTML_INetFmt( rWrt, *pINetFmt, false ); + const sal_Char* pAttributeName = (nFrameOptions & HTML_FRMOPT_ID) ? OOO_STRING_SVTOOLS_HTML_O_id : OOO_STRING_SVTOOLS_HTML_O_name; + aHtml.attribute(pAttributeName, rFrmFmt.GetName()); } - const SfxPoolItem* pItem; - const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet(); + // Name + if (nFrameOptions & HTML_FRMOPT_DIR) + { + sal_uInt16 nCurrentDirection = GetHTMLDirection(rItemSet); + OString sDirection = convertDirection(nCurrentDirection); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_dir, sDirection); + } + + // alt + if( (nFrameOptions & HTML_FRMOPT_ALT) && !rAlternateText.isEmpty() ) + { + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_alt, rAlternateText); + } + + // align + const sal_Char* pAlignString = 0; + RndStdIds eAnchorId = rFrmFmt.GetAnchor().GetAnchorId(); + if( (nFrameOptions & HTML_FRMOPT_ALIGN) && + ((FLY_AT_PARA == eAnchorId) || (FLY_AT_CHAR == eAnchorId)) ) + { + const SwFmtHoriOrient& rHoriOri = rFrmFmt.GetHoriOrient(); + if( !(nFrameOptions & HTML_FRMOPT_S_ALIGN) || + text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() || + text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() ) + { + pAlignString = text::HoriOrientation::RIGHT == rHoriOri.GetHoriOrient() + ? OOO_STRING_SVTOOLS_HTML_AL_right + : OOO_STRING_SVTOOLS_HTML_AL_left; + } + } + if( (nFrameOptions & HTML_FRMOPT_ALIGN) && !pAlignString && + ( (nFrameOptions & HTML_FRMOPT_S_ALIGN) == 0 || + (FLY_AS_CHAR == eAnchorId) ) && + SfxItemState::SET == rItemSet.GetItemState( RES_VERT_ORIENT, true, &pItem )) + { + switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() ) + { + case text::VertOrientation::LINE_TOP: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_top; break; + case text::VertOrientation::CHAR_TOP: + case text::VertOrientation::BOTTOM: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; + case text::VertOrientation::LINE_CENTER: + case text::VertOrientation::CHAR_CENTER: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; + case text::VertOrientation::CENTER: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_middle; break; + case text::VertOrientation::LINE_BOTTOM: + case text::VertOrientation::CHAR_BOTTOM: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; + case text::VertOrientation::TOP: pAlignString = OOO_STRING_SVTOOLS_HTML_VA_bottom; break; + case text::VertOrientation::NONE: break; + } + } + if (pAlignString) + { + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_align, pAlignString); + } + + // hspace und vspace + Size aTwipSpc( 0, 0 ); + if( (nFrameOptions & (HTML_FRMOPT_SPACE | HTML_FRMOPT_MARGINSIZE)) && + SfxItemState::SET == rItemSet.GetItemState( RES_LR_SPACE, true, &pItem )) + { + aTwipSpc.Width() = + ( ((SvxLRSpaceItem*)pItem)->GetLeft() + + ((SvxLRSpaceItem*)pItem)->GetRight() ) / 2; + nDfltLeftMargin = nDfltRightMargin = aTwipSpc.Width(); + } + if( (nFrameOptions & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) && + SfxItemState::SET == rItemSet.GetItemState( RES_UL_SPACE, true, &pItem )) + { + aTwipSpc.Height() = + ( ((SvxULSpaceItem*)pItem)->GetUpper() + + ((SvxULSpaceItem*)pItem)->GetLower() ) / 2; + nDfltTopMargin = nDfltBottomMargin = (sal_uInt16)aTwipSpc.Height(); + } + + if( (nFrameOptions & HTML_FRMOPT_SPACE) && + (aTwipSpc.Width() || aTwipSpc.Height()) && + Application::GetDefaultDevice() ) + { + Size aPixelSpc = + Application::GetDefaultDevice()->LogicToPixel( aTwipSpc, + MapMode(MAP_TWIP) ); + if( !aPixelSpc.Width() && aTwipSpc.Width() ) + aPixelSpc.Width() = 1; + if( !aPixelSpc.Height() && aTwipSpc.Height() ) + aPixelSpc.Height() = 1; + + if (aPixelSpc.Width()) + { + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_hspace, static_cast<sal_Int32>(aPixelSpc.Width())); + } + + if (aPixelSpc.Height()) + { + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_vspace, static_cast<sal_Int32>(aPixelSpc.Height())); + } + } + + // Der Abstand muss bei der Groesse beruecksichtigt, wenn das entsprechende + // Flag gesetzt ist. + if( (nFrameOptions & HTML_FRMOPT_MARGINSIZE) ) + { + aTwipSpc.Width() *= -2; + aTwipSpc.Height() *= -2; + } + else + { + aTwipSpc.Width() = 0; + aTwipSpc.Height() = 0; + } + + if( !(nFrameOptions & HTML_FRMOPT_ABSSIZE) && + SfxItemState::SET == rItemSet.GetItemState( RES_BOX, true, &pItem )) + { + const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem; + + aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_LEFT ); + aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_RIGHT ); + aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_TOP ); + aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_BOTTOM ); + } + + // "width" and/or "height" + // ATT_VAR_SIZE/ATT_MIN_SIZE nur ausgeben, wenn ANYSIZE gesezut ist + if( (nFrameOptions & HTML_FRMOPT_SIZE) && + SfxItemState::SET == rItemSet.GetItemState( RES_FRM_SIZE, true, &pItem ) && + ( (nFrameOptions & HTML_FRMOPT_ANYSIZE) || + ATT_FIX_SIZE == ((const SwFmtFrmSize *)pItem)->GetHeightSizeType()) ) + { + const SwFmtFrmSize *pFSItem = (const SwFmtFrmSize *)pItem; + sal_uInt8 nPrcWidth = pFSItem->GetWidthPercent(); + sal_uInt8 nPrcHeight = pFSItem->GetHeightPercent(); + + // Groesse des Objekts Twips ohne Raender + Size aTwipSz( (nPrcWidth ? 0 + : pFSItem->GetWidth()-aTwipSpc.Width()), + (nPrcHeight ? 0 + : pFSItem->GetHeight()-aTwipSpc.Height()) ); + + OSL_ENSURE( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0, + "Rahmengroesse minus Abstand < 0!!!???" ); + if( aTwipSz.Width() < 0 ) + aTwipSz.Width() = 0; + if( aTwipSz.Height() < 0 ) + aTwipSz.Height() = 0; + + Size aPixelSz( 0, 0 ); + if( (aTwipSz.Width() || aTwipSz.Height()) && + Application::GetDefaultDevice() ) + { + aPixelSz = + Application::GetDefaultDevice()->LogicToPixel( aTwipSz, + MapMode(MAP_TWIP) ); + if( !aPixelSz.Width() && aTwipSz.Width() ) + aPixelSz.Width() = 1; + if( !aPixelSz.Height() && aTwipSz.Height() ) + aPixelSz.Height() = 1; + } - const SwFmtURL *pURLItem = 0; + if( (nFrameOptions & HTML_FRMOPT_WIDTH) && + ((nPrcWidth && nPrcWidth!=255) || aPixelSz.Width()) ) + { + OString sWidth; + if (nPrcWidth) + sWidth = OString::number(static_cast<sal_Int32>(nPrcWidth)) + "%"; + else + sWidth = OString::number(static_cast<sal_Int32>(aPixelSz.Width())); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_width, sWidth); + } + + if( (nFrameOptions & HTML_FRMOPT_HEIGHT) && + ((nPrcHeight && nPrcHeight!=255) || aPixelSz.Height()) ) + { + OString sHeight; + if (nPrcWidth) + sHeight = OString::number(static_cast<sal_Int32>(nPrcHeight)) + "%"; + else + sHeight = OString::number(static_cast<sal_Int32>(aPixelSz.Height())); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_height, sHeight); + } + } + + // Umlauf fuer absatzgeb. Grafiken als <BR CLEAR=...> in den String + // schreiben + + const sal_Char* pSurroundString = 0; + if( (nFrameOptions & HTML_FRMOPT_BRCLEAR) && + ((FLY_AT_PARA == rFrmFmt.GetAnchor().GetAnchorId()) || + (FLY_AT_CHAR == rFrmFmt.GetAnchor().GetAnchorId())) && + SfxItemState::SET == rItemSet.GetItemState( RES_SURROUND, true, &pItem )) + { + const SwFmtSurround* pSurround = (const SwFmtSurround*)pItem; + sal_Int16 eHoriOri = rFrmFmt.GetHoriOrient().GetHoriOrient(); + SwSurround eSurround = pSurround->GetSurround(); + bool bAnchorOnly = pSurround->IsAnchorOnly(); + switch( eHoriOri ) + { + case text::HoriOrientation::RIGHT: + { + switch( eSurround ) + { + case SURROUND_NONE: + case SURROUND_RIGHT: + pSurroundString = OOO_STRING_SVTOOLS_HTML_AL_right; + break; + case SURROUND_LEFT: + case SURROUND_PARALLEL: + if( bAnchorOnly ) + bClearRight = true; + break; + default: + ; + } + } + break; + + default: + // If a frame is centered, it gets left aligned. This + // should be taken into account here, too. + { + switch( eSurround ) + { + case SURROUND_NONE: + case SURROUND_LEFT: + pSurroundString = OOO_STRING_SVTOOLS_HTML_AL_left; + break; + case SURROUND_RIGHT: + case SURROUND_PARALLEL: + if( bAnchorOnly ) + bClearLeft = true; + break; + default: + break; + } + } + break; + } + + if (pSurroundString) + { + aHtml.start(OOO_STRING_SVTOOLS_HTML_linebreak); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_clear, pSurroundString); + aHtml.end(); + } + } +} + +namespace +{ + +OUString lclWriteOutImap(SwHTMLWriter& rHTMLWrt, const SfxItemSet& rItemSet, const SwFrmFmt& rFrmFmt, + const Size& rRealSize, const ImageMap* pAltImgMap, SwFmtURL*& pURLItem) +{ + OUString aIMapName; + + const SfxPoolItem* pItem; // das URL-Attribut nur beruecksichtigen, wenn keine Image-Map // uebergeben wurde - if( !pAltImgMap && - SfxItemState::SET == rItemSet.GetItemState( RES_URL, true, &pItem )) + if (!pAltImgMap && SfxItemState::SET == rItemSet.GetItemState( RES_URL, true, &pItem)) { - pURLItem = (const SwFmtURL *)pItem; + pURLItem = (SwFmtURL*) pItem; } // Image-Map rausschreiben - const ImageMap *pIMap = pAltImgMap; + const ImageMap* pIMap = pAltImgMap; if( !pIMap && pURLItem ) { pIMap = pURLItem->GetMap(); } - OUString aIMapName; - if( pIMap ) + if (pIMap) { // den Namen eindeutig machen aIMapName = pIMap->GetName(); OUString aNameBase; - if( !aIMapName.isEmpty() ) + if (!aIMapName.isEmpty()) aNameBase = aIMapName; else aNameBase = OOO_STRING_SVTOOLS_HTML_map; - if( aIMapName.isEmpty() ) - aIMapName = aNameBase + OUString::number( rHTMLWrt.nImgMapCnt ); + + if (aIMapName.isEmpty()) + aIMapName = aNameBase + OUString::number(rHTMLWrt.nImgMapCnt); bool bFound; do { bFound = false; - for(size_t i = 0; i < rHTMLWrt.aImgMapNames.size(); ++i) + for (size_t i = 0; i < rHTMLWrt.aImgMapNames.size(); ++i) { // TODO: Unicode: Comparison is case insensitive for ASCII // characters only now! - if( aIMapName.equalsIgnoreAsciiCase( rHTMLWrt.aImgMapNames[i] ) ) + if (aIMapName.equalsIgnoreAsciiCase(rHTMLWrt.aImgMapNames[i])) { bFound = true; break; } } - if( bFound ) + if (bFound) { rHTMLWrt.nImgMapCnt++; aIMapName = aNameBase + OUString::number( rHTMLWrt.nImgMapCnt ); } - - } while( bFound ); + } while (bFound); bool bScale = false; - Fraction aScaleX( 1, 1 ); - Fraction aScaleY( 1, 1 ); + Fraction aScaleX(1, 1); + Fraction aScaleY(1, 1); const SwFmtFrmSize& rFrmSize = rFrmFmt.GetFrmSize(); const SvxBoxItem& rBox = rFrmFmt.GetBox(); - if( !rFrmSize.GetWidthPercent() && rRealSize.Width() ) + if (!rFrmSize.GetWidthPercent() && rRealSize.Width()) { SwTwips nWidth = rFrmSize.GetWidth(); - nWidth -= ( rBox.CalcLineSpace(BOX_LINE_LEFT) + - rBox.CalcLineSpace(BOX_LINE_RIGHT) ); + nWidth -= rBox.CalcLineSpace(BOX_LINE_LEFT) + rBox.CalcLineSpace(BOX_LINE_RIGHT); - OSL_ENSURE( nWidth>0, "Gibt es 0 twip breite Grafiken!?" ); - if( nWidth<=0 ) // sollte nicht passieren + OSL_ENSURE( nWidth > 0, "Gibt es 0 twip breite Grafiken!?" ); + if (nWidth <= 0) // sollte nicht passieren nWidth = 1; - if( rRealSize.Width() != nWidth ) + if (rRealSize.Width() != nWidth) { - aScaleX = Fraction( nWidth, rRealSize.Width() ); + aScaleX = Fraction(nWidth, rRealSize.Width()); bScale = true; } } - if( !rFrmSize.GetHeightPercent() && rRealSize.Height() ) + + if (!rFrmSize.GetHeightPercent() && rRealSize.Height()) { SwTwips nHeight = rFrmSize.GetHeight(); - nHeight -= ( rBox.CalcLineSpace(BOX_LINE_TOP) + - rBox.CalcLineSpace(BOX_LINE_BOTTOM) ); - OSL_ENSURE( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" ); - if( nHeight<=0 ) + nHeight -= rBox.CalcLineSpace(BOX_LINE_TOP) + rBox.CalcLineSpace(BOX_LINE_BOTTOM); + + OSL_ENSURE( nHeight > 0, "Gibt es 0 twip hohe Grafiken!?" ); + if (nHeight <= 0) nHeight = 1; - if( rRealSize.Height() != nHeight ) + if (rRealSize.Height() != nHeight) { - aScaleY = Fraction( nHeight, rRealSize.Height() ); + aScaleY = Fraction(nHeight, rRealSize.Height()); bScale = true; } } @@ -921,7 +1166,7 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt, OString aIndMap, aIndArea; const sal_Char *pIndArea = 0, *pIndMap = 0; - if( rHTMLWrt.bLFPossible ) + if (rHTMLWrt.bLFPossible) { rHTMLWrt.OutNewLine( true ); aIndMap = rHTMLWrt.GetIndentString(); @@ -930,11 +1175,11 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt, pIndMap = aIndMap.getStr(); } - if( bScale ) + if (bScale) { - ImageMap aScaledIMap( *pIMap ); - aScaledIMap.Scale( aScaleX, aScaleY ); - HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), aScaledIMap, aIMapName, + ImageMap aScaledIMap(*pIMap); + aScaledIMap.Scale(aScaleX, aScaleY); + HTMLOutFuncs::Out_ImageMap( rHTMLWrt.Strm(), rHTMLWrt.GetBaseURL(), aScaledIMap, aIMapName, aIMapEventTable, rHTMLWrt.bCfgStarBasic, SAL_NEWLINE_STRING, pIndArea, pIndMap, @@ -943,7 +1188,7 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt, } else { - HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), *pIMap, aIMapName, + HTMLOutFuncs::Out_ImageMap( rHTMLWrt.Strm(), rHTMLWrt.GetBaseURL(), *pIMap, aIMapName, aIMapEventTable, rHTMLWrt.bCfgStarBasic, SAL_NEWLINE_STRING, pIndArea, pIndMap, @@ -951,94 +1196,101 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt, &rHTMLWrt.aNonConvertableCharacters ); } } + return aIMapName; +} - // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben +} + +Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt, + Graphic& rGraphic, const OUString& rAlternateTxt, + const Size &rRealSize, sal_uInt32 nFrmOpts, + const sal_Char *pMarkType, + const ImageMap *pAltImgMap ) +{ + SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt); + + if (rHTMLWrt.mbSkipImages) + return rHTMLWrt; + + // ggf. ein noch offenes Attribut voruebergehend beenden + if( !rHTMLWrt.aINetFmts.empty() ) + { + SwFmtINetFmt* pINetFmt = rHTMLWrt.aINetFmts.back(); + OutHTML_INetFmt( rWrt, *pINetFmt, false ); + } + + const SfxPoolItem* pItem; + const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet(); + + SwFmtURL* pURLItem = 0; + OUString aIMapName = lclWriteOutImap(rHTMLWrt, rItemSet, rFrmFmt, rRealSize, pAltImgMap, pURLItem); + + // put img into new line if( rHTMLWrt.bLFPossible ) rHTMLWrt.OutNewLine( true ); - // Attribute die ausserhelb der Grafik geschreiben werden muessen sammeln - OStringBuffer sOut; - OString aEndTags; + HtmlWriter aHtml(rWrt.Strm()); - // implizite Sprungmarke -> <A NAME=...></A>...<IMG ...> + // <a name=...></a>...<img ...> if( pMarkType && !rFrmFmt.GetName().isEmpty() ) + { rHTMLWrt.OutImplicitMark( rFrmFmt.GetName(), pMarkType ); + } - // URL -> <A>...<IMG ... >...</A> + // URL -> <a>...<img ... >...</a> const SvxMacroItem *pMacItem = 0; - if( SfxItemState::SET == rItemSet.GetItemState( RES_FRMMACRO, true, &pItem )) + if (SfxItemState::SET == rItemSet.GetItemState(RES_FRMMACRO, true, &pItem)) + { pMacItem = (const SvxMacroItem *)pItem; + } - if( pURLItem || pMacItem ) + if (pURLItem || pMacItem) { OUString aMapURL; OUString aName; OUString aTarget; - if( pURLItem ) + + if(pURLItem) { aMapURL = pURLItem->GetURL(); aName = pURLItem->GetName(); aTarget = pURLItem->GetTargetFrameName(); } + bool bEvents = pMacItem && !pMacItem->GetMacroTable().empty(); if( !aMapURL.isEmpty() || !aName.isEmpty() || !aTarget.isEmpty() || bEvents ) { - sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_anchor); + aHtml.start(OOO_STRING_SVTOOLS_HTML_anchor); - // Ein HREF nur Ausgaben, wenn es einen Link oder Makros gibt + // Output "href" element if a link or macro exists if( !aMapURL.isEmpty() || bEvents ) { - sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_href). - append("=\""); - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); - rHTMLWrt.OutHyperlinkHRefValue( aMapURL ); - sOut.append('\"'); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_href, OUStringToOString(rHTMLWrt.convertHyperlinkHRefValue(aMapURL), RTL_TEXTENCODING_UTF8)); } if( !aName.isEmpty() ) { - sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_name). - append("=\""); - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); - HTMLOutFuncs::Out_String( rWrt.Strm(), aName, - rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ); - sOut.append('\"'); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_name, OUStringToOString(aName, RTL_TEXTENCODING_UTF8)); } if( !aTarget.isEmpty() ) { - sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_target). - append("=\""); - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); - HTMLOutFuncs::Out_String( rWrt.Strm(), aTarget, - rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ); - sOut.append('\"'); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_target, OUStringToOString(aTarget, RTL_TEXTENCODING_UTF8)); } - if (!sOut.isEmpty()) - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); - if( pMacItem ) { const SvxMacroTableDtor& rMacTable = pMacItem->GetMacroTable(); - if( !rMacTable.empty() ) - HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable, - aAnchorEventTable, - rHTMLWrt.bCfgStarBasic, - rHTMLWrt.eDestEnc, - &rHTMLWrt.aNonConvertableCharacters ); + if (!rMacTable.empty()) + { + HtmlWriterHelper::applyEvents(aHtml, rMacTable, aAnchorEventTable, rHTMLWrt.bCfgStarBasic); + } } - - rWrt.Strm().WriteCharPtr( ">" ); - aEndTags = OStringBuffer().append("</"). - append(OOO_STRING_SVTOOLS_HTML_anchor). - append(">").append(aEndTags). - makeStringAndClear(); } } - // Umrandung -> <FONT COLOR = ...>...<IMG ... >...</FONT> + // <font color = ...>...<img ... >...</font> sal_uInt16 nBorderWidth = 0; if( (nFrmOpts & HTML_FRMOPT_BORDER) && SfxItemState::SET == rItemSet.GetItemState( RES_BOX, true, &pItem )) @@ -1098,74 +1350,57 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt, if( pColBorderLine ) { - sOut.append('<'); - sOut.append(OOO_STRING_SVTOOLS_HTML_font).append(' '). - append(OOO_STRING_SVTOOLS_HTML_O_color).append("="); - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); - HTMLOutFuncs::Out_Color( rWrt.Strm(), - pColBorderLine->GetColor(), rHTMLWrt.eDestEnc ).WriteChar( '>' ); - - aEndTags = OStringBuffer(). - append("</"). - append(OOO_STRING_SVTOOLS_HTML_font). - append('>').append(aEndTags).makeStringAndClear(); + aHtml.start(OOO_STRING_SVTOOLS_HTML_font); + HtmlWriterHelper::applyColor(aHtml, OOO_STRING_SVTOOLS_HTML_O_color, pColBorderLine->GetColor()); } } - sOut.append('<'); - sOut.append(OOO_STRING_SVTOOLS_HTML_image).append(' '). - append(OOO_STRING_SVTOOLS_HTML_O_src). - append("=\"").append(OOO_STRING_SVTOOLS_HTML_O_data).append(":"); - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); + aHtml.start(OOO_STRING_SVTOOLS_HTML_image); OUString aGraphicInBase64; sal_uLong nErr = XOutBitmap::GraphicToBase64(rGraphic, aGraphicInBase64); - if( nErr ) + if (nErr) { rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE; } - HTMLOutFuncs::Out_String( rWrt.Strm(), aGraphicInBase64, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ).WriteChar( '\"' ); + + OStringBuffer sBuffer; + sBuffer.append(OOO_STRING_SVTOOLS_HTML_O_data); + sBuffer.append(":"); + sBuffer.append(OUStringToOString(aGraphicInBase64, RTL_TEXTENCODING_UTF8)); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_src, sBuffer.makeStringAndClear().getStr()); // Events - if( SfxItemState::SET == rItemSet.GetItemState( RES_FRMMACRO, true, &pItem )) + if (SfxItemState::SET == rItemSet.GetItemState(RES_FRMMACRO, true, &pItem)) { - const SvxMacroTableDtor& rMacTable = - ((const SvxMacroItem *)pItem)->GetMacroTable(); - if( !rMacTable.empty() ) - HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable, aImageEventTable, - rHTMLWrt.bCfgStarBasic, rHTMLWrt.eDestEnc, - &rHTMLWrt.aNonConvertableCharacters ); + const SvxMacroTableDtor& rMacTable = ((const SvxMacroItem *)pItem)->GetMacroTable(); + if (!rMacTable.empty()) + { + HtmlWriterHelper::applyEvents(aHtml, rMacTable, aImageEventTable, rHTMLWrt.bCfgStarBasic); + } } - // ALT, ALIGN, WIDTH, HEIGHT, HSPACE, VSPACE - aEndTags = rHTMLWrt.OutFrmFmtOptions( rFrmFmt, rAlternateTxt, nFrmOpts, aEndTags ); + // alt, align, width, height, hspace, vspace + rHTMLWrt.writeFrameFormatOptions(aHtml, rFrmFmt, rAlternateTxt, nFrmOpts); if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) ) rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmOpts ); if( nFrmOpts & HTML_FRMOPT_BORDER ) { - sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_border). - append("=\"").append(static_cast<sal_Int32>(nBorderWidth)).append("\""); - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_border, nBorderWidth); } if( pURLItem && pURLItem->IsServerMap() ) { - sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_ismap); - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_ismap); } + if( !aIMapName.isEmpty() ) { - sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_usemap). - append("=\"#"); - rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); - HTMLOutFuncs::Out_String( rWrt.Strm(), aIMapName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ).WriteChar( '\"' ); + aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_usemap, "#" + aIMapName); } - rHTMLWrt.Strm().WriteChar( '>' ); - - if( !aEndTags.isEmpty() ) - rWrt.Strm().WriteCharPtr( aEndTags.getStr() ); + aHtml.flushStack(); if( !rHTMLWrt.aINetFmts.empty() ) { diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx index a6f138b..b64f9aa 100644 --- a/sw/source/filter/html/wrthtml.cxx +++ b/sw/source/filter/html/wrthtml.cxx @@ -1171,32 +1171,32 @@ void SwHTMLWriter::OutImplicitMark( const OUString& rMark, } } -void SwHTMLWriter::OutHyperlinkHRefValue( const OUString& rURL ) +OUString SwHTMLWriter::convertHyperlinkHRefValue(const OUString& rURL) { - OUString sURL( rURL ); - sal_Int32 nPos = sURL.lastIndexOf( cMarkSeparator ); - if( nPos != -1 ) + OUString sURL(rURL); + sal_Int32 nPos = sURL.lastIndexOf(cMarkSeparator); + if (nPos != -1) { - OUString sCmp(comphelper::string::remove(sURL.copy(nPos+1), ' ')); - if( !sCmp.isEmpty() ) + OUString sCompare(comphelper::string::remove(sURL.copy(nPos + 1), ' ')); + if (!sCompare.isEmpty()) { - sCmp = sCmp.toAsciiLowerCase(); - if( sCmp == "region" || - sCmp == "frame" || - sCmp == "graphic" || - sCmp == "ole" || - sCmp == "table" || - sCmp == "outline" || - sCmp == "text" ) + sCompare = sCompare.toAsciiLowerCase(); + if( sCompare == "region" || sCompare == "frame" || + sCompare == "graphic" || sCompare == "ole" || + sCompare == "table" || sCompare == "outline" || + sCompare == "text" ) { sURL = sURL.replace( '?', '_' ); // '?' causes problems in IE/Netscape 5 } } } + return URIHelper::simpleNormalizedMakeRelative(GetBaseURL(), sURL); +} - sURL = URIHelper::simpleNormalizedMakeRelative( GetBaseURL(), sURL); - HTMLOutFuncs::Out_String( Strm(), sURL, eDestEnc, - &aNonConvertableCharacters ); +void SwHTMLWriter::OutHyperlinkHRefValue( const OUString& rURL ) +{ + OUString sURL = convertHyperlinkHRefValue(rURL); + HTMLOutFuncs::Out_String( Strm(), sURL, eDestEnc, &aNonConvertableCharacters ); } void SwHTMLWriter::OutBackground( const SvxBrushItem *pBrushItem, bool bGraphic ) @@ -1297,25 +1297,31 @@ sal_uInt16 SwHTMLWriter::GetHTMLDirection( sal_uInt16 nDir ) const void SwHTMLWriter::OutDirection( sal_uInt16 nDir ) { - const sal_Char *pValue = 0; - switch( nDir ) + OString sConverted = convertDirection(nDir); + if (!sConverted.isEmpty()) + { + OStringBuffer sOut; + sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_dir) + .append("=\"").append(sConverted).append('\"'); + Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); + } +} + +OString SwHTMLWriter::convertDirection(sal_uInt16 nDirection) +{ + OString sConverted; + switch (nDirection) { case FRMDIR_HORI_LEFT_TOP: case FRMDIR_VERT_TOP_LEFT: - pValue = "ltr"; + sConverted = "ltr"; break; case FRMDIR_HORI_RIGHT_TOP: case FRMDIR_VERT_TOP_RIGHT: - pValue = "rtl"; + sConverted = "rtl"; break; } - if( pValue != 0 ) - { - OStringBuffer sOut; - sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_dir) - .append("=\"").append(pValue).append('\"'); - Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() ); - } + return sConverted; } OString SwHTMLWriter::GetIndentString(sal_uInt16 nIncLvl) diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx index a62cae3..7cef620 100644 --- a/sw/source/filter/html/wrthtml.hxx +++ b/sw/source/filter/html/wrthtml.hxx @@ -414,6 +414,9 @@ public: void OutBookmarks(); void OutPointFieldmarks( const SwPosition& rPos ); void OutImplicitMark( const OUString& rMark, const sal_Char *pMarkType ); + + OUString convertHyperlinkHRefValue(const OUString& rURL); + void OutHyperlinkHRefValue( const OUString& rURL ); // gebe die evt. an der akt. Position stehenden FlyFrame aus. @@ -465,12 +468,16 @@ public: sal_uInt16 GetHTMLDirection( sal_uInt16 nDir ) const; sal_uInt16 GetHTMLDirection( const SfxItemSet& rItemSet ) const; void OutDirection( sal_uInt16 nDir ); + OString convertDirection(sal_uInt16 nDirection); // ALT/ALIGN/WIDTH/HEIGHT/HSPACE/VSPACE-Optionen des aktuellen // Frame-Formats ausgeben und ggf. ein <BR CLEAR=...> vorne an // rEndTags anhaengen OString OutFrmFmtOptions( const SwFrmFmt& rFrmFmt, const OUString& rAltTxt, sal_uInt32 nFrmOpts, const OString& rEndTags = OString() ); + + void writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrmFmt& rFrmFmt, const OUString& rAltTxt, sal_uInt32 nFrmOpts); + void OutCSS1_TableFrmFmtOptions( const SwFrmFmt& rFrmFmt ); void OutCSS1_TableCellBorderHack(const SwFrmFmt& rFrmFmt); void OutCSS1_SectionFmtOptions( const SwFrmFmt& rFrmFmt, const SwFmtCol *pCol ); commit 3aa99295a72d6129b72ce22805f03da3edb64432 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Sep 20 15:40:11 2014 +0200 html: add applyEvents to HTML output Change-Id: I8cc2d752673254c0f23f63030a8fa7d4d288c0a9 diff --git a/include/svtools/htmlout.hxx b/include/svtools/htmlout.hxx index f904a05..5612207 100644 --- a/include/svtools/htmlout.hxx +++ b/include/svtools/htmlout.hxx @@ -109,6 +109,7 @@ struct HTMLOutFuncs struct HtmlWriterHelper { SVT_DLLPUBLIC static void applyColor( HtmlWriter& rHtmlWriter, const OString &aAttributeName, const Color& rColor); + SVT_DLLPUBLIC static void applyEvents(HtmlWriter& rHtmlWriter, const SvxMacroTableDtor& rMacroTable, const HTMLOutEvent* pEventTable, bool bOutStarBasic); }; #endif diff --git a/svtools/source/svhtml/htmlout.cxx b/svtools/source/svhtml/htmlout.cxx index da58dc3..003889d 100644 --- a/svtools/source/svhtml/htmlout.cxx +++ b/svtools/source/svhtml/htmlout.cxx @@ -1001,4 +1001,29 @@ void HtmlWriterHelper::applyColor(HtmlWriter& rHtmlWriter, const OString &aAttri rHtmlWriter.attribute(aAttributeName, sBuffer.makeStringAndClear()); } + +void HtmlWriterHelper::applyEvents(HtmlWriter& rHtmlWriter, const SvxMacroTableDtor& rMacroTable, const HTMLOutEvent* pEventTable, bool bOutStarBasic) +{ + sal_uInt16 i = 0; + while (pEventTable[i].pBasicName || pEventTable[i].pJavaName) + { + const SvxMacro* pMacro = rMacroTable.Get(pEventTable[i].nEvent); + + if (pMacro && pMacro->HasMacro() && (JAVASCRIPT == pMacro->GetScriptType() || bOutStarBasic)) + { + const sal_Char* pAttributeName = NULL; + if (STARBASIC == pMacro->GetScriptType()) + pAttributeName = pEventTable[i].pBasicName; + else + pAttributeName = pEventTable[i].pJavaName; + + if (pAttributeName) + { + rHtmlWriter.attribute(pAttributeName, OUStringToOString(pMacro->GetMacName(), RTL_TEXTENCODING_UTF8)); + } + } + i++; + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 4bc2d7c39c1c5c1cff05665c07330ce9f9395010 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Sep 20 14:53:39 2014 +0200 html: line break <br/> - use XML style single element declaration Change-Id: I2e2b7fb85bd272a45d973c29f792c54aa7be0a82 diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx index a6f507a..826c7cc 100644 --- a/sw/source/filter/html/htmlatr.cxx +++ b/sw/source/filter/html/htmlatr.cxx @@ -2524,7 +2524,8 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode ) if( 0x0a == c ) { HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext ); - HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak ); + HtmlWriter aHtml(rWrt.Strm()); + aHtml.single(OOO_STRING_SVTOOLS_HTML_linebreak); } // #i120442#: if c is outside the unicode base plane output it as "&#******;" else if( c > 0xffff) commit d42813db533b0a4930528ba1ccd34f33498ffe36 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.com> Date: Sat Sep 20 14:50:46 2014 +0200 Extend HTMLWriter: flush the stack, more values for attribute(..) Change-Id: I733426ba5f82ee25751387f88942dbc66689821d diff --git a/include/svtools/HtmlWriter.hxx b/include/svtools/HtmlWriter.hxx index fc2c5c5..3c065ff 100644 --- a/include/svtools/HtmlWriter.hxx +++ b/include/svtools/HtmlWriter.hxx @@ -12,6 +12,7 @@ #define INCLUDED_SVTOOLS_HTMLWRITER_HXX #include <rtl/string.hxx> +#include <rtl/ustring.hxx> #include <tools/stream.hxx> #include <vector> #include <svtools/svtdllapi.h> @@ -20,11 +21,13 @@ class SVT_DLLPUBLIC HtmlWriter { private: std::vector<OString> maElementStack; - SvStream& mrStream; - bool mbElementOpen; - bool mbContentWritten; - bool mbPrettyPrint; + SvStream& mrStream; + + bool mbElementOpen; + bool mbContentWritten; + bool mbPrettyPrint; + rtl_TextEncoding maEncoding; public: HtmlWriter(SvStream& rStream); @@ -32,11 +35,23 @@ public: void prettyPrint(bool bChoice); - void start(const OString &aElement); + void start(const OString& aElement); + void end(); - void write(const OString &aContent); - void attribute(const OString &aAttribute, const OString &aValue); - void single(const OString &aContent); + + void flushStack(); + void flushStack(const OString& aElement); + + void write(const OString& aContent); + + void attribute(const OString& aAttribute, const char* aValue); + void attribute(const OString& aAttribute, sal_Int32 aValue); + void attribute(const OString& aAttribute, const OString& aValue); + void attribute(const OString& aAttribute, const OUString& aValue); + // boolean attribute e.g. <img ismap> + void attribute(const OString& aAttribute); + + void single(const OString& aContent); void endAttribute(); }; diff --git a/svtools/qa/unit/testHtmlWriter.cxx b/svtools/qa/unit/testHtmlWriter.cxx index 59cdb24..7c9d38f 100644 --- a/svtools/qa/unit/testHtmlWriter.cxx +++ b/svtools/qa/unit/testHtmlWriter.cxx @@ -40,6 +40,8 @@ public: void testSingleElementWithContent(); void testSingleElementWithContentAndAttributes(); void testNested(); + void testAttributeValues(); + void testFlushStack(); CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST(testSingleElement); @@ -47,6 +49,8 @@ public: CPPUNIT_TEST(testSingleElementWithContent); CPPUNIT_TEST(testSingleElementWithContentAndAttributes); CPPUNIT_TEST(testNested); + CPPUNIT_TEST(testAttributeValues); + CPPUNIT_TEST(testFlushStack); CPPUNIT_TEST_SUITE_END(); }; @@ -162,6 +166,126 @@ void Test::testNested() CPPUNIT_ASSERT_EQUAL(OString("<abc><xyz>xxx</xyz></abc>"), aString); } +void Test::testAttributeValues() +{ + SvMemoryStream aStream; + + HtmlWriter aHtml(aStream); + aHtml.prettyPrint(false); + aHtml.start("abc"); + aHtml.attribute("one", OString("one")); + aHtml.attribute("two", OUString("two")); + aHtml.attribute("three", sal_Int32(12)); + aHtml.end(); + + OString aString = extractFromStream(aStream); + + CPPUNIT_ASSERT_EQUAL(OString("<abc one=\"one\" two=\"two\" three=\"12\"/>"), aString); +} + +void Test::testFlushStack() +{ + { + SvMemoryStream aStream; + + HtmlWriter aHtml(aStream); + aHtml.prettyPrint(false); + aHtml.start("a"); + aHtml.flushStack("a"); // simple ,end element "a" = like end() + + OString aString = extractFromStream(aStream); + + CPPUNIT_ASSERT_EQUAL(OString("<a/>"), aString); + } + + { + SvMemoryStream aStream; + + HtmlWriter aHtml(aStream); + aHtml.prettyPrint(false); + aHtml.start("a"); + aHtml.start("b"); + aHtml.flushStack("b"); // end at first element "b", don't output "a" yet + + OString aString = extractFromStream(aStream); + + CPPUNIT_ASSERT_EQUAL(OString("<a><b/>"), aString); + } + + { + SvMemoryStream aStream; + + HtmlWriter aHtml(aStream); + aHtml.prettyPrint(false); + aHtml.start("a"); + aHtml.start("b"); + aHtml.flushStack("a"); // end at first element "a" + + OString aString = extractFromStream(aStream); + + CPPUNIT_ASSERT_EQUAL(OString("<a><b/></a>"), aString); + } + + { + SvMemoryStream aStream; + + HtmlWriter aHtml(aStream); + aHtml.prettyPrint(false); + aHtml.start("a"); + aHtml.start("b"); + aHtml.start("c"); + aHtml.flushStack("a"); // end at first element "a" + + OString aString = extractFromStream(aStream); + + CPPUNIT_ASSERT_EQUAL(OString("<a><b><c/></b></a>"), aString); + } + + { + SvMemoryStream aStream; + + HtmlWriter aHtml(aStream); + aHtml.prettyPrint(false); + aHtml.start("a"); + aHtml.start("b"); + aHtml.start("c"); + aHtml.flushStack("b"); // end at first element "b" + + OString aString = extractFromStream(aStream); + + CPPUNIT_ASSERT_EQUAL(OString("<a><b><c/></b>"), aString); + } + + { + SvMemoryStream aStream; + + HtmlWriter aHtml(aStream); + aHtml.prettyPrint(false); + aHtml.start("a"); + aHtml.start("b"); + aHtml.start("c"); + aHtml.flushStack("x"); // no known element - ends when stack is empty + + OString aString = extractFromStream(aStream); + + CPPUNIT_ASSERT_EQUAL(OString("<a><b><c/></b></a>"), aString); + } + + { + SvMemoryStream aStream; + + HtmlWriter aHtml(aStream); + aHtml.prettyPrint(false); + aHtml.start("a"); + aHtml.start("b"); + aHtml.start("c"); + aHtml.flushStack(); // flush the whole stack + + OString aString = extractFromStream(aStream); + + CPPUNIT_ASSERT_EQUAL(OString("<a><b><c/></b></a>"), aString); + } +} CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/svtools/source/svhtml/HtmlWriter.cxx b/svtools/source/svhtml/HtmlWriter.cxx index 5accc5d..f075d40 100644 --- a/svtools/source/svhtml/HtmlWriter.cxx +++ b/svtools/source/svhtml/HtmlWriter.cxx @@ -14,7 +14,8 @@ HtmlWriter::HtmlWriter(SvStream& rStream) : mrStream(rStream), mbElementOpen(false), mbContentWritten(false), - mbPrettyPrint(true) + mbPrettyPrint(true), + maEncoding(RTL_TEXTENCODING_UTF8) {} HtmlWriter::~HtmlWriter() @@ -25,7 +26,7 @@ void HtmlWriter::prettyPrint(bool bChoice) mbPrettyPrint = bChoice; } -void HtmlWriter::start(const OString &aElement) +void HtmlWriter::start(const OString& aElement) { if (mbElementOpen) { @@ -66,6 +67,24 @@ void HtmlWriter::endAttribute() } } +void HtmlWriter::flushStack() +{ + while (!maElementStack.empty()) + { + end(); + } +} + +void HtmlWriter::flushStack(const OString& aElement) +{ + OString sCurrentElement; + do + { + sCurrentElement = maElementStack.back(); + end(); + } while (!maElementStack.empty() && aElement != sCurrentElement); +} + void HtmlWriter::end() { if (mbElementOpen) @@ -105,7 +124,7 @@ void HtmlWriter::write(const OString &aContent) mrStream.WriteOString(aContent); } -void HtmlWriter::attribute(const OString &aAttribute, const OString &aValue) +void HtmlWriter::attribute(const OString &aAttribute, const OString& aValue) { if (mbElementOpen && !aAttribute.isEmpty() && !aValue.isEmpty()) { @@ -118,5 +137,29 @@ void HtmlWriter::attribute(const OString &aAttribute, const OString &aValue) } } +void HtmlWriter::attribute(const OString& aAttribute, const sal_Int32 aValue) +{ + attribute(aAttribute, OString::number(aValue)); +} + +void HtmlWriter::attribute(const OString& aAttribute, const char* pValue) +{ + attribute(aAttribute, OString(pValue)); +} + +void HtmlWriter::attribute(const OString& aAttribute, const OUString& aValue) +{ + attribute(aAttribute, OUStringToOString(aValue, maEncoding)); +} + +void HtmlWriter::attribute(const OString& aAttribute) +{ + if (mbElementOpen && !aAttribute.isEmpty()) + { + mrStream.WriteChar(' '); + mrStream.WriteOString(aAttribute); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits