public string GetEndOfLineThatFits(string text, float maxWidth, bool encoding, SymbolStyle symbolStyle) { if (this.mReplacement != null) { return(this.mReplacement.GetEndOfLineThatFits(text, maxWidth, encoding, symbolStyle)); } int num = Mathf.RoundToInt(maxWidth * this.size); if (num < 1) { return(text); } int length = text.Length; int num3 = num; BMGlyph glyph = null; int offset = length; bool flag = (encoding && (symbolStyle != SymbolStyle.None)) && this.hasSymbols; bool isDynamic = this.isDynamic; if (isDynamic) { this.mDynamicFont.textureRebuildCallback = new Font.FontTextureRebuildCallback(this.OnFontChanged); this.mDynamicFont.RequestCharactersInTexture(text, this.mDynamicFontSize, this.mDynamicFontStyle); this.mDynamicFont.textureRebuildCallback = null; } while ((offset > 0) && (num3 > 0)) { char index = text[--offset]; BMSymbol symbol = !flag ? null : this.MatchSymbol(text, offset, length); int mSpacingX = this.mSpacingX; if (!isDynamic) { if (symbol != null) { mSpacingX += symbol.advance; goto Label_017F; } BMGlyph glyph2 = this.mFont.GetGlyph(index); if (glyph2 != null) { mSpacingX += glyph2.advance + ((glyph != null) ? glyph.GetKerning(index) : 0); glyph = glyph2; goto Label_017F; } glyph = null; continue; } if (this.mDynamicFont.GetCharacterInfo(index, out mChar, this.mDynamicFontSize, this.mDynamicFontStyle)) { mSpacingX += (int)mChar.width; } Label_017F: num3 -= mSpacingX; } if (num3 < 0) { offset++; } return(text.Substring(offset, length - offset)); }
private static IThemeStyle CreateCityTheme() { //Lets scale city icons based on city population //cities below 1.000.000 gets the smallest symbol, and cities with more than 5.000.000 the largest symbol var citymin = new SymbolStyle(); var citymax = new SymbolStyle(); const string iconPath = "Resources\\Images\\icon.png"; if (!File.Exists(iconPath)) { throw new Exception( String.Format("Error file '{0}' could not be found, make sure it is at the expected location", iconPath)); } citymin.Symbol = new Bitmap { Data = new FileStream(iconPath, FileMode.Open, FileAccess.Read) }; citymin.SymbolScale = 0.5f; citymax.Symbol = new Bitmap { Data = new FileStream(iconPath, FileMode.Open, FileAccess.Read) }; citymax.SymbolScale = 1f; return(new GradientTheme("Population", 1000000, 5000000, citymin, citymax)); }
public static Map CreateMap(IMapControl mapControl) { var style = new SymbolStyle() { Fill = new Brush(Color.Red), SymbolScale = 1, }; var map = new Map(); map.Layers.Add(OpenStreetMap.CreateTileLayer()); map.Layers.Add(CreateLayer(style)); var animations = CreateAnimationsForSymbolStyle(style); // todo: Introduce one Animation for the MapControl that could be reused here. var animation = new Animation(); animation.Ticked += (s, e) => { animation.UpdateAnimations(); mapControl.Refresh(); }; animation.Start(animations, 10000); return(map); }
private void DrawMarkers(IEnumerable <Land> landPieces) { if (landPieces == null) { return; } ClearGraphics(); foreach (var land in landPieces) { var sphericalMid = SphericalMercator.FromLonLat(land.Longitude, land.Latitude); var feature = new Feature { Geometry = new Mapsui.Geometries.Point(sphericalMid.x, sphericalMid.y) }; var symbolStyle = new SymbolStyle { Symbol = GetSymbol("warning.png"), SymbolType = SymbolType.Rectangle }; feature.Styles.Add(symbolStyle); source.Features.Add(feature); } Current.Instance.MapControl.OnViewChanged(true); }
public static void Draw(SKCanvas canvas, SymbolStyle style, double x, double y, float opacity, SymbolType symbolType, double mapRotation) { canvas.Save(); canvas.Translate((float)x, (float)y); canvas.Scale((float)style.SymbolScale, (float)style.SymbolScale); if (style.SymbolOffset.IsRelative) { canvas.Translate((float)(SymbolStyle.DefaultWidth * style.SymbolOffset.X), (float)(-SymbolStyle.DefaultWidth * style.SymbolOffset.Y)); } else { canvas.Translate((float)style.SymbolOffset.X, (float)-style.SymbolOffset.Y); } if (style.SymbolRotation != 0) { var rotation = style.SymbolRotation; if (style.RotateWithMap) { rotation += mapRotation; } canvas.RotateDegrees((float)rotation); } Draw(canvas, style, opacity, symbolType); canvas.Restore(); }
private static void DrawPointWithSymbolStyle(SKCanvas canvas, SymbolStyle style, Point destination, float opacity, SymbolType symbolType, float mapRotation) { canvas.Save(); canvas.Translate((float)destination.X, (float)destination.Y); canvas.Scale((float)style.SymbolScale, (float)style.SymbolScale); if (style.SymbolOffset.IsRelative) { canvas.Translate((float)(SymbolStyle.DefaultWidth * style.SymbolOffset.X), (float)(-SymbolStyle.DefaultWidth * style.SymbolOffset.Y)); } else { canvas.Translate((float)style.SymbolOffset.X, (float)-style.SymbolOffset.Y); } if (style.SymbolRotation != 0) { var rotation = (float)style.SymbolRotation; if (style.RotateWithMap) { rotation += mapRotation; } canvas.RotateDegrees(rotation); } DrawPointWithVectorStyle(canvas, style, opacity, symbolType); canvas.Restore(); }
private static SymbolStyle ToSymbolStyle(IStyle style) { var symbolStyle = style as SymbolStyle; if (symbolStyle != null) { return(symbolStyle); } var vectorStyle = style as VectorStyle; if (vectorStyle == null) { symbolStyle = new SymbolStyle(); } else { symbolStyle = new SymbolStyle { Fill = vectorStyle.Fill, Outline = vectorStyle.Outline, Line = vectorStyle.Line } }; return(symbolStyle); }
private static Feature CreatePoint(double x, double y) { var result = new Feature(); var style = new SymbolStyle() { Fill = new Brush(Color.Red), SymbolScale = 1, }; result.Geometry = new Point(x, y); result.Styles.Add(style); var animations = new List <AnimationEntry>(); var entry1 = new AnimationEntry( start: style.SymbolScale, end: style.SymbolScale * 2, animationStart: 0, animationEnd: .5, easing: Easing.SinInOut, tick: (entry, value) => { style.SymbolScale = (double)((double)entry.Start + ((double)entry.End - (double)entry.Start) * entry.Easing.Ease(value)); }, final: (entry) => { style.SymbolScale = (double)entry.End; } ); animations.Add(entry1); var entry2 = new AnimationEntry( start: style.SymbolScale * 2, end: style.SymbolScale, animationStart: .5, animationEnd: 1, easing: Easing.SinInOut, tick: (entry, value) => { style.SymbolScale = (double)((double)entry.Start + ((double)entry.End - (double)entry.Start) * entry.Easing.Ease(value)); }, final: (entry) => { style.SymbolScale = (double)entry.End; } ); animations.Add(entry2); var entry3 = new AnimationEntry( start: style.Outline.Color, end: style.Outline.Color, animationStart: 0, animationEnd: 1, easing: Easing.Linear, tick: (entry, value) => { var color = (Color)entry.Start; style.Fill.Color = new Color(color.R, color.G, (int)(value < 0.5 ? (1.0 - 2.0 * value) * 255 : ((value - 0.5) * 2.0) * 255)); }, final: (entry) => { style.Fill.Color = (Color)entry.End; } ); animations.Add(entry3); var animation = new Animation(1000); animation.Loop = true; animation.Entries.AddRange(animations); animation.Start(); return(result); }
private Map CreateMap() { var map = new Map(); var osmLayer = new TileLayer(new OsmTileSource()) { LayerName = "OSM" }; map.Layers.Add(osmLayer); var pointLayer = PointLayerSample.CreateRandomPointLayer(map.Envelope, 600); var bitmapData = System.Reflection.Assembly.GetExecutingAssembly() .GetManifestResourceStream("Mapsui.Silverlight.UI.Images.btnBbox.png"); var symbolStyle = new SymbolStyle { Symbol = new Bitmap { Data = bitmapData } }; pointLayer.Styles.Add(symbolStyle); map.Layers.Add(pointLayer); return(map); }
private void AddCircleLayer() { if (CircleLayer == null) { Mapsui.Layers.MemoryLayer _pointlayer = new Mapsui.Layers.MemoryLayer(); List <Mapsui.Geometries.Point> _points = new List <Mapsui.Geometries.Point>(); _pointlayer.DataSource = new Mapsui.Providers.MemoryProvider(_points); _pointlayer.Name = "Circle"; SymbolStyle _style = new SymbolStyle(); string path = Path.Combine(appdir, largeiconpath, Path.Combine(appdir, @"MarkerImages\Circle.png")); if (!IconCache.ContainsKey(path)) { using (FileStream fs = new FileStream(path, FileMode.Open)) { MemoryStream ms = new MemoryStream(); fs.CopyTo(ms); int id = BitmapRegistry.Instance.Register(ms); IconCache[path] = id; } } _style.BitmapId = IconCache[path]; _pointlayer.Style = _style; CircleLayer = _pointlayer; } MyMapControl.Map.Layers.Add(CircleLayer); }
/// <summary> /// Different line wrapping functionality -- contributed by MightyM. /// http://www.tasharen.com/forum/index.php?topic=1049.0 /// </summary> public string GetEndOfLineThatFits(string text, float maxWidth, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) { return(mReplacement.GetEndOfLineThatFits(text, maxWidth, encoding, symbolStyle)); } int lineWidth = Mathf.RoundToInt(maxWidth * size); if (lineWidth < 1) { return(text); } int textLength = text.Length; int remainingWidth = lineWidth; BMGlyph followingGlyph = null; int currentCharacterIndex = textLength; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; while (currentCharacterIndex > 0 && remainingWidth > 0) { char currentCharacter = text[--currentCharacterIndex]; // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, currentCharacterIndex, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (symbol != null && symbol.Validate(atlas)) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = mFont.GetGlyph(currentCharacter); if (glyph != null) { glyphWidth += glyph.advance + ((followingGlyph == null) ? 0 : followingGlyph.GetKerning(currentCharacter)); followingGlyph = glyph; } else { followingGlyph = null; continue; } } // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; } if (remainingWidth < 0) { ++currentCharacterIndex; } return(text.Substring(currentCharacterIndex, textLength - currentCharacterIndex)); }
public AnimatedPointsWithAutoUpdateLayer() : base(new DynamicMemoryProvider()) { Style = new SymbolStyle { Fill = { Color = new Color(255, 215, 0, 200) }, SymbolScale = 0.9 }; _timer = new Timer(_ => UpdateData(), this, 0, 2000); }
private readonly System.Threading.Timer _timer; // timer used in polling the update data // Create a Layer that will update the position of the rater using a DynamicMemoryProvider public AnimatedPointsWithAutoUpdateLayer(ref MySettings settings) : base(new DynamicMemoryProvider()) { Style = new SymbolStyle { Fill = { Color = settings.ReturnColor() }, SymbolScale = .5 }; // Set the symbol color and size used to represent the Vehicle on the map _timer = new System.Threading.Timer(arg => UpdateData(), this, 0, 3000); // Set the timer to update the data from DynamicMemoryProvider }
public VertexOnlyLayer(ILayer source) { _source = source; _source.DataChanged += (sender, args) => OnDataChanged(args); Style = new SymbolStyle { SymbolScale = 0.5 }; }
public PositionLayer(GeoPosition originalPosition, SymbolStyle style) { _style = style; Position = originalPosition; DataSource = new MemoryProvider(GetFeatures()); Style = null; }
public AnimatedPointsWithAutoUpdateLayer() : base(new DynamicMemoryProvider()) { Style = new SymbolStyle() { BitmapId = GetBitmapIdForEmbeddedResource(MarkerLocationName), SymbolScale = 0.5 }; }
private SymbolStyle GetNodeLayerStyle() { var s = new SymbolStyle(); s.Fill = new Mapsui.Styles.Brush(_defaultColor); s.SymbolScale = 0.3; s.SymbolType = SymbolType.Ellipse; return(s); }
private static void DrawPointWithSymbolStyle(SKCanvas canvas, SymbolStyle style, Point destination, SymbolType symbolType = SymbolType.Ellipse) { canvas.Save(); canvas.Translate((float)destination.X, (float)destination.Y); canvas.Scale((float)style.SymbolScale, (float)style.SymbolScale); DrawPointWithVectorStyle(canvas, style, symbolType); canvas.Restore(); }
private IStyle GetNodeLayerStyle() { var s = new SymbolStyle(); s.Fill = new Mapsui.Styles.Brush(Colors.Black.ToMapsui()); s.SymbolScale = 0.3; s.SymbolType = SymbolType.Ellipse; return(s); }
private void CalculateSymbolStyle(SymbolStyle style, SymbolStyle min, SymbolStyle max, double value) { double dFrac = Fraction(value); style.BitmapId = (dFrac > 0.5) ? min.BitmapId : max.BitmapId; style.SymbolOffset = (dFrac > 0.5 ? min.SymbolOffset : max.SymbolOffset); //We don't interpolate the offset but let it follow the symbol instead style.SymbolScale = InterpolateDouble(min.SymbolScale, max.SymbolScale, value); }
//private RenderType renderType = RenderType.ColorBySeries; public DataSeries() { pointList = new ArrayList(); errorList = new ArrayList(); lineStyle = new LineStyle(); errorlineStyle = new LineStyle(); SymbolStyle = new SymbolStyle(); //valueList = new ArrayList(); }
private void SyncSymbolSettings(ShapefileLayer pointLayer) { SymbolStyle symbolStyle = (SymbolStyle)pointLayer.Styles[0]; symbolStyle.SymbolType = (SymbolType)SymbolTypeComboBox.SelectedValue; symbolStyle.Size = (float)SymbolSizeComboBox.SelectedValue; symbolStyle.Margin = 40; Map1.Refresh("PointOverlay"); }
public AnimatedPointsWithAutoUpdateLayer() : base(new DynamicMemoryProvider()) { //Yellow circle Style = new SymbolStyle { Fill = { Color = new Mapsui.Styles.Color(255, 215, 0, 200) }, SymbolScale = 0.7 }; //Execute every second _timer = new Timer(arg => UpdateData(), this, 0, 1000); }
private static IRenderTheme replaceThemeSymbols(RenderTheme renderTheme, IDictionary <object, TextureRegion> regionMap) { //JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET: //ORIGINAL LINE: org.oscim.theme.styles.SymbolStyle.SymbolBuilder<?> symbolBuilder = org.oscim.theme.styles.SymbolStyle.builder(); SymbolStyle.SymbolBuilder <object> symbolBuilder = SymbolStyle.builder(); foreach (Rule rule in renderTheme.Rules) { replaceRuleSymbols(rule, regionMap, symbolBuilder); } return(renderTheme); }
private static void DrawPointWithBitmapStyle(SKCanvas canvas, SymbolStyle symbolStyle, Point destination, SymbolCache symbolCache) { var bitmap = symbolCache.GetOrCreate(symbolStyle.BitmapId); BitmapHelper.RenderBitmap(canvas, bitmap.Bitmap, (float)destination.X, (float)destination.Y, (float)symbolStyle.SymbolRotation, (float)symbolStyle.SymbolOffset.X, (float)symbolStyle.SymbolOffset.Y, opacity: (float)symbolStyle.Opacity, scale: (float)symbolStyle.SymbolScale); }
private static CALayer CreateSymbolFromBitmap(SymbolStyle style, SymbolStyle symbolStyle) { var symbol = new CALayer(); var image = ToUIImage(style.Symbol.Data); symbol.Contents = image.CGImage; symbol.Frame = new RectangleF(-image.Size.Width * 0.5f, -image.Size.Height * 0.5f, image.Size.Width, image.Size.Height); symbol.Opacity = (float)symbolStyle.Opacity; return(symbol); }
private static CALayer CreateSymbolFromBitmap(SymbolStyle style) { var symbol = new CALayer(); var image = ToUIImage(BitmapRegistry.Instance.Get(style.BitmapId)); symbol.Contents = image.CGImage; symbol.Frame = new CGRect(-image.Size.Width * 0.5f, -image.Size.Height * 0.5f, image.Size.Width, image.Size.Height); symbol.Opacity = (float)style.Opacity; return(symbol); }
private void LoadUserLocationPin() { Assembly assembly = typeof(MapService).GetTypeInfo().Assembly; Stream stream = assembly.GetManifestResourceStream("TramlineFive.Common.person.png"); var bitmapId = BitmapRegistry.Instance.Register(stream); userStyle = new SymbolStyle { BitmapId = bitmapId }; }
private static SymbolStyle Copy(SymbolStyle source, SymbolStyle dest) { dest.BitmapId = source.BitmapId; dest.SymbolScale = source.SymbolScale; dest.SymbolOffset = source.SymbolOffset.Copy(); dest.SymbolRotation = source.SymbolRotation; dest.RotateWithMap = source.RotateWithMap; dest.UnitType = source.UnitType; dest.SymbolType = source.SymbolType; Copy((VectorStyle)source, dest); return(dest); }
public RoutePointsLayer() { _memoryProvider = new MemoryProvider(); DataSource = _memoryProvider; IsMapInfoLayer = true; Style = new SymbolStyle { Enabled = true, SymbolType = SymbolType.Ellipse, SymbolScale = 0.25, Fill = new Brush(new Color(40, 40, 40)) }; }
public bool Equals(SymbolStyle symbolStyle) { if (!base.Equals(symbolStyle)) { return false; } if ((Symbol == null) ^ (symbolStyle.Symbol == null)) { return false; } if (Symbol != null && !Symbol.Equals(symbolStyle.Symbol)) { return false; } if (!SymbolScale.Equals(SymbolScale)) { return false; } if ((SymbolOffset == null) ^ (symbolStyle.SymbolOffset == null)) { return false; } if ((SymbolOffset != null) && (!SymbolOffset.Equals(symbolStyle.SymbolOffset))) { return false; } if (SymbolRotation != symbolStyle.SymbolRotation) { return false; } if (UnitType != symbolStyle.UnitType) { return false; } if (SymbolType != symbolStyle.SymbolType) { return false; } if (Opacity != symbolStyle.Opacity) { return false; } if (Width != symbolStyle.Width) { return false; } if (Height != symbolStyle.Height) { return false; } return true; }
/// <summary> /// Print the specified text into the buffers. /// Note: 'lineWidth' parameter should be in pixels. /// </summary> public void Print(string text, Color32 color, BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols, bool encoding, SymbolStyle symbolStyle, Alignment alignment, int lineWidth, bool premultiply) { if (mReplacement != null) { mReplacement.Print(text, color, verts, uvs, cols, encoding, symbolStyle, alignment, lineWidth, premultiply); } else if (text != null) { if (!isValid) { Debug.LogError("Attempting to print using an invalid font!"); return; } // Make sure the characters are present in the dynamic font before printing them bool dynamic = isDynamic; #if !UNITY_3_5 if (dynamic) { mDynamicFont.textureRebuildCallback = OnFontChanged; mDynamicFont.RequestCharactersInTexture(text, mDynamicFontSize, mDynamicFontStyle); mDynamicFont.textureRebuildCallback = null; } #endif mColors.Clear(); mColors.Add(color); int fs = size; Vector2 invSize = fs > 0 ? new Vector2(1f / fs, 1f / fs) : Vector2.one; int indexOffset = verts.size; int maxX = 0; int x = 0; int y = 0; int prev = 0; int lineHeight = (fs + mSpacingY); Vector3 v0 = Vector3.zero, v1 = Vector3.zero; Vector2 u0 = Vector2.zero, u1 = Vector2.zero; float invX = uvRect.width / mFont.texWidth; float invY = mUVRect.height / mFont.texHeight; int textLength = text.Length; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols && (dynamicSymbolsFont == null? sprite != null : dynamicSymbolsFont.sprite != null) ; List<int> dynamicSymblosIndexs = new List<int>(); //need to record all dynamic symblo verts index. List<Vector2> dynamicSymblosPosBase = new List<Vector2>(); List<string> dynamicSymblosKeyName = new List<string>(); for (int i = 0; i < textLength; ++i) { char c = text[i]; if (c == '\n') { if (x > maxX) maxX = x; if (alignment != Alignment.Left) { Align(verts, indexOffset, alignment, x, lineWidth); indexOffset = verts.size; } x = 0; y += lineHeight; prev = 0; continue; } if (c < ' ') { prev = 0; continue; } if (encoding && c == '[') { int retVal = NGUITools.ParseSymbol(text, i, mColors, premultiply); if (retVal > 0) { color = mColors[mColors.Count - 1]; i += retVal - 1; continue; } } if (!dynamic) { // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, i, textLength) : null; if (symbol == null) { BMGlyph glyph = mFont.GetGlyph(c); if (glyph == null) continue; if (prev != 0) x += glyph.GetKerning(prev); if (c == ' ') { x += mSpacingX + glyph.advance; prev = c; continue; } v0.x = invSize.x * (x + glyph.offsetX); v0.y = -invSize.y * (y + glyph.offsetY); v1.x = v0.x + invSize.x * glyph.width; v1.y = v0.y - invSize.y * glyph.height; u0.x = mUVRect.xMin + invX * glyph.x; u0.y = mUVRect.yMax - invY * glyph.y; u1.x = u0.x + invX * glyph.width; u1.y = u0.y - invY * glyph.height; x += mSpacingX + glyph.advance; prev = c; if (glyph.channel == 0 || glyph.channel == 15) { for (int b = 0; b < 4; ++b) cols.Add(color); } else { // Packed fonts come as alpha masks in each of the RGBA channels. // In order to use it we need to use a special shader. // // Limitations: // - Effects (drop shadow, outline) will not work. // - Should not be a part of the atlas (eastern fonts rarely are anyway). // - Lower color precision Color col = color; col *= 0.49f; switch (glyph.channel) { case 1: col.b += 0.51f; break; case 2: col.g += 0.51f; break; case 4: col.r += 0.51f; break; case 8: col.a += 0.51f; break; } for (int b = 0; b < 4; ++b) cols.Add(col); } } else { v0.x = invSize.x * (x + symbol.offsetX); v0.y = -invSize.y * (y + symbol.offsetY); v1.x = v0.x + invSize.x * symbol.width; v1.y = v0.y - invSize.y * symbol.height; Rect uv = symbol.uvRect; u0.x = uv.xMin; u0.y = uv.yMax; u1.x = uv.xMax; u1.y = uv.yMin; x += mSpacingX + symbol.advance; i += symbol.length - 1; prev = 0; if (symbolStyle == SymbolStyle.Colored) { for (int b = 0; b < 4; ++b) cols.Add(color); } else { Color32 col = Color.white; col.a = color.a; for (int b = 0; b < 4; ++b) cols.Add(col); } } verts.Add(new Vector3(v1.x, v0.y)); verts.Add(new Vector3(v1.x, v1.y)); verts.Add(new Vector3(v0.x, v1.y)); verts.Add(new Vector3(v0.x, v0.y)); uvs.Add(new Vector2(u1.x, u0.y)); uvs.Add(new Vector2(u1.x, u1.y)); uvs.Add(new Vector2(u0.x, u1.y)); uvs.Add(new Vector2(u0.x, u0.y)); } #if !UNITY_3_5 else { // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, i, textLength) : null; if(symbol != null) { v0.x = invSize.x * (x + symbol.offsetX); v0.y = -invSize.y * (y + symbol.offsetY); v1.x = v0.x + invSize.x * symbol.width; v1.y = v0.y - invSize.y * symbol.height; Rect uv = symbol.uvRect; u0.x = uv.xMin; u0.y = uv.yMax; u1.x = uv.xMax; u1.y = uv.yMin; //x += mSpacingX + symbol.advance; x += mSpacingX + mDynamicFontSize; i += symbol.length - 1; prev = 0; if (symbolStyle == SymbolStyle.Colored) { Color32 col = color; col.a = 0; for (int b = 0; b < 4; ++b) cols.Add(col); } else { Color32 col = Color.white; col.a = 0; for (int b = 0; b < 4; ++b) cols.Add(col); } uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(0, 0)); verts.Add(new Vector3(v1.x, v0.y)); verts.Add(new Vector3(v0.x, v0.y)); //maybe need to add into dynamic symblos verts dynamicSymblosIndexs.Add(verts.size - 1); //record this index position.. dynamicSymblosPosBase.Add(new Vector3(v0.x, v0.y)); dynamicSymblosKeyName.Add(symbol.spriteName); verts.Add(new Vector3(v0.x, v1.y)); verts.Add(new Vector3(v1.x, v1.y)); } else // add dynamic font's info { if (!mDynamicFont.GetCharacterInfo(c, out mChar, mDynamicFontSize, mDynamicFontStyle)) continue; v0.x = invSize.x * (x + mChar.vert.xMin); v0.y = -invSize.y * (y - mChar.vert.yMax + mDynamicFontOffset); v1.x = v0.x + invSize.x * mChar.vert.width; v1.y = v0.y - invSize.y * mChar.vert.height; u0.x = mChar.uv.xMin; u0.y = mChar.uv.yMin; u1.x = mChar.uv.xMax; u1.y = mChar.uv.yMax; x += mSpacingX + (int)mChar.width; for (int b = 0; b < 4; ++b) cols.Add(color); if (mChar.flipped) { uvs.Add(new Vector2(u0.x, u1.y)); uvs.Add(new Vector2(u0.x, u0.y)); uvs.Add(new Vector2(u1.x, u0.y)); uvs.Add(new Vector2(u1.x, u1.y)); } else { uvs.Add(new Vector2(u1.x, u0.y)); uvs.Add(new Vector2(u0.x, u0.y)); uvs.Add(new Vector2(u0.x, u1.y)); uvs.Add(new Vector2(u1.x, u1.y)); } verts.Add(new Vector3(v1.x, v0.y)); verts.Add(new Vector3(v0.x, v0.y)); verts.Add(new Vector3(v0.x, v1.y)); verts.Add(new Vector3(v1.x, v1.y)); } } #endif } if (alignment != Alignment.Left && indexOffset < verts.size) { Align(verts, indexOffset, alignment, x, lineWidth); indexOffset = verts.size; } //get all after align dynamic symblos verts if(dynamicSymblosIndexs.Count > 0 && mDynamicSymbolLabel != null) { for(int i =0; i< dynamicSymblosIndexs.Count; i++) { int tIndex = dynamicSymblosIndexs[i]; if(tIndex <= verts.size - 1) { if(alignment == Alignment.Left) mDynamicSymbolLabel.addSymbloVert(dynamicSymblosPosBase[i],dynamicSymblosKeyName[i]); else mDynamicSymbolLabel.addSymbloVert(verts.buffer[tIndex],dynamicSymblosKeyName[i]); } } } //reset mDynamicSymbolLabel = null; } }
public void Print (string text, Color32 color, BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols, bool encoding, SymbolStyle symbolStyle, Alignment alignment, int lineWidth, bool premultiply) #endif { if (mReplacement != null) { mReplacement.Print(text, color, verts, uvs, cols, encoding, symbolStyle, alignment, lineWidth, premultiply); } else if (mFont != null && text != null) { if (!mFont.isValid) { Debug.LogError("Attempting to print using an invalid font!"); return; } mColors.Clear(); mColors.Add(color); Vector2 scale = mFont.charSize > 0 ? new Vector2(1f / mFont.charSize, 1f / mFont.charSize) : Vector2.one; int indexOffset = verts.size; int maxX = 0; int x = 0; int y = 0; int prev = 0; int lineHeight = (mFont.charSize + mSpacingY); Vector3 v0 = Vector3.zero, v1 = Vector3.zero; Vector2 u0 = Vector2.zero, u1 = Vector2.zero; float invX = uvRect.width / mFont.texWidth; float invY = mUVRect.height / mFont.texHeight; int textLength = text.Length; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols && sprite != null; for (int i = 0; i < textLength; ++i) { char c = text[i]; if (c == '\n') { if (x > maxX) maxX = x; if (alignment != Alignment.Left) { Align(verts, indexOffset, alignment, x, lineWidth); indexOffset = verts.size; } x = 0; y += lineHeight; prev = 0; continue; } if (c < ' ') { prev = 0; continue; } if (encoding && c == '[') { int retVal = NGUITools.ParseSymbol(text, i, mColors, premultiply); if (retVal > 0) { color = mColors[mColors.Count - 1]; i += retVal - 1; continue; } } // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, i, textLength) : null; if (symbol == null || !symbol.Validate(atlas)) { BMGlyph glyph = mFont.GetGlyph(c); if (glyph == null) continue; if (prev != 0) x += glyph.GetKerning(prev); if (c == ' ') { x += mSpacingX + glyph.advance; prev = c; continue; } v0.x = scale.x * (x + glyph.offsetX); v0.y = -scale.y * (y + glyph.offsetY); v1.x = v0.x + scale.x * glyph.width; v1.y = v0.y - scale.y * glyph.height; u0.x = mUVRect.xMin + invX * glyph.x; u0.y = mUVRect.yMax - invY * glyph.y; u1.x = u0.x + invX * glyph.width; u1.y = u0.y - invY * glyph.height; x += mSpacingX + glyph.advance; prev = c; if (glyph.channel == 0 || glyph.channel == 15) { for (int b = 0; b < 4; ++b) cols.Add(color); } else { // Packed fonts come as alpha masks in each of the RGBA channels. // In order to use it we need to use a special shader. // // Limitations: // - Effects (drop shadow, outline) will not work. // - Should not be a part of the atlas (eastern fonts rarely are anyway). // - Lower color precision Color col = color; col *= 0.49f; switch (glyph.channel) { case 1: col.b += 0.51f; break; case 2: col.g += 0.51f; break; case 4: col.r += 0.51f; break; case 8: col.a += 0.51f; break; } for (int b = 0; b < 4; ++b) cols.Add(col); } } else { v0.x = scale.x * (x + symbol.offsetX); v0.y = -scale.y * (y + symbol.offsetY); v1.x = v0.x + scale.x * symbol.width; v1.y = v0.y - scale.y * symbol.height; Rect uv = symbol.uvRect; u0.x = uv.xMin; u0.y = uv.yMax; u1.x = uv.xMax; u1.y = uv.yMin; x += mSpacingX + symbol.advance; i += symbol.length - 1; prev = 0; if (symbolStyle == SymbolStyle.Colored) { for (int b = 0; b < 4; ++b) cols.Add(color); } else { Color32 col = Color.white; col.a = color.a; for (int b = 0; b < 4; ++b) cols.Add(col); } } verts.Add(new Vector3(v1.x, v0.y)); verts.Add(new Vector3(v1.x, v1.y)); verts.Add(new Vector3(v0.x, v1.y)); verts.Add(new Vector3(v0.x, v0.y)); uvs.Add(new Vector2(u1.x, u0.y)); uvs.Add(new Vector2(u1.x, u1.y)); uvs.Add(new Vector2(u0.x, u1.y)); uvs.Add(new Vector2(u0.x, u0.y)); } if (alignment != Alignment.Left && indexOffset < verts.size) { Align(verts, indexOffset, alignment, x, lineWidth); indexOffset = verts.size; } } }
/// <summary> /// Print the specified text into the buffers. /// Note: 'lineWidth' parameter should be in pixels. /// </summary> #if UNITY_3_5_4 public void Print (string text, Color color, BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color> cols, bool encoding, SymbolStyle symbolStyle, Alignment alignment, int lineWidth, bool premultiply)
/// <summary> /// Text wrapping functionality. The 'maxWidth' should be in local coordinates (take pixels and divide them by transform's scale). /// </summary> public string WrapText(string text, float maxWidth, int maxLineCount, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) return mReplacement.WrapText(text, maxWidth, maxLineCount, encoding, symbolStyle); // Width of the line in pixels int lineWidth = Mathf.RoundToInt(maxWidth * size); if (lineWidth < 1) return text; StringBuilder sb = new StringBuilder(); int textLength = text.Length; int remainingWidth = lineWidth; int previousChar = 0; int start = 0; int offset = 0; bool lineIsEmpty = true; bool multiline = (maxLineCount != 1); int lineCount = 1; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; // Run through all characters for (; offset < textLength; ++offset) { char ch = text[offset]; // New line character -- start a new line if (ch == '\n') { if (!multiline || lineCount == maxLineCount ) break; remainingWidth = lineWidth; // Add the previous word to the final string if (start < offset) sb.Append(text.Substring(start, offset - start + 1)); else sb.Append(ch); lineIsEmpty = true; ++lineCount; start = offset + 1; previousChar = 0; continue; } // If this marks the end of a word, add it to the final string. if (ch == ' ' && previousChar != ' ' && start < offset) { sb.Append(text.Substring(start, offset - start + 1)); lineIsEmpty = false; start = offset + 1; previousChar = ch; } // When encoded symbols such as [RrGgBb] or [-] are encountered, skip past them if (encoding && ch == '[') { if (offset + 2 < textLength) { if (text[offset + 1] == '-' && text[offset + 2] == ']') { offset += 2; continue; } else if (offset + 7 < textLength && text[offset + 7] == ']') { if (NGUITools.EncodeColor(NGUITools.ParseColor(text, offset + 1)) == text.Substring(offset + 1, 6).ToUpper()) { offset += 7; continue; } } } } // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, offset, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (symbol != null && symbol.Validate(atlas)) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = (symbol == null) ? mFont.GetGlyph(ch) : null; if (glyph != null) { glyphWidth += (previousChar != 0) ? glyph.advance + glyph.GetKerning(previousChar) : glyph.advance; } else continue; } // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; // Doesn't fit? if (remainingWidth < 0) { // Can't start a new line if (lineIsEmpty || !multiline || lineCount == maxLineCount) { // This is the first word on the line -- add it up to the character that fits sb.Append(text.Substring(start, Mathf.Max(0, offset - start))); if (!multiline || lineCount == maxLineCount) { start = offset; break; } EndLine(ref sb); // Start a brand-new line lineIsEmpty = true; ++lineCount; if (ch == ' ') { start = offset + 1; remainingWidth = lineWidth; } else { start = offset; remainingWidth = lineWidth - glyphWidth; } previousChar = 0; } else { // Skip all spaces before the word while (start < textLength && text[start] == ' ') ++start; // Revert the position to the beginning of the word and reset the line lineIsEmpty = true; remainingWidth = lineWidth; offset = start - 1; previousChar = 0; if (!multiline || lineCount == maxLineCount) break; ++lineCount; EndLine(ref sb); continue; } } else previousChar = ch; // Advance the offset past the symbol if (symbol != null) { offset += symbol.length - 1; previousChar = 0; } } if (start < offset) sb.Append(text.Substring(start, offset - start)); return sb.ToString(); }
/// <summary> /// Different line wrapping functionality -- contributed by MightyM. /// http://www.tasharen.com/forum/index.php?topic=1049.0 /// </summary> public string GetEndOfLineThatFits (string text, float maxWidth, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) return mReplacement.GetEndOfLineThatFits(text, maxWidth, encoding, symbolStyle); int lineWidth = Mathf.RoundToInt(maxWidth * size); if (lineWidth < 1) return text; int textLength = text.Length; int remainingWidth = lineWidth; BMGlyph followingGlyph = null; int currentCharacterIndex = textLength; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; while (currentCharacterIndex > 0 && remainingWidth > 0) { char currentCharacter = text[--currentCharacterIndex]; // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, currentCharacterIndex, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (symbol != null && symbol.Validate(atlas)) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = mFont.GetGlyph(currentCharacter); if (glyph != null) { glyphWidth += glyph.advance + ((followingGlyph == null) ? 0 : followingGlyph.GetKerning(currentCharacter)); followingGlyph = glyph; } else { followingGlyph = null; continue; } } // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; } if (remainingWidth < 0) ++currentCharacterIndex; return text.Substring(currentCharacterIndex, textLength - currentCharacterIndex); }
/// <summary> /// Get the printed size of the specified string. The returned value is in local coordinates. Multiply by transform's scale to get pixels. /// </summary> public Vector2 CalculatePrintedSize (string text, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) return mReplacement.CalculatePrintedSize(text, encoding, symbolStyle); Vector2 v = Vector2.zero; if (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text)) { if (encoding) text = NGUITools.StripSymbols(text); int length = text.Length; int maxX = 0; int x = 0; int y = 0; int prev = 0; int lineHeight = (mFont.charSize + mSpacingY); bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; for (int i = 0; i < length; ++i) { char c = text[i]; // Start a new line if (c == '\n') { if (x > maxX) maxX = x; x = 0; y += lineHeight; prev = 0; continue; } // Skip invalid characters if (c < ' ') { prev = 0; continue; } // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, i, length) : null; if (symbol == null || !symbol.Validate(atlas)) { // Get the glyph for this character BMGlyph glyph = mFont.GetGlyph(c); if (glyph != null) { x += mSpacingX + ((prev != 0) ? glyph.advance + glyph.GetKerning(prev) : glyph.advance); prev = c; } } else { // Symbol found -- use it x += mSpacingX + symbol.advance; i += symbol.length - 1; prev = 0; } } // Convert from pixel coordinates to local coordinates float scale = (mFont.charSize > 0) ? 1f / mFont.charSize : 1f; v.x = scale * ((x > maxX) ? x : maxX); v.y = scale * (y + lineHeight); } return v; }
/// <summary> /// Text wrapping functionality. The 'maxWidth' should be in local coordinates (take pixels and divide them by transform's scale). /// </summary> public bool WrapText (string text, out string finalText, float width, float height, int lines, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) { return mReplacement.WrapText(text, out finalText, width, height, lines, encoding, symbolStyle); } // Zero means unlimited if (width == 0f) width = 100000f; if (height == 0f) height = 100000f; // Width and height of the line in pixels int lineWidth = Mathf.FloorToInt(width * size); int lineHeight = Mathf.FloorToInt(height * size); if (lineWidth < 1 || lineHeight < 1) { finalText = ""; return false; } int maxLineCount = (lines > 0) ? lines : 999999; if (height != 0f) { maxLineCount = Mathf.Min(maxLineCount, Mathf.FloorToInt(height)); if (maxLineCount == 0) { finalText = ""; return false; } } #if DYNAMIC_FONT if (mDynamicFont != null) mDynamicFont.RequestCharactersInTexture(text, mDynamicFontSize); #endif StringBuilder sb = new StringBuilder(); int textLength = text.Length; int remainingWidth = lineWidth; int previousChar = 0; int start = 0; int offset = 0; bool lineIsEmpty = true; bool multiline = (lines != 1); int lineCount = 1; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; bool dynamic = isDynamic; // Run through all characters for (; offset < textLength; ++offset) { char ch = text[offset]; // New line character -- start a new line if (ch == '\n') { if (!multiline || lineCount == maxLineCount) break; remainingWidth = lineWidth; // Add the previous word to the final string if (start < offset) sb.Append(text.Substring(start, offset - start + 1)); else sb.Append(ch); lineIsEmpty = true; ++lineCount; start = offset + 1; previousChar = 0; continue; } // If this marks the end of a word, add it to the final string. if (ch == ' ' && previousChar != ' ' && start < offset) { sb.Append(text.Substring(start, offset - start + 1)); lineIsEmpty = false; start = offset + 1; previousChar = ch; } // When encoded symbols such as [RrGgBb] or [-] are encountered, skip past them if (encoding && ch == '[') { if (offset + 2 < textLength) { if (text[offset + 1] == '-' && text[offset + 2] == ']') { offset += 2; continue; } else if (offset + 7 < textLength && text[offset + 7] == ']') { if (NGUITools.EncodeColor(NGUITools.ParseColor(text, offset + 1)) == text.Substring(offset + 1, 6).ToUpper()) { offset += 7; continue; } } } } // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, offset, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (!dynamic) { if (symbol != null) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = (symbol == null) ? mFont.GetGlyph(ch) : null; if (glyph != null) { glyphWidth += (previousChar != 0) ? glyph.advance + glyph.GetKerning(previousChar) : glyph.advance; } else continue; } } #if DYNAMIC_FONT else { if (mDynamicFont.GetCharacterInfo(ch, out mChar, mDynamicFontSize, mDynamicFontStyle)) glyphWidth += Mathf.RoundToInt(mChar.advance); } #endif // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; // Doesn't fit? if (remainingWidth < 0) { // Can't start a new line if (lineIsEmpty || !multiline || lineCount == maxLineCount) { // This is the first word on the line -- add it up to the character that fits sb.Append(text.Substring(start, Mathf.Max(0, offset - start))); if (!multiline || lineCount == maxLineCount) { start = offset; break; } EndLine(ref sb); // Start a brand-new line lineIsEmpty = true; ++lineCount; if (ch == ' ') { start = offset + 1; remainingWidth = lineWidth; } else { start = offset; remainingWidth = lineWidth - glyphWidth; } previousChar = 0; } else { // Skip all spaces before the word while (start < textLength && text[start] == ' ') ++start; // Revert the position to the beginning of the word and reset the line lineIsEmpty = true; remainingWidth = lineWidth; offset = start - 1; previousChar = 0; if (!multiline || lineCount == maxLineCount) break; ++lineCount; EndLine(ref sb); continue; } } else previousChar = ch; // Advance the offset past the symbol if (!dynamic && symbol != null) { offset += symbol.length - 1; previousChar = 0; } } if (start < offset) sb.Append(text.Substring(start, offset - start)); finalText = sb.ToString(); return (!multiline || offset == textLength || (lines > 0 && lineCount <= lines)); }
/// <summary> /// Different line wrapping functionality -- contributed by MightyM. /// http://www.tasharen.com/forum/index.php?topic=1049.0 /// </summary> public string GetEndOfLineThatFits (string text, float maxWidth, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) return mReplacement.GetEndOfLineThatFits(text, maxWidth, encoding, symbolStyle); int lineWidth = Mathf.RoundToInt(maxWidth); if (lineWidth < 1) return text; #if DYNAMIC_FONT if (mDynamicFont != null) mDynamicFont.RequestCharactersInTexture(text, mDynamicFontSize, mDynamicFontStyle); #endif int textLength = text.Length; int remainingWidth = lineWidth; BMGlyph followingGlyph = null; int currentCharacterIndex = textLength; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; bool dynamic = isDynamic; while (currentCharacterIndex > 0 && remainingWidth > 0) { char currentCharacter = text[--currentCharacterIndex]; // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, currentCharacterIndex, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (!dynamic) { if (symbol != null) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = mFont.GetGlyph(currentCharacter); if (glyph != null) { glyphWidth += glyph.advance + ((followingGlyph == null) ? 0 : followingGlyph.GetKerning(currentCharacter)); followingGlyph = glyph; } else { followingGlyph = null; continue; } } } #if DYNAMIC_FONT else { if (mDynamicFont.GetCharacterInfo(currentCharacter, out mChar, mDynamicFontSize, mDynamicFontStyle)) glyphWidth += (int)mChar.width; } #endif // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; } if (remainingWidth < 0) ++currentCharacterIndex; return text.Substring(currentCharacterIndex, textLength - currentCharacterIndex); }
/// <summary> /// Get the printed size of the specified string. The returned value is in pixels. /// </summary> public Vector2 CalculatePrintedSize (string text, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) return mReplacement.CalculatePrintedSize(text, encoding, symbolStyle); Vector2 v = Vector2.zero; bool dynamic = isDynamic; #if DYNAMIC_FONT if (dynamic || (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text))) #else if (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text)) #endif { if (encoding) text = NGUITools.StripSymbols(text); #if DYNAMIC_FONT if (mDynamicFont != null) mDynamicFont.RequestCharactersInTexture(text, mDynamicFontSize, mDynamicFontStyle); #endif int length = text.Length; int maxX = 0; int x = 0; int y = 0; int prev = 0; int fs = size; int lineHeight = (fs + mSpacingY); bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; for (int i = 0; i < length; ++i) { char c = text[i]; // Start a new line if (c == '\n') { if (x > maxX) maxX = x; x = 0; y += lineHeight; prev = 0; continue; } // Skip invalid characters if (c < ' ') { prev = 0; continue; } if (!dynamic) { // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, i, length) : null; if (symbol == null) { // Get the glyph for this character BMGlyph glyph = mFont.GetGlyph(c); if (glyph != null) { x += mSpacingX + ((prev != 0) ? glyph.advance + glyph.GetKerning(prev) : glyph.advance); prev = c; } } else { // Symbol found -- use it x += mSpacingX + symbol.width; i += symbol.length - 1; prev = 0; } } #if DYNAMIC_FONT else { if (mDynamicFont.GetCharacterInfo(c, out mChar, mDynamicFontSize, mDynamicFontStyle)) x += (int)(mSpacingX + mChar.width); } #endif } // Convert from pixel coordinates to local coordinates v.x = ((x > maxX) ? x : maxX); v.y = (y + lineHeight); } return v; }
/// <summary> /// Text wrapping functionality. The 'width' and 'height' should be in pixels. /// Returns 'true' if the specified text was able to fit into the provided dimensions, 'false' otherwise. /// </summary> public bool WrapText (string text, int size, out string finalText, int width, int height, int maxLines, bool encoding, SymbolStyle symbolStyle) { if (mReplacement != null) { return mReplacement.WrapText(text, size, out finalText, width, height, maxLines, encoding, symbolStyle); } #if DYNAMIC_FONT if (isDynamic) return NGUIText.WrapText(text, mDynamicFont, size, mDynamicFontStyle, width, height, maxLines, encoding, out finalText); #endif if (width < 1 || height < 1) { finalText = ""; return false; } if (maxLines > 0) height = Mathf.Min(height, size * maxLines); int maxLineCount = (maxLines > 0) ? maxLines : 1000000; maxLineCount = Mathf.Min(maxLineCount, height / size); if (maxLineCount == 0) { finalText = ""; return false; } StringBuilder sb = new StringBuilder(); int textLength = text.Length; int remainingWidth = width; int previousChar = 0; int start = 0; int offset = 0; int lineCount = 1; bool lineIsEmpty = true; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; // Run through all characters for (; offset < textLength; ++offset) { char ch = text[offset]; // New line character -- start a new line if (ch == '\n') { if (lineCount == maxLineCount) break; remainingWidth = width; // Add the previous word to the final string if (start < offset) sb.Append(text.Substring(start, offset - start + 1)); else sb.Append(ch); lineIsEmpty = true; ++lineCount; start = offset + 1; previousChar = 0; continue; } // If this marks the end of a word, add it to the final string. if (ch == ' ' && previousChar != ' ' && start < offset) { sb.Append(text.Substring(start, offset - start + 1)); lineIsEmpty = false; start = offset + 1; previousChar = ch; } // When encoded symbols such as [RrGgBb] or [-] are encountered, skip past them if (NGUIText.ParseSymbol(text, ref offset)) { --offset; continue; } // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, offset, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (symbol != null) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = (symbol == null) ? mFont.GetGlyph(ch) : null; if (glyph != null) glyphWidth += (previousChar != 0) ? glyph.advance + glyph.GetKerning(previousChar) : glyph.advance; else continue; } // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; // Doesn't fit? if (remainingWidth < 0) { // Can't start a new line if (lineIsEmpty || lineCount == maxLineCount) { // This is the first word on the line -- add it up to the character that fits sb.Append(text.Substring(start, Mathf.Max(0, offset - start))); if (lineCount++ == maxLineCount) { start = offset; break; } NGUIText.EndLine(ref sb); // Start a brand-new line lineIsEmpty = true; if (ch == ' ') { start = offset + 1; remainingWidth = width; } else { start = offset; remainingWidth = width - glyphWidth; } previousChar = 0; } else { // Skip all spaces before the word while (start < textLength && text[start] == ' ') ++start; // Revert the position to the beginning of the word and reset the line lineIsEmpty = true; remainingWidth = width; offset = start - 1; previousChar = 0; if (lineCount++ == maxLineCount) break; NGUIText.EndLine(ref sb); continue; } } else previousChar = ch; // Advance the offset past the symbol if (symbol != null) { offset += symbol.length - 1; previousChar = 0; } } if (start < offset) sb.Append(text.Substring(start, offset - start)); finalText = sb.ToString(); return (offset == textLength) || (lineCount <= Mathf.Min(maxLines, maxLineCount)); }
/// <summary> /// Calculate the character index offset required to print the end of the specified text. /// Originally contributed by MightyM: http://www.tasharen.com/forum/index.php?topic=1049.0 /// </summary> public int CalculateOffsetToFit (string text, int size, int lineWidth, bool encoding, SymbolStyle symbolStyle) { if (lineWidth < 1) return 0; if (mReplacement != null) return mReplacement.CalculateOffsetToFit(text, size, lineWidth, encoding, symbolStyle); #if DYNAMIC_FONT if (isDynamic) return NGUIText.CalculateOffsetToFit(text, mDynamicFont, size, mDynamicFontStyle, lineWidth); #endif int textLength = text.Length; int remainingWidth = lineWidth; BMGlyph followingGlyph = null; int currentCharacterIndex = textLength; bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols; while (currentCharacterIndex > 0 && remainingWidth > 0) { char currentCharacter = text[--currentCharacterIndex]; // See if there is a symbol matching this text BMSymbol symbol = useSymbols ? MatchSymbol(text, currentCharacterIndex, textLength) : null; // Calculate how wide this symbol or character is going to be int glyphWidth = mSpacingX; if (symbol != null) { glyphWidth += symbol.advance; } else { // Find the glyph for this character BMGlyph glyph = mFont.GetGlyph(currentCharacter); if (glyph != null) { glyphWidth += glyph.advance + ((followingGlyph == null) ? 0 : followingGlyph.GetKerning(currentCharacter)); followingGlyph = glyph; } else { followingGlyph = null; continue; } } // Remaining width after this glyph gets printed remainingWidth -= glyphWidth; } if (remainingWidth < 0) ++currentCharacterIndex; return currentCharacterIndex; }
/// <summary> /// Get the end of line that would fit into a field of given width. /// </summary> public string GetEndOfLineThatFits (string text, int size, int lineWidth, bool encoding, SymbolStyle symbolStyle) { int textLength = text.Length; int offset = CalculateOffsetToFit(text, size, lineWidth, encoding, symbolStyle); return text.Substring(offset, textLength - offset); }