Lines 17-27
Link Here
|
17 |
|
17 |
|
18 |
package org.apache.poi.hssf.record; |
18 |
package org.apache.poi.hssf.record; |
19 |
|
19 |
|
20 |
import java.util.ArrayList; |
20 |
import java.io.ByteArrayOutputStream; |
21 |
import java.util.HashMap; |
21 |
import java.io.IOException; |
22 |
import java.util.Iterator; |
22 |
import java.util.*; |
23 |
import java.util.List; |
|
|
24 |
import java.util.Map; |
25 |
|
23 |
|
26 |
import org.apache.poi.ddf.DefaultEscherRecordFactory; |
24 |
import org.apache.poi.ddf.DefaultEscherRecordFactory; |
27 |
import org.apache.poi.ddf.EscherBoolProperty; |
25 |
import org.apache.poi.ddf.EscherBoolProperty; |
Lines 65-948
Link Here
|
65 |
* combination of MSODRAWING -> OBJ -> MSODRAWING -> OBJ records |
63 |
* combination of MSODRAWING -> OBJ -> MSODRAWING -> OBJ records |
66 |
* but the escher records are serialized _across_ the MSODRAWING |
64 |
* but the escher records are serialized _across_ the MSODRAWING |
67 |
* records. |
65 |
* records. |
68 |
* <p> |
66 |
* <p/> |
69 |
* It gets even worse when you start looking at TXO records. |
67 |
* It gets even worse when you start looking at TXO records. |
70 |
* <p> |
68 |
* <p/> |
71 |
* So what we do with this class is aggregate lazily. That is |
69 |
* So what we do with this class is aggregate lazily. That is |
72 |
* we don't aggregate the MSODRAWING -> OBJ records unless we |
70 |
* we don't aggregate the MSODRAWING -> OBJ records unless we |
73 |
* need to modify them. |
71 |
* need to modify them. |
|
|
72 |
* <p/> |
73 |
* At first document contains 4 types of records which belong to drawing layer. |
74 |
* There are can be such sequence of record: |
75 |
* <p/> |
76 |
* DrawingRecord |
77 |
* ContinueRecord |
78 |
* ... |
79 |
* ContinueRecord |
80 |
* ObjRecord | TextObjectRecord |
81 |
* ..... |
82 |
* ContinueRecord |
83 |
* ... |
84 |
* ContinueRecord |
85 |
* ObjRecord | TextObjectRecord |
86 |
* NoteRecord |
87 |
* ... |
88 |
* NoteRecord |
89 |
* <p/> |
90 |
* To work with shapes we have to read data from Drawing and Continue records into single array of bytes and |
91 |
* build escher(office art) records tree from this array. |
92 |
* Each shape in drawing layer matches corresponding ObjRecord |
93 |
* Each textbox matches corresponding TextObjectRecord |
74 |
* |
94 |
* |
|
|
95 |
* ObjRecord contains information about shape. Thus each ObjRecord corresponds EscherContainerRecord(SPGR) |
75 |
* |
96 |
* |
|
|
97 |
* EscherAggrefate contains also NoteRecords |
98 |
* NoteRecords must be serial |
99 |
* |
76 |
* @author Glen Stampoultzis (glens at apache.org) |
100 |
* @author Glen Stampoultzis (glens at apache.org) |
77 |
*/ |
101 |
*/ |
|
|
102 |
|
78 |
public final class EscherAggregate extends AbstractEscherHolderRecord { |
103 |
public final class EscherAggregate extends AbstractEscherHolderRecord { |
79 |
public static final short sid = 9876; // not a real sid - dummy value |
104 |
public static final short sid = 9876; // not a real sid - dummy value |
80 |
private static POILogger log = POILogFactory.getLogger(EscherAggregate.class); |
105 |
private static POILogger log = POILogFactory.getLogger(EscherAggregate.class); |
81 |
|
106 |
|
82 |
public static final short ST_MIN = (short) 0; |
107 |
public static final short ST_MIN = (short) 0; |
83 |
public static final short ST_NOT_PRIMATIVE = ST_MIN; |
108 |
public static final short ST_NOT_PRIMATIVE = ST_MIN; |
84 |
public static final short ST_RECTANGLE = (short) 1; |
109 |
public static final short ST_RECTANGLE = (short) 1; |
85 |
public static final short ST_ROUNDRECTANGLE = (short) 2; |
110 |
public static final short ST_ROUNDRECTANGLE = (short) 2; |
86 |
public static final short ST_ELLIPSE = (short) 3; |
111 |
public static final short ST_ELLIPSE = (short) 3; |
87 |
public static final short ST_DIAMOND = (short) 4; |
112 |
public static final short ST_DIAMOND = (short) 4; |
88 |
public static final short ST_ISOCELESTRIANGLE = (short) 5; |
113 |
public static final short ST_ISOCELESTRIANGLE = (short) 5; |
89 |
public static final short ST_RIGHTTRIANGLE = (short) 6; |
114 |
public static final short ST_RIGHTTRIANGLE = (short) 6; |
90 |
public static final short ST_PARALLELOGRAM = (short) 7; |
115 |
public static final short ST_PARALLELOGRAM = (short) 7; |
91 |
public static final short ST_TRAPEZOID = (short) 8; |
116 |
public static final short ST_TRAPEZOID = (short) 8; |
92 |
public static final short ST_HEXAGON = (short) 9; |
117 |
public static final short ST_HEXAGON = (short) 9; |
93 |
public static final short ST_OCTAGON = (short) 10; |
118 |
public static final short ST_OCTAGON = (short) 10; |
94 |
public static final short ST_PLUS = (short) 11; |
119 |
public static final short ST_PLUS = (short) 11; |
95 |
public static final short ST_STAR = (short) 12; |
120 |
public static final short ST_STAR = (short) 12; |
96 |
public static final short ST_ARROW = (short) 13; |
121 |
public static final short ST_ARROW = (short) 13; |
97 |
public static final short ST_THICKARROW = (short) 14; |
122 |
public static final short ST_THICKARROW = (short) 14; |
98 |
public static final short ST_HOMEPLATE = (short) 15; |
123 |
public static final short ST_HOMEPLATE = (short) 15; |
99 |
public static final short ST_CUBE = (short) 16; |
124 |
public static final short ST_CUBE = (short) 16; |
100 |
public static final short ST_BALLOON = (short) 17; |
125 |
public static final short ST_BALLOON = (short) 17; |
101 |
public static final short ST_SEAL = (short) 18; |
126 |
public static final short ST_SEAL = (short) 18; |
102 |
public static final short ST_ARC = (short) 19; |
127 |
public static final short ST_ARC = (short) 19; |
103 |
public static final short ST_LINE = (short) 20; |
128 |
public static final short ST_LINE = (short) 20; |
104 |
public static final short ST_PLAQUE = (short) 21; |
129 |
public static final short ST_PLAQUE = (short) 21; |
105 |
public static final short ST_CAN = (short) 22; |
130 |
public static final short ST_CAN = (short) 22; |
106 |
public static final short ST_DONUT = (short) 23; |
131 |
public static final short ST_DONUT = (short) 23; |
107 |
public static final short ST_TEXTSIMPLE = (short) 24; |
132 |
public static final short ST_TEXTSIMPLE = (short) 24; |
108 |
public static final short ST_TEXTOCTAGON = (short) 25; |
133 |
public static final short ST_TEXTOCTAGON = (short) 25; |
109 |
public static final short ST_TEXTHEXAGON = (short) 26; |
134 |
public static final short ST_TEXTHEXAGON = (short) 26; |
110 |
public static final short ST_TEXTCURVE = (short) 27; |
135 |
public static final short ST_TEXTCURVE = (short) 27; |
111 |
public static final short ST_TEXTWAVE = (short) 28; |
136 |
public static final short ST_TEXTWAVE = (short) 28; |
112 |
public static final short ST_TEXTRING = (short) 29; |
137 |
public static final short ST_TEXTRING = (short) 29; |
113 |
public static final short ST_TEXTONCURVE = (short) 30; |
138 |
public static final short ST_TEXTONCURVE = (short) 30; |
114 |
public static final short ST_TEXTONRING = (short) 31; |
139 |
public static final short ST_TEXTONRING = (short) 31; |
115 |
public static final short ST_STRAIGHTCONNECTOR1 = (short) 32; |
140 |
public static final short ST_STRAIGHTCONNECTOR1 = (short) 32; |
116 |
public static final short ST_BENTCONNECTOR2 = (short) 33; |
141 |
public static final short ST_BENTCONNECTOR2 = (short) 33; |
117 |
public static final short ST_BENTCONNECTOR3 = (short) 34; |
142 |
public static final short ST_BENTCONNECTOR3 = (short) 34; |
118 |
public static final short ST_BENTCONNECTOR4 = (short) 35; |
143 |
public static final short ST_BENTCONNECTOR4 = (short) 35; |
119 |
public static final short ST_BENTCONNECTOR5 = (short) 36; |
144 |
public static final short ST_BENTCONNECTOR5 = (short) 36; |
120 |
public static final short ST_CURVEDCONNECTOR2 = (short) 37; |
145 |
public static final short ST_CURVEDCONNECTOR2 = (short) 37; |
121 |
public static final short ST_CURVEDCONNECTOR3 = (short) 38; |
146 |
public static final short ST_CURVEDCONNECTOR3 = (short) 38; |
122 |
public static final short ST_CURVEDCONNECTOR4 = (short) 39; |
147 |
public static final short ST_CURVEDCONNECTOR4 = (short) 39; |
123 |
public static final short ST_CURVEDCONNECTOR5 = (short) 40; |
148 |
public static final short ST_CURVEDCONNECTOR5 = (short) 40; |
124 |
public static final short ST_CALLOUT1 = (short) 41; |
149 |
public static final short ST_CALLOUT1 = (short) 41; |
125 |
public static final short ST_CALLOUT2 = (short) 42; |
150 |
public static final short ST_CALLOUT2 = (short) 42; |
126 |
public static final short ST_CALLOUT3 = (short) 43; |
151 |
public static final short ST_CALLOUT3 = (short) 43; |
127 |
public static final short ST_ACCENTCALLOUT1 = (short) 44; |
152 |
public static final short ST_ACCENTCALLOUT1 = (short) 44; |
128 |
public static final short ST_ACCENTCALLOUT2 = (short) 45; |
153 |
public static final short ST_ACCENTCALLOUT2 = (short) 45; |
129 |
public static final short ST_ACCENTCALLOUT3 = (short) 46; |
154 |
public static final short ST_ACCENTCALLOUT3 = (short) 46; |
130 |
public static final short ST_BORDERCALLOUT1 = (short) 47; |
155 |
public static final short ST_BORDERCALLOUT1 = (short) 47; |
131 |
public static final short ST_BORDERCALLOUT2 = (short) 48; |
156 |
public static final short ST_BORDERCALLOUT2 = (short) 48; |
132 |
public static final short ST_BORDERCALLOUT3 = (short) 49; |
157 |
public static final short ST_BORDERCALLOUT3 = (short) 49; |
133 |
public static final short ST_ACCENTBORDERCALLOUT1 = (short) 50; |
158 |
public static final short ST_ACCENTBORDERCALLOUT1 = (short) 50; |
134 |
public static final short ST_ACCENTBORDERCALLOUT2 = (short) 51; |
159 |
public static final short ST_ACCENTBORDERCALLOUT2 = (short) 51; |
135 |
public static final short ST_ACCENTBORDERCALLOUT3 = (short) 52; |
160 |
public static final short ST_ACCENTBORDERCALLOUT3 = (short) 52; |
136 |
public static final short ST_RIBBON = (short) 53; |
161 |
public static final short ST_RIBBON = (short) 53; |
137 |
public static final short ST_RIBBON2 = (short) 54; |
162 |
public static final short ST_RIBBON2 = (short) 54; |
138 |
public static final short ST_CHEVRON = (short) 55; |
163 |
public static final short ST_CHEVRON = (short) 55; |
139 |
public static final short ST_PENTAGON = (short) 56; |
164 |
public static final short ST_PENTAGON = (short) 56; |
140 |
public static final short ST_NOSMOKING = (short) 57; |
165 |
public static final short ST_NOSMOKING = (short) 57; |
141 |
public static final short ST_SEAL8 = (short) 58; |
166 |
public static final short ST_SEAL8 = (short) 58; |
142 |
public static final short ST_SEAL16 = (short) 59; |
167 |
public static final short ST_SEAL16 = (short) 59; |
143 |
public static final short ST_SEAL32 = (short) 60; |
168 |
public static final short ST_SEAL32 = (short) 60; |
144 |
public static final short ST_WEDGERECTCALLOUT = (short) 61; |
169 |
public static final short ST_WEDGERECTCALLOUT = (short) 61; |
145 |
public static final short ST_WEDGERRECTCALLOUT = (short) 62; |
170 |
public static final short ST_WEDGERRECTCALLOUT = (short) 62; |
146 |
public static final short ST_WEDGEELLIPSECALLOUT = (short) 63; |
171 |
public static final short ST_WEDGEELLIPSECALLOUT = (short) 63; |
147 |
public static final short ST_WAVE = (short) 64; |
172 |
public static final short ST_WAVE = (short) 64; |
148 |
public static final short ST_FOLDEDCORNER = (short) 65; |
173 |
public static final short ST_FOLDEDCORNER = (short) 65; |
149 |
public static final short ST_LEFTARROW = (short) 66; |
174 |
public static final short ST_LEFTARROW = (short) 66; |
150 |
public static final short ST_DOWNARROW = (short) 67; |
175 |
public static final short ST_DOWNARROW = (short) 67; |
151 |
public static final short ST_UPARROW = (short) 68; |
176 |
public static final short ST_UPARROW = (short) 68; |
152 |
public static final short ST_LEFTRIGHTARROW = (short) 69; |
177 |
public static final short ST_LEFTRIGHTARROW = (short) 69; |
153 |
public static final short ST_UPDOWNARROW = (short) 70; |
178 |
public static final short ST_UPDOWNARROW = (short) 70; |
154 |
public static final short ST_IRREGULARSEAL1 = (short) 71; |
179 |
public static final short ST_IRREGULARSEAL1 = (short) 71; |
155 |
public static final short ST_IRREGULARSEAL2 = (short) 72; |
180 |
public static final short ST_IRREGULARSEAL2 = (short) 72; |
156 |
public static final short ST_LIGHTNINGBOLT = (short) 73; |
181 |
public static final short ST_LIGHTNINGBOLT = (short) 73; |
157 |
public static final short ST_HEART = (short) 74; |
182 |
public static final short ST_HEART = (short) 74; |
158 |
public static final short ST_PICTUREFRAME = (short) 75; |
183 |
public static final short ST_PICTUREFRAME = (short) 75; |
159 |
public static final short ST_QUADARROW = (short) 76; |
184 |
public static final short ST_QUADARROW = (short) 76; |
160 |
public static final short ST_LEFTARROWCALLOUT = (short) 77; |
185 |
public static final short ST_LEFTARROWCALLOUT = (short) 77; |
161 |
public static final short ST_RIGHTARROWCALLOUT = (short) 78; |
186 |
public static final short ST_RIGHTARROWCALLOUT = (short) 78; |
162 |
public static final short ST_UPARROWCALLOUT = (short) 79; |
187 |
public static final short ST_UPARROWCALLOUT = (short) 79; |
163 |
public static final short ST_DOWNARROWCALLOUT = (short) 80; |
188 |
public static final short ST_DOWNARROWCALLOUT = (short) 80; |
164 |
public static final short ST_LEFTRIGHTARROWCALLOUT = (short) 81; |
189 |
public static final short ST_LEFTRIGHTARROWCALLOUT = (short) 81; |
165 |
public static final short ST_UPDOWNARROWCALLOUT = (short) 82; |
190 |
public static final short ST_UPDOWNARROWCALLOUT = (short) 82; |
166 |
public static final short ST_QUADARROWCALLOUT = (short) 83; |
191 |
public static final short ST_QUADARROWCALLOUT = (short) 83; |
167 |
public static final short ST_BEVEL = (short) 84; |
192 |
public static final short ST_BEVEL = (short) 84; |
168 |
public static final short ST_LEFTBRACKET = (short) 85; |
193 |
public static final short ST_LEFTBRACKET = (short) 85; |
169 |
public static final short ST_RIGHTBRACKET = (short) 86; |
194 |
public static final short ST_RIGHTBRACKET = (short) 86; |
170 |
public static final short ST_LEFTBRACE = (short) 87; |
195 |
public static final short ST_LEFTBRACE = (short) 87; |
171 |
public static final short ST_RIGHTBRACE = (short) 88; |
196 |
public static final short ST_RIGHTBRACE = (short) 88; |
172 |
public static final short ST_LEFTUPARROW = (short) 89; |
197 |
public static final short ST_LEFTUPARROW = (short) 89; |
173 |
public static final short ST_BENTUPARROW = (short) 90; |
198 |
public static final short ST_BENTUPARROW = (short) 90; |
174 |
public static final short ST_BENTARROW = (short) 91; |
199 |
public static final short ST_BENTARROW = (short) 91; |
175 |
public static final short ST_SEAL24 = (short) 92; |
200 |
public static final short ST_SEAL24 = (short) 92; |
176 |
public static final short ST_STRIPEDRIGHTARROW = (short) 93; |
201 |
public static final short ST_STRIPEDRIGHTARROW = (short) 93; |
177 |
public static final short ST_NOTCHEDRIGHTARROW = (short) 94; |
202 |
public static final short ST_NOTCHEDRIGHTARROW = (short) 94; |
178 |
public static final short ST_BLOCKARC = (short) 95; |
203 |
public static final short ST_BLOCKARC = (short) 95; |
179 |
public static final short ST_SMILEYFACE = (short) 96; |
204 |
public static final short ST_SMILEYFACE = (short) 96; |
180 |
public static final short ST_VERTICALSCROLL = (short) 97; |
205 |
public static final short ST_VERTICALSCROLL = (short) 97; |
181 |
public static final short ST_HORIZONTALSCROLL = (short) 98; |
206 |
public static final short ST_HORIZONTALSCROLL = (short) 98; |
182 |
public static final short ST_CIRCULARARROW = (short) 99; |
207 |
public static final short ST_CIRCULARARROW = (short) 99; |
183 |
public static final short ST_NOTCHEDCIRCULARARROW = (short) 100; |
208 |
public static final short ST_NOTCHEDCIRCULARARROW = (short) 100; |
184 |
public static final short ST_UTURNARROW = (short) 101; |
209 |
public static final short ST_UTURNARROW = (short) 101; |
185 |
public static final short ST_CURVEDRIGHTARROW = (short) 102; |
210 |
public static final short ST_CURVEDRIGHTARROW = (short) 102; |
186 |
public static final short ST_CURVEDLEFTARROW = (short) 103; |
211 |
public static final short ST_CURVEDLEFTARROW = (short) 103; |
187 |
public static final short ST_CURVEDUPARROW = (short) 104; |
212 |
public static final short ST_CURVEDUPARROW = (short) 104; |
188 |
public static final short ST_CURVEDDOWNARROW = (short) 105; |
213 |
public static final short ST_CURVEDDOWNARROW = (short) 105; |
189 |
public static final short ST_CLOUDCALLOUT = (short) 106; |
214 |
public static final short ST_CLOUDCALLOUT = (short) 106; |
190 |
public static final short ST_ELLIPSERIBBON = (short) 107; |
215 |
public static final short ST_ELLIPSERIBBON = (short) 107; |
191 |
public static final short ST_ELLIPSERIBBON2 = (short) 108; |
216 |
public static final short ST_ELLIPSERIBBON2 = (short) 108; |
192 |
public static final short ST_FLOWCHARTPROCESS = (short) 109; |
217 |
public static final short ST_FLOWCHARTPROCESS = (short) 109; |
193 |
public static final short ST_FLOWCHARTDECISION = (short) 110; |
218 |
public static final short ST_FLOWCHARTDECISION = (short) 110; |
194 |
public static final short ST_FLOWCHARTINPUTOUTPUT = (short) 111; |
219 |
public static final short ST_FLOWCHARTINPUTOUTPUT = (short) 111; |
195 |
public static final short ST_FLOWCHARTPREDEFINEDPROCESS = (short) 112; |
220 |
public static final short ST_FLOWCHARTPREDEFINEDPROCESS = (short) 112; |
196 |
public static final short ST_FLOWCHARTINTERNALSTORAGE = (short) 113; |
221 |
public static final short ST_FLOWCHARTINTERNALSTORAGE = (short) 113; |
197 |
public static final short ST_FLOWCHARTDOCUMENT = (short) 114; |
222 |
public static final short ST_FLOWCHARTDOCUMENT = (short) 114; |
198 |
public static final short ST_FLOWCHARTMULTIDOCUMENT = (short) 115; |
223 |
public static final short ST_FLOWCHARTMULTIDOCUMENT = (short) 115; |
199 |
public static final short ST_FLOWCHARTTERMINATOR = (short) 116; |
224 |
public static final short ST_FLOWCHARTTERMINATOR = (short) 116; |
200 |
public static final short ST_FLOWCHARTPREPARATION = (short) 117; |
225 |
public static final short ST_FLOWCHARTPREPARATION = (short) 117; |
201 |
public static final short ST_FLOWCHARTMANUALINPUT = (short) 118; |
226 |
public static final short ST_FLOWCHARTMANUALINPUT = (short) 118; |
202 |
public static final short ST_FLOWCHARTMANUALOPERATION = (short) 119; |
227 |
public static final short ST_FLOWCHARTMANUALOPERATION = (short) 119; |
203 |
public static final short ST_FLOWCHARTCONNECTOR = (short) 120; |
228 |
public static final short ST_FLOWCHARTCONNECTOR = (short) 120; |
204 |
public static final short ST_FLOWCHARTPUNCHEDCARD = (short) 121; |
229 |
public static final short ST_FLOWCHARTPUNCHEDCARD = (short) 121; |
205 |
public static final short ST_FLOWCHARTPUNCHEDTAPE = (short) 122; |
230 |
public static final short ST_FLOWCHARTPUNCHEDTAPE = (short) 122; |
206 |
public static final short ST_FLOWCHARTSUMMINGJUNCTION = (short) 123; |
231 |
public static final short ST_FLOWCHARTSUMMINGJUNCTION = (short) 123; |
207 |
public static final short ST_FLOWCHARTOR = (short) 124; |
232 |
public static final short ST_FLOWCHARTOR = (short) 124; |
208 |
public static final short ST_FLOWCHARTCOLLATE = (short) 125; |
233 |
public static final short ST_FLOWCHARTCOLLATE = (short) 125; |
209 |
public static final short ST_FLOWCHARTSORT = (short) 126; |
234 |
public static final short ST_FLOWCHARTSORT = (short) 126; |
210 |
public static final short ST_FLOWCHARTEXTRACT = (short) 127; |
235 |
public static final short ST_FLOWCHARTEXTRACT = (short) 127; |
211 |
public static final short ST_FLOWCHARTMERGE = (short) 128; |
236 |
public static final short ST_FLOWCHARTMERGE = (short) 128; |
212 |
public static final short ST_FLOWCHARTOFFLINESTORAGE = (short) 129; |
237 |
public static final short ST_FLOWCHARTOFFLINESTORAGE = (short) 129; |
213 |
public static final short ST_FLOWCHARTONLINESTORAGE = (short) 130; |
238 |
public static final short ST_FLOWCHARTONLINESTORAGE = (short) 130; |
214 |
public static final short ST_FLOWCHARTMAGNETICTAPE = (short) 131; |
239 |
public static final short ST_FLOWCHARTMAGNETICTAPE = (short) 131; |
215 |
public static final short ST_FLOWCHARTMAGNETICDISK = (short) 132; |
240 |
public static final short ST_FLOWCHARTMAGNETICDISK = (short) 132; |
216 |
public static final short ST_FLOWCHARTMAGNETICDRUM = (short) 133; |
241 |
public static final short ST_FLOWCHARTMAGNETICDRUM = (short) 133; |
217 |
public static final short ST_FLOWCHARTDISPLAY = (short) 134; |
242 |
public static final short ST_FLOWCHARTDISPLAY = (short) 134; |
218 |
public static final short ST_FLOWCHARTDELAY = (short) 135; |
243 |
public static final short ST_FLOWCHARTDELAY = (short) 135; |
219 |
public static final short ST_TEXTPLAINTEXT = (short) 136; |
244 |
public static final short ST_TEXTPLAINTEXT = (short) 136; |
220 |
public static final short ST_TEXTSTOP = (short) 137; |
245 |
public static final short ST_TEXTSTOP = (short) 137; |
221 |
public static final short ST_TEXTTRIANGLE = (short) 138; |
246 |
public static final short ST_TEXTTRIANGLE = (short) 138; |
222 |
public static final short ST_TEXTTRIANGLEINVERTED = (short) 139; |
247 |
public static final short ST_TEXTTRIANGLEINVERTED = (short) 139; |
223 |
public static final short ST_TEXTCHEVRON = (short) 140; |
248 |
public static final short ST_TEXTCHEVRON = (short) 140; |
224 |
public static final short ST_TEXTCHEVRONINVERTED = (short) 141; |
249 |
public static final short ST_TEXTCHEVRONINVERTED = (short) 141; |
225 |
public static final short ST_TEXTRINGINSIDE = (short) 142; |
250 |
public static final short ST_TEXTRINGINSIDE = (short) 142; |
226 |
public static final short ST_TEXTRINGOUTSIDE = (short) 143; |
251 |
public static final short ST_TEXTRINGOUTSIDE = (short) 143; |
227 |
public static final short ST_TEXTARCHUPCURVE = (short) 144; |
252 |
public static final short ST_TEXTARCHUPCURVE = (short) 144; |
228 |
public static final short ST_TEXTARCHDOWNCURVE = (short) 145; |
253 |
public static final short ST_TEXTARCHDOWNCURVE = (short) 145; |
229 |
public static final short ST_TEXTCIRCLECURVE = (short) 146; |
254 |
public static final short ST_TEXTCIRCLECURVE = (short) 146; |
230 |
public static final short ST_TEXTBUTTONCURVE = (short) 147; |
255 |
public static final short ST_TEXTBUTTONCURVE = (short) 147; |
231 |
public static final short ST_TEXTARCHUPPOUR = (short) 148; |
256 |
public static final short ST_TEXTARCHUPPOUR = (short) 148; |
232 |
public static final short ST_TEXTARCHDOWNPOUR = (short) 149; |
257 |
public static final short ST_TEXTARCHDOWNPOUR = (short) 149; |
233 |
public static final short ST_TEXTCIRCLEPOUR = (short) 150; |
258 |
public static final short ST_TEXTCIRCLEPOUR = (short) 150; |
234 |
public static final short ST_TEXTBUTTONPOUR = (short) 151; |
259 |
public static final short ST_TEXTBUTTONPOUR = (short) 151; |
235 |
public static final short ST_TEXTCURVEUP = (short) 152; |
260 |
public static final short ST_TEXTCURVEUP = (short) 152; |
236 |
public static final short ST_TEXTCURVEDOWN = (short) 153; |
261 |
public static final short ST_TEXTCURVEDOWN = (short) 153; |
237 |
public static final short ST_TEXTCASCADEUP = (short) 154; |
262 |
public static final short ST_TEXTCASCADEUP = (short) 154; |
238 |
public static final short ST_TEXTCASCADEDOWN = (short) 155; |
263 |
public static final short ST_TEXTCASCADEDOWN = (short) 155; |
239 |
public static final short ST_TEXTWAVE1 = (short) 156; |
264 |
public static final short ST_TEXTWAVE1 = (short) 156; |
240 |
public static final short ST_TEXTWAVE2 = (short) 157; |
265 |
public static final short ST_TEXTWAVE2 = (short) 157; |
241 |
public static final short ST_TEXTWAVE3 = (short) 158; |
266 |
public static final short ST_TEXTWAVE3 = (short) 158; |
242 |
public static final short ST_TEXTWAVE4 = (short) 159; |
267 |
public static final short ST_TEXTWAVE4 = (short) 159; |
243 |
public static final short ST_TEXTINFLATE = (short) 160; |
268 |
public static final short ST_TEXTINFLATE = (short) 160; |
244 |
public static final short ST_TEXTDEFLATE = (short) 161; |
269 |
public static final short ST_TEXTDEFLATE = (short) 161; |
245 |
public static final short ST_TEXTINFLATEBOTTOM = (short) 162; |
270 |
public static final short ST_TEXTINFLATEBOTTOM = (short) 162; |
246 |
public static final short ST_TEXTDEFLATEBOTTOM = (short) 163; |
271 |
public static final short ST_TEXTDEFLATEBOTTOM = (short) 163; |
247 |
public static final short ST_TEXTINFLATETOP = (short) 164; |
272 |
public static final short ST_TEXTINFLATETOP = (short) 164; |
248 |
public static final short ST_TEXTDEFLATETOP = (short) 165; |
273 |
public static final short ST_TEXTDEFLATETOP = (short) 165; |
249 |
public static final short ST_TEXTDEFLATEINFLATE = (short) 166; |
274 |
public static final short ST_TEXTDEFLATEINFLATE = (short) 166; |
250 |
public static final short ST_TEXTDEFLATEINFLATEDEFLATE = (short) 167; |
275 |
public static final short ST_TEXTDEFLATEINFLATEDEFLATE = (short) 167; |
251 |
public static final short ST_TEXTFADERIGHT = (short) 168; |
276 |
public static final short ST_TEXTFADERIGHT = (short) 168; |
252 |
public static final short ST_TEXTFADELEFT = (short) 169; |
277 |
public static final short ST_TEXTFADELEFT = (short) 169; |
253 |
public static final short ST_TEXTFADEUP = (short) 170; |
278 |
public static final short ST_TEXTFADEUP = (short) 170; |
254 |
public static final short ST_TEXTFADEDOWN = (short) 171; |
279 |
public static final short ST_TEXTFADEDOWN = (short) 171; |
255 |
public static final short ST_TEXTSLANTUP = (short) 172; |
280 |
public static final short ST_TEXTSLANTUP = (short) 172; |
256 |
public static final short ST_TEXTSLANTDOWN = (short) 173; |
281 |
public static final short ST_TEXTSLANTDOWN = (short) 173; |
257 |
public static final short ST_TEXTCANUP = (short) 174; |
282 |
public static final short ST_TEXTCANUP = (short) 174; |
258 |
public static final short ST_TEXTCANDOWN = (short) 175; |
283 |
public static final short ST_TEXTCANDOWN = (short) 175; |
259 |
public static final short ST_FLOWCHARTALTERNATEPROCESS = (short) 176; |
284 |
public static final short ST_FLOWCHARTALTERNATEPROCESS = (short) 176; |
260 |
public static final short ST_FLOWCHARTOFFPAGECONNECTOR = (short) 177; |
285 |
public static final short ST_FLOWCHARTOFFPAGECONNECTOR = (short) 177; |
261 |
public static final short ST_CALLOUT90 = (short) 178; |
286 |
public static final short ST_CALLOUT90 = (short) 178; |
262 |
public static final short ST_ACCENTCALLOUT90 = (short) 179; |
287 |
public static final short ST_ACCENTCALLOUT90 = (short) 179; |
263 |
public static final short ST_BORDERCALLOUT90 = (short) 180; |
288 |
public static final short ST_BORDERCALLOUT90 = (short) 180; |
264 |
public static final short ST_ACCENTBORDERCALLOUT90 = (short) 181; |
289 |
public static final short ST_ACCENTBORDERCALLOUT90 = (short) 181; |
265 |
public static final short ST_LEFTRIGHTUPARROW = (short) 182; |
290 |
public static final short ST_LEFTRIGHTUPARROW = (short) 182; |
266 |
public static final short ST_SUN = (short) 183; |
291 |
public static final short ST_SUN = (short) 183; |
267 |
public static final short ST_MOON = (short) 184; |
292 |
public static final short ST_MOON = (short) 184; |
268 |
public static final short ST_BRACKETPAIR = (short) 185; |
293 |
public static final short ST_BRACKETPAIR = (short) 185; |
269 |
public static final short ST_BRACEPAIR = (short) 186; |
294 |
public static final short ST_BRACEPAIR = (short) 186; |
270 |
public static final short ST_SEAL4 = (short) 187; |
295 |
public static final short ST_SEAL4 = (short) 187; |
271 |
public static final short ST_DOUBLEWAVE = (short) 188; |
296 |
public static final short ST_DOUBLEWAVE = (short) 188; |
272 |
public static final short ST_ACTIONBUTTONBLANK = (short) 189; |
297 |
public static final short ST_ACTIONBUTTONBLANK = (short) 189; |
273 |
public static final short ST_ACTIONBUTTONHOME = (short) 190; |
298 |
public static final short ST_ACTIONBUTTONHOME = (short) 190; |
274 |
public static final short ST_ACTIONBUTTONHELP = (short) 191; |
299 |
public static final short ST_ACTIONBUTTONHELP = (short) 191; |
275 |
public static final short ST_ACTIONBUTTONINFORMATION = (short) 192; |
300 |
public static final short ST_ACTIONBUTTONINFORMATION = (short) 192; |
276 |
public static final short ST_ACTIONBUTTONFORWARDNEXT = (short) 193; |
301 |
public static final short ST_ACTIONBUTTONFORWARDNEXT = (short) 193; |
277 |
public static final short ST_ACTIONBUTTONBACKPREVIOUS = (short) 194; |
302 |
public static final short ST_ACTIONBUTTONBACKPREVIOUS = (short) 194; |
278 |
public static final short ST_ACTIONBUTTONEND = (short) 195; |
303 |
public static final short ST_ACTIONBUTTONEND = (short) 195; |
279 |
public static final short ST_ACTIONBUTTONBEGINNING = (short) 196; |
304 |
public static final short ST_ACTIONBUTTONBEGINNING = (short) 196; |
280 |
public static final short ST_ACTIONBUTTONRETURN = (short) 197; |
305 |
public static final short ST_ACTIONBUTTONRETURN = (short) 197; |
281 |
public static final short ST_ACTIONBUTTONDOCUMENT = (short) 198; |
306 |
public static final short ST_ACTIONBUTTONDOCUMENT = (short) 198; |
282 |
public static final short ST_ACTIONBUTTONSOUND = (short) 199; |
307 |
public static final short ST_ACTIONBUTTONSOUND = (short) 199; |
283 |
public static final short ST_ACTIONBUTTONMOVIE = (short) 200; |
308 |
public static final short ST_ACTIONBUTTONMOVIE = (short) 200; |
284 |
public static final short ST_HOSTCONTROL = (short) 201; |
309 |
public static final short ST_HOSTCONTROL = (short) 201; |
285 |
public static final short ST_TEXTBOX = (short) 202; |
310 |
public static final short ST_TEXTBOX = (short) 202; |
286 |
public static final short ST_NIL = (short) 0x0FFF; |
311 |
public static final short ST_NIL = (short) 0x0FFF; |
287 |
|
312 |
|
288 |
protected HSSFPatriarch patriarch; |
313 |
protected HSSFPatriarch patriarch; |
289 |
|
314 |
|
290 |
/** Maps shape container objects to their {@link TextObjectRecord} or {@link ObjRecord} */ |
315 |
/** |
291 |
Map<EscherRecord, Record> shapeToObj = new HashMap<EscherRecord, Record>(); |
316 |
* Maps shape container objects to their {@link TextObjectRecord} or {@link ObjRecord} |
|
|
317 |
*/ |
318 |
private final Map<EscherRecord, Record> shapeToObj = new HashMap<EscherRecord, Record>(); |
292 |
private DrawingManager2 drawingManager; |
319 |
private DrawingManager2 drawingManager; |
293 |
private short drawingGroupId; |
320 |
private short drawingGroupId; |
294 |
|
321 |
|
295 |
/** |
322 |
/** |
296 |
* list of "tail" records that need to be serialized after all drawing group records |
323 |
* list of "tail" records that need to be serialized after all drawing group records |
297 |
*/ |
324 |
*/ |
298 |
private List tailRec = new ArrayList(); |
325 |
private List tailRec = new ArrayList(); |
299 |
|
326 |
|
300 |
public EscherAggregate( DrawingManager2 drawingManager ) |
327 |
public EscherAggregate(DrawingManager2 drawingManager) { |
301 |
{ |
|
|
302 |
this.drawingManager = drawingManager; |
328 |
this.drawingManager = drawingManager; |
303 |
} |
329 |
} |
304 |
|
330 |
|
305 |
/** |
331 |
/** |
306 |
* @return Returns the current sid. |
332 |
* @return Returns the current sid. |
307 |
*/ |
333 |
*/ |
308 |
public short getSid() |
334 |
public short getSid() { |
309 |
{ |
|
|
310 |
return sid; |
335 |
return sid; |
311 |
} |
336 |
} |
312 |
|
337 |
|
313 |
/** |
338 |
/** |
314 |
* Calculates the string representation of this record. This is |
339 |
* Calculates the string representation of this record. This is |
315 |
* simply a dump of all the records. |
340 |
* simply a dump of all the records. |
316 |
*/ |
341 |
*/ |
317 |
public String toString() |
342 |
public String toString() { |
318 |
{ |
|
|
319 |
String nl = System.getProperty( "line.separtor" ); |
343 |
String nl = System.getProperty("line.separtor"); |
320 |
|
344 |
|
321 |
StringBuffer result = new StringBuffer(); |
345 |
StringBuffer result = new StringBuffer(); |
322 |
result.append( '[' ).append( getRecordName() ).append( ']' + nl ); |
346 |
result.append('[').append(getRecordName()).append(']' + nl); |
323 |
for ( Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); ) |
347 |
for (Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); ) { |
324 |
{ |
|
|
325 |
EscherRecord escherRecord = (EscherRecord) iterator.next(); |
348 |
EscherRecord escherRecord = (EscherRecord) iterator.next(); |
326 |
result.append( escherRecord.toString() ); |
349 |
result.append(escherRecord.toString()); |
327 |
} |
350 |
} |
328 |
result.append( "[/" ).append( getRecordName() ).append( ']' + nl ); |
351 |
result.append("[/").append(getRecordName()).append(']' + nl); |
329 |
|
352 |
|
330 |
return result.toString(); |
353 |
return result.toString(); |
331 |
} |
354 |
} |
332 |
|
355 |
|
333 |
public String toXml(String tab){ |
356 |
public String toXml(String tab) { |
334 |
StringBuilder builder = new StringBuilder(); |
357 |
StringBuilder builder = new StringBuilder(); |
335 |
builder.append(tab).append("<").append(getRecordName()).append(">\n"); |
358 |
builder.append(tab).append("<").append(getRecordName()).append(">\n"); |
336 |
for ( Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); ) |
359 |
for (Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); ) { |
337 |
{ |
|
|
338 |
EscherRecord escherRecord = (EscherRecord) iterator.next(); |
360 |
EscherRecord escherRecord = (EscherRecord) iterator.next(); |
339 |
builder.append( escherRecord.toXml(tab+"\t") ); |
361 |
builder.append(escherRecord.toXml(tab + "\t")); |
340 |
} |
362 |
} |
341 |
builder.append(tab).append("</").append(getRecordName()).append(">\n"); |
363 |
builder.append(tab).append("</").append(getRecordName()).append(">\n"); |
342 |
return builder.toString(); |
364 |
return builder.toString(); |
343 |
} |
365 |
} |
344 |
|
366 |
|
345 |
/** |
367 |
private static boolean isDrawingLayerRecord(final short sid) { |
346 |
* Collapses the drawing records into an aggregate. |
368 |
return sid == DrawingRecord.sid || |
|
|
369 |
sid == ContinueRecord.sid || |
370 |
sid == ObjRecord.sid || |
371 |
sid == TextObjectRecord.sid; |
372 |
} |
373 |
|
347 |
*/ |
374 |
/** |
|
|
375 |
* Collapses the drawing records into an aggregate. |
376 |
* read Drawing and Continue records into single byte array, create Escher tree from byte array, create map <EscherRecord, Record> |
348 |
public static EscherAggregate createAggregate( List records, int locFirstDrawingRecord, DrawingManager2 drawingManager ) |
377 |
*/ |
349 |
{ |
|
|
350 |
// Keep track of any shape records created so we can match them back to the object id's. |
378 |
public static EscherAggregate createAggregate(List records, int locFirstDrawingRecord, DrawingManager2 drawingManager) { |
351 |
// Textbox objects are also treated as shape objects. |
|
|
352 |
final List<EscherRecord> shapeRecords = new ArrayList<EscherRecord>(); |
353 |
EscherRecordFactory recordFactory = new DefaultEscherRecordFactory() |
379 |
// Keep track of any shape records created so we can match them back to the object id's. |
354 |
{ |
380 |
// Textbox objects are also treated as shape objects. |
355 |
public EscherRecord createRecord( byte[] data, int offset ) |
381 |
final List<EscherRecord> shapeRecords = new ArrayList<EscherRecord>(); |
356 |
{ |
|
|
357 |
EscherRecord r = super.createRecord( data, offset ); |
382 |
EscherRecordFactory recordFactory = new DefaultEscherRecordFactory() { |
|
|
383 |
public EscherRecord createRecord(byte[] data, int offset) { |
358 |
if ( r.getRecordId() == EscherClientDataRecord.RECORD_ID || r.getRecordId() == EscherTextboxRecord.RECORD_ID ) |
384 |
EscherRecord r = super.createRecord(data, offset); |
359 |
{ |
|
|
360 |
shapeRecords.add( r ); |
385 |
if (r.getRecordId() == EscherClientDataRecord.RECORD_ID || r.getRecordId() == EscherTextboxRecord.RECORD_ID) { |
361 |
} |
386 |
shapeRecords.add(r); |
362 |
return r; |
|
|
363 |
} |
364 |
}; |
|
|
387 |
} |
388 |
return r; |
389 |
} |
390 |
}; |
365 |
|
391 |
|
366 |
// Calculate the size of the buffer |
392 |
// Create one big buffer |
|
|
393 |
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); |
394 |
|
367 |
EscherAggregate agg = new EscherAggregate(drawingManager); |
395 |
EscherAggregate agg = new EscherAggregate(drawingManager); |
368 |
int loc = locFirstDrawingRecord; |
396 |
int loc = locFirstDrawingRecord; |
369 |
int dataSize = 0; |
397 |
while (loc + 1 < records.size() |
370 |
while ( loc + 1 < records.size() |
|
|
371 |
&& sid( records, loc ) == DrawingRecord.sid |
398 |
&& (isDrawingLayerRecord(sid(records, loc)))) { |
372 |
&& isObjectRecord( records, loc + 1 ) ) |
399 |
try { |
373 |
{ |
400 |
if (!(sid(records, loc) == DrawingRecord.sid || sid(records, loc) == ContinueRecord.sid)) { |
374 |
dataSize += ( (DrawingRecord) records.get( loc ) ).getRecordData().length; |
401 |
loc++; |
375 |
loc += 2; |
402 |
continue; |
376 |
while ( loc + 1 < records.size() |
|
|
377 |
&& sid( records, loc ) == ContinueRecord.sid |
378 |
&& isObjectRecord( records, loc + 1 ) ) |
379 |
{ |
380 |
dataSize += ( (ContinueRecord) records.get( loc ) ).getData().length; |
381 |
loc += 2; |
382 |
} |
403 |
} |
|
|
404 |
if (sid(records, loc) == DrawingRecord.sid) { |
405 |
buffer.write(((DrawingRecord) records.get(loc)).getRecordData()); |
406 |
} else { |
407 |
buffer.write(((ContinueRecord) records.get(loc)).getData()); |
383 |
} |
408 |
} |
384 |
|
409 |
} catch (IOException e) { |
385 |
// Create one big buffer |
410 |
throw new RuntimeException("Couldn't get data from drawing/continue records", e); |
386 |
byte buffer[] = new byte[dataSize]; |
|
|
387 |
int offset = 0; |
388 |
loc = locFirstDrawingRecord; |
389 |
while ( loc + 1 < records.size() |
390 |
&& sid( records, loc ) == DrawingRecord.sid |
391 |
&& isObjectRecord( records, loc + 1 ) ) |
392 |
{ |
393 |
DrawingRecord drawingRecord = (DrawingRecord) records.get( loc ); |
394 |
System.arraycopy( drawingRecord.getRecordData(), 0, buffer, offset, drawingRecord.getRecordData().length ); |
395 |
offset += drawingRecord.getRecordData().length; |
396 |
loc += 2; |
397 |
while ( loc + 1 < records.size() |
398 |
&& sid( records, loc ) == ContinueRecord.sid |
399 |
&& isObjectRecord( records, loc + 1 ) ) |
400 |
{ |
401 |
ContinueRecord continueRecord = (ContinueRecord) records.get( loc ); |
402 |
System.arraycopy( continueRecord.getData(), 0, buffer, offset, continueRecord.getData().length ); |
403 |
offset += continueRecord.getData().length; |
404 |
loc += 2; |
405 |
} |
411 |
} |
406 |
} |
412 |
loc++; |
|
|
413 |
} |
407 |
|
414 |
|
408 |
// Decode the shapes |
415 |
// Decode the shapes |
409 |
// agg.escherRecords = new ArrayList(); |
416 |
// agg.escherRecords = new ArrayList(); |
410 |
int pos = 0; |
417 |
int pos = 0; |
411 |
while ( pos < dataSize ) |
418 |
while (pos < buffer.size()) { |
412 |
{ |
419 |
EscherRecord r = recordFactory.createRecord(buffer.toByteArray(), pos); |
413 |
EscherRecord r = recordFactory.createRecord( buffer, pos ); |
420 |
int bytesRead = r.fillFields(buffer.toByteArray(), pos, recordFactory); |
414 |
int bytesRead = r.fillFields( buffer, pos, recordFactory ); |
|
|
415 |
agg.addEscherRecord( r ); |
421 |
agg.addEscherRecord(r); |
416 |
pos += bytesRead; |
422 |
pos += bytesRead; |
417 |
} |
423 |
} |
418 |
|
424 |
|
419 |
// Associate the object records with the shapes |
425 |
// Associate the object records with the shapes |
420 |
loc = locFirstDrawingRecord; |
426 |
loc = locFirstDrawingRecord + 1; |
421 |
int shapeIndex = 0; |
427 |
int shapeIndex = 0; |
422 |
agg.shapeToObj = new HashMap<EscherRecord, Record>(); |
428 |
while (loc < records.size() |
423 |
while ( loc + 1 < records.size() |
429 |
&& (isDrawingLayerRecord(sid(records, loc)))) { |
424 |
&& sid( records, loc ) == DrawingRecord.sid |
430 |
if (!isObjectRecord(records, loc)) { |
425 |
&& isObjectRecord( records, loc + 1 ) ) |
431 |
loc++; |
426 |
{ |
432 |
continue; |
427 |
Record objRecord = (Record) records.get( loc + 1 ); |
433 |
} |
|
|
434 |
Record objRecord = (Record) records.get(loc); |
428 |
agg.shapeToObj.put( shapeRecords.get( shapeIndex++ ), objRecord ); |
435 |
agg.shapeToObj.put(shapeRecords.get(shapeIndex++), objRecord); |
429 |
loc += 2; |
436 |
loc++; |
430 |
while ( loc + 1 < records.size() |
|
|
431 |
&& sid( records, loc ) == ContinueRecord.sid |
432 |
&& isObjectRecord( records, loc + 1 ) ) |
433 |
{ |
434 |
objRecord = (Record) records.get( loc + 1 ); |
435 |
agg.shapeToObj.put( shapeRecords.get( shapeIndex++ ), objRecord ); |
436 |
loc += 2; |
437 |
} |
437 |
} |
|
|
438 |
|
439 |
// any NoteRecords that follow the drawing block must be aggregated and and saved in the tailRec collection |
440 |
// TODO remove this logic. 'tail' records should be inserted in the main record stream |
441 |
while (loc < records.size()) { |
442 |
if (sid(records, loc) == NoteRecord.sid) { |
443 |
NoteRecord r = (NoteRecord) records.get(loc); |
444 |
agg.tailRec.add(r); |
445 |
} else { |
446 |
break; |
438 |
} |
447 |
} |
|
|
448 |
loc++; |
449 |
} |
439 |
|
450 |
|
440 |
return agg; |
451 |
int locLastDrawingRecord = loc; |
|
|
452 |
// replace drawing block with the created EscherAggregate |
453 |
records.subList(locFirstDrawingRecord, locLastDrawingRecord).clear(); |
454 |
records.add(locFirstDrawingRecord, agg); |
441 |
|
455 |
|
442 |
} |
456 |
|
|
|
457 |
return agg; |
|
|
458 |
} |
443 |
|
459 |
|
444 |
/** |
460 |
/** |
445 |
* Serializes this aggregate to a byte array. Since this is an aggregate |
461 |
* Serializes this aggregate to a byte array. Since this is an aggregate |
446 |
* record it will effectively serialize the aggregated records. |
462 |
* record it will effectively serialize the aggregated records. |
447 |
* |
463 |
* |
448 |
* @param offset The offset into the start of the array. |
464 |
* @param offset The offset into the start of the array. |
449 |
* @param data The byte array to serialize to. |
465 |
* @param data The byte array to serialize to. |
450 |
* @return The number of bytes serialized. |
466 |
* @return The number of bytes serialized. |
451 |
*/ |
467 |
*/ |
452 |
public int serialize( int offset, byte[] data ) |
468 |
public int serialize(int offset, byte[] data) { |
453 |
{ |
|
|
454 |
convertUserModelToRecords(); |
469 |
convertUserModelToRecords(); |
455 |
|
470 |
|
456 |
// Determine buffer size |
471 |
// Determine buffer size |
457 |
List records = getEscherRecords(); |
472 |
List records = getEscherRecords(); |
458 |
int size = getEscherRecordSize( records ); |
473 |
int size = getEscherRecordSize(records); |
459 |
byte[] buffer = new byte[size]; |
474 |
byte[] buffer = new byte[size]; |
460 |
|
475 |
|
461 |
|
476 |
|
462 |
// Serialize escher records into one big data structure and keep note of ending offsets. |
477 |
// Serialize escher records into one big data structure and keep note of ending offsets. |
463 |
final List spEndingOffsets = new ArrayList(); |
478 |
final List spEndingOffsets = new ArrayList(); |
464 |
final List shapes = new ArrayList(); |
479 |
final List shapes = new ArrayList(); |
465 |
int pos = 0; |
480 |
int pos = 0; |
466 |
for ( Iterator iterator = records.iterator(); iterator.hasNext(); ) |
481 |
for (Iterator iterator = records.iterator(); iterator.hasNext(); ) { |
467 |
{ |
|
|
468 |
EscherRecord e = (EscherRecord) iterator.next(); |
482 |
EscherRecord e = (EscherRecord) iterator.next(); |
469 |
pos += e.serialize( pos, buffer, new EscherSerializationListener() |
483 |
pos += e.serialize(pos, buffer, new EscherSerializationListener() { |
470 |
{ |
484 |
public void beforeRecordSerialize(int offset, short recordId, EscherRecord record) { |
471 |
public void beforeRecordSerialize( int offset, short recordId, EscherRecord record ) |
|
|
472 |
{ |
473 |
} |
485 |
} |
474 |
|
486 |
|
475 |
public void afterRecordSerialize( int offset, short recordId, int size, EscherRecord record ) |
487 |
public void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record) { |
476 |
{ |
488 |
if (recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID) { |
477 |
if ( recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID ) |
|
|
478 |
{ |
479 |
spEndingOffsets.add( Integer.valueOf( offset ) ); |
489 |
spEndingOffsets.add(Integer.valueOf(offset)); |
480 |
shapes.add( record ); |
490 |
shapes.add(record); |
481 |
} |
491 |
} |
482 |
} |
492 |
} |
483 |
} ); |
493 |
}); |
484 |
} |
494 |
} |
485 |
// todo: fix this |
495 |
// todo: fix this |
486 |
shapes.add( 0, null ); |
496 |
shapes.add(0, null); |
487 |
spEndingOffsets.add( 0, null ); |
497 |
spEndingOffsets.add(0, null); |
488 |
|
498 |
|
489 |
// Split escher records into separate MSODRAWING and OBJ, TXO records. (We don't break on |
499 |
// Split escher records into separate MSODRAWING and OBJ, TXO records. (We don't break on |
490 |
// the first one because it's the patriach). |
500 |
// the first one because it's the patriach). |
491 |
pos = offset; |
501 |
pos = offset; |
492 |
for ( int i = 1; i < shapes.size(); i++ ) |
502 |
int writtenEscherBytes = 0; |
493 |
{ |
503 |
for (int i = 1; i < shapes.size(); i++) { |
494 |
int endOffset = ( (Integer) spEndingOffsets.get( i ) ).intValue() - 1; |
504 |
int endOffset = ((Integer) spEndingOffsets.get(i)).intValue() - 1; |
495 |
int startOffset; |
505 |
int startOffset; |
496 |
if ( i == 1 ) |
506 |
if (i == 1) |
497 |
startOffset = 0; |
507 |
startOffset = 0; |
498 |
else |
508 |
else |
499 |
startOffset = ( (Integer) spEndingOffsets.get( i - 1 ) ).intValue(); |
509 |
startOffset = ((Integer) spEndingOffsets.get(i - 1)).intValue(); |
500 |
|
510 |
|
501 |
// Create and write a new MSODRAWING record |
511 |
|
502 |
DrawingRecord drawing = new DrawingRecord(); |
|
|
503 |
byte[] drawingData = new byte[endOffset - startOffset + 1]; |
512 |
byte[] drawingData = new byte[endOffset - startOffset + 1]; |
504 |
System.arraycopy( buffer, startOffset, drawingData, 0, drawingData.length ); |
513 |
System.arraycopy(buffer, startOffset, drawingData, 0, drawingData.length); |
505 |
drawing.setData( drawingData ); |
514 |
int temp = 0; |
506 |
int temp = drawing.serialize( pos, data ); |
515 |
|
|
|
516 |
//First record in drawing layer MUST be DrawingRecord |
517 |
if (writtenEscherBytes + drawingData.length > RecordInputStream.MAX_RECORD_DATA_SIZE && i != 1) { |
518 |
for (int j = 0; j < drawingData.length; j += RecordInputStream.MAX_RECORD_DATA_SIZE) { |
519 |
ContinueRecord drawing = new ContinueRecord(Arrays.copyOfRange(drawingData, j, Math.min(j + RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length))); |
520 |
temp += drawing.serialize(pos + temp, data); |
521 |
} |
522 |
} else { |
523 |
for (int j = 0; j < drawingData.length; j += RecordInputStream.MAX_RECORD_DATA_SIZE) { |
524 |
if (j == 0) { |
525 |
DrawingRecord drawing = new DrawingRecord(); |
526 |
drawing.setData(Arrays.copyOfRange(drawingData, j, Math.min(j + RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length))); |
527 |
temp += drawing.serialize(pos + temp, data); |
528 |
} else { |
529 |
ContinueRecord drawing = new ContinueRecord(Arrays.copyOfRange(drawingData, j, Math.min(j + RecordInputStream.MAX_RECORD_DATA_SIZE, drawingData.length))); |
530 |
temp += drawing.serialize(pos + temp, data); |
531 |
} |
532 |
} |
533 |
|
534 |
} |
535 |
|
507 |
pos += temp; |
536 |
pos += temp; |
|
|
537 |
writtenEscherBytes += drawingData.length; |
508 |
|
538 |
|
509 |
// Write the matching OBJ record |
539 |
// Write the matching OBJ record |
510 |
Record obj = shapeToObj.get( shapes.get( i ) ); |
540 |
Record obj = shapeToObj.get(shapes.get(i)); |
511 |
temp = obj.serialize( pos, data ); |
541 |
temp = obj.serialize(pos, data); |
512 |
pos += temp; |
542 |
pos += temp; |
513 |
|
543 |
|
514 |
} |
544 |
} |
515 |
|
545 |
|
516 |
// write records that need to be serialized after all drawing group records |
546 |
// write records that need to be serialized after all drawing group records |
517 |
for ( int i = 0; i < tailRec.size(); i++ ) |
547 |
for (int i = 0; i < tailRec.size(); i++) { |
518 |
{ |
|
|
519 |
Record rec = (Record)tailRec.get(i); |
548 |
Record rec = (Record) tailRec.get(i); |
520 |
pos += rec.serialize( pos, data ); |
549 |
pos += rec.serialize(pos, data); |
521 |
} |
550 |
} |
522 |
|
551 |
|
523 |
int bytesWritten = pos - offset; |
552 |
int bytesWritten = pos - offset; |
524 |
if ( bytesWritten != getRecordSize() ) |
553 |
if (bytesWritten != getRecordSize()) |
525 |
throw new RecordFormatException( bytesWritten + " bytes written but getRecordSize() reports " + getRecordSize() ); |
554 |
throw new RecordFormatException(bytesWritten + " bytes written but getRecordSize() reports " + getRecordSize()); |
526 |
return bytesWritten; |
555 |
return bytesWritten; |
527 |
} |
556 |
} |
528 |
|
557 |
|
529 |
/** |
558 |
/** |
530 |
* How many bytes do the raw escher records contain. |
559 |
* How many bytes do the raw escher records contain. |
|
|
560 |
* |
531 |
* @param records List of escher records |
561 |
* @param records List of escher records |
532 |
* @return the number of bytes |
562 |
* @return the number of bytes |
533 |
*/ |
563 |
*/ |
534 |
private int getEscherRecordSize( List records ) |
564 |
private int getEscherRecordSize(List records) { |
535 |
{ |
|
|
536 |
int size = 0; |
565 |
int size = 0; |
537 |
for ( Iterator iterator = records.iterator(); iterator.hasNext(); ) |
566 |
for (Iterator iterator = records.iterator(); iterator.hasNext(); ) |
538 |
size += ( (EscherRecord) iterator.next() ).getRecordSize(); |
567 |
size += ((EscherRecord) iterator.next()).getRecordSize(); |
539 |
return size; |
568 |
return size; |
540 |
} |
569 |
} |
541 |
|
570 |
|
542 |
public int getRecordSize() { |
571 |
public int getRecordSize() { |
543 |
// TODO - convert this to RecordAggregate |
572 |
// TODO - convert this to RecordAggregate |
544 |
convertUserModelToRecords(); |
573 |
convertUserModelToRecords(); |
545 |
List records = getEscherRecords(); |
574 |
// To determine size of aggregate record we have to know size of each DrawingRecord because if DrawingRecord |
|
|
575 |
// is split into several continue records we have to add header size to total EscherAggregate size |
576 |
int continueRecordsHeadersSize = 0; |
577 |
// Determine buffer size |
578 |
List<EscherRecord> records = getEscherRecords(); |
546 |
int rawEscherSize = getEscherRecordSize( records ); |
579 |
int rawEscherSize = getEscherRecordSize(records); |
|
|
580 |
byte[] buffer = new byte[rawEscherSize]; |
581 |
final List<Integer> spEndingOffsets = new ArrayList<Integer>(); |
582 |
int pos = 0; |
583 |
for (EscherRecord e : records) { |
584 |
pos += e.serialize(pos, buffer, new EscherSerializationListener() { |
585 |
public void beforeRecordSerialize(int offset, short recordId, EscherRecord record) { |
586 |
} |
587 |
|
588 |
public void afterRecordSerialize(int offset, short recordId, int size, EscherRecord record) { |
589 |
if (recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID) { |
590 |
spEndingOffsets.add(offset); |
591 |
} |
592 |
} |
593 |
}); |
594 |
} |
595 |
spEndingOffsets.add(0, 0); |
596 |
|
597 |
for (int i = 1; i < spEndingOffsets.size(); i++) { |
598 |
if (spEndingOffsets.get(i) - spEndingOffsets.get(i - 1) <= RecordInputStream.MAX_RECORD_DATA_SIZE){ |
599 |
continue; |
600 |
} |
601 |
continueRecordsHeadersSize += ((spEndingOffsets.get(i) - spEndingOffsets.get(i - 1)) / RecordInputStream.MAX_RECORD_DATA_SIZE)*4; |
602 |
} |
603 |
|
547 |
int drawingRecordSize = rawEscherSize + ( shapeToObj.size() ) * 4; |
604 |
int drawingRecordSize = rawEscherSize + (shapeToObj.size()) * 4; |
548 |
int objRecordSize = 0; |
605 |
int objRecordSize = 0; |
549 |
for ( Iterator iterator = shapeToObj.values().iterator(); iterator.hasNext(); ) |
606 |
for (Iterator iterator = shapeToObj.values().iterator(); iterator.hasNext(); ) { |
550 |
{ |
|
|
551 |
Record r = (Record) iterator.next(); |
607 |
Record r = (Record) iterator.next(); |
552 |
objRecordSize += r.getRecordSize(); |
608 |
objRecordSize += r.getRecordSize(); |
553 |
} |
609 |
} |
554 |
int tailRecordSize = 0; |
610 |
int tailRecordSize = 0; |
555 |
for ( Iterator iterator = tailRec.iterator(); iterator.hasNext(); ) |
611 |
for (Iterator iterator = tailRec.iterator(); iterator.hasNext(); ) { |
556 |
{ |
|
|
557 |
Record r = (Record) iterator.next(); |
612 |
Record r = (Record) iterator.next(); |
558 |
tailRecordSize += r.getRecordSize(); |
613 |
tailRecordSize += r.getRecordSize(); |
559 |
} |
614 |
} |
560 |
return drawingRecordSize + objRecordSize + tailRecordSize; |
615 |
return drawingRecordSize + objRecordSize + tailRecordSize +continueRecordsHeadersSize; |
561 |
} |
616 |
} |
562 |
|
617 |
|
563 |
/** |
618 |
/** |
564 |
* Associates an escher record to an OBJ record or a TXO record. |
619 |
* Associates an escher record to an OBJ record or a TXO record. |
565 |
*/ |
620 |
*/ |
566 |
Object associateShapeToObjRecord( EscherRecord r, ObjRecord objRecord ) |
621 |
Object associateShapeToObjRecord(EscherRecord r, ObjRecord objRecord) { |
567 |
{ |
|
|
568 |
return shapeToObj.put( r, objRecord ); |
622 |
return shapeToObj.put(r, objRecord); |
569 |
} |
623 |
} |
570 |
|
624 |
|
571 |
public HSSFPatriarch getPatriarch() |
625 |
public HSSFPatriarch getPatriarch() { |
572 |
{ |
|
|
573 |
return patriarch; |
626 |
return patriarch; |
574 |
} |
627 |
} |
575 |
|
628 |
|
576 |
public void setPatriarch( HSSFPatriarch patriarch ) |
629 |
public void setPatriarch(HSSFPatriarch patriarch) { |
577 |
{ |
|
|
578 |
this.patriarch = patriarch; |
630 |
this.patriarch = patriarch; |
579 |
} |
631 |
} |
580 |
|
632 |
|
581 |
/** |
633 |
/** |
582 |
* Converts the Records into UserModel |
634 |
* Converts the Records into UserModel |
583 |
* objects on the bound HSSFPatriarch |
635 |
* objects on the bound HSSFPatriarch |
584 |
*/ |
636 |
*/ |
585 |
public void convertRecordsToUserModel() { |
637 |
public void convertRecordsToUserModel() { |
586 |
if(patriarch == null) { |
638 |
if (patriarch == null) { |
587 |
throw new IllegalStateException("Must call setPatriarch() first"); |
639 |
throw new IllegalStateException("Must call setPatriarch() first"); |
588 |
} |
640 |
} |
589 |
|
641 |
|
590 |
// The top level container ought to have |
642 |
// The top level container ought to have |
591 |
// the DgRecord and the container of one container |
643 |
// the DgRecord and the container of one container |
592 |
// per shape group (patriach overall first) |
644 |
// per shape group (patriach overall first) |
593 |
EscherContainerRecord topContainer = getEscherContainer(); |
645 |
EscherContainerRecord topContainer = getEscherContainer(); |
594 |
if(topContainer == null) { |
646 |
if (topContainer == null) { |
595 |
return; |
647 |
return; |
596 |
} |
648 |
} |
597 |
topContainer = topContainer.getChildContainers().get(0); |
649 |
topContainer = topContainer.getChildContainers().get(0); |
598 |
|
650 |
|
599 |
List tcc = topContainer.getChildContainers(); |
651 |
List tcc = topContainer.getChildContainers(); |
600 |
if(tcc.size() == 0) { |
652 |
if (tcc.size() == 0) { |
601 |
throw new IllegalStateException("No child escher containers at the point that should hold the patriach data, and one container per top level shape!"); |
653 |
throw new IllegalStateException("No child escher containers at the point that should hold the patriach data, and one container per top level shape!"); |
602 |
} |
654 |
} |
603 |
|
655 |
|
604 |
// First up, get the patriach position |
656 |
// First up, get the patriach position |
605 |
// This is in the first EscherSpgrRecord, in |
657 |
// This is in the first EscherSpgrRecord, in |
606 |
// the first container, with a EscherSRecord too |
658 |
// the first container, with a EscherSRecord too |
607 |
EscherContainerRecord patriachContainer = |
659 |
EscherContainerRecord patriachContainer = |
608 |
(EscherContainerRecord)tcc.get(0); |
660 |
(EscherContainerRecord) tcc.get(0); |
609 |
EscherSpgrRecord spgr = null; |
661 |
EscherSpgrRecord spgr = null; |
610 |
for(Iterator<EscherRecord> it = patriachContainer.getChildIterator(); it.hasNext();) { |
662 |
for (Iterator<EscherRecord> it = patriachContainer.getChildIterator(); it.hasNext(); ) { |
611 |
EscherRecord r = it.next(); |
663 |
EscherRecord r = it.next(); |
612 |
if(r instanceof EscherSpgrRecord) { |
664 |
if (r instanceof EscherSpgrRecord) { |
613 |
spgr = (EscherSpgrRecord)r; |
665 |
spgr = (EscherSpgrRecord) r; |
614 |
break; |
666 |
break; |
615 |
} |
667 |
} |
616 |
} |
668 |
} |
617 |
if(spgr != null) { |
669 |
if (spgr != null) { |
618 |
patriarch.setCoordinates( |
670 |
patriarch.setCoordinates( |
619 |
spgr.getRectX1(), spgr.getRectY1(), |
671 |
spgr.getRectX1(), spgr.getRectY1(), |
620 |
spgr.getRectX2(), spgr.getRectY2() |
672 |
spgr.getRectX2(), spgr.getRectY2() |
621 |
); |
673 |
); |
622 |
} |
674 |
} |
623 |
|
675 |
|
624 |
convertRecordsToUserModelRecursive(tcc, patriarch, null); |
676 |
convertRecordsToUserModelRecursive(tcc, patriarch, null); |
625 |
|
677 |
|
626 |
// Now, clear any trace of what records make up |
678 |
// Now, clear any trace of what records make up |
627 |
// the patriarch |
679 |
// the patriarch |
628 |
// Otherwise, everything will go horribly wrong |
680 |
// Otherwise, everything will go horribly wrong |
629 |
// when we try to write out again.... |
681 |
// when we try to write out again.... |
630 |
// clearEscherRecords(); |
682 |
// clearEscherRecords(); |
631 |
drawingManager.getDgg().setFileIdClusters(new EscherDggRecord.FileIdCluster[0]); |
683 |
drawingManager.getDgg().setFileIdClusters(new EscherDggRecord.FileIdCluster[0]); |
632 |
|
684 |
|
633 |
// TODO: Support converting our records |
685 |
// TODO: Support converting our records |
634 |
// back into shapes |
686 |
// back into shapes |
635 |
// log.log(POILogger.WARN, "Not processing objects into Patriarch!"); |
687 |
// log.log(POILogger.WARN, "Not processing objects into Patriarch!"); |
636 |
} |
688 |
} |
637 |
|
689 |
|
638 |
private static void convertRecordsToUserModelRecursive(List tcc, HSSFShapeContainer container, HSSFShape parent) { |
690 |
private static void convertRecordsToUserModelRecursive(List tcc, HSSFShapeContainer container, HSSFShape parent) { |
639 |
// Now process the containers for each group |
691 |
// Now process the containers for each group |
640 |
// and objects |
692 |
// and objects |
641 |
for(int i=1; i<tcc.size(); i++) { |
693 |
for (int i = 1; i < tcc.size(); i++) { |
642 |
EscherContainerRecord shapeContainer = (EscherContainerRecord)tcc.get(i); |
694 |
EscherContainerRecord shapeContainer = (EscherContainerRecord) tcc.get(i); |
643 |
|
695 |
|
644 |
// Could be a group, or a base object |
696 |
// Could be a group, or a base object |
645 |
if (shapeContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) |
697 |
if (shapeContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) { |
646 |
{ |
|
|
647 |
// Group |
698 |
// Group |
648 |
final int shapeChildren = shapeContainer.getChildRecords().size(); |
699 |
final int shapeChildren = shapeContainer.getChildRecords().size(); |
649 |
if (shapeChildren > 0) |
700 |
if (shapeChildren > 0) { |
650 |
{ |
|
|
651 |
HSSFShapeGroup group = new HSSFShapeGroup( parent, new HSSFClientAnchor() ); |
701 |
HSSFShapeGroup group = new HSSFShapeGroup(parent, new HSSFClientAnchor()); |
652 |
addToParentOrContainer(group, container, parent); |
702 |
addToParentOrContainer(group, container, parent); |
653 |
|
703 |
|
654 |
EscherContainerRecord groupContainer = (EscherContainerRecord) shapeContainer.getChild( 0 ); |
704 |
EscherContainerRecord groupContainer = (EscherContainerRecord) shapeContainer.getChild(0); |
655 |
convertRecordsToUserModel( groupContainer, group ); |
705 |
convertRecordsToUserModel(groupContainer, group); |
656 |
|
706 |
|
657 |
if (shapeChildren>1){ |
707 |
if (shapeChildren > 1) { |
658 |
convertRecordsToUserModelRecursive(shapeContainer.getChildRecords(), container, group); |
708 |
convertRecordsToUserModelRecursive(shapeContainer.getChildRecords(), container, group); |
659 |
} |
709 |
} |
660 |
} else |
710 |
} else { |
661 |
{ |
|
|
662 |
log.log( POILogger.WARN, |
711 |
log.log(POILogger.WARN, |
663 |
"Found drawing group without children." ); |
712 |
"Found drawing group without children."); |
664 |
} |
713 |
} |
665 |
|
714 |
|
666 |
} else if (shapeContainer.getRecordId() == EscherContainerRecord.SP_CONTAINER) |
715 |
} else if (shapeContainer.getRecordId() == EscherContainerRecord.SP_CONTAINER) { |
667 |
{ |
|
|
668 |
EscherSpRecord spRecord = shapeContainer |
716 |
EscherSpRecord spRecord = shapeContainer |
669 |
.getChildById( EscherSpRecord.RECORD_ID ); |
717 |
.getChildById(EscherSpRecord.RECORD_ID); |
670 |
int type = spRecord.getShapeType(); |
718 |
int type = spRecord.getShapeType(); |
671 |
|
719 |
|
672 |
switch (type) |
720 |
switch (type) { |
673 |
{ |
|
|
674 |
case ST_TEXTBOX: |
721 |
case ST_TEXTBOX: |
675 |
HSSFTextbox box = new HSSFTextbox( parent, |
722 |
HSSFTextbox box = new HSSFTextbox(parent, |
676 |
new HSSFClientAnchor() ); |
723 |
new HSSFClientAnchor()); |
677 |
addToParentOrContainer(box, container, parent); |
724 |
addToParentOrContainer(box, container, parent); |
678 |
|
725 |
|
679 |
convertRecordsToUserModel( shapeContainer, box ); |
726 |
convertRecordsToUserModel(shapeContainer, box); |
680 |
break; |
727 |
break; |
681 |
case ST_PICTUREFRAME: |
728 |
case ST_PICTUREFRAME: |
682 |
// Duplicated from |
729 |
// Duplicated from |
683 |
// org.apache.poi.hslf.model.Picture.getPictureIndex() |
730 |
// org.apache.poi.hslf.model.Picture.getPictureIndex() |
684 |
EscherOptRecord opt = (EscherOptRecord) getEscherChild( |
731 |
EscherOptRecord opt = (EscherOptRecord) getEscherChild( |
685 |
shapeContainer, EscherOptRecord.RECORD_ID ); |
732 |
shapeContainer, EscherOptRecord.RECORD_ID); |
686 |
EscherSimpleProperty prop = (EscherSimpleProperty)opt.lookup( |
733 |
EscherSimpleProperty prop = (EscherSimpleProperty) opt.lookup( |
687 |
EscherProperties.BLIP__BLIPTODISPLAY ); |
734 |
EscherProperties.BLIP__BLIPTODISPLAY); |
688 |
if (prop == null) |
735 |
if (prop == null) { |
689 |
{ |
|
|
690 |
log.log( POILogger.WARN, |
736 |
log.log(POILogger.WARN, |
691 |
"Picture index for picture shape not found." ); |
737 |
"Picture index for picture shape not found."); |
692 |
} else |
738 |
} else { |
693 |
{ |
|
|
694 |
int pictureIndex = prop.getPropertyValue(); |
739 |
int pictureIndex = prop.getPropertyValue(); |
695 |
|
740 |
|
696 |
EscherClientAnchorRecord anchorRecord = (EscherClientAnchorRecord) getEscherChild( |
741 |
EscherClientAnchorRecord anchorRecord = (EscherClientAnchorRecord) getEscherChild( |
697 |
shapeContainer, |
742 |
shapeContainer, |
698 |
EscherClientAnchorRecord.RECORD_ID ); |
743 |
EscherClientAnchorRecord.RECORD_ID); |
699 |
|
744 |
|
700 |
EscherChildAnchorRecord childRecord = (EscherChildAnchorRecord) getEscherChild( |
745 |
EscherChildAnchorRecord childRecord = (EscherChildAnchorRecord) getEscherChild( |
701 |
shapeContainer, |
746 |
shapeContainer, |
702 |
EscherChildAnchorRecord.RECORD_ID ); |
747 |
EscherChildAnchorRecord.RECORD_ID); |
703 |
|
748 |
|
704 |
if (anchorRecord!=null && childRecord!=null){ |
749 |
if (anchorRecord != null && childRecord != null) { |
705 |
log.log( POILogger.WARN, "Picture with both CLIENT and CHILD anchor: "+ type ); |
750 |
log.log(POILogger.WARN, "Picture with both CLIENT and CHILD anchor: " + type); |
706 |
} |
751 |
} |
707 |
|
752 |
|
708 |
HSSFAnchor anchor; |
753 |
HSSFAnchor anchor; |
709 |
if (anchorRecord!=null){ |
754 |
if (anchorRecord != null) { |
710 |
anchor = toClientAnchor(anchorRecord); |
755 |
anchor = toClientAnchor(anchorRecord); |
711 |
}else{ |
756 |
} else { |
712 |
anchor = toChildAnchor(childRecord); |
757 |
anchor = toChildAnchor(childRecord); |
713 |
} |
758 |
} |
714 |
|
759 |
|
715 |
HSSFPicture picture = new HSSFPicture( parent, anchor ); |
760 |
HSSFPicture picture = new HSSFPicture(parent, anchor); |
716 |
picture.setPictureIndex( pictureIndex ); |
761 |
picture.setPictureIndex(pictureIndex); |
717 |
|
762 |
|
718 |
addToParentOrContainer(picture, container, parent); |
763 |
addToParentOrContainer(picture, container, parent); |
719 |
} |
764 |
} |
720 |
break; |
765 |
break; |
721 |
default: |
766 |
default: |
722 |
final HSSFSimpleShape shape = new HSSFSimpleShape( parent, |
767 |
final HSSFSimpleShape shape = new HSSFSimpleShape(parent, |
723 |
new HSSFClientAnchor() ); |
768 |
new HSSFClientAnchor()); |
724 |
addToParentOrContainer(shape, container, parent); |
769 |
addToParentOrContainer(shape, container, parent); |
725 |
convertRecordsToUserModel( shapeContainer, shape); |
770 |
convertRecordsToUserModel(shapeContainer, shape); |
726 |
|
771 |
|
727 |
log.log( POILogger.WARN, "Unhandled shape type: " |
772 |
log.log(POILogger.WARN, "Unhandled shape type: " |
728 |
+ type ); |
773 |
+ type); |
729 |
break; |
774 |
break; |
730 |
} |
775 |
} |
731 |
} else |
776 |
} else { |
732 |
{ |
|
|
733 |
log.log( POILogger.WARN, "Unexpected record id of shape group." ); |
777 |
log.log(POILogger.WARN, "Unexpected record id of shape group."); |
734 |
} |
778 |
} |
735 |
|
779 |
|
736 |
} |
780 |
} |
737 |
} |
781 |
} |
738 |
|
782 |
|
739 |
private static void addToParentOrContainer(HSSFShape shape, HSSFShapeContainer container, HSSFShape parent) { |
783 |
private static void addToParentOrContainer(HSSFShape shape, HSSFShapeContainer container, HSSFShape parent) { |
740 |
|
784 |
|
741 |
if (parent instanceof HSSFShapeGroup) |
785 |
if (parent instanceof HSSFShapeGroup) |
742 |
((HSSFShapeGroup) parent).addShape(shape); |
786 |
((HSSFShapeGroup) parent).addShape(shape); |
743 |
else if (container instanceof HSSFPatriarch) |
787 |
else if (container instanceof HSSFPatriarch) |
744 |
((HSSFPatriarch) container).addShape(shape); |
788 |
((HSSFPatriarch) container).addShape(shape); |
745 |
else |
789 |
else |
746 |
container.getChildren().add(shape); |
790 |
container.getChildren().add(shape); |
747 |
} |
791 |
} |
748 |
|
792 |
|
749 |
private static HSSFClientAnchor toClientAnchor(EscherClientAnchorRecord anchorRecord){ |
793 |
private static HSSFClientAnchor toClientAnchor(EscherClientAnchorRecord anchorRecord) { |
750 |
HSSFClientAnchor anchor = new HSSFClientAnchor(); |
794 |
HSSFClientAnchor anchor = new HSSFClientAnchor(); |
751 |
anchor.setAnchorType(anchorRecord.getFlag()); |
795 |
anchor.setAnchorType(anchorRecord.getFlag()); |
752 |
anchor.setCol1( anchorRecord.getCol1() ); |
796 |
anchor.setCol1(anchorRecord.getCol1()); |
753 |
anchor.setCol2( anchorRecord.getCol2() ); |
797 |
anchor.setCol2(anchorRecord.getCol2()); |
754 |
anchor.setDx1( anchorRecord.getDx1() ); |
798 |
anchor.setDx1(anchorRecord.getDx1()); |
755 |
anchor.setDx2( anchorRecord.getDx2() ); |
799 |
anchor.setDx2(anchorRecord.getDx2()); |
756 |
anchor.setDy1( anchorRecord.getDy1() ); |
800 |
anchor.setDy1(anchorRecord.getDy1()); |
757 |
anchor.setDy2( anchorRecord.getDy2() ); |
801 |
anchor.setDy2(anchorRecord.getDy2()); |
758 |
anchor.setRow1( anchorRecord.getRow1() ); |
802 |
anchor.setRow1(anchorRecord.getRow1()); |
759 |
anchor.setRow2( anchorRecord.getRow2() ); |
803 |
anchor.setRow2(anchorRecord.getRow2()); |
760 |
return anchor; |
804 |
return anchor; |
761 |
} |
805 |
} |
762 |
|
806 |
|
763 |
private static HSSFChildAnchor toChildAnchor(EscherChildAnchorRecord anchorRecord){ |
807 |
private static HSSFChildAnchor toChildAnchor(EscherChildAnchorRecord anchorRecord) { |
764 |
HSSFChildAnchor anchor = new HSSFChildAnchor(); |
808 |
HSSFChildAnchor anchor = new HSSFChildAnchor(); |
765 |
// anchor.setAnchorType(anchorRecord.getFlag()); |
809 |
// anchor.setAnchorType(anchorRecord.getFlag()); |
766 |
// anchor.setCol1( anchorRecord.getCol1() ); |
810 |
// anchor.setCol1( anchorRecord.getCol1() ); |
767 |
// anchor.setCol2( anchorRecord.getCol2() ); |
811 |
// anchor.setCol2( anchorRecord.getCol2() ); |
768 |
anchor.setDx1( anchorRecord.getDx1() ); |
812 |
anchor.setDx1(anchorRecord.getDx1()); |
769 |
anchor.setDx2( anchorRecord.getDx2() ); |
813 |
anchor.setDx2(anchorRecord.getDx2()); |
770 |
anchor.setDy1( anchorRecord.getDy1() ); |
814 |
anchor.setDy1(anchorRecord.getDy1()); |
771 |
anchor.setDy2( anchorRecord.getDy2() ); |
815 |
anchor.setDy2(anchorRecord.getDy2()); |
772 |
// anchor.setRow1( anchorRecord.getRow1() ); |
816 |
// anchor.setRow1( anchorRecord.getRow1() ); |
773 |
// anchor.setRow2( anchorRecord.getRow2() ); |
817 |
// anchor.setRow2( anchorRecord.getRow2() ); |
774 |
return anchor; |
818 |
return anchor; |
775 |
} |
819 |
} |
776 |
|
820 |
|
777 |
private static void convertRecordsToUserModel(EscherContainerRecord shapeContainer, Object model) { |
821 |
private static void convertRecordsToUserModel(EscherContainerRecord shapeContainer, Object model) { |
778 |
for(Iterator<EscherRecord> it = shapeContainer.getChildIterator(); it.hasNext();) { |
822 |
for (Iterator<EscherRecord> it = shapeContainer.getChildIterator(); it.hasNext(); ) { |
779 |
EscherRecord r = it.next(); |
823 |
EscherRecord r = it.next(); |
780 |
if(r instanceof EscherSpgrRecord) { |
824 |
if (r instanceof EscherSpgrRecord) { |
781 |
// This may be overriden by a later EscherClientAnchorRecord |
825 |
// This may be overriden by a later EscherClientAnchorRecord |
782 |
EscherSpgrRecord spgr = (EscherSpgrRecord)r; |
826 |
EscherSpgrRecord spgr = (EscherSpgrRecord) r; |
783 |
|
827 |
|
784 |
if(model instanceof HSSFShapeGroup) { |
828 |
if (model instanceof HSSFShapeGroup) { |
785 |
HSSFShapeGroup g = (HSSFShapeGroup)model; |
829 |
HSSFShapeGroup g = (HSSFShapeGroup) model; |
786 |
g.setCoordinates( |
830 |
g.setCoordinates( |
787 |
spgr.getRectX1(), spgr.getRectY1(), |
831 |
spgr.getRectX1(), spgr.getRectY1(), |
788 |
spgr.getRectX2(), spgr.getRectY2() |
832 |
spgr.getRectX2(), spgr.getRectY2() |
789 |
); |
833 |
); |
790 |
} else { |
834 |
} else { |
791 |
throw new IllegalStateException("Got top level anchor but not processing a group"); |
835 |
throw new IllegalStateException("Got top level anchor but not processing a group"); |
792 |
} |
836 |
} |
793 |
} |
837 |
} else if (r instanceof EscherClientAnchorRecord) { |
794 |
else if(r instanceof EscherClientAnchorRecord) { |
|
|
795 |
EscherClientAnchorRecord car = (EscherClientAnchorRecord)r; |
838 |
EscherClientAnchorRecord car = (EscherClientAnchorRecord) r; |
796 |
|
839 |
|
797 |
if(model instanceof HSSFShape) { |
840 |
if (model instanceof HSSFShape) { |
798 |
HSSFShape g = (HSSFShape)model; |
841 |
HSSFShape g = (HSSFShape) model; |
799 |
g.getAnchor().setDx1(car.getDx1()); |
842 |
g.getAnchor().setDx1(car.getDx1()); |
800 |
g.getAnchor().setDx2(car.getDx2()); |
843 |
g.getAnchor().setDx2(car.getDx2()); |
801 |
g.getAnchor().setDy1(car.getDy1()); |
844 |
g.getAnchor().setDy1(car.getDy1()); |
802 |
g.getAnchor().setDy2(car.getDy2()); |
845 |
g.getAnchor().setDy2(car.getDy2()); |
803 |
} else { |
846 |
} else { |
804 |
throw new IllegalStateException("Got top level anchor but not processing a group or shape"); |
847 |
throw new IllegalStateException("Got top level anchor but not processing a group or shape"); |
805 |
} |
848 |
} |
806 |
} |
849 |
} else if (r instanceof EscherTextboxRecord) { |
807 |
else if(r instanceof EscherTextboxRecord) { |
|
|
808 |
EscherTextboxRecord tbr = (EscherTextboxRecord)r; |
850 |
EscherTextboxRecord tbr = (EscherTextboxRecord) r; |
809 |
|
851 |
|
810 |
// Also need to find the TextObjectRecord too |
852 |
// Also need to find the TextObjectRecord too |
811 |
// TODO |
853 |
// TODO |
812 |
} |
854 |
} else if (r instanceof EscherSpRecord) { |
813 |
else if(r instanceof EscherSpRecord) { |
|
|
814 |
// Use flags if needed |
855 |
// Use flags if needed |
815 |
final EscherSpRecord spr = (EscherSpRecord) r; |
856 |
final EscherSpRecord spr = (EscherSpRecord) r; |
816 |
if (model instanceof HSSFShape){ |
857 |
if (model instanceof HSSFShape) { |
817 |
final HSSFShape s = (HSSFShape) model; |
858 |
final HSSFShape s = (HSSFShape) model; |
818 |
} |
859 |
} |
819 |
} |
860 |
} else if (r instanceof EscherOptRecord) { |
820 |
else if(r instanceof EscherOptRecord) { |
|
|
821 |
// Use properties if needed |
861 |
// Use properties if needed |
822 |
} |
862 |
} else { |
823 |
else { |
|
|
824 |
//System.err.println(r); |
863 |
//System.err.println(r); |
825 |
} |
864 |
} |
826 |
} |
865 |
} |
827 |
} |
866 |
} |
828 |
|
867 |
|
829 |
public void clear() |
868 |
public void clear() { |
830 |
{ |
|
|
831 |
clearEscherRecords(); |
869 |
clearEscherRecords(); |
832 |
shapeToObj.clear(); |
870 |
shapeToObj.clear(); |
833 |
// lastShapeId = 1024; |
871 |
// lastShapeId = 1024; |
834 |
} |
872 |
} |
835 |
|
873 |
|
836 |
protected String getRecordName() |
874 |
protected String getRecordName() { |
837 |
{ |
|
|
838 |
return "ESCHERAGGREGATE"; |
875 |
return "ESCHERAGGREGATE"; |
839 |
} |
876 |
} |
840 |
|
877 |
|
841 |
// =============== Private methods ======================== |
878 |
// =============== Private methods ======================== |
842 |
|
879 |
|
843 |
private static boolean isObjectRecord( List records, int loc ) |
880 |
private static boolean isObjectRecord(List records, int loc) { |
844 |
{ |
|
|
845 |
return sid( records, loc ) == ObjRecord.sid || sid( records, loc ) == TextObjectRecord.sid; |
881 |
return sid(records, loc) == ObjRecord.sid || sid(records, loc) == TextObjectRecord.sid; |
846 |
} |
882 |
} |
847 |
|
883 |
|
848 |
private void convertUserModelToRecords() |
884 |
private void convertUserModelToRecords() { |
849 |
{ |
885 |
if (patriarch != null) { |
850 |
if ( patriarch != null ) |
|
|
851 |
{ |
852 |
shapeToObj.clear(); |
886 |
shapeToObj.clear(); |
853 |
tailRec.clear(); |
887 |
tailRec.clear(); |
854 |
clearEscherRecords(); |
888 |
clearEscherRecords(); |
855 |
if ( patriarch.getChildren().size() != 0 ) |
889 |
if (patriarch.getChildren().size() != 0) { |
856 |
{ |
|
|
857 |
convertPatriarch( patriarch ); |
890 |
convertPatriarch(patriarch); |
858 |
EscherContainerRecord dgContainer = (EscherContainerRecord) getEscherRecord( 0 ); |
891 |
EscherContainerRecord dgContainer = (EscherContainerRecord) getEscherRecord(0); |
859 |
EscherContainerRecord spgrContainer = null; |
892 |
EscherContainerRecord spgrContainer = null; |
860 |
Iterator<EscherRecord> iter = dgContainer.getChildIterator(); |
893 |
Iterator<EscherRecord> iter = dgContainer.getChildIterator(); |
861 |
while (iter.hasNext()) { |
894 |
while (iter.hasNext()) { |
862 |
EscherRecord child = iter.next(); |
895 |
EscherRecord child = iter.next(); |
863 |
if (child.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) { |
896 |
if (child.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) { |
864 |
spgrContainer = (EscherContainerRecord) child; |
897 |
spgrContainer = (EscherContainerRecord) child; |
865 |
} |
898 |
} |
866 |
} |
899 |
} |
867 |
convertShapes( patriarch, spgrContainer, shapeToObj ); |
900 |
convertShapes(patriarch, spgrContainer, shapeToObj); |
868 |
|
901 |
|
869 |
patriarch = null; |
902 |
patriarch = null; |
870 |
} |
903 |
} |
871 |
} |
904 |
} |
872 |
} |
905 |
} |
873 |
|
906 |
|
874 |
private void convertShapes( HSSFShapeContainer parent, EscherContainerRecord escherParent, Map shapeToObj ) |
907 |
private void convertShapes(HSSFShapeContainer parent, EscherContainerRecord escherParent, Map shapeToObj) { |
875 |
{ |
|
|
876 |
if ( escherParent == null ) throw new IllegalArgumentException( "Parent record required" ); |
908 |
if (escherParent == null) throw new IllegalArgumentException("Parent record required"); |
877 |
|
909 |
|
878 |
List shapes = parent.getChildren(); |
910 |
List shapes = parent.getChildren(); |
879 |
for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); ) |
911 |
for (Iterator iterator = shapes.iterator(); iterator.hasNext(); ) { |
880 |
{ |
|
|
881 |
HSSFShape shape = (HSSFShape) iterator.next(); |
912 |
HSSFShape shape = (HSSFShape) iterator.next(); |
882 |
if ( shape instanceof HSSFShapeGroup ) |
913 |
if (shape instanceof HSSFShapeGroup) { |
883 |
{ |
|
|
884 |
convertGroup( (HSSFShapeGroup) shape, escherParent, shapeToObj ); |
914 |
convertGroup((HSSFShapeGroup) shape, escherParent, shapeToObj); |
885 |
} |
915 |
} else { |
886 |
else |
|
|
887 |
{ |
888 |
AbstractShape shapeModel = AbstractShape.createShape( |
916 |
AbstractShape shapeModel = AbstractShape.createShape( |
889 |
shape, |
917 |
shape, |
890 |
drawingManager.allocateShapeId(drawingGroupId) ); |
918 |
drawingManager.allocateShapeId(drawingGroupId)); |
891 |
shapeToObj.put( findClientData( shapeModel.getSpContainer() ), shapeModel.getObjRecord() ); |
919 |
shapeToObj.put(findClientData(shapeModel.getSpContainer()), shapeModel.getObjRecord()); |
892 |
if ( shapeModel instanceof TextboxShape ) |
920 |
if (shapeModel instanceof TextboxShape) { |
893 |
{ |
|
|
894 |
EscherRecord escherTextbox = ( (TextboxShape) shapeModel ).getEscherTextbox(); |
921 |
EscherRecord escherTextbox = ((TextboxShape) shapeModel).getEscherTextbox(); |
895 |
shapeToObj.put( escherTextbox, ( (TextboxShape) shapeModel ).getTextObjectRecord() ); |
922 |
shapeToObj.put(escherTextbox, ((TextboxShape) shapeModel).getTextObjectRecord()); |
896 |
// escherParent.addChildRecord(escherTextbox); |
923 |
// escherParent.addChildRecord(escherTextbox); |
897 |
|
924 |
|
898 |
if ( shapeModel instanceof CommentShape ){ |
925 |
if (shapeModel instanceof CommentShape) { |
899 |
CommentShape comment = (CommentShape)shapeModel; |
926 |
CommentShape comment = (CommentShape) shapeModel; |
900 |
tailRec.add(comment.getNoteRecord()); |
927 |
tailRec.add(comment.getNoteRecord()); |
901 |
} |
928 |
} |
902 |
|
929 |
|
903 |
} |
930 |
} |
904 |
escherParent.addChildRecord( shapeModel.getSpContainer() ); |
931 |
escherParent.addChildRecord(shapeModel.getSpContainer()); |
905 |
} |
932 |
} |
906 |
} |
933 |
} |
907 |
// drawingManager.newCluster( (short)1 ); |
934 |
// drawingManager.newCluster( (short)1 ); |
908 |
// drawingManager.newCluster( (short)2 ); |
935 |
// drawingManager.newCluster( (short)2 ); |
909 |
|
936 |
|
910 |
} |
937 |
} |
911 |
|
938 |
|
912 |
private void convertGroup( HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj ) |
939 |
private void convertGroup(HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj) { |
913 |
{ |
|
|
914 |
EscherContainerRecord spgrContainer = new EscherContainerRecord(); |
940 |
EscherContainerRecord spgrContainer = new EscherContainerRecord(); |
915 |
EscherContainerRecord spContainer = new EscherContainerRecord(); |
941 |
EscherContainerRecord spContainer = new EscherContainerRecord(); |
916 |
EscherSpgrRecord spgr = new EscherSpgrRecord(); |
942 |
EscherSpgrRecord spgr = new EscherSpgrRecord(); |
917 |
EscherSpRecord sp = new EscherSpRecord(); |
943 |
EscherSpRecord sp = new EscherSpRecord(); |
918 |
EscherOptRecord opt = new EscherOptRecord(); |
944 |
EscherOptRecord opt = new EscherOptRecord(); |
919 |
EscherRecord anchor; |
945 |
EscherRecord anchor; |
920 |
EscherClientDataRecord clientData = new EscherClientDataRecord(); |
946 |
EscherClientDataRecord clientData = new EscherClientDataRecord(); |
921 |
|
947 |
|
922 |
spgrContainer.setRecordId( EscherContainerRecord.SPGR_CONTAINER ); |
948 |
spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); |
923 |
spgrContainer.setOptions( (short) 0x000F ); |
949 |
spgrContainer.setOptions((short) 0x000F); |
924 |
spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER ); |
950 |
spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER); |
925 |
spContainer.setOptions( (short) 0x000F ); |
951 |
spContainer.setOptions((short) 0x000F); |
926 |
spgr.setRecordId( EscherSpgrRecord.RECORD_ID ); |
952 |
spgr.setRecordId(EscherSpgrRecord.RECORD_ID); |
927 |
spgr.setOptions( (short) 0x0001 ); |
953 |
spgr.setOptions((short) 0x0001); |
928 |
spgr.setRectX1( shape.getX1() ); |
954 |
spgr.setRectX1(shape.getX1()); |
929 |
spgr.setRectY1( shape.getY1() ); |
955 |
spgr.setRectY1(shape.getY1()); |
930 |
spgr.setRectX2( shape.getX2() ); |
956 |
spgr.setRectX2(shape.getX2()); |
931 |
spgr.setRectY2( shape.getY2() ); |
957 |
spgr.setRectY2(shape.getY2()); |
932 |
sp.setRecordId( EscherSpRecord.RECORD_ID ); |
958 |
sp.setRecordId(EscherSpRecord.RECORD_ID); |
933 |
sp.setOptions( (short) 0x0002 ); |
959 |
sp.setOptions((short) 0x0002); |
934 |
int shapeId = drawingManager.allocateShapeId(drawingGroupId); |
960 |
int shapeId = drawingManager.allocateShapeId(drawingGroupId); |
935 |
sp.setShapeId( shapeId ); |
961 |
sp.setShapeId(shapeId); |
936 |
if (shape.getAnchor() instanceof HSSFClientAnchor) |
962 |
if (shape.getAnchor() instanceof HSSFClientAnchor) |
937 |
sp.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR ); |
963 |
sp.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR); |
938 |
else |
964 |
else |
939 |
sp.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_CHILD ); |
965 |
sp.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_CHILD); |
940 |
opt.setRecordId( EscherOptRecord.RECORD_ID ); |
966 |
opt.setRecordId(EscherOptRecord.RECORD_ID); |
941 |
opt.setOptions( (short) 0x0023 ); |
967 |
opt.setOptions((short) 0x0023); |
942 |
opt.addEscherProperty( new EscherBoolProperty( EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00040004 ) ); |
968 |
opt.addEscherProperty(new EscherBoolProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00040004)); |
943 |
opt.addEscherProperty( new EscherBoolProperty( EscherProperties.GROUPSHAPE__PRINT, 0x00080000 ) ); |
969 |
opt.addEscherProperty(new EscherBoolProperty(EscherProperties.GROUPSHAPE__PRINT, 0x00080000)); |
944 |
|
970 |
|
945 |
anchor = ConvertAnchor.createAnchor( shape.getAnchor() ); |
971 |
anchor = ConvertAnchor.createAnchor(shape.getAnchor()); |
946 |
// clientAnchor.setCol1( ( (HSSFClientAnchor) shape.getAnchor() ).getCol1() ); |
972 |
// clientAnchor.setCol1( ( (HSSFClientAnchor) shape.getAnchor() ).getCol1() ); |
947 |
// clientAnchor.setRow1( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow1() ); |
973 |
// clientAnchor.setRow1( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow1() ); |
948 |
// clientAnchor.setDx1( (short) shape.getAnchor().getDx1() ); |
974 |
// clientAnchor.setDx1( (short) shape.getAnchor().getDx1() ); |
Lines 951-1063
Link Here
|
951 |
// clientAnchor.setRow2( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow2() ); |
977 |
// clientAnchor.setRow2( (short) ( (HSSFClientAnchor) shape.getAnchor() ).getRow2() ); |
952 |
// clientAnchor.setDx2( (short) shape.getAnchor().getDx2() ); |
978 |
// clientAnchor.setDx2( (short) shape.getAnchor().getDx2() ); |
953 |
// clientAnchor.setDy2( (short) shape.getAnchor().getDy2() ); |
979 |
// clientAnchor.setDy2( (short) shape.getAnchor().getDy2() ); |
954 |
clientData.setRecordId( EscherClientDataRecord.RECORD_ID ); |
980 |
clientData.setRecordId(EscherClientDataRecord.RECORD_ID); |
955 |
clientData.setOptions( (short) 0x0000 ); |
981 |
clientData.setOptions((short) 0x0000); |
956 |
|
982 |
|
957 |
spgrContainer.addChildRecord( spContainer ); |
983 |
spgrContainer.addChildRecord(spContainer); |
958 |
spContainer.addChildRecord( spgr ); |
984 |
spContainer.addChildRecord(spgr); |
959 |
spContainer.addChildRecord( sp ); |
985 |
spContainer.addChildRecord(sp); |
960 |
spContainer.addChildRecord( opt ); |
986 |
spContainer.addChildRecord(opt); |
961 |
spContainer.addChildRecord( anchor ); |
987 |
spContainer.addChildRecord(anchor); |
962 |
spContainer.addChildRecord( clientData ); |
988 |
spContainer.addChildRecord(clientData); |
963 |
|
989 |
|
964 |
ObjRecord obj = new ObjRecord(); |
990 |
ObjRecord obj = new ObjRecord(); |
965 |
CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord(); |
991 |
CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord(); |
966 |
cmo.setObjectType( CommonObjectDataSubRecord.OBJECT_TYPE_GROUP ); |
992 |
cmo.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_GROUP); |
967 |
cmo.setObjectId( shapeId ); |
993 |
cmo.setObjectId(shapeId); |
968 |
cmo.setLocked( true ); |
994 |
cmo.setLocked(true); |
969 |
cmo.setPrintable( true ); |
995 |
cmo.setPrintable(true); |
970 |
cmo.setAutofill( true ); |
996 |
cmo.setAutofill(true); |
971 |
cmo.setAutoline( true ); |
997 |
cmo.setAutoline(true); |
972 |
GroupMarkerSubRecord gmo = new GroupMarkerSubRecord(); |
998 |
GroupMarkerSubRecord gmo = new GroupMarkerSubRecord(); |
973 |
EndSubRecord end = new EndSubRecord(); |
999 |
EndSubRecord end = new EndSubRecord(); |
974 |
obj.addSubRecord( cmo ); |
1000 |
obj.addSubRecord(cmo); |
975 |
obj.addSubRecord( gmo ); |
1001 |
obj.addSubRecord(gmo); |
976 |
obj.addSubRecord( end ); |
1002 |
obj.addSubRecord(end); |
977 |
shapeToObj.put( clientData, obj ); |
1003 |
shapeToObj.put(clientData, obj); |
978 |
|
1004 |
|
979 |
escherParent.addChildRecord( spgrContainer ); |
1005 |
escherParent.addChildRecord(spgrContainer); |
980 |
|
1006 |
|
981 |
convertShapes( shape, spgrContainer, shapeToObj ); |
1007 |
convertShapes(shape, spgrContainer, shapeToObj); |
982 |
|
1008 |
|
983 |
} |
1009 |
} |
984 |
|
1010 |
|
985 |
private EscherRecord findClientData( EscherContainerRecord spContainer ) |
1011 |
private EscherRecord findClientData(EscherContainerRecord spContainer) { |
986 |
{ |
|
|
987 |
for (Iterator<EscherRecord> iterator = spContainer.getChildIterator(); iterator.hasNext();) { |
1012 |
for (Iterator<EscherRecord> iterator = spContainer.getChildIterator(); iterator.hasNext(); ) { |
988 |
EscherRecord r = iterator.next(); |
1013 |
EscherRecord r = iterator.next(); |
989 |
if (r.getRecordId() == EscherClientDataRecord.RECORD_ID) { |
1014 |
if (r.getRecordId() == EscherClientDataRecord.RECORD_ID) { |
990 |
return r; |
1015 |
return r; |
991 |
} |
1016 |
} |
992 |
} |
1017 |
} |
993 |
throw new IllegalArgumentException( "Can not find client data record" ); |
1018 |
throw new IllegalArgumentException("Can not find client data record"); |
994 |
} |
1019 |
} |
995 |
|
1020 |
|
996 |
private void convertPatriarch( HSSFPatriarch patriarch ) |
1021 |
private void convertPatriarch(HSSFPatriarch patriarch) { |
997 |
{ |
|
|
998 |
EscherContainerRecord dgContainer = new EscherContainerRecord(); |
1022 |
EscherContainerRecord dgContainer = new EscherContainerRecord(); |
999 |
EscherDgRecord dg; |
1023 |
EscherDgRecord dg; |
1000 |
EscherContainerRecord spgrContainer = new EscherContainerRecord(); |
1024 |
EscherContainerRecord spgrContainer = new EscherContainerRecord(); |
1001 |
EscherContainerRecord spContainer1 = new EscherContainerRecord(); |
1025 |
EscherContainerRecord spContainer1 = new EscherContainerRecord(); |
1002 |
EscherSpgrRecord spgr = new EscherSpgrRecord(); |
1026 |
EscherSpgrRecord spgr = new EscherSpgrRecord(); |
1003 |
EscherSpRecord sp1 = new EscherSpRecord(); |
1027 |
EscherSpRecord sp1 = new EscherSpRecord(); |
1004 |
|
1028 |
|
1005 |
dgContainer.setRecordId( EscherContainerRecord.DG_CONTAINER ); |
1029 |
dgContainer.setRecordId(EscherContainerRecord.DG_CONTAINER); |
1006 |
dgContainer.setOptions( (short) 0x000F ); |
1030 |
dgContainer.setOptions((short) 0x000F); |
1007 |
dg = drawingManager.createDgRecord(); |
1031 |
dg = drawingManager.createDgRecord(); |
1008 |
drawingGroupId = dg.getDrawingGroupId(); |
1032 |
drawingGroupId = dg.getDrawingGroupId(); |
1009 |
// dg.setOptions( (short) ( drawingId << 4 ) ); |
1033 |
// dg.setOptions( (short) ( drawingId << 4 ) ); |
1010 |
// dg.setNumShapes( getNumberOfShapes( patriarch ) ); |
1034 |
// dg.setNumShapes( getNumberOfShapes( patriarch ) ); |
1011 |
// dg.setLastMSOSPID( 0 ); // populated after all shape id's are assigned. |
1035 |
// dg.setLastMSOSPID( 0 ); // populated after all shape id's are assigned. |
1012 |
spgrContainer.setRecordId( EscherContainerRecord.SPGR_CONTAINER ); |
1036 |
spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER); |
1013 |
spgrContainer.setOptions( (short) 0x000F ); |
1037 |
spgrContainer.setOptions((short) 0x000F); |
1014 |
spContainer1.setRecordId( EscherContainerRecord.SP_CONTAINER ); |
1038 |
spContainer1.setRecordId(EscherContainerRecord.SP_CONTAINER); |
1015 |
spContainer1.setOptions( (short) 0x000F ); |
1039 |
spContainer1.setOptions((short) 0x000F); |
1016 |
spgr.setRecordId( EscherSpgrRecord.RECORD_ID ); |
1040 |
spgr.setRecordId(EscherSpgrRecord.RECORD_ID); |
1017 |
spgr.setOptions( (short) 0x0001 ); // version |
1041 |
spgr.setOptions((short) 0x0001); // version |
1018 |
spgr.setRectX1( patriarch.getX1() ); |
1042 |
spgr.setRectX1(patriarch.getX1()); |
1019 |
spgr.setRectY1( patriarch.getY1() ); |
1043 |
spgr.setRectY1(patriarch.getY1()); |
1020 |
spgr.setRectX2( patriarch.getX2() ); |
1044 |
spgr.setRectX2(patriarch.getX2()); |
1021 |
spgr.setRectY2( patriarch.getY2() ); |
1045 |
spgr.setRectY2(patriarch.getY2()); |
1022 |
sp1.setRecordId( EscherSpRecord.RECORD_ID ); |
1046 |
sp1.setRecordId(EscherSpRecord.RECORD_ID); |
1023 |
sp1.setOptions( (short) 0x0002 ); |
1047 |
sp1.setOptions((short) 0x0002); |
1024 |
sp1.setShapeId( drawingManager.allocateShapeId(dg.getDrawingGroupId()) ); |
1048 |
sp1.setShapeId(drawingManager.allocateShapeId(dg.getDrawingGroupId())); |
1025 |
sp1.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_PATRIARCH ); |
1049 |
sp1.setFlags(EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_PATRIARCH); |
1026 |
|
1050 |
|
1027 |
dgContainer.addChildRecord( dg ); |
1051 |
dgContainer.addChildRecord(dg); |
1028 |
dgContainer.addChildRecord( spgrContainer ); |
1052 |
dgContainer.addChildRecord(spgrContainer); |
1029 |
spgrContainer.addChildRecord( spContainer1 ); |
1053 |
spgrContainer.addChildRecord(spContainer1); |
1030 |
spContainer1.addChildRecord( spgr ); |
1054 |
spContainer1.addChildRecord(spgr); |
1031 |
spContainer1.addChildRecord( sp1 ); |
1055 |
spContainer1.addChildRecord(sp1); |
1032 |
|
1056 |
|
1033 |
addEscherRecord( dgContainer ); |
1057 |
addEscherRecord(dgContainer); |
1034 |
} |
1058 |
} |
1035 |
|
1059 |
|
1036 |
|
1060 |
|
1037 |
private static short sid( List records, int loc ) |
1061 |
private static short sid(List records, int loc) { |
1038 |
{ |
|
|
1039 |
return ( (Record) records.get( loc ) ).getSid(); |
1062 |
return ((Record) records.get(loc)).getSid(); |
1040 |
} |
1063 |
} |
1041 |
|
1064 |
|
1042 |
|
1065 |
|
1043 |
// Duplicated from org.apache.poi.hslf.model.Shape |
1066 |
// Duplicated from org.apache.poi.hslf.model.Shape |
1044 |
|
1067 |
|
1045 |
/** |
1068 |
/** |
1046 |
* Helper method to return escher child by record ID |
1069 |
* Helper method to return escher child by record ID |
1047 |
* |
1070 |
* |
1048 |
* @return escher record or <code>null</code> if not found. |
1071 |
* @return escher record or <code>null</code> if not found. |
1049 |
*/ |
1072 |
*/ |
1050 |
private static EscherRecord getEscherChild(EscherContainerRecord owner, |
1073 |
private static EscherRecord getEscherChild(EscherContainerRecord owner, |
1051 |
int recordId) |
1074 |
int recordId) { |
1052 |
{ |
|
|
1053 |
for (Iterator iterator = owner.getChildRecords().iterator(); iterator |
1075 |
for (Iterator iterator = owner.getChildRecords().iterator(); iterator |
1054 |
.hasNext();) |
1076 |
.hasNext(); ) { |
1055 |
{ |
|
|
1056 |
EscherRecord escherRecord = (EscherRecord) iterator.next(); |
1077 |
EscherRecord escherRecord = (EscherRecord) iterator.next(); |
1057 |
if (escherRecord.getRecordId() == recordId) |
1078 |
if (escherRecord.getRecordId() == recordId) |
1058 |
return escherRecord; |
1079 |
return escherRecord; |
1059 |
} |
1080 |
} |
1060 |
return null; |
1081 |
return null; |
1061 |
} |
1082 |
} |
1062 |
|
1083 |
|
1063 |
} |
1084 |
} |