/** * Fills the background before drawing if needed. * * @param trs - text segment * @param g2d - graphics to draw to * @param xOffset - offset in X direction to the upper left corner of the layout from the origin * of the graphics * @param yOffset - offset in Y direction to the upper left corner of the layout from the origin * of the graphics */ static void prepareGraphics(TextRunSegment trs, Graphics2D g2d, float xOffset, float yOffset) { Decoration d = trs.decoration; if (d.fg == null && d.bg == null && d.swapBfFg == false) { return; // Nothing to do } d.graphicsPaint = g2d.getPaint(); if (d.fg == null) { d.fg = d.graphicsPaint; } if (d.swapBfFg) { // Fill background area g2d.setPaint(d.fg); Rectangle2D bgArea = trs.getLogicalBounds(); Rectangle2D toFill = new Rectangle2D.Double( bgArea.getX() + xOffset, bgArea.getY() + yOffset, bgArea.getWidth(), bgArea.getHeight()); g2d.fill(toFill); // Set foreground color g2d.setPaint(d.bg == null ? Color.WHITE : d.bg); } else { if (d.bg != null) { // Fill background area g2d.setPaint(d.bg); Rectangle2D bgArea = trs.getLogicalBounds(); Rectangle2D toFill = new Rectangle2D.Double( bgArea.getX() + xOffset, bgArea.getY() + yOffset, bgArea.getWidth(), bgArea.getHeight()); g2d.fill(toFill); } // Set foreground color g2d.setPaint(d.fg); } }
/** * Extends the visual bounds of the text run segment to include text decorations. * * @param trs - text segment * @param segmentBounds - bounds of the undecorated text * @param d - decoration * @return extended bounds */ static Rectangle2D extendVisualBounds( TextRunSegment trs, Rectangle2D segmentBounds, Decoration d) { if (d == null) { return segmentBounds; } double minx = segmentBounds.getMinX(); double miny = segmentBounds.getMinY(); double maxx = segmentBounds.getMaxX(); double maxy = segmentBounds.getMaxY(); Rectangle2D lb = trs.getLogicalBounds(); if (d.swapBfFg || d.bg != null) { minx = Math.min(lb.getMinX() - trs.x, minx); miny = Math.min(lb.getMinY() - trs.y, miny); maxx = Math.max(lb.getMaxX() - trs.x, maxx); maxy = Math.max(lb.getMaxY() - trs.y, maxy); } if (d.ulOn || d.imUlStroke != null || d.strikeThrough) { minx = Math.min(lb.getMinX() - trs.x, minx); maxx = Math.max(lb.getMaxX() - trs.x, maxx); d.getStrokes(trs.metrics); if (d.ulStroke != null) { maxy = Math.max(maxy, trs.metrics.underlineOffset + d.ulStroke.getLineWidth()); } if (d.imUlStroke != null) { maxy = Math.max( maxy, trs.metrics.underlineOffset + d.imUlStroke.getLineWidth() + (d.imUlStroke2 == null ? 0 : d.imUlStroke2.getLineWidth())); } } return new Rectangle2D.Double(minx, miny, maxx - minx, maxy - miny); }