Graphical content is expressed as a shape object. Shape objects are created by the document and then added to the draw page. OOo supports numerous types of shapes (see Table 3 )
ShapeType | Description |
---|---|
ClosedBezierShape | A series of Bezier shapes that are closed. |
ConnectorShape | Used to connect shapes or glue points. |
ControlShape | A shape that displays a control such as a button. |
EllipseShape | Draw a circle, an ellipse, or an arc. |
GraphicObjectShape | Display a graphic object such as a bitmap image. There are separate types for presentation documents and drawing documents. |
GroupShape | Represent multiple shapes as a single shape. |
LineShape | A single line. |
MeasureShape | A shape used for measuring in a diagram. |
OLE2Shape | Display an OLE object in a presentation document. There are separate types for presentation documents and drawing documents. |
OpenBezierShape | A series of Bezier lines. |
PageShape | Display a preview of another page. There are separate types for presentation documents and drawing documents. |
PolyLineShape | A series of connected straight lines. |
PolyPolygonBezierShape | A polygon using Bezier curves. |
PolyPolygonShape | A series of straight lines with the first and last points connected. |
RectangleShape | Draw rectangles. |
TextShape | Box designed to hold text. |
PluginShape | Represent a media type that is not directly supported. |
TitleTextShape | A TextShape for titles in a presentation document. |
SubtitleShape | A TextShape for subtitles in a presentation document. |
OutlinerShape | A TextShape for outlines in a presentation document. |
ChartShape | Chart shape in a presentation document. |
NotesShape | A TextShape for notes in a presentation document. |
HandoutShape | A drawing document PageShape for handouts in a presentation document. |
A shape's position is stored in a com.sun.star.awt.Point structure, which contains two Long Integer values, X and Y, representing the upper-left corner in 1/100 mm. A shape's size is stored in a com.sun.star.awt. Size structure, which contains two Long Integer values, Width and Height, in 1/100 mm. See Table. 4
Method | Description |
---|---|
getPosition() | Get the shape's current position in 1/100 mm. |
setPosition(Point) | Set the shape's current position in 1/100 mm. |
getSize() | Get the shape's current size in 1/100 mm. |
setSize(Size) | Set the shape's current size in 1/100 mm. |
getGluePoints() | Get an object that provides indexed access to a set of glue points used internally by the object. Each glue point is a com.sun.star.drawing.GluePoint2 structure (see Table 16). |
getShapeType() | String representing the shape's type. |
Macros that deal with shape objects frequently require the Size and Point structures. The two methods in Listing 9 make it easier to create and set these structures.
Function CreatePoint(ByVal x As Long,ByVal y As Long) As com.sun.star.awt.Point Dim oPoint oPoint = createUnoStruct( "com.sun.star.awt.Point" ) oPoint.X = x : oPoint.Y = y CreatePoint = oPoint End Function Function CreateSize(ByVal x As Long,ByVal y As Long) As com.sun.star.awt.Size Dim oSize oSize = createUnoStruct( "com.sun.star.awt.Size" ) oSize.Width = x : oSize.Height = y CreateSize = oSize End Function
Interfaces define methods and can be derived from other interfaces. Services, on the other hand, implement interfaces and other services. Services also define properties. Some services are defined strictly to define a group of related properties. The properties defined by the Shape service are general and applicable to most shape types (see Table 5 ).
Property | Description |
---|---|
ZOrder | Long Integer representing the ZOrder of this shape. This controls the drawing order of objects, effectively moving an object forward or backward. |
LayerID | Short Integer identifying the layer that contains the shape. |
LayerName | Name of the layer that contains the shape. |
Printable | If True, the shape is included in printed output. |
MoveProtect | If True, the shape cannot be moved interactively by the user . |
Name | Shape name as a String. |
SizeProtect | If True, the user may not change the shape's size. |
Style | Shape's style as a com.sun.star.style.XStyle object. |
Transformation | Transformation matrix of type com.sun.star.drawing.HomogenMatrix3 that can contain translation, rotation, shearing , and scaling. |
OOo defines separate services that encapsulate properties and methods specific to lines, text, shadows, shape rotation, and filling area. Not all shape types support all of these services. For example, it makes no sense for a line shape to support the properties and methods related to filling areas. Table 6 provides a quick overview of the special services supported by each shape type.
ShapeType | Text | Line | Fill | Shadow | Rotation |
---|---|---|---|---|---|
ClosedBezierShape | x | x | x | x | x |
ConnectorShape | x | x | x | x | |
ControlShape | |||||
EllipseShape | x | x | x | x | x |
GraphicObjectShape | x | x | x | ||
GroupShape | |||||
LineShape | x | x | x | x | |
MeasureShape | x | x | x | x | |
OLE2Shape | |||||
OpenBezierShape | x | x | x | x | |
PageShape | |||||
PolyLineShape | x | x | x | x | |
PolyPolygonBezierShape | x | x | x | x | x |
PolyPolygonShape | x | x | x | x | x |
RectangleShape | x | x | x | x | x |
TextShape | x | x | x | x | x |
TitleTextShape | x | x | x | x | x |
SubtitleShape | x | x | x | x | x |
OutlinerShape | x | x | x | x | x |
ChartShape | |||||
NotesShape | x | x | x | x | x |
HandoutShape |
Any shape that supports the com.sun.star.drawing.Text service has the ability to contain text. The drawing text service supports the standard com.sun.star.text.XText interface and a special set of drawing text properties. Besides character and paragraph properties, the drawing text properties service defines properties specifically designed for shape objects (see Table 7 ).
Property | Description |
---|---|
IsNumbering | If True, numbering is ON for the text in this shape. |
NumberingRules | Describes the numbering levels as a sequence of com.sun.star.style.NumberingRule. |
TextAutoGrowHeight | If True, the shape height changes automatically when text is added or removed. |
TextAutoGrowWidth | If True, the shape width changes automatically when text is added or removed. |
TextContourFrame | If True, the text is aligned with the left edge of the shape. |
TextFitToSize | Enumerated value of type com.sun.star.drawing.TextFitToSizeType:
|
TextHorizontalAdjust | Enumerated value of type com.sun.star.drawing.TextHorizontalAdjust:
|
TextVerticalAdjust | Enumerated value of type com.sun.star.drawing.TextVerticalAdjust:
|
TextLeftDistance | Distance from the left edge of the shape to the text as a Long Integer. |
TextRightDistance | Distance from the right edge of the shape to the text as a Long Integer. |
TextUpperDistance | Distance from the upper edge of the shape to the text as a Long Integer. |
TextLowerDistance | Distance from the lower edge of the shape to the text as a Long Integer. |
TextMaximumFrameHeight | Limit a shape's height as it grows automatically as you enter text. |
TextMaximumFrameWidth | Limit a shape's width as it grows automatically as you enter text. |
TextMinimumFrameHeight | Limit a shape's minimum height as it grows automatically as you enter text. |
TextMinimumFrameWidth | Limit a shape's minimum width as it grows automatically as you enter text. |
TextAnimationAmount | Number of pixels the text is moved in each animation step. |
TextAnimationCount | Number of times the text animation is repeated. |
TextAnimationDelay | Delay, in thousandths of a second, between each animation step. |
TextAnimationDirection | Enumerated value of type com.sun.star.drawing.TextAnimationDirection: LEFT, RIGHT, UP, and DOWN. |
TextAnimationKind | Enumerated value of type com. sun. star.drawing.TextAnimationKind:
|
TextAnimationStartInside | If True, the text is visible at the start of the animation. |
TextAnimationStopInside | If True, the text is visible at the end of the animation. |
TextWritingMode | Enumerated value of type com.sun.star.text.TextWritingMode:
|
The default behavior of a MeasureShape (see Figure 3 ) is to display the actual length of the shape. The macro in Listing 10 creates two measure shapes and changes the text of one of them to "Width". To help illustrate setting the properties in Table 7, the TextAnimationKind property is set to SCROLL so that the text continuously scrolls from right to left.
Sub drawMeasureShape() Dim oPage 'Page on which to draw Dim oShape 'Shape to insert Dim oStart As new com.sun.star.awt.Point Dim oEnd As new com.sun.star.awt.Point oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = ThisComponent.createInstance("com.sun.star.drawing.MeasureShape") oPage.add(oShape) REM The following values MUST be set AFTER the object is inserted. oStart.X = oPage.Width / 4 : oEnd.X = oPage.Width / 2 oStart.Y = oPage.Height/4 : oEnd.Y = oPage.Height/4 oShape.StartPosition = oStart oShape.EndPosition = oEnd oShape.setString("Width") oShape.TextAnimationKind = com.sun.star.drawing.TextAnimationKind.SCROLL oShape = ThisComponent.createInstance("com.sun.star.drawing.MeasureShape") oPage.add(oShape) oStart.X = oPage.Width / 5 : oEnd.X = oPage.Width / 5 oStart.Y = oPage.Height/4 : oEnd.Y = oPage.Height/2.5 oShape.StartPosition = oStart oShape.EndPosition = oEnd End Sub
Shapes that support the com.sun.star.drawing.LineProperties service can influence how lines are drawn. Most shapes support line properties because most shapes contain lines of some sort . The specific properties dealing with line endpoints and start points are supported only by shapes with open ends. See Table 8 .
Property | Description |
---|---|
LineStyle | Enumerated value of type com. sun. star.drawing. LineStyle: NONE (the line is hidden), SOLID, and DASH. |
LineDash | Enumerated value of type com. sun.star.drawing.LineDash that defines how dashed lines are drawn.
|
LineColor | Line color as a Long Integer. |
LineTransparence | Line transparency percentage as a Short Integer. |
LineWidth | Line width in 1/100 mm as a Long Integer. |
LineJoint | Enumerated value of type com.sun.star.drawing.LineJoint:
|
LineStartName | Name of the line start point's PolyPolygonBezierCoords. |
LineStart | Line start in the form of a PolyPolygonBezierCoords. |
LineEnd | Line end in the form of a PolyPolygonBezierCoords. |
LineStartCenter | If True, the line starts from the center of the polygon. |
LineStartWidth | Width of the line start polygon. |
LineEndCenter | If True, the line ends in the center of the polygon. |
LineEndWidth | Width of the line end polygon. |
Shapes that support the com.sun.star.drawing.FillProperties service (see Table 9 ) are able to control how open area in the shape is filled. In general, if the shape is closed, it can be filled.
Property | Description |
---|---|
FillStyle | Enumerated value of type com. sun. star.drawing. FillStyle: NONE, SOLID, GRADIENT, HATCH, and BITMAP. |
FillColor | Color to use if the FillStyle is SOLID. |
FillTransparence | Transparency percentage if the FillStyle is SOLID. |
FillTransparenceGradientName | Name of the gradient style to use; empty is okay. |
FillTransparenceGradient | Defines the gradient with a com. sun. star.awt. Gradient structure:
|
FillGradientName | If the FillStyle is GRADIENT, this is the name of the fill gradient style used. |
FillGradient | If the FillStyle is GRADIENT, this describes the gradient used. |
FillHatchName | If the FillStyle is GRADIENT, this is the name of the fill hatch style used. |
FillHatch | If the FillStyle is HATCH, this describes the hatch used. |
FillBitmapName | If the FillStyle is BITMAP, this is the name of the fill bitmap style used. |
FillBitmap | If the FillStyle is BITMAP, this is the bitmap used. |
FillBitmapURL | If the FillStyle is BITMAP, this is a URL to the bitmap used. |
FillBitmapOffsetX | The horizontal offset where the tile starts. |
FillBitmapOffsetY | The vertical offset where the tile starts. It is given as a percentage in relation to the width of the bitmap. |
FillBitmapPositionOffsetX | Every second line of tiles is moved the given percentage of the witdh of the bitmap. |
FillBitmapPositionOffsetY | Every second row of tiles is moved the given percentage of the width of the bitmap. |
FillBitmapRectanglePoint | The RectanglePoint specifies the position inside the bitmap to use as the top-left position for rendering. |
FillBitmapLogicalSize | Specifies if the size is given in percentage or as an absolute value. |
FillBitmapSizeX | The width of the tile for filling. |
FillBitmapSizeY | The height of the tile for filling. |
FillBitmapMode | This enum selects how an area is filled with a single bitmap. |
FillBackground | If True, the transparent background of a hatch-filled area is drawn in the current background color. |
The macro in Listing 11 draws a closed Bezier shape. The fill style is set to use a gradient, which means that the darkness of the shape changes over the shape. The resulting shape (see Figure 4 ) contains narrow bands of each color or intensity. You can smooth the appearance of the gradient by using the FillTransparenceGradient property as mentioned in Table 9.
Sub DrawClosedBezierShape Dim oDoc Dim oPage 'Page on which to draw Dim oShape 'Shape to insert Dim oCoords 'Coordinates of the polygon to insert oCoords = createUnoStruct("com.sun.star.drawing.PolyPolygonBezierCoords") REM Fill in the actual coordinates. The first and last points REM are normal points and the middle points are Bezier control points. oCoords.Coordinates = Array(_ Array(_ CreatePoint( 1000, 1000 ),_ CreatePoint( 3000, 4000 ),_ CreatePoint( 3000, 4000 ),_ CreatePoint( 5000, 1000 )_ )_ ) oCoords.Flags = Array(_ Array(_ com.sun.star.drawing.PolygonFlags.NORMAL,_ com.sun.star.drawing.PolygonFlags.CONTROL,_ com.sun.star.drawing.PolygonFlags.CONTROL,_ com.sun.star.drawing.PolygonFlags.NORMAL _ )_ ) oDoc = ThisComponent oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = oDoc.createInstance("com.sun.star.drawing.ClosedBezierShape") oPage.add(oShape) oShape.FillStyle = com.sun.star.drawing.FillStyle.GRADIENT oShape.PolyPolygonBezier = oCoords End Sub
Shapes that support the ShadowProperties service can be drawn with a shadow. You can set the shadow location and color by using the properties in Table 10 .
Property | Description |
---|---|
Shadow | If True, the shape has a shadow. |
ShadowColor | Color of the shadow as a Long Integer. |
ShadowTransparence | Shadow transparency as a percentage. |
ShadowXDistance | Horizontal distance of the left edge of the shape to the shadow. |
ShadowYDistance | Vertical distance of the top edge of the shape to the shadow. |
A common method for drawing shadows is to draw the shape at an offset location using a shadow color, and then draw the shape normally (see Figure 5 ). With this in mind, consider the properties ShadowXDistance and ShadowYDistance as the distance that the "shadow object'' is shifted when it is drawn. The default values for ShadowXDistance and ShadowYDistance are positive, which shifts the shadow right and down. A negative shadow distance shifts the shadow left and up. The macro in Listing 12 draws two boxes; the first box uses a standard shadow that is shifted right and down, and the second box has the shadow shifted left and down (see Figure 5).
Sub drawRectangleWithShadow() Dim oPage 'Page on which to draw Dim oShape 'Shape to insert oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = ThisComponent.createInstance("com.sun.star.drawing.RectangleShape") oPage.add(oShape) oShape.setPosition(createPoint(1000, 1000)) oShape.setSize(createSize(4000, 1000)) oShape.setString("box 1") oShape.Shadow = True oShape = ThisComponent.createInstance("com.sun.star.drawing.RectangleShape") oPage.add(oShape) oShape.setPosition(createPoint(6000, 1000)) oShape.setSize(createSize(4000, 1000)) oShape.setString("box 2") oShape.Shadow = True oShape.ShadowXDistance = -150 oShape.CornerRadius = 100 End Sub
The com.sun.star.drawing.RotationDescriptor provides the ability to rotate and shear a shape. Shear stretches a shape and would, for example, change a rectangle into a parallelogram. The RotateAngle property is a Long Integer measured in 1/100 degrees. The shape is rotated counterclockwise around the center of the shape's bounding box. The ShearAngle property is also a Long Integer measured in 1/100 degrees, but the shape is sheared clockwise around the center of the bounding box.
The macro in Listing 13 rotates a rectangle 20 degrees counterclockwise and shears a rectangle 25 degrees clockwise. This code also draws a normal rectangle with no rotation or shear to help you visualize the effects (see Figure 6 ).
Sub drawRotateRectangle() Dim oPage 'Page on which to draw Dim oShape 'Shape to insert oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = ThisComponent.createInstance("com.sun.star.drawing.RectangleShape") oPage.add(oShape) oShape.setPosition(createPoint(1000, 1000)) oShape.setSize(createSize(4000, 1500)) oShape.setstring("box 1") oShape.RotateAngle = 2000 '20 degrees oShape = ThisComponent.createlnstance("com.sun.star.drawing.RectangleShape") oPage.add(oShape) oShape.setPosition(createPoint(1000, 1000)) oShape.setSize(createSize(4000, 1500)) oShape.FillStyle = com.sun.star.drawing.FillStyle.NONE oShape.LineStyle = com.sun.star.drawing.LineStyle.DASH oShape = ThisComponent.createInstance("com.sun.star.drawing.RectangleShape") oPage.add(oShape) oShape.setPosition(createPoint(6000, 1000)) oShape.setSize(createSize(4000, 1500)) oShape.setstring("box 2") oShape.ShearAngle = 2500 '25 degrees oShape = ThisComponent.createInstance("com.sun.star.drawing.RectangleShape") oPage.add(oShape) oShape.setPosition(createPoint(6000, 1000)) oShape.setSize(createSize(4000, 1500)) oShape.FillStyle = com.sun.star.drawing.FillStyle.NONE oShape.LineStyle = com.sun.star.drawing.LineStyle.DASH End Sub
OOo supports many different shape types, which build on each other. Most of the shape types are obvious from their names. For example, a LineShape is a line. I was initially confused , however, by the gratuitous use of the word "Poly" in shape names such as PolyLineShape and PolyPolygonShape. The prefix "Poly" comes from the Greek and it means "many." So in OOo, a Polygon is a figure containing many angles, a PolyLineShape contains many line shapes, and a PolyPolygonShape contains many polygon shapes.
The purpose of the LineShape service is to draw a simple line. A LineShape requires an initial position and a size. The macro in Listing 14 draws a line from the point (1000, 1000) to the point (1999, 1999). The endpoint of the line is set by setting the shape's size.
Sub SimpleLine Dim oPage 'Page on which to draw Dim oShape 'Shape to insert oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = ThisComponent.createInstance("com.sun.star.drawing.LineShape") oPage.add(oShape) oShape.setPosition(CreatePoint(1000, 1000)) oShape.setSize(CreateSize(1000, 1000)) End Sub
Although I've never seen it used, the LineShape service supports the PolyPolygonDescriptor service (see Table 11 ). The implication is that internally simple lines are represented as an open polygon that contains one line. The PolyPolygonDescriptor is used in other services as well.
Property | Description |
---|---|
PolygonKind | This read-only property identifies the polygon type (see Table 12). |
PolyPolygon | Reference points for this polygon. This is an array of arrays. Each contained array is an array of com.sun. star.awt. Point structures. These points are used to draw the polygon and may have been transformed by a rotation or other transformation. |
Geometry | These are the PolyPolygon points with no transformations. |
The PolygonKind enumeration identifies the polygon type (see Table 12 ). The PolygonKind is a read-only property in the PolyPolygonDescriptor service (see Table 11). In other words, you can see what the type is, but you can't set it.
Value | Description |
---|---|
LINE | Identifies a LineShape. |
POLY | Identifies a PolyPolygonShape. |
PLIN | Identifies a PolyLineShape. |
PATHLINE | Identifies an OpenBezierShape. |
PATHFILL | Identifies a ClosedBezierShape. |
FREELINE | Identifies an OpenFreeHandShape. |
FREEFILL | Identifies a ClosedFreeHandShape. |
PATHPOLY | Identifies a PolyPolygonPathShape. |
PATHPLIN | Identifies a PolyLinePathShape. |
The PolyPolygon property in Table 11 allows you to inspect the actual points used in the creation of the line. The code in Listing 15 assumes that oShape contains a LineShape object and it displays the two points in the line.
x = oShape.PolyPolygon(0) MsgBox "" & x(0).X & " and " & x(0).Y MsgBox "" & x(1).X & " and " & x(1).Y
The LineShape service defines a single line, and the PolyLineShape service defines a series of lines. A LineShape is defined by setting its position and size. A PolyLineShape, however, is defined by the PolyPolygonDescriptor (see Table 11). Although it's easy to create a PolyLineShape when you know how, it isn't widely understood .
Note | The PolyPolygon property is an array of arrays that contain points. |
The lines in the PolyLineShape are defined by the PolyPolygon property, which is an array that contains one or more arrays of points. Each array of points is drawn as a series of connected lines, but each array is not specifically connected to the other. The macro in Listing 16 generates two arrays of points (oPoints_1 and oPoints_2) and then the arrays are stored in another array. See Figure 7 .
Sub SimplePolyLineShape Dim oPage 'Page on which to draw Dim oShape 'Shape to insert Dim oPoints_1 'First set of points to plot Dim oPoints_2 'Second set of points to plot oPoints_1 = Array(_ CreatePoint( 1000, 1000 ),_ CreatePoint( 3000, 2000 ),_ CreatePoint( 1000, 2000 ),_ CreatePoint( 3000, 1000 )_ ) oPoints_2 = Array(_ CreatePoint( 4000, 1200 ),_ CreatePoint( 4000, 2000 ),_ CreatePoint( 5000, 2000 ),_ CreatePoint( 5000, 1200 )_ ) oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = ThisComponent.createInstance("com.sun.star.drawing.PolyLineShape") oPage.add(oShape) oShape.PolyPolygon = Array(oPoints_1, oPoints_2) oShape.LineWidth = 50 End Sub
Note | The shape is added to the draw page before points are assigned to the PolyPolygon property. |
The PolyPolygon property (shown in Listing 17 ) is an array of arrays. You can run the macro in Listing 16 with only one set of points, but the single array of points must still reside inside a second array.
oShape.PolyPolygon = Array(oPoints_1)
The PolyPolygonShape service defines a series of closed polygons that are not connected (see Figure 8 ). This service is essentially a closed-shape version of the PolyLineShape. Because it produces closed shapes, the PolyPolygonShape service supports fill properties.
The macro in Listing 18 uses the same set of points as the macro in Listing 16, but I moved things around to demonstrate different methods for creating an array of arrays of points. Both macros, however, create the shape and add it to the draw page before setting the properties.
Sub SimplePolyPolygonShape Dim oPage 'Page on which to draw Dim oShape 'Shape to insert oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = ThisComponent.createInstance("com.sun.star.drawing.PolyPolygonShape") oPage.add(oShape) oShape.PolyPolygon = Array(_ Array( CreatePoint( 1000, 1000 ),_ CreatePoint( 3000, 2000 ),_ CreatePoint( 1000, 2000 ),_ CreatePoint( 3000, 1000 )_ ),_ Array( CreatePoint( 4000, 1200 ),_ CreatePoint( 4000, 2000 ),_ CreatePoint( 5000, 2000 ),_ CreatePoint( 5000, 1200 )_ )_ ) oShape.LineWidth = 50 End Sub
Externally, the RectangleShape and the TextShape are virtually identical. The two shape types support the same set of services (except for the defining service, of course) and they can be configured to produce the same output. The primary difference between the two shape types is their default values while producing output. In principle, properties can be adjusted from default values, so that each type could produce either output. The macro in Listing 19 creates a rectangle shape and a text shape next to each other (see Figure 9 ).
Sub SimpleRectangleShape Dim oPage 'Page on which to draw Dim oShape 'Shape to insert oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = ThisComponent.createInstance("com.sun.star.drawing.RectangleShape") oPage.add(oShape) oShape.setPosition(createPoint(1000, 1000)) oShape.setSize(createSize(6000, 1000)) oShape.setString("rectangle") oShape.Shadow = True oShape = ThisComponent.createInstance("com.sun.star.drawing.TextShape") oPage.add(oShape) oShape.setPosition(createPoint(8000, 1000)) oShape.setSize(createSize(10000, 1000)) oShape.setString("text") oShape.Shadow = True End Sub
The RectangleShape and the TextShape types both support the CornerRadius property. The corner radius is a Long Integer that indicates the radius of the circle used to produce the corners. This is demonstrated in Figure 5 as produced by Listing 12.
A mathematician would say that an ellipse is a closed curve that is formed from two points (called the foci) in which the sum of the distances from any point on the curve to the two points is a constant. If the two foci are at the same point, the ellipse is a circle. In simpler terms, an ellipse is a circle or a squashed circle.
While drawing a rectangle, the position identifies the upper-left corner of the rectangle and then the size defines the width and height. If the same point and size is used to draw an ellipse, the ellipse will be contained inside the rectangle and will just barely touch the four sides of the rectangle. Mathematically, the sides of the rectangle are tangent to the ellipse at its principal axes, the maximum and minimum distances across the ellipse. The macro in Listing 20 starts by drawing four ellipse shapes. The final ellipse is rotated 30 degrees. The macro then draws a rectangle using the same position, size, and rotation as the last ellipse (see Figure 10 ). The final rectangle helps to illustrate the relationship between a rectangle and an ellipse.
Sub SimpleEllipseShapes Dim oPage 'Page on which to draw Dim oShape 'Shape to insert Dim i% Dim x Dim nLocs nLocs = Array(_ Array(CreatePoint(1000, 1000), createSize(1000, 1000)),_ Array(CreatePoint(3000, 1000), createSize(1000, 1500)),_ Array(CreatePoint(5000, 1000), createSize(1500, 1000)),_ Array(CreatePoint(7000, 1000), createSize(1500, 1000))_ ) oPage = createDrawPage(ThisComponent, "Test Draw", True) For i = LBound(nLocs) To UBound(nLocs) oShape = ThisComponent.createInstance("com.sun.star.drawing.EllipseShape") oPage.add(oShape) x = nLocs(i) oShape.setPosition(x(0)) oShape.setSize(x(1)) oShape.setString(i) Next oShape.RotateAngle = 3000 REM Now draw a rectangle the same size as the last ellipse. oShape = ThisComponent.createInstance("com.sun.star.drawing.RectangleShape") oPage.add(oShape) oShape.setPosition(x(0)) oShape.setSize(x(1)) oShape.RotateAngle = 3000 oShape.FillStyle = com.sun.star.drawing.FillStyle.NONE End Sub
The Ellipse Shape service contains a property of type CircleKind that determines whether the entire ellipse should be drawn, or only a portion of it (see Table 13 ). In other words, you can draw an arc. The properties CircleStartAngle and CircleEndAngle define where the arc starts and ends. Each ellipse in Figure 10 uses a FULL CircleKind.
Value | Description |
---|---|
com.sun.star.drawing.CircleKind.FULL | A full ellipse. |
com.sun.star.drawing.CircleKind.SECTION | An ellipse with a cut connected by a line. |
com.sun.star.drawing.CircleKind.CUT | An ellipse with a cut connected by two lines. |
com.sun.star.drawing.CircleKind.ARC | An ellipse with an open cut. |
The four different circle kinds are drawn by Listing 21 and shown in Figure 11 .
Sub ArcEllipseShapes Dim oPage 'Page on which to draw Dim oShape 'Shape to insert Dim i% Dim x Dim nLocs nLocs = Array (_ com.sun.star.drawing.CircleKind.FULL,_ com.sun.star.drawing.CircleKind.SECTION,_ com.sun.star.drawing.CircleKind.CUT,_ com.sun.star.drawing.CircleKind.ARC,_ ) oPage = createDrawPage(ThisComponent, "Test Draw", True) For i = LBound(nLocs) To UBound(nLocs) oShape = ThisComponent.createInstance("com.sun.star.drawing.EllipseShape") oPage.add(oShape) oShape.setPosition(CreatePoint((i+1)*2000, 1000)) oShape.setSize(CreateSize(1000,700)) oShape.setString(i) oShape.CircleStartAngle = 9000 oShape.CircleEndAngle = 36000 oShape.CircleKind = nLocs(i) Next End Sub
A Bezier curve is a smooth curve controlled by multiple points. Bezier curves connect the first and last points, but are only influenced by the other points. Mathematicians like Bezier curves because they are invariant under any affine mapping (any arbitrary combination of translation or rotation). Computer graphics professionals like Bezier curves because they are easy to manipulate and transform.
Bezier curves are controlled by a PolyPolygonBezierDescriptor (see Table 14 ), which is almost identical to the PolyPolygonDescriptor described in Table 11. The difference between the two descriptors is that each point in the Bezier curve is categorized based on how the point affects the curve.
Property | Description |
---|---|
PolygonKind | This read-only property identifies the polygon type (see Table 12). |
PolyPolygonBezier | Reference points for this Bezier curve. This is a PolyPolygonBezierCoords structure. The structure contains an array of points and an array of flags to categorize each point as to its function in the curve. |
Geometry | This is the PolyPolygonBezierCoords with no transformations. |
The PolygonBezier property (see Table 14) is a PolyPolygonBezierCoords structure that contains two properties, Coordinates and Flags. The Coordinates property is an array of arrays of points that represent the control points for the Bezier curve. The Flags property is an array of arrays of PolygonFlags (see Table 15 ) that identifies how the corresponding point affects the curve.
Value | Description |
---|---|
NORMAL | The curve travels through normal points. |
SMOOTH | The point is smooth through the point. |
CONTROL | Influence the curve. |
SYMMETRIC | The point is symmetric through the point. |
The macro in Listing 22 draws a small circle at each point in the Coordinates array. Drawing each point helps to visualize and understand how the different points affect the shape of a Bezier curve.
Sub DrawControlPoints(oCoords, oPage, oDoc, nWidth As Long) Dim oPoints 'One subarray of points Dim oPoint 'One point Dim oFlags 'One subarray of flags Dim oShape 'The circle to draw Dim nShape% 'Index into the oCoords arrays Dim i% 'General index variable For nShape = LBound(oCoords.Coordinates) To UBound (oCoords.Coordinates) oPoints = oCoords.Coordinates(nShape) oFlags = oCoords.Flags(nShape) For i = LBound(oPoints) To UBound(oPoints) oShape = oDoc.createInstance("com.sun.star.drawing.EllipseShape") oPage.add(oShape) oPoint = oPoints(i) REM To center the circle, I need to set the position REM as half width back and half width up. oShape.setPosition(CreatePoint(oPoint.X-nWidth/2, oPoint.Y-nWidth/2)) oShape.setSize(CreateSize(nWidth, nWidth) Next Next End Sub
Listing 23 draws two disconnected Bezier curves (see Figure 12 ). The second curve places two control points at the same location. The DrawControlPoints macro in Listing 22 is used to draw the control points along with the Bezier curve.
Sub DrawOpenBezierCurves() Dim oPage 'Page on which to draw Dim oShape 'Shape to insert Dim oDoc Dim i% Dim oCoords 'Coordinates of the polygon to insert oCoords = createUnoStruct("com.sun.star.drawing.PolyPolygonBezierCoords") REM Fill in the actual coordinates. The first and last points REM are normal points and the middle points are Bezier control points. oCoords.Coordinates = Array(_ Array(_ CreatePoint( 1000, 1000 ),_ CreatePoint( 2000, 3000 ),_ CreatePoint( 3000, 0500 ),_ CreatePoint( 4000, 1000 ),_ ),_ Array(_ CreatePoint( 5000, 1000 ),_ CreatePoint( 6500, 0200 ),_ CreatePoint( 6500, 0200 ),_ CreatePoint( 8000, 1000 ),_ ),_ ) oCoords.Flags = Array(_ Array(_ com.sun.star.drawing.PolygonFlags.NORMAL,_ com.sun.star.drawing.PolygonFlags.CONTROL,_ com.sun.star.drawing.PolygonFlags.CONTROL, _ com.sun.star.drawing.PolygonFlags.NORMAL,_ ),_ Array(_ com.sun.star.drawing.PolygonFlags.NORMAL,_ com.sun.star.drawing.PolygonFlags.CONTROL,_ com.sun.star.drawing.PolygonFlags.CONTROL, _ com.sun.star.drawing.PolygonFlags.NORMAL,_ )_ ) oDoc = ThisComponent oPage = createDrawPage(ThisComponent, "Test Draw", True) oShape = oDoc.createInstance("com.sun.star.drawing.OpenBezierShape") oPage.add(oShape) oShape.PolyPolygonBezier = oCoords DrawControlPoints(oCoords, oPage, oDoc, 100) End Sub
Not all combinations of points and flags are valid. A complete discussion of what constitutes a valid combination of points and flags is beyond the scope of this book. A run-time error occurs if you use an incorrect number of points or an unsupported sequence of control flags.
Use the ConnectorShape to provide a connection between two shapes. A "glue point" is a position inside a shape where the endpoint of a ConnectorShape can connect. Each glue point is defined by the GluePoint2 structure (see Table 16 ).
Property | Description |
---|---|
Position | Glue-point position as a point structure. |
IsRelative | If True, Position is given in 1/100 percent. |
PositionAlignment | com.sun.star.drawing.Alignment enumerated value that specifies how the point is moved if the shape is resized. Valid values include: TOP_LEFT, TOP, TOP_RIGHT, LEFT, CENTER, RIGHT, BOTTOM_LEFT, BOTTOM, and BOTTOM_RIGHT. |
Escape | com.sun.star.drawing.EscapeDirection enumerated value that specifies the escape direction for a glue point. Valid values include: SMART, LEFT, RIGHT, UP, DOWN, HORIZONTAL, and VERTICAL. |
IsUserDefined | If False, this is a default glue point. |
Each shape contains a default glue point at the top, right, bottom, and left of the shape. You can access a shape's glue points by using the getGluePoints() method (see Table 4). The index of the default glue points are 0 (top), 1 (right), 2 (bottom), and 3 (left). You also can add new glue points to a shape's default glue points (see Listing 25).
Connector shapes contain StartPosition and EndPosition properties (see Table 17 ), which identify the connector's start and end positions. The start and end positions are used only if the corresponding properties StartShape and EndShape are empty. If the StartShape and EndShape properties are not empty, the connector shape connects to a glue point in the corresponding shape. Connector shapes reference other shapes' glue points by index using the StartGluePointlndex and EndGluePointlndex properties.
Property | Description |
---|---|
StartShape | Start shape, or empty if the start point is not connected to a shape. |
StartGluePointIndex | Index of the glue point in the start shape. |
StartPosition | Start point position in 1/100 mm. You can set the position only if the start point is not connected, but you can always read the point. |
EndShape | End shape, or empty if the start point is not connected to a shape. |
EndPosition | End point position in 1/100 mm. You can set the position only if the end point is not connected, but you can always read the point. |
EndGluePointIndex | Index of the glue point in the end shape. |
EdgeLine1Delta | Distance of line 1. |
EdgeLine2Delta | Distance of line 2. |
EdgeLine3Delta | Distance of line 3. |
EdgeKind | Type of connector (see Table 18). |
Value | Description |
---|---|
STANDARD | The ConnectorShape is drawn with three lines, with the middle line perpendicular to the other two. |
CURVE | The ConnectorShape is drawn as a curve. |
LINE | The ConnectorShape is drawn as one straight line. |
LINES | The ConnectorShape is drawn with three lines. |
Four connector types are supported (see Table 18 ). The connector type determines how the line is drawn between the two points. The STANDARD type prefers to use three lines to connect the shapes, but it will use more lines if required.
Bug | As of OOo 1.1.1, the LINE connector type is not available by name; you must use the corresponding integer value of 2. This is scheduled to be fixed by OOo 2.0. |
The macro in Listing 24 draws four rectangles and then connects the rectangles using a ConnectorShape. Although the macro specifies the initial glue point, the end glue point is automatically chosen by OOo. If the macro did not explicitly set the initial glue point, it also would be automatically chosen. When a glue point is automatically chosen , it is done intelligently, as you can see in Figure 13 .
Sub DrawConnectorShape PrintConTypes() Dim oPage 'Page on which to draw Dim oShapes 'Shape to insert Dim oShape 'Shape to insert Dim nConTypes Dim oDoc Dim i% oDoc = ThisComponent REM The value com.sun.star.drawing.ConnectorType.LINE does not work! nConTypes = Array(_ com.sun.star.drawing.ConnectorType.STANDARD,_ com.sun.star.drawing.ConnectorType.CURVE,_ 2,_ com.sun.star.drawing.ConnectorType.LINES,_ ) oShapes = Array(_ oDoc.createInstance("com.sun.star.drawing.RectangleShape"),_ oDoc.createInstance("com.sun.star.drawing.RectangleShape"),_ oDoc.createInstance("com.sun.star.drawing.RectangleShape"),_ ) REM Create the draw page and then add the shapes before manipulating them. oPage = createDrawPage(oDoc, "Test Draw", True) For i = 0 To 3 oPage.add(oShapes(i)) oShapes(i).setSize(createSize(1300, 1000)) Next oShapes(0).setPosition(createPoint(1000, 1500)) oShapes(1).setPosition(createPoint(4000, 1000)) oShapes(2).setPosition(createPoint(7000, 500)) oShapes(3).setPosition(createPoint(4000, 2500)) For i = 0 To 3 oShapes(i).setString(i) oShape = oDoc.createInstance("com.sun.star.drawing.ConnectorShape") oPage.add(oShape) oShape.StartShape = oShapes(i) oShape.StartGluePointIndex = i oShape.EndShape = oShapes((i + 1) MOD 4) oShape.EdgeKind = nConTypes(i) Next End Sub
Tip | Many of a shape's properties are reset when the shape is added to a draw page. Therefore, you should set most properties after adding the shape to the draw page. It is also important to set properties in the correct order because setting some properties resets other properties. For example, setting a connector's StartShape resets the StartGluePointlndex. |
If you want to attach a connector to a shape at a location of your choosing, you must create a GluePoint2 structure and add it to the shape. Modify Listing 24 by adding the code from Listing 25 immediately after setting the EdgeKind property. Listing 25 creates a glue point located at the center of the rectangle (see Figure 14 ) and then uses this point as the start point. Table 16 contains a description of the GluePoint2 structure.
Rem Now create a glue point in the center of the shape. oGlue = createUnoStruct("com.sun.star.drawing.GluePoint2") oGlue.IsRelative = False oGlue.Escape = com.sun.star.drawing.EscapeDirection.SMART oGlue.PositionAlignment = com.sun.star.drawing.Alignment.CENTER oGlue.IsUserDefined = True oGlue.Position.X = oShapes(i).getPosition().X + 650 oGlue.Position.Y = oShapes(i).getPosition().Y + 500 oShape.StartGluePointIndex = oShapes(i).getGluePoints().insert(oGlue)
You can set many properties for a shape by creating a style. If you frequently use certain fill styles and shadow styles, you should create a special style so you can quickly change the objects if required. Listing 26 displays the graphics styles supported by an Impress document (shown in Figure 15 ).
Sub PrintStyles Dim oStyles Dim oStyleFamilies oStyleFamilies = ThisComponent.getStyleFamilies() MsgBox Join(oStyleFamilies.getElementNames(), CHR$(10)), 0, "Families" oStyles = ThisComponent.getStyleFamilies().getByName("graphics") MsgBox Join(oStyles.getElementNames(), CHR$(10)), 0, "Graphics Styles" End Sub
You can add arrows to a shape by setting the shape's style to "objectwitharrow". If you don't like the default values in the "objectwitharrow" style, which produces very wide lines (see Figure 16 ), you can create your own style and use that instead. Modify Listing 24 by adding the code from Listing 27 immediately after setting the EdgeKind property.
oStyles = oDoc.getStyleFamilies().getByName("graphics") oShape.Style = oStyles.getByName("objectwitharrow")