29 #include <rtl/tencinfo.h>
33 #include <unicode/ubidi.h>
35 #include <com/sun/star/i18n/ScriptType.hpp>
36 #include <com/sun/star/i18n/XBreakIterator.hpp>
150 RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
151 RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
158 OSL_ENSURE(
SAL_N_ELEMENTS(aArr) == 75,
"Style Array has false size");
164 if (sal::static_int_cast< size_t >(eSti) <
SAL_N_ELEMENTS(aArr) && aArr[eSti] != RES_NONE)
165 pRet = mrDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( static_cast< sal_uInt16 >(aArr[eSti]),
false);
176 return mrDoc.MakeTextFormatColl(rName,
177 mrDoc.GetDfltTextFormatColl());
226 pRet = mrDoc.getIDocumentStylePoolAccess().GetCharFormatFromPool( static_cast< sal_uInt16 >(eLookup) );
237 return mrDoc.MakeCharFormat(rName, mrDoc.GetDfltCharFormat());
245 C* MakeNonCollidingStyle(
const OUString& rName);
249 StyleResult GetStyle(
const OUString& rName,
ww::sti eSti);
253 typename StyleMapperImpl<C>::StyleResult
256 C *pRet = maHelper.GetBuiltInStyle(eSti);
259 if (pRet && (maUsedStyles.end() != maUsedStyles.find(pRet)))
264 pRet = maHelper.GetStyle(rName);
266 if (pRet && (maUsedStyles.end() != maUsedStyles.find(pRet)))
270 bool bStyExist = pRet !=
nullptr;
274 OUString
aName(rName);
275 sal_Int32 nIdx = rName.indexOf(
',');
278 aName = rName.copy( 0, nIdx );
279 pRet = MakeNonCollidingStyle( aName );
283 maUsedStyles.insert(pRet);
291 OUString
aName(rName);
294 if (
nullptr != (pColl = maHelper.GetStyle(aName)))
299 if (!aName.startsWith(
"WW-"))
300 aName =
"WW-" + aName;
303 OUString aBaseName = aName;
305 nullptr != (pColl = maHelper.GetStyle(aName)) &&
309 aName = aBaseName + OUString::number(nI++);
313 return pColl ?
nullptr : maHelper.MakeStyle(aName);
319 return "Arial Unicode MS";
320 return GetSubsFontName(rFont, SubsFontFlags::ONLYONE | SubsFontFlags::MS);
331 explicit IfBeforeStart(sal_Int32 nStart) : mnStart(nStart) {}
347 aLR.SetLeft(aLR.GetLeft() + rBox.GetDistance(SvxBoxItemLine::LEFT));
349 aLR.SetLeft(aLR.GetLeft() + pLeft->GetWidth());
351 aLR.SetRight(aLR.GetRight() + rBox.GetDistance(SvxBoxItemLine::RIGHT));
353 aLR.SetRight(aLR.GetRight() + pRight->GetWidth());
365 bool bPlausableSingleWordSection =
true;
376 if (rFirstColumns.size() != rFollowColumns.size())
379 bPlausableSingleWordSection =
false;
381 else if (aOneLR != aTwoLR)
382 bPlausableSingleWordSection =
false;
383 else if (rFirstFrameSize != rFollowFrameSize)
384 bPlausableSingleWordSection =
false;
390 if (!aOne.StrictEqualTopBottom(aTwo))
391 bPlausableSingleWordSection =
false;
393 return bPlausableSingleWordSection;
400 dyaHdrTop = pBox->CalcLineSpace( SvxBoxItemLine::TOP,
true );
401 dyaHdrBottom = pBox->CalcLineSpace( SvxBoxItemLine::BOTTOM,
true );
405 dyaHdrTop = dyaHdrBottom = 0;
412 dyaBottom = dyaHdrBottom;
440 if (dyaTop != rOther.
dyaTop)
455 ParaStyleMapper::ParaStyleMapper(
SwDoc &rDoc)
465 const OUString& rName,
ww::sti eSti)
467 return mpImpl->GetStyle(rName, eSti);
480 const OUString& rName,
ww::sti eSti)
482 return mpImpl->GetStyle(rName, eSti);
519 const OUString &rText = rTextNd.
GetText();
521 bool bParaIsRTL =
false;
522 if (SvxFrameDirection::Horizontal_RL_TB ==
530 sal_uInt16 nScript = i18n::ScriptType::LATIN;
532 if (!rText.isEmpty())
536 rtl_TextEncoding eChrSet = rTextNd.
GetAttr(nFontWhichId).GetCharSet();
543 aRunChanges.emplace_back(0, nScript, eChrSet,
548 typedef std::pair<int32_t, bool> DirEntry;
549 typedef std::pair<sal_Int32, sal_uInt16> ScriptEntry;
550 std::vector<DirEntry> aDirChanges;
551 std::vector<ScriptEntry> aScripts;
553 UBiDiDirection eDefaultDir = bParaIsRTL ? UBIDI_RTL : UBIDI_LTR;
554 UErrorCode nError = U_ZERO_ERROR;
555 UBiDi* pBidi = ubidi_openSized(rText.getLength(), 0, &nError);
556 ubidi_setPara(pBidi, reinterpret_cast<const UChar *>(rText.getStr()), rText.getLength(),
557 static_cast< UBiDiLevel
>(eDefaultDir),
nullptr, &nError);
559 sal_Int32
nCount = ubidi_countRuns(pBidi, &nError);
560 aDirChanges.reserve(nCount);
566 for (sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx)
568 ubidi_getLogicalRun(pBidi, nStart, &nEnd, &nCurrDir);
579 aDirChanges.emplace_back(nEnd, nCurrDir & 0x1);
586 sal_Int32 nLen = rText.getLength();
595 aScripts.emplace_back(nPos, nScript);
599 auto aBiDiEnd = aDirChanges.cend();
600 auto aScriptEnd = aScripts.cend();
602 auto aBiDiIter = aDirChanges.cbegin();
603 auto aScriptIter = aScripts.cbegin();
605 bool bCharIsRTL = bParaIsRTL;
608 aBiDiIter != aBiDiEnd ||
609 aScriptIter != aScriptEnd
612 sal_Int32 nMinPos = rText.getLength();
614 if (aBiDiIter != aBiDiEnd)
616 if (aBiDiIter->first < nMinPos)
617 nMinPos = aBiDiIter->first;
618 bCharIsRTL = aBiDiIter->second;
621 if (aScriptIter != aScriptEnd)
623 if (aScriptIter->first < nMinPos)
624 nMinPos = aScriptIter->first;
625 nScript = aScriptIter->second;
628 aRunChanges.emplace_back(nMinPos, nScript, eChrSet, bCharIsRTL);
630 if (aBiDiIter != aBiDiEnd)
632 if (aBiDiIter->first == nMinPos)
636 if (aScriptIter != aScriptEnd)
638 if (aScriptIter->first == nMinPos)
643 aRunChanges.erase(std::remove_if(aRunChanges.begin(),
644 aRunChanges.end(), myImplHelpers::IfBeforeStart(0)), aRunChanges.end());
655 rtl_getBestWindowsCharsetFromTextEncoding(eTextEncoding);
656 switch (eTextEncoding)
658 case RTL_TEXTENCODING_DONTKNOW:
659 case RTL_TEXTENCODING_UCS2:
660 case RTL_TEXTENCODING_UTF7:
661 case RTL_TEXTENCODING_UTF8:
662 case RTL_TEXTENCODING_JAVA_UTF8:
672 CanEncode(OUString
const& rString, rtl_TextEncoding
const eEncoding)
675 return rString.convertToString(&tmp, eEncoding,
676 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
677 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR);
681 OUString
const& rFontName, OUString
const& rAltName,
682 rtl_TextEncoding eTextEncoding)
685 rtl_getBestWindowsCharsetFromTextEncoding(eTextEncoding);
686 rtl_TextEncoding enc2 = rtl_getTextEncodingFromWindowsCharset(nRet);
687 if (!rtl_isOctetTextEncoding(enc2) ||
690 static struct { rtl_TextEncoding enc;
sal_uInt8 charset; }
691 const s_fallbacks [] = {
692 { RTL_TEXTENCODING_MS_932, 0x80 },
693 { RTL_TEXTENCODING_MS_936, 0x86 },
694 { RTL_TEXTENCODING_MS_950, 0x88 },
695 { RTL_TEXTENCODING_MS_949, 0x81 },
697 for (
const auto &
i : s_fallbacks)
707 SAL_INFO(
"sw.rtf",
"no fallback charset found for font: "
708 << rFontName <<
" " << rAltName);
735 nDT += ( rDT.
GetYear() - 1900 ) & 0x1ff;
739 nDT += rDT.
GetDay() & 0x1f;
743 nDT += rDT.
GetMin() & 0x3f;
753 const sal_Int32 nLen = rParams.getLength();
754 if (nFromPos < 0 || nLen <= nFromPos)
756 for (sal_Int32 nI = nFromPos; nI < nLen; ++nI)
767 if (rParams[nI] ==
'\"' && rParams[nI-1] !=
'\\')
784 static bool replaceUnquoted( OUString& rParams,
const OUString& rFind,
const OUString& rReplace )
786 bool bReplaced =
false;
791 sal_Int32 nLen = rParams.getLength();
792 for (sal_Int32 nI = 0; nI < nLen; ++nI)
795 if (rParams[nI] ==
'\\')
797 else if (rParams[nI] ==
'\"')
803 if (rParams[nI] ==
'\"' && rParams[nI-1] !=
'\\')
810 if (c == cFirst && rParams.match( rFind, nI))
812 const sal_Int32 nFindLen = rFind.getLength();
813 const sal_Int32 nDiff = rReplace.getLength() - nFindLen;
814 rParams = rParams.replaceAt( nI, nFindLen, rReplace);
815 nI += nFindLen + nDiff - 1;
829 sal_Int32 nCheckPos = 0;
839 bool bForceJapanese = (-1 !=
findUnquoted( rParams,
'g', 0));
849 sal_Int32 nLastPos = 0;
853 bForceJapanese |= ( nPos != -1 &&
IsNotAM( rParams, nPos ) );
855 }
while ( -1 != nLastPos );
864 sal_Int32 nLastPos = 0;
868 bool bIsCharA = ( nPos != -1 &&
IsNotAM( rParams, nPos ) );
869 bForceNatNum |= bIsCharA;
871 rParams = rParams.replaceAt( nPos, 1,
u"D" );
873 }
while ( -1 != nLastPos );
876 sal_Int32 nLen = rParams.getLength();
877 for (sal_Int32 nI = 0; nI < nLen; ++nI)
879 if (rParams[nI] ==
'\\')
881 else if (rParams[nI] ==
'\"')
887 if (rParams[nI] ==
'\"' && rParams[nI-1] !=
'\\')
899 if ( ( nChar ==
'a' || nChar ==
'A' ) &&
IsNotAM(rParams, nI) )
900 rParams = rParams.replaceAt(nI, 1,
u"Y");
908 rParams = rParams.replaceAt(nI, 1,
u"\\/");
918 if ( !bForceJapanese && !bForceNatNum )
923 if (nChar ==
'y' || nChar ==
'Y')
924 rParams = rParams.replaceAt(nI, 1,
u"V");
925 else if (nChar ==
'm' || nChar ==
'M')
926 rParams = rParams.replaceAt(nI, 1,
u"K");
927 else if (nChar ==
'd' || nChar ==
'D')
928 rParams = rParams.replaceAt(nI, 1,
u"P");
929 else if (nChar ==
'h' || nChar ==
'H')
930 rParams = rParams.replaceAt(nI, 1,
u"T");
932 else if ( rLang.
anyOf(
940 if (nChar ==
'h' || nChar ==
'H')
941 rParams = rParams.replaceAt(nI, 1,
u"T");
943 else if ( rLang.
anyOf(
967 if (nChar ==
'a' || nChar ==
'A')
968 rParams = rParams.replaceAt(nI, 1,
u"O");
969 else if (nChar ==
'y' || nChar ==
'Y')
970 rParams = rParams.replaceAt(nI, 1,
u"A");
972 else if ( rLang.
anyOf(
976 if (nChar ==
'y' || nChar ==
'Y')
977 rParams = rParams.replaceAt(nI, 1,
u"J");
978 else if (nChar ==
'u' || nChar ==
'U')
979 rParams = rParams.replaceAt(nI, 1,
u"H");
981 else if ( rLang.
anyOf(
985 if (nChar ==
'a' || nChar ==
'A')
986 rParams = rParams.replaceAt(nI, 1,
u"O");
987 else if (nChar ==
'g' || nChar ==
'G')
988 rParams = rParams.replaceAt(nI, 1,
u"X");
989 else if (nChar ==
'y' || nChar ==
'Y')
990 rParams = rParams.replaceAt(nI, 1,
u"A");
991 else if (nChar ==
'd' || nChar ==
'D')
992 rParams = rParams.replaceAt(nI, 1,
u"G");
994 else if ( rLang.
anyOf(
1001 if (nChar ==
'y' || nChar ==
'Y')
1002 rParams = rParams.replaceAt(nI, 1,
u"J");
1003 else if (nChar ==
'd' || nChar ==
'D')
1004 rParams = rParams.replaceAt(nI, 1,
u"T");
1006 else if ( rLang.
anyOf(
1014 if (nChar ==
'y' || nChar ==
'Y' || nChar ==
'a')
1015 rParams = rParams.replaceAt(nI, 1,
u"A");
1016 else if (nChar ==
'd' || nChar ==
'D' || nChar ==
'j')
1017 rParams = rParams.replaceAt(nI, 1,
u"J");
1024 bForceJapanese =
true;
1030 rParams =
"[NatNum1][$-411]" + rParams;
1033 rParams =
"[~hijri]" + rParams;
1035 pFormatter->
PutEntry(rParams, nCheckPos, nType, nKey, rLang);
1044 bool IsNextPM(std::u16string_view rParams, sal_Int32 nPos)
1048 bool IsNotAM(std::u16string_view rParams, sal_Int32 nPos)
1051 return o3tl::make_unsigned(nPos)>=rParams.size() || (rParams[nPos]!=
'M' && rParams[nPos]!=
'm');
1057 const sal_Int32 nLen = rFormat.getLength();
1058 for (sal_Int32 nI = 0; nI < nLen; ++nI)
1060 if (!nI || rFormat[nI-1]!=
'\\')
1062 if (rFormat[nI]==
'\"')
1063 rFormat = rFormat.replaceAt(nI, 1,
u"\'");
1064 else if (rFormat[nI]==
'\'')
1065 rFormat = rFormat.replaceAt(nI, 1,
u"\"");
#define LANGUAGE_SPANISH_PANAMA
#define LANGUAGE_SPANISH_EL_SALVADOR
constexpr TypedWhichId< SwHeaderAndFooterEatSpacingItem > RES_HEADER_FOOTER_EAT_SPACING(121)
#define LANGUAGE_SPANISH_VENEZUELA
Represents the style of a paragraph.
Marks a position in the document model.
std::vector< SwColumn > SwColumns
DayOfWeek GetDayOfWeek() const
#define LANGUAGE_DUTCH_BELGIAN
sal_uInt16 GetLower() const
const OUString & GetText() const
constexpr TypedWhichId< SwFormatHeader > RES_HEADER(96)
sal_uLong MSDateTimeFormatToSwFormat(OUString &rParams, SvNumberFormatter *pFormatter, LanguageType &rLang, bool bHijri, LanguageType nDocLang)
Convert from Word Date/Time field str to Writer's Date Time str.
bool IsNextPM(std::u16string_view rParams, sal_Int32 nPos)
#define LANGUAGE_SPANISH_GUATEMALA
std::u16string_view GetNextFontToken(std::u16string_view rTokenStr, sal_Int32 &rIndex)
#define LANGUAGE_SPANISH_ECUADOR
#define LANGUAGE_FRENCH_MONACO
SvxFrameDirection GetTextDirection(const SwPosition &rPos, const Point *pPt=nullptr) const
Dialog to specify the properties of date form field.
#define LANGUAGE_FRENCH_SWISS
#define LANGUAGE_GERMAN_AUSTRIAN
Of course Writer needs its own rectangles.
static SwTwips CalcHdDist(const SwFrameFormat &rFormat)
static SvxLRSpaceItem lcl_getWordLRSpace(const SwFrameFormat &rFormat)
Count what Word calls left/right margin from a format's LRSpace + Box.
#define LANGUAGE_FRENCH_CANADIAN
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
bool IsStarSymbol(std::u16string_view rFontName)
std::unique_ptr<::myImplHelpers::StyleMapperImpl< SwTextFormatColl > > mpImpl
#define LANGUAGE_SPANISH_NICARAGUA
bool matchIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2, sal_Int32 fromIndex=0)
#define LANGUAGE_NORWEGIAN_NYNORSK
#define LANGUAGE_SPANISH_HONDURAS
#define LANGUAGE_PORTUGUESE
StyleResult GetStyle(const OUString &rName, ww::sti eSti)
Get the writer style which the word style should map to.
static OUString FindBestMSSubstituteFont(std::u16string_view rFont)
sal_uInt16 GetMonth() const
StyleMapperImpl(SwDoc &rDoc)
std::pair< SwTextFormatColl *, bool > StyleResult
StyleResult StyleResult is a std::pair of a pointer to a style and a flag which is true if the style ...
bool operator()(sal_uInt16 nA, sal_uInt16 nB) const
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
sal_Int32 GetDate() const
OUString GetSubsFontName(std::u16string_view rName, SubsFontFlags nFlags)
#define LANGUAGE_SWEDISH_FINLAND
#define LANGUAGE_NORWEGIAN_BOKMAL
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
#define LANGUAGE_NORWEGIAN
#define SAL_N_ELEMENTS(arr)
rtl_TextEncoding GetExtendedTextEncoding(rtl_TextEncoding eEncoding)
sal_Int16 GetYear() const
#define LANGUAGE_SPANISH_COLOMBIA
bool IsPreviousAM(std::u16string_view rParams, sal_Int32 nPos)
#define LANGUAGE_ITALIAN_SWISS
#define LANGUAGE_SPANISH_DOMINICAN_REPUBLIC
static bool CanEncode(OUString const &rString, rtl_TextEncoding const eEncoding)
sal_uInt8 rtl_TextEncodingToWinCharsetRTF(OUString const &rFontName, OUString const &rAltName, rtl_TextEncoding eTextEncoding)
MSOffice appears to set the charset of unicode fonts to MS 932.
#define LANGUAGE_GERMAN_LIECHTENSTEIN
#define LANGUAGE_SPANISH_MEXICAN
std::pair< C *, bool > StyleResult
static SwTwips CalcFtDist(const SwFrameFormat &rFormat)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
static SwTwips CalcHdFtDist(const SwFrameFormat &rFormat, sal_uInt16 nSpacing)
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
sal_uInt16 GetDay() const
FontMapExport(std::u16string_view rFontDescription)
o3tl::sorted_vector< const C * > maUsedStyles
#define LANGUAGE_GERMAN_LUXEMBOURG
tools::Long GetHeight() const
#define LANGUAGE_SPANISH_BOLIVIA
RES_POOL_CHRFMT_TYPE
Ranges for the IDs of the formats.
#define LANGUAGE_SPANISH_PUERTO_RICO
#define LANGUAGE_SPANISH_MODERN
CharRuns GetPseudoCharRuns(const SwTextNode &rTextNd)
Collect the ranges of Text which share.
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
SwTextFormatColl * GetParaStyle(SwDoc &rDoc, const OUString &rName)
Get a Paragraph Style which fits a given name.
SwTextNode is a paragraph in the document model.
#define LANGUAGE_PORTUGUESE_BRAZILIAN
CharStyleMapper(SwDoc &rDoc)
#define LANGUAGE_SPANISH_URUGUAY
#define LANGUAGE_SPANISH_COSTARICA
#define LANGUAGE_SPANISH_PERU
Make export a word section top/bottom values easy.
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
sal_uInt8 rtl_TextEncodingToWinCharset(rtl_TextEncoding eTextEncoding)
MSOffice appears to set the charset of unicode fonts to MS 932.
sal_uInt32 DateTime2DTTM(const DateTime &rDT)
Convert from DTTM to Writer's DateTime.
#define SAL_INFO(area, stream)
std::pair< SwCharFormat *, bool > StyleResult
StyleResult StyleResult is a std::pair of a pointer to a style and a flag which is true if the style ...
StyleResult GetStyle(const OUString &rName, ww::sti eSti)
Get the writer style which the word style should map to.
bool IsPlausableSingleWordSection(const SwFrameFormat &rTitleFormat, const SwFrameFormat &rFollowFormat)
See if two page formats can be expressed as a single word section.
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
static sal_Int32 findUnquoted(const OUString &rParams, sal_Unicode cFind, sal_Int32 nFromPos)
Find cFind in rParams if not embedded in " double quotes.
#define LANGUAGE_FRENCH_LUXEMBOURG
constexpr TypedWhichId< SwFormatFooter > RES_FOOTER(97)
#define LANGUAGE_SPANISH_PARAGUAY
#define LANGUAGE_FRENCH_BELGIAN
std::vector< CharRunEntry > CharRuns
bool IsNotAM(std::u16string_view rParams, sal_Int32 nPos)
Used by MSDateTimeFormatToSwFormat to identify AM time fields.
Frame is variable in Var-direction.
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
void SwapQuotesInField(OUString &rFormat)
Another function used by MSDateTimeFormatToSwFormat.
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
SwCharFormat * GetCharStyle(SwDoc &rDoc, const OUString &rName)
Get a Character Style which fits a given name.
void Height(tools::Long nNew)
#define LANGUAGE_JAPANESE
#define LANGUAGE_SPANISH_DATED
#define LANGUAGE_GERMAN_SWISS
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
std::unique_ptr<::myImplHelpers::StyleMapperImpl< SwCharFormat > > mpImpl
#define LANGUAGE_SPANISH_ARGENTINA
#define LANGUAGE_SPANISH_CHILE
bool anyOf(strong_int v) const
sal_uInt16 GetUpper() const
static bool replaceUnquoted(OUString &rParams, const OUString &rFind, const OUString &rReplace)
Find all rFind in rParams if not embedded in " double quotes and replace with rReplace.