public void DrawString(char[] text, int startAt, int len, double x, double y)
        {
            float ox = canvasPainter.OriginX;
            float oy = canvasPainter.OriginY;

            //1. update some props..
            //2. update current type face
            UpdateTypefaceAndGlyphBuilder();
            Typeface typeface = _glyphPathBuilder.Typeface;
            //3. layout glyphs with selected layout technique
            //TODO: review this again, we should use pixel?

            float fontSizePoint = this.FontSizeInPoints;
            float scale         = typeface.CalculateToPixelScaleFromPointSize(fontSizePoint);

            _outputGlyphPlans.Clear();
            _glyphLayout.Layout(typeface, text, startAt, len, _outputGlyphPlans);
            //4. render each glyph
            int j = _outputGlyphPlans.Count;

            //---------------------------------------------------
            //consider use cached glyph, to increase performance
            hintGlyphCollection.SetCacheInfo(typeface, fontSizePoint, this.HintTechnique);
            //---------------------------------------------------
            for (int i = 0; i < j; ++i)
            {
                GlyphPlan glyphPlan = _outputGlyphPlans[i];
                //-----------------------------------
                //TODO: review here ***
                //PERFORMANCE revisit here
                //if we have create a vxs we can cache it for later use?
                //-----------------------------------
                VertexStore glyphVxs;
                if (!hintGlyphCollection.TryGetCacheGlyph(glyphPlan.glyphIndex, out glyphVxs))
                {
                    //if not found then create new glyph vxs and cache it
                    _glyphPathBuilder.SetHintTechnique(this.HintTechnique);
                    _glyphPathBuilder.BuildFromGlyphIndex(glyphPlan.glyphIndex, fontSizePoint);
                    //-----------------------------------
                    _tovxs.Reset();
                    _glyphPathBuilder.ReadShapes(_tovxs);

                    //TODO: review here,
                    //float pxScale = _glyphPathBuilder.GetPixelScale();
                    glyphVxs = new VertexStore();
                    _tovxs.WriteOutput(glyphVxs, _vxsPool);
                    //
                    hintGlyphCollection.RegisterCachedGlyph(glyphPlan.glyphIndex, glyphVxs);
                }
                canvasPainter.SetOrigin((float)(glyphPlan.x * scale + x), (float)(glyphPlan.y * scale + y));
                canvasPainter.Fill(glyphVxs);
            }
            //restore prev origin
            canvasPainter.SetOrigin(ox, oy);
        }
        public override void DrawGlyphPlanList(List <GlyphPlan> glyphPlanList, int startAt, int len, float xpos, float ypos)
        {
            CanvasPainter canvasPainter = this.TargetCanvasPainter;
            Typeface      typeface      = _glyphPathBuilder.Typeface;
            //3. layout glyphs with selected layout technique
            //TODO: review this again, we should use pixel?

            float fontSizePoint = this.FontSizeInPoints;
            float scale         = typeface.CalculateFromPointToPixelScale(fontSizePoint);


            //4. render each glyph
            float ox        = canvasPainter.OriginX;
            float oy        = canvasPainter.OriginY;
            int   endBefore = startAt + len;

            //---------------------------------------------------
            //consider use cached glyph, to increase performance
            hintGlyphCollection.SetCacheInfo(typeface, fontSizePoint, this.HintTechnique);
            //---------------------------------------------------
            for (int i = startAt; i < endBefore; ++i)
            {
                GlyphPlan glyphPlan = glyphPlanList[i];
                //-----------------------------------
                //TODO: review here ***
                //PERFORMANCE revisit here
                //if we have create a vxs we can cache it for later use?
                //-----------------------------------
                VertexStore glyphVxs;
                if (!hintGlyphCollection.TryGetCacheGlyph(glyphPlan.glyphIndex, out glyphVxs))
                {
                    //if not found then create new glyph vxs and cache it
                    _glyphPathBuilder.BuildFromGlyphIndex(glyphPlan.glyphIndex, fontSizePoint);
                    //-----------------------------------
                    _tovxs.Reset();
                    _glyphPathBuilder.ReadShapes(_tovxs);

                    //TODO: review here,
                    //float pxScale = _glyphPathBuilder.GetPixelScale();
                    glyphVxs = new VertexStore();
                    _tovxs.WriteOutput(glyphVxs, _vxsPool);
                    //
                    hintGlyphCollection.RegisterCachedGlyph(glyphPlan.glyphIndex, glyphVxs);
                }
                canvasPainter.SetOrigin((float)(glyphPlan.x * scale + xpos), (float)(glyphPlan.y * scale + ypos));
                canvasPainter.Fill(glyphVxs);
            }
            //restore prev origin
            canvasPainter.SetOrigin(ox, oy);
        }
Exemple #3
0
        static SimpleFontAtlasBuilder CreateAggSubPixelRenderingTextureFont(
            Typeface typeface, float sizeInPoint, HintTechnique hintTech, IEnumerable <ushort> glyphIndexIter)
        {
            ////read type face from file
            //Typeface typeface;
            //using (var fs = new FileStream(fontfile, FileMode.Open, FileAccess.Read))
            //{
            //    var reader = new OpenFontReader();
            //    //1. read typeface from font file
            //    typeface = reader.Read(fs);
            //}
            //sample: create sample msdf texture
            //-------------------------------------------------------------
            var builder = new GlyphPathBuilder(typeface);

            builder.SetHintTechnique(hintTech);
            //-------------------------------------------------------------
            var atlasBuilder = new SimpleFontAtlasBuilder();

            atlasBuilder.SetAtlasInfo(TextureKind.AggSubPixel, sizeInPoint);
            VertexStorePool vxsPool = new VertexStorePool();

            //create agg cavnas

            foreach (ushort gindex in glyphIndexIter)
            {
                //build glyph

                builder.BuildFromGlyphIndex(gindex, sizeInPoint);


                var txToVxs = new GlyphTranslatorToVxs();
                builder.ReadShapes(txToVxs);
                //
                //create new one
                var glyphVxs = new VertexStore();
                txToVxs.WriteOutput(glyphVxs, vxsPool);
                //find bound

                //--------------------------------------------
                //GlyphImage glyphImg = new GlyphImage()
                RectD bounds = new Agg.RectD();
                BoundingRect.GetBoundingRect(new VertexStoreSnap(glyphVxs), ref bounds);

                //--------------------------------------------
                int w = (int)System.Math.Ceiling(bounds.Width);
                int h = (int)System.Math.Ceiling(bounds.Height);
                if (w < 5)
                {
                    w = 5;
                }
                if (h < 5)
                {
                    h = 5;
                }
                //translate to positive quadrant
                double dx = (bounds.Left < 0) ? -bounds.Left : 0;
                double dy = (bounds.Bottom < 0) ? -bounds.Bottom : 0;
                w = w * 4;

                if (dx != 0 || dy != 0)
                {
                    Agg.Transform.Affine transformMat = Agg.Transform.Affine.NewTranslation(dx, dy);
                    VertexStore          vxs2         = new VertexStore();
                    glyphVxs.TranslateToNewVxs(dx, dy, vxs2);
                    glyphVxs = vxs2;
                }
                //--------------------------------------------
                //create glyph img
                ActualImage      img         = new Agg.ActualImage(w, h, PixelFormat.ARGB32);
                ImageGraphics2D  imgCanvas2d = new Agg.ImageGraphics2D(img);
                AggCanvasPainter painter     = new Agg.AggCanvasPainter(imgCanvas2d);
                //we use white glyph on black bg for this texture
                painter.Clear(Color.Black); //fill with black
                painter.FillColor   = Color.White;
                painter.StrokeColor = Color.White;
                //--------------------------------------------

                painter.UseSubPixelRendering = true;
                //--------------------------------------------


                //--------------------------------------------
                painter.Fill(glyphVxs);
                //--------------------------------------------
                var glyphImage = new GlyphImage(w, h);
                glyphImage.TextureOffsetX = dx;
                glyphImage.TextureOffsetY = dy;
                glyphImage.SetImageBuffer(ActualImage.GetBuffer2(img), false);
                //copy data from agg canvas to glyph image
                atlasBuilder.AddGlyph(gindex, glyphImage);

                //int[] buffer = glyphImage.GetImageBuffer();
                //using (var bmp = new System.Drawing.Bitmap(glyphImage.Width, glyphImage.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                //{
                //    var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, glyphImage.Width, glyphImage.Height),
                //        System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
                //    System.Runtime.InteropServices.Marshal.Copy(buffer, 0, bmpdata.Scan0, buffer.Length);
                //    bmp.UnlockBits(bmpdata);
                //    bmp.Save("d:\\WImageTest\\a001_subpix_xn2_" + gindex + ".png");
                //}
            }
            //var glyphImg2 = atlasBuilder.BuildSingleImage();
            //using (var bmp = new System.Drawing.Bitmap(glyphImg2.Width, glyphImg2.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
            //{
            //    var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, glyphImg2.Width, glyphImg2.Height),
            //        System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
            //    int[] intBuffer = glyphImg2.GetImageBuffer();

            //    System.Runtime.InteropServices.Marshal.Copy(intBuffer, 0, bmpdata.Scan0, intBuffer.Length);
            //    bmp.UnlockBits(bmpdata);
            //    bmp.Save("d:\\WImageTest\\a_total.png");
            //}
            //atlasBuilder.SaveFontInfo("d:\\WImageTest\\a_info.xml");

            return(atlasBuilder);
        }