001: /*
002: * $Id: SWFRenderer.java,v 1.2 2002/02/15 23:44:28 skavish Exp $
003: *
004: * ==========================================================================
005: *
006: * The JGenerator Software License, Version 1.0
007: *
008: * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution, if
022: * any, must include the following acknowlegement:
023: * "This product includes software developed by Dmitry Skavish
024: * (skavish@usa.net, http://www.flashgap.com/)."
025: * Alternately, this acknowlegement may appear in the software itself,
026: * if and wherever such third-party acknowlegements normally appear.
027: *
028: * 4. The name "The JGenerator" must not be used to endorse or promote
029: * products derived from this software without prior written permission.
030: * For written permission, please contact skavish@usa.net.
031: *
032: * 5. Products derived from this software may not be called "The JGenerator"
033: * nor may "The JGenerator" appear in their names without prior written
034: * permission of Dmitry Skavish.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
040: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: *
049: */
050:
051: package org.openlaszlo.iv.flash.fop;
052:
053: import org.xml.sax.InputSource;
054:
055: import org.apache.fop.configuration.*;
056: import org.apache.fop.fo.properties.*;
057: import org.apache.fop.layout.*;
058: import org.apache.fop.layout.inline.*;
059: import org.apache.fop.messaging.MessageHandler;
060: import org.apache.fop.datatypes.*;
061: import org.apache.fop.image.*;
062: import org.apache.fop.svg.*;
063: import org.apache.fop.render.pdf.*;
064: import org.apache.fop.viewer.*;
065: import org.apache.fop.apps.*;
066:
067: import java.io.*;
068: import java.util.*;
069:
070: /**
071: * This is a implementation of the FOP Renderer interface that places Flash objects
072: * based on FOP data.
073: *
074: * @author Johan "Spocke" Sörlin
075: * @author James Taylor
076: */
077:
078: public class SWFRenderer implements org.apache.fop.render.Renderer {
079: private int currentPosX = 0;
080: private int currentPosY = 0;
081: private int currentACPosX = 0;
082: private int currentPage = 0;
083: private int movieWidth = 0;
084: private int movieHeight = 0;
085: private AreaTree tree;
086: private Hashtable fontNames;
087: private Hashtable fontStyles;
088:
089: private FOPScriptBuilder flashMovie = new FOPScriptBuilder();
090:
091: public void startRenderer(OutputStream outputStream)
092: throws IOException {
093: }
094:
095: public void stopRenderer(OutputStream outputStream)
096: throws IOException {
097: }
098:
099: /**
100: * Constructs a new FOPSWFRenderer
101: */
102:
103: public SWFRenderer() {
104: }
105:
106: /**
107: * Get the script this renderer is drawing into
108: */
109:
110: public FOPScriptBuilder getScriptBuilder() {
111: return flashMovie;
112: }
113:
114: public void setLinkHandler(String s) {
115: flashMovie.setLinkHandler(s);
116: }
117:
118: /**
119: * set up the given FontInfo
120: *
121: * @param fontInfo font info passed from FOP framework
122: */
123:
124: public void setupFontInfo(org.apache.fop.layout.FontInfo fontInfo) {
125: org.apache.fop.render.pdf.FontSetup.setup(fontInfo);
126:
127: ConfigurationReader reader = new ConfigurationReader(
128: new InputSource(
129: org.openlaszlo.iv.flash.util.Util
130: .getInstallDir()
131: + java.io.File.separator
132: + org.openlaszlo.iv.flash.util.PropertyManager
133: .getProperty("org.openlaszlo.iv.flash.fopConfig")));
134:
135: try {
136: reader.start();
137: } catch (org.apache.fop.apps.FOPException error) {
138: MessageHandler
139: .errorln("Unable to read user configuration file.");
140: }
141:
142: String internalName = null;
143: int fontNumber = 0;
144:
145: Vector fontInfos = Configuration.getFonts();
146:
147: if (fontInfos == null) {
148: return;
149: }
150:
151: for (Enumeration e = fontInfos.elements(); e.hasMoreElements();) {
152: org.apache.fop.configuration.FontInfo configFontInfo = (org.apache.fop.configuration.FontInfo) e
153: .nextElement();
154:
155: String fontFile = configFontInfo.getEmbedFile();
156:
157: internalName = "F" + (fontNumber++);
158:
159: fontInfo.addMetrics(internalName, new SWFFontMetric(
160: fontFile));
161:
162: Vector triplets = configFontInfo.getFontTriplets();
163:
164: for (Enumeration t = triplets.elements(); t
165: .hasMoreElements();) {
166: FontTriplet triplet = (FontTriplet) t.nextElement();
167:
168: fontInfo.addFontProperties(internalName, triplet
169: .getName(), triplet.getStyle(), triplet
170: .getWeight());
171: }
172: }
173: }
174:
175: /**
176: * Set up renderer options -- Empty
177: *
178: * @param options options passed from FOP framework
179: */
180:
181: public void setOptions(java.util.Hashtable options) {
182: }
183:
184: /**
185: * Set the producer of the rendering -- Empty
186: *
187: * @param producer producer passed from FOP framework
188: */
189:
190: public void setProducer(String producer) {
191: }
192:
193: /**
194: * render the given page.
195: * The stream parameter is ignored.
196: *
197: * @param area_tree area tree passed from FOP framework
198: * @param stream stream to write to, ignored
199: */
200:
201: public void render(Page page, OutputStream stream)
202: throws IOException {
203: renderPage(page);
204: }
205:
206: /**
207: * render the given area container
208: *
209: * @param area area passed from FOP framework
210: */
211:
212: public void renderAreaContainer(AreaContainer area) {
213: int oldX = this .currentACPosX;
214: int oldY = this .currentPosY;
215:
216: if (area.getPosition() == Position.ABSOLUTE) {
217: this .currentPosY = area.getYPosition()
218: - (2 * area.getPaddingTop())
219: - (2 * area.getBorderTopWidth());
220:
221: this .currentACPosX = area.getXPosition();
222: } else if (area.getPosition() == Position.RELATIVE) {
223: this .currentPosY -= area.getYPosition();
224: this .currentACPosX += area.getXPosition();
225: } else if (area.getPosition() == Position.STATIC) {
226: this .currentPosY -= (area.getPaddingTop() + area
227: .getBorderTopWidth());
228:
229: this .currentACPosX += (area.getPaddingLeft() + area
230: .getBorderLeftWidth());
231: }
232:
233: drawFrame(area);
234:
235: renderChildren(area);
236:
237: this .currentACPosX = oldX;
238: this .currentPosY = oldY;
239:
240: if (area.getPosition() == Position.STATIC) {
241: this .currentPosY -= area.getHeight();
242: }
243: }
244:
245: /**
246: * render the given body area container
247: *
248: * @param area body area container passed from FOP framework
249: */
250:
251: public void renderBodyAreaContainer(BodyAreaContainer area) {
252: renderAreaContainer(area.getBeforeFloatReferenceArea());
253: renderAreaContainer(area.getFootnoteReferenceArea());
254:
255: // Children are span areas? ( see AWTRenderer )
256:
257: renderChildren(area);
258: }
259:
260: /**
261: * render the given span area
262: *
263: * @param area span area passed from FOP framework
264: */
265:
266: public void renderSpanArea(SpanArea area) {
267: // Children are column areas? ( see AWTRenderer )
268:
269: renderChildren(area);
270: }
271:
272: /**
273: * render the given block area
274: *
275: * @param area span block passed from FOP framework
276: */
277:
278: public void renderBlockArea(BlockArea area) {
279: this .currentPosY -= (area.getPaddingTop() + area
280: .getBorderTopWidth());
281:
282: drawFrame(area);
283:
284: renderChildren(area);
285:
286: this .currentPosY -= (area.getPaddingBottom() + area
287: .getBorderBottomWidth());
288: }
289:
290: /**
291: * render the display space area
292: *
293: * @param space display space passed from FOP framework
294: */
295:
296: public void renderDisplaySpace(DisplaySpace space) {
297: currentPosY -= space.getSize();
298: }
299:
300: /**
301: * render the given SVG area -- Empty
302: *
303: * @param area area passed from FOP framework
304: */
305:
306: public void renderSVGArea(SVGArea area) {
307: currentPosX += area.getContentWidth();
308: }
309:
310: /**
311: * render a foreign object area -- Empty
312: *
313: * @param area area passed from FOP framework
314: */
315:
316: public void renderForeignObjectArea(ForeignObjectArea area) {
317: }
318:
319: /**
320: * render the given image area -- Empty
321: *
322: * @param area area passed from FOP framework
323: */
324:
325: public void renderImageArea(ImageArea area) {
326: currentPosY -= area.getHeight();
327: }
328:
329: /**
330: * render the given word area
331: *
332: * @param area word area passed from FOP framework
333: */
334:
335: public void renderWordArea(WordArea area) {
336: FontState fontState = area.getFontState();
337:
338: SWFFontMetric fontMetric;
339:
340: try {
341: fontMetric = (SWFFontMetric) fontState.getFontInfo()
342: .getMetricsFor(fontState.getFontName());
343: } catch (FOPException e) {
344: MessageHandler.errorln("Failed to get metrics for font \""
345: + fontState.getFontName()
346: + "\", using default font.");
347:
348: fontMetric = new SWFFontMetric("Arial.fft");
349: }
350:
351: flashMovie.addText(area.getText(), this .currentPosX,
352: this .currentPosY, area.getRed(), area.getGreen(), area
353: .getBlue(), fontMetric,
354: fontState.getFontSize(), area.getContentWidth());
355:
356: addWordAreaLines(area, fontState.getFontSize());
357:
358: this .currentPosX += area.getContentWidth();
359: }
360:
361: protected void addWordAreaLines(WordArea area, int size) {
362: int y;
363:
364: if (area.getUnderlined()) {
365: y = currentPosY - size / 14;
366:
367: flashMovie.addRect(currentPosX, y, area.getContentWidth(),
368: -size / 14, area.getRed(), area.getBlue(), area
369: .getGreen());
370: }
371:
372: if (area.getOverlined()) {
373: y = currentPosY + area.getFontState().getAscender() + 2
374: * (size / 14);
375:
376: flashMovie.addRect(currentPosX, y, area.getContentWidth(),
377: size / 14, area.getRed(), area.getBlue(), area
378: .getGreen());
379: }
380:
381: if (area.getLineThrough()) {
382: y = currentPosY + area.getFontState().getAscender() / 2;
383:
384: flashMovie.addRect(currentPosX, y, area.getContentWidth(),
385: -size / 14, area.getRed(), area.getBlue(), area
386: .getGreen());
387: }
388: }
389:
390: /**
391: * render the given inline space
392: *
393: * @param space inline space passed from FOP framework
394: */
395:
396: public void renderInlineSpace(InlineSpace space) {
397: this .currentPosX += space.getSize();
398: }
399:
400: /**
401: * render the given line area
402: *
403: * @param area line area passed from FOP framework
404: */
405:
406: public void renderLineArea(LineArea area) {
407: int x = currentACPosX + area.getStartIndent();
408: int y = currentPosY;
409: int w = area.getContentWidth();
410: int h = area.getHeight();
411:
412: currentPosY -= area.getPlacementOffset();
413: currentPosX = x;
414:
415: Enumeration e = area.getChildren().elements();
416:
417: while (e.hasMoreElements()) {
418: org.apache.fop.layout.Box box = (org.apache.fop.layout.Box) e
419: .nextElement();
420:
421: if (box instanceof InlineArea) {
422: currentPosY = y - ((InlineArea) box).getYOffset();
423: } else {
424: currentPosY = y - area.getPlacementOffset();
425: }
426:
427: box.render(this );
428: }
429:
430: currentPosY = y - h;
431: }
432:
433: /**
434: * render the given page
435: *
436: * @param page page passed from FOP framework
437: */
438:
439: public void renderPage(Page page) {
440: BodyAreaContainer body;
441: AreaContainer before, after;
442:
443: flashMovie.startPage(page.getWidth(), page.getHeight());
444:
445: body = page.getBody();
446: before = page.getBefore();
447: after = page.getAfter();
448:
449: renderBodyAreaContainer(body);
450:
451: if (before != null) {
452: renderAreaContainer(before);
453: }
454:
455: if (after != null) {
456: renderAreaContainer(after);
457: }
458:
459: if (page.hasLinks()) {
460: Enumeration e = page.getLinkSets().elements();
461:
462: while (e.hasMoreElements()) {
463: LinkSet linkSet = (LinkSet) e.nextElement();
464:
465: linkSet.align();
466:
467: Enumeration f = linkSet.getRects().elements();
468:
469: while (f.hasMoreElements()) {
470: LinkedRectangle rect = (LinkedRectangle) f
471: .nextElement();
472:
473: flashMovie.addLink(rect.getX(), rect.getY(), rect
474: .getWidth(), rect.getHeight(), linkSet
475: .getDest());
476: }
477: }
478: }
479: }
480:
481: /**
482: * render the leader area
483: *
484: * FIXME: Rule style is currently ignored.
485: *
486: * @param area leader area passed from FOP framework
487: */
488:
489: public void renderLeaderArea(LeaderArea area) {
490: flashMovie.addRect(currentPosX, currentPosY, area
491: .getLeaderLength(), area.getRuleThickness(), area
492: .getRed(), area.getGreen(), area.getBlue());
493:
494: this .currentPosX += area.getContentWidth();
495: }
496:
497: /**
498: * Renders all child objects of an area.
499: *
500: * @param area area to render children on
501: */
502:
503: protected void renderChildren(Area area) {
504: Enumeration e = area.getChildren().elements();
505:
506: while (e.hasMoreElements()) {
507: org.apache.fop.layout.Box box = (org.apache.fop.layout.Box) e
508: .nextElement();
509: box.render(this );
510: }
511: }
512:
513: /**
514: * Draws a frame of a area, filled or outlined.
515: *
516: * @param area area to draw frame around
517: */
518:
519: private void drawFrame(Area area) {
520: int x = this .currentACPosX;
521: int y = this .currentPosY;
522: int h = area.getContentHeight();
523: int w = area.getContentWidth();
524:
525: if (area instanceof BlockArea) {
526: x += ((BlockArea) area).getStartIndent();
527: }
528:
529: ColorType bg = area.getBackgroundColor();
530:
531: x = x - area.getPaddingLeft();
532: y = y + area.getPaddingTop();
533: w = w + area.getPaddingLeft() + area.getPaddingRight();
534: h = h + area.getPaddingTop() + area.getPaddingBottom();
535:
536: if ((bg != null) && (bg.alpha() == 0)) {
537: flashMovie.addRect(x, y - h, w, h, bg.red(), bg.green(), bg
538: .blue());
539: }
540:
541: BorderAndPadding bp = area.getBorderAndPadding();
542:
543: if (bp != null) {
544: x = x - area.getBorderLeftWidth();
545: y = y + area.getBorderTopWidth();
546: w = w + area.getBorderLeftWidth()
547: + area.getBorderRightWidth();
548: h = h + area.getBorderTopWidth()
549: + area.getBorderBottomWidth();
550:
551: ColorType borderColor;
552:
553: if (area.getBorderTopWidth() != 0) {
554: borderColor = bp.getBorderColor(BorderAndPadding.TOP);
555:
556: flashMovie.addRect(x, y, w, -area.getBorderTopWidth(),
557: borderColor.red(), borderColor.green(),
558: borderColor.blue());
559: }
560:
561: if (area.getBorderLeftWidth() != 0) {
562: borderColor = bp.getBorderColor(BorderAndPadding.LEFT);
563:
564: flashMovie.addRect(x, y, area.getBorderLeftWidth(), -h,
565: borderColor.red(), borderColor.green(),
566: borderColor.blue());
567: }
568:
569: if (area.getBorderRightWidth() != 0) {
570: borderColor = bp.getBorderColor(BorderAndPadding.RIGHT);
571:
572: flashMovie.addRect(x + w, y, -area
573: .getBorderRightWidth(), -h, borderColor.red(),
574: borderColor.green(), borderColor.blue());
575: }
576:
577: if (area.getBorderBottomWidth() != 0) {
578: borderColor = bp
579: .getBorderColor(BorderAndPadding.BOTTOM);
580:
581: flashMovie.addRect(x, y - h, w, area
582: .getBorderBottomWidth(), borderColor.red(),
583: borderColor.green(), borderColor.blue());
584: }
585: }
586: }
587:
588: // LASZLO
589: public void render(org.apache.fop.layout.AreaTree t,
590: java.io.OutputStream s) {
591: }
592:
593: }
|