Difference between revisions of "Working with Shapes"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (Shape's Rotation and sharing)
m (Line Style)
Line 274: Line 274:
==Line Style==
==Line Style==
The corresponding IDL files are :
The corresponding IDL files are (<idl>com.sun.star.drawing.LineProperties</idl>, <idl>com.sun.star.drawing.LineStyle</idl> and <idl>com.sun.star.drawing.LineDash</idl>):
<source lang="idl">
<source lang="idl">
Line 364: Line 364:
The dash styles are given  
The dash styles are given now (<idl>com.sun.star.drawing.DashStyle</idl>)
<source lang="idl">
<source lang="idl">

Revision as of 16:32, 7 March 2009


We describe first our new starting code. Any procedures are added to simplify the listings given here (from Christian Junker). We are using in this code com.sun.star.drawing.XShapes, com.sun.star.drawing.XShape, com.sun.star.drawing.XDrawPage and com.sun.star.beans.XPropertySet interfaces and com.sun.star.awt.Point, com.sun.star.awt.Size structures.

//Listing 1 New sub to simplify Shape Management
// C++
// Don't forget to add : #include <com/sun/star/drawing/XShapes.hpp>
// Don't forget to add "com.sun.star.drawing.XShapes \" in the makefile
// Don't forget to add : using namespace com::sun::star::beans;
// Don't forget to add : #include <com/sun/star/beans/XPropertySet.hpp>
// Don't forget to add "com.sun.star.beans.XPropertySet \" in the makefile
// Christian Junker code
void MakePosition(sal_Int32 x, sal_Int32 y, ::com::sun::star::awt::Point *Pos) 
	Pos->X = x; 
	Pos->Y = y; 
void MakeSize(sal_Int32 width, sal_Int32 height, ::com::sun::star::awt::Size *Size) 
	Size->Width = width; 
	Size->Height = height; 
void DrawMe(Reference< XShape > &Shape, Reference< XDrawPage > &page, const char *shapename) 
	Reference< XShapes > Shapes(page, UNO_QUERY); 
	Reference< XPropertySet > shapeprops(Shape, UNO_QUERY); 

With these procedures we start now from a rectangle shape. Our new starting main code is then using a lot of interfaces com.sun.star.drawing.XDrawPagesSupplier, com.sun.star.drawing.XDrawPages, com.sun.star.beans.XIndexAccess, com.sun.star.drawing.XDrawPage, com.sun.star.drawing.XShape, com.sun.star.container.XNamed and com.sun.star.drawing.RectangleShape service:

//Listing 2 Our new starting Code
int main( ) {
//retrieve an instance of the remote service manager
    Reference< XMultiServiceFactory > rOfficeServiceManager;
    rOfficeServiceManager = ooConnect();
    if( rOfficeServiceManager.is() ){
        printf( "Connected sucessfully to the office\n" );
//get the desktop service using createInstance returns an XInterface type
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
//query for the XComponentLoader interface
    Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
    if( rComponentLoader.is() ){
        	printf( "XComponentloader successfully instanciated\n" );
//get an instance of the OOowriter document
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
        Sequence < ::com::sun::star::beans::PropertyValue >());
// added code here
	Reference< XDrawPagesSupplier > rDrawDoc(xcomponent, UNO_QUERY);
// query the XDrawPages Interface
	Reference< XDrawPages > rDrawPages = rDrawDoc->getDrawPages();
// query the XIndexAccess Interface
	Reference< XIndexAccess > rPageIndexAccess(rDrawPages, UNO_QUERY);
	Any DrawPage = rPageIndexAccess->getByIndex(0);
// Query the XDrawPage Interface
	Reference< XDrawPage > rDrawPage(DrawPage, UNO_QUERY);
// query for the XNamed Interface
	Reference< XNamed > rNamed(DrawPage, UNO_QUERY);
	rNamed->setName(OUString::createFromAscii("My first page"));
	Reference< XMultiServiceFactory > DocFactory(xcomponent, UNO_QUERY);
	Point *Pos = new (Point);
	Size *TheSize = new ( Size );
	Reference< XInterface > RectangleShape = DocFactory->createInstance(
	               OUString::createFromAscii("com.sun.star.drawing.RectangleShape") );
	Reference< XShape > rRectShape(RectangleShape, UNO_QUERY);
	MakePosition(2000, 6000, Pos);
	MakeSize(7000, 2000, TheSize);
	DrawMe(rRectShape, rDrawPage, "My TextShape");
// add code here 
    return 0;

This code draws a blue colored rectangle.

Shape's Properties

Background Colors and Shape Colors

The shape is usually created with a default background color and and a uniform (solid) color. It is possible to change this. We search how, and then begin with a look to <OpenOffice.org1.1_SDK>/idl/com/sun/star/drawing/fillstyle.idl file (available also here :com.sun.star.drawing.fillstyle):

//Listing 3 Fillstyle IDL File 
// IDL
module com {  module sun {  module star {  module drawing {
enum FillStyle
}; }; }; };

This problem has been already tackled in To go further : the Enumeration values Problem  : we can deduce from this IDL file that our constants in C++ are : FillStyle_NONE, FillStyle_SOLID, ... and FillStyle_BITMAP and we have to construct the corresponding hpp and hxx files. The second problem is how to translate this OOoBasic piece of code :

'Listing 4 How to translate this OOoBasic Code ?
REM  *****  BASIC  *****
MaForme.FillColor = RGB(255,200,255)
MaForme.FillStyle = com.sun.star.drawing.FillStyle.NONE

To put it differently, is the FillStyle a property and what about FillColor ? To search an answer we return to IDL file with FillProperties.idl (available also here com.sun.star.drawing.FillProperties) :

//Listing 5 Fillproperties IDL File 
// IDL
module com { module sun { module star { module drawing {
service FillProperties
	[property] com::sun::star::drawing::FillStyle FillStyle;
	[property] long FillColor;
	[property] short FillTransparence;
	[property] string FillTransparenceGradientName;
	[optional, property] com::sun::star::awt::Gradient FillTransparenceGradient;
	[property] string FillGradientName;
	[optional, property] com::sun::star::awt::Gradient FillGradient;
	[property] string FillHatchName;
	[optional, property] com::sun::star::drawing::Hatch FillHatch;
	[property] string FillBitmapName;
	[optional, property] com::sun::star::awt::XBitmap FillBitmap;
	[optional, property] string FillBitmapURL;
	[property] short FillBitmapOffsetX;
	[property] short FillBitmapOffsetY;
	[property] short FillBitmapPositionOffsetX;
	[property] short FillBitmapPositionOffsetY;
	[property] com::sun::star::drawing::RectanglePoint FillBitmapRectanglePoint;
	[property] boolean FillBitmapLogicalSize;
	[property] long FillBitmapSizeX;
	[property] long FillBitmapSizeY;
	[property] com::sun::star::drawing::BitmapMode FillBitmapMode;
	[property] boolean FillBackground;
}; }; }; };

The both first properties seem interesting for us. We begin with FillColor. Adding the code below, we obtain a rectangle with an other color (green here) using com.sun.star.beans.XPropertySet interface

//Listing 6 Coloring the Shape Background
// C++
// Don't forget to add : using namespace com::sun::star::beans;
// Don't forget to add : #include <com/sun/star/beans/XPropertySet.hpp>
// Don't forget to add "com.sun.star.beans.XPropertySet \" in the makefile
// Get the property set of the rRectShape 
	Reference< XPropertySet > rShapeProps(rRectShape,UNO_QUERY);
	Any color;
	color<<=(long)0xFF00;  //green

The color is defined in RGB : one octet for each : 0xff0000 is red, 0x00ff00 is green and 0x0000ff is blue. It's time to remove the background color with the FillStyle_NONE constant. Simply add this code :

//Listing 7 Removing the Shape Background
// C++
// Don't forget to add : #include <com/sun/star/drawing/FillStyle.hpp>
// Don't forget to add "com.sun.star.drawing.FillStyle \" in the makefile
	Any FillStyle;
	FillStyle <<= FillStyle_NONE;

We stop here but there is a lot to do with other FillStyle constants.

See also com.sun.star.drawing.FillStyle, com.sun.star.beans.XPropertySet, com.sun.star.drawing.FillProperties and com.sun.star.beans.XPropertySet.

Shape and Shadow

Shadow is described by com.sun.star.drawing.ShadowProperties interface presented below :

// IDL
module com {  module sun {  module star {  module drawing {
service ShadowProperties
	[property] boolean Shadow;
	[property] long ShadowColor;
	[property] short ShadowTransparence;
	[property] long ShadowXDistance;
	[property] long ShadowYDistance;
}; }; }; };

Then the corresponding C++ code to manipulate these properties could be :

//Listing 8 Shadowing a Shape
// C++
// Shadow
	Any ShadowProperties[4];
	ShadowProperties[0] <<= (sal_Bool)true;
	ShadowProperties[1] <<= (long) 0xFF0000; // red
	ShadowProperties[2] <<= (long) 300;
	ShadowProperties[3] <<= (long) 300;

This code adds a red shadow at the rectangle shape.

Shape's Rotation and sharing

The corresponding IDL file is

// IDL
module com {  module sun {  module star {  module drawing {
service RotationDescriptor
/** This is the angle for rotation of this Shape.
	The shape is rotated counter-clockwise around the center of the bounding box. */
	[property] long RotateAngle;
	[optional, property] long ShearAngle;
}; }; }; };

The angle is given in 1/100° starting from an horizontal line.

//Listing 9 Rotating a Shape
// C++
	Any Angle;
	Angle <<= (long)3000; // 30 degres

which gives a 30° rotation. We have already defined in previous code, the variable rShapeProps as a com.sun.star.beans.XPropertySet interface.

See also com.sun.star.drawing.RotationDescriptor.

Line Style

The corresponding IDL files are (com.sun.star.drawing.LineProperties, com.sun.star.drawing.LineStyle and com.sun.star.drawing.LineDash):

//Listing 10 Lineproperties IDL file 
// IDL
module com {  module sun {  module star {  module drawing {
service LineProperties
	[property] com::sun::star::drawing::LineStyle LineStyle;
	[property] com::sun::star::drawing::LineDash LineDash;
	[property] long LineColor;
	[property] short LineTransparence;
	[property] long LineWidth; 
	[property] com::sun::star::drawing::LineJoint LineJoint; 
	[optional, property] string LineStartName;
	[optional, property] com::sun::star::drawing::PolyPolygonBezierCoords LineStart; 
	[optional, property] com::sun::star::drawing::PolyPolygonBezierCoords LineEnd; 
	[optional, property] boolean LineStartCenter; 
	[optional, property] long LineStartWidth; 
	[optional, property] boolean LineEndCenter; 
	[optional, property] long LineEndWidth; 
}; }; }; };

completed with :

//Listing 11 LineStyle Enumeration
// IDL
module com {  module sun {  module star {  module drawing {
enum LineStyle
}; }; }; };

We give the significance of these constants :

line styles
Constant Signification
NONE Line is not visible
SOLID continuous line (default value)
DASH Dash line; LineDash property is controling the dash's shape

We give now the LineDash properties with an IDL file

//Listing 12 IDL File : Linedash
// IDL
module com {  module sun {  module star {  module drawing {
struct LineDash
	com::sun::star::drawing::DashStyle Style;
	short Dots; 
	long DotLen; 
	short Dashes; 
	long DashLen; 
	long Distance; 
}; }; }; };

and their meaning :

lineDash properties
Proprerty Signification
Style A constant ( com.sun.star.drawing.DashStyle.xxx) gives the dash style
Dots How many dots
DotLen Dot length in 1/100 mm
Dashes How many dashes
DashLen Dash length in 1/100 mm
Distance distance between dots in 1/100 mm

The dash styles are given now (com.sun.star.drawing.DashStyle)

//Listing 13 DashStyle IDL File 
// IDL
module com {  module sun {  module star {  module drawing {
enum DashStyle
}; }; }; };

Here is an example in C++ which uses a line style :

//Listing 14 Modifying a Line Style : en Example
// C++
// Line dash
// Don't forget to add : #include <com/sun/star/drawing/LineDash.hpp>
// Don't forget to add "com.sun.star.drawing.LineDash \" in the makefile
// Don't forget to add : #include <com/sun/star/drawing/LineStyle.hpp>
// Don't forget to add "com.sun.star.drawing.LineStyle \" in the makefile
	LineDash *Tirets = new (LineDash);
	Tirets->Style = DashStyle_RECT;
  	Tirets->Dots = 3;
  	Tirets->DotLen = 50;
  	Tirets->Dashes = 2;
  	Tirets->DashLen = 200;
  	Tirets->Distance = 150;
	Any LineStyle,LineDash,LineWidth;
	LineStyle <<= LineStyle_DASH;
	LineDash <<= *Tirets;
	color <<= (long)0xFF00;
	LineWidth <<= (long) 50;

Adding this code to the previous one, gives this figure :


See also com.sun.star.drawing.LineDash and com.sun.star.drawing.LineStyle.

We can go further with shapes now.

Drawing Shapes

Polyline Shape

When working with polyline the first question we have to answer is what is a Sequence < Sequence < Point >> ? We give the IDL description :

//Listing 15 PointSequenceSequence IDL File
// IDL
module com { module sun { module star { module drawing {
	typedef sequence<PointSequence> PointSequenceSequence;
}; }; }; };

What is a PointSequence ?

//Listing 16 PointSequence IDL File
// IDL
module com { module sun { module star { module drawing {
	typedef sequence<com::sun::star::awt::Point> PointSequence;
}; }; }; };

We can have a look at PolyLineShape now :

//Listing 17 PolyLineShape IDL File 
// IDL
 module com {  module sun {  module star {  module drawing {
service PolyLineShape
	service com::sun::star::drawing::Shape;
	service com::sun::star::drawing::LineProperties;
	service com::sun::star::drawing::PolyPolygonDescriptor;
	service com::sun::star::drawing::Text;
	service com::sun::star::drawing::ShadowProperties;
	service com::sun::star::drawing::RotationDescriptor;
}; }; }; };

The last IDL file we have to inspect is the PolyPolygonDescriptor service :

//Listing 18 PolyPolygonDescriptor IDL File
// IDL
module com {  module sun {  module star {  module drawing {
service PolyPolygonDescriptor
	[readonly, property] com::sun::star::drawing::PolygonKind PolygonKind;
	[property] com::sun::star::drawing::PointSequenceSequence PolyPolygon;
	[property] com::sun::star::drawing::PointSequenceSequence Geometry;
}; }; }; };

where we see the PolyPolygon is a property. These files allow us to draw any tips : first construct a Sequence< Sequence< Point >> and put values in it second transform it in an Any variable third, use the XPropertySet to gives a value to the property "PolyPolygon" This conduct us to the following example

//Listing 19 Using a Polyline Shape
// C++
	Sequence< Sequence< Point > > PointsSeqSeq(2);
	Sequence< Point > PointsArray(4);
	//Size *TheSize = new ( Size );
	Reference< XInterface > PolyLineShape = DocFactory->createInstance(
	               OUString::createFromAscii("com.sun.star.drawing.PolyLineShape") );
	Reference< XShape > rPolyLineShape(PolyLineShape, UNO_QUERY);
	MakePosition(1100, 8000, &PointsArray[0]);
	MakePosition(1500, 6000, &PointsArray[1]);
	MakePosition(1900, 8000, &PointsArray[2]);
	MakePosition(2300, 6000, &PointsArray[3]);
	MakePosition(1100, 9000, &PointsArray[0]);
	MakePosition(1500, 7000, &PointsArray[1]);
	MakePosition(1900, 9000, &PointsArray[2]);
	MakePosition(2300, 7000, &PointsArray[3]);
	MakePosition(2700, 9000, &PointsArray[4]);
	DrawMe(rPolyLineShape, rDrawPage, "");
	Any PropspolyPoly;
	PropspolyPoly <<= PointsSeqSeq;
	Reference< XPropertySet > rPolyShapeProps(rPolyLineShape,UNO_QUERY);

When running, this example gives a figure presented below :

Polyline Example

If you replace “PolyLineShape” with “PolyPolygonShape” in the previous code, you obtain the same shape but closed (and by default filled).

See also com.sun.star.drawing.PointSequenceSequence, com.sun.star.drawing.PolyLineShape, com.sun.star.drawing.PolyPolygonDescriptor and com.sun.star.drawing.PolyPolygonShape.

Bezier Shape

Let us begin describing the Bezier's struct : PolyPolygonBezierCoords is presented now :

//Listing 20 PolyPolygonBezierCoords IDL File
// IDL
module com {  module sun {  module star {  module drawing {
struct PolyPolygonBezierCoords
	// DocMerge: empty anyway
	com::sun::star::drawing::PointSequenceSequence Coordinates; 
	// DocMerge: empty anyway
	com::sun::star::drawing::FlagSequenceSequence Flags;
}; }; }; };

PointSequenceSequence has been already encountered in the previous chapter. More precision on flags is expected. Again the IDL file will give us this information :

//Listing 21 PolygonFlags enumeration : IDL File 
// IDL
 module com {  module sun {  module star {  module drawing {
enum PolygonFlags
}; }; }; };

The service ClosedBezierShape is interesting :

//Listing 22 ClosedBezierShape Service : IDL File 
// IDL
 module com {  module sun {  module star {  module drawing {
service ClosedBezierShape
	service com::sun::star::drawing::Shape;
	service com::sun::star::drawing::LineProperties;
	service com::sun::star::drawing::FillProperties;
	service com::sun::star::drawing::PolyPolygonBezierDescriptor;
	service com::sun::star::drawing::Text;
	service com::sun::star::drawing::ShadowProperties;
	service com::sun::star::drawing::RotationDescriptor;
}; }; }; };

and also the PolyPolygonDescriptor :

//Listing 23 PolyPolygonBezierDescriptor Service : IDL File 
// IDL
module com {  module sun {  module star {  module drawing {
service PolyPolygonBezierDescriptor
	[readonly, property] com::sun::star::drawing::PolygonKind PolygonKind;
	[property] com::sun::star::drawing::PolyPolygonBezierCoords PolyPolygonBezier;
	[property] com::sun::star::drawing::PolyPolygonBezierCoords Geometry;
}; }; }; };

Again as in previous chapter, what we see are properties. We have never encounter the first (PolygonKind) and then give the corresponding IDL file :

//Listing 24 PolygonKind Enumeration : IDL File 
// IDL
module com {  module sun {  module star {  module drawing {
enum PolygonKind
	/** This is the PolygonKind for a LineShape.	 */
	/** This is the PolygonKind for a PolyPolygonShape.	 */
	/** This is the PolygonKind for a PolyLineShape.	 */
	/** This is the PolygonKind for an OpenBezierShape.	 */
	/** This is the PolygonKind for a ClosedBezierShape.	 */
	/** This is the PolygonKind for an OpenFreeHandShape.	 */
	/** This is the PolygonKind for a ClosedFreeHandShape.	 */
	/** This is the PolygonKind for a PolyPolygonPathShape.	 */
	/** This is the PolygonKind for a PolyLinePathShape.	 */
}; }; }; };

Note this property is read only. We have left comments to understand the values' significance, difficult to guess with only their name. The following code draw a Bezier closed shape :

//Listing 25 Bezier Shape : an Example
// C++
// Bezier
// Don't forget to add : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
// Don't forget to add "com.sun.star.drawing.PolyPolygonBezierCoords \" in the makefile
	struct PolyPolygonBezierCoords BezierCords;
// we suppose we use the previous declarations of PointsSeqSeq and PointsArray 
// (previous chapter on PolyPolygonShape) : we then only realloc
	MakePosition(1000, 1000, &PointsArray[0]);
	MakePosition(3000, 4000, &PointsArray[1]);
	MakePosition(3000, 4000, &PointsArray[2]);
	MakePosition(5000, 1000, &PointsArray[3]);
	BezierCords.Coordinates = PointsSeqSeq;
// Don't forget to add : #include <com/sun/star/drawing/FlagSequenceSequence.hpp>
// Don't forget to add "com.sun.star.drawing.FlagSequenceSequence \" in the makefile
// Don't forget to add : #include <com/sun/star/drawing/FlagSequence.hpp>
// Don't forget to add "com.sun.star.drawing.FlagSequence \" in the makefile
	FlagSequenceSequence flagsSeqSeq(1);
	FlagSequence flagsSeq(4);
// Don't forget to add : #include <com/sun/star/drawing/PolygonFlags.hpp>
// Don't forget to add "com.sun.star.drawing.PolygonFlags \" in the makefile
	flagsSeq[0] = PolygonFlags_NORMAL;
	flagsSeq[1] = PolygonFlags_CONTROL;
	flagsSeq[2] = PolygonFlags_CONTROL;
	flagsSeq[3] = PolygonFlags_NORMAL;
	flagsSeqSeq[0] = flagsSeq;
	BezierCords.Flags = flagsSeqSeq;
// PolyPolygonBezier is a property => construct a Any type;
	Any ClosedBezierProperty;
	ClosedBezierProperty <<= BezierCords;
// create the PolyPolygonBezierShape Service
	Reference< XInterface > closedBezierShape = DocFactory->createInstance(
	               OUString::createFromAscii("com.sun.star.drawing.ClosedBezierShape") );
	Reference< XShape > rClosedBezierShape(closedBezierShape, UNO_QUERY);
	if (! rClosedBezierShape.is()) printf("****Pb with Bezier\n");
	DrawMe(rClosedBezierShape, rDrawPage, "");
// Adjust the properties :
	Reference< XPropertySet > rClosedBezierShapeProps(rClosedBezierShape,UNO_QUERY);
                               ("PolyPolygonBezier"),	ClosedBezierProperty);

It is possible to replace “ClosedBezierShape” with “OpenBezierShape” and obtain an open shape. When reading the PolyPolygonBezierShape.idl file I deduce I have only to replace “ClosedBezierShape” with “PolyPolygonBezierShape to have an open Bezier Shape. But it doesn't work and I don't know why for the moment. Andrew Pitonyak writes in his book : “Not all combinations of points and flags are valid” and I suppose I have a false combination.

See also com.sun.star.drawing.PolyPolygonBezierCoords, com.sun.star.drawing.FlagSequenceSequence, com.sun.star.drawing.FlagSequence, com.sun.star.drawing.PolygonFlags and com.sun.star.drawing.ClosedBezierShape

Connectors and glues points

//Listing 26  XGluePointsSupplier IDL File 
// IDL
module com {  module sun {  module star {  module drawing {
interface XGluePointsSupplier: com::sun::star::uno::XInterface
	com::sun::star::container::XIndexContainer getGluePoints();
}; }; }; };

To do : to continue

See also

Personal tools