quadrium | prime architecture
quadrium | prime is one of the most advanced fractal image renderers available for OS X, and includes many features not found on any other product on any other platform. It is designed from the ground up for flexibility, speed, and power. Plus, it has all the features found in other products in the quadrium family, such as the ability to render high resolution images, drag and drop based user interface, live interactive feedback, mutations, breeding together images to create new ones, QuickTime movie creation, ColorSync support, and AppleScriptability.
What makes quadrium | prime unique, however, is its core architecture, which is built on the concept of reusable modules. An image is created by selecting a combination of these objects (as well as other parameters, including things like gradients). Everything that is used to render the image is defined in the same way, using quadriumScript, and can be replaced with custom objects (internally, the application simply says "What color is this pixel" and hands control over to the quadriumScript engine to figure it out, which it does by executing the appropriate quadriumScript code).
Starting at the top level, let's look at a simple document (a standard Mandelbrot fractal). The image below shows the settings:

As you can see, all of the settings are arranged in a nested, heirarchical fashion. Each box represents an object, and objects are composed of a series of parameters, which can be other objects, numbers, checkboxes, gradients, etc... If one of those objects has settings inside of it, it can be expanded to show them (in this example, the fractal formula and colorer both have additional settings).
The outermost box is the renderer - in this case, it is rendering a color escape fractal ("color" as opposed to indexed or grayscale, and "escape fractal" being the name of the algorithm used to draw the image). It has seven parameters - four of which are other objects, two of which are values (shown as sliders - the gradient background indicates the two sliders are part of a single complex parameter, the real and imaginary parts), and one is a checkbox.
In the header of each of those boxes (Transformation and Bailout Shape have no contents, i.e., no sub-settings, and are thus nothing but header) is a popup menu. This allows you to change that parameter to a different kind of object. For example, the transformation parameter of the renderer controls how to twist/warp/reflect/tile the image (the coordinates of the pixel to be rendered are run though that transformation object to calcuate a new location for them) - the default is the Unity transformation which does nothing other than returning the same value that is fed into it.

Similarly, the Fractal Formula setting allows you to choose from different formulas (such as Julia, Newton, Spider, etc...), the Bailout Shape controls how the fractal bailout is interpreted, and Colorer controls the object that actually does the dirty work converting between how any given pixel escapes the fractal and what color to display for that (in this case, we use a simple thing that is based on the "angle" of the point to produce a shiny looking color value).
How does quadrium | prime know what can be shown in these different popup menus? Just like a parameter can be declared to be a real value, or boolean (checkbox), or gradient, it can be declared to be an object that adopts a given protocol. A protocol defines a set of routines that this object will implement. So the transformation parameter is declared as an object that adopts the CoordinateTransformProtocol. That protocol is pretty simple - it just has a single method that does the "dirty work":
protocol CoordinateTransformProtocol
name "Coordinate Transform";
method transform(x:real, y:real) : point
return {x,y};
end;
end;
So if you wanted to write your own transformation, you would just have to write that one routine - take an x and y value, and return a transformed (two dimensional) point. Things like fractal formulas and colorers are a bit more complicated (in that they provide more routines that allow you to customize things to a greater degree). Any object can declare a series of parameters, just like we've seen here - you're not limited to having to try to "piggy back" your settings based on some small set of available "general purpose" sliders.
One important feature of quadrium | prime is the concept of "adapters" which allows you to convert between one kind of object (i.e., that adopts a given protocol) and another. For example, fractal coloring algorithms tend to be broken down into three kinds - one produces an index in a gradient, another could produce a grayscale value with an alpha channel, or it could produce a full color RGBA color. They have a lot of things in common - it's just at the very end that there is a difference. As a result, there is an adapter (actually, several of them) that can convert between one and another.
In this example, we've chosen a color that just uses the iteration count (i.e., how many passes were made before the point "escaped"). But since that returns an index value, and we want a full color value, we use an adapter to convert between them:

This adapter appears below the contents of the object - there is a popup menu that allows you to choose what kind of adapter you use (in this case, the "Index Gradient to Color" adapter). As you can see, it includes a gradient, another object (used to adjust the index value in a wide range of ways, such as scaling, offseting, wrapping around in different ways, etc...), and a checkbox that indicates that "color 0 is transparent" (i.e., if the index 0 creates a transparent color for things that use such features).
And these adapters are similar to other objects, in that they are all created and defined in quadriumScript, and the user can create their own. So if you had a better way to convert an index into a color, you could write an adapter to do this, and it would then be available in all places that used an indexed color (and needed an RGBA color).
These building blocks are small, but are extremely powerful as they get used together. For example, anytime we need to "measure" something (such as if the value has escaped in the escape fractal) we use an object that adopts the DistanceShapeProtocol. But there is also a technique for coloring that uses what are called "traps" - objects that if the point lands in, we do something special. Those traps have both a shape and a "contour" and "shading" (which allow things like fading the edges of them, or applying a texture to them) - we've got an adapter that converts a DistanceShapeProtocol object to a trap by allowing you to specify objects used to define the contour and shading (such as solid, ramping in or out), or another one that includes a texture that is blended in (using your choice of texture object and compositing object).
Now if you come up with a different way to measure a distance, not only will that new technique be available for calculating the bailout, but it will also be available as a trap, as well as in other places that use either that protocol directly or via a converter. So adding something for the purpose of providing a different bailout scheme will also allow you to have the new trap, a new shape for masking, or used in generating some other sort of texture. And if you want to write an object that needs to measure something, rather than hardcoding in a single way (or providing a menu to decide between a couple of limited choices), by using a parameter declared as a DistanceShapeProtocol adopting object, your algorithm can be extended by other peoples objects.