The different changeable parts of a Keynote shape comprise its graphic style. There are 12 different shapes available to users when opening a new Keynote presentation, including circles, squares, arrows, and so on.
Nine variations in shapes are shown in the sample Keynote presentation resimple.key, discussed in this chapter. The shapes are
Basic
Shadow
Translucent
Color fill
Gradient fill
Tinted fill
Image fill
Thick-color stroke
Rotated default
The Keynote presentation resimple.key with the nine variations in shape is illustrated in “Figure 3-1.”
Basic Shape
The Shadow Shape
The Translucent Shape
The Color Fill Shape
The Gradient Fill Shape
The Image Fill Shape
The Tinted Image Fill
The Thick-Colored Stroke
The Rotated Default Shape
The Overriden Slide Style
The Title Placeholder Style
“Figure 3-2” illustrates the first and most basic shape available for a Keynote slide.
The basic shape in XML is defined in “Listing 3-1.”
<sf:shape sfa:ID="SFDShapeInfo-2"> |
<sf:geometry sfa:ID="SFDAffineGeometry-93"> |
<sf:naturalSize sfa:w="100" sfa:h="100"/> |
<sf:size sfa:w="100" sfa:h="100"/> |
<sf:position sfa:x="48" sfa:y="140"/> |
</sf:geometry> |
<sf:style> |
<sf:graphic-style-ref sfa:IDREF="SFDGraphicStyle-62"/> |
</sf:style> |
<sf:path> |
<sf:bezier-path sfa:ID="SFDBezierPathSource-2"> |
<sf:bezier sfa:ID="NSBezierPath-2" sfa:path="M 0 0 L 100 0 L 100 100 L 0 100 Z M 0 0" sfa:version="524"/> |
</sf:bezier-path> |
</sf:path> |
<sf:text sfa:ID="SFWPFrame-141"> |
<sf:text-storage sfa:ID="SFWPStorage-477" sf:kind="textbox" sf:exclude-shapes="true" sf:exclude-tables="true" sf:exclude-attachments="true"> |
<sf:stylesheet-ref sfa:IDREF="SFSStylesheet-27"/> |
<sf:text-body> |
<sf:layout sf:style="SFWPLayoutStyle-189"> |
<sf:p sf:style="SFWPParagraphStyle-390">basic</sf:p> |
</sf:layout> |
</sf:text-body> |
</sf:text-storage> |
</sf:text> |
</sf:shape> |
The empty property map here indicates that all style properties of this shape are inherited from the master slide’s prototype for shapes. This means that all the style properties are inherited from the master slide’s stylesheet’s style, with the identifier "shapeStyleID".
The <sf:geometry> element consists of a natural size, a size, and a position. For shapes, natural size and size are the same, and determine how large the shape is on the canvas. The units of width and height are in pixels. The position is also in pixels, with (0,0) being the top left of the slide.
The <sf:path> element describes how the path is to be drawn. The format is the same as the format for the Keynote 1.x path elements. Note the sfa:version attribute, with a value of "524".
Important: If you are a developer working with the Keynote XML file format specification, you should make sure that the sfa:version attribute is present and has a value of "524", or the behavior of your application may become unpredictable.
The <sf:text> element describes the text that appears in the shape. Details of the text are beyond the scope of this chapter, but it is worth noting that you can change the text contents of a shape simply by changing what is specified in the <sf:p> element.
“Figure 3-3” illustrates a simple shadow shape, another variation of the basic shape shown in “Figure 3-2.”
The elements for the shadow shape are defined, as follows in XML in “Listing 3-2”:
<sf:shape sfa:ID="SFDShapeInfo-3"> |
<sf:geometry sfa:ID="SFDAffineGeometry-94"> |
<sf:naturalSize sfa:w="100" sfa:h="100"/> |
<sf:size sfa:w="121" sfa:h="100"/> |
<sf:position sfa:x="207" sfa:y="140"/> |
</sf:geometry> |
<sf:style> |
<sf:graphic-style-ref sfa:IDREF="SFDGraphicStyle-59"/> |
</sf:style> |
<sf:path> |
<sf:bezier-path sfa:ID="SFDBezierPathSource-3"> |
<sf:bezier sfa:ID="NSBezierPath-3" sfa:path="M 0 0 L 100 0 L 100 100 L 0 100 Z M 0 0" sfa:version="524"/> |
</sf:bezier-path> |
</sf:path> |
<sf:text sfa:ID="SFWPFrame-142"> |
<sf:text-storage sfa:ID="SFWPStorage-478" sf:kind="textbox" sf:exclude-shapes="true" sf:exclude-tables="true" sf:exclude-attachments="true"> |
<sf:stylesheet-ref sfa:IDREF="SFSStylesheet-27"/> |
<sf:text-body> |
<sf:layout sf:style="SFWPLayoutStyle-189"> |
<sf:p sf:style="SFWPParagraphStyle-390">shadow</sf:p> |
</sf:layout> |
</sf:text-body> |
</sf:text-storage> |
</sf:text> |
</sf:shape> |
The shadow shape is similar to the previous example basic shape, except for changes to its geometry, style reference, and text. Otherwise, all the elements are identical to the basic shape. The shadow shape, of course, is in a different position, with a shadow, as well as with different text.
The shape’s graphic style is defined as follows in XML in “Listing 3-3”:
<sf:graphic-style sfa:ID="SFDGraphicStyle-59" sf:parent-ident="shapeStyleID"> |
<sf:property-map> |
<sf:shadow> |
<sf:shadow sfa:ID="SFRShadow-9" sf:angle="45" sf:offset="50" sf:radius="10" sf:opacity="0.75"> |
<sf:color xsi:type="sfa:calibrated-rgb-color-type" sfa:r="0.52822577953338623" sfa:g="0" sfa:b="0" sfa:a="1"/> |
</sf:shadow> |
</sf:shadow> |
</sf:property-map> |
</sf:graphic-style> |
Notably, the only attribute defined here is the sf:shadow; the other attributes are inherited from the master slide style with the identifier "shapeStyleID".
The shadow property contains a <sf:shadow> element, which defines the angle, offset, radius and opacity of the shadow, as well as the color of the shadow. The sf:angle attribute corresponds to the angle in the application’s inspector, although it is the opposite of what the inspector shows. In other words, the inspector shows 315, but the angle here is 45, which happens to be (360 - 315). The sf:offset attribute corresponds to the offset value in the inspector; the radius corresponds to the blur value in the inspector; and the opacity corresponds to the opacity value in the inspector.
The <sf:color> child defines the color of the shadow. There are many different ways to define colors, but this is one of the simplest. The xsi:type attribute of "sfa:calibrated-rgb-color-type" must be present so the application "knows" in what format the color is written. The other attributes are sfa:r, sfa:g, sfa:b, and sfa:a, which define the amount of red, blue and green in the color, and the opacity (alpha) of the color. These values can range from 0 to 1.
“Figure 3-4” illustrates the translucent shape, and again, this shape only differs in its geometry, style and text from the previously discussed shapes.
Because this shape does not differ significantly from previous shape elements, only its style is shown in the following XML, as illustrated in “Listing 3-4”:
Listing 2-4 Translucent shape XML
<sf:graphic-style sfa:ID="SFDGraphicStyle-57" sf:parent-ident="shapeStyleID"> |
<sf:property-map> |
<sf:opacity> |
<sf:number sfa:number="0.5150376" sfa:type="f"/> |
</sf:opacity> |
</sf:property-map> |
</sf:graphic-style> |
Note that, again, the style inherits most of its values from the master style. It overrides <sf:opacity>. When the <sf:opacity> override occurs, it always has an sfa:number element with an sfa:type attribute of sfa:f, and an sfa:number attribute that varies from 0 to 1, with 1 being completely opaque, and 0 being completely transparent.
“Figure 3-5” illustrates the color fill shape.
Here is the XML for the color fill shape as described in “Listing 3-5”:
<sf:shape sfa:ID="SFDShapeInfo-5"> |
<sf:geometry sfa:ID="SFDAffineGeometry-96"> |
<sf:naturalSize sfa:w="100" sfa:h="100"/> |
<sf:size sfa:w="100" sfa:h="100"/> |
<sf:position sfa:x="48" sfa:y="315"/> |
</sf:geometry> |
<sf:style> |
<sf:graphic-style-ref sfa:IDREF="SFDGraphicStyle-60"/> |
</sf:style> |
<sf:path> |
<sf:bezier-path sfa:ID="SFDBezierPathSource-5"> |
<sf:bezier sfa:ID="NSBezierPath-5" sfa:path="M 0 0 L 100 0 L 100 100 L 0 100 Z M 0 0" sfa:version="524"/> |
</sf:bezier-path> |
</sf:path> |
<sf:text sfa:ID="SFWPFrame-144"> |
<sf:text-storage sfa:ID="SFWPStorage-480" sf:kind="textbox" sf:exclude-shapes="true" sf:exclude-tables="true" sf:exclude-attachments="true"> |
<sf:stylesheet-ref sfa:IDREF="SFSStylesheet-27"/> |
<sf:text-body> |
<sf:layout sf:style="SFWPLayoutStyle-189"> |
<sf:p sf:style="SFWPParagraphStyle-390">color<sf:br/></sf:p> |
<sf:p sf:style="SFWPParagraphStyle-390">fill</sf:p> |
</sf:layout> |
</sf:text-body> |
</sf:text-storage> |
</sf:text> |
</sf:shape> |
In this shape, both the geometry and the text are different from the previously discussed shapes. For text, instead of a single <sf:p> element in the <sf:layout> element, there are two, and one has an <sf:br/> element, which indicates a line break.
The different fill is, of course, encoded in the style:
<sf:graphic-style sfa:ID="SFDGraphicStyle-60" sf:parent-ident="shapeStyleID"> |
<sf:property-map> |
<sf:fill> |
<sf:color xsi:type="sfa:calibrated-rgb-color-type" sfa:r="0" sfa:g="0" sfa:b="1" sfa:a="1"/> |
</sf:fill> |
</sf:property-map> |
</sf:graphic-style> |
As with other shapes, the color fill shape inherits most of its properties from the master style. However, the fill property is overridden, and its value is an <sf:color>. The <sf:color> element here takes the same format as the <sf:color> element in the shadow example.
“Figure 3-6” illustrates a gradient fill shape, and again, the only notable change in this shape is the style.
The XML for the gradient fill shape is as follows in “Listing 3-6”:
Listing 2-6 Gradient fill shape XML
<sf:graphic-style sfa:ID="SFDGraphicStyle-64" sf:parent-ident="shapeStyleID"> |
<sf:property-map> |
<sf:fill> |
<sf:angle-gradient sfa:ID="SFRAngleGradient-0" sf:opacity="1" sf:type="linear" sf:angle="3.0717794895172119"> |
<sf:stops sfa:ID="NSMutableArray-81"> |
<sf:gradient-stop sfa:ID="SFRGradientStop-0" sf:fraction="0"> |
<sf:color xsi:type="sfa:calibrated-rgb-color-type" sfa:r="0" sfa:g="0" sfa:b="1" sfa:a="1"/> |
</sf:gradient-stop> |
<sf:gradient-stop sfa:ID="SFRGradientStop-1" sf:fraction="1"> |
<sf:color xsi:type="sfa:calibrated-rgb-color-type" sfa:r="0.27450981736183167" sfa:g="0.27450981736183167" sfa:b="0.34509804844856262" sfa:a="1"/> |
</sf:gradient-stop> |
</sf:stops> |
</sf:angle-gradient> |
</sf:fill> |
</sf:property-map> |
</sf:graphic-style> |
The sf:fill property here is similar to the sf:fill property in the color fill example, except that instead of having a color, it has an <sf:angle-gradient>. The xsi:type attribute of the angle-gradient should always be "linear" . (It is provided for forward compatibility.) The angle is the amount that the gradient differs from 180. Opacity refers to how opaque the gradient is.
The <sf:angle-gradient> element contains an <sf:stops> element, which must contain two or more stops. Each stop has a sf:fraction attribute, which describes how far along the gradient the stop occurs, with 0 being the beginning of the gradient and 1 being the end. The value of this attribute should always be larger for any stop than for the previous stop within the gradient. Each <sf:gradient-stop> contains a color, which is of the same format as the color for shadows or color fills.
“Figure 3-7” illustrates an image fill, whose only notable difference from the previous shapes is, again, its style.
The XML for the image fill shape is shown in “Listing 3-7”:
<sf:graphic-style sfa:ID="SFDGraphicStyle-61" sf:parent-ident="shapeStyleID"> |
<sf:property-map> |
<sf:fill> |
<sf:textured-fill sfa:ID="SFDTexturedImageFill-28" sf:technique="tile" xsi:type="textured-fill"> |
<sf:image sfa:ID="SFRImageBinary-38"> |
<sf:size sfa:w="48" sfa:h="48"/> |
<sf:data sfa:ID="SFEData-39" sf:path="Nest.tif" sf:displayname="Nest.tif" sf:size="22520" sf:hfs-type="0" sf:checksum="4bf7bacf" sfa:version="1"/> |
</sf:image> |
</sf:textured-fill> |
</sf:fill> |
</sf:property-map> |
</sf:graphic-style> |
The <sf:fill> property, as shown in the above XML, has an "textured-image-fill" child. The sf:technique attribute describes how the image is drawn to fill the space: it can tile, scale to fit, scale to fill, or stretch the image, or leave the image as its original size.
The "image-binary" child defines the actual image. The <sf:size> child of the image-binary child defines the dimensions, in pixels, of the unscaled image. The sf:path is relative to the document bundle, and the sf:displayname is the name as it appears in the inspector. The sf:hfs-type attribute describes the type of the file as far as the Finder is concerned, but may be omitted. The sf:size and sf:checksum attributes are used to determine if the image has changed, and may be omitted. In fact, it is preferable to omit these attributes rather than define them incorrectly. The sf:version attribute should always be "1".
“Figure 3-8” illustrates a tinted image fill, which is similar to the image fill in the above example.
The XML for the tinted image fill is “Listing 3-8”:
Listing 2-8 Tinted image fill XML
<sf:graphic-style sfa:ID="SFDGraphicStyle-63" sf:parent-ident="shapeStyleID"> |
<sf:property-map> |
<sf:fill> |
<sf:textured-fill sfa:ID="SFDTexturedImageFill-29" sf:technique="tile" xsi:type="textured-fill"> |
<sf:color xsi:type="sfa:calibrated-rgb-color-type" sfa:r="0" sfa:g="0" sfa:b="1" sfa:a="0.5"/> |
<sf:image-ref sfa:IDREF="SFRImageBinary-38"/> |
</sf:textured-fill> |
</sf:fill> |
</sf:property-map> |
While the tinted image fill shape is similar in many respects to the image fill example, there are several notable differences:
The <sf:textured-fill> element has a sf:color attribute, similar to the sf:color attribute described in the fill and shadow examples.
The <sf:image>, instead of being a full-fledged image element, is an image-ref that refers to the same image used for the previous example. This allows the document to use the same image multiple times without having to write it over and over again, thus keeping the document simpler, smaller, and more consistent.
“Figure 3-9” illustrates a thick-colored stroke.
Its style is defined in the XML in “Listing 3-9”:
Listing 2-9 Thick-colored stroke XML
<sf:graphic-style sfa:ID="SFDGraphicStyle-58" sf:parent-ident="shapeStyleID"> |
<sf:property-map> |
<sf:stroke> |
<sf:stroke sfa:ID="SFRStroke-123" sf:miter-limit="4" sf:width="8" sf:cap="butt" sf:join="miter"> |
<sf:color xsi:type="sfa:calibrated-rgb-color-type" sfa:r="1" sfa:g="0" sfa:b="1" sfa:a="1"/> |
<sf:pattern sfa:ID="SFRStrokePattern-123" sf:phase="0" sf:type="pattern"> |
<sf:pattern> |
<sf:element sf:val="6"/> |
<sf:element sf:val="6"/> |
</sf:pattern> |
</sf:pattern> |
</sf:stroke> |
</sf:stroke> |
</sf:property-map> |
</sf:graphic-style> |
The stroke property has a <sf:stroke> child, with a sf:width attribute that defines how many pixels wide the stroke is. The sf:miter-limit and sf:cap attributes define how the stroke joins to itself, but there is no user interface exposed for editing these.
Important: Developers should avoid using different values for these attributes than the ones specified in the above example.
The <sf:color> child defines the color of the stroke, and is of the same format as the previous color examples.
The <sf:pattern> element contains a pattern child which has two, four or six element children. The first element child of each pair describes the length of a piece of line that is drawn, and the next element describes the length of an empty space.
“Figure 3-10” illustrates a default shape that has been rotated 45 degrees.
Not surprisingly, there is a change in the geometry, as shown in the following XML in “Listing 3-10”:
Listing 2-10 Rotated default shape XML
<sf:shape sfa:ID="SFDShapeInfo-10"> |
<sf:geometry sfa:ID="SFDAffineGeometry-101" sf:angle="45"> |
<sf:naturalSize sfa:w="100" sfa:h="100"/> |
<sf:size sfa:w="100" sfa:h="100"/> |
<sf:position sfa:x="385.289306640625" sfa:y="450.289306640625"/> |
</sf:geometry> |
<sf:style> |
<sf:graphic-style-ref sfa:IDREF="SFDGraphicStyle-56"/> |
</sf:style> |
<sf:path> |
<sf:bezier-path sfa:ID="SFDBezierPathSource-10"> |
<sf:bezier sfa:ID="NSBezierPath-10" sfa:path="M 0 0 L 100 0 L 100 100 L 0 100 Z M 0 0" sfa:version="524"/> |
</sf:bezier-path> |
</sf:path> |
<sf:text sfa:ID="SFWPFrame-149"> |
<sf:text-storage sfa:ID="SFWPStorage-573" sf:kind="textbox" sf:exclude-shapes="true" sf:exclude-tables="true" sf:exclude-attachments="true"> |
<sf:stylesheet-ref sfa:IDREF="SFSStylesheet-27"/> |
<sf:text-body> |
<sf:layout sf:style="SFWPLayoutStyle-189"> |
<sf:p sf:style="SFWPParagraphStyle-390">rotated</sf:p> |
</sf:layout> |
</sf:text-body> |
</sf:text-storage> |
</sf:text> |
</sf:shape> |
In this example, note the addition of the sf:angle attribute on the <sf:geometry> element. This defines the amount of rotation, and is identical to the value the user sees in the Keynote Inspector.
“Figure 3-11” illustrates the overriden slide style, which is unique to Keynote.
The XML looks like this in“Listing 3-11”:
Listing 2-11 The overriden slide style XML
<sf:slide-style sfa:ID="BGSlideStyle-16" sfa:sfclass="" sf:ident="slideStyleID" sf:parent-ident="slideStyleID"> |
<sf:property-map> |
<sf:bodyPlaceholderVisibility> |
<sf:number sfa:number="1" sfa:type="c"/> |
</sf:bodyPlaceholderVisibility> |
<sf:slideNumberPlaceholderVisibility> |
<sf:number sfa:number="1" sfa:type="c"/> |
</sf:slideNumberPlaceholderVisibility> |
<sf:fill> |
<sf:textured-fill sfa:ID="SFDTexturedImageFill-27" sf:technique="fit" xsi:type="textured-fill"> |
<sf:image sfa:ID="SFRImageBinary-27"> |
<sf:size sfa:w="1600" sfa:h="1024"/> |
<sf:data sfa:ID="SFEData-28" sf:path="Aqua Blue.jpg" sf:displayname="Aqua Blue.jpg" sf:size="637181" sf:hfs-type="0" sf:checksum="e5d6c9c9" sfa:version="1"/> |
</sf:image> |
</sf:textured-fill> |
</sf:fill> |
<sf:transition> |
<sf:transition-attributes sfa:ID="BGTransitionAttributes-11" key:type="apple:3D-cube"> |
<key:animationAuto> |
<key:number sfa:number="1" sfa:type="c"/> |
</key:animationAuto> |
<key:animationDelay> |
<key:decimal-number sfa:number="1.5" sfa:type="d"/> |
</key:animationDelay> |
<key:direction> |
<key:number sfa:number="11" sfa:type="i"/> |
</key:direction> |
</sf:transition-attributes> |
</sf:transition> |
</sf:property-map> |
</sf:slide-style> |
This slide style inherits from a master with only the title placeholder visible. However, it also makes the body and slide number placeholders visible. This is accomplished with the <sf:bodyPlaceholderVisibility> and <sf:slideNumberPlaceholderVisibility> elements, each of which has a child element that is an <sf:number> element with an sfa:type of "c" and an sfa:number of 0 or 1. Both elements have a value of 1, meaning that the placeholders are visible. To make a placeholder invisible, if it is visible on the master, use a value of 0.
The slide also has an image fill. This is encoded in the <sf:fill> property. The <sf:fill> property for a slide style is identical to the fill property for a graphic style: it can be a color, gradient, or image fill (with or without tinting.)
The <sf:transition> property defines the transition between this slide and the next. The sfa:type attribute is a string that encodes the name of the transition. The <key:animationAuto> property is a number similar to the number for placeholder visibility, with a value of 0 if the user must take some action to show the next slide, and 1 if the next slide is shown automatically. If the next slide is shown automatically, the <key:animationDelay> property encodes the length of the delay from when the slide starts (or the last build completes) and the transition begins. The key:direction attribute has a different meaning for different transitions.
“Figure 3-11” illustrates a title placeholder style (unique to Keynote) with customized position, stroke, shadow, and fill.
The title placeholder style is defined in “Listing 3-12”:
Listing 2-12 The title placeholder style XML
<sf:placeholder-style sfa:ID="BGPlaceholderStyle-114" sfa:sfclass="" sf:ident="titlePlaceholderStyleID" sf:parent-ident="titlePlaceholderStyleID"> |
<sf:property-map> |
<sf:fill> |
<sf:color xsi:type="sfa:calibrated-rgb-color-type" sfa:r="0" sfa:g="0" sfa:b="1" sfa:a="0.5"/> |
</sf:fill> |
<sf:stroke> |
<sf:stroke sfa:ID="SFRStroke-124" sf:miter-limit="4" sf:width="1" sf:cap="butt" sf:join="miter"> |
<sf:color xsi:type="sfa:calibrated-white-color-type" sfa:w="0" sfa:a="1"/> |
<sf:pattern sfa:ID="SFRStrokePattern-124" sf:phase="0" sf:type="pattern"> |
<sf:pattern> |
<sf:element sf:val="1"/> |
<sf:element sf:val="1"/> |
</sf:pattern> |
</sf:pattern> |
</sf:stroke> |
</sf:stroke> |
<sf:geometry> |
<sf:geometry sfa:ID="SFDAffineGeometry-103" sf:sizesLocked="true"> |
<sf:naturalSize sfa:w="644" sfa:h="150"/> |
<sf:size sfa:w="644" sfa:h="150"/> |
<sf:position sfa:x="77" sfa:y="224"/> |
</sf:geometry> |
</sf:geometry> |
<sf:opacity> |
<sf:number sfa:number="0.7030075" sfa:type="f"/> |
</sf:opacity> |
<sf:shadow> |
<sf:shadow sfa:ID="SFRShadow-10" sf:angle="45" sf:offset="50" sf:radius="10" sf:opacity="0.75"> |
<sf:color xsi:type="sfa:calibrated-rgb-color-type" sfa:r="0" sfa:g="0" sfa:b="0" sfa:a="1"/> |
</sf:shadow> |
</sf:shadow> |
</sf:property-map> |
</sf:placeholder-style> |
The stroke, shadow, and fill are identical in form to the same properties for graphic styles.
Notably, the geometry for the placeholder is not stored in the <sf:placeholder> element, but rather, in its style. The form of this element is the same as the form of the geometry element for the shape or image, but lives in the style.
Last updated: 2005-11-09