示例#1
0
        public override void Draw(Painter p)
        {
            AggPainter painter = p as AggPainter;

            if (painter == null)
            {
                return;
            }

            painter.Clear(Color.White);

            int width  = painter.Width;
            int height = painter.Height;


            //switch to alpha mask
            painter.TargetBufferName = TargetBufferName.AlphaMask;
            //draw white rect on the mask
            painter.FillColor = Color.White;
            painter.FillRect(20, 20, 50, 50);
            painter.FillRect(20, 5, 20, 10);

            //------------------------------------
            //switch back to default color
            painter.TargetBufferName = TargetBufferName.Default;
            painter.FillColor        = Color.Red;
            //enable mask composite
            painter.EnableBuiltInMaskComposite = true;
            painter.FillRect(0, 0, 100, 100);
            //disable mask buffer
            painter.EnableBuiltInMaskComposite = false;
            painter.FillColor = Color.Yellow;
            painter.FillRect(0, 0, 20, 20);

            //if (!_maskReady)
            //{
            //    SetupMaskPixelBlender(width, height);
            //    _maskReady = true;
            //}

            ////
            ////painter.DestBitmapBlender.OutputPixelBlender = maskPixelBlender; //change to new blender
            //painter.DestBitmapBlender.OutputPixelBlender = maskPixelBlenderPerCompo; //change to new blender

            ////4.
            //painter.FillColor = Color.Black;
            ////this test lcd-effect => we need to draw it 3 times with different color component, on the same position
            ////(same as we do with OpenGLES rendering surface)
            //maskPixelBlenderPerCompo.SelectedMaskComponent = PixelBlenderColorComponent.B;
            //maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.B;
            //painter.FillRect(0, 0, 200, 100);
            ////
            //maskPixelBlenderPerCompo.SelectedMaskComponent = PixelBlenderColorComponent.G;
            //maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.G;
            //painter.FillRect(0, 0, 200, 100);
            ////
            //maskPixelBlenderPerCompo.SelectedMaskComponent = PixelBlenderColorComponent.R;
            //maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.R;
            //painter.FillRect(0, 0, 200, 100);
        }
示例#2
0
        public override void Draw(Painter p)
        {
            AggPainter painter = p as AggPainter;

            if (painter == null)
            {
                return;
            }
            //

            painter.Clear(Color.White);

            int width  = painter.Width;
            int height = painter.Height;

            //change value ***

            if (!_maskReady)
            {
                SetupMaskPixelBlender(width, height);
                _maskReady = true;
            }

            //
            //painter.DestBitmapBlender.OutputPixelBlender = maskPixelBlender; //change to new blender
            painter.DestBitmapBlender.OutputPixelBlender = _maskPixelBlenderPerCompo; //change to new blender

            //4.
            painter.FillColor = Color.Black;
            //this test lcd-effect => we need to draw it 3 times with different color component, on the same position
            //(same as we do with OpenGLES rendering surface)
            _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.B;
            _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.B;
            painter.FillRect(0, 0, 200, 100);
            //
            _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.G;
            _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.G;
            painter.FillRect(0, 0, 200, 100);
            //
            _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.R;
            _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.R;
            painter.FillRect(0, 0, 200, 100);
        }
示例#3
0
        public override void Draw(Painter p)
        {
            AggPainter painter = p as AggPainter;

            if (painter == null)
            {
                return;
            }
            //
            painter.Clear(Color.White);

            int width  = painter.Width;
            int height = painter.Height;

            //change value ***
            if (_isMaskSliderValueChanged)
            {
                SetupMaskPixelBlender(width, height);
                _isMaskSliderValueChanged = false;
                //
                //painter.DestBitmapBlender.OutputPixelBlender = maskPixelBlender; //change to new blender
                painter.DestBitmapBlender.OutputPixelBlender = maskPixelBlenderPerCompo; //change to new blender
            }
            //1. alpha mask...
            //p2.DrawImage(alphaBitmap, 0, 0);

            //2.
            painter.FillColor = Color.Black;
            painter.FillRect(0, 0, 200, 100);

            //3.
            painter.FillColor = Color.Blue;
            painter.FillCircle(300, 300, 100);
            painter.DrawImage(lionImg, 20, 20);



            ////4.
            //painter.FillColor = Color.Black;
            ////this test lcd-effect => we need to draw it 3 times with different color component, on the same position
            ////(same as we do with OpenGLES rendering surface)
            //maskPixelBlenderPerCompo.SelectedMaskComponent = PixelBlenderColorComponent.B;
            //maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.B;
            //painter.FillRect(0, 0, 200, 100);
            //maskPixelBlenderPerCompo.SelectedMaskComponent = PixelBlenderColorComponent.G;
            //maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.G;
            //painter.FillRect(0, 0, 200, 100);
            //maskPixelBlenderPerCompo.SelectedMaskComponent = PixelBlenderColorComponent.R;
            //maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.R;
            //painter.FillRect(0, 0, 200, 100);
        }
示例#4
0
        void RenderGrids(int width, int height, int sqSize, AggPainter p)
        {
            //render grid
            p.FillColor = PixelFarm.Drawing.Color.Gray;

            float pointW = (sqSize >= 100) ? 2 : 1;

            for (int y = 0; y < height;)
            {
                for (int x = 0; x < width;)
                {
                    p.FillRect(x, y, pointW, pointW);
                    x += sqSize;
                }
                y += sqSize;
            }
        }
示例#5
0
        void DrawStringToMemBitmap(RequestFont reqFont, string textOutput, float x_pos, float y_pos, int repeatLines = 1)
        {
            ResolvedFont resolvedFont = _textService.ResolveFont(reqFont);

            if (resolvedFont == null)
            {
                //we dont' have
                resolvedFont = _textService.ResolveFont(_defaultReqFont);
                if (resolvedFont == null)
                {
                    throw new NotSupportedException();
                }

                //use alternative typeface, but use reqFont's Size
                resolvedFont = new ResolvedFont(resolvedFont.Typeface, reqFont.SizeInPoints);
            }

            //check if reqFont has alternative or not

            _myAlternativeTypefaceSelector.SetCurrentReqFont(reqFont, _textService);

            PixelFarm.Drawing.VxsTextSpanPrinter _selectedTextPrinter = _devVxsTextPrinter;
            _painter.UseLcdEffectSubPixelRendering = true;
            _painter.FillColor = PixelFarm.Drawing.Color.Black;

            _selectedTextPrinter = _devVxsTextPrinter;

            _selectedTextPrinter.FontSizeInPoints  = resolvedFont.SizeInPoints;
            _selectedTextPrinter.Typeface          = resolvedFont.Typeface;
            _selectedTextPrinter.ScriptLang        = new ScriptLang(ScriptTagDefs.Latin.Tag);
            _selectedTextPrinter.PositionTechnique = PositionTechnique.OpenFont;

            _selectedTextPrinter.HintTechnique  = HintTechnique.None;
            _selectedTextPrinter.EnableLigature = true;
            _selectedTextPrinter.SimulateSlant  = false;

            _selectedTextPrinter.EnableMultiTypefaces = true; //*** for auto typeface selection***

            //_selectedTextPrinter.TextBaseline = PixelFarm.Drawing.TextBaseline.Alphabetic;
            //_selectedTextPrinter.TextBaseline = PixelFarm.Drawing.TextBaseline.Bottom;
            _selectedTextPrinter.TextBaseline = (Typography.Text.TextBaseline)PixelFarm.Drawing.TextBaseline.Top;

            //test print 3 lines
            //#if DEBUG
            //            DynamicOutline.dbugTestNewGridFitting = _contourAnalysisOpts.EnableGridFit;
            //            DynamicOutline.dbugActualPosToConsole = _contourAnalysisOpts.WriteFitOutputToConsole;
            //            DynamicOutline.dbugUseHorizontalFitValue = _contourAnalysisOpts.UseHorizontalFitAlignment;
            //#endif


            char[] printTextBuffer = textOutput.ToCharArray();


            float lineSpacingPx = _selectedTextPrinter.FontLineSpacingPx;

            const int REF_LINE_LEN = 300;

            for (int i = 0; i < repeatLines; ++i)
            {
                _selectedTextPrinter.DrawString(printTextBuffer, x_pos, y_pos);
#if DEBUG
                //show debug info...
                var prevColor      = _painter.FillColor;
                var prevStrokColor = _painter.StrokeColor;
                _painter.FillColor = PixelFarm.Drawing.Color.Red;
                _painter.FillRect(x_pos, y_pos, 5, 5); // start point

                //see   //https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline
                switch (_selectedTextPrinter.TextBaseline)
                {
                default:
                {
                    System.Diagnostics.Debug.WriteLine("UNIMPLEMENTED" + _selectedTextPrinter.TextBaseline.ToString());
                    goto case Typography.Text.TextBaseline.Alphabetic;        //
                }

                case Typography.Text.TextBaseline.Alphabetic:
                {
                    //alphabetic baseline
                    _painter.StrokeColor = _grayColor;
                    _painter.DrawLine(x_pos, /**/ y_pos,
                                      x_pos + REF_LINE_LEN, y_pos);

                    _painter.StrokeColor = PixelFarm.Drawing.Color.Blue;
                    _painter.DrawLine(x_pos, /**/ y_pos - _selectedTextPrinter.FontDescedingPx,
                                      x_pos + REF_LINE_LEN, y_pos - _selectedTextPrinter.FontDescedingPx);        //bottom most
                }
                break;

                case Typography.Text.TextBaseline.Top:
                {
                    //alphabetic baseline
                    _painter.StrokeColor = _grayColor;
                    _painter.DrawLine(x_pos, /**/ y_pos + _selectedTextPrinter.FontAscendingPx,
                                      x_pos + REF_LINE_LEN, y_pos + _selectedTextPrinter.FontAscendingPx);
                    //em bottom
                    _painter.StrokeColor = PixelFarm.Drawing.Color.Blue;
                    _painter.DrawLine(x_pos, /**/ y_pos + (_selectedTextPrinter.FontAscendingPx - _selectedTextPrinter.FontDescedingPx),
                                      x_pos + REF_LINE_LEN, y_pos + (_selectedTextPrinter.FontAscendingPx - _selectedTextPrinter.FontDescedingPx));        //bottom most
                }
                break;

                case Typography.Text.TextBaseline.Bottom:
                {
                    //alphabetic baseline
                    _painter.StrokeColor = _grayColor;
                    _painter.DrawLine(x_pos, /**/ y_pos + _selectedTextPrinter.FontDescedingPx,
                                      x_pos + REF_LINE_LEN, y_pos + _selectedTextPrinter.FontDescedingPx);
                    //em bottom
                    _painter.StrokeColor = PixelFarm.Drawing.Color.Blue;
                    _painter.DrawLine(x_pos, /**/ y_pos,
                                      x_pos + REF_LINE_LEN, y_pos);        //bottom most
                }
                break;
                }


                _painter.FillColor   = prevColor;
                _painter.StrokeColor = prevColor;
#endif
                y_pos += (_selectedTextPrinter.FontAscendingPx - _selectedTextPrinter.FontDescedingPx);
            }

            //reset
            _myAlternativeTypefaceSelector.SetCurrentReqFont(null, null);
        }
示例#6
0
        public void DrawString(Painter p, char[] buffer, int startAt, int len, double x, double y)
        {
            AggPainter painter = p as AggPainter;



            if (painter == null)
            {
                return;
            }
            //

            int width  = painter.Width;
            int height = painter.Height;

            if (!_pixelBlenderSetup)
            {
                SetupMaskPixelBlender(width, height);
                _pixelBlenderSetup = true;
            }

            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 = 1;// _fontAtlas.TargetTextureScale;
            int   recommendLineSpacing = (int)_font.LineSpacingInPixels;

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

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

            float gx    = 0;
            float gy    = 0;
            int   baseY = (int)Math.Round(y);

            float acc_x = 0;
            float acc_y = 0;

            int lineHeight = (int)_font.LineSpacingInPixels;//temp

            //painter.DestBitmapBlender.OutputPixelBlender = maskPixelBlenderPerCompo; //change to new blender
            painter.DestBitmapBlender.OutputPixelBlender = _maskPixelBlenderPerCompo; //change to new blender

            int seqLen = glyphPlanSeq.Count;

            for (int i = 0; i < seqLen; ++i)
            {
                UnscaledGlyphPlan   glyph = glyphPlanSeq[i];
                TextureGlyphMapData glyphData;
                if (!_fontAtlas.TryGetGlyphMapData(glyph.glyphIndex, out glyphData))
                {
                    //if no glyph data, we should render a missing glyph ***
                    continue;
                }
                //--------------------------------------
                //TODO: review precise height in float
                //--------------------------------------
                int srcX, srcY, srcW, srcH;
                glyphData.GetRect(out srcX, out srcY, out srcW, out srcH);

                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
                //--------------------------
                gx = (float)(x + (ngx - glyphData.TextureXOffset) * scaleFromTexture); //ideal x
                gy = (float)(y + (ngy - glyphData.TextureYOffset - srcH + lineHeight) * scaleFromTexture);

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

                //clear with solid black color
                //_maskBufferPainter.Clear(Color.Black);
                _maskBufferPainter.FillRect(gx - 1, gy - 1, srcW + 2, srcH + 2, Color.Black);
                //draw 'stencil' glyph on mask-buffer
                _maskBufferPainter.DrawImage(_fontBmp, gx, gy, srcX, _fontBmp.Height - (srcY), srcW, srcH);

                //select component to render this need to render 3 times for lcd technique
                //1. B
                _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.B;
                _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.B;
                painter.FillRect(gx + 1, gy, srcW, srcH);
                //2. G
                _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.G;
                _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.G;
                painter.FillRect(gx + 1, gy, srcW, srcH);
                //3. R
                _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.R;
                _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.R;
                painter.FillRect(gx + 1, gy, srcW, srcH);
            }
        }
示例#7
0
文件: Form1.cs 项目: ywscr/Typography
        void UpdateRenderOutput()
        {
            if (!_readyToRender)
            {
                return;
            }
            //
            if (_g == null)
            {
                InitGraphics();
            }

            if (string.IsNullOrEmpty(this.txtInputChar.Text))
            {
                return;
            }

            //test option use be used with lcd subpixel rendering.
            //this demonstrate how we shift a pixel for subpixel rendering tech

            if (_contourAnalysisOpts.SetupPrinterLayoutForLcdSubPix)
            {
                //TODO: set lcd or not here
            }
            else
            {
                //TODO: set lcd or not here
            }

            //1. read typeface from font file
            TypographyTest.RenderChoice renderChoice = _basicOptions.RenderChoice;
            switch (renderChoice)
            {
            case TypographyTest.RenderChoice.RenderWithGdiPlusPath:
                //not render in this example
                //see more at ...
                break;

            case TypographyTest.RenderChoice.RenderWithTextPrinterAndMiniAgg:
            {
                //clear previous draw
                _painter.Clear(PixelFarm.Drawing.Color.White);
                _painter.UseLcdEffectSubPixelRendering = _contourAnalysisOpts.LcdTechnique;
                _painter.FillColor = PixelFarm.Drawing.Color.Black;

                _selectedTextPrinter                   = _devVxsTextPrinter;
                _selectedTextPrinter.Typeface          = _basicOptions.Typeface;
                _selectedTextPrinter.FontSizeInPoints  = _basicOptions.FontSizeInPoints;
                _selectedTextPrinter.ScriptLang        = _basicOptions.ScriptLang;
                _selectedTextPrinter.PositionTechnique = _basicOptions.PositionTech;


                if (_selectedTextPrinter is PixelFarm.Drawing.VxsTextSpanPrinter vxsTextPrinter)
                {
                    vxsTextPrinter.HintTechnique = _glyphRenderOptions.HintTechnique;
                }
                _selectedTextPrinter.EnableLigature       = _glyphRenderOptions.EnableLigature;
                _selectedTextPrinter.EnableMultiTypefaces = _basicOptions.EnableMultiTypefaces;
                _selectedTextPrinter.SimulateSlant        = _contourAnalysisOpts.SimulateSlant;
                _selectedTextPrinter.TextBaseline         = (Typography.Text.TextBaseline)(int) lstTextBaseline.SelectedItem;



                //test print 3 lines
#if DEBUG
                DynamicOutline.dbugTestNewGridFitting    = _contourAnalysisOpts.EnableGridFit;
                DynamicOutline.dbugActualPosToConsole    = _contourAnalysisOpts.WriteFitOutputToConsole;
                DynamicOutline.dbugUseHorizontalFitValue = _contourAnalysisOpts.UseHorizontalFitAlignment;
#endif

                char[] printTextBuffer = this.txtInputChar.Text.ToCharArray();
                float  x_pos = 0, y_pos = 0;
                float  lineSpacingPx = _selectedTextPrinter.FontLineSpacingPx;

                const int REF_LINE_LEN = 300;
                for (int i = 0; i < 3; ++i)
                {
                    _selectedTextPrinter.DrawString(printTextBuffer, x_pos, y_pos);
#if DEBUG
                    //show debug info...
                    var prevColor      = _painter.FillColor;
                    var prevStrokColor = _painter.StrokeColor;
                    _painter.FillColor = PixelFarm.Drawing.Color.Red;
                    _painter.FillRect(x_pos, y_pos, 5, 5);         // start point

                    //see   //https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline
                    switch (_selectedTextPrinter.TextBaseline)
                    {
                    default:
                    {
                        System.Diagnostics.Debug.WriteLine("UNIMPLEMENTED" + _selectedTextPrinter.TextBaseline.ToString());
                        goto case Typography.Text.TextBaseline.Alphabetic;                //
                    }

                    case Typography.Text.TextBaseline.Alphabetic:
                    {
                        //alphabetic baseline
                        _painter.StrokeColor = _grayColor;
                        _painter.DrawLine(x_pos, /**/ y_pos,
                                          x_pos + REF_LINE_LEN, y_pos);

                        _painter.StrokeColor = PixelFarm.Drawing.Color.Blue;
                        _painter.DrawLine(x_pos, /**/ y_pos - _selectedTextPrinter.FontDescedingPx,
                                          x_pos + REF_LINE_LEN, y_pos - _selectedTextPrinter.FontDescedingPx);                //bottom most
                    }
                    break;

                    case Typography.Text.TextBaseline.Top:
                    {
                        //alphabetic baseline
                        _painter.StrokeColor = _grayColor;
                        _painter.DrawLine(x_pos, /**/ y_pos + _selectedTextPrinter.FontAscendingPx,
                                          x_pos + REF_LINE_LEN, y_pos + _selectedTextPrinter.FontAscendingPx);
                        //em bottom
                        _painter.StrokeColor = PixelFarm.Drawing.Color.Blue;
                        _painter.DrawLine(x_pos, /**/ y_pos + (_selectedTextPrinter.FontAscendingPx - _selectedTextPrinter.FontDescedingPx),
                                          x_pos + REF_LINE_LEN, y_pos + (_selectedTextPrinter.FontAscendingPx - _selectedTextPrinter.FontDescedingPx));                //bottom most
                    }
                    break;

                    case Typography.Text.TextBaseline.Bottom:
                    {
                        //alphabetic baseline
                        _painter.StrokeColor = _grayColor;
                        _painter.DrawLine(x_pos, /**/ y_pos + _selectedTextPrinter.FontDescedingPx,
                                          x_pos + REF_LINE_LEN, y_pos + _selectedTextPrinter.FontDescedingPx);
                        //em bottom
                        _painter.StrokeColor = PixelFarm.Drawing.Color.Blue;
                        _painter.DrawLine(x_pos, /**/ y_pos,
                                          x_pos + REF_LINE_LEN, y_pos);                //bottom most
                    }
                    break;
                    }


                    _painter.FillColor   = prevColor;
                    _painter.StrokeColor = prevColor;
#endif
                    y_pos += (_selectedTextPrinter.FontAscendingPx - _selectedTextPrinter.FontDescedingPx);
                }


                //copy from Agg's memory buffer to gdi
                PixelFarm.CpuBlit.BitmapHelper.CopyToGdiPlusBitmapSameSizeNotFlip(_destImg, _winBmp);
                _g.Clear(Color.White);
                _g.DrawImage(_winBmp, new Point(0, 0));
            }
            break;

            //==============================================
            //render 1 glyph for debug and test
            case TypographyTest.RenderChoice.RenderWithMsdfGen:
            case TypographyTest.RenderChoice.RenderWithSdfGen:
            {
                char     testChar = this.txtInputChar.Text[0];
                Typeface typeFace = _basicOptions.Typeface;
                RenderWithMsdfImg(typeFace, testChar, _basicOptions.FontSizeInPoints);
            }
            break;

            case TypographyTest.RenderChoice.RenderWithMiniAgg_SingleGlyph:
            {
                _selectedTextPrinter = _devVxsTextPrinter;
                //for test only 1 char
                RenderSingleCharWithMiniAgg(
                    _basicOptions.Typeface,
                    this.txtInputChar.Text[0],
                    _basicOptions.FontSizeInPoints);
            }
            break;

            default:
                throw new NotSupportedException();
            }
        }
        public override void DrawFromGlyphPlans(GlyphPlanSequence glyphPlanSeq, int startAt, int len, float left, float top)
        {
            Typeface typeface = _textServices.ResolveTypeface(_font);

            float scale = typeface.CalculateScaleToPixelFromPointSize(_font.SizeInPoints);
            int   recommendLineSpacing = (int)_font.LineSpacingInPixels;
            //--------------------------
            //TODO:
            //if (x,y) is left top
            //we need to adjust y again

            //

            TextureKind textureKind = _fontAtlas.TextureKind;

            float gx    = 0;
            float gy    = 0;
            int   baseY = (int)Math.Round(top);


            float acc_x = 0;
            float acc_y = 0;

            int lineHeight = (int)_font.LineSpacingInPixels;                              //temp

            PixelBlender32 prevPxBlender = _painter.DestBitmapBlender.OutputPixelBlender; //save

            _painter.DestBitmapBlender.OutputPixelBlender = _maskPixelBlenderPerCompo;    //change to new blender

            bool fillGlyphByGlyph = true;

            if (fillGlyphByGlyph)
            {
                //test...
                //fill glyph-by-glyh

                var aaTech = this.AntialiasTech;
                int seqLen = glyphPlanSeq.Count;


                for (int i = 0; i < seqLen; ++i)
                {
                    UnscaledGlyphPlan   unscaledGlyphPlan = glyphPlanSeq[i];
                    TextureGlyphMapData glyphData;
                    if (!_fontAtlas.TryGetGlyphMapData(unscaledGlyphPlan.glyphIndex, out glyphData))
                    {
                        //if no glyph data, we should render a missing glyph ***
                        continue;
                    }
                    //--------------------------------------
                    //TODO: review precise height in float
                    //--------------------------------------
                    int srcX, srcY, srcW, srcH;
                    glyphData.GetRect(out srcX, out srcY, out srcW, out srcH);

                    float ngx = acc_x + (float)Math.Round(unscaledGlyphPlan.OffsetX * scale);
                    float ngy = acc_y + (float)Math.Round(unscaledGlyphPlan.OffsetY * scale);
                    //NOTE:
                    // -glyphData.TextureXOffset => restore to original pos
                    // -glyphData.TextureYOffset => restore to original pos
                    //--------------------------

                    //if (glyphData.TextureXOffset != 0)
                    //{
                    //}

                    gx = (float)(left + (ngx - glyphData.TextureXOffset)); //ideal x
                    gy = (float)(top + (ngy + glyphData.TextureYOffset - srcH + lineHeight));

                    acc_x += (float)Math.Round(unscaledGlyphPlan.AdvanceX * scale);
                    gy     = (float)Math.Floor(gy);// + lineHeight;

                    //clear with solid black color
                    //_maskBufferPainter.Clear(Color.Black);
                    //clear mask buffer at specific pos
                    _maskBufferPainter.FillRect(gx - 1, gy - 1, srcW + 2, srcH + 2, Color.Black);
                    //draw 'stencil' glyph on mask-buffer
                    _maskBufferPainter.DrawImage(_fontBmp, gx, gy, srcX, _fontBmp.Height - (srcY + srcH), srcW, srcH);

                    switch (aaTech)
                    {
                    default:
                    {
                        //select component to render this need to render 3 times for lcd technique
                        //1. B
                        _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.B;
                        _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.B;
                        _painter.FillRect(gx + 1, gy, srcW, srcH);
                        //2. G
                        _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.G;
                        _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.G;
                        _painter.FillRect(gx + 1, gy, srcW, srcH);
                        //3. R
                        _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.R;
                        _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.R;
                        _painter.FillRect(gx + 1, gy, srcW, srcH);
                    }
                    break;

                    case AntialiasTechnique.GreyscaleStencil:
                    {
                        //fill once
                        //we choose greeh channel (middle)
                        _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.G;
                        _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.EnableAll;
                        _painter.FillRect(gx + 1, gy, srcW, srcH);
                    }
                    break;
                    }
                }
            }
            else
            {
                //clear entire line
                _maskBufferPainter.FillRect(gx - 1, gy - 1, _maskBufferPainter.Width - gx + 2, lineHeight + 2, Color.Black);

                bool  isFirst = true;
                int   startX = 0, startY = 0;
                float lenW = 0;
                float lenH = 0;

                int seqLen = glyphPlanSeq.Count;
                for (int i = 0; i < seqLen; ++i)
                {
                    UnscaledGlyphPlan glyph = glyphPlanSeq[i];

                    TextureGlyphMapData glyphData;
                    if (!_fontAtlas.TryGetGlyphMapData(glyph.glyphIndex, out glyphData))
                    {
                        //if no glyph data, we should render a missing glyph ***
                        continue;
                    }
                    //--------------------------------------
                    //TODO: review precise height in float
                    //--------------------------------------
                    int srcX, srcY, srcW, srcH;
                    glyphData.GetRect(out srcX, out srcY, out srcW, out srcH);

                    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
                    //--------------------------
                    gx = (float)(left + (ngx - glyphData.TextureXOffset)); //ideal x
                    gy = (float)(top + (ngy - glyphData.TextureYOffset - srcH + lineHeight));

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

                    if (isFirst)
                    {
                        startX  = (int)gx;
                        startY  = (int)gy;
                        isFirst = false;
                    }

                    _maskBufferPainter.DrawImage(_fontBmp, gx + 1, gy, srcX, _fontBmp.Height - (srcY), srcW + 1, srcH);

                    lenW = gx + srcW;
                    if (srcH > lenH)
                    {
                        lenH = srcH;
                    }
                }
                //--------------------------
                //fill color on 'stencil' mask
                {
                    //select component to render this need to render 3 times for lcd technique
                    //1. B
                    _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.B;
                    _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.B;
                    _painter.FillRect(startX + 1, startY, lenW, lenH);
                    //2. G
                    _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.G;
                    _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.G;
                    _painter.FillRect(startX + 1, startY, lenW, lenH);
                    //3. R
                    _maskPixelBlenderPerCompo.SelectedMaskComponent      = PixelBlenderColorComponent.R;
                    _maskPixelBlenderPerCompo.EnableOutputColorComponent = EnableOutputColorComponent.R;
                    _painter.FillRect(startX + 1, startY, lenW, lenH);
                }
            }

            //
            _painter.DestBitmapBlender.OutputPixelBlender = prevPxBlender;//restore back
        }