Lines 28-33
Link Here
|
28 |
import java.util.List; |
28 |
import java.util.List; |
29 |
import java.util.Locale; |
29 |
import java.util.Locale; |
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 69-75
Link Here
|
69 |
import org.apache.fop.area.inline.TextArea; |
70 |
import org.apache.fop.area.inline.TextArea; |
70 |
import org.apache.fop.area.inline.WordArea; |
71 |
import org.apache.fop.area.inline.WordArea; |
71 |
import org.apache.fop.fo.Constants; |
72 |
import org.apache.fop.fo.Constants; |
|
|
73 |
import org.apache.fop.fo.flow.ChangeBar; |
72 |
import org.apache.fop.fonts.FontInfo; |
74 |
import org.apache.fop.fonts.FontInfo; |
|
|
75 |
import org.apache.fop.traits.BorderProps; |
76 |
import org.apache.fop.traits.WritingMode; |
73 |
|
77 |
|
74 |
/** |
78 |
/** |
75 |
* Abstract base class for all renderers. The Abstract renderer does all the |
79 |
* Abstract base class for all renderers. The Abstract renderer does all the |
Lines 109-114
Link Here
|
109 |
*/ |
113 |
*/ |
110 |
protected int containingIPPosition = 0; |
114 |
protected int containingIPPosition = 0; |
111 |
|
115 |
|
|
|
116 |
/** |
117 |
* The "start edge" IP Position of the current column (for change bars) |
118 |
*/ |
119 |
protected int columnStartIPPosition = 0; |
120 |
|
121 |
/** |
122 |
* The "end edge" IP Position of the current column (for change bars) |
123 |
*/ |
124 |
protected int columnEndIPPosition = 0; |
125 |
|
126 |
/** |
127 |
* The "left" position of the current column (for change bars) |
128 |
*/ |
129 |
protected int columnLeftIPPosition = 0; |
130 |
|
131 |
/** |
132 |
* The "right" position of the current column (for change bars) |
133 |
*/ |
134 |
protected int columnRightIPPosition = 0; |
135 |
|
136 |
/** |
137 |
* The number of columns in the span (for change bars) |
138 |
*/ |
139 |
protected int columnCount = 0; |
140 |
|
141 |
/** |
142 |
* The index number of the current column (for change bars) |
143 |
*/ |
144 |
protected int columnNumber = 0; |
145 |
|
146 |
/** |
147 |
* Is binding on start edge of column? |
148 |
*/ |
149 |
protected boolean bindingOnStartEdge = false; |
150 |
|
151 |
/** |
152 |
* Is binding on end edge of column? |
153 |
*/ |
154 |
protected boolean bindingOnEndEdge = false; |
155 |
|
156 |
/** |
157 |
* The IP begin offset of coordinate 0 |
158 |
*/ |
159 |
private int beginOffset = 0; |
160 |
|
112 |
/** the currently active PageViewport */ |
161 |
/** the currently active PageViewport */ |
113 |
protected PageViewport currentPageViewport; |
162 |
protected PageViewport currentPageViewport; |
114 |
|
163 |
|
Lines 409-414
Link Here
|
409 |
int saveIPPos = currentIPPosition; |
458 |
int saveIPPos = currentIPPosition; |
410 |
for (int count = 0; count < spans.size(); count++) { |
459 |
for (int count = 0; count < spans.size(); count++) { |
411 |
span = (Span) spans.get(count); |
460 |
span = (Span) spans.get(count); |
|
|
461 |
columnCount = span.getColumnCount(); |
462 |
|
412 |
int level = span.getBidiLevel(); |
463 |
int level = span.getBidiLevel(); |
413 |
if ( level < 0 ) { |
464 |
if ( level < 0 ) { |
414 |
level = 0; |
465 |
level = 0; |
Lines 418-425
Link Here
|
418 |
currentIPPosition += mr.getColumnGap(); |
469 |
currentIPPosition += mr.getColumnGap(); |
419 |
} |
470 |
} |
420 |
for (int c = 0; c < span.getColumnCount(); c++) { |
471 |
for (int c = 0; c < span.getColumnCount(); c++) { |
|
|
472 |
columnNumber = c; |
473 |
|
421 |
NormalFlow flow = span.getNormalFlow(c); |
474 |
NormalFlow flow = span.getNormalFlow(c); |
|
|
475 |
WritingMode writingMode = mr.getParent().getWritingMode(); |
476 |
int referenceOrientation = mr.getParent().getReferenceOrientation(); |
477 |
|
478 |
|
479 |
|
422 |
if (flow != null) { |
480 |
if (flow != null) { |
|
|
481 |
columnStartIPPosition = currentIPPosition; |
482 |
columnEndIPPosition = currentIPPosition + flow.getIPD() + mr.getColumnGap(); |
483 |
|
484 |
// if direction is right to left, then end is left, else end is right edge |
485 |
// if orientation is portrait, then binding edge is on left edge for odd pages |
486 |
// and on right edge for even pages |
487 |
int pageIndex = currentPageViewport.getPageIndex(); |
488 |
CTM trans = currentPageViewport.getBodyRegion().getCTM(); |
489 |
|
490 |
bindingOnStartEdge = false; |
491 |
bindingOnEndEdge = false; |
492 |
|
493 |
if (writingMode == WritingMode.RL_TB) { |
494 |
columnLeftIPPosition = columnEndIPPosition; |
495 |
columnRightIPPosition = columnStartIPPosition; |
496 |
if (0 == referenceOrientation) { |
497 |
if (pageIndex % 2 == 0 ) { |
498 |
bindingOnEndEdge = true; |
499 |
} else { |
500 |
bindingOnStartEdge = true; |
501 |
} |
502 |
} |
503 |
} else { |
504 |
columnLeftIPPosition = columnStartIPPosition; |
505 |
columnRightIPPosition = columnEndIPPosition; |
506 |
if (0 == referenceOrientation) { |
507 |
if (pageIndex % 2 == 0 ) { |
508 |
bindingOnStartEdge = true; |
509 |
} else { |
510 |
bindingOnEndEdge = true; |
511 |
} |
512 |
} |
513 |
} |
514 |
|
423 |
currentBPPosition = saveSpanBPPos; |
515 |
currentBPPosition = saveSpanBPPos; |
424 |
if ( ( level & 1 ) == 1 ) { |
516 |
if ( ( level & 1 ) == 1 ) { |
425 |
currentIPPosition -= flow.getIPD(); |
517 |
currentIPPosition -= flow.getIPD(); |
Lines 571-576
Link Here
|
571 |
* @param block The block area |
663 |
* @param block The block area |
572 |
*/ |
664 |
*/ |
573 |
protected void renderBlock(Block block) { |
665 |
protected void renderBlock(Block block) { |
|
|
666 |
Vector changeBars = block.getChangeBars(); |
667 |
|
668 |
if (null != changeBars && !changeBars.isEmpty()) { |
669 |
// this block has change bars attached to it |
670 |
int saveIP = currentIPPosition; |
671 |
int saveBP = currentBPPosition; |
672 |
|
673 |
drawChangeBars(block, changeBars); |
674 |
|
675 |
currentIPPosition = saveIP; |
676 |
currentBPPosition = saveBP; |
677 |
} |
678 |
|
574 |
assert block != null; |
679 |
assert block != null; |
575 |
List children = block.getChildAreas(); |
680 |
List children = block.getChildAreas(); |
576 |
if (block instanceof BlockViewport) { |
681 |
if (block instanceof BlockViewport) { |
Lines 660-665
Link Here
|
660 |
* @param inlineArea inline area text to render |
765 |
* @param inlineArea inline area text to render |
661 |
*/ |
766 |
*/ |
662 |
protected void renderInlineArea(InlineArea inlineArea) { |
767 |
protected void renderInlineArea(InlineArea inlineArea) { |
|
|
768 |
Vector changeBars = inlineArea.getChangeBars(); |
769 |
|
770 |
if (null != changeBars && !changeBars.isEmpty()) { |
771 |
// area has change bar, handle |
772 |
drawChangeBars(inlineArea, changeBars); |
773 |
} |
774 |
|
663 |
if (inlineArea instanceof TextArea) { |
775 |
if (inlineArea instanceof TextArea) { |
664 |
renderText((TextArea) inlineArea); |
776 |
renderText((TextArea) inlineArea); |
665 |
//} else if (inlineArea instanceof Character) { |
777 |
//} else if (inlineArea instanceof Character) { |
Lines 715-720
Link Here
|
715 |
* @param text the text to render |
827 |
* @param text the text to render |
716 |
*/ |
828 |
*/ |
717 |
protected void renderText(TextArea text) { |
829 |
protected void renderText(TextArea text) { |
|
|
830 |
Vector changeBars = text.getChangeBars(); |
831 |
|
832 |
if (null != changeBars && !changeBars.isEmpty()) { |
833 |
// this block has change bars attached to it |
834 |
int saveIP = currentIPPosition; |
835 |
int saveBP = currentBPPosition; |
836 |
|
837 |
drawChangeBars(text, changeBars); |
838 |
|
839 |
currentIPPosition = saveIP; |
840 |
currentBPPosition = saveBP; |
841 |
} |
842 |
|
718 |
List children = text.getChildAreas(); |
843 |
List children = text.getChildAreas(); |
719 |
int saveIP = currentIPPosition; |
844 |
int saveIP = currentIPPosition; |
720 |
int saveBP = currentBPPosition; |
845 |
int saveBP = currentBPPosition; |
Lines 833-838
Link Here
|
833 |
* (todo) Make renderImage() protected |
958 |
* (todo) Make renderImage() protected |
834 |
*/ |
959 |
*/ |
835 |
public void renderImage(Image image, Rectangle2D pos) { |
960 |
public void renderImage(Image image, Rectangle2D pos) { |
|
|
961 |
// handle change bars |
962 |
Vector changeBars = image.getChangeBars(); |
963 |
|
964 |
if (null != changeBars && !changeBars.isEmpty()) { |
965 |
drawChangeBars(image, changeBars); |
966 |
} |
836 |
// Default: do nothing. |
967 |
// Default: do nothing. |
837 |
// Some renderers (ex. Text) don't support images. |
968 |
// Some renderers (ex. Text) don't support images. |
838 |
} |
969 |
} |
Lines 859-864
Link Here
|
859 |
* (todo) Make renderForeignObject() protected |
990 |
* (todo) Make renderForeignObject() protected |
860 |
*/ |
991 |
*/ |
861 |
protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) { |
992 |
protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) { |
|
|
993 |
// handle change bars |
994 |
Vector changeBars = fo.getChangeBars(); |
995 |
|
996 |
if (null != changeBars && !changeBars.isEmpty()) { |
997 |
drawChangeBars(fo, changeBars); |
998 |
} |
999 |
|
862 |
// Default: do nothing. |
1000 |
// Default: do nothing. |
863 |
// Some renderers (ex. Text) don't support foreign objects. |
1001 |
// Some renderers (ex. Text) don't support foreign objects. |
864 |
} |
1002 |
} |
Lines 931-934
Link Here
|
931 |
matrix[5] = Math.round(matrix[5] * 1000); |
1069 |
matrix[5] = Math.round(matrix[5] * 1000); |
932 |
return new AffineTransform(matrix); |
1070 |
return new AffineTransform(matrix); |
933 |
} |
1071 |
} |
|
|
1072 |
|
1073 |
/** |
1074 |
* Draw all change bars associated with an area |
1075 |
* |
1076 |
* @param block The area to draw change bars for |
1077 |
* @param changeBars The list of change bars affecting the area |
1078 |
*/ |
1079 |
private void drawChangeBars(Area block, Vector changeBars) { |
1080 |
Block cbArea; |
1081 |
|
1082 |
int saveIP = currentIPPosition; |
1083 |
int saveBP = currentBPPosition; |
1084 |
|
1085 |
for (int idx = 0; idx < changeBars.size(); idx++) { |
1086 |
ChangeBar bar = (ChangeBar)changeBars.get(idx); |
1087 |
cbArea = new Block(); |
1088 |
|
1089 |
currentIPPosition = 0; |
1090 |
currentBPPosition = saveBP; |
1091 |
|
1092 |
// offset by default is negative width for change bars placed on the start edge |
1093 |
// this will be overriden if placement is at the end edge |
1094 |
// xScale is for adding or subtracting the offset of the change bar depending on |
1095 |
// placing the bar towards or away from the edge it is bound to |
1096 |
int xOffset = -bar.getWidth().getValue(); |
1097 |
int xScale = 1; |
1098 |
|
1099 |
// determine currentIPPosition based on placement |
1100 |
switch (bar.getPlacement()) { |
1101 |
case EN_START: |
1102 |
xOffset += columnStartIPPosition; |
1103 |
xScale = -1; |
1104 |
break; |
1105 |
case EN_END: |
1106 |
xOffset = columnEndIPPosition; |
1107 |
break; |
1108 |
case EN_LEFT: |
1109 |
xOffset += columnLeftIPPosition; |
1110 |
xScale = -1; |
1111 |
break; |
1112 |
case EN_RIGHT: |
1113 |
xOffset = columnRightIPPosition; |
1114 |
break; |
1115 |
case EN_INSIDE: |
1116 |
if (bindingOnStartEdge) { |
1117 |
xOffset += columnStartIPPosition; |
1118 |
xScale = -1; |
1119 |
} else if (bindingOnEndEdge) { |
1120 |
xOffset = columnEndIPPosition; |
1121 |
} else { |
1122 |
xOffset += columnStartIPPosition; |
1123 |
xScale = -1; |
1124 |
} |
1125 |
break; |
1126 |
case EN_OUTSIDE: |
1127 |
if (bindingOnStartEdge) { |
1128 |
xOffset = columnEndIPPosition; |
1129 |
} else if (bindingOnEndEdge) { |
1130 |
xOffset += columnStartIPPosition; |
1131 |
xScale = -1; |
1132 |
} else { |
1133 |
xOffset += columnStartIPPosition; |
1134 |
xScale = -1; |
1135 |
} |
1136 |
break; |
1137 |
case EN_ALTERNATE: |
1138 |
if (2 == columnCount) { |
1139 |
if ( 0 == columnNumber) { |
1140 |
xOffset += columnStartIPPosition; |
1141 |
xScale = -1; |
1142 |
} else { |
1143 |
xOffset = columnEndIPPosition; |
1144 |
} |
1145 |
} else { |
1146 |
if (bindingOnStartEdge) { |
1147 |
xOffset = columnEndIPPosition; |
1148 |
} else if (bindingOnEndEdge) { |
1149 |
xOffset += columnStartIPPosition; |
1150 |
xScale = -1; |
1151 |
} else { |
1152 |
xOffset = columnStartIPPosition; |
1153 |
xScale = -1; |
1154 |
} |
1155 |
} |
1156 |
break; |
1157 |
default: |
1158 |
break; |
1159 |
} |
1160 |
|
1161 |
xOffset += getBeginOffset(); |
1162 |
|
1163 |
// Change bar area has 0 ipd, class xsl-absolute, no margin or padding |
1164 |
cbArea.setAreaClass(Area.CLASS_ABSOLUTE); |
1165 |
cbArea.setIPD(0); |
1166 |
cbArea.setPositioning(Block.ABSOLUTE); |
1167 |
cbArea.setBPD(block.getAllocBPD()); |
1168 |
|
1169 |
BorderProps props = new BorderProps(bar.getStyle(), bar.getWidth().getValue(), |
1170 |
bar.getColor(), BorderProps.SEPARATE); |
1171 |
|
1172 |
cbArea.addTrait(Trait.BORDER_END, props); |
1173 |
|
1174 |
cbArea.setXOffset(xOffset + xScale * bar.getOffset().getValue()); |
1175 |
cbArea.setYOffset(block.getSpaceBefore()); |
1176 |
|
1177 |
renderBlock(cbArea); |
1178 |
|
1179 |
// restore position on page |
1180 |
currentIPPosition = saveIP; |
1181 |
currentBPPosition = saveBP; |
1182 |
|
1183 |
} |
1184 |
} |
1185 |
|
1186 |
/** |
1187 |
* return the begin offset of the inline begin (changes by reference area transforms) |
1188 |
* @return the offset from current coordinate system 0 that the IP begin is at |
1189 |
*/ |
1190 |
protected int getBeginOffset() { |
1191 |
return beginOffset; |
1192 |
} |
1193 |
|
1194 |
/** |
1195 |
* Set the begin offset for inline progression begin (changes by reference area tranforms) |
1196 |
* @param offset the new offset from IPP 0 that true IP start is at |
1197 |
*/ |
1198 |
protected void setBeginOffset(int offset) { |
1199 |
beginOffset = offset; |
1200 |
} |
1201 |
|
934 |
} |
1202 |
} |