001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.parser;
020:
021: import java.io.IOException;
022:
023: /**
024: * This class implements an event-based parser for the SVG preserveAspectRatio
025: * attribute values.
026: *
027: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
028: * @version $Id: PreserveAspectRatioParser.java 502167 2007-02-01 09:26:51Z dvholten $
029: */
030: public class PreserveAspectRatioParser extends AbstractParser {
031:
032: /**
033: * The PreserveAspectRatio handler used to report parse events.
034: */
035: protected PreserveAspectRatioHandler preserveAspectRatioHandler;
036:
037: /**
038: * Creates a new PreserveAspectRatioParser.
039: */
040: public PreserveAspectRatioParser() {
041: preserveAspectRatioHandler = DefaultPreserveAspectRatioHandler.INSTANCE;
042: }
043:
044: /**
045: * Allows an application to register a PreserveAspectRatioParser handler.
046: *
047: * <p>If the application does not register a handler, all
048: * events reported by the parser will be silently ignored.
049: *
050: * <p>Applications may register a new or different handler in the
051: * middle of a parse, and the parser must begin using the new
052: * handler immediately.</p>
053: * @param handler The transform list handler.
054: */
055: public void setPreserveAspectRatioHandler(
056: PreserveAspectRatioHandler handler) {
057: preserveAspectRatioHandler = handler;
058: }
059:
060: /**
061: * Returns the length handler in use.
062: */
063: public PreserveAspectRatioHandler getPreserveAspectRatioHandler() {
064: return preserveAspectRatioHandler;
065: }
066:
067: /**
068: * Parses the current stream.
069: */
070: protected void doParse() throws ParseException, IOException {
071: current = reader.read();
072: skipSpaces();
073:
074: parsePreserveAspectRatio();
075: }
076:
077: /**
078: * Parses a PreserveAspectRatio attribute.
079: */
080: protected void parsePreserveAspectRatio() throws ParseException,
081: IOException {
082: preserveAspectRatioHandler.startPreserveAspectRatio();
083:
084: align: switch (current) {
085: case 'n':
086: current = reader.read();
087: if (current != 'o') {
088: reportCharacterExpectedError('o', current);
089: skipIdentifier();
090: break align;
091: }
092: current = reader.read();
093: if (current != 'n') {
094: reportCharacterExpectedError('o', current);
095: skipIdentifier();
096: break align;
097: }
098: current = reader.read();
099: if (current != 'e') {
100: reportCharacterExpectedError('e', current);
101: skipIdentifier();
102: break align;
103: }
104: current = reader.read();
105: skipSpaces();
106: preserveAspectRatioHandler.none();
107: break;
108:
109: case 'x':
110: current = reader.read();
111: if (current != 'M') {
112: reportCharacterExpectedError('M', current);
113: skipIdentifier();
114: break;
115: }
116: current = reader.read();
117: switch (current) {
118: case 'a':
119: current = reader.read();
120: if (current != 'x') {
121: reportCharacterExpectedError('x', current);
122: skipIdentifier();
123: break align;
124: }
125: current = reader.read();
126: if (current != 'Y') {
127: reportCharacterExpectedError('Y', current);
128: skipIdentifier();
129: break align;
130: }
131: current = reader.read();
132: if (current != 'M') {
133: reportCharacterExpectedError('M', current);
134: skipIdentifier();
135: break align;
136: }
137: current = reader.read();
138: switch (current) {
139: case 'a':
140: current = reader.read();
141: if (current != 'x') {
142: reportCharacterExpectedError('x', current);
143: skipIdentifier();
144: break align;
145: }
146: preserveAspectRatioHandler.xMaxYMax();
147: current = reader.read();
148: break;
149: case 'i':
150: current = reader.read();
151: switch (current) {
152: case 'd':
153: preserveAspectRatioHandler.xMaxYMid();
154: current = reader.read();
155: break;
156: case 'n':
157: preserveAspectRatioHandler.xMaxYMin();
158: current = reader.read();
159: break;
160: default:
161: reportUnexpectedCharacterError(current);
162: skipIdentifier();
163: break align;
164: }
165: }
166: break;
167: case 'i':
168: current = reader.read();
169: switch (current) {
170: case 'd':
171: current = reader.read();
172: if (current != 'Y') {
173: reportCharacterExpectedError('Y', current);
174: skipIdentifier();
175: break align;
176: }
177: current = reader.read();
178: if (current != 'M') {
179: reportCharacterExpectedError('M', current);
180: skipIdentifier();
181: break align;
182: }
183: current = reader.read();
184: switch (current) {
185: case 'a':
186: current = reader.read();
187: if (current != 'x') {
188: reportCharacterExpectedError('x', current);
189: skipIdentifier();
190: break align;
191: }
192: preserveAspectRatioHandler.xMidYMax();
193: current = reader.read();
194: break;
195: case 'i':
196: current = reader.read();
197: switch (current) {
198: case 'd':
199: preserveAspectRatioHandler.xMidYMid();
200: current = reader.read();
201: break;
202: case 'n':
203: preserveAspectRatioHandler.xMidYMin();
204: current = reader.read();
205: break;
206: default:
207: reportUnexpectedCharacterError(current);
208: skipIdentifier();
209: break align;
210: }
211: }
212: break;
213: case 'n':
214: current = reader.read();
215: if (current != 'Y') {
216: reportCharacterExpectedError('Y', current);
217: skipIdentifier();
218: break align;
219: }
220: current = reader.read();
221: if (current != 'M') {
222: reportCharacterExpectedError('M', current);
223: skipIdentifier();
224: break align;
225: }
226: current = reader.read();
227: switch (current) {
228: case 'a':
229: current = reader.read();
230: if (current != 'x') {
231: reportCharacterExpectedError('x', current);
232: skipIdentifier();
233: break align;
234: }
235: preserveAspectRatioHandler.xMinYMax();
236: current = reader.read();
237: break;
238: case 'i':
239: current = reader.read();
240: switch (current) {
241: case 'd':
242: preserveAspectRatioHandler.xMinYMid();
243: current = reader.read();
244: break;
245: case 'n':
246: preserveAspectRatioHandler.xMinYMin();
247: current = reader.read();
248: break;
249: default:
250: reportUnexpectedCharacterError(current);
251: skipIdentifier();
252: break align;
253: }
254: }
255: break;
256: default:
257: reportUnexpectedCharacterError(current);
258: skipIdentifier();
259: break align;
260: }
261: break;
262: default:
263: reportUnexpectedCharacterError(current);
264: skipIdentifier();
265: }
266: break;
267: default:
268: if (current != -1) {
269: reportUnexpectedCharacterError(current);
270: skipIdentifier();
271: }
272: }
273:
274: skipCommaSpaces();
275:
276: switch (current) {
277: case 'm':
278: current = reader.read();
279: if (current != 'e') {
280: reportCharacterExpectedError('e', current);
281: skipIdentifier();
282: break;
283: }
284: current = reader.read();
285: if (current != 'e') {
286: reportCharacterExpectedError('e', current);
287: skipIdentifier();
288: break;
289: }
290: current = reader.read();
291: if (current != 't') {
292: reportCharacterExpectedError('t', current);
293: skipIdentifier();
294: break;
295: }
296: preserveAspectRatioHandler.meet();
297: current = reader.read();
298: break;
299: case 's':
300: current = reader.read();
301: if (current != 'l') {
302: reportCharacterExpectedError('l', current);
303: skipIdentifier();
304: break;
305: }
306: current = reader.read();
307: if (current != 'i') {
308: reportCharacterExpectedError('i', current);
309: skipIdentifier();
310: break;
311: }
312: current = reader.read();
313: if (current != 'c') {
314: reportCharacterExpectedError('c', current);
315: skipIdentifier();
316: break;
317: }
318: current = reader.read();
319: if (current != 'e') {
320: reportCharacterExpectedError('e', current);
321: skipIdentifier();
322: break;
323: }
324: preserveAspectRatioHandler.slice();
325: current = reader.read();
326: break;
327: default:
328: if (current != -1) {
329: reportUnexpectedCharacterError(current);
330: skipIdentifier();
331: }
332: }
333:
334: skipSpaces();
335: if (current != -1) {
336: reportError("end.of.stream.expected",
337: new Object[] { new Integer(current) });
338: }
339:
340: preserveAspectRatioHandler.endPreserveAspectRatio();
341: }
342:
343: /**
344: * Skips characters in the given reader until a white space is encountered.
345: */
346: protected void skipIdentifier() throws IOException {
347: loop: for (;;) {
348: current = reader.read();
349: switch (current) {
350: case 0xD:
351: case 0xA:
352: case 0x20:
353: case 0x9:
354: current = reader.read();
355: break loop;
356: default:
357: if (current == -1) {
358: break loop;
359: }
360: }
361: }
362: }
363: }
|