jdk/src/windows/classes/sun/awt/windows/WPathGraphics.java
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 8352 956b231fed62
child 17674 46246fbf98d4
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 8352
diff changeset
     2
 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.awt.windows;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.BasicStroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.Color;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.Font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.Graphics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.Graphics2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.Image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.Shape;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.awt.Stroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.Transparency;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.awt.font.FontRenderContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.awt.font.GlyphVector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.awt.font.TextLayout;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.awt.geom.AffineTransform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.awt.geom.NoninvertibleTransformException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.awt.geom.PathIterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.awt.geom.Point2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.awt.geom.Rectangle2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.awt.geom.Line2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import java.awt.image.BufferedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
import java.awt.image.ColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import java.awt.image.DataBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import java.awt.image.IndexColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import java.awt.image.WritableRaster;
8352
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
    54
import java.awt.image.ComponentSampleModel;
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
    55
import java.awt.image.MultiPixelPackedSampleModel;
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
    56
import java.awt.image.SampleModel;
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
    57
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
import sun.awt.image.ByteComponentRaster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
import sun.awt.image.BytePackedRaster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
import java.awt.print.PageFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
import java.awt.print.Printable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
import java.awt.print.PrinterException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
import java.awt.print.PrinterJob;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
import sun.font.CharToGlyphMapper;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
import sun.font.CompositeFont;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
import sun.font.Font2D;
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
    70
import sun.font.FontUtilities;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
import sun.font.PhysicalFont;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
import sun.font.TrueTypeFont;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
import sun.print.PathGraphics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
import sun.print.ProxyGraphics2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
class WPathGraphics extends PathGraphics {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     * For a drawing application the initial user space
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * resolution is 72dpi.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    private static final int DEFAULT_USER_RES = 72;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    private static final float MIN_DEVICE_LINEWIDTH = 1.2f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    private static final float MAX_THINLINE_INCHES = 0.014f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    /* Note that preferGDITextLayout implies useGDITextLayout.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
     * "prefer" is used to override cases where would otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * choose not to use it. Note that non-layout factors may
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * still mean that GDI cannot be used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    private static boolean useGDITextLayout = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    private static boolean preferGDITextLayout = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        String textLayoutStr =
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
            (String)java.security.AccessController.doPrivileged(
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                   new sun.security.action.GetPropertyAction(
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                         "sun.java2d.print.enableGDITextLayout"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        if (textLayoutStr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            useGDITextLayout = Boolean.getBoolean(textLayoutStr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            if (!useGDITextLayout) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                if (textLayoutStr.equalsIgnoreCase("prefer")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                    useGDITextLayout = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                    preferGDITextLayout = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    WPathGraphics(Graphics2D graphics, PrinterJob printerJob,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                  Printable painter, PageFormat pageFormat, int pageIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                  boolean canRedraw) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        super(graphics, printerJob, painter, pageFormat, pageIndex, canRedraw);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * Creates a new <code>Graphics</code> object that is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * a copy of this <code>Graphics</code> object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * @return     a new graphics context that is a copy of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     *                       this graphics context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * @since      JDK1.0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   125
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    public Graphics create() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        return new WPathGraphics((Graphics2D) getDelegate().create(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                                 getPrinterJob(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                                 getPrintable(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                                 getPageFormat(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
                                 getPageIndex(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                                 canDoRedraws());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * Strokes the outline of a Shape using the settings of the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * graphics state.  The rendering attributes applied include the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * clip, transform, paint or color, composite and stroke attributes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * @param s The shape to be drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * @see #setStroke
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * @see #setPaint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * @see java.awt.Graphics#setColor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * @see #transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * @see #setTransform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * @see #clip
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * @see #setClip
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * @see #setComposite
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   150
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    public void draw(Shape s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        Stroke stroke = getStroke();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        /* If the line being drawn is thinner than can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
         * rendered, then change the line width, stroke
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
         * the shape, and then set the line width back.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
         * We can only do this for BasicStroke's.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        if (stroke instanceof BasicStroke) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            BasicStroke lineStroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            BasicStroke minLineStroke = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            float deviceLineWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            float lineWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            AffineTransform deviceTransform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            Point2D.Float penSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            /* Get the requested line width in user space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            lineStroke = (BasicStroke) stroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
            lineWidth = lineStroke.getLineWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            penSize = new Point2D.Float(lineWidth, lineWidth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            /* Compute the line width in device coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
             * Work on a point in case there is asymetric scaling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
             * between user and device space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
             * Take the absolute value in case there is negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
             * scaling in effect.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            deviceTransform = getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            deviceTransform.deltaTransform(penSize, penSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            deviceLineWidth = Math.min(Math.abs(penSize.x),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                                       Math.abs(penSize.y));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            /* If the requested line is too thin then map our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
             * minimum line width back to user space and set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
             * a new BasicStroke.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            if (deviceLineWidth < MIN_DEVICE_LINEWIDTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                Point2D.Float minPenSize = new Point2D.Float(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                                                MIN_DEVICE_LINEWIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                                                MIN_DEVICE_LINEWIDTH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                    AffineTransform inverse;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                    float minLineWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                    /* Convert the minimum line width from device
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                     * space to user space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                    inverse = deviceTransform.createInverse();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                    inverse.deltaTransform(minPenSize, minPenSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                    minLineWidth = Math.max(Math.abs(minPenSize.x),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                                            Math.abs(minPenSize.y));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                    /* Use all of the parameters from the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                     * stroke but change the line width to our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                     * calculated minimum.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                    minLineStroke = new BasicStroke(minLineWidth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                                                    lineStroke.getEndCap(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                                                    lineStroke.getLineJoin(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                                                    lineStroke.getMiterLimit(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                                                    lineStroke.getDashArray(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                                                    lineStroke.getDashPhase());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                    setStroke(minLineStroke);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                } catch (NoninvertibleTransformException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                    /* If we can't invert the matrix there is something
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                     * very wrong so don't worry about the minor matter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                     * of a minimum line width.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            super.draw(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            /* If we changed the stroke, put back the old
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
             * stroke in order to maintain a minimum line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
             * width.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            if (minLineStroke != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                setStroke(lineStroke);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        /* The stroke in effect was not a BasicStroke so we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
         * will not try to enforce a minimum line width.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
            super.draw(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * Draws the text given by the specified string, using this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * graphics context's current font and color. The baseline of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * graphics context's coordinate system.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * @param       str      the string to be drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * @param       x        the <i>x</i> coordinate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * @param       y        the <i>y</i> coordinate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * @see         java.awt.Graphics#drawBytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * @see         java.awt.Graphics#drawChars
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     * @since       JDK1.0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   258
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    public void drawString(String str, int x, int y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        drawString(str, (float) x, (float) y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   263
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     public void drawString(String str, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
         drawString(str, x, y, getFont(), getFontRenderContext(), 0f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    /* A return value of 0 would mean font not available to GDI, or the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * it can't be used for this string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     * A return of 1 means it is suitable, including for composites.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * We check that the transform in effect is doable with GDI, and that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * this is a composite font AWT can handle, or a physical font GDI
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * can handle directly. Its possible that some strings may ultimately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * fail the more stringent tests in drawString but this is rare and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * also that method will always succeed, as if the font isn't available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * it will use outlines via a superclass call. Also it is only called for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * the default render context (as canDrawStringToWidth() will return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * false. That is why it ignores the frc and width arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   280
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    protected int platformFontCount(Font font, String str) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        AffineTransform deviceTransform = getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        AffineTransform fontTransform = new AffineTransform(deviceTransform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        fontTransform.concatenate(getFont().getTransform());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        int transformType = fontTransform.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        /* Test if GDI can handle the transform */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        boolean directToGDI = ((transformType !=
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                               AffineTransform.TYPE_GENERAL_TRANSFORM)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                               && ((transformType & AffineTransform.TYPE_FLIP)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                                   == 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        if (!directToGDI) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        /* Since all windows fonts are available, and the JRE fonts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
         * are also registered. Only the Font.createFont() case is presently
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
         * unknown to GDI. Those can be registered too, although that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
         * code does not exist yet, it can be added too, so we should not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
         * fail that case. Just do a quick check whether its a TrueTypeFont
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
         * - ie not a Type1 font etc, and let drawString() resolve the rest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
         */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   305
        Font2D font2D = FontUtilities.getFont2D(font);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        if (font2D instanceof CompositeFont ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            font2D instanceof TrueTypeFont) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    private static boolean isXP() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        String osVersion = System.getProperty("os.version");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        if (osVersion != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            Float version = Float.valueOf(osVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            return (version.floatValue() >= 5.1f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    /* In case GDI doesn't handle shaping or BIDI consistently with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * 2D's TextLayout, we can detect these cases and redelegate up to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * be drawn via TextLayout, which in is rendered as runs of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * GlyphVectors, to which we can assign positions for each glyph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    private boolean strNeedsTextLayout(String str, Font font) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        char[] chars = str.toCharArray();
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   331
        boolean isComplex = FontUtilities.isComplexText(chars, 0, chars.length);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        if (!isComplex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        } else if (!useGDITextLayout) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            if (preferGDITextLayout ||
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   338
                (isXP() && FontUtilities.textLayoutIsCompatible(font))) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    private int getAngle(Point2D.Double pt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        /* Get the rotation in 1/10'ths degree (as needed by Windows)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
         * so that GDI can draw the text rotated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
         * This calculation is only valid for a uniform scale, no shearing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        double angle = Math.toDegrees(Math.atan2(pt.y, pt.x));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        if (angle < 0.0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            angle+= 360.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        /* Windows specifies the rotation anti-clockwise from the x-axis
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
         * of the device, 2D specifies +ve rotation towards the y-axis
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
         * Since the 2D y-axis runs from top-to-bottom, windows angle of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
         * rotation here is opposite than 2D's, so the rotation needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
         * needs to be recalculated in the opposite direction.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        if (angle != 0.0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            angle = 360.0 - angle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        return (int)Math.round(angle * 10.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    private float getAwScale(double scaleFactorX, double scaleFactorY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        float awScale = (float)(scaleFactorX/scaleFactorY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        /* don't let rounding errors be interpreted as non-uniform scale */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        if (awScale > 0.999f && awScale < 1.001f) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            awScale = 1.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        return awScale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     * Renders the text specified by the specified <code>String</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * using the current <code>Font</code> and <code>Paint</code> attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * in the <code>Graphics2D</code> context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * The baseline of the first character is at position
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     * The rendering attributes applied include the <code>Clip</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * <code>Composite</code> attributes. For characters in script systems
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     * such as Hebrew and Arabic, the glyphs can be rendered from right to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     * left, in which case the coordinate supplied is the location of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * leftmost character on the baseline.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * @param s the <code>String</code> to be rendered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * @param x,&nbsp;y the coordinates where the <code>String</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * should be rendered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * @see #setPaint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * @see java.awt.Graphics#setColor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * @see java.awt.Graphics#setFont
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     * @see #setTransform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * @see #setComposite
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * @see #setClip
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   399
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    public void drawString(String str, float x, float y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                           Font font, FontRenderContext frc, float targetW) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        if (str.length() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        if (WPrinterJob.shapeTextProp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            super.drawString(str, x, y, font, frc, targetW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        /* If the Font has layout attributes we need to delegate to TextLayout.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
         * TextLayout renders text as GlyphVectors. We try to print those
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
         * using printer fonts - ie using Postscript text operators so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
         * we may be reinvoked. In that case the "!printingGlyphVector" test
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
         * prevents us recursing and instead sends us into the body of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
         * method where we can safely ignore layout attributes as those
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
         * are already handled by TextLayout.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
         * Similarly if layout is needed based on the text, then we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
         * delegate to TextLayout if possible, or failing that we delegate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
         * upwards to filled shapes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        boolean layoutNeeded = strNeedsTextLayout(str, font);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        if ((font.hasLayoutAttributes() || layoutNeeded)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            && !printingGlyphVector) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            TextLayout layout = new TextLayout(str, font, frc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            layout.draw(this, x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        } else if (layoutNeeded) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            super.drawString(str, x, y, font, frc, targetW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        AffineTransform deviceTransform = getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        AffineTransform fontTransform = new AffineTransform(deviceTransform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        fontTransform.concatenate(font.getTransform());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        int transformType = fontTransform.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        /* Use GDI for the text if the graphics transform is something
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
         * for which we can obtain a suitable GDI font.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
         * A flip or shearing transform on the graphics or a transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
         * on the font force us to decompose the text into a shape.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        boolean directToGDI = ((transformType !=
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                               AffineTransform.TYPE_GENERAL_TRANSFORM)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                               && ((transformType & AffineTransform.TYPE_FLIP)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                                   == 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            wPrinterJob.setTextColor((Color)getPaint());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        } catch (ClassCastException e) { // peek should detect such paints.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            directToGDI = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        if (!directToGDI) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            super.drawString(str, x, y, font, frc, targetW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        /* Now we have checked everything is OK to go through GDI as text
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
         * with the exception of testing GDI can find and use the font. That
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
         * is handled in the textOut() call.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        /* Compute the starting position of the string in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
         * device space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        Point2D.Float userpos = new Point2D.Float(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        Point2D.Float devpos = new Point2D.Float();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        /* Already have the translate from the deviceTransform,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
         * but the font may have a translation component too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        if (font.isTransformed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            AffineTransform fontTx = font.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            float translateX = (float)(fontTx.getTranslateX());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            float translateY = (float)(fontTx.getTranslateY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            if (Math.abs(translateX) < 0.00001) translateX = 0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            if (Math.abs(translateY) < 0.00001) translateY = 0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
            userpos.x += translateX; userpos.y += translateY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        deviceTransform.transform(userpos, devpos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        if (getClip() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
            deviceClip(getClip().getPathIterator(deviceTransform));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        /* Get the font size in device coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
         * The size needed is the font height scaled to device space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
         * Although we have already tested that there is no shear,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
         * there may be a non-uniform scale, so the width of the font
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
         * does not scale equally with the height. That is handled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
         * by specifying an 'average width' scale to GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        float fontSize = font.getSize2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        Point2D.Double pty = new Point2D.Double(0.0, 1.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        fontTransform.deltaTransform(pty, pty);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        double scaleFactorY = Math.sqrt(pty.x*pty.x+pty.y*pty.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        float scaledFontSizeY = (float)(fontSize * scaleFactorY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        Point2D.Double ptx = new Point2D.Double(1.0, 0.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        fontTransform.deltaTransform(ptx, ptx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        double scaleFactorX = Math.sqrt(ptx.x*ptx.x+ptx.y*ptx.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        float scaledFontSizeX = (float)(fontSize * scaleFactorX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        float awScale = getAwScale(scaleFactorX, scaleFactorY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        int iangle = getAngle(ptx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   510
        Font2D font2D = FontUtilities.getFont2D(font);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        if (font2D instanceof TrueTypeFont) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            textOut(str, font, (TrueTypeFont)font2D, frc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                    scaledFontSizeY, iangle, awScale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                    deviceTransform, scaleFactorX,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                    x, y, devpos.x, devpos.y, targetW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        } else if (font2D instanceof CompositeFont) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            /* Composite fonts are made up of multiple fonts and each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
             * substring that uses a particular component font needs to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
             * be separately sent to GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
             * This works for standard composite fonts, alternate ones,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
             * Fonts that are a physical font backed by a standard composite,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
             * and with fallback fonts.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            CompositeFont compFont = (CompositeFont)font2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            float userx = x, usery = y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            float devx = devpos.x, devy = devpos.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            char[] chars = str.toCharArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            int len = chars.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            int[] glyphs = new int[len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            compFont.getMapper().charsToGlyphs(len, chars, glyphs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            int startChar = 0, endChar = 0, slot = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            while (endChar < len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                startChar = endChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                slot = glyphs[startChar] >>> 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                while (endChar < len && ((glyphs[endChar] >>> 24) == slot)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                    endChar++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                String substr = new String(chars, startChar,endChar-startChar);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                PhysicalFont slotFont = compFont.getSlotFont(slot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                textOut(substr, font, slotFont, frc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                        scaledFontSizeY, iangle, awScale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                        deviceTransform, scaleFactorX,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                        userx, usery, devx, devy, 0f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                Rectangle2D bds = font.getStringBounds(substr, frc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                float xAdvance = (float)bds.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                userx += xAdvance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                userpos.x += xAdvance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                deviceTransform.transform(userpos, devpos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            super.drawString(str, x, y, font, frc, targetW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    /** return true if the Graphics instance can directly print
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * this glyphvector
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   561
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    protected boolean printGlyphVector(GlyphVector gv, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
        /* We don't want to try to handle per-glyph transforms. GDI can't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
         * handle per-glyph rotations, etc. There's no way to express it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
         * in a single call, so just bail for this uncommon case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        if ((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        AffineTransform deviceTransform = getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        AffineTransform fontTransform = new AffineTransform(deviceTransform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        Font font = gv.getFont();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        fontTransform.concatenate(font.getTransform());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        int transformType = fontTransform.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        /* Use GDI for the text if the graphics transform is something
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
         * for which we can obtain a suitable GDI font.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
         * A flip or shearing transform on the graphics or a transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
         * on the font force us to decompose the text into a shape.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        boolean directToGDI =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            ((transformType != AffineTransform.TYPE_GENERAL_TRANSFORM) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
             ((transformType & AffineTransform.TYPE_FLIP) == 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            wPrinterJob.setTextColor((Color)getPaint());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        } catch (ClassCastException e) { // peek should detect such paints.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            directToGDI = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        if (WPrinterJob.shapeTextProp || !directToGDI) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        /* Compute the starting position of the string in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
         * device space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        Point2D.Float userpos = new Point2D.Float(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        Point2D.Float devpos = new Point2D.Float();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        /* Already have the translate from the deviceTransform,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
         * but the font may have a translation component too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        if (font.isTransformed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            AffineTransform fontTx = font.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            float translateX = (float)(fontTx.getTranslateX());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            float translateY = (float)(fontTx.getTranslateY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
            if (Math.abs(translateX) < 0.00001) translateX = 0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            if (Math.abs(translateY) < 0.00001) translateY = 0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            userpos.x += translateX; userpos.y += translateY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        deviceTransform.transform(userpos, devpos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        if (getClip() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            deviceClip(getClip().getPathIterator(deviceTransform));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        /* Get the font size in device coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
         * The size needed is the font height scaled to device space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
         * Although we have already tested that there is no shear,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
         * there may be a non-uniform scale, so the width of the font
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
         * does not scale equally with the height. That is handled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
         * by specifying an 'average width' scale to GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        float fontSize = font.getSize2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        Point2D.Double pty = new Point2D.Double(0.0, 1.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        fontTransform.deltaTransform(pty, pty);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        double scaleFactorY = Math.sqrt(pty.x*pty.x+pty.y*pty.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        float scaledFontSizeY = (float)(fontSize * scaleFactorY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        Point2D.Double pt = new Point2D.Double(1.0, 0.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        fontTransform.deltaTransform(pt, pt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        double scaleFactorX = Math.sqrt(pt.x*pt.x+pt.y*pt.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        float scaledFontSizeX = (float)(fontSize * scaleFactorX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        float awScale = getAwScale(scaleFactorX, scaleFactorY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        int iangle = getAngle(pt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        int numGlyphs = gv.getNumGlyphs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        int[] glyphCodes = gv.getGlyphCodes(0, numGlyphs, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        float[] glyphPos = gv.getGlyphPositions(0, numGlyphs, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        /* layout replaces glyphs which have been combined away
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
         * with 0xfffe or 0xffff. These are supposed to be invisible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
         * and we need to handle this here as GDI will interpret it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
         * as a missing glyph. We'll do it here by compacting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
         * glyph codes array, but we have to do it in conjunction with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
         * compacting the positions/advances arrays too AND updating
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
         * the number of glyphs ..
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
         * Note that since the slot number for composites is in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
         * significant byte we need to mask out that for comparison of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
         * the invisible glyph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
        int invisibleGlyphCnt = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        for (int gc=0; gc<numGlyphs; gc++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            if ((glyphCodes[gc] & 0xffff) >=
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                CharToGlyphMapper.INVISIBLE_GLYPHS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                invisibleGlyphCnt++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        if (invisibleGlyphCnt > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            int visibleGlyphCnt = numGlyphs - invisibleGlyphCnt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            int[] visibleGlyphCodes = new int[visibleGlyphCnt];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            float[] visiblePositions = new float[visibleGlyphCnt*2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            int index = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            for (int i=0; i<numGlyphs; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                if ((glyphCodes[i] & 0xffff)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                    < CharToGlyphMapper.INVISIBLE_GLYPHS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                    visibleGlyphCodes[index] = glyphCodes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                    visiblePositions[index*2]   = glyphPos[i*2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                    visiblePositions[index*2+1] = glyphPos[i*2+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                    index++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            numGlyphs = visibleGlyphCnt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            glyphCodes = visibleGlyphCodes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            glyphPos = visiblePositions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        /* To get GDI to rotate glyphs we need to specify the angle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
         * of rotation to GDI when creating the HFONT. This implicitly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
         * also rotates the baseline, and this adjusts the X & Y advances
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
         * of the glyphs accordingly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
         * When we specify the advances, they are in device space, so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
         * we don't want any further interpretation applied by GDI, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
         * since as noted the advances are interpreted in the HFONT's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
         * coordinate space, our advances would be rotated again.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
         * We don't have any way to tell GDI to rotate only the glyphs and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
         * not the advances, so we need to account for this in the advances
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
         * we supply, by supplying unrotated advances.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
         * Note that "iangle" is in the opposite direction to 2D's normal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
         * direction of rotation, so this rotation inverts the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
         * rotation element of the deviceTransform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        AffineTransform advanceTransform =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
            new AffineTransform(deviceTransform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        advanceTransform.rotate(iangle*Math.PI/1800.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        float[] glyphAdvPos = new float[glyphPos.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        advanceTransform.transform(glyphPos, 0,         //source
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                                   glyphAdvPos, 0,      //destination
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                                   glyphPos.length/2);  //num points
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   706
        Font2D font2D = FontUtilities.getFont2D(font);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        if (font2D instanceof TrueTypeFont) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
            String family = font2D.getFamilyName(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            int style = font.getStyle() | font2D.getStyle();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
            if (!wPrinterJob.setFont(family, scaledFontSizeY, style,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                                     iangle, awScale)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            wPrinterJob.glyphsOut(glyphCodes, devpos.x, devpos.y, glyphAdvPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        } else if (font2D instanceof CompositeFont) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            /* Composite fonts are made up of multiple fonts and each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
             * substring that uses a particular component font needs to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
             * be separately sent to GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
             * This works for standard composite fonts, alternate ones,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
             * Fonts that are a physical font backed by a standard composite,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
             * and with fallback fonts.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
            CompositeFont compFont = (CompositeFont)font2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            float userx = x, usery = y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            float devx = devpos.x, devy = devpos.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
            int start = 0, end = 0, slot = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            while (end < numGlyphs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
                start = end;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
                slot = glyphCodes[start] >>> 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                while (end < numGlyphs && ((glyphCodes[end] >>> 24) == slot)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                    end++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                /* If we can't get the font, bail to outlines.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                 * But we should always be able to get all fonts for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                 * Composites, so this is unlikely, so any overstriking
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                 * if only one slot is unavailable is not worth worrying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
                 * about.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
                PhysicalFont slotFont = compFont.getSlotFont(slot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                if (!(slotFont instanceof TrueTypeFont)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                String family = slotFont.getFamilyName(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                int style = font.getStyle() | slotFont.getStyle();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                if (!wPrinterJob.setFont(family, scaledFontSizeY, style,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                                         iangle, awScale)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                int[] glyphs = Arrays.copyOfRange(glyphCodes, start, end);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                float[] posns = Arrays.copyOfRange(glyphAdvPos,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                                                   start*2, end*2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                if (start != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    Point2D.Float p =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                        new Point2D.Float(x+glyphPos[start*2],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                                          y+glyphPos[start*2+1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    deviceTransform.transform(p, p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                    devx = p.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                    devy = p.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                wPrinterJob.glyphsOut(glyphs, devx, devy, posns);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    private void textOut(String str,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                          Font font, PhysicalFont font2D,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                          FontRenderContext frc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                          float deviceSize, int rotation, float awScale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                          AffineTransform deviceTransform,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                          double scaleFactorX,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                          float userx, float usery,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                          float devx, float devy, float targetW) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
         String family = font2D.getFamilyName(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
         int style = font.getStyle() | font2D.getStyle();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
         WPrinterJob wPrinterJob = (WPrinterJob)getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
         boolean setFont = wPrinterJob.setFont(family, deviceSize, style,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                                               rotation, awScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
         if (!setFont) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
             super.drawString(str, userx, usery, font, frc, targetW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
             return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
         float[] glyphPos = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
         if (!okGDIMetrics(str, font, frc, scaleFactorX)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
             /* If there is a 1:1 char->glyph mapping then char positions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
              * are the same as glyph positions and we can tell GDI
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
              * where to place the glyphs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
              * On drawing we remove control chars so these need to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
              * removed now so the string and positions are the same length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
              * For other cases we need to pass glyph codes to GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
              */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
             str = wPrinterJob.removeControlChars(str);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
             char[] chars = str.toCharArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
             int len = chars.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
             GlyphVector gv = null;
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 715
diff changeset
   805
             if (!FontUtilities.isComplexText(chars, 0, len)) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                 gv = font.createGlyphVector(frc, str);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
             if (gv == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                 super.drawString(str, userx, usery, font, frc, targetW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                 return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
             glyphPos = gv.getGlyphPositions(0, len, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
             Point2D gvAdvPt = gv.getGlyphPosition(gv.getNumGlyphs());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
             /* GDI advances must not include device space rotation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
              * See earlier comment in printGlyphVector() for details.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
              */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
             AffineTransform advanceTransform =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
               new AffineTransform(deviceTransform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
             advanceTransform.rotate(rotation*Math.PI/1800.0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
             float[] glyphAdvPos = new float[glyphPos.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
             advanceTransform.transform(glyphPos, 0,         //source
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                                        glyphAdvPos, 0,      //destination
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                                        glyphPos.length/2);  //num points
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
             glyphPos = glyphAdvPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
         wPrinterJob.textOut(str, devx, devy, glyphPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
     /* If 2D and GDI agree on the advance of the string we do not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
      * need to explicitly assign glyph positions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
      * If we are to use the GDI advance, require it to agree with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
      * JDK to a precision of <= 0.2% - ie 1 pixel in 500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
      * discrepancy after rounding the 2D advance to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
      * nearest pixel and is greater than one pixel in total.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
      * ie strings < 500 pixels in length will be OK so long
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
      * as they differ by only 1 pixel even though that is > 0.02%
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
      * The bounds from 2D are in user space so need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
      * be scaled to device space for comparison with GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
      * scaleX is the scale from user space to device space needed for this.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
     private boolean okGDIMetrics(String str, Font font,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                                  FontRenderContext frc, double scaleX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
         Rectangle2D bds = font.getStringBounds(str, frc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
         double jdkAdvance = bds.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
         jdkAdvance = Math.round(jdkAdvance*scaleX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
         int gdiAdvance = ((WPrinterJob)getPrinterJob()).getGDIAdvance(str);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
         if (jdkAdvance > 0 && gdiAdvance > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
             double diff = Math.abs(gdiAdvance-jdkAdvance);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
             double ratio = gdiAdvance/jdkAdvance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
             if (ratio < 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                 ratio = 1/ratio;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
             return diff <= 1 || ratio < 1.002;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
         return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
     * The various <code>drawImage()</code> methods for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
     * <code>WPathGraphics</code> are all decomposed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
     * into an invocation of <code>drawImageToPlatform</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
     * The portion of the passed in image defined by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
     * <code>srcX, srcY, srcWidth, and srcHeight</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
     * is transformed by the supplied AffineTransform and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
     * drawn using GDI to the printer context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
     * @param   img     The image to be drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
     * @param   xform   Used to tranform the image before drawing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
     *                  This can be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
     * @param   bgcolor This color is drawn where the image has transparent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
     *                  pixels. If this parameter is null then the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
     *                  pixels already in the destination should show
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
     *                  through.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
     * @param   srcX    With srcY this defines the upper-left corner
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
     *                  of the portion of the image to be drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
     * @param   srcY    With srcX this defines the upper-left corner
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
     *                  of the portion of the image to be drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
     * @param   srcWidth    The width of the portion of the image to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
     *                      be drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
     * @param   srcHeight   The height of the portion of the image to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
     *                      be drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
     * @param   handlingTransparency if being recursively called to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
     *                    print opaque region of transparent image
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
    protected boolean drawImageToPlatform(Image image, AffineTransform xform,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
                                          Color bgcolor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                                          int srcX, int srcY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                                          int srcWidth, int srcHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
                                          boolean handlingTransparency) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
        BufferedImage img = getBufferedImage(image);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
        if (img == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        /* The full transform to be applied to the image is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
         * caller's transform concatenated on to the transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
         * from user space to device space. If the caller didn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
         * supply a transform then we just act as if they passed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
         * in the identify transform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        AffineTransform fullTransform = getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        if (xform == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
            xform = new AffineTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
        fullTransform.concatenate(xform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
        /* Split the full transform into a pair of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
         * transforms. The first transform holds effects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
         * that GDI (under Win95) can not perform such
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
         * as rotation and shearing. The second transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
         * is setup to hold only the scaling effects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
         * These transforms are created such that a point,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
         * p, in user space, when transformed by 'fullTransform'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
         * lands in the same place as when it is transformed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
         * by 'rotTransform' and then 'scaleTransform'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
         * The entire image transformation is not in Java in order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
         * to minimize the amount of memory needed in the VM. By
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
         * dividing the transform in two, we rotate and shear
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
         * the source image in its own space and only go to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
         * the, usually, larger, device space when we ask
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
         * GDI to perform the final scaling.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
         * Clamp this to the device scale for better quality printing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
        double[] fullMatrix = new double[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
        fullTransform.getMatrix(fullMatrix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
        /* Calculate the amount of scaling in the x
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
         * and y directions. This scaling is computed by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
         * transforming a unit vector along each axis
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
         * and computing the resulting magnitude.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
         * The computed values 'scaleX' and 'scaleY'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
         * represent the amount of scaling GDI will be asked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
         * to perform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
        Point2D.Float unitVectorX = new Point2D.Float(1, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        Point2D.Float unitVectorY = new Point2D.Float(0, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
        fullTransform.deltaTransform(unitVectorX, unitVectorX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
        fullTransform.deltaTransform(unitVectorY, unitVectorY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
        Point2D.Float origin = new Point2D.Float(0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
        double scaleX = unitVectorX.distance(origin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
        double scaleY = unitVectorY.distance(origin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        double devResX = wPrinterJob.getXRes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        double devResY = wPrinterJob.getYRes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
        double devScaleX = devResX / DEFAULT_USER_RES;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        double devScaleY = devResY / DEFAULT_USER_RES;
553
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   956
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   957
        /* check if rotated or sheared */
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   958
        int transformType = fullTransform.getType();
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   959
        boolean clampScale = ((transformType &
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   960
                               (AffineTransform.TYPE_GENERAL_ROTATION |
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   961
                                AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   962
        if (clampScale) {
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   963
            if (scaleX > devScaleX) scaleX = devScaleX;
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   964
            if (scaleY > devScaleY) scaleY = devScaleY;
38a9503f374d 6696292: Printing transformed images accuracy problems
prr
parents: 2
diff changeset
   965
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        /* We do not need to draw anything if either scaling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
         * factor is zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
        if (scaleX != 0 && scaleY != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
            /* Here's the transformation we will do with Java2D,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
            */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
            AffineTransform rotTransform = new AffineTransform(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
                                        fullMatrix[0] / scaleX,  //m00
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
                                        fullMatrix[1] / scaleY,  //m10
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
                                        fullMatrix[2] / scaleX,  //m01
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
                                        fullMatrix[3] / scaleY,  //m11
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
                                        fullMatrix[4] / scaleX,  //m02
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
                                        fullMatrix[5] / scaleY); //m12
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
            /* The scale transform is not used directly: we instead
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
             * directly multiply by scaleX and scaleY.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
             * Conceptually here is what the scaleTransform is:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
             * AffineTransform scaleTransform = new AffineTransform(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
             *                      scaleX,                     //m00
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
             *                      0,                          //m10
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
             *                      0,                          //m01
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
             *                      scaleY,                     //m11
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
             *                      0,                          //m02
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
             *                      0);                         //m12
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
            /* Convert the image source's rectangle into the rotated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
             * and sheared space. Once there, we calculate a rectangle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
             * that encloses the resulting shape. It is this rectangle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
             * which defines the size of the BufferedImage we need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
             * create to hold the transformed image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
            Rectangle2D.Float srcRect = new Rectangle2D.Float(srcX, srcY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                                                              srcWidth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                                                              srcHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
            Shape rotShape = rotTransform.createTransformedShape(srcRect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
            Rectangle2D rotBounds = rotShape.getBounds2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
            /* add a fudge factor as some fp precision problems have
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
             * been observed which caused pixels to be rounded down and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
             * out of the image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
            rotBounds.setRect(rotBounds.getX(), rotBounds.getY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
                              rotBounds.getWidth()+0.001,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                              rotBounds.getHeight()+0.001);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
            int boundsWidth = (int) rotBounds.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
            int boundsHeight = (int) rotBounds.getHeight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
            if (boundsWidth > 0 && boundsHeight > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                /* If the image has transparent or semi-transparent
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
                 * pixels then we'll have the application re-render
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
                 * the portion of the page covered by the image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
                 * The BufferedImage will be at the image's resolution
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
                 * to avoid wasting memory. By re-rendering this portion
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
                 * of a page all compositing is done by Java2D into
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
                 * the BufferedImage and then that image is copied to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
                 * GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
                 * However several special cases can be handled otherwise:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
                 * - bitmask transparency with a solid background colour
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
                 * - images which have transparency color models but no
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
                 * transparent pixels
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
                 * - images with bitmask transparency and an IndexColorModel
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
                 * (the common transparent GIF case) can be handled by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
                 * rendering just the opaque pixels.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
                boolean drawOpaque = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
                if (!handlingTransparency && hasTransparentPixels(img)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
                    drawOpaque = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
                    if (isBitmaskTransparency(img)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                        if (bgcolor == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
                            if (drawBitmaskImage(img, xform, bgcolor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
                                                 srcX, srcY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
                                                 srcWidth, srcHeight)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
                                // image drawn, just return.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
                        } else if (bgcolor.getTransparency()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
                                   == Transparency.OPAQUE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
                            drawOpaque = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
                    if (!canDoRedraws()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                        drawOpaque = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                    // if there's no transparent pixels there's no need
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
                    // for a background colour. This can avoid edge artifacts
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
                    // in rotation cases.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
                    bgcolor = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
                // if src region extends beyond the image, the "opaque" path
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
                // may blit b/g colour (including white) where it shoudn't.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
                if ((srcX+srcWidth > img.getWidth(null) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
                     srcY+srcHeight > img.getHeight(null))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                    && canDoRedraws()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                    drawOpaque = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                if (drawOpaque == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
                    fullTransform.getMatrix(fullMatrix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
                    AffineTransform tx =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
                        new AffineTransform(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
                                            fullMatrix[0] / devScaleX,  //m00
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
                                            fullMatrix[1] / devScaleY,  //m10
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
                                            fullMatrix[2] / devScaleX,  //m01
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
                                            fullMatrix[3] / devScaleY,  //m11
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
                                            fullMatrix[4] / devScaleX,  //m02
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
                                            fullMatrix[5] / devScaleY); //m12
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
                    Rectangle2D.Float rect =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
                        new Rectangle2D.Float(srcX, srcY, srcWidth, srcHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
                    Shape shape = fullTransform.createTransformedShape(rect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                    // Region isn't user space because its potentially
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
                    // been rotated for landscape.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
                    Rectangle2D region = shape.getBounds2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
                    region.setRect(region.getX(), region.getY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
                                   region.getWidth()+0.001,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
                                   region.getHeight()+0.001);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
                    // Try to limit the amount of memory used to 8Mb, so
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
                    // if at device resolution this exceeds a certain
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
                    // image size then scale down the region to fit in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
                    // that memory, but never to less than 72 dpi.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
                    int w = (int)region.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
                    int h = (int)region.getHeight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
                    int nbytes = w * h * 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
                    int maxBytes = 8 * 1024 * 1024;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
                    double origDpi = (devResX < devResY) ? devResX : devResY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
                    int dpi = (int)origDpi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
                    double scaleFactor = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
                    double maxSFX = w/(double)boundsWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
                    double maxSFY = h/(double)boundsHeight;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
                    double maxSF = (maxSFX > maxSFY) ? maxSFY : maxSFX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
                    int minDpi = (int)(dpi/maxSF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
                    if (minDpi < DEFAULT_USER_RES) minDpi = DEFAULT_USER_RES;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
                    while (nbytes > maxBytes && dpi > minDpi) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
                        scaleFactor *= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
                        dpi /= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
                        nbytes /= 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
                    if (dpi < minDpi) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
                        scaleFactor = (origDpi / minDpi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
                    region.setRect(region.getX()/scaleFactor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
                                   region.getY()/scaleFactor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
                                   region.getWidth()/scaleFactor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
                                   region.getHeight()/scaleFactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
                     * We need to have the clip as part of the saved state,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
                     * either directly, or all the components that are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
                     * needed to reconstitute it (image source area,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
                     * image transform and current graphics transform).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
                     * The clip is described in user space, so we need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
                     * save the current graphics transform anyway so just
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
                     * save these two.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
                    wPrinterJob.saveState(getTransform(), getClip(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
                                          region, scaleFactor, scaleFactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
                    return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
                /* The image can be rendered directly by GDI so we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
                 * copy it into a BufferedImage (this takes care of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
                 * ColorSpace and BufferedImageOp issues) and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
                 * send that to GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
                    /* Create a buffered image big enough to hold the portion
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
                     * of the source image being printed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                     * The image format will be 3BYTE_BGR for most cases
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                     * except where we can represent the image as a 1, 4 or 8
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
                     * bits-per-pixel DIB.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
                    int dibType = BufferedImage.TYPE_3BYTE_BGR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                    IndexColorModel icm = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
                    ColorModel cm = img.getColorModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
                    int imgType = img.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
                    if (cm instanceof IndexColorModel &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
                        cm.getPixelSize() <= 8 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
                        (imgType == BufferedImage.TYPE_BYTE_BINARY ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
                         imgType == BufferedImage.TYPE_BYTE_INDEXED)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
                        icm = (IndexColorModel)cm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
                        dibType = imgType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
                        /* BYTE_BINARY may be 2 bpp which DIB can't handle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
                         * Convert this to 4bpp.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
                        if (imgType == BufferedImage.TYPE_BYTE_BINARY &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
                            cm.getPixelSize() == 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
                            int[] rgbs = new int[16];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
                            icm.getRGBs(rgbs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                            boolean transparent =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
                                icm.getTransparency() != Transparency.OPAQUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
                            int transpixel = icm.getTransparentPixel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
                            icm = new IndexColorModel(4, 16,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
                                                      rgbs, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
                                                      transparent, transpixel,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
                                                      DataBuffer.TYPE_BYTE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
                    int iw = (int)rotBounds.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
                    int ih = (int)rotBounds.getHeight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
                    BufferedImage deepImage = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
                    /* If there is no special transform needed (this is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                     * simple BLIT) and dibType == img.getType() and we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
                     * didn't create a new IndexColorModel AND the whole of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
                     * the source image is being drawn (GDI can't handle a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                     * portion of the original source image) then we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                     * don't need to create this intermediate image - GDI
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                     * can access the data from the original image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                     * Since a subimage can be created by calling
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
                     * BufferedImage.getSubImage() that condition needs to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                     * be accounted for too. This implies inspecting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
                     * data buffer. In the end too many cases are not able
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
                     * to take advantage of this option until we can teach
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
                     * the native code to properly navigate the data buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
                     * There was a concern that since in native code since we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
                     * need to DWORD align and flip to a bottom up DIB that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
                     * the "original" image may get perturbed by this.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
                     * But in fact we always malloc new memory for the aligned
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
                     * copy so this isn't a problem.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
                     * This points out that we allocate two temporaries copies
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
                     * of the image : one in Java and one in native. If
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
                     * we can be smarter about not allocating this one when
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
                     * not needed, that would seem like a good thing to do,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
                     * even if in many cases the ColorModels don't match and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
                     * its needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
                     * Until all of this is resolved newImage is always true.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
                    boolean newImage = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
                    if (newImage) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
                        if (icm == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                            deepImage = new BufferedImage(iw, ih, dibType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
                            deepImage = new BufferedImage(iw, ih, dibType,icm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
                        /* Setup a Graphics2D on to the BufferedImage so that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
                         * the source image when copied, lands within the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
                         * image buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
                        Graphics2D imageGraphics = deepImage.createGraphics();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
                        imageGraphics.clipRect(0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
                                               deepImage.getWidth(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
                                               deepImage.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
                        imageGraphics.translate(-rotBounds.getX(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
                                                -rotBounds.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
                        imageGraphics.transform(rotTransform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                        /* Fill the BufferedImage either with the caller
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                         * supplied color, 'bgColor' or, if null, with white.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                        if (bgcolor == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
                            bgcolor = Color.white;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
                        imageGraphics.drawImage(img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
                                                srcX, srcY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
                                                srcX + srcWidth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
                                                srcY + srcHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
                                                srcX, srcY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
                                                srcX + srcWidth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
                                                srcY + srcHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
                                                bgcolor, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
                        imageGraphics.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
                        deepImage = img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
                    /* Scale the bounding rectangle by the scale transform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
                     * Because the scaling transform has only x and y
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
                     * scaling components it is equivalent to multiply
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
                     * the x components of the bounding rectangle by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
                     * the x scaling factor and to multiply the y components
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
                     * by the y scaling factor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
                    Rectangle2D.Float scaledBounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
                            = new Rectangle2D.Float(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
                                    (float) (rotBounds.getX() * scaleX),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
                                    (float) (rotBounds.getY() * scaleY),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
                                    (float) (rotBounds.getWidth() * scaleX),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
                                    (float) (rotBounds.getHeight() * scaleY));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
                    /* Pull the raster data from the buffered image
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
                     * and pass it along to GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
                    WritableRaster raster = deepImage.getRaster();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
                    byte[] data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
                    if (raster instanceof ByteComponentRaster) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
                        data = ((ByteComponentRaster)raster).getDataStorage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
                    } else if (raster instanceof BytePackedRaster) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
                        data = ((BytePackedRaster)raster).getDataStorage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
                        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
8352
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1278
                    int bitsPerPixel = 24;
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1279
                    SampleModel sm = deepImage.getSampleModel();
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1280
                    if (sm instanceof ComponentSampleModel) {
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1281
                        ComponentSampleModel csm = (ComponentSampleModel)sm;
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1282
                        bitsPerPixel = csm.getPixelStride() * 8;
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1283
                    } else if (sm instanceof MultiPixelPackedSampleModel) {
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1284
                        MultiPixelPackedSampleModel mppsm =
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1285
                            (MultiPixelPackedSampleModel)sm;
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1286
                        bitsPerPixel = mppsm.getPixelBitStride();
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1287
                    } else {
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1288
                        if (icm != null) {
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1289
                            int diw = deepImage.getWidth();
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1290
                            int dih = deepImage.getHeight();
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1291
                            if (diw > 0 && dih > 0) {
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1292
                                bitsPerPixel = data.length*8/diw/dih;
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1293
                            }
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1294
                        }
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1295
                    }
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1296
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
                    /* Because the caller's image has been rotated
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
                     * and sheared into our BufferedImage and because
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
                     * we will be handing that BufferedImage directly to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
                     * GDI, we need to set an additional clip. This clip
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
                     * makes sure that only parts of the BufferedImage
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
                     * that are also part of the caller's image are drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
                    Shape holdClip = getClip();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
                    clip(xform.createTransformedShape(srcRect));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
                    deviceClip(getClip().getPathIterator(getTransform()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
                    wPrinterJob.drawDIBImage
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
                        (data, scaledBounds.x, scaledBounds.y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
                         (float)Math.rint(scaledBounds.width+0.5),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
                         (float)Math.rint(scaledBounds.height+0.5),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
                         0f, 0f,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
                         deepImage.getWidth(), deepImage.getHeight(),
8352
956b231fed62 7006865: Regression: Corrupted output when printing images with bit depth of 4
prr
parents: 5506
diff changeset
  1314
                         bitsPerPixel, icm);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
                    setClip(holdClip);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
     * Have the printing application redraw everything that falls
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
     * within the page bounds defined by <code>region</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
    public void redrawRegion(Rectangle2D region, double scaleX, double scaleY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
                             Shape savedClip, AffineTransform savedTransform)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
            throws PrinterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
        WPrinterJob wPrinterJob = (WPrinterJob)getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
        Printable painter = getPrintable();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
        PageFormat pageFormat = getPageFormat();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
        int pageIndex = getPageIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
        /* Create a buffered image big enough to hold the portion
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
         * of the source image being printed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
        BufferedImage deepImage = new BufferedImage(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
                                        (int) region.getWidth(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
                                        (int) region.getHeight(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
                                        BufferedImage.TYPE_3BYTE_BGR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
        /* Get a graphics for the application to render into.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
         * We initialize the buffer to white in order to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
         * match the paper and then we shift the BufferedImage
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
         * so that it covers the area on the page where the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
         * caller's Image will be drawn.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
        Graphics2D g = deepImage.createGraphics();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
        ProxyGraphics2D proxy = new ProxyGraphics2D(g, wPrinterJob);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
        proxy.setColor(Color.white);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        proxy.fillRect(0, 0, deepImage.getWidth(), deepImage.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
        proxy.clipRect(0, 0, deepImage.getWidth(), deepImage.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
        proxy.translate(-region.getX(), -region.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
        /* Calculate the resolution of the source image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
        float sourceResX = (float)(wPrinterJob.getXRes() / scaleX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
        float sourceResY = (float)(wPrinterJob.getYRes() / scaleY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
        /* The application expects to see user space at 72 dpi.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
         * so change user space from image source resolution to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
         *  72 dpi.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
        proxy.scale(sourceResX / DEFAULT_USER_RES,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
                    sourceResY / DEFAULT_USER_RES);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
        proxy.translate(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
            -wPrinterJob.getPhysicalPrintableX(pageFormat.getPaper())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
               / wPrinterJob.getXRes() * DEFAULT_USER_RES,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
            -wPrinterJob.getPhysicalPrintableY(pageFormat.getPaper())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
               / wPrinterJob.getYRes() * DEFAULT_USER_RES);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
        /* NB User space now has to be at 72 dpi for this calc to be correct */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
        proxy.transform(new AffineTransform(getPageFormat().getMatrix()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
        proxy.setPaint(Color.black);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
        painter.print(proxy, pageFormat, pageIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
        g.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
        /* We need to set the device clip using saved information.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
         * savedClip intersects the user clip with a clip that restricts
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
         * the GDI rendered area of our BufferedImage to that which
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
         * may correspond to a rotate or shear.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
         * The saved device transform is needed as the current transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
         * is not likely to be the same.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
        deviceClip(savedClip.getPathIterator(savedTransform));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
        /* Scale the bounding rectangle by the scale transform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
         * Because the scaling transform has only x and y
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
         * scaling components it is equivalent to multiplying
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
         * the x components of the bounding rectangle by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
         * the x scaling factor and to multiplying the y components
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
         * by the y scaling factor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
        Rectangle2D.Float scaledBounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
                = new Rectangle2D.Float(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
                        (float) (region.getX() * scaleX),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
                        (float) (region.getY() * scaleY),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
                        (float) (region.getWidth() * scaleX),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
                        (float) (region.getHeight() * scaleY));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
        /* Pull the raster data from the buffered image
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
         * and pass it along to GDI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
       ByteComponentRaster tile
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
                = (ByteComponentRaster)deepImage.getRaster();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
        wPrinterJob.drawImage3ByteBGR(tile.getDataStorage(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
                    scaledBounds.x, scaledBounds.y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
                    scaledBounds.width,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
                    scaledBounds.height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
                    0f, 0f,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
                    deepImage.getWidth(), deepImage.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
     * Fill the path defined by <code>pathIter</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
     * with the specified color.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
     * The path is provided in device coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
    protected void deviceFill(PathIterator pathIter, Color color) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
        WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
        convertToWPath(pathIter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
        wPrinterJob.selectSolidBrush(color);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
        wPrinterJob.fillPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
     * Set the printer device's clip to be the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
     * path defined by <code>pathIter</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
     * The path is provided in device coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
    protected void deviceClip(PathIterator pathIter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
        WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
        convertToWPath(pathIter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
        wPrinterJob.selectClipPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
     * Draw the bounding rectangle using transformed coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
     protected void deviceFrameRect(int x, int y, int width, int height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
                                     Color color) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
        AffineTransform deviceTransform = getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
        /* check if rotated or sheared */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
        int transformType = deviceTransform.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
        boolean usePath = ((transformType &
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
                           (AffineTransform.TYPE_GENERAL_ROTATION |
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
                            AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
        if (usePath) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
            draw(new Rectangle2D.Float(x, y, width, height));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
        Stroke stroke = getStroke();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
        if (stroke instanceof BasicStroke) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
            BasicStroke lineStroke = (BasicStroke) stroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
            int endCap = lineStroke.getEndCap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
            int lineJoin = lineStroke.getLineJoin();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
            /* check for default style and try to optimize it by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
             * calling the frameRect native function instead of using paths.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
            if ((endCap == BasicStroke.CAP_SQUARE) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
                (lineJoin == BasicStroke.JOIN_MITER) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
                (lineStroke.getMiterLimit() ==10.0f)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
                float lineWidth = lineStroke.getLineWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
                Point2D.Float penSize = new Point2D.Float(lineWidth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
                                                          lineWidth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
                deviceTransform.deltaTransform(penSize, penSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
                float deviceLineWidth = Math.min(Math.abs(penSize.x),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
                                                 Math.abs(penSize.y));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
                /* transform upper left coordinate */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
                Point2D.Float ul_pos = new Point2D.Float(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
                deviceTransform.transform(ul_pos, ul_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
                /* transform lower right coordinate */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
                Point2D.Float lr_pos = new Point2D.Float(x + width,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
                                                         y + height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
                deviceTransform.transform(lr_pos, lr_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
                float w = (float) (lr_pos.getX() - ul_pos.getX());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
                float h = (float)(lr_pos.getY() - ul_pos.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
                WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
                /* use selectStylePen, if supported */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
                if (wPrinterJob.selectStylePen(endCap, lineJoin,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
                                           deviceLineWidth, color) == true)  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
                    wPrinterJob.frameRect((float)ul_pos.getX(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
                                          (float)ul_pos.getY(), w, h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
                /* not supported, must be a Win 9x */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
                    double lowerRes = Math.min(wPrinterJob.getXRes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
                                               wPrinterJob.getYRes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
                    if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
                        /* use the default pen styles for thin pens. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
                        wPrinterJob.selectPen(deviceLineWidth, color);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
                        wPrinterJob.frameRect((float)ul_pos.getX(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
                                              (float)ul_pos.getY(), w, h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
                        draw(new Rectangle2D.Float(x, y, width, height));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
                draw(new Rectangle2D.Float(x, y, width, height));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
     /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
      * Fill the rectangle with specified color and using Windows'
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
      * GDI fillRect function.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
      * Boundaries are determined by the given coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
    protected void deviceFillRect(int x, int y, int width, int height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
                                  Color color) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
         * Transform to device coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
        AffineTransform deviceTransform = getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
        /* check if rotated or sheared */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
        int transformType = deviceTransform.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
        boolean usePath =  ((transformType &
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
                               (AffineTransform.TYPE_GENERAL_ROTATION |
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
                                AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
        if (usePath) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
            fill(new Rectangle2D.Float(x, y, width, height));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
        Point2D.Float tlc_pos = new Point2D.Float(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
        deviceTransform.transform(tlc_pos, tlc_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
        Point2D.Float brc_pos = new Point2D.Float(x+width, y+height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
        deviceTransform.transform(brc_pos, brc_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
        float deviceWidth = (float) (brc_pos.getX() - tlc_pos.getX());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
        float deviceHeight = (float)(brc_pos.getY() - tlc_pos.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
        WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
        wPrinterJob.fillRect((float)tlc_pos.getX(), (float)tlc_pos.getY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
                             deviceWidth, deviceHeight, color);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
     * Draw a line using a pen created using the specified color
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
     * and current stroke properties.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
    protected void deviceDrawLine(int xBegin, int yBegin, int xEnd, int yEnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
                                  Color color) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
        Stroke stroke = getStroke();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
        if (stroke instanceof BasicStroke) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
            BasicStroke lineStroke = (BasicStroke) stroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
            if (lineStroke.getDashArray() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
                draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
            float lineWidth = lineStroke.getLineWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
            Point2D.Float penSize = new Point2D.Float(lineWidth, lineWidth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
            AffineTransform deviceTransform = getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
            deviceTransform.deltaTransform(penSize, penSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
            float deviceLineWidth = Math.min(Math.abs(penSize.x),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
                                             Math.abs(penSize.y));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
            Point2D.Float begin_pos = new Point2D.Float(xBegin, yBegin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
            deviceTransform.transform(begin_pos, begin_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
            Point2D.Float end_pos = new Point2D.Float(xEnd, yEnd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
            deviceTransform.transform(end_pos, end_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
            int endCap = lineStroke.getEndCap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
            int lineJoin = lineStroke.getLineJoin();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
            /* check if it's a one-pixel line */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
            if ((end_pos.getX() == begin_pos.getX())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
                && (end_pos.getY() == begin_pos.getY())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
                /* endCap other than Round will not print!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
                 * due to Windows GDI limitation, force it to CAP_ROUND
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
                endCap = BasicStroke.CAP_ROUND;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
            WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
            /* call native function that creates pen with style */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
            if (wPrinterJob.selectStylePen(endCap, lineJoin,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
                                           deviceLineWidth, color)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
                wPrinterJob.moveTo((float)begin_pos.getX(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
                                   (float)begin_pos.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
                wPrinterJob.lineTo((float)end_pos.getX(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
                                   (float)end_pos.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
            /* selectStylePen is not supported, must be Win 9X */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
                /* let's see if we can use a a default pen
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
                 *  if it's round end (Windows' default style)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
                 *  or it's vertical/horizontal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
                 *  or stroke is too thin.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
                double lowerRes = Math.min(wPrinterJob.getXRes(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
                                           wPrinterJob.getYRes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
                if ((endCap == BasicStroke.CAP_ROUND) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
                 (((xBegin == xEnd) || (yBegin == yEnd)) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
                 (deviceLineWidth/lowerRes < MAX_THINLINE_INCHES))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
                    wPrinterJob.selectPen(deviceLineWidth, color);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
                    wPrinterJob.moveTo((float)begin_pos.getX(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
                                       (float)begin_pos.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
                    wPrinterJob.lineTo((float)end_pos.getX(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
                                       (float)end_pos.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
                    draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
     * Given a Java2D <code>PathIterator</code> instance,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
     * this method translates that into a Window's path
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
     * in the printer device context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
    private void convertToWPath(PathIterator pathIter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
        float[] segment = new float[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
        int segmentType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
        WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
        /* Map the PathIterator's fill rule into the Window's
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
         * polygon fill rule.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
        int polyFillRule;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
        if (pathIter.getWindingRule() == PathIterator.WIND_EVEN_ODD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
            polyFillRule = WPrinterJob.POLYFILL_ALTERNATE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
            polyFillRule = WPrinterJob.POLYFILL_WINDING;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
        wPrinterJob.setPolyFillMode(polyFillRule);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
        wPrinterJob.beginPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
        while (pathIter.isDone() == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
            segmentType = pathIter.currentSegment(segment);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
            switch (segmentType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
             case PathIterator.SEG_MOVETO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
                wPrinterJob.moveTo(segment[0], segment[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
             case PathIterator.SEG_LINETO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
                wPrinterJob.lineTo(segment[0], segment[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
            /* Convert the quad path to a bezier.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
             case PathIterator.SEG_QUADTO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
                int lastX = wPrinterJob.getPenX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
                int lastY = wPrinterJob.getPenY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
                float c1x = lastX + (segment[0] - lastX) * 2 / 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
                float c1y = lastY + (segment[1] - lastY) * 2 / 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
                float c2x = segment[2] - (segment[2] - segment[0]) * 2/ 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
                float c2y = segment[3] - (segment[3] - segment[1]) * 2/ 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
                wPrinterJob.polyBezierTo(c1x, c1y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
                                         c2x, c2y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
                                         segment[2], segment[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
             case PathIterator.SEG_CUBICTO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
                wPrinterJob.polyBezierTo(segment[0], segment[1],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
                                         segment[2], segment[3],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
                                         segment[4], segment[5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
             case PathIterator.SEG_CLOSE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
                wPrinterJob.closeFigure();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
            pathIter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
        wPrinterJob.endPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
}