src/share/classes/sun/java2d/SurfaceData.java

Print this page




  31 import java.awt.GraphicsConfiguration;
  32 import java.awt.Image;
  33 import java.awt.image.ColorModel;
  34 import java.awt.image.IndexColorModel;
  35 import java.awt.image.Raster;
  36 
  37 import sun.java2d.loops.RenderCache;
  38 import sun.java2d.loops.RenderLoops;
  39 import sun.java2d.loops.CompositeType;
  40 import sun.java2d.loops.SurfaceType;
  41 import sun.java2d.loops.MaskFill;
  42 import sun.java2d.loops.DrawLine;
  43 import sun.java2d.loops.FillRect;
  44 import sun.java2d.loops.DrawRect;
  45 import sun.java2d.loops.DrawPolygons;
  46 import sun.java2d.loops.DrawPath;
  47 import sun.java2d.loops.FillPath;
  48 import sun.java2d.loops.FillSpans;
  49 import sun.java2d.loops.FillParallelogram;
  50 import sun.java2d.loops.DrawParallelogram;
  51 import sun.java2d.loops.FontInfo;
  52 import sun.java2d.loops.DrawGlyphList;
  53 import sun.java2d.loops.DrawGlyphListAA;
  54 import sun.java2d.loops.DrawGlyphListLCD;
  55 import sun.java2d.pipe.LoopPipe;
  56 import sun.java2d.pipe.ShapeDrawPipe;
  57 import sun.java2d.pipe.ParallelogramPipe;
  58 import sun.java2d.pipe.CompositePipe;
  59 import sun.java2d.pipe.GeneralCompositePipe;
  60 import sun.java2d.pipe.SpanClipRenderer;
  61 import sun.java2d.pipe.SpanShapeRenderer;
  62 import sun.java2d.pipe.AAShapePipe;
  63 import sun.java2d.pipe.AlphaPaintPipe;
  64 import sun.java2d.pipe.AlphaColorPipe;
  65 import sun.java2d.pipe.PixelToShapeConverter;
  66 import sun.java2d.pipe.PixelToParallelogramConverter;
  67 import sun.java2d.pipe.TextPipe;
  68 import sun.java2d.pipe.TextRenderer;
  69 import sun.java2d.pipe.AATextRenderer;
  70 import sun.java2d.pipe.LCDTextRenderer;
  71 import sun.java2d.pipe.SolidTextRenderer;


 503     public boolean canRenderLCDText(SunGraphics2D sg2d) {
 504         // For now the answer can only be true in the following cases:
 505         if (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
 506             sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
 507             sg2d.clipState <= SunGraphics2D.CLIP_RECTANGULAR &&
 508             sg2d.surfaceData.getTransparency() == Transparency.OPAQUE)
 509         {
 510             if (haveLCDLoop == LOOP_UNKNOWN) {
 511                 DrawGlyphListLCD loop =
 512                     DrawGlyphListLCD.locate(SurfaceType.AnyColor,
 513                                             CompositeType.SrcNoEa,
 514                                             getSurfaceType());
 515                 haveLCDLoop = (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
 516             }
 517             return haveLCDLoop == LOOP_FOUND;
 518         }
 519         return false; /* for now - in the future we may want to search */
 520     }
 521 
 522     public boolean canRenderParallelograms(SunGraphics2D sg2d) {
 523         if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) {
 524             if (sg2d.compositeState == sg2d.COMP_XOR) {
 525                 if (havePgramXORLoop == LOOP_UNKNOWN) {
 526                     FillParallelogram loop =
 527                         FillParallelogram.locate(SurfaceType.AnyColor,
 528                                                  CompositeType.Xor,
 529                                                  getSurfaceType());
 530                     havePgramXORLoop =
 531                         (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
 532                 }
 533                 return havePgramXORLoop == LOOP_FOUND;
 534             } else if (sg2d.compositeState <= sg2d.COMP_ISCOPY &&
 535                        sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
 536                        sg2d.clipState != sg2d.CLIP_SHAPE)
 537             {
 538                 if (havePgramSolidLoop == LOOP_UNKNOWN) {
 539                     FillParallelogram loop =
 540                         FillParallelogram.locate(SurfaceType.AnyColor,
 541                                                  CompositeType.SrcNoEa,
 542                                                  getSurfaceType());
 543                     havePgramSolidLoop =
 544                         (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
 545                 }
 546                 return havePgramSolidLoop == LOOP_FOUND;
 547             }
 548         }
 549         return false;
 550     }
 551 
 552     public void validatePipe(SunGraphics2D sg2d) {
 553         sg2d.imagepipe = imagepipe;
 554         if (sg2d.compositeState == sg2d.COMP_XOR) {
 555             if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR) {
 556                 sg2d.drawpipe = paintViaShape;
 557                 sg2d.fillpipe = paintViaShape;
 558                 sg2d.shapepipe = paintShape;
 559                 // REMIND: Ideally custom paint mode would use glyph
 560                 // rendering as opposed to outline rendering but the
 561                 // glyph paint rendering pipeline uses MaskBlit which
 562                 // is not defined for XOR.  This means that text drawn
 563                 // in XOR mode with a Color object is different than
 564                 // text drawn in XOR mode with a Paint object.
 565                 sg2d.textpipe = outlineTextRenderer;
 566             } else {
 567                 PixelToShapeConverter converter;
 568                 if (canRenderParallelograms(sg2d)) {
 569                     converter = colorViaPgram;
 570                     // Note that we use the transforming pipe here because it
 571                     // will examine the shape and possibly perform an optimized
 572                     // operation if it can be simplified.  The simplifications
 573                     // will be valid for all STROKE and TRANSFORM types.
 574                     sg2d.shapepipe = colorViaPgram;
 575                 } else {
 576                     converter = colorViaShape;
 577                     sg2d.shapepipe = colorPrimitives;
 578                 }
 579                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
 580                     sg2d.drawpipe = converter;
 581                     sg2d.fillpipe = converter;
 582                     // REMIND: We should not be changing text strategies
 583                     // between outline and glyph rendering based upon the
 584                     // presence of a complex clip as that could cause a
 585                     // mismatch when drawing the same text both clipped
 586                     // and unclipped on two separate rendering passes.
 587                     // Unfortunately, all of the clipped glyph rendering
 588                     // pipelines rely on the use of the MaskBlit operation
 589                     // which is not defined for XOR.
 590                     sg2d.textpipe = outlineTextRenderer;
 591                 } else {
 592                     if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
 593                         sg2d.drawpipe = converter;
 594                         sg2d.fillpipe = converter;
 595                     } else {
 596                         if (sg2d.strokeState != sg2d.STROKE_THIN) {
 597                             sg2d.drawpipe = converter;
 598                         } else {
 599                             sg2d.drawpipe = colorPrimitives;
 600                         }
 601                         sg2d.fillpipe = colorPrimitives;
 602                     }
 603                     sg2d.textpipe = solidTextRenderer;
 604                 }
 605                 // assert(sg2d.surfaceData == this);
 606             }
 607         } else if (sg2d.compositeState == sg2d.COMP_CUSTOM) {
 608             if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
 609                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
 610                     sg2d.drawpipe = AAClipCompViaShape;
 611                     sg2d.fillpipe = AAClipCompViaShape;
 612                     sg2d.shapepipe = AAClipCompViaShape;
 613                     sg2d.textpipe = clipCompText;
 614                 } else {
 615                     sg2d.drawpipe = AACompViaShape;
 616                     sg2d.fillpipe = AACompViaShape;
 617                     sg2d.shapepipe = AACompViaShape;
 618                     sg2d.textpipe = compText;
 619                 }
 620             } else {
 621                 sg2d.drawpipe = compViaShape;
 622                 sg2d.fillpipe = compViaShape;
 623                 sg2d.shapepipe = compShape;
 624                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
 625                     sg2d.textpipe = clipCompText;
 626                 } else {
 627                     sg2d.textpipe = compText;
 628                 }
 629             }
 630         } else if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
 631             sg2d.alphafill = getMaskFill(sg2d);
 632             // assert(sg2d.surfaceData == this);
 633             if (sg2d.alphafill != null) {
 634                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
 635                     sg2d.drawpipe = AAClipColorViaShape;
 636                     sg2d.fillpipe = AAClipColorViaShape;
 637                     sg2d.shapepipe = AAClipColorViaShape;
 638                     sg2d.textpipe = clipColorText;
 639                 } else {
 640                     PixelToParallelogramConverter converter =
 641                         (sg2d.alphafill.canDoParallelograms()
 642                          ? AAColorViaPgram
 643                          : AAColorViaShape);
 644                     sg2d.drawpipe = converter;
 645                     sg2d.fillpipe = converter;
 646                     sg2d.shapepipe = converter;
 647                     if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||
 648                         sg2d.compositeState > sg2d.COMP_ISCOPY)
 649                     {
 650                         sg2d.textpipe = colorText;
 651                     } else {
 652                         sg2d.textpipe = getTextPipe(sg2d, true /* AA==ON */);
 653                     }
 654                 }
 655             } else {
 656                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
 657                     sg2d.drawpipe = AAClipPaintViaShape;
 658                     sg2d.fillpipe = AAClipPaintViaShape;
 659                     sg2d.shapepipe = AAClipPaintViaShape;
 660                     sg2d.textpipe = clipPaintText;
 661                 } else {
 662                     sg2d.drawpipe = AAPaintViaShape;
 663                     sg2d.fillpipe = AAPaintViaShape;
 664                     sg2d.shapepipe = AAPaintViaShape;
 665                     sg2d.textpipe = paintText;
 666                 }
 667             }
 668         } else if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||
 669                    sg2d.compositeState > sg2d.COMP_ISCOPY ||
 670                    sg2d.clipState == sg2d.CLIP_SHAPE)
 671         {
 672             sg2d.drawpipe = paintViaShape;
 673             sg2d.fillpipe = paintViaShape;
 674             sg2d.shapepipe = paintShape;
 675             sg2d.alphafill = getMaskFill(sg2d);
 676             // assert(sg2d.surfaceData == this);
 677             if (sg2d.alphafill != null) {
 678                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
 679                     sg2d.textpipe = clipColorText;
 680                 } else {
 681                     sg2d.textpipe = colorText;
 682                 }
 683             } else {
 684                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
 685                     sg2d.textpipe = clipPaintText;
 686                 } else {
 687                     sg2d.textpipe = paintText;
 688                 }
 689             }
 690         } else {
 691             PixelToShapeConverter converter;
 692             if (canRenderParallelograms(sg2d)) {
 693                 converter = colorViaPgram;
 694                 // Note that we use the transforming pipe here because it
 695                 // will examine the shape and possibly perform an optimized
 696                 // operation if it can be simplified.  The simplifications
 697                 // will be valid for all STROKE and TRANSFORM types.
 698                 sg2d.shapepipe = colorViaPgram;
 699             } else {
 700                 converter = colorViaShape;
 701                 sg2d.shapepipe = colorPrimitives;
 702             }
 703             if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
 704                 sg2d.drawpipe = converter;
 705                 sg2d.fillpipe = converter;
 706             } else {
 707                 if (sg2d.strokeState != sg2d.STROKE_THIN) {
 708                     sg2d.drawpipe = converter;
 709                 } else {
 710                     sg2d.drawpipe = colorPrimitives;
 711                 }
 712                 sg2d.fillpipe = colorPrimitives;
 713             }
 714 
 715             sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);
 716             // assert(sg2d.surfaceData == this);
 717         }
 718 
 719         // check for loops
 720         if (sg2d.textpipe  instanceof LoopBasedPipe ||
 721             sg2d.shapepipe instanceof LoopBasedPipe ||
 722             sg2d.fillpipe  instanceof LoopBasedPipe ||
 723             sg2d.drawpipe  instanceof LoopBasedPipe ||
 724             sg2d.imagepipe instanceof LoopBasedPipe)
 725         {
 726             sg2d.loops = getRenderLoops(sg2d);
 727         }


 800         case SunGraphics2D.PAINT_RAD_GRADIENT:
 801             if (sg2d.paint.getTransparency() == OPAQUE) {
 802                 return SurfaceType.OpaqueRadialGradientPaint;
 803             } else {
 804                 return SurfaceType.RadialGradientPaint;
 805             }
 806         case SunGraphics2D.PAINT_TEXTURE:
 807             if (sg2d.paint.getTransparency() == OPAQUE) {
 808                 return SurfaceType.OpaqueTexturePaint;
 809             } else {
 810                 return SurfaceType.TexturePaint;
 811             }
 812         default:
 813         case SunGraphics2D.PAINT_CUSTOM:
 814             return SurfaceType.AnyPaint;
 815         }
 816     }
 817 
 818     private static CompositeType getFillCompositeType(SunGraphics2D sg2d) {
 819         CompositeType compType = sg2d.imageComp;
 820         if (sg2d.compositeState == sg2d.COMP_ISCOPY) {
 821             if (compType == CompositeType.SrcOverNoEa) {
 822                 compType = CompositeType.OpaqueSrcOverNoEa;
 823             } else {
 824                 compType = CompositeType.SrcNoEa;
 825             }
 826         }
 827         return compType;
 828     }
 829 
 830     /**
 831      * Returns a MaskFill object that can be used on this destination
 832      * with the source (paint) and composite types determined by the given
 833      * SunGraphics2D, or null if no such MaskFill object can be located.
 834      * Subclasses can override this method if they wish to filter other
 835      * attributes (such as the hardware capabilities of the destination
 836      * surface) before returning a specific MaskFill object.
 837      */
 838     protected MaskFill getMaskFill(SunGraphics2D sg2d) {
 839         SurfaceType src = getPaintSurfaceType(sg2d);
 840         CompositeType comp = getFillCompositeType(sg2d);




  31 import java.awt.GraphicsConfiguration;
  32 import java.awt.Image;
  33 import java.awt.image.ColorModel;
  34 import java.awt.image.IndexColorModel;
  35 import java.awt.image.Raster;
  36 
  37 import sun.java2d.loops.RenderCache;
  38 import sun.java2d.loops.RenderLoops;
  39 import sun.java2d.loops.CompositeType;
  40 import sun.java2d.loops.SurfaceType;
  41 import sun.java2d.loops.MaskFill;
  42 import sun.java2d.loops.DrawLine;
  43 import sun.java2d.loops.FillRect;
  44 import sun.java2d.loops.DrawRect;
  45 import sun.java2d.loops.DrawPolygons;
  46 import sun.java2d.loops.DrawPath;
  47 import sun.java2d.loops.FillPath;
  48 import sun.java2d.loops.FillSpans;
  49 import sun.java2d.loops.FillParallelogram;
  50 import sun.java2d.loops.DrawParallelogram;

  51 import sun.java2d.loops.DrawGlyphList;
  52 import sun.java2d.loops.DrawGlyphListAA;
  53 import sun.java2d.loops.DrawGlyphListLCD;
  54 import sun.java2d.pipe.LoopPipe;
  55 import sun.java2d.pipe.ShapeDrawPipe;
  56 import sun.java2d.pipe.ParallelogramPipe;
  57 import sun.java2d.pipe.CompositePipe;
  58 import sun.java2d.pipe.GeneralCompositePipe;
  59 import sun.java2d.pipe.SpanClipRenderer;
  60 import sun.java2d.pipe.SpanShapeRenderer;
  61 import sun.java2d.pipe.AAShapePipe;
  62 import sun.java2d.pipe.AlphaPaintPipe;
  63 import sun.java2d.pipe.AlphaColorPipe;
  64 import sun.java2d.pipe.PixelToShapeConverter;
  65 import sun.java2d.pipe.PixelToParallelogramConverter;
  66 import sun.java2d.pipe.TextPipe;
  67 import sun.java2d.pipe.TextRenderer;
  68 import sun.java2d.pipe.AATextRenderer;
  69 import sun.java2d.pipe.LCDTextRenderer;
  70 import sun.java2d.pipe.SolidTextRenderer;


 502     public boolean canRenderLCDText(SunGraphics2D sg2d) {
 503         // For now the answer can only be true in the following cases:
 504         if (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
 505             sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
 506             sg2d.clipState <= SunGraphics2D.CLIP_RECTANGULAR &&
 507             sg2d.surfaceData.getTransparency() == Transparency.OPAQUE)
 508         {
 509             if (haveLCDLoop == LOOP_UNKNOWN) {
 510                 DrawGlyphListLCD loop =
 511                     DrawGlyphListLCD.locate(SurfaceType.AnyColor,
 512                                             CompositeType.SrcNoEa,
 513                                             getSurfaceType());
 514                 haveLCDLoop = (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
 515             }
 516             return haveLCDLoop == LOOP_FOUND;
 517         }
 518         return false; /* for now - in the future we may want to search */
 519     }
 520 
 521     public boolean canRenderParallelograms(SunGraphics2D sg2d) {
 522         if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
 523             if (sg2d.compositeState == SunGraphics2D.COMP_XOR) {
 524                 if (havePgramXORLoop == LOOP_UNKNOWN) {
 525                     FillParallelogram loop =
 526                         FillParallelogram.locate(SurfaceType.AnyColor,
 527                                                  CompositeType.Xor,
 528                                                  getSurfaceType());
 529                     havePgramXORLoop =
 530                         (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
 531                 }
 532                 return havePgramXORLoop == LOOP_FOUND;
 533             } else if (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
 534                        sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
 535                        sg2d.clipState != SunGraphics2D.CLIP_SHAPE)
 536             {
 537                 if (havePgramSolidLoop == LOOP_UNKNOWN) {
 538                     FillParallelogram loop =
 539                         FillParallelogram.locate(SurfaceType.AnyColor,
 540                                                  CompositeType.SrcNoEa,
 541                                                  getSurfaceType());
 542                     havePgramSolidLoop =
 543                         (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
 544                 }
 545                 return havePgramSolidLoop == LOOP_FOUND;
 546             }
 547         }
 548         return false;
 549     }
 550 
 551     public void validatePipe(SunGraphics2D sg2d) {
 552         sg2d.imagepipe = imagepipe;
 553         if (sg2d.compositeState == SunGraphics2D.COMP_XOR) {
 554             if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR) {
 555                 sg2d.drawpipe = paintViaShape;
 556                 sg2d.fillpipe = paintViaShape;
 557                 sg2d.shapepipe = paintShape;
 558                 // REMIND: Ideally custom paint mode would use glyph
 559                 // rendering as opposed to outline rendering but the
 560                 // glyph paint rendering pipeline uses MaskBlit which
 561                 // is not defined for XOR.  This means that text drawn
 562                 // in XOR mode with a Color object is different than
 563                 // text drawn in XOR mode with a Paint object.
 564                 sg2d.textpipe = outlineTextRenderer;
 565             } else {
 566                 PixelToShapeConverter converter;
 567                 if (canRenderParallelograms(sg2d)) {
 568                     converter = colorViaPgram;
 569                     // Note that we use the transforming pipe here because it
 570                     // will examine the shape and possibly perform an optimized
 571                     // operation if it can be simplified.  The simplifications
 572                     // will be valid for all STROKE and TRANSFORM types.
 573                     sg2d.shapepipe = colorViaPgram;
 574                 } else {
 575                     converter = colorViaShape;
 576                     sg2d.shapepipe = colorPrimitives;
 577                 }
 578                 if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
 579                     sg2d.drawpipe = converter;
 580                     sg2d.fillpipe = converter;
 581                     // REMIND: We should not be changing text strategies
 582                     // between outline and glyph rendering based upon the
 583                     // presence of a complex clip as that could cause a
 584                     // mismatch when drawing the same text both clipped
 585                     // and unclipped on two separate rendering passes.
 586                     // Unfortunately, all of the clipped glyph rendering
 587                     // pipelines rely on the use of the MaskBlit operation
 588                     // which is not defined for XOR.
 589                     sg2d.textpipe = outlineTextRenderer;
 590                 } else {
 591                     if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
 592                         sg2d.drawpipe = converter;
 593                         sg2d.fillpipe = converter;
 594                     } else {
 595                         if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) {
 596                             sg2d.drawpipe = converter;
 597                         } else {
 598                             sg2d.drawpipe = colorPrimitives;
 599                         }
 600                         sg2d.fillpipe = colorPrimitives;
 601                     }
 602                     sg2d.textpipe = solidTextRenderer;
 603                 }
 604                 // assert(sg2d.surfaceData == this);
 605             }
 606         } else if (sg2d.compositeState == SunGraphics2D.COMP_CUSTOM) {
 607             if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
 608                 if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
 609                     sg2d.drawpipe = AAClipCompViaShape;
 610                     sg2d.fillpipe = AAClipCompViaShape;
 611                     sg2d.shapepipe = AAClipCompViaShape;
 612                     sg2d.textpipe = clipCompText;
 613                 } else {
 614                     sg2d.drawpipe = AACompViaShape;
 615                     sg2d.fillpipe = AACompViaShape;
 616                     sg2d.shapepipe = AACompViaShape;
 617                     sg2d.textpipe = compText;
 618                 }
 619             } else {
 620                 sg2d.drawpipe = compViaShape;
 621                 sg2d.fillpipe = compViaShape;
 622                 sg2d.shapepipe = compShape;
 623                 if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
 624                     sg2d.textpipe = clipCompText;
 625                 } else {
 626                     sg2d.textpipe = compText;
 627                 }
 628             }
 629         } else if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
 630             sg2d.alphafill = getMaskFill(sg2d);
 631             // assert(sg2d.surfaceData == this);
 632             if (sg2d.alphafill != null) {
 633                 if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
 634                     sg2d.drawpipe = AAClipColorViaShape;
 635                     sg2d.fillpipe = AAClipColorViaShape;
 636                     sg2d.shapepipe = AAClipColorViaShape;
 637                     sg2d.textpipe = clipColorText;
 638                 } else {
 639                     PixelToParallelogramConverter converter =
 640                         (sg2d.alphafill.canDoParallelograms()
 641                          ? AAColorViaPgram
 642                          : AAColorViaShape);
 643                     sg2d.drawpipe = converter;
 644                     sg2d.fillpipe = converter;
 645                     sg2d.shapepipe = converter;
 646                     if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR ||
 647                         sg2d.compositeState > SunGraphics2D.COMP_ISCOPY)
 648                     {
 649                         sg2d.textpipe = colorText;
 650                     } else {
 651                         sg2d.textpipe = getTextPipe(sg2d, true /* AA==ON */);
 652                     }
 653                 }
 654             } else {
 655                 if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
 656                     sg2d.drawpipe = AAClipPaintViaShape;
 657                     sg2d.fillpipe = AAClipPaintViaShape;
 658                     sg2d.shapepipe = AAClipPaintViaShape;
 659                     sg2d.textpipe = clipPaintText;
 660                 } else {
 661                     sg2d.drawpipe = AAPaintViaShape;
 662                     sg2d.fillpipe = AAPaintViaShape;
 663                     sg2d.shapepipe = AAPaintViaShape;
 664                     sg2d.textpipe = paintText;
 665                 }
 666             }
 667         } else if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR ||
 668                    sg2d.compositeState > SunGraphics2D.COMP_ISCOPY ||
 669                    sg2d.clipState == SunGraphics2D.CLIP_SHAPE)
 670         {
 671             sg2d.drawpipe = paintViaShape;
 672             sg2d.fillpipe = paintViaShape;
 673             sg2d.shapepipe = paintShape;
 674             sg2d.alphafill = getMaskFill(sg2d);
 675             // assert(sg2d.surfaceData == this);
 676             if (sg2d.alphafill != null) {
 677                 if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
 678                     sg2d.textpipe = clipColorText;
 679                 } else {
 680                     sg2d.textpipe = colorText;
 681                 }
 682             } else {
 683                 if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
 684                     sg2d.textpipe = clipPaintText;
 685                 } else {
 686                     sg2d.textpipe = paintText;
 687                 }
 688             }
 689         } else {
 690             PixelToShapeConverter converter;
 691             if (canRenderParallelograms(sg2d)) {
 692                 converter = colorViaPgram;
 693                 // Note that we use the transforming pipe here because it
 694                 // will examine the shape and possibly perform an optimized
 695                 // operation if it can be simplified.  The simplifications
 696                 // will be valid for all STROKE and TRANSFORM types.
 697                 sg2d.shapepipe = colorViaPgram;
 698             } else {
 699                 converter = colorViaShape;
 700                 sg2d.shapepipe = colorPrimitives;
 701             }
 702             if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
 703                 sg2d.drawpipe = converter;
 704                 sg2d.fillpipe = converter;
 705             } else {
 706                 if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) {
 707                     sg2d.drawpipe = converter;
 708                 } else {
 709                     sg2d.drawpipe = colorPrimitives;
 710                 }
 711                 sg2d.fillpipe = colorPrimitives;
 712             }
 713 
 714             sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);
 715             // assert(sg2d.surfaceData == this);
 716         }
 717 
 718         // check for loops
 719         if (sg2d.textpipe  instanceof LoopBasedPipe ||
 720             sg2d.shapepipe instanceof LoopBasedPipe ||
 721             sg2d.fillpipe  instanceof LoopBasedPipe ||
 722             sg2d.drawpipe  instanceof LoopBasedPipe ||
 723             sg2d.imagepipe instanceof LoopBasedPipe)
 724         {
 725             sg2d.loops = getRenderLoops(sg2d);
 726         }


 799         case SunGraphics2D.PAINT_RAD_GRADIENT:
 800             if (sg2d.paint.getTransparency() == OPAQUE) {
 801                 return SurfaceType.OpaqueRadialGradientPaint;
 802             } else {
 803                 return SurfaceType.RadialGradientPaint;
 804             }
 805         case SunGraphics2D.PAINT_TEXTURE:
 806             if (sg2d.paint.getTransparency() == OPAQUE) {
 807                 return SurfaceType.OpaqueTexturePaint;
 808             } else {
 809                 return SurfaceType.TexturePaint;
 810             }
 811         default:
 812         case SunGraphics2D.PAINT_CUSTOM:
 813             return SurfaceType.AnyPaint;
 814         }
 815     }
 816 
 817     private static CompositeType getFillCompositeType(SunGraphics2D sg2d) {
 818         CompositeType compType = sg2d.imageComp;
 819         if (sg2d.compositeState == SunGraphics2D.COMP_ISCOPY) {
 820             if (compType == CompositeType.SrcOverNoEa) {
 821                 compType = CompositeType.OpaqueSrcOverNoEa;
 822             } else {
 823                 compType = CompositeType.SrcNoEa;
 824             }
 825         }
 826         return compType;
 827     }
 828 
 829     /**
 830      * Returns a MaskFill object that can be used on this destination
 831      * with the source (paint) and composite types determined by the given
 832      * SunGraphics2D, or null if no such MaskFill object can be located.
 833      * Subclasses can override this method if they wish to filter other
 834      * attributes (such as the hardware capabilities of the destination
 835      * surface) before returning a specific MaskFill object.
 836      */
 837     protected MaskFill getMaskFill(SunGraphics2D sg2d) {
 838         SurfaceType src = getPaintSurfaceType(sg2d);
 839         CompositeType comp = getFillCompositeType(sg2d);