Lines 28-33
Link Here
|
28 |
import java.util.Iterator; |
28 |
import java.util.Iterator; |
29 |
import java.util.List; |
29 |
import java.util.List; |
30 |
import java.util.Set; |
30 |
import java.util.Set; |
|
|
31 |
import java.util.Vector; |
31 |
|
32 |
|
32 |
import org.w3c.dom.Document; |
33 |
import org.w3c.dom.Document; |
33 |
|
34 |
|
Lines 68-74
Link Here
|
68 |
import org.apache.fop.area.inline.InlineViewport; |
69 |
import org.apache.fop.area.inline.InlineViewport; |
69 |
import org.apache.fop.area.inline.WordArea; |
70 |
import org.apache.fop.area.inline.WordArea; |
70 |
import org.apache.fop.fo.Constants; |
71 |
import org.apache.fop.fo.Constants; |
|
|
72 |
import org.apache.fop.fo.flow.ChangeBar; |
71 |
import org.apache.fop.fonts.FontInfo; |
73 |
import org.apache.fop.fonts.FontInfo; |
|
|
74 |
import org.apache.fop.traits.BorderProps; |
72 |
|
75 |
|
73 |
/** |
76 |
/** |
74 |
* Abstract base class for all renderers. The Abstract renderer does all the |
77 |
* Abstract base class for all renderers. The Abstract renderer does all the |
Lines 108-113
Link Here
|
108 |
*/ |
111 |
*/ |
109 |
protected int containingIPPosition = 0; |
112 |
protected int containingIPPosition = 0; |
110 |
|
113 |
|
|
|
114 |
/** |
115 |
* The "start edge" IP Position of the current column (for change bars) |
116 |
*/ |
117 |
protected int columnStartIPPosition = 0; |
118 |
|
119 |
/** |
120 |
* The "end edge" IP Position of the current column (for change bars) |
121 |
*/ |
122 |
protected int columnEndIPPosition = 0; |
123 |
|
124 |
/** |
125 |
* The "left" position of the current column (for change bars) |
126 |
*/ |
127 |
protected int columnLeftIPPosition = 0; |
128 |
|
129 |
/** |
130 |
* The "right" position of the current column (for change bars) |
131 |
*/ |
132 |
protected int columnRightIPPosition = 0; |
133 |
|
134 |
/** |
135 |
* The number of columns in the span (for change bars) |
136 |
*/ |
137 |
protected int columnCount = 0; |
138 |
|
139 |
/** |
140 |
* The index number of the current column (for change bars) |
141 |
*/ |
142 |
protected int columnNumber = 0; |
143 |
|
144 |
/** |
145 |
* Is binding on start edge of column? |
146 |
*/ |
147 |
protected boolean bindingOnStartEdge = false; |
148 |
|
149 |
/** |
150 |
* Is binding on end edge of column? |
151 |
*/ |
152 |
protected boolean bindingOnEndEdge = false; |
153 |
|
154 |
/** |
155 |
* The IP begin offset of coordinate 0 |
156 |
*/ |
157 |
private int beginOffset = 0; |
158 |
|
111 |
/** the currently active PageViewport */ |
159 |
/** the currently active PageViewport */ |
112 |
protected PageViewport currentPageViewport; |
160 |
protected PageViewport currentPageViewport; |
113 |
|
161 |
|
Lines 405-414
Link Here
|
405 |
int saveSpanBPPos = saveBPPos; |
453 |
int saveSpanBPPos = saveBPPos; |
406 |
for (int count = 0; count < spans.size(); count++) { |
454 |
for (int count = 0; count < spans.size(); count++) { |
407 |
span = (Span) spans.get(count); |
455 |
span = (Span) spans.get(count); |
|
|
456 |
columnCount = span.getColumnCount(); |
457 |
|
408 |
for (int c = 0; c < span.getColumnCount(); c++) { |
458 |
for (int c = 0; c < span.getColumnCount(); c++) { |
|
|
459 |
columnNumber = c; |
460 |
|
409 |
NormalFlow flow = span.getNormalFlow(c); |
461 |
NormalFlow flow = span.getNormalFlow(c); |
410 |
|
462 |
|
|
|
463 |
int writingMode = mr.getParent().getWritingMode(); |
464 |
int referenceOrientation = mr.getParent().getReferenceOrientation(); |
465 |
|
466 |
|
467 |
|
411 |
if (flow != null) { |
468 |
if (flow != null) { |
|
|
469 |
columnStartIPPosition = currentIPPosition; |
470 |
columnEndIPPosition = currentIPPosition + flow.getIPD() + mr.getColumnGap(); |
471 |
|
472 |
// if direction is right to left, then end is left, else end is right edge |
473 |
// if orientation is portrait, then binding edge is on left edge for odd pages |
474 |
// and on right edge for even pages |
475 |
int pageIndex = currentPageViewport.getPageIndex(); |
476 |
CTM trans = currentPageViewport.getBodyRegion().getCTM(); |
477 |
|
478 |
bindingOnStartEdge = false; |
479 |
bindingOnEndEdge = false; |
480 |
|
481 |
if (writingMode == Constants.EN_RL_TB) { |
482 |
columnLeftIPPosition = columnEndIPPosition; |
483 |
columnRightIPPosition = columnStartIPPosition; |
484 |
if (0 == referenceOrientation) { |
485 |
if (pageIndex % 2 == 0 ) { |
486 |
bindingOnEndEdge = true; |
487 |
} |
488 |
else { |
489 |
bindingOnStartEdge = true; |
490 |
} |
491 |
} |
492 |
} |
493 |
else { |
494 |
columnLeftIPPosition = columnStartIPPosition; |
495 |
columnRightIPPosition = columnEndIPPosition; |
496 |
if (0 == referenceOrientation) { |
497 |
if (pageIndex % 2 == 0 ) { |
498 |
bindingOnStartEdge = true; |
499 |
} |
500 |
else { |
501 |
bindingOnEndEdge = true; |
502 |
} |
503 |
} |
504 |
} |
505 |
|
506 |
|
507 |
|
508 |
|
509 |
|
412 |
currentBPPosition = saveSpanBPPos; |
510 |
currentBPPosition = saveSpanBPPos; |
413 |
renderFlow(flow); |
511 |
renderFlow(flow); |
414 |
currentIPPosition += flow.getIPD(); |
512 |
currentIPPosition += flow.getIPD(); |
Lines 557-562
Link Here
|
557 |
* @param block The block area |
655 |
* @param block The block area |
558 |
*/ |
656 |
*/ |
559 |
protected void renderBlock(Block block) { |
657 |
protected void renderBlock(Block block) { |
|
|
658 |
Vector changeBars = block.getChangeBars(); |
659 |
|
660 |
if (null != changeBars && !changeBars.isEmpty()) { |
661 |
// this block has change bars attached to it |
662 |
int saveIP = currentIPPosition; |
663 |
int saveBP = currentBPPosition; |
664 |
|
665 |
drawChangeBars(block, changeBars); |
666 |
|
667 |
currentIPPosition = saveIP; |
668 |
currentBPPosition = saveBP; |
669 |
} |
670 |
|
560 |
List children = block.getChildAreas(); |
671 |
List children = block.getChildAreas(); |
561 |
if (block instanceof BlockViewport) { |
672 |
if (block instanceof BlockViewport) { |
562 |
if (children != null) { |
673 |
if (children != null) { |
Lines 618-623
Link Here
|
618 |
* @param inlineArea inline area text to render |
729 |
* @param inlineArea inline area text to render |
619 |
*/ |
730 |
*/ |
620 |
protected void renderInlineArea(InlineArea inlineArea) { |
731 |
protected void renderInlineArea(InlineArea inlineArea) { |
|
|
732 |
Vector changeBars = inlineArea.getChangeBars(); |
733 |
|
734 |
if (null != changeBars && !changeBars.isEmpty()) { |
735 |
// area has change bar, handle |
736 |
drawChangeBars(inlineArea, changeBars); |
737 |
} |
738 |
|
621 |
if (inlineArea instanceof TextArea) { |
739 |
if (inlineArea instanceof TextArea) { |
622 |
renderText((TextArea) inlineArea); |
740 |
renderText((TextArea) inlineArea); |
623 |
//} else if (inlineArea instanceof Character) { |
741 |
//} else if (inlineArea instanceof Character) { |
Lines 673-678
Link Here
|
673 |
* @param text the text to render |
791 |
* @param text the text to render |
674 |
*/ |
792 |
*/ |
675 |
protected void renderText(TextArea text) { |
793 |
protected void renderText(TextArea text) { |
|
|
794 |
Vector changeBars = text.getChangeBars(); |
795 |
|
796 |
if (null != changeBars && !changeBars.isEmpty()) { |
797 |
// this block has change bars attached to it |
798 |
int saveIP = currentIPPosition; |
799 |
int saveBP = currentBPPosition; |
800 |
|
801 |
drawChangeBars(text, changeBars); |
802 |
|
803 |
currentIPPosition = saveIP; |
804 |
currentBPPosition = saveBP; |
805 |
} |
806 |
|
676 |
int saveIP = currentIPPosition; |
807 |
int saveIP = currentIPPosition; |
677 |
int saveBP = currentBPPosition; |
808 |
int saveBP = currentBPPosition; |
678 |
Iterator iter = text.getChildAreas().iterator(); |
809 |
Iterator iter = text.getChildAreas().iterator(); |
Lines 760-765
Link Here
|
760 |
* (todo) Make renderImage() protected |
891 |
* (todo) Make renderImage() protected |
761 |
*/ |
892 |
*/ |
762 |
public void renderImage(Image image, Rectangle2D pos) { |
893 |
public void renderImage(Image image, Rectangle2D pos) { |
|
|
894 |
// handle change bars |
895 |
Vector changeBars = image.getChangeBars(); |
896 |
|
897 |
if (null != changeBars && !changeBars.isEmpty()) { |
898 |
drawChangeBars(image, changeBars); |
899 |
} |
763 |
// Default: do nothing. |
900 |
// Default: do nothing. |
764 |
// Some renderers (ex. Text) don't support images. |
901 |
// Some renderers (ex. Text) don't support images. |
765 |
} |
902 |
} |
Lines 786-791
Link Here
|
786 |
* (todo) Make renderForeignObject() protected |
923 |
* (todo) Make renderForeignObject() protected |
787 |
*/ |
924 |
*/ |
788 |
protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) { |
925 |
protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) { |
|
|
926 |
// handle change bars |
927 |
Vector changeBars = fo.getChangeBars(); |
928 |
|
929 |
if (null != changeBars && !changeBars.isEmpty()) { |
930 |
drawChangeBars(fo, changeBars); |
931 |
} |
932 |
|
789 |
// Default: do nothing. |
933 |
// Default: do nothing. |
790 |
// Some renderers (ex. Text) don't support foreign objects. |
934 |
// Some renderers (ex. Text) don't support foreign objects. |
791 |
} |
935 |
} |
Lines 858-861
Link Here
|
858 |
matrix[5] = Math.round(matrix[5] * 1000); |
1002 |
matrix[5] = Math.round(matrix[5] * 1000); |
859 |
return new AffineTransform(matrix); |
1003 |
return new AffineTransform(matrix); |
860 |
} |
1004 |
} |
|
|
1005 |
|
1006 |
/** |
1007 |
* Draw all change bars associated with an area |
1008 |
* |
1009 |
* @param block The area to draw change bars for |
1010 |
* @param changeBars The list of change bars affecting the area |
1011 |
*/ |
1012 |
private void drawChangeBars(Area block, Vector changeBars) { |
1013 |
Block cbArea; |
1014 |
|
1015 |
int saveIP = currentIPPosition; |
1016 |
int saveBP = currentBPPosition; |
1017 |
|
1018 |
for (int idx = 0; idx < changeBars.size(); idx++) { |
1019 |
ChangeBar bar = (ChangeBar)changeBars.get(idx); |
1020 |
cbArea = new Block(); |
1021 |
|
1022 |
currentIPPosition = 0; |
1023 |
currentBPPosition = saveBP; |
1024 |
|
1025 |
// offset by default is negative width for change bars placed on the start edge |
1026 |
// this will be overriden if placement is at the end edge |
1027 |
// xScale is for adding or subtracting the offset of the change bar depending on |
1028 |
// placing the bar towards or away from the edge it is bound to |
1029 |
int xOffset = -bar.getWidth().getValue(); |
1030 |
int xScale = 1; |
1031 |
|
1032 |
// determine currentIPPosition based on placement |
1033 |
switch (bar.getPlacement()) { |
1034 |
case EN_START: |
1035 |
xOffset += columnStartIPPosition; |
1036 |
xScale = -1; |
1037 |
break; |
1038 |
case EN_END: |
1039 |
xOffset = columnEndIPPosition; |
1040 |
break; |
1041 |
case EN_LEFT: |
1042 |
xOffset += columnLeftIPPosition; |
1043 |
xScale = -1; |
1044 |
break; |
1045 |
case EN_RIGHT: |
1046 |
xOffset = columnRightIPPosition; |
1047 |
break; |
1048 |
case EN_INSIDE: |
1049 |
if (bindingOnStartEdge) { |
1050 |
xOffset += columnStartIPPosition; |
1051 |
xScale = -1; |
1052 |
} |
1053 |
else if (bindingOnEndEdge) { |
1054 |
xOffset = columnEndIPPosition; |
1055 |
} |
1056 |
else { |
1057 |
xOffset += columnStartIPPosition; |
1058 |
xScale = -1; |
1059 |
} |
1060 |
break; |
1061 |
case EN_OUTSIDE: |
1062 |
if (bindingOnStartEdge) { |
1063 |
xOffset = columnEndIPPosition; |
1064 |
} |
1065 |
else if (bindingOnEndEdge) { |
1066 |
xOffset += columnStartIPPosition; |
1067 |
xScale = -1; |
1068 |
} |
1069 |
else { |
1070 |
xOffset += columnStartIPPosition; |
1071 |
xScale = -1; |
1072 |
} |
1073 |
break; |
1074 |
case EN_ALTERNATE: |
1075 |
if (2 == columnCount) { |
1076 |
if ( 0 == columnNumber) { |
1077 |
xOffset += columnStartIPPosition; |
1078 |
xScale = -1; |
1079 |
} |
1080 |
else { |
1081 |
xOffset = columnEndIPPosition; |
1082 |
} |
1083 |
} |
1084 |
else { |
1085 |
if (bindingOnStartEdge) { |
1086 |
xOffset = columnEndIPPosition; |
1087 |
} |
1088 |
else if (bindingOnEndEdge) { |
1089 |
xOffset += columnStartIPPosition; |
1090 |
xScale = -1; |
1091 |
} |
1092 |
else { |
1093 |
xOffset = columnStartIPPosition; |
1094 |
xScale = -1; |
1095 |
} |
1096 |
} |
1097 |
break; |
1098 |
default: |
1099 |
break; |
1100 |
} |
1101 |
|
1102 |
xOffset += getBeginOffset(); |
1103 |
|
1104 |
// Change bar area has 0 ipd, class xsl-absolute, no margin or padding |
1105 |
cbArea.setAreaClass(Area.CLASS_ABSOLUTE); |
1106 |
cbArea.setIPD(0); |
1107 |
cbArea.setPositioning(Block.ABSOLUTE); |
1108 |
cbArea.setBPD(block.getBPD()); |
1109 |
BorderProps props = new BorderProps(bar.getStyle(), bar.getWidth().getValue(), |
1110 |
bar.getColor(), BorderProps.SEPARATE); |
1111 |
|
1112 |
cbArea.addTrait(Trait.BORDER_END, props); |
1113 |
|
1114 |
cbArea.setXOffset(xOffset + xScale * bar.getOffset().getValue()); |
1115 |
cbArea.setYOffset(block.getSpaceBefore()); |
1116 |
|
1117 |
renderBlock(cbArea); |
1118 |
|
1119 |
// restore position on page |
1120 |
currentIPPosition = saveIP; |
1121 |
currentBPPosition = saveBP; |
1122 |
|
1123 |
} |
1124 |
} |
1125 |
|
1126 |
/** |
1127 |
* return the begin offset of the inline begin (changes by reference area transforms) |
1128 |
* @return the offset from current coordinate system 0 that the IP begin is at |
1129 |
*/ |
1130 |
protected int getBeginOffset() { |
1131 |
return beginOffset; |
1132 |
} |
1133 |
|
1134 |
/** |
1135 |
* Set the begin offset for inline progression begin (changes by reference area tranforms) |
1136 |
* @param offset the new offset from IPP 0 that true IP start is at |
1137 |
*/ |
1138 |
protected void setBeginOffset(int offset) { |
1139 |
beginOffset = offset; |
1140 |
} |
1141 |
|
861 |
} |
1142 |
} |