Exemple #1
0
        static float MeasureGlyphPlans(this GlyphLayout glyphLayout,
                                       float pxscale,
                                       bool snapToGrid)
        {
            //user can implement this with some 'PixelScaleEngine'
            IGlyphPositions glyphPositions = glyphLayout.ResultUnscaledGlyphPositions;
            float           accumW         = 0; //acummulate Width

            if (snapToGrid)
            {
                int finalGlyphCount = glyphPositions.Count;
                for (int i = 0; i < finalGlyphCount; ++i)
                {
                    //all from pen-pos
                    ushort glyphIndex = glyphPositions.GetGlyph(i,
                                                                out ushort input_offset,
                                                                out short offsetX,
                                                                out short offsetY,
                                                                out short advW);
                    accumW += (short)Math.Round(advW * pxscale);
                }
            }
            else
            {
                //not snap to grid
                //scaled but not snap to grid
                int finalGlyphCount = glyphPositions.Count;
                for (int i = 0; i < finalGlyphCount; ++i)
                {
                    //all from pen-pos
                    ushort glyphIndex = glyphPositions.GetGlyph(i,
                                                                out ushort input_offset,
                                                                out short offsetX,
                                                                out short offsetY,
                                                                out short advW);
                    accumW += advW * pxscale;
                }
            }
            return(accumW);
        }
Exemple #2
0
        //static void ConcatMeasureBox(ref float accumW, ref float accumH, ref MeasuredStringBox measureBox)
        //{
        //    accumW += measureBox.width;
        //    float h = measureBox.CalculateLineHeight();
        //    if (h > accumH)
        //    {
        //        accumH = h;
        //    }
        //}



        public static MeasuredStringBox LayoutAndMeasureString(
            this GlyphLayout glyphLayout,
            char[] textBuffer,
            int startAt,
            int len,
            float fontSizeInPoints,
            float limitW    = -1,//-1 unlimit scaled width (px)
            bool snapToGrid = true)
        {
            //1. unscale layout, in design unit
            glyphLayout.Layout(textBuffer, startAt, len);

            //2. scale  to specific font size

            Typeface typeface = glyphLayout.Typeface;
            float    pxscale  = typeface.CalculateScaleToPixelFromPointSize(fontSizeInPoints);

            //....
            float scaled_accumX = 0;

            if (limitW < 0)
            {
                //no limit
                scaled_accumX = MeasureGlyphPlans(
                    glyphLayout,
                    pxscale,
                    snapToGrid);

                return(new MeasuredStringBox(
                           scaled_accumX,
                           typeface.Ascender,
                           typeface.Descender,
                           typeface.LineGap,
                           typeface.ClipedAscender,
                           typeface.ClipedDescender,
                           pxscale));
            }
            else if (limitW > 0)
            {
                scaled_accumX = MeasureGlyphPlanWithLimitWidth(
                    glyphLayout,
                    pxscale,
                    limitW,
                    snapToGrid,
                    out int stopAtChar);

                var mstrbox = new MeasuredStringBox(
                    scaled_accumX,
                    typeface.Ascender,
                    typeface.Descender,
                    typeface.LineGap,
                    typeface.ClipedAscender,
                    typeface.ClipedDescender,
                    pxscale);

                mstrbox.StopAt = (ushort)stopAtChar;
                return(mstrbox);
            }
            else
            {
                return(new MeasuredStringBox(
                           0,
                           typeface.Ascender,
                           typeface.Descender,
                           typeface.LineGap,
                           typeface.ClipedAscender,
                           typeface.ClipedDescender,
                           pxscale));
            }
        }
Exemple #3
0
        static float MeasureGlyphPlanWithLimitWidth(this GlyphLayout glyphLayout,
                                                    float pxscale,
                                                    float limitWidth,
                                                    bool snapToGrid,
                                                    out int stopAtGlyphIndex)
        {
            //user can implement this with some 'PixelScaleEngine'
            IGlyphPositions glyphPositions = glyphLayout.ResultUnscaledGlyphPositions;
            float           accumW         = 0; //acummulate Width

            stopAtGlyphIndex = 0;

            if (snapToGrid)
            {
                int finalGlyphCount = glyphPositions.Count;
                for (int i = 0; i < finalGlyphCount; ++i)
                {
                    //all from pen-pos
                    ushort glyphIndex = glyphPositions.GetGlyph(i,
                                                                out ushort input_offset,
                                                                out short offsetX,
                                                                out short offsetY,
                                                                out short advW);

                    stopAtGlyphIndex = i; //***
                    //
                    short w = (short)Math.Round(advW * pxscale);
                    if (accumW + w > limitWidth)
                    {
                        //stop
                        break;
                    }
                    else
                    {
                        accumW += w;
                    }
                }
            }
            else
            {
                //not snap to grid
                //scaled but not snap to grid
                int finalGlyphCount = glyphPositions.Count;
                for (int i = 0; i < finalGlyphCount; ++i)
                {
                    //all from pen-pos
                    ushort glyphIndex = glyphPositions.GetGlyph(i,
                                                                out ushort input_offset,
                                                                out short offsetX,
                                                                out short offsetY,
                                                                out short advW);


                    stopAtGlyphIndex = i; //***

                    float w = advW * pxscale;
                    if (accumW + w > limitWidth)
                    {
                        //stop
                        break;
                    }
                    else
                    {
                        accumW += w;
                    }
                }
            }
            return(accumW);


            ////measure string
            //if (str.Length < 1)
            //{
            //    charFitWidth = 0;
            //}

            //_reusableMeasureBoxList.Clear(); //reset


            //float pxscale = _currentTypeface.CalculateScaleToPixelFromPointSize(_fontSizeInPts);
            ////NOET:at this moment, simple operation
            ////may not be simple...
            ////-------------------
            ////input string may contain more than 1 script lang
            ////user can parse it by other parser
            ////but in this code, we use our Typography' parser
            ////-------------------
            ////user must setup the CustomBreakerBuilder before use

            //int cur_startAt = startAt;
            //float accumW = 0;

            //float acc_x = 0;//accum_x
            //float acc_y = 0;//accum_y
            //float g_x = 0;
            //float g_y = 0;
            //float x = 0;
            //float y = 0;
            //foreach (Typography.TextLayout.BreakSpan breakSpan in BreakToLineSegments(str, startAt, len))
            //{

            //    //measure string at specific px scale
            //    _glyphLayout.Layout(str, breakSpan.startAt, breakSpan.len);
            //    //

            //    _reusableGlyphPlanList.Clear();
            //    _glyphLayout.GenerateUnscaledGlyphPlans(_reusableGlyphPlanList);
            //    //measure ...


            //    //measure each glyph
            //    //limit at specific width
            //    int glyphCount = _reusableGlyphPlanList.Count;



            //    for (int i = 0; i < glyphCount; ++i)
            //    {
            //        UnscaledGlyphPlan glyphPlan = _reusableGlyphPlanList[i];

            //        float ngx = acc_x + (float)Math.Round(glyphPlan.OffsetX * pxscale);
            //        float ngy = acc_y + (float)Math.Round(glyphPlan.OffsetY * pxscale);
            //        //NOTE:
            //        // -glyphData.TextureXOffset => restore to original pos
            //        // -glyphData.TextureYOffset => restore to original pos
            //        //--------------------------
            //        g_x = (float)(x + (ngx)); //ideal x
            //        g_y = (float)(y + (ngy));
            //        float g_w = (float)Math.Round(glyphPlan.AdvanceX * pxscale);
            //        acc_x += g_w;
            //        //g_x = (float)Math.Round(g_x);
            //        g_y = (float)Math.Floor(g_y);

            //        float right = g_x + g_w;

            //        if (right >= accumW)
            //        {
            //            //stop here at this glyph
            //            charFit = i - 1;
            //            //TODO: review this
            //            charFitWidth = (int)System.Math.Round(accumW);
            //            return;
            //        }
            //        else
            //        {
            //            accumW = right;
            //        }
            //    }
            //}

            //charFit = 0;
            //charFitWidth = 0;
        }