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.Iterator;
033: import java.util.Map;
034: import de.intarsys.pdf.cos.COSArray;
035: import de.intarsys.pdf.cos.COSDictionary;
036: import de.intarsys.pdf.cos.COSName;
037: import de.intarsys.pdf.cos.COSNumber;
038: import de.intarsys.pdf.cos.COSObject;
039: import de.intarsys.pdf.cos.COSString;
040: import de.intarsys.pdf.font.PDFont;
041: import de.intarsys.pdf.font.PDFontTools;
042: import de.intarsys.pdf.pd.PDColorSpace;
043: import de.intarsys.pdf.pd.PDExtGState;
044: import de.intarsys.pdf.pd.PDImage;
045: import de.intarsys.pdf.pd.PDPattern;
046: import de.intarsys.pdf.pd.PDResources;
047: import de.intarsys.pdf.pd.PDShading;
048: import de.intarsys.pdf.pd.PDXObject;
049:
050: /**
051: * A content stream interpreter for PDF graphics primitives that delegates
052: * execution to an {@link ICSDevice} object.
053: *
054: */
055: public class CSDeviceBasedInterpreter extends CSInterpreter {
056: protected ICSDevice device;
057:
058: /** An image created dynamically by the BI/EI operations */
059: private PDImage img;
060:
061: public CSDeviceBasedInterpreter(Map paramOptions, ICSDevice device) {
062: super (paramOptions);
063: this .device = device;
064: }
065:
066: /**
067: * The {@link ICSDevice} currently associated with the interpreter.
068: *
069: * @return The {@link ICSDevice} currently associated with the interpreter.
070: */
071: public ICSDevice getDevice() {
072: return device;
073: }
074:
075: protected PDColorSpace lookupColorSpace(COSName name) {
076: PDColorSpace result = PDColorSpace.getNamed(name);
077: if (result == null) {
078: if (getResources() == null) {
079: throw new IllegalStateException(
080: "resource dictionary missing"); //$NON-NLS-1$
081: }
082: return getResources().getColorSpaceResource(name);
083: }
084: return result;
085: }
086:
087: protected PDPattern lookupPattern(COSName name) {
088: if (getResources() == null) {
089: throw new IllegalStateException(
090: "resource dictionary missing"); //$NON-NLS-1$
091: }
092: return getResources().getPatternResource(name);
093: }
094:
095: protected PDXObject lookupXObject(COSName name) {
096: if (getResources() == null) {
097: throw new IllegalStateException(
098: "resource dictionary missing"); //$NON-NLS-1$
099: }
100: return getResources().getXObjectResource(name);
101: }
102:
103: protected PDExtGState lookupExtGState(COSName name) {
104: if (getResources() == null) {
105: throw new IllegalStateException(
106: "resource dictionary missing"); //$NON-NLS-1$
107: }
108: return getResources().getExtGStateResource(name);
109: }
110:
111: protected COSDictionary lookupProperties(COSName name) {
112: if (getResources() == null) {
113: throw new IllegalStateException(
114: "resource dictionary missing"); //$NON-NLS-1$
115: }
116: return getResources().cosGetResource(
117: PDResources.CN_RT_Properties, name).asDictionary();
118: }
119:
120: protected PDShading lookupShading(COSName name) {
121: if (getResources() == null) {
122: throw new IllegalStateException(
123: "resource dictionary missing"); //$NON-NLS-1$
124: }
125: return getResources().getShadingResource(name);
126: }
127:
128: private int nesting = 0;
129:
130: /*
131: * (non-Javadoc)
132: *
133: * @see de.intarsys.pdf.content.CSInterpreter#process(de.intarsys.pdf.content.CSContent,
134: * de.intarsys.pdf.pd.PDResources)
135: */
136: public void process(CSContent pContent, PDResources resourceDict)
137: throws CSException {
138: try {
139: if (nesting == 0) {
140: device.open(this );
141: }
142: nesting++;
143: super .process(pContent, resourceDict);
144: } finally {
145: nesting--;
146: if (nesting == 0) {
147: device.close();
148: }
149: img = null;
150: }
151: }
152:
153: protected void render_b(CSOperation operation) {
154: device.pathCloseFillStrokeNonZero();
155: }
156:
157: protected void render_B(CSOperation operation) {
158: device.pathFillStrokeNonZero();
159: }
160:
161: /*
162: * (non-Javadoc)
163: *
164: * @see de.intarsys.pdf.content.CSInterpreter#render_BDC(de.intarsys.pdf.content.CSOperation)
165: */
166: protected void render_BDC(CSOperation operation) throws CSException {
167: COSName tag = ((COSName) operation.getOperand(0)).asName();
168: COSObject op1 = operation.getOperand(1);
169: COSName resourceName;
170: COSDictionary properties;
171: if (op1 instanceof COSName) {
172: resourceName = (COSName) op1;
173: properties = lookupProperties(resourceName);
174: } else {
175: resourceName = null;
176: properties = (COSDictionary) op1;
177: }
178: device.markedContentBeginProperties(tag, resourceName,
179: properties);
180: }
181:
182: protected void render_BI(CSOperation operation) {
183: img = (PDImage) PDImage.META.createNew();
184: }
185:
186: /*
187: * (non-Javadoc)
188: *
189: * @see de.intarsys.pdf.content.CSInterpreter#render_BMC(de.intarsys.pdf.content.CSOperation)
190: */
191: protected void render_BMC(CSOperation operation) throws CSException {
192: COSName tag = ((COSName) operation.getOperand(0)).asName();
193: device.markedContentBegin(tag);
194: }
195:
196: protected void render_bstar(CSOperation operation) {
197: device.pathCloseFillStrokeEvenOdd();
198: }
199:
200: protected void render_Bstar(CSOperation operation) {
201: device.pathFillStrokeEvenOdd();
202: }
203:
204: protected void render_BT(CSOperation operation) {
205: device.textBegin();
206: }
207:
208: protected void render_c(CSOperation operation) {
209: float x1 = ((COSNumber) operation.getOperand(0)).floatValue();
210: float y1 = ((COSNumber) operation.getOperand(1)).floatValue();
211: float x2 = ((COSNumber) operation.getOperand(2)).floatValue();
212: float y2 = ((COSNumber) operation.getOperand(3)).floatValue();
213: float x3 = ((COSNumber) operation.getOperand(4)).floatValue();
214: float y3 = ((COSNumber) operation.getOperand(5)).floatValue();
215: device.penCurveToC(x1, y1, x2, y2, x3, y3);
216: }
217:
218: protected void render_cm(CSOperation operation) {
219: float a = ((COSNumber) operation.getOperand(0)).floatValue();
220: float b = ((COSNumber) operation.getOperand(1)).floatValue();
221: float c = ((COSNumber) operation.getOperand(2)).floatValue();
222: float d = ((COSNumber) operation.getOperand(3)).floatValue();
223: float e = ((COSNumber) operation.getOperand(4)).floatValue();
224: float f = ((COSNumber) operation.getOperand(5)).floatValue();
225: device.transform(a, b, c, d, e, f);
226: }
227:
228: protected void render_cs(CSOperation operation) {
229: COSName name = operation.getOperand(0).asName();
230: PDColorSpace colorSpace = lookupColorSpace(name);
231: device.setNonStrokeColorSpace(name, colorSpace);
232: }
233:
234: protected void render_CS(CSOperation operation) {
235: COSName name = operation.getOperand(0).asName();
236: PDColorSpace colorSpace = lookupColorSpace(name);
237: device.setStrokeColorSpace(name, colorSpace);
238: }
239:
240: protected void render_d(CSOperation operation) {
241: COSArray cosDashArray = (COSArray) operation.getOperand(0);
242: float[] pattern = new float[cosDashArray.size()];
243: int i = 0;
244: for (Iterator it = cosDashArray.iterator(); it.hasNext();) {
245: COSNumber element = ((COSObject) it.next()).asNumber();
246: if (element != null) {
247: pattern[i] = element.floatValue();
248: i++;
249: }
250: }
251: float phase = ((COSNumber) operation.getOperand(1))
252: .floatValue();
253: device.setLineDash(pattern, phase);
254: }
255:
256: protected void render_Do(CSOperation operation) throws CSException {
257: COSName name = (COSName) operation.getOperand(0);
258: PDXObject xobject = lookupXObject(name);
259: device.doXObject(name, xobject);
260: }
261:
262: protected void render_DoubleQuote(CSOperation operation)
263: throws CSException {
264: float ws = ((COSNumber) operation.getOperand(0)).floatValue();
265: device.textSetWordSpacing(ws);
266: float cs = ((COSNumber) operation.getOperand(1)).floatValue();
267: device.textSetCharSpacing(cs);
268: device.textLineNew();
269: byte[] value = ((COSString) operation.getOperand(2))
270: .byteValue();
271: device.textShow(value, 0, value.length);
272: }
273:
274: /*
275: * (non-Javadoc)
276: *
277: * @see de.intarsys.pdf.content.CSInterpreter#render_DP(de.intarsys.pdf.content.CSOperation)
278: */
279: protected void render_DP(CSOperation operation) throws CSException {
280: COSName tag = ((COSName) operation.getOperand(0)).asName();
281: COSObject op1 = operation.getOperand(1);
282: COSName resourceName;
283: COSDictionary properties;
284: if (op1 instanceof COSName) {
285: resourceName = (COSName) op1;
286: properties = lookupProperties(resourceName);
287: } else {
288: resourceName = null;
289: properties = (COSDictionary) op1;
290: }
291: device.markedContentPointProperties(tag, resourceName,
292: properties);
293: }
294:
295: protected void render_EI(CSOperation operation) throws CSException {
296: COSString data = (COSString) operation.getOperand(0);
297: img.cosGetStream().setEncodedBytes(data.byteValue());
298: COSObject cs = img.cosGetColorSpace();
299: if (cs instanceof COSName) {
300: if (getResources() != null) {
301: /*
302: * will be null if cs is one of the predefined names. pd image
303: * will resolve lazily then
304: */
305: PDColorSpace pdCS = getResources()
306: .getColorSpaceResource((COSName) cs);
307: if (pdCS != null) {
308: img.setColorSpace(pdCS);
309: }
310: }
311: }
312: device.inlineImage(img);
313: img = null;
314: }
315:
316: /*
317: * (non-Javadoc)
318: *
319: * @see de.intarsys.pdf.content.CSInterpreter#render_EMC(de.intarsys.pdf.content.CSOperation)
320: */
321: protected void render_EMC(CSOperation operation) throws CSException {
322: device.markedContentEnd();
323: }
324:
325: protected void render_ET(CSOperation operation) {
326: device.textEnd();
327: }
328:
329: protected void render_f(CSOperation operation) {
330: device.pathFillNonZero();
331: }
332:
333: protected void render_F(CSOperation operation) {
334: device.pathFillNonZero();
335: }
336:
337: protected void render_fstar(CSOperation operation) {
338: device.pathFillEvenOdd();
339: }
340:
341: protected void render_g(CSOperation operation) {
342: device.setNonStrokeColorGray(((COSNumber) operation
343: .getOperand(0)).floatValue());
344: }
345:
346: protected void render_G(CSOperation operation) {
347: device.setStrokeColorGray(((COSNumber) operation.getOperand(0))
348: .floatValue());
349: }
350:
351: protected void render_gs(CSOperation operation) {
352: if (getResources() == null) {
353: throw new IllegalStateException(
354: "resource dictionary missing"); //$NON-NLS-1$
355: }
356: COSName name = operation.getOperand(0).asName();
357: PDExtGState gstate = lookupExtGState(name);
358: device.setExtendedState(name, gstate);
359: }
360:
361: protected void render_h(CSOperation operation) {
362: device.pathClose();
363: }
364:
365: /*
366: * (non-Javadoc)
367: *
368: * @see de.intarsys.pdf.content.CSInterpreter#render_i(de.intarsys.pdf.content.CSOperation)
369: */
370: protected void render_i(CSOperation operation) throws CSException {
371: float flatness = ((COSNumber) operation.getOperand(0))
372: .floatValue();
373: device.setFlatnessTolerance(flatness);
374: }
375:
376: protected void render_ID(CSOperation operation) {
377: COSDictionary dict = img.cosGetDict();
378: for (Iterator it = operation.getOperands(); it.hasNext();) {
379: COSName key = (COSName) it.next();
380: COSObject value = (COSObject) it.next();
381: dict.put(key, value.copyShallow());
382: }
383: }
384:
385: protected void render_j(CSOperation operation) {
386: int joinStyle = ((COSNumber) operation.getOperand(0))
387: .intValue();
388: device.setLineJoin(joinStyle);
389: }
390:
391: protected void render_J(CSOperation operation) {
392: int cap = ((COSNumber) operation.getOperand(0)).intValue();
393: device.setLineCap(cap);
394: }
395:
396: protected void render_k(CSOperation operation) {
397: device.setNonStrokeColorCMYK(((COSNumber) operation
398: .getOperand(0)).floatValue(), ((COSNumber) operation
399: .getOperand(1)).floatValue(), ((COSNumber) operation
400: .getOperand(2)).floatValue(), ((COSNumber) operation
401: .getOperand(3)).floatValue());
402: }
403:
404: protected void render_K(CSOperation operation) {
405: device.setStrokeColorCMYK(((COSNumber) operation.getOperand(0))
406: .floatValue(), ((COSNumber) operation.getOperand(1))
407: .floatValue(), ((COSNumber) operation.getOperand(2))
408: .floatValue(), ((COSNumber) operation.getOperand(3))
409: .floatValue());
410: }
411:
412: protected void render_l(CSOperation operation) {
413: device.penLineTo(((COSNumber) operation.getOperand(0))
414: .floatValue(), ((COSNumber) operation.getOperand(1))
415: .floatValue());
416: }
417:
418: protected void render_m(CSOperation operation) {
419: device.penMoveTo(((COSNumber) operation.getOperand(0))
420: .floatValue(), ((COSNumber) operation.getOperand(1))
421: .floatValue());
422: }
423:
424: protected void render_M(CSOperation operation) {
425: float value = ((COSNumber) operation.getOperand(0))
426: .floatValue();
427: device.setMiterLimit(value);
428: }
429:
430: /*
431: * (non-Javadoc)
432: *
433: * @see de.intarsys.pdf.content.CSInterpreter#render_MP(de.intarsys.pdf.content.CSOperation)
434: */
435: protected void render_MP(CSOperation operation) throws CSException {
436: COSName tag = ((COSName) operation.getOperand(0)).asName();
437: device.markedContentPoint(tag);
438: }
439:
440: protected void render_n(CSOperation operation) {
441: device.pathEnd();
442: }
443:
444: protected void render_Quote(CSOperation operation)
445: throws CSException {
446: device.textLineNew();
447: byte[] value = ((COSString) operation.getOperand(0))
448: .byteValue();
449: device.textShow(value, 0, value.length);
450: }
451:
452: protected void render_re(CSOperation operation) {
453: float x = ((COSNumber) operation.getOperand(0)).floatValue();
454: float y = ((COSNumber) operation.getOperand(1)).floatValue();
455: float width = ((COSNumber) operation.getOperand(2))
456: .floatValue();
457: float height = ((COSNumber) operation.getOperand(3))
458: .floatValue();
459: device.penRectangle(x, y, width, height);
460: }
461:
462: protected void render_rg(CSOperation operation) {
463: device.setNonStrokeColorRGB(((COSNumber) operation
464: .getOperand(0)).floatValue(), ((COSNumber) operation
465: .getOperand(1)).floatValue(), ((COSNumber) operation
466: .getOperand(2)).floatValue());
467: }
468:
469: protected void render_RG(CSOperation operation) {
470: device.setStrokeColorRGB(((COSNumber) operation.getOperand(0))
471: .floatValue(), ((COSNumber) operation.getOperand(1))
472: .floatValue(), ((COSNumber) operation.getOperand(2))
473: .floatValue());
474: }
475:
476: protected void render_ri(CSOperation operation) throws CSException {
477: COSName intent = ((COSName) operation.getOperand(0)).asName();
478: device.setRenderingIntent(intent);
479: }
480:
481: protected void render_s(CSOperation operation) {
482: device.pathCloseStroke();
483: }
484:
485: protected void render_S(CSOperation operation) {
486: device.pathStroke();
487: }
488:
489: protected void render_sc(CSOperation operation) {
490: // set color for non stroking
491: int totalSize = operation.operandSize();
492: float[] values = new float[totalSize];
493: for (int i = 0; i < totalSize; i++) {
494: values[i] = ((COSNumber) operation.getOperand(i))
495: .floatValue();
496: }
497: device.setNonStrokeColorValues(values);
498: }
499:
500: protected void render_SC(CSOperation operation) {
501: // set color for stroking
502: int totalSize = operation.operandSize();
503: float[] values = new float[totalSize];
504: for (int i = 0; i < totalSize; i++) {
505: values[i] = ((COSNumber) operation.getOperand(i))
506: .floatValue();
507: }
508: device.setStrokeColorValues(values);
509: }
510:
511: protected void render_scn(CSOperation operation) {
512: // set color for non stroking (ICCBased, special color spaces)
513: int totalSize = operation.operandSize();
514: int numberSize = totalSize;
515: COSName patternName = null;
516: if ((totalSize > 0)
517: && (operation.getOperand(totalSize - 1) instanceof COSName)) {
518: patternName = (COSName) operation.getOperand(totalSize - 1);
519: numberSize--;
520: }
521: float[] values = new float[numberSize];
522: for (int i = 0; i < numberSize; i++) {
523: values[i] = ((COSNumber) operation.getOperand(i))
524: .floatValue();
525: }
526: if (patternName == null) {
527: device.setNonStrokeColorValues(values);
528: } else {
529: PDPattern pattern = lookupPattern(patternName);
530: device
531: .setNonStrokeColorValues(values, patternName,
532: pattern);
533: }
534: }
535:
536: protected void render_SCN(CSOperation operation) {
537: int totalSize = operation.operandSize();
538: int numberSize = totalSize;
539: COSName patternName = null;
540: if ((totalSize > 0)
541: && (operation.getOperand(totalSize - 1) instanceof COSName)) {
542: patternName = (COSName) operation.getOperand(totalSize - 1);
543: numberSize--;
544: }
545: float[] values = new float[numberSize];
546: for (int i = 0; i < numberSize; i++) {
547: values[i] = ((COSNumber) operation.getOperand(i))
548: .floatValue();
549: }
550: if (patternName == null) {
551: device.setStrokeColorValues(values);
552: } else {
553: PDPattern pattern = lookupPattern(patternName);
554: device.setStrokeColorValues(values, patternName, pattern);
555: }
556: }
557:
558: protected void render_sh(CSOperation operation) {
559: COSName name;
560: PDShading shading;
561:
562: name = operation.getOperand(0).asName();
563: shading = lookupShading(name);
564: device.doShading(name, shading);
565: }
566:
567: protected void render_Tc(CSOperation operation) {
568: float value = ((COSNumber) operation.getOperand(0))
569: .floatValue();
570: device.textSetCharSpacing(value);
571: }
572:
573: protected void render_Td(CSOperation operation) {
574: float x = ((COSNumber) operation.getOperand(0)).floatValue();
575: float y = ((COSNumber) operation.getOperand(1)).floatValue();
576: device.textLineMove(x, y);
577: }
578:
579: protected void render_TD(CSOperation operation) {
580: float x = ((COSNumber) operation.getOperand(0)).floatValue();
581: float y = ((COSNumber) operation.getOperand(1)).floatValue();
582: device.textSetLeading(y);
583: device.textLineMove(x, y);
584: }
585:
586: private float fontSize = 0;
587:
588: protected void render_Tf(CSOperation operation) throws CSWarning {
589: COSName fontname = operation.getOperand(0).asName();
590: float size = operation.getOperand(1).asNumber().floatValue();
591: PDFont pdFont = PDFontTools.getFont(getDoc(), getResources(),
592: fontname);
593: fontSize = size;
594: device.textSetFont(fontname, pdFont, size);
595: }
596:
597: protected void render_Tj(CSOperation operation) throws CSException {
598: byte[] value = ((COSString) operation.getOperand(0))
599: .byteValue();
600: device.textShow(value, 0, value.length);
601: }
602:
603: protected void render_TJ(CSOperation operation) throws CSException {
604: COSArray array = operation.getOperand(0).asArray();
605: Iterator it = array.iterator();
606: while (it.hasNext()) {
607: COSObject cosObj;
608: cosObj = (COSObject) it.next();
609: if (cosObj instanceof COSNumber) {
610: float offset = ((COSNumber) cosObj).floatValue();
611: float advance = -offset / 1000
612: * horizontalScalingFactor * fontSize;
613: device.textMove(advance, 0);
614: } else if (cosObj instanceof COSString) {
615: byte[] value = ((COSString) cosObj).byteValue();
616: device.textShow(value, 0, value.length);
617: } else {
618: // todo 2 report warning
619: continue;
620: }
621: }
622: }
623:
624: protected void render_TL(CSOperation operation) {
625: float value = ((COSNumber) operation.getOperand(0))
626: .floatValue();
627: device.textSetLeading(-value);
628: }
629:
630: protected void render_Tm(CSOperation operation) {
631: float a = ((COSNumber) operation.getOperand(0)).floatValue();
632: float b = ((COSNumber) operation.getOperand(1)).floatValue();
633: float c = ((COSNumber) operation.getOperand(2)).floatValue();
634: float d = ((COSNumber) operation.getOperand(3)).floatValue();
635: float e = ((COSNumber) operation.getOperand(4)).floatValue();
636: float f = ((COSNumber) operation.getOperand(5)).floatValue();
637: device.textSetTransform(a, b, c, d, e, f);
638: }
639:
640: protected void render_Tr(CSOperation operation) {
641: int value = ((COSNumber) operation.getOperand(0)).intValue();
642: device.textSetRenderingMode(value);
643: }
644:
645: protected void render_Ts(CSOperation operation) {
646: float value = ((COSNumber) operation.getOperand(0))
647: .floatValue();
648: device.textSetRise(value);
649: }
650:
651: protected void render_Tstar(CSOperation operation) {
652: device.textLineNew();
653: }
654:
655: protected void render_Tw(CSOperation operation) {
656: float value = ((COSNumber) operation.getOperand(0))
657: .floatValue();
658: device.textSetWordSpacing(value);
659: }
660:
661: private float horizontalScalingFactor = 1;
662:
663: protected void render_Tz(CSOperation operation) {
664: float value = ((COSNumber) operation.getOperand(0))
665: .floatValue();
666: horizontalScalingFactor = value / 100;
667: device.textSetHorizontalScaling(value);
668: }
669:
670: protected void render_v(CSOperation operation) {
671: float x2 = ((COSNumber) operation.getOperand(0)).floatValue();
672: float y2 = ((COSNumber) operation.getOperand(1)).floatValue();
673: float x3 = ((COSNumber) operation.getOperand(2)).floatValue();
674: float y3 = ((COSNumber) operation.getOperand(3)).floatValue();
675: device.penCurveToV(x2, y2, x3, y3);
676: }
677:
678: protected void render_w(CSOperation operation) {
679: device.setLineWidth(((COSNumber) operation.getOperand(0))
680: .floatValue());
681: }
682:
683: protected void render_W(CSOperation operation) {
684: device.pathClipNonZero();
685: }
686:
687: protected void render_Wstar(CSOperation operation) {
688: device.pathClipEvenOdd();
689: }
690:
691: protected void render_y(CSOperation operation) {
692: float x1 = ((COSNumber) operation.getOperand(0)).floatValue();
693: float y1 = ((COSNumber) operation.getOperand(1)).floatValue();
694: float x2 = ((COSNumber) operation.getOperand(2)).floatValue();
695: float y2 = ((COSNumber) operation.getOperand(3)).floatValue();
696: device.penCurveToY(x1, y1, x2, y2);
697: }
698:
699: protected void render_q(CSOperation operation) throws CSException {
700: device.saveState();
701: }
702:
703: protected void render_Q(CSOperation operation) throws CSException {
704: device.restoreState();
705: }
706: }
|