示例#1
0
        unsafe void CustomBlendPixel32(int *dstPtr, Color srcColor)
        {
            if (FillMode == BlenderFillMode.Force)
            {
                *dstPtr = srcColor.ToARGB();
                return;
            }
            //-------------------------------------------------------------
            int srcColorABGR  = (int)srcColor.ToABGR();
            int existingColor = *dstPtr;
            //int existing_R = (existingColor >> CO.R_SHIFT) & 0xFF;
            int existing_G = (existingColor >> PixelFarm.Drawing.Internal.CO.G_SHIFT) & 0xFF;

            //int existing_B = (existingColor >> CO.B_SHIFT) & 0xFF;


            if (FillMode == BlenderFillMode.InnerAreaX)
            {
                if (existing_G == EdgeBmpLut.BORDER_OUTSIDE || existing_G == EdgeBmpLut.BORDER_OVERLAP_OUTSIDE)
                {
                    *dstPtr = srcColor.ToARGB();
                }
                return;
            }

            if (existingColor == BLACK)
            {
                *dstPtr = srcColor.ToARGB();
                return;
            }


            if (existingColor == _areaInside100)
            {
                *dstPtr = srcColor.ToARGB();
                return;
            }
            if (srcColorABGR == existingColor)
            {
                return;
            }
            if (FillMode == BlenderFillMode.InnerArea50)
            {
                *dstPtr = srcColor.ToARGB();
                return;
            }

            //-------------------------------------------------------------
            //decode edge information
            //we use 2 bytes for encode edge number

            ushort existingEdgeNo = EdgeBmpLut.DecodeEdgeFromColor(existingColor, out AreaKind existingAreaKind);
            ushort newEdgeNo      = EdgeBmpLut.DecodeEdgeFromColor(srcColor, out AreaKind newEdgeAreaKind);


            if (newEdgeAreaKind == AreaKind.OverlapInside || newEdgeAreaKind == AreaKind.OverlapOutside)
            {
                //new color is overlap color
                if (existingAreaKind == AreaKind.OverlapInside || existingAreaKind == AreaKind.OverlapOutside)
                {
                    CornerList registerList = _overlapList[newEdgeNo];
                    _overlapList[existingEdgeNo].Append(registerList);
                }
                else
                {
                    CornerList registerList = _overlapList[newEdgeNo];
                    registerList.Append(existingEdgeNo);
                    *dstPtr = EdgeBmpLut.EncodeToColor(newEdgeNo, (existing_G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside).ToARGB();
                }
            }
            else
            {
                if (existingAreaKind == AreaKind.OverlapInside ||
                    existingAreaKind == AreaKind.OverlapOutside)
                {
                    _overlapList[existingEdgeNo].Append(newEdgeNo);
                }
                else
                {
                    OverlapPart overlapPart;
                    AreaKind    areaKind;
                    if (existingAreaKind == AreaKind.BorderInside || existingAreaKind == AreaKind.AreaInsideCoverage100)
                    {
                        if (newEdgeAreaKind == AreaKind.BorderInside)
                        {
                            areaKind    = AreaKind.OverlapInside;
                            overlapPart = new OverlapPart(
                                existingEdgeNo, (existing_G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside,
                                newEdgeNo, (srcColor.G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside);
                        }
                        else
                        {
                            areaKind    = AreaKind.OverlapInside;
                            overlapPart = new OverlapPart(
                                existingEdgeNo, (existing_G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside,
                                newEdgeNo, (existing_G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside);
                        }
                    }
                    else
                    {
                        //existing is outside
                        if (newEdgeAreaKind == AreaKind.BorderInside)
                        {
                            areaKind    = AreaKind.OverlapInside;
                            overlapPart = new OverlapPart(
                                existingEdgeNo, (existing_G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside,
                                newEdgeNo, (existing_G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside);
                        }
                        else
                        {
                            areaKind    = AreaKind.OverlapOutside;
                            overlapPart = new OverlapPart(
                                existingEdgeNo, (existing_G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside,
                                newEdgeNo, (srcColor.G == EdgeBmpLut.BORDER_INSIDE) ? AreaKind.OverlapInside : AreaKind.OverlapOutside);
                        }
                    }


                    if (!_overlapParts.TryGetValue(overlapPart, out ushort found))
                    {
                        if (_overlapList.Count >= ushort.MaxValue)
                        {
                            throw new NotSupportedException();
                        }
                        //
                        ushort newPartNo = (ushort)_overlapList.Count;
                        _overlapParts.Add(overlapPart, newPartNo);
                        //
                        CornerList cornerList = new CornerList();
#if DEBUG
                        if (_overlapList.Count >= 388)
                        {
                        }
#endif

                        _overlapList.Add(cornerList);

                        cornerList.Append(existingEdgeNo);
                        cornerList.Append(newEdgeNo);
                        //set new color
                        *dstPtr = EdgeBmpLut.EncodeToColor(newPartNo, areaKind).ToARGB();
                    }
                    else
                    {
                        //set new color
                        *dstPtr = EdgeBmpLut.EncodeToColor(found, areaKind).ToARGB();
                    }
                }
            }
        }