summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-01-25 21:29:46 +0000
committerMichael Meeks <michael.meeks@collabora.com>2015-01-25 21:29:46 +0000
commitfd9ab498690ec2bcee31d0d97492fb317432e1a4 (patch)
tree5b814d621cdd7c5fa1908fa18637502ec702f493
parentzint-barcode: add optional internal barcode functionality from zint. (diff)
downloadcore-feature/barcode.tar.gz
core-feature/barcode.zip
barcodes: initial attempt to use zint to render bar-codes. feature/barcode
We create a plug-able CustomShape engine; currently no UI for editing (add draw:engine="org.libreoffice.draw.barcode" draw:data="baa code" to your draw:custom-shape in the ODF). Change-Id: Ibcc7e6e068402a0aa37dfb858fa2aafe5e7c94c8
-rw-r--r--include/svx/EnhancedCustomShape2d.hxx1
-rw-r--r--svx/Library_svx.mk5
-rw-r--r--svx/source/customshapes/BarCodeCustomShapeEngine.cxx172
-rw-r--r--svx/source/customshapes/BarCodeRender.cxx112
-rw-r--r--svx/source/customshapes/BarCodeRender.hxx22
-rw-r--r--svx/source/customshapes/EnhancedCustomShape2d.cxx2
-rw-r--r--svx/util/svx.component4
7 files changed, 316 insertions, 2 deletions
diff --git a/include/svx/EnhancedCustomShape2d.hxx b/include/svx/EnhancedCustomShape2d.hxx
index 871776e1417d..af576eac4011 100644
--- a/include/svx/EnhancedCustomShape2d.hxx
+++ b/include/svx/EnhancedCustomShape2d.hxx
@@ -74,7 +74,6 @@ class SVX_DLLPUBLIC EnhancedCustomShape2d : public SfxItemSet
{
SdrObject* pCustomShapeObj;
MSO_SPT eSpType;
-
sal_Int32 nCoordLeft;
sal_Int32 nCoordTop;
sal_Int32 nCoordWidthG;
diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk
index f1c0c2ba54fe..2bc3e7273505 100644
--- a/svx/Library_svx.mk
+++ b/svx/Library_svx.mk
@@ -73,6 +73,7 @@ $(eval $(call gb_Library_use_externals,svx,\
boost_headers \
icuuc \
icu_headers \
+ $(if $(filter ZINT,$(BUILD_TYPE)),zint) \
))
$(eval $(call gb_Library_add_exception_objects,svx,\
@@ -97,6 +98,10 @@ $(eval $(call gb_Library_add_exception_objects,svx,\
svx/source/accessibility/lookupcolorname \
svx/source/accessibility/svxpixelctlaccessiblecontext \
svx/source/accessibility/svxrectctaccessiblecontext \
+ $(if $(filter ZINT,$(BUILD_TYPE)),\
+ svx/source/customshapes/BarCodeCustomShapeEngine \
+ svx/source/customshapes/BarCodeRender \
+ ) \
svx/source/customshapes/EnhancedCustomShape3d \
svx/source/customshapes/EnhancedCustomShapeEngine \
svx/source/customshapes/EnhancedCustomShapeFontWork \
diff --git a/svx/source/customshapes/BarCodeCustomShapeEngine.cxx b/svx/source/customshapes/BarCodeCustomShapeEngine.cxx
new file mode 100644
index 000000000000..798598ab9265
--- /dev/null
+++ b/svx/source/customshapes/BarCodeCustomShapeEngine.cxx
@@ -0,0 +1,172 @@
+/* -*- 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 <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/drawing/XCustomShapeEngine.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <basegfx/tools/unotools.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+#include <svx/unoapi.hxx>
+#include <svx/unopage.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/sdasitm.hxx>
+
+#include "BarCodeRender.hxx"
+
+using namespace css;
+using namespace css::uno;
+
+namespace {
+
+class BarCodeCustomShapeEngine : public cppu::WeakImplHelper3
+ < lang::XInitialization, lang::XServiceInfo,
+ drawing::XCustomShapeEngine >
+{
+ Reference< drawing::XShape > mxShape;
+
+public:
+ BarCodeCustomShapeEngine() {}
+ virtual ~BarCodeCustomShapeEngine() {}
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw ( uno::Exception, uno::RuntimeException, std::exception ) SAL_OVERRIDE;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE
+ {
+ return OUString( "org.libreoffice.draw.barcode" );
+ }
+ virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName )
+ throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE
+ {
+ return cppu::supportsService(this, rServiceName);
+ }
+ virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE
+ {
+ Sequence< OUString > aRet(1);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = "com.sun.star.drawing.CustomShapeEngine";
+ return aRet;
+ }
+
+ // XCustomShapeEngine
+ virtual uno::Reference< drawing::XShape > SAL_CALL render()
+ throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
+ virtual awt::Rectangle SAL_CALL getTextBounds()
+ throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
+ virtual drawing::PolyPolygonBezierCoords SAL_CALL getLineGeometry()
+ throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
+ virtual uno::Sequence< uno::Reference< drawing::XCustomShapeHandle > > SAL_CALL getInteraction()
+ throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
+};
+
+// XInitialization
+void SAL_CALL BarCodeCustomShapeEngine::initialize( const Sequence< Any >& aArgs )
+ throw ( Exception, RuntimeException, std::exception )
+{
+ sal_Int32 i;
+ Sequence< beans::PropertyValue > aParameter;
+ for ( i = 0; i < aArgs.getLength(); i++ )
+ {
+ if ( aArgs[ i ] >>= aParameter )
+ break;
+ }
+ for ( i = 0; i < aParameter.getLength(); i++ )
+ {
+ const beans::PropertyValue& rProp = aParameter[ i ];
+ if ( rProp.Name == "CustomShape" )
+ rProp.Value >>= mxShape;
+ }
+}
+
+Reference< drawing::XShape > SAL_CALL BarCodeCustomShapeEngine::render()
+ throw ( RuntimeException, std::exception )
+{
+ Reference< drawing::XShape > xShape;
+ SAL_INFO("svx", "barcode engine render");
+ SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) );
+ if ( pSdrObjCustomShape )
+ {
+ Point aP( pSdrObjCustomShape->GetSnapRect().Center() );
+ Size aS( pSdrObjCustomShape->GetLogicRect().GetSize() );
+ aP.X() -= aS.Width() / 2;
+ aP.Y() -= aS.Height() / 2;
+
+ Rectangle aLogicRect;
+ aLogicRect = Rectangle( aP, aS );
+
+ OUString aData(static_cast<const SdrCustomShapeDataItem&>(pSdrObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_DATA )).GetValue());
+
+ SdrObjGroup *pShape = svx::BarCodeRender(aLogicRect, aData);
+ if (pShape)
+ {
+ SfxItemSet aSet( pSdrObjCustomShape->GetMergedItemSet() );
+ pShape->SetMergedItemSet( aSet );
+
+ pShape->NbcSetStyleSheet( pSdrObjCustomShape->GetStyleSheet(), true );
+ pShape->RecalcSnapRect();
+
+ xShape = SvxDrawPage::CreateShapeByTypeAndInventor(
+ pShape->GetObjIdentifier(),
+ pShape->GetObjInventor(), pShape, NULL );
+ }
+
+ if ( xShape.is() )
+ {
+ SvxShape* pTake = SvxShape::getImplementation( xShape );
+ if ( pTake )
+ pTake->TakeSdrObjectOwnership();
+ }
+ }
+ return xShape;
+}
+
+awt::Rectangle SAL_CALL BarCodeCustomShapeEngine::getTextBounds()
+ throw ( RuntimeException, std::exception )
+{
+ awt::Rectangle aTextRect;
+ SAL_INFO("svx", "barcode engine get text bounds: stub");
+ return aTextRect;
+}
+
+drawing::PolyPolygonBezierCoords SAL_CALL BarCodeCustomShapeEngine::getLineGeometry()
+ throw ( RuntimeException, std::exception )
+{
+ drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords;
+ SAL_INFO("svx", "barcode engine get line geometry: stub");
+ return aPolyPolygonBezierCoords;
+}
+
+Sequence< Reference< drawing::XCustomShapeHandle > > SAL_CALL BarCodeCustomShapeEngine::getInteraction()
+ throw ( RuntimeException, std::exception )
+{
+ return Sequence< Reference< drawing::XCustomShapeHandle > >();
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface * SAL_CALL
+org_libreoffice_draw_barcode_get_implementation(
+ uno::XComponentContext *,
+ uno::Sequence<uno::Any> const &)
+{
+ return cppu::acquire(new BarCodeCustomShapeEngine);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/customshapes/BarCodeRender.cxx b/svx/source/customshapes/BarCodeRender.cxx
new file mode 100644
index 000000000000..8b13e36d383a
--- /dev/null
+++ b/svx/source/customshapes/BarCodeRender.cxx
@@ -0,0 +1,112 @@
+/* -*- 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 <BarCodeRender.hxx>
+
+#include <svx/svdobj.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdopath.hxx>
+
+#include <backend/zint.h>
+
+namespace {
+ bool isZIntBitSet(struct zint_symbol *pSymbol, int x, int y)
+ {
+ // this is very odd; bit-masking !?
+ int x_bit = x % 7;
+ x /= 7;
+ return pSymbol->encoded_data[y][x] & (1 << x_bit);
+ }
+}
+
+namespace svx {
+
+SdrObjGroup *BarCodeRender(const Rectangle &rLogicRect, const rtl::OUString &rData)
+{
+ SdrObjGroup *pShape = new SdrObjGroup();
+
+ struct zint_symbol *pSymbol = ZBarcode_Create();
+
+ pSymbol = ZBarcode_Create();
+
+ pSymbol->symbology = BARCODE_QRCODE;
+
+ pSymbol->output_options = 0; // no border
+ pSymbol->border_width = 1;
+ pSymbol->height = rLogicRect.GetSize().Height();
+ pSymbol->option_2 = rLogicRect.GetSize().Width();
+ pSymbol->option_1 = -1; // security level
+ pSymbol->input_mode = UNICODE_MODE;
+ pSymbol->show_hrt = 1; // bool: don't hide text
+ pSymbol->option_3 = 0; // PDF417 may need some love here.
+ pSymbol->scale = 1.0;
+
+ OString aUtf8(rtl::OUStringToOString(rData, RTL_TEXTENCODING_UTF8));
+ if (ZBarcode_Encode(pSymbol, (unsigned char*)aUtf8.getStr(),
+ aUtf8.getLength()))
+ {
+ SAL_WARN("svx", "Failed to encode string '" << rData << " '" <<
+ (pSymbol->errtxt ? pSymbol->errtxt : "<unknown>") << "'");
+ }
+
+ OUString aCaption((const char *)pSymbol->text,
+ pSymbol->text ? strlen((const char *)pSymbol->text) : 0,
+ RTL_TEXTENCODING_UTF8);
+
+ // FIXME: use the pSymbol->errtxt as content if we fail ?
+ // or translate that somehow.
+
+ basegfx::B2DPolyPolygon aPolyPoly;
+ basegfx::B2DPolygon aPoly;
+
+ Point aP(rLogicRect.TopLeft());
+ Size aS(rLogicRect.GetSize() );
+
+ // FIXME: should we use ZBarcode_Render - and walk a list
+ // of output rendering primitives instead ? [ easier? ]
+
+ double xscale = aS.Width()/pSymbol->width;
+ double yscale = aS.Height()/pSymbol->rows;
+ double y = aP.Y();
+ for (int row = 0; row < pSymbol->rows; row++)
+ {
+ for (int i = 0; i < pSymbol->width; i++)
+ {
+ if (isZIntBitSet(pSymbol, i, row))
+ {
+ // FIXME: really we want to build larger polygons
+ // so we should at least scan horizontally to collate.
+
+ // all this for a rectangle ?
+ double xpos = aP.X() + xscale * i;
+ aPoly.append(basegfx::B2DPoint(xpos, y));
+ aPoly.append(basegfx::B2DPoint(xpos + xscale , y));
+ aPoly.append(basegfx::B2DPoint(xpos + xscale , y + yscale));
+ aPoly.append(basegfx::B2DPoint(xpos , y + yscale));
+ aPoly.setClosed(true);
+ aPolyPoly.append(aPoly);
+
+ aPoly.clear();
+ }
+ }
+ y += yscale * pSymbol->row_height[row];
+ }
+
+ SdrPathObj* pStroke = new SdrPathObj(OBJ_POLY, aPolyPoly, 0.5);
+ pShape->GetSubList()->NbcInsertObject(pStroke);
+
+ ZBarcode_Delete(pSymbol);
+
+ return pShape;
+}
+
+} // namespace svx
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/customshapes/BarCodeRender.hxx b/svx/source/customshapes/BarCodeRender.hxx
new file mode 100644
index 000000000000..1ae4b430250a
--- /dev/null
+++ b/svx/source/customshapes/BarCodeRender.hxx
@@ -0,0 +1,22 @@
+/* -*- 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 BAR_CODE_RENDER_HXX
+#define BAR_CODE_RENDER_HXX
+
+class Rectangle;
+class SdrObjGroup;
+namespace rtl { class OUString; }
+
+namespace svx {
+ SdrObjGroup *BarCodeRender(const Rectangle &rLogicRect, const rtl::OUString &rData);
+}
+
+#endif // BAR_CODE_RENDER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx
index 38478bbcb583..98dcd804dcbe 100644
--- a/svx/source/customshapes/EnhancedCustomShape2d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -704,7 +704,7 @@ EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
ClearItem( SDRATTR_TEXTDIRECTION ); //SJ: vertical writing is not required, by removing this item no outliner is created
- // #i105323# For 2D AtoShapes, the shadow attirbute does not need to be applied to any
+ // #i105323# For 2D AutoShapes, the shadow attribute does not need to be applied to any
// of the constucted helper SdrObjects. This would lead to problems since the shadow
// of one helper object would fall on one helper object behind it (e.g. with the
// eyes of the smiley shape). This is not wanted; instead a single shadow 'behind'
diff --git a/svx/util/svx.component b/svx/util/svx.component
index 967677befed0..dba148f4ec25 100644
--- a/svx/util/svx.component
+++ b/svx/util/svx.component
@@ -84,4 +84,8 @@
constructor="com_sun_star_comp_svx_NumberingToolBoxControl_get_implementation">
<service name="com.sun.star.frame.ToolbarController"/>
</implementation>
+ <implementation name="org.libreoffice.draw.barcode"
+ constructor="org_libreoffice_draw_barcode_get_implementation">
+ <service name="com.sun.star.drawing.CustomShapeEngine"/>
+ </implementation>
</component>