| Summary: | The Curl® language's graphics and multimedia capabilities provide low-level support for:
|
In addition to the GUI Toolkit, other graphics components provide the means of creating your own two- and three-dimensional rendering, scenes, image filters, and the other features you need to add procedural graphics, animations, interactive games, or simulations to your Web pages.
Information on the various graphics and multimedia APIs, including interactive examples, can be found in the following places:
| Chapter | Contents |
|---|---|
| FillPatternsandTextures | How to set and modify the color or pattern of a surface using the FillPattern, Texture, and Pixmap classes. |
| ImageFilters | How you can modify existing FillPatterns or images by applying filters to them. |
| Animation | Information about using timers and doing animation. |
| 2DRendering | How to do two-dimensional rendering, including the use of the Region and Path classes. |
| 3DRendering | How to do three-dimensional rendering for immediate-mode graphics. |
| Scene (3D retained-mode graphics) | How to create and use scene graphs and key-frame animation. |
| Sound | Incorporating audio elements into your Web pages. |
In addition, documentation on the interface for input devices such as the joystick controller can be found in the API Reference Manual; see
Controller.
Which Curl Language Components Will You Need?
The following interactive diagram suggests which of the Curl language GUI, graphics, and related APIs you are likely to need for various kinds of task. When you move the cursor over a task, the related tools change color. Click on the tool to go to further documentation. Of course, you can combine these subsystems and others in any way that best suits your development needs.

The Graphics Superpackage: CURL.GRAPHICS.STANDARD
The superpackage
CURL.GRAPHICS.STANDARDincludes the various packages that make up the graphics APIs, and gives your applet access to most of the commonly used features of the Curl language graphics system. These features include the 2D and 3D rendering systems and a library of image filters.
CURL.GRAPHICS.STANDARDis imported as part of
CURL.GUI.STANDARD, which is imported automatically when the Curl runtime encounters the {curl ... applet} herald in applet source code.
If you are using the {curl ... package} herald to create a package rather than an applet, CURL.GUI.STANDARD is not automatically loaded when the package is compiled. To include the GUI and graphics functionality in a package, import statement
CURL.GUI.STANDARDexplicitly:
{import * from CURL.GUI.STANDARD}
Note: If you would rather import only the specific packages that your applet requires, such as
CURL.GRAPHICS.STANDARD, be aware that there are many dependencies between the packages in CURL.GUI.STANDARD.
Additional Related Graphics Packages
Several additional graphics-related packages are not included in CURL.GRAPHICS.STANDARD and must be imported separately by applets and packages that need to use them. These packages include:
- CURL.GRAPHICS.SCENE, which supports the retained-mode 3D graphics capabilities of the Scene API
- CURL.GRAPHICS.PARTICLE, which supports the Particle System API
- CURL.DEVICE.CONTROLLER, the joystick controller package
- CURL.AUDIO.STANDARD, the audio superpackage, which loads all of the necessary audio packages
- CURL.GRAPHICS.IMAGEIO.BASE, the image IO package
| Summary: |
|
A texture is an infinitely thin surface, expressing a pattern or a solid color, which serves as a source object in any rendering process. Textures can be represented by the abstract base classes
FillPatternand
Texture, where:
- FillPattern and its subclasses are usually used by GUI developers for high-level application development, and with the Renderer2d class. A FillPattern can be modified after it is created.
- Texture and its subclasses are usually used in low-level graphics contexts, such as with the Renderer3d class. One common subclass of Texture is Color, which represents a uniform texture, a solid color. A Texture cannot be modified after it is created.
Textures can be applied to surfaces in two ways:
- A texture can be stretched onto a surface; you can think of it as a stretchy picture.
- A texture can be repeated on a surface; you can think of it as a set of tiles.
Creating a FillPattern
There are two general ways of creating a
FillPattern:
- You can create a FillPattern by supplying a convertible object where a FillPattern is needed. A convertible object is one that can be automatically converted (or cast) to a FillPattern.
- You can use following FillPattern factories to construct a FillPattern from an object of any of these types:
- FillPattern.from-color#factory
- FillPattern.from-drawable#factory
- FillPattern.from-pixmap#factory
- FillPattern.from-string#factory
- FillPattern.from-texture#factory
- FillPattern.from-url#factory
- A less efficient alternative is to use the following syntax, which checks the type of its argument at run time:
{FillPattern convertibleobject}
The argument convertibleobject must be an object of one of the following types:
- Pixmap
- Texture (of which Color is a subclass.)
- Drawable
This is a relatively uncommon way to create FillPatterns and it is normally done using an offscreen Drawable in conjunction with Image Filters.
- A StringInterface representing a color string for a solid color. See the From Solid Colors section for more information on using solid colors.
- A Url representing an image file. See the From Image Files section for more information on using image files.
From Solid Colors
Textures that are solid colors are represented by the
Colorclass, which is a subclass of Texture. There is no equivalent in the FillPattern class hierarchy, because FillPattern is able to convert any Texture, including Color. Therefore, you need not be concerned with the details of the Color class to be able to set the color of graphical objects and text.
Most of the color-related properties of graphical objects and text are represented by options whose type is FillPattern. To apply a uniform texture to these objects, set their relevant options to any of the following ways, and FillPattern will perform the conversion:
- A Color object. (For example, the Color.from-rgb procedure returns a Color object.)
- A String in the form:
"#rrggbb"
where rr, gg, and bb are pairs of hexadecimal digits specifying the red, green, and blue color intensities, respectively. - A String naming one of the supported color names. See Supported Color Names for the list of supported color names.
- For standard colors, it is more efficient to use the procedure FillPattern.get-<color>, where <color> is one of the supported color names.
For example, you can set the option color (see
color) to any supported color name, because its type is FillPattern. For text, you can use the color= keyword argument syntax, as shown in the following example. The colors of the frames are set using the other techniques outlined above:
| Example: Setting Color Options | |
![]() | |
|| Using the color= syntax with a string containing a color name{paragraph color = "teal", Bet you didn't know that \"teal\" is a supported color name.}{HBox border-width = 5pt, || Using a string of hexadecimal red, green, blue color intensities border-color="#980adf", || Using a supported color name directly {Frame width = 2cm, height = 2cm, background = "aqua"}, || Using a supported color name via the get- |
Supported Color Names

From Image Files
To create a FillPattern from an image file, you simply specify the file as a
Urlobject.
The basic syntax for doing so is:
{url url-string}where url-string specifies, in double-quotes, the location of the image file, using url format. The quotes enclose the path and name of an image file whose format is supported. See Image File Formats for the supported image file formats. The contents of the image file are converted to a FillPattern.
Because you can easily convert an image file to a FillPattern, you can supply it as a value for any parameter that requires a FillPattern object. The example below shows the effects of setting the background property of a graphical object, such as
VBox:
| Example: Using a FillPattern As a Background | |
![]() | |
{VBox spacing = 10pt, color = "lime", font-size = 12pt, || Set the background to an image (converted to a || FillPattern). background = {url "../../default/images/cherries.gif"}, || The text is superimposed on the image. {bold color = "cyan", The Cherry Diet}, {bold Breakfast: Cherries}, {bold Lunch: Cherries}, {bold Dinner: Cherries}} |
Working with FillPatterns
This section discusses various operations you can perform with fill patterns.
Converting a FillPattern
The previous section shows how a
FillPatterncan be automatically created from a
Texture,
Pixmap,
Drawable, or image file. You can also convert from FillPattern to Pixmap, Texture, or Drawable. You should plan you application to avoid unnecessary conversions.
See Mutating a FillPattern for information on how you can change a FillPattern by calling the methods of Pixmap, Drawable, or Renderer2d.
The following methods facilitate the conversion between the classes FillPattern, Pixmap, Texture, and Drawable.
- FillPattern.to-Pixmap
- FillPattern.to-Texture
- Drawable.to-Pixmap
- Texture.from-drawable#factory
- Texture.to-Pixmap
- Color.to-Pixmap
FillPatternHints
The
FillPatternHintsclass encapsulates information that describes the environment in which a FillPattern will be used. Standard hints are usually provided when a FillPattern is applied to a graphical object. The standard hints are:
- width
- height
- resolution
Each of the FillPattern's to-* methods takes a FillPatternHints object as its argument and may use the standard hints, if provided, to determine the manner in which the output object is generated.
The standard hints are also properties of the FillPatternHints class. To create a FillPatternHints object, call
FillPatternHints.create#factoryand supply the hints.
If you are writing your own FillPattern subclass and are implementing the to-* methods, you can use another property,
FillPatternHints.has-standard-hints?, to verify whether the caller has provided standard hints before you attempt to get them.
In addition, your implementation of these methods can expect and make use of its own hints, not just the standard hints.
- The implementation of a subclass's to-* method can get the value of a hint by calling FillPatternHints.get and providing the hint's key as a string.
- When calling such a class's to-* method, you can supply the non-standard hints by:
- calling FillPatternHints.create#factory, and
- supplying the non-standard hints by entering them as key = value keyword arguments.
Any number and combination of standard and non-standard hints may be supplied.
Mutating a FillPattern
You can modify a FillPattern by using the
mutate-fill-patternmacro, which requires you to provide a FillPattern and specify the class you would like to use to operate on the FillPattern. This class must be one of:
- Pixmap
- Drawable
- Renderer2d
Then, within the body of a mutate-fill-pattern code block, you can perform operations on the Pixmap, Drawable, or Renderer2d to modify the FillPattern.
The following example:
- creates a FillPattern from an image file,
- mutates the FillPattern with the mutate-fill-pattern macro, using a Pixmap method that inverts an image,
- uses the mutated FillPattern as the background of a Fill graphical object.
| Example: Mutating a FillPattern | |
![]() | |
{value let pattern:FillPattern = {url "../../default/images/kid1.jpg"} {mutate-fill-pattern dst:Pixmap on pattern do {dst.flip-vertical} } {Fill width = 1.5in, height = 1in, background = pattern }} |
Readable/Writable FillPatterns
A FillPattern may be readable and/or writable, as indicated by its
FillPattern.readable?and
FillPattern.writable?properties.
- If a FillPattern is writable, you can mutate it by calling the mutate-fill-pattern macro, which allows you to work on it using a Drawable or Pixmap interface.
For example, the image filters of the graphics system operate on FillPatterns, which serve as source and destination.
- If a FillPattern is readable, as most are, you can call its to-* methods (such as to-Texture or to-Pixmap), which read from the FillPattern and return an instance of the specified type of object.
Procedurally Generated FillPatterns
A subclass of FillPattern is the
PixmapBasedFillPatternclass. This class is abstract. It represents a FillPattern that is based on Pixmaps, and therefore has an underlying Pixmap. If you are writing your own subclasses, you can subclass from FillPattern or from PixmapBasedFillPattern.
PixmapBasedFillPattern also serves as a base class for time-invariant procedural textures, from which procedurally generated FillPattern classes may be defined. The underlying pixmap does not restrict the PixmapBasedFillPattern to any particular size; it serves as a place for computations. Note that PixmapBasedFillPatterns are readable but not writable.
The key method implemented by PixmapBasedFillPattern is to-Pixmap. This method computes and returns a Pixmap representation of the FillPattern. The first time it is called, it creates the underlying pixmap.
In subsequent calls, it may re-create and/or resize the underlying Pixmap so that the returned Pixmap is a new object. In modifying the underlying Pixmap, this method also creates the underlying
Texturesuch that a call to to-Texture on the FillPattern returns the underlying Texture.
Subclasses of PixmapBasedFillPattern
Two implemented subclasses of PixmapBasedFillPattern are
LinearGradientFillPatternand
RadialGradientFillPattern. They are examples of procedural FillPatterns, which generate their images from code rather than pixels, and therefore reduce download. These FillPatterns are readable but not writable.
Their implementations of
PixmapBasedFillPattern.compute-pixmapcompute the values of the elements in the underlying pixmap. Both use
for-pixelto iterate over the pixmap.
- LinearGradientFillPattern creates a PixmapBasedFillPattern that displays a linear gradient. You supply two points and a Spectrum.
- RadialGradientFillPattern creates a PixmapBasedFillPattern that displays a circular gradient effect. You specify the center of the circular gradient, its radius, and a Spectrum.
To write your own procedural FillPattern, you should also subclass PixmapBasedFillPattern and override the following methods:
- The constructor
- The PixmapBasedFillPattern.clone-from constructor
- PixmapBasedFillPattern.compute-pixmap
- PixmapBasedFillPattern.to-Pixel
Image Filters
Image filters are simple procedures that work on FillPatterns. Refer to the Image Filters chapter for information on using image filters and a list of the current image filters provided by the Curl language.
Applying a FillPattern to a Graphical Object
FillPatterns are often applied to certain properties of graphical objects. For example, the graphical option background takes a FillPattern. You can supply either a FillPattern object or any object that can be converted to a FillPattern, including a
Colorobject, which is a Texture.
For information on the options applicable to a particular Visual subclass, refer to the class's API Reference Manual entry, under its Local Options and Nonlocal Options categories, if options exist for it.
The following sections describe various ways of applying FillPatterns to graphical objects.
Stretching a FillPattern
Sometimes it is desirable to have a "stretchy" picture that sizes itself to fill available space. Although you can do this by creating custom
Elastics for the width and height properties of an
imageobject, this approach has some drawbacks. Notably, there is no way to express the constraint of an aspect ratio in the Curl language layout system.
However, there is a simple way to produce a stretchy image in a document: create a FillPattern out of the image file and set the background property of a graphical object to it, as shown in some of the earlier examples. This stretches the picture to the layout bounds of the object.
If you set the width or height options of an object whose background is a FillPattern, the texture is stretched or compressed to the bounds of the graphical object using it. In the following example, try changing the width and height of the frame to see the effect of stretching or compressing the image in one or both dimensions.
| Example: Stretching Images | |
![]() | |
{Frame border-width = 1pt, border-color = "red", width = 1cm, height = 1cm, background = {url "../../default/images/cherries.gif"}} |
In the following example, the code builds a row of houses using various materials. The material specified is assigned to the background property of each house. All of the strings supplied are convertible to FillPatterns.
- leaves.jpg and brick-staggered.jpg are images.
- the string "navy" is automatically converted to a Color, which is in turn converted to a FillPattern.
You will notice that because we did not specify a color for the triangle forming the roof of each house, the roof color defaults to black in this case.
| Example: Build Some Houses | |
![]() | |
|| Define one house.{define-proc {build-house material:FillPattern}:VBox {return {VBox halign = "center", {RegularPolygonGraphic sides = 3, width = 2in, height = 0.5in}, {Frame width = 1.5in, height = 1.5in, background = material } } }}|| Use that definition to build a row of houses.{value let row-of-houses:HBox = {spaced-hbox} {row-of-houses.add {build-house {url "curl://install/docs/default/images/leaves.jpg"} } } {row-of-houses.add {build-house {url "curl://install/docs/default/images/brick-staggered.jpg"} } } {row-of-houses.add {build-house "navy"}} row-of-houses} |
Tiling a FillPattern
There are two ways to tile the surface of a graphical object. One is to tile a FillPattern by using the
Renderer2d.render-rectanglemethod. If the difference between the uv1 and uv2 parameters is greater than 1, the image represented by the color parameter repeats. The number of tiles is determined by the difference between uv1 and uv2, and the offset of the tiles within the image is determined by the value of uv1. Try setting different values for uv1 and uv2 in the following example:
| Example: Tiling Using Renderer2d.render-rectangle | |
![]() | |
{let fill-pattern:FillPattern = {url "curl://install/docs/default/images/adria.jpg"}}{define-class MyFill {inherits Fill} {constructor {default ...} {construct-super ...} } {method public {draw r2d:Renderer2d}:void let gr:GRect = {self.layout.get-bounds} {r2d.render-rectangle -gr.lextent, -gr.ascent, gr.rextent + gr.lextent, gr.descent + gr.ascent, fill-pattern = fill-pattern, uv1 = {Fraction2d 0, 0}, uv2 = {Fraction2d 5, 5} } }}{value {VBox height = 5in, width = 5in, {MyFill} }} |
Another way of achieving the same effect is to use the
Background.tiled#factoryfactory.
Backgroundis a wrapper for
FillPatterns that can be used to simplify certain tasks. Here is the same image, in this case a
Canvastiled via this approach. Notice that you can specify the tile size, if it is not the same as the size of the input image, as well as the total size of the area to be tiled. The pattern parameter is a FillPattern.
| Example: Tiling Using Background.tiled | |
![]() | |
{value let back:Background = {Background.tiled offset-x = 0pt, offset-y = 0pt, from-root? = false, tile-width = 1in, tile-height = 1in, pattern = {url "curl://install/docs/default/images/adria.jpg"} } let c:Canvas = {Canvas width = 5in, height = 5in, background = back } c} |
Using Textures
The
Textureclass is very similar to the
FillPatternclass; both represent images, and they are created in similar ways. However, Texture is a lower-level class, and is used with lower-level interfaces. FillPattern is mutable (via the
mutate-fill-patternmechanism), whereas Texture is immutable; once you have a Texture object, you cannot change its contents. Note, however, that you always have the option of creating a new Texture object and throwing the old one away.
FillPattern is generally used with higher-level interfaces, such as the Curl® GUI Toolkit, the Scene package (for 3D retained-mode rendering), and the
Renderer2dinterface. Texture is generally used with lower-level interfaces, such as
Renderer3d, which is commonly used to do immediate-mode 3D rendering.
Despite their differences, the two classes have very similar creation mechanisms. A Texture can be created from:
- a StringInterface representing a standard color name or color identifier, such as "#fe30ff"
- a Pixmap
- a Url that points to a valid image file
- rgb or hsv values, by way of Color.from-rgb#factory or Color.from-hsv#factory
Finally, as with FillPatterns, you can easily access the built-in colors by obtaining an existing Texture object. This is done via the methods of the
Paletteclass, such as
Palette.get-maroon. A complete list of the color names you can use this way is shown in Supported Color Names.
An important difference between Texture and FillPattern is that none of these objects is implicitly cast to a Texture. Instead, you must create a Texture explicitly. The following example shows how to do this for several kinds of object:
| Example: Five Ways of Using Texture | |
![]() | |
{import * from CURL.GRAPHICS.RENDERER3D}|| Define a procedure to render to a Drawable using a given Texture.|| This will be used below to show how to create (and use) Textures.{define-proc package {render-a-rectangle drawable:Drawable, renderer:Renderer3d, texture:Texture}:void || Clear the whole Drawable to black. {renderer.clear color = {Palette.get-black}} || Set our texture as the current one. set renderer.texture = texture let x1:Distance = 0.1in let y1:Distance = 0.1in let x2:Distance = drawable.width - 0.1in let y2:Distance = drawable.height - 0.1in || Render a rectangle using that texture. {render-primitive primitive, type = "quads" on renderer do {primitive.texture-coord2 0.0, 0.0} {primitive.vertex2 x1, y1} {primitive.texture-coord2 0.0, 1.0} {primitive.vertex2 x1, y2} {primitive.texture-coord2 1.0, 1.0} {primitive.vertex2 x2, y2} {primitive.texture-coord2 1.0, 0.0} {primitive.vertex2 x2, y1} }}|| Create a pixmap for use in creating a texture, below.{let my-pixmap:Pixmap = {Pixmap 64, 64}}{do {for-pixel pixel at x, y in my-pixmap do || Use the X coordinate as red and the Y coordinate as blue || to create a nice little gradient pattern. set pixel = {Pixel.create x / 64, 0, y / 64} }}|| EXAMPLE: How to create a Texture from a String representing a|| solid color.{let texture-1:Texture = {Texture "#a830b8"}}|| EXAMPLE: How to create a Texture from a Pixmap.{let texture-2:Texture = {Texture my-pixmap}}|| EXAMPLE: How to create a Texture from a Url.{let texture-3:Texture = {Texture {url "../../default/images/cherries.gif"}}}|| EXAMPLE: How to create a Color using Color.from-rgb.|| (Note: Color is a subclass of Texture, so Color isa Texture.){let texture-4:Texture = {Color.from-rgb 0.1, 0.5, 0.7}}|| EXAMPLE: How to get a standard color using Palette.{let texture-5:Texture = {Palette.get-fuchsia}}|| Now, display each of these, labeled to show how it was made.{VBox {HBox valign = "center", {Renderer3dGraphic width = 1in, height = 1in, repaint-handler = {proc {rg:Renderer3dGraphic, r:Renderer3d, area:#RectangleSet }:void {render-a-rectangle {non-null rg.drawable}, r, texture-1} } }, {Fill width = 0.5in}, "\{Texture \"#a830b8\"\}" }, {Fill height = 0.1in}, {HBox valign = "center", {Renderer3dGraphic width = 1in, height = 1in, repaint-handler = {proc {rg:Renderer3dGraphic, r:Renderer3d, area:#RectangleSet }:void {render-a-rectangle {non-null rg.drawable}, r, texture-2} } }, {Fill width = 0.5in}, "\{Texture my-pixmap\}" }, {Fill height = 0.1in}, {HBox valign = "center", {Renderer3dGraphic width = 1in, height = 1in, repaint-handler = {proc {rg:Renderer3dGraphic, r:Renderer3d, area:#RectangleSet }:void {render-a-rectangle {non-null rg.drawable}, r, texture-3} } }, {Fill width = 0.5in}, "\{Texture \{url \"../../default/images/cherries.gif\"\}\}" }, {Fill height = 0.1in}, {HBox valign = "center", {Renderer3dGraphic width = 1in, height = 1in, repaint-handler = {proc {rg:Renderer3dGraphic, r:Renderer3d, area:#RectangleSet }:void {render-a-rectangle {non-null rg.drawable}, r, texture-4} } }, {Fill width = 0.5in}, "\{Color.from-rgb 0.1, 0.5, 0.7\}" }, {Fill height = 0.1in}, {HBox valign = "center", {Renderer3dGraphic width = 1in, height = 1in, repaint-handler = {proc {rg:Renderer3dGraphic, r:Renderer3d, area:#RectangleSet }:void {render-a-rectangle {non-null rg.drawable}, r, texture-5} } }, {Fill width = 0.5in}, "\{Palette.get-fuchsia\}" }} |
The Pixmap Class
One way to work on textures is through the Pixmap interface. The
Pixmapclass represents a two-dimensional array of
Pixels, each holding red, green, blue, and alpha values.
There are various ways of getting a Pixmap, depending on the resources you are beginning with. This table summarizes the main ways you can obtain a Pixmap.
| To Do This | Use |
|---|---|
| Create a Pixmap from scratch | Pixmap's default constructor |
| Get a Pixmap from an image file | Pixmap.from-url#factory |
| Get a Pixmap from any Texture, including Color | Texture.to-Pixmap |
| Get a Pixmap from a FillPattern | FillPattern.to-Pixmap |
| Get a Pixmap from a Drawable | Drawable.to-Pixmap |
| Create a Pixmap given an existing Pixmap | Pixmap.clone Pixmap.new-like-self |
About Pixmaps
A
Pixmapis a 2D array of pixels. Its width and height represent the number of pixels in each of those dimensions. There are two ways of referencing the pixels of a pixmap:
- The 2D addressing scheme requires two coordinates. The upper-left pixel is pixel (0, 0), and the lower-right pixel is (Pixmap.width - 1, Pixmap.height - 1).
- The 1D addressing scheme requires an index value. You can think of the pixmap as a one-dimensional array of pixels, where the first element is the upper-left pixel, the subsequent elements follow from left to right, proceeding from the top row to the bottom row. The last element in the 1D array is the lower-right pixel in the pixmap.
You can differentiate between class members that apply to the two addressing schemes by the naming convention. Class members that use the 1D addressing scheme use the term "offset" in their names.
For example,
Pixmap.set-offsetsets the specified pixel to a value. You specify the pixel by using the 1D addressing scheme.
The Pixmap class has three properties that serve as helper properties to accommodate these two addressing schemes.
- Pixmap.max-x and Pixmap.max-y return the pixmap's width - 1 and height - 1 respectively. Use them as appropriate in 2D addressing to reference edge pixels.
- Pixmap.max-offset returns the index of the last pixel in the 1D addressing scheme.
Setting Elements of a Pixmap
To set a particular element in a pixmap, use the
Pixmap.setmethod, and provide a
Pixelas the value.
Note: You can use array notation, e.g., pixmap[x,y], as shorthand for get and set. That is,
{pixmap.get 3,4} is equivalent to pixmap[3,4], and
{pixmap.set 3,4,pixel} is equivalent to set pixmap[3,4] = pixel.
To set a range of elements in a pixmap, use
for-pixel, which iterates over the elements of a pixmap, allowing you to set the ones you want.
The following example shows both of these approaches:
| Example: Setting Elements of a Pixmap | |
![]() | |
{value let pixmap:Pixmap = {Pixmap.from-url {url "../../default/images/generic.gif"} } || Set a rectangular area to magenta. {for-pixel p in-rectangle 100, 100, 150, 150 in pixmap do set p = {Pixel.create 1, 0, 1, alpha = 0.5} } || Set the upper-left pixel to black. {pixmap.set 0, 0, {Pixel.create 0, 0, 0}} let fp:FillPattern = {FillPattern.from-pixmap pixmap} {Fill width = 256pixels, height = 256pixels, background = fp }} |
Applying an Image Filter to a Pixmap
Each of the image filters provided in the
CURL.GRAPHICS.IMAGEFILTERpackage is a procedure that takes a source FillPattern and returns a (different) processed FillPattern. See the Image Filters chapter for information on them.
If you choose, instead, to work with Pixmaps, use the
filter-pixmapprocedure to wrap the image filter procedure.
For example, if you want to use the
twirlprocedure on the image shown in the previous example, wrap it in filter-pixmap as follows:
| Example: Filtering a Pixmap | |
![]() | |
{import * from CURL.GRAPHICS.IMAGEFILTER}{value let src:Pixmap = {Pixmap.from-url {url "../../default/images/generic.gif"} } let dst:Pixmap = {filter-pixmap twirl, src, angle=360deg} let fp:FillPattern = {FillPattern.from-pixmap dst} {Fill width = 256pixels, height = 256pixels, background = fp }} |
Distorting a Pixmap
You can distort a texture using the
DisplacementMeshclass.
A DisplacementMesh is a regular grid of points whose locations can be set to specify a distortion. Underlying each grid is a 2D map of its grid point locations. The grid point locations (x and y values) of an undistorted grid fall between 0 and 1, with the upper-left corner grid point's location expressed as 0.0, 0.0 and the lower-right corner grid point's location as 1.0, 1.0.
If you use the
Pixmap.distortmethod to perform a distortion, one of the arguments is a DisplacementMesh object describing the distortion. To specify a distortion, you set the desired grid points to new locations. Calling
DisplacementMesh.setsets each specified grid point to the specified location.
The following example distorts a curtain texture by resetting the locations of eight grid points in a 4x4 grid. It displays the original texture and the distorted texture:
| Example: Distorting a Texture | |
![]() | |
{import * from CURL.GRAPHICS.RENDERER3D}{let d-mesh:DisplacementMesh = {DisplacementMesh 4, 4}}{d-mesh.set 1, 0, {Fraction2d 0.1, 0.0}}{d-mesh.set 2, 0, {Fraction2d 0.9, 0.0}}{d-mesh.set 0, 1, {Fraction2d 0.0, 0.1}}{d-mesh.set 3, 1, {Fraction2d 1.0, 0.1}}{d-mesh.set 0, 2, {Fraction2d 0.0, 0.9}}{d-mesh.set 3, 2, {Fraction2d 1.0, 0.9}}{d-mesh.set 1, 3, {Fraction2d 0.1, 1.0}}{d-mesh.set 2, 3, {Fraction2d 0.9, 1.0}}{let pixmap:Pixmap = {{Texture {url "curl://install/docs/default/images/curtain.jpg"}}.to-Pixmap}}{let fp:FillPattern = {FillPattern.from-pixmap {pixmap.distort d-mesh}}}{spaced-hbox {Fill width = 3in, height = 3in, background = {url "curl://install/docs/default/images/curtain.jpg"} }, {Fill width = 3in, height = 3in, background = fp }} |
Copyright © 1998-2019 SCSK Corporation. All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation. that are registered in the United States. Surge Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE) logo are trademarks of SCSK Corporation.










