1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
|
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- ====================================================================== -->
<!-- author Thomas.DeWeese@kodak.com -->
<!-- version $Id$ -->
<!-- ====================================================================== -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
<document>
<header>
<title>Extending Batik</title>
</header>
<body>
<p>
This page provides an overview of the built in extension mechanisms of
Batik. As an open source project, people can of course make any
extension they feel is interesting, however Batik has been
designed with several forms of extension in mind.
</p>
<p>
In general, extensions are added through the Service
Provider Interface mechanism as described in the
<a href="http://java.sun.com/j2se/1.4/docs/guide/jar/jar.html#Service Provider">jar
file documentation</a>. This allows for the extension of Batik
simply by adding a new jar file(s) to the class path, and thus no
modification of the Batik source is required!
</p>
<note>
If you feel that the Batik team has overlooked an
important area for extension please let your feelings be
known on the mailing lists.
</note>
<section id="customXMLTags">
<title>Custom XML elements</title>
<p>
First one must ask what it means to support custom
XML elements? There are three basic options Batik considers:
</p>
<dl>
<dt>Having your elements appear in the DOM tree</dt>
<dd>
<p>
As long as your custom elements are well formed
XML they will appear in the SVG DOM tree. When rendering Batik
will skip branches of the tree that use elements it doesn’t know
about (so even if standard SVG elements are child nodes they will
not be displayed). Note that you must make use of XML namespaces
for your personal elements even if you are not planning on
validating the XML.
</p>
<p>
This can be useful if you want to add extra pieces of
data into the standard SVG drawing. These might be
annotations, or other application specific data. In
general this wouldn’t be particularly useful with
squiggle (the SVG browser) or the rasterizer, but
might be very useful if you were writing a custom
browser, rasterizer, or pre/post processing tools.
</p>
</dd>
<dt>Adding functionality to your custom element DOM objects</dt>
<dd>
<p>
If you need your elements to use a custom element subclass
in the DOM tree (for behavioral or performance reasons) then you
need to provide an <a href="#domExtension">extension to the Batik
DOM</a>.
</p>
<p>
Doing this gives you the opportunity to override the standard
methods on DOM elements, or to provide additional methods to
your DOM elements. For example, you may wish to add specialized
get and set methods for attributes on your custom elements, so
that they can be manipulated more easily than just using the
string-based <code>getAttribute</code> and
<code>setAttribute</code> methods provided by DOM Core.
</p>
</dd>
<dt>Having your custom elements be rendered</dt>
<dd>
<p>
Probably the most common reason to develop custom elements is to
add new rendering primitives to the SVG language. In this case
you must provide an <a href="#bridgeExtension">extension to the
Batik bridge</a>. The bridge extension is resposible
for constructing the class(es) that will handle the rendering of
the new primitive in Batik.
</p>
<p>
In most cases it will also be necessary to write a DOM
extension to make the element behave like other SVG elements
(most notably for support of styling).
</p>
</dd>
</dl>
<section id="domExtension">
<title>Writing a Batik DOM extension</title>
<p>
The ability to extend the elements used in the SVG DOM tree allows
users to provide implementations for nodes that can be used in
place of Batik’s default implementation of a node. This may be
done for a variety of reasons, but is most commonly done to
extend the behavior of standard node calls (such as
to include styling in attribute lookup), or to
implement the DOM interface for an element.
</p>
<p>
The key class for building the DOM tree is
<a class="class" href="../javadoc/org/apache/batik/dom/ExtensibleSVGDOMImplementation.html">org.apache.batik.dom.ExtensibleSVGDOMImplementation</a>.
When an instance of this class is constructed it searches for
instances of the
<a class="class" href="../javadoc/org/apache/batik/dom/svg/DomExtension.html">org.apache.batik.dom.svg.DomExtension</a>
Service Provider Interface. It then calls the
<code>registerTags</code> method, passing itself as the only
parameter. This method typically would typically call
<code>registerCustomElementFactory</code> for each element that
it wishes to handle.
</p>
<p>
With Batik the most likely reason to extend a node is to provide
proper CSS styling of the node attributes. To this end Batik
provides a class you can extend:
<a class="class" href="../javadoc/org/apache/batik/extension/PrefixableStylableExtensionElement.html">org.apache.batik.extension.PrefixableStylableExtensionElement</a>.
If you derive a new DOM class from this class you are only
required to implement three methods: <code>getLocalName</code>,
<code>getNamespaceURI</code>, and <code>newNode</code>
(plus constructors). If all you want is proper style support
(commonly the case) then you are done implementing your element
at this point.
</p>
<p>
The distribution comes with a number of examples:
</p>
<ul>
<li><code>org.apache.batik.extension.svg.BatikStarElement</code></li>
<li><code>org.apache.batik.extension.svg.BatikRegularPolygonElement</code></li>
<li><code>org.apache.batik.extension.svg.BatikHistogramNormalizationElement</code></li>
<li><code>org.apache.batik.extension.svg.SolidColorElement</code></li>
<li><code>org.apache.batik.extension.svg.ColorSwitchElement</code></li>
</ul>
<p>
Included with these examples is
<code>org.apache.batik.extension.svg.BatikDomExtension</code>,
which is the required instance of <code>DomExtension</code>
used to register the elements with the
<code>ExtensibleSVGDOMImplementation</code>.
</p>
<p>
If your new element requires new “presentation attributes”
(XML attributes that can be modified through CSS, or, depending
on your viewpoint, the other way around—CSS properties that
can be specified using XML attributes), you will also need to
extend the CSS engine. This can be done by registering a
custom CSS value factory. Both of the color examples do
this (see <code>BatikDomExtension</code>).
</p>
</section>
<section id="bridgeExtension">
<title>Writing a Batik bridge extension</title>
<p>
Before you write a bridge extension it may be useful to
understand what role the bridge package plays in
Batik. The bridge package is responsible for creating and
maintaining elements in the Graphics Vector Toolkit (GVT)
tree based on the corresponding element in the SVG DOM. This
is done because, for a variety of reasons, the SVG DOM is not
well suited for rendering, thus the GVT tree is used for all
rendering and transcoding operations.
</p>
<p>
The key class for managing this link is the
<a class="class" href="../javadoc/org/apache/batik/bridge/BridgeContext.html">BridgeContext</a>.
This class maintains an association between a element name
with namespace and a particular bridge instance that will
handle it. The work of constructing the proper entity or
entities in the GVT tree is then deferred to the
<a class="class" href="../javadoc/org/apache/batik/bridge/Bridge.html">Bridge</a>
registered for a particular element. If no bridge is
regiestered nothing is done.
</p>
<p>
New associations can be added by implementors of the
<a class="class" href="../javadoc/org/apache/batik/bridge/BridgeExtension.html">BridgeExtension</a>
Service Provider Interface. This interface has a number
of methods that provide information about the particular
extension being registered (including contact information,
and the list of implemented extensions). It also has a
<code>registerTags</code> method which is responsible for
registering the bridge instances with a
<code>BridgeContext</code>. All the built-in
bridges are bundled together with a
<code>BridgeExtension</code> (the
<a class="class" href="../javadoc/org/apache/batik/bridge/SVGBridgeExtension.html">org.apache.batik.bridge.SVGBridgeExtension</a>
class), as are the example extensions
(<a class="class" href="../javadoc/org/apache/batik/extension/svg/BatikBridgeExtension.html">org.apache.batik.extension.svg</a>),
so these are both good places to start.
</p>
<p>
The <code>Bridge</code> interface itself is very simple.
It only includes methods to get the namespace and local
name of the element the bridge is responsible for. This
interface is then extended for each of the major
concepts present in SVG:
</p>
<dl>
<dt><a href="#graphicsNodeBridge">GraphicsNodeBridge</a></dt>
<dd>
<p>
These are probably the most common SVG elements, as
they represent graphic elements in the “visible” SVG tree.
These are the elements most other bridges modify in some way
(by clipping, masking, filtering, etc).
</p>
<p>
<em>Example SVG elements:</em>
<code>svg</code>, <code>g</code>, <code>path</code>,
<code>rect</code>.
</p>
<p>
<em>Example extension bridges:</em>
<code>BatikRegularPolygonElementBridge</code>,
<code>BatikStarElementBridge</code>.
</p>
</dd>
<dt>FilterBridge</dt>
<dd>
<p>
This handles the SVG <code>filter</code> element. If you
wanted to implement a new element that could be
referenced from the <code>filter</code> attribute on an SVG
graphics node then you would need to subclass this
bridge. However, adding new types of filters to the
existing SVG <code>filter</code> element is accomplished via the
FilterPrimitiveBridge.
</p>
<p>
<em>Example SVG element:</em> <code>filter</code>
</p>
</dd>
<dt><a href="#filterPrimitiveBridge">FilterPrimitiveBridge</a></dt>
<dd>
<p>
This constructs an element in the filter chain
applied to an SVG graphics node.
</p>
<p>
<em>Example SVG elements:</em>
<code>feBlend</code>, <code>feCompose</code>,
<code>feGaussianBlur</code>.
</p>
<p>
<em>Example extension bridge:</em>
<code>BatikHistogramNormalizationElementBridge</code>
</p>
</dd>
<dt><a href="#paintBridge">PaintBridge</a></dt>
<dd>
<p>
This constructs a Java
<a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Paint.html">Paint</a>
object to be used in filling or stroking graphic elements.
</p>
<p>
<em>Example SVG elements:</em>
<code>gradient</code>, <code>pattern</code>.
</p>
<p>
<em>Example extension bridge:</em>
<code>ColorSwitchBridge</code>.
</p>
</dd>
<dt>ClipBridge</dt>
<dd>
<p>
This constructs a
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/renderable/ClipRable.html">ClipRable</a>
to apply to a graphics node. This provides a path that data
is clipped to.
</p>
<p>
<em>Example SVG element:</em> <code>clipPath</code>.
</p>
</dd>
<dt>MarkerBridge</dt>
<dd>
<p>
This constructs a
<a class="class" href="../javadoc/org/apache/batik/gvt/Marker.html">Marker</a>
for annotating the path of a graphics node.
</p>
<p>
<em>Example SVG element:</em> <code>marker</code>.
</p>
</dd>
<dt>MaskBridge</dt>
<dd>
<p>
This constructs a mask filter to apply to a graphics
node. Mask filters typically modify the alpha channel of the
graphics node output to make portions fully or partially
transparent that wouldn’t be otherwise.
</p>
<p>
<em>Example SVG element:</em> <code>mask</code>.
</p>
</dd>
</dl>
<p>
Extension writers are free to work with any of the
above bridges, however the three most common are
likely to be the <code>GraphicsNodeBridge</code>, the
<code>FilterPrimitiveBridge</code>, and the
<code>PaintBridge</code> (each of which has example
extensions available for inspection). Each of these interfaces
has several very useful subclasses that handle much of the
common behavior among elements.
</p>
<p>
In some simple cases it is possible to provide only an
extension to the bridge and achieve your desired effect,
however in most cases you will find that for your
element to behave like a normal SVG element (for
example, to support styling) you will need to provide
a DOM extension as well.
</p>
<section id="graphicsNodeBridge">
<title>GraphicsNodeBridge</title>
<p>
The graphics node bridge is oriented around
constructing a new
<a class="class" href="../javadoc/org/apache/batik/gvt/GraphicsNode.html">GraphicsNode</a>
in the GVT tree. The <code>GraphicsNode</code> is the basic
object that makes up the GVT tree. Each
<code>GraphicsNode</code> has a <code>paint</code> method that
is responsible for painting the object (including considering
clipping, masking, filtering, and opacity for the
node).
</p>
<p>
If you want to you can implement the
<a class="class" href="../javadoc/org/apache/batik/bridge/GraphicsNodeBridge.html">GraphicsNodeBridge</a>
interface directly, or you can subclass the
<a class="class" href="../javadoc/org/apache/batik/bridge/AbstractGraphicsNodeBridge.html">AbstractGraphicsNodeBridge</a>
class. This gives you the most flexibility since you can
construct your new subclass of <code>GraphicsNode</code>, where
you can implement the paint method to do essentially anything
you want. This is quite involved, however, and the steps
necessary to create a full <code>GraphicsNodeBridge</code>
are not detailed here.
</p>
<p>
However, if you just want to generate a custom
filled or stroked shape the easiest way is to
subclass one of the following two classes. In this
case you are essentially only responsible for
constructing a standard Java
<a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Shape.html">Shape</a>
object to describe the desired area to operate on:
</p>
<dl>
<dt>SVGShapeElementBridge</dt>
<dd>
<p>
Subclasses of this class only need to implement
<code>buildShape</code>, <code>getNamespaceURI</code>,
and <code>getLocalName</code>. <code>buildShape</code>
generally constructs a <code>Shape</code> object and sets it
on the provided <code>shapeNode</code> object, however it
may adjust other features of the given shape node.
</p>
</dd>
<dt>SVGDecoratedShapeElementBridge</dt>
<dd>
<p>
This is very similar to <code>SVGShapeElementBridge</code>,
except that it also handles the standard marker properties.
Markers will be placed at the end of each segment of
the path that describes the shape.
</p>
</dd>
</dl>
<p>
If you decide that you need to implement a new subclass
of <code>GraphicsNode</code> it is strongly suggested that
you extend
<a class="class" href="../javadoc/org/apache/batik/gvt/AbstractGraphicsNode.html">AbstractGraphicsNode</a>,
as this class does much of the work to behave like other
rendered elements in SVG (like clipping, filtering and
masking). In this case you implement the
<code>primitivePaint</code> method instead of the
<code>paint</code> method.
</p>
</section>
<section id="filterPrimitiveBridge">
<title>FilterPrimitiveBridge</title>
<p>
The
<a class="class" href="../javadoc/org/apache/batik/bridge/FilterPrimitiveBridge.html">FilterPrimitiveBridge</a>
is concerned with the construction of individual elements of the
filter chain. Unlike graphics nodes, which generally just
draw new objects on top of the destination, filters take
existing image data and modify it to apply effects.
</p>
<p>
This part of GVT rendering is based on the Java2D
<a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/renderable/RenderableImage.html">java.awt.image.renderable.RenderableImage</a>
and <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/renderable/RenderedImage.html">java.awt.image.RenderedImage</a>
interfaces. These provide a convenient framework to handle
image processing (an inherently resolution dependent
operation) in the resolution independent system defined by
SVG.
</p>
<p>
The <code>org.apache.batik.ext.awt.image</code> package
hierarchy contains a large set of generally useful extensions
to the core JDK classes and methods, that help to implement
SVG-related graphics operations.
</p>
<p>
Note that the <code>FilterPrimitiveBridge</code> is invoked
once for each reference to the <code>filter</code> element that
the filter primitive is part of. So if a filter effect is used
a half dozen times the <code>createFilter</code> method will be
called a half dozen times, even though the element may only
appear once in the file. This means that it is safe for the
filters returned to be “fixed” for a particular
<code>GraphicsNode</code> being filtered.
</p>
<p>
You will notice that Batik uses extended versions of
the standard <code>RenderableImage</code> and <code>RenderedImage</code>
interfaces to provide additional information about
surrounding requirements for operations as well as a few
convenience methods. These interfaces are called:
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/renderable/Filter.html">org.apache.batik.ext.awt.image.renderable.Filter</a>
and
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/rendered/CacheableRed.html">org.apache.batik.ext.awt.image.rendered.CacheableRed</a>.
Batik contains simple wrapper classes that can take the default
JDK <code>RenderableImage</code> and <code>RenderedImage</code>
interfaces. Within the codebase the naming convention “Red” for
classes implementing <code>RenderedImage</code> and “Rable” for classes
implementing <code>RenderableImage</code> is commonly
used (“Red” is to be pronounced like the color, and
“Rable” is to be pronounced like “horrible” with a
silent “h”).
</p>
<p>
The <code>FilterPrimitiveBridge</code> has only
one method, <code>createFilter</code>, that must
construct an instance of <code>Filter</code> to perform
the required operation. This is still a fairly complex task
given the general need to support accessing the various
standard sources of image data. To this end there is
a provided subclass,
<a class="class" href="../javadoc/org/apache/batik/bridge/AbstractSVGFilterPrimitiveElementBridge.html">AbstractSVGFilterPrimitiveElementBridge</a>,
that provides convenience methods to handle many common tasks.
</p>
<p>
Generally the bulk of the work in writing a filter
extension is the writing of the concrete <code>Filter</code>
class, not tying it into the GVT tree. Batik does contain
several base classes that make this processes a bit
easier:
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/renderable/AbstractRable.html">org.apache.batik.ext.awt.image.renderable.AbstractRable</a>,
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/rendered/AbstractRed.html">org.apache.batik.ext.awt.image.rendered.AbstractRed</a>,
and
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/rendered/AbstractTiledRed.html">org.apache.batik.ext.awt.image.rendered.AbstractTiledRed</a>,
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/rendered/TiledRed.html">TiledRed</a>
ties into the Batik tile cache (use this with caution as it is a
complex area of the Batik code).
</p>
<p>
The <code>org.apache.batik.ext.awt.image.rendered</code>
and <code>org.apache.batik.ext.awt.image.renderable</code>
packages contain quite a number of fairly general examples
covering most common cases, please refer to them for more detail.
</p>
</section>
<section id="paintBridge">
<title>PaintBridge</title>
<p>
The
<a class="class" href="../javadoc/org/apache/batik/bridge/PaintBridge.html">PaintBridge</a>
constructs an instance of <code>java.awt.Paint</code> to be used
to fill or stroke shapes/text (part of the paint server
architecture of SVG).
</p>
<p>
Like the filter primitive bridge, the <code>PaintBridge</code>
is invoked for each reference to the paint. This makes
it possible to customize the <code>Paint</code> returned for the
particular element to be painted.
</p>
<p>
This is how gradients and patterns are implemented
in Batik, so it is possible to construct rather
complex paint effects through this mechanism.
</p>
<p>
For paints you are mostly on your own, because unlike
the other cases there aren’t any really generally useful
base classes to derive off, the closest is the
<a class="class" href="../javadoc/org/apache/batik/bridge/AbstractSVGGradientElementBridge.html">AbstractSVGGradientElementBridge</a>,
which is used to handle most of the radial and linear gradient
attributes.
</p>
<p>
The existing gradient paint implementations are in the
<code>org.apache.batik.ext.awt</code>, and the pattern
implementation is in <code>org.apache.batik.gvt</code> since it
requires access to GVT internals.
</p>
</section>
</section>
</section>
<section id="imageTagFormats">
<title>New image file formats</title>
<p>
When Batik encounters an <code>image</code> element and it
determines the element does not reference an SVG file, it defers
the loading of the referenced image to
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/spi/ImageTagRegistry.html">org.apache.batik.ext.awt.image.spi.ImageTagRegistry</a>.
This class maintains a list of
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/spi/RegistryEntry.html">RegistryEntry</a>s,
generally one for each format.
</p>
<p>
Since the formats supported natively by Batik are also
implemented through this mechanism. The
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/codec/jpeg/JPEGRegistryEntry.html">JPEGRegistryEntry</a>
and
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/codec/png/PNGRegistryEntry.html">PNGRegistryEntry</a>
classes should be used as good references for extensions.
</p>
<section>
<title>RegistryEntry</title>
<p>
There are currently two flavors of <code>RegistryEntry</code>:
</p>
<dl>
<dt>URLRegistryEntry</dt>
<dd>
<p>
A
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/spi/URLRegistryEntry.html">URLRegistryEntry</a>
takes a
<a class="class" href="../javadoc/org/apache/batik/util/ParsedURL.html">ParsedURL</a>
and tries to decide if the URL is intended for it. This group
of entries is mostly intended to handle alternate network
protocols. It can also be useful for interfacing with
libraries that want a URL instead of a stream.
</p>
</dd>
<dt>StreamRegistryEntry</dt>
<dd>
<p>
A
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/spi/StreamRegistryEntry.html">StreamRegistryEntry</a>
works with a markable
<a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/InputStream.html">InputStream</a>.
This is the preferred form of registry entry as it generally
avoids opening a potentially expensive connection multiple
times, instead it opens the stream once and relies on mark and
reset to allow entries to check the stream.
</p>
</dd>
</dl>
</section>
<section>
<title>Helper classes</title>
<p>
There exists quite a number of classes to assist in
implementing a <code>RegistryEntry</code>. It is strongly
recommended that you review these classes and make use
of them where appropriate. They will likely save you
time and improve the integration with Batik.
</p>
<dl>
<dt>MagicNumberRegistryEntry</dt>
<dd>
<p>
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/spi/MagicNumberRegistryEntry.html">MagicNumberRegistryEntry</a>
is an abstract class that can handle the
<code>isCompatibleStream</code> method for formats that
make use of “magic numbers.” Magic numbers are a well
known sequence of bytes at a well known offset in the
file, that are commonly used to identify image file formats.
</p>
</dd>
<dt>RedRable</dt>
<dd>
<p>
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/renderable/RedRable.html">RedRable</a>
takes any <code>java.awt.image.RenderedImage</code> and wraps it
into a <code>Filter</code> (Batik’s subinterface of
<code>RenderableImage</code>). This is very useful for
<em>single resolution</em> file formats.
</p>
</dd>
<dt>DeferRable</dt>
<dd>
<p>
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/renderable/DeferRable.html">DeferRable</a>
allows one to load the image in a background
thread, rather than hold up the construction of the
GVT tree while reading the image (useful since
reading the image is generally I/O bound, so it
makes a good background task). This is used by most of
the current image readers.
</p>
</dd>
<dt>AbstractRable</dt>
<dd>
<p>
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/renderable/AbstractRable.html">AbstractRable</a>
is an abstract base class that makes it relatively
easy to implement the Filter interface.
</p>
</dd>
<dt>AbstractRed</dt>
<dd>
<p>
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/rendered/AbstractRed.html">AbstractRed</a>
is an abstract base class that makes it relatively
easy to implement the
<a class="class" href="../javadoc/org/apache/batik/ext/awt/image/rendered/CacheableRed.html">CacheableRed</a>
interface (Batik's subclass of <code>RenderedImage</code>).
</p>
</dd>
</dl>
</section>
</section>
<section id="urlProtocols">
<title>New URL protocols</title>
<p>
For a variety of reasons (not the least of which is the
heavy use of the <code>data:</code> URL protocol in SVG), several
parts of Batik use a
<a class="class" href="../javadoc/org/apache/batik/util/ParsedURL.html">ParsedURL</a>
instead of the JDK’s
<a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URL.html">java.net.URL</a>
class.
</p>
<p>
<code>ParsedURL</code> offers a few advantages over the JDK’s
<code>URL</code> class. First, it is designed to make minimal use of
exceptions, so it is possible to use it to parse a malformed
URL and get “the good parts”. Second, it is extensible, so
support for new URL protocols can be added, even those that
change the normal parsing rules for URLs (such as our friend the
<code>data:</code> protocol). Third, it can automatically check a
when a stream can be opened for common compression types and decode
them for you (this behavior can also be bypassed if needed).
</p>
<p>
The service class is
<a class="class" href="../javadoc/org/apache/batik/util/ParsedURLProtocolHandler.html">org.apache.batik.util.ParsedURLProtocolHandler</a>.
This interface consists of three methods: one returns the protocol
to be handled, one is for parsing an absolute URL string and
one is for parsing relative URL strings. Both the parsing
methods return an object of type
<a class="class" href="../javadoc/org/apache/batik/util/ParsedURLData.html">ParsedURLData</a>
(the instance may of course be a subclass of
<code>ParsedURLData</code>).
</p>
<p>
The <code>ParsedURLData</code> class holds all the data and
implements all the stream handling commands for the
<code>ParsedURL</code> class. This allows
<code>ParsedURLProtocolHandler</code>s to return custom subclasses
for particular protocols.
</p>
</section>
<section id="interpreters">
<title>Additional script interpreters</title>
<p>
While conforming SVG browsers need support only ECMAScript as a scripting
language, Batik can support any scripting language given the right glue
to connect it to the rest of the system.
</p>
<p>
Script interpreters are also handled via the Service Provider Interface,
The interface that needs to be implemented to expose a new interpreter
to Batik is
<a class="class" href="../javadoc/org/apache/batik/script/InterpreterFactory.html">InterpreterFactory</a>.
This class has two methods: <code>getMimeType</code>, which returns
a string that specifies what script type this intepreter handles
(specifically, what the <code>type</code> attribute of
<code>script</code> elements must be for them to be handled by this
intepreter), and <code>createInterpreter</code>, which creates an
instance of the
<a class="class" href="../javadoc/org/apache/batik/script/Interpreter.html">Interpreter</a>
interface.
</p>
<p>
Batik comes with implementations of <code>Interpreter</code> and
<code>IntepreterFactory</code> to support TCL and Python script in
SVG documents, if the Jacl and Jython distributions are installed,
respectively. See the classes in the
<code>org.apache.batik.script.jacl</code> and
<code>org.apache.batik.script.jython</code> packages to guidance
on how to implement the interpreter interfaces, and the
<a href="site:install">installation notes</a> on what jar files are
needed for TCL and Python support.
</p>
</section>
</body>
</document>
|