Add support for ETO_PDY in WMF/EMF
Currently it is implemented by making all characters different text arrays. Unit test included. Change-Id: I850bf192cf5d978a126d3f37b1084021d37bdf30 Reviewed-on: https://gerrit.libreoffice.org/32490 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
@@ -421,6 +421,8 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
|
|||||||
rWriter.attribute("index", aIndex);
|
rWriter.attribute("index", aIndex);
|
||||||
rWriter.attribute("length", aLength);
|
rWriter.attribute("length", aLength);
|
||||||
|
|
||||||
|
if (pMetaTextArrayAction->GetDXArray())
|
||||||
|
{
|
||||||
rWriter.startElement("dxarray");
|
rWriter.startElement("dxarray");
|
||||||
OUString sDxLengthString;
|
OUString sDxLengthString;
|
||||||
for (sal_Int32 i = 0; i < aLength; ++i)
|
for (sal_Int32 i = 0; i < aLength; ++i)
|
||||||
@@ -430,6 +432,7 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
|
|||||||
}
|
}
|
||||||
rWriter.content(sDxLengthString);
|
rWriter.content(sDxLengthString);
|
||||||
rWriter.endElement();
|
rWriter.endElement();
|
||||||
|
}
|
||||||
|
|
||||||
rWriter.startElement("text");
|
rWriter.startElement("text");
|
||||||
rWriter.content(pMetaTextArrayAction->GetText());
|
rWriter.content(pMetaTextArrayAction->GetText());
|
||||||
|
BIN
vcl/qa/cppunit/wmf/data/ETO_PDY.emf
Normal file
BIN
vcl/qa/cppunit/wmf/data/ETO_PDY.emf
Normal file
Binary file not shown.
BIN
vcl/qa/cppunit/wmf/data/ETO_PDY.wmf
Normal file
BIN
vcl/qa/cppunit/wmf/data/ETO_PDY.wmf
Normal file
Binary file not shown.
@@ -60,6 +60,7 @@ public:
|
|||||||
void testTdf93750();
|
void testTdf93750();
|
||||||
void testTdf99402();
|
void testTdf99402();
|
||||||
void testTdf39894();
|
void testTdf39894();
|
||||||
|
void testETO_PDY();
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(WmfTest);
|
CPPUNIT_TEST_SUITE(WmfTest);
|
||||||
CPPUNIT_TEST(globalSetUp);
|
CPPUNIT_TEST(globalSetUp);
|
||||||
@@ -71,6 +72,7 @@ public:
|
|||||||
CPPUNIT_TEST(testTdf93750);
|
CPPUNIT_TEST(testTdf93750);
|
||||||
CPPUNIT_TEST(testTdf99402);
|
CPPUNIT_TEST(testTdf99402);
|
||||||
CPPUNIT_TEST(testTdf39894);
|
CPPUNIT_TEST(testTdf39894);
|
||||||
|
CPPUNIT_TEST(testETO_PDY);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -289,6 +291,30 @@ void WmfTest::testTdf39894()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WmfTest::testETO_PDY()
|
||||||
|
{
|
||||||
|
OUString files[] = { "ETO_PDY.wmf", "ETO_PDY.emf" };
|
||||||
|
for (const auto& file: files)
|
||||||
|
{
|
||||||
|
SvFileStream aFileStream(getFullUrl(file), StreamMode::READ);
|
||||||
|
GDIMetaFile aGDIMetaFile;
|
||||||
|
ReadWindowMetafile(aFileStream, aGDIMetaFile);
|
||||||
|
|
||||||
|
MetafileXmlDump dumper;
|
||||||
|
xmlDocPtr pDoc = dumper.dumpAndParse(aGDIMetaFile);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(pDoc);
|
||||||
|
|
||||||
|
// The y position of following text
|
||||||
|
// must be smaller than that of previous
|
||||||
|
auto y1 = getXPath(pDoc, "/metafile/push[2]/textarray[1]", "y");
|
||||||
|
auto y2 = getXPath(pDoc, "/metafile/push[2]/textarray[2]", "y");
|
||||||
|
auto y3 = getXPath(pDoc, "/metafile/push[2]/textarray[3]", "y");
|
||||||
|
CPPUNIT_ASSERT_MESSAGE(file.toUtf8().getStr(), y2.toInt32() < y1.toInt32());
|
||||||
|
CPPUNIT_ASSERT_MESSAGE(file.toUtf8().getStr(), y3.toInt32() < y2.toInt32());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(WmfTest);
|
CPPUNIT_TEST_SUITE_REGISTRATION(WmfTest);
|
||||||
|
|
||||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||||
|
@@ -1547,7 +1547,6 @@ bool EnhWMFReader::ReadEnhWMF()
|
|||||||
sal_Int32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale;
|
sal_Int32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale;
|
||||||
sal_uInt32 nOffString, nOptions, offDx;
|
sal_uInt32 nOffString, nOptions, offDx;
|
||||||
sal_Int32 nLen;
|
sal_Int32 nLen;
|
||||||
std::vector<long> aDX;
|
|
||||||
|
|
||||||
nCurPos = pWMF->Tell() - 8;
|
nCurPos = pWMF->Tell() - 8;
|
||||||
|
|
||||||
@@ -1568,23 +1567,6 @@ bool EnhWMFReader::ReadEnhWMF()
|
|||||||
bool bOffStringSane = nOffString <= nEndPos - nCurPos;
|
bool bOffStringSane = nOffString <= nEndPos - nCurPos;
|
||||||
if (bLenSane && bOffStringSane)
|
if (bLenSane && bOffStringSane)
|
||||||
{
|
{
|
||||||
sal_Int32 nDxSize = nLen * ((nOptions & ETO_PDY) ? 8 : 4);
|
|
||||||
if ( offDx && (( nCurPos + offDx + nDxSize ) <= nNextPos ) && nNextPos <= nEndPos )
|
|
||||||
{
|
|
||||||
pWMF->Seek( nCurPos + offDx );
|
|
||||||
aDX.resize(nLen);
|
|
||||||
for (sal_Int32 i = 0; i < nLen; ++i)
|
|
||||||
{
|
|
||||||
sal_Int32 val(0);
|
|
||||||
pWMF->ReadInt32(val);
|
|
||||||
aDX[i] = val;
|
|
||||||
if (nOptions & ETO_PDY)
|
|
||||||
{
|
|
||||||
pWMF->ReadInt32(val);
|
|
||||||
// TODO: Use Dy value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pWMF->Seek( nCurPos + nOffString );
|
pWMF->Seek( nCurPos + nOffString );
|
||||||
OUString aText;
|
OUString aText;
|
||||||
if ( bFlag )
|
if ( bFlag )
|
||||||
@@ -1594,22 +1576,6 @@ bool EnhWMFReader::ReadEnhWMF()
|
|||||||
std::unique_ptr<sal_Char[]> pBuf(new sal_Char[ nLen ]);
|
std::unique_ptr<sal_Char[]> pBuf(new sal_Char[ nLen ]);
|
||||||
pWMF->ReadBytes(pBuf.get(), nLen);
|
pWMF->ReadBytes(pBuf.get(), nLen);
|
||||||
aText = OUString(pBuf.get(), nLen, pOut->GetCharSet());
|
aText = OUString(pBuf.get(), nLen, pOut->GetCharSet());
|
||||||
pBuf.reset();
|
|
||||||
|
|
||||||
if ( aText.getLength() != nLen )
|
|
||||||
{
|
|
||||||
std::vector<long> aOldDX(aText.getLength());
|
|
||||||
aOldDX.swap(aDX);
|
|
||||||
sal_Int32 nDXLen = std::min<sal_Int32>(nLen, aOldDX.size());
|
|
||||||
for (sal_Int32 i = 0, j = 0; i < aText.getLength(); ++i)
|
|
||||||
{
|
|
||||||
sal_Unicode cUniChar = aText[i];
|
|
||||||
OString aCharacter(&cUniChar, 1, pOut->GetCharSet());
|
|
||||||
aDX[i] = 0;
|
|
||||||
for (sal_Int32 k = 0; ( k < aCharacter.getLength() ) && ( j < nDXLen ) && ( i < aText.getLength() ); ++k)
|
|
||||||
aDX[ i ] += aOldDX[j++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1630,7 +1596,53 @@ bool EnhWMFReader::ReadEnhWMF()
|
|||||||
aText = OUString(pBuf.get(), nLen);
|
aText = OUString(pBuf.get(), nLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pOut->DrawText(aPos, aText, aDX.data(), bRecordPath, nGfxMode);
|
|
||||||
|
std::unique_ptr<long[]> pDXAry, pDYAry;
|
||||||
|
sal_Int32 nDxSize = nLen * ((nOptions & ETO_PDY) ? 8 : 4);
|
||||||
|
if ( offDx && (( nCurPos + offDx + nDxSize ) <= nNextPos ) && nNextPos <= nEndPos )
|
||||||
|
{
|
||||||
|
pWMF->Seek( nCurPos + offDx );
|
||||||
|
pDXAry.reset( new long[aText.getLength()] );
|
||||||
|
if (nOptions & ETO_PDY)
|
||||||
|
{
|
||||||
|
pDYAry.reset( new long[aText.getLength()] );
|
||||||
|
}
|
||||||
|
|
||||||
|
for (sal_Int32 i = 0; i < aText.getLength(); ++i)
|
||||||
|
{
|
||||||
|
sal_Int32 nDxCount = 1;
|
||||||
|
if (aText.getLength() != nLen)
|
||||||
|
{
|
||||||
|
sal_Unicode cUniChar = aText[i];
|
||||||
|
OString aTmp(&cUniChar, 1, pOut->GetCharSet());
|
||||||
|
if (aTmp.getLength() > 1)
|
||||||
|
{
|
||||||
|
nDxCount = aTmp.getLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sal_Int32 nDx = 0, nDy = 0;
|
||||||
|
while (nDxCount--)
|
||||||
|
{
|
||||||
|
sal_Int32 nDxTmp = 0;
|
||||||
|
pWMF->ReadInt32(nDxTmp);
|
||||||
|
nDx += nDxTmp;
|
||||||
|
if (nOptions & ETO_PDY)
|
||||||
|
{
|
||||||
|
sal_Int32 nDyTmp = 0;
|
||||||
|
pWMF->ReadInt32(nDyTmp);
|
||||||
|
nDy += nDyTmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pDXAry[i] = nDx;
|
||||||
|
if (nOptions & ETO_PDY)
|
||||||
|
{
|
||||||
|
pDYAry[i] = nDy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pOut->DrawText(aPos, aText, pDXAry.get(), pDYAry.get(), bRecordPath, nGfxMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -1348,7 +1348,7 @@ void WinMtfOutput::DrawPolyBezier( tools::Polygon& rPolygon, bool bTo, bool bRec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, bool bRecordPath, sal_Int32 nGfxMode )
|
void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, long* pDYArry, bool bRecordPath, sal_Int32 nGfxMode )
|
||||||
{
|
{
|
||||||
UpdateClipRegion();
|
UpdateClipRegion();
|
||||||
rPosition = ImplMap( rPosition );
|
rPosition = ImplMap( rPosition );
|
||||||
@@ -1357,18 +1357,25 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b
|
|||||||
|
|
||||||
if (pDXArry)
|
if (pDXArry)
|
||||||
{
|
{
|
||||||
sal_Int32 i;
|
sal_Int32 nSumX = 0, nSumY = 0;
|
||||||
sal_Int32 nSum = 0;
|
for (sal_Int32 i = 0; i < rText.getLength(); i++ )
|
||||||
sal_Int32 nLen = rText.getLength();
|
|
||||||
|
|
||||||
for (i = 0; i < nLen; i++ )
|
|
||||||
{
|
{
|
||||||
nSum += pDXArry[i];
|
nSumX += pDXArry[i];
|
||||||
|
|
||||||
// #i121382# Map DXArray using WorldTransform
|
// #i121382# Map DXArray using WorldTransform
|
||||||
const Size aSize(ImplMap(Size(nSum, 0)));
|
const Size aSizeX(ImplMap(Size(nSumX, 0)));
|
||||||
const basegfx::B2DVector aVector(aSize.Width(), aSize.Height());
|
const basegfx::B2DVector aVectorX(aSizeX.Width(), aSizeX.Height());
|
||||||
pDXArry[i] = basegfx::fround(aVector.getLength());
|
pDXArry[i] = basegfx::fround(aVectorX.getLength()) * (nSumX >= 0 ? 1 : -1);
|
||||||
|
|
||||||
|
if (pDYArry)
|
||||||
|
{
|
||||||
|
nSumY += pDYArry[i];
|
||||||
|
|
||||||
|
const Size aSizeY(ImplMap(Size(0, nSumY)));
|
||||||
|
const basegfx::B2DVector aVectorY(aSizeY.Width(), aSizeY.Height());
|
||||||
|
// Reverse Y
|
||||||
|
pDYArry[i] = basegfx::fround(aVectorY.getLength()) * (nSumY >= 0 ? -1 : 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( mnLatestTextLayoutMode != mnTextLayoutMode )
|
if ( mnLatestTextLayoutMode != mnTextLayoutMode )
|
||||||
@@ -1377,11 +1384,6 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b
|
|||||||
mpGDIMetaFile->AddAction( new MetaLayoutModeAction( mnTextLayoutMode ) );
|
mpGDIMetaFile->AddAction( new MetaLayoutModeAction( mnTextLayoutMode ) );
|
||||||
}
|
}
|
||||||
SetGfxMode( nGfxMode );
|
SetGfxMode( nGfxMode );
|
||||||
bool bChangeFont = false;
|
|
||||||
if ( mnLatestTextAlign != mnTextAlign )
|
|
||||||
{
|
|
||||||
bChangeFont = true;
|
|
||||||
mnLatestTextAlign = mnTextAlign;
|
|
||||||
TextAlign eTextAlign;
|
TextAlign eTextAlign;
|
||||||
if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
|
if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
|
||||||
eTextAlign = ALIGN_BASELINE;
|
eTextAlign = ALIGN_BASELINE;
|
||||||
@@ -1389,6 +1391,11 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b
|
|||||||
eTextAlign = ALIGN_BOTTOM;
|
eTextAlign = ALIGN_BOTTOM;
|
||||||
else
|
else
|
||||||
eTextAlign = ALIGN_TOP;
|
eTextAlign = ALIGN_TOP;
|
||||||
|
bool bChangeFont = false;
|
||||||
|
if ( mnLatestTextAlign != mnTextAlign )
|
||||||
|
{
|
||||||
|
bChangeFont = true;
|
||||||
|
mnLatestTextAlign = mnTextAlign;
|
||||||
mpGDIMetaFile->AddAction( new MetaTextAlignAction( eTextAlign ) );
|
mpGDIMetaFile->AddAction( new MetaTextAlignAction( eTextAlign ) );
|
||||||
}
|
}
|
||||||
if ( maLatestTextColor != maTextColor )
|
if ( maLatestTextColor != maTextColor )
|
||||||
@@ -1422,12 +1429,7 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b
|
|||||||
else
|
else
|
||||||
aTmp.SetTransparent( false );
|
aTmp.SetTransparent( false );
|
||||||
|
|
||||||
if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
|
aTmp.SetAlignment( eTextAlign );
|
||||||
aTmp.SetAlignment( ALIGN_BASELINE );
|
|
||||||
else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
|
|
||||||
aTmp.SetAlignment( ALIGN_BOTTOM );
|
|
||||||
else
|
|
||||||
aTmp.SetAlignment( ALIGN_TOP );
|
|
||||||
|
|
||||||
if ( nGfxMode == GM_ADVANCED )
|
if ( nGfxMode == GM_ADVANCED )
|
||||||
{
|
{
|
||||||
@@ -1455,7 +1457,8 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b
|
|||||||
// #i117968# VirtualDevice is not thread safe, but filter is used in multithreading
|
// #i117968# VirtualDevice is not thread safe, but filter is used in multithreading
|
||||||
SolarMutexGuard aGuard;
|
SolarMutexGuard aGuard;
|
||||||
ScopedVclPtrInstance< VirtualDevice > pVDev;
|
ScopedVclPtrInstance< VirtualDevice > pVDev;
|
||||||
sal_Int32 nTextWidth, nActPosDeltaX = 0;
|
sal_Int32 nTextWidth;
|
||||||
|
Point aActPosDelta;
|
||||||
pVDev->SetMapMode( MapMode( MapUnit::Map100thMM ) );
|
pVDev->SetMapMode( MapMode( MapUnit::Map100thMM ) );
|
||||||
pVDev->SetFont( maFont );
|
pVDev->SetFont( maFont );
|
||||||
if( pDXArry )
|
if( pDXArry )
|
||||||
@@ -1465,23 +1468,33 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b
|
|||||||
if( nLen > 1 )
|
if( nLen > 1 )
|
||||||
nTextWidth += pDXArry[ nLen - 2 ];
|
nTextWidth += pDXArry[ nLen - 2 ];
|
||||||
// tdf#39894: We should consider the distance to next character cell origin
|
// tdf#39894: We should consider the distance to next character cell origin
|
||||||
nActPosDeltaX = pDXArry[ nLen - 1 ];
|
aActPosDelta.X() = pDXArry[ nLen - 1 ];
|
||||||
|
if ( pDYArry )
|
||||||
|
{
|
||||||
|
aActPosDelta.Y() = pDYArry[ nLen - 1 ];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
nTextWidth = pVDev->GetTextWidth( rText );
|
nTextWidth = pVDev->GetTextWidth( rText );
|
||||||
|
aActPosDelta.X() = nTextWidth;
|
||||||
|
}
|
||||||
|
|
||||||
if( mnTextAlign & TA_UPDATECP )
|
if( mnTextAlign & TA_UPDATECP )
|
||||||
rPosition = maActPos;
|
rPosition = maActPos;
|
||||||
|
|
||||||
if ( mnTextAlign & TA_RIGHT_CENTER )
|
if ( mnTextAlign & TA_RIGHT_CENTER )
|
||||||
{
|
{
|
||||||
double fLength = ( ( mnTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : nTextWidth >> 1;
|
Point aDisplacement( ( ( mnTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : nTextWidth >> 1, 0 );
|
||||||
rPosition.X() -= (sal_Int32)( fLength * cos( maFont.GetOrientation() * F_PI1800 ) );
|
Point().RotateAround(aDisplacement.X(), aDisplacement.Y(), maFont.GetOrientation());
|
||||||
rPosition.Y() -= (sal_Int32)(-( fLength * sin( maFont.GetOrientation() * F_PI1800 ) ) );
|
rPosition -= aDisplacement;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mnTextAlign & TA_UPDATECP )
|
if( mnTextAlign & TA_UPDATECP )
|
||||||
maActPos.X() = rPosition.X() + (pDXArry ? nActPosDeltaX : nTextWidth);
|
{
|
||||||
|
Point().RotateAround(aActPosDelta.X(), aActPosDelta.Y(), maFont.GetOrientation());
|
||||||
|
maActPos = rPosition + aActPosDelta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( bChangeFont || ( maLatestFont != aTmp ) )
|
if ( bChangeFont || ( maLatestFont != aTmp ) )
|
||||||
{
|
{
|
||||||
@@ -1496,6 +1509,17 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if ( pDXArry && pDYArry )
|
||||||
|
{
|
||||||
|
for (sal_Int32 i = 0; i < rText.getLength(); ++i)
|
||||||
|
{
|
||||||
|
Point aCharDisplacement( i ? pDXArry[i-1] : 0, i ? pDYArry[i-1] : 0 );
|
||||||
|
Point().RotateAround(aCharDisplacement.X(), aCharDisplacement.Y(), maFont.GetOrientation());
|
||||||
|
mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition + aCharDisplacement, OUString( rText[i] ), nullptr, 0, 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* because text without dx array is badly scaled, we
|
/* because text without dx array is badly scaled, we
|
||||||
will create such an array if necessary */
|
will create such an array if necessary */
|
||||||
@@ -1514,6 +1538,7 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b
|
|||||||
if ( !pDXArry ) // this means we have created our own array
|
if ( !pDXArry ) // this means we have created our own array
|
||||||
delete[] pDX; // which must be deleted
|
delete[] pDX; // which must be deleted
|
||||||
}
|
}
|
||||||
|
}
|
||||||
SetGfxMode( nOldGfxMode );
|
SetGfxMode( nOldGfxMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -600,6 +600,7 @@ public:
|
|||||||
void DrawText( Point& rPosition,
|
void DrawText( Point& rPosition,
|
||||||
OUString& rString,
|
OUString& rString,
|
||||||
long* pDXArry = nullptr,
|
long* pDXArry = nullptr,
|
||||||
|
long* pDYArry = nullptr,
|
||||||
bool bRecordPath = false,
|
bool bRecordPath = false,
|
||||||
sal_Int32 nGraphicsMode = GM_COMPATIBLE);
|
sal_Int32 nGraphicsMode = GM_COMPATIBLE);
|
||||||
|
|
||||||
|
@@ -551,7 +551,7 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc )
|
|||||||
// dxAry will not fit
|
// dxAry will not fit
|
||||||
if ( nNewTextLen )
|
if ( nNewTextLen )
|
||||||
{
|
{
|
||||||
std::unique_ptr<long[]> pDXAry;
|
std::unique_ptr<long[]> pDXAry, pDYAry;
|
||||||
sal_uInt32 nMaxStreamPos = nRecordPos + ( nRecordSize << 1 );
|
sal_uInt32 nMaxStreamPos = nRecordPos + ( nRecordSize << 1 );
|
||||||
sal_Int32 nDxArySize = nMaxStreamPos - pWMF->Tell();
|
sal_Int32 nDxArySize = nMaxStreamPos - pWMF->Tell();
|
||||||
sal_Int32 nDxAryEntries = nDxArySize >> 1;
|
sal_Int32 nDxAryEntries = nDxArySize >> 1;
|
||||||
@@ -561,6 +561,10 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc )
|
|||||||
{
|
{
|
||||||
sal_uInt16 i; // needed just outside the for
|
sal_uInt16 i; // needed just outside the for
|
||||||
pDXAry.reset(new long[ nNewTextLen ]);
|
pDXAry.reset(new long[ nNewTextLen ]);
|
||||||
|
if ( nOptions & ETO_PDY )
|
||||||
|
{
|
||||||
|
pDYAry.reset(new long[ nNewTextLen ]);
|
||||||
|
}
|
||||||
for (i = 0; i < nNewTextLen; i++ )
|
for (i = 0; i < nNewTextLen; i++ )
|
||||||
{
|
{
|
||||||
if ( pWMF->Tell() >= nMaxStreamPos )
|
if ( pWMF->Tell() >= nMaxStreamPos )
|
||||||
@@ -568,15 +572,15 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc )
|
|||||||
sal_Int32 nDxCount = 1;
|
sal_Int32 nDxCount = 1;
|
||||||
if ( nNewTextLen != nOriginalTextLen )
|
if ( nNewTextLen != nOriginalTextLen )
|
||||||
{
|
{
|
||||||
sal_Unicode nUniChar = aText[i];
|
sal_Unicode cUniChar = aText[i];
|
||||||
OString aTmp(&nUniChar, 1, pOut->GetCharSet());
|
OString aTmp(&cUniChar, 1, pOut->GetCharSet());
|
||||||
if ( aTmp.getLength() > 1 )
|
if ( aTmp.getLength() > 1 )
|
||||||
{
|
{
|
||||||
nDxCount = aTmp.getLength();
|
nDxCount = aTmp.getLength();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sal_Int16 nDx = 0;
|
sal_Int16 nDx = 0, nDy = 0;
|
||||||
while ( nDxCount-- )
|
while ( nDxCount-- )
|
||||||
{
|
{
|
||||||
if ( ( pWMF->Tell() + 2 ) > nMaxStreamPos )
|
if ( ( pWMF->Tell() + 2 ) > nMaxStreamPos )
|
||||||
@@ -590,17 +594,21 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc )
|
|||||||
break;
|
break;
|
||||||
sal_Int16 nDyTmp = 0;
|
sal_Int16 nDyTmp = 0;
|
||||||
pWMF->ReadInt16(nDyTmp);
|
pWMF->ReadInt16(nDyTmp);
|
||||||
// TODO: use Dy offset
|
nDy += nDyTmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pDXAry[ i ] = nDx;
|
pDXAry[ i ] = nDx;
|
||||||
|
if ( nOptions & ETO_PDY )
|
||||||
|
{
|
||||||
|
pDYAry[i] = nDy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( i == nNewTextLen )
|
if ( i == nNewTextLen )
|
||||||
bUseDXAry = true;
|
bUseDXAry = true;
|
||||||
}
|
}
|
||||||
if ( pDXAry && bUseDXAry )
|
if ( pDXAry && bUseDXAry )
|
||||||
pOut->DrawText( aPosition, aText, pDXAry.get() );
|
pOut->DrawText( aPosition, aText, pDXAry.get(), pDYAry.get() );
|
||||||
else
|
else
|
||||||
pOut->DrawText( aPosition, aText );
|
pOut->DrawText( aPosition, aText );
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user