KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > AbstractPathOrientedRenderer


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: AbstractPathOrientedRenderer.java 426576 2006-07-28 15:44:37Z jeremias $ */
19
20 package org.apache.fop.render;
21
22 import java.awt.Color JavaDoc;
23 import java.awt.Rectangle JavaDoc;
24 import java.awt.geom.Rectangle2D JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import org.apache.fop.area.Area;
29 import org.apache.fop.area.Block;
30 import org.apache.fop.area.BlockViewport;
31 import org.apache.fop.area.CTM;
32 import org.apache.fop.area.RegionViewport;
33 import org.apache.fop.area.Trait;
34 import org.apache.fop.area.inline.ForeignObject;
35 import org.apache.fop.area.inline.InlineArea;
36 import org.apache.fop.area.inline.Viewport;
37 import org.apache.fop.fo.Constants;
38 import org.apache.fop.fonts.FontMetrics;
39 import org.apache.fop.image.FopImage;
40 import org.apache.fop.traits.BorderProps;
41 import org.w3c.dom.Document JavaDoc;
42
43 /**
44  * Abstract base class for renderers like PDF and PostScript where many painting operations
45  * follow similar patterns which makes it possible to share some code.
46  */

47 public abstract class AbstractPathOrientedRenderer extends PrintRenderer {
48
49     /**
50      * Handle block traits.
51      * The block could be any sort of block with any positioning
52      * so this should render the traits such as border and background
53      * in its position.
54      *
55      * @param block the block to render the traits
56      */

57     protected void handleBlockTraits(Block block) {
58         int borderPaddingStart = block.getBorderAndPaddingWidthStart();
59         int borderPaddingBefore = block.getBorderAndPaddingWidthBefore();
60         
61         float startx = currentIPPosition / 1000f;
62         float starty = currentBPPosition / 1000f;
63         float width = block.getIPD() / 1000f;
64         float height = block.getBPD() / 1000f;
65
66         /* using start-indent now
67         Integer spaceStart = (Integer) block.getTrait(Trait.SPACE_START);
68         if (spaceStart != null) {
69             startx += spaceStart.floatValue() / 1000f;
70         }*/

71         startx += block.getStartIndent() / 1000f;
72         startx -= block.getBorderAndPaddingWidthStart() / 1000f;
73
74         width += borderPaddingStart / 1000f;
75         width += block.getBorderAndPaddingWidthEnd() / 1000f;
76         height += borderPaddingBefore / 1000f;
77         height += block.getBorderAndPaddingWidthAfter() / 1000f;
78
79         drawBackAndBorders(block, startx, starty,
80             width, height);
81     }
82
83     /**
84      * Handle the traits for a region
85      * This is used to draw the traits for the given page region.
86      * (See Sect. 6.4.1.2 of XSL-FO spec.)
87      * @param region the RegionViewport whose region is to be drawn
88      */

89     protected void handleRegionTraits(RegionViewport region) {
90         Rectangle2D JavaDoc viewArea = region.getViewArea();
91         float startx = (float)(viewArea.getX() / 1000f);
92         float starty = (float)(viewArea.getY() / 1000f);
93         float width = (float)(viewArea.getWidth() / 1000f);
94         float height = (float)(viewArea.getHeight() / 1000f);
95
96         if (region.getRegionReference().getRegionClass() == FO_REGION_BODY) {
97             currentBPPosition = region.getBorderAndPaddingWidthBefore();
98             currentIPPosition = region.getBorderAndPaddingWidthStart();
99         }
100         drawBackAndBorders(region, startx, starty, width, height);
101     }
102
103     
104     /**
105      * Draw the background and borders.
106      * This draws the background and border traits for an area given
107      * the position.
108      *
109      * @param area the area to get the traits from
110      * @param startx the start x position
111      * @param starty the start y position
112      * @param width the width of the area
113      * @param height the height of the area
114      */

115     protected void drawBackAndBorders(Area area,
116                     float startx, float starty,
117                     float width, float height) {
118         // draw background then border
119

120         BorderProps bpsBefore = (BorderProps)area.getTrait(Trait.BORDER_BEFORE);
121         BorderProps bpsAfter = (BorderProps)area.getTrait(Trait.BORDER_AFTER);
122         BorderProps bpsStart = (BorderProps)area.getTrait(Trait.BORDER_START);
123         BorderProps bpsEnd = (BorderProps)area.getTrait(Trait.BORDER_END);
124
125         Trait.Background back;
126         back = (Trait.Background)area.getTrait(Trait.BACKGROUND);
127         if (back != null) {
128             endTextObject();
129
130             //Calculate padding rectangle
131
float sx = startx;
132             float sy = starty;
133             float paddRectWidth = width;
134             float paddRectHeight = height;
135             if (bpsStart != null) {
136                 sx += bpsStart.width / 1000f;
137                 paddRectWidth -= bpsStart.width / 1000f;
138             }
139             if (bpsBefore != null) {
140                 sy += bpsBefore.width / 1000f;
141                 paddRectHeight -= bpsBefore.width / 1000f;
142             }
143             if (bpsEnd != null) {
144                 paddRectWidth -= bpsEnd.width / 1000f;
145             }
146             if (bpsAfter != null) {
147                 paddRectHeight -= bpsAfter.width / 1000f;
148             }
149
150             if (back.getColor() != null) {
151                 updateColor(back.getColor(), true);
152                 fillRect(sx, sy, paddRectWidth, paddRectHeight);
153             }
154             if (back.getFopImage() != null) {
155                 FopImage fopimage = back.getFopImage();
156                 if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) {
157                     saveGraphicsState();
158                     clipRect(sx, sy, paddRectWidth, paddRectHeight);
159                     int horzCount = (int)((paddRectWidth
160                             * 1000 / fopimage.getIntrinsicWidth()) + 1.0f);
161                     int vertCount = (int)((paddRectHeight
162                             * 1000 / fopimage.getIntrinsicHeight()) + 1.0f);
163                     if (back.getRepeat() == EN_NOREPEAT) {
164                         horzCount = 1;
165                         vertCount = 1;
166                     } else if (back.getRepeat() == EN_REPEATX) {
167                         vertCount = 1;
168                     } else if (back.getRepeat() == EN_REPEATY) {
169                         horzCount = 1;
170                     }
171                     //change from points to millipoints
172
sx *= 1000;
173                     sy *= 1000;
174                     if (horzCount == 1) {
175                         sx += back.getHoriz();
176                     }
177                     if (vertCount == 1) {
178                         sy += back.getVertical();
179                     }
180                     for (int x = 0; x < horzCount; x++) {
181                         for (int y = 0; y < vertCount; y++) {
182                             // place once
183
Rectangle2D JavaDoc pos;
184                             // Image positions are relative to the currentIP/BP
185
pos = new Rectangle2D.Float JavaDoc(sx - currentIPPosition
186                                                             + (x * fopimage.getIntrinsicWidth()),
187                                                         sy - currentBPPosition
188                                                             + (y * fopimage.getIntrinsicHeight()),
189                                                         fopimage.getIntrinsicWidth(),
190                                                         fopimage.getIntrinsicHeight());
191                             drawImage(back.getURL(), pos);
192                         }
193                     }
194                     
195                     restoreGraphicsState();
196                 } else {
197                     log.warn("Can't find background image: " + back.getURL());
198                 }
199             }
200         }
201
202         Rectangle2D.Float JavaDoc borderRect = new Rectangle2D.Float JavaDoc(startx, starty, width, height);
203         drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
204     }
205
206     /**
207      * Draws borders.
208      * @param borderRect the border rectangle
209      * @param bpsBefore the border specification on the before side
210      * @param bpsAfter the border specification on the after side
211      * @param bpsStart the border specification on the start side
212      * @param bpsEnd the border specification on the end side
213      */

214     protected void drawBorders(Rectangle2D.Float JavaDoc borderRect,
215             BorderProps bpsBefore, BorderProps bpsAfter, BorderProps bpsStart, BorderProps bpsEnd) {
216         float startx = borderRect.x;
217         float starty = borderRect.y;
218         float width = borderRect.width;
219         float height = borderRect.height;
220         boolean[] b = new boolean[] {
221             (bpsBefore != null), (bpsEnd != null),
222             (bpsAfter != null), (bpsStart != null)};
223         if (!b[0] && !b[1] && !b[2] && !b[3]) {
224             return;
225         }
226         float[] bw = new float[] {
227             (b[0] ? bpsBefore.width / 1000f : 0.0f),
228             (b[1] ? bpsEnd.width / 1000f : 0.0f),
229             (b[2] ? bpsAfter.width / 1000f : 0.0f),
230             (b[3] ? bpsStart.width / 1000f : 0.0f)};
231         float[] clipw = new float[] {
232             BorderProps.getClippedWidth(bpsBefore) / 1000f,
233             BorderProps.getClippedWidth(bpsEnd) / 1000f,
234             BorderProps.getClippedWidth(bpsAfter) / 1000f,
235             BorderProps.getClippedWidth(bpsStart) / 1000f};
236         starty += clipw[0];
237         height -= clipw[0];
238         height -= clipw[2];
239         startx += clipw[3];
240         width -= clipw[3];
241         width -= clipw[1];
242         
243         boolean[] slant = new boolean[] {
244             (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])};
245         if (bpsBefore != null) {
246             endTextObject();
247
248             float sx1 = startx;
249             float sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1);
250             float ex1 = startx + width;
251             float ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1);
252             float outery = starty - clipw[0];
253             float clipy = outery + clipw[0];
254             float innery = outery + bw[0];
255
256             saveGraphicsState();
257             moveTo(sx1, clipy);
258             float sx1a = sx1;
259             float ex1a = ex1;
260             if (bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
261                 if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
262                     sx1a -= clipw[3];
263                 }
264                 if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
265                     ex1a += clipw[1];
266                 }
267                 lineTo(sx1a, outery);
268                 lineTo(ex1a, outery);
269             }
270             lineTo(ex1, clipy);
271             lineTo(ex2, innery);
272             lineTo(sx2, innery);
273             closePath();
274             clip();
275             drawBorderLine(sx1a, outery, ex1a, innery, true, true,
276                     bpsBefore.style, bpsBefore.color);
277             restoreGraphicsState();
278         }
279         if (bpsEnd != null) {
280             endTextObject();
281
282             float sy1 = starty;
283             float sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1);
284             float ey1 = starty + height;
285             float ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1);
286             float outerx = startx + width + clipw[1];
287             float clipx = outerx - clipw[1];
288             float innerx = outerx - bw[1];
289             
290             saveGraphicsState();
291             moveTo(clipx, sy1);
292             float sy1a = sy1;
293             float ey1a = ey1;
294             if (bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
295                 if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
296                     sy1a -= clipw[0];
297                 }
298                 if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
299                     ey1a += clipw[2];
300                 }
301                 lineTo(outerx, sy1a);
302                 lineTo(outerx, ey1a);
303             }
304             lineTo(clipx, ey1);
305             lineTo(innerx, ey2);
306             lineTo(innerx, sy2);
307             closePath();
308             clip();
309             drawBorderLine(innerx, sy1a, outerx, ey1a, false, false, bpsEnd.style, bpsEnd.color);
310             restoreGraphicsState();
311         }
312         if (bpsAfter != null) {
313             endTextObject();
314
315             float sx1 = startx;
316             float sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1);
317             float ex1 = startx + width;
318             float ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1);
319             float outery = starty + height + clipw[2];
320             float clipy = outery - clipw[2];
321             float innery = outery - bw[2];
322
323             saveGraphicsState();
324             moveTo(ex1, clipy);
325             float sx1a = sx1;
326             float ex1a = ex1;
327             if (bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
328                 if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
329                     sx1a -= clipw[3];
330                 }
331                 if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
332                     ex1a += clipw[1];
333                 }
334                 lineTo(ex1a, outery);
335                 lineTo(sx1a, outery);
336             }
337             lineTo(sx1, clipy);
338             lineTo(sx2, innery);
339             lineTo(ex2, innery);
340             closePath();
341             clip();
342             drawBorderLine(sx1a, innery, ex1a, outery, true, false, bpsAfter.style, bpsAfter.color);
343             restoreGraphicsState();
344         }
345         if (bpsStart != null) {
346             endTextObject();
347
348             float sy1 = starty;
349             float sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1);
350             float ey1 = sy1 + height;
351             float ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1);
352             float outerx = startx - clipw[3];
353             float clipx = outerx + clipw[3];
354             float innerx = outerx + bw[3];
355
356             saveGraphicsState();
357             moveTo(clipx, ey1);
358             float sy1a = sy1;
359             float ey1a = ey1;
360             if (bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
361                 if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
362                     sy1a -= clipw[0];
363                 }
364                 if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
365                     ey1a += clipw[2];
366                 }
367                 lineTo(outerx, ey1a);
368                 lineTo(outerx, sy1a);
369             }
370             lineTo(clipx, sy1);
371             lineTo(innerx, sy2);
372             lineTo(innerx, ey2);
373             closePath();
374             clip();
375             drawBorderLine(outerx, sy1a, innerx, ey1a, false, true, bpsStart.style, bpsStart.color);
376             restoreGraphicsState();
377         }
378     }
379     
380     /**
381      * Common method to render the background and borders for any inline area.
382      * The all borders and padding are drawn outside the specified area.
383      * @param area the inline area for which the background, border and padding is to be
384      * rendered
385      */

386     protected void renderInlineAreaBackAndBorders(InlineArea area) {
387         float x = currentIPPosition / 1000f;
388         float y = (currentBPPosition + area.getOffset()) / 1000f;
389         float width = area.getIPD() / 1000f;
390         float height = area.getBPD() / 1000f;
391         float borderPaddingStart = area.getBorderAndPaddingWidthStart() / 1000f;
392         float borderPaddingBefore = area.getBorderAndPaddingWidthBefore() / 1000f;
393         float bpwidth = borderPaddingStart
394                 + (area.getBorderAndPaddingWidthEnd() / 1000f);
395         float bpheight = borderPaddingBefore
396                 + (area.getBorderAndPaddingWidthAfter() / 1000f);
397         
398         if (height != 0.0f || bpheight != 0.0f && bpwidth != 0.0f) {
399             drawBackAndBorders(area, x, y - borderPaddingBefore
400                                 , width + bpwidth
401                                 , height + bpheight);
402         }
403         
404     }
405     
406     /**
407      * @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List)
408      */

409     protected void renderBlockViewport(BlockViewport bv, List JavaDoc children) {
410         // clip and position viewport if necessary
411

412         // save positions
413
int saveIP = currentIPPosition;
414         int saveBP = currentBPPosition;
415         //String saveFontName = currentFontName;
416

417         CTM ctm = bv.getCTM();
418         int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
419         int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
420         float x, y;
421         x = (float)(bv.getXOffset() + containingIPPosition) / 1000f;
422         y = (float)(bv.getYOffset() + containingBPPosition) / 1000f;
423         //This is the content-rect
424
float width = (float)bv.getIPD() / 1000f;
425         float height = (float)bv.getBPD() / 1000f;
426         
427
428         if (bv.getPositioning() == Block.ABSOLUTE
429                 || bv.getPositioning() == Block.FIXED) {
430
431             currentIPPosition = bv.getXOffset();
432             currentBPPosition = bv.getYOffset();
433
434             //For FIXED, we need to break out of the current viewports to the
435
//one established by the page. We save the state stack for restoration
436
//after the block-container has been painted. See below.
437
List JavaDoc breakOutList = null;
438             if (bv.getPositioning() == Block.FIXED) {
439                 breakOutList = breakOutOfStateStack();
440             }
441             
442             CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
443             ctm = tempctm.multiply(ctm);
444
445             //Adjust for spaces (from margin or indirectly by start-indent etc.
446
x += bv.getSpaceStart() / 1000f;
447             currentIPPosition += bv.getSpaceStart();
448             
449             y += bv.getSpaceBefore() / 1000f;
450             currentBPPosition += bv.getSpaceBefore();
451
452             float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f;
453             float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f;
454
455             drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
456
457             //Now adjust for border/padding
458
currentIPPosition += borderPaddingStart;
459             currentBPPosition += borderPaddingBefore;
460             
461             Rectangle2D JavaDoc clippingRect = null;
462             if (bv.getClip()) {
463                 clippingRect = new Rectangle JavaDoc(currentIPPosition, currentBPPosition,
464                         bv.getIPD(), bv.getBPD());
465             }
466
467             startVParea(ctm, clippingRect);
468             currentIPPosition = 0;
469             currentBPPosition = 0;
470             renderBlocks(bv, children);
471             endVParea();
472
473             if (breakOutList != null) {
474                 restoreStateStackAfterBreakOut(breakOutList);
475             }
476             
477             currentIPPosition = saveIP;
478             currentBPPosition = saveBP;
479         } else {
480
481             currentBPPosition += bv.getSpaceBefore();
482
483             //borders and background in the old coordinate system
484
handleBlockTraits(bv);
485
486             //Advance to start of content area
487
currentIPPosition += bv.getStartIndent();
488
489             CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
490             ctm = tempctm.multiply(ctm);
491             
492             //Now adjust for border/padding
493
currentBPPosition += borderPaddingBefore;
494
495             Rectangle2D JavaDoc clippingRect = null;
496             if (bv.getClip()) {
497                 clippingRect = new Rectangle JavaDoc(currentIPPosition, currentBPPosition,
498                         bv.getIPD(), bv.getBPD());
499             }
500             
501             startVParea(ctm, clippingRect);
502             currentIPPosition = 0;
503             currentBPPosition = 0;
504             renderBlocks(bv, children);
505             endVParea();
506
507             currentIPPosition = saveIP;
508             currentBPPosition = saveBP;
509             
510             currentBPPosition += (int)(bv.getAllocBPD());
511         }
512         //currentFontName = saveFontName;
513
}
514
515     /**
516      * Render an inline viewport.
517      * This renders an inline viewport by clipping if necessary.
518      * @param viewport the viewport to handle
519      */

520     public void renderViewport(Viewport viewport) {
521
522         float x = currentIPPosition / 1000f;
523         float y = (currentBPPosition + viewport.getOffset()) / 1000f;
524         float width = viewport.getIPD() / 1000f;
525         float height = viewport.getBPD() / 1000f;
526         // TODO: Calculate the border rect correctly.
527
float borderPaddingStart = viewport.getBorderAndPaddingWidthStart() / 1000f;
528         float borderPaddingBefore = viewport.getBorderAndPaddingWidthBefore() / 1000f;
529         float bpwidth = borderPaddingStart
530                 + (viewport.getBorderAndPaddingWidthEnd() / 1000f);
531         float bpheight = borderPaddingBefore
532                 + (viewport.getBorderAndPaddingWidthAfter() / 1000f);
533
534         drawBackAndBorders(viewport, x, y, width + bpwidth, height + bpheight);
535
536         if (viewport.getClip()) {
537             saveGraphicsState();
538
539             clipRect(x + borderPaddingStart, y + borderPaddingBefore, width, height);
540         }
541         super.renderViewport(viewport);
542
543         if (viewport.getClip()) {
544             restoreGraphicsState();
545         }
546     }
547
548     /**
549      * Restores the state stack after a break out.
550      * @param breakOutList the state stack to restore.
551      */

552     protected abstract void restoreStateStackAfterBreakOut(List JavaDoc breakOutList);
553     
554     /**
555      * Breaks out of the state stack to handle fixed block-containers.
556      * @return the saved state stack to recreate later
557      */

558     protected abstract List JavaDoc breakOutOfStateStack();
559
560     /** Saves the graphics state of the rendering engine. */
561     protected abstract void saveGraphicsState();
562     
563     /** Restores the last graphics state of the rendering engine. */
564     protected abstract void restoreGraphicsState();
565
566     /** Indicates the beginning of a text object. */
567     protected abstract void beginTextObject();
568     
569     /** Indicates the end of a text object. */
570     protected abstract void endTextObject();
571     
572     /**
573      * Paints the text decoration marks.
574      * @param fm Current typeface
575      * @param fontsize Current font size
576      * @param inline inline area to paint the marks for
577      * @param baseline position of the baseline
578      * @param startx start IPD
579      */

580     protected void renderTextDecoration(FontMetrics fm, int fontsize, InlineArea inline,
581                     int baseline, int startx) {
582         boolean hasTextDeco = inline.hasUnderline()
583                 || inline.hasOverline()
584                 || inline.hasLineThrough();
585         if (hasTextDeco) {
586             endTextObject();
587             float descender = fm.getDescender(fontsize) / 1000f;
588             float capHeight = fm.getCapHeight(fontsize) / 1000f;
589             float halfLineWidth = (descender / -8f) / 2f;
590             float endx = (startx + inline.getIPD()) / 1000f;
591             if (inline.hasUnderline()) {
592                 Color JavaDoc ct = (Color JavaDoc) inline.getTrait(Trait.UNDERLINE_COLOR);
593                 float y = baseline - descender / 2f;
594                 drawBorderLine(startx / 1000f, (y - halfLineWidth) / 1000f,
595                         endx, (y + halfLineWidth) / 1000f,
596                         true, true, Constants.EN_SOLID, ct);
597             }
598             if (inline.hasOverline()) {
599                 Color JavaDoc ct = (Color JavaDoc) inline.getTrait(Trait.OVERLINE_COLOR);
600                 float y = (float)(baseline - (1.1 * capHeight));
601                 drawBorderLine(startx / 1000f, (y - halfLineWidth) / 1000f,
602                         endx, (y + halfLineWidth) / 1000f,
603                         true, true, Constants.EN_SOLID, ct);
604             }
605             if (inline.hasLineThrough()) {
606                 Color JavaDoc ct = (Color JavaDoc) inline.getTrait(Trait.LINETHROUGH_COLOR);
607                 float y = (float)(baseline - (0.45 * capHeight));
608                 drawBorderLine(startx / 1000f, (y - halfLineWidth) / 1000f,
609                         endx, (y + halfLineWidth) / 1000f,
610                         true, true, Constants.EN_SOLID, ct);
611             }
612         }
613     }
614
615     /** Clip using the current path. */
616     protected abstract void clip();
617         
618     /**
619      * Clip using a rectangular area.
620      * @param x the x coordinate
621      * @param y the y coordinate
622      * @param width the width of the rectangle
623      * @param height the height of the rectangle
624      */

625     protected abstract void clipRect(float x, float y, float width, float height);
626     
627     /**
628      * Moves the current point to (x, y), omitting any connecting line segment.
629      * @param x x coordinate
630      * @param y y coordinate
631      */

632     protected abstract void moveTo(float x, float y);
633     
634     /**
635      * Appends a straight line segment from the current point to (x, y). The
636      * new current point is (x, y).
637      * @param x x coordinate
638      * @param y y coordinate
639      */

640     protected abstract void lineTo(float x, float y);
641     
642     /**
643      * Closes the current subpath by appending a straight line segment from
644      * the current point to the starting point of the subpath.
645      */

646     protected abstract void closePath();
647     
648     /**
649      * Fill a rectangular area.
650      * @param x the x coordinate
651      * @param y the y coordinate
652      * @param width the width of the rectangle
653      * @param height the height of the rectangle
654      */

655     protected abstract void fillRect(float x, float y, float width, float height);
656
657     /**
658      * Establishes a new foreground or fill color.
659      * @param col the color to apply (null skips this operation)
660      * @param fill true to set the fill color, false for the foreground color
661      */

662     protected abstract void updateColor(Color JavaDoc col, boolean fill);
663     
664     /**
665      * Draw an image at the indicated location.
666      * @param url the URI/URL of the image
667      * @param pos the position of the image
668      * @param foreignAttributes an optional Map with foreign attributes, may be null
669      */

670     protected abstract void drawImage(String JavaDoc url, Rectangle2D JavaDoc pos, Map JavaDoc foreignAttributes);
671     
672     /**
673      * Draw an image at the indicated location.
674      * @param url the URI/URL of the image
675      * @param pos the position of the image
676      */

677     protected final void drawImage(String JavaDoc url, Rectangle2D JavaDoc pos) {
678         drawImage(url, pos, null);
679     }
680     
681     /**
682      * Draw a border segment of an XSL-FO style border.
683      * @param x1 starting x coordinate
684      * @param y1 starting y coordinate
685      * @param x2 ending x coordinate
686      * @param y2 ending y coordinate
687      * @param horz true for horizontal border segments, false for vertical border segments
688      * @param startOrBefore true for border segments on the start or before edge,
689      * false for end or after.
690      * @param style the border style (one of Constants.EN_DASHED etc.)
691      * @param col the color for the border segment
692      */

693     protected abstract void drawBorderLine(float x1, float y1, float x2, float y2,
694             boolean horz, boolean startOrBefore, int style, Color JavaDoc col);
695
696     /**
697      * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D)
698      */

699     public void renderForeignObject(ForeignObject fo, Rectangle2D JavaDoc pos) {
700         endTextObject();
701         Document JavaDoc doc = fo.getDocument();
702         String JavaDoc ns = fo.getNameSpace();
703         renderDocument(doc, ns, pos, fo.getForeignAttributes());
704     }
705     
706 }
707
Popular Tags