001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.pdf.content;
031:
032: import java.util.Map;
033: import de.intarsys.pdf.pd.PDDocument;
034: import de.intarsys.pdf.pd.PDResources;
035: import de.intarsys.tools.string.StringTools;
036:
037: /**
038: * An abstrct superclass for implementing an interpreter for PDF content
039: * streams.
040: */
041: abstract public class CSInterpreter implements ICSInterpreter {
042: /** The options for the rendering process */
043: private Map options;
044:
045: private ICSExceptionHandler exceptionHandler;
046:
047: private CSInterpreterFrame frame;
048:
049: public CSInterpreter(Map paramOptions) {
050: super ();
051: options = paramOptions;
052: }
053:
054: protected void decCompatibilitySectionDepth() {
055: frame.compatibilitySectionDepth--;
056: }
057:
058: protected PDDocument getDoc() {
059: if (frame.doc == null) {
060: frame.doc = getResources().getDoc();
061: }
062: return frame.doc;
063: }
064:
065: /*
066: * (non-Javadoc)
067: *
068: * @see de.intarsys.pdf.content.ICSInterpreter#getExceptionHandler()
069: */
070: public ICSExceptionHandler getExceptionHandler() {
071: return exceptionHandler;
072: }
073:
074: /*
075: * (non-Javadoc)
076: *
077: * @see de.intarsys.pdf.content.ICSInterpreter#getOptions()
078: */
079: public Map getOptions() {
080: return options;
081: }
082:
083: protected PDResources getResources() {
084: return frame.resources;
085: }
086:
087: protected void handleError(CSError error) throws CSException {
088: if (exceptionHandler != null) {
089: exceptionHandler.error(error);
090: } else {
091: throw error;
092: }
093: }
094:
095: protected void handleWarning(CSWarning warning) throws CSException {
096: if (exceptionHandler != null) {
097: exceptionHandler.warning(warning);
098: } else {
099: // it is just a warning...
100: }
101: }
102:
103: protected void incCompatibilitySectionDepth() {
104: frame.compatibilitySectionDepth++;
105: }
106:
107: protected boolean isCompatibilitySection() {
108: return frame.compatibilitySectionDepth > 0;
109: }
110:
111: protected void notSupported(CSOperation operation)
112: throws CSException {
113: if (isCompatibilitySection()) {
114: return;
115: }
116: handleWarning(new CSNotSupported("operation " //$NON-NLS-1$
117: + StringTools.safeString(operation) + " not supported")); //$NON-NLS-1$
118: }
119:
120: /*
121: * (non-Javadoc)
122: *
123: * @see de.intarsys.pdf.content.ICSInterpreter#process(de.intarsys.pdf.content.CSContent,
124: * de.intarsys.pdf.pd.PDResources)
125: */
126: public void process(CSContent pContent, PDResources pResources)
127: throws CSException {
128: if (pContent == null) {
129: return;
130: }
131: CSInterpreterFrame oldFrame = frame;
132: try {
133: frame = createFrame();
134: frame.resources = pResources;
135: int len = pContent.size();
136: for (int i = 0; i < len; i++) {
137: CSOperation operation = pContent.getOperation(i);
138: try {
139: process(operation);
140: } catch (CSError e) {
141: handleError(e);
142: } catch (CSWarning w) {
143: handleWarning(w);
144: } catch (RuntimeException e) {
145: handleError(new CSError("unexpected exception", e)); //$NON-NLS-1$
146: }
147: }
148: } finally {
149: frame = oldFrame;
150: }
151: }
152:
153: protected CSInterpreterFrame createFrame() {
154: return new CSInterpreterFrame();
155: }
156:
157: protected void process(CSOperation operation) throws CSException {
158: byte[] token = operation.getOperatorToken();
159: switch (token[0]) {
160: case 'q':
161: render_q(operation);
162: break;
163: case 'Q':
164: render_Q(operation);
165: break;
166: case 'T':
167: switch (token[1]) {
168: case 'j':
169: render_Tj(operation);
170: break;
171: case 'J':
172: render_TJ(operation);
173: break;
174: case 'f':
175: render_Tf(operation);
176: break;
177: case 'd':
178: render_Td(operation);
179: break;
180: case 'L':
181: render_TL(operation);
182: break;
183: case 'D':
184: render_TD(operation);
185: break;
186: case 'c':
187: render_Tc(operation);
188: break;
189: case 'm':
190: render_Tm(operation);
191: break;
192: case 'r':
193: render_Tr(operation);
194: break;
195: case 's':
196: render_Ts(operation);
197: break;
198: case 'w':
199: render_Tw(operation);
200: break;
201: case 'z':
202: render_Tz(operation);
203: break;
204: case '*':
205: render_Tstar(operation);
206: break;
207: }
208: break;
209: case 'n':
210: render_n(operation);
211: break;
212: case 's':
213: if (token.length == 1) {
214: render_s(operation);
215: } else {
216: switch (token[1]) {
217: case 'c':
218: if (token.length == 2) {
219: render_sc(operation);
220: } else {
221: render_scn(operation);
222: }
223: break;
224: case 'h':
225: render_sh(operation);
226: break;
227: }
228: }
229: break;
230: case 'g':
231: if (token.length == 1) {
232: render_g(operation);
233: } else {
234: render_gs(operation);
235: }
236: break;
237: case 'r':
238: switch (token[1]) {
239: case 'e':
240: render_re(operation);
241: break;
242: case 'g':
243: render_rg(operation);
244: break;
245: case 'i':
246: render_ri(operation);
247: break;
248: }
249: break;
250: case 'R':
251: render_RG(operation);
252: break;
253: case 'm':
254: render_m(operation);
255: break;
256: case 'l':
257: render_l(operation);
258: break;
259: case 'f':
260: if (token.length == 1) {
261: render_f(operation);
262: } else {
263: render_fstar(operation);
264: }
265: break;
266: case 'B':
267: if (token.length == 1) {
268: render_B(operation);
269: } else {
270: switch (token[1]) {
271: case '*':
272: render_Bstar(operation);
273: break;
274: case 'T':
275: render_BT(operation);
276: break;
277: case 'M':
278: render_BMC(operation);
279: break;
280: case 'D':
281: render_BDC(operation);
282: break;
283: case 'I':
284: render_BI(operation);
285: break;
286: case 'X':
287: render_BX(operation);
288: break;
289: }
290: }
291: break;
292: case 'b':
293: if (token.length == 1) {
294: render_b(operation);
295: } else {
296: render_bstar(operation);
297: }
298: break;
299: case 'S':
300: if (token.length == 1) {
301: render_S(operation);
302: } else {
303: if (token.length == 2) {
304: render_SC(operation);
305: } else {
306: render_SCN(operation);
307: }
308: }
309: break;
310: case 'h':
311: render_h(operation);
312: break;
313: case 'W':
314: if (token.length == 1) {
315: render_W(operation);
316: } else {
317: render_Wstar(operation);
318: }
319: break;
320: case 'c':
321: if (token.length == 1) {
322: render_c(operation);
323: } else {
324: switch (token[1]) {
325: case 'm':
326: render_cm(operation);
327: break;
328: case 's':
329: render_cs(operation);
330: break;
331: }
332: }
333: break;
334: case 'E':
335: switch (token[1]) {
336: case 'T':
337: render_ET(operation);
338: break;
339: case 'M':
340: render_EMC(operation);
341: break;
342: case 'I':
343: render_EI(operation);
344: break;
345: case 'X':
346: render_EX(operation);
347: break;
348: }
349: break;
350: case 'G':
351: render_G(operation);
352: break;
353: case '\'':
354: render_Quote(operation);
355: break;
356: case '"':
357: render_DoubleQuote(operation);
358: break;
359: case 'C':
360: render_CS(operation);
361: break;
362: case 'd':
363: if (token.length == 1) {
364: render_d(operation);
365: } else {
366: switch (token[1]) {
367: case '0':
368: render_d0(operation);
369: break;
370: case '1':
371: render_d1(operation);
372: break;
373: }
374: }
375: break;
376: case 'D':
377: switch (token[1]) {
378: case 'o':
379: render_Do(operation);
380: break;
381: case 'P':
382: render_DP(operation);
383: break;
384: }
385: break;
386: case 'F':
387: render_F(operation);
388: break;
389: case 'i':
390: render_i(operation);
391: break;
392: case 'I':
393: render_ID(operation);
394: break;
395: case 'j':
396: render_j(operation);
397: break;
398: case 'J':
399: render_J(operation);
400: break;
401: case 'K':
402: render_K(operation);
403: break;
404: case 'k':
405: render_k(operation);
406: break;
407: case 'M':
408: if (token.length == 1) {
409: render_M(operation);
410: } else {
411: render_MP(operation);
412: }
413: break;
414: case 'v':
415: render_v(operation);
416: break;
417: case 'w':
418: render_w(operation);
419: break;
420: case 'y':
421: render_y(operation);
422: break;
423: }
424: }
425:
426: protected void render_b(CSOperation operation) throws CSException {
427: // close, fill and stroke path using nonzero winding rule
428: notSupported(operation);
429: }
430:
431: protected void render_B(CSOperation operation) throws CSException {
432: // fill and stroke path using nonzero winding rule
433: notSupported(operation);
434: }
435:
436: protected void render_BDC(CSOperation operation) throws CSException {
437: // begin marked content sequence with property
438: notSupported(operation);
439: }
440:
441: protected void render_BI(CSOperation operation) throws CSException {
442: // begin inline image
443: notSupported(operation);
444: }
445:
446: protected void render_BMC(CSOperation operation) throws CSException {
447: // begin marked content sequence
448: notSupported(operation);
449: }
450:
451: protected void render_bstar(CSOperation operation)
452: throws CSException {
453: // close, fill and stroke path using even/odd rule
454: notSupported(operation);
455: }
456:
457: protected void render_Bstar(CSOperation operation)
458: throws CSException {
459: // fill and stroke path using even/odd rule
460: notSupported(operation);
461: }
462:
463: protected void render_BT(CSOperation operation) throws CSException {
464: // begin text
465: notSupported(operation);
466: }
467:
468: protected void render_BX(CSOperation operation) throws CSException {
469: // begin compatibility section
470: incCompatibilitySectionDepth();
471: }
472:
473: protected void render_c(CSOperation operation) throws CSException {
474: // append curved segment
475: notSupported(operation);
476: }
477:
478: protected void render_cm(CSOperation operation) throws CSException {
479: // concatenate matrix
480: notSupported(operation);
481: }
482:
483: protected void render_cs(CSOperation operation) throws CSException {
484: // set color space for non stroking
485: notSupported(operation);
486: }
487:
488: protected void render_CS(CSOperation operation) throws CSException {
489: // set color space for stroking
490: notSupported(operation);
491: }
492:
493: protected void render_d(CSOperation operation) throws CSException {
494: // set line dash pattern
495: notSupported(operation);
496: }
497:
498: protected void render_d0(CSOperation operation) throws CSException {
499: // set glyph width in type 3
500: notSupported(operation);
501: }
502:
503: protected void render_d1(CSOperation operation) throws CSException {
504: // set glyph width and bounding box
505: notSupported(operation);
506: }
507:
508: protected void render_Do(CSOperation operation) throws CSException {
509: // invoke XObject
510: notSupported(operation);
511: }
512:
513: protected void render_DoubleQuote(CSOperation operation)
514: throws CSException {
515: // set word and character spacing, move to next line, show text
516: notSupported(operation);
517: }
518:
519: protected void render_DP(CSOperation operation) throws CSException {
520: // define marked content with property
521: notSupported(operation);
522: }
523:
524: protected void render_EI(CSOperation operation) throws CSException {
525: // end inline image
526: notSupported(operation);
527: }
528:
529: protected void render_EMC(CSOperation operation) throws CSException {
530: // end marked content
531: notSupported(operation);
532: }
533:
534: protected void render_ET(CSOperation operation) throws CSException {
535: // end text
536: notSupported(operation);
537: }
538:
539: protected void render_EX(CSOperation operation) throws CSException {
540: // end compatibility
541: decCompatibilitySectionDepth();
542: }
543:
544: protected void render_f(CSOperation operation) throws CSException {
545: // fill path using nonzero winding rule
546: notSupported(operation);
547: }
548:
549: protected void render_F(CSOperation operation) throws CSException {
550: // fill path using nonzero winding rule (obsolete)
551: notSupported(operation);
552: }
553:
554: protected void render_fstar(CSOperation operation)
555: throws CSException {
556: // fill path using even/odd rule
557: notSupported(operation);
558: }
559:
560: protected void render_g(CSOperation operation) throws CSException {
561: // gray level for non stroking operations
562: notSupported(operation);
563: }
564:
565: protected void render_G(CSOperation operation) throws CSException {
566: // gray level for stroking operations
567: notSupported(operation);
568: }
569:
570: protected void render_gs(CSOperation operation) throws CSException {
571: // set parameters from graphics state parameters
572: notSupported(operation);
573: }
574:
575: protected void render_h(CSOperation operation) throws CSException {
576: // close subpath, line to start
577: notSupported(operation);
578: }
579:
580: protected void render_i(CSOperation operation) throws CSException {
581: // set flatness tolerance
582: notSupported(operation);
583: }
584:
585: protected void render_ID(CSOperation operation) throws CSException {
586: // begin inline image data
587: notSupported(operation);
588: }
589:
590: protected void render_j(CSOperation operation) throws CSException {
591: // set line joins style
592: notSupported(operation);
593: }
594:
595: protected void render_J(CSOperation operation) throws CSException {
596: // set line cap style
597: notSupported(operation);
598: }
599:
600: protected void render_k(CSOperation operation) throws CSException {
601: // set CMYK color for non stroking
602: notSupported(operation);
603: }
604:
605: protected void render_K(CSOperation operation) throws CSException {
606: // set CMYK color for stroking
607: notSupported(operation);
608: }
609:
610: protected void render_l(CSOperation operation) throws CSException {
611: // append line to path
612: notSupported(operation);
613: }
614:
615: protected void render_m(CSOperation operation) throws CSException {
616: // move current point
617: notSupported(operation);
618: }
619:
620: protected void render_M(CSOperation operation) throws CSException {
621: // set miter limit
622: notSupported(operation);
623: }
624:
625: protected void render_MP(CSOperation operation) throws CSException {
626: // define marked content point
627: notSupported(operation);
628: }
629:
630: protected void render_n(CSOperation operation) throws CSException {
631: // end path without filling or stroking
632: notSupported(operation);
633: }
634:
635: protected void render_q(CSOperation operation) throws CSException {
636: // save graphics state
637: notSupported(operation);
638: }
639:
640: protected void render_Q(CSOperation operation) throws CSException {
641: // restore graphics state
642: notSupported(operation);
643: }
644:
645: protected void render_Quote(CSOperation operation)
646: throws CSException {
647: // move to next line and show text
648: notSupported(operation);
649: }
650:
651: protected void render_re(CSOperation operation) throws CSException {
652: // append rectangle to path
653: notSupported(operation);
654: }
655:
656: protected void render_rg(CSOperation operation) throws CSException {
657: // set RGB color for non stroking
658: notSupported(operation);
659: }
660:
661: protected void render_RG(CSOperation operation) throws CSException {
662: // set RGB color for stroking
663: notSupported(operation);
664: }
665:
666: protected void render_ri(CSOperation operation) throws CSException {
667: // set color rendering intent
668: notSupported(operation);
669: }
670:
671: protected void render_s(CSOperation operation) throws CSException {
672: // close and stroke path
673: notSupported(operation);
674: }
675:
676: protected void render_S(CSOperation operation) throws CSException {
677: // stroke path
678: notSupported(operation);
679: }
680:
681: protected void render_sc(CSOperation operation) throws CSException {
682: // set color for non stroking
683: notSupported(operation);
684: }
685:
686: protected void render_SC(CSOperation operation) throws CSException {
687: // set color for stroking
688: notSupported(operation);
689: }
690:
691: protected void render_scn(CSOperation operation) throws CSException {
692: // set color for non stroking (ICCBased, special color spaces)
693: notSupported(operation);
694: }
695:
696: protected void render_SCN(CSOperation operation) throws CSException {
697: // set color for stroking (ICCBased, special color spaces)
698: notSupported(operation);
699: }
700:
701: protected void render_sh(CSOperation operation) throws CSException {
702: // paint area defined by shading pattern
703: notSupported(operation);
704: }
705:
706: protected void render_Tc(CSOperation operation) throws CSException {
707: // set character spacing
708: notSupported(operation);
709: }
710:
711: protected void render_Td(CSOperation operation) throws CSException {
712: // move text position
713: notSupported(operation);
714: }
715:
716: protected void render_TD(CSOperation operation) throws CSException {
717: // move text position and set leading
718: notSupported(operation);
719: }
720:
721: protected void render_Tf(CSOperation operation) throws CSException {
722: // set text font and size
723: notSupported(operation);
724: }
725:
726: protected void render_Tj(CSOperation operation) throws CSException {
727: // show text
728: notSupported(operation);
729: }
730:
731: protected void render_TJ(CSOperation operation) throws CSException {
732: // show text, allowing individual positioning
733: notSupported(operation);
734: }
735:
736: protected void render_TL(CSOperation operation) throws CSException {
737: // set text leading
738: notSupported(operation);
739: }
740:
741: protected void render_Tm(CSOperation operation) throws CSException {
742: // set text matrix and text line matrix
743: notSupported(operation);
744: }
745:
746: protected void render_Tr(CSOperation operation) throws CSException {
747: // set text rendering mode
748: notSupported(operation);
749: }
750:
751: protected void render_Ts(CSOperation operation) throws CSException {
752: // set text rise
753: notSupported(operation);
754: }
755:
756: protected void render_Tstar(CSOperation operation)
757: throws CSException {
758: // move to start of next line
759: notSupported(operation);
760: }
761:
762: protected void render_Tw(CSOperation operation) throws CSException {
763: // set word spacing
764: notSupported(operation);
765: }
766:
767: protected void render_Tz(CSOperation operation) throws CSException {
768: // set horizontal text scaling
769: notSupported(operation);
770: }
771:
772: protected void render_v(CSOperation operation) throws CSException {
773: // append curved segment to path (initial point replicated)
774: notSupported(operation);
775: }
776:
777: protected void render_w(CSOperation operation) throws CSException {
778: // set line width
779: notSupported(operation);
780: }
781:
782: protected void render_W(CSOperation operation) throws CSException {
783: // request clipping path using nonzero winding rule
784: notSupported(operation);
785: }
786:
787: protected void render_Wstar(CSOperation operation)
788: throws CSException {
789: // request clipping path using even/odd winding rule
790: notSupported(operation);
791: }
792:
793: protected void render_y(CSOperation operation) throws CSException {
794: // append curved segment to path (final point replicated)
795: notSupported(operation);
796: }
797:
798: /*
799: * (non-Javadoc)
800: *
801: * @see de.intarsys.pdf.content.ICSInterpreter#setExceptionHandler(de.intarsys.pdf.content.ICSExceptionHandler)
802: */
803: public void setExceptionHandler(ICSExceptionHandler errorHandler) {
804: this.exceptionHandler = errorHandler;
805: }
806: }
|