示例#1
0
        public void HintGlyph(PointF[] glyphPoints, int[] contours, byte[] instructions)
        {
            if (instructions == null || instructions.Length == 0)
                return;

            // check if the CVT program disabled hinting
            if ((state.InstructionControl & InstructionControlFlags.InhibitGridFitting) != 0)
                return;

            // TODO: composite glyphs
            // TODO: round the phantom points?

            // save contours and points
            this.contours = contours;
            zp0 = zp1 = zp2 = points = new Zone(glyphPoints, isTwilight: false);

            // reset all of our shared state
            state = cvtState;
            callStackSize = 0;
            debugList.Clear();
            stack.Clear();
            OnVectorsUpdated();

            // normalize the round state settings
            switch (state.RoundState)
            {
                case RoundMode.Super: SetSuperRound(1.0f); break;
                case RoundMode.Super45: SetSuperRound(Sqrt2Over2); break;
            }

            Execute(new InstructionStream(instructions), false, false);
        }
示例#2
0
        public static void DecomposeContour(SharpFontRenderer renderer, int firstIndex, int lastIndex, PointF[] points)
        {
            var pointIndex = firstIndex;
            var start = points[pointIndex];
            var end = points[lastIndex];
            var control = start;

            if (start.Type == PointType.Cubic)
                throw new Exception("Contours can't start with a cubic control point.");

            if (start.Type == PointType.Quadratic)
            {
                // if first point is a control point, try using the last point
                if (end.Type == PointType.OnCurve)
                {
                    start = end;
                    lastIndex--;
                }
                else
                {
                    // if they're both control points, start at the middle
                    start.P = (start.P + end.P) / 2;
                }
                pointIndex--;
            }

            // let's draw this contour
            renderer.MoveTo(start);

            var needClose = true;
            while (pointIndex < lastIndex)
            {
                var point = points[++pointIndex];
                switch (point.Type)
                {
                    case PointType.OnCurve:
                        renderer.LineTo(point);
                        break;

                    case PointType.Quadratic:
                        control = point;
                        var done = false;
                        while (pointIndex < lastIndex)
                        {
                            var next = points[++pointIndex];
                            if (next.Type == PointType.OnCurve)
                            {
                                renderer.QuadraticCurveTo(control, next);
                                done = true;
                                break;
                            }

                            if (next.Type != PointType.Quadratic)
                                throw new Exception("Bad outline data.");

                            renderer.QuadraticCurveTo(control, (control.P + next.P) / 2);
                            control = next;
                        }

                        if (!done)
                        {
                            // if we hit this point, we're ready to close out the contour
                            renderer.QuadraticCurveTo(control, start);
                            needClose = false;
                        }
                        break;

                    case PointType.Cubic:
                        throw new NotSupportedException();
                }
            }

            if (needClose)
                renderer.LineTo(start);
        }
示例#3
0
 public Zone(PointF[] points, bool isTwilight)
 {
     IsTwilight = isTwilight;
     Current = points;
     Original = (PointF[])points.Clone();
     TouchState = new TouchState[points.Length];
 }
示例#4
0
        internal Glyph(Renderer renderer, PointF[] points, int[] contours, float linearHorizontalAdvance)
        {
            this.renderer = renderer;
            this.points = points;
            this.contours = contours;

            // find the bounding box
            var min = new Vector2(float.MaxValue, float.MaxValue);
            var max = new Vector2(float.MinValue, float.MinValue);
            var pointCount = points.Length - 4;
            for (int i = 0; i < pointCount; i++)
            {
                min = Vector2.Min(min, points[i].P);
                max = Vector2.Max(max, points[i].P);
            }

            // save the "pure" size of the glyph, in fractional pixels
            var size = max - min;
            Width = size.X;
            Height = size.Y;

            // find the "render" size of the glyph, in whole pixels
            var shiftX = (int)Math.Floor(min.X);
            var shiftY = (int)Math.Floor(min.Y);
            RenderWidth = (int)Math.Ceiling(max.X) - shiftX;
            RenderHeight = (int)Math.Ceiling(max.Y) - shiftY;

            // translate the points so that 0,0 is at the bottom left corner
            var offset = new Vector2(-shiftX, -shiftY);
            for (int i = 0; i < pointCount; i++)
                points[i] = points[i].Offset(offset);

            HorizontalMetrics = new GlyphMetrics(new Vector2(min.X, max.Y), points[pointCount + 1].P.X - points[pointCount].P.X, linearHorizontalAdvance);

            // TODO: vertical metrics
        }