예제 #1
0
        /// <summary>
        /// read fitting output
        /// </summary>
        /// <param name="tx">glyph translator</param>
        public static void ReadOutput(this GlyphFitOutline glyphOutline, IGlyphTranslator tx, float pxScale)
        {
            if (glyphOutline == null)
            {
                return;
            }
            //
            //-----------------------------------------------------------
            //create fit contour
            //this version use only Agg's vertical hint only ****
            //(ONLY vertical fitting , NOT apply horizontal fit)
            //-----------------------------------------------------------
            //create outline
            //then create
            List <GlyphContour> contours = glyphOutline.Contours;
            int j = contours.Count;

            tx.BeginRead(j);
            for (int i = 0; i < j; ++i)
            {
                //new contour
                CreateFitShape(tx, contours[i], pxScale, false, true, false);
                tx.CloseContour();
            }
            tx.EndRead();
        }
예제 #2
0
        public override void ReadShapes(IGlyphTranslator tx)
        {
            //read output shape from dynamic outline

            if (this.UseTrueTypeInstructions)
            {
                base.ReadShapes(tx);
                return;
            }
            if (!TemporaryDisableCustomFit && this.UseVerticalHinting)
            {
                //read from our auto hint fitoutline
                //need scale from original. 
                float toPixelScale = Typeface.CalculateScaleToPixel(RecentFontSizeInPixels);
                if (toPixelScale < 0)
                {
                    toPixelScale = 1;
                }
                _latestDynamicOutline.GenerateOutput(tx, toPixelScale);
            }
            else
            {
                base.ReadShapes(tx);
            }
        }
예제 #3
0
 public virtual void ReadShapes(IGlyphTranslator tx)
 {
     //read output from glyph points
     if (_cffGlyphData != null)
     {
         _cffEvalEngine.Run(tx, _ownerCff, _cffGlyphData, _recentPixelScale);
     }
     else
     {
         tx.Read(_outputGlyphPoints, _outputContours, _recentPixelScale);
     }
 }
예제 #4
0
        void GenerateContourOutput(IGlyphTranslator tx, GlyphContour contour)
        {
            List <GlyphPoint> points = contour.flattenPoints;
            int j = points.Count;

            if (j == 0)
            {
                return;
            }
            //-------------------------------------------------
            Bounds controlBounds = this.OriginalGlyphControlBounds;
            //walk along the edge in the contour to generate new edge output
            float pxscale = this._pxScale;


#if DEBUG
            //            dbugWriteLine("===begin===" + fit_x_offset);
            //            if (!dbugUseHorizontalFitValue)
            //            {
            //                fit_x_offset = 0;
            //            }
#endif

            //-------------------------------------------------
            //fineSubPixelRenderingOffset = 0.33f;

            //-------------------------------------------------

            //TODO: review here
            float fit_x, fit_y;
            points[0].GetFitXY(pxscale, out fit_x, out fit_y);
            //
            tx.MoveTo(fit_x, fit_y);
#if DEBUG
            // dbugWriteOutput("M", fit_x, fit_x + fit_x_offset, fit_y);
#endif
            //2. others
            for (int i = 1; i < j; ++i)
            {
                //try to fit to grid
                points[i].GetFitXY(pxscale, out fit_x, out fit_y);
                tx.LineTo(fit_x, fit_y);
#if DEBUG
                //for debug
                //dbugWriteOutput("L", fit_x, fit_x + fit_x_offset, fit_y);
#endif
            }
            //close
            tx.CloseContour();
#if DEBUG
            //dbugWriteLine("===end===");
#endif
        }
예제 #5
0
 public void ReadShapes(IGlyphTranslator tx)
 {
     if (_useAutoHint)
     {
         //read from our auto hint fitoutline
         //need scale from original.
         _fitOutline.ReadOutput(tx, _recentPixelScale);
     }
     else
     {
         //read output from glyph points
         tx.Read(this._outputGlyphPoints, this._outputContours, _recentPixelScale);
     }
 }
예제 #6
0
        internal void Run(IGlyphTranslator tx, Cff1Font cff1Font, Type2GlyphInstructionList instructionList, float scale = 1)
        {
            //all fields are set to new values***

            _cff1Font = cff1Font;
            _scale    = scale;

            //-------------
            //from Technical Note #5176 (CFF spec)
            //resolve with bias
            //Card16 bias;
            //Card16 nSubrs = subrINDEX.count;
            //if (CharstringType == 1)
            //    bias = 0;
            //else if (nSubrs < 1240)
            //    bias = 107;
            //else if (nSubrs < 33900)
            //    bias = 1131;
            //else
            //    bias = 32768;

            //find local subroutine

            int nsubrs = cff1Font._localSubrs.Count;

            _cffBias = (nsubrs < 1240) ? 107 :
                       (nsubrs < 33900) ? 1131 : 32769;      //TODO: review 32769 or 32768

            //
            double currentX = 0, currentY = 0;


            var scaleTx = new PxScaleGlyphTx(scale, tx);

            //
            scaleTx.BeginRead(0);//unknown contour count
            //
            Run(scaleTx, instructionList, ref currentX, ref currentY);
            //

            //
            //some cff end without closing the latest contour?

            if (scaleTx.IsContourOpened)
            {
                scaleTx.CloseContour();
            }

            scaleTx.EndRead();
        }
예제 #7
0
        /// <summary>
        /// generate output with specific pixel scale
        /// </summary>
        /// <param name="tx"></param>
        /// <param name="pxScale"></param>
        public void GenerateOutput(IGlyphTranslator tx, float pxScale)
        {
            if (_contours == null)
            {
                return;                    //blank
            }
#if DEBUG
            this.EnableGridFit = dbugTestNewGridFitting;
#endif

            if (_pxScale != pxScale)
            {
                //new scale need to adjust fit value again
                _needAdjustGridFitValues = true;
            }
            //
            this._pxScale = pxScale;
            //
            if (EnableGridFit)
            {
                if (_needRefreshBoneGroup)
                {
                    //change scale not affect the grid fit ***
                    AnalyzeBoneGroups(GridBoxWidth, GridBoxHeight);
                    _needRefreshBoneGroup = false;
                }
                //
                if (_needAdjustGridFitValues)
                {
                    ReCalculateFittingValues();
                    _needAdjustGridFitValues = false;
                }
            }

            if (tx != null)
            {
                List <GlyphContour> contours = this._contours;
                int j = contours.Count;
                tx.BeginRead(j);
                for (int i = 0; i < j; ++i)
                {
                    //generate in order of contour
                    GenerateContourOutput(tx, contours[i]);
                }
                tx.EndRead();
            }
        }
예제 #8
0
 public override void ReadShapes(IGlyphTranslator tx)
 {
     if (this.UseTrueTypeInstructions)
     {
         base.ReadShapes(tx);
         return;
     }
     if (this.UseVerticalHinting)
     {
         //read from our auto hint fitoutline
         //need scale from original.
         float toPixelScale = Typeface.CalculateToPixelScale(this.RecentFontSizeInPixels);
         if (toPixelScale < 0)
         {
             toPixelScale = 1;
         }
         _fitOutline.ReadOutput(tx, toPixelScale);
     }
     else
     {
         base.ReadShapes(tx);
     }
 }
예제 #9
0
 public PxScaleGlyphTx(float scale, IGlyphTranslator tx)
 {
     _scale = scale;
     _tx    = tx;
 }
예제 #10
0
 public virtual void ReadShapes(IGlyphTranslator tx)
 {
     //read output from glyph points
     tx.Read(this._outputGlyphPoints, this._outputContours, _recentPixelScale);
 }
 public PxScaleGlyphTx(float scale, IGlyphTranslator tx)
 {
     this.scale = scale;
     this.tx    = tx;
 }
        //for TrueType Font
        public static void Read(this IGlyphTranslator tx, GlyphPointF[] glyphPoints, ushort[] contourEndPoints, float scale = 1)
        {
            int startContour = 0;
            int cpoint_index = 0;//current point index

            int todoContourCount = contourEndPoints.Length;

            //-----------------------------------
            //1. start read data from a glyph
            tx.BeginRead(todoContourCount);
            //-----------------------------------
            float latest_moveto_x        = 0;
            float latest_moveto_y        = 0;
            int   curveControlPointCount = 0; // 1 curve control point => Quadratic, 2 curve control points => Cubic


            while (todoContourCount > 0)
            {
                //reset
                curveControlPointCount = 0;

                //foreach contour...
                //next contour will begin at...
                int nextCntBeginAtIndex = contourEndPoints[startContour] + 1;

                //reset  ...

                bool    has_c_begin = false;         //see below [A]
                Vector2 c_begin     = new Vector2(); //special point if the glyph starts with 'off-curve' control point
                Vector2 c1          = new Vector2(); //control point of quadratic curve
                //-------------------------------------------------------------------
                bool offCurveMode           = false;
                bool foundFirstOnCurvePoint = false;
                bool startWithOffCurve      = false;
                int  cnt_point_count        = 0;
                //-------------------------------------------------------------------
                //[A]
                //first point may start with 'ON CURVE" or 'OFF-CURVE'
                //1. if first point is 'ON-CURVE' => we just set moveto command to it
                //
                //2. if first point is 'OFF-CURVE' => we store it into c_begin and set has_c_begin= true
                //   the c_begin will be use when we close the contour
                //
                //
                //eg. glyph '2' in Century font starts with 'OFF-CURVE' point, and ends with 'OFF-CURVE'
                //-------------------------------------------------------------------

#if DEBUG
                int dbug_cmdcount = 0;
#endif
                for (; cpoint_index < nextCntBeginAtIndex; ++cpoint_index)
                {
#if DEBUG
                    dbug_cmdcount++;
#endif
                    //for each point in this contour

                    //point p is an on-curve point (on outline). (not curve control point)
                    //possible ways..
                    //1. if we are in curve mode, then p is end point
                    //   we must decide which curve to create (Curve3 or Curve4)
                    //   easy, ...
                    //      if  curveControlPointCount == 1 , then create Curve3
                    //      else curveControlPointCount ==2 , then create Curve4
                    //2. if we are NOT in curve mode,
                    //      if p is first point then set this to x0,y0
                    //      else then p is end point of a line.

                    GlyphPointF p = glyphPoints[cpoint_index];
                    cnt_point_count++;

                    float p_x = p.X * scale;
                    float p_y = p.Y * scale;

                    //int vtag = (int)flags[cpoint_index] & 0x1;
                    //bool has_dropout = (((vtag >> 2) & 0x1) != 0);
                    //int dropoutMode = vtag >> 3;


                    if (p.onCurve)
                    {
                        //-------------------------------------------------------------------
                        //[B]
                        //point p is an 'on-curve' point (on outline).
                        //(not curve control point)***
                        //the point touch the outline.

                        //possible ways..
                        //1. if we are in offCurveMode, then p is a curve end point.
                        //   we must decide which curve to create (Curve3 or Curve4)
                        //   easy, ...
                        //      if  curveControlPointCount == 1 , then create Curve3
                        //      else curveControlPointCount ==2 , then create Curve4 (BUT SHOULD NOT BE FOUND IN TRUE TYPEFONT'(
                        //2. if we are NOT in offCurveMode,
                        //      if p is first point then set this to =>moveto(x0,y0)
                        //      else then p is end point of a line => lineto(x1,y1)
                        //-------------------------------------------------------------------

                        if (offCurveMode)
                        {
                            //as describe above [B.1] ,...

                            switch (curveControlPointCount)
                            {
                            case 1:

                                tx.Curve3(
                                    c1.X, c1.Y,
                                    p_x, p_y);

                                break;

                            default:

                                //for TrueType font
                                //we should not be here?
                                throw new NotSupportedException();
                            }

                            //reset curve control point count
                            curveControlPointCount = 0;
                            //we touch the curve, set offCurveMode= false
                            offCurveMode = false;
                        }
                        else
                        {
                            // p is ON CURVE, but now we are in OFF-CURVE mode.
                            //
                            //as describe above [B.2] ,...
                            if (!foundFirstOnCurvePoint)
                            {
                                //special treament for first point
                                foundFirstOnCurvePoint = true;
                                switch (curveControlPointCount)
                                {
                                case 0:
                                    //describe above, see [A.1]
                                    tx.MoveTo(latest_moveto_x = p_x, latest_moveto_y = p_y);
                                    break;

                                case 1:

                                    //describe above, see [A.2]
                                    c_begin     = c1;
                                    has_c_begin = true;
                                    //since c1 is off curve
                                    //we skip the c1 for and use it when we close the curve

                                    tx.MoveTo(latest_moveto_x = p_x, latest_moveto_y = p_y);
                                    curveControlPointCount--;
                                    break;

                                default: throw new NotSupportedException();
                                }
                            }
                            else
                            {
                                tx.LineTo(p_x, p_y);
                            }

                            //if (has_dropout)
                            //{
                            //    //printf("[%d] on,dropoutMode=%d: %d,y:%d \n", mm, dropoutMode, vpoint.x, vpoint.y);
                            //}
                            //else
                            //{
                            //    //printf("[%d] on,x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                            //}
                        }
                    }
                    else
                    {
                        //p is OFF-CURVE point (this is curve control point)
                        //
                        if (cnt_point_count == 1)
                        {
                            //1st point
                            startWithOffCurve = true;
                        }
                        switch (curveControlPointCount)
                        {
                        case 0:
                            c1 = new Vector2(p_x, p_y);
                            if (foundFirstOnCurvePoint)
                            {
                                //this point is curve control point***
                                //so set curve mode = true
                                //check number if existing curve control
                                offCurveMode = true;
                            }
                            else
                            {
                                //describe above, see [A.2]
                            }
                            break;

                        case 1:
                        {
                            if (!foundFirstOnCurvePoint)
                            {
                                Vector2 mid2 = GetMidPoint(c1, p_x, p_y);
                                //----------
                                //2. generate curve3 ***
                                c_begin     = c1;
                                has_c_begin = true;


                                tx.MoveTo(latest_moveto_x = mid2.X, latest_moveto_y = mid2.Y);
                                // curveControlPointCount--;
                                foundFirstOnCurvePoint = true;
                                c1 = new Vector2(p_x, p_y);
                                continue;
                            }

                            //we already have previous 1st control point (c1)
                            //-------------------------------------
                            //please note that TrueType font
                            //compose of Quadractic Bezier Curve (Curve3) ***
                            //-------------------------------------
                            //in this case, this is NOT Cubic,
                            //this is 2 CONNECTED Quadractic Bezier Curves***
                            //
                            //we must create 'end point' of the first curve
                            //and set it as 'begin point of the second curve.
                            //
                            //this is done by ...
                            //1. calculate mid point between c1 and the latest point (p_x,p_y)
                            Vector2 mid = GetMidPoint(c1, p_x, p_y);
                            //----------
                            //2. generate curve3 ***
                            tx.Curve3(
                                c1.X, c1.Y,
                                mid.X, mid.Y);
                            //------------------------
                            //3. so curve control point number is reduce by 1***
                            curveControlPointCount--;
                            //------------------------
                            //4. and set (p_x,p_y) as 1st control point for the new curve
                            c1           = new Vector2(p_x, p_y);
                            offCurveMode = true;
                            //
                            //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                        }
                        break;

                        default:
                            throw new NotSupportedException();
                        }
                        //count
                        curveControlPointCount++;
                    }
                }
                //--------
                //when finish,
                //ensure that the contour is closed.

                if (offCurveMode)
                {
                    switch (curveControlPointCount)
                    {
                    case 0: break;

                    case 1:
                    {
                        if (has_c_begin)
                        {
                            Vector2 mid = GetMidPoint(c1, c_begin.X, c_begin.Y);
                            //----------
                            //2. generate curve3 ***
                            tx.Curve3(
                                c1.X, c1.Y,
                                mid.X, mid.Y);
                            //------------------------
                            //3. so curve control point number is reduce by 1***
                            curveControlPointCount--;
                            //------------------------
                            tx.Curve3(
                                c_begin.X, c_begin.Y,
                                latest_moveto_x, latest_moveto_y);
                        }
                        else
                        {
                            tx.Curve3(
                                c1.X, c1.Y,
                                latest_moveto_x, latest_moveto_y);
                        }
                    }
                    break;

                    default:
                        //for TrueType font
                        //we should not be here?
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    //end with touch curve
                    //but if this start with off curve
                    //then we must close it properly
                    if (startWithOffCurve)
                    {
                        //start with off-curve and end with touch curve
                        tx.Curve3(
                            c_begin.X, c_begin.Y,
                            latest_moveto_x, latest_moveto_y);
                    }
                }

                //--------
                tx.CloseContour(); //***
                startContour++;
                //--------
                todoContourCount--;
                //--------
            }
            //finish
            tx.EndRead();
        }
예제 #13
0
 public ContourToGlyphTranslator(IGlyphTranslator tx) => _tx = tx;
예제 #14
0
        void Run(IGlyphTranslator tx, Type2GlyphInstructionList instructionList, ref double currentX, ref double currentY)
        {
            //recursive ***

            Type2EvaluationStack evalStack = GetFreeEvalStack(); //**

            evalStack._currentX = currentX;
            evalStack._currentY = currentY;

            List <Type2Instruction> insts = instructionList.Insts;

            evalStack.GlyphTranslator = tx;
            int j = insts.Count;

            for (int i = 0; i < j; ++i)
            {
                Type2Instruction inst = insts[i];
                //if (inst.Op != OperatorName.LoadInt)
                //{
                //}
                switch (inst.Op)
                {
                default: throw new NotSupportedException();

                case OperatorName.GlyphWidth:
                    //TODO:
                    break;

                case OperatorName.LoadInt:
                    evalStack.Push(inst.Value);
                    break;                        //

                case OperatorName.endchar:
                    evalStack.EndChar();
                    break;

                case OperatorName.flex: evalStack.Flex(); break;

                case OperatorName.hflex: evalStack.H_Flex(); break;

                case OperatorName.hflex1: evalStack.H_Flex1(); break;

                case OperatorName.flex1: evalStack.Flex1(); break;

                //-------------------------
                //4.4: Arithmetic Operators
                case OperatorName.abs: evalStack.Op_Abs(); break;

                case OperatorName.add: evalStack.Op_Add(); break;

                case OperatorName.sub: evalStack.Op_Sub(); break;

                case OperatorName.div: evalStack.Op_Div(); break;

                case OperatorName.neg: evalStack.Op_Neg(); break;

                case OperatorName.random: evalStack.Op_Random(); break;

                case OperatorName.mul: evalStack.Op_Mul(); break;

                case OperatorName.sqrt: evalStack.Op_Sqrt(); break;

                case OperatorName.drop: evalStack.Op_Drop(); break;

                case OperatorName.exch: evalStack.Op_Exch(); break;

                case OperatorName.index: evalStack.Op_Index(); break;

                case OperatorName.roll: evalStack.Op_Roll(); break;

                case OperatorName.dup: evalStack.Op_Dup(); break;

                //-------------------------
                //4.5: Storage Operators
                case OperatorName.put: evalStack.Put(); break;

                case OperatorName.get: evalStack.Get(); break;

                //-------------------------
                //4.6: Conditional
                case OperatorName.and: evalStack.Op_And(); break;

                case OperatorName.or: evalStack.Op_Or(); break;

                case OperatorName.not: evalStack.Op_Not(); break;

                case OperatorName.eq: evalStack.Op_Eq(); break;

                case OperatorName.ifelse: evalStack.Op_IfElse(); break;

                //
                case OperatorName.rlineto: evalStack.R_LineTo(); break;

                case OperatorName.hlineto: evalStack.H_LineTo(); break;

                case OperatorName.vlineto: evalStack.V_LineTo(); break;

                case OperatorName.rrcurveto: evalStack.RR_CurveTo(); break;

                case OperatorName.hhcurveto: evalStack.HH_CurveTo(); break;

                case OperatorName.hvcurveto: evalStack.HV_CurveTo(); break;

                case OperatorName.rcurveline: evalStack.R_CurveLine(); break;

                case OperatorName.rlinecurve: evalStack.R_LineCurve(); break;

                case OperatorName.vhcurveto: evalStack.VH_CurveTo(); break;

                case OperatorName.vvcurveto: evalStack.VV_CurveTo(); break;

                //-------------------------------------------------------------------
                case OperatorName.rmoveto: evalStack.R_MoveTo(); break;

                case OperatorName.hmoveto: evalStack.H_MoveTo(); break;

                case OperatorName.vmoveto: evalStack.V_MoveTo(); break;

                //-------------------------------------------------------------------
                //4.3 Hint Operators
                case OperatorName.hstem: evalStack.H_Stem(); break;

                case OperatorName.vstem: evalStack.V_Stem(); break;

                case OperatorName.vstemhm: evalStack.V_StemHM(); break;

                case OperatorName.hstemhm: evalStack.H_StemHM(); break;

                //--------------------------
                case OperatorName.hintmask1: evalStack.HintMask1(inst.Value); break;

                case OperatorName.hintmask2: evalStack.HintMask2(inst.Value); break;

                case OperatorName.hintmask3: evalStack.HintMask3(inst.Value); break;

                case OperatorName.hintmask4: evalStack.HintMask4(inst.Value); break;

                case OperatorName.hintmask_bits: evalStack.HintMaskBits(inst.Value); break;

                //------------------------------
                case OperatorName.cntrmask1: evalStack.CounterSpaceMask1(inst.Value); break;

                case OperatorName.cntrmask2: evalStack.CounterSpaceMask2(inst.Value); break;

                case OperatorName.cntrmask3: evalStack.CounterSpaceMask3(inst.Value); break;

                case OperatorName.cntrmask4: evalStack.CounterSpaceMask4(inst.Value); break;

                case OperatorName.cntrmask_bits: evalStack.CounterSpaceMaskBits(inst.Value); break;

                //-------------------------
                //4.7: Subroutine Operators
                case OperatorName._return:
                {
                    //***
                    //don't forget to return _evalStack's currentX, currentY to prev evl context
                    currentX = evalStack._currentX;
                    currentY = evalStack._currentY;
                    evalStack.Ret();
                }
                break;

                case OperatorName.callsubr:
                {
                    //resolve local subrountine
                    int rawSubRoutineNum = (int)evalStack.Pop();
                    Type2GlyphInstructionList resolvedSubroutine = _cff1Font._localSubrs[rawSubRoutineNum + _cffBias];
                    //then we move to another context
                    //recursive ***
                    Run(tx, resolvedSubroutine, ref evalStack._currentX, ref evalStack._currentY);
                }
                break;

                case OperatorName.callgsubr: throw new NotSupportedException();
                }
            }


            ReleaseEvalStack(evalStack);//****
        }
예제 #15
0
        static void CreateFitShape(IGlyphTranslator tx,
                                   GlyphContour contour,
                                   float pixelScale,
                                   bool x_axis,
                                   bool y_axis,
                                   bool useHalfPixel)
        {
            List <GlyphPoint2D> mergePoints = contour.mergedPoints;
            int j = mergePoints.Count;
            //merge 0 = start
            double prev_px  = 0;
            double prev_py  = 0;
            double p_x      = 0;
            double p_y      = 0;
            double first_px = 0;
            double first_py = 0;

            {
                GlyphPoint2D p = mergePoints[0];
                p_x = p.x * pixelScale;
                p_y = p.y * pixelScale;

                if (y_axis && p.isPartOfHorizontalEdge && p.isUpperSide && p_y > 3)
                {
                    //vertical fitting
                    //fit p_y to grid
                    p_y = RoundToNearestVerticalSide((float)p_y, useHalfPixel);
                }

                if (x_axis && p.IsPartOfVerticalEdge && p.IsLeftSide)
                {
                    float new_x = RoundToNearestHorizontalSide((float)p_x);
                    //adjust right-side vertical edge
                    EdgeLine rightside = p.GetMatchingVerticalEdge();
                    if (rightside != null)
                    {
                    }
                    p_x = new_x;
                }
                tx.MoveTo((float)p_x, (float)p_y);
                //-------------
                first_px = prev_px = p_x;
                first_py = prev_py = p_y;
            }

            for (int i = 1; i < j; ++i)
            {
                //all merge point is polygon point
                GlyphPoint2D p = mergePoints[i];
                p_x = p.x * pixelScale;
                p_y = p.y * pixelScale;

                if (y_axis && p.isPartOfHorizontalEdge && p.isUpperSide && p_y > 3)
                {
                    //vertical fitting
                    //fit p_y to grid
                    p_y = RoundToNearestVerticalSide((float)p_y, useHalfPixel);
                }

                if (x_axis && p.IsPartOfVerticalEdge && p.IsLeftSide)
                {
                    //horizontal fitting
                    //fix p_x to grid
                    float new_x = RoundToNearestHorizontalSide((float)p_x);
                    ////adjust right-side vertical edge
                    //PixelFarm.Agg.Typography.EdgeLine rightside = p.GetMatchingVerticalEdge();
                    //if (rightside != null && !rightside.IsLeftSide && rightside.IsOutside)
                    //{
                    //    var rightSideP = rightside.p.userData as GlyphPoint2D;
                    //    var rightSideQ = rightside.q.userData as GlyphPoint2D;
                    //    //find move diff
                    //    float movediff = (float)p_x - new_x;
                    //    //adjust right side edge
                    //    rightSideP.x = rightSideP.x + movediff;
                    //    rightSideQ.x = rightSideQ.x + movediff;
                    //}
                    p_x = new_x;
                }
                //
                tx.LineTo((float)p_x, (float)p_y);
                //
                prev_px = p_x;
                prev_py = p_y;
            }

            tx.LineTo((float)first_px, (float)first_py);
        }
예제 #16
0
        public static void Read(this IGlyphTranslator tx, GlyphPointF[] glyphPoints, ushort[] contourEndPoints, float scale = 1, float offsetX = 0, float offsetY = 0)
        {
            int startContour = 0;
            int cpoint_index = 0;//current point index

            int todoContourCount = contourEndPoints.Length;

            //-----------------------------------
            //1. start read data from a glyph
            tx.BeginRead(todoContourCount);
            //-----------------------------------
            float latest_moveto_x        = 0;
            float latest_moveto_y        = 0;
            int   curveControlPointCount = 0; // 1 curve control point => Quadratic, 2 curve control points => Cubic


            while (todoContourCount > 0)
            {
                //foreach contour...
                //next contour will begin at...
                int nextCntBeginAtIndex = contourEndPoints[startContour] + 1;

                //reset  ...

                bool    has_c_begin = false;         //see below [A]
                Vector2 c_begin     = new Vector2(); //special point if the glyph starts with 'off-curve' control point
                Vector2 c1          = new Vector2(); //control point of quadratic curve
                //-------------------------------------------------------------------
                bool offCurveMode        = false;
                bool isFirstOnCurvePoint = true; //first point of this contour

                //-------------------------------------------------------------------
                //[A]
                //first point may start with 'ON CURVE" or 'OFF-CURVE'
                //1. if first point is 'ON-CURVE' => we just set moveto command to it
                //
                //2. if first point is 'OFF-CURVE' => we store it into c_begin and set has_c_begin= true
                //   the c_begin will be use when we close the contour
                //
                //
                //eg. glyph '2' in Century font starts with 'OFF-CURVE' point, and ends with 'OFF-CURVE'
                //-------------------------------------------------------------------

                for (; cpoint_index < nextCntBeginAtIndex; ++cpoint_index)
                {    //for each point in this contour
                    GlyphPointF p   = glyphPoints[cpoint_index];
                    float       p_x = p.X * scale;
                    float       p_y = p.Y * -scale;
                    p_x += offsetX;
                    p_y += offsetY;

                    if (p.onCurve)
                    {
                        //-------------------------------------------------------------------
                        //[B]
                        //point p is an 'on-curve' point (on outline).
                        //(not curve control point)***
                        //the point touch the outline.

                        //possible ways..
                        //1. if we are in offCurveMode, then p is a curve end point.
                        //   we must decide which curve to create (Curve3 or Curve4)
                        //   easy, ...
                        //      if  curveControlPointCount == 1 , then create Curve3
                        //      else curveControlPointCount ==2 , then create Curve4 (BUT SHOULD NOT BE FOUND IN TRUE TYPEFONT'(
                        //2. if we are NOT in offCurveMode,
                        //      if p is first point then set this to =>moveto(x0,y0)
                        //      else then p is end point of a line => lineto(x1,y1)
                        //-------------------------------------------------------------------

                        if (offCurveMode)
                        {
                            //as describe above [B.1]
                            switch (curveControlPointCount)
                            {
                            case 1:
                                tx.Curve3(c1.X, c1.Y, p_x, p_y);
                                break;

                            default:
                                throw new NotSupportedException();
                            }

                            //reset curve control point count
                            curveControlPointCount = 0;
                            //we touch the curve, set offCurveMode= false
                            offCurveMode = false;
                        }
                        else
                        {
                            // p is ON CURVE, but now we are in OFF-CURVE mode.
                            //as describe above [B.2]
                            if (isFirstOnCurvePoint)
                            {
                                //special treament for first point
                                isFirstOnCurvePoint = false;
                                switch (curveControlPointCount)
                                {
                                case 0:
                                    //describe above, see [A.1]
                                    tx.MoveTo(latest_moveto_x = p_x, latest_moveto_y = p_y);
                                    break;

                                case 1:
                                    //describe above, see [A.2]
                                    c_begin     = c1;
                                    has_c_begin = true;
                                    //since c1 is off curve
                                    //we skip the c1 for and use it when we close the curve
                                    //tx.MoveTo(latest_moveto_x = c1.X, latest_moveto_y = c1.Y);
                                    //tx.LineTo(p_x, p_y);
                                    tx.MoveTo(latest_moveto_x = p_x, latest_moveto_y = p_y);
                                    curveControlPointCount--;
                                    break;

                                default:
                                    throw new NotSupportedException();
                                }
                            }
                            else
                            {
                                tx.LineTo(p_x, p_y);
                            }
                        }
                    }
                    else
                    {
                        //p is OFF-CURVE point (this is curve control point)
                        switch (curveControlPointCount)
                        {
                        case 0:
                            c1 = new Vector2(p_x, p_y);
                            if (!isFirstOnCurvePoint)
                            {
                                //this point is curve control point
                                //so set curve mode = true
                                //check number if existing curve control
                                offCurveMode = true;
                            }
                            else
                            {
                                //describe above, see [A.2]
                            }
                            break;

                        case 1:
                        {
                            //we already have previous 1st control point (c1)
                            //-------------------------------------
                            //please note that TrueType font
                            //compose of Quadractic Bezier Curve (Curve3)
                            //-------------------------------------
                            //in this case, this is NOT Cubic,
                            //this is 2 CONNECTED Quadractic Bezier Curves
                            //
                            //we must create 'end point' of the first curve
                            //and set it as 'begin point of the second curve.
                            //
                            //this is done by ...
                            //1. calculate mid point between c1 and the latest point (p_x,p_y)
                            Vector2 mid = GetMidPoint(c1, p_x, p_y);
                            //2. generate curve3 ***
                            tx.Curve3(c1.X, c1.Y, mid.X, mid.Y);
                            //3. so curve control point number is reduce by 1
                            curveControlPointCount--;
                            //4. and set (p_x,p_y) as 1st control point for the new curve
                            c1           = new Vector2(p_x, p_y);
                            offCurveMode = true;
                        }
                        break;

                        default:
                            throw new NotSupportedException();
                        }
                        //count
                        curveControlPointCount++;
                    }
                }
                //when finish, ensure that the contour is closed.
                if (offCurveMode)
                {
                    switch (curveControlPointCount)
                    {
                    case 0: break;

                    case 1:
                    {
                        if (has_c_begin)
                        {
                            Vector2 mid = GetMidPoint(c1, c_begin.X, c_begin.Y);
                            //2. generate curve3
                            tx.Curve3(c1.X, c1.Y, mid.X, mid.Y);
                            //3. so curve control point number is reduce by 1
                            curveControlPointCount--;
                            tx.Curve3(c_begin.X, c_begin.Y,
                                      latest_moveto_x, latest_moveto_y);
                        }
                        else
                        {
                            tx.Curve3(
                                c1.X, c1.Y,
                                latest_moveto_x, latest_moveto_y);
                        }
                    }
                    break;

                    default:
                    {
                        throw new NotSupportedException();
                    }
                    }
                    //reset
                    offCurveMode           = false;
                    curveControlPointCount = 0;
                }

                tx.CloseContour();
                startContour++;
                todoContourCount--;
            }
            //finish
            tx.EndRead();
        }
예제 #17
0
        public static void Read(this IGlyphTranslator tx, GlyphPointF[] glyphPoints, ushort[] contourEndPoints, float scale = 1)
        {
            int startContour = 0;
            int cpoint_index = 0;//current point index

            int todoContourCount = contourEndPoints.Length;

            //-----------------------------------
            //1. start read data from a glyph
            tx.BeginRead(todoContourCount);
            //-----------------------------------
            float latest_moveto_x = 0;
            float latest_moveto_y = 0;

            int curveControlPointCount = 0; // 1 curve control point => Quadratic, 2 curve control points => Cubic


            while (todoContourCount > 0)
            {
                //foreach contour...

                //next contour will begin at...
                int nextCntBeginAtIndex = contourEndPoints[startContour] + 1;

                //reset  ...
                Vector2 c1           = new Vector2();
                Vector2 c2           = new Vector2();
                bool    curveMode    = false;
                bool    isFirstPoint = true; //first point of this contour


                ///for each point in this contour
                for (; cpoint_index < nextCntBeginAtIndex; ++cpoint_index)
                {
                    GlyphPointF p   = glyphPoints[cpoint_index];
                    float       p_x = p.X * scale;
                    float       p_y = p.Y * scale;

                    //int vtag = (int)flags[cpoint_index] & 0x1;
                    //bool has_dropout = (((vtag >> 2) & 0x1) != 0);
                    //int dropoutMode = vtag >> 3;

                    if (p.onCurve)
                    {
                        //point p is an on-curve point (on outline). (not curve control point)
                        //possible ways..
                        //1. if we are in curve mode, then p is end point
                        //   we must decide which curve to create (Curve3 or Curve4)
                        //   easy, ...
                        //      if  curveControlPointCount == 1 , then create Curve3
                        //      else curveControlPointCount ==2 , then create Curve4
                        //2. if we are NOT in curve mode,
                        //      if p is first point then set this to x0,y0
                        //      else then p is end point of a line.


                        if (curveMode)
                        {
                            switch (curveControlPointCount)
                            {
                            case 1:
                            {
                                tx.Curve3(
                                    c1.X, c1.Y,
                                    p_x, p_y);
                            }
                            break;

                            case 2:
                            {
                                //for TrueType font
                                //we should not be here?

                                tx.Curve4(
                                    c1.X, c1.Y,
                                    c2.X, c2.Y,
                                    p_x, p_y);
                            }
                            break;

                            default:
                            {
                                throw new NotSupportedException();
                            }
                            }

                            //reset curve control point count
                            curveControlPointCount = 0;
                            //exist from curve mode
                            curveMode = false;
                        }
                        else
                        {
                            //as describe above,...

                            if (isFirstPoint)
                            {
                                isFirstPoint = false;
                                tx.MoveTo(latest_moveto_x = (p_x), latest_moveto_y = (p_y));
                            }
                            else
                            {
                                tx.LineTo(p_x, p_y);
                            }

                            //if (has_dropout)
                            //{
                            //    //printf("[%d] on,dropoutMode=%d: %d,y:%d \n", mm, dropoutMode, vpoint.x, vpoint.y);
                            //}
                            //else
                            //{
                            //    //printf("[%d] on,x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                            //}
                        }
                    }
                    else
                    {
                        //this point is curve control point***
                        //so set curve mode = true
                        curveMode = true;
                        //check number if existing curve control

                        switch (curveControlPointCount)
                        {
                        case 0:
                            c1 = new Vector2(p_x, p_y);
                            //this point may be part 1st control point of a curve,
                            //store it and wait for next point before make decision ***
                            break;

                        case 1:
                            //we already have previous 1st control point (c1)
                            //-------------------------------------
                            //please note that TrueType font
                            //compose of Quadractic Bezier Curve (Curve3) ***
                            //-------------------------------------
                            //in this case, this is NOT Cubic,
                            //this is 2 CONNECTED Quadractic Bezier Curves***
                            //
                            //we must create 'end point' of the first curve
                            //and set it as 'begin point of the second curve.
                            //
                            //this is done by ...
                            //1. calculate mid point between c1 and the latest point (p_x,p_y)
                            Vector2 mid = GetMid(c1, p_x, p_y);
                            //----------
                            //2. generate curve3 ***
                            tx.Curve3(
                                c1.X, c1.Y,
                                mid.X, mid.Y);
                            //------------------------
                            //3. so curve control point number is reduce by 1***
                            curveControlPointCount--;
                            //------------------------
                            //4. and set (p_x,p_y) as 1st control point for the new curve
                            c1 = new Vector2(p_x, p_y);
                            //
                            //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                            break;

                        default:
                            throw new NotSupportedException();
                        }
                        //count
                        curveControlPointCount++;
                    }
                }
                //--------
                //when finish,
                //ensure that the contour is closed.
                if (curveMode)
                {
                    switch (curveControlPointCount)
                    {
                    case 0: break;

                    case 1:
                    {
                        tx.Curve3(c1.X, c1.Y,
                                  latest_moveto_x, latest_moveto_y);
                    }
                    break;

                    case 2:
                    {
                        //for TrueType font
                        //we should not be here?
                        tx.Curve4(c1.X, c1.Y,
                                  c2.X, c2.Y,
                                  latest_moveto_x, latest_moveto_y);
                    }
                    break;

                    default:
                    { throw new NotSupportedException(); }
                    }
                    //reset
                    curveMode = false;
                    curveControlPointCount = 0;
                }
                //--------
                tx.CloseContour(); //***
                startContour++;
                todoContourCount--;
                //--------
            }
            //finish
            tx.EndRead();
        }
 //-----------
 //for CFF1
 public static void Read(this IGlyphTranslator tx, CFF.Cff1Font cff1Font, CFF.Cff1GlyphData glyphData, float scale = 1)
 {
     CFF.CffEvaluationEngine evalEngine = new CFF.CffEvaluationEngine();
     evalEngine.Run(tx, cff1Font, glyphData.GlyphInstructions, scale);
 }
예제 #19
0
 public void Reset()
 {
     _currentIndex    = 0;
     _currentX        = _currentY = 0;
     _glyphTranslator = null;
 }
예제 #20
0
 public void Run(IGlyphTranslator tx, Cff1Font cff1Font, Cff1GlyphData glyphData, float scale = 1)
 {
     Run(tx, cff1Font, glyphData.GlyphInstructions, scale);
 }
예제 #21
0
 /// <summary>
 /// build and translate
 /// </summary>
 /// <param name="builder"></param>
 /// <param name="glyphIndex"></param>
 /// <param name="sizeInPoints"></param>
 /// <param name="tx"></param>
 public static void BuildFromGlyphIndex(this GlyphOutlineBuilderBase builder, ushort glyphIndex, float sizeInPoints, IGlyphTranslator tx)
 {
     builder.BuildFromGlyphIndex(glyphIndex, sizeInPoints);
     builder.ReadShapes(tx);
 }