diff options
author | Mark Hung <marklh9@gmail.com> | 2015-07-16 02:55:32 +0800 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2015-08-27 17:02:29 +0000 |
commit | e2be23d1718b363650bf1853d629df89347d906e (patch) | |
tree | f0f0e4a1b7857f6630f4bad5ec3dd4cc8f88a3a6 /sw/source/filter/ww8/rtfattributeoutput.cxx | |
parent | Addition of new controls to Wrap sidebar tab in Writer (diff) | |
download | core-e2be23d1718b363650bf1853d629df89347d906e.tar.gz core-e2be23d1718b363650bf1853d629df89347d906e.zip |
Improving Asian phonetic guide for docx and rtf files.
RTF import, export, and ooxml export for ruby text are implemented.
tdf#49073 - FILEOPEN: Furigana (ruby text) and characters with them are
missing in opened .docx files.
tdf#50786 - [TASK, METABUG] FILEOPEN, FILESAVE, FORMATTING : Japanese
ruby-character handling is broken
Change-Id: I4a5c30bad180241e3344e9da7efe7da4369fb325
Reviewed-on: https://gerrit.libreoffice.org/17241
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Stahl <mstahl@redhat.com>
Diffstat (limited to 'sw/source/filter/ww8/rtfattributeoutput.cxx')
-rw-r--r-- | sw/source/filter/ww8/rtfattributeoutput.cxx | 151 |
1 files changed, 138 insertions, 13 deletions
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 4e0c0a2f0ddb..bebcd0046efe 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -62,6 +62,7 @@ #include <fmtclds.hxx> #include <fmtrowsplt.hxx> #include <fmtline.hxx> +#include <breakit.hxx> #include <fmtanchr.hxx> #include <htmltbl.hxx> #include <ndgrf.hxx> @@ -78,8 +79,11 @@ #include <vcl/cvtgrf.hxx> #include <oox/mathml/export.hxx> #include <com/sun/star/i18n/ScriptType.hpp> +#include "writerhelper.hxx" using namespace ::com::sun::star; +using namespace sw::util; +using namespace nsFieldFlags; static OString OutTBLBorderLine(RtfExport& rExport, const editeng::SvxBorderLine* pLine, const sal_Char* pStr) { @@ -411,14 +415,119 @@ void RtfAttributeOutput::RawText(const OUString& rText, rtl_TextEncoding eCharSe m_aRunText->append(msfilter::rtfutil::OutString(rText, eCharSet)); } -void RtfAttributeOutput::StartRuby(const SwTextNode& /*rNode*/, sal_Int32 /*nPos*/, const SwFormatRuby& /*rRuby*/) +void RtfAttributeOutput::StartRuby(const SwTextNode& rNode, sal_Int32 /*nPos*/, const SwFormatRuby& rRuby) { - SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC); + OUString aStr( FieldString( ww::eEQ ) ); + aStr += "\\* jc"; + sal_Int32 nJC = 0; + sal_Char cDirective = 0; + switch ( rRuby.GetAdjustment() ) + { + case 0: + nJC = 3; + cDirective = 'l'; + break; + case 1: + //defaults to 0 + break; + case 2: + nJC = 4; + cDirective = 'r'; + break; + case 3: + nJC = 1; + cDirective = 'd'; + break; + case 4: + nJC = 2; + cDirective = 'd'; + break; + default: + OSL_ENSURE( false,"Unhandled Ruby justication code" ); + break; + } + aStr += OUString::number( nJC ); + + /* + MS needs to know the name and size of the font used in the ruby item, + but we could have written it in a mixture of asian and western + scripts, and each of these can be a different font and size than the + other, so we make a guess based upon the first character of the text, + defaulting to asian. + */ + sal_uInt16 nRubyScript; + if( g_pBreakIt->GetBreakIter().is() ) + nRubyScript = g_pBreakIt->GetBreakIter()->getScriptType( rRuby.GetText(), 0); + else + nRubyScript = i18n::ScriptType::ASIAN; + + const SwTextRuby* pRubyText = rRuby.GetTextRuby(); + const SwCharFormat* pFormat = pRubyText ? pRubyText->GetCharFormat() : 0; + OUString sFamilyName; + long nHeight; + if ( pFormat ) + { + const SvxFontItem &rFont = ItemGet< SvxFontItem >( *pFormat, + GetWhichOfScript(RES_CHRATR_FONT,nRubyScript) ); + sFamilyName = rFont.GetFamilyName(); + + const SvxFontHeightItem &rHeight = ItemGet< SvxFontHeightItem >( *pFormat, + GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) ); + nHeight = rHeight.GetHeight(); + } + else + { + /*Get defaults if no formatting on ruby text*/ + + const SfxItemPool *pPool = rNode.GetSwAttrSet().GetPool(); + pPool = pPool ? pPool : &m_rExport.m_pDoc->GetAttrPool(); + + const SvxFontItem &rFont = DefaultItemGet< SvxFontItem >( *pPool, + GetWhichOfScript( RES_CHRATR_FONT,nRubyScript ) ); + sFamilyName = rFont.GetFamilyName(); + + const SvxFontHeightItem &rHeight = DefaultItemGet< SvxFontHeightItem > + ( *pPool, GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) ); + nHeight = rHeight.GetHeight(); + } + nHeight = (nHeight + 5)/10; + + aStr += " \\* \"Font:"; + aStr += sFamilyName; + aStr += "\" \\* hps"; + aStr += OUString::number( nHeight ); + aStr += " \\o"; + if ( cDirective ) + { + aStr += "\\a" + OUString(cDirective); + } + aStr += "(\\s\\up "; + + if ( g_pBreakIt->GetBreakIter().is() ) + nRubyScript = g_pBreakIt->GetBreakIter()->getScriptType( rNode.GetText(), + pRubyText->GetStart() ); + else + nRubyScript = i18n::ScriptType::ASIAN; + + const SwAttrSet& rSet = rNode.GetSwAttrSet(); + const SvxFontHeightItem &rHeightItem = + static_cast< const SvxFontHeightItem& >(rSet.Get( + GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) )); + nHeight = (rHeightItem.GetHeight() + 10)/20-1; + aStr += OUString::number(nHeight); + aStr += "("; + EndRun(); + m_rExport.OutputField( 0, ww::eEQ, aStr, WRITEFIELD_START | WRITEFIELD_CMD_START ); + aStr = rRuby.GetText(); + aStr += ")"; + aStr += ","; + m_rExport.OutputField( 0, ww::eEQ, aStr, 0); } void RtfAttributeOutput::EndRuby() { - SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC); + m_rExport.OutputField( 0, ww::eEQ, OUString(")"), WRITEFIELD_END | WRITEFIELD_CLOSE ); + EndRun( ); } bool RtfAttributeOutput::StartURL(const OUString& rUrl, const OUString& rTarget) @@ -1442,21 +1551,37 @@ void RtfAttributeOutput::NumberingLevel(sal_uInt8 nLevel, m_rExport.Strm().WriteChar('}'); } -void RtfAttributeOutput::WriteField_Impl(const SwField* pField, ww::eField /*eType*/, const OUString& rFieldCmd, sal_uInt8 /*nMode*/) +void RtfAttributeOutput::WriteField_Impl(const SwField* pField, ww::eField eType, const OUString& rFieldCmd, sal_uInt8 nMode) { // If there are no field instructions, don't export it as a field. bool bHasInstructions = !rFieldCmd.isEmpty(); - if (bHasInstructions) + if (WRITEFIELD_ALL == nMode) { - m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD); - m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " "); - m_aRunText->append(msfilter::rtfutil::OutString(rFieldCmd, m_rExport.eCurrentEncoding)); - m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " "); + if (bHasInstructions) + { + m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD); + m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " "); + m_aRunText->append(msfilter::rtfutil::OutString(rFieldCmd, m_rExport.eCurrentEncoding)); + m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " "); + } + if (pField) + m_aRunText->append(msfilter::rtfutil::OutString(pField->ExpandField(true), m_rExport.eDefaultEncoding)); + if (bHasInstructions) + m_aRunText->append("}}"); + } else if (eType == ww::eEQ) { + if (WRITEFIELD_START & nMode) + { + m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD); + m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " "); + } + if (bHasInstructions) + m_aRunText->append(msfilter::rtfutil::OutString(rFieldCmd, m_rExport.eCurrentEncoding)); + if (WRITEFIELD_END & nMode) + { + m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " "); + m_aRunText->append("}}"); + } } - if (pField) - m_aRunText->append(msfilter::rtfutil::OutString(pField->ExpandField(true), m_rExport.eDefaultEncoding)); - if (bHasInstructions) - m_aRunText->append("}}"); } void RtfAttributeOutput::WriteBookmarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds) |