1 /*
  2  * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package sun.print;
 27 
 28 import java.io.Serial;
 29 import java.util.ArrayList;
 30 
 31 import javax.print.attribute.EnumSyntax;
 32 import javax.print.attribute.standard.Media;
 33 import javax.print.attribute.standard.MediaSize;
 34 import javax.print.attribute.standard.MediaSizeName;
 35 
 36 class CustomMediaSizeName extends MediaSizeName {
 37     private static ArrayList<String> customStringTable = new ArrayList<>();
 38     private static ArrayList<MediaSizeName> customEnumTable = new ArrayList<>();
 39     private String choiceName;
 40     private MediaSizeName mediaName;
 41 
 42     private CustomMediaSizeName(int x) {
 43         super(x);
 44 
 45     }
 46 
 47     private static synchronized int nextValue(String name) {
 48       customStringTable.add(name);
 49 
 50       return (customStringTable.size()-1);
 51     }
 52 
 53     public CustomMediaSizeName(String name) {
 54         super(nextValue(name));
 55         customEnumTable.add(this);
 56         choiceName = null;
 57         mediaName = null;
 58     }
 59 
 60     public CustomMediaSizeName(String name, String choice,
 61                                float width, float length) {
 62         super(nextValue(name));
 63         choiceName = choice;
 64         customEnumTable.add(this);
 65         mediaName = null;
 66         try {
 67             mediaName = MediaSize.findMedia(width, length,
 68                                             MediaSize.INCH);
 69         } catch (IllegalArgumentException iae) {
 70         }
 71         // The public API method finds a closest match even if it not
 72         // all that close. Here we want to be sure its *really* close.
 73         if (mediaName != null) {
 74             MediaSize sz = MediaSize.getMediaSizeForName(mediaName);
 75             if (sz == null) {
 76                 mediaName = null;
 77             } else {
 78                 float w = sz.getX(MediaSize.INCH);
 79                 float h = sz.getY(MediaSize.INCH);
 80                 float dw = Math.abs(w - width);
 81                 float dh = Math.abs(h - length);
 82                 if (dw > 0.1 || dh > 0.1) {
 83                     mediaName = null;
 84                 }
 85             }
 86         }
 87     }
 88 
 89     /**
 90      * Use serialVersionUID from JDK 1.5 for interoperability.
 91      */
 92     @Serial
 93     private static final long serialVersionUID = 7412807582228043717L;
 94 
 95     /**
 96      * Returns the command string for this media.
 97      */
 98     public String getChoiceName() {
 99         return choiceName;
100     }
101 
102 
103     /**
104      * Returns matching standard MediaSizeName.
105      */
106     public MediaSizeName getStandardMedia() {
107         return mediaName;
108     }
109 
110 
111     // moved from RasterPrinterJob
112     /**
113      * Returns closest matching MediaSizeName among given array of Media
114      */
115     public static MediaSizeName findMedia(Media[] media, float x, float y,
116                                           int units) {
117 
118 
119         if (x <= 0.0f || y <= 0.0f || units < 1) {
120             throw new IllegalArgumentException("args must be +ve values");
121         }
122 
123         if (media == null || media.length == 0) {
124             throw new IllegalArgumentException("args must have valid array of media");
125         }
126 
127         int size =0;
128         MediaSizeName[] msn = new MediaSizeName[media.length];
129         for (int i=0; i<media.length; i++) {
130             if (media[i] instanceof MediaSizeName) {
131                 msn[size++] = (MediaSizeName)media[i];
132             }
133         }
134 
135         if (size == 0) {
136             return null;
137         }
138 
139         int match = 0;
140 
141         double ls = x * x + y * y;
142         double tmp_ls;
143         float []dim;
144         float diffx = x;
145         float diffy = y;
146 
147         for (int i=0; i < size ; i++) {
148             MediaSize mediaSize = MediaSize.getMediaSizeForName(msn[i]);
149             if (mediaSize == null) {
150                 continue;
151             }
152             dim = mediaSize.getSize(units);
153             if (x == dim[0] && y == dim[1]) {
154                 match = i;
155                 break;
156             } else {
157                 diffx = x - dim[0];
158                 diffy = y - dim[1];
159                 tmp_ls = diffx * diffx + diffy * diffy;
160                 if (tmp_ls < ls) {
161                     ls = tmp_ls;
162                     match = i;
163                 }
164             }
165         }
166 
167         return msn[match];
168     }
169 
170     /**
171      * Returns the string table for super class MediaSizeName.
172      */
173     public  Media[] getSuperEnumTable() {
174         return (Media[])super.getEnumValueTable();
175     }
176 
177 
178     /**
179      * Returns the string table for class CustomMediaSizeName.
180      */
181     protected String[] getStringTable() {
182       String[] nameTable = new String[customStringTable.size()];
183       return customStringTable.toArray(nameTable);
184     }
185 
186     /**
187      * Returns the enumeration value table for class CustomMediaSizeName.
188      */
189     protected EnumSyntax[] getEnumValueTable() {
190       MediaSizeName[] enumTable = new MediaSizeName[customEnumTable.size()];
191       return customEnumTable.toArray(enumTable);
192     }
193 
194 }