Path: blob/master/src/java.desktop/share/classes/sun/print/PSStreamPrintService.java
41153 views
/*1* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.print;2627import java.io.OutputStream;28import java.util.Iterator;29import java.util.Locale;3031import javax.print.DocFlavor;32import javax.print.DocPrintJob;33import javax.print.StreamPrintService;34import javax.print.StreamPrintServiceFactory;35import javax.print.ServiceUIFactory;36import javax.print.attribute.Attribute;37import javax.print.attribute.AttributeSet;38import javax.print.attribute.AttributeSetUtilities;39import javax.print.attribute.HashAttributeSet;40import javax.print.attribute.HashPrintServiceAttributeSet;41import javax.print.attribute.PrintServiceAttribute;42import javax.print.attribute.PrintServiceAttributeSet;43import javax.print.attribute.Size2DSyntax;44import javax.print.event.PrintServiceAttributeListener;45import javax.print.attribute.standard.JobName;46import javax.print.attribute.standard.RequestingUserName;47import javax.print.attribute.standard.Chromaticity;48import javax.print.attribute.standard.ColorSupported;49import javax.print.attribute.standard.Copies;50import javax.print.attribute.standard.CopiesSupported;51import javax.print.attribute.standard.Fidelity;52import javax.print.attribute.standard.Media;53import javax.print.attribute.standard.MediaPrintableArea;54import javax.print.attribute.standard.MediaSize;55import javax.print.attribute.standard.MediaSizeName;56import javax.print.attribute.standard.OrientationRequested;57import javax.print.attribute.standard.PageRanges;58import javax.print.attribute.standard.SheetCollate;59import javax.print.attribute.standard.Sides;6061public class PSStreamPrintService extends StreamPrintService62implements SunPrinterJobService {6364private static final Class<?>[] suppAttrCats = {65Chromaticity.class,66Copies.class,67Fidelity.class,68JobName.class,69Media.class,70MediaPrintableArea.class,71OrientationRequested.class,72PageRanges.class,73RequestingUserName.class,74SheetCollate.class,75Sides.class,76};7778private static int MAXCOPIES = 1000;7980private static final MediaSizeName[] mediaSizes = {81MediaSizeName.NA_LETTER,82MediaSizeName.TABLOID,83MediaSizeName.LEDGER,84MediaSizeName.NA_LEGAL,85MediaSizeName.EXECUTIVE,86MediaSizeName.ISO_A3,87MediaSizeName.ISO_A4,88MediaSizeName.ISO_A5,89MediaSizeName.ISO_B4,90MediaSizeName.ISO_B5,91};9293public PSStreamPrintService(OutputStream out) {94super(out);95}9697public String getOutputFormat() {98return PSStreamPrinterFactory.psMimeType;99}100101102public DocFlavor[] getSupportedDocFlavors() {103return PSStreamPrinterFactory.getFlavors();104}105106public DocPrintJob createPrintJob() {107return new PSStreamPrintJob(this);108}109110public boolean usesClass(Class<?> c) {111return (c == sun.print.PSPrinterJob.class);112}113114public String getName() {115return "Postscript output";116}117118public void addPrintServiceAttributeListener(119PrintServiceAttributeListener listener) {120return;121}122123public void removePrintServiceAttributeListener(124PrintServiceAttributeListener listener) {125return;126}127128129public <T extends PrintServiceAttribute>130T getAttribute(Class<T> category)131{132if (category == null) {133throw new NullPointerException("category");134}135if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {136throw new IllegalArgumentException("Not a PrintServiceAttribute");137}138if (category == ColorSupported.class) {139@SuppressWarnings("unchecked")140T tmp = (T)ColorSupported.SUPPORTED;141return tmp;142} else {143return null;144}145}146public PrintServiceAttributeSet getAttributes() {147PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();148attrs.add(ColorSupported.SUPPORTED);149150return AttributeSetUtilities.unmodifiableView(attrs);151}152153public boolean isDocFlavorSupported(DocFlavor flavor) {154DocFlavor [] flavors = getSupportedDocFlavors();155for (int f=0; f<flavors.length; f++) {156if (flavor.equals(flavors[f])) {157return true;158}159}160return false;161}162163164public Class<?>[] getSupportedAttributeCategories() {165Class<?>[] cats = new Class<?>[suppAttrCats.length];166System.arraycopy(suppAttrCats, 0, cats, 0, cats.length);167return cats;168}169170public boolean171isAttributeCategorySupported(Class<? extends Attribute> category)172{173if (category == null) {174throw new NullPointerException("null category");175}176if (!(Attribute.class.isAssignableFrom(category))) {177throw new IllegalArgumentException(category +178" is not an Attribute");179}180181for (int i=0;i<suppAttrCats.length;i++) {182if (category == suppAttrCats[i]) {183return true;184}185}186return false;187}188189190public Object191getDefaultAttributeValue(Class<? extends Attribute> category)192{193if (category == null) {194throw new NullPointerException("null category");195}196if (!Attribute.class.isAssignableFrom(category)) {197throw new IllegalArgumentException(category +198" is not an Attribute");199}200201if (!isAttributeCategorySupported(category)) {202return null;203}204205if (category == Copies.class) {206return new Copies(1);207} else if (category == Chromaticity.class) {208return Chromaticity.COLOR;209} else if (category == Fidelity.class) {210return Fidelity.FIDELITY_FALSE;211} else if (category == Media.class) {212String defaultCountry = Locale.getDefault().getCountry();213if (defaultCountry != null &&214(defaultCountry.isEmpty() ||215defaultCountry.equals(Locale.US.getCountry()) ||216defaultCountry.equals(Locale.CANADA.getCountry()))) {217return MediaSizeName.NA_LETTER;218} else {219return MediaSizeName.ISO_A4;220}221} else if (category == MediaPrintableArea.class) {222String defaultCountry = Locale.getDefault().getCountry();223float iw, ih;224float margin = 0.5f; // both these papers > 5" in all dimensions225if (defaultCountry != null &&226(defaultCountry.isEmpty() ||227defaultCountry.equals(Locale.US.getCountry()) ||228defaultCountry.equals(Locale.CANADA.getCountry()))) {229iw = MediaSize.NA.LETTER.getX(Size2DSyntax.INCH) - 2*margin;230ih = MediaSize.NA.LETTER.getY(Size2DSyntax.INCH) - 2*margin;231} else {232iw = MediaSize.ISO.A4.getX(Size2DSyntax.INCH) - 2*margin;233ih = MediaSize.ISO.A4.getY(Size2DSyntax.INCH) - 2*margin;234}235return new MediaPrintableArea(margin, margin, iw, ih,236MediaPrintableArea.INCH);237} else if (category == OrientationRequested.class) {238return OrientationRequested.PORTRAIT;239} else if (category == PageRanges.class) {240return new PageRanges(1, Integer.MAX_VALUE);241} else if (category == SheetCollate.class) {242return SheetCollate.UNCOLLATED;243} else if (category == Sides.class) {244return Sides.ONE_SIDED;245246} else247return null;248}249250251public Object252getSupportedAttributeValues(Class<? extends Attribute> category,253DocFlavor flavor,254AttributeSet attributes)255{256257if (category == null) {258throw new NullPointerException("null category");259}260if (!Attribute.class.isAssignableFrom(category)) {261throw new IllegalArgumentException(category +262" does not implement Attribute");263}264if (flavor != null && !isDocFlavorSupported(flavor)) {265throw new IllegalArgumentException(flavor +266" is an unsupported flavor");267}268269if (!isAttributeCategorySupported(category)) {270return null;271}272273if (category == Chromaticity.class) {274Chromaticity[]arr = new Chromaticity[1];275arr[0] = Chromaticity.COLOR;276//arr[1] = Chromaticity.MONOCHROME;277return (arr);278} else if (category == JobName.class) {279return new JobName("", null);280} else if (category == RequestingUserName.class) {281return new RequestingUserName("", null);282} else if (category == OrientationRequested.class) {283if (flavor == null ||284flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||285flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||286flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||287flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||288flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||289flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||290flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||291flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||292flavor.equals(DocFlavor.URL.GIF) ||293flavor.equals(DocFlavor.URL.JPEG) ||294flavor.equals(DocFlavor.URL.PNG)) {295OrientationRequested []arr = new OrientationRequested[3];296arr[0] = OrientationRequested.PORTRAIT;297arr[1] = OrientationRequested.LANDSCAPE;298arr[2] = OrientationRequested.REVERSE_LANDSCAPE;299return arr;300} else {301return null;302}303} else if ((category == Copies.class) ||304(category == CopiesSupported.class)) {305return new CopiesSupported(1, MAXCOPIES);306} else if (category == Media.class) {307Media []arr = new Media[mediaSizes.length];308System.arraycopy(mediaSizes, 0, arr, 0, mediaSizes.length);309return arr;310} else if (category == Fidelity.class) {311Fidelity []arr = new Fidelity[2];312arr[0] = Fidelity.FIDELITY_FALSE;313arr[1] = Fidelity.FIDELITY_TRUE;314return arr;315} else if (category == MediaPrintableArea.class) {316if (attributes == null) {317return null;318}319MediaSize mediaSize = (MediaSize)attributes.get(MediaSize.class);320if (mediaSize == null) {321Media media = (Media)attributes.get(Media.class);322if (media != null && media instanceof MediaSizeName) {323MediaSizeName msn = (MediaSizeName)media;324mediaSize = MediaSize.getMediaSizeForName(msn);325}326}327if (mediaSize == null) {328return null;329} else {330MediaPrintableArea []arr = new MediaPrintableArea[1];331float w = mediaSize.getX(MediaSize.INCH);332float h = mediaSize.getY(MediaSize.INCH);333/* For dimensions >= 5 inches use 0.5 inch margins.334* For smaller dimensions, use 10% margins.335*/336float xmargin = 0.5f;337float ymargin = 0.5f;338if (w < 5f) {339xmargin = w/10;340}341if (h < 5f) {342ymargin = h/10;343}344arr[0] = new MediaPrintableArea(xmargin, ymargin,345w - 2*xmargin,346h - 2*ymargin,347MediaSize.INCH);348return arr;349}350} else if (category == PageRanges.class) {351if (flavor == null ||352flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||353flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {354PageRanges []arr = new PageRanges[1];355arr[0] = new PageRanges(1, Integer.MAX_VALUE);356return arr;357} else {358return null;359}360} else if (category == SheetCollate.class) {361if (flavor == null ||362flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||363flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {364SheetCollate []arr = new SheetCollate[2];365arr[0] = SheetCollate.UNCOLLATED;366arr[1] = SheetCollate.COLLATED;367return arr;368} else {369SheetCollate []arr = new SheetCollate[1];370arr[0] = SheetCollate.UNCOLLATED;371return arr;372}373} else if (category == Sides.class) {374if (flavor == null ||375flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||376flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {377Sides []arr = new Sides[3];378arr[0] = Sides.ONE_SIDED;379arr[1] = Sides.TWO_SIDED_LONG_EDGE;380arr[2] = Sides.TWO_SIDED_SHORT_EDGE;381return arr;382} else {383return null;384}385} else {386return null;387}388}389390private boolean isSupportedCopies(Copies copies) {391int numCopies = copies.getValue();392return (numCopies > 0 && numCopies < MAXCOPIES);393}394395private boolean isSupportedMedia(MediaSizeName msn) {396for (int i=0; i<mediaSizes.length; i++) {397if (msn.equals(mediaSizes[i])) {398return true;399}400}401return false;402}403404public boolean isAttributeValueSupported(Attribute attr,405DocFlavor flavor,406AttributeSet attributes) {407if (attr == null) {408throw new NullPointerException("null attribute");409}410if (flavor != null && !isDocFlavorSupported(flavor)) {411throw new IllegalArgumentException(flavor +412" is an unsupported flavor");413}414Class<? extends Attribute> category = attr.getCategory();415if (!isAttributeCategorySupported(category)) {416return false;417}418else if (attr.getCategory() == Chromaticity.class) {419return attr == Chromaticity.COLOR;420}421else if (attr.getCategory() == Copies.class) {422return isSupportedCopies((Copies)attr);423} else if (attr.getCategory() == Media.class &&424attr instanceof MediaSizeName) {425return isSupportedMedia((MediaSizeName)attr);426} else if (attr.getCategory() == OrientationRequested.class) {427if (attr == OrientationRequested.REVERSE_PORTRAIT ||428(flavor != null) &&429!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||430flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {431return false;432}433} else if (attr.getCategory() == PageRanges.class) {434if (flavor != null &&435!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||436flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {437return false;438}439} else if (attr.getCategory() == SheetCollate.class) {440if (flavor != null &&441!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||442flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {443return false;444}445} else if (attr.getCategory() == Sides.class) {446if (flavor != null &&447!(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||448flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {449return false;450}451}452return true;453}454455public AttributeSet getUnsupportedAttributes(DocFlavor flavor,456AttributeSet attributes) {457458if (flavor != null && !isDocFlavorSupported(flavor)) {459throw new IllegalArgumentException("flavor " + flavor +460"is not supported");461}462463if (attributes == null) {464return null;465}466467Attribute attr;468AttributeSet unsupp = new HashAttributeSet();469Attribute[] attrs = attributes.toArray();470for (int i=0; i<attrs.length; i++) {471try {472attr = attrs[i];473if (!isAttributeCategorySupported(attr.getCategory())) {474unsupp.add(attr);475} else if (!isAttributeValueSupported(attr, flavor,476attributes)) {477unsupp.add(attr);478}479} catch (ClassCastException e) {480}481}482if (unsupp.isEmpty()) {483return null;484} else {485return unsupp;486}487}488489public ServiceUIFactory getServiceUIFactory() {490return null;491}492493public String toString() {494return "PSStreamPrintService: " + getName();495}496497/* Stream services have an output stream which cannot be shared,498* so two services are equal only if they are the same object.499*/500public boolean equals(Object obj) {501return (obj == this ||502(obj instanceof PSStreamPrintService &&503((PSStreamPrintService)obj).getName().equals(getName())));504}505506public int hashCode() {507return this.getClass().hashCode()+getName().hashCode();508}509510}511512513