示例#1
0
        public static void MeasureString(
            this GlyphLayout glyphLayout,
            char[] textBuffer,
            int startAt,
            int len, out MeasuredStringBox strBox, float scale = 1)
        {
            //TODO: consider extension method
            List <GlyphPlan> outputGlyphPlans = glyphLayout._myGlyphPlans;

            outputGlyphPlans.Clear();
            glyphLayout.Layout(textBuffer, startAt, len, outputGlyphPlans);
            //
            int j = outputGlyphPlans.Count;

            Typeface currentTypeface = glyphLayout.Typeface;

            if (j == 0)
            {
                //not scale
                strBox = new MeasuredStringBox(0,
                                               currentTypeface.Ascender * scale,
                                               currentTypeface.Descender * scale,
                                               currentTypeface.LineGap * scale);
            }
            //get last one
            GlyphPlan lastOne = outputGlyphPlans[j - 1];

            strBox = new MeasuredStringBox((lastOne.x + lastOne.advX) * scale,
                                           currentTypeface.Ascender * scale,
                                           currentTypeface.Descender * scale,
                                           currentTypeface.LineGap * scale);
        }
示例#2
0
        public void DoLeft()
        {
            int count = _charBuffer.Count;

            if (count == 0)
            {
                _caretCharIndex = 0;
                return;
            }
            else if (_caretCharIndex > 0)
            {
                //this is on the end
                _caretCharIndex--;

                //check if the caret can rest on this glyph?
                if (_caretCharIndex > 0)
                {
                    //find its mapping to glyph index
                    UserCharToGlyphIndexMap userCharToGlyphMap = _userCharToGlyphMap[_caretCharIndex];
                    int mapToGlyphIndex = userCharToGlyphMap.glyphIndexListOffset_plus1;
                    //
                    if (mapToGlyphIndex == 0)
                    {
                        //no map
                        DoLeft();   //recursive ***
                        return;
                    }
                    //-------------------------
                    //we -1 ***
                    GlyphPlan glyphPlan = _glyphPlans[userCharToGlyphMap.glyphIndexListOffset_plus1 - 1];
                    if (!glyphPlan.AdvanceMoveForward)
                    {
                        //caret can't rest here
                        //so
                        DoLeft();   //recursive ***
                        return;
                    }
                    //---------------------
                    //
                }
            }
            else
            {
            }
        }
示例#3
0
 public void Append(GlyphPlan glyphPlan)
 {
     _glyphPlans.Add(glyphPlan);
     _accumAdvanceX += glyphPlan.AdvanceX;
 }
示例#4
0
        List <ushort> inputGlyphs = new List <ushort>(); //not thread safe***



        public void Layout(Typeface typeface, float size, char[] str, List <GlyphPlan> glyphPlanBuffer)
        {
            //----------------------------------------------
            //1. convert char[] to glyph[]
            //2. send to shaping engine
            //3. layout position of each glyph
            //----------------------------------------------
            //check if we have created a glyph cache for the typeface
            GlyphsCache glyphCache;

            if (!_glyphCaches.TryGetValue(typeface, out glyphCache))
            {
                //create new
                glyphCache = new GlyphsCache(typeface);
                _glyphCaches.Add(typeface, glyphCache);
            }

            //----------------------------------------------
            int j = str.Length;

            inputGlyphs.Clear();
            for (int i = 0; i < j; ++i)
            {
                //1. convert char[] to glyphIndex[]
                inputGlyphs.Add((ushort)typeface.LookupIndex(str[i]));
            }
            //----------------------------------------------
            //glyph substitution
            if (j > 1)
            {
                GlyphSubStitution glyphSubstitution = new GlyphSubStitution(typeface, this.ScriptLang.shortname);
                glyphSubstitution.EnableLigation = this.EnableLigature;
                glyphSubstitution.DoSubstitution(inputGlyphs);
            }
            //----------------------------------------------
            //glyph position
            j = inputGlyphs.Count;
            List <GlyphPos> glyphPositions = new List <GlyphPos>(j);

            for (int i = 0; i < j; ++i)
            {
                ushort glyIndex = inputGlyphs[i];
                glyphPositions.Add(new GlyphPos(
                                       glyIndex,
                                       typeface.GetGlyphByIndex(glyIndex).GlyphClass,
                                       typeface.GetHAdvanceWidthFromGlyphIndex(glyIndex))
                                   );
            }

            PositionTecnhique posTech = this.PositionTechnique;

            if (j > 1 && posTech == PositionTecnhique.OpenFont)
            {
                GlyphSetPosition glyphSetPos = new GlyphSetPosition(typeface, ScriptLang.shortname);
                glyphSetPos.DoGlyphPosition(glyphPositions);
            }
            //--------------
            float scale = typeface.CalculateFromPointToPixelScale(size);
            float cx    = 0;
            float cy    = 0;

            j = inputGlyphs.Count;

            for (int i = 0; i < j; ++i)
            {
                ushort glyIndex = inputGlyphs[i];

                GlyphPlan glyphPlan = new GlyphPlan(glyIndex);
                glyphPlanBuffer.Add(glyphPlan);
                //this advWidth in font design unit


                float advWidth = typeface.GetHAdvanceWidthFromGlyphIndex(glyIndex) * scale;
                //----------------------------------

                switch (posTech)
                {
                case PositionTecnhique.None:
                {
                    glyphPlan.x    = cx;
                    glyphPlan.y    = cy;
                    glyphPlan.advX = advWidth;
                }
                break;

                case PositionTecnhique.OpenFont:
                {
                    GlyphPos gpos_offset = glyphPositions[i];
                    glyphPlan.x    = cx + (scale * gpos_offset.xoffset);
                    glyphPlan.y    = cy + (scale * gpos_offset.yoffset);
                    glyphPlan.advX = advWidth;
                }
                break;

                case PositionTecnhique.Kerning:
                {
                    glyphPlan.x    = cx;
                    glyphPlan.y    = cy;
                    glyphPlan.advX = advWidth;
                    if (i > 0)
                    {
                        advWidth += typeface.GetKernDistance(glyphPlanBuffer[i - 1].glyphIndex, glyphPlanBuffer[i].glyphIndex) * scale;
                    }
                }
                break;
                }
                cx += advWidth;
            }
        }