Ejemplo n.º 1
0
        public void DrawString(char[] buffer, int startAt, int len, double left, double top)
        {
            _vboBuilder.Clear();
            _vboBuilder.SetTextureInfo(_glBmp.Width, _glBmp.Height, _glBmp.IsYFlipped, _pcx.OriginKind);

            //
            _pcx.FontFillColor = _painter.FontFillColor;
            _pcx.LoadTexture(_glBmp);


            //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             px_scale     = _px_scale;
            //--------------------------
            //TODO:
            //if (x,y) is left top
            //we need to adjust y again

            float       scaleFromTexture = 1;
            TextureKind textureKind      = _fontAtlas.TextureKind;

            float g_left   = 0;
            float g_top    = 0;
            int   baseLine = (int)Math.Round((float)top + _font.AscentInPixels);
            int   bottom   = (int)Math.Round((float)top + _font.AscentInPixels - _font.DescentInPixels);

            float acc_x = 0; //local accumulate x
            float acc_y = 0; //local accumulate y

#if DEBUG
            if (s_dbugShowMarkers)
            {
                if (s_dbugShowGlyphTexture)
                {
                    //show original glyph texture at top
                    _pcx.DrawImage(_glBmp, 0, 0);
                }
                //draw red-line-marker for baseLine
                _painter.StrokeColor = Color.Red;
                _painter.DrawLine(left, baseLine, left + 200, baseLine);
                //
                //draw magenta-line-marker for bottom line
                _painter.StrokeColor = Color.Magenta;
                int bottomLine = (int)Math.Round((float)top + _font.LineSpacingInPixels);
                _painter.DrawLine(left, bottomLine, left + 200, bottomLine);
                //draw blue-line-marker for top line
                _painter.StrokeColor = Color.Blue;
                _painter.DrawLine(0, top, left + 200, top);
            }

            DrawingTechnique = s_dbugDrawTechnique; //for debug only
            UseVBO           = s_dbugUseVBO;        //for debug only
#endif



            int seqLen = glyphPlanSeq.Count;

            for (int i = 0; i < seqLen; ++i)
            {
                UnscaledGlyphPlan glyph = glyphPlanSeq[i];
                Typography.Rendering.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
                //--------------------------------------

                //paint src rect
                //temp fix, glyph texture img is not flipped
                //but the associate info is flipped => so
                //we need remap exact Y from the image

                Rectangle srcRect =
                    new Rectangle(glyphData.Left,
                                  _glBmp.Height - (glyphData.Top + glyphData.Height),
                                  glyphData.Width,
                                  glyphData.Height);

                //offset length from 'base-line'
                float x_offset = acc_x + (float)Math.Round(glyph.OffsetX * px_scale - glyphData.TextureXOffset);
                float y_offset = acc_y + (float)Math.Round(glyph.OffsetY * px_scale - glyphData.TextureYOffset) + srcRect.Height; //***

                //NOTE:
                // -glyphData.TextureXOffset => restore to original pos
                // -glyphData.TextureYOffset => restore to original pos
                //--------------------------

                g_left = (float)(left + x_offset);
                g_top  = (float)(bottom - y_offset); //***

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

                //g_x = (float)Math.Round(g_x); //***
                g_top = (float)Math.Floor(g_top);//adjust to integer num ***

#if DEBUG
                if (s_dbugShowMarkers)
                {
                    if (s_dbugShowGlyphTexture)
                    {
                        //draw yellow-rect-marker on original texture
                        _painter.DrawRectangle(srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, Color.Yellow);
                    }

                    //draw debug-rect box at target glyph position
                    _painter.DrawRectangle(g_left, g_top, srcRect.Width, srcRect.Height, Color.Black);
                    _painter.StrokeColor = Color.Blue; //restore
                }
#endif
                if (textureKind == TextureKind.Msdf)
                {
                    _pcx.DrawSubImageWithMsdf(_glBmp,
                                              ref srcRect,
                                              g_left,
                                              g_top,
                                              scaleFromTexture);
                }
                else
                {
                    switch (DrawingTechnique)
                    {
                    case GlyphTexturePrinterDrawingTechnique.Stencil:
                        if (UseVBO)
                        {
                            _vboBuilder.WriteVboToList(
                                ref srcRect,
                                g_left, g_top);
                        }
                        else
                        {
                            //stencil gray scale with fill-color
                            _pcx.DrawGlyphImageWithStecil(_glBmp,
                                                          ref srcRect,
                                                          g_left,
                                                          g_top,
                                                          scaleFromTexture);
                        }
                        break;

                    case GlyphTexturePrinterDrawingTechnique.Copy:
                        if (UseVBO)
                        {
                            _vboBuilder.WriteVboToList(
                                ref srcRect,
                                g_left, g_top);
                        }
                        else
                        {
                            _pcx.DrawSubImage(_glBmp,
                                              ref srcRect,
                                              g_left,
                                              g_top,
                                              1);
                        }
                        break;

                    case GlyphTexturePrinterDrawingTechnique.LcdSubPixelRendering:
                        if (UseVBO)
                        {
                            _vboBuilder.WriteVboToList(
                                ref srcRect,
                                g_left, g_top);
                        }
                        else
                        {
                            _pcx.DrawGlyphImageWithSubPixelRenderingTechnique2_GlyphByGlyph(
                                ref srcRect,
                                g_left,
                                g_top,
                                1);
                        }
                        break;
                    }
                }
            }
            //-------------------------------------------
            //
            if (UseVBO)
            {
                switch (DrawingTechnique)
                {
                case GlyphTexturePrinterDrawingTechnique.Copy:
                    _pcx.DrawGlyphImageWithCopy_VBO(_vboBuilder);
                    break;

                case GlyphTexturePrinterDrawingTechnique.LcdSubPixelRendering:
                    _pcx.DrawGlyphImageWithSubPixelRenderingTechnique3_DrawElements(_vboBuilder);
                    break;

                case GlyphTexturePrinterDrawingTechnique.Stencil:
                    _pcx.DrawGlyphImageWithStecil_VBO(_vboBuilder);
                    break;
                }

                _vboBuilder.Clear();
            }
        }