< prev index next >

src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java

Print this page




  99                          "sun.java2d.print.enableGDITextLayout"));
 100 
 101         if (textLayoutStr != null) {
 102             useGDITextLayout = Boolean.getBoolean(textLayoutStr);
 103             if (!useGDITextLayout) {
 104                 if (textLayoutStr.equalsIgnoreCase("prefer")) {
 105                     useGDITextLayout = true;
 106                     preferGDITextLayout = true;
 107                 }
 108             }
 109         }
 110     }
 111 
 112     WPathGraphics(Graphics2D graphics, PrinterJob printerJob,
 113                   Printable painter, PageFormat pageFormat, int pageIndex,
 114                   boolean canRedraw) {
 115         super(graphics, printerJob, painter, pageFormat, pageIndex, canRedraw);
 116     }
 117 
 118     /**
 119      * Creates a new <code>Graphics</code> object that is
 120      * a copy of this <code>Graphics</code> object.
 121      * @return     a new graphics context that is a copy of
 122      *                       this graphics context.
 123      * @since      1.0
 124      */
 125     @Override
 126     public Graphics create() {
 127 
 128         return new WPathGraphics((Graphics2D) getDelegate().create(),
 129                                  getPrinterJob(),
 130                                  getPrintable(),
 131                                  getPageFormat(),
 132                                  getPageIndex(),
 133                                  canDoRedraws());
 134     }
 135 
 136     /**
 137      * Strokes the outline of a Shape using the settings of the current
 138      * graphics state.  The rendering attributes applied include the
 139      * clip, transform, paint or color, composite and stroke attributes.
 140      * @param s The shape to be drawn.


 358          * rotation here is opposite than 2D's, so the rotation needed
 359          * needs to be recalculated in the opposite direction.
 360          */
 361         if (angle != 0.0) {
 362             angle = 360.0 - angle;
 363         }
 364         return (int)Math.round(angle * 10.0);
 365     }
 366 
 367     private float getAwScale(double scaleFactorX, double scaleFactorY) {
 368 
 369         float awScale = (float)(scaleFactorX/scaleFactorY);
 370         /* don't let rounding errors be interpreted as non-uniform scale */
 371         if (awScale > 0.999f && awScale < 1.001f) {
 372             awScale = 1.0f;
 373         }
 374         return awScale;
 375     }
 376 
 377     /**
 378      * Renders the text specified by the specified <code>String</code>,
 379      * using the current <code>Font</code> and <code>Paint</code> attributes
 380      * in the <code>Graphics2D</code> context.
 381      * The baseline of the first character is at position
 382      * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
 383      * The rendering attributes applied include the <code>Clip</code>,
 384      * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
 385      * <code>Composite</code> attributes. For characters in script systems
 386      * such as Hebrew and Arabic, the glyphs can be rendered from right to
 387      * left, in which case the coordinate supplied is the location of the
 388      * leftmost character on the baseline.
 389      * @param str the <code>String</code> to be rendered
 390      * @param x,&nbsp;y the coordinates where the <code>String</code>
 391      * should be rendered
 392      * @see #setPaint
 393      * @see java.awt.Graphics#setColor
 394      * @see java.awt.Graphics#setFont
 395      * @see #setTransform
 396      * @see #setComposite
 397      * @see #setClip
 398      */
 399     @Override
 400     public void drawString(String str, float x, float y,
 401                            Font font, FontRenderContext frc, float targetW) {
 402         if (str.length() == 0) {
 403             return;
 404         }
 405 
 406         if (WPrinterJob.shapeTextProp) {
 407             super.drawString(str, x, y, font, frc, targetW);
 408             return;
 409         }
 410 


 852       */
 853      private boolean okGDIMetrics(String str, Font font,
 854                                   FontRenderContext frc, double scaleX) {
 855 
 856          Rectangle2D bds = font.getStringBounds(str, frc);
 857          double jdkAdvance = bds.getWidth();
 858          jdkAdvance = Math.round(jdkAdvance*scaleX);
 859          int gdiAdvance = ((WPrinterJob)getPrinterJob()).getGDIAdvance(str);
 860          if (jdkAdvance > 0 && gdiAdvance > 0) {
 861              double diff = Math.abs(gdiAdvance-jdkAdvance);
 862              double ratio = gdiAdvance/jdkAdvance;
 863              if (ratio < 1) {
 864                  ratio = 1/ratio;
 865              }
 866              return diff <= 1 || ratio < 1.002;
 867          }
 868          return true;
 869      }
 870 
 871     /**
 872      * The various <code>drawImage()</code> methods for
 873      * <code>WPathGraphics</code> are all decomposed
 874      * into an invocation of <code>drawImageToPlatform</code>.
 875      * The portion of the passed in image defined by
 876      * <code>srcX, srcY, srcWidth, and srcHeight</code>
 877      * is transformed by the supplied AffineTransform and
 878      * drawn using GDI to the printer context.
 879      *
 880      * @param   image   The image to be drawn.
 881      * @param   xform   Used to transform the image before drawing.
 882      *                  This can be null.
 883      * @param   bgcolor This color is drawn where the image has transparent
 884      *                  pixels. If this parameter is null then the
 885      *                  pixels already in the destination should show
 886      *                  through.
 887      * @param   srcX    With srcY this defines the upper-left corner
 888      *                  of the portion of the image to be drawn.
 889      *
 890      * @param   srcY    With srcX this defines the upper-left corner
 891      *                  of the portion of the image to be drawn.
 892      * @param   srcWidth    The width of the portion of the image to
 893      *                      be drawn.
 894      * @param   srcHeight   The height of the portion of the image to
 895      *                      be drawn.
 896      * @param   handlingTransparency if being recursively called to


1317                     deviceClip(getClip().getPathIterator(getTransform()));
1318 
1319                     wPrinterJob.drawDIBImage
1320                         (data, scaledBounds.x, scaledBounds.y,
1321                          (float)Math.rint(scaledBounds.width+0.5),
1322                          (float)Math.rint(scaledBounds.height+0.5),
1323                          0f, 0f,
1324                          deepImage.getWidth(), deepImage.getHeight(),
1325                          bitsPerPixel, icm);
1326 
1327                     setClip(holdClip);
1328                 }
1329             }
1330         }
1331 
1332         return true;
1333     }
1334 
1335     /**
1336      * Have the printing application redraw everything that falls
1337      * within the page bounds defined by <code>region</code>.
1338      */
1339     @Override
1340     public void redrawRegion(Rectangle2D region, double scaleX, double scaleY,
1341                              Shape savedClip, AffineTransform savedTransform)
1342             throws PrinterException {
1343 
1344         WPrinterJob wPrinterJob = (WPrinterJob)getPrinterJob();
1345         Printable painter = getPrintable();
1346         PageFormat pageFormat = getPageFormat();
1347         int pageIndex = getPageIndex();
1348 
1349         /* Create a buffered image big enough to hold the portion
1350          * of the source image being printed.
1351          */
1352         BufferedImage deepImage = new BufferedImage(
1353                                         (int) region.getWidth(),
1354                                         (int) region.getHeight(),
1355                                         BufferedImage.TYPE_3BYTE_BGR);
1356 
1357         /* Get a graphics for the application to render into.


1417                         (float) (region.getY() * scaleY),
1418                         (float) (region.getWidth() * scaleX),
1419                         (float) (region.getHeight() * scaleY));
1420 
1421         /* Pull the raster data from the buffered image
1422          * and pass it along to GDI.
1423          */
1424        ByteComponentRaster tile
1425                 = (ByteComponentRaster)deepImage.getRaster();
1426 
1427         wPrinterJob.drawImage3ByteBGR(tile.getDataStorage(),
1428                     scaledBounds.x, scaledBounds.y,
1429                     scaledBounds.width,
1430                     scaledBounds.height,
1431                     0f, 0f,
1432                     deepImage.getWidth(), deepImage.getHeight());
1433 
1434     }
1435 
1436     /*
1437      * Fill the path defined by <code>pathIter</code>
1438      * with the specified color.
1439      * The path is provided in device coordinates.
1440      */
1441     @Override
1442     protected void deviceFill(PathIterator pathIter, Color color) {
1443 
1444         WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
1445 
1446         convertToWPath(pathIter);
1447         wPrinterJob.selectSolidBrush(color);
1448         wPrinterJob.fillPath();
1449     }
1450 
1451     /*
1452      * Set the printer device's clip to be the
1453      * path defined by <code>pathIter</code>
1454      * The path is provided in device coordinates.
1455      */
1456     @Override
1457     protected void deviceClip(PathIterator pathIter) {
1458 
1459         WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
1460 
1461         convertToWPath(pathIter);
1462         wPrinterJob.selectClipPath();
1463     }
1464 
1465     /**
1466      * Draw the bounding rectangle using transformed coordinates.
1467      */
1468      @Override
1469      protected void deviceFrameRect(int x, int y, int width, int height,
1470                                      Color color) {
1471 
1472         AffineTransform deviceTransform = getTransform();
1473 


1657 
1658                 if ((endCap == BasicStroke.CAP_ROUND) ||
1659                  (((xBegin == xEnd) || (yBegin == yEnd)) &&
1660                  (deviceLineWidth/lowerRes < MAX_THINLINE_INCHES))) {
1661 
1662                     wPrinterJob.selectPen(deviceLineWidth, color);
1663                     wPrinterJob.moveTo((float)begin_pos.getX(),
1664                                        (float)begin_pos.getY());
1665                     wPrinterJob.lineTo((float)end_pos.getX(),
1666                                        (float)end_pos.getY());
1667                 }
1668                 else {
1669                     draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
1670                 }
1671             }
1672         }
1673     }
1674 
1675 
1676     /**
1677      * Given a Java2D <code>PathIterator</code> instance,
1678      * this method translates that into a Window's path
1679      * in the printer device context.
1680      */
1681     private void convertToWPath(PathIterator pathIter) {
1682 
1683         float[] segment = new float[6];
1684         int segmentType;
1685 
1686         WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
1687 
1688         /* Map the PathIterator's fill rule into the Window's
1689          * polygon fill rule.
1690          */
1691         int polyFillRule;
1692         if (pathIter.getWindingRule() == PathIterator.WIND_EVEN_ODD) {
1693             polyFillRule = WPrinterJob.POLYFILL_ALTERNATE;
1694         } else {
1695             polyFillRule = WPrinterJob.POLYFILL_WINDING;
1696         }
1697         wPrinterJob.setPolyFillMode(polyFillRule);




  99                          "sun.java2d.print.enableGDITextLayout"));
 100 
 101         if (textLayoutStr != null) {
 102             useGDITextLayout = Boolean.getBoolean(textLayoutStr);
 103             if (!useGDITextLayout) {
 104                 if (textLayoutStr.equalsIgnoreCase("prefer")) {
 105                     useGDITextLayout = true;
 106                     preferGDITextLayout = true;
 107                 }
 108             }
 109         }
 110     }
 111 
 112     WPathGraphics(Graphics2D graphics, PrinterJob printerJob,
 113                   Printable painter, PageFormat pageFormat, int pageIndex,
 114                   boolean canRedraw) {
 115         super(graphics, printerJob, painter, pageFormat, pageIndex, canRedraw);
 116     }
 117 
 118     /**
 119      * Creates a new {@code Graphics} object that is
 120      * a copy of this {@code Graphics} object.
 121      * @return     a new graphics context that is a copy of
 122      *                       this graphics context.
 123      * @since      1.0
 124      */
 125     @Override
 126     public Graphics create() {
 127 
 128         return new WPathGraphics((Graphics2D) getDelegate().create(),
 129                                  getPrinterJob(),
 130                                  getPrintable(),
 131                                  getPageFormat(),
 132                                  getPageIndex(),
 133                                  canDoRedraws());
 134     }
 135 
 136     /**
 137      * Strokes the outline of a Shape using the settings of the current
 138      * graphics state.  The rendering attributes applied include the
 139      * clip, transform, paint or color, composite and stroke attributes.
 140      * @param s The shape to be drawn.


 358          * rotation here is opposite than 2D's, so the rotation needed
 359          * needs to be recalculated in the opposite direction.
 360          */
 361         if (angle != 0.0) {
 362             angle = 360.0 - angle;
 363         }
 364         return (int)Math.round(angle * 10.0);
 365     }
 366 
 367     private float getAwScale(double scaleFactorX, double scaleFactorY) {
 368 
 369         float awScale = (float)(scaleFactorX/scaleFactorY);
 370         /* don't let rounding errors be interpreted as non-uniform scale */
 371         if (awScale > 0.999f && awScale < 1.001f) {
 372             awScale = 1.0f;
 373         }
 374         return awScale;
 375     }
 376 
 377     /**
 378      * Renders the text specified by the specified {@code String},
 379      * using the current {@code Font} and {@code Paint} attributes
 380      * in the {@code Graphics2D} context.
 381      * The baseline of the first character is at position
 382      * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
 383      * The rendering attributes applied include the {@code Clip},
 384      * {@code Transform}, {@code Paint}, {@code Font} and
 385      * {@code Composite} attributes. For characters in script systems
 386      * such as Hebrew and Arabic, the glyphs can be rendered from right to
 387      * left, in which case the coordinate supplied is the location of the
 388      * leftmost character on the baseline.
 389      * @param str the {@code String} to be rendered
 390      * @param x,&nbsp;y the coordinates where the {@code String}
 391      * should be rendered
 392      * @see #setPaint
 393      * @see java.awt.Graphics#setColor
 394      * @see java.awt.Graphics#setFont
 395      * @see #setTransform
 396      * @see #setComposite
 397      * @see #setClip
 398      */
 399     @Override
 400     public void drawString(String str, float x, float y,
 401                            Font font, FontRenderContext frc, float targetW) {
 402         if (str.length() == 0) {
 403             return;
 404         }
 405 
 406         if (WPrinterJob.shapeTextProp) {
 407             super.drawString(str, x, y, font, frc, targetW);
 408             return;
 409         }
 410 


 852       */
 853      private boolean okGDIMetrics(String str, Font font,
 854                                   FontRenderContext frc, double scaleX) {
 855 
 856          Rectangle2D bds = font.getStringBounds(str, frc);
 857          double jdkAdvance = bds.getWidth();
 858          jdkAdvance = Math.round(jdkAdvance*scaleX);
 859          int gdiAdvance = ((WPrinterJob)getPrinterJob()).getGDIAdvance(str);
 860          if (jdkAdvance > 0 && gdiAdvance > 0) {
 861              double diff = Math.abs(gdiAdvance-jdkAdvance);
 862              double ratio = gdiAdvance/jdkAdvance;
 863              if (ratio < 1) {
 864                  ratio = 1/ratio;
 865              }
 866              return diff <= 1 || ratio < 1.002;
 867          }
 868          return true;
 869      }
 870 
 871     /**
 872      * The various {@code drawImage()} methods for
 873      * {@code WPathGraphics} are all decomposed
 874      * into an invocation of {@code drawImageToPlatform}.
 875      * The portion of the passed in image defined by
 876      * {@code srcX, srcY, srcWidth, and srcHeight}
 877      * is transformed by the supplied AffineTransform and
 878      * drawn using GDI to the printer context.
 879      *
 880      * @param   image   The image to be drawn.
 881      * @param   xform   Used to transform the image before drawing.
 882      *                  This can be null.
 883      * @param   bgcolor This color is drawn where the image has transparent
 884      *                  pixels. If this parameter is null then the
 885      *                  pixels already in the destination should show
 886      *                  through.
 887      * @param   srcX    With srcY this defines the upper-left corner
 888      *                  of the portion of the image to be drawn.
 889      *
 890      * @param   srcY    With srcX this defines the upper-left corner
 891      *                  of the portion of the image to be drawn.
 892      * @param   srcWidth    The width of the portion of the image to
 893      *                      be drawn.
 894      * @param   srcHeight   The height of the portion of the image to
 895      *                      be drawn.
 896      * @param   handlingTransparency if being recursively called to


1317                     deviceClip(getClip().getPathIterator(getTransform()));
1318 
1319                     wPrinterJob.drawDIBImage
1320                         (data, scaledBounds.x, scaledBounds.y,
1321                          (float)Math.rint(scaledBounds.width+0.5),
1322                          (float)Math.rint(scaledBounds.height+0.5),
1323                          0f, 0f,
1324                          deepImage.getWidth(), deepImage.getHeight(),
1325                          bitsPerPixel, icm);
1326 
1327                     setClip(holdClip);
1328                 }
1329             }
1330         }
1331 
1332         return true;
1333     }
1334 
1335     /**
1336      * Have the printing application redraw everything that falls
1337      * within the page bounds defined by {@code region}.
1338      */
1339     @Override
1340     public void redrawRegion(Rectangle2D region, double scaleX, double scaleY,
1341                              Shape savedClip, AffineTransform savedTransform)
1342             throws PrinterException {
1343 
1344         WPrinterJob wPrinterJob = (WPrinterJob)getPrinterJob();
1345         Printable painter = getPrintable();
1346         PageFormat pageFormat = getPageFormat();
1347         int pageIndex = getPageIndex();
1348 
1349         /* Create a buffered image big enough to hold the portion
1350          * of the source image being printed.
1351          */
1352         BufferedImage deepImage = new BufferedImage(
1353                                         (int) region.getWidth(),
1354                                         (int) region.getHeight(),
1355                                         BufferedImage.TYPE_3BYTE_BGR);
1356 
1357         /* Get a graphics for the application to render into.


1417                         (float) (region.getY() * scaleY),
1418                         (float) (region.getWidth() * scaleX),
1419                         (float) (region.getHeight() * scaleY));
1420 
1421         /* Pull the raster data from the buffered image
1422          * and pass it along to GDI.
1423          */
1424        ByteComponentRaster tile
1425                 = (ByteComponentRaster)deepImage.getRaster();
1426 
1427         wPrinterJob.drawImage3ByteBGR(tile.getDataStorage(),
1428                     scaledBounds.x, scaledBounds.y,
1429                     scaledBounds.width,
1430                     scaledBounds.height,
1431                     0f, 0f,
1432                     deepImage.getWidth(), deepImage.getHeight());
1433 
1434     }
1435 
1436     /*
1437      * Fill the path defined by {@code pathIter}
1438      * with the specified color.
1439      * The path is provided in device coordinates.
1440      */
1441     @Override
1442     protected void deviceFill(PathIterator pathIter, Color color) {
1443 
1444         WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
1445 
1446         convertToWPath(pathIter);
1447         wPrinterJob.selectSolidBrush(color);
1448         wPrinterJob.fillPath();
1449     }
1450 
1451     /*
1452      * Set the printer device's clip to be the
1453      * path defined by {@code pathIter}
1454      * The path is provided in device coordinates.
1455      */
1456     @Override
1457     protected void deviceClip(PathIterator pathIter) {
1458 
1459         WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
1460 
1461         convertToWPath(pathIter);
1462         wPrinterJob.selectClipPath();
1463     }
1464 
1465     /**
1466      * Draw the bounding rectangle using transformed coordinates.
1467      */
1468      @Override
1469      protected void deviceFrameRect(int x, int y, int width, int height,
1470                                      Color color) {
1471 
1472         AffineTransform deviceTransform = getTransform();
1473 


1657 
1658                 if ((endCap == BasicStroke.CAP_ROUND) ||
1659                  (((xBegin == xEnd) || (yBegin == yEnd)) &&
1660                  (deviceLineWidth/lowerRes < MAX_THINLINE_INCHES))) {
1661 
1662                     wPrinterJob.selectPen(deviceLineWidth, color);
1663                     wPrinterJob.moveTo((float)begin_pos.getX(),
1664                                        (float)begin_pos.getY());
1665                     wPrinterJob.lineTo((float)end_pos.getX(),
1666                                        (float)end_pos.getY());
1667                 }
1668                 else {
1669                     draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
1670                 }
1671             }
1672         }
1673     }
1674 
1675 
1676     /**
1677      * Given a Java2D {@code PathIterator} instance,
1678      * this method translates that into a Window's path
1679      * in the printer device context.
1680      */
1681     private void convertToWPath(PathIterator pathIter) {
1682 
1683         float[] segment = new float[6];
1684         int segmentType;
1685 
1686         WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
1687 
1688         /* Map the PathIterator's fill rule into the Window's
1689          * polygon fill rule.
1690          */
1691         int polyFillRule;
1692         if (pathIter.getWindingRule() == PathIterator.WIND_EVEN_ODD) {
1693             polyFillRule = WPrinterJob.POLYFILL_ALTERNATE;
1694         } else {
1695             polyFillRule = WPrinterJob.POLYFILL_WINDING;
1696         }
1697         wPrinterJob.setPolyFillMode(polyFillRule);


< prev index next >