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"); //} } }
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); } } }
private FontGlyph CreateEmpty(int id) { FontGlyph ret = new FontGlyph(); ret.id = id; return(ret); }
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); }
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(); } } }
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); } }
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); }
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; }
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++; } }
/// <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); }
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); }
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); }
// 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); //---------------------- }
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); }
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); //------------------------------------------------------------- } }
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;
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); } }
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); }
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 //------------------------------------------------------------- } }
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); //---------------------- }
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"); //} }
///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; } } } }
/// <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); }
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]; }
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 }
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); //---------------------------------- }