protected override BitmapFont Read(ContentReader reader, BitmapFont existingInstance) { var totalTextures = reader.ReadInt32(); var textures = new Texture2D[totalTextures]; for (var i = 0; i < totalTextures; i++) { textures[i] = reader.ReadObject <Texture2D>(); } var lineHeight = reader.ReadInt32(); var regionCount = reader.ReadInt32(); var regions = new BitmapFontRegion[regionCount]; for (var r = 0; r < regionCount; r++) { var character = (char)reader.ReadInt32(); var textureIndex = reader.ReadInt32(); var x = reader.ReadInt32(); var y = reader.ReadInt32(); var width = reader.ReadInt32(); var height = reader.ReadInt32(); var xOffset = reader.ReadInt32(); var yOffset = reader.ReadInt32(); var xAdvance = reader.ReadInt32(); var textureRegion = new Subtexture(textures[textureIndex], x, y, width, height); regions[r] = new BitmapFontRegion(textureRegion, character, xOffset, yOffset, xAdvance); } return(new BitmapFont(regions, lineHeight)); }
void measureString(ref CharacterSource text, out Vector2 size) { if (text.Length == 0) { size = Vector2.Zero; return; } var width = 0.0f; var finalLineHeight = (float)lineHeight; var fullLineCount = 0; BitmapFontRegion currentFontRegion = null; var offset = Vector2.Zero; for (var i = 0; i < text.Length; i++) { var c = text[i]; if (c == '\r') { continue; } if (c == '\n') { fullLineCount++; finalLineHeight = lineHeight; offset.X = 0; offset.Y = lineHeight * fullLineCount; currentFontRegion = null; continue; } if (currentFontRegion != null) { offset.X += spacing + currentFontRegion.xAdvance; } if (!_characterMap.TryGetValue(c, out currentFontRegion)) { currentFontRegion = _defaultCharacterRegion; } var proposedWidth = offset.X + currentFontRegion.xAdvance + spacing; if (proposedWidth > width) { width = proposedWidth; } if (currentFontRegion.height + currentFontRegion.yOffset > finalLineHeight) { finalLineHeight = currentFontRegion.height + currentFontRegion.yOffset; } } size.X = width; size.Y = fullLineCount * lineHeight + finalLineHeight; }
/// <summary> /// gets the BitmapFontRegion for the given char optionally substituting the default region if it isnt present. /// </summary> /// <returns><c>true</c>, if get font region for char was tryed, <c>false</c> otherwise.</returns> /// <param name="c">C.</param> /// <param name="fontRegion">Font region.</param> /// <param name="useDefaultRegionIfNotPresent">If set to <c>true</c> use default region if not present.</param> public bool tryGetFontRegionForChar(char c, out BitmapFontRegion fontRegion, bool useDefaultRegionIfNotPresent = false) { if (!_characterMap.TryGetValue(c, out fontRegion)) { if (useDefaultRegionIfNotPresent) { fontRegion = defaultCharacterRegion; return(true); } return(false); } return(true); }
public static BitmapFont GetFromBMPSpriteFont(int xOffset, int yOffset, SpriteFont font) { var glyphs = font.GetGlyphs().ToArray(); var regions = new BitmapFontRegion[glyphs.Length]; for (var i = 0; i < regions.Length; i++) { var ch = glyphs[i].Key; var glyph = glyphs[i].Value; var rect = glyph.BoundsInTexture; var subtext = new Subtexture(font.Texture, rect); regions[i] = new BitmapFontRegion(subtext, ch, xOffset, glyph.Cropping.Y - yOffset, (int)glyph.WidthIncludingBearings); } return(new BitmapFont(regions, font.LineSpacing)); }
protected override BitmapFont Read(ContentReader reader, BitmapFont existingInstance) { Texture2D[] textures = null; Vector2[] atlasOrigins = null; var hasTextures = reader.ReadBoolean(); if (hasTextures) { var totalTextures = reader.ReadInt32(); textures = new Texture2D[totalTextures]; for (var i = 0; i < totalTextures; i++) { textures[i] = reader.ReadObject <Texture2D>(); } } else { var totalTextureNames = reader.ReadInt32(); atlasOrigins = new Vector2[totalTextureNames]; textures = new Texture2D[totalTextureNames]; for (var i = 0; i < totalTextureNames; i++) { var textureName = reader.ReadString(); atlasOrigins[i] = reader.ReadVector2(); textures[i] = reader.ContentManager.Load <Texture2D>(textureName); } } var lineHeight = reader.ReadInt32(); var padTop = reader.ReadInt32(); var padLeft = reader.ReadInt32(); var padBottom = reader.ReadInt32(); var padRight = reader.ReadInt32(); var descent = reader.ReadInt32(); var regionCount = reader.ReadInt32(); var regions = new BitmapFontRegion[regionCount]; for (var r = 0; r < regionCount; r++) { var character = (char)reader.ReadInt32(); var textureIndex = reader.ReadInt32(); var x = reader.ReadInt32(); var y = reader.ReadInt32(); var width = reader.ReadInt32(); var height = reader.ReadInt32(); var xOffset = reader.ReadInt32(); var yOffset = reader.ReadInt32(); var xAdvance = reader.ReadInt32(); Subtexture textureRegion = null; if (hasTextures) { textureRegion = new Subtexture(textures[textureIndex], x, y, width, height); } else { textureRegion = new Subtexture(textures[textureIndex], atlasOrigins[textureIndex].X + x, atlasOrigins[textureIndex].Y + y, width, height); } regions[r] = new BitmapFontRegion(textureRegion, character, xOffset, yOffset, xAdvance); } return(new BitmapFont(regions, lineHeight) { padTop = padTop, padBottom = padBottom, padRight = padRight, padLeft = padLeft, descent = descent }); }
internal void drawInto(SpriteBatch spriteBatch, ref CharacterSource text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth) { var flipAdjustment = Vector2.Zero; var flippedVert = (effect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically; var flippedHorz = (effect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally; if (flippedVert || flippedHorz) { Vector2 size; measureString(ref text, out size); if (flippedHorz) { origin.X *= -1; flipAdjustment.X = -size.X; } if (flippedVert) { origin.Y *= -1; flipAdjustment.Y = lineHeight - size.Y; } } var requiresTransformation = flippedHorz || flippedVert || rotation != 0f || scale != Vector2.One; if (requiresTransformation) { Matrix temp; Matrix.CreateTranslation(-origin.X, -origin.Y, 0f, out _transformationMatrix); Matrix.CreateScale((flippedHorz ? -scale.X : scale.X), (flippedVert ? -scale.Y : scale.Y), 1f, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix.CreateTranslation(flipAdjustment.X, flipAdjustment.Y, 0, out temp); Matrix.Multiply(ref temp, ref _transformationMatrix, out _transformationMatrix); Matrix.CreateRotationZ(rotation, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix.CreateTranslation(position.X, position.Y, 0f, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); } BitmapFontRegion currentFontRegion = null; var offset = requiresTransformation ? Vector2.Zero : position - origin; for (var i = 0; i < text.Length; ++i) { var c = text[i]; if (c == '\r') { continue; } if (c == '\n') { offset.X = requiresTransformation ? 0f : position.X - origin.X; offset.Y += lineHeight; currentFontRegion = null; continue; } if (currentFontRegion != null) { offset.X += spacing + currentFontRegion.xAdvance; } if (!_characterMap.TryGetValue(c, out currentFontRegion)) { currentFontRegion = _defaultCharacterRegion; } var p = offset; if (flippedHorz) { p.X += currentFontRegion.width; } p.X += currentFontRegion.xOffset; if (flippedVert) { p.Y += currentFontRegion.height - lineHeight; } p.Y += currentFontRegion.yOffset; // transform our point if we need to if (requiresTransformation) { Vector2.Transform(ref p, ref _transformationMatrix, out p); } var destRect = RectangleExt.fromFloats ( p.X, p.Y, currentFontRegion.width * scale.X, currentFontRegion.height * scale.Y ); spriteBatch.Draw(currentFontRegion.subtexture, destRect, currentFontRegion.subtexture.sourceRect, color, rotation, Vector2.Zero, effect, depth); } }
/// <summary> /// truncates text and returns a new string with ellipsis appended if necessary. This method ignores all /// line breaks. /// </summary> /// <returns>The text.</returns> /// <param name="text">Text.</param> /// <param name="ellipsis">Ellipsis.</param> /// <param name="maxLineWidth">Max line width.</param> public string truncateText(string text, string ellipsis, float maxLineWidth) { if (maxLineWidth < spaceWidth) { return(string.Empty); } var size = measureString(text); // do we even need to truncate? var ellipsisWidth = measureString(ellipsis).X; if (size.X > maxLineWidth) { var sb = new StringBuilder(); var width = 0.0f; BitmapFontRegion currentFontRegion = null; var offsetX = 0.0f; // determine how many chars we can fit in maxLineWidth - ellipsisWidth for (var i = 0; i < text.Length; i++) { var c = text[i]; // we dont deal with line breaks or tabs if (c == '\r' || c == '\n') { continue; } if (currentFontRegion != null) { offsetX += spacing + currentFontRegion.xAdvance; } if (!_characterMap.TryGetValue(c, out currentFontRegion)) { currentFontRegion = defaultCharacterRegion; } var proposedWidth = offsetX + currentFontRegion.xAdvance + spacing; if (proposedWidth > width) { width = proposedWidth; } if (width < maxLineWidth - ellipsisWidth) { sb.Append(c); } else { // no more room. append our ellipsis and get out of here sb.Append(ellipsis); break; } } return(sb.ToString()); } return(text); }