Beispiel #1
0
        public static SpriteTextureMapData <PixelFarm.CpuBlit.MemBitmap> CreateMsdfImage(ExtMsdfGen.Shape shape, MsdfGenParams genParams, EdgeBmpLut lutBuffer = null)
        {
            double left   = MAX;
            double bottom = MAX;
            double right  = -MAX;
            double top    = -MAX;

            shape.findBounds(ref left, ref bottom, ref right, ref top);
            int w = (int)Math.Ceiling((right - left));
            int h = (int)Math.Ceiling((top - bottom));

            if (w < genParams.minImgWidth)
            {
                w = genParams.minImgWidth;
            }
            if (h < genParams.minImgHeight)
            {
                h = genParams.minImgHeight;
            }


            //temp, for debug with glyph 'I', tahoma font
            //double edgeThreshold = 1.00000001;//default, if edgeThreshold < 0 then  set  edgeThreshold=1
            //Msdfgen.Vector2 scale = new Msdfgen.Vector2(0.98714652956298199, 0.98714652956298199);
            //double pxRange = 4;
            //translate = new Msdfgen.Vector2(12.552083333333332, 4.0520833333333330);
            //double range = pxRange / Math.Min(scale.x, scale.y);


            int borderW = (int)((float)w / 5f) + 3;

            //org
            //var translate = new ExtMsdfgen.Vector2(left < 0 ? -left + borderW : borderW, bottom < 0 ? -bottom + borderW : borderW);
            //test
            var translate = new Vector2(-left + borderW, -bottom + borderW);

            w += borderW * 2; //borders,left- right
            h += borderW * 2; //borders, top- bottom

            double edgeThreshold = genParams.edgeThreshold;

            if (edgeThreshold < 0)
            {
                edgeThreshold = 1.00000001; //use default if  edgeThreshold <0
            }

            var    scale = new Vector2(genParams.scaleX, genParams.scaleY); //scale
            double range = genParams.pxRange / Math.Min(scale.x, scale.y);
            //---------
            FloatRGBBmp frgbBmp = new FloatRGBBmp(w, h);

            EdgeColoring.edgeColoringSimple(shape, genParams.angleThreshold);

            if (lutBuffer != null)
            {
                MsdfGenerator.generateMSDF2(frgbBmp,
                                            shape,
                                            range,
                                            scale,
                                            translate,//translate to positive quadrant
                                            edgeThreshold,
                                            lutBuffer);
            }
            else
            {
                MsdfGenerator.generateMSDF(frgbBmp,
                                           shape,
                                           range,
                                           scale,
                                           translate,//translate to positive quadrant
                                           edgeThreshold);
            }

            var spriteData = new SpriteTextureMapData <PixelFarm.CpuBlit.MemBitmap>(0, 0, w, h);

            spriteData.Source         = PixelFarm.CpuBlit.MemBitmap.CreateFromCopy(w, h, MsdfGenerator.ConvertToIntBmp(frgbBmp));
            spriteData.TextureXOffset = (float)translate.x;
            spriteData.TextureYOffset = (float)translate.y;
            return(spriteData);
        }
Beispiel #2
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 >> CO.G_SHIFT) & 0xFF;

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


            if (FillMode == BlenderFillMode.InnerAreaX)
            {
                //special mode
                if (existing_G == EdgeBmpLut.AREA_INSIDE_COVERAGE50 ||
                    existing_G == EdgeBmpLut.AREA_INSIDE_COVERAGE100)
                {
                    *dstPtr = srcColor.ToARGB();
                }
                return;
            }
            else
            {
            }
            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;
            }
            if (FillMode == BlenderFillMode.FinalFill)
            {
                if (existing_G == EdgeBmpLut.AREA_INSIDE_COVERAGEX ||
                    existing_G == EdgeBmpLut.AREA_INSIDE_COVERAGE50 ||
                    existing_G == EdgeBmpLut.AREA_INSIDE_COVERAGE100 ||
                    existing_G == EdgeBmpLut.BORDER_OVERLAP_INSIDE ||
                    existing_G == EdgeBmpLut.BORDER_INSIDE)
                {
                    *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 (existingAreaKind == AreaKind.AreaInsideCoverage100)
            //{
            //    //*dstPtr = srcColor.ToARGB();
            //    return;
            //}
            //if (existingAreaKind == AreaKind.AreaInsideCoverage100)
            //{
            //    switch (newEdgeAreaKind)
            //    {
            //        case AreaKind.BorderOutside:
            //        case AreaKind.OverlapOutside:
            //            return;
            //        case AreaKind.AreaInsideCoverage100:
            //            return;
            //        case AreaKind.OverlapInside:
            //            return;
            //        default:
            //            {

            //            }
            //            break;
            //    }

            //}
#if DEBUG
            if (existingEdgeNo == 389)
            {
            }
#endif


            //if (FillMode == BlenderFillMode.FinalFill)
            //{
            //    if (existingAreaKind == AreaKind.BorderOutside || existingAreaKind == AreaKind.OverlapOutside)
            //    {
            //        *dstPtr = srcColor.ToARGB();
            //    }
            //    return;
            //}

            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
                {
                    ////create new overlap part
                    if (newEdgeNo == existingEdgeNo)
                    {
                        return;
                    }

                    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 (existingEdgeNo == 0)
                    //{
                    //    if (existingAreaKind == AreaKind.AreaInsideCoverage100)
                    //    {
                    //        *dstPtr = EdgeBmpLut.EncodeToColor(newEdgeNo, newEdgeAreaKind).ToARGB();
                    //        return;
                    //    }
                    //}
                    //else
                    //{
                    //}

                    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();
                    }
                }
            }
        }