23#include <rtl/ustrbuf.hxx>
45#include <textlayout.hxx>
51#include <com/sun/star/i18n/WordType.hpp>
52#include <com/sun/star/i18n/XBreakIterator.hpp>
53#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
58#define TEXT_DRAW_ELLIPSIS (DrawTextFlags::EndEllipsis | DrawTextFlags::PathEllipsis | DrawTextFlags::NewsEllipsis)
121 if ( !(nOrientation % 900_deg10) )
123 if ( nOrientation == 900_deg10 )
133 else if ( nOrientation == 1800_deg10 )
209 Point aBasePt( nBaseX, nBaseY );
278 aPoint +=
Point( nX, nY );
284 bool bOldMap =
mbMap;
355 Color aTextColor( aOldColor );
357 Color aTextLineColor( aOldTextLineColor );
358 Color aOverlineColor( aOldOverlineColor );
398 if ( aTextColor != aOldColor )
490 SAL_WARN_IF( nWidth <= 0,
"vcl",
"ImplGetTextLines: nWidth <= 0!" );
503 css::uno::Reference< css::linguistic2::XHyphenator > xHyph;
508 css::uno::Reference<css::linguistic2::XLinguServiceManager2> xLinguMgr = css::linguistic2::LinguServiceManager::create(xContext);
509 xHyph = xLinguMgr->getHyphenator();
512 css::uno::Reference<css::i18n::XBreakIterator> xBI;
514 sal_Int32 nLen = rStr.getLength();
515 sal_Int32 nCurrentTextY = 0;
516 while (
nPos < nLen )
518 sal_Int32 nBreakPos =
nPos;
520 while ( ( nBreakPos < nLen ) && ( rStr[ nBreakPos ] !=
'\r' ) && ( rStr[ nBreakPos ] !=
'\n' ) )
544 if ( nBreakPos ==
nPos )
548 if (
nPos < nLen && ( ( rStr[
nPos ] ==
'\r' ) || ( rStr[
nPos ] ==
'\n' ) ) )
552 if ( (
nPos < nLen ) && ( rStr[
nPos ] ==
'\n' ) && ( rStr[
nPos-1 ] ==
'\r' ) )
555 nCurrentTextY += nTextHeight;
556 if (bClipping && nCurrentTextY > rRect.
GetHeight())
561 for ( sal_Int32 nL = 0; nL < rLineInfo.
Count(); nL++ )
565 SAL_WARN_IF( aLine.indexOf(
'\r' ) != -1,
"vcl",
"ImplGetTextLines - Found CR!" );
566 SAL_WARN_IF( aLine.indexOf(
'\n' ) != -1,
"vcl",
"ImplGetTextLines - Found LF!" );
570 return nMaxLineWidth;
574 const css::uno::Reference< css::linguistic2::XHyphenator >& xHyph,
575 const css::uno::Reference<css::i18n::XBreakIterator>& xBI,
576 const bool bHyphenate,
577 const sal_Int32 nPos, sal_Int32 nBreakPos)
581 if (nSoftBreak == -1)
585 SAL_WARN_IF( nSoftBreak >= nBreakPos,
"vcl",
"Break?!" );
586 css::i18n::LineBreakHyphenationOptions aHyphOptions( xHyph, css::uno::Sequence <css::beans::PropertyValue>(), 1 );
587 css::i18n::LineBreakUserOptions aUserOptions;
588 css::i18n::LineBreakResults aLBR = xBI->getLineBreak( rStr, nSoftBreak, rDefLocale,
nPos, aHyphOptions, aUserOptions );
589 nBreakPos = aLBR.breakIndex;
590 if ( nBreakPos <=
nPos )
591 nBreakPos = nSoftBreak;
606 css::i18n::Boundary aBoundary = xBI->getWordBoundary( rStr, nBreakPos, rDefLocale, css::i18n::WordType::DICTIONARY_WORD,
true );
607 sal_Int32 nWordStart =
nPos;
608 sal_Int32 nWordEnd = aBoundary.endPos;
609 SAL_WARN_IF( nWordEnd <= nWordStart, "vcl", "ImpBreakLine: Start >=
End?
" );
611 sal_Int32 nWordLen = nWordEnd - nWordStart;
612 if ( ( nWordEnd < nSoftBreak ) || ( nWordLen <= 3 ) )
615 // #104415# May happen, because getLineBreak may differ from getWordBoundary with DICTIONARY_WORD
616 // SAL_WARN_IF( nWordEnd < nMaxBreakPos, "vcl", "Hyph:
Break?
" );
617 OUString aWord = rStr.copy( nWordStart, nWordLen );
618 sal_Int32 nMinTrail = nWordEnd-nSoftBreak+1; //+1: Before the "broken off
" char
619 css::uno::Reference< css::linguistic2::XHyphenatedWord > xHyphWord;
621 xHyphWord = xHyph->hyphenate( aWord, rDefLocale, aWord.getLength() - nMinTrail, css::uno::Sequence< css::beans::PropertyValue >() );
625 bool bAlternate = xHyphWord->isAlternativeSpelling();
626 sal_Int32 _nWordLen = 1 + xHyphWord->getHyphenPos();
628 if ( ( _nWordLen < 2 ) || ( (nWordStart+_nWordLen) < 2 ) )
633 nBreakPos = nWordStart + _nWordLen;
638 OUString aAlt( xHyphWord->getHyphenatedWord() );
640 // We can have two cases:
641 // 1) "packen
" turns into "pak-ken
"
642 // 2) "Schiffahrt
" turns into "Schiff-fahrt
"
644 // In case 1 we need to replace a char
645 // In case 2 we add a char
647 // Correct recognition is made harder by words such as
648 // "Schiffahrtsbrennesseln
", as the Hyphenator splits all
649 // positions of the word and comes up with "Schifffahrtsbrennnesseln
"
650 // Thus, we cannot infer the aWord from the AlternativeWord's
652 // TODO: The whole junk will be made easier by a function in
653 // the Hyphenator, as soon as AMA adds it.
654 sal_Int32 nAltStart = _nWordLen - 1;
655 sal_Int32 nTxtStart = nAltStart - (aAlt.getLength() - aWord.getLength());
656 sal_Int32 nTxtEnd = nTxtStart;
657 sal_Int32 nAltEnd = nAltStart;
659 // The area between nStart and nEnd is the difference
660 // between AlternativeString and OriginalString
661 while( nTxtEnd < aWord.getLength() && nAltEnd < aAlt.getLength() &&
662 aWord[nTxtEnd] != aAlt[nAltEnd] )
668 // If a char was added, we notice it now:
669 if( nAltEnd > nTxtEnd && nAltStart == nAltEnd &&
670 aWord[ nTxtEnd ] == aAlt[nAltEnd] )
677 SAL_WARN_IF( ( nAltEnd - nAltStart ) != 1, "vcl", "Alternate: Wrong assumption!
" );
679 sal_Unicode cAlternateReplChar = 0;
680 if ( nTxtEnd > nTxtStart )
681 cAlternateReplChar = aAlt[ nAltStart ];
683 nBreakPos = nWordStart + nTxtStart;
684 if ( cAlternateReplChar )
689sal_Int32 OutputDevice::ImplBreakLinesSimple( const tools::Long nWidth, const OUString& rStr,
690 const vcl::ITextLayout& _rLayout, const sal_Int32 nPos, sal_Int32 nBreakPos, tools::Long& nLineWidth )
692 sal_Int32 nSpacePos = rStr.getLength();
696 nSpacePos = rStr.lastIndexOf( ' ', nSpacePos );
697 if( nSpacePos != -1 )
699 if( nSpacePos > nPos )
701 nW = _rLayout.GetTextWidth( rStr, nPos, nSpacePos-nPos );
703 } while( nW > nWidth );
705 if( nSpacePos != -1 )
707 nBreakPos = nSpacePos;
708 nLineWidth = _rLayout.GetTextWidth( rStr, nPos, nBreakPos-nPos );
709 if( nBreakPos < rStr.getLength()-1 )
716void OutputDevice::SetTextColor( const Color& rColor )
719 Color aColor(vcl::drawmode::GetTextColor(rColor, GetDrawMode(), GetSettings().GetStyleSettings()));
722 mpMetaFile->AddAction( new MetaTextColorAction( aColor ) );
724 if ( maTextColor != aColor )
726 maTextColor = aColor;
727 mbInitTextColor = true;
731 mpAlphaVDev->SetTextColor( COL_BLACK );
734void OutputDevice::SetTextFillColor()
738 mpMetaFile->AddAction( new MetaTextFillColorAction( Color(), false ) );
740 if ( maFont.GetColor() != COL_TRANSPARENT ) {
741 maFont.SetFillColor( COL_TRANSPARENT );
743 if ( !maFont.IsTransparent() )
744 maFont.SetTransparent( true );
747 mpAlphaVDev->SetTextFillColor();
750void OutputDevice::SetTextFillColor( const Color& rColor )
752 Color aColor(vcl::drawmode::GetFillColor(rColor, GetDrawMode(), GetSettings().GetStyleSettings()));
755 mpMetaFile->AddAction( new MetaTextFillColorAction( aColor, true ) );
757 if ( maFont.GetFillColor() != aColor )
758 maFont.SetFillColor( aColor );
759 if ( maFont.IsTransparent() != rColor.IsTransparent() )
760 maFont.SetTransparent( rColor.IsTransparent() );
763 mpAlphaVDev->SetTextFillColor( COL_BLACK );
766Color OutputDevice::GetTextFillColor() const
768 if ( maFont.IsTransparent() )
769 return COL_TRANSPARENT;
771 return maFont.GetFillColor();
774void OutputDevice::SetTextAlign( TextAlign eAlign )
778 mpMetaFile->AddAction( new MetaTextAlignAction( eAlign ) );
780 if ( maFont.GetAlignment() != eAlign )
782 maFont.SetAlignment( eAlign );
787 mpAlphaVDev->SetTextAlign( eAlign );
790vcl::Region OutputDevice::GetOutputBoundsClipRegion() const
792 return GetClipRegion();
795const SalLayoutFlags eDefaultLayout = SalLayoutFlags::NONE;
797void OutputDevice::DrawText( const Point& rStartPt, const OUString& rStr,
798 sal_Int32 nIndex, sal_Int32 nLen,
799 std::vector< tools::Rectangle >* pVector, OUString* pDisplayText,
800 const SalLayoutGlyphs* pLayoutCache
803 assert(!is_double_buffered_window());
805 if( (nLen < 0) || (nIndex + nLen >= rStr.getLength()))
807 nLen = rStr.getLength() - nIndex;
810 if (mpOutDevData->mpRecordLayout)
812 pVector = &mpOutDevData->mpRecordLayout->m_aUnicodeBoundRects;
813 pDisplayText = &mpOutDevData->mpRecordLayout->m_aDisplayText;
816#if OSL_DEBUG_LEVEL > 2
833 std::vector< tools::Rectangle > aTmp;
836 bool bInserted =
false;
837 for( std::vector< tools::Rectangle >::const_iterator it = aTmp.begin(); it != aTmp.end(); ++it,
nIndex++ )
839 bool bAppend =
false;
843 else if( rStr[
nIndex ] ==
' ' && bInserted )
845 std::vector< tools::Rectangle >::const_iterator next = it;
847 if( next != aTmp.end() && aClip.
Overlaps( *next ) )
853 pVector->push_back( *it );
855 *pDisplayText += OUStringChar(rStr[
nIndex ]);
864 *pDisplayText += rStr.subView(
nIndex, nLen );
874 pLayoutCache =
nullptr;
876 std::unique_ptr<SalLayout> pSalLayout =
ImplLayout(rStr, nIndex, nLen, rStartPt, 0, {}, {},
eDefaultLayout,
nullptr, pLayoutCache);
892 nLen,
false, pLayoutCache, pSalLayoutCache );
931 if( nLen < 0 || nIndex + nLen >= rStr.getLength() )
933 nLen = rStr.getLength() -
nIndex;
948 std::unique_ptr<SalLayout> pSalLayout =
ImplLayout(rStr,
nIndex, nLen, rStartPt, 0, pDXAry, pKashidaAry, flags,
nullptr, pSalLayoutCache);
959 sal_Int32 nIndex, sal_Int32 nLen,
bool bCaret,
963 if(
nIndex >= rStr.getLength() )
966 if( nLen < 0 || nIndex + nLen >= rStr.getLength() )
968 nLen = rStr.getLength() -
nIndex;
971 std::vector<sal_Int32>* pDXAry = pKernArray ? &pKernArray->
get_subunit_array() :
nullptr;
986 pDXAry->resize(nLen);
987 std::fill(pDXAry->begin(), pDXAry->end(), 0);
992#if VCL_FLOAT_DEVICE_PIXEL
993 std::unique_ptr<std::vector<DeviceCoordinate>> xDXPixelArray;
996 xDXPixelArray.reset(
new std::vector<DeviceCoordinate>(nLen));
998 std::vector<DeviceCoordinate>* pDXPixelArray = xDXPixelArray.get();
999 DeviceCoordinate nWidth = pSalLayout->FillDXArray(pDXPixelArray, bCaret ? rStr : OUString());
1004 for(
int i = 1;
i < nLen; ++
i )
1006 (*pDXPixelArray)[
i] += (*pDXPixelArray)[
i - 1];
1013 for(
int i = 0;
i < nLen; ++
i )
1022 pDXAry->resize(nLen);
1023 for(
int i = 0;
i < nLen; ++
i )
1032 tools::Long nWidth = pSalLayout->FillDXArray( pDXAry, bCaret ? rStr : OUString() );
1036 for(
int i = 1;
i < nLen; ++
i )
1037 (*pDXAry)[
i ] += (*pDXAry)[
i-1 ];
1042 int nSubPixelFactor = pKernArray->
get_factor();
1045 for (
int i = 0;
i < nLen; ++
i)
1048 else if (nSubPixelFactor)
1050 for (
int i = 0;
i < nLen; ++
i)
1051 (*pDXAry)[
i] *= nSubPixelFactor;
1063 sal_Int32 nIndex, sal_Int32 nLen,
1067 if(
nIndex >= rStr.getLength() )
1069 if(
nIndex+nLen >= rStr.getLength() )
1070 nLen = rStr.getLength() -
nIndex;
1077 std::fill(pCaretXArray, pCaretXArray + nLen * 2, -1);
1081 pSalLayout->GetCaretPositions( 2*nLen, pCaretXArray );
1086 for(
i = 0;
i < 2 * nLen; ++
i )
1087 if( pCaretXArray[
i ] >= 0 )
1090 for(
i = 0;
i < 2 * nLen; ++
i )
1092 if( pCaretXArray[
i ] >= 0 )
1093 nXPos = pCaretXArray[
i ];
1095 pCaretXArray[
i ] = nXPos;
1101 for(
i = 0;
i < 2 * nLen; ++
i )
1102 pCaretXArray[
i] = nWidth - pCaretXArray[
i] - 1;
1108 for(
i = 0;
i < 2*nLen; ++
i )
1114 const OUString& rStr,
1115 sal_Int32 nIndex, sal_Int32 nLen)
1119 if( (nLen < 0) || (
nIndex + nLen >= rStr.getLength()))
1121 nLen = rStr.getLength() -
nIndex;
1130 std::unique_ptr<SalLayout> pSalLayout =
ImplLayout(rStr,
nIndex, nLen, rStartPt, nWidth);
1141 const sal_Int32 nMinIndex,
const sal_Int32 nLen,
1146 assert(nMinIndex >= 0);
1150 sal_Int32 nEndIndex = rStr.getLength();
1151 if( nMinIndex + nLen < nEndIndex )
1152 nEndIndex = nMinIndex + nLen;
1155 if( nEndIndex < nMinIndex )
1156 nEndIndex = nMinIndex;
1176 std::optional<OUStringBuffer> xTmpStr;
1177 for( ; pStr < pEnd; ++pStr )
1180 if( (*pStr >=
'0') && (*pStr <=
'9') )
1184 if( cChar != *pStr )
1187 xTmpStr = OUStringBuffer(rStr);
1189 (*xTmpStr)[pStr - pBase] = cChar;
1194 rStr = (*xTmpStr).makeStringAndClear();
1200 bRightAlign =
false;
1206 bRightAlign ^= bRTLWindow;
1222 const sal_Int32 nMinIndex,
1223 const sal_Int32 nEndIndex )
const
1233 bool bAllLtr =
true;
1234 for (sal_Int32
i = nMinIndex;
i < nEndIndex;
i++)
1239 if (rStr[
i] > 0x052F)
1248 return nLayoutFlags;
1261 OUString originalName = originalFont.
GetStyleName().isEmpty()
1264 std::vector<OUString> usedFontNames;
1273 usedFontNames.push_back(
name );
1277 if( item.mOriginalFont == originalName && item.mUsedFonts == usedFontNames )
1303 sal_Int32 nMinIndex, sal_Int32 nLen,
1304 const Point& rLogicalPos,
tools::Long nLogicalWidth,
1311 if (pGlyphs && !pGlyphs->
IsValid())
1313 SAL_WARN(
"vcl",
"Trying to setup invalid cached glyphs - falling back to relayout!");
1319 for(
int level = 0;; ++level )
1322 if(glyphsImpl ==
nullptr)
1338 if( -1 == nLen || nMinIndex + nLen > rOrigStr.getLength() )
1340 const sal_Int32 nNewLen = rOrigStr.getLength() - nMinIndex;
1346 OUString
aStr = rOrigStr;
1351 pLayoutCache =
nullptr;
1356 if( nLogicalWidth &&
mbMap )
1363 nPixelWidth, flags, pLayoutCache);
1366 std::unique_ptr<double[]> xNaturalDXPixelArray;
1367 if( !pDXArray.
empty() )
1369 xNaturalDXPixelArray.reset(
new double[nLen]);
1376 for (
int i = 0;
i < nLen; ++
i)
1381 for(
int i = 0;
i < nLen; ++
i)
1382 xNaturalDXPixelArray[
i] = pDXArray.
get(
i);
1386 nEndGlyphCoord = std::lround(xNaturalDXPixelArray[nLen - 1]);
1389 if (!pKashidaArray.
empty())
1396 if( pSalLayout && !pSalLayout->LayoutText( aLayoutArgs, pGlyphs ? pGlyphs->
Impl(0) :
nullptr ) )
1404 pSalLayout->SetTextRenderModeForResolutionIndependentLayout(
mbMap);
1417 pSalLayout->AdjustLayout( aLayoutArgs );
1426 pSalLayout->DrawBase() =
DevicePoint(aDevicePos.X(), aDevicePos.Y());
1433 if (!pDXArray.
empty())
1434 nRTLOffset = nEndGlyphCoord;
1435 else if( nPixelWidth )
1436 nRTLOffset = nPixelWidth;
1438 nRTLOffset = pSalLayout->GetTextWidth();
1439 pSalLayout->DrawOffset().setX( 1 - nRTLOffset );
1449 OUString
const& rString)
1456 OUString
aStr( rString );
1462 return (nCharPos !=
nIndex);
1466 sal_Int32 nIndex, sal_Int32 nLen,
1473 sal_Int32 nRetVal = -1;
1481 nTextWidth *= nSubPixelFactor;
1484 if( nCharExtra != 0 )
1486 nCharExtra *= nSubPixelFactor;
1489 nRetVal = pSalLayout->GetTextBreak( nTextPixelWidth, nExtraPixelWidth, nSubPixelFactor );
1497 sal_Int32 nIndex, sal_Int32 nLen,
1506 sal_Int32 nRetVal = -1;
1515 nTextWidth *= nSubPixelFactor;
1518 if( nCharExtra != 0 )
1520 nCharExtra *= nSubPixelFactor;
1525 nRetVal = pSalLayout->GetTextBreak( nTextPixelWidth, nExtraPixelWidth, nSubPixelFactor );
1528 OUString aHyphenStr(nHyphenChar);
1529 std::unique_ptr<SalLayout> pHyphenLayout =
ImplLayout( aHyphenStr, 0, 1 );
1533 tools::Long nHyphenPixelWidth = pHyphenLayout->GetTextWidth() * nSubPixelFactor;
1536 nTextPixelWidth -= nHyphenPixelWidth;
1537 if( nExtraPixelWidth > 0 )
1538 nTextPixelWidth -= nExtraPixelWidth;
1540 rHyphenPos = pSalLayout->GetTextBreak(nTextPixelWidth, nExtraPixelWidth, nSubPixelFactor);
1542 if( rHyphenPos > nRetVal )
1543 rHyphenPos = nRetVal;
1552 std::vector< tools::Rectangle >* pVector, OUString* pDisplayText,
1556 Color aOldTextColor;
1557 Color aOldTextFillColor;
1558 bool bRestoreFillColor =
false;
1561 bool bHighContrastBlack =
false;
1562 bool bHighContrastWhite =
false;
1575 bHighContrastBlack = aCol.
IsDark();
1576 bHighContrastWhite = aCol.
IsBright();
1582 bRestoreFillColor =
true;
1585 if( bHighContrastBlack )
1587 else if( bHighContrastWhite )
1600 if (nWidth <= 0 || nHeight <= 0)
1605 SAL_WARN_IF(bFuzzing,
"vcl",
"skipping negative rectangle of: " << nWidth <<
" x " << nHeight);
1614 sal_Int32 nMnemonicPos = -1;
1616 OUString
aStr = rOrigStr;
1628 sal_Int32 nFormatLines;
1633 sal_Int32 nLines =
static_cast<sal_Int32
>(nHeight/nTextHeight);
1635 nFormatLines = aMultiLineInfo.
Count();
1638 if ( nFormatLines > nLines )
1643 nFormatLines = nLines-1;
1648 OUStringBuffer aLastLineBuffer(aLastLine);
1649 sal_Int32 nLastLineLen = aLastLineBuffer.getLength();
1650 for (
i = 0;
i < nLastLineLen;
i++ )
1652 if ( aLastLineBuffer[
i ] ==
'\n' )
1653 aLastLineBuffer[
i ] =
' ';
1655 aLastLine = aLastLineBuffer.makeStringAndClear();
1663 if ( nMaxTextWidth <= nWidth )
1668 if ( nFormatLines*nTextHeight > nHeight )
1680 aPos.AdjustY(nHeight-(nFormatLines*nTextHeight) );
1682 aPos.AdjustY((nHeight-(nFormatLines*nTextHeight))/2 );
1686 aPos.AdjustY(nTextHeight );
1691 for (
i = 0;
i < nFormatLines;
i++ )
1695 aPos.AdjustX(nWidth-rLineInfo.
GetWidth() );
1697 aPos.AdjustX((nWidth-rLineInfo.
GetWidth())/2 );
1699 sal_Int32 nLineLen = rLineInfo.
GetLen();
1701 if ( bDrawMnemonics )
1703 if ( (nMnemonicPos >=
nIndex) && (nMnemonicPos <
nIndex+nLineLen) )
1709 std::unique_ptr<sal_Int32[]>
const pCaretXArray(
new sal_Int32[2 * nLineLen]);
1712 sal_Int32 lc_x1 = pCaretXArray[2*(nMnemonicPos -
nIndex)];
1713 sal_Int32 lc_x2 = pCaretXArray[2*(nMnemonicPos -
nIndex)+1];
1722 aPos.AdjustY(nTextHeight );
1723 aPos.setX( rRect.
Left() );
1727 if ( !aLastLine.isEmpty() )
1728 _rLayout.
DrawText( aPos, aLastLine, 0, aLastLine.getLength(), pVector, pDisplayText );
1732 rTargetDevice.
Pop();
1740 if ( nTextWidth > nWidth )
1752 if ( nTextHeight <= nHeight )
1758 aPos.AdjustX(nWidth-nTextWidth );
1760 aPos.AdjustX((nWidth-nTextWidth)/2 );
1764 aPos.AdjustY(nTextHeight );
1769 aPos.AdjustY(nHeight-nTextHeight );
1771 aPos.AdjustY((nHeight-nTextHeight)/2 );
1776 if (nMnemonicPos != -1 && nMnemonicPos <
aStr.getLength())
1778 std::unique_ptr<sal_Int32[]>
const pCaretXArray(
new sal_Int32[2 *
aStr.getLength()]);
1781 tools::Long lc_x2 = pCaretXArray[2*nMnemonicPos+1];
1793 _rLayout.
DrawText( aPos,
aStr, 0,
aStr.getLength(), pVector, pDisplayText );
1794 if ( bDrawMnemonics && nMnemonicPos != -1 )
1796 rTargetDevice.
Pop();
1800 _rLayout.
DrawText( aPos,
aStr, 0,
aStr.getLength(), pVector, pDisplayText );
1801 if ( bDrawMnemonics && nMnemonicPos != -1 )
1809 if ( bRestoreFillColor )
1815 const OUString& rOrigStr,
1820 if ( rOrigStr.isEmpty() || rRect.
IsEmpty() )
1841 ImplDrawText( *
this, rRect, rOrigStr, nStyle,
nullptr,
nullptr, aLayout );
1849 std::vector< tools::Rectangle >* pVector, OUString* pDisplayText,
1856 pVector = &
mpOutDevData->mpRecordLayout->m_aUnicodeBoundRects;
1857 pDisplayText = &
mpOutDevData->mpRecordLayout->m_aDisplayText;
1861 if (
mpMetaFile && !bDecomposeTextRectAction )
1879 if ( !bDecomposeTextRectAction )
1885 ImplDrawText( *
this, rRect, rOrigStr, nStyle, pVector, pDisplayText, _pTextLayout ? *_pTextLayout : aDefaultLayout );
1906 OUString
aStr = rStr;
1913 sal_Int32 nFormatLines;
1918 ImplGetTextLines( rRect, nTextHeight, aMultiLineInfo, nWidth,
aStr, nStyle, _pTextLayout ? *_pTextLayout : aDefaultLayout );
1919 nFormatLines = aMultiLineInfo.
Count();
1922 nLines =
static_cast<sal_uInt16
>(aRect.
GetHeight()/nTextHeight);
1927 if ( nFormatLines <= nLines )
1928 nLines = nFormatLines;
1932 nLines = nFormatLines;
1942 bool bMaxWidth = nMaxWidth == 0;
1944 for (
i = 0;
i < nLines;
i++ )
1947 if ( bMaxWidth && (rLineInfo.
GetWidth() > nMaxWidth) )
1953 else if ( !nMaxWidth )
1955 for (
i = 0;
i < nLines;
i++ )
1958 if ( rLineInfo.
GetWidth() > nMaxWidth )
2040 OUString
aStr = rOrigStr;
2047 OUStringBuffer aTmpStr(
aStr );
2049 sal_Int32 nEraseChars = std::max<sal_Int32>(4,
aStr.getLength() - (
nIndex*4)/3);
2050 while( nEraseChars <
aStr.getLength() && _rLayout.
GetTextWidth( aTmpStr.toString(), 0, aTmpStr.getLength() ) > nMaxWidth )
2053 sal_Int32
i = (aTmpStr.getLength() - nEraseChars)/2;
2054 aTmpStr.remove(
i, nEraseChars++);
2055 aTmpStr.insert(
i,
"...");
2057 aStr = aTmpStr.makeStringAndClear();
2074 aStr += OUStringChar(rOrigStr[ 0 ]);
2078 OUString aPath( rOrigStr );
2079 OUString aAbbreviatedPath;
2080 osl_abbreviateSystemPath( aPath.pData, &aAbbreviatedPath.pData,
nIndex,
nullptr );
2081 aStr = aAbbreviatedPath;
2085 static char const pSepChars[] =
".";
2087 sal_Int32 nLastContent =
aStr.getLength();
2088 while ( nLastContent )
2094 while ( nLastContent &&
2098 OUString aLastStr =
aStr.copy(nLastContent);
2099 OUString aTempLastStr1 =
"..." + aLastStr;
2100 if ( _rLayout.
GetTextWidth( aTempLastStr1, 0, aTempLastStr1.getLength() ) > nMaxWidth )
2104 sal_Int32 nFirstContent = 0;
2105 while ( nFirstContent < nLastContent )
2111 while ( (nFirstContent < nLastContent) &&
2115 if ( nFirstContent >= nLastContent )
2119 if ( nFirstContent > 4 )
2121 OUString aFirstStr = OUString::Concat(
aStr.subView( 0, nFirstContent )) +
"...";
2122 OUString aTempStr = aFirstStr + aLastStr;
2123 if ( _rLayout.
GetTextWidth( aTempStr, 0, aTempStr.getLength() ) > nMaxWidth )
2130 if( nLastContent >
aStr.getLength() )
2131 nLastContent =
aStr.getLength();
2132 while ( nFirstContent < nLastContent )
2139 while ( (nFirstContent < nLastContent) &&
2143 if ( nFirstContent < nLastContent )
2145 std::u16string_view aTempLastStr =
aStr.subView( nLastContent );
2146 aTempStr = aFirstStr + aTempLastStr;
2148 if ( _rLayout.
GetTextWidth( aTempStr, 0, aTempStr.getLength() ) > nMaxWidth )
2152 while ( nFirstContent < nLastContent );
2163 sal_Int32 nIndex, sal_Int32 nLen,
2164 DrawTextFlags nStyle, std::vector< tools::Rectangle >* pVector, OUString* pDisplayText,
2169 if( (nLen < 0) || (
nIndex + nLen >= rStr.getLength()))
2171 nLen = rStr.getLength() -
nIndex;
2187 if(
nIndex >= rStr.getLength() )
2190 if( (nLen < 0) || (
nIndex + nLen >= rStr.getLength()))
2192 nLen = rStr.getLength() -
nIndex;
2194 OUString
aStr = rStr;
2195 sal_Int32 nMnemonicPos = -1;
2203 if ( nMnemonicPos != -1 )
2205 if( nMnemonicPos <
nIndex )
2211 if( nMnemonicPos < (
nIndex+nLen) )
2213 SAL_WARN_IF( nMnemonicPos >= (
nIndex+nLen),
"vcl",
"Mnemonic underline marker after last character" );
2215 bool bInvalidPos =
false;
2217 if( nMnemonicPos >= nLen )
2223 nMnemonicPos = nLen-1;
2226 std::unique_ptr<sal_Int32[]>
const pCaretXArray(
new sal_Int32[2 * nLen]);
2228 sal_Int32 lc_x1 = pCaretXArray[ 2*(nMnemonicPos -
nIndex) ];
2229 sal_Int32 lc_x2 = pCaretXArray[ 2*(nMnemonicPos -
nIndex)+1 ];
2230 nMnemonicWidth = ::abs(
static_cast<int>(lc_x1 - lc_x2));
2247 Color aOldTextColor;
2248 Color aOldTextFillColor;
2249 bool bRestoreFillColor;
2250 bool bHighContrastBlack =
false;
2251 bool bHighContrastWhite =
false;
2259 bHighContrastBlack = aCol.
IsDark();
2260 bHighContrastWhite = aCol.
IsBright();
2267 bRestoreFillColor =
true;
2271 bRestoreFillColor =
false;
2273 if( bHighContrastBlack )
2275 else if( bHighContrastWhite )
2284 if ( nMnemonicPos != -1 )
2288 if ( bRestoreFillColor )
2297 if ( nMnemonicPos != -1 )
2308 sal_Int32 nLen = rStr.getLength();
2311 sal_Int32 nMnemonicPos;
2313 if ( nMnemonicPos != -1 )
2315 if ( nMnemonicPos <
nIndex )
2324 const OUString& rStr, sal_Int32 nBase,
2325 sal_Int32 nIndex, sal_Int32 nLen,
2333 std::unique_ptr<SalLayout> pSalLayout;
2339 sal_Int32 nStart = std::min( nBase,
nIndex );
2340 sal_Int32 nOfsLen = std::max( nBase,
nIndex ) - nStart;
2341 pSalLayout =
ImplLayout( rStr, nStart, nOfsLen, aPoint, nLayoutWidth, pDXAry, pKashidaAry );
2344 nXOffset = pSalLayout->GetTextWidth();
2347 nXOffset = -nXOffset;
2356 bRet = pSalLayout->GetBoundRect(aPixelRect);
2363 aPixelRect += aRotatedOfs;
2374 const OUString& rStr, sal_Int32 nBase,
2375 sal_Int32 nIndex, sal_Int32 nLen,
2387 nLen = rStr.getLength() -
nIndex;
2389 rVector.reserve( nLen );
2393 bool bOldMap =
mbMap;
2400 std::unique_ptr<SalLayout> pSalLayout;
2406 sal_Int32 nStart = std::min( nBase,
nIndex );
2407 sal_Int32 nOfsLen = std::max( nBase,
nIndex ) - nStart;
2408 pSalLayout =
ImplLayout( rStr, nStart, nOfsLen,
Point(0,0), nLayoutWidth, pDXArray, pKashidaArray);
2411 nXOffset = pSalLayout->GetTextWidth();
2415 nXOffset = -nXOffset;
2422 bRet = pSalLayout->GetOutline(rVector);
2431 aRotatedOfs -= pSalLayout->GetDrawPosition(
DevicePoint(nXOffset, 0));
2437 for (
auto & elem : rVector)
2438 elem.transform( aMatrix );
2456 const OUString& rStr, sal_Int32 nBase,
2457 sal_Int32 nIndex, sal_Int32 nLen,
2461 rResultVector.clear();
2466 nLayoutWidth, pDXArray, pKashidaArray ) )
2470 rResultVector.reserve( aB2DPolyPolyVector.size() );
2471 for (
auto const& elem : aB2DPolyPolyVector)
2472 rResultVector.emplace_back(elem);
2488 for (
auto const& elem : aB2DPolyPolyVector)
2489 for(
auto const& rB2DPolygon : elem)
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
bool Rotate(Degree10 nAngle10, const Color &rFillColor)
Rotate bitmap by the specified angle.
const OUString & GetFamilyName() const
const OUString & GetStyleName() const
tools::Long GetAscent() const
void AddLine(const ImplTextLineInfo &)
std::vector< ImplTextLineInfo > mvLines
const ImplTextLineInfo & GetLine(sal_Int32 nLine) const
sal_Int32 GetIndex() const
tools::Long GetWidth() const
sal_Int32 get(size_t nIndex) const
sal_Int32 get_subunit(size_t nIndex) const
std::vector< sal_Int32 > & get_subunit_array()
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
tools::Long mnEmphasisAscent
bool ImplDrawRotateText(SalLayout &)
virtual void InitClipRegion()
void ImplDrawTextLines(SalLayout &, FontStrikeout eStrikeout, FontLineStyle eUnderline, FontLineStyle eOverline, bool bWordLine, bool bUnderlineAbove)
tools::Long GetCtrlTextWidth(const OUString &rStr, const SalLayoutGlyphs *pLayoutCache=nullptr) const
float approximate_digit_width() const
std::vector< FontMappingUseItem > FontMappingUseData
bool GetGlyphBoundRects(const Point &rOrigin, const OUString &rStr, int nIndex, int nLen, std::vector< tools::Rectangle > &rVector) const
SAL_DLLPRIVATE std::unique_ptr< SalLayout > ImplGlyphFallbackLayout(std::unique_ptr< SalLayout >, vcl::text::ImplLayoutArgs &, const SalLayoutGlyphs *) const
static FontMappingUseData FinishTrackingFontMappingUse()
void EnableMapMode(bool bEnable=true)
void DrawCtrlText(const Point &rPos, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, DrawTextFlags nStyle=DrawTextFlags::Mnemonic, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr)
tools::Long GetOutOffYPixel() const
const vcl::Font & GetFont() const
sal_Int32 GetTextBreak(const OUString &rStr, tools::Long nTextWidth, sal_Int32 nIndex, sal_Int32 nLen=-1, tools::Long nCharExtra=0, vcl::text::TextLayoutCache const *=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
SAL_DLLPRIVATE bool is_double_buffered_window() const
void DrawTextArray(const Point &rStartPt, const OUString &rStr, KernArraySpan aKernArray, o3tl::span< const sal_Bool > pKashidaAry, sal_Int32 nIndex, sal_Int32 nLen, SalLayoutFlags flags=SalLayoutFlags::NONE, const SalLayoutGlyphs *pLayoutCache=nullptr)
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames)
void EnableOutput(bool bEnable=true)
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicHeight(tools::Long nHeight) const
Convert device pixels to a height in logical units.
void SetFont(const vcl::Font &rNewFont)
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
bool GetTextOutline(tools::PolyPolygon &, const OUString &rStr) const
SAL_DLLPRIVATE void ImplDrawPolygon(const tools::Polygon &rPoly, const tools::PolyPolygon *pClipPolyPoly=nullptr)
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames)
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
std::unique_ptr< ImplOutDevData > mpOutDevData
const Wallpaper & GetBackground() const
virtual void SetSystemTextColor(SystemTextColorFlags nFlags, bool bEnabled)
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, KernArraySpan aDXArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}, const SalLayoutGlyphs *pGlyphs=nullptr) const
Return the exact bounding rectangle of rStr.
static SAL_DLLPRIVATE sal_Int32 ImplBreakLinesSimple(const tools::Long nWidth, const OUString &rStr, const vcl::ITextLayout &_rLayout, const sal_Int32 nPos, sal_Int32 nBreakPos, tools::Long &nLineWidth)
vcl::text::ComplexTextLayoutFlags mnTextLayoutMode
OUString GetEllipsisString(const OUString &rStr, tools::Long nMaxWidth, DrawTextFlags nStyle=DrawTextFlags::EndEllipsis) const
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
const Color & GetOverlineColor() const
tools::Long mnEmphasisDescent
SAL_DLLPRIVATE SalLayoutFlags GetBiDiLayoutFlags(std::u16string_view rStr, const sal_Int32 nMinIndex, const sal_Int32 nEndIndex) const
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
Width of the text.
SalGraphics * mpGraphics
Graphics context to draw on.
void AddTextRectActions(const tools::Rectangle &rRect, const OUString &rOrigStr, DrawTextFlags nStyle, GDIMetaFile &rMtf)
Generate MetaTextActions for the text rect.
void SetTextColor(const Color &rColor)
static SAL_DLLPRIVATE sal_Int32 ImplBreakLinesWithIterator(const tools::Long nWidth, const OUString &rStr, const vcl::ITextLayout &_rLayout, const css::uno::Reference< css::linguistic2::XHyphenator > &xHyph, const css::uno::Reference< css::i18n::XBreakIterator > &xBI, const bool bHyphenate, const sal_Int32 nPos, sal_Int32 nBreakPos)
void DrawMask(const Point &rDestPt, const Bitmap &rBitmap, const Color &rMaskColor)
tools::Rectangle ImplGetTextBoundRect(const SalLayout &) const
tools::Long GetTextArray(const OUString &rStr, KernArray *pDXAry, sal_Int32 nIndex=0, sal_Int32 nLen=-1, bool bCaret=false, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
rtl::Reference< LogicalFontInstance > mpFontInstance
static SAL_DLLPRIVATE OUString ImplGetEllipsisString(const OutputDevice &rTargetDevice, const OUString &rStr, tools::Long nMaxWidth, DrawTextFlags nStyle, const vcl::ITextLayout &_rLayout)
SAL_DLLPRIVATE void ImplDrawEmphasisMarks(SalLayout &)
LanguageType meTextLanguage
SAL_DLLPRIVATE double ImplLogicWidthToDeviceSubPixel(tools::Long nWidth) const
bool IsRTLEnabled() const
void SetDigitLanguage(LanguageType)
SAL_DLLPRIVATE float approximate_char_width() const
SAL_DLLPRIVATE DeviceCoordinate LogicWidthToDeviceCoordinate(tools::Long nWidth) const
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
tools::Rectangle GetTextRect(const tools::Rectangle &rRect, const OUString &rStr, DrawTextFlags nStyle=DrawTextFlags::WordBreak, TextRectInfo *pInfo=nullptr, const vcl::ITextLayout *_pTextLayout=nullptr) const
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicWidth(tools::Long nWidth) const
Convert device pixels to a width in logical units.
TextAlign GetTextAlign() const
bool IsTextFillColor() const
SAL_DLLPRIVATE void ImplDrawSpecialText(SalLayout &)
FontMetric GetFontMetric() const
virtual bool HasMirroredGraphics() const
SAL_DLLPRIVATE DevicePoint ImplLogicToDeviceSubPixel(const Point &rLogicPt) const
static SAL_DLLPRIVATE tools::Long ImplGetTextLines(const tools::Rectangle &rRect, tools::Long nTextHeight, ImplMultiTextLineInfo &rLineInfo, tools::Long nWidth, const OUString &rStr, DrawTextFlags nStyle, const vcl::ITextLayout &_rLayout)
virtual Bitmap GetBitmap(const Point &rSrcPt, const Size &rSize) const
bool IsDeviceOutputNecessary() const
VclPtr< VirtualDevice > mpAlphaVDev
static void StartTrackingFontMappingUse()
const Color & GetTextColor() const
void ImplDrawTextBackground(const SalLayout &)
virtual vcl::Region GetOutputBoundsClipRegion() const
static void ImplDrawText(OutputDevice &rTargetDevice, const tools::Rectangle &rRect, const OUString &rOrigStr, DrawTextFlags nStyle, std::vector< tools::Rectangle > *pVector, OUString *pDisplayText, vcl::ITextLayout &_rLayout)
bool IsBackground() const
void GetCaretPositions(const OUString &, sal_Int32 *pCaretXArray, sal_Int32 nIndex, sal_Int32 nLen, const SalLayoutGlyphs *pGlyphs=nullptr) const
bool GetTextIsRTL(const OUString &, sal_Int32 nIndex, sal_Int32 nLen) const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
SAL_DLLPRIVATE vcl::text::ImplLayoutArgs ImplPrepareLayoutArgs(OUString &, const sal_Int32 nIndex, const sal_Int32 nLen, DeviceCoordinate nPixelWidth, SalLayoutFlags flags=SalLayoutFlags::NONE, vcl::text::TextLayoutCache const *=nullptr) const
SAL_DLLPRIVATE void ImplInitTextColor()
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
bool IsOutputEnabled() const
std::unique_ptr< SalLayout > ImplLayout(const OUString &, sal_Int32 nIndex, sal_Int32 nLen, const Point &rLogicPos=Point(0, 0), tools::Long nLogicWidth=0, KernArraySpan aKernArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}, SalLayoutFlags flags=SalLayoutFlags::NONE, vcl::text::TextLayoutCache const *=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
tools::Long mnTextOffX
font specific text alignment offsets in pixel units
SAL_DLLPRIVATE void ImplDrawTextRect(tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight)
Color GetTextFillColor() const
SAL_DLLPRIVATE void ImplDrawTextDirect(SalLayout &, bool bTextLines)
tools::Long GetOutOffXPixel() const
bool GetTextOutlines(PolyPolyVector &, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, KernArraySpan aDXArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}) const
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
void SetLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode)
const AllSettings & GetSettings() const
static std::shared_ptr< const vcl::text::TextLayoutCache > CreateTextLayoutCache(OUString const &)
void IntersectClipRegion(const tools::Rectangle &rRect)
SAL_DLLPRIVATE void ImplDrawMnemonicLine(tools::Long nX, tools::Long nY, tools::Long nWidth)
const Color & GetTextLineColor() const
SAL_DLLPRIVATE bool InitFont() const
void DrawStretchText(const Point &rStartPt, sal_Int32 nWidth, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1)
virtual bool IsVirtual() const
const OutDevType meOutDevType
virtual void SetTextColor(Color nColor)=0
virtual void SetLineColor()=0
virtual void SetFillColor()=0
virtual tools::Long GetGraphicsWidth() const =0
void DrawRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice &rOutDev)
virtual std::unique_ptr< GenericSalLayout > GetTextLayout(int nFallbackLevel)=0
SalLayoutFlags GetFlags() const
SalLayoutGlyphsImpl * Impl(unsigned int nLevel) const
bool GetBoundRect(tools::Rectangle &) const
DevicePoint GetDrawPosition(const DevicePoint &rRelative=DevicePoint(0, 0)) const
virtual DeviceCoordinate GetTextWidth() const
virtual void DrawText(SalGraphics &) const =0
virtual SalLayoutGlyphs GetGlyphs() const
bool GetHighContrastMode() const
StyleSettingsOptions GetOptions() const
const Color & GetFaceColor() const
const Color & GetDisableColor() const
static VclPtr< reference_type > Create(Arg &&... arg)
A construction helper for VclPtr.
bool SetOutputSizePixel(const Size &rNewSize, bool bErase=true)
const Color & GetColor() const
void translate(double fX, double fY)
constexpr pointer data() const noexcept
constexpr bool empty() const noexcept
is an implementation of the ITextLayout interface which simply delegates its calls to the respective ...
FontKerning GetKerning() const
void SetFontSize(const Size &)
void SetOrientation(Degree10 nLineOrientation)
const LanguageTag & GetLanguageTag() const
const OUString & GetStyleName() const
FontStrikeout GetStrikeout() const
FontLineStyle GetOverline() const
FontRelief GetRelief() const
FontEmphasisMark GetEmphasisMark() const
const OUString & GetFamilyName() const
bool IsUnderlineAbove() const
FontLineStyle GetUnderline() const
bool IsFixKerning() const
bool IsWordLineMode() const
Degree10 GetOrientation() const
virtual bool DecomposeTextRectAction() const =0
virtual void DrawText(const Point &_rStartPoint, const OUString &_rText, sal_Int32 _nStartIndex, sal_Int32 _nLength, std::vector< tools::Rectangle > *_pVector, OUString *_pDisplayText)=0
virtual tools::Long GetTextWidth(const OUString &_rText, sal_Int32 _nStartIndex, sal_Int32 _nLength) const =0
virtual sal_Int32 GetTextBreak(const OUString &_rText, tools::Long _nMaxTextWidth, sal_Int32 _nStartIndex, sal_Int32 _nLength) const =0
virtual void GetCaretPositions(const OUString &_rText, sal_Int32 *_pCaretXArray, sal_Int32 _nStartIndex, sal_Int32 _nLength) const =0
void Intersect(const tools::Rectangle &rRegion)
bool Overlaps(const tools::Rectangle &rRect) const
abstract base class for physical font faces
bool GetNextPos(int *nCharPos, bool *bRTL)
void SetOrientation(Degree10 nOrientation)
void SetKashidaArray(const sal_Bool *pKashidaArray)
void SetLayoutWidth(DeviceCoordinate nWidth)
void SetNaturalDXArray(const double *pDXArray)
bool HasFallbackRun() const
static std::shared_ptr< const vcl::text::TextLayoutCache > Create(OUString const &)
constexpr ::Color COL_GREEN(0x00, 0x80, 0x00)
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
constexpr ::Color COL_LIGHTGREEN(0x00, 0xFF, 0x00)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
#define DBG_TESTSOLARMUTEX()
sal_Int32 DeviceCoordinate
basegfx::B2DPoint DevicePoint
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
::std::vector< B2DPolyPolygon > B2DPolyPolygonVector
B2IRange fround(const B2DRange &rRange)
const LanguageTag & getLocale()
Reference< XComponentContext > getProcessComponentContext()
VCL_DLLPUBLIC css::uno::Reference< css::i18n::XBreakIterator > CreateBreakIterator()
std::vector< tools::PolyPolygon > PolyPolyVector
sal_UCS4 GetLocalizedChar(sal_UCS4 nChar, LanguageType eLang)
tools::Long mnMapOfsY
Offset in Y direction.
tools::Long mnMapOfsX
Offset in X direction.
ImplSVData * ImplGetSVData()
OUString removeMnemonicFromString(OUString const &rStr)
static OutputDevice::FontMappingUseData * fontMappingUseData
#define TEXT_DRAW_ELLIPSIS
static bool ImplIsCharIn(sal_Unicode c, const char *pStr)
static void TrackFontMappingUse(const vcl::Font &originalFont, const SalLayout *salLayout)
static bool IsTrackingFontMappingUse()
const SalLayoutFlags eDefaultLayout