示例#1
0
        static void GenerateMSDF3(FloatRGBBmp output, Shape shape, double range, Vector2 scale, Vector2 translate, double edgeThreshold, EdgeBmpLut lut)
        {
            //----------------------
            //this is our extension,
            //we use lookup bitmap (lut) to check
            //what is the nearest contour of a given pixel.
            //----------------------

            int w = output.Width;
            int h = output.Height;

            EdgeSegment[] singleSegment = new EdgeSegment[1];//temp array for



            for (int y = 0; y < h; ++y)
            {
                for (int x = 0; x < w; ++x)
                {
                    //PER-PIXEL-OPERATION
                    //check preview pixel

                    int lutPix  = lut.GetPixel(x, y);
                    int lutPixR = (lutPix & 0xFF);
                    int lutPixG = (lutPix >> 8) & 0xff;
                    int lutPixB = (lutPix >> 16) & 0xff;

                    if (lutPixG == 0)
                    {
                        continue;               //black=> completely outside, skip
                    }
                    if (lutPixG == EdgeBmpLut.AREA_INSIDE_COVERAGE100 ||
                        lutPixG == EdgeBmpLut.AREA_INSIDE_COVERAGE50 ||
                        lutPixG == EdgeBmpLut.AREA_INSIDE_COVERAGEX)
                    {
                        //inside the contour => fill all with white
                        output.SetPixel(x, y, new FloatRGB(1f, 1f, 1f));
                        continue;
                    }

                    //reset variables
                    EdgePoint r = new EdgePoint {
                        minDistance = SignedDistance.INFINITE
                    },
                              g = new EdgePoint {
                        minDistance = SignedDistance.INFINITE
                    },
                              b = new EdgePoint {
                        minDistance = SignedDistance.INFINITE
                    };

                    bool useR, useG, useB;
                    useR = useG = useB = true;
                    //------

                    Vector2 p = (new Vector2(x + .5, y + .5) / scale) - translate;

                    EdgeStructure edgeStructure = lut.GetEdgeStructure(x, y);

#if DEBUG
                    if (edgeStructure.IsEmpty)
                    {
                        //should not occurs
                        throw new NotSupportedException();
                    }
#endif
                    EdgeSegment[] edges = null;
                    if (edgeStructure.HasOverlappedSegments)
                    {
                        edges = edgeStructure.Segments;
                    }
                    else
                    {
                        singleSegment[0] = edgeStructure.Segment;
                        edges            = singleSegment;
                    }
                    //-------------

                    for (int i = 0; i < edges.Length; ++i)
                    {
                        EdgeSegment edge = edges[i];

                        SignedDistance distance = edge.signedDistance(p, out double param);//***

                        if (edge.HasComponent(EdgeColor.RED) && distance < r.minDistance)
                        {
                            r.minDistance = distance;
                            r.nearEdge    = edge;
                            r.nearParam   = param;
                            useR          = false;
                        }
                        if (edge.HasComponent(EdgeColor.GREEN) && distance < g.minDistance)
                        {
                            g.minDistance = distance;
                            g.nearEdge    = edge;
                            g.nearParam   = param;
                            useG          = false;
                        }
                        if (edge.HasComponent(EdgeColor.BLUE) && distance < b.minDistance)
                        {
                            b.minDistance = distance;
                            b.nearEdge    = edge;
                            b.nearParam   = param;
                            useB          = false;
                        }
                    }

                    double contour_r = r.CalculateContourColor(p);
                    double contour_g = g.CalculateContourColor(p);
                    double contour_b = b.CalculateContourColor(p);

                    if (useB && contour_b <= SignedDistance.INFINITE.distance)
                    {
                        contour_b = 1 * range;
                    }
                    if (useG && contour_g <= SignedDistance.INFINITE.distance)
                    {
                        contour_g = 1 * range;
                    }
                    if (useR && contour_r <= SignedDistance.INFINITE.distance)
                    {
                        contour_r = 1 * range;
                    }

                    output.SetPixel(x, y,
                                    new FloatRGB(
                                        (float)(contour_r / range + .5),
                                        (float)(contour_g / range + .5),
                                        (float)(contour_b / range + .5)
                                        ));
                }
            }
        }