/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
auto it1 = std::lower_bound(m_HintsByStart.begin(), m_HintsByStart.end(), pHt, CompareSwpHtStart);
m_HintsByStart.insert(it1, pHt);
auto it2 = std::lower_bound(m_HintsByEnd.begin(), m_HintsByEnd.end(), pHt, CompareSwpHtEnd());
m_HintsByEnd.insert(it2, pHt);
auto it3 = std::lower_bound(m_HintsByWhichAndStart.begin(), m_HintsByWhichAndStart.end(), pHt, CompareSwpHtWhichStart());
m_HintsByWhichAndStart.insert(it3, pHt);
}
bool SwpHints::Contains( const SwTextAttr *pHt ) const
{ // DO NOT use find() or CHECK here! // if called from SwTextNode::InsertItem, pHt has already been deleted, // so it cannot be dereferenced return std::find(m_HintsByStart.begin(), m_HintsByStart.end(), pHt)
!= m_HintsByStart.end();
}
bool SwpHints::Check(bool bPortionsMerged) const
{ // 1) both arrays have same size
CHECK_ERR( m_HintsByStart.size() == m_HintsByEnd.size(), "HintsCheck: wrong sizes" );
sal_Int32 nLastStart = 0;
sal_Int32 nLastEnd = 0;
const SwTextAttr *pLastStart = nullptr; const SwTextAttr *pLastEnd = nullptr;
o3tl::sorted_vector<SwTextAttr const*> RsidOnlyAutoFormats; if (bPortionsMerged)
{ for (size_t i = 0; i < Count(); ++i)
{
SwTextAttr const*const pHint(m_HintsByStart[i]); if (RES_TXTATR_AUTOFMT == pHint->Which())
{
std::shared_ptr<SfxItemSet> const & pSet(
pHint->GetAutoFormat().GetStyleHandle()); if (pSet->Count() == 1 && pSet->GetItem(RES_CHRATR_RSID, false))
{
RsidOnlyAutoFormats.insert(pHint);
}
}
}
}
// --- cross checks --- // same pointers in both arrays auto tmpHintsByEnd = m_HintsByEnd;
std::sort(tmpHintsByEnd.begin(), tmpHintsByEnd.end(), CompareSwpHtStart);
CHECK_ERR( tmpHintsByEnd == m_HintsByStart, "HintsCheck: the two arrays do not contain the same set of pointers" );
for( size_t i = 0; i < Count(); ++i )
{ // --- check Starts ---
// 2a) valid pointer? depends on overwriting freed mem with 0xFF const SwTextAttr *pHt = m_HintsByStart[i];
CHECK_ERR( 0xFF != *reinterpret_cast<unsignedcharconst *>(pHt), "HintsCheck: start ptr was deleted" );
CHECK_ERR( COMPLETE_STRING != nIdx, "HintsCheck: no GetEndOf" );
// 7a) character attributes in array?
sal_uInt16 nWhich = pHt->Which();
CHECK_ERR( !isCHRATR(nWhich), "HintsCheck: Character attribute in start array" );
// 7b) character attributes in array?
nWhich = pHtEnd->Which();
CHECK_ERR( !isCHRATR(nWhich), "HintsCheck: Character attribute in end array" );
// 8) style portion check const SwTextAttr* pHtThis = m_HintsByStart[i]; const SwTextAttr* pHtLast = i > 0 ? m_HintsByStart[i-1] : nullptr;
CHECK_ERR( (0 == i)
|| ( (RES_TXTATR_CHARFMT != pHtLast->Which())
&& (RES_TXTATR_AUTOFMT != pHtLast->Which()))
|| ( (RES_TXTATR_CHARFMT != pHtThis->Which())
&& (RES_TXTATR_AUTOFMT != pHtThis->Which()))
|| (pHtThis->GetStart() >= *pHtLast->End()) // no overlap
|| ( ( (pHtThis->GetStart() == pHtLast->GetStart())
&& (*pHtThis->End() == *pHtLast->End())
) // same range
&& ( (pHtThis->Which() != RES_TXTATR_AUTOFMT)
|| (pHtLast->Which() != RES_TXTATR_AUTOFMT)
) // never two AUTOFMT on same range
&& ( (pHtThis->Which() != RES_TXTATR_CHARFMT)
|| (pHtLast->Which() != RES_TXTATR_CHARFMT)
|| (static_txtattr_cast<const SwTextCharFormat *>(pHtThis)
->GetSortNumber() !=
static_txtattr_cast<const SwTextCharFormat *>(pHtLast)
->GetSortNumber())
) // multiple CHARFMT on same range need distinct sorter
)
|| (pHtThis->GetStart() == *pHtThis->End()), // this empty "HintsCheck: Portion inconsistency. " "This can be temporarily ok during undo operations" );
// 8 1/2) format ignore start/end flag check // (problems because MergePortions buggy or not called) if (bPortionsMerged)
{ if (RES_TXTATR_AUTOFMT == pHt->Which() ||
RES_TXTATR_CHARFMT == pHt->Which())
{ // mostly ignore the annoying no-length hints // BuildPortions inserts these in the middle of an existing one boolconst bNoLength(pHt->GetStart() == *pHt->End()); bool bNeedContinuation(!bNoLength && pHt->IsFormatIgnoreEnd()); bool bForbidContinuation(!bNoLength && !bNeedContinuation); if (RES_TXTATR_AUTOFMT == pHt->Which())
{ if (RsidOnlyAutoFormats.find(pHt) != RsidOnlyAutoFormats.end())
{
assert(pHt->IsFormatIgnoreStart());
bNeedContinuation = false; // don't forbid continuation - may be other hint here!
}
} if (bNeedContinuation || bForbidContinuation)
{ bool bFound(false); for (size_t j = i + 1; j < Count(); ++j)
{
SwTextAttr *const pOther(m_HintsByStart[j]); if (pOther->GetStart() > *pHt->End())
{ break; // done
} elseif (pOther->GetStart() == pOther->GetAnyEnd())
{ continue; // empty hint: ignore
} elseif (pOther->GetStart() == *pHt->End())
{ if (RES_TXTATR_AUTOFMT == pOther->Which() ||
RES_TXTATR_CHARFMT == pOther->Which())
{ // multiple charfmt on same range must all match if (bNeedContinuation)
{
assert(pOther->IsFormatIgnoreStart());
bFound = true;
} elseif (bForbidContinuation &&
(RsidOnlyAutoFormats.find(pOther) ==
RsidOnlyAutoFormats.end()))
{
assert(!pOther->IsFormatIgnoreStart());
}
}
}
} if (bNeedContinuation)
{
assert(bFound); // ? can this happen temp. during undo?
}
}
} else
{
assert(!pHt->IsFormatIgnoreStart());
assert(!pHt->IsFormatIgnoreEnd());
}
}
// Resort() is called before every Insert and Delete. // Various SwTextNode methods modify hints in a way that violates the // sort order of the m_HintsByStart, m_HintsByEnd arrays, so this method is needed // to restore the order.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.