/* -*- 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 .
*/
// insert the list tab stop into SvxTabItem instance <pRuler> const SvxTabStop aListTabStop( m_nListTabStopPosition,
SvxTabAdjust::Left );
m_oRuler->Insert( aListTabStop );
// remove default tab stops, which are before the inserted list tab stop for ( sal_uInt16 i = 0; i < m_oRuler->Count(); i++ )
{ if ( (*m_oRuler)[i].GetTabPos() < m_nListTabStopPosition &&
(*m_oRuler)[i].GetAdjustment() == SvxTabAdjust::Default )
{
m_oRuler->Remove(i); continue;
}
}
}
if ( !rTextNode.getIDocumentSettingAccess()->get(DocumentSettingId::TABS_RELATIVE_TO_INDENT) )
{ // remove default tab stop at position 0 for ( sal_uInt16 i = 0; i < m_oRuler->Count(); i++ )
{ if ( (*m_oRuler)[i].GetTabPos() == 0 &&
(*m_oRuler)[i].GetAdjustment() == SvxTabAdjust::Default )
{
m_oRuler->Remove(i); break;
}
}
}
// Get the output and reference device if ( m_pVsh )
{
m_pOut = pRenderContext;
m_pRef = &m_pVsh->GetRefDev();
m_bOnWin = m_pVsh->GetWin() || OUTDEV_WINDOW == m_pOut->GetOutDevType() || m_pVsh->isOutputToWindow();
} else
{ // Access via StarONE. We do not need a Shell or an active one. if (rDoc.getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE))
{ // We can only pick the AppWin here? (there's nothing better to pick?)
m_pOut = Application::GetDefaultDevice();
} else
m_pOut = rDoc.getIDocumentDeviceAccess().getPrinter(false);
m_pOpt = m_pVsh ?
m_pVsh->GetViewOptions() :
SwModule::get()->GetViewOption(rDoc.getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE)); // Options from Module, due to StarONE
// bURLNotify is set if MakeGraphic prepares it // TODO: Unwind
m_bURLNotify = pNoteURL && !m_bOnWin;
void SwTextSizeInfo::SelectFont()
{ // The path needs to go via ChgPhysFnt or the FontMetricCache gets confused. // In this case pLastMet has it's old value. // Wrong: GetOut()->SetFont( GetFont()->GetFnt() );
GetFont()->Invalidate();
GetFont()->ChgPhysFnt( m_pVsh, *GetOut() );
}
// The SwScriptInfo is useless if we are inside a field portion
SwScriptInfo* pSI = nullptr; if ( ! rPor.InFieldGrp() )
pSI = &GetParaPortion()->GetScriptInfo();
// in some cases, kana compression is not allowed or suppressed for // performance reasons
sal_uInt16 nComp = 0; if ( ! IsMulti() )
nComp = GetKanaComp();
// the font is used to identify the current script via nActual
aDrawInf.SetFont( m_pFnt ); // the frame is used to identify the orientation
aDrawInf.SetFrame( GetTextFrame() ); // we have to know if the paragraph should snap to grid
aDrawInf.SetSnapToGrid( SnapToGrid() ); // for underlining we must know when not to add extra space behind // a character in justified mode
aDrawInf.SetSpaceStop( ! rPor.GetNextPortion() ||
rPor.GetNextPortion()->InFixMargGrp() ||
rPor.GetNextPortion()->IsHolePortion() );
// Draw text next to the left border
Point aFontPos(m_aPos); if( m_pFnt->GetLeftBorder() && rPor.InTextGrp() && !static_cast<const SwTextPortion&>(rPor).GetJoinBorderWithPrev() )
{ const sal_uInt16 nLeftBorderSpace = m_pFnt->GetLeftBorderSpace(); if ( GetTextFrame()->IsRightToLeft() )
{
aFontPos.AdjustX( -nLeftBorderSpace );
} else
{ switch( m_pFnt->GetOrientation(GetTextFrame()->IsVertical()).get() )
{ case 0 :
aFontPos.AdjustX(nLeftBorderSpace ); break; case 900 :
aFontPos.AdjustY( -nLeftBorderSpace ); break; case 1800 :
aFontPos.AdjustX( -nLeftBorderSpace ); break; case 2700 :
aFontPos.AdjustY(nLeftBorderSpace ); break;
}
} if( aFontPos.X() < 0 )
aFontPos.setX( 0 ); if( aFontPos.Y() < 0 )
aFontPos.setY( 0 );
}
// Handle semi-transparent text if necessary.
std::unique_ptr<SwTransparentTextGuard, o3tl::default_delete<SwTransparentTextGuard>> pTransparentText; if (m_pFnt->GetColor() != COL_AUTO && m_pFnt->GetColor().IsTransparent())
{ // if drawing to a backend that supports transparency for text color, then we don't need to use this if (!m_bOnWin || !m_pOut->SupportsOperation(OutDevSupportType::TransparentText) || m_pOut->GetConnectMetaFile())
pTransparentText.reset(new SwTransparentTextGuard(rPor, *this, aDrawInf));
}
/** * Draws a special portion * E.g.: line break portion, tab portion * * @param rPor The portion * @param rRect The rectangle surrounding the character * @param rCol Specify a color for the character * @param bCenter Draw the character centered, otherwise left aligned * @param bRotate Rotate the character if character rotation is set
*/ staticvoid lcl_DrawSpecial( const SwTextPaintInfo& rTextPaintInfo, const SwLinePortion& rPor,
SwRect& rRect, const Color& rCol, sal_Unicode cChar,
sal_uInt8 nOptions )
{ bool bCenter = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_CENTER ); bool bRotate = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_ROTATE );
// rRect is given in absolute coordinates if ( rTextPaintInfo.GetTextFrame()->IsRightToLeft() )
rTextPaintInfo.GetTextFrame()->SwitchRTLtoLTR( rRect ); if ( rTextPaintInfo.GetTextFrame()->IsVertical() )
rTextPaintInfo.GetTextFrame()->SwitchVerticalToHorizontal( rRect );
// Some of the current values are set at the font: if ( ! bRotate )
s_aFnt.SetVertical( 0_deg10, rTextPaintInfo.GetTextFrame()->IsVertical() ); else
s_aFnt.SetVertical( pOldFnt->GetOrientation() );
// The maximum width depends on the current orientation const Degree10 nDir = s_aFnt.GetOrientation( rTextPaintInfo.GetTextFrame()->IsVertical() );
SwTwips nMaxWidth; if (nDir == 900_deg10 || nDir == 2700_deg10)
nMaxWidth = rRect.Height(); else
{
assert(nDir == 0_deg10); //Unknown direction set at font
nMaxWidth = rRect.Width();
}
if (eClear != SwLineBreakClear::NONE)
{ // Paint indicator if this clear is left/right/all.
m_pOut->Push(vcl::PushFlags::LINECOLOR);
m_pOut->SetLineColor(SwViewOption::GetCurrentViewOptions().GetNonPrintingCharacterColor()); if (eClear != SwLineBreakClear::RIGHT)
m_pOut->DrawLine(aRect.BottomLeft(), aRect.TopLeft()); if (eClear != SwLineBreakClear::LEFT)
m_pOut->DrawLine(aRect.BottomRight(), aRect.TopRight());
m_pOut->Pop();
}
}
void SwTextPaintInfo::DrawCSDFHighlighting(const SwLinePortion &rPor) const
{ // Don't use GetActiveView() as it does not work as expected when there are multiple open // documents.
SwView* pView = SwTextFrame::GetView(); if (!pView) return;
if (!pView->IsSpotlightCharStyles() && !pView->IsHighlightCharDF()) return;
std::optional<OUString> sCSNumberOrDF; // CS number or "df" or not used
std::optional<Color> aFillColor;
// check for CS formatting, if not CS formatted check for direct character formatting if (!sCurrentCharStyle.isEmpty())
{
UIName sCharStyleDisplayName = SwStyleNameMapper::GetUIName(ProgName(sCurrentCharStyle),
SwGetPoolIdFromName::ChrFmt); if (comphelper::LibreOfficeKit::isActive())
{ // For simplicity in kit mode, we render in the document "all styles" that exist if (const SwCharFormat* pCharFormat = pFrame->GetDoc().FindCharFormatByName(sCharStyleDisplayName))
{ // Do this so these are stable across views regardless of an individual // user's selection mode in the style panel.
sCSNumberOrDF = OUString::number(pFrame->GetDoc().GetCharFormats()->GetPos(pCharFormat));
aFillColor = ColorHash(sCharStyleDisplayName.toString());
}
} else
{ if (!sCharStyleDisplayName.isEmpty())
{
StylesSpotlightColorMap& rCharStylesColorMap = pView->GetStylesSpotlightCharColorMap(); auto it = rCharStylesColorMap.find(sCharStyleDisplayName.toString()); if (it != rCharStylesColorMap.end())
{
sCSNumberOrDF = OUString::number(it->second.second);
aFillColor = it->second.first;
}
}
}
} // not character style formatted elseif (pView->IsHighlightCharDF())
{ const std::vector<OUString> aHiddenProperties{ UNO_NAME_RSID,
UNO_NAME_PARA_IS_NUMBERING_RESTART,
UNO_NAME_PARA_STYLE_NAME,
UNO_NAME_PARA_CONDITIONAL_STYLE_NAME,
UNO_NAME_PAGE_STYLE_NAME,
UNO_NAME_NUMBERING_START_VALUE,
UNO_NAME_NUMBERING_IS_NUMBER,
UNO_NAME_PARA_CONTINUEING_PREVIOUS_SUB_TREE,
UNO_NAME_CHAR_STYLE_NAME,
UNO_NAME_NUMBERING_LEVEL,
UNO_NAME_SORTED_TEXT_ID,
UNO_NAME_PARRSID,
UNO_NAME_CHAR_COLOR_THEME,
UNO_NAME_CHAR_COLOR_TINT_OR_SHADE };
// draw a filled rectangle at the formatted CS or DF text
pTmpOut->SetFillColor(aFillColor.value());
pTmpOut->SetLineColor(aFillColor.value());
tools::Rectangle aSVRect(aRect.SVRect());
pTmpOut->DrawRect(aSVRect);
// calculate size and position for the CS number or "df" text and rectangle
tools::Long nWidth = pTmpOut->GetTextWidth(sCSNumberOrDF.value());
tools::Long nHeight = pTmpOut->GetTextHeight();
aSVRect.SetSize(Size(nWidth, nHeight));
aSVRect.Move(-(nWidth / 1.5), -(nHeight / 1.5));
bool bDraw = false; if ( !GetOpt().IsPagePreview()
&& !GetOpt().IsReadonly() )
{ switch( nWhich )
{ case PortionType::Tab: if ( GetOpt().IsViewMetaChars() )
bDraw = GetOpt().IsTab(); break; case PortionType::SoftHyphen: if ( GetOpt().IsViewMetaChars() )
bDraw = GetOpt().IsSoftHyph(); break; case PortionType::Blank: if ( GetOpt().IsViewMetaChars() )
bDraw = GetOpt().IsHardBlank(); break; case PortionType::ControlChar: if ( GetOpt().IsViewMetaChars() )
bDraw = true; break; case PortionType::Bookmark: // no shading break; case PortionType::Footnote: case PortionType::QuoVadis: case PortionType::Number: case PortionType::Hidden: case PortionType::Tox: case PortionType::Ref: case PortionType::Meta: case PortionType::ContentControl: case PortionType::Field: case PortionType::InputField: // input field shading also in read-only mode if (GetOpt().IsFieldShadings()
&& ( PortionType::Number != nWhich
|| m_pFrame->GetTextNodeForParaProps()->HasMarkedLabel())) // #i27615#
{
bDraw = PortionType::Footnote != nWhich || m_pFrame->IsFootnoteAllowed();
} break; default:
{
OSL_ENSURE( false, "SwTextPaintInfo::DrawViewOpt: don't know how to draw this" ); break;
}
}
}
SvtCTLOptions::TextNumerals const nTextNumerals(SwModule::get()->GetCTLTextNumerals()); // cannot cache for NUMERALS_CONTEXT because we need to know the string // for the whole paragraph now if (nTextNumerals != SvtCTLOptions::NUMERALS_CONTEXT)
{ // set digit mode to what will be used later to get same results
SwDigitModeModifier const m(*m_pRef, LANGUAGE_NONE /*dummy*/, nTextNumerals);
assert(m_pRef->GetDigitLanguage() != LANGUAGE_NONE);
SetCachedVclData(OutputDevice::CreateTextLayoutCache(*m_pText));
}
Init();
}
/** * If the Hyphenator returns ERROR or the language is set to NOLANGUAGE * we do not hyphenate. * Else, we always hyphenate if we do interactive hyphenation. * If we do not do interactive hyphenation, we only hyphenate if ParaFormat is * set to automatic hyphenation.
*/ bool SwTextFormatInfo::IsHyphenate() const
{ if( !m_bInterHyph && !m_bAutoHyph ) returnfalse;
LanguageType eTmp = GetFont()->GetLanguage(); // TODO: check for more ideographic langs w/o hyphenation as a concept if ( LANGUAGE_DONTKNOW == eTmp || LANGUAGE_NONE == eTmp
|| !MsLangId::usesHyphenation(eTmp) ) returnfalse;
uno::Reference< XHyphenator > xHyph = ::GetHyphenator(); if (!xHyph.is()) returnfalse;
if (m_bInterHyph)
SvxSpellWrapper::CheckHyphLang( xHyph, eTmp );
if (!xHyph->hasLocale(g_pBreakIt->GetLocale(eTmp)))
{
SfxObjectShell* pShell = m_pFrame->GetDoc().GetDocShell(); if (pShell)
{
pShell->AppendInfoBarWhenReady(
u"hyphenationmissing"_ustr, SwResId(STR_HYPH_MISSING),
SwResId(STR_HYPH_MISSING_DETAIL)
.replaceFirst("%1", LanguageTag::convertToBcp47( g_pBreakIt->GetLocale(eTmp))),
InfobarType::WARNING);
}
}
// generally we do not allow number portions in follows, except... if ( GetTextFrame()->IsFollow() )
{ const SwTextFrame* pMaster = GetTextFrame()->FindMaster();
OSL_ENSURE(pMaster, "pTextFrame without Master"); const SwLinePortion* pTmpPara = pMaster ? pMaster->GetPara() : nullptr;
// there is a master for this follow and the master does not have // any contents (especially it does not have a number portion)
m_bNumDone = ! pTmpPara ||
! static_cast<const SwParaPortion*>(pTmpPara)->GetFirstPortion()->IsFlyPortion();
}
/** * There are a few differences between a copy constructor * and the following constructor for multi-line formatting. * The root is the first line inside the multi-portion, * the line start is the actual position in the text, * the line width is the rest width from the surrounding line * and the bMulti and bFirstMulti-flag has to be set correctly.
*/
SwTextFormatInfo::SwTextFormatInfo( const SwTextFormatInfo& rInf,
SwLineLayout& rLay, SwTwips nActWidth ) :
SwTextPaintInfo( rInf ),
m_pRoot(&rLay),
m_pLast(&rLay),
m_pFly(nullptr),
m_pUnderflow(nullptr),
m_pRest(nullptr),
m_pLastTab(nullptr),
m_nSoftHyphPos(TextFrameIndex(0)),
m_nLineStart(rInf.GetIdx()),
m_nLeft(rInf.m_nLeft),
m_nRight(rInf.m_nRight),
m_nFirst(rInf.m_nLeft),
m_nRealWidth(nActWidth),
m_nWidth(m_nRealWidth),
m_nLineHeight(0),
m_nLineNetHeight(0),
m_nForcedLeftMargin(0),
m_nExtraAscent(0),
m_nExtraDescent(0),
m_bFull(false),
m_bFootnoteDone(true),
m_bErgoDone(true),
m_bNumDone(true),
m_bArrowDone(true),
m_bStop(false),
m_bNewLine(true),
m_bShift(false),
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet)
¤
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.