Example #1
0
        static void BuildFontGlyphs(PixelFarm.Drawing.RequestFont font,
                                    Typography.Rendering.SimpleFontAtlasBuilder atlasBuilder,
                                    int startAt, int endAt)
        {
            //font glyph for specific font face
            ActualFont nativeFont = GetActualFont(font.Name, font.SizeInPoints);// nativeFontStore.GetResolvedNativeFont(font);

            for (int i = startAt; i <= endAt; ++i)
            {
                char      c         = (char)i;
                FontGlyph fontGlyph = nativeFont.GetGlyph(c);
                //-------------------
                GlyphImage glyphImg = NativeMsdfGen.BuildMsdfFontImage(fontGlyph);

                // Console.WriteLine(c.ToString() + " ox,oy" + glyphImg.OffsetX + "," + glyphImg.OffsetY);

                int   w      = glyphImg.Width;
                int   h      = glyphImg.Height;
                int[] buffer = glyphImg.GetImageBuffer();
                NativeMsdfGen.SwapColorComponentFromBigEndianToWinGdi(buffer);
                glyphImg.SetImageBuffer(buffer, false);
                // atlasBuilder.AddGlyph(fontGlyph.glyphMatrix.u c, fontGlyph, glyphImg);
                //using (Bitmap bmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                //{
                //    var bmpdata = bmp.LockBits(new Rectangle(0, 0, w, h), 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_x1_" + (int)c + ".png");
                //}
            }
        }
Example #2
0
        public static SpriteFont FromStream(Stream stream)
        {
            using (var reader = new BinaryReader(stream))
            {
                var rangeStart  = reader.ReadInt32();
                var glyphWidth  = reader.ReadInt32();
                var glyphHeight = reader.ReadInt32();
                var glyphCount  = reader.ReadInt32();
                var glyphs      = new FontGlyph[glyphCount];
                for (int i = 0; i < glyphs.Length; i++)
                {
                    glyphs[i].X      = reader.ReadSingle();
                    glyphs[i].Y      = reader.ReadSingle();
                    glyphs[i].Width  = reader.ReadSingle();
                    glyphs[i].Height = reader.ReadSingle();
                }

                var textureBytes = reader.ReadInt32();
                var textureData  = reader.ReadBytes(textureBytes);
                using (var textureStream = new MemoryStream(textureData))
                {
                    var texture = Texture2D.FromStream(textureStream);
                    var font    = new SpriteFont(texture, glyphs, rangeStart);
                    font.Spacing     = glyphWidth;
                    font.LineSpacing = glyphHeight;
                    return(font);
                }
            }
        }
Example #3
0
        private FontGlyph CreateEmpty(int id)
        {
            FontGlyph ret = new FontGlyph();

            ret.id = id;
            return(ret);
        }
Example #4
0
        private Vertex[] GetGlyphVerts(FontGlyph glyph, int x, int y)
        {
            Vertex[] ret = new Vertex[4];
            int      rx  = x + glyph.xoffset;
            int      ry  = y + glyph.yoffset;
            int      w   = glyph.width;
            int      h   = glyph.height;

            ret[0] = new Vertex()
            {
                x = rx, y = ry, u = glyph.x1, v = glyph.y1
            };
            ret[1] = new Vertex()
            {
                x = rx + w, y = ry, u = glyph.x2, v = glyph.y1
            };
            ret[2] = new Vertex()
            {
                x = rx + w, y = ry + h, u = glyph.x2, v = glyph.y2
            };
            ret[3] = new Vertex()
            {
                x = rx, y = ry + h, u = glyph.x1, v = glyph.y2
            };
            return(ret);
        }
        public VertexStore CreateVxs(char[] buffer, double x = 0, double y = 0)
        {
            int j        = buffer.Length;
            int buffsize = j * 2;

            //get kerning list

            ProperGlyph[] properGlyphs = new ProperGlyph[buffsize];
            currentFont.GetGlyphPos(buffer, 0, buffsize, properGlyphs);
            VertexStore resultVxs = new VertexStore();
            double      xpos      = x;

            for (int i = 0; i < buffsize; ++i)
            {
                uint codepoint = properGlyphs[i].codepoint;
                if (codepoint == 0)
                {
                    break;
                }
                //-------------------------------------------------------------
                FontGlyph glyph = this.currentFont.GetGlyphByIndex(codepoint);
                var       left  = glyph.exportGlyph.img_horiBearingX;
                //--------------------------------------------------------
                VertexStore vxs1 = Agg.Transform.Affine.TranslateToVxs(
                    glyph.flattenVxs,
                    (float)(xpos),
                    (float)(y));
                //--------------------------------------------------------
                resultVxs.AddSubVertices(vxs1);
                int w = (glyph.exportGlyph.advanceX) >> 6;
                xpos += (w);
                //-------------------------------------------------------------
            }
            return(resultVxs);
        }
Example #6
0
        public void ApplyToGlyphs(int numberOfHMetrics, FontGlyph[] glyphs)
        {
            _reader.Position = 0;

            for (var i = 0; i < numberOfHMetrics; i++)
            {
                FontGlyph glyph = glyphs[i];
                glyph.AdvanceWidth    = _reader.ReadUShortBE();
                glyph.LeftSideBearing = _reader.ReadShortBE();
            }

            // There can be more left side bearings after the ending.
            // These contain only the LSB.
            if (_reader.Position + 2 <= _reader.Data.Length)
            {
                _reader.ReadBytes(2);
                int extraMetricCount = (_reader.Data.Length - _reader.Position) / 2;
                if (extraMetricCount < 0)
                {
                    extraMetricCount = 0;
                }

                for (int i = numberOfHMetrics; i < extraMetricCount; i++)
                {
                    FontGlyph glyph = glyphs[i];
                    glyph.LeftSideBearing = _reader.ReadShortBE();
                }
            }
        }
Example #7
0
        public static unsafe void CompareMetricsWithStb(Font f, DrawableFontAtlas atlas, StbTrueType.stbtt_fontinfo stbFont)
        {
            var pc = new StbTrueType.stbtt_pack_context();

            StbTrueType.stbtt_PackBegin(pc, (byte *)0, 512, 512, 512, 1, null);

            var cd = new StbTrueType.stbtt_packedchar[f.LastCharIndex + 1];

            StbTrueType.stbrp_rect[] rects;
            fixed(StbTrueType.stbtt_packedchar *charDataPtr = &cd[0])
            {
                var range = new StbTrueType.stbtt_pack_range
                {
                    first_unicode_codepoint_in_range = 0,
                    array_of_unicode_codepoints      = null,
                    num_chars          = (int)f.LastCharIndex + 1,
                    chardata_for_range = charDataPtr,
                    font_size          = -atlas.FontSize
                };

                rects = new StbTrueType.stbrp_rect[f.LastCharIndex + 1];
                fixed(StbTrueType.stbrp_rect *rectPtr = &rects[0])
                {
                    int n = StbTrueType.stbtt_PackFontRangesGatherRects(pc, stbFont, &range, 1, rectPtr);

                    StbTrueType.stbtt_PackFontRangesPackRects(pc, rectPtr, n);
                }
            }

            foreach ((char charIndex, DrawableGlyph atlasGlyph) in atlas.Glyphs)
            {
                FontGlyph glyph = atlasGlyph.FontGlyph;

                var advance = 0;
                var bearing = 0;
                StbTrueType.stbtt_GetCodepointHMetrics(stbFont, charIndex, &advance, &bearing);
                Assert.True(advance == glyph.AdvanceWidth);
                Assert.True(bearing == glyph.LeftSideBearing || glyph.LeftSideBearing == 0); // stb has junk data beyond valid

                var minX = 0;
                var maxX = 0;
                var minY = 0;
                var maxY = 0;
                StbTrueType.stbtt_GetCodepointBitmapBoxSubpixel(stbFont, charIndex, atlas.RenderScale, atlas.RenderScale, 0, 0, &minX, &minY, &maxX, &maxY);

                Rectangle bbox = glyph.GetBBox(atlas.RenderScale);

                Assert.Equal(minX, bbox.X);
                Assert.Equal(minY, bbox.Y);
                Assert.Equal(maxX, bbox.Width);
                Assert.Equal(maxY, bbox.Height);

                Rectangle drawBox = new Rectangle(0, 0, bbox.Width - bbox.X, bbox.Height - bbox.Y);
                drawBox.Size += Vector2.One; // Add padding from stb
                StbTrueType.stbrp_rect rect = rects[charIndex];
                Assert.Equal(rect.w, drawBox.Width);
                Assert.Equal(rect.h, drawBox.Height);
            }
        }
Example #8
0
        public FontGlyph CreateGlyph(char c, int size, float deviceScale)
        {
            var scaledSize = (uint)(size * deviceScale);

            if (FreeType.FT_Set_Pixel_Sizes(face, scaledSize, scaledSize) != FreeType.OK)
            {
                return(EmptyGlyph);
            }

            if (FreeType.FT_Load_Char(face, c, FreeType.FT_LOAD_RENDER) != FreeType.OK)
            {
                return(EmptyGlyph);
            }

            // Extract the glyph data we care about
            // HACK: This uses raw pointer offsets to avoid defining structs and types that are 95% unnecessary
            var glyph = Marshal.ReadIntPtr(IntPtr.Add(face, FreeType.FaceRecGlyphOffset));               // face->glyph

            var metrics        = IntPtr.Add(glyph, FreeType.GlyphSlotMetricsOffset);                     // face->glyph->metrics
            var metricsWidth   = Marshal.ReadIntPtr(IntPtr.Add(metrics, FreeType.MetricsWidthOffset));   // face->glyph->metrics.width
            var metricsHeight  = Marshal.ReadIntPtr(IntPtr.Add(metrics, FreeType.MetricsHeightOffset));  // face->glyph->metrics.width
            var metricsAdvance = Marshal.ReadIntPtr(IntPtr.Add(metrics, FreeType.MetricsAdvanceOffset)); // face->glyph->metrics.horiAdvance

            var bitmap       = IntPtr.Add(glyph, FreeType.GlyphSlotBitmapOffset);                        // face->glyph->bitmap
            var bitmapPitch  = Marshal.ReadInt32(IntPtr.Add(bitmap, FreeType.BitmapPitchOffset));        // face->glyph->bitmap.pitch
            var bitmapBuffer = Marshal.ReadIntPtr(IntPtr.Add(bitmap, FreeType.BitmapBufferOffset));      // face->glyph->bitmap.buffer

            var bitmapLeft = Marshal.ReadInt32(IntPtr.Add(glyph, FreeType.GlyphSlotBitmapLeftOffset));   // face->glyph.bitmap_left
            var bitmapTop  = Marshal.ReadInt32(IntPtr.Add(glyph, FreeType.GlyphSlotBitmapTopOffset));    // face->glyph.bitmap_top

            // Convert FreeType's 26.6 fixed point format to integers by discarding fractional bits
            var glyphSize    = new Size((int)metricsWidth >> 6, (int)metricsHeight >> 6);
            var glyphAdvance = (int)metricsAdvance >> 6;

            var g = new FontGlyph
            {
                Advance = glyphAdvance,
                Offset  = new int2(bitmapLeft, -bitmapTop),
                Size    = glyphSize,
                Data    = new byte[glyphSize.Width * glyphSize.Height]
            };

            unsafe
            {
                var p = (byte *)bitmapBuffer;
                var k = 0;
                for (var j = 0; j < glyphSize.Height; j++)
                {
                    for (var i = 0; i < glyphSize.Width; i++)
                    {
                        g.Data[k++] = p[i];
                    }

                    p += bitmapPitch;
                }
            }

            return(g);
        }
Example #9
0
 public DrawableGlyph(char c, FontGlyph g, float scale)
 {
     Character = c;
     FontGlyph = g;
     Width     = (g.Max.X - g.Min.X) * scale;
     Height    = (g.Max.Y - g.Min.Y) * scale;
     XAdvance  = g.AdvanceWidth * scale;
     XBearing  = g.LeftSideBearing * scale;
     Descent   = g.Min.Y * scale;
 }
Example #10
0
        private void LoadFont(string fontName)
        {
            var assembly     = Assembly.GetExecutingAssembly();
            var resourceName = "crcPdf.Resources." + fontName + "_resource.txt";

            string[] result;
            Stream   stream = assembly.GetManifestResourceStream(resourceName);

            using (StreamReader reader = new StreamReader(stream))
            {
                result = reader.ReadToEnd().Split('\n');
            }

            string[] parts = result[0].Split(',');
            Width          = Convert.ToInt32(parts[0]);
            ItalicAngle    = Convert.ToInt32(parts[1]);
            boundingBox[0] = Convert.ToInt16(parts[2]);
            boundingBox[1] = Convert.ToInt16(parts[3]);
            boundingBox[2] = Convert.ToInt16(parts[4]);
            boundingBox[3] = Convert.ToInt16(parts[5]);
            Ascendent      = Convert.ToInt16(parts[6]);
            Descendent     = Convert.ToInt16(parts[7]);

            parts = result[1].Split(',');
            for (int i = 0; i < parts.Length; i += 2)
            {
                dctCharCodeToGlyphID.Add(Convert.ToInt32(parts[i]), Convert.ToInt32(parts[i + 1]));
            }

            parts = result[2].Split(',');
            if (parts.Length > 1)
            {
                for (int i = 0; i < parts.Length; i += 2)
                {
                    dctKerning.Add(Convert.ToInt32(parts[i]), Convert.ToInt16(parts[i + 1]));
                }
            }

            parts  = result[3].Split(',');
            Glypth = new FontGlyph[parts.Length / 6];
            int j = 0;

            for (int i = 0; i < parts.Length; i += 6)
            {
                Glypth[j] = new FontGlyph(
                    Convert.ToInt32(parts[i]),
                    Convert.ToInt32(parts[i + 1]));
                j++;
            }
        }
Example #11
0
        /// <summary>
        /// Запускается из PrecacheColor.
        /// </summary>
        /// <param name="c">Буква шрифта.</param>
        /// <returns>Один визуальный образ буквы.</returns>
        GlyphInfo CreateGlyph(Pair <char, Color> c)
        {
            FontGlyph glyph = font.CreateGlyph(c.First);

            if (glyph.Data == null)
            {
                return(new GlyphInfo
                {
                    Sprite = null,
                    Advance = 0,
                    Offset = int2.Zero
                });
            }

            var s = builder.Allocate(glyph.Size);
            var g = new GlyphInfo
            {
                Sprite  = s,
                Advance = glyph.Advance,
                Offset  = glyph.Bearing,
                fg      = glyph
            };

            //var dest = s.Sheet.GetData();
            //var destStride = s.Sheet.Size.Width * 4;

            //for (var j = 0; j < s.Size.Y; j++)
            //{
            //	for (var i = 0; i < s.Size.X; i++)
            //	{
            //		// тут происходит копирование байтов из глифа в "p", а после в dest общий массив текстуры.
            //		var p = glyph.Data[j * glyph.Size.Width + i];
            //		if (p != 0)
            //		{
            //			var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left);
            //			var pmc = Util.PremultiplyAlpha(Color.FromArgb(p, c.Second));

            //			dest[q] = pmc.B;
            //			dest[q + 1] = pmc.G;
            //			dest[q + 2] = pmc.R;
            //			dest[q + 3] = pmc.A;
            //		}
            //	}
            //}

            //s.Sheet.CommitBufferedData();

            return(g);
        }
Example #12
0
        public void Print(PixelFarm.Drawing.Color color, char[] buffer, int start, int len, double x, double y)
        {
            if (this.currentFont.IsAtlasFont)
            {
                //temp hard-code here!
                PixelFarm.Agg.Fonts.GdiTextureFont textureFont = (PixelFarm.Agg.Fonts.GdiTextureFont)currentFont;
                var srcAndDestList = textureFont.GetGlyphPos(buffer, start, len, (int)x, (int)y);
                //***
                canvas2d.DrawGlyphImages(color, textureFont.BmpBoard, srcAndDestList);
            }
            else
            {
                int j        = len;
                int buffsize = j * 2;
                //get kerning list
                if (properGlyphs == null)
                {
                    properGlyphs = new ProperGlyph[buffsize];
                    currentFont.GetGlyphPos(buffer, start, buffsize, properGlyphs);
                }

                double xpos = x;
                for (int i = 0; i < buffsize; ++i)
                {
                    uint codepoint = properGlyphs[i].codepoint;
                    if (codepoint == 0)
                    {
                        break;
                    }

                    //-------------------------------------------------------------
                    FontGlyph glyph = this.currentFont.GetGlyphByIndex(codepoint);
                    //glyph image32
                    //-------------------------------------------------------------
                    GLBitmap bmp  = new GLBitmap(new LazyAggBitmapBufferProvider(glyph.glyphImage32));
                    var      left = glyph.exportGlyph.img_horiBearingX;
                    this.canvas2d.DrawImage(bmp,
                                            (float)(xpos + (left >> 6)),
                                            (float)(y + (glyph.exportGlyph.bboxYmin >> 6)));

                    int w = (glyph.exportGlyph.advanceX) >> 6;
                    xpos += (w);

                    bmp.Dispose(); //temp here
                    //-------------------------------------------------------------
                }
            }
        }
        // TODO: ~FreeTypeFontGlyph() {}

        public override float GetRenderedAdvance(FontGlyph nextGlyph, float xScale)
        {
            bool isFollowedByAnotherCharacter = (nextGlyph != null);
            var  nextGlyphFT = nextGlyph as FreeTypeFontGlyph;

            if (isFollowedByAnotherCharacter && nextGlyphFT == null)
            {
                throw new InvalidRequestException(
                          "FreeTypeFontGlyph::getRenderedAdvance - Attempted to cast following Font Glyph to a FreeTypeFontGlyph has failed. " +
                          "This should not occur because FreeTypeFontGlyphs shall be followed by FreeTypeFontGlyphs only.");
            }

            var sizeX = GetImage().GetRenderedSize().Width + GetImage().GetRenderedOffset().X;

            sizeX *= xScale;

            // Last character, no kerning is done
            if (!isFollowedByAnotherCharacter)
            {
                return(sizeX);
            }

            //// Determine kerning
            //FT_Vector kerning;

            var face        = d_freeTypeFont.GetFontFace();
            var kerningMode = d_freeTypeFont.GetKerningMode();

            if (face == null)
            {
                throw new InvalidRequestException("FreeTypeFontGlyph::getRenderedAdvance - Attempted to access Font Face of a FreeType font, but it is not set to a valid Face.");
            }

            var leftGlyphIndex  = d_glyphIndex;
            var rightGlyphIndex = nextGlyphFT.GetGlyphIndex();

            var kerning = face.GetKerning(leftGlyphIndex, rightGlyphIndex, kerningMode);

            //if (error != 0)
            //{
            //    throw new InvalidRequestException("FreeTypeFontGlyph::getRenderedAdvance - Kerning returned with error code " + error);
            //}

            sizeX += (float)kerning.X * xScale;

            return(sizeX);
        }
Example #14
0
        protected override void OnReadyForInitGLShaderProgram()
        {
            InstalledTypefaceCollection collection = new InstalledTypefaceCollection();

            collection.LoadSystemFonts();
            InstalledTypeface tahomaFont = collection.GetInstalledTypeface("tahoma", TypefaceStyle.Regular);
            FontFace          tahomaFace = OpenFontLoader.LoadFont(tahomaFont.FontPath);
            ActualFont        actualFont = tahomaFace.GetFontAtPointSize(72);
            FontGlyph         glyph      = (FontGlyph)actualFont.GetGlyph('K');


            _glyph_vx = _painter.CreateRenderVx(_tempSnap1 = glyph.flattenVxs);

            _linearGrBrush2 = new LinearGradientBrush(
                new PointF(0, 0), new PointF(100, 100),
                Color.Red, Color.Black);
        }
Example #15
0
        //  PixelFarm.Drawing.Fonts.SvgFontStore svgFontStore = new PixelFarm.Drawing.Fonts.SvgFontStore();
        protected override void OnInitGLProgram(object sender, EventArgs args)
        {
            //temp***
            int max = Math.Max(this.Width, this.Height);

            canvas2d = PixelFarm.Drawing.GLES2.GLES2Platform.CreateCanvasGL2d(max, max);
            painter  = new GLCanvasPainter(canvas2d, max, max);

            //----------------------
            var win32InstallFontProvider       = new PixelFarm.Drawing.InstallFontsProviderWin32();
            InstalledFontCollection collection = new InstalledFontCollection();

            collection.LoadInstalledFont(win32InstallFontProvider.GetInstalledFontIter());
            InstalledFont tahomaFont = collection.GetFont("tahoma", InstalledFontStyle.Regular);
            FontFace      tahomaFace = OpenFontLoader.LoadFont(tahomaFont.FontPath, ScriptLangs.Latin);
            ActualFont    actualFont = tahomaFace.GetFontAtPointsSize(72);
            FontGlyph     glyph      = actualFont.GetGlyph('K');

            //var svgFont = svgFontStore.LoadFont("svg-LiberationSansFont", 300);
            ////PathWriter p01 = new PathWriter();
            ////p01.MoveTo(0, 0);
            ////p01.LineTo(50, 100);
            ////p01.LineTo(100, 0);
            //////-
            ////p01.MoveTo(220, 10);
            ////p01.LineTo(50, 75);
            ////p01.LineTo(25, 15);
            ////p01.CloseFigure();
            ////p01.Stop();
            ////m_pathVxs = p01.Vxs;

            //var m_pathVxs = svgFont.GetGlyph('K').originalVxs;// typeFaceForLargeA.GetGlyphForCharacter('a');
            ////m_pathVxs = MergeFontSubFigures(m_pathVxs);

            //Affine shape_mtx = Affine.NewMatix(AffinePlan.Translate(150, 100));
            //m_pathVxs = shape_mtx.TransformToVxs(m_pathVxs);
            //var curveFlattener = new CurveFlattener();
            //var m_pathVxs2 = curveFlattener.MakeVxs(m_pathVxs);

            glyph_vx = painter.CreateRenderVx(tempSnap1 = new PixelFarm.Agg.VertexStoreSnap(glyph.flattenVxs));

            linearGrBrush2 = new LinearGradientBrush(
                new PointF(0, 0), Color.Red,
                new PointF(100, 100), Color.Black);
            //----------------------
        }
Example #16
0
 public Character(CharacterRow row, CharacterContext context, uint id)
     : base(context.ServiceProvider)
 {
     this.context   = context ?? throw new ArgumentNullException(nameof(context));
     this.Row       = row;
     this.ID        = id;
     this.IsEnabled = this.context.Glyphs.ContainsKey(id);
     if (this.context.Glyphs.ContainsKey(id))
     {
         this.glyph        = this.context.Glyphs[id];
         this.glyphMetrics = this.context.Glyphs[id].Metrics;
     }
     else
     {
         this.glyphMetrics.VerticalAdvance = this.context.Height;
     }
     this.context.Register(this);
 }
Example #17
0
        public void Print(CanvasPainter painter, char[] buffer, double x, double y)
        {
            int j        = buffer.Length;
            int buffsize = j * 2;

            //get kerning list

            ProperGlyph[] properGlyphs = new ProperGlyph[buffsize];
            currentFont.GetGlyphPos(buffer, 0, buffsize, properGlyphs);
            double xpos = x;

            for (int i = 0; i < buffsize; ++i)
            {
                uint codepoint = properGlyphs[i].codepoint;
                if (codepoint == 0)
                {
                    break;
                }
                //-------------------------------------------------------------
                FontGlyph glyph = this.currentFont.GetGlyphByIndex(codepoint);
                var       left  = glyph.exportGlyph.img_horiBearingX;
                //--------------------------------------------------------
                //render with vector
                //var mat = Agg.Transform.Affine.NewMatix(
                //Agg.Transform.AffinePlan.Scale(0.30),
                //Agg.Transform.AffinePlan.Translate(xpos, y));
                //var vxs1 = mat.TransformToVxs(glyph.flattenVxs);

                VertexStore vxs1 = Agg.Transform.Affine.TranslateToVxs(
                    glyph.flattenVxs,
                    (float)(xpos),
                    (float)(y));
                painter.Fill(vxs1);
                //--------------------------------------------------------
                ////render with bitmap
                //this.painter.DrawImage(glyph.glyphImage32,
                //    (float)(xpos + (left >> 6)),
                //    (float)(y + (glyph.exportGlyph.bboxYmin >> 6)));

                int w = (glyph.exportGlyph.advanceX) >> 6;
                xpos += (w);
                //-------------------------------------------------------------
            }
        }
Example #18
0
        private static void ReadGlyph(FontGlyph g, LocaTable locaTable, ByteReader glyfTableReader, float scale)
        {
            int glyphIndex = g.MapIndex;

            int[] glyphOffsets = locaTable.GlyphOffsets;

            if (glyphIndex > glyphOffsets.Length)
            {
                return;
            }
            int glyphOffset = glyphOffsets[glyphIndex];
            int nextOffset  = glyphOffsets[glyphIndex + 1];

            // No data for glyph.
            if (glyphOffset == nextOffset || glyphOffset >= glyfTableReader.Data.Length)
            {
                return;
            }

            glyfTableReader.Position = glyphOffset;
            int   numberOfContours = glyfTableReader.ReadShortBE();
            float minX             = glyfTableReader.ReadShortBE();
            float minY             = glyfTableReader.ReadShortBE();
            float maxX             = glyfTableReader.ReadShortBE();
            float maxY             = glyfTableReader.ReadShortBE();

            g.Min = new Vector2(minX, minY) * scale;
            g.Max = new Vector2(maxX, maxY) * scale;

            // Simple glyph
            if (numberOfContours > 0)
            {
                // Indices for the last point of each contour
                var endPointIndices = new ushort[numberOfContours];
                for (var i = 0; i < endPointIndices.Length; i++)
                {
                    endPointIndices[i] = glyfTableReader.ReadUShortBE();
                }

                ushort instructionLength = glyfTableReader.ReadUShortBE();
                glyfTableReader.ReadBytes(instructionLength);

                int numberOfCoordinates = endPointIndices[^ 1] + 1;
Example #19
0
        public static void ParseGlyf(ByteReader reader, LocaTable locaTableParsed, FontGlyph[] glyphs, float scale)
        {
            // First pass: read commands of all glyphs
            for (var i = 0; i < glyphs.Length; i++)
            {
                FontGlyph glyph = glyphs[i];
                ReadGlyph(glyph, locaTableParsed, reader, scale);
            }

            // Second pass: combine composite glyphs.
            for (var i = 0; i < glyphs.Length; i++)
            {
                FontGlyph glyph = glyphs[i];
                if (!glyph.Composite)
                {
                    continue;
                }
                CombineCompositeGlyph(glyph, glyphs);
            }
        }
Example #20
0
        public Font GetFont(byte[] raw)
        {
            var font = new Font();

            font.Format = FontFormat.CFL;

            var File = new BinaryReader(raw);

            font.UnitsPerEm = File.GetUint16();
            font.XMin       = File.GetInt16();
            font.YMin       = File.GetInt16();
            font.XMax       = File.GetInt16();
            font.YMax       = File.GetInt16();

            var c = File.GetInt32();

            for (int i = 0; i < c; i++)
            {
                var g = new FontGlyph();

                g.YMin = File.GetInt16();
                g.YMax = File.GetInt16();
                g.XMax = File.GetInt16();
                g.XMin = File.GetInt16();

                var triangleCount = File.GetInt32();

                for (int j = 0; j < triangleCount; j++)
                {
                    var at      = new Point(File.GetInt32(), File.GetInt32());
                    var bt      = new Point(File.GetInt32(), File.GetInt32());
                    var ct      = new Point(File.GetInt32(), File.GetInt32());
                    var trianle = new Triangle(at, bt, ct);

                    g.Triangles.Add(trianle);
                    font.Glyphs.Add(g);
                }
            }

            return(font);
        }
Example #21
0
        public void Print(char[] buffer, double x, double y)
        {
            int j        = buffer.Length;
            int buffsize = j * 2;

            //get kerning list
            if (properGlyphs == null)
            {
                properGlyphs = new ProperGlyph[buffsize];
                currentFont.GetGlyphPos(buffer, 0, buffsize, properGlyphs);
            }

            double xpos = x;

            for (int i = 0; i < buffsize; ++i)
            {
                uint codepoint = properGlyphs[i].codepoint;
                if (codepoint == 0)
                {
                    break;
                }

                //-------------------------------------------------------------
                FontGlyph glyph = this.currentFont.GetGlyphByIndex(codepoint);
                //glyph image32
                //-------------------------------------------------------------
                GLBitmap bmp  = new GLBitmap(new LazyAggBitmapBufferProvider(glyph.glyphImage32));
                var      left = glyph.exportGlyph.img_horiBearingX;
                this.canvas2d.DrawImage(bmp,
                                        (float)(xpos + (left >> 6)),
                                        (float)(y + (glyph.exportGlyph.bboxYmin >> 6)));

                int w = (glyph.exportGlyph.advanceX) >> 6;
                xpos += (w);

                bmp.Dispose(); //temp here
                //-------------------------------------------------------------
            }
        }
Example #22
0
        protected override void OnReadyForInitGLShaderProgram()
        {
            InstalledFontCollection collection = new InstalledFontCollection();

            collection.LoadSystemFonts();
            InstalledFont tahomaFont = collection.GetFont("tahoma", InstalledFontStyle.Normal);
            FontFace      tahomaFace = OpenFontLoader.LoadFont(tahomaFont.FontPath);
            ActualFont    actualFont = tahomaFace.GetFontAtPointSize(72);
            FontGlyph     glyph      = (FontGlyph)actualFont.GetGlyph('K');

            //var svgFont = svgFontStore.LoadFont("svg-LiberationSansFont", 300);
            ////PathWriter p01 = new PathWriter();
            ////p01.MoveTo(0, 0);
            ////p01.LineTo(50, 100);
            ////p01.LineTo(100, 0);
            //////-
            ////p01.MoveTo(220, 10);
            ////p01.LineTo(50, 75);
            ////p01.LineTo(25, 15);
            ////p01.CloseFigure();
            ////p01.Stop();
            ////m_pathVxs = p01.Vxs;

            //var m_pathVxs = svgFont.GetGlyph('K').originalVxs;// typeFaceForLargeA.GetGlyphForCharacter('a');
            ////m_pathVxs = MergeFontSubFigures(m_pathVxs);

            //Affine shape_mtx = Affine.NewMatix(AffinePlan.Translate(150, 100));
            //m_pathVxs = shape_mtx.TransformToVxs(m_pathVxs);
            //var curveFlattener = new CurveFlattener();
            //var m_pathVxs2 = curveFlattener.MakeVxs(m_pathVxs);

            glyph_vx = painter.CreateRenderVx(tempSnap1 = new PixelFarm.Drawing.VertexStoreSnap(glyph.flattenVxs));

            linearGrBrush2 = new LinearGradientBrush(
                new PointF(0, 0), Color.Red,
                new PointF(100, 100), Color.Black);
            //----------------------
        }
Example #23
0
        static void BuildFontGlyph(ActualFont nativefont, Typography.Rendering.SimpleFontAtlasBuilder atlasBuilder, char c)
        {
            //font glyph for specific font face



            FontGlyph  fontGlyph = nativefont.GetGlyph(c);
            GlyphImage glyphImg  = NativeMsdfGen.BuildMsdfFontImage(fontGlyph);

            int w = glyphImg.Width;
            int h = glyphImg.Height;

            int[] buffer = glyphImg.GetImageBuffer();
            NativeMsdfGen.SwapColorComponentFromBigEndianToWinGdi(buffer);
            glyphImg.SetImageBuffer(buffer, false);
            atlasBuilder.AddGlyph(0, glyphImg);
            //using (Bitmap bmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
            //{
            //    var bmpdata = bmp.LockBits(new Rectangle(0, 0, w, h), 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_x1_" + (int)c + ".png");
            //}
        }
Example #24
0
        ///Creates a bitmap ASCII font
        public BMFont(string bmfont)
        {
            using (StringReader sr = new StringReader(bmfont))
            {
                string fullline;
                while ((fullline = sr.ReadLine()) != null)
                {
                    var            line = fullline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    Queue <string> lq   = new Queue <string>();
                    foreach (var lword in line)
                    {
                        lq.Enqueue(lword);
                    }
                    string cword = lq.Dequeue();
                    if (cword == "info")
                    {
                        var facesubstr = "face=\"";
                        var faceidx1   = fullline.IndexOf(facesubstr, StringComparison.Ordinal) + facesubstr.Length;
                        var faceidx2   = fullline.IndexOf("\"", faceidx1, StringComparison.Ordinal);

                        var sizesubstr = "size=";
                        var sizeidx1   = fullline.IndexOf(sizesubstr, StringComparison.Ordinal) + sizesubstr.Length;
                        var sizeidx2   = fullline.IndexOf(" ", sizeidx1, StringComparison.Ordinal);

                        Face     = fullline.Substring(faceidx1, faceidx2 - faceidx1);
                        FontSize = ParseInt(fullline.Substring(sizeidx1, sizeidx2 - sizeidx1));
                    }
                    else if (cword == "common")
                    {
                        while (lq.Count > 0)
                        {
                            cword = lq.Dequeue();
                            var key = extract_key(cword);
                            var val = extract_value(cword);
                            switch (key)
                            {
                            case "lineHeight":
                                LineHeight = ParseInt(val);
                                break;

                            case "scaleW":
                                _texWidth = ParseInt(val);
                                break;

                            case "scaleH":
                                _texHeight = ParseInt(val);
                                break;

                            case "pages":
                                if (ParseInt(val) > 1)
                                {
                                    throw new Exception("Unsupported BMFont: > 1 pages");
                                }
                                break;
                            }
                        }
                    }
                    else if (cword == "char")
                    {
                        FontGlyph glyph = new FontGlyph();
                        glyph.id = 0;
                        while (lq.Count > 0)
                        {
                            cword = lq.Dequeue();
                            var key = extract_key(cword);
                            var val = int.Parse(extract_value(cword));
                            switch (key)
                            {
                            case "id":
                                glyph.id = val;
                                break;

                            case "x":
                                glyph.x1 = val / (float)_texWidth;
                                break;

                            case "y":
                                glyph.y1 = ((float)val / (float)_texHeight);
                                break;

                            case "width":
                                glyph.width = val;
                                glyph.x2    = glyph.x1 + ((float)val / (float)_texWidth);
                                break;

                            case "height":
                                glyph.height = val;
                                glyph.y2     = glyph.y1 + ((float)val / (float)_texHeight);
                                break;

                            case "xoffset":
                                glyph.xoffset = val;
                                break;

                            case "yoffset":
                                glyph.yoffset = val;
                                break;

                            case "xadvance":
                                glyph.xadvance = val;
                                break;
                            }
                        }
                        if (glyph.id != 0)
                        {
                            if (glyph.id == -1)
                            {
                                _invalid = glyph;
                            }
                            else
                            {
                                _glyphs[glyph.id] = glyph;
                            }
                        }
                    }
                    else if (cword == "kerning")
                    {
                        int first  = 0;
                        int second = 0;
                        int amount = 0;
                        while (lq.Count > 0)
                        {
                            cword = lq.Dequeue();
                            var key = extract_key(cword);
                            var val = int.Parse(extract_value(cword));
                            switch (key)
                            {
                            case "first":
                                first = val;
                                break;

                            case "second":
                                second = val;
                                break;

                            case "amount":
                                amount = val;
                                break;
                            }
                        }
                        if (first != 0 && second != 0 && amount != 0)
                        {
                            if (_glyphs[first].kerning == null)
                            {
                                _glyphs[first].kerning = new sbyte[256];
                            }
                            var glyph = _glyphs[first];
                            if (Math.Abs(amount) > 127)
                            {
                                throw new Exception("Unsupported kerning value");
                            }
                            glyph.kerning[second] = (sbyte)amount;
                        }
                    }
                }
            }
            for (int i = 0; i < _glyphs.Length; i++)
            {
                if (_glyphs[i].id == 0)
                {
                    switch ((char)i)
                    {
                    case '\r':
                    case '\n':
                        _glyphs[i] = CreateEmpty(i);
                        break;

                    case '\t':
                        _glyphs[i]           = _glyphs[(int)' '];
                        _glyphs[i].xadvance *= 4;
                        break;

                    default:
                        //invalid may not be set
                        //but that's okay.
                        _glyphs[i] = _invalid;
                        break;
                    }
                }
            }
        }
Example #25
0
 /// <summary>
 /// Return the rendered advance value for this glyph.
 /// <para>
 /// The rendered advance value is the total number of pixels from the
 /// current pen position that will be occupied by this glyph when rendered.
 /// </para>
 /// </summary>
 /// <param name="nectGlyph"></param>
 /// <param name="xScale"></param>
 /// <returns></returns>
 public virtual float GetRenderedAdvance(FontGlyph nectGlyph, float xScale)
 {
     return((_image.GetRenderedSize().Width +
             _image.GetRenderedOffset().X) * xScale);
 }
Example #26
0
        private void button6_Click(object sender, EventArgs e)
        {
            //1. load font
            ActualFont font = GetActualFont("tahoma", 28);// nativeFontStore.LoadFont("tahoma", 28);
            //2. get glyph

            var g1 = font.GetGlyph('C');

            var plans = new List <Typography.TextLayout.GlyphPlan>();

            PixelFarm.Drawing.Text.TextShapingService.GetGlyphPos(font, "ABC".ToCharArray(), 0, 3, plans);


            int[] glyphIndice = new int[] { 1076, 1127, 1164 };
            int   j           = glyphIndice.Length;

            var atlasBuilder = new Typography.Rendering.SimpleFontAtlasBuilder();

            for (int i = 0; i < j; ++i)
            {
                int       codepoint = glyphIndice[i];
                FontGlyph fontGlyph = font.GetGlyphByIndex((uint)codepoint);

                GlyphImage glyphImg = NativeMsdfGen.BuildMsdfFontImage(fontGlyph);
                int        w        = glyphImg.Width;
                int        h        = glyphImg.Height;
                int[]      buffer   = glyphImg.GetImageBuffer();
                NativeMsdfGen.SwapColorComponentFromBigEndianToWinGdi(buffer);
                glyphImg.SetImageBuffer(buffer, false);
                atlasBuilder.AddGlyph(codepoint, glyphImg);

                using (Bitmap bmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                {
                    var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, w, h), 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_y1_" + codepoint + ".png");
                }
            }
            //----------------------------------------------------
            GlyphImage totalImg = atlasBuilder.BuildSingleImage();

            using (Bitmap bmp = new Bitmap(totalImg.Width, totalImg.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
            {
                int[] buffer = totalImg.GetImageBuffer();
                if (totalImg.IsBigEndian)
                {
                    NativeMsdfGen.SwapColorComponentFromBigEndianToWinGdi(buffer);
                    totalImg.SetImageBuffer(buffer, false);
                }

                var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, totalImg.Width, totalImg.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\\a_total.png");
            }

            string fontfilename = "d:\\WImageTest\\a_total.xml";

            atlasBuilder.SaveFontInfo(fontfilename);
            //----------------------------------
        }
 static void RenderFontGlyph(ref FontGlyph glyph)
 {
     glyph.bmp = new byte[10];
 }
Example #28
0
 public CffGlyphFactory(float scale)
 {
     Scale = scale;
     Glyph = new FontGlyph();
 }
 static void Main()
 {
     FontGlyph[] glyphs = new FontGlyph[100];
     RenderFontGlyph(ref glyphs[0]);
     Console.WriteLine(glyphs[0].bmp.Length);     // 10
 }
Example #30
0
        private void button3_Click(object sender, EventArgs e)
        {
            //1. load font
            string     fontName      = "tahoma";
            int        fontSizeInPts = 28;
            ActualFont font          = GetActualFont(fontName, fontSizeInPts);

            //2. get glyph
            char[] fontChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray();
            int    j         = fontChars.Length;


            var atlasBuilder = new Typography.Rendering.SimpleFontAtlasBuilder();

            atlasBuilder.SetAtlasInfo(TextureKind.Msdf, fontSizeInPts);

            for (int i = 0; i < j; ++i)
            {
                char c = fontChars[i];

                FontGlyph  fontGlyph = font.GetGlyph(c);
                GlyphImage glyphImg  = NativeMsdfGen.BuildMsdfFontImage(fontGlyph);

                int   w      = glyphImg.Width;
                int   h      = glyphImg.Height;
                int[] buffer = glyphImg.GetImageBuffer();
                NativeMsdfGen.SwapColorComponentFromBigEndianToWinGdi(buffer);
                glyphImg.SetImageBuffer(buffer, false);
                atlasBuilder.AddGlyph(0, glyphImg);

                using (Bitmap bmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                {
                    var bmpdata = bmp.LockBits(
                        new System.Drawing.Rectangle(0, 0, w, h),
                        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_x1_" + (int)c + ".png");
                }
            }
            //----------------------------------------------------
            GlyphImage totalImg = atlasBuilder.BuildSingleImage();

            using (Bitmap bmp = new Bitmap(totalImg.Width, totalImg.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
            {
                int[] buffer = totalImg.GetImageBuffer();
                if (totalImg.IsBigEndian)
                {
                    NativeMsdfGen.SwapColorComponentFromBigEndianToWinGdi(buffer);
                    totalImg.SetImageBuffer(buffer, false);
                }

                var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, totalImg.Width, totalImg.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\\a_total.png");
            }

            string fontfilename = "d:\\WImageTest\\a_total.xml";

            atlasBuilder.SaveFontInfo(fontfilename);
            //----------------------------------
        }