public void GetOffset(int index, out short offsetX, out short offsetY)
        {
            GlyphPos pos = _glyphPosList[index];

            offsetX = pos.xoffset;
            offsetY = pos.yoffset;
        }
        public void AppendGlyphAdvance(int index, short appendAdvX, short appendAdvY)
        {
            GlyphPos pos = _glyphPosList[index];

            pos.advanceW        += appendAdvX;//TODO: review for appendY
            _glyphPosList[index] = pos;
        }
        public ushort GetGlyph(int index, out ushort advW)
        {
            GlyphPos pos = _glyphPosList[index];

            advW = (ushort)pos.advanceW;
            return(pos.glyphIndex);
        }
        public void AppendGlyphOffset(int index, short appendOffsetX, short appendOffsetY)
        {
            GlyphPos existing = _glyphPosList[index];

            existing.xoffset    += appendOffsetX;
            existing.yoffset    += appendOffsetY;
            _glyphPosList[index] = existing;
        }
        public ushort GetGlyph(int index, out short offsetX, out short offsetY, out short advW)
        {
            GlyphPos pos = _glyphs[index];

            offsetX = pos.xoffset;
            offsetY = pos.yoffset;
            advW    = pos.advanceW;
            return(pos.glyphIndex);
        }
        public ushort GetGlyph(int index, out short inputOffset, out short offsetX, out short offsetY, out short advW)
        {
            GlyphPos pos = _glyphPosList[index];

            offsetX     = pos.xoffset;
            offsetY     = pos.yoffset;
            advW        = pos.advanceW;
            inputOffset = pos.o_offset;
            return(pos.glyphIndex);
        }
Exemple #7
0
        /// <summary>
        /// read latest layout output
        /// </summary>
        /// <param name="glyphLayout"></param>
        /// <param name="readDel"></param>
        public static void ReadOutput(this GlyphLayout glyphLayout, GlyphReadOutputDelegate readDel)
        {
            Typeface        typeface       = glyphLayout.Typeface;
            List <GlyphPos> glyphPositions = glyphLayout._glyphPositions;
            //3.read back
            int   finalGlyphCount = glyphPositions.Count;
            int   cx = 0;
            short cy = 0;

            PositionTechnique posTech    = glyphLayout.PositionTechnique;
            ushort            prev_index = 0;

            for (int i = 0; i < finalGlyphCount; ++i)
            {
                GlyphPos glyphPos = glyphPositions[i];
                //----------------------------------
                switch (posTech)
                {
                default: throw new NotSupportedException();

                case PositionTechnique.None:
                    readDel(i, new GlyphPlan(glyphPos.glyphIndex, cx, cy, glyphPos.advWidth));
                    break;

                case PositionTechnique.OpenFont:
                    readDel(i, new GlyphPlan(
                                glyphPos.glyphIndex,
                                cx + glyphPos.xoffset,
                                (short)(cy + glyphPos.yoffset),
                                glyphPos.advWidth));
                    break;

                case PositionTechnique.Kerning:

                    if (i > 0)
                    {
                        cx += typeface.GetKernDistance(prev_index, glyphPos.glyphIndex);
                    }
                    readDel(i, new GlyphPlan(
                                prev_index = glyphPos.glyphIndex,
                                cx,
                                cy,
                                glyphPos.advWidth));

                    break;
                }
                cx += glyphPos.advWidth;
            }
        }
        /// <summary>
        /// read latest layout output into outputGlyphPlanList
        /// </summary>
        public static void ReadOutput(this GlyphLayout glyphLayout, List <GlyphPlan> outputGlyphPlanList)
        {
            GlyphPosStream glyphPositions  = glyphLayout._glyphPositions; //from opentype's layout result,
            int            finalGlyphCount = glyphPositions.Count;
            //------------------------
            IPixelScaleLayout pxscaleLayout = glyphLayout.PxScaleLayout;

            if (pxscaleLayout != null)
            {
                //use custom pixel scale layout engine

                pxscaleLayout.SetFont(glyphLayout.Typeface, glyphLayout.FontSizeInPoints);
                pxscaleLayout.Layout(glyphPositions, outputGlyphPlanList);
            }
            else
            {
                //default scale
                float  pxscale = glyphLayout.PixelScale;
                double cx      = 0;
                short  cy      = 0;
                for (int i = 0; i < finalGlyphCount; ++i)
                {
                    GlyphPos glyph_pos = glyphPositions[i];
                    float    advW      = glyph_pos.advanceW * pxscale;
                    float    exact_x   = (float)(cx + glyph_pos.OffsetX * pxscale);
                    float    exact_y   = (float)(cy + glyph_pos.OffsetY * pxscale);

                    outputGlyphPlanList.Add(new GlyphPlan(
                                                glyph_pos.glyphIndex,
                                                exact_x,
                                                exact_y,
                                                advW));
                    cx += advW;
                }
            }
        }
Exemple #9
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;
            }
        }