[Libreoffice-commits] core.git: Branch 'feature/drawinglayercore' - 74 commits - avmedia/source chart2/qa chart2/source compilerplugins/clang cui/inc cui/source cui/uiconfig distro-configs/LibreOfficeiOS.conf drawinglayer/CppunitTest_drawinglayer_border.mk drawinglayer/inc drawinglayer/Library_drawinglayercore.mk drawinglayer/Library_drawinglayer.mk drawinglayer/Module_drawinglayer.mk drawinglayer/source emfio/CppunitTest_emfio_emf_test.mk emfio/Library_emfio.mk extras/CustomTarget_tplpresnt.mk extras/source filter/Library_svgfilter.mk fpicker/source helpcontent2 icon-themes/colibre include/drawinglayer include/sfx2 include/svx include/tools include/unotools include/vcl include/xmloff instsetoo_native/inc_common lotuswordpro/source Repository.mk sc/CppunitTest_sc_ucalc.mk sc/Library_sc.mk sc/qa sc/source sd/CppunitTest_sd_uimpress.mk sd/Library_sd.mk sd/qa sd/source setup_native/source sfx2/inc sfx2/Library_sfx.mk sfx2/qa sfx2/source slideshow/source solenv/bin solenv/clang-format solenv/flatpak- manifest.in svgio/CppunitTest_svgio.mk svgio/Library_svgio.mk svx/CppunitTest_svx_gallery_test.mk svx/CppunitTest_svx_unit.mk svx/Library_svxcore.mk svx/Library_svx.mk svx/Module_svx.mk svx/qa svx/source sw/CppunitTest_sw_htmlexport.mk sw/CppunitTest_sw_uwriter.mk sw/inc sw/Library_sw.mk sw/Library_swui.mk sw/qa sw/source vcl/CppunitTest_vcl_type_serializer_test.mk vcl/inc vcl/Library_vcl.mk vcl/qa vcl/skia vcl/source vcl/unx vcl/workben writerfilter/source writerperfect/qa writerperfect/source xmloff/inc xmloff/source xmlsecurity/qa
Tomaž Vajngerl (via logerrit)
logerrit at kemper.freedesktop.org
Sat May 2 17:42:38 UTC 2020
Rebased ref, commits from common ancestor:
commit 4d89b69a28c4d74bf8a2e2e2c6b982877485bc72
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sat May 2 19:33:57 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:50 2020 +0200
remove vclhelperbufferdevice.{cxx,hxx} from clang-format blacklist
Change-Id: I0ab6572ab700756322f96b982f7faeb6d8dc9fb6
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index f362559d12bf..53ecdd4ee685 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -35,422 +35,430 @@
#include <vcl/lazydelete.hxx>
#include <vcl/dibtools.hxx>
-
// buffered VDev usage
namespace
{
- typedef std::vector< VclPtr<VirtualDevice> > aBuffers;
-
- class VDevBuffer : public Timer, protected cppu::BaseMutex
- {
- private:
- // available buffers
- aBuffers maFreeBuffers;
-
- // allocated/used buffers (remembered to allow deleting them in destructor)
- aBuffers maUsedBuffers;
-
- // remember what outputdevice was the template passed to VirtualDevice::Create
- // so we can test if that OutputDevice was disposed before reusing a
- // virtualdevice because that isn't safe to do at least for Gtk2
- std::map< VclPtr<VirtualDevice>, VclPtr<OutputDevice> > maDeviceTemplates;
+typedef std::vector<VclPtr<VirtualDevice>> aBuffers;
- public:
- VDevBuffer();
- virtual ~VDevBuffer() override;
-
- VclPtr<VirtualDevice> alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, bool bMonoChrome);
- void free(VirtualDevice& rDevice);
+class VDevBuffer : public Timer, protected cppu::BaseMutex
+{
+private:
+ // available buffers
+ aBuffers maFreeBuffers;
+
+ // allocated/used buffers (remembered to allow deleting them in destructor)
+ aBuffers maUsedBuffers;
+
+ // remember what outputdevice was the template passed to VirtualDevice::Create
+ // so we can test if that OutputDevice was disposed before reusing a
+ // virtualdevice because that isn't safe to do at least for Gtk2
+ std::map<VclPtr<VirtualDevice>, VclPtr<OutputDevice>> maDeviceTemplates;
+
+public:
+ VDevBuffer();
+ virtual ~VDevBuffer() override;
+
+ VclPtr<VirtualDevice> alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear,
+ bool bMonoChrome);
+ void free(VirtualDevice& rDevice);
+
+ // Timer virtuals
+ virtual void Invoke() override;
+};
+
+VDevBuffer::VDevBuffer()
+ : Timer("VDevBuffer timer")
+ , maFreeBuffers()
+ , maUsedBuffers()
+{
+ SetTimeout(10L * 1000L); // ten seconds
+ SetDebugName("drawinglayer::VDevBuffer via Invoke()");
+}
- // Timer virtuals
- virtual void Invoke() override;
- };
+VDevBuffer::~VDevBuffer()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ Stop();
- VDevBuffer::VDevBuffer()
- : Timer("VDevBuffer timer"),
- maFreeBuffers(),
- maUsedBuffers()
+ while (!maFreeBuffers.empty())
{
- SetTimeout(10L * 1000L); // ten seconds
- SetDebugName("drawinglayer::VDevBuffer via Invoke()");
+ (*(maFreeBuffers.end() - 1)).disposeAndClear();
+ maFreeBuffers.pop_back();
}
- VDevBuffer::~VDevBuffer()
+ while (!maUsedBuffers.empty())
{
- ::osl::MutexGuard aGuard(m_aMutex);
- Stop();
+ (*(maUsedBuffers.end() - 1)).disposeAndClear();
+ maUsedBuffers.pop_back();
+ }
+}
- while(!maFreeBuffers.empty())
- {
- (*(maFreeBuffers.end() - 1)).disposeAndClear();
- maFreeBuffers.pop_back();
- }
+VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear,
+ bool bMonoChrome)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ VclPtr<VirtualDevice> pRetval;
- while(!maUsedBuffers.empty())
- {
- (*(maUsedBuffers.end() - 1)).disposeAndClear();
- maUsedBuffers.pop_back();
- }
- }
+ sal_Int32 nBits = bMonoChrome ? 1 : rOutDev.GetBitCount();
- VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, bool bMonoChrome)
+ bool bOkay(false);
+ if (!maFreeBuffers.empty())
{
- ::osl::MutexGuard aGuard(m_aMutex);
- VclPtr<VirtualDevice> pRetval;
+ aBuffers::iterator aFound(maFreeBuffers.end());
- sal_Int32 nBits = bMonoChrome ? 1 : rOutDev.GetBitCount();
-
- bool bOkay(false);
- if(!maFreeBuffers.empty())
+ for (aBuffers::iterator a(maFreeBuffers.begin()); a != maFreeBuffers.end(); ++a)
{
- aBuffers::iterator aFound(maFreeBuffers.end());
+ assert(*a && "Empty pointer in VDevBuffer (!)");
- for(aBuffers::iterator a(maFreeBuffers.begin()); a != maFreeBuffers.end(); ++a)
+ if (nBits == (*a)->GetBitCount())
{
- assert(*a && "Empty pointer in VDevBuffer (!)");
-
- if (nBits == (*a)->GetBitCount())
+ // candidate is valid due to bit depth
+ if (aFound != maFreeBuffers.end())
{
- // candidate is valid due to bit depth
- if(aFound != maFreeBuffers.end())
+ // already found
+ if (bOkay)
{
- // already found
- if(bOkay)
+ // found is valid
+ const bool bCandidateOkay(
+ (*a)->GetOutputWidthPixel() >= rSizePixel.getWidth()
+ && (*a)->GetOutputHeightPixel() >= rSizePixel.getHeight());
+
+ if (bCandidateOkay)
{
- // found is valid
- const bool bCandidateOkay((*a)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*a)->GetOutputHeightPixel() >= rSizePixel.getHeight());
+ // found and candidate are valid
+ const sal_uLong aSquare((*aFound)->GetOutputWidthPixel()
+ * (*aFound)->GetOutputHeightPixel());
+ const sal_uLong aCandidateSquare((*a)->GetOutputWidthPixel()
+ * (*a)->GetOutputHeightPixel());
- if(bCandidateOkay)
- {
- // found and candidate are valid
- const sal_uLong aSquare((*aFound)->GetOutputWidthPixel() * (*aFound)->GetOutputHeightPixel());
- const sal_uLong aCandidateSquare((*a)->GetOutputWidthPixel() * (*a)->GetOutputHeightPixel());
-
- if(aCandidateSquare < aSquare)
- {
- // candidate is valid and smaller, use it
- aFound = a;
- }
- }
- else
+ if (aCandidateSquare < aSquare)
{
- // found is valid, candidate is not. Keep found
+ // candidate is valid and smaller, use it
+ aFound = a;
}
}
else
{
- // found is invalid, use candidate
- aFound = a;
- bOkay = (*aFound)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*aFound)->GetOutputHeightPixel() >= rSizePixel.getHeight();
+ // found is valid, candidate is not. Keep found
}
}
else
{
- // none yet, use candidate
+ // found is invalid, use candidate
aFound = a;
- bOkay = (*aFound)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*aFound)->GetOutputHeightPixel() >= rSizePixel.getHeight();
- }
- }
- }
-
- if(aFound != maFreeBuffers.end())
- {
- pRetval = *aFound;
- maFreeBuffers.erase(aFound);
- }
- }
-
- if (pRetval)
- {
- // found a suitable cached virtual device, but the
- // outputdevice it was based on has been disposed,
- // drop it and create a new one instead as reusing
- // such devices is unsafe under at least Gtk2
- if (maDeviceTemplates[pRetval]->isDisposed())
- {
- maDeviceTemplates.erase(pRetval);
- pRetval.disposeAndClear();
- }
- else
- {
- if (bOkay)
- {
- if (bClear)
- {
- pRetval->Erase(::tools::Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight()));
+ bOkay = (*aFound)->GetOutputWidthPixel() >= rSizePixel.getWidth()
+ && (*aFound)->GetOutputHeightPixel() >= rSizePixel.getHeight();
}
}
else
{
- pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ // none yet, use candidate
+ aFound = a;
+ bOkay = (*aFound)->GetOutputWidthPixel() >= rSizePixel.getWidth()
+ && (*aFound)->GetOutputHeightPixel() >= rSizePixel.getHeight();
}
}
}
- // no success yet, create new buffer
- if(!pRetval)
+ if (aFound != maFreeBuffers.end())
{
- pRetval = VclPtr<VirtualDevice>::Create(rOutDev, bMonoChrome ? DeviceFormat::BITMASK : DeviceFormat::DEFAULT);
- maDeviceTemplates[pRetval] = &rOutDev;
- pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ pRetval = *aFound;
+ maFreeBuffers.erase(aFound);
+ }
+ }
+
+ if (pRetval)
+ {
+ // found a suitable cached virtual device, but the
+ // outputdevice it was based on has been disposed,
+ // drop it and create a new one instead as reusing
+ // such devices is unsafe under at least Gtk2
+ if (maDeviceTemplates[pRetval]->isDisposed())
+ {
+ maDeviceTemplates.erase(pRetval);
+ pRetval.disposeAndClear();
}
else
{
- // reused, reset some values
- pRetval->SetMapMode();
- pRetval->SetRasterOp(RasterOp::OverPaint);
+ if (bOkay)
+ {
+ if (bClear)
+ {
+ pRetval->Erase(
+ ::tools::Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight()));
+ }
+ }
+ else
+ {
+ pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ }
}
-
- // remember allocated buffer
- maUsedBuffers.push_back(pRetval);
-
- return pRetval;
}
- void VDevBuffer::free(VirtualDevice& rDevice)
+ // no success yet, create new buffer
+ if (!pRetval)
{
- ::osl::MutexGuard aGuard(m_aMutex);
- const aBuffers::iterator aUsedFound(std::find(maUsedBuffers.begin(), maUsedBuffers.end(), &rDevice));
- OSL_ENSURE(aUsedFound != maUsedBuffers.end(), "OOps, non-registered buffer freed (!)");
-
- maUsedBuffers.erase(aUsedFound);
- maFreeBuffers.emplace_back(&rDevice);
- SAL_WARN_IF(maFreeBuffers.size() > 1000, "drawinglayer", "excessive cached buffers, "
- << maFreeBuffers.size() << " entries!");
- Start();
+ pRetval = VclPtr<VirtualDevice>::Create(rOutDev, bMonoChrome ? DeviceFormat::BITMASK
+ : DeviceFormat::DEFAULT);
+ maDeviceTemplates[pRetval] = &rOutDev;
+ pRetval->SetOutputSizePixel(rSizePixel, bClear);
}
-
- void VDevBuffer::Invoke()
+ else
{
- ::osl::MutexGuard aGuard(m_aMutex);
-
- while(!maFreeBuffers.empty())
- {
- aBuffers::iterator aLastOne(maFreeBuffers.end() - 1);
- maDeviceTemplates.erase(*aLastOne);
- aLastOne->disposeAndClear();
- maFreeBuffers.pop_back();
- }
+ // reused, reset some values
+ pRetval->SetMapMode();
+ pRetval->SetRasterOp(RasterOp::OverPaint);
}
+
+ // remember allocated buffer
+ maUsedBuffers.push_back(pRetval);
+
+ return pRetval;
}
+void VDevBuffer::free(VirtualDevice& rDevice)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ const aBuffers::iterator aUsedFound(
+ std::find(maUsedBuffers.begin(), maUsedBuffers.end(), &rDevice));
+ OSL_ENSURE(aUsedFound != maUsedBuffers.end(), "OOps, non-registered buffer freed (!)");
+
+ maUsedBuffers.erase(aUsedFound);
+ maFreeBuffers.emplace_back(&rDevice);
+ SAL_WARN_IF(maFreeBuffers.size() > 1000, "drawinglayer",
+ "excessive cached buffers, " << maFreeBuffers.size() << " entries!");
+ Start();
+}
+
+void VDevBuffer::Invoke()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ while (!maFreeBuffers.empty())
+ {
+ aBuffers::iterator aLastOne(maFreeBuffers.end() - 1);
+ maDeviceTemplates.erase(*aLastOne);
+ aLastOne->disposeAndClear();
+ maFreeBuffers.pop_back();
+ }
+}
+}
// support for rendering Bitmap and BitmapEx contents
namespace drawinglayer
{
- // static global VDev buffer for the VclProcessor2D's (VclMetafileProcessor2D and VclPixelProcessor2D)
- VDevBuffer& getVDevBuffer()
- {
- // secure global instance with Vcl's safe destroyer of external (seen by
- // library base) stuff, the remembered VDevs need to be deleted before
- // Vcl's deinit
- static vcl::DeleteOnDeinit< VDevBuffer > aVDevBuffer(new VDevBuffer());
- return *aVDevBuffer.get();
- }
+// static global VDev buffer for the VclProcessor2D's (VclMetafileProcessor2D and VclPixelProcessor2D)
+VDevBuffer& getVDevBuffer()
+{
+ // secure global instance with Vcl's safe destroyer of external (seen by
+ // library base) stuff, the remembered VDevs need to be deleted before
+ // Vcl's deinit
+ static vcl::DeleteOnDeinit<VDevBuffer> aVDevBuffer(new VDevBuffer());
+ return *aVDevBuffer.get();
+}
- impBufferDevice::impBufferDevice(
- OutputDevice& rOutDev,
- const basegfx::B2DRange& rRange)
- : mrOutDev(rOutDev),
- mpContent(nullptr),
- mpMask(nullptr),
- mpAlpha(nullptr)
- {
- basegfx::B2DRange aRangePixel(rRange);
- aRangePixel.transform(mrOutDev.GetViewTransformation());
- const ::tools::Rectangle aRectPixel(
- static_cast<sal_Int32>(floor(aRangePixel.getMinX())), static_cast<sal_Int32>(floor(aRangePixel.getMinY())),
- static_cast<sal_Int32>(ceil(aRangePixel.getMaxX())), static_cast<sal_Int32>(ceil(aRangePixel.getMaxY())));
- const Point aEmptyPoint;
- maDestPixel = ::tools::Rectangle(aEmptyPoint, mrOutDev.GetOutputSizePixel());
- maDestPixel.Intersection(aRectPixel);
-
- if(!isVisible())
- return;
+impBufferDevice::impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange)
+ : mrOutDev(rOutDev)
+ , mpContent(nullptr)
+ , mpMask(nullptr)
+ , mpAlpha(nullptr)
+{
+ basegfx::B2DRange aRangePixel(rRange);
+ aRangePixel.transform(mrOutDev.GetViewTransformation());
+ const ::tools::Rectangle aRectPixel(static_cast<sal_Int32>(floor(aRangePixel.getMinX())),
+ static_cast<sal_Int32>(floor(aRangePixel.getMinY())),
+ static_cast<sal_Int32>(ceil(aRangePixel.getMaxX())),
+ static_cast<sal_Int32>(ceil(aRangePixel.getMaxY())));
+ const Point aEmptyPoint;
+ maDestPixel = ::tools::Rectangle(aEmptyPoint, mrOutDev.GetOutputSizePixel());
+ maDestPixel.Intersection(aRectPixel);
+
+ if (!isVisible())
+ return;
#ifdef IOS
- // Exact mechanism unknown, but for some reason SmartArt
- // rendering, especially shadows, is broken on iOS unless
- // we pass 'true' here. Are virtual devices always de
- // facto cleared when created on other platforms?
- mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false);
+ // Exact mechanism unknown, but for some reason SmartArt
+ // rendering, especially shadows, is broken on iOS unless
+ // we pass 'true' here. Are virtual devices always de
+ // facto cleared when created on other platforms?
+ mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false);
#else
- mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, false);
+ mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, false);
#endif
- // #i93485# assert when copying from window to VDev is used
- OSL_ENSURE(mrOutDev.GetOutDevType() != OUTDEV_WINDOW,
- "impBufferDevice render helper: Copying from Window to VDev, this should be avoided (!)");
+ // #i93485# assert when copying from window to VDev is used
+ OSL_ENSURE(
+ mrOutDev.GetOutDevType() != OUTDEV_WINDOW,
+ "impBufferDevice render helper: Copying from Window to VDev, this should be avoided (!)");
- const bool bWasEnabledSrc(mrOutDev.IsMapModeEnabled());
- mrOutDev.EnableMapMode(false);
- mpContent->DrawOutDev(aEmptyPoint, maDestPixel.GetSize(), maDestPixel.TopLeft(), maDestPixel.GetSize(), mrOutDev);
- mrOutDev.EnableMapMode(bWasEnabledSrc);
+ const bool bWasEnabledSrc(mrOutDev.IsMapModeEnabled());
+ mrOutDev.EnableMapMode(false);
+ mpContent->DrawOutDev(aEmptyPoint, maDestPixel.GetSize(), maDestPixel.TopLeft(),
+ maDestPixel.GetSize(), mrOutDev);
+ mrOutDev.EnableMapMode(bWasEnabledSrc);
- MapMode aNewMapMode(mrOutDev.GetMapMode());
+ MapMode aNewMapMode(mrOutDev.GetMapMode());
- const Point aLogicTopLeft(mrOutDev.PixelToLogic(maDestPixel.TopLeft()));
- aNewMapMode.SetOrigin(Point(-aLogicTopLeft.X(), -aLogicTopLeft.Y()));
+ const Point aLogicTopLeft(mrOutDev.PixelToLogic(maDestPixel.TopLeft()));
+ aNewMapMode.SetOrigin(Point(-aLogicTopLeft.X(), -aLogicTopLeft.Y()));
- mpContent->SetMapMode(aNewMapMode);
+ mpContent->SetMapMode(aNewMapMode);
- // copy AA flag for new target
- mpContent->SetAntialiasing(mrOutDev.GetAntialiasing());
+ // copy AA flag for new target
+ mpContent->SetAntialiasing(mrOutDev.GetAntialiasing());
- // copy RasterOp (e.g. may be RasterOp::Xor on destination)
- mpContent->SetRasterOp(mrOutDev.GetRasterOp());
- }
+ // copy RasterOp (e.g. may be RasterOp::Xor on destination)
+ mpContent->SetRasterOp(mrOutDev.GetRasterOp());
+}
- impBufferDevice::~impBufferDevice()
+impBufferDevice::~impBufferDevice()
+{
+ if (mpContent)
{
- if(mpContent)
- {
- getVDevBuffer().free(*mpContent);
- }
-
- if(mpMask)
- {
- getVDevBuffer().free(*mpMask);
- }
+ getVDevBuffer().free(*mpContent);
+ }
- if(mpAlpha)
- {
- getVDevBuffer().free(*mpAlpha);
- }
+ if (mpMask)
+ {
+ getVDevBuffer().free(*mpMask);
}
- void impBufferDevice::paint(double fTrans)
+ if (mpAlpha)
{
- if(!isVisible())
- return;
+ getVDevBuffer().free(*mpAlpha);
+ }
+}
+
+void impBufferDevice::paint(double fTrans)
+{
+ if (!isVisible())
+ return;
- const Point aEmptyPoint;
- const Size aSizePixel(maDestPixel.GetSize());
- const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled());
+ const Point aEmptyPoint;
+ const Size aSizePixel(maDestPixel.GetSize());
+ const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled());
#ifdef DBG_UTIL
- static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore
+ static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore
#endif
- mrOutDev.EnableMapMode(false);
- mpContent->EnableMapMode(false);
+ mrOutDev.EnableMapMode(false);
+ mpContent->EnableMapMode(false);
#ifdef DBG_UTIL
- if(bDoSaveForVisualControl)
- {
- SvFileStream aNew(
+ if (bDoSaveForVisualControl)
+ {
+ SvFileStream aNew(
#ifdef _WIN32
- "c:\\content.bmp",
+ "c:\\content.bmp",
#else
- "~/content.bmp",
+ "~/content.bmp",
#endif
- StreamMode::WRITE|StreamMode::TRUNC);
- Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
- WriteDIB(aContent, aNew, false, true);
- }
+ StreamMode::WRITE | StreamMode::TRUNC);
+ Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
+ WriteDIB(aContent, aNew, false, true);
+ }
#endif
- // during painting the buffer, disable evtl. set RasterOp (may be RasterOp::Xor)
- const RasterOp aOrigRasterOp(mrOutDev.GetRasterOp());
- mrOutDev.SetRasterOp(RasterOp::OverPaint);
+ // during painting the buffer, disable evtl. set RasterOp (may be RasterOp::Xor)
+ const RasterOp aOrigRasterOp(mrOutDev.GetRasterOp());
+ mrOutDev.SetRasterOp(RasterOp::OverPaint);
- if(mpAlpha)
- {
- mpAlpha->EnableMapMode(false);
- const AlphaMask aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint, aSizePixel));
+ if (mpAlpha)
+ {
+ mpAlpha->EnableMapMode(false);
+ const AlphaMask aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint, aSizePixel));
#ifdef DBG_UTIL
- if(bDoSaveForVisualControl)
- {
- SvFileStream aNew(
+ if (bDoSaveForVisualControl)
+ {
+ SvFileStream aNew(
#ifdef _WIN32
- "c:\\transparence.bmp",
+ "c:\\transparence.bmp",
#else
- "~/transparence.bmp",
+ "~/transparence.bmp",
#endif
- StreamMode::WRITE|StreamMode::TRUNC);
- WriteDIB(aAlphaMask.GetBitmap(), aNew, false, true);
- }
+ StreamMode::WRITE | StreamMode::TRUNC);
+ WriteDIB(aAlphaMask.GetBitmap(), aNew, false, true);
+ }
#endif
- Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
- }
- else if(mpMask)
- {
- mpMask->EnableMapMode(false);
- const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint, aSizePixel));
+ Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
+ }
+ else if (mpMask)
+ {
+ mpMask->EnableMapMode(false);
+ const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint, aSizePixel));
#ifdef DBG_UTIL
- if(bDoSaveForVisualControl)
- {
- SvFileStream aNew(
+ if (bDoSaveForVisualControl)
+ {
+ SvFileStream aNew(
#ifdef _WIN32
- "c:\\mask.bmp",
+ "c:\\mask.bmp",
#else
- "~/mask.bmp",
+ "~/mask.bmp",
#endif
- StreamMode::WRITE|StreamMode::TRUNC);
- WriteDIB(aMask, aNew, false, true);
- }
-#endif
-
- Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask));
- }
- else if(0.0 != fTrans)
- {
- sal_uInt8 nMaskValue(static_cast<sal_uInt8>(basegfx::fround(fTrans * 255.0)));
- const AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
- Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
- }
- else
- {
- mrOutDev.DrawOutDev(maDestPixel.TopLeft(), aSizePixel,
- aEmptyPoint, aSizePixel,
- *mpContent);
+ StreamMode::WRITE | StreamMode::TRUNC);
+ WriteDIB(aMask, aNew, false, true);
}
+#endif
- mrOutDev.SetRasterOp(aOrigRasterOp);
- mrOutDev.EnableMapMode(bWasEnabledDst);
+ Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask));
}
-
- VirtualDevice& impBufferDevice::getContent()
+ else if (0.0 != fTrans)
{
- assert(mpContent && "impBufferDevice: No content, check isVisible() before accessing (!)");
- return *mpContent;
+ sal_uInt8 nMaskValue(static_cast<sal_uInt8>(basegfx::fround(fTrans * 255.0)));
+ const AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
+ Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
}
-
- VirtualDevice& impBufferDevice::getMask()
+ else
{
- assert(mpContent && "impBufferDevice: No content, check isVisible() before accessing (!)");
- if (!mpMask)
- {
- mpMask = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, true);
- mpMask->SetMapMode(mpContent->GetMapMode());
+ mrOutDev.DrawOutDev(maDestPixel.TopLeft(), aSizePixel, aEmptyPoint, aSizePixel, *mpContent);
+ }
- // do NOT copy AA flag for mask!
- }
+ mrOutDev.SetRasterOp(aOrigRasterOp);
+ mrOutDev.EnableMapMode(bWasEnabledDst);
+}
- return *mpMask;
- }
+VirtualDevice& impBufferDevice::getContent()
+{
+ assert(mpContent && "impBufferDevice: No content, check isVisible() before accessing (!)");
+ return *mpContent;
+}
- VirtualDevice& impBufferDevice::getTransparence()
+VirtualDevice& impBufferDevice::getMask()
+{
+ assert(mpContent && "impBufferDevice: No content, check isVisible() before accessing (!)");
+ if (!mpMask)
{
- OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
- if(!mpAlpha)
- {
- mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false);
- mpAlpha->SetMapMode(mpContent->GetMapMode());
+ mpMask = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, true);
+ mpMask->SetMapMode(mpContent->GetMapMode());
- // copy AA flag for new target; masking needs to be smooth
- mpAlpha->SetAntialiasing(mpContent->GetAntialiasing());
- }
+ // do NOT copy AA flag for mask!
+ }
+
+ return *mpMask;
+}
+
+VirtualDevice& impBufferDevice::getTransparence()
+{
+ OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
+ if (!mpAlpha)
+ {
+ mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false);
+ mpAlpha->SetMapMode(mpContent->GetMapMode());
- return *mpAlpha;
+ // copy AA flag for new target; masking needs to be smooth
+ mpAlpha->SetAntialiasing(mpContent->GetAntialiasing());
}
+
+ return *mpAlpha;
+}
} // end of namespace drawinglayer
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
index 5305b1c0541e..90d351eac50f 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
@@ -21,32 +21,33 @@
#include <vcl/virdev.hxx>
-namespace basegfx { class B2DRange; }
+namespace basegfx
+{
+class B2DRange;
+}
// support methods for vcl direct gradient rendering
namespace drawinglayer
{
- class impBufferDevice
- {
- OutputDevice& mrOutDev;
- VclPtr<VirtualDevice> mpContent;
- VclPtr<VirtualDevice> mpMask;
- VclPtr<VirtualDevice> mpAlpha;
- ::tools::Rectangle maDestPixel;
-
- public:
- impBufferDevice(
- OutputDevice& rOutDev,
- const basegfx::B2DRange& rRange);
- ~impBufferDevice();
-
- void paint(double fTrans = 0.0);
- bool isVisible() const { return !maDestPixel.IsEmpty(); }
- VirtualDevice& getContent();
- VirtualDevice& getMask();
- VirtualDevice& getTransparence();
- };
+class impBufferDevice
+{
+ OutputDevice& mrOutDev;
+ VclPtr<VirtualDevice> mpContent;
+ VclPtr<VirtualDevice> mpMask;
+ VclPtr<VirtualDevice> mpAlpha;
+ tools::Rectangle maDestPixel;
+
+public:
+ impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange);
+ ~impBufferDevice();
+
+ void paint(double fTrans = 0.0);
+ bool isVisible() const { return !maDestPixel.IsEmpty(); }
+ VirtualDevice& getContent();
+ VirtualDevice& getMask();
+ VirtualDevice& getTransparence();
+};
} // end of namespace drawinglayer
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/solenv/clang-format/blacklist b/solenv/clang-format/blacklist
index 466245492198..298745b86375 100644
--- a/solenv/clang-format/blacklist
+++ b/solenv/clang-format/blacklist
@@ -3752,8 +3752,6 @@ drawinglayer/source/processor2d/objectinfoextractor2d.cxx
drawinglayer/source/processor2d/processor2dtools.cxx
drawinglayer/source/processor2d/processorfromoutputdevice.cxx
drawinglayer/source/processor2d/textaspolygonextractor2d.cxx
-drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
-drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
drawinglayer/source/processor3d/baseprocessor3d.cxx
commit e0a271c5e11ad469db5c2bef625997c930f5d2c9
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sat May 2 19:29:49 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:50 2020 +0200
pragma once in vclhelperbufferdevice.hxx
Change-Id: I12e53849fa23496799ba5e45fc0077cb9b54048c
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
index 3bcbb979761e..5305b1c0541e 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
@@ -17,17 +17,12 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#ifndef INCLUDED_DRAWINGLAYER_SOURCE_PROCESSOR2D_VCLHELPERBUFFERDEVICE_HXX
-#define INCLUDED_DRAWINGLAYER_SOURCE_PROCESSOR2D_VCLHELPERBUFFERDEVICE_HXX
+#pragma once
#include <vcl/virdev.hxx>
-
-// predefines
-
namespace basegfx { class B2DRange; }
-
// support methods for vcl direct gradient rendering
namespace drawinglayer
@@ -54,7 +49,4 @@ namespace drawinglayer
};
} // end of namespace drawinglayer
-
-#endif // INCLUDED_DRAWINGLAYER_SOURCE_PROCESSOR2D_VCLHELPERBUFFERDEVICE_HXX
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 088eae9d40a563d4f3795b815de8b8fea4026fe3
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sat May 2 14:46:37 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:50 2020 +0200
vcl: simplify graphic type detection for EPS files
Change-Id: Ia48560274c33aaa8e81a5ee6eb00f6470e92e0fd
diff --git a/vcl/source/filter/GraphicFormatDetector.cxx b/vcl/source/filter/GraphicFormatDetector.cxx
index 5682d78f8e3c..56f7a9f2d006 100644
--- a/vcl/source/filter/GraphicFormatDetector.cxx
+++ b/vcl/source/filter/GraphicFormatDetector.cxx
@@ -311,8 +311,7 @@ bool GraphicFormatDetector::checkEPS()
msDetectedFormat = "EPS";
return true;
}
- else if (matchArrayWithString(pFirstBytesAsCharArray, 10, "%!PS-Adobe")
- && matchArrayWithString(pFirstBytesAsCharArray + 15, 3, "EPS"))
+ else if (checkArrayForMatchingStrings(pFirstBytesAsCharArray, 30, { "%!PS-Adobe", " EPS" }))
{
msDetectedFormat = "EPS";
return true;
commit 627c4ae1bfaea259e2bd54bf1efec22951c61c66
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sat May 2 14:42:58 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:50 2020 +0200
vcl: add test case for EPS file detection
Change-Id: Ia6a4cedf5c570e5d9544887ae66da0ec1e491647
diff --git a/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx b/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
index 155ff089811b..1ce516bf52b3 100644
--- a/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
+++ b/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
@@ -42,6 +42,7 @@ class GraphicFormatDetectorTest : public test::BootstrapFixtureBase
void testDetectSVG();
void testDetectSVGZ();
void testDetectPDF();
+ void testDetectEPS();
void testMatchArray();
void testCheckArrayForMatchingStrings();
@@ -61,6 +62,7 @@ class GraphicFormatDetectorTest : public test::BootstrapFixtureBase
CPPUNIT_TEST(testDetectSVG);
CPPUNIT_TEST(testDetectSVGZ);
CPPUNIT_TEST(testDetectPDF);
+ CPPUNIT_TEST(testDetectEPS);
CPPUNIT_TEST(testMatchArray);
CPPUNIT_TEST(testCheckArrayForMatchingStrings);
CPPUNIT_TEST_SUITE_END();
@@ -291,6 +293,21 @@ void GraphicFormatDetectorTest::testDetectPDF()
CPPUNIT_ASSERT_EQUAL(OUString("PDF"), rFormatExtension);
}
+void GraphicFormatDetectorTest::testDetectEPS()
+{
+ SvFileStream aFileStream(getFullUrl("TypeDetectionExample.eps"), StreamMode::READ);
+ vcl::GraphicFormatDetector aDetector(aFileStream, "EPS");
+
+ CPPUNIT_ASSERT(aDetector.detect());
+ CPPUNIT_ASSERT(aDetector.checkEPS());
+
+ aFileStream.Seek(aDetector.mnStreamPosition);
+
+ OUString rFormatExtension;
+ CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
+ CPPUNIT_ASSERT_EQUAL(OUString("EPS"), rFormatExtension);
+}
+
void GraphicFormatDetectorTest::testMatchArray()
{
std::string aString("<?xml version=\"1.0\" standalone=\"no\"?>\n"
diff --git a/vcl/qa/cppunit/data/TypeDetectionExample.eps b/vcl/qa/cppunit/data/TypeDetectionExample.eps
new file mode 100644
index 000000000000..7f0db47bc80c
--- /dev/null
+++ b/vcl/qa/cppunit/data/TypeDetectionExample.eps
@@ -0,0 +1,82 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: cairo 1.16.0 (https://cairographics.org)
+%%CreationDate: Sat May 2 14:29:27 2020
+%%Pages: 1
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 2
+%%BoundingBox: 0 1 7 8
+%%EndComments
+%%BeginProlog
+50 dict begin
+/q { gsave } bind def
+/Q { grestore } bind def
+/cm { 6 array astore concat } bind def
+/w { setlinewidth } bind def
+/J { setlinecap } bind def
+/j { setlinejoin } bind def
+/M { setmiterlimit } bind def
+/d { setdash } bind def
+/m { moveto } bind def
+/l { lineto } bind def
+/c { curveto } bind def
+/h { closepath } bind def
+/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
+ 0 exch rlineto 0 rlineto closepath } bind def
+/S { stroke } bind def
+/f { fill } bind def
+/f* { eofill } bind def
+/n { newpath } bind def
+/W { clip } bind def
+/W* { eoclip } bind def
+/BT { } bind def
+/ET { } bind def
+/BDC { mark 3 1 roll /BDC pdfmark } bind def
+/EMC { mark /EMC pdfmark } bind def
+/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
+/Tj { show currentpoint cairo_store_point } bind def
+/TJ {
+ {
+ dup
+ type /stringtype eq
+ { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
+ } forall
+ currentpoint cairo_store_point
+} bind def
+/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
+ cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
+/Tf { pop /cairo_font exch def /cairo_font_matrix where
+ { pop cairo_selectfont } if } bind def
+/Td { matrix translate cairo_font_matrix matrix concatmatrix dup
+ /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
+ /cairo_font where { pop cairo_selectfont } if } bind def
+/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
+ cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
+/g { setgray } bind def
+/rg { setrgbcolor } bind def
+/d1 { setcachedevice } bind def
+/cairo_data_source {
+ CairoDataIndex CairoData length lt
+ { CairoData CairoDataIndex get /CairoDataIndex CairoDataIndex 1 add def }
+ { () } ifelse
+} def
+/cairo_flush_ascii85_file { cairo_ascii85_file status { cairo_ascii85_file flushfile } if } def
+/cairo_image { image cairo_flush_ascii85_file } def
+/cairo_imagemask { imagemask cairo_flush_ascii85_file } def
+%%EndProlog
+%%BeginSetup
+%%EndSetup
+%%Page: 1 1
+%%BeginPageSetup
+%%PageBoundingBox: 0 1 7 8
+%%EndPageSetup
+q 0 1 7 7 rectclip
+1 0 0 -1 0 8 cm q
+0.956863 0.831373 0.266667 rg
+3.75 0.75 m 5.41 0.75 6.75 2.09 6.75 3.75 c 6.75 5.41 5.41 6.75 3.75 6.75
+ c 2.09 6.75 0.75 5.41 0.75 3.75 c 0.75 2.09 2.09 0.75 3.75 0.75 c h
+3.75 0.75 m f
+Q Q
+showpage
+%%Trailer
+end
+%%EOF
commit d6e94ff9d9f4c87eecc8f0fd09fb0bbab00f848c
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sat May 2 14:35:23 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:49 2020 +0200
vcl: add DetectorTools + tests, refactor array string matching
Add DetectorTools with byte array searching and matching to a
input string (or another byte array). This refactors the existing
function in GraphicFormatDetector. It needs to go into its own
header so that the function(s) can be tested easily. Replace
the previous searchEntry implementation with refactored one in
the source code.
Change-Id: I59d30b694e13f28d6366f1a99fe2ef2ea3c1a07d
diff --git a/vcl/inc/graphic/DetectorTools.hxx b/vcl/inc/graphic/DetectorTools.hxx
new file mode 100644
index 000000000000..b9163de135d9
--- /dev/null
+++ b/vcl/inc/graphic/DetectorTools.hxx
@@ -0,0 +1,63 @@
+/* -*- 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/.
+ *
+ */
+
+#pragma once
+
+namespace vcl
+{
+const char* matchArray(const char* pSource, sal_Int32 nSourceSize, const char* pSearch,
+ sal_Int32 nSearchSize)
+{
+ for (sal_Int32 increment = 0; increment <= (nSourceSize - nSearchSize); ++increment)
+ {
+ bool bMatch = true;
+ // search both arrays if they match
+ for (sal_Int32 index = 0; index < nSearchSize && bMatch; ++index)
+ {
+ if (pSource[index] != pSearch[index])
+ bMatch = false;
+ }
+ // match has been found
+ if (bMatch)
+ return pSource;
+ pSource++;
+ }
+ return nullptr;
+}
+
+const char* matchArrayWithString(const char* pSource, sal_Int32 nSourceSize, OString const& rString)
+{
+ return matchArray(pSource, nSourceSize, rString.getStr(), rString.getLength());
+}
+
+bool checkArrayForMatchingStrings(const char* pSource, sal_Int32 nSourceSize,
+ std::vector<OString> const& rStrings)
+{
+ if (rStrings.empty())
+ return false;
+ if (rStrings.size() < 2)
+ return matchArrayWithString(pSource, nSourceSize, rStrings[0]) != nullptr;
+
+ const char* pBegin = pSource;
+ const char* pCurrent = pSource;
+ for (OString const& rString : rStrings)
+ {
+ sal_Int32 nCurrentSize = nSourceSize - sal_Int32(pCurrent - pBegin);
+ printf("Current size %d -> %d\n", nCurrentSize, nSourceSize);
+ pCurrent = matchArray(pCurrent, nCurrentSize, rString.getStr(), rString.getLength());
+ if (pCurrent == nullptr)
+ return false;
+ printf("%s\n", pCurrent);
+ }
+ return true;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx b/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
index 90183279dbc9..155ff089811b 100644
--- a/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
+++ b/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
@@ -12,6 +12,7 @@
#include <unotest/bootstrapfixturebase.hxx>
#include <graphic/GraphicFormatDetector.hxx>
+#include <graphic/DetectorTools.hxx>
#include <tools/stream.hxx>
@@ -41,6 +42,8 @@ class GraphicFormatDetectorTest : public test::BootstrapFixtureBase
void testDetectSVG();
void testDetectSVGZ();
void testDetectPDF();
+ void testMatchArray();
+ void testCheckArrayForMatchingStrings();
CPPUNIT_TEST_SUITE(GraphicFormatDetectorTest);
CPPUNIT_TEST(testDetectMET);
@@ -58,6 +61,8 @@ class GraphicFormatDetectorTest : public test::BootstrapFixtureBase
CPPUNIT_TEST(testDetectSVG);
CPPUNIT_TEST(testDetectSVGZ);
CPPUNIT_TEST(testDetectPDF);
+ CPPUNIT_TEST(testMatchArray);
+ CPPUNIT_TEST(testCheckArrayForMatchingStrings);
CPPUNIT_TEST_SUITE_END();
};
@@ -286,6 +291,107 @@ void GraphicFormatDetectorTest::testDetectPDF()
CPPUNIT_ASSERT_EQUAL(OUString("PDF"), rFormatExtension);
}
+void GraphicFormatDetectorTest::testMatchArray()
+{
+ std::string aString("<?xml version=\"1.0\" standalone=\"no\"?>\n"
+ "<svg width=\"5cm\" height=\"4cm\" version=\"1.1\"\n"
+ "xmlns=\"http://www.w3.org/2000/svg\">\n"
+ "</svg>");
+
+ const char* pCompleteStringPointer = aString.c_str();
+ const char* pMatchPointer;
+ int nCheckSize = aString.size();
+
+ // Check beginning of the input string
+ pMatchPointer = vcl::matchArrayWithString(pCompleteStringPointer, nCheckSize, "<?xml");
+ CPPUNIT_ASSERT(pMatchPointer != nullptr);
+ CPPUNIT_ASSERT_EQUAL(0, int(pMatchPointer - pCompleteStringPointer));
+ CPPUNIT_ASSERT_EQUAL(true, OString(pMatchPointer).startsWith("<?xml"));
+
+ // Check middle of the input string
+ pMatchPointer = vcl::matchArrayWithString(aString.c_str(), nCheckSize, "version");
+ CPPUNIT_ASSERT(pMatchPointer != nullptr);
+ CPPUNIT_ASSERT_EQUAL(6, int(pMatchPointer - pCompleteStringPointer));
+ CPPUNIT_ASSERT_EQUAL(true, OString(pMatchPointer).startsWith("version"));
+
+ pMatchPointer = vcl::matchArrayWithString(aString.c_str(), nCheckSize, "<svg");
+ CPPUNIT_ASSERT(pMatchPointer != nullptr);
+ CPPUNIT_ASSERT_EQUAL(38, int(pMatchPointer - pCompleteStringPointer));
+ CPPUNIT_ASSERT_EQUAL(true, OString(pMatchPointer).startsWith("<svg"));
+
+ // Check end of the input string
+ pMatchPointer = vcl::matchArrayWithString(aString.c_str(), nCheckSize, "/svg>");
+ CPPUNIT_ASSERT(pMatchPointer != nullptr);
+ CPPUNIT_ASSERT_EQUAL(119, int(pMatchPointer - pCompleteStringPointer));
+ CPPUNIT_ASSERT_EQUAL(true, OString(pMatchPointer).startsWith("/svg>"));
+
+ // Check that non-existing search string
+ pMatchPointer = vcl::matchArrayWithString(aString.c_str(), nCheckSize, "none");
+ CPPUNIT_ASSERT(pMatchPointer == nullptr);
+}
+
+void GraphicFormatDetectorTest::testCheckArrayForMatchingStrings()
+{
+ std::string aString("<?xml version=\"1.0\" standalone=\"no\"?>\n"
+ "<svg width=\"5cm\" height=\"4cm\" version=\"1.1\"\n"
+ "xmlns=\"http://www.w3.org/2000/svg\">\n"
+ "</svg>");
+ const char* pCompleteStringPointer = aString.c_str();
+ int nCheckSize = aString.size();
+ bool bResult;
+
+ // check beginning string
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize, { "<?xml" });
+ CPPUNIT_ASSERT_EQUAL(true, bResult);
+
+ // check ending string
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize, { "/svg>" });
+ CPPUNIT_ASSERT_EQUAL(true, bResult);
+
+ // check middle string
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize, { "version" });
+ CPPUNIT_ASSERT_EQUAL(true, bResult);
+
+ // check beginning and then ending string
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize,
+ { "<?xml", "/svg>" });
+ CPPUNIT_ASSERT_EQUAL(true, bResult);
+
+ // check ending and then beginning string
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize,
+ { "/svg>", "<?xml" });
+ CPPUNIT_ASSERT_EQUAL(false, bResult);
+
+ // check middle strings
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize,
+ { "version", "<svg" });
+ CPPUNIT_ASSERT_EQUAL(true, bResult);
+
+ // check beginning, middle and ending strings
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize,
+ { "<?xml", "version", "<svg", "/svg>" });
+ CPPUNIT_ASSERT_EQUAL(true, bResult);
+
+ // check non-existing
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize, { "none" });
+ CPPUNIT_ASSERT_EQUAL(false, bResult);
+
+ // check non-existing on the beginning
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize,
+ { "none", "version", "<svg", "/svg>" });
+ CPPUNIT_ASSERT_EQUAL(false, bResult);
+
+ // check non-existing on the end
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize,
+ { "<?xml", "version", "<svg", "none" });
+ CPPUNIT_ASSERT_EQUAL(false, bResult);
+
+ // check non-existing after the end
+ bResult = vcl::checkArrayForMatchingStrings(pCompleteStringPointer, nCheckSize,
+ { "<?xml", "/svg>", "none" });
+ CPPUNIT_ASSERT_EQUAL(false, bResult);
+}
+
} // namespace
CPPUNIT_TEST_SUITE_REGISTRATION(GraphicFormatDetectorTest);
diff --git a/vcl/source/filter/GraphicFormatDetector.cxx b/vcl/source/filter/GraphicFormatDetector.cxx
index 56624074366e..5682d78f8e3c 100644
--- a/vcl/source/filter/GraphicFormatDetector.cxx
+++ b/vcl/source/filter/GraphicFormatDetector.cxx
@@ -22,6 +22,7 @@
#include <algorithm>
#include <graphic/GraphicFormatDetector.hxx>
+#include <graphic/DetectorTools.hxx>
#include <tools/solar.h>
#include <tools/zcodec.hxx>
@@ -67,23 +68,6 @@ bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen)
return false;
}
-sal_uInt8* searchEntry(sal_uInt8* pSource, const char* pDest, sal_uLong nComp, sal_uLong nSize)
-{
- while (nComp-- >= nSize)
- {
- sal_uLong i;
- for (i = 0; i < nSize; i++)
- {
- if ((pSource[i] & ~0x20) != (pDest[i] & ~0x20))
- break;
- }
- if (i == nSize)
- return pSource;
- pSource++;
- }
- return nullptr;
-}
-
} // end anonymous namespace
GraphicFormatDetector::GraphicFormatDetector(SvStream& rStream, OUString const& rFormatExtension)
@@ -320,13 +304,15 @@ bool GraphicFormatDetector::checkPSD()
bool GraphicFormatDetector::checkEPS()
{
+ const char* pFirstBytesAsCharArray = reinterpret_cast<char*>(maFirstBytes.data());
+
if (mnFirstLong == 0xC5D0D3C6)
{
msDetectedFormat = "EPS";
return true;
}
- else if (searchEntry(maFirstBytes.data(), "%!PS-Adobe", 10, 10)
- && searchEntry(&maFirstBytes[15], "EPS", 3, 3))
+ else if (matchArrayWithString(pFirstBytesAsCharArray, 10, "%!PS-Adobe")
+ && matchArrayWithString(pFirstBytesAsCharArray + 15, 3, "EPS"))
{
msDetectedFormat = "EPS";
return true;
@@ -419,7 +405,8 @@ bool GraphicFormatDetector::checkRAS()
bool GraphicFormatDetector::checkXPM()
{
- if (searchEntry(maFirstBytes.data(), "/* XPM */", 256, 9))
+ const char* pFirstBytesAsCharArray = reinterpret_cast<char*>(maFirstBytes.data());
+ if (matchArrayWithString(pFirstBytesAsCharArray, 256, "/* XPM */"))
{
msDetectedFormat = "XPM";
return true;
@@ -434,15 +421,13 @@ bool GraphicFormatDetector::checkXBM()
mrStream.Seek(mnStreamPosition);
mrStream.ReadBytes(pBuffer.get(), nSize);
- sal_uInt8* pPtr = searchEntry(pBuffer.get(), "#define", nSize, 7);
- if (pPtr)
+ const char* pBufferAsCharArray = reinterpret_cast<char*>(pBuffer.get());
+
+ if (checkArrayForMatchingStrings(pBufferAsCharArray, nSize, { "#define", "_width" }))
{
- if (searchEntry(pPtr, "_width", pBuffer.get() + nSize - pPtr, 6))
- {
- msDetectedFormat = "XBM";
- return true;
- }
+ msDetectedFormat = "XBM";
+ return true;
}
return false;
}
@@ -473,20 +458,20 @@ bool GraphicFormatDetector::checkSVG()
bool bIsSvg(false);
+ const char* pCheckArrayAsCharArray = reinterpret_cast<char*>(pCheckArray);
+
// check for XML
// #119176# SVG files which have no xml header at all have shown up this is optional
// check for "xml" then "version" then "DOCTYPE" and "svg" tags
- if (searchEntry(pCheckArray, "<?xml", nCheckSize, 5)
- && searchEntry(pCheckArray, "version", nCheckSize, 7)
- && searchEntry(pCheckArray, "DOCTYPE", nCheckSize, 7)
- && searchEntry(pCheckArray, "svg", nCheckSize, 3))
+ if (checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize,
+ { "<?xml", "version", "DOCTYPE", "svg" }))
{
bIsSvg = true;
}
// check for svg element in 1st 256 bytes
// search for '<svg'
- if (!bIsSvg && searchEntry(pCheckArray, "<svg", nCheckSize, 4))
+ if (!bIsSvg && checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize, { "<svg" }))
{
bIsSvg = true;
}
@@ -499,7 +484,7 @@ bool GraphicFormatDetector::checkSVG()
// with Svg files containing big comment headers or Svg as the host
// language
- pCheckArray = sExtendedOrDecompressedFirstBytes;
+ pCheckArrayAsCharArray = reinterpret_cast<char*>(sExtendedOrDecompressedFirstBytes);
if (bIsGZip)
{
@@ -513,7 +498,7 @@ bool GraphicFormatDetector::checkSVG()
}
// search for '<svg'
- if (searchEntry(pCheckArray, "<svg", nCheckSize, 4))
+ if (checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize, { "<svg" }))
{
bIsSvg = true;
}
commit e951b2e0bc7aec3cef77d79d075f43a3e60305f7
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sat May 2 00:12:05 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:49 2020 +0200
vcl: Simplify searchEntry in GraphicFormatDetector
Makes the code much more readable..
Change-Id: I99d89652bda4ac74c867d70ec565403510c58c61
diff --git a/vcl/source/filter/GraphicFormatDetector.cxx b/vcl/source/filter/GraphicFormatDetector.cxx
index 1ad825ee47c7..56624074366e 100644
--- a/vcl/source/filter/GraphicFormatDetector.cxx
+++ b/vcl/source/filter/GraphicFormatDetector.cxx
@@ -67,8 +67,7 @@ bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen)
return false;
}
-sal_uInt8* ImplSearchEntry(sal_uInt8* pSource, sal_uInt8 const* pDest, sal_uLong nComp,
- sal_uLong nSize)
+sal_uInt8* searchEntry(sal_uInt8* pSource, const char* pDest, sal_uLong nComp, sal_uLong nSize)
{
while (nComp-- >= nSize)
{
@@ -321,14 +320,18 @@ bool GraphicFormatDetector::checkPSD()
bool GraphicFormatDetector::checkEPS()
{
- if ((mnFirstLong == 0xC5D0D3C6)
- || (ImplSearchEntry(maFirstBytes.data(), reinterpret_cast<sal_uInt8 const*>("%!PS-Adobe"),
- 10, 10)
- && ImplSearchEntry(&maFirstBytes[15], reinterpret_cast<sal_uInt8 const*>("EPS"), 3, 3)))
+ if (mnFirstLong == 0xC5D0D3C6)
{
msDetectedFormat = "EPS";
return true;
}
+ else if (searchEntry(maFirstBytes.data(), "%!PS-Adobe", 10, 10)
+ && searchEntry(&maFirstBytes[15], "EPS", 3, 3))
+ {
+ msDetectedFormat = "EPS";
+ return true;
+ }
+
return false;
}
@@ -416,8 +419,7 @@ bool GraphicFormatDetector::checkRAS()
bool GraphicFormatDetector::checkXPM()
{
- if (ImplSearchEntry(maFirstBytes.data(), reinterpret_cast<sal_uInt8 const*>("/* XPM */"), 256,
- 9))
+ if (searchEntry(maFirstBytes.data(), "/* XPM */", 256, 9))
{
msDetectedFormat = "XPM";
return true;
@@ -432,13 +434,11 @@ bool GraphicFormatDetector::checkXBM()
mrStream.Seek(mnStreamPosition);
mrStream.ReadBytes(pBuffer.get(), nSize);
- sal_uInt8* pPtr
- = ImplSearchEntry(pBuffer.get(), reinterpret_cast<sal_uInt8 const*>("#define"), nSize, 7);
+ sal_uInt8* pPtr = searchEntry(pBuffer.get(), "#define", nSize, 7);
if (pPtr)
{
- if (ImplSearchEntry(pPtr, reinterpret_cast<sal_uInt8 const*>("_width"),
- pBuffer.get() + nSize - pPtr, 6))
+ if (searchEntry(pPtr, "_width", pBuffer.get() + nSize - pPtr, 6))
{
msDetectedFormat = "XBM";
return true;
@@ -473,27 +473,20 @@ bool GraphicFormatDetector::checkSVG()
bool bIsSvg(false);
- // check for Xml
+ // check for XML
// #119176# SVG files which have no xml header at all have shown up this is optional
- if (ImplSearchEntry(pCheckArray, reinterpret_cast<sal_uInt8 const*>("<?xml"), nCheckSize,
- 5) // is it xml
- && ImplSearchEntry(pCheckArray, reinterpret_cast<sal_uInt8 const*>("version"), nCheckSize,
- 7)) // does it have a version (required for xml)
- {
- // check for DOCTYPE svg combination
- if (ImplSearchEntry(pCheckArray, reinterpret_cast<sal_uInt8 const*>("DOCTYPE"), nCheckSize,
- 7) // 'DOCTYPE' is there
- && ImplSearchEntry(pCheckArray, reinterpret_cast<sal_uInt8 const*>("svg"), nCheckSize,
- 3)) // 'svg' is there
- {
- bIsSvg = true;
- }
+ // check for "xml" then "version" then "DOCTYPE" and "svg" tags
+ if (searchEntry(pCheckArray, "<?xml", nCheckSize, 5)
+ && searchEntry(pCheckArray, "version", nCheckSize, 7)
+ && searchEntry(pCheckArray, "DOCTYPE", nCheckSize, 7)
+ && searchEntry(pCheckArray, "svg", nCheckSize, 3))
+ {
+ bIsSvg = true;
}
// check for svg element in 1st 256 bytes
- if (!bIsSvg
- && ImplSearchEntry(pCheckArray, reinterpret_cast<sal_uInt8 const*>("<svg"), nCheckSize,
- 4)) // '<svg'
+ // search for '<svg'
+ if (!bIsSvg && searchEntry(pCheckArray, "<svg", nCheckSize, 4))
{
bIsSvg = true;
}
@@ -519,8 +512,8 @@ bool GraphicFormatDetector::checkSVG()
nCheckSize = mrStream.ReadBytes(sExtendedOrDecompressedFirstBytes, nCheckSize);
}
- if (ImplSearchEntry(pCheckArray, reinterpret_cast<sal_uInt8 const*>("<svg"), nCheckSize,
- 4)) // '<svg'
+ // search for '<svg'
+ if (searchEntry(pCheckArray, "<svg", nCheckSize, 4))
{
bIsSvg = true;
}
commit 2b7896fcfab24c5b2c5efaff8d463d7120dee16d
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Fri May 1 23:52:31 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:49 2020 +0200
vcl: extend TypeSerializerTest for Graphic serialization
Add test case for Animation and GDIMetaFile serialization.
Change-Id: Ibe2fa9982c8faea36e1f26ca9c6b735ae0ebd8ea
diff --git a/vcl/qa/cppunit/TypeSerializerTest.cxx b/vcl/qa/cppunit/TypeSerializerTest.cxx
index c7ad8827a28d..0193ce272142 100644
--- a/vcl/qa/cppunit/TypeSerializerTest.cxx
+++ b/vcl/qa/cppunit/TypeSerializerTest.cxx
@@ -17,6 +17,8 @@
#include <unotest/directories.hxx>
#include <vcl/graph.hxx>
#include <vcl/graphicfilter.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/gdimtf.hxx>
#include <comphelper/hash.hxx>
#include <tools/vcompat.hxx>
#include <comphelper/fileformat.h>
@@ -53,11 +55,15 @@ class TypeSerializerTest : public CppUnit::TestFixture
void testGradient();
void testGraphic_Vector();
void testGraphic_Bitmap_NoGfxLink();
+ void testGraphic_Animation();
+ void testGraphic_GDIMetaFile();
CPPUNIT_TEST_SUITE(TypeSerializerTest);
CPPUNIT_TEST(testGradient);
CPPUNIT_TEST(testGraphic_Vector);
CPPUNIT_TEST(testGraphic_Bitmap_NoGfxLink);
+ CPPUNIT_TEST(testGraphic_Animation);
+ CPPUNIT_TEST(testGraphic_GDIMetaFile);
CPPUNIT_TEST_SUITE_END();
};
@@ -276,6 +282,200 @@ void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink()
}
}
+void TypeSerializerTest::testGraphic_Animation()
+{
+ test::Directories aDirectories;
+ OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "123_Numbers.gif";
+ SvFileStream aStream(aURL, StreamMode::READ);
+ GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
+ Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
+ aGraphic.makeAvailable();
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsAnimated());
+
+ // Test WriteGraphic
+ {
+ SvMemoryStream aMemoryStream;
+ WriteGraphic(aMemoryStream, aGraphic);
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(15167), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("69d0f80832a0aebcbda7ad43ecadf85e99fc1057"),
+ toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ sal_uInt16 nType;
+ aMemoryStream.ReadUInt16(nType);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ ReadGraphic(aMemoryStream, aNewGraphic);
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(true, aNewGraphic.IsAnimated());
+ }
+
+ // Test WriteGraphic - Native Format 5
+ {
+ SvMemoryStream aMemoryStream;
+ aMemoryStream.SetVersion(SOFFICE_FILEFORMAT_50);
+ aMemoryStream.SetCompressMode(SvStreamCompressFlags::NATIVE);
+ WriteGraphic(aMemoryStream, aGraphic);
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(1582), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("da3b9600340fa80a895f2107357e4ab65a9292eb"),
+ toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ sal_uInt32 nType;
+ aMemoryStream.ReadUInt32(nType);
+ CPPUNIT_ASSERT_EQUAL(COMPAT_FORMAT('N', 'A', 'T', '5'), nType);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ ReadGraphic(aMemoryStream, aNewGraphic);
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(true, aNewGraphic.IsAnimated());
+ }
+
+ // Test TypeSerializer
+ {
+ SvMemoryStream aMemoryStream;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.writeGraphic(aGraphic);
+ }
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(15167), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("69d0f80832a0aebcbda7ad43ecadf85e99fc1057"),
+ toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ sal_uInt16 nType;
+ aMemoryStream.ReadUInt16(nType);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.readGraphic(aNewGraphic);
+ }
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(true, aNewGraphic.IsAnimated());
+ }
+
+ // Test TypeSerializer - Native Format 5
+ {
+ SvMemoryStream aMemoryStream;
+ aMemoryStream.SetVersion(SOFFICE_FILEFORMAT_50);
+ aMemoryStream.SetCompressMode(SvStreamCompressFlags::NATIVE);
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.writeGraphic(aGraphic);
+ }
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(1582), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("da3b9600340fa80a895f2107357e4ab65a9292eb"),
+ toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ sal_uInt32 nType;
+ aMemoryStream.ReadUInt32(nType);
+ CPPUNIT_ASSERT_EQUAL(COMPAT_FORMAT('N', 'A', 'T', '5'), nType);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.readGraphic(aNewGraphic);
+ }
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(true, aNewGraphic.IsAnimated());
+ }
+}
+
+void TypeSerializerTest::testGraphic_GDIMetaFile()
+{
+ GDIMetaFile aGDIMetaFile;
+ {
+ ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+ pVirtualDev->SetConnectMetaFile(&aGDIMetaFile);
+ Size aVDSize(10, 10);
+ pVirtualDev->SetOutputSizePixel(aVDSize);
+ pVirtualDev->SetBackground(Wallpaper(COL_LIGHTRED));
+ pVirtualDev->Erase();
+ pVirtualDev->DrawPixel(Point(4, 4));
+ }
+ Graphic aGraphic(aGDIMetaFile);
+ CPPUNIT_ASSERT_EQUAL(GraphicType::GdiMetafile, aGraphic.GetType());
+
+ // Test WriteGraphic
+ {
+ SvMemoryStream aMemoryStream;
+ WriteGraphic(aMemoryStream, aGraphic);
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(229), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("144c518e5149d61ab4bc34643df820372405d61d"),
+ toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ char aIdCharArray[7] = { 0, 0, 0, 0, 0, 0, 0 };
+ aMemoryStream.ReadBytes(aIdCharArray, 6);
+ OString sID(aIdCharArray);
+ CPPUNIT_ASSERT_EQUAL(OString("VCLMTF"), sID);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ ReadGraphic(aMemoryStream, aNewGraphic);
+ CPPUNIT_ASSERT_EQUAL(GraphicType::GdiMetafile, aNewGraphic.GetType());
+ }
+
+ // Test TypeSerializer
+ {
+ SvMemoryStream aMemoryStream;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.writeGraphic(aGraphic);
+ }
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(229), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("144c518e5149d61ab4bc34643df820372405d61d"),
+ toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ char aIdCharArray[7] = { 0, 0, 0, 0, 0, 0, 0 };
+ aMemoryStream.ReadBytes(aIdCharArray, 6);
+ OString sID(aIdCharArray);
+ CPPUNIT_ASSERT_EQUAL(OString("VCLMTF"), sID);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.readGraphic(aNewGraphic);
+ }
+ CPPUNIT_ASSERT_EQUAL(GraphicType::GdiMetafile, aNewGraphic.GetType());
+ }
+}
+
} // namespace
CPPUNIT_TEST_SUITE_REGISTRATION(TypeSerializerTest);
diff --git a/vcl/qa/cppunit/data/123_Numbers.gif b/vcl/qa/cppunit/data/123_Numbers.gif
new file mode 100644
index 000000000000..2e47e28cb4e9
Binary files /dev/null and b/vcl/qa/cppunit/data/123_Numbers.gif differ
commit 9b01545bff99d24e6b72f5d263c28b27dd1acad2
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Fri May 1 19:24:01 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:48 2020 +0200
vcl: add Graphic reading to TypeSerializer + tests
Change-Id: I73aafc4f9a6f964a31d116610df6cf15dc51770c
diff --git a/vcl/inc/TypeSerializer.hxx b/vcl/inc/TypeSerializer.hxx
index 136af57a399a..060876593aa5 100644
--- a/vcl/inc/TypeSerializer.hxx
+++ b/vcl/inc/TypeSerializer.hxx
@@ -26,6 +26,12 @@
#include <vcl/gfxlink.hxx>
#include <vcl/graph.hxx>
+constexpr sal_uInt32 createMagic(char char1, char char2, char char3, char char4)
+{
+ return (static_cast<sal_uInt32>(char1) << 24) | (static_cast<sal_uInt32>(char2) << 16)
+ | (static_cast<sal_uInt32>(char3) << 8) | (static_cast<sal_uInt32>(char4) << 0);
+}
+
class VCL_DLLPUBLIC TypeSerializer : public tools::GenericTypeSerializer
{
public:
diff --git a/vcl/qa/cppunit/TypeSerializerTest.cxx b/vcl/qa/cppunit/TypeSerializerTest.cxx
index 0c737a4c4f03..c7ad8827a28d 100644
--- a/vcl/qa/cppunit/TypeSerializerTest.cxx
+++ b/vcl/qa/cppunit/TypeSerializerTest.cxx
@@ -51,12 +51,12 @@ std::string toHexString(const std::vector<unsigned char>& a)
class TypeSerializerTest : public CppUnit::TestFixture
{
void testGradient();
- void testGraphic();
+ void testGraphic_Vector();
void testGraphic_Bitmap_NoGfxLink();
CPPUNIT_TEST_SUITE(TypeSerializerTest);
CPPUNIT_TEST(testGradient);
- CPPUNIT_TEST(testGraphic);
+ CPPUNIT_TEST(testGraphic_Vector);
CPPUNIT_TEST(testGraphic_Bitmap_NoGfxLink);
CPPUNIT_TEST_SUITE_END();
};
@@ -91,7 +91,7 @@ void TypeSerializerTest::testGradient()
CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aReadGradient.GetSteps());
}
-void TypeSerializerTest::testGraphic()
+void TypeSerializerTest::testGraphic_Vector()
{
test::Directories aDirectories;
OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "SimpleExample.svg";
@@ -99,6 +99,7 @@ void TypeSerializerTest::testGraphic()
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
aGraphic.makeAvailable();
+ BitmapChecksum aChecksum = aGraphic.getVectorGraphicData()->GetChecksum();
// Test WriteGraphic - Native Format 5
{
@@ -117,6 +118,13 @@ void TypeSerializerTest::testGraphic()
sal_uInt32 nType;
aMemoryStream.ReadUInt32(nType);
CPPUNIT_ASSERT_EQUAL(COMPAT_FORMAT('N', 'A', 'T', '5'), nType);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ ReadGraphic(aMemoryStream, aNewGraphic);
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(aChecksum, aNewGraphic.getVectorGraphicData()->GetChecksum());
}
// Test WriteGraphic - Normal
@@ -129,6 +137,18 @@ void TypeSerializerTest::testGraphic()
std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
CPPUNIT_ASSERT_EQUAL(std::string("c2bed2099ce617f1cc035701de5186f0d43e3064"),
toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ sal_uInt32 nType;
+ aMemoryStream.ReadUInt32(nType);
+ CPPUNIT_ASSERT_EQUAL(createMagic('s', 'v', 'g', '0'), nType);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ ReadGraphic(aMemoryStream, aNewGraphic);
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(aChecksum, aNewGraphic.getVectorGraphicData()->GetChecksum());
}
// Test TypeSerializer - Native Format 5
@@ -151,6 +171,16 @@ void TypeSerializerTest::testGraphic()
sal_uInt32 nType;
aMemoryStream.ReadUInt32(nType);
CPPUNIT_ASSERT_EQUAL(COMPAT_FORMAT('N', 'A', 'T', '5'), nType);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.readGraphic(aNewGraphic);
+ }
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(aChecksum, aNewGraphic.getVectorGraphicData()->GetChecksum());
}
// Test TypeSerializer - Normal
@@ -166,6 +196,21 @@ void TypeSerializerTest::testGraphic()
std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
CPPUNIT_ASSERT_EQUAL(std::string("c2bed2099ce617f1cc035701de5186f0d43e3064"),
toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ sal_uInt32 nType;
+ aMemoryStream.ReadUInt32(nType);
+ CPPUNIT_ASSERT_EQUAL(createMagic('s', 'v', 'g', '0'), nType);
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.readGraphic(aNewGraphic);
+ }
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(aChecksum, aNewGraphic.getVectorGraphicData()->GetChecksum());
}
}
@@ -191,6 +236,13 @@ void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink()
sal_uInt16 nType;
aMemoryStream.ReadUInt16(nType);
CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType); // Magic written with WriteDIBBitmapEx
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ ReadGraphic(aMemoryStream, aNewGraphic);
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(aBitmapEx.GetChecksum(), aNewGraphic.GetBitmapExRef().GetChecksum());
}
// Test TypeSerializer
@@ -211,6 +263,16 @@ void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink()
sal_uInt16 nType;
aMemoryStream.ReadUInt16(nType);
CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType); // Magic written with WriteDIBBitmapEx
+
+ // Read it back
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ Graphic aNewGraphic;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.readGraphic(aNewGraphic);
+ }
+ CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType());
+ CPPUNIT_ASSERT_EQUAL(aBitmapEx.GetChecksum(), aNewGraphic.GetBitmapExRef().GetChecksum());
}
}
diff --git a/vcl/source/gdi/TypeSerializer.cxx b/vcl/source/gdi/TypeSerializer.cxx
index 8266c6ac9813..0f1fd0ee43b9 100644
--- a/vcl/source/gdi/TypeSerializer.cxx
+++ b/vcl/source/gdi/TypeSerializer.cxx
@@ -22,6 +22,7 @@
#include <sal/log.hxx>
#include <comphelper/fileformat.h>
#include <vcl/gdimtf.hxx>
+#include <vcl/dibtools.hxx>
TypeSerializer::TypeSerializer(SvStream& rStream)
: GenericTypeSerializer(rStream)
@@ -152,20 +153,171 @@ void TypeSerializer::writeGfxLink(const GfxLink& rGfxLink)
namespace
{
-constexpr sal_uInt32 constSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16)
- | (sal_uInt32('g') << 8) | sal_uInt32('0'));
-constexpr sal_uInt32 constWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16)
- | (sal_uInt32('f') << 8) | sal_uInt32('0'));
-constexpr sal_uInt32 constEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16)
- | (sal_uInt32('f') << 8) | sal_uInt32('0'));
-constexpr sal_uInt32 constPdfMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16)
- | (sal_uInt32('g') << 8) | sal_uInt32('0'));
-
#define NATIVE_FORMAT_50 COMPAT_FORMAT('N', 'A', 'T', '5')
+constexpr sal_uInt32 constSvgMagic = createMagic('s', 'v', 'g', '0');
+constexpr sal_uInt32 constWmfMagic = createMagic('w', 'm', 'f', '0');
+constexpr sal_uInt32 constEmfMagic = createMagic('e', 'm', 'f', '0');
+constexpr sal_uInt32 constPdfMagic = createMagic('p', 'd', 'f', '0');
+
} // end anonymous namespace
-void TypeSerializer::readGraphic(Graphic& /*rGraphic*/) {}
+void TypeSerializer::readGraphic(Graphic& rGraphic)
+{
+ if (mrStream.GetError())
+ return;
+
+ const sal_uLong nInitialStreamPosition = mrStream.Tell();
+ sal_uInt32 nType;
+
+ // read Id
+ mrStream.ReadUInt32(nType);
+
+ // if there is no more data, avoid further expensive
+ // reading which will create VDevs and other stuff, just to
+ // read nothing. CAUTION: Eof is only true AFTER reading another
+ // byte, a speciality of SvMemoryStream (!)
+ if (!mrStream.good())
+ return;
+
+ if (NATIVE_FORMAT_50 == nType)
+ {
+ Graphic aGraphic;
+ GfxLink aLink;
+
+ // read compat info, destructor writes stuff into the header
+ {
+ VersionCompat aCompat(mrStream, StreamMode::READ);
+ }
+
+ readGfxLink(aLink);
+
+ if (!mrStream.GetError() && aLink.LoadNative(aGraphic))
+ {
+ if (aLink.IsPrefMapModeValid())
+ aGraphic.SetPrefMapMode(aLink.GetPrefMapMode());
+
+ if (aLink.IsPrefSizeValid())
+ aGraphic.SetPrefSize(aLink.GetPrefSize());
+ }
+ else
+ {
+ mrStream.Seek(nInitialStreamPosition);
+ mrStream.SetError(ERRCODE_IO_WRONGFORMAT);
+ }
+ rGraphic = aGraphic;
+ }
+ else
+ {
+ BitmapEx aBitmapEx;
+ const SvStreamEndian nOldFormat = mrStream.GetEndian();
+
+ mrStream.SeekRel(-4);
+ mrStream.SetEndian(SvStreamEndian::LITTLE);
+ ReadDIBBitmapEx(aBitmapEx, mrStream);
+
+ if (!mrStream.GetError())
+ {
+ sal_uInt32 nMagic1 = 0;
+ sal_uInt32 nMagic2 = 0;
+ sal_uInt64 nBeginPoisition = mrStream.Tell();
+
+ mrStream.ReadUInt32(nMagic1);
+ mrStream.ReadUInt32(nMagic2);
+ mrStream.Seek(nBeginPoisition);
+
+ if (!mrStream.GetError())
+ {
+ if (nMagic1 == 0x5344414e && nMagic2 == 0x494d4931)
+ {
+ Animation aAnimation;
+ ReadAnimation(mrStream, aAnimation);
+
+ // #108077# manually set loaded BmpEx to Animation
+ // (which skips loading its BmpEx if already done)
+ aAnimation.SetBitmapEx(aBitmapEx);
+ rGraphic = Graphic(aAnimation);
+ }
+ else
+ {
+ rGraphic = Graphic(aBitmapEx);
+ }
+ }
+ else
+ {
+ mrStream.ResetError();
+ }
+ }
+ else
+ {
+ Graphic aGraphic;
+ GDIMetaFile aMetaFile;
+
+ mrStream.Seek(nInitialStreamPosition);
+ mrStream.ResetError();
+ ReadGDIMetaFile(mrStream, aMetaFile);
+
+ if (!mrStream.GetError())
+ {
+ rGraphic = Graphic(aMetaFile);
+ }
+ else
+ {
+ ErrCode nOriginalError = mrStream.GetErrorCode();
+ // try to stream in Svg defining data (length, byte array and evtl. path)
+ // See below (operator<<) for more information
+ sal_uInt32 nMagic;
+ mrStream.Seek(nInitialStreamPosition);
+ mrStream.ResetError();
+ mrStream.ReadUInt32(nMagic);
+
+ if (constSvgMagic == nMagic || constWmfMagic == nMagic || constEmfMagic == nMagic
+ || constPdfMagic == nMagic)
+ {
+ sal_uInt32 nLength = 0;
+ mrStream.ReadUInt32(nLength);
+
+ if (nLength)
+ {
+ VectorGraphicDataArray aData(nLength);
+
+ mrStream.ReadBytes(aData.getArray(), nLength);
+ OUString aPath = mrStream.ReadUniOrByteString(mrStream.GetStreamCharSet());
+
+ if (!mrStream.GetError())
+ {
+ VectorGraphicDataType aDataType(VectorGraphicDataType::Svg);
+
+ switch (nMagic)
+ {
+ case constWmfMagic:
+ aDataType = VectorGraphicDataType::Wmf;
+ break;
+ case constEmfMagic:
+ aDataType = VectorGraphicDataType::Emf;
+ break;
+ case constPdfMagic:
+ aDataType = VectorGraphicDataType::Pdf;
+ break;
+ }
+
+ auto aVectorGraphicDataPtr
+ = std::make_shared<VectorGraphicData>(aData, aPath, aDataType);
+ rGraphic = Graphic(aVectorGraphicDataPtr);
+ }
+ }
+ }
+ else
+ {
+ mrStream.SetError(nOriginalError);
+ }
+
+ mrStream.Seek(nInitialStreamPosition);
+ }
+ }
+ mrStream.SetEndian(nOldFormat);
+ }
+}
void TypeSerializer::writeGraphic(const Graphic& rGraphic)
{
commit c7d3e2cc703f0f4f2483dd643002c207ca88160b
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Fri May 1 17:30:22 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:48 2020 +0200
SdrPdfImport: rename ImportText to InsertTextObject
There are two ImportText methods, so rename one to something
else to avoid confusion.
Change-Id: I1ccc491fca47b2d72ba1f7bd5a75d325819ec041
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 296d2b53f31b..7e4a3e6a5345 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -879,10 +879,10 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTex
mbFntDirty = true;
}
- ImportText(aRect.TopLeft(), aRect.GetSize(), sText);
+ InsertTextObject(aRect.TopLeft(), aRect.GetSize(), sText);
}
-void ImpSdrPdfImport::ImportText(const Point& rPos, const Size& rSize, const OUString& rStr)
+void ImpSdrPdfImport::InsertTextObject(const Point& rPos, const Size& rSize, const OUString& rStr)
{
// calc text box size, add 5% to make it fit safely
diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx
index db5eabe3445d..d9d35fe0c80c 100644
--- a/svx/source/svdraw/svdpdf.hxx
+++ b/svx/source/svdraw/svdpdf.hxx
@@ -110,7 +110,7 @@ class ImpSdrPdfImport final
void ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
void ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
void ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage, int nPageObjectIndex);
- void ImportText(const Point& rPos, const Size& rSize, const OUString& rStr);
+ void InsertTextObject(const Point& rPos, const Size& rSize, const OUString& rStr);
void SetupPageScale(const double dPageWidth, const double dPageHeight);
void SetAttributes(SdrObject* pObj, bool bForceTextAttr = false);
commit 132a63af058c6a07987ea533630b78879e645712
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Fri May 1 17:20:26 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:48 2020 +0200
move unit conversions to UnitConversion, add convertPointToMm100
Change-Id: I3e5a4632e9809562885c1e0ec5c5262acec145d0
diff --git a/include/tools/UnitConversion.hxx b/include/tools/UnitConversion.hxx
new file mode 100644
index 000000000000..8ad489dee590
--- /dev/null
+++ b/include/tools/UnitConversion.hxx
@@ -0,0 +1,25 @@
+/* -*- 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/.
+ *
+ */
+
+#pragma once
+
+constexpr sal_Int64 convertTwipToMm100(sal_Int64 n)
+{
+ return (n >= 0) ? (n * 127 + 36) / 72 : (n * 127 - 36) / 72;
+}
+
+constexpr sal_Int64 convertPointToMm100(sal_Int64 n) { return convertTwipToMm100(n * 20); }
+
+constexpr sal_Int64 convertMm100ToTwip(sal_Int64 n)
+{
+ return (n >= 0) ? (n * 72 + 63) / 127 : (n * 72 - 63) / 127;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/mapunit.hxx b/include/tools/mapunit.hxx
index 2209f4d35261..6112bc7ef461 100644
--- a/include/tools/mapunit.hxx
+++ b/include/tools/mapunit.hxx
@@ -21,6 +21,7 @@
#define INCLUDED_TOOLS_MAPUNIT_HXX
#include <sal/types.h>
+#include <tools/UnitConversion.hxx>
enum class MapUnit
{
@@ -34,16 +35,6 @@ enum class MapUnit
LASTENUMDUMMY // used as an error return
};
-constexpr sal_Int64 convertTwipToMm100(sal_Int64 n)
-{
- return (n >= 0)? (n*127+36)/72: (n*127-36)/72;
-}
-
-constexpr sal_Int64 convertMm100ToTwip(sal_Int64 n)
-{
- return (n >= 0)? (n*72+63)/127: (n*72-63)/127;
-}
-
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 643bde4c761750419af37771e9197b595ef8217f
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu Apr 30 19:07:44 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:47 2020 +0200
SdrPdfImport: fix garbled text at breaking the PDF graphic
The text size of OUString expects no. of characters, but we give
the number of bytes as that is what we get from PDFium. Best to
just not give the text size at all and let OUString determine
that as the text shouldbe terminated correctly.
Change-Id: Icc5cd6e851a9d2920faa9ca2eb6d827465483e72
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 806e82ebf5ac..296d2b53f31b 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -798,16 +798,19 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTex
const tools::Rectangle aRect = PointsToLogic(aTextRect.getMinX(), aTextRect.getMaxX(),
aTextRect.getMinY(), aTextRect.getMaxY());
- const int nChars = FPDFTextObj_GetText(pPageObject, pTextPage, nullptr, 0);
- std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars]);
+ const int nBytes = FPDFTextObj_GetText(pPageObject, pTextPage, nullptr, 0);
+ std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nBytes]);
- const int nActualChars = FPDFTextObj_GetText(pPageObject, pTextPage, pText.get(), nChars);
- if (nActualChars <= 0)
+ const int nActualBytes = FPDFTextObj_GetText(pPageObject, pTextPage, pText.get(), nBytes);
+ if (nActualBytes <= 0)
{
return;
}
- OUString sText(pText.get(), nActualChars);
+ // Let's rely on null-terminaton for the length of the string. We
+ // just know the number of bytes the string takes, but in OUString
+ // needs the number of charaters.
+ OUString sText(pText.get());
const double dFontSize = FPDFTextObj_GetFontSize(pPageObject);
double dFontSizeH = fabs(sqrt2(matrix.a, matrix.c) * dFontSize);
commit 7319a3bcbecd9ffdf0da79148380d8ea86329261
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu Apr 30 13:18:21 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:47 2020 +0200
SdrPdfImport: rename some variables to non-abbreviated names
Change-Id: I1cb004a8e426f8ea26bb930d4897db3763433b31
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index c6a11c16d73f..806e82ebf5ac 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -85,6 +85,7 @@ namespace
/// Here we effectively render at 96 DPI (to match
/// the image rendered in vcl::ImportPDF in pdfread.cxx).
double lcl_PointToPixel(double fPoint) { return fPoint * 96. / 72.; }
+
/// Convert from pixels to logic (twips).
long lcl_ToLogic(double value)
{
@@ -883,21 +884,22 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const Size& rSize, const OUS
// calc text box size, add 5% to make it fit safely
FontMetric aFontMetric(mpVD->GetFontMetric());
- vcl::Font aFnt(mpVD->GetFont());
- FontAlign eAlg(aFnt.GetAlignment());
+ vcl::Font aFont(mpVD->GetFont());
+ FontAlign eAlignment(aFont.GetAlignment());
// sal_Int32 nTextWidth = static_cast<sal_Int32>(mpVD->GetTextWidth(rStr) * mfScaleX);
sal_Int32 nTextHeight = static_cast<sal_Int32>(mpVD->GetTextHeight() * mfScaleY);
- Point aPos(FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()));
+ Point aPosition(FRound(rPos.X() * mfScaleX + maOfs.X()),
+ FRound(rPos.Y() * mfScaleY + maOfs.Y()));
Size aSize(FRound(rSize.Width() * mfScaleX), FRound(rSize.Height() * mfScaleY));
- if (eAlg == ALIGN_BASELINE)
- aPos.AdjustY(-FRound(aFontMetric.GetAscent() * mfScaleY));
- else if (eAlg == ALIGN_BOTTOM)
- aPos.AdjustY(-nTextHeight);
+ if (eAlignment == ALIGN_BASELINE)
+ aPosition.AdjustY(-FRound(aFontMetric.GetAscent() * mfScaleY));
+ else if (eAlignment == ALIGN_BOTTOM)
+ aPosition.AdjustY(-nTextHeight);
- tools::Rectangle aTextRect(aPos, aSize);
+ tools::Rectangle aTextRect(aPosition, aSize);
SdrRectObj* pText = new SdrRectObj(*mpModel, OBJ_TEXT, aTextRect);
pText->SetMergedItem(makeSdrTextUpperDistItem(0));
@@ -905,7 +907,7 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const Size& rSize, const OUS
pText->SetMergedItem(makeSdrTextRightDistItem(0));
pText->SetMergedItem(makeSdrTextLeftDistItem(0));
- if (aFnt.GetAverageFontWidth())
+ if (aFont.GetAverageFontWidth())
{
pText->ClearMergedItem(SDRATTR_TEXT_AUTOGROWWIDTH);
pText->SetMergedItem(makeSdrTextAutoGrowHeightItem(false));
@@ -922,21 +924,21 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const Size& rSize, const OUS
SetAttributes(pText, true);
pText->SetSnapRect(aTextRect);
- if (!aFnt.IsTransparent())
+ if (!aFont.IsTransparent())
{
SfxItemSet aAttr(*mpFillAttr->GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
aAttr.Put(XFillStyleItem(drawing::FillStyle_SOLID));
- aAttr.Put(XFillColorItem(OUString(), aFnt.GetFillColor()));
+ aAttr.Put(XFillColorItem(OUString(), aFont.GetFillColor()));
pText->SetMergedItemSet(aAttr);
}
- sal_uInt32 nAngle = aFnt.GetOrientation();
+ sal_uInt32 nAngle = aFont.GetOrientation();
if (nAngle)
{
nAngle *= 10;
double a = nAngle * F_PI18000;
double nSin = sin(a);
double nCos = cos(a);
- pText->NbcRotate(aPos, nAngle, nSin, nCos);
+ pText->NbcRotate(aPosition, nAngle, nSin, nCos);
}
InsertObj(pText, false);
}
commit fb9e9e30852d110532bd32f8e34600a610806d52
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu Apr 30 10:48:44 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:47 2020 +0200
vcl: add Graphic serialization (writing) to TypeSerializer + tests
Change-Id: I3c4845550e776c4c2c891d94db71bacea27c9a37
diff --git a/vcl/inc/TypeSerializer.hxx b/vcl/inc/TypeSerializer.hxx
index befd4edd7660..136af57a399a 100644
--- a/vcl/inc/TypeSerializer.hxx
+++ b/vcl/inc/TypeSerializer.hxx
@@ -24,6 +24,7 @@
#include <tools/GenericTypeSerializer.hxx>
#include <vcl/gradient.hxx>
#include <vcl/gfxlink.hxx>
+#include <vcl/graph.hxx>
class VCL_DLLPUBLIC TypeSerializer : public tools::GenericTypeSerializer
{
@@ -35,6 +36,9 @@ public:
void readGfxLink(GfxLink& rGfxLink);
void writeGfxLink(const GfxLink& rGfxLink);
+
+ void readGraphic(Graphic& rGraphic);
+ void writeGraphic(const Graphic& rGraphic);
};
#endif
diff --git a/vcl/qa/cppunit/TypeSerializerTest.cxx b/vcl/qa/cppunit/TypeSerializerTest.cxx
index e5d3a259f803..0c737a4c4f03 100644
--- a/vcl/qa/cppunit/TypeSerializerTest.cxx
+++ b/vcl/qa/cppunit/TypeSerializerTest.cxx
@@ -130,6 +130,43 @@ void TypeSerializerTest::testGraphic()
CPPUNIT_ASSERT_EQUAL(std::string("c2bed2099ce617f1cc035701de5186f0d43e3064"),
toHexString(aHash));
}
+
+ // Test TypeSerializer - Native Format 5
+ {
+ SvMemoryStream aMemoryStream;
+ aMemoryStream.SetVersion(SOFFICE_FILEFORMAT_50);
+ aMemoryStream.SetCompressMode(SvStreamCompressFlags::NATIVE);
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.writeGraphic(aGraphic);
+ }
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(290), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("ee55ab6faa73b61b68bc3d5628d95f0d3c528e2a"),
+ toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ sal_uInt32 nType;
+ aMemoryStream.ReadUInt32(nType);
+ CPPUNIT_ASSERT_EQUAL(COMPAT_FORMAT('N', 'A', 'T', '5'), nType);
+ }
+
+ // Test TypeSerializer - Normal
+ {
+ SvMemoryStream aMemoryStream;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.writeGraphic(aGraphic);
+ }
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(233), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("c2bed2099ce617f1cc035701de5186f0d43e3064"),
+ toHexString(aHash));
+ }
}
void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink()
@@ -155,6 +192,26 @@ void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink()
aMemoryStream.ReadUInt16(nType);
CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType); // Magic written with WriteDIBBitmapEx
}
+
+ // Test TypeSerializer
+ {
+ SvMemoryStream aMemoryStream;
+ {
+ TypeSerializer aSerializer(aMemoryStream);
+ aSerializer.writeGraphic(aGraphic);
+ }
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt64(383), aMemoryStream.remainingSize());
+ std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+ CPPUNIT_ASSERT_EQUAL(std::string("da831418499146d51bf245fadf60b9111faa76c2"),
+ toHexString(aHash));
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ sal_uInt16 nType;
+ aMemoryStream.ReadUInt16(nType);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType); // Magic written with WriteDIBBitmapEx
+ }
}
} // namespace
diff --git a/vcl/source/gdi/TypeSerializer.cxx b/vcl/source/gdi/TypeSerializer.cxx
index ad2f1400da85..8266c6ac9813 100644
--- a/vcl/source/gdi/TypeSerializer.cxx
+++ b/vcl/source/gdi/TypeSerializer.cxx
@@ -20,6 +20,8 @@
#include <TypeSerializer.hxx>
#include <tools/vcompat.hxx>
#include <sal/log.hxx>
+#include <comphelper/fileformat.h>
+#include <vcl/gdimtf.hxx>
TypeSerializer::TypeSerializer(SvStream& rStream)
: GenericTypeSerializer(rStream)
@@ -148,4 +150,119 @@ void TypeSerializer::writeGfxLink(const GfxLink& rGfxLink)
}
}
+namespace
+{
+constexpr sal_uInt32 constSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16)
+ | (sal_uInt32('g') << 8) | sal_uInt32('0'));
+constexpr sal_uInt32 constWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16)
+ | (sal_uInt32('f') << 8) | sal_uInt32('0'));
+constexpr sal_uInt32 constEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16)
+ | (sal_uInt32('f') << 8) | sal_uInt32('0'));
+constexpr sal_uInt32 constPdfMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16)
+ | (sal_uInt32('g') << 8) | sal_uInt32('0'));
+
+#define NATIVE_FORMAT_50 COMPAT_FORMAT('N', 'A', 'T', '5')
+
+} // end anonymous namespace
+
+void TypeSerializer::readGraphic(Graphic& /*rGraphic*/) {}
+
+void TypeSerializer::writeGraphic(const Graphic& rGraphic)
+{
+ Graphic aGraphic(rGraphic);
+
+ if (!aGraphic.makeAvailable())
+ return;
+
+ auto pGfxLink = aGraphic.GetSharedGfxLink();
+
+ if (mrStream.GetVersion() >= SOFFICE_FILEFORMAT_50
+ && (mrStream.GetCompressMode() & SvStreamCompressFlags::NATIVE) && pGfxLink
+ && pGfxLink->IsNative())
+ {
+ // native format
+ mrStream.WriteUInt32(NATIVE_FORMAT_50);
+
+ // write compat info, destructor writes stuff into the header
+ {
+ VersionCompat aCompat(mrStream, StreamMode::WRITE, 1);
+ }
+ pGfxLink->SetPrefMapMode(aGraphic.GetPrefMapMode());
+ pGfxLink->SetPrefSize(aGraphic.GetPrefSize());
+ writeGfxLink(*pGfxLink);
+ }
+ else
+ {
+ // own format
+ const SvStreamEndian nOldFormat = mrStream.GetEndian();
+ mrStream.SetEndian(SvStreamEndian::LITTLE);
+
+ switch (aGraphic.GetType())
+ {
+ case GraphicType::NONE:
+ case GraphicType::Default:
+ break;
+
+ case GraphicType::Bitmap:
+ {
+ auto pVectorGraphicData = aGraphic.getVectorGraphicData();
+ if (pVectorGraphicData)
+ {
+ // stream out Vector Graphic defining data (length, byte array and evtl. path)
+ // this is used e.g. in swapping out graphic data and in transporting it over UNO API
+ // as sequence of bytes, but AFAIK not written anywhere to any kind of file, so it should be
+ // no problem to extend it; only used at runtime
+ switch (pVectorGraphicData->getVectorGraphicDataType())
+ {
+ case VectorGraphicDataType::Wmf:
+ {
+ mrStream.WriteUInt32(constWmfMagic);
+ break;
+ }
+ case VectorGraphicDataType::Emf:
+ {
+ mrStream.WriteUInt32(constEmfMagic);
+ break;
+ }
+ case VectorGraphicDataType::Svg:
+ {
+ mrStream.WriteUInt32(constSvgMagic);
+ break;
+ }
+ case VectorGraphicDataType::Pdf:
+ {
+ mrStream.WriteUInt32(constPdfMagic);
+ break;
+ }
+ }
+
+ sal_uInt32 nSize = pVectorGraphicData->getVectorGraphicDataArrayLength();
+ mrStream.WriteUInt32(nSize);
+ mrStream.WriteBytes(
+ pVectorGraphicData->getVectorGraphicDataArray().getConstArray(), nSize);
+ mrStream.WriteUniOrByteString(pVectorGraphicData->getPath(),
+ mrStream.GetStreamCharSet());
+ }
+ else if (aGraphic.IsAnimated())
+ {
+ WriteAnimation(mrStream, aGraphic.GetAnimation());
+ }
+ else
+ {
+ WriteDIBBitmapEx(aGraphic.GetBitmapEx(), mrStream);
+ }
+ }
+ break;
+
+ default:
+ {
+ if (aGraphic.IsSupportedGraphic())
+ WriteGDIMetaFile(mrStream, rGraphic.GetGDIMetaFile());
+ }
+ break;
+ }
+ mrStream.SetEndian(nOldFormat);
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit fb88521c88d7f7a01796c6deeab8f4470e84a224
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu Apr 30 10:42:56 2020 +0200
Commit: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
CommitDate: Sat May 2 19:41:46 2020 +0200
vcl: test Graphic serialization to a stream - WriteGraphic funct.
Change-Id: Ic365d27e9ef1c676e47de22b8949b5679c0a2841
diff --git a/vcl/CppunitTest_vcl_type_serializer_test.mk b/vcl/CppunitTest_vcl_type_serializer_test.mk
index aa4a36e2ee32..b2d78c34a6a1 100644
--- a/vcl/CppunitTest_vcl_type_serializer_test.mk
+++ b/vcl/CppunitTest_vcl_type_serializer_test.mk
@@ -33,18 +33,9 @@ $(eval $(call gb_CppunitTest_use_libraries,vcl_type_serializer_test, \
))
$(eval $(call gb_CppunitTest_use_sdk_api,vcl_type_serializer_test))
-
+$(eval $(call gb_CppunitTest_use_rdb,vcl_type_serializer_test,services))
$(eval $(call gb_CppunitTest_use_ure,vcl_type_serializer_test))
$(eval $(call gb_CppunitTest_use_vcl,vcl_type_serializer_test))
-
-$(eval $(call gb_CppunitTest_use_components,vcl_type_serializer_test,\
- configmgr/source/configmgr \
- i18npool/util/i18npool \
- ucb/source/core/ucb1 \
- ucb/source/ucp/file/ucpfile1 \
- uui/util/uui \
-))
-
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list