// Draws the vert editor at the given position, returning true if there were changes bool DrawVertEditor(Vector2 origin, ref FontCharacter fc) { var vert = DrawFontChar(fc, origin); DrawVertSelection(origin, fc, false); DrawHandles(ref vert, ref dragging); if (dragging != GrabCorner.None) { fc.vert = UiToVert(vert, origin); changed = true; return true; } return false; }
public void TryParseFontCharacter_correctly_parses_valid_line() { FontCharacter c = new FontCharacter(); bool result = FontMetaParser.TryParseCharacterInfoLine(exampleLine, out c); //@"char id=1 x=507 y=463 width=4 height=5 xoffset=-1.500 yoffset=1.600 xadvance=30.813 page=0 chnl=0"; Assert.AreEqual(1, c.ID); Assert.IsTrue(Math.Abs(507.0f - c.TexcoordX) < floatError); Assert.IsTrue(Math.Abs(463.0f - c.TexcoordY) < floatError); Assert.IsTrue(Math.Abs(4.0f - c.TexcoordW) < floatError); Assert.IsTrue(Math.Abs(5.0f - c.TexcoordH) < floatError); Assert.IsTrue(Math.Abs(-1.5f - c.XOffset) < floatError); Assert.IsTrue(Math.Abs(1.6f - c.YOffset) < floatError); Assert.IsTrue(Math.Abs(30.813f - c.XAdvance) < floatError); }
public static void PutChar(int x, int y, char c, Color fg, Font font) { int cw = font.CharWidth, ch = font.CharHeight; FontCharacter fontChar = Font.CharToFontChar(c); for (int yy = 0; yy < ch; yy++) { for (int xx = 0; xx < cw; xx++) { if (font.Characters[(int)fontChar][xx + (yy * cw)] == 1) { SetPixel(x + xx, y + yy, fg); } } } }
public override FontCharacter GetFontData(char character) { if (character < 32 || character > 127) { character = '?'; } var result = new FontCharacter(); result.Data = font8x8_basic[character - 32]; result.Width = _characterWidth; result.Height = _characterHeight; result.Space = 1; return(result); }
private void LockedCharactersWindow_FormClosing(object sender, FormClosingEventArgs e) { _scriptFile.LockedCharacters.Clear(); foreach (ListViewItem lvi in listView_FontCharacters.Items) { if (lvi.Checked) { FontCharacter fontCharacter = _fontFile.Characters.FirstOrDefault(c => c.IndexString == lvi.Text); if (fontCharacter == null) { continue; } _scriptFile.LockedCharacters.Add(fontCharacter); } } }
public static FontInfo GetFontInfo(GMFileContent content, uint id) { if (id >= content.Fonts->Count) { throw new ArgumentOutOfRangeException(nameof(id)); } var fe = (FontEntry *)GMFile.PtrFromOffset(content, (&content.Fonts->Offsets)[id]); var ret = new FontInfo(); var tpag = TPagFromOffset(content, fe->TPagOffset); ret.CodeName = StringFromOffset(content, fe->CodeName); ret.SystemName = StringFromOffset(content, fe->SystemName); ret.EmSize = fe->EmSize; ret.IsBold = fe->Bold.IsTrue(); ret.IsItalic = fe->Italic.IsTrue(); ret.Charset = fe->Charset; ret.AntiAliasing = fe->AntiAliasing; ret.Scale = fe->Scale; for (uint i = 0; i < content.TexturePages->Count; i++) { if (fe->TPagOffset == (&content.TexturePages->Offsets)[i]) { ret.TexPagId = i; break; } } ret.Characters = ReadList(content, &fe->Chars, (_, p) => { var entry = (FontCharEntry *)p; var c = new FontCharacter(); c.Character = entry->Character; c.TPagFrame = entry->TexPagFrame; c.Shift = entry->Shift; c.Offset = entry->Offset; return(c); }); return(ret); }
// Draws a single character (with correct vert) Rect DrawFontChar(FontCharacter fc, Vector2 origin) { var vert = VertToUi(fc.vert, origin); var oldMatrix = GUI.matrix; if (fc.rotated) { var rv = RotateUiRect(vert); GUIUtility.RotateAroundPivot(-90f, rv.min); GUI.DrawTextureWithTexCoords(rv, Texture, fc.uv); GUI.matrix = oldMatrix; } else { GUI.DrawTextureWithTexCoords(vert, Texture, fc.uv); } return vert; }
public override FontCharacter GetFontData(char character) { if (character < 32 || character > 127) { character = '?'; } var result = new FontCharacter { Data = font8x8_basic[character - 32], Width = _characterWidth, Height = _characterHeight, Space = 1 }; return(result); }
public bool DeleteCharacter(FontCharacter character) { return(false); /*switch (_version) * { * case 1: * if (!(character is GFDv1Character chrv1)) return false; * _gfdv1.Characters.Remove(chrv1); * break; * case 2: * if (!(character is GFDv2Character chrv2)) return false; * _gfdv2.Characters.Remove(chrv2); * break; * } * * return true;*/ }
private static FontCharacter[] _genFontCharacters(Face face, IEnumerable <char> chars) { var x = 0; return(chars.Select(c => { face.LoadChar(c, LoadFlags.Default, LoadTarget.Normal); face.Glyph.RenderGlyph(RenderMode.Normal); var m = face.Glyph.Metrics; var fc = new FontCharacter(c, x, 0, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows, face.Glyph.BitmapLeft, face.Glyph.LinearVerticalAdvance.ToInt32() - face.Glyph.BitmapTop, face.Glyph.Advance.X.ToInt32()); x += fc.Width + 1; return fc; }).ToArray()); }
private List <ContentGroup> GetContentsForCharacter(FontCharacter character) { if (_contentsForCharacter.ContainsKey(character)) { return(_contentsForCharacter[character]); } var shapes = character.Shapes; var size = shapes.Count; var contents = new List <ContentGroup>(size); for (var i = 0; i < size; i++) { var sg = shapes[i]; contents.Add(new ContentGroup(_lottieDrawable, this, sg)); } _contentsForCharacter[character] = contents; return(contents); }
public void DrawChar(int x, int y, int color, FontCharacter character) { lock (this) { SetWindow(x, x + character.Width - 1, y, y + character.Height - 1); var pixels = new ushort[character.Width * character.Height]; var pixelPosition = 0; for (var segmentIndex = 0; segmentIndex < character.Data.Length; segmentIndex++) { var segment = character.Data[segmentIndex]; if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x80) != 0 ? (ushort)color : (ushort)0; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x40) != 0 ? (ushort)color : (ushort)0; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x20) != 0 ? (ushort)color : (ushort)0; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x10) != 0 ? (ushort)color : (ushort)0; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x8) != 0 ? (ushort)color : (ushort)0; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x4) != 0 ? (ushort)color : (ushort)0; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x2) != 0 ? (ushort)color : (ushort)0; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x1) != 0 ? (ushort)color : (ushort)0; pixelPosition++; } } //uncomment this to see the characters in the debug window that would be displayed on the screen. //var currentBuffer = string.Empty; //for (var pixel = 0; pixel < pixels.Length; pixel++) //{ // if (pixels[pixel] > 0) // { // currentBuffer += "X"; // } // else // { // currentBuffer += "-"; // } // if (currentBuffer.Length >= character.Width) // { // Debug.Print(currentBuffer); // currentBuffer = string.Empty; // } //} SendData(pixels); } }
public bool AddCharacter(FontCharacter character) { return(false); /*switch (_version) * { * case 1: * if (!(character is GFDv1Character chrv1)) return false; * _gfdv1.Characters.Add(chrv1); * * // Set GFD Kerning for new characters * if (chrv1.CharacterKerning == 0) * chrv1.CharacterKerning = chrv1.GlyphWidth; * * // Set GFD Unknown for space characters * switch (character.Character) * { * case 'Ø': * case '¬': * case 'þ': * case ' ': * chrv1.CharacterUnknown = 32; * break; * } * * _gfdv1.Characters.Sort((l, r) => l.Character.CompareTo(r.Character)); * break; * case 2: * if (!(character is GFDv2Character chrv2)) return false; * _gfdv2.Characters.Add(chrv2); * * // Set Character Width and Height * if (chrv2.CharacterWidth == 0) * chrv2.CharacterWidth = chrv2.GlyphWidth - 1; // They often seem to subtract one * if (chrv2.CharacterHeight == 0) * chrv2.CharacterHeight = chrv2.GlyphHeight; // Use glyph height because we don't generate compact textures. * * _gfdv2.Characters.Sort((l, r) => l.Character.CompareTo(r.Character)); * break; * } * * return true;*/ }
public void DeFormat(ScriptFile script) { MatchCollection matches = _regexSubCommand.Matches(Content); StringBuilder stringBuilder = new StringBuilder(); int matchIndex = 0; for (int i = 0; i < Content.Length; i++) { if (Content[i] == '\n') { stringBuilder.Append('\n'); continue; } if (Content[i] == '\r') { stringBuilder.Append('\r'); continue; } if (matches[matchIndex].Index == i) { i += matches[matchIndex].Length; stringBuilder.Append(matches[matchIndex].Value); matchIndex++; continue; } string neededSymbol = Content[i].ToString(); int fontCharacterIndex = BitConverter.ToInt16(_shiftJis.GetBytes(neededSymbol), 0); FontCharacter fontCharacter = script.GeneratedFont.FirstOrDefault(fc => fc.Index == fontCharacterIndex); if (fontCharacter == null) { MessageBox.Show("Font character index out of range!", "DeFormat Error!"); return; } stringBuilder.Append(fontCharacter.Symbol); } Content = stringBuilder.ToString(); }
/// <summary> /// Loads the characters of the FONT file. /// </summary> /// <param name="useMetadata"></param> /// <returns></returns> public bool Load(bool useMetadata = false) { if (!File.Exists(FilePath)) { return(false); } if (File.Exists(FilePath + ".INFO") && useMetadata) { using (StreamReader reader = new StreamReader(new FileStream(FilePath + ".INFO", FileMode.Open))) { XmlSerializer serializer = new XmlSerializer(typeof(List <FontCharacter>)); Characters = (List <FontCharacter>)serializer.Deserialize(reader); } } else { byte[] buffer = new byte[_originalSize]; using (BinaryReader reader = new BinaryReader(new FileStream(FilePath, FileMode.Open))) { if (reader.BaseStream.Length != _originalSize) { return(false); } reader.Read(buffer, 0, _originalSize); } Encoding encoder = Encoding.GetEncoding("shift_jis"); Characters.Clear(); for (int i = 0; i < 6604; i += 2) { byte[] data = new byte[32]; short index = BitConverter.ToInt16(buffer, i); Array.Copy(buffer, 6608 + i / 2 * 32, data, 0, 32); FontCharacter character = new FontCharacter(data, index, encoder.GetString(BitConverter.GetBytes(index))); Characters.Add(character); } } return(true); }
public Tuple <int, FontCharacter> ExtractCharacterFromLine(string line, int pageWidth, int pageHeight) { //Input expected in form such as: //char id=32 x=128 y=75 width=3 height=1 xoffset=-1 yoffset=94 xadvance=14 page=0 chnl=15 var id = ExtractNamedIntFromLine("id", line); var x = ExtractNamedIntFromLine("x", line); var y = ExtractNamedIntFromLine("y", line); var width = ExtractNamedIntFromLine("width", line); var height = ExtractNamedIntFromLine("height", line); var xoffset = ExtractNamedIntFromLine("xoffset", line); var yoffset = ExtractNamedIntFromLine("yoffset", line); var xadvance = ExtractNamedIntFromLine("xadvance", line); var page = ExtractNamedIntFromLine("page", line); if (id == null || x == null || y == null || width == null || height == null || xoffset == null || yoffset == null || xadvance == null || page == null) { return(new Tuple <int, FontCharacter>(-1, null)); } var character = new FontCharacter(pageWidth, pageHeight, (int)x, (int)y, (int)width, (int)height, (int)xoffset, (int)yoffset, (int)xadvance, (int)page); return(new Tuple <int, FontCharacter>((int)id, character)); }
private void _blit(Face face, FontCharacter character, Color[,] dst) { face.LoadChar(character.Char, LoadFlags.Default, LoadTarget.Normal); face.Glyph.RenderGlyph(RenderMode.Normal); if (face.Glyph.Bitmap.Buffer == IntPtr.Zero) { return; } var data = face.Glyph.Bitmap.BufferData; var c = 0; for (var y = 0; y < character.Height; y++) { for (var x = 0; x < character.Width; x++) { dst[character.Y + y, character.X + x] = new Color(255, 255, 255, data[c++]); } } }
public override SpriteFont Read(ContentManager manager, ContentReader reader) { Texture2D texture = reader.Read <Texture2D>(manager); SpriteFont font = new SpriteFont(texture); font.Spacing = reader.ReadSingle(); font.LineSpacing = reader.ReadInt32(); font.BaseLine = reader.ReadInt32(); bool hasDefaultChar = reader.ReadBoolean(); if (hasDefaultChar) { font.DefaultCharacter = reader.ReadChar(); } else { font.DefaultCharacter = null; } int kerningCount = reader.ReadInt32(); for (int i = 0; i < kerningCount; i++) { int key = reader.ReadInt32(); int kerning = reader.ReadInt32(); font.kernings.Add(key, kerning); } int characterMapCount = reader.ReadInt32(); for (int i = 0; i < characterMapCount; i++) { char key = reader.ReadChar(); Vector2 offset = reader.ReadVector2(); FontCharacter fntChar = new FontCharacter(key, new RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), offset, reader.ReadSingle()); font.characterMap.Add(key, fntChar); } return(font); }
private void DrawCharacterAsGlyph(FontCharacter character, Matrix3X3 parentMatrix, float fontScale, DocumentData documentData, BitmapCanvas canvas) { var contentGroups = GetContentsForCharacter(character); for (var j = 0; j < contentGroups.Count; j++) { var path = contentGroups[j].Path; //path.ComputeBounds(out _rectF); Matrix.Set(parentMatrix); Matrix = MatrixExt.PreScale(Matrix, fontScale, fontScale); path.Transform(Matrix); if (documentData.StrokeOverFill) { DrawGlyph(path, _fillPaint, canvas); DrawGlyph(path, _strokePaint, canvas); } else { DrawGlyph(path, _strokePaint, canvas); DrawGlyph(path, _fillPaint, canvas); } } }
public Glyph?GetGlyph(uint Unicode) { if (GlyphTexture.ContainsKey(Unicode)) { return(GlyphTexture[Unicode]); } FontCharacter FChar = new FontCharacter(); if (Msdfgen.LoadGlyphNormal(Fnt, Unicode, ref FChar)) { if (FChar.Width == 0 || FChar.Height == 0) { if (!GlyphTexture.ContainsKey(Unicode)) { GlyphTexture.Add(Unicode, new Glyph(FChar, null)); } return(GetGlyph(Unicode)); } Glyph G = new Glyph(FChar, FChar.GetBitmap()); if (!Packer.Pack(G.Bitmap.Width, G.Bitmap.Height, out G.X, out G.Y)) { throw new NotImplementedException("Cannot pack glyph"); } G.Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); TextureAtlas.SubRect2D(G.Bitmap, G.X, G.Y); G.Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); GlyphTexture.Add(Unicode, G); return(GetGlyph(Unicode)); } return(null); }
void DrawVertSelection(Vector2 origin, FontCharacter fc, bool highlight) { GUI.DrawTexture(new Rect(origin.x, origin.y, axisWidth, -GetAscent()), axisY); GUI.DrawTexture(new Rect(origin.x, origin.y, fc.advance, axisWidth), axisX); if (highlight) GUI.DrawTexture(VertToUi(fc.vert, origin), selection); }
public FontCharacter GetCharacter( uint code ) { uint index = ttf.FindGlyphIndex( code ); FontCharacter c; if( !charmap.TryGetValue( index, out c ) ) { c = new FontCharacter(); ttf.GetGlyphHMetrics( index, out c.advanceWidth, out c.leftSideBearing ); c.advanceWidth = (int)Math.Ceiling(c.advanceWidth* scalex ); c.leftSideBearing = (int)( c.leftSideBearing * scalex ); int a, b, cv, d; ttf.GetGlyphBox( index, out a, out c.topSideBearing, out cv, out d ); c.topSideBearing = (int)( c.topSideBearing * scaley ); byte[] data = ttf.GetGlyphBitmap( index, scalex, scaley, out c.width, out c.height, out c.xOffset, out c.yOffset ); //static void SaveBitmap( byte[] data, int x0, int y0, int x1, int y1, //int stride, string filename ) { if( c.width == 0 || c.height == 0 ) { charmap.Add( index, c ); return c; } //Color WHITE = Color.White; FindSpot( c ); //BitmapData bm_data = fontmap.LockBits( fontrect, System.Drawing.Imaging.ImageLockMode.ReadWrite, fontmap.PixelFormat ); for( int by = 0; by < c.height; by++ ) { for( int bx = 0; bx < c.width; bx++ ) { byte opacity = data[by * c.width + bx]; fontmap.SetPixel( c.x + bx, c.y + by #if USE_GLES2 , Android.Graphics.Color.Argb( opacity, 0xFF, 0xFF, 0xFF ) #else , Color.FromArgb( opacity, 0xFF, 0xFF, 0xFF ) #endif ); //bm_data.Scan0.bitmap.SetPixel( x - x0, y - y0, Color.FromArgb( opacity, 0x00, 0x00, 0x00 ) ); } } //fontmap.Save( "fontmap" + version++ + ".png" ); //fontmap.UnlockBits( bm_data ); } dirty = true; charmap.Add( index, c ); } return c; }
public override FontCharacter GetFontData(char character) { if (character < 32 || character > 127) { character = '?'; } var result = new FontCharacter(); result.Data = font8x8_basic[character - 32]; result.Width = _characterWidth; result.Height = _characterHeight; result.Space = 1; return result; }
void FindSpot( FontCharacter fc ) { int width = fc.width; int height = fc.height; int row_start = 0; int row; for( row = 0; row < line_heights.Count; row++ ) { int h = line_heights[row]; if( h == -1 ) { line_heights[row] = height+1; line_heights.Add( -1 ); line_offsets.Add( 0 ); break; } if( (height+1) <= h ) { if( width <= ( fontmap.Width - line_offsets[row] ) ) break; } row_start += h; } if( row_start + height > fontmap.Height ) { ExpandMap(); } fc.x = line_offsets[row]; fc.y = row_start; line_offsets[row] += width+1; fc.u = (short)( 65536 * fc.x / fontrect.Width ); fc.v = (short)( 65536 * fc.y / fontrect.Height ); fc.uw = (short)( 65536 * fc.width / fontrect.Width ); fc.vh = (short)( 65536 * fc.height / fontrect.Height ); fc.uvs = new float[8]; fc.uvs[2 * 2 + 0] = (float)fc.x / fontrect.Width + (float)fc.width / fontrect.Width; fc.uvs[2 * 2 + 1] = (float)fc.y / fontrect.Height + (float)fc.height / fontrect.Height; fc.uvs[3 * 2 + 0] = (float)fc.x / fontrect.Width + (float)fc.width / fontrect.Width; fc.uvs[3 * 2 + 1] = (float)fc.y / fontrect.Height; fc.uvs[0 * 2 + 0] = (float)fc.x / fontrect.Width; fc.uvs[0 * 2 + 1] = (float)fc.y / fontrect.Height + (float)fc.height / fontrect.Height; fc.uvs[1 * 2 + 0] = (float)fc.x / fontrect.Width; fc.uvs[1 * 2 + 1] = (float)fc.y / fontrect.Height; }
static void Vf3ToXml(Options options) { Dictionary <char, char> charMap = null; using (Stream cStream = File.OpenRead(options.Charlist)) { charMap = LanguageUtility.GetDecodeCharMapFromStream(cStream); } using (Stream s = File.OpenRead(options.Source)) { FontFile font = new FontFile(s); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = "\t"; settings.NewLineChars = "\r\n"; using (XmlWriter xml = XmlWriter.Create(options.Output, settings)) { xml.WriteStartDocument(); xml.WriteStartElement("font"); xml.WriteAttributeString("id", font.Header.ID.ToString()); xml.WriteAttributeString("version", font.Header.Version.ToString()); xml.WriteAttributeString("first_ascii", font.Header.FirstAscii.ToString()); xml.WriteAttributeString("width", font.Header.Width.ToString()); xml.WriteAttributeString("height", font.Header.Height.ToString()); xml.WriteAttributeString("render_height", font.Header.RenderHeight.ToString()); xml.WriteAttributeString("baseline_offset", font.Header.BaselineOffset.ToString()); xml.WriteAttributeString("character_spacing", font.Header.CharacterSpacing.ToString()); xml.WriteAttributeString("vertical_offset", font.Header.VerticalOffset.ToString()); xml.WriteAttributeString("peg_name", font.Header.PegName); xml.WriteAttributeString("bitmap_name", font.Header.BitmapName); xml.WriteStartElement("characters"); for (int i = 0; i < font.Characters.Count; i++) { FontCharacter c = font.Characters[i]; int u = font.U[i]; int v = font.V[i]; xml.WriteStartElement("character"); int charValue = font.Header.FirstAscii + i; char actualChar = DecodeChar(font.Header, charMap, i); xml.WriteAttributeString("spacing", c.Spacing.ToString()); xml.WriteAttributeString("byte_width", c.ByteWidth.ToString()); xml.WriteAttributeString("offset", c.Offset.ToString()); xml.WriteAttributeString("kerning_entry", c.KerningEntry.ToString()); xml.WriteAttributeString("user_data", c.UserData.ToString()); xml.WriteAttributeString("u", u.ToString()); xml.WriteAttributeString("v", v.ToString()); xml.WriteAttributeString("char_value", charValue.ToString()); xml.WriteAttributeString("actual_char", actualChar.ToString()); xml.WriteEndElement(); // character } xml.WriteEndElement(); // characters xml.WriteStartElement("kerning_pairs"); for (int i = 0; i < font.KerningPairs.Count; i++) { FontKerningPair pair = font.KerningPairs[i]; xml.WriteStartElement("kerning_pair"); char char1 = DecodeChar(font.Header, charMap, pair.Char1); char char2 = DecodeChar(font.Header, charMap, pair.Char2); xml.WriteAttributeString("char1", char1.ToString()); xml.WriteAttributeString("char2", char2.ToString()); xml.WriteAttributeString("offset", pair.Offset.ToString()); xml.WriteAttributeString("padding", pair.Padding.ToString()); xml.WriteEndElement(); // kerning_pair } xml.WriteEndElement(); // kerning_pairs xml.WriteEndElement(); // font xml.WriteEndDocument(); } } }
public static void DrawSelectionText(Graphics graphics, ScriptFile scriptFile, ScriptMessage message, bool alternative = false) { Color fontColor = Color.FromArgb(255, 255, 255); Font font = scriptFile.Font; int left = 15; int top = 7; string[] lines = null; if (alternative) { lines = ScriptParser.TextToLines(message.ContentAlternative); } else { lines = ScriptParser.TextToLines(message.Content); } bool open = false; if (lines != null) { foreach (string line in lines) { if (line.StartsWith("%SEL:")) { open = true; continue; } if (line.StartsWith("%END:")) { open = false; continue; } if (open) { string[] splitted = line.Split(','); if (splitted.Length < 3) { continue; } string displayText = splitted[2]; for (int i = 0; i < displayText.Length; i++) { char character = displayText[i]; if (left >= 223 || top >= 159) { continue; } if (scriptFile.IsValidChar(character)) { i++; if (i == displayText.Length) { FontCharacter fontCharacter = new FontCharacter(new FontSymbol(character), font); Bitmap bitmap = fontCharacter.GetBitmapTransparent(fontColor); graphics.DrawImage(bitmap, new Rectangle(left, top, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel); left += 16; } else if (scriptFile.IsValidChar(displayText[i])) { FontCharacter fontCharacter = new FontCharacter(new FontSymbol(character, displayText[i]), font); Bitmap bitmap = fontCharacter.GetBitmapTransparent(fontColor); graphics.DrawImage(bitmap, new Rectangle(left, top, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel); left += 16; } else { FontCharacter fontCharacter = new FontCharacter(new FontSymbol(character), font); Bitmap bitmap = fontCharacter.GetBitmapTransparent(fontColor); graphics.DrawImage(bitmap, new Rectangle(left, top, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel); left += 16; } } } } top += 16; left = 15; } } }
public override CompiledSpriteFont Process(FontContent input, string filename, ContentProcessorContext context) { try { CompiledSpriteFont font = new CompiledSpriteFont(); var text = new System.Drawing.Bitmap(input.TextureFile); var textData = text.LockBits(new System.Drawing.Rectangle(0, 0, text.Width, text.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); font.texture = new TextureContent(context.GraphicsDevice, false, 1, textData.Scan0, text.Width, text.Height, TextureContentFormat.Png, TextureContentFormat.Png); text.UnlockBits(textData); text.Dispose(); string[] lines = input.Content.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); int lineOffset = 0; if (!lines[lineOffset].StartsWith("common ")) { throw new Exception("No common data found"); } { string[] splt = lines[lineOffset].Substring("common ".Length).Split(' '); foreach (string pair in splt) { string[] kv = pair.Split(new char[] { '=' }, 2); if (kv.Length == 1) { throw new Exception("Invalid common data"); } if (kv[0] == "lineHeight") { font.LineSpacing = int.Parse(kv[1]); } else if (kv[0] == "base") { font.BaseLine = int.Parse(kv[1]); } } } while (lineOffset < lines.Length) { if (lines[lineOffset].StartsWith("chars count=")) { break; } lineOffset++; } if (lineOffset >= lines.Length) { throw new Exception("Invalid char count"); } int charCount = int.Parse(lines[lineOffset++].Substring("chars count=".Length)); Dictionary <int, char> idCharMap = new Dictionary <int, char>(); for (int i = 0; i < charCount - 1; i++) { string line = lines[lineOffset]; if (!line.StartsWith("char id=")) { throw new Exception("Invalid char definition"); } string[] splt = line.Substring("char ".Length).Split(new char[] { ' ' }, 11); int id = 0;//x=2 y=2 width=25 height=80 xoffset=0 yoffset=15 xadvance=28 page=0 chnl=0 letter="}" int x = 0, y = 0, width = 0, height = 0; int xOffset = 0, yOffset = 0; int advance = 0; char letter = '\0'; foreach (string pair in splt) { string[] pairSplit = pair.Split(new char[] { '=' }, 2); string key = pairSplit[0].ToLower(); string value = pairSplit[1]; if (key == "id") { id = int.Parse(value); } else if (key == "x") { x = int.Parse(value); } else if (key == "y") { y = int.Parse(value); } else if (key == "width") { width = int.Parse(value); } else if (key == "height") { height = int.Parse(value); } else if (key == "xoffset") { xOffset = int.Parse(value); } else if (key == "yoffset") { yOffset = int.Parse(value); } else if (key == "xadvance") { advance = int.Parse(value); } else if (key == "letter") { letter = value.Trim().ToCharArray()[1]; } } lineOffset++; if (idCharMap.ContainsKey(id)) { continue; } idCharMap.Add(id, letter); FontCharacter fontChar = new FontCharacter(letter, new Rectangle(0, 0, font.texture.Width, font.texture.Height), new Rectangle(x, y, width, height), new Vector2(xOffset, yOffset), advance); if (font.characterMap.ContainsKey(letter)) { continue; } font.characterMap.Add(letter, fontChar); } int kerningCount = int.Parse(lines[lineOffset++].Substring("kernings count=".Length)); for (int i = 0; i < kerningCount; i++) { string line = lines[lineOffset]; if (!line.StartsWith("kerning ")) { throw new Exception("Invalid kerning definition"); } string[] splt = line.Substring("kerning ".Length).Split(' '); char first = '\0', second = '\0'; int amount = 0; foreach (string pair in splt) { string[] pairSplit = pair.Split('='); string key = pairSplit[0].ToLower(); string value = pairSplit[1]; if (key == "first") { first = idCharMap[int.Parse(value)]; } else if (key == "second") { second = idCharMap[int.Parse(value)]; } else if (key == "amount") { amount = int.Parse(value); } } int kerningKey = SpriteFont.getKerningKey(first, second); if (!font.kernings.ContainsKey(kerningKey)) { font.kernings.Add(kerningKey, amount); } lineOffset++; } return(font); } catch (Exception ex) { context.RaiseBuildMessage(filename, ex.Message, BuildMessageEventArgs.BuildMessageType.Error); } return(null); }
public void TryParseFontCharacter_will_ignore_invalid_lines() { FontCharacter c = new FontCharacter(); Assert.IsFalse(FontMetaParser.TryParseCharacterInfoLine(@"sfsdf", out c)); }
// ============================ // ==== Store and retrieve ==== // ============================ void GetCharacters() { Revert(); if(currentFont != null) { var characterInfo = currentFont.characterInfo; chars = new FontCharacter[characterInfo.Length]; for (int i = 0; i < chars.Length; i++) { var c = characterInfo[i]; chars[i] = new FontCharacter { index = c.index, /*uv = new Rect( c.uvBottomLeft.x, c.uvBottomLeft.y, c.uvTopRight.x - c.uvBottomLeft.x, c.uvTopRight.y - c.uvBottomLeft.y),*/ #pragma warning disable 618 // The normal vert properties are mixed in with an inaccessible 'ascent' field // that is presumably set by Unity when it retrieves the data vert = new Rect(c.vert.x, c.vert.y + GetAscent(), c.vert.width, c.vert.height), uv = c.uv, rotated = c.flipped, advance = c.width #pragma warning restore 618 //rotated = Math.Abs(c.uvTopLeft.x - c.uvTopRight.x) < float.Epsilon, //advance = c.advance }; } } }
public static void DrawDialogueText(Graphics graphics, ScriptFile scriptFile, ScriptMessage message) { Color fontColor = Color.FromArgb(255, 255, 255); int line = 0; int left = 15; int top = 7; int windowCount = 1; int matchIndex = 0; MatchCollection matches = message.Matches; for (int i = 0; i < message.Content.Length; i++) { if (message.Content[i] == '\n' || message.Content[i] == '\r') { continue; } if (matchIndex < matches.Count) { if (i == matches[matchIndex].Index + 1) { Match match = matches[matchIndex]; if (match.Groups[1].Value == "COL") { int colorIndex = 0; int.TryParse(match.Groups[2].Value, out colorIndex); if (colorIndex > 15) { fontColor = FontColors[0]; } else { fontColor = FontColors[colorIndex]; } } else if (match.Groups[1].Value == "LF") { line++; top += 16; left = 15; } else if (match.Groups[1].Value == "CLR") { left = 15; top = windowCount * 96 + 7; windowCount++; } matchIndex++; i += match.Length - 2; continue; } } char character = message.Content[i]; Font font = scriptFile.Font; if (left >= 191) { continue; } if (scriptFile.IsValidChar(character)) { i++; //if (scriptFile.IsLockedChar(character)) //{ // FontCharacter fontCharacter = new FontCharacter(new FontSymbol(character, character), font); //not accurate engine rendering // Bitmap bitmap = fontCharacter.GetBitmapTransparent(fontColor); // graphics.DrawImage(bitmap, new Rectangle(left, top, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel); // left += 16; //} //else if (i == message.Content.Length) { FontCharacter fontCharacter = new FontCharacter(new FontSymbol(character), font); Bitmap bitmap = fontCharacter.GetBitmapTransparent(fontColor); graphics.DrawImage(bitmap, new Rectangle(left, top, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel); left += 16; } else if (scriptFile.IsValidChar(message.Content[i])) { FontCharacter fontCharacter = new FontCharacter(new FontSymbol(character, message.Content[i]), font); Bitmap bitmap = fontCharacter.GetBitmapTransparent(fontColor); graphics.DrawImage(bitmap, new Rectangle(left, top, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel); left += 16; } else { FontCharacter fontCharacter = new FontCharacter(new FontSymbol(character), font); Bitmap bitmap = fontCharacter.GetBitmapTransparent(fontColor); graphics.DrawImage(bitmap, new Rectangle(left, top, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel); left += 16; } } else { continue; } } }
static void Main(string[] args) { Options options = null; try { options = CommandLine.Parse <Options>(); } catch (CommandLineException exception) { Console.WriteLine(exception.ArgumentHelp.Message); Console.WriteLine(); Console.WriteLine(exception.ArgumentHelp.GetHelpText(Console.BufferWidth)); #if DEBUG Console.ReadLine(); #endif return; } if (options.Output == null) { options.Output = "output"; } if (!Directory.Exists(options.Output)) { Directory.CreateDirectory(options.Output); } FontFile font = null; using (Stream s = File.OpenRead(options.Source)) { font = new FontFile(s); } Dictionary <char, char> charMap = new Dictionary <char, char>(); using (Stream s = File.OpenRead(options.Charmap)) { charMap = LanguageUtility.GetDecodeCharMapFromStream(s); } string indicatedPegPath = Path.Combine(Path.GetDirectoryName(options.Source), font.Header.BitmapName); string[] pegExtensions = new string[] { ".cpeg_pc", ".cvbm_pc" }; string[] gpegExtensions = new string[] { ".gpeg_pc", ".gvbm_pc" }; bool foundPeg = false; string pegPath = null; string gpegPath = null; for (int i = 0; i < pegExtensions.Length; i++) { string pegExtension = pegExtensions[i]; string gpegExtension = gpegExtensions[i]; string candidatePath = Path.ChangeExtension(indicatedPegPath, pegExtension); if (File.Exists(candidatePath)) { foundPeg = true; pegPath = candidatePath; gpegPath = Path.ChangeExtension(pegPath, gpegExtension); break; } } if (!foundPeg) { Console.WriteLine("Couldn't find {0}! Extension may be \".cpeg_pc\" or \".cvbm_pc\".", indicatedPegPath); return; } Bitmap fontBitmap = null; using (Stream pegStream = File.OpenRead(pegPath)) { PegFile peg = new PegFile(pegStream); PegEntry entry = null; foreach (PegEntry e in peg.Entries) { if (e.Filename == font.Header.BitmapName) { entry = e; break; } } if (entry == null) { Console.WriteLine("Couldn't find bitmap {0} in font peg!", font.Header.BitmapName); return; } byte[] bitmapData = null; using (Stream gpegStream = File.OpenRead(gpegPath)) { bitmapData = entry.GetData(gpegStream); } byte[] uncompressed = null; switch (entry.Data.BitmapFormat) { case PegBitmapFormat.D3DFMT_DXT3: uncompressed = ManagedSquish.Squish.DecompressImage(bitmapData, entry.Data.Width, entry.Data.Height, ManagedSquish.SquishFlags.Dxt3); break; case PegBitmapFormat.D3DFMT_DXT5: uncompressed = ManagedSquish.Squish.DecompressImage(bitmapData, entry.Data.Width, entry.Data.Height, ManagedSquish.SquishFlags.Dxt5); break; default: throw new Exception(); } fontBitmap = new Bitmap(entry.Data.Width, entry.Data.Height, PixelFormat.Format32bppArgb); BitmapData data = fontBitmap.LockBits(new Rectangle(0, 0, fontBitmap.Width, fontBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); Marshal.Copy(uncompressed, 0, data.Scan0, uncompressed.Length); fontBitmap.UnlockBits(data); } using (StreamWriter sw = new StreamWriter(Path.Combine(options.Output, "out.txt"))) { for (int i = 0; i < font.Characters.Count; i++) { FontCharacter c = font.Characters[i]; int u = font.U[i]; int v = font.V[i]; int charValue = font.Header.FirstAscii + i; if (c.ByteWidth == 0) { continue; } char actualChar = '\0'; char rawChar = (char)charValue; if (charMap.ContainsKey(rawChar)) { actualChar = charMap[rawChar]; sw.WriteLine("{0} \"{1}\"", charValue, actualChar); } else { sw.WriteLine("{0} \"\"", charValue); } using (Bitmap bm = new Bitmap(c.ByteWidth, font.Header.RenderHeight)) { using (Graphics g = Graphics.FromImage(bm)) { g.Clear(Color.Black); g.DrawImage(fontBitmap, 0, 0, new Rectangle(u, v, c.ByteWidth, font.Header.RenderHeight), GraphicsUnit.Pixel); g.Flush(); } string bmName = String.Format("{0}.png", charValue); string bmPath = Path.Combine(options.Output, bmName); bm.Save(bmPath, ImageFormat.Png); } } } }
public void DrawChar(int x, int y, FontCharacter character, Color666 color, Color666 background = Color666.Black, bool isDebug = false) { lock (this) { SetWindow(x, x + character.Width - 1, y, y + character.Height - 1); var pixels = new byte[character.Width * character.Height * 3]; var pixelPosition = 0; var b = (byte)((UInt32)color & 0xff); var g = (byte)(((UInt32)color >> 8) & 0xff); var r = (byte)(((UInt32)color >> 16) & 0xff); var bb = (byte)((UInt32)background & 0xff); var bg = (byte)(((UInt32)background >> 8) & 0xff); var br = (byte)(((UInt32)background >> 16) & 0xff); for (var segmentIndex = 0; segmentIndex < character.Data.Length; segmentIndex++) { var segment = character.Data[segmentIndex]; if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x80) != 0 ? r : br; pixelPosition++; pixels[pixelPosition] = (segment & 0x80) != 0 ? g : bg; pixelPosition++; pixels[pixelPosition] = (segment & 0x80) != 0 ? b : bb; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x40) != 0 ? r : br; pixelPosition++; pixels[pixelPosition] = (segment & 0x40) != 0 ? g : bg; pixelPosition++; pixels[pixelPosition] = (segment & 0x40) != 0 ? b : bb; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x20) != 0 ? r : br; pixelPosition++; pixels[pixelPosition] = (segment & 0x20) != 0 ? g : bg; pixelPosition++; pixels[pixelPosition] = (segment & 0x20) != 0 ? b : bb; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x10) != 0 ? r : br; pixelPosition++; pixels[pixelPosition] = (segment & 0x10) != 0 ? g : bg; pixelPosition++; pixels[pixelPosition] = (segment & 0x10) != 0 ? b : bb; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x8) != 0 ? r : br; pixelPosition++; pixels[pixelPosition] = (segment & 0x8) != 0 ? g : bg; pixelPosition++; pixels[pixelPosition] = (segment & 0x8) != 0 ? b : bb; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x4) != 0 ? r : br; pixelPosition++; pixels[pixelPosition] = (segment & 0x4) != 0 ? g : bg; pixelPosition++; pixels[pixelPosition] = (segment & 0x4) != 0 ? b : bb; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x2) != 0 ? r : br; pixelPosition++; pixels[pixelPosition] = (segment & 0x2) != 0 ? g : bg; pixelPosition++; pixels[pixelPosition] = (segment & 0x2) != 0 ? b : bb; pixelPosition++; } if (pixelPosition < pixels.Length) { pixels[pixelPosition] = (segment & 0x1) != 0 ? r : br; pixelPosition++; pixels[pixelPosition] = (segment & 0x1) != 0 ? g : bg; pixelPosition++; pixels[pixelPosition] = (segment & 0x1) != 0 ? b : bb; pixelPosition++; } } if (isDebug) { var currentBuffer = string.Empty; for (var pixel = 0; pixel < pixels.Length; pixel++) { if (pixels[pixel] > 0) { currentBuffer += "X"; } else { currentBuffer += "-"; } if (currentBuffer.Length >= character.Width) { Console.WriteLine(currentBuffer); currentBuffer = string.Empty; } } } SendData(pixels); } }
// ======================== // ==== Add and remove ==== // ======================== public int AddSelected() { if (GetSelectionIndex() >= 0) throw new InvalidOperationException("Adding a character that already exists"); var ret = chars.Length; Array.Resize(ref chars, ret + 1); chars[ret] = new FontCharacter { index = selectedChar, uv = new Rect(0.375f, 0.375f, 0.25f, 0.25f), vert = new Rect(0f, 0f, 50f, 100f), advance = 50f }; changed = true; return ret; }