public void SetData(float pxscale, GlyphControlParameters controlPars, short offsetX, short offsetY, ushort orgAdvW)
            {
#if DEBUG
                dbugIsPrev = false;
#endif
                s_avg_x_ToFit = controlPars.avgXOffsetToFit;


                float o_a = controlPars.minX;
                float o_c = (short)(orgAdvW - controlPars.maxX);
                if (o_c < 0)
                {
                    //TODO: review here ...
                    //?
                    //o_c = 0;
                }
                //-----------------
                //calculate...
                s_offsetX = pxscale * offsetX;
                s_offsetY = pxscale * offsetY;
                s_advW    = pxscale * orgAdvW;
                s_xmin    = pxscale * controlPars.minX;
                s_xmax    = pxscale * controlPars.maxX;
                s_a       = pxscale * o_a;
                s_c       = pxscale * o_c;

                final_advW = ((s_advW - (int)s_advW) > 0.5) ?
                             (int)(s_advW + 1) :    //round
                             (int)(s_advW);

                //
                m_c = final_advW - (s_xmax + s_avg_x_ToFit);
                m_a = s_avg_x_ToFit + s_xmin;

                if (m_a < 0.5f)
                {
                    m_a_adjust = 1;
                }
                else
                {
                    m_a_adjust = 0;
                }

                if (final_advW - m_c > 1f)
                {
                    m_c_adjust = -1;
                }
                else
                {
                    m_c = 0;
                }


                m_max = s_xmax + s_avg_x_ToFit;
            }
            public GlyphControlParameters GetControlPars()
            {
                var pars = new GlyphControlParameters();

                pars.minX            = orgBounds.XMin;
                pars.minY            = orgBounds.YMin;
                pars.maxX            = orgBounds.XMax;
                pars.maxY            = orgBounds.YMax;
                pars.avgXOffsetToFit = avgXOffsetToFit;
                return(pars);
            }
        public void Layout(IGlyphPositions posStream, PxScaledGlyphPlanList outputGlyphPlanList)
        {
            float pxscale = _typeface.CalculateScaleToPixelFromPointSize(this._fontSizeInPoints);

            if (!UseWithLcdSubPixelRenderingTechnique)
            {
                //layout without fit to alignment direction
                GlyphLayoutExtensions.GenerateGlyphPlans(posStream, pxscale, false, outputGlyphPlanList);
                return; //early exit
            }
            //------------------------------
            int finalGlyphCount = posStream.Count;

#if DEBUG
            float dbug_onepx = 1 / pxscale;
#endif
            //
            int   cx = 0;
            short cy = 0;
            //
            //at this state, we need exact info at this specific pxscale
            //
            _glyphMeshStore.SetFont(_typeface, this._fontSizeInPoints);
            FineABC current_ABC = new FineABC();
            FineABC prev_ABC    = new FineABC();

            for (int i = 0; i < finalGlyphCount; ++i)
            {
                short  input_offset, offsetX, offsetY, advW; //all from pen-pos
                ushort glyphIndex = posStream.GetGlyph(i, out input_offset, out offsetX, out offsetY, out advW);
                GlyphControlParameters controlPars = _glyphMeshStore.GetControlPars(glyphIndex);
                current_ABC.SetData(pxscale, controlPars, offsetX, offsetY, (ushort)advW);
                //-------------------------------------------------------------

                if (i > 0)
                {
                    //inter-glyph space
                    //ideal space
                    float ideal_space = prev_ABC.s_c + current_ABC.s_a;
                    //actual space
                    float actual_space = prev_ABC.m_c + current_ABC.m_a;

                    if (ideal_space < 0)
                    {
                        //f-f
                        //f-o
                        if (prev_ABC.s_c < 0)
                        {
                            ideal_space = 0 + current_ABC.s_a;
                        }
                        if (ideal_space < 0)
                        {
                            ideal_space = 0;
                        }
                    }
                    if (ideal_space >= 0)
                    {
                        //m-a
                        //i-i
                        //o-p
                        if (actual_space > 1.5 && actual_space - 0.5 > ideal_space)
                        {
                            cx--;
                        }
                        else
                        {
                            if (actual_space < ideal_space)
                            {
                                if (prev_ABC.final_advW + prev_ABC.m_c_adjust < prev_ABC.m_max)
                                {
                                    cx += current_ABC.m_a_adjust;
                                }
                            }
                            else
                            {
                                if (prev_ABC.final_advW - prev_ABC.m_c + prev_ABC.m_c_adjust > prev_ABC.m_max)
                                {
                                    cx += prev_ABC.m_c_adjust;
                                }
                            }
                        }
                    }
                    else
                    {
                        //this should not occur?
                    }
                }
                //-------------------------------------------------------------

                //TODO: review here again***


                float exact_x = (float)(cx + current_ABC.s_offsetX);
                float exact_y = (float)(cy + current_ABC.s_offsetY);

                //check if the current position can create a sharp glyph
                int   exact_x_floor   = (int)exact_x;
                float x_offset_to_fit = current_ABC.s_avg_x_ToFit;

                float final_x = exact_x_floor + x_offset_to_fit;
                if (UseWithLcdSubPixelRenderingTechnique)
                {
                    final_x += 0.33f;
                }

                outputGlyphPlanList.Append(new PxScaledGlyphPlan(
                                               input_offset,
                                               glyphIndex,
                                               (short)current_ABC.final_advW,
                                               (short)Math.Round(current_ABC.s_offsetX),
                                               (short)Math.Round(current_ABC.s_offsetY)
                                               ));
                //
                //
                cx += current_ABC.final_advW;
                //-----------------------------------------------
                prev_ABC = current_ABC;//copy current to prev
#if DEBUG
                prev_ABC.dbugIsPrev = true;
#endif
                // Console.WriteLine(exact_x + "+" + (x_offset_to_fit) + "=>" + final_x);
            }
        }