1060 lines · 42.6 KB · Java
RawDownload
    int havePgramSolidLoop;     public boolean canRenderLCDText(SunGraphics2D sg2d) {        // For now the answer can only be true in the following cases:        if (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&            sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&            sg2d.clipState <= SunGraphics2D.CLIP_RECTANGULAR &&            sg2d.surfaceData.getTransparency() == Transparency.OPAQUE)        {            if (haveLCDLoop == LOOP_UNKNOWN) {                DrawGlyphListLCD loop =                    DrawGlyphListLCD.locate(SurfaceType.AnyColor,                                            CompositeType.SrcNoEa,                                            getSurfaceType());                haveLCDLoop = (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;            }            return haveLCDLoop == LOOP_FOUND;        }        return false; /* for now - in the future we may want to search */    }     public boolean canRenderParallelograms(SunGraphics2D sg2d) {        if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) {            if (sg2d.compositeState == sg2d.COMP_XOR) {                if (havePgramXORLoop == LOOP_UNKNOWN) {                    FillParallelogram loop =                        FillParallelogram.locate(SurfaceType.AnyColor,                                                 CompositeType.Xor,                                                 getSurfaceType());                    havePgramXORLoop =                        (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;                }                return havePgramXORLoop == LOOP_FOUND;            } else if (sg2d.compositeState <= sg2d.COMP_ISCOPY &&                       sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&                       sg2d.clipState != sg2d.CLIP_SHAPE)            {                if (havePgramSolidLoop == LOOP_UNKNOWN) {                    FillParallelogram loop =                        FillParallelogram.locate(SurfaceType.AnyColor,                                                 CompositeType.SrcNoEa,                                                 getSurfaceType());                    havePgramSolidLoop =                        (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;                }                return havePgramSolidLoop == LOOP_FOUND;            }        }        return false;    }     public void validatePipe(SunGraphics2D sg2d) {        sg2d.imagepipe = imagepipe;        if (sg2d.compositeState == sg2d.COMP_XOR) {            if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR) {                sg2d.drawpipe = paintViaShape;                sg2d.fillpipe = paintViaShape;                sg2d.shapepipe = paintShape;                // REMIND: Ideally custom paint mode would use glyph                // rendering as opposed to outline rendering but the                // glyph paint rendering pipeline uses MaskBlit which                // is not defined for XOR.  This means that text drawn                // in XOR mode with a Color object is different than                // text drawn in XOR mode with a Paint object.                sg2d.textpipe = outlineTextRenderer;            } else {                PixelToShapeConverter converter;                if (canRenderParallelograms(sg2d)) {                    converter = colorViaPgram;                    // Note that we use the transforming pipe here because it                    // will examine the shape and possibly perform an optimized                    // operation if it can be simplified.  The simplifications                    // will be valid for all STROKE and TRANSFORM types.                    sg2d.shapepipe = colorViaPgram;                } else {                    converter = colorViaShape;                    sg2d.shapepipe = colorPrimitives;                }                if (sg2d.clipState == sg2d.CLIP_SHAPE) {                    sg2d.drawpipe = converter;                    sg2d.fillpipe = converter;                    // REMIND: We should not be changing text strategies                    // between outline and glyph rendering based upon the                    // presence of a complex clip as that could cause a                    // mismatch when drawing the same text both clipped                    // and unclipped on two separate rendering passes.                    // Unfortunately, all of the clipped glyph rendering                    // pipelines rely on the use of the MaskBlit operation                    // which is not defined for XOR.                    sg2d.textpipe = outlineTextRenderer;                } else {                    if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {                        sg2d.drawpipe = converter;                        sg2d.fillpipe = converter;                    } else {                        if (sg2d.strokeState != sg2d.STROKE_THIN) {                            sg2d.drawpipe = converter;                        } else {                            sg2d.drawpipe = colorPrimitives;                        }                        sg2d.fillpipe = colorPrimitives;                    }                    sg2d.textpipe = solidTextRenderer;                }                // assert(sg2d.surfaceData == this);            }        } else if (sg2d.compositeState == sg2d.COMP_CUSTOM) {            if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {                if (sg2d.clipState == sg2d.CLIP_SHAPE) {                    sg2d.drawpipe = AAClipCompViaShape;                    sg2d.fillpipe = AAClipCompViaShape;                    sg2d.shapepipe = AAClipCompViaShape;                    sg2d.textpipe = clipCompText;                } else {                    sg2d.drawpipe = AACompViaShape;                    sg2d.fillpipe = AACompViaShape;                    sg2d.shapepipe = AACompViaShape;                    sg2d.textpipe = compText;                }            } else {                sg2d.drawpipe = compViaShape;                sg2d.fillpipe = compViaShape;                sg2d.shapepipe = compShape;                if (sg2d.clipState == sg2d.CLIP_SHAPE) {                    sg2d.textpipe = clipCompText;                } else {                    sg2d.textpipe = compText;                }            }        } else if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {            sg2d.alphafill = getMaskFill(sg2d);            // assert(sg2d.surfaceData == this);            if (sg2d.alphafill != null) {                if (sg2d.clipState == sg2d.CLIP_SHAPE) {                    sg2d.drawpipe = AAClipColorViaShape;                    sg2d.fillpipe = AAClipColorViaShape;                    sg2d.shapepipe = AAClipColorViaShape;                    sg2d.textpipe = clipColorText;                } else {                    PixelToParallelogramConverter converter =                        (sg2d.alphafill.canDoParallelograms()                         ? AAColorViaPgram                         : AAColorViaShape);                    sg2d.drawpipe = converter;                    sg2d.fillpipe = converter;                    sg2d.shapepipe = converter;                    if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||                        sg2d.compositeState > sg2d.COMP_ISCOPY)                    {                        sg2d.textpipe = colorText;                    } else {                        sg2d.textpipe = getTextPipe(sg2d, true /* AA==ON */);                    }                }            } else {                if (sg2d.clipState == sg2d.CLIP_SHAPE) {                    sg2d.drawpipe = AAClipPaintViaShape;                    sg2d.fillpipe = AAClipPaintViaShape;                    sg2d.shapepipe = AAClipPaintViaShape;                    sg2d.textpipe = clipPaintText;                } else {                    sg2d.drawpipe = AAPaintViaShape;                    sg2d.fillpipe = AAPaintViaShape;                    sg2d.shapepipe = AAPaintViaShape;                    sg2d.textpipe = paintText;                }            }        } else if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||                   sg2d.compositeState > sg2d.COMP_ISCOPY ||                   sg2d.clipState == sg2d.CLIP_SHAPE)        {            sg2d.drawpipe = paintViaShape;            sg2d.fillpipe = paintViaShape;            sg2d.shapepipe = paintShape;            sg2d.alphafill = getMaskFill(sg2d);            // assert(sg2d.surfaceData == this);            if (sg2d.alphafill != null) {                if (sg2d.clipState == sg2d.CLIP_SHAPE) {                    sg2d.textpipe = clipColorText;                } else {                    sg2d.textpipe = colorText;                }            } else {                if (sg2d.clipState == sg2d.CLIP_SHAPE) {                    sg2d.textpipe = clipPaintText;                } else {                    sg2d.textpipe = paintText;                }            }        } else {            PixelToShapeConverter converter;            if (canRenderParallelograms(sg2d)) {                converter = colorViaPgram;                // Note that we use the transforming pipe here because it                // will examine the shape and possibly perform an optimized                // operation if it can be simplified.  The simplifications                // will be valid for all STROKE and TRANSFORM types.                sg2d.shapepipe = colorViaPgram;            } else {                converter = colorViaShape;                sg2d.shapepipe = colorPrimitives;            }            if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {                sg2d.drawpipe = converter;                sg2d.fillpipe = converter;            } else {                if (sg2d.strokeState != sg2d.STROKE_THIN) {                    sg2d.drawpipe = converter;                } else {                    sg2d.drawpipe = colorPrimitives;                }                sg2d.fillpipe = colorPrimitives;            }             sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);            // assert(sg2d.surfaceData == this);        }         // check for loops        if (sg2d.textpipe  instanceof LoopBasedPipe ||            sg2d.shapepipe instanceof LoopBasedPipe ||            sg2d.fillpipe  instanceof LoopBasedPipe ||            sg2d.drawpipe  instanceof LoopBasedPipe ||            sg2d.imagepipe instanceof LoopBasedPipe)        {            sg2d.loops = getRenderLoops(sg2d);        }    }     /* Return the text pipe to be used based on the graphics AA hint setting,     * and the rest of the graphics state is compatible with these loops.     * If the text AA hint is "DEFAULT", then the AA graphics hint requests     * the AA text renderer, else it requests the B&W text renderer.     */    private TextPipe getTextPipe(SunGraphics2D sg2d, boolean aaHintIsOn) {         /* Try to avoid calling getFontInfo() unless its needed to         * resolve one of the new AA types.         */        switch (sg2d.textAntialiasHint) {        case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT:            if (aaHintIsOn) {                return aaTextRenderer;            } else {                return solidTextRenderer;            }        case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:            return solidTextRenderer;         case SunHints.INTVAL_TEXT_ANTIALIAS_ON:            return aaTextRenderer;         default:            switch (sg2d.getFontInfo().aaHint) {             case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:            case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:                return lcdTextRenderer;             case SunHints.INTVAL_TEXT_ANTIALIAS_ON:                return aaTextRenderer;             case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:                return solidTextRenderer;                  /* This should not be reached as the FontInfo will                 * always explicitly set its hint value. So whilst                 * this could be collapsed to returning say just                 * solidTextRenderer, or even removed, its left                 * here in case DEFAULT is ever passed in.                 */            default:                if (aaHintIsOn) {                    return aaTextRenderer;                } else {                    return solidTextRenderer;                }            }        }    }     private static SurfaceType getPaintSurfaceType(SunGraphics2D sg2d) {        switch (sg2d.paintState) {        case SunGraphics2D.PAINT_OPAQUECOLOR:            return SurfaceType.OpaqueColor;        case SunGraphics2D.PAINT_ALPHACOLOR:            return SurfaceType.AnyColor;        case SunGraphics2D.PAINT_GRADIENT:            if (sg2d.paint.getTransparency() == OPAQUE) {                return SurfaceType.OpaqueGradientPaint;            } else {                return SurfaceType.GradientPaint;            }        case SunGraphics2D.PAINT_LIN_GRADIENT:            if (sg2d.paint.getTransparency() == OPAQUE) {                return SurfaceType.OpaqueLinearGradientPaint;            } else {                return SurfaceType.LinearGradientPaint;            }        case SunGraphics2D.PAINT_RAD_GRADIENT:            if (sg2d.paint.getTransparency() == OPAQUE) {                return SurfaceType.OpaqueRadialGradientPaint;            } else {                return SurfaceType.RadialGradientPaint;            }        case SunGraphics2D.PAINT_TEXTURE:            if (sg2d.paint.getTransparency() == OPAQUE) {                return SurfaceType.OpaqueTexturePaint;            } else {                return SurfaceType.TexturePaint;            }        default:        case SunGraphics2D.PAINT_CUSTOM:            return SurfaceType.AnyPaint;        }    }     private static CompositeType getFillCompositeType(SunGraphics2D sg2d) {        CompositeType compType = sg2d.imageComp;        if (sg2d.compositeState == sg2d.COMP_ISCOPY) {            if (compType == CompositeType.SrcOverNoEa) {                compType = CompositeType.OpaqueSrcOverNoEa;            } else {                compType = CompositeType.SrcNoEa;            }        }        return compType;    }     /**     * Returns a MaskFill object that can be used on this destination     * with the source (paint) and composite types determined by the given     * SunGraphics2D, or null if no such MaskFill object can be located.     * Subclasses can override this method if they wish to filter other     * attributes (such as the hardware capabilities of the destination     * surface) before returning a specific MaskFill object.     */    protected MaskFill getMaskFill(SunGraphics2D sg2d) {        SurfaceType src = getPaintSurfaceType(sg2d);        CompositeType comp = getFillCompositeType(sg2d);        SurfaceType dst = getSurfaceType();        return MaskFill.getFromCache(src, comp, dst);    }     private static RenderCache loopcache = new RenderCache(30);     /**     * Return a RenderLoops object containing all of the basic     * GraphicsPrimitive objects for rendering to the destination     * surface with the current attributes of the given SunGraphics2D.     */    public RenderLoops getRenderLoops(SunGraphics2D sg2d) {        SurfaceType src = getPaintSurfaceType(sg2d);        CompositeType comp = getFillCompositeType(sg2d);        SurfaceType dst = sg2d.getSurfaceData().getSurfaceType();         Object o = loopcache.get(src, comp, dst);        if (o != null) {            return (RenderLoops) o;        }         RenderLoops loops = makeRenderLoops(src, comp, dst);        loopcache.put(src, comp, dst, loops);        return loops;    }     /**     * Construct and return a RenderLoops object containing all of     * the basic GraphicsPrimitive objects for rendering to the     * destination surface with the given source, destination, and     * composite types.     */    public static RenderLoops makeRenderLoops(SurfaceType src,                                              CompositeType comp,                                              SurfaceType dst)    {        RenderLoops loops = new RenderLoops();        loops.drawLineLoop = DrawLine.locate(src, comp, dst);        loops.fillRectLoop = FillRect.locate(src, comp, dst);        loops.drawRectLoop = DrawRect.locate(src, comp, dst);        loops.drawPolygonsLoop = DrawPolygons.locate(src, comp, dst);        loops.drawPathLoop = DrawPath.locate(src, comp, dst);        loops.fillPathLoop = FillPath.locate(src, comp, dst);        loops.fillSpansLoop = FillSpans.locate(src, comp, dst);        loops.fillParallelogramLoop = FillParallelogram.locate(src, comp, dst);        loops.drawParallelogramLoop = DrawParallelogram.locate(src, comp, dst);        loops.drawGlyphListLoop = DrawGlyphList.locate(src, comp, dst);        loops.drawGlyphListAALoop = DrawGlyphListAA.locate(src, comp, dst);        loops.drawGlyphListLCDLoop = DrawGlyphListLCD.locate(src, comp, dst);        /*        System.out.println("drawLine: "+loops.drawLineLoop);        System.out.println("fillRect: "+loops.fillRectLoop);        System.out.println("drawRect: "+loops.drawRectLoop);        System.out.println("drawPolygons: "+loops.drawPolygonsLoop);        System.out.println("fillSpans: "+loops.fillSpansLoop);        System.out.println("drawGlyphList: "+loops.drawGlyphListLoop);        System.out.println("drawGlyphListAA: "+loops.drawGlyphListAALoop);        System.out.println("drawGlyphListLCD: "+loops.drawGlyphListLCDLoop);        */        return loops;    }     /**     * Return the GraphicsConfiguration object that describes this     * destination surface.     */    public abstract GraphicsConfiguration getDeviceConfiguration();     /**     * Return the SurfaceType object that describes the destination     * surface.     */    public final SurfaceType getSurfaceType() {        return surfaceType;    }     /**     * Return the ColorModel for the destination surface.     */    public final ColorModel getColorModel() {        return colorModel;    }     /**     * Returns the type of this <code>Transparency</code>.     * @return the field type of this <code>Transparency</code>, which is     *          either OPAQUE, BITMASK or TRANSLUCENT.     */    public int getTransparency() {        return getColorModel().getTransparency();    }     /**     * Return a readable Raster which contains the pixels for the     * specified rectangular region of the destination surface.     * The coordinate origin of the returned Raster is the same as     * the device space origin of the destination surface.     * In some cases the returned Raster might also be writeable.     * In most cases, the returned Raster might contain more pixels     * than requested.     *     * @see useTightBBoxes     */    public abstract Raster getRaster(int x, int y, int w, int h);     /**     * Does the pixel accessibility of the destination surface     * suggest that rendering algorithms might want to take     * extra time to calculate a more accurate bounding box for     * the operation being performed?     * The typical case when this will be true is when a copy of     * the pixels has to be made when doing a getRaster.  The     * fewer pixels copied, the faster the operation will go.     *     * @see getRaster     */    public boolean useTightBBoxes() {        // Note: The native equivalent would trigger on VISIBLE_TO_NATIVE        // REMIND: This is not used - should be obsoleted maybe        return true;    }     /**     * Returns the pixel data for the specified Argb value packed     * into an integer for easy storage and conveyance.     */    public int pixelFor(int rgb) {        return surfaceType.pixelFor(rgb, colorModel);    }     /**     * Returns the pixel data for the specified color packed into an     * integer for easy storage and conveyance.     *     * This method will use the getRGB() method of the Color object     * and defer to the pixelFor(int rgb) method if not overridden.     *     * For now this is a convenience function, but for cases where     * the highest quality color conversion is requested, this method     * should be overridden in those cases so that a more direct     * conversion of the color to the destination color space     * can be done using the additional information in the Color     * object.     */    public int pixelFor(Color c) {        return pixelFor(c.getRGB());    }     /**     * Returns the Argb representation for the specified integer value     * which is packed in the format of the associated ColorModel.     */    public int rgbFor(int pixel) {        return surfaceType.rgbFor(pixel, colorModel);    }     /**     * Returns the bounds of the destination surface.     */    public abstract Rectangle getBounds();

Lines 501–1000 of 1060. Previous lines