Пример #1
0
        VertexStore BuildVxsForGlyph(GlyphOutlineBuilder builder, char character, float size)
        {
            //-----------
            //TODO: review here
            builder.Build(character, size);
            var txToVxs = new GlyphTranslatorToVxs();

            builder.ReadShapes(txToVxs);

            VertexStore v2 = new VertexStore();

            using (Tools.BorrowVxs(out var v0))
                using (Tools.BorrowCurveFlattener(out var flattener))
                {
                    txToVxs.WriteOutput(v0);

                    Q1RectD bounds = v0.GetBoundingRect();

                    AffineMat mat = AffineMat.Iden();
                    mat.Scale(1, -1);//flipY
                    mat.Translate(0, bounds.Height);

                    flattener.MakeVxs(v0, mat, v2);
                }
            return(v2);
        }
Пример #2
0
        public override Rectangle GetRectBounds()
        {
            if (!_evalRectBounds)
            {
                //
                Q1RectD bound1 = BoundingRect.GetBoundingRect(_vxs);
                _bounds = new Rectangle(
                    (int)Math.Round(bound1.Left),
                    (int)Math.Round(bound1.Bottom), //***
                    (int)Math.Round(bound1.Width),
                    (int)Math.Round(bound1.Height));
                _evalRectBounds = true;
            }

            return(_bounds);
        }
Пример #3
0
        private void button2_Click(object sender, EventArgs e)
        {
            //EXAMPLE, low-level

            //this show how to render a glyph on screen
            //read font file
            LoadFont();
            //inside a font
            //get some glyph by its name
            //Glyph oneGlyph = _latinModernMathFont.GetGlyphByName("one"); //for get glyph by name

            ushort glyphIndex = _latinModernMathFont.GetGlyphIndex((int)'1');


            //a glyph contains coordinates of line and curves
            //we transform data inside it to vxs
            //this is done by GlyphContour builder
            GlyphTranslatorToVxs glyphTxToVxs   = new GlyphTranslatorToVxs();
            GlyphOutlineBuilder  outlineBuilder = new GlyphOutlineBuilder(_latinModernMathFont);

            outlineBuilder.BuildFromGlyphIndex(glyphIndex, 20); //read data into outline builder
            outlineBuilder.ReadShapes(glyphTxToVxs);            //translate data inside outline builder to vxs
            using (Tools.BorrowVxs(out var v1, out var v2))
                using (Tools.BorrowAggPainter(_memBmp, out var p))
                {
                    glyphTxToVxs.WriteOutput(v1);
                    //original v1 is head-down
                    Q1RectD bounds = v1.GetBoundingRect(); //with this bounds you also know glyph width/height
                    //we want head up, so => flip it
                    AffineMat aff = AffineMat.Iden();
                    aff.Translate(-bounds.Width / 2, -bounds.Height / 2);
                    aff.Scale(1, -1);
                    aff.Translate(bounds.Width / 2, bounds.Height / 2);

                    aff.TransformToVxs(v1, v2);

                    //copy data
                    //now the glyph data is inside v1
                    //test paint this glyph
                    p.Clear(PixelFarm.Drawing.Color.White);
                    p.Fill(v2, PixelFarm.Drawing.Color.Black);
                }

            //-----------
            CopyBitmapToScreen();
        }
Пример #4
0
        public static void ReverseClockDirection(this VertexStore src, VertexStore outputVxs)
        {
            //temp fix for reverse clock direction
            Q1RectD bounds  = src.GetBoundingRect();
            double  centerX = (bounds.Left + bounds.Width) / 2;
            double  centerY = (bounds.Top + bounds.Height) / 2;

            //Affine aff = Affine.New(AffinePlan.Translate(-centerX, -centerY),
            //     AffinePlan.Scale(1, -1),//flipY,
            //     AffinePlan.Translate(centerX, centerY));
            AffineMat aff = AffineMat.Iden();

            aff.Translate(-centerX, -centerY);
            aff.Translate(1, -1);//flipY
            aff.Translate(centerX, centerY);
            aff.TransformToVxs(src, outputVxs);
        }
Пример #5
0
        public static VgVisualElement CreateVgVisualElementFromGlyph(string actualFontFile, float sizeInPts, char c)
        {
            if (!s_loadedTypefaces.TryGetValue(actualFontFile, out Typography.OpenFont.Typeface typeface))
            {
                //create vgrender vx from font-glyph
                //
                using (System.IO.FileStream fs = new FileStream(actualFontFile, FileMode.Open))
                {
                    Typography.OpenFont.OpenFontReader reader = new Typography.OpenFont.OpenFontReader();
                    typeface = reader.Read(fs);
                }
            }
            if (_glyphMaskStore == null)
            {
                _glyphMaskStore = new Typography.OpenFont.Contours.GlyphMeshStore();
                _glyphMaskStore.FlipGlyphUpward = true;
            }
            _glyphMaskStore.SetFont(typeface, sizeInPts);
            //-----------------
            VertexStore vxs  = _glyphMaskStore.GetGlyphMesh(typeface.GetGlyphIndex(c));
            var         spec = new SvgPathSpec()
            {
                FillColor = Color.Red
            };
            VgVisualDoc     renderRoot = new VgVisualDoc();
            VgVisualElement renderE    = new VgVisualElement(WellknownSvgElementName.Path, spec, renderRoot);


            //offset the original vxs to (0,0) bounds
            //PixelFarm.CpuBlit.RectD bounds = vxs.GetBoundingRect();
            //Affine translate = Affine.NewTranslation(-bounds.Left, -bounds.Bottom);
            //renderE._vxsPath = vxs.CreateTrim(translate);

            Q1RectD bounds    = vxs.GetBoundingRect();
            Affine  translate = Affine.NewTranslation(-bounds.Left, -bounds.Bottom);

            renderE.VxsPath = vxs.CreateTrim(translate);
            return(renderE);
        }
Пример #6
0
        public BitmapAtlasItemSource CreateAtlasItem(GlyphOutlineBuilder builder, float pxscale)
        {
            _txToVxs.Reset();
            //1. builder read shape and translate it with _txToVxs
            builder.ReadShapes(_txToVxs);

            using (Tools.BorrowVxs(out var glyphVxs, out var vxs2))
            {
                //2. write translated data (in the _txToVxs) to glyphVxs

                _txToVxs.WriteOutput(glyphVxs, pxscale);

                Q1RectD bounds = glyphVxs.GetBoundingRect();

                //--------------------------------------------
                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;
                }
                //we need some margin
                int horizontal_margin = 1;
                int vertical_margin   = 1;

                //translate to positive quadrant and use minimum space

                int dx = (int)Math.Ceiling((bounds.Left < 0) ? -bounds.Left : 0);
                int dy = 0;

                //vertical adjust =>since we need to move it, then move it with integer value
                if (bounds.Bottom < 0)
                {
                    dy = (int)Math.Ceiling(-bounds.Bottom);
                }
                else if (bounds.Bottom > 0)
                {
                    dy = (int)Math.Floor(-bounds.Bottom);
                }
                dx += horizontal_margin; //margin left
                dy += vertical_margin;
                //--------------------------------------------
                w = dx + w + horizontal_margin;            //+right margin

                h = vertical_margin + h + vertical_margin; //+bottom margin
                AggPainter painter = Painter;
                if (TextureKind == TextureKind.StencilLcdEffect)
                {
                    glyphVxs.TranslateToNewVxs(dx + 0.33f, dy, vxs2); //offset to proper x of subpixel rendering  ***
                    glyphVxs = vxs2;

                    Q1RectD bounds2 = vxs2.GetBoundingRect();
                    if (w < bounds2.Right)
                    {
                        w = (int)Math.Ceiling(bounds2.Right);
                    }
                    //
                    painter.UseLcdEffectSubPixelRendering = true;
                    //we use white glyph on black bg for this texture


                    painter.Clear(Color.Black);
                    painter.FillColor = Color.White;


                    //painter.Clear(Color.FromArgb(0, 255, 255, 255)); //white -transparent
                    //painter.FillColor = Color.Black;


                    //painter.Clear(Color.White);
                    //painter.FillColor = Color.Black;

                    //painter.Clear(Color.Empty);
                    //painter.FillColor = Color.Black;

                    painter.Fill(glyphVxs);

                    //apply sharpen filter
                    //painter.DoFilter(new RectInt(0, h, w, 0), 2);
                    //painter.DoFilter(new RectInt(0, h, w, 0), 2); //?
                }
                else
                {
                    glyphVxs.TranslateToNewVxs(dx, dy, vxs2);
                    glyphVxs = vxs2;

                    painter.UseLcdEffectSubPixelRendering = false;

                    if (TextureKind == TextureKind.StencilGreyScale)
                    {
                        painter.Clear(Color.Empty);
                        painter.FillColor = Color.Black;
                    }
                    else
                    {
                        painter.Clear(BackGroundColor);
                        painter.FillColor = this.GlyphColor;
                    }
                    painter.Fill(glyphVxs);
                }
                //


                if (w > painter.RenderSurface.DestBitmap.Width)
                {
                    w = painter.RenderSurface.DestBitmap.Width;
                }
                if (h > painter.RenderSurface.DestBitmap.Height)
                {
                    h = painter.RenderSurface.DestBitmap.Height;
                }

                var glyphImage = new BitmapAtlasItemSource(w, h);

#if DEBUG
                if (dx < short.MinValue || dx > short.MaxValue)
                {
                    throw new NotSupportedException();
                }
                if (dy < short.MinValue || dy > short.MaxValue)
                {
                    throw new NotSupportedException();
                }
#endif

                glyphImage.TextureXOffset = (short)dx;
                glyphImage.TextureYOffset = (short)dy;

                glyphImage.SetImageBuffer(MemBitmapExt.CopyImgBuffer(painter.RenderSurface.DestBitmap, w, h), false);
                //copy data from agg canvas to glyph image
                return(glyphImage);
            }
        }
Пример #7
0
        GlyphBitmap GetGlyphBitmapFromColorOutlineGlyph(ushort glyphIndex, GlyphMeshStore glyphMeshStore, ushort colorLayerStart)
        {
            //not found=> create a newone
            Typography.OpenFont.Tables.COLR _colrTable = _typeface.COLRTable;
            Typography.OpenFont.Tables.CPAL _cpalTable = _typeface.CPALTable;


            Q1RectD totalBounds = Q1RectD.ZeroIntersection();
            {
                //calculate bounds of this glyph
                ushort colorLayerCount = _colrTable.LayerCounts[glyphIndex];
                for (int c = colorLayerStart; c < colorLayerStart + colorLayerCount; ++c)
                {
                    BoundingRect.GetBoundingRect(glyphMeshStore.GetGlyphMesh(_colrTable.GlyphLayers[c]), ref totalBounds);
                }
            }
            //dbugExportCount++;
            var memBmp   = new MemBitmap((int)Math.Round(totalBounds.Width), (int)Math.Round(totalBounds.Height));//???
            int offset_x = 0;
            int offset_y = 0;

            using (Tools.BorrowAggPainter(memBmp, out AggPainter painter))
            {
                painter.Clear(Color.Transparent);
                painter.SetOrigin(0, 0);

                offset_x = -(int)(totalBounds.Left);
                offset_y = -(int)(totalBounds.Bottom);

                ushort colorLayerCount = _colrTable.LayerCounts[glyphIndex];
                int    palette         = 0; // FIXME: assume palette 0 for now
                for (int c = colorLayerStart; c < colorLayerStart + colorLayerCount; ++c)
                {
                    _cpalTable.GetColor(
                        _cpalTable.Palettes[palette] + _colrTable.GlyphPalettes[c], //index
                        out byte r, out byte g, out byte b, out byte a);

                    ushort      gIndex = _colrTable.GlyphLayers[c];
                    VertexStore vxs    = glyphMeshStore.GetGlyphMesh(gIndex);
                    using (Tools.BorrowVxs(out var v1))
                    {
                        vxs.TranslateToNewVxs(offset_x, offset_y, v1);
                        painter.FillColor = new Color(r, g, b);//? a component
                        painter.Fill(v1);
                    }
                }
                //find ex
#if DEBUG
                //memBmp.SaveImage("a0x" + (dbugExportCount) + ".png");
#endif
            }

            return(new GlyphBitmap
            {
                Bitmap = memBmp,
                Width = memBmp.Width,
                Height = memBmp.Height,
                ImageStartX = -offset_x, //offset back
                ImageStartY = -offset_y  //offset back
            });
        }
Пример #8
0
 public void UpdateBounds()
 {
     _vgVisElem.InvalidateBounds();
     _boundingRect = _vgVisElem.GetRectBounds();
 }