1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package org.openoffice.xmerge.converter.xml.sxw.wordsmith;
25 
26 import java.io.IOException;
27 
28 import org.w3c.dom.NodeList;
29 import org.w3c.dom.Node;
30 import org.w3c.dom.NamedNodeMap;
31 import org.w3c.dom.Element;
32 
33 import org.openoffice.xmerge.Document;
34 import org.openoffice.xmerge.ConverterCapabilities;
35 import org.openoffice.xmerge.converter.xml.OfficeDocument;
36 import org.openoffice.xmerge.converter.xml.sxw.SxwDocument;
37 import org.openoffice.xmerge.converter.xml.*;
38 
39 
40 /**
41  *  This class represents a paragraph in a WordSmith document.
42  *  (A paragraph is "5" followed by 12 bytes of attributes.)
43  *
44  *  @author   David Proulx
45  */
46 class WsePara extends Wse {
47 
48     private byte spaceBefore = 0;
49     private byte spaceAfter = 0;
50     private byte leftIndent = 0;
51     private byte firstIndent = 0;
52     private byte rightIndent = 0;
53     private byte misc = 0;
54     private byte style = 0;
55     private byte lineSpace = 0;
56     private byte outline = 0;
57     private byte reserved = 0;
58 
59     private static final byte LS_EXACTLY   = (byte)0xC0;
60     private static final byte LS_ATLEAST   = (byte)0x80;
61     private static final byte LS_MULTIPLE  = (byte)0x40;
62     private static final byte LS_VALUEMASK = (byte)0x3F;
63 
64     private static final byte ALIGN_RIGHT  = (byte)2;
65     private static final byte ALIGN_LEFT   = (byte)0;
66     private static final byte ALIGN_CENTER = (byte)1;
67     private static final byte ALIGN_JUST   = (byte)3;
68 
69     private StyleCatalog sc = null;
70 
71 
72     /**
73      *  Constructor for use when going from DOM to WordSmith.
74      *
75      *  @param  p   The paragraph style.
76      *  @param  sc  The <code>StyleCatalog</code>.
77      */
WsePara(ParaStyle p, StyleCatalog sc)78     public WsePara(ParaStyle p, StyleCatalog sc) {
79         this.sc = sc;
80         ParaStyle ps = (ParaStyle)p.getResolved();
81 
82         if (ps.isAttributeSet(ParaStyle.MARGIN_LEFT)) {
83             double temp = ps.getAttribute(ParaStyle.MARGIN_LEFT) * 1.6 / 100;
84             leftIndent = (byte) temp;
85             if ((temp - leftIndent) > 0.5) leftIndent++;
86         }
87 
88         if (ps.isAttributeSet(ParaStyle.MARGIN_RIGHT)) {
89             double temp = ps.getAttribute(ParaStyle.MARGIN_RIGHT) * 1.6 / 100;
90             rightIndent = (byte) temp;
91             if ((temp - rightIndent) > 0.5) rightIndent++;
92         }
93 
94         if (ps.isAttributeSet(ParaStyle.TEXT_INDENT)) {
95             double temp = ps.getAttribute(ParaStyle.TEXT_INDENT) * 1.6 / 100;
96             firstIndent = (byte) temp;
97             if ((temp - firstIndent) > 0.5) firstIndent++;
98         }
99 
100         if (ps.isAttributeSet(ParaStyle.MARGIN_TOP)) {
101             double temp = ps.getAttribute(ParaStyle.MARGIN_TOP) * 1.6 / 100;
102             spaceBefore = (byte) temp;
103             if ((temp - spaceBefore) > 0.5) spaceBefore++;
104         }
105 
106         if (ps.isAttributeSet(ParaStyle.MARGIN_BOTTOM)) {
107             double temp = ps.getAttribute(ParaStyle.MARGIN_BOTTOM) * 1.6 / 100;
108             spaceAfter = (byte) temp;
109             if ((temp - spaceAfter) > 0.5) spaceAfter++;
110         }
111 
112         if (ps.isAttributeSet(ParaStyle.LINE_HEIGHT)) {
113             int lh = ps.getAttribute(ParaStyle.LINE_HEIGHT);
114             if ((lh & ~ParaStyle.LH_VALUEMASK) == 0)
115                 lineSpace = (byte)(LS_MULTIPLE | (lh * 2));
116             else if ((lh & ParaStyle.LH_PCT) != 0) {
117                 lh = (lh & ParaStyle.LH_VALUEMASK) / 100;
118                 lineSpace = (byte)(LS_MULTIPLE | (lh * 2));
119             }
120             // DJP: handle other cases....
121         }
122 
123         if (ps.isAttributeSet(ParaStyle.TEXT_ALIGN)) {
124 
125             int val = ps.getAttribute(ParaStyle.TEXT_ALIGN);
126 
127             switch (val) {
128             case ParaStyle.ALIGN_RIGHT:
129                 misc = ALIGN_RIGHT;
130                 break;
131             case ParaStyle.ALIGN_LEFT:
132                 misc = ALIGN_LEFT;
133                 break;
134             case ParaStyle.ALIGN_CENTER:
135                 misc = ALIGN_CENTER;
136                 break;
137             case ParaStyle.ALIGN_JUST:
138                 misc = ALIGN_JUST;
139                 break;
140             }
141         }
142 
143     }
144 
145 
146     /**
147      *  Constructor for use when going from WordSmith to DOM.
148      *  Assumes <code>dataArray[startIndex]</code> is the first
149      *  <code>byte</code> of a valid WordSmith paragraph descriptor.
150      *
151      *  @param  dataArray   <code>byte</code> array.
152      *  @param  startIndex  The start index.
153      */
WsePara(byte dataArray[], int startIndex)154     public WsePara(byte dataArray[], int startIndex) {
155         spaceBefore = dataArray[startIndex + 1];
156         spaceAfter  = dataArray[startIndex + 2];
157         leftIndent  = dataArray[startIndex + 3];
158         firstIndent = dataArray[startIndex + 4];
159         rightIndent = dataArray[startIndex + 5];
160         misc        = dataArray[startIndex + 6];
161         style       = dataArray[startIndex + 7];
162         lineSpace   = dataArray[startIndex + 8];
163         outline     = dataArray[startIndex + 9];
164     }
165 
166 
167     /**
168      *  Compute the index of the first <code>byte</code> following the
169      *  paragraph descriptor, assuming that
170      *  <code>dataArray[startIndex]</code> is the beginning of a valid
171      *  paragraph descriptor.
172      *
173      *  @param  dataArray   <code>byte</code> array.
174      *  @param  startIndex  The start index.
175      *
176      *  @return  The index of the first <code>byte</code> following the
177      *           paragraph description.
178      */
computeNewIndex(byte dataArray[], int startIndex)179     static int computeNewIndex(byte dataArray[], int startIndex) {
180         return startIndex + 13;
181     }
182 
183 
184     /**
185      *  Return true if <code>dataArray[startIndex]</code> is the start
186      *  of a valid paragraph descriptor.
187      *
188      *  @param  dataArray   <code>byte</code> array.
189      *  @param  startIndex  The start index.
190      *
191      *  @return  true if <code>dataArray[startIndex]</code> is the start
192      *           of a valid paragraph descriptor, false otherwise.
193      */
isValid(byte dataArray[], int startIndex)194     static boolean isValid(byte dataArray[], int startIndex) {
195         return (dataArray[startIndex] == 5);
196     }
197 
198     /**
199      *  Return the number of bytes needed to represent this paragraph.
200      *
201      *  @return  The number of bytes needed to represent this paragraph.
202      */
getByteCount()203     int getByteCount() {
204         return 13;
205     }
206 
207     /**
208      *  Return an <code>byte</code> array representing this paragraph.
209      *
210      *  @return  An <code>byte</code> array representing this paragraph.
211      */
getBytes()212     byte[] getBytes() {
213         byte b[] = new byte[13];
214 
215         b[0] = 5;
216         b[1] = spaceBefore;
217         b[2] = spaceAfter;
218         b[3] = leftIndent;
219         b[4] = firstIndent;
220         b[5] = rightIndent;
221         b[6] = misc;
222         b[7] = style;
223         b[8] = lineSpace;
224         b[9] = outline;
225         b[10] = reserved;
226         b[11] = 0;
227         b[12] = 0;
228 
229         return b;
230     }
231 
232     /**
233      *  Return a <code>ParaStyle</code> that reflects the formatting of
234      *  this run.
235      *
236      *  @return  A <code>ParaStyle</code> that reflects the formatting
237      *           of this run.
238      */
makeStyle()239     ParaStyle makeStyle() {
240         /* Csaba: Commented out the LINE_HEIGHT syle, because there was no
241                   incoming data for that style. It was resulting a zero line
242                   height in the xml document, ie. the doc looked empty.
243         */
244         int attrs[] = { ParaStyle.MARGIN_LEFT, ParaStyle.MARGIN_RIGHT,
245                            ParaStyle.TEXT_INDENT, //ParaStyle.LINE_HEIGHT,
246                            ParaStyle.MARGIN_TOP, ParaStyle.MARGIN_BOTTOM,
247                            ParaStyle.TEXT_ALIGN };
248         String values[] = new String[attrs.length];
249         double temp;
250 
251         temp = leftIndent / 1.6;
252         values[0] = (new Double(temp)).toString() + "mm";
253 
254         temp = rightIndent / 1.6;
255         values[1] = (new Double(temp)).toString() + "mm";
256 
257         temp = firstIndent / 1.6;
258         values[2] = (new Double(temp)).toString() + "mm";
259 
260 /*        if ((lineSpace & LS_MULTIPLE) != 0) {
261             temp = (lineSpace & LS_VALUEMASK) / 2;
262             temp *= 100;
263             values[3] = (new Double(temp)).toString() + "%";
264           } else {
265             values[3] = (new Double(temp)).toString() + "mm";
266             // DJP: handle other cases
267           }
268 */
269         temp = spaceBefore / 1.6;
270 //        values[4] = (new Double(temp)).toString() + "mm";
271         values[3] = (new Double(temp)).toString() + "mm";
272 
273         temp = spaceAfter / 1.6;
274 //        values[5] = (new Double(temp)).toString() + "mm";
275         values[4] = (new Double(temp)).toString() + "mm";
276 
277         switch (misc) {
278 
279 // case ALIGN_RIGHT: values[6] = "right"; break;
280 //        case ALIGN_LEFT:  values[6] = "left"; break;
281 //        case ALIGN_CENTER:values[6] = "center"; break;
282 //        case ALIGN_JUST:  values[6] = "justified"; break;
283 
284             case ALIGN_RIGHT: values[5] = "right"; break;
285             case ALIGN_LEFT:  values[5] = "left"; break;
286             case ALIGN_CENTER:values[5] = "center"; break;
287             case ALIGN_JUST:  values[5] = "justified"; break;
288         }
289         ParaStyle x = new ParaStyle(null, "paragraph", null, attrs,
290                                         values, sc);
291 
292         return x;
293     }
294 }
295 
296