diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2021-02-14 22:26:00 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2021-02-17 02:43:45 +0100 |
commit | 4d22e3ce32959d795a90653807c1c19cc9c1838e (patch) | |
tree | 2c643edebb6d967ad38800c05b63de584c1a72ff /filter | |
parent | 246af1d40ec515fe31ef2ac3375401c3fe284157 (diff) |
Move PICT reader from filter module into VCL
Change-Id: I6d3a28769ff3bffa3970a4ab6ab2384bb0aebbca
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111011
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'filter')
21 files changed, 11 insertions, 2528 deletions
diff --git a/filter/CppunitTest_filter_pict_test.mk b/filter/CppunitTest_filter_pict_test.mk deleted file mode 100644 index 431166e6e3cd..000000000000 --- a/filter/CppunitTest_filter_pict_test.mk +++ /dev/null @@ -1,50 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# -# 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/. -# -$(eval $(call gb_CppunitTest_CppunitTest,filter_pict_test)) - -$(eval $(call gb_CppunitTest_use_externals,filter_pict_test,\ - boost_headers \ - libxml2 \ -)) - -$(eval $(call gb_CppunitTest_add_exception_objects,filter_pict_test, \ - filter/qa/cppunit/filters-pict-test \ -)) - -$(eval $(call gb_CppunitTest_use_libraries,filter_pict_test, \ - cppu \ - comphelper \ - basegfx \ - sal \ - salhelper \ - test \ - tk \ - tl \ - utl \ - unotest \ - vcl \ -)) - -$(eval $(call gb_CppunitTest_use_library_objects,filter_pict_test, \ - gie \ -)) - -$(eval $(call gb_CppunitTest_use_sdk_api,filter_pict_test)) - -$(eval $(call gb_CppunitTest_use_ure,filter_pict_test)) -$(eval $(call gb_CppunitTest_use_vcl,filter_pict_test)) - -$(eval $(call gb_CppunitTest_use_components,filter_pict_test,\ - configmgr/source/configmgr \ - i18npool/util/i18npool \ -)) - -$(eval $(call gb_CppunitTest_use_configuration,filter_pict_test)) - -# vim: set noet sw=4 ts=4: diff --git a/filter/Library_gie.mk b/filter/Library_gie.mk index be60d68e3de7..4f383a0770bd 100644 --- a/filter/Library_gie.mk +++ b/filter/Library_gie.mk @@ -52,8 +52,6 @@ $(eval $(call gb_Library_add_exception_objects,gie,\ filter/source/graphicfilter/egif/egif \ filter/source/graphicfilter/eps/eps \ filter/source/graphicfilter/egif/giflzwc \ - filter/source/graphicfilter/ipict/ipict \ - filter/source/graphicfilter/ipict/shape \ filter/source/graphicfilter/ipcx/ipcx \ filter/source/graphicfilter/iras/iras \ filter/source/graphicfilter/ieps/ieps \ diff --git a/filter/Module_filter.mk b/filter/Module_filter.mk index a998c65b60ab..18481a33c0e1 100644 --- a/filter/Module_filter.mk +++ b/filter/Module_filter.mk @@ -60,7 +60,6 @@ $(eval $(call gb_Module_add_check_targets,filter,\ CppunitTest_filter_met_test \ CppunitTest_filter_pcd_test \ CppunitTest_filter_pcx_test \ - CppunitTest_filter_pict_test \ CppunitTest_filter_ppm_test \ CppunitTest_filter_psd_test \ CppunitTest_filter_ras_test \ diff --git a/filter/qa/cppunit/data/pict/clipping-problem.pct b/filter/qa/cppunit/data/pict/clipping-problem.pct Binary files differdeleted file mode 100644 index 37fe66c80f7a..000000000000 --- a/filter/qa/cppunit/data/pict/clipping-problem.pct +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/fail/.gitignore b/filter/qa/cppunit/data/pict/fail/.gitignore deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/filter/qa/cppunit/data/pict/fail/.gitignore +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/fail/CVE-2008-1097-1.pct b/filter/qa/cppunit/data/pict/fail/CVE-2008-1097-1.pct Binary files differdeleted file mode 100644 index 73943c9d79b9..000000000000 --- a/filter/qa/cppunit/data/pict/fail/CVE-2008-1097-1.pct +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/fail/CVE-2012-0277-1.pct b/filter/qa/cppunit/data/pict/fail/CVE-2012-0277-1.pct Binary files differdeleted file mode 100644 index 5683a55b5f1d..000000000000 --- a/filter/qa/cppunit/data/pict/fail/CVE-2012-0277-1.pct +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/fail/CVE-2013-2577-1.pct b/filter/qa/cppunit/data/pict/fail/CVE-2013-2577-1.pct Binary files differdeleted file mode 100644 index 1e1f6d5b5f05..000000000000 --- a/filter/qa/cppunit/data/pict/fail/CVE-2013-2577-1.pct +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/fail/EDB-19332-1.pct b/filter/qa/cppunit/data/pict/fail/EDB-19332-1.pct Binary files differdeleted file mode 100644 index 5f8740305076..000000000000 --- a/filter/qa/cppunit/data/pict/fail/EDB-19332-1.pct +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/fail/exception-1.pct b/filter/qa/cppunit/data/pict/fail/exception-1.pct Binary files differdeleted file mode 100644 index f9cd85a4aece..000000000000 --- a/filter/qa/cppunit/data/pict/fail/exception-1.pct +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/fail/hang-1.pct b/filter/qa/cppunit/data/pict/fail/hang-1.pct Binary files differdeleted file mode 100644 index 735ce0aca7f3..000000000000 --- a/filter/qa/cppunit/data/pict/fail/hang-1.pct +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/indeterminate/.gitignore b/filter/qa/cppunit/data/pict/indeterminate/.gitignore deleted file mode 100644 index 1bdee77373fa..000000000000 --- a/filter/qa/cppunit/data/pict/indeterminate/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.pict-* -*.pct-* diff --git a/filter/qa/cppunit/data/pict/pass/.gitignore b/filter/qa/cppunit/data/pict/pass/.gitignore deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/filter/qa/cppunit/data/pict/pass/.gitignore +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/pass/ooo25876-2.pct b/filter/qa/cppunit/data/pict/pass/ooo25876-2.pct Binary files differdeleted file mode 100644 index 9807e36f74cb..000000000000 --- a/filter/qa/cppunit/data/pict/pass/ooo25876-2.pct +++ /dev/null diff --git a/filter/qa/cppunit/data/pict/pass/tdf92789.pct b/filter/qa/cppunit/data/pict/pass/tdf92789.pct Binary files differdeleted file mode 100644 index 2d6f0d8848bf..000000000000 --- a/filter/qa/cppunit/data/pict/pass/tdf92789.pct +++ /dev/null diff --git a/filter/qa/cppunit/filters-pict-test.cxx b/filter/qa/cppunit/filters-pict-test.cxx deleted file mode 100644 index b4f0432441db..000000000000 --- a/filter/qa/cppunit/filters-pict-test.cxx +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- 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/. - */ - -#include <unotest/filters-test.hxx> -#include <test/bootstrapfixture.hxx> -#include <vcl/FilterConfigItem.hxx> -#include <test/xmltesttools.hxx> -#include <tools/stream.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/graph.hxx> -#include <vcl/metaactiontypes.hxx> - -#include "../../source/graphicfilter/ipict/ipict.hxx" - -extern "C" -{ - SAL_DLLPUBLIC_EXPORT bool SAL_CALL - iptGraphicImport(SvStream & rStream, Graphic & rGraphic, - FilterConfigItem*); -} - -using namespace ::com::sun::star; - -/* Implementation of Filters test */ - -class PictFilterTest - : public test::FiltersTest - , public test::BootstrapFixture - , public XmlTestTools -{ -public: - PictFilterTest() : BootstrapFixture(true, false) {} - - virtual bool load(const OUString &, - const OUString &rURL, const OUString &, - SfxFilterFlags, SotClipboardFormatId, unsigned int) override; - - OUString pictURL() - { - return m_directories.getURLFromSrc(u"/filter/qa/cppunit/data/pict/"); - } - - /** - * Ensure CVEs remain unbroken - */ - void testCVEs(); - - void testDontClipTooMuch(); - - CPPUNIT_TEST_SUITE(PictFilterTest); - CPPUNIT_TEST(testCVEs); - CPPUNIT_TEST(testDontClipTooMuch); - CPPUNIT_TEST_SUITE_END(); -}; - -bool PictFilterTest::load(const OUString &, - const OUString &rURL, const OUString &, - SfxFilterFlags, SotClipboardFormatId, unsigned int) -{ - SvFileStream aFileStream(rURL, StreamMode::READ); - Graphic aGraphic; - return iptGraphicImport(aFileStream, aGraphic, nullptr); -} - -void PictFilterTest::testCVEs() -{ - testDir(OUString(), - pictURL()); -} - -void PictFilterTest::testDontClipTooMuch() -{ - SvFileStream aFileStream(pictURL() + "clipping-problem.pct", StreamMode::READ); - GDIMetaFile aGDIMetaFile; - pict::ReadPictFile(aFileStream, aGDIMetaFile); - - MetafileXmlDump dumper; - dumper.filterAllActionTypes(); - dumper.filterActionType(MetaActionType::CLIPREGION, false); - xmlDocUniquePtr pDoc = dumpAndParse(dumper, aGDIMetaFile); - - CPPUNIT_ASSERT (pDoc); - - assertXPath(pDoc, "/metafile/clipregion[5]", "top", "0"); - assertXPath(pDoc, "/metafile/clipregion[5]", "left", "0"); - assertXPath(pDoc, "/metafile/clipregion[5]", "bottom", "empty"); - assertXPath(pDoc, "/metafile/clipregion[5]", "right", "empty"); -} - -CPPUNIT_TEST_SUITE_REGISTRATION(PictFilterTest); - -CPPUNIT_PLUGIN_IMPLEMENT(); - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/filter/source/config/fragments/internalgraphicfilters/pct_Import.xcu b/filter/source/config/fragments/internalgraphicfilters/pct_Import.xcu index 63048f9b4eb2..974bb330066b 100644 --- a/filter/source/config/fragments/internalgraphicfilters/pct_Import.xcu +++ b/filter/source/config/fragments/internalgraphicfilters/pct_Import.xcu @@ -15,13 +15,14 @@ * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . --> - <node oor:name="pct_Import" oor:op="replace" > - <prop oor:name="Type"><value>pct_Mac_Pict</value></prop> - <prop oor:name="FormatName"><value>ipt</value></prop> - <prop oor:name="RealFilterName"><value>PCT - Mac Pict</value></prop> - <prop oor:name="UIComponent"/> - <prop oor:name="UIName"> - <value xml:lang="en-US">PCT - Mac Pict</value> - </prop> - <prop oor:name="Flags"><value>IMPORT</value></prop> - </node> + +<node oor:name="pct_Import" oor:op="replace" > + <prop oor:name="Type"><value>pct_Mac_Pict</value></prop> + <prop oor:name="FormatName"><value>SVPICT</value></prop> + <prop oor:name="RealFilterName"><value>PCT - Mac Pict</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UIName"> + <value xml:lang="en-US">PCT - Mac Pict</value> + </prop> + <prop oor:name="Flags"><value>IMPORT</value></prop> +</node> diff --git a/filter/source/graphicfilter/ipict/ipict.cxx b/filter/source/graphicfilter/ipict/ipict.cxx deleted file mode 100644 index 16b5c3f6be6e..000000000000 --- a/filter/source/graphicfilter/ipict/ipict.cxx +++ /dev/null @@ -1,2021 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <string.h> -#include <osl/thread.h> -#include <sal/log.hxx> -#include <vcl/BitmapTools.hxx> -#include <vcl/graph.hxx> -#include <vcl/gdimtf.hxx> -#include <tools/poly.hxx> -#include <tools/fract.hxx> -#include <tools/stream.hxx> -#include <vcl/virdev.hxx> -#include <math.h> - -#include "ipict.hxx" -#include "shape.hxx" -#include <memory> - -#include <vcl/FilterConfigItem.hxx> - // complete FilterConfigItem for GraphicImport under -fsanitize=function - -namespace PictReaderInternal { - namespace { - - //! utilitary class to store a pattern, ... - class Pattern { - public: - //! constructor - Pattern() : penStyle(PEN_SOLID), - brushStyle(BRUSH_SOLID), - nBitCount(64), - isColor(false), - isRead(false) - {} - - //! reads black/white pattern from SvStream - sal_uInt8 read(SvStream &stream); - //! sets the color - void setColor(Color col) { isColor = true; color = col; } - /** returns a color which can be "used" to replace the pattern, - * created from ForeColor and BackColor, ... - * - * note: maybe, we must also use some mode PatCopy, ... to define the color - */ - Color getColor(Color bkColor, Color fgColor) const { - if (isColor) return color; - // we create a gray pattern from nBitCount - double alpha = nBitCount / 64.0; - return Color(sal_uInt8(alpha*fgColor.GetRed()+(1.0-alpha)*bkColor.GetRed()), - sal_uInt8(alpha*fgColor.GetGreen()+(1.0-alpha)*bkColor.GetGreen()), - sal_uInt8(alpha*fgColor.GetBlue()+(1.0-alpha)*bkColor.GetBlue())); - } - - //! returns true if this is the default pattern - bool isDefault() const { return !isRead; } - - enum PenStyle { PEN_NULL, PEN_SOLID, PEN_DOT, PEN_DASH, PEN_DASHDOT }; - enum BrushStyle { BRUSH_SOLID, BRUSH_HORZ, BRUSH_VERT, - BRUSH_CROSS, BRUSH_DIAGCROSS, BRUSH_UPDIAG, BRUSH_DOWNDIAG, - BRUSH_25, BRUSH_50, BRUSH_75 }; - // Data - enum PenStyle penStyle; - enum BrushStyle brushStyle; - short nBitCount; - - bool isColor; // true if it is a color pattern - Color color; - - protected: - // flag to know if the pattern came from reading the picture, or if it is the default pattern - bool isRead; - }; - - } - - sal_uInt8 Pattern::read(SvStream &stream) { - unsigned char nbyte[8]; - sal_uInt32 nHiBytes, nLoBytes; - isColor = false; - - // count the no of bits in pattern which are set to 1: - nBitCount=0; - for (unsigned char & ny : nbyte) { - stream.ReadChar( reinterpret_cast<char&>(ny) ); - for (short nx=0; nx<8; nx++) { - if ( (ny & (1<<nx)) != 0 ) nBitCount++; - } - } - - // store pattern in 2 long words: - nHiBytes=(((((static_cast<sal_uInt32>(nbyte[0])<<8)| - static_cast<sal_uInt32>(nbyte[1]))<<8)| - static_cast<sal_uInt32>(nbyte[2]))<<8)| - static_cast<sal_uInt32>(nbyte[3]); - nLoBytes=(((((static_cast<sal_uInt32>(nbyte[4])<<8)| - static_cast<sal_uInt32>(nbyte[5]))<<8)| - static_cast<sal_uInt32>(nbyte[6]))<<8)| - static_cast<sal_uInt32>(nbyte[7]); - - // create a PenStyle: - if (nBitCount<=0) penStyle=PEN_NULL; - else if (nBitCount<=16) penStyle=PEN_DOT; - else if (nBitCount<=32) penStyle=PEN_DASHDOT; - else if (nBitCount<=48) penStyle=PEN_DASH; - else penStyle=PEN_SOLID; - - // create a BrushStyle: - if (nHiBytes==0xffffffff && nLoBytes==0xffffffff) brushStyle=BRUSH_SOLID; - else if (nHiBytes==0xff000000 && nLoBytes==0x00000000) brushStyle=BRUSH_HORZ; - else if (nHiBytes==0x80808080 && nLoBytes==0x80808080) brushStyle=BRUSH_VERT; - else if (nHiBytes==0xff808080 && nLoBytes==0x80808080) brushStyle=BRUSH_CROSS; - else if (nHiBytes==0x01824428 && nLoBytes==0x10284482) brushStyle=BRUSH_DIAGCROSS; - else if (nHiBytes==0x80402010 && nLoBytes==0x08040201) brushStyle=BRUSH_UPDIAG; - else if (nHiBytes==0x01020408 && nLoBytes==0x10204080) brushStyle=BRUSH_DOWNDIAG; - else if (nBitCount<=24) brushStyle=BRUSH_25; - else if (nBitCount<=40) brushStyle=BRUSH_50; - else if (nBitCount<=56) brushStyle=BRUSH_75; - else brushStyle=BRUSH_SOLID; - - isRead = true; - - return 8; - } -} - -//============================ PictReader ================================== - -namespace { - -enum class PictDrawingMethod { - FRAME, PAINT, ERASE, INVERT, FILL, - TEXT, UNDEFINED -}; - -class PictReader { - typedef class PictReaderInternal::Pattern Pattern; -private: - - SvStream * pPict; // The Pict file to read. - VclPtr<VirtualDevice> pVirDev; // Here the drawing method will be called. - // A recording into the GDIMetaFile will take place. - - sal_uInt64 nOrigPos; // Initial position in pPict. - bool IsVersion2; // If it is a version 2 Pictfile. - tools::Rectangle aBoundingRect; // Min/Max-Rectangle for the whole drawing. - - Point aPenPosition; - Point aTextPosition; - Color aActForeColor; - Color aActBackColor; - Pattern eActPenPattern; - Pattern eActFillPattern; - Pattern eActBackPattern; - Size nActPenSize; - // Note: Postscript mode is stored by setting eActRop to RasterOp::N1 - RasterOp eActROP; - PictDrawingMethod eActMethod; - Size aActOvalSize; - vcl::Font aActFont; - - Fraction aHRes; - Fraction aVRes; - - Point ReadPoint(); - - Point ReadDeltaH(Point aBase); - Point ReadDeltaV(Point aBase); - - Point ReadUnsignedDeltaH(Point aBase); - Point ReadUnsignedDeltaV(Point aBase); - - Size ReadSize(); - - Color ReadColor(); - - Color ReadRGBColor(); - - void ReadRectangle(tools::Rectangle & rRect); - - sal_uInt64 ReadPolygon(tools::Polygon & rPoly); - - sal_uInt64 ReadPixPattern(Pattern &pattern); - - tools::Rectangle aLastRect; - sal_uInt8 ReadAndDrawRect(PictDrawingMethod eMethod); - sal_uInt8 ReadAndDrawSameRect(PictDrawingMethod eMethod); - - tools::Rectangle aLastRoundRect; - sal_uInt8 ReadAndDrawRoundRect(PictDrawingMethod eMethod); - sal_uInt8 ReadAndDrawSameRoundRect(PictDrawingMethod eMethod); - - tools::Rectangle aLastOval; - sal_uInt8 ReadAndDrawOval(PictDrawingMethod eMethod); - sal_uInt8 ReadAndDrawSameOval(PictDrawingMethod eMethod); - - tools::Polygon aLastPolygon; - sal_uInt64 ReadAndDrawPolygon(PictDrawingMethod eMethod); - sal_uInt8 ReadAndDrawSamePolygon(PictDrawingMethod eMethod); - - tools::Rectangle aLastArcRect; - sal_uInt8 ReadAndDrawArc(PictDrawingMethod eMethod); - sal_uInt8 ReadAndDrawSameArc(PictDrawingMethod eMethod); - - sal_uInt64 ReadAndDrawRgn(PictDrawingMethod eMethod); - sal_uInt8 ReadAndDrawSameRgn(PictDrawingMethod eMethod); - - // returns true if there's no need to print the shape/text/frame - bool IsInvisible( PictDrawingMethod eMethod ) const { - if ( eActROP == RasterOp::N1 ) return true; - if ( eMethod == PictDrawingMethod::FRAME && nActPenSize.IsEmpty() ) return true; - return false; - } - - void DrawingMethod(PictDrawingMethod eMethod); - - sal_uInt64 ReadAndDrawText(); - - sal_uInt64 ReadPixMapEtc(BitmapEx & rBitmap, bool bBaseAddr, bool bColorTable, - tools::Rectangle * pSrcRect, tools::Rectangle * pDestRect, - bool bMode, bool bMaskRgn); - - void ReadHeader(); - // Reads the header of the Pict file, set IsVersion and aBoundingRect - - sal_uInt64 ReadData(sal_uInt16 nOpcode); - // Reads the date of anOopcode and executes the operation. - // The number of data bytes belonging to the opcode will be returned - // in any case. - - void SetLineColor( const Color& rColor ); - void SetFillColor( const Color& rColor ); - - // OSNOLA: returns the text encoding which must be used for system id - static rtl_TextEncoding GetTextEncoding (sal_uInt16 fId = 0xFFFF); - -public: - - PictReader() - : pPict(nullptr) - , pVirDev(nullptr) - , nOrigPos(0) - , IsVersion2(false) - , eActROP(RasterOp::OverPaint) - , eActMethod(PictDrawingMethod::UNDEFINED) - { - aActFont.SetCharSet(GetTextEncoding()); - } - - void ReadPict( SvStream & rStreamPict, GDIMetaFile & rGDIMetaFile ); - // reads a pict file from the stream and fills the GDIMetaFile - -}; - -} - -static void SetByte(sal_uInt16& nx, sal_uInt16 ny, vcl::bitmap::RawBitmap& rBitmap, sal_uInt16 nPixelSize, sal_uInt8 nDat, sal_uInt16 nWidth, std::vector<Color> const & rvPalette) -{ - switch (nPixelSize) - { - case 1: - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 7) & 1]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 6) & 1]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 5) & 1]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 4) & 1]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 3) & 1]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 2) & 1]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 1) & 1]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[nDat & 1]); - break; - case 2: - rBitmap.SetPixel(ny, nx++, rvPalette[nDat >> 6]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat>>4)&3]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[(nDat>>2)&3]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[nDat & 3]); - break; - case 4: - rBitmap.SetPixel(ny, nx++, rvPalette[nDat >> 4]); - if ( nx == nWidth ) break; - rBitmap.SetPixel(ny, nx++, rvPalette[nDat & 0x0f]); - break; - case 8: - rBitmap.SetPixel(ny, nx++, rvPalette[nDat]); - break; - } -} - -//=================== methods of PictReader ============================== -rtl_TextEncoding PictReader::GetTextEncoding (sal_uInt16 fId) { - static rtl_TextEncoding enc = [&]() - { - rtl_TextEncoding def = osl_getThreadTextEncoding(); - // we keep osl_getThreadTextEncoding only if it is a mac encoding - switch(def) { - case RTL_TEXTENCODING_APPLE_ROMAN: - case RTL_TEXTENCODING_APPLE_ARABIC: - case RTL_TEXTENCODING_APPLE_CENTEURO: - case RTL_TEXTENCODING_APPLE_CROATIAN: - case RTL_TEXTENCODING_APPLE_CYRILLIC: - case RTL_TEXTENCODING_APPLE_DEVANAGARI: - case RTL_TEXTENCODING_APPLE_FARSI: - case RTL_TEXTENCODING_APPLE_GREEK: - case RTL_TEXTENCODING_APPLE_GUJARATI: - case RTL_TEXTENCODING_APPLE_GURMUKHI: - case RTL_TEXTENCODING_APPLE_HEBREW: - case RTL_TEXTENCODING_APPLE_ICELAND: - case RTL_TEXTENCODING_APPLE_ROMANIAN: - case RTL_TEXTENCODING_APPLE_THAI: - case RTL_TEXTENCODING_APPLE_TURKISH: - case RTL_TEXTENCODING_APPLE_UKRAINIAN: - case RTL_TEXTENCODING_APPLE_CHINSIMP: - case RTL_TEXTENCODING_APPLE_CHINTRAD: - case RTL_TEXTENCODING_APPLE_JAPANESE: - case RTL_TEXTENCODING_APPLE_KOREAN: - return def; break; - default: - break; - } - return RTL_TEXTENCODING_APPLE_ROMAN; - }(); - if (fId == 13) return RTL_TEXTENCODING_ADOBE_DINGBATS; // CHECKME - if (fId == 23) return RTL_TEXTENCODING_ADOBE_SYMBOL; - return enc; -} - -void PictReader::SetLineColor( const Color& rColor ) -{ - pVirDev->SetLineColor( rColor ); -} - -void PictReader::SetFillColor( const Color& rColor ) -{ - pVirDev->SetFillColor( rColor ); -} - -Point PictReader::ReadPoint() -{ - short nx,ny; - - pPict->ReadInt16( ny ).ReadInt16( nx ); - - Point aPoint( static_cast<tools::Long>(nx) - aBoundingRect.Left(), - static_cast<tools::Long>(ny) - aBoundingRect.Top() ); - - SAL_INFO("filter.pict", "ReadPoint: " << aPoint); - return aPoint; -} - -Point PictReader::ReadDeltaH(Point aBase) -{ - signed char ndh; - - pPict->ReadChar( reinterpret_cast<char&>(ndh) ); - - return Point( aBase.X() + static_cast<tools::Long>(ndh), aBase.Y() ); -} - -Point PictReader::ReadDeltaV(Point aBase) -{ - signed char ndv; - - pPict->ReadChar( reinterpret_cast<char&>(ndv) ); - - return Point( aBase.X(), aBase.Y() + static_cast<tools::Long>(ndv) ); -} - -Point PictReader::ReadUnsignedDeltaH(Point aBase) -{ - sal_uInt8 ndh; - - pPict->ReadUChar( ndh ); - - return Point( aBase.X() + static_cast<tools::Long>(ndh), aBase.Y() ); -} - -Point PictReader::ReadUnsignedDeltaV(Point aBase) -{ - sal_uInt8 ndv; - - pPict->ReadUChar( ndv ); - - return Point( aBase.X(), aBase.Y() + static_cast<tools::Long>(ndv) ); -} - -Size PictReader::ReadSize() -{ - short nx,ny; - - pPict->ReadInt16( ny ).ReadInt16( nx ); - - return Size( static_cast<tools::Long>(nx), static_cast<tools::Long>(ny) ); -} - -Color PictReader::ReadColor() -{ - sal_uInt32 nCol; - Color aCol; - - pPict->ReadUInt32( nCol ); - switch (nCol) - { - case 33: aCol=COL_BLACK; break; - case 30: aCol=COL_WHITE; break; - case 205: aCol=COL_LIGHTRED; break; - case 341: aCol=COL_LIGHTGREEN; break; - case 409: aCol=COL_LIGHTBLUE; break; - case 273: aCol=COL_LIGHTCYAN; break; - case 137: aCol=COL_LIGHTMAGENTA; break; - case 69: aCol=COL_YELLOW; break; - default: aCol=COL_LIGHTGRAY; - } - return aCol; -} - - -Color PictReader::ReadRGBColor() -{ - sal_uInt16 nR, nG, nB; - - pPict->ReadUInt16( nR ).ReadUInt16( nG ).ReadUInt16( nB ); - return Color( static_cast<sal_uInt8>( nR >> 8 ), static_cast<sal_uInt8>( nG >> 8 ), static_cast<sal_uInt8>( nB >> 8 ) ); -} - - -void PictReader::ReadRectangle(tools::Rectangle & rRect) -{ - Point aTopLeft, aBottomRight; - - aTopLeft=ReadPoint(); - aBottomRight=ReadPoint(); - if (aTopLeft.X() > aBottomRight.X() || aTopLeft.Y() > aBottomRight.Y()) - { - SAL_WARN("filter.pict", "broken rectangle"); - pPict->SetError( SVSTREAM_FILEFORMAT_ERROR ); - rRect = tools::Rectangle(); - return; - } - rRect=tools::Rectangle(aTopLeft,aBottomRight); - - SAL_INFO("filter.pict", "ReadRectangle: " << rRect); -} - -sal_uInt64 PictReader::ReadPolygon(tools::Polygon & rPoly) -{ - sal_uInt16 nSize(0); - pPict->ReadUInt16(nSize); - pPict->SeekRel(8); - sal_uInt64 nDataSize = static_cast<sal_uInt64>(nSize); - nSize=(nSize-10)/4; - const size_t nMaxPossiblePoints = pPict->remainingSize() / 2 * sizeof(sal_uInt16); - if (nSize > nMaxPossiblePoints) - { - SAL_WARN("filter.pict", "pict record claims to have: " << nSize << " points, but only " << nMaxPossiblePoints << " possible, clamping"); - nSize = nMaxPossiblePoints; - } - rPoly.SetSize(nSize); - for (sal_uInt16 i = 0; i < nSize; ++i) - { - rPoly.SetPoint(ReadPoint(), i); - if (!pPict->good()) - { - rPoly.SetSize(i); - break; - } - } - return nDataSize; -} - -sal_uInt64 PictReader::ReadPixPattern(PictReader::Pattern &pattern) -{ - // Don't know if this is correct because no picture which contains PixPatterns found. - // Here again the attempt to calculate the size of the date to create simple StarView-Styles - // from them. Luckily a PixPattern always contains a normal pattern. - - - sal_uInt64 nDataSize; - sal_uInt16 nPatType; - BitmapEx aBMP; - - pPict->ReadUInt16( nPatType ); - if (nPatType==1) { - pattern.read(*pPict); - nDataSize=ReadPixMapEtc(aBMP,false,true,nullptr,nullptr,false,false); - // CHANGEME: use average pixmap colors to update the pattern, ... - if (nDataSize!=0xffffffff) nDataSize+=10; - } - else if (nPatType==2) { - pattern.read(*pPict); - // RGBColor - sal_uInt16 nR, nG, nB; - pPict->ReadUInt16( nR ).ReadUInt16( nG ).ReadUInt16( nB ); - Color col(static_cast<sal_uInt8>( nR >> 8 ), static_cast<sal_uInt8>( nG >> 8 ), static_cast<sal_uInt8>( nB >> 8 ) ); - pattern.setColor(col); - nDataSize=16; - } - else nDataSize=0xffffffff; - - return nDataSize; -} - -sal_uInt8 PictReader::ReadAndDrawRect(PictDrawingMethod eMethod) -{ - ReadRectangle(aLastRect); - ReadAndDrawSameRect(eMethod); - return 8; -} - -sal_uInt8 PictReader::ReadAndDrawSameRect(PictDrawingMethod eMethod) -{ - if (IsInvisible(eMethod)) return 0; - DrawingMethod(eMethod); - PictReaderShape::drawRectangle( pVirDev, eMethod == PictDrawingMethod::FRAME, aLastRect, nActPenSize ); - return 0; -} - -sal_uInt8 PictReader::ReadAndDrawRoundRect(PictDrawingMethod eMethod) -{ - ReadRectangle(aLastRoundRect); - ReadAndDrawSameRoundRect(eMethod); - return 8; -} - -sal_uInt8 PictReader::ReadAndDrawSameRoundRect(PictDrawingMethod eMethod) -{ - if (IsInvisible(eMethod)) return 0; - DrawingMethod(eMethod); - PictReaderShape::drawRoundRectangle( pVirDev, eMethod == PictDrawingMethod::FRAME, aLastRoundRect, aActOvalSize, nActPenSize ); - return 0; -} - -sal_uInt8 PictReader::ReadAndDrawOval(PictDrawingMethod eMethod) -{ - ReadRectangle(aLastOval); - ReadAndDrawSameOval(eMethod); - return 8; -} - -sal_uInt8 PictReader::ReadAndDrawSameOval(PictDrawingMethod eMethod) -{ - if (IsInvisible(eMethod)) return 0; - DrawingMethod(eMethod); - PictReaderShape::drawEllipse( pVirDev, eMethod == PictDrawingMethod::FRAME, aLastOval, nActPenSize ); - return 0; -} - -sal_uInt64 PictReader::ReadAndDrawPolygon(PictDrawingMethod eMethod) -{ - sal_uInt64 nDataSize; - nDataSize=ReadPolygon(aLastPolygon); - ReadAndDrawSamePolygon(eMethod); - return nDataSize; -} - -sal_uInt8 PictReader::ReadAndDrawSamePolygon(PictDrawingMethod eMethod) -{ - if (IsInvisible(eMethod)) return 0; - DrawingMethod(eMethod); - PictReaderShape::drawPolygon( pVirDev, eMethod == PictDrawingMethod::FRAME, aLastPolygon, nActPenSize ); - return 0; -} - - -sal_uInt8 PictReader::ReadAndDrawArc(PictDrawingMethod eMethod) -{ - ReadRectangle(aLastArcRect); - ReadAndDrawSameArc(eMethod); - return 12; -} - -sal_uInt8 PictReader::ReadAndDrawSameArc(PictDrawingMethod eMethod) -{ - short nstartAngle, narcAngle; - double fAng1, fAng2; - - pPict->ReadInt16( nstartAngle ).ReadInt16( narcAngle ); - if (IsInvisible(eMethod)) return 4; - DrawingMethod(eMethod); - - if (narcAngle<0) { - nstartAngle = nstartAngle + narcAngle; - narcAngle=-narcAngle; - } - const double pi = 2 * acos(0.0); - fAng1 = static_cast<double>(nstartAngle) * pi / 180.0; - fAng2 = static_cast<double>(nstartAngle + narcAngle) * pi / 180.0; - PictReaderShape::drawArc( pVirDev, eMethod == PictDrawingMethod::FRAME, aLastArcRect, fAng1, fAng2, nActPenSize ); - return 4; -} - -sal_uInt64 PictReader::ReadAndDrawRgn(PictDrawingMethod eMethod) -{ - sal_uInt16 nSize; - - pPict->ReadUInt16( nSize ); - // read the DATA - // - // a region data is a mask and is probably coded as - // - the first 8 bytes: bdbox ( which can be read by ReadRectangle ) - // - then a list of line modifiers: y_i, a_0, b_0, a_1, b_1, ..., a_{n_i}, b_{n_i}, 0x7fff - // - 0x7fff - // where y_i is the increasing sequences of line coordinates - // and on each line: a0 < b0 < a1 < b1 < ... < a_{n_i} < b_{n_i} - - // it can be probably decoded as : - // M=an empty mask: ie. (0, 0, ... ) with (left_box-right_box+1) zeroes - // then for each line (y_i): - // - takes M and inverts all values in [a_0,b_0-1], in [a_1,b_1-1] ... - // - sets M = new y_i line mask - ReadAndDrawSameRgn(eMethod); - return static_cast<sal_uInt64>(nSize); -} - -sal_uInt8 PictReader::ReadAndDrawSameRgn(PictDrawingMethod eMethod) -{ - if (IsInvisible(eMethod)) return 0; - DrawingMethod(eMethod); - // DISPLAY: ...???... - return 0; -} - -void PictReader::DrawingMethod(PictDrawingMethod eMethod) -{ - if( eActMethod==eMethod ) return; - switch (eMethod) { - case PictDrawingMethod::FRAME: - if (eActPenPattern.isDefault()) - SetLineColor( aActForeColor ); - else - SetLineColor(eActPenPattern.getColor(aActBackColor, aActForeColor)); - SetFillColor( COL_TRANSPARENT ); - pVirDev->SetRasterOp(eActROP); - break; - case PictDrawingMethod::PAINT: - SetLineColor( COL_TRANSPARENT ); - if (eActPenPattern.isDefault()) - SetFillColor( aActForeColor ); - else - SetFillColor(eActPenPattern.getColor(aActBackColor, aActForeColor)); - pVirDev->SetRasterOp(eActROP); - break; - case PictDrawingMethod::ERASE: - SetLineColor( COL_TRANSPARENT ); - if (eActBackPattern.isDefault()) - SetFillColor( aActBackColor );// Osnola: previously aActForeColor - else // checkMe - SetFillColor(eActBackPattern.getColor(COL_BLACK, aActBackColor)); - pVirDev->SetRasterOp(RasterOp::OverPaint); - break; - case PictDrawingMethod::INVERT: // checkme - SetLineColor( COL_TRANSPARENT); - SetFillColor( COL_BLACK ); - pVirDev->SetRasterOp(RasterOp::Invert); - break; - case PictDrawingMethod::FILL: - SetLineColor( COL_TRANSPARENT ); - if (eActFillPattern.isDefault()) - SetFillColor( aActForeColor ); - else - SetFillColor(eActFillPattern.getColor(aActBackColor, aActForeColor)); - pVirDev->SetRasterOp(RasterOp::OverPaint); - break; - case PictDrawingMethod::TEXT: - aActFont.SetColor(aActForeColor); - aActFont.SetFillColor(aActBackColor); - aActFont.SetTransparent(true); - pVirDev->SetFont(aActFont); - pVirDev->SetRasterOp(RasterOp::OverPaint); - break; - default: - break; // -Wall undefined not handled... - } - eActMethod=eMethod; -} - -sal_uInt64 PictReader::ReadAndDrawText() -{ - char nByteLen; - sal_uInt32 nLen, nDataLen; - char sText[256]; - - pPict->ReadChar( nByteLen ); nLen=static_cast<sal_uInt32>(nByteLen)&0x000000ff; - nDataLen = nLen + 1; - pPict->ReadBytes(&sText, nLen); - - if (IsInvisible( PictDrawingMethod::TEXT )) return nDataLen; - DrawingMethod( PictDrawingMethod::TEXT ); - - // remove annoying control characters: - while ( nLen > 0 && static_cast<unsigned char>(sText[ nLen - 1 ]) < 32 ) - nLen--; - sText[ nLen ] = 0; - OUString aString( sText, strlen(sText), aActFont.GetCharSet()); - pVirDev->DrawText( Point( aTextPosition.X(), aTextPosition.Y() ), aString ); - return nDataLen; -} - -sal_uInt64 PictReader::ReadPixMapEtc( BitmapEx &rBitmap, bool bBaseAddr, bool bColorTable, tools::Rectangle* pSrcRect, - tools::Rectangle* pDestRect, bool bMode, bool bMaskRgn ) -{ - std::unique_ptr<vcl::bitmap::RawBitmap> pBitmap; - sal_uInt16 nPackType(0), nPixelSize(0), nCmpCount(0), nCmpSize(0); - sal_uInt8 nDat(0), nRed(0), nGreen(0), nBlue(0); - - // The calculation of nDataSize is considering the size of the whole data. - size_t nDataSize = 0; - - // conditionally skip BaseAddr - if ( bBaseAddr ) - { - pPict->SeekRel( 4 ); - nDataSize += 4; - } - - // Read PixMap or Bitmap structure; - sal_uInt16 nRowBytes(0), nBndX(0), nBndY(0), nWidth(0), nHeight(0); - pPict->ReadUInt16(nRowBytes).ReadUInt16(nBndY).ReadUInt16(nBndX).ReadUInt16(nHeight).ReadUInt16(nWidth); - if (nBndY > nHeight) - return 0xffffffff; - nHeight = nHeight - nBndY; - if (nHeight == 0) - return 0xffffffff; - if (nBndX > nWidth) - return 0xffffffff; - nWidth = nWidth - nBndX; - if (nWidth == 0) - return 0xffffffff; - - std::vector<Color> aPalette; - const bool bNotMonoChrome = (nRowBytes & 0x8000) != 0; - if (bNotMonoChrome) - { // it is a PixMap - nRowBytes &= 0x3fff; - sal_uInt16 nVersion; - sal_uInt32 nPackSize; - sal_uInt16 nPixelType; - sal_uInt32 nPlaneBytes; - sal_uInt32 nHRes, nVRes; - pPict->ReadUInt16( nVersion ).ReadUInt16( nPackType ).ReadUInt32( nPackSize ).ReadUInt32( nHRes ).ReadUInt32( nVRes ).ReadUInt16( nPixelType ).ReadUInt16( nPixelSize ).ReadUInt16( nCmpCount ).ReadUInt16( nCmpSize ).ReadUInt32( nPlaneBytes ); - - pPict->SeekRel( 8 ); - nDataSize += 46; - - if ( bColorTable ) - { - pPict->SeekRel( 6 ); - sal_uInt16 nColTabSize(0); - pPict->ReadUInt16(nColTabSize); - - if (nColTabSize > 255) - return 0xffffffff; - - ++nColTabSize; - - aPalette.resize(nColTabSize); - - for (size_t i = 0; i < nColTabSize; ++i) - { - pPict->SeekRel(2); - sal_uInt8 nDummy; - pPict->ReadUChar( nRed ).ReadUChar( nDummy ).ReadUChar( nGreen ).ReadUChar( nDummy ).ReadUChar( nBlue ).ReadUChar( nDummy ); - aPalette[i] = Color(nRed, nGreen, nBlue); - } - - nDataSize += 8 + nColTabSize * 8; - } - } - else - { - nRowBytes &= 0x3fff; - nPixelSize = nCmpCount = nCmpSize = 1; - nDataSize += 10; - aPalette.resize(2); - aPalette[0] = Color(0xff, 0xff, 0xff); - aPalette[1] = Color(0, 0, 0); - } - - // conditionally read source rectangle: - if ( pSrcRect != nullptr) - { - sal_uInt16 nTop, nLeft, nBottom, nRight; - pPict->ReadUInt16( nTop ).ReadUInt16( nLeft ).ReadUInt16( nBottom ).ReadUInt16( nRight ); - *pSrcRect = tools::Rectangle(nLeft, nTop, nRight, nBottom); - nDataSize += 8; - } - - // conditionally read destination rectangle: - if ( pDestRect != nullptr ) - { - Point aTL, aBR; - aTL = ReadPoint(); - aBR = ReadPoint(); - *pDestRect = tools::Rectangle( aTL, aBR ); - nDataSize += 8; - } - - // conditionally read mode (or skip it): - if ( bMode ) - { - pPict->SeekRel(2); - nDataSize += 2; - } - - // conditionally read region (or skip it): - if ( bMaskRgn ) - { - sal_uInt16 nSize; - pPict->ReadUInt16( nSize ); - pPict->SeekRel( nSize - 2 ); - nDataSize += nSize; - } - - // read and write Bitmap bits: - if ( nPixelSize == 1 || nPixelSize == 2 || nPixelSize == 4 || nPixelSize == 8 ) - { - sal_uInt16 nSrcBPL, nDestBPL; - size_t nCount; - - if ( nPixelSize == 1 ) nSrcBPL = ( nWidth + 7 ) >> 3; - else if ( nPixelSize == 2 ) nSrcBPL = ( nWidth + 3 ) >> 2; - else if ( nPixelSize == 4 ) nSrcBPL = ( nWidth + 1 ) >> 1; - else nSrcBPL = nWidth; - nDestBPL = ( nSrcBPL + 3 ) & 0xfffc; - if (!nRowBytes || nRowBytes < nSrcBPL || nRowBytes > nDestBPL) - return 0xffffffff; - - if (nRowBytes < 8 || nPackType == 1) - { - if (nHeight > pPict->remainingSize() / (sizeof(sal_uInt8) * nRowBytes)) - return 0xffffffff; - } - else - { - size_t nByteCountSize = nRowBytes > 250 ? sizeof(sal_uInt16) : sizeof(sal_uInt8); - if (nHeight > pPict->remainingSize() / nByteCountSize) - return 0xffffffff; - } - - pBitmap.reset(new vcl::bitmap::RawBitmap( Size(nWidth, nHeight), 24 )); - - for (sal_uInt16 ny = 0; ny < nHeight; ++ny) - { - sal_uInt16 nx = 0; - if ( nRowBytes < 8 || nPackType == 1 ) - { - for (size_t i = 0; i < nRowBytes; ++i) - { - pPict->ReadUChar( nDat ); - if ( nx < nWidth ) - SetByte(nx, ny, *pBitmap, nPixelSize, nDat, nWidth, aPalette); - } - nDataSize += nRowBytes; - } - else - { - sal_uInt16 nByteCount(0); - if ( nRowBytes > 250 ) - { - pPict->ReadUInt16( nByteCount ); - nDataSize += 2 + static_cast<sal_uInt32>(nByteCount); - } - else - { - sal_uInt8 nByteCountAsByte(0); - pPict->ReadUChar( nByteCountAsByte ); - nByteCount = static_cast<sal_uInt16>(nByteCountAsByte) & 0x00ff; - nDataSize += 1 + nByteCount; - } - - while (pPict->good() && nByteCount) - { - sal_uInt8 nFlagCounterByte(0); - pPict->ReadUChar(nFlagCounterByte); - if ( ( nFlagCounterByte & 0x80 ) == 0 ) - { - nCount = static_cast<sal_uInt16>(nFlagCounterByte) + 1; - for (size_t i = 0; i < nCount; ++i) - { - pPict->ReadUChar( nDat ); - if ( nx < nWidth ) - SetByte(nx, ny, *pBitmap, nPixelSize, nDat, nWidth, aPalette); - } - nByteCount -= 1 + nCount; - } - else - { - nCount = static_cast<sal_uInt16>( 1 - sal_Int16( static_cast<sal_uInt16>(nFlagCounterByte) | 0xff00 ) ); - pPict->ReadUChar( nDat ); - for (size_t i = 0; i < nCount; ++i) - { - if ( nx < nWidth ) - SetByte(nx, ny, *pBitmap, nPixelSize, nDat, nWidth, aPalette); - } - nByteCount -= 2; - } - } - } - } - } - else if ( nPixelSize == 16 ) - { - sal_uInt8 nByteCountAsByte, nFlagCounterByte; - sal_uInt16 nByteCount, nCount, nD; - sal_uInt64 nSrcBitsPos; - - if (nWidth > nRowBytes / 2) - return 0xffffffff; - - if (nRowBytes < 8 || nPackType == 1) - { - if (nHeight > pPict->remainingSize() / (sizeof(sal_uInt8) * nRowBytes)) - return 0xffffffff; - } - else - { - size_t nByteCountSize = nRowBytes > 250 ? sizeof(sal_uInt16) : sizeof(sal_uInt8); - if (nHeight > pPict->remainingSize() / nByteCountSize) - return 0xffffffff; - } - - pBitmap.reset(new vcl::bitmap::RawBitmap( Size(nWidth, nHeight), 24 )); - - for (sal_uInt16 ny = 0; ny < nHeight; ++ny) - { - sal_uInt16 nx = 0; - if ( nRowBytes < 8 || nPackType == 1 ) - { - for (size_t i = 0; i < nWidth; ++i) - { - pPict->ReadUInt16( nD ); - nRed = static_cast<sal_uInt8>( nD >> 7 ); - nGreen = static_cast<sal_uInt8>( nD >> 2 ); - nBlue = static_cast<sal_uInt8>( nD << 3 ); - pBitmap->SetPixel(ny, nx++, Color(nRed, nGreen, nBlue)); - } - nDataSize += static_cast<sal_uInt32>(nWidth) * 2; - } - else - { - nSrcBitsPos = pPict->Tell(); - if ( nRowBytes > 250 ) - { - pPict->ReadUInt16( nByteCount ); - nByteCount += 2; - } - else - { - pPict->ReadUChar( nByteCountAsByte ); - nByteCount = static_cast<sal_uInt16>(nByteCountAsByte) & 0x00ff; - nByteCount++; - } - while ( nx != nWidth ) - { - pPict->ReadUChar( nFlagCounterByte ); - if ( (nFlagCounterByte & 0x80) == 0) - { - nCount=static_cast<sal_uInt16>(nFlagCounterByte)+1; - if ( nCount + nx > nWidth) - nCount = nWidth - nx; - if (pPict->remainingSize() < sizeof(sal_uInt16) * nCount) - return 0xffffffff; - /* SJ: the RLE decoding seems not to be correct here, - I don't want to change this until I have a bugdoc for - this case. Have a look at 32bit, there I changed the - encoding, so that it is used a straight forward array - */ - for (size_t i = 0; i < nCount; ++i) - { - pPict->ReadUInt16( nD ); - nRed = static_cast<sal_uInt8>( nD >> 7 ); - nGreen = static_cast<sal_uInt8>( nD >> 2 ); - nBlue = static_cast<sal_uInt8>( nD << 3 ); - pBitmap->SetPixel(ny, nx++, Color(nRed, nGreen, nBlue)); - } - } - else - { - if (pPict->remainingSize() < sizeof(sal_uInt16)) - return 0xffffffff; - nCount=(1-sal_Int16(static_cast<sal_uInt16>(nFlagCounterByte)|0xff00)); - if ( nCount + nx > nWidth ) - nCount = nWidth - nx; - pPict->ReadUInt16( nD ); - nRed = static_cast<sal_uInt8>( nD >> 7 ); - nGreen = static_cast<sal_uInt8>( nD >> 2 ); - nBlue = static_cast<sal_uInt8>( nD << 3 ); - for (size_t i = 0; i < nCount; ++i) - { - pBitmap->SetPixel(ny, nx++, Color(nRed, nGreen, nBlue)); - } - } - } - nDataSize += nByteCount; - pPict->Seek(nSrcBitsPos+nByteCount); - } - } - } - else if ( nPixelSize == 32 ) - { - sal_uInt16 nByteCount; - size_t nCount; - sal_uInt64 nSrcBitsPos; - if ( nRowBytes != 4*nWidth ) - return 0xffffffff; - - if ( nRowBytes < 8 || nPackType == 1 ) - { - const size_t nMaxPixels = pPict->remainingSize() / 4; - const size_t nMaxRows = nMaxPixels / nWidth; - if (nHeight > nMaxRows) - return 0xffffffff; - const size_t nMaxCols = nMaxPixels / nHeight; - if (nWidth > nMaxCols) - return 0xffffffff; - - pBitmap.reset(new vcl::bitmap::RawBitmap( Size(nWidth, nHeight), 24 )); - - for (sal_uInt16 ny = 0; ny < nHeight; ++ny) - { - for (sal_uInt16 nx = 0; nx < nWidth; ++nx) - { - sal_uInt8 nDummy; - pPict->ReadUChar( nDummy ).ReadUChar( nRed ).ReadUChar( nGreen ).ReadUChar( nBlue ); - pBitmap->SetPixel(ny, nx, Color(nRed, nGreen, nBlue)); - } - nDataSize += static_cast<sal_uInt32>(nWidth) * 4; - } - } - else if ( nPackType == 2 ) - { - const size_t nMaxPixels = pPict->remainingSize() / 3; - const size_t nMaxRows = nMaxPixels / nWidth; - if (nHeight > nMaxRows) - return 0xffffffff; - const size_t nMaxCols = nMaxPixels / nHeight; - if (nWidth > nMaxCols) - return 0xffffffff; - - pBitmap.reset(new vcl::bitmap::RawBitmap( Size(nWidth, nHeight), 24 )); - - for (sal_uInt16 ny = 0; ny < nHeight; ++ny) - { - for (sal_uInt16 nx = 0; nx < nWidth; ++nx) - { - pPict->ReadUChar( nRed ).ReadUChar( nGreen ).ReadUChar( nBlue ); - pBitmap->SetPixel(ny, nx, Color(nRed, nGreen, nBlue)); - } - nDataSize += static_cast<sal_uInt32>(nWidth) * 3; - } - } - else - { - sal_uInt8 nByteCountAsByte; - sal_uInt8 nFlagCounterByte; - if ( ( nCmpCount == 3 ) || ( nCmpCount == 4 ) ) - { - size_t nByteCountSize = nRowBytes > 250 ? sizeof(sal_uInt16) : sizeof(sal_uInt8); - if (nHeight > pPict->remainingSize() / nByteCountSize) - return 0xffffffff; - - pBitmap.reset(new vcl::bitmap::RawBitmap( Size(nWidth, nHeight), 24 )); - - // cid#1458434 to sanitize Untrusted loop bound - nWidth = pBitmap->Width(); - - size_t nByteWidth = static_cast<size_t>(nWidth) * nCmpCount; - std::vector<sal_uInt8> aScanline(nByteWidth); - for (sal_uInt16 ny = 0; ny < nHeight; ++ny) - { - nSrcBitsPos = pPict->Tell(); - if ( nRowBytes > 250 ) - { - pPict->ReadUInt16( nByteCount ); - nByteCount += 2; - } - else - { - pPict->ReadUChar( nByteCountAsByte ); - nByteCount = nByteCountAsByte; - nByteCount++; - } - size_t i = 0; - while (i < aScanline.size()) - { - pPict->ReadUChar( nFlagCounterByte ); - if ( ( nFlagCounterByte & 0x80 ) == 0) - { - nCount = static_cast<sal_uInt16>(nFlagCounterByte) + 1; - if ((i + nCount) > aScanline.size()) - nCount = aScanline.size() - i; - if (pPict->remainingSize() < nCount) - return 0xffffffff; - while( nCount-- ) - { - pPict->ReadUChar( nDat ); - aScanline[ i++ ] = nDat; - } - } - else - { - if (pPict->remainingSize() < 1) - return 0xffffffff; - nCount = ( 1 - sal_Int16( static_cast<sal_uInt16>(nFlagCounterByte) | 0xff00 ) ); - if (( i + nCount) > aScanline.size()) - nCount = aScanline.size() - i; - pPict->ReadUChar( nDat ); - while( nCount-- ) - aScanline[ i++ ] = nDat; - } - } - sal_uInt8* pTmp = aScanline.data(); - if ( nCmpCount == 4 ) - pTmp += nWidth; - for (sal_uInt16 nx = 0; nx < nWidth; pTmp++) - pBitmap->SetPixel(ny, nx++, Color(*pTmp, pTmp[ nWidth ], pTmp[ 2 * nWidth ])); - nDataSize += nByteCount; - pPict->Seek( nSrcBitsPos + nByteCount ); - } - } - } - } - else - return 0xffffffff; - rBitmap = vcl::bitmap::CreateFromData(std::move(*pBitmap)); - return nDataSize; -} - -void PictReader::ReadHeader() -{ - short y1,x1,y2,x2; - - char sBuf[ 2 ]; - // previous code considers pPict->Tell() as the normal starting position, - // can we have nStartPos != 0 ? - sal_uInt64 nStartPos = pPict->Tell(); - // Standard: - // a picture file begins by 512 bytes (reserved to the application) followed by the picture data - // while clipboard, pictures stored in a document often contain only the picture data. - - // Special cases: - // - some Pict v.1 use 0x00 0x11 0x01 ( instead of 0x11 0x01) to store the version op - // (we consider here this as another standard for Pict. v.1 ) - // - some files seem to contain extra garbage data at the beginning - // - some picture data seem to contain extra NOP opcode(0x00) between the bounding box and the version opcode - - // This code looks hard to find a picture header, ie. it looks at positions - // - nStartPos+0, nStartPos+512 with potential extra NOP codes between bdbox and version (at most 9 extra NOP) - // - 512..1024 with more strict bdbox checking and no extra NOP codes - - // Notes: - // - if the header can begin at nStartPos+0 and at nStartPos+512, we try to choose the more - // <<probable>> ( using the variable confidence) - // - svtools/source/filter.vcl/filter/{filter.cxx,filter2.cxx} only check for standard Pict, - // this may cause future problems - int st; - sal_uInt32 nOffset; - int confidence[2] = { 0, 0}; - for ( st = 0; st < 3 + 513; st++ ) - { - int actualConfid = 20; // the actual confidence - pPict->ResetError(); - if (st < 2) nOffset = nStartPos+st*512; - else if (st == 2) { - // choose nStartPos+0 or nStartPos+512 even if there are a little dubious - int actPos = -1, actConf=0; - if (confidence[0] > 0) { actPos = 0; actConf = confidence[0]; } - if (confidence[1] > 0 && confidence[1] >= actConf) actPos = 1; - if (actPos < 0) continue; - nOffset = nStartPos+actPos*512; - } - else { - nOffset = 509+st; // illogical : more logical will be nStartPos+509+st or to consider that nStartPos=0 - // a small test to check if versionOp code exists after the bdbox ( with no extra NOP codes) - pPict->Seek(nOffset+10); - pPict->ReadBytes(sBuf, 2); - if (!pPict->good()) break; - if (sBuf[0] == 0x11 || (sBuf[0] == 0x00 && sBuf[1] == 0x11)) ; // maybe ok - else continue; - } - pPict->Seek(nOffset); - - // 2 bytes to store size ( version 1 ) ignored - pPict->SeekRel( 2 ); - pPict->ReadInt16( y1 ).ReadInt16( x1 ).ReadInt16( y2 ).ReadInt16( x2 ); // frame rectangle of the picture - if (x1 > x2 || y1 > y2) continue; // bad bdbox - if (x1 < -2048 || x2 > 2048 || y1 < -2048 || y2 > 2048 || // origin|dest is very small|large - (x1 == x2 && y1 == y2) ) // 1 pixel pict is dubious - actualConfid-=3; - else if (x2 < x1+8 || y2 < y1+8) // a little dubious - actualConfid-=1; - if (st >= 3 && actualConfid != 20) continue; - aBoundingRect=tools::Rectangle( x1,y1, x2, y2 ); - - if (!pPict->good()) continue; - // read version - pPict->ReadBytes(sBuf, 2); - // version 1 file - if ( sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 ) { - // pict v1 must be rare and we do only few tests - if (st < 2) { confidence[st] = --actualConfid; continue; } - IsVersion2 = false; return; - } - if (sBuf[0] != 0x00) continue; // unrecoverable error - int numZero = 0; - do - { - numZero++; - pPict->SeekRel(-1); - pPict->ReadBytes(sBuf, 2); - } - while ( sBuf[0] == 0x00 && numZero < 10); - actualConfid -= (numZero-1); // extra nop are dubious - if (!pPict->good()) continue; - if (sBuf[0] != 0x11) continue; // not a version opcode - // abnormal version 1 file - if (sBuf[1] == 0x01 ) { - // pict v1 must be rare and we do only few tests - if (st < 2) { confidence[st] = --actualConfid; continue; } - IsVersion2 = false; return; - } - if (sBuf[1] != 0x02 ) continue; // not a version 2 file - - IsVersion2=true; - short nExtVer, nReserved; - // 3 Bytes ignored : end of version arg 0x02FF (ie: 0xFF), HeaderOp : 0x0C00 - pPict->SeekRel( 3 ); - pPict->ReadInt16( nExtVer ).ReadInt16( nReserved ); - if (!pPict->good()) continue; - - if ( nExtVer == -2 ) // extended version 2 picture - { - sal_Int32 nHResFixed, nVResFixed; - pPict->ReadInt32( nHResFixed ).ReadInt32( nVResFixed ); - pPict->ReadInt16( y1 ).ReadInt16( x1 ).ReadInt16( y2 ).ReadInt16( x2 ); // reading the optimal bounding rect - if (x1 > x2 || y1 > y2) continue; // bad bdbox - if (st < 2 && actualConfid != 20) { confidence[st] = actualConfid; continue; } - - double fHRes = nHResFixed; - fHRes /= 65536; - double fVRes = nVResFixed; - fVRes /= 65536; - aHRes /= fHRes; - aVRes /= fVRes; - aBoundingRect=tools::Rectangle( x1,y1, x2, y2 ); - pPict->SeekRel( 4 ); // 4 bytes reserved - return; - } - else if (nExtVer == -1 ) { // basic version 2 picture - if (st < 2 && actualConfid != 20) { confidence[st] = actualConfid; continue; } - pPict->SeekRel( 16); // bdbox(4 fixed number) - pPict->SeekRel(4); // 4 bytes reserved - return; - } - } - pPict->SetError(SVSTREAM_FILEFORMAT_ERROR); -} - -#if OSL_DEBUG_LEVEL > 0 -static const char* operationName(sal_uInt16 nOpcode) -{ - // add here whatever makes the debugging easier for you, otherwise you'll - // see only the operation's opcode - switch (nOpcode) - { - case 0x0001: return "Clip"; - case 0x0003: return "TxFont"; - case 0x0004: return "TxFace"; - case 0x0008: return "PnMode"; - case 0x0009: return "PnPat"; - case 0x000d: return "TxSize"; - case 0x001a: return "RGBFgCol"; - case 0x001d: return "HiliteColor"; - case 0x0020: return "Line"; - case 0x0022: return "ShortLine"; - case 0x0028: return "LongText"; - case 0x0029: return "DHText"; - case 0x002a: return "DVText"; - case 0x002c: return "fontName"; - case 0x002e: return "glyphState"; - case 0x0031: return "paintRect"; - case 0x0038: return "frameSameRect"; - case 0x0070: return "framePoly"; - case 0x0071: return "paintPoly"; - case 0x00a1: return "LongComment"; - default: return "?"; - } -} -#endif - -sal_uInt64 PictReader::ReadData(sal_uInt16 nOpcode) -{ - sal_uInt16 nUSHORT; - Point aPoint; - sal_uInt64 nDataSize=0; - PictDrawingMethod shapeDMethod = PictDrawingMethod::UNDEFINED; - switch (nOpcode & 7) { - case 0: shapeDMethod = PictDrawingMethod::FRAME; break; - case 1: shapeDMethod = PictDrawingMethod::PAINT; break; - case 2: shapeDMethod = PictDrawingMethod::ERASE; break; - case 3: shapeDMethod = PictDrawingMethod::INVERT; break; - case 4: shapeDMethod = PictDrawingMethod::FILL; break; - default: break; - } - -#if OSL_DEBUG_LEVEL > 0 - SAL_INFO("filter.pict", "Operation: 0x" << OUString::number(nOpcode, 16) << " [" << operationName(nOpcode) << "]"); -#endif - - switch(nOpcode) { - - case 0x0000: // NOP - nDataSize=0; - break; - - case 0x0001: { // Clip - tools::Rectangle aRect; - pPict->ReadUInt16( nUSHORT ); - nDataSize=nUSHORT; - ReadRectangle(aRect); - // checkme: do we really want to extend the rectangle here ? - // I do that because the clipping is often used to clean a region, - // before drawing some text and also to draw this text. - // So using a too small region can lead to clip the end of the text ; - // but this can be discussable... - aRect.setWidth(aRect.getWidth()+1); - aRect.setHeight(aRect.getHeight()+1); - pVirDev->SetClipRegion( vcl::Region( aRect ) ); - break; - } - case 0x0002: // BkPat - nDataSize = eActBackPattern.read(*pPict); - eActMethod = PictDrawingMethod::UNDEFINED; - break; - - case 0x0003: // TxFont - pPict->ReadUInt16( nUSHORT ); - if (nUSHORT <= 1) aActFont.SetFamily(FAMILY_SWISS); - else if (nUSHORT <= 12) aActFont.SetFamily(FAMILY_DECORATIVE); - else if (nUSHORT <= 20) aActFont.SetFamily(FAMILY_ROMAN); - else if (nUSHORT == 21) aActFont.SetFamily(FAMILY_SWISS); - else if (nUSHORT == 22) aActFont.SetFamily(FAMILY_MODERN); - else if (nUSHORT <= 1023) aActFont.SetFamily(FAMILY_SWISS); - else aActFont.SetFamily(FAMILY_ROMAN); - aActFont.SetCharSet(GetTextEncoding(nUSHORT)); - eActMethod = PictDrawingMethod::UNDEFINED; - nDataSize=2; - break; - - case 0x0004: { // TxFace - char nFace; - pPict->ReadChar( nFace ); - if ( (nFace & 0x01)!=0 ) aActFont.SetWeight(WEIGHT_BOLD); - else aActFont.SetWeight(WEIGHT_NORMAL); - if ( (nFace & 0x02)!=0 ) aActFont.SetItalic(ITALIC_NORMAL); - else aActFont.SetItalic(ITALIC_NONE); - if ( (nFace & 0x04)!=0 ) aActFont.SetUnderline(LINESTYLE_SINGLE); - else aActFont.SetUnderline(LINESTYLE_NONE); - if ( (nFace & 0x08)!=0 ) aActFont.SetOutline(true); - else aActFont.SetOutline(false); - if ( (nFace & 0x10)!=0 ) aActFont.SetShadow(true); - else aActFont.SetShadow(false); - eActMethod = PictDrawingMethod::UNDEFINED; - nDataSize=1; - break; - } - case 0x0005: // TxMode - nDataSize=2; - break; - - case 0x0006: // SpExtra - nDataSize=4; - break; - - case 0x0007: { // PnSize - nActPenSize=ReadSize(); - eActMethod = PictDrawingMethod::UNDEFINED; - nDataSize=4; - break; - } - case 0x0008: // PnMode - pPict->ReadUInt16( nUSHORT ); - // internal code for postscript command (Quickdraw Reference Drawing B-30,B-34) - if (nUSHORT==23) eActROP = RasterOp::N1; - else { - switch (nUSHORT & 0x0007) { - case 0: eActROP=RasterOp::OverPaint; break; // Copy - case 1: eActROP=RasterOp::OverPaint; break; // Or - case 2: eActROP=RasterOp::Xor; break; // Xor - case 3: eActROP=RasterOp::OverPaint; break; // Bic - case 4: eActROP=RasterOp::Invert; break; // notCopy - case 5: eActROP=RasterOp::OverPaint; break; // notOr - case 6: eActROP=RasterOp::Xor; break; // notXor - case 7: eActROP=RasterOp::OverPaint; break; // notBic - } - } - eActMethod = PictDrawingMethod::UNDEFINED; - nDataSize=2; - break; - - case 0x0009: // PnPat - nDataSize=eActPenPattern.read(*pPict); - eActMethod = PictDrawingMethod::UNDEFINED; - break; - - case 0x000a: // FillPat - nDataSize=eActFillPattern.read(*pPict); - eActMethod = PictDrawingMethod::UNDEFINED; - break; - - case 0x000b: // OvSize - aActOvalSize=ReadSize(); - nDataSize=4; - break; - - case 0x000c: // Origin - nDataSize=4; - break; - - case 0x000d: // TxSize - { - pPict->ReadUInt16( nUSHORT ); - aActFont.SetFontSize( Size( 0, static_cast<tools::Long>(nUSHORT) ) ); - eActMethod = PictDrawingMethod::UNDEFINED; - nDataSize=2; - } - break; - - case 0x000e: // FgColor - aActForeColor=ReadColor(); - eActMethod = PictDrawingMethod::UNDEFINED; - nDataSize=4; - break; - - case 0x000f: // BkColor - aActBackColor=ReadColor(); - nDataSize=4; - break; - - case 0x0010: // TxRatio - nDataSize=8; - break; - - case 0x0011: // VersionOp - nDataSize=1; - break; - - case 0x0012: // BkPixPat - nDataSize=ReadPixPattern(eActBackPattern); - eActMethod = PictDrawingMethod::UNDEFINED; - break; - - case 0x0013: // PnPixPat - nDataSize=ReadPixPattern(eActPenPattern); - eActMethod = PictDrawingMethod::UNDEFINED; - break; - - case 0x0014: // FillPixPat - nDataSize=ReadPixPattern(eActFillPattern); - eActMethod = PictDrawingMethod::UNDEFINED; - break; - - case 0x0015: // PnLocHFrac - nDataSize=2; - break; - - case 0x0016: // ChExtra - nDataSize=2; - break; - - case 0x0017: // Reserved (0 Bytes) - case 0x0018: // Reserved (0 Bytes) - case 0x0019: // Reserved (0 Bytes) - nDataSize=0; - break; - - case 0x001a: // RGBFgCol - aActForeColor=ReadRGBColor(); - eActMethod = PictDrawingMethod::UNDEFINED; - nDataSize=6; - break; - - case 0x001b: // RGBBkCol - aActBackColor=ReadRGBColor(); - eActMethod = PictDrawingMethod::UNDEFINED; - nDataSize=6; - break; - - case 0x001c: // HiliteMode - nDataSize=0; - break; - - case 0x001d: // HiliteColor - nDataSize=6; - break; - - case 0x001e: // DefHilite - nDataSize=0; - break; - - case 0x001f: // OpColor - nDataSize=6; - break; - - case 0x0020: // Line - aPoint=ReadPoint(); aPenPosition=ReadPoint(); - nDataSize=8; - - if (IsInvisible( PictDrawingMethod::FRAME )) break; - DrawingMethod( PictDrawingMethod::FRAME ); - PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize); - break; - - case 0x0021: // LineFrom - aPoint=aPenPosition; aPenPosition=ReadPoint(); - nDataSize=4; - - if (IsInvisible( PictDrawingMethod::FRAME )) break; - DrawingMethod( PictDrawingMethod::FRAME ); - PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize); - break; - - case 0x0022: // ShortLine - aPoint=ReadPoint(); - aPenPosition=ReadDeltaH(aPoint); - aPenPosition=ReadDeltaV(aPenPosition); - nDataSize=6; - - if ( IsInvisible(PictDrawingMethod::FRAME) ) break; - DrawingMethod( PictDrawingMethod::FRAME ); - PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize); - break; - - case 0x0023: // ShortLineFrom - aPoint=aPenPosition; - aPenPosition=ReadDeltaH(aPoint); - aPenPosition=ReadDeltaV(aPenPosition); - nDataSize=2; - - if (IsInvisible( PictDrawingMethod::FRAME )) break; - DrawingMethod( PictDrawingMethod::FRAME ); - PictReaderShape::drawLine(pVirDev, aPoint,aPenPosition, nActPenSize); - break; - - case 0x0024: // Reserved (n Bytes) - case 0x0025: // Reserved (n Bytes) - case 0x0026: // Reserved (n Bytes) - case 0x0027: // Reserved (n Bytes) - pPict->ReadUInt16( nUSHORT ); - nDataSize=2+nUSHORT; - break; - - case 0x0028: // LongText - aTextPosition=ReadPoint(); - nDataSize=4+ReadAndDrawText(); - break; - - case 0x0029: // DHText - aTextPosition=ReadUnsignedDeltaH(aTextPosition); - nDataSize=1+ReadAndDrawText(); - break; - - case 0x002a: // DVText - aTextPosition=ReadUnsignedDeltaV(aTextPosition); - nDataSize=1+ReadAndDrawText(); - break; - - case 0x002b: // DHDVText - aTextPosition=ReadUnsignedDeltaH(aTextPosition); - aTextPosition=ReadUnsignedDeltaV(aTextPosition); - nDataSize=2+ReadAndDrawText(); - break; - - case 0x002c: { // fontName - char sFName[ 256 ], nByteLen; - sal_uInt16 nLen; - pPict->ReadUInt16( nUSHORT ); nDataSize=nUSHORT+2; - pPict->ReadUInt16( nUSHORT ); - if (nUSHORT <= 1) aActFont.SetFamily(FAMILY_SWISS); - else if (nUSHORT <= 12) aActFont.SetFamily(FAMILY_DECORATIVE); - else if (nUSHORT <= 20) aActFont.SetFamily(FAMILY_ROMAN); - else if (nUSHORT == 21) aActFont.SetFamily(FAMILY_SWISS); - else if (nUSHORT == 22) aActFont.SetFamily(FAMILY_MODERN); - else if (nUSHORT <= 1023) aActFont.SetFamily(FAMILY_SWISS); - else aActFont.SetFamily(FAMILY_ROMAN); - aActFont.SetCharSet(GetTextEncoding(nUSHORT)); - pPict->ReadChar( nByteLen ); nLen=static_cast<sal_uInt16>(nByteLen)&0x00ff; - pPict->ReadBytes(&sFName, nLen); - sFName[ nLen ] = 0; - OUString aString( sFName, strlen(sFName), osl_getThreadTextEncoding() ); - aActFont.SetFamilyName( aString ); - eActMethod = PictDrawingMethod::UNDEFINED; - break; - } - case 0x002d: // lineJustify - nDataSize=10; - break; - - case 0x002e: // glyphState - pPict->ReadUInt16( nUSHORT ); - nDataSize=2+nUSHORT; - break; - - case 0x002f: // Reserved (n Bytes) - pPict->ReadUInt16( nUSHORT ); - nDataSize=2+nUSHORT; - break; - - case 0x0030: // frameRect - case 0x0031: // paintRect - case 0x0032: // eraseRect - case 0x0033: // invertRect - case 0x0034: // fillRect - nDataSize=ReadAndDrawRect(shapeDMethod); - break; - - case 0x0035: // Reserved (8 Bytes) - case 0x0036: // Reserved (8 Bytes) - case 0x0037: // Reserved (8 Bytes) - nDataSize=8; - break; - - case 0x0038: // frameSameRect - case 0x0039: // paintSameRect - case 0x003a: // eraseSameRect - case 0x003b: // invertSameRect - case 0x003c: // fillSameRect - nDataSize=ReadAndDrawSameRect(shapeDMethod); - break; - - case 0x003d: // Reserved (0 Bytes) - case 0x003e: // Reserved (0 Bytes) - case 0x003f: // Reserved (0 Bytes) - nDataSize=0; - break; - - case 0x0040: // frameRRect - case 0x0041: // paintRRect - case 0x0042: // eraseRRect - case 0x0043: // invertRRect - case 0x0044: // fillRRect - nDataSize=ReadAndDrawRoundRect(shapeDMethod); - break; - - case 0x0045: // Reserved (8 Bytes) - case 0x0046: // Reserved (8 Bytes) - case 0x0047: // Reserved (8 Bytes) - nDataSize=8; - break; - - case 0x0048: // frameSameRRect - case 0x0049: // paintSameRRect - case 0x004a: // eraseSameRRect - case 0x004b: // invertSameRRect - case 0x004c: // fillSameRRect - nDataSize=ReadAndDrawSameRoundRect(shapeDMethod); - break; - - case 0x004d: // Reserved (0 Bytes) - case 0x004e: // Reserved (0 Bytes) - case 0x004f: // Reserved (0 Bytes) - nDataSize=0; - break; - - case 0x0050: // frameOval - case 0x0051: // paintOval - case 0x0052: // eraseOval - case 0x0053: // invertOval - case 0x0054: // fillOval - nDataSize=ReadAndDrawOval(shapeDMethod); - break; - - case 0x0055: // Reserved (8 Bytes) - case 0x0056: // Reserved (8 Bytes) - case 0x0057: // Reserved (8 Bytes) - nDataSize=8; - break; - - case 0x0058: // frameSameOval - case 0x0059: // paintSameOval - case 0x005a: // eraseSameOval - case 0x005b: // invertSameOval - case 0x005c: // fillSameOval - nDataSize=ReadAndDrawSameOval(shapeDMethod); - break; - - case 0x005d: // Reserved (0 Bytes) - case 0x005e: // Reserved (0 Bytes) - case 0x005f: // Reserved (0 Bytes) - nDataSize=0; - break; - - case 0x0060: // frameArc - case 0x0061: // paintArc - case 0x0062: // eraseArc - case 0x0063: // invertArc - case 0x0064: // fillArc - nDataSize=ReadAndDrawArc(shapeDMethod); - break; - - case 0x0065: // Reserved (12 Bytes) - case 0x0066: // Reserved (12 Bytes) - case 0x0067: // Reserved (12 Bytes) - nDataSize=12; - break; - - case 0x0068: // frameSameArc - case 0x0069: // paintSameArc - case 0x006a: // eraseSameArc - case 0x006b: // invertSameArc - case 0x006c: // fillSameArc - nDataSize=ReadAndDrawSameArc(shapeDMethod); - break; - - case 0x006d: // Reserved (4 Bytes) - case 0x006e: // Reserved (4 Bytes) - case 0x006f: // Reserved (4 Bytes) - nDataSize=4; - break; - - case 0x0070: // framePoly - case 0x0071: // paintPoly - case 0x0072: // erasePoly - case 0x0073: // invertPoly - case 0x0074: // fillPoly - nDataSize=ReadAndDrawPolygon(shapeDMethod); - break; - - case 0x0075: // Reserved (Polygon-Size) - case 0x0076: // Reserved (Polygon-Size) - case 0x0077: // Reserved (Polygon-Size) - pPict->ReadUInt16( nUSHORT ); nDataSize=nUSHORT; - break; - - case 0x0078: // frameSamePoly - case 0x0079: // paintSamePoly - case 0x007a: // eraseSamePoly - case 0x007b: // invertSamePoly - case 0x007c: // fillSamePoly - nDataSize=ReadAndDrawSamePolygon(shapeDMethod); - break; - - case 0x007d: // Reserved (0 Bytes) - case 0x007e: // Reserved (0 Bytes) - case 0x007f: // Reserved (0 Bytes) - nDataSize=0; - break; - - case 0x0080: // frameRgn - case 0x0081: // paintRgn - case 0x0082: // eraseRgn - case 0x0083: // invertRgn - case 0x0084: // fillRgn - nDataSize=ReadAndDrawRgn(shapeDMethod); - break; - - case 0x0085: // Reserved (Region-Size) - case 0x0086: // Reserved (Region-Size) - case 0x0087: // Reserved (Region-Size) - pPict->ReadUInt16( nUSHORT ); nDataSize=nUSHORT; - break; - - case 0x0088: // frameSameRgn - case 0x0089: // paintSameRgn - case 0x008a: // eraseSameRgn - case 0x008b: // invertSameRgn - case 0x008c: // fillSameRgn - nDataSize=ReadAndDrawSameRgn(shapeDMethod); - break; - - case 0x008d: // Reserved (0 Bytes) - case 0x008e: // Reserved (0 Bytes) - case 0x008f: // Reserved (0 Bytes) - nDataSize=0; - break; - - case 0x0090: { // BitsRect - BitmapEx aBmp; - tools::Rectangle aSrcRect, aDestRect; - nDataSize=ReadPixMapEtc(aBmp, false, true, &aSrcRect, &aDestRect, true, false); - DrawingMethod( PictDrawingMethod::PAINT ); - pVirDev->DrawBitmapEx(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp); - break; - } - case 0x0091: { // BitsRgn - BitmapEx aBmp; - tools::Rectangle aSrcRect, aDestRect; - nDataSize=ReadPixMapEtc(aBmp, false, true, &aSrcRect, &aDestRect, true, true); - DrawingMethod( PictDrawingMethod::PAINT ); - pVirDev->DrawBitmapEx(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp); - break; - } - case 0x0092: // Reserved (n Bytes) - case 0x0093: // Reserved (n Bytes) - case 0x0094: // Reserved (n Bytes) - case 0x0095: // Reserved (n Bytes) - case 0x0096: // Reserved (n Bytes) - case 0x0097: // Reserved (n Bytes) - pPict->ReadUInt16( nUSHORT ); nDataSize=2+nUSHORT; - break; - - case 0x0098: { // PackBitsRect - BitmapEx aBmp; - tools::Rectangle aSrcRect, aDestRect; - nDataSize=ReadPixMapEtc(aBmp, false, true, &aSrcRect, &aDestRect, true, false); - DrawingMethod( PictDrawingMethod::PAINT ); - pVirDev->DrawBitmapEx(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp); - break; - } - case 0x0099: { // PackBitsRgn - BitmapEx aBmp; - tools::Rectangle aSrcRect, aDestRect; - nDataSize=ReadPixMapEtc(aBmp, false, true, &aSrcRect, &aDestRect, true, true); - DrawingMethod( PictDrawingMethod::PAINT ); - pVirDev->DrawBitmapEx(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp); - break; - } - case 0x009a: { // DirectBitsRect - BitmapEx aBmp; - tools::Rectangle aSrcRect, aDestRect; - nDataSize=ReadPixMapEtc(aBmp, true, false, &aSrcRect, &aDestRect, true, false); - DrawingMethod( PictDrawingMethod::PAINT ); - pVirDev->DrawBitmapEx(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp); - break; - } - case 0x009b: { // DirectBitsRgn - BitmapEx aBmp; - tools::Rectangle aSrcRect, aDestRect; - nDataSize=ReadPixMapEtc(aBmp, true, false, &aSrcRect, &aDestRect, true, true); - DrawingMethod( PictDrawingMethod::PAINT ); - pVirDev->DrawBitmapEx(aDestRect.TopLeft(),aDestRect.GetSize(),aBmp); - break; - } - case 0x009c: // Reserved (n Bytes) - case 0x009d: // Reserved (n Bytes) - case 0x009e: // Reserved (n Bytes) - case 0x009f: // Reserved (n Bytes) - pPict->ReadUInt16( nUSHORT ); nDataSize=2+nUSHORT; - break; - - case 0x00a0: // ShortComment - nDataSize=2; - break; - - case 0x00a1: // LongComment - pPict->SeekRel(2); pPict->ReadUInt16( nUSHORT ); nDataSize=4+nUSHORT; - break; - - default: // 0x00a2 bis 0xffff (most times reserved) - if (nOpcode<=0x00af) { pPict->ReadUInt16( nUSHORT ); nDataSize=2+nUSHORT; } - else if (nOpcode<=0x00cf) { nDataSize=0; } - else if (nOpcode<=0x00fe) { sal_uInt32 nTemp; pPict->ReadUInt32( nTemp ) ; nDataSize = nTemp; nDataSize+=4; } - // Osnola: checkme: in the Quickdraw Ref examples ( for pict v2) - // 0x00ff(EndOfPict) is also not followed by any data... - else if (nOpcode==0x00ff) { nDataSize=IsVersion2 ? 2 : 0; } // OpEndPic - else if (nOpcode<=0x01ff) { nDataSize=2; } - else if (nOpcode<=0x0bfe) { nDataSize=4; } - else if (nOpcode<=0x0bff) { nDataSize=22; } - else if (nOpcode==0x0c00) { nDataSize=24; } // HeaderOp - else if (nOpcode<=0x7eff) { nDataSize=24; } - else if (nOpcode<=0x7fff) { nDataSize=254; } - else if (nOpcode<=0x80ff) { nDataSize=0; } - else { sal_uInt32 nTemp; pPict->ReadUInt32( nTemp ) ; nDataSize = nTemp; nDataSize+=4; } - } - - if (nDataSize==0xffffffff) { - pPict->SetError(SVSTREAM_FILEFORMAT_ERROR); - return 0; - } - return nDataSize; -} - -void PictReader::ReadPict( SvStream & rStreamPict, GDIMetaFile & rGDIMetaFile ) -{ - try { - sal_uInt16 nOpcode; - sal_uInt8 nOneByteOpcode; - sal_uInt64 nSize; - - pPict = &rStreamPict; - nOrigPos = pPict->Tell(); - SvStreamEndian nOrigNumberFormat = pPict->GetEndian(); - - aActForeColor = COL_BLACK; - aActBackColor = COL_WHITE; - nActPenSize = Size(1,1); - eActROP = RasterOp::OverPaint; - eActMethod = PictDrawingMethod::UNDEFINED; - aActOvalSize = Size(1,1); - - aActFont.SetCharSet( GetTextEncoding()); - aActFont.SetFamily(FAMILY_SWISS); - aActFont.SetFontSize(Size(0,12)); - aActFont.SetAlignment(ALIGN_BASELINE); - - aHRes = aVRes = Fraction( 1, 1 ); - - pVirDev = VclPtr<VirtualDevice>::Create(); - pVirDev->EnableOutput(false); - rGDIMetaFile.Record(pVirDev); - - pPict->SetEndian(SvStreamEndian::BIG); - - ReadHeader(); - - aPenPosition=Point(-aBoundingRect.Left(),-aBoundingRect.Top()); - aTextPosition=aPenPosition; - - sal_uInt64 nPos=pPict->Tell(); - - for (;;) { - - if (IsVersion2 ) - pPict->ReadUInt16( nOpcode ); - else - { - pPict->ReadUChar( nOneByteOpcode ); - nOpcode=static_cast<sal_uInt16>(nOneByteOpcode); - } - - if (pPict->GetError()) - break; - - if (pPict->eof()) - { - pPict->SetError(SVSTREAM_FILEFORMAT_ERROR); - break; - } - - if (nOpcode==0x00ff) - break; - - nSize=ReadData(nOpcode); - - if ( IsVersion2 ) - { - if ( nSize & 1 ) - nSize++; - - nPos+=2+nSize; - } - else - nPos+=1+nSize; - - if (!checkSeek(*pPict, nPos)) - { - pPict->SetError(SVSTREAM_FILEFORMAT_ERROR); - break; - } - } - - pVirDev->SetClipRegion(); - rGDIMetaFile.Stop(); - pVirDev.disposeAndClear(); - - rGDIMetaFile.SetPrefMapMode( MapMode( MapUnit::MapInch, Point(), aHRes, aVRes ) ); - rGDIMetaFile.SetPrefSize( aBoundingRect.GetSize() ); - - pPict->SetEndian(nOrigNumberFormat); - - if (pPict->GetError()) pPict->Seek(nOrigPos); - } catch (...) - { - rStreamPict.SetError(SVSTREAM_FILEFORMAT_ERROR); - } -} - -namespace pict { - -void ReadPictFile(SvStream &rStreamPict, GDIMetaFile& rGDIMetaFile) -{ - PictReader aPictReader; - aPictReader.ReadPict(rStreamPict, rGDIMetaFile); -} - -} - -//================== GraphicImport - the exported function ================ - -extern "C" SAL_DLLPUBLIC_EXPORT bool -iptGraphicImport( SvStream& rIStm, Graphic & rGraphic, FilterConfigItem* ) -{ - GDIMetaFile aMTF; - bool bRet = false; - - pict::ReadPictFile( rIStm, aMTF ); - - if ( !rIStm.GetError() ) - { - rGraphic = Graphic( aMTF ); - bRet = true; - } - - return bRet; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/filter/source/graphicfilter/ipict/ipict.hxx b/filter/source/graphicfilter/ipict/ipict.hxx deleted file mode 100644 index 31ffdac0a81e..000000000000 --- a/filter/source/graphicfilter/ipict/ipict.hxx +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- 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/. - */ - -#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IPICT_HXX -#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IPICT_HXX - -#include <sal/config.h> - -class GDIMetaFile; -class SvStream; - -namespace pict -{ -/// Function to access PictReader::ReadPict for unit testing. -void ReadPictFile(SvStream& rStreamPict, GDIMetaFile& rGDIMetaFile); -} - -#endif // INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IPICT_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/filter/source/graphicfilter/ipict/shape.cxx b/filter/source/graphicfilter/ipict/shape.cxx deleted file mode 100644 index 79643123639c..000000000000 --- a/filter/source/graphicfilter/ipict/shape.cxx +++ /dev/null @@ -1,259 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -/** Osnola: -IMPORTANT NOTE: some Quickdraw lines/frames can not be "quickly" drawn exactly: -for instance, when PenSize=(1,1), the line from (0,0) to (8,0) -corresponds to the rectangle (0,0)(0,1)(9,1)(9,0), which can only be drawn - by drawing a rectangle. Drawing a non horizontal/vertical will imply to draw -a polygon, ... -Similarly, drawing the frame of a rectangle (0,0)(0,1)(9,1)(9,0) when PenSize=(1,1), -will imply to draw a rectangle (0.5,0.5)(0.5,8.5)(8.5,8.5)(8.5,0.5) with linewidth=1... - -Here, we choose: -- for horizontal/vertical lines and line with length less than five to draw the real line, -- in the other case, we keep the same shape (even if this means some "bad" coordinates) -*/ - -#include <basegfx/polygon/b2dpolygon.hxx> -#include <basegfx/polygon/b2dpolygontools.hxx> -#include "shape.hxx" - -namespace PictReaderShapePrivate { - /** returns an inside rectangle knowing the penSize in order to obtain the ``correct'' position - when we draw a frame in wide length*/ - static tools::Rectangle contractRectangle(bool drawFrame, tools::Rectangle const &rect, Size const &pSize) { - if (!drawFrame) return rect; - tools::Long penSize=(pSize.Width()+pSize.Height())/2; - if (2*penSize > rect.Right()-rect.Left()) penSize = (rect.Right()-rect.Left()+1)/2; - if (2*penSize > rect.Bottom()-rect.Top()) penSize = (rect.Bottom()-rect.Top()+1)/2; - tools::Long const X[2] = { rect.Left()+penSize/2, rect.Right()-(penSize+1)/2 }; - tools::Long const Y[2] = { rect.Top()+penSize/2, rect.Bottom()-(penSize+1)/2 }; - return tools::Rectangle(Point(X[0],Y[0]), Point(X[1], Y[1])); - } -} - -namespace PictReaderShape { - //--------- draws a horizontal/vertical/small line (by creating a "rectangle/polygon") --------- - static bool drawLineHQ(VirtualDevice *dev, Point const &orig, Point const &dest, Size const &pSize) { - tools::Long dir[2] = { dest.X()-orig.X(), dest.Y()-orig.Y() }; - bool vertic = dir[0] == 0; - bool horiz = dir[1] == 0; - if (!horiz && !vertic && dir[0]*dir[0]+dir[1]*dir[1] > 25) return false; - - using namespace basegfx; - B2DPolygon poly; - if (horiz || vertic) { - tools::Long X[2]={ orig.X(), dest.X() }, Y[2] = { orig.Y(), dest.Y() }; - if (horiz) { - if (X[0] < X[1]) X[1]+=pSize.Width(); - else X[0]+=pSize.Width(); - Y[1] += pSize.Height(); - } - else { - if (Y[0] < Y[1]) Y[1]+=pSize.Height(); - else Y[0]+=pSize.Height(); - X[1] += pSize.Width(); - } - poly.append(B2DPoint(X[0], Y[0])); poly.append(B2DPoint(X[1], Y[0])); - poly.append(B2DPoint(X[1], Y[1])); poly.append(B2DPoint(X[0], Y[1])); - poly.append(B2DPoint(X[0], Y[0])); - } - else { - tools::Long origPt[4][2] = { { orig.X(), orig.Y() }, { orig.X()+pSize.Width(), orig.Y() }, - { orig.X()+pSize.Width(), orig.Y()+pSize.Height() }, - { orig.X(), orig.Y()+pSize.Height() }}; - int origAvoid = dir[0] > 0 ? (dir[1] > 0 ? 2 : 1) : (dir[1] > 0 ? 3 : 0); - tools::Long destPt[4][2] = { { dest.X(), dest.Y() }, { dest.X()+pSize.Width(), dest.Y() }, - { dest.X()+pSize.Width(), dest.Y()+pSize.Height() }, - { dest.X(), dest.Y()+pSize.Height() }}; - for (int w = origAvoid+1; w < origAvoid+4; w++) { - int wh = w%4; - poly.append(B2DPoint(origPt[wh][0], origPt[wh][1])); - } - for (int w = origAvoid+3; w < origAvoid+6; w++) { - int wh = w%4; - poly.append(B2DPoint(destPt[wh][0], destPt[wh][1])); - } - int wh = (origAvoid+1)%4; - poly.append(B2DPoint(origPt[wh][0], origPt[wh][1])); - } - - // HACK: here we use the line coloring when drawing the shape - // must be changed if other parameter are changed to draw - // a line/fill shape - Color oldFColor = dev->GetFillColor(), oldLColor = dev->GetLineColor(); - dev->SetFillColor(oldLColor); dev->SetLineColor(COL_TRANSPARENT); - dev->DrawPolygon(poly); - dev->SetLineColor(oldLColor); dev->SetFillColor(oldFColor); - return true; - } - - - //-------------------- draws a line -------------------- - - void drawLine(VirtualDevice *dev, Point const &orig, Point const &dest, Size const &pSize) { - if (drawLineHQ(dev,orig,dest,pSize)) return; - - tools::Long penSize=(pSize.Width()+pSize.Height())/2; - tools::Long decal[2] = { pSize.Width()/2, pSize.Height()/2}; - - using namespace basegfx; - B2DPolygon poly; - poly.append(B2DPoint(double(orig.X()+decal[0]), double(orig.Y()+decal[1]))); - poly.append(B2DPoint(double(dest.X()+decal[0]), double(dest.Y()+decal[1]))); - dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLineJoin::NONE); - } - - //-------------------- draws a rectangle -------------------- - /* Note(checkme): contradictally with the QuickDraw's reference 3-23, it seems better to consider - that the frame/content of a rectangle appears inside the given rectangle. Does a conversion - appear between the pascal functions and the data stored in the file ? */ - void drawRectangle(VirtualDevice *dev, bool drawFrame, tools::Rectangle const &orig, Size const &pSize) { - int penSize=(pSize.Width()+pSize.Height())/2; - tools::Rectangle rect = PictReaderShapePrivate::contractRectangle(drawFrame, orig, pSize); - tools::Long const X[2] = { rect.Left(), rect.Right() }; - tools::Long const Y[2] = { rect.Top(), rect.Bottom() }; - - using namespace basegfx; - B2DPolygon poly; - poly.append(B2DPoint(X[0], Y[0])); poly.append(B2DPoint(X[1], Y[0])); - poly.append(B2DPoint(X[1], Y[1])); poly.append(B2DPoint(X[0], Y[1])); - poly.append(B2DPoint(X[0], Y[0])); - - if (drawFrame) - dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLineJoin::NONE); - else - dev->DrawPolygon(poly); - } - - //-------------------- draws an ellipse -------------------- - void drawEllipse(VirtualDevice *dev, bool drawFrame, tools::Rectangle const &orig, Size const &pSize) { - int penSize=(pSize.Width()+pSize.Height())/2; - tools::Rectangle oval = PictReaderShapePrivate::contractRectangle(drawFrame, orig, pSize); - using namespace basegfx; - tools::Long const X[2] = { oval.Left(), oval.Right() }; - tools::Long const Y[2] = { oval.Top(), oval.Bottom() }; - B2DPoint center(0.5*(X[1]+X[0]), 0.5*(Y[1]+Y[0])); - B2DPolygon poly = basegfx::utils::createPolygonFromEllipse(center, 0.5*(X[1]-X[0]), 0.5*(Y[1]-Y[0])); - if (drawFrame) - dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLineJoin::NONE); - else - dev->DrawPolygon(poly); - } - - //-------------------- draws an arc/pie -------------------- - void drawArc(VirtualDevice *dev, bool drawFrame, tools::Rectangle const &orig, const double& angle1, const double& angle2, Size const &pSize) { - int penSize=(pSize.Width()+pSize.Height())/2; - tools::Rectangle arc = PictReaderShapePrivate::contractRectangle(drawFrame, orig, pSize); - using namespace basegfx; - - // pict angle are CW with 0 at twelve o'clock (with Y-axis inverted)... - double angl1 = angle1-M_PI_2; - double angl2 = angle2-M_PI_2; - tools::Long const X[2] = { arc.Left(), arc.Right() }; - tools::Long const Y[2] = { arc.Top(), arc.Bottom() }; - B2DPoint center(0.5*(X[1]+X[0]), 0.5*(Y[1]+Y[0])); - - // We must have angl1 between 0 and F_2PI - while (angl1 < 0.0) { angl1 += F_2PI; angl2 += F_2PI; } - while (angl1 >= F_2PI) { angl1 -= F_2PI; angl2 -= F_2PI; } - - // if this happen, we want a complete circle - // so we set angl2 slightly less than angl1 - if (angl2 >= angl1+F_2PI) angl2 = angl1-0.001; - - // We must have angl2 between 0 and F_2PI - while (angl2 < 0.0) angl2 += F_2PI; - while (angl2 >= F_2PI) angl2 -= F_2PI; - - B2DPolygon poly = basegfx::utils::createPolygonFromEllipseSegment(center, 0.5*(X[1]-X[0]), 0.5*(Y[1]-Y[0]), angl1, angl2); - if (drawFrame) - dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLineJoin::NONE); - else { - // adds circle's center - poly.append(center); - dev->DrawPolygon(poly); - } - } - //-------------------- draws a rectangle with round corner -------------------- - void drawRoundRectangle(VirtualDevice *dev, bool drawFrame, tools::Rectangle const &orig, Size const &ovalSize, Size const &pSize) { - int penSize=(pSize.Width()+pSize.Height())/2; - tools::Rectangle oval = PictReaderShapePrivate::contractRectangle(drawFrame, orig, pSize); - int ovalW=ovalSize.Width(), ovalH=ovalSize.Height(); - using namespace basegfx; - tools::Long const X[2] = { oval.Left(), oval.Right() }; - tools::Long const Y[2] = { oval.Top(), oval.Bottom() }; - tools::Long width = X[1] - X[0]; - tools::Long height = Y[1] - Y[0]; - if (ovalW > width) ovalW = static_cast< int >( width ); - if (ovalH > height) ovalH = static_cast< int >( height ); - - B2DRectangle rect(B2DPoint(X[0],Y[0]), B2DPoint(X[1],Y[1])); - B2DPolygon poly = basegfx::utils::createPolygonFromRect(rect, (width != 0.0) ? ovalW/width : 0.0, (height != 0.0) ? ovalH/height : 0.0); - - if (drawFrame) - dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLineJoin::NONE); - else - dev->DrawPolygon(poly); - } - - //-------------------- draws a polygon -------------------- -void drawPolygon(VirtualDevice *dev, bool drawFrame, tools::Polygon const &orig, Size const &pSize) { - int penSize=(pSize.Width()+pSize.Height())/2; - tools::Long decalTL[2] = {0, 0}, decalBR[2] = { pSize.Width(), pSize.Height()}; - if (drawFrame) { - decalTL[0] += penSize/2; decalTL[1] += penSize/2; - decalBR[0] -= (penSize+1)/2; decalBR[1] -= (penSize+1)/2; - } - // Quickdraw Drawing Reference 3-82: the pen size is only used for frame - else decalBR[0] = decalBR[1] = 0; - - - int numPt = orig.GetSize(); - if (numPt <= 1) return; - - // we compute a barycenter of the point to define the extended direction of each point - double bary[2] = { 0.0, 0.0 }; - for (int i = 0; i < numPt; i++) { - Point const &pt = orig.GetPoint(i); - bary[0] += double(pt.X()); bary[1] += double(pt.Y()); - } - bary[0]/=double(numPt); bary[1]/=double(numPt); - - using namespace basegfx; - B2DPolygon poly; - poly.reserve(numPt); - // Note: a polygon can be open, so we must not close it when we draw the frame - for (int i = 0; i < numPt; i++) { - Point const &pt = orig.GetPoint(i); - double x = (double(pt.X()) < bary[0]) ? pt.X()+decalTL[0] : pt.X()+decalBR[0]; - double y = (double(pt.Y()) < bary[1]) ? pt.Y()+decalTL[1] : pt.Y()+decalBR[1]; - poly.append(B2DPoint(x, y)); - } - if (drawFrame) - dev->DrawPolyLine(poly, double(penSize), basegfx::B2DLineJoin::NONE); - else - dev->DrawPolygon(poly); - } - - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/filter/source/graphicfilter/ipict/shape.hxx b/filter/source/graphicfilter/ipict/shape.hxx deleted file mode 100644 index bccd39e63c26..000000000000 --- a/filter/source/graphicfilter/ipict/shape.hxx +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IPICT_SHAPE_HXX -#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IPICT_SHAPE_HXX - -#include <vcl/virdev.hxx> - -namespace PictReaderShape { - /** draws a line from orig to dest knowing penSize - - Attention: in order to draw horizontal/vertical/small lines, this function can instead draw a rectangle or - a polygon. In this case, we retrieve the line information from VirtualDev ( GetLineColor ) - and we use them as fill information ( SetFillColor ). We restore after the VirtualDev state. - - This implies also that this function must be modified if we use real pattern to draw these primitives. - */ - void drawLine(VirtualDevice *dev, Point const &orig, Point const &dest, Size const &pSize); - - /** draws a rectangle knowing penSize */ - void drawRectangle(VirtualDevice *dev, bool drawFrame, tools::Rectangle const &rect, Size const &pSize); - - /** draws a polygon knowing penSize */ -void drawPolygon(VirtualDevice *dev, bool drawFrame, tools::Polygon const &rect, Size const &pSize); - - /** draws an ellipse knowing penSize */ - void drawEllipse(VirtualDevice *dev, bool drawFrame, tools::Rectangle const &orig, Size const &pSize); - - /** draws a rounded rectangle knowing penSize - \note ovalSize is two time the size of the corner - */ - void drawRoundRectangle(VirtualDevice *dev, bool drawFrame, tools::Rectangle const &orig, Size const &ovalS, Size const &pSize); - - /** draws an arc in a b2dpolygon knowing penSize - \note - it supposes that angl1 < angl2 - */ - void drawArc(VirtualDevice *dev, bool drawFrame, tools::Rectangle const &orig, const double& angle1, const double& angle2, Size const &pSize); -} - -#endif // INCLUDED_FILTER_SOURCE_GRAPHICFILTER_IPICT_SHAPE_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |