summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorZolnai Tamás <zolnaitamas2000@gmail.com>2013-09-08 10:39:31 +0200
committerZolnai Tamás <zolnaitamas2000@gmail.com>2013-09-08 11:23:45 +0200
commitb94b1fe936ddc4a9b86fbeb9c9c6ab0fca52f0bc (patch)
tree5c8b71151251c27795aa5671b4a1581d7fd37675 /sw
parent6a71bea7cf19c7b6a5031734354073d82ae8916e (diff)
CharBrd 9.1: HTML filters
-I don't implement shadow because HTML filter use css1 attributes and there isn't box-shadow in css1. -Border merge: skip span open and close tags to get the right result. Change-Id: I17edc2e1cc42359b5f1721b8891350c528c7793e
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/htmlexport/data/charborder.odtbin0 -> 7773 bytes
-rw-r--r--sw/qa/extras/htmlexport/htmlexport.cxx33
-rw-r--r--sw/source/filter/html/css1atr.cxx21
-rw-r--r--sw/source/filter/html/htmlatr.cxx58
-rw-r--r--sw/source/filter/html/htmlcss1.cxx10
-rw-r--r--sw/source/filter/html/htmlctxt.cxx18
-rw-r--r--sw/source/filter/html/swhtml.hxx3
7 files changed, 136 insertions, 7 deletions
diff --git a/sw/qa/extras/htmlexport/data/charborder.odt b/sw/qa/extras/htmlexport/data/charborder.odt
new file mode 100644
index 000000000000..e9667b2da45a
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/charborder.odt
Binary files differ
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index 34cd2ee0b4e4..3b02f2b21f70 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -15,6 +15,7 @@ class Test : public SwModelTestBase
{
public:
void testFdo62336();
+ void testCharBorder();
CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT)
@@ -30,6 +31,7 @@ void Test::run()
{
MethodEntry<Test> aMethods[] = {
{"fdo62336.docx", &Test::testFdo62336},
+ {"charborder.odt", &Test::testCharBorder},
};
header();
for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -49,6 +51,37 @@ void Test::testFdo62336()
// The problem was essentially a crash during table export as docx/rtf/html
}
+void Test::testCharBorder()
+{
+
+ uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1),1), uno::UNO_QUERY);
+ // Different Border
+ {
+ CPPUNIT_ASSERT_EQUAL_BORDER(
+ table::BorderLine2(6711039,12,12,12,3,37),
+ getProperty<table::BorderLine2>(xRun,"CharTopBorder"));
+ CPPUNIT_ASSERT_EQUAL_BORDER(
+ table::BorderLine2(16750848,0,99,0,2,99),
+ getProperty<table::BorderLine2>(xRun,"CharLeftBorder"));
+ CPPUNIT_ASSERT_EQUAL_BORDER(
+ table::BorderLine2(16711680,0,169,0,1,169),
+ getProperty<table::BorderLine2>(xRun,"CharBottomBorder"));
+ CPPUNIT_ASSERT_EQUAL_BORDER(
+ table::BorderLine2(255,0,169,0,0,169),
+ getProperty<table::BorderLine2>(xRun,"CharRightBorder"));
+ }
+
+ // Different Padding
+ {
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(450), getProperty<sal_Int32>(xRun,"CharTopBorderDistance"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(550), getProperty<sal_Int32>(xRun,"CharLeftBorderDistance"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xRun,"CharBottomBorderDistance"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xRun,"CharRightBorderDistance"));
+ }
+
+ // No shadow
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx
index 98ef8d42fa1d..7e82dabe024c 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -3500,6 +3500,25 @@ Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt )
{
SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ // Avoid interference between character and paragraph attributes
+ if( rHt.Which() < RES_CHRATR_END &&
+ rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ return rWrt;
+
+ if( rHt.Which() == RES_CHRATR_BOX )
+ {
+ if( rHTMLWrt.bTagOn )
+ {
+ // Inline-block to make the line height changing correspond to the character border
+ rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_display, "inline-block");
+ }
+ else
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, sal_False );
+ return rWrt;
+ }
+ }
+
const SvxBoxItem& rBoxItem = (const SvxBoxItem&)rHt;
const SvxBorderLine *pTop = rBoxItem.GetTop();
const SvxBorderLine *pBottom = rBoxItem.GetBottom();
@@ -3630,7 +3649,7 @@ SwAttrFnTab aCSS1AttrFnTab = {
/* RES_CHRATR_HIDDEN */ OutCSS1_SvxHidden,
/* RES_CHRATR_OVERLINE */ OutCSS1_SvxOverline,
/* RES_CHRATR_RSID */ 0,
-/* RES_CHRATR_BOX */ 0,
+/* RES_CHRATR_BOX */ OutCSS1_SvxBox,
/* RES_CHRATR_SHADOW */ 0,
/* RES_CHRATR_DUMMY1 */ 0,
/* RES_CHRATR_DUMMY2 */ 0,
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index 1f141bc4d8b3..4ec590c0048c 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -1384,6 +1384,11 @@ HTMLOnOffState HTMLEndPosLst::GetHTMLItemState( const SfxPoolItem& rItem )
case RES_PARATR_DROP:
eState = HTML_DROPCAP_VALUE;
break;
+
+ case RES_CHRATR_BOX:
+ if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
+ eState = HTML_STYLE_VALUE;
+ break;
}
return eState;
@@ -1703,6 +1708,7 @@ void HTMLEndPosLst::InsertNoScript( const SfxPoolItem& rItem,
bSet = bOutStyles &&
(!bParaAttrs
|| rItem.Which()==RES_CHRATR_BACKGROUND
+ || rItem.Which()==RES_CHRATR_BOX
|| rItem.Which()==RES_CHRATR_OVERLINE);
break;
@@ -1951,10 +1957,31 @@ void HTMLEndPosLst::OutStartAttrs( SwHTMLWriter& rHWrt, sal_Int32 nPos,
{
rHWrt.bTagOn = sal_True;
+ // Character border attribute must be the first which is written out
+ // because of border merge.
+ sal_uInt16 nCharBoxIndex = 0;
+ while( nCharBoxIndex < aStartLst.size() &&
+ aStartLst[nCharBoxIndex]->GetItem()->Which() != RES_CHRATR_BOX )
+ {
+ ++nCharBoxIndex;
+ }
+
// die Attribute in der Start-Liste sind aufsteigend sortiert
for( sal_uInt16 i=0; i< aStartLst.size(); i++ )
{
- HTMLSttEndPos *pPos = aStartLst[i];
+ HTMLSttEndPos *pPos = 0;
+ if( nCharBoxIndex < aStartLst.size() )
+ {
+ if( i == 0 )
+ pPos = aStartLst[nCharBoxIndex];
+ else if( i == nCharBoxIndex )
+ pPos = aStartLst[0];
+ else
+ pPos = aStartLst[i];
+ }
+ else
+ pPos = aStartLst[i];
+
sal_Int32 nStart = pPos->GetStart();
if( nStart > nPos )
{
@@ -2002,7 +2029,27 @@ void HTMLEndPosLst::OutEndAttrs( SwHTMLWriter& rHWrt, sal_Int32 nPos,
HTMLOutFuncs::FlushToAscii( rHWrt.Strm(), *pContext );
pContext = 0; // one time ony
}
- Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
+ // Skip closing span if next character span has the same border (border merge)
+ bool bSkipOut = false;
+ if( pPos->GetItem()->Which() == RES_CHRATR_BOX )
+ {
+ for(sal_uInt16 nIndex = _FindStartPos(pPos) + 1; nIndex < aStartLst.size(); ++nIndex )
+ {
+ HTMLSttEndPos *pEndPos = aStartLst[nIndex];
+ if( pEndPos->GetItem()->Which() == RES_CHRATR_BOX &&
+ *static_cast<const SvxBoxItem*>(pEndPos->GetItem()) ==
+ *static_cast<const SvxBoxItem*>(pPos->GetItem()) )
+ {
+ pEndPos->SetStart(pPos->GetStart());
+ bSkipOut = true;
+ break;
+ }
+ }
+ }
+ if( !bSkipOut )
+ {
+ Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
+ }
_RemoveItem( i );
}
else if( nEnd > nPos )
@@ -2386,13 +2433,14 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode )
sal_Int32 nPreSplitPos = 0;
for( ; nStrPos < nEnde; nStrPos++ )
{
- aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
-
// Die an der aktuellen Position verankerten Rahmen ausgeben
if( bFlysLeft )
+ {
+ aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
nStrPos, HTML_POS_INSIDE,
&aContext );
+ }
sal_Bool bOutChar = sal_True;
const SwTxtAttr * pTxtHt = 0;
@@ -3226,7 +3274,7 @@ SwAttrFnTab aHTMLAttrFnTab = {
/* RES_CHRATR_HIDDEN */ OutHTML_CSS1Attr,
/* RES_CHRATR_OVERLINE */ OutHTML_CSS1Attr,
/* RES_CHRATR_RSID */ 0,
-/* RES_CHRATR_BOX */ 0,
+/* RES_CHRATR_BOX */ OutHTML_CSS1Attr,
/* RES_CHRATR_SHADOW */ 0,
/* RES_CHRATR_DUMMY1 */ 0,
/* RES_CHRATR_DUMMY2 */ 0,
diff --git a/sw/source/filter/html/htmlcss1.cxx b/sw/source/filter/html/htmlcss1.cxx
index ee84ac3e17ec..ebef8fface75 100644
--- a/sw/source/filter/html/htmlcss1.cxx
+++ b/sw/source/filter/html/htmlcss1.cxx
@@ -218,6 +218,13 @@ static void SetCharFmtAttrs( SwCharFmt *pCharFmt, SfxItemSet& rItemSet )
aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
pCharFmt->SetFmtAttr( aBrushItem );
}
+
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, sal_False, &pItem ) )
+ {
+ SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
+ aBoxItem.SetWhich( RES_CHRATR_BOX );
+ pCharFmt->SetFmtAttr( aBoxItem );
+ }
}
void SwCSS1Parser::SetLinkCharFmts()
@@ -1623,6 +1630,9 @@ _HTMLAttr **SwHTMLParser::GetAttrTabEntry( sal_uInt16 nWhich )
case RES_CHRATR_BACKGROUND:
ppAttr = &aAttrTab.pCharBrush;
break;
+ case RES_CHRATR_BOX:
+ ppAttr = &aAttrTab.pCharBox;
+ break;
case RES_PARATR_LINESPACING:
ppAttr = &aAttrTab.pLineSpacing;
diff --git a/sw/source/filter/html/htmlctxt.cxx b/sw/source/filter/html/htmlctxt.cxx
index 423c0b5341ff..fb077664de28 100644
--- a/sw/source/filter/html/htmlctxt.cxx
+++ b/sw/source/filter/html/htmlctxt.cxx
@@ -24,6 +24,7 @@
#include <editeng/brushitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <svtools/htmltokn.h>
+#include <editeng/boxitem.hxx>
#include "doc.hxx"
#include "pam.hxx"
@@ -666,6 +667,23 @@ void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
}
break;
+ case RES_BOX:
+ if( bCharLvl )
+ {
+ SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
+ aBoxItem.SetWhich( RES_CHRATR_BOX );
+
+ NewAttr( &aAttrTab.pCharBox, aBoxItem );
+
+ _HTMLAttrs &rAttrs = pContext->GetAttrs();
+ rAttrs.push_back( aAttrTab.pCharBox );
+ }
+ else
+ {
+ ppAttr = &aAttrTab.pBox;
+ }
+ break;
+
default:
// den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
ppAttr = GetAttrTabEntry( pItem->Which() );
diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx
index 510487878b99..f2f1147803b9 100644
--- a/sw/source/filter/html/swhtml.hxx
+++ b/sw/source/filter/html/swhtml.hxx
@@ -177,7 +177,8 @@ struct _HTMLAttrTable
*pCharBrush, // Zeichen-Hintergrund
*pLanguage,
*pLanguageCJK,
- *pLanguageCTL
+ *pLanguageCTL,
+ *pCharBox
;
};