示例#1
0
        private void button2_Click(object sender, EventArgs e)
        {
            //test text service
            if (_textService == null)
            {
                _textService = new TextServiceHub();
            }

            Typography.TextServices.TextShapingService shapingService = _textService.ShapingService;
            shapingService.SetCurrentFont(_basicOptions.Typeface.Name, InstalledFontStyle.Normal, 8);
            shapingService.SetCurrentScriptLang(Typography.OpenFont.ScriptLangs.Latin);
            GlyphPlanSequence seq = shapingService.LayoutText("Hello");


            //----
            // test render the output
            selectedTextPrinter                   = _devVxsTextPrinter;
            selectedTextPrinter.Typeface          = _basicOptions.Typeface;
            selectedTextPrinter.FontSizeInPoints  = _basicOptions.FontSizeInPoints;
            selectedTextPrinter.ScriptLang        = _basicOptions.ScriptLang;
            selectedTextPrinter.PositionTechnique = _basicOptions.PositionTech;
            selectedTextPrinter.HintTechnique     = HintTechnique.None;
            selectedTextPrinter.EnableLigature    = true;
            _devVxsTextPrinter.UpdateGlyphLayoutSettings();

            //-------------
            //pre-render
            painter.Clear(PixelFarm.Drawing.Color.White);
            painter.UseSubPixelRendering           = false;
            painter.FillColor                      = PixelFarm.Drawing.Color.Black;
            _devVxsTextPrinter.TargetCanvasPainter = painter; //*** essential ***

            //render!,
            float x = 20, y = 200;

            _devVxsTextPrinter.DrawFromGlyphPlans(
                GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(seq),
                seq.startAt,
                seq.len,
                x, y);
            //----------
            //use this util to copy image from Agg actual image to System.Drawing.Bitmap
            PixelFarm.Agg.Imaging.BitmapHelper.CopyToGdiPlusBitmapSameSize(painter.Graphics.DestActualImage, winBmp);
            //----------------
            //copy from Agg's memory buffer to gdi
            //PixelFarm.Agg.Imaging.BitmapHelper.CopyToGdiPlusBitmapSameSize(destImg, winBmp);
            g.Clear(Color.White);
            g.DrawImage(winBmp, new Point(10, 0));
        }
示例#2
0
        public void CalculateUserCharGlyphAdvancePos(ref TextBufferSpan textBufferSpan,
                                                     ILineSegmentList lineSegs, RequestFont font,
                                                     int[] outputUserInputCharAdvance, out int outputTotalW, out int lineHeight)
        {
            //layout
            //from font
            //resolve for typeface
            //
            Typeface typeface = ResolveTypeface(font);

            _typographyTxtServices.SetCurrentFont(typeface, font.SizeInPoints);


            MyLineSegmentList mylineSegs = (MyLineSegmentList)lineSegs;
            float             scale      = typeface.CalculateScaleToPixelFromPointSize(font.SizeInPoints);

            outputTotalW = 0;
            int j   = mylineSegs.Count;
            int pos = 0; //start at 0

            _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer());

            for (int i = 0; i < j; ++i)
            {
                //userGlyphPlanList.Clear();
                //userCharToGlyphMapList.Clear();
                //get each segment
                MyLineSegment lineSeg = mylineSegs.GetSegment(i);
                //each line seg may has different script lang
                _typographyTxtServices.CurrentScriptLang = lineSeg.scriptLang;
                //
                //CACHING ...., reduce number of GSUB/GPOS
                //
                //we cache used line segment for a while
                //we ask for caching context for a specific typeface and font size
                GlyphPlanSequence seq = _typographyTxtServices.GetUnscaledGlyphPlanSequence(_reusableTextBuffer,
                                                                                            lineSeg.StartAt,
                                                                                            lineSeg.Length);

                GlyphPlanList planList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(seq);
                //IMPORTANT
                //num of glyph may more or less than original user input char buffer
                //


                int endAt       = seq.startAt + seq.len;
                int seq_startAt = seq.startAt;

                for (int s = seq_startAt; s < endAt; ++s)
                {
                    GlyphPlan glyphPlan  = planList[s];
                    float     tx         = glyphPlan.ExactX;
                    float     ty         = glyphPlan.ExactY;
                    double    actualAdvX = glyphPlan.AdvanceX;

                    outputTotalW +=
                        outputUserInputCharAdvance[pos + glyphPlan.input_cp_offset] +=
                            (int)Math.Round(actualAdvX * scale);
                }
                pos += lineSeg.Length;
            }

            //

            lineHeight = (int)Math.Round(typeface.CalculateRecommendLineSpacing() * scale);

            _reusableTextBuffer.SetRawCharBuffer(null);
        }
        public void PrepareStringForRenderVx(RenderVxFormattedString renderVx, char[] buffer, int startAt, int len)
        {
            int j = buffer.Length;

            //create temp buffer span that describe the part of a whole char buffer
            TextBufferSpan textBufferSpan = new TextBufferSpan(buffer, startAt, len);

            //ask text service to parse user input char buffer and create a glyph-plan-sequence (list of glyph-plan)
            //with specific request font
            GlyphPlanSequence glyphPlanSeq = _textServices.CreateGlyphPlanSeq(ref textBufferSpan, font);

            float scale = _fontAtlas.TargetTextureScale;
            int   recommendLineSpacing = _fontAtlas.OriginalRecommendLineSpacing;

            //--------------------------
            //TODO:
            //if (x,y) is left top
            //we need to adjust y again
            float x = 0;
            float y = 0;

            y -= ((recommendLineSpacing) * scale);
            renderVx.RecommmendLineSpacing = (int)(recommendLineSpacing * scale);

            //
            float       scaleFromTexture = _finalTextureScale;
            TextureKind textureKind      = _fontAtlas.TextureKind;

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

            //TODO: review render steps
            //NOTE:
            // -glyphData.TextureXOffset => restore to original pos
            // -glyphData.TextureYOffset => restore to original pos
            // ideal_x = (float)(x + (glyph.x * scale - glyphData.TextureXOffset) * scaleFromTexture);
            // ideal_y = (float)(y + (glyph.y * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture);
            //--------------------------

            float g_x       = 0;
            float g_y       = 0;
            int   baseY     = (int)Math.Round(y);
            int   n         = glyphPlanSeq.len;
            int   endBefore = glyphPlanSeq.startAt + n;

            //***
            _glsx.SetAssociatedTextureInfo(_glBmp);
            //
            vboBufferList2.Clear();
            indexList2.Clear();

            float acc_x = 0;
            float acc_y = 0;

            for (int i = glyphPlanSeq.startAt; i < endBefore; ++i)
            {
                UnscaledGlyphPlanList glyphPlanList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(glyphPlanSeq);
                UnscaledGlyphPlan     glyph         = glyphPlanList[i];

                Typography.Rendering.TextureFontGlyphData glyphData;
                if (!_fontAtlas.TryGetGlyphDataByGlyphIndex(glyph.glyphIndex, out glyphData))
                {
                    //if no glyph data, we should render a missing glyph ***
                    continue;
                }

                //--------------------------------------
                //TODO: review precise height in float
                //--------------------------------------
                PixelFarm.Drawing.Rectangle srcRect = ConvToRect(glyphData.Rect);

                float ngx = acc_x + (float)Math.Round(glyph.OffsetX * scale);
                float ngy = acc_y + (float)Math.Round(glyph.OffsetY * scale);

                //NOTE:
                // -glyphData.TextureXOffset => restore to original pos
                // -glyphData.TextureYOffset => restore to original pos
                //--------------------------
                g_x = (float)(x + (ngx - glyphData.TextureXOffset) * scaleFromTexture); //ideal x
                g_y = (float)(y + (ngy - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture);


                acc_x += (float)Math.Round(glyph.AdvanceX * scale);

                //g_x = (float)Math.Round(g_x);
                g_y = (float)Math.Floor(g_y);



                switch (textureKind)
                {
                case TextureKind.Msdf:

                    _glsx.DrawSubImageWithMsdf(_glBmp,
                                               ref srcRect,
                                               g_x,
                                               g_y,
                                               scaleFromTexture);

                    break;

                case TextureKind.StencilGreyScale:

                    //stencil gray scale with fill-color
                    _glsx.DrawGlyphImageWithStecil(_glBmp,
                                                   ref srcRect,
                                                   g_x,
                                                   g_y,
                                                   scaleFromTexture);

                    break;

                case TextureKind.Bitmap:
                    _glsx.DrawSubImage(_glBmp,
                                       ref srcRect,
                                       g_x,
                                       g_y,
                                       scaleFromTexture);
                    break;

                case TextureKind.StencilLcdEffect:
                    _glsx.WriteVboToList(
                        vboBufferList2,
                        indexList2,
                        ref srcRect,
                        g_x,
                        g_y,
                        scaleFromTexture);
                    break;
                }
            }
            //---------

            DrawingGL.GLRenderVxFormattedString renderVxFormattedString = (DrawingGL.GLRenderVxFormattedString)renderVx;
            renderVxFormattedString.IndexArray   = indexList2.ToArray();
            renderVxFormattedString.VertexCoords = vboBufferList2.ToArray();
            renderVxFormattedString.VertexCount  = indexList2.Count;
        }
        public void DrawString(char[] buffer, int startAt, int len, double x, double y)
        {
            _glsx.FontFillColor = painter.FontFillColor;

            int j = buffer.Length;

            //create temp buffer span that describe the part of a whole char buffer
            TextBufferSpan textBufferSpan = new TextBufferSpan(buffer, startAt, len);

            //ask text service to parse user input char buffer and create a glyph-plan-sequence (list of glyph-plan)
            //with specific request font
            GlyphPlanSequence glyphPlanSeq = _textServices.CreateGlyphPlanSeq(ref textBufferSpan, font);

            float scale = _fontAtlas.TargetTextureScale;
            int   recommendLineSpacing = _fontAtlas.OriginalRecommendLineSpacing;

            //--------------------------
            //TODO:
            //if (x,y) is left top
            //we need to adjust y again
            y -= ((_fontAtlas.OriginalRecommendLineSpacing) * scale);

            EnsureLoadGLBmp();
            //
            float       scaleFromTexture = _finalTextureScale;
            TextureKind textureKind      = _fontAtlas.TextureKind;

            float g_x       = 0;
            float g_y       = 0;
            int   baseY     = (int)Math.Round(y);
            int   n         = glyphPlanSeq.len;
            int   endBefore = glyphPlanSeq.startAt + n;

            //-------------------------------------
            _glsx.LoadTexture1(_glBmp);
            //-------------------------------------

            _vboBufferList.Clear(); //clear before use
            _indexList.Clear();     //clear before use


            float acc_x = 0;
            float acc_y = 0;

            for (int i = glyphPlanSeq.startAt; i < endBefore; ++i)
            {
                UnscaledGlyphPlanList glyphPlanList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(glyphPlanSeq);
                UnscaledGlyphPlan     glyph         = glyphPlanList[i];

                Typography.Rendering.TextureFontGlyphData glyphData;
                if (!_fontAtlas.TryGetGlyphDataByGlyphIndex(glyph.glyphIndex, out glyphData))
                {
                    //if no glyph data, we should render a missing glyph ***
                    continue;
                }
                //--------------------------------------
                //TODO: review precise height in float
                //--------------------------------------
                PixelFarm.Drawing.Rectangle srcRect = ConvToRect(glyphData.Rect);


                float ngx = acc_x + (float)Math.Round(glyph.OffsetX * scale);
                float ngy = acc_y + (float)Math.Round(glyph.OffsetY * scale);
                //NOTE:
                // -glyphData.TextureXOffset => restore to original pos
                // -glyphData.TextureYOffset => restore to original pos
                //--------------------------
                g_x = (float)(x + (ngx - glyphData.TextureXOffset) * scaleFromTexture); //ideal x
                g_y = (float)(y + (ngy - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture);


                acc_x += (float)Math.Round(glyph.AdvanceX * scale);

                //g_x = (float)Math.Round(g_x);
                g_y = (float)Math.Floor(g_y);


                switch (textureKind)
                {
                case TextureKind.Msdf:

                    _glsx.DrawSubImageWithMsdf(_glBmp,
                                               ref srcRect,
                                               g_x,
                                               g_y,
                                               scaleFromTexture);

                    break;

                case TextureKind.StencilGreyScale:

                    //stencil gray scale with fill-color
                    _glsx.DrawGlyphImageWithStecil(_glBmp,
                                                   ref srcRect,
                                                   g_x,
                                                   g_y,
                                                   scaleFromTexture);

                    break;

                case TextureKind.Bitmap:
                    _glsx.DrawSubImage(_glBmp,
                                       ref srcRect,
                                       g_x,
                                       g_y,
                                       scaleFromTexture);
                    break;

                case TextureKind.StencilLcdEffect:

                    _glsx.WriteVboToList(
                        _vboBufferList,
                        _indexList,
                        ref srcRect,
                        g_x,
                        g_y,
                        scaleFromTexture);

                    break;
                }
            }
            //-------
            //we create vbo first
            //then render
            _glsx.DrawGlyphImageWithSubPixelRenderingTechnique3(_vboBufferList.ToArray(), _indexList.ToArray());
        }
示例#5
0
        private void button1_Click(object sender, EventArgs e)
        {
            selectedTextPrinter                   = _devVxsTextPrinter;
            selectedTextPrinter.Typeface          = _basicOptions.Typeface;
            selectedTextPrinter.FontSizeInPoints  = _basicOptions.FontSizeInPoints;
            selectedTextPrinter.ScriptLang        = _basicOptions.ScriptLang;
            selectedTextPrinter.PositionTechnique = _basicOptions.PositionTech;
            selectedTextPrinter.HintTechnique     = HintTechnique.None;
            selectedTextPrinter.EnableLigature    = true;
            _devVxsTextPrinter.UpdateGlyphLayoutSettings();

            //-------
            var editableTextBlockLayoutEngine = new EditableTextBlockLayoutEngine();

            editableTextBlockLayoutEngine.DefaultTypeface = _basicOptions.Typeface;
            editableTextBlockLayoutEngine.FontSizeInPts   = _basicOptions.FontSizeInPoints;
            editableTextBlockLayoutEngine.LoadText("ABCD\r\n   EFGH!");
            editableTextBlockLayoutEngine.DoLayout();

            //then we render the output to the screen
            //see UpdateRenderOutput() code
            //clear previous draw
            //----------------

            //-------------
            painter.Clear(PixelFarm.Drawing.Color.White);
            painter.UseSubPixelLcdEffect           = false;
            painter.FillColor                      = PixelFarm.Drawing.Color.Black;
            _devVxsTextPrinter.TargetCanvasPainter = painter;

            List <EditableTextLine> textlines = editableTextBlockLayoutEngine.UnsafeGetEditableTextLine();
            //render eachline with painter
            int lineCount = textlines.Count;

            float x           = 0;
            int   y           = 200;
            int   lineSpacing = (int)_devVxsTextPrinter.FontLineSpacingPx;

            for (int i = 0; i < lineCount; ++i)
            {
                EditableTextLine line = textlines[i];
                List <IRun>      runs = line.UnsageGetTextRunList();
                int runCount          = runs.Count;

                for (int r = 0; r < runCount; ++r)
                {
                    IRun    run     = runs[r];
                    TextRun textRun = run as TextRun;
                    if (textRun == null)
                    {
                        continue;
                    }
                    //
                    GlyphPlanSequence seq = textRun.GetGlyphPlanSeq();
                    _devVxsTextPrinter.DrawFromGlyphPlans(
                        GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(seq),
                        seq.startAt,
                        seq.len,
                        x, y);
                    x += run.Width;
                    y -= lineSpacing; //next line?
                }
                x = 0;                //reset at newline
            }
            //----------

            //use this util to copy image from Agg actual image to System.Drawing.Bitmap
            PixelFarm.Agg.Imaging.BitmapHelper.CopyToGdiPlusBitmapSameSize(painter.RenderSurface.DestActualImage, winBmp);
            //----------------
            //copy from Agg's memory buffer to gdi
            //PixelFarm.Agg.Imaging.BitmapHelper.CopyToGdiPlusBitmapSameSize(destImg, winBmp);
            g.Clear(Color.White);
            g.DrawImage(winBmp, new Point(10, 0));
        }
        public void CalculateUserCharGlyphAdvancePos(ref TextBufferSpan textBufferSpan,
                                                     ILineSegmentList lineSegs, RequestFont font,
                                                     int[] outputUserInputCharAdvance, out int outputTotalW, out int lineHeight)
        {
            //layout
            //from font
            //resolve for typeface
            //
            Typeface typeface = ResolveTypeface(font);

            _typographyTxtServices.SetCurrentFont(typeface, font.SizeInPoints);


            MyLineSegmentList mylineSegs = (MyLineSegmentList)lineSegs;
            float             scale      = typeface.CalculateScaleToPixelFromPointSize(font.SizeInPoints);

            outputTotalW = 0;
            int j   = mylineSegs.Count;
            int pos = 0; //start at 0

            _reusableTextBuffer.SetRawCharBuffer(textBufferSpan.GetRawCharBuffer());

            for (int i = 0; i < j; ++i)
            {
                //userGlyphPlanList.Clear();
                //userCharToGlyphMapList.Clear();
                //get each segment
                MyLineSegment lineSeg = mylineSegs.GetSegment(i);
                //each line seg may has different script lang
                _typographyTxtServices.CurrentScriptLang = lineSeg.scriptLang;
                //
                //CACHING ...., reduce number of GSUB/GPOS
                //
                //we cache used line segment for a while
                //we ask for caching context for a specific typeface and font size
                GlyphPlanSequence seq = _typographyTxtServices.GetUnscaledGlyphPlanSequence(_reusableTextBuffer,
                                                                                            lineSeg.StartAt,
                                                                                            lineSeg.Length);

                UnscaledGlyphPlanList planList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(seq);
                //IMPORTANT
                //num of glyph may more or less than original user input char buffer
                //
                int endAt       = seq.startAt + seq.len;
                int seq_startAt = seq.startAt;



                //float g_x = 0;
                //float g_y = 0;
                //int baseY = (int)Math.Round(y);
                //int n = glyphPlanSeq.len;
                //int endBefore = glyphPlanSeq.startAt + n;

                ////***
                //_glsx.SetAssociatedTextureInfo(_glBmp);

                //List<float> vboBufferList = new List<float>();
                //List<ushort> indexList = new List<ushort>();

                //for (int i = glyphPlanSeq.startAt; i < endBefore; ++i)
                //{
                //    GlyphPlanList glyphPlanList = GlyphPlanSequence.UnsafeGetInteralGlyphPlanList(glyphPlanSeq);
                //    GlyphPlan glyph = glyphPlanList[i];

                //    Typography.Rendering.TextureFontGlyphData glyphData;
                //    if (!_fontAtlas.TryGetGlyphDataByCodePoint(glyph.glyphIndex, out glyphData))
                //    {
                //        //if no glyph data, we should render a missing glyph ***
                //        continue;
                //    }
                //    //if (scaleFromTexture != 1)
                //    //{

                //    //}
                //    //--------------------------------------
                //    //TODO: review precise height in float
                //    //--------------------------------------
                //    PixelFarm.Drawing.Rectangle srcRect = ConvToRect(glyphData.Rect);
                //    g_x = (float)(x + (glyph.ExactX * scale - glyphData.TextureXOffset) * scaleFromTexture); //ideal x
                //    g_y = (float)(y + (glyph.ExactY * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture);


                //    //for sharp glyph
                //    //we adjust g_x,g_y to integer value
                //    //float g_y2 = (float)Math.Floor(g_y);

                //    g_x = (float)Math.Round(g_x);
                //    g_y = (float)Math.Floor(g_y);


                //    switch (textureKind)
                //    {
                //        case TextureKind.Msdf:

                //            _glsx.DrawSubImageWithMsdf(_glBmp,
                //                ref srcRect,
                //                g_x,
                //                g_y,
                //                scaleFromTexture);

                //            break;
                //        case TextureKind.StencilGreyScale:

                //            //stencil gray scale with fill-color
                //            _glsx.DrawGlyphImageWithStecil(_glBmp,
                //             ref srcRect,
                //                g_x,
                //                g_y,
                //                scaleFromTexture);

                //            break;
                //        case TextureKind.Bitmap:
                //            _glsx.DrawSubImage(_glBmp,
                //             ref srcRect,
                //                g_x,
                //                g_y,
                //                scaleFromTexture);
                //            break;
                //        case TextureKind.StencilLcdEffect:
                //            _glsx.WriteVboToList(
                //              vboBufferList,
                //              indexList,
                //              ref srcRect,
                //              g_x,
                //              g_y,
                //              scaleFromTexture);
                //            break;
                //    }
                //}
                ////---------



                for (int s = seq_startAt; s < endAt; ++s)
                {
                    UnscaledGlyphPlan glyphPlan = planList[s];

                    double actualAdvX = glyphPlan.AdvanceX;

                    outputTotalW +=
                        outputUserInputCharAdvance[pos + glyphPlan.input_cp_offset] +=
                            (int)Math.Round(actualAdvX * scale);
                }
                pos += lineSeg.Length;
            }

            //

            lineHeight = (int)Math.Round(typeface.CalculateRecommendLineSpacing() * scale);

            _reusableTextBuffer.SetRawCharBuffer(null);
        }