private TransparencyGroup()

in pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java [1767:1937]


        private TransparencyGroup(PDTransparencyGroup form, boolean isSoftMask, Matrix ctm, 
                PDColor backdropColor) throws IOException
        {
            Graphics2D savedGraphics = graphics;
            List<Path2D> savedLastClips = lastClips;
            Shape savedInitialClip = initialClip;

            // get the CTM x Form Matrix transform
            Matrix transform = Matrix.concatenate(ctm, form.getMatrix());

            // transform the bbox
            PDRectangle formBBox = form.getBBox();
            if (formBBox == null)
            {
                // PDFBOX-5471
                // check done here and not in caller to avoid getBBox() creating rectangle twice
                LOG.warn("transparency group ignored because BBox is null");
                formBBox = new PDRectangle();
            }
            GeneralPath transformedBox = formBBox.transform(transform);

            // clip the bbox to prevent giant bboxes from consuming all memory
            Area transformed = new Area(transformedBox);
            transformed.intersect(getGraphicsState().getCurrentClippingPath());
            Rectangle2D clipRect = transformed.getBounds2D();
            if (clipRect.isEmpty())
            {
                image = null;
                bbox = null;
                minX = 0;
                minY = 0;
                maxX = 0;
                maxY = 0;
                width = 0;
                height = 0;
                return;
            }
            this.bbox = new PDRectangle((float)clipRect.getX(), (float)clipRect.getY(),
                                        (float)clipRect.getWidth(), (float)clipRect.getHeight());

            // apply the underlying Graphics2D device's DPI transform
            AffineTransform xformOriginal = xform;
            xform = AffineTransform.getScaleInstance(xformScalingFactorX, xformScalingFactorY);
            Rectangle2D bounds = xform.createTransformedShape(clipRect).getBounds2D();

            minX = (int) Math.floor(bounds.getMinX());
            minY = (int) Math.floor(bounds.getMinY());
            maxX = (int) Math.floor(bounds.getMaxX()) + 1;
            maxY = (int) Math.floor(bounds.getMaxY()) + 1;

            width = maxX - minX;
            height = maxY - minY;

            // FIXME - color space
            if (isGray(form.getGroup().getColorSpace(form.getResources())))
            {
                image = create2ByteGrayAlphaImage(width, height);
            }
            else
            {
                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            }

            boolean needsBackdrop = !isSoftMask && !form.getGroup().isIsolated() &&
                hasBlendMode(form, new HashSet<>());
            BufferedImage backdropImage = null;
            // Position of this group in parent group's coordinates
            int backdropX = 0;
            int backdropY = 0;
            if (needsBackdrop)
            {
                if (transparencyGroupStack.isEmpty())
                {
                    // Use the current page as the parent group.
                    backdropImage = renderer.getPageImage();
                    if (backdropImage == null)
                    {
                        needsBackdrop = false;
                    }
                    else
                    {
                        backdropX = minX;
                        backdropY = backdropImage.getHeight() - maxY;
                    }
                }
                else
                {
                    TransparencyGroup parentGroup = transparencyGroupStack.peek();
                    backdropImage = parentGroup.image;
                    backdropX = minX - parentGroup.minX;
                    backdropY = parentGroup.maxY - maxY;
                }
            }

            Graphics2D g = image.createGraphics();
            if (needsBackdrop)
            {
                // backdropImage must be included in group image but not in group alpha.
                g.drawImage(backdropImage, 0, 0, width, height,
                    backdropX, backdropY, backdropX + width, backdropY + height, null);
                g = new GroupGraphics(image, g);
            }
            if (isSoftMask && backdropColor != null)
            {
                // "If the subtype is Luminosity, the transparency group XObject G shall be 
                // composited with a fully opaque backdrop whose colour is everywhere defined 
                // by the soft-mask dictionary's BC entry."
                g.setBackground(new Color(backdropColor.toRGB()));
                g.clearRect(0, 0, width, height);
            }

            // flip y-axis
            g.translate(0, image.getHeight());
            g.scale(1, -1);

            boolean savedFlipTG = flipTG;
            flipTG = false;

            // apply device transform (DPI)
            // the initial translation is ignored, because we're not writing into the initial graphics device
            g.transform(xform);

            PDRectangle pageSizeOriginal = pageSize;
            pageSize = new PDRectangle(minX / xformScalingFactorX,
                                       minY / xformScalingFactorY,
                                       (float) (bounds.getWidth() / xformScalingFactorX),
                                        (float) (bounds.getHeight() / xformScalingFactorY));
            int clipWindingRuleOriginal = clipWindingRule;
            clipWindingRule = -1;
            GeneralPath linePathOriginal = linePath;
            linePath = new GeneralPath();

            // adjust the origin
            g.translate(-clipRect.getX(), -clipRect.getY());

            graphics = g;
            setRenderingHints();
            try
            {
                if (isSoftMask)
                {
                    processSoftMask(form);
                }
                else
                {
                    transparencyGroupStack.push(this);
                    processTransparencyGroup(form);
                    if (!transparencyGroupStack.isEmpty())
                    {
                        transparencyGroupStack.pop();
                    }
                }

                if (needsBackdrop)
                {
                    ((GroupGraphics) graphics).removeBackdrop(backdropImage, backdropX, backdropY);
                }
            }
            finally 
            {
                flipTG = savedFlipTG;
                lastClips = savedLastClips;
                graphics.dispose();
                graphics = savedGraphics;
                initialClip = savedInitialClip;
                clipWindingRule = clipWindingRuleOriginal;
                linePath = linePathOriginal;
                pageSize = pageSizeOriginal;
                xform = xformOriginal;
            }
        }