Example #1
0
 public BitmapAtlasManager(TextureKind textureKind,
                           LoadNewBmpDelegate <SimpleBitmaptAtlas, B> _createNewDel)
     : this(textureKind)
 {
     //glyph cahce for specific atlas
     SetLoadNewBmpDel(_createNewDel);
 }
        public void CreateTextureFontFromInputChars(
            Typeface typeface, float sizeInPoint,
            TextureKind textureKind,
            char[] chars,
            OnEachFinishTotal onFinishTotal)
        {
            //convert input chars into glyphIndex
            List <ushort> glyphIndices = new List <ushort>(chars.Length);
            int           i            = 0;

            foreach (char ch in chars)
            {
                glyphIndices.Add(typeface.LookupIndex(ch));
                i++;
            }
            //-------------------------------------------------------------
            var atlasBuilder = new SimpleFontAtlasBuilder();

            atlasBuilder.SetAtlasInfo(textureKind, sizeInPoint);
            //-------------------------------------------------------------
            //we can specfic subset with special setting for each set
            CreateTextureFontFromGlyphIndices(typeface, sizeInPoint,
                                              HintTechnique.TrueTypeInstruction_VerticalOnly, atlasBuilder, false, GetUniqueGlyphIndexList(glyphIndices));
            onFinishTotal(0, null, atlasBuilder);
        }
Example #3
0
        public SimpleBitmapAtlasBuilder CreateTextureFontFromInputChars(
            Typeface typeface, float sizeInPoint,
            TextureKind textureKind,
            char[] chars,
            OnEachGlyph onEachGlyphDel = null)
        {
            _onEachGlyphDel = onEachGlyphDel;
            //convert input chars into glyphIndex
            List <ushort> glyphIndices = new List <ushort>(chars.Length);
            int           i            = 0;

            foreach (char ch in chars)
            {
                glyphIndices.Add(typeface.GetGlyphIndex(ch));
                i++;
            }
            //-------------------------------------------------------------
            var atlasBuilder = new SimpleBitmapAtlasBuilder();

            atlasBuilder.SetAtlasInfo(textureKind, sizeInPoint);
            //-------------------------------------------------------------
            //we can specfic subset with special setting for each set
            CreateTextureFontFromGlyphIndices(typeface, sizeInPoint,
                                              HintTechnique.TrueTypeInstruction_VerticalOnly, atlasBuilder, GetUniqueGlyphIndexList(glyphIndices));

            _onEachGlyphDel = null;//reset
            return(atlasBuilder);
        }
Example #4
0
 public BitmapFontManager(TextureKind textureKind,
                          LayoutFarm.OpenFontTextService textServices,
                          LoadNewBmpDelegate <SimpleFontAtlas, B> _createNewDel)
     : this(textureKind, textServices)
 {
     //glyph cahce for specific atlas
     SetLoadNewBmpDel(_createNewDel);
 }
        public void Build(
            GlyphTextureBitmapGenerator glyphTextureGen,
            Typeface typeface, float fontSizeInPoints,
            TextureKind textureKind,
            GlyphTextureBuildDetail[] buildDetails)
        {
#if DEBUG
            //overall, glyph atlas generation time
            System.Diagnostics.Stopwatch dbugStopWatch = new System.Diagnostics.Stopwatch();
            dbugStopWatch.Start();
#endif
            var atlasBuilder = new SimpleBitmapAtlasBuilder();
            glyphTextureGen.CreateTextureFontFromBuildDetail(
                atlasBuilder,
                typeface,
                fontSizeInPoints,
                textureKind,
                buildDetails);

            //3. set information before write to font-info
            atlasBuilder.SpaceCompactOption = SimpleBitmapAtlasBuilder.CompactOption.ArrangeByHeight;
            atlasBuilder.SetAtlasFontInfo(typeface.Name, fontSizeInPoints);

            //4. merge all glyph in the builder into a single image
            using (MemBitmap totalGlyphsImg = atlasBuilder.BuildSingleImage(true))
            {
                if (TextureInfoFilename == null)
                {
                    //use random suffix
                    string random_suffix      = Guid.NewGuid().ToString().Substring(0, 7);
                    string textureName        = typeface.Name.ToLower() + "_" + random_suffix + ".info";
                    string output_imgFilename = textureName + ".png";

                    TextureInfoFilename = textureName;
                    OutputImgFilename   = output_imgFilename;
                }


                //5. save atlas info to disk
                using (FileStream fs = new FileStream(TextureInfoFilename, FileMode.Create))
                {
                    atlasBuilder.SaveAtlasInfo(fs);
                }

                //6. save total-glyph-image to disk
                totalGlyphsImg.SaveImage(OutputImgFilename);
            }

#if DEBUG
            dbugStopWatch.Stop();
            dbugBuildTimeMillisec = dbugStopWatch.ElapsedMilliseconds;
#endif
        }
        private void cmdMakeFromScriptLangs_Click(object sender, EventArgs e)
        {
            //create a simple stencil texture font

            //string sampleFontFile = "../../../TestFonts/tahoma.ttf";
            if (this.textBox1.Text == null || _typeface == null)
            {
                return;
            }
            if (SelectedScriptLangs.Count == 0)
            {
                return;
            }

            //
            string sampleFontFile = _typeface.Filename ?? "";

            TextureKind selectedTextureKind = (TextureKind)lstTextureType.SelectedItem;

            char[] chars = this.textBox1.Text.ToCharArray();

            string bitmapImgSaveFileName = "d:\\WImageTest\\sample_" + selectedTextureKind + "_" +
                                           System.IO.Path.GetFileNameWithoutExtension(sampleFontFile);

            bool saveEachGlyphSeparatly = chkSaveEachGlyph.Checked;
            var  textureGen             = new GlyphTextureBitmapGenerator();

            textureGen.CreateTextureFontFromScriptLangs(
                _typeface,
                FontSizeInPoints,
                selectedTextureKind,
                SelectedScriptLangs.ToArray(),
                (gindex, glyphImg, atlasBuilder) =>
            {
                if (atlasBuilder != null)
                {
                    atlasBuilder.CompactGlyphSpace = chkCompactGlyphSpace.Checked;
                    GlyphImage totalGlyphs         = atlasBuilder.BuildSingleImage();
                    SaveImgBufferToFile(totalGlyphs, bitmapImgSaveFileName + ".png");
                    atlasBuilder.SaveFontInfo(bitmapImgSaveFileName + ".xml");
                    MessageBox.Show("glyph gen " + bitmapImgSaveFileName);
                }
                else
                {
                    //save each glyph
                    if (saveEachGlyphSeparatly)
                    {
                        SaveImgBufferToFile(glyphImg, bitmapImgSaveFileName + "_" + gindex + ".png");
                    }
                }
            });
        }
Example #7
0
 public MySimpleGLBitmapAtlasManager(TextureKind textureKind)
     : base(textureKind)
 {
     SetLoadNewBmpDel(atlas =>
     {
         //create new one
         AtlasItemImage totalGlyphImg = atlas.TotalImg;
         //load to glbmp
         GLBitmap found   = new GLBitmap(totalGlyphImg.Bitmap, false);
         found.IsYFlipped = false;
         return(found);
     });
 }
Example #8
0
        public SimpleBitmapAtlasBuilder CreateTextureFontFromBuildDetail(
            Typeface typeface, float sizeInPoint,
            TextureKind textureKind,
            GlyphTextureBuildDetail[] details,
            OnEachGlyph onEachGlyphDel = null)
        {
            _onEachGlyphDel = onEachGlyphDel;
            //-------------------------------------------------------------
            var atlasBuilder = new SimpleBitmapAtlasBuilder();

            atlasBuilder.SetAtlasInfo(textureKind, sizeInPoint);
            //-------------------------------------------------------------
            int j = details.Length;

            for (int i = 0; i < j; ++i)
            {
                GlyphTextureBuildDetail detail = details[i];
                if (detail.ScriptLang != null)
                {
                    //skip those script lang=null
                    //2. find associated glyph index base on input script langs
                    List <ushort> outputGlyphIndexList = new List <ushort>();
                    typeface.CollectAllAssociateGlyphIndex(outputGlyphIndexList, detail.ScriptLang);
                    CreateTextureFontFromGlyphIndices(typeface,
                                                      sizeInPoint,
                                                      detail.HintTechnique,
                                                      atlasBuilder,
                                                      GetUniqueGlyphIndexList(outputGlyphIndexList)
                                                      );
                }
            }
            for (int i = 0; i < j; ++i)
            {
                GlyphTextureBuildDetail detail = details[i];
                if (detail.OnlySelectedGlyphIndices != null)
                {
                    //skip those script lang=null
                    //2. find associated glyph index base on input script langs

                    CreateTextureFontFromGlyphIndices(typeface,
                                                      sizeInPoint,
                                                      detail.HintTechnique,
                                                      atlasBuilder,
                                                      detail.OnlySelectedGlyphIndices
                                                      );
                }
            }

            _onEachGlyphDel = null;//reset
            return(atlasBuilder);
        }
Example #9
0
        public MySimpleGLBitmapFontManager(TextureKind textureKind, LayoutFarm.OpenFontTextService textServices)
        {
            this.textServices = textServices;
            //glyph cahce for specific atlas
            _loadedGlyphs = new GLBitmapCache <SimpleFontAtlas>(atlas =>
            {
                //create new one
                Typography.Rendering.GlyphImage totalGlyphImg = atlas.TotalGlyph;
                //load to glbmp
                GLBitmap found = new GLBitmap(totalGlyphImg.Width, totalGlyphImg.Height, totalGlyphImg.GetImageBuffer(), false);
                found.IsInvert = false;
                return(found);
            });

            _textureKind = textureKind;
        }
        public void CreateTextureFontFromInputChars(
            Typeface typeface, float sizeInPoint,
            TextureKind textureKind,
            char[] chars, OnEachFinishTotal onFinishTotal)
        {
            //convert input chars into glyphIndex
            List <ushort> glyphIndices = new List <ushort>(chars.Length);
            int           i            = 0;

            foreach (char ch in chars)
            {
                glyphIndices.Add(typeface.LookupIndex(ch));
                i++;
            }

            CreateTextureFontFromGlyphIndices(typeface, sizeInPoint, textureKind, GetUniqueGlyphIndexList(glyphIndices), onFinishTotal);
        }
Example #11
0
 public MySimpleGLBitmapFontManager(TextureKind textureKind, LayoutFarm.OpenFontTextService textServices)
     : base(textureKind, textServices)
 {
     SetLoadNewBmpDel(atlas =>
     {
         //create new one
         GlyphImage totalGlyphImg = atlas.TotalGlyph;
         //load to glbmp
         GLBitmap found = new GLBitmap(
             PixelFarm.CpuBlit.MemBitmap.CreateFromCopy(
                 totalGlyphImg.Width,
                 totalGlyphImg.Height,
                 totalGlyphImg.GetImageBuffer()),
             true); //set true=> glbmp is the original owner of the membmp, when glbmp is disposed => the membmp is disposed too
         found.IsYFlipped = false;
         return(found);
     });
 }
        public void CreateTextureFontFromScriptLangs(
            Typeface typeface, float sizeInPoint,
            TextureKind textureKind,
            ScriptLang[] scLangs,
            OnEachFinishTotal onFinishTotal)
        {
            //2. find associated glyph index base on input script langs
            List <ushort> outputGlyphIndexList = new List <ushort>();

            //
            foreach (ScriptLang scLang in scLangs)
            {
                typeface.CollectAllAssociateGlyphIndex(outputGlyphIndexList, scLang);
            }
            //

            CreateTextureFontFromGlyphIndices(typeface, sizeInPoint, textureKind, GetUniqueGlyphIndexList(outputGlyphIndexList), onFinishTotal);
        }
Example #13
0
        public void AddSimpleAtlasFile(RequestFont reqFont,
                                       string bitmapAtlasFile, string imgFile, TextureKind textureKind)
        {
            //TODO: use 'File' provider to access system file
            var fontAtlasFile = new BitmapAtlasFile();

            using (FileStream fs = new FileStream(bitmapAtlasFile, FileMode.Open))
            {
                fontAtlasFile.Read(fs);
            }

            _atlasList.Add(new TempMergingAtlasInfo()
            {
                reqFont             = reqFont,
                simpleFontAtlasFile = bitmapAtlasFile,
                imgFile             = imgFile,
                fontAtlasFile       = fontAtlasFile,
                textureKind         = textureKind
            });
        }
Example #14
0
        private static TextureKind Kind(string path)
        {
            TextureKind kind = TextureKind.None;

            foreach (var _temp in dictionary)
            {
                for (int i = 0; i < _temp.Value.Count; i++)
                {
                    if (path.StartsWith(_temp.Value[i]))
                    {
                        kind = _temp.Key;
                        break;
                    }
                }
                if (kind != TextureKind.None)
                {
                    break;
                }
            }
            return(kind);
        }
Example #15
0
        public static void Start(TextureImporter texture)
        {
            string path = AssetDatabase.GetAssetPath(texture);

            TextureKind kind = Kind(path);

            if (kind == TextureKind.None)
            {
                return;
            }

            switch (kind)
            {
            case TextureKind.Texture:
            case TextureKind.TexturePowerof2:
                texture.textureType  = TextureImporterType.Default;
                texture.textureShape = TextureImporterShape.Texture2D;
                break;

            case TextureKind.Image:
                texture.textureType = TextureImporterType.Sprite;
                break;

            case TextureKind.NormalMap:
                texture.textureType  = TextureImporterType.NormalMap;
                texture.textureShape = TextureImporterShape.Texture2D;
                break;
            }
            texture.sRGBTexture = true;
            bool alpha = texture.DoesSourceTextureHaveAlpha();

            texture.alphaSource         = alpha ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None;
            texture.alphaIsTransparency = alpha;
            texture.npotScale           = kind == TextureKind.TexturePowerof2 ? TextureImporterNPOTScale.ToNearest : TextureImporterNPOTScale.None;
            texture.isReadable          = false;
            texture.mipmapEnabled       = false;
            texture.crunchedCompression = true;
            PlatformSettings(texture, "ios");
            PlatformSettings(texture, "android");
        }
        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());
        }
Example #18
0
        public void DrawString(Painter p, char[] buffer, int startAt, int len, double x, double y)
        {
            //if (_stencilBmp == null)
            //{
            //    //create a stencil bmp
            //    _stencilBmp = new ActualBitmap(p.Width, p.Height);
            //    _stencilBlender = new PixelProcessing.SubBitmapBlender(_stencilBmp, new PixelProcessing.PixelBlenderBGRA());
            //    _backPainter = AggPainter.Create(_stencilBmp);
            //    //------
            //}

            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);

            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
            y -= _font.LineSpacingInPixels;

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

            float g_x   = 0;
            float g_y   = 0;
            int   baseY = (int)Math.Round(y);

            //-------------------------------------
            //load texture
            //_pcx.LoadTexture1(_glBmp);
            //-------------------------------------


            float acc_x = 0;
            float acc_y = 0;

            p.DrawImage(_fontBmp, 100, 100);

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

                acc_x += (float)Math.Round(glyph.AdvanceX * scale);
                //g_x = (float)Math.Round(g_x);
                g_y = (float)Math.Floor(g_y);

                //p.RenderQuality = RenderQuality.Fast;

                //*** the atlas is inverted so...
                //p.DrawImage(_fontBmp, g_x, g_y, srcX, _fontBmp.Height - (srcY), srcW, srcH);
                //p.DrawImage(_fontBmp, g_x, g_y);

                //1. draw to back buffer
                //_backPainter.DrawImage(_fontBmp, g_x, g_y, srcX, _fontBmp.Height - (srcY), srcW, srcH);

                //2. then copy content to this

                //p.DrawImage(_stencilBmp, 100, 100);
                p.DrawImage(_fontBmp, g_x, g_y, srcX, _fontBmp.Height - (srcY + srcH), srcW, srcH);
                switch (textureKind)
                {
                default:
                    break;

                case TextureKind.StencilLcdEffect:
                {
                }
                break;
                }



                //copy some part from the bitmap
                //switch (textureKind)
                //{
                //    case TextureKind.Msdf:
                //        _pcx.DrawSubImageWithMsdf(_glBmp,
                //            ref srcRect,
                //            g_x,
                //            g_y,
                //            scaleFromTexture);
                //        break;
                //    case TextureKind.StencilGreyScale:
                //        //stencil gray scale with fill-color
                //        _pcx.DrawGlyphImageWithStecil(_glBmp,
                //         ref srcRect,
                //            g_x,
                //            g_y,
                //            scaleFromTexture);
                //        break;
                //    case TextureKind.Bitmap:
                //        _pcx.DrawSubImage(_glBmp,
                //         ref srcRect,
                //            g_x,
                //            g_y,
                //            scaleFromTexture);
                //        break;
                //    case TextureKind.StencilLcdEffect:
                //        _pcx.WriteVboToList(
                //          _vboBufferList,
                //          _indexList,
                //          ref srcRect,
                //          g_x,
                //          g_y,
                //          scaleFromTexture);

                //        break;
                //}
            }
            //-------
            //we create vbo first
            //then render
        }
Example #19
0
        public void DrawImage(GLPainter glPainter, AtlasImageBinder atlasImgBinder, float left, float top)
        {
            if (atlasImgBinder.State == BinderState.Loaded && atlasImgBinder.LatestPainterId != _painterId)
            {
                atlasImgBinder.State           = BinderState.Unload;
                atlasImgBinder.LatestPainterId = _painterId;
            }


            switch (atlasImgBinder.State)
            {
            case BinderState.Loaded:
            {
                if (PixelFarm.Drawing.ImageBinder.GetCacheInnerImage(atlasImgBinder) is GLBitmap glbmp)
                {
                    AtlasItem atlasItem = atlasImgBinder.AtlasItem;
                    Rectangle srcRect   =
                        new Rectangle(atlasItem.Left,
                                      atlasItem.Top, //diff from font atlas***
                                      atlasItem.Width,
                                      atlasItem.Height);

                    switch (atlasImgBinder.TextureKind)
                    {
                    default:
                    case TextureKind.Msdf:
                        throw new NotSupportedException();

                    case TextureKind.Bitmap:
                    {
                        //atlasImgBinder.State = BinderState.Loaded;
                        //ImageBinder.SetCacheInnerImage(atlasImgBinder, glbmp, false);
                        //atlasImgBinder.AtlasItem = atlasItem;

                        glPainter.Core.DrawSubImage(glbmp,
                                                    srcRect,
                                                    left,
                                                    top);
                    }
                    break;
                    }
                }
            }
            break;

            case BinderState.Unload:
            {
                atlasImgBinder.LatestPainterId = _painterId;
                //load img first
                if (_bmpAtlas == null || _lastestImgFile != atlasImgBinder.AtlasName)
                {
                    _bmpAtlas = _atlasManager.GetBitmapAtlas(atlasImgBinder.AtlasName, out _glBmp);
                    if (_bmpAtlas == null)
                    {
                        //error
                        atlasImgBinder.State = BinderState.Error;        //not found
                        return;
                    }
                    _lastestImgFile = atlasImgBinder.AtlasName;
                }
                //--------

                if (_bmpAtlas.TryGetItem(atlasImgBinder.ImageName, out AtlasItem atlasItem))
                {
                    //found map data
                    Rectangle srcRect =
                        new Rectangle(atlasItem.Left,
                                      atlasItem.Top, //diff from font atlas***
                                      atlasItem.Width,
                                      atlasItem.Height);

                    TextureKind textureKind = _bmpAtlas.TextureKind;
                    switch (textureKind)
                    {
                    default:
                    case TextureKind.Msdf:
                        throw new NotSupportedException();

                    case TextureKind.Bitmap:
                    {
                        atlasImgBinder.State = BinderState.Loaded;
                        ImageBinder.SetCacheInnerImage(atlasImgBinder, _glBmp, false);
                        atlasImgBinder.AtlasItem = atlasItem;
                        atlasImgBinder.SetPreviewImageSize(atlasItem.Width, atlasItem.Height);
                        atlasImgBinder.RaiseImageChanged();
                        atlasImgBinder.TextureKind = textureKind;
                        glPainter.Core.DrawSubImage(_glBmp,
                                                    srcRect,
                                                    left,
                                                    top);
                    }
                    break;
                    }
                }
                else
                {
                    atlasImgBinder.State = BinderState.Error;        //not found
                }
            }
            break;
            }
#if DEBUG
            if (atlasImgBinder.State == BinderState.Unload)
            {
            }
#endif
        }
Example #20
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);
            }
        }
 public void WriteTotalImageInfo(ushort width, ushort height, byte colorComponent, TextureKind textureKind)
 {
     _writer.Write((ushort)FontTextureObjectKind.TotalImageInfo);
     _writer.Write(width);
     _writer.Write(height);
     _writer.Write(colorComponent);
     _writer.Write((byte)textureKind);
 }
 public void SetAtlasInfo(TextureKind textureKind, float fontSizeInPts)
 {
     this.TextureKind      = textureKind;
     this.FontSizeInPoints = fontSizeInPts;
 }
Example #23
0
 public BitmapFontManager(TextureKind textureKind, LayoutFarm.OpenFontTextService textServices)
 {
     _textServices = textServices;
     _textureKind  = textureKind;
 }
        public void DrawString(RenderVxFormattedString renderVx, double x, double y)
        {
            RenderVxGlyphPlan[] glyphPlans = renderVx.glyphList;
            int n = glyphPlans.Length;

            EnsureLoadGLBmp();

            //PERF:
            //TODO: review here, can we cache the glbmp for later use
            //not to create it every time

            float scaleFromTexture = _finalTextureScale;

            TextureKind textureKind = _fontAtlas.TextureKind;
            float       g_x         = 0;
            float       g_y         = 0;
            int         baseY       = (int)Math.Round(y);
            float       scale       = 1;

            for (int i = 0; i < n; ++i)
            {
                //PERF:
                //TODO:
                //render a set of glyph instead of one glyph per time ***
                RenderVxGlyphPlan glyph = glyphPlans[i];
                Typography.Rendering.TextureFontGlyphData glyphData;
                if (!_fontAtlas.TryGetGlyphDataByCodePoint(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);
                //--------------------------
                g_x = (float)(x + (glyph.x * scale - glyphData.TextureXOffset) * scaleFromTexture); //ideal x
                g_y = (float)((glyph.y * scale - glyphData.TextureYOffset + srcRect.Height) * scaleFromTexture);

                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.DrawGlyphImageWithSubPixelRenderingTechnique(_glBmp,
                                                                       ref srcRect,
                                                                       g_x,
                                                                       g_y,
                                                                       scaleFromTexture);
                    break;
                }
            }
        }
Example #25
0
 public DefVar(TextureKind kind, DestRegister reg)
 {
     this.kind = kind;
     this.reg = reg;
 }
 //create new one
 //load to glbmp
 public MySimpleGLBitmapAtlasManager(TextureKind textureKind)
     : base(atlas => new GLBitmap(atlas.MainBitmap, false) { IsYFlipped = false })
 {
 }
Example #27
0
        internal void DefineVar(TextureKind kind, DestRegister reg)
        {
            switch (reg.Kind) {
            case RegKind.Texture:
                if (tex0 != null)
                    throw new Exception ("Cannot handle multiple texture registers");
                if (reg.Number != 0)
                    throw new Exception ("Only one texture register supported");
                //FIXME since we only support 2d textures, is this the right thing?
                if (reg.WriteMask != DestRegister.MakeMask (true, true, false, false))
                    throw new Exception ("Cannot handle a texture register with a write mask different than rg");
                tex0 = DeclareAndZeroLocal (typeof (Vector4f), "tex_" + reg.Number); //FIXME using a pair of floats would be faster
                break;
            case RegKind.SamplerState:
                if (kind != TextureKind.Text2d)
                    throw new Exception ("Cannot handle non text2d samplers.");

                if (samplerMap.ContainsKey (reg.Number))
                    throw new Exception (String.Format ("sampler {0} already defined", reg.Number));

                LocalBuilder lb = DeclareLocal (typeof (Sampler), "sampler_" + reg.Number);
                samplerMap [reg.Number] = lb;

                ilgen.Emit (OpCodes.Ldarg_0);
                ilgen.Emit (OpCodes.Ldc_I4, reg.Number);
                ilgen.Emit (OpCodes.Call, typeof (ShaderData).GetMethod ("GetSampler"));
                ilgen.Emit (OpCodes.Stloc, lb);
                break;
            }
        }
        void CreateTextureFontFromGlyphIndices(
            Typeface typeface,
            float sizeInPoint,
            TextureKind textureKind,
            ushort[] glyphIndices, OnEachFinishTotal onFinishTotal)
        {
            if (onFinishTotal == null)
            {
                return;
            }
            //sample: create sample msdf texture
            //-------------------------------------------------------------
            var builder = new GlyphPathBuilder(typeface);

            builder.UseTrueTypeInstructions = this.UseTrueTypeInstruction;
            //-------------------------------------------------------------
            var atlasBuilder = new SimpleFontAtlasBuilder();

            atlasBuilder.SetAtlasInfo(textureKind, sizeInPoint);
            //-------------------------------------------------------------

            //
            MsdfGenParams      msdfGenParams = null;
            AggGlyphTextureGen aggTextureGen = null;

            if (textureKind == TextureKind.Msdf)
            {
                msdfGenParams = new MsdfGenParams();
            }
            else
            {
                aggTextureGen = new AggGlyphTextureGen();
            }


            float pxscale = typeface.CalculateScaleToPixelFromPointSize(sizeInPoint);
            int   j       = glyphIndices.Length;

            for (int i = 0; i < j; ++i)
            {
                //build glyph
                ushort gindex = glyphIndices[i];
                builder.BuildFromGlyphIndex(gindex, -1);
                GlyphImage glyphImg = null;
                if (textureKind == TextureKind.Msdf)
                {
                    var glyphToContour = new GlyphContourBuilder();
                    //glyphToContour.Read(builder.GetOutputPoints(), builder.GetOutputContours());
                    builder.ReadShapes(glyphToContour);
                    msdfGenParams.shapeScale = 1f / 64; //as original
                    glyphImg = MsdfGlyphGen.CreateMsdfImage(glyphToContour, msdfGenParams);
                }
                else
                {
                    //create alpha channel texture
                    aggTextureGen.TextureKind = textureKind;
                    glyphImg = aggTextureGen.CreateGlyphImage(builder, pxscale);
                }
                //

                atlasBuilder.AddGlyph(gindex, glyphImg);
                onFinishTotal(gindex, glyphImg, null);
            }
            onFinishTotal(0, null, atlasBuilder);
        }
        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();
            }
        }
        public void PrepareStringForRenderVx(GLRenderVxFormattedString renderVxFormattedString, char[] buffer, int startAt, int len)
        {
            int top  = 0; //simulate top
            int left = 0; //simulate left

            _vboBuilder.Clear();
            _vboBuilder.SetTextureInfo(_glBmp.Width, _glBmp.Height, _glBmp.IsYFlipped, _pcx.OriginKind);

            //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;
            //--------------------------
            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

            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 ***
                //
                _vboBuilder.WriteVboToList(ref srcRect, g_left, g_top);
            }
            //---
            //copy vbo result and store into  renderVx
            float[]  vertexList = _vboBuilder._buffer.ToArray();
            ushort[] indexList  = _vboBuilder._indexList.ToArray();
            //---

            renderVxFormattedString.IndexArrayCount = _vboBuilder._indexList.Count;
            renderVxFormattedString.IndexArray      = _vboBuilder._indexList.ToArray();
            renderVxFormattedString.VertexCoords    = _vboBuilder._buffer.ToArray();
            _vboBuilder.Clear();
        }
Example #31
0
 public TextureKindAndDescription(TextureKind kind, string desc)
 {
     Kind        = kind;
     Description = desc;
 }
Example #32
0
        public void DrawString(Painter p, char[] buffer, int startAt, int len, double x, double y)
        {
            //if (_stencilBmp == null)
            //{
            //    //create a stencil bmp
            //    _stencilBmp = new ActualBitmap(p.Width, p.Height);
            //    _stencilBlender = new PixelProcessing.SubBitmapBlender(_stencilBmp, new PixelProcessing.PixelBlenderBGRA());
            //    _backPainter = AggPainter.Create(_stencilBmp);
            //    //------
            //}

            int j = buffer.Length;
            //create temp buffer span that describe the part of a whole char buffer
            var textBufferSpan = new Typography.Text.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 = _txtClient.CreateGlyphPlanSeq(textBufferSpan, _font);

            ResolvedFont resolvedFont = _textServices.ResolveFont(_font);
            Typeface     typeface     = resolvedFont.Typeface;
            float        scale        = typeface.CalculateScaleToPixelFromPointSize(_font.SizeInPoints);

            int recommendLineSpacing = resolvedFont.LineSpacingInPixels;

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

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

            float g_x   = 0;
            float g_y   = 0;
            int   baseY = (int)Math.Round(y);

            //-------------------------------------
            //load texture
            //_pcx.LoadTexture1(_glBmp);
            //-------------------------------------


            float acc_x = 0;
            float acc_y = 0;

            p.DrawImage(_fontBmp, 100, 100);

            int seqLen = glyphPlanSeq.Count;

            for (int i = 0; i < seqLen; ++i)
            {
                UnscaledGlyphPlan glyph = glyphPlanSeq[i];
                AtlasItem         glyphData;
                if (!_fontAtlas.TryGetItem(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
                //--------------------------
                g_x = (float)(x + (ngx - glyphData.TextureXOffset) * scaleFromTexture); //ideal x
                g_y = (float)(y + (ngy - glyphData.TextureYOffset + srcH) * scaleFromTexture);

                acc_x += (float)Math.Round(glyph.AdvanceX * scale);
                //g_x = (float)Math.Round(g_x);
                g_y = (float)Math.Floor(g_y);


                p.DrawImage(_fontBmp, g_x, g_y, srcX, srcY, srcW, srcH);
            }
            //-------
            //we create vbo first
            //then render
        }