internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { if (string.IsNullOrEmpty(text)) { return(new CCTexture2D()); } int imageWidth; int imageHeight; var textDef = textDefinition; var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width; var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height; textDef.FontSize *= contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; bool hasPremultipliedAlpha; // var display = Game.Activity.WindowManager.DefaultDisplay; // var metrics = new DisplayMetrics(); // display.GetMetrics(metrics); // Do not take into account ScaleDensity for now. // var fontScaleFactor = metrics.ScaledDensity; // textDef.FontSize = (int)(textDef.FontSize * fontScaleFactor); // out paint object to hold our drawn text // var paintFlags = new PaintFlags(); // if (textDefinition.isShouldAntialias) // paintFlags = PaintFlags.AntiAlias | PaintFlags.SubpixelText; var textPaint = new TextPaint(); textPaint.Color = Android.Graphics.Color.White; textPaint.TextAlign = Paint.Align.Left; textPaint.AntiAlias = textDefinition.isShouldAntialias; textPaint.TextSize = textDef.FontSize; var fontName = textDef.FontName; var ext = System.IO.Path.GetExtension(fontName); if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf") { CCContentManager.SharedContentManager.GetAssetStreamAsBytes(fontName, out fontName); var activity = Android.App.Application.Context; try { var typeface = Typeface.CreateFromAsset(activity.Assets, fontName); textPaint.SetTypeface(typeface); } catch (Exception) { textPaint.SetTypeface(Typeface.Create(fontName, TypefaceStyle.Normal)); } } else { textPaint.SetTypeface(Typeface.Create(fontName, TypefaceStyle.Normal)); } // color var foregroundColor = Android.Graphics.Color.White; textPaint.Color = foregroundColor; // alignment var horizontalAlignment = textDef.Alignment; var verticleAlignement = textDef.LineAlignment; var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? Layout.Alignment.AlignOpposite : (CCTextAlignment.Center == horizontalAlignment) ? Layout.Alignment.AlignCenter : Layout.Alignment.AlignNormal; // LineBreak // TODO: Find a way to specify the type of line breaking if possible. var dimensions = new CCSize(textDef.Dimensions.Width, textDef.Dimensions.Height); var layoutAvailable = true; if (dimensions.Width <= 0) { dimensions.Width = 8388608; layoutAvailable = false; } if (dimensions.Height <= 0) { dimensions.Height = 8388608; layoutAvailable = false; } // Get bounding rectangle - we need its attribute and method values var layout = new StaticLayout(text, textPaint, (int)dimensions.Width, textAlign, 1.0f, 0.0f, false); var boundingRect = new Rect(); var lineBounds = new Rect(); // Loop through all the lines so we can find our drawing offsets var lineCount = layout.LineCount; // early out if something went wrong somewhere and nothing is to be drawn if (lineCount == 0) { return(new CCTexture2D()); } for (int lc = 0; lc < lineCount; lc++) { layout.GetLineBounds(lc, lineBounds); var max = (int)Math.Ceiling(layout.GetLineMax(lc)); if (boundingRect.Right < max) { boundingRect.Right = max; } boundingRect.Bottom = lineBounds.Bottom; } if (!layoutAvailable) { if (dimensions.Width == 8388608) { dimensions.Width = boundingRect.Right; } if (dimensions.Height == 8388608) { dimensions.Height = boundingRect.Bottom; } } imageWidth = (int)dimensions.Width; imageHeight = (int)dimensions.Height; // Recreate our layout based on calculated dimensions so that we can draw the text correctly // in our image when Alignment is not Left. if (textAlign != Layout.Alignment.AlignNormal) { layout = new StaticLayout(text, textPaint, (int)dimensions.Width, textAlign, 1.0f, 0.0f, false); } // Line alignment var yOffset = (CCVerticalTextAlignment.Bottom == verticleAlignement || boundingRect.Bottom >= dimensions.Height) ? dimensions.Height - boundingRect.Bottom // align to bottom : (CCVerticalTextAlignment.Top == verticleAlignement) ? 0 // align to top : (imageHeight - boundingRect.Bottom) * 0.5f; // align to center try { // Create our platform dependant image to be drawn to. using (Bitmap textureBitmap = Bitmap.CreateBitmap(imageWidth, imageHeight, Bitmap.Config.Argb8888)) { using (Canvas drawingCanvas = new Canvas(textureBitmap)) { drawingCanvas.DrawARGB(0, 255, 255, 255); // Set our vertical alignment drawingCanvas.Translate(0, yOffset); // Now draw the text using our layout layout.Draw(drawingCanvas); // Create a pixel array int[] pixels = new int[imageWidth * imageHeight]; // Now lets get our pixels. // We use CopyPixelsToBuffer so that it is in Premultiplied Alpha already. // Using Bitmap.GetPixels return non Premultiplied Alpha which causes blending problems Java.Nio.IntBuffer byteBuffer = Java.Nio.IntBuffer.Allocate(imageWidth * imageHeight); textureBitmap.CopyPixelsToBuffer(byteBuffer); if (byteBuffer.HasArray) { byteBuffer.Rewind(); byteBuffer.Get(pixels, 0, pixels.Length); } // Make sure we recycle - Let's keep it green textureBitmap.Recycle(); // Here we create our Texture and then set our pixel data. var texture = new CCTexture2D(imageWidth, imageHeight); texture.XNATexture.SetData <int>(pixels); return(texture); } } } catch (Exception exc) { CCLog.Log("CCLabel Android: Error creating native label:{0}\n{1}", exc.Message, exc.StackTrace); return(new CCTexture2D()); } }
public void StartElement(object ctx, string name, string[] atts) { CCTMXMapInfo pTMXMapInfo = this; string elementName = name; var attributeDict = new Dictionary <string, string>(); if (atts != null && atts[0] != null) { for (int i = 0; i + 1 < atts.Length; i += 2) { string key = atts[i]; string value = atts[i + 1]; attributeDict.Add(key, value); } } if (elementName == "map") { string version = attributeDict["version"]; if (version != "1.0") { CCLog.Log("CocosSharp: TMXFormat: Unsupported TMX version: {0}", version); } string orientationStr = attributeDict["orientation"]; if (orientationStr == "orthogonal") { pTMXMapInfo.Orientation = (int)(CCTMXOrientation.Ortho); } else if (orientationStr == "isometric") { pTMXMapInfo.Orientation = (int)(CCTMXOrientation.Iso); } else if (orientationStr == "hexagonal") { pTMXMapInfo.Orientation = (int)(CCTMXOrientation.Hex); } else { CCLog.Log("CocosSharp: TMXFomat: Unsupported orientation: {0}", pTMXMapInfo.Orientation); } CCSize sMapSize; sMapSize.Width = CCUtils.CCParseFloat(attributeDict["width"]); sMapSize.Height = CCUtils.CCParseFloat(attributeDict["height"]); pTMXMapInfo.MapSize = sMapSize; CCSize sTileSize; sTileSize.Width = CCUtils.CCParseFloat(attributeDict["tilewidth"]); sTileSize.Height = CCUtils.CCParseFloat(attributeDict["tileheight"]); pTMXMapInfo.TileSize = sTileSize; // The parent element is now "map" pTMXMapInfo.ParentElement = (int)CCTMXProperty.Map; } else if (elementName == "tileset") { // If this is an external tileset then start parsing that if (attributeDict.ContainsKey("source")) { string externalTilesetFilename = attributeDict["source"]; externalTilesetFilename = CCFileUtils.FullPathFromRelativeFile(externalTilesetFilename, pTMXMapInfo.TMXFileName); currentFirstGID = uint.Parse(attributeDict["firstgid"]); pTMXMapInfo.ParseXmlFile(externalTilesetFilename); } else { var tileset = new CCTMXTilesetInfo(); tileset.Name = attributeDict["name"]; if (currentFirstGID == 0) { tileset.FirstGid = uint.Parse(attributeDict["firstgid"]); } else { tileset.FirstGid = currentFirstGID; currentFirstGID = 0; } if (attributeDict.ContainsKey("spacing")) { tileset.Spacing = int.Parse(attributeDict["spacing"]); } if (attributeDict.ContainsKey("margin")) { tileset.Margin = int.Parse(attributeDict["margin"]); } CCSize s; s.Width = CCUtils.CCParseFloat(attributeDict["tilewidth"]); s.Height = CCUtils.CCParseFloat(attributeDict["tileheight"]); tileset.TileSize = s; pTMXMapInfo.Tilesets.Add(tileset); } } else if (elementName == "tile") { List <CCTMXTilesetInfo> tilesets = pTMXMapInfo.Tilesets; int tilesetCount = tilesets != null ? tilesets.Count : 0; CCTMXTilesetInfo info = tilesetCount > 0 ? tilesets[tilesetCount - 1] : null; var dict = new Dictionary <string, string>(); pTMXMapInfo.ParentGID = (info.FirstGid + uint.Parse(attributeDict["id"])); pTMXMapInfo.TileProperties.Add(pTMXMapInfo.ParentGID, dict); pTMXMapInfo.ParentElement = (int)CCTMXProperty.Tile; } else if (elementName == "layer") { var layer = new CCTMXLayerInfo(); layer.Name = attributeDict["name"]; CCSize s; s.Width = CCUtils.CCParseFloat(attributeDict["width"]); s.Height = CCUtils.CCParseFloat(attributeDict["height"]); layer.LayerSize = s; layer.Tiles = new uint[(int)s.Width * (int)s.Height]; if (attributeDict.ContainsKey("visible")) { string visible = attributeDict["visible"]; layer.Visible = !(visible == "0"); } else { layer.Visible = true; } if (attributeDict.ContainsKey("opacity")) { string opacity = attributeDict["opacity"]; layer.Opacity = (byte)(255 * CCUtils.CCParseFloat(opacity)); } else { layer.Opacity = 255; } float x = attributeDict.ContainsKey("x") ? CCUtils.CCParseFloat(attributeDict["x"]) : 0; float y = attributeDict.ContainsKey("y") ? CCUtils.CCParseFloat(attributeDict["y"]) : 0; layer.Offset = new CCPoint(x, y); pTMXMapInfo.Layers.Add(layer); // The parent element is now "layer" pTMXMapInfo.ParentElement = (int)CCTMXProperty.Layer; } else if (elementName == "objectgroup") { var objectGroup = new CCTMXObjectGroup(); objectGroup.GroupName = attributeDict["name"]; CCPoint positionOffset = CCPoint.Zero; if (attributeDict.ContainsKey("x")) { positionOffset.X = CCUtils.CCParseFloat(attributeDict["x"]) * pTMXMapInfo.TileSize.Width; } if (attributeDict.ContainsKey("y")) { positionOffset.Y = CCUtils.CCParseFloat(attributeDict["y"]) * pTMXMapInfo.TileSize.Height; } objectGroup.PositionOffset = positionOffset; pTMXMapInfo.ObjectGroups.Add(objectGroup); // The parent element is now "objectgroup" pTMXMapInfo.ParentElement = (int)CCTMXProperty.ObjectGroup; } else if (elementName == "image") { List <CCTMXTilesetInfo> tilesets = pTMXMapInfo.Tilesets; int tilesetCount = tilesets != null ? tilesets.Count : 0; CCTMXTilesetInfo tileset = tilesetCount > 0 ? tilesets[tilesetCount - 1] : null; // build full path string imagename = attributeDict["source"]; tileset.SourceImage = CCFileUtils.FullPathFromRelativeFile(imagename, pTMXMapInfo.TMXFileName); } else if (elementName == "data") { string encoding = attributeDict.ContainsKey("encoding") ? attributeDict["encoding"] : ""; string compression = attributeDict.ContainsKey("compression") ? attributeDict["compression"] : ""; if (encoding == "base64") { int layerAttribs = pTMXMapInfo.LayerAttribs; pTMXMapInfo.LayerAttribs = layerAttribs | (int)CCTMXLayerAttrib.Base64; pTMXMapInfo.StoringCharacters = true; if (compression == "gzip") { layerAttribs = pTMXMapInfo.LayerAttribs; pTMXMapInfo.LayerAttribs = layerAttribs | (int)CCTMXLayerAttrib.Gzip; } else if (compression == "zlib") { layerAttribs = pTMXMapInfo.LayerAttribs; pTMXMapInfo.LayerAttribs = layerAttribs | (int)CCTMXLayerAttrib.Zlib; } Debug.Assert(compression == "" || compression == "gzip" || compression == "zlib", "TMX: unsupported compression method"); } Debug.Assert(pTMXMapInfo.LayerAttribs != (int)CCTMXLayerAttrib.None, "TMX tile map: Only base64 and/or gzip/zlib maps are supported"); } else if (elementName == "object") { List <CCTMXObjectGroup> objectGroups = pTMXMapInfo.ObjectGroups; int objectGroupCount = objectGroups != null ? objectGroups.Count : 0; CCTMXObjectGroup objectGroup = objectGroupCount > 0 ? objectGroups[objectGroupCount - 1] : null; // The value for "type" was blank or not a valid class name // Create an instance of TMXObjectInfo to store the object and its properties var dict = new Dictionary <string, string>(); var pArray = new[] { "name", "type", "width", "height", "gid" }; for (int i = 0; i < pArray.Length; i++) { string key = pArray[i]; if (attributeDict.ContainsKey(key)) { dict.Add(key, attributeDict[key]); } } // But X and Y since they need special treatment // X int x = int.Parse(attributeDict["x"]) + (int)objectGroup.PositionOffset.X; dict.Add("x", x.ToString()); int y = int.Parse(attributeDict["y"]) + (int)objectGroup.PositionOffset.Y; // Correct y position. (Tiled uses Flipped, cocos2d uses Standard) y = (int)(pTMXMapInfo.MapSize.Height * pTMXMapInfo.TileSize.Height) - y - (attributeDict.ContainsKey("height") ? int.Parse(attributeDict["height"]) : 0); dict.Add("y", y.ToString()); // Add the object to the objectGroup objectGroup.Objects.Add(dict); // The parent element is now "object" pTMXMapInfo.ParentElement = (int)CCTMXProperty.Object; } else if (elementName == "property") { if (pTMXMapInfo.ParentElement == (int)CCTMXProperty.None) { CCLog.Log("TMX tile map: Parent element is unsupported. Cannot add property named '{0}' with value '{1}'", attributeDict["name"], attributeDict["value"]); } else if (pTMXMapInfo.ParentElement == (int)CCTMXProperty.Map) { // The parent element is the map string value = attributeDict["value"]; string key = attributeDict["name"]; pTMXMapInfo.Properties.Add(key, value); } else if (pTMXMapInfo.ParentElement == (int)CCTMXProperty.Layer) { // The parent element is the last layer List <CCTMXLayerInfo> layers = pTMXMapInfo.Layers; int layersCount = layers != null ? layers.Count : 0; CCTMXLayerInfo layer = layersCount > 0 ? layers[layersCount - 1] : null; string value = attributeDict["value"]; string key = attributeDict["name"]; // Add the property to the layer layer.Properties.Add(key, value); } else if (pTMXMapInfo.ParentElement == (int)CCTMXProperty.ObjectGroup) { // The parent element is the last object group List <CCTMXObjectGroup> objectGroups = pTMXMapInfo.ObjectGroups; int objGroupsCount = objectGroups != null ? objectGroups.Count : 0; CCTMXObjectGroup objectGroup = objGroupsCount > 0 ? objectGroups[objGroupsCount - 1] : null; string value = attributeDict["value"]; string key = attributeDict["name"]; objectGroup.Properties.Add(key, value); } else if (pTMXMapInfo.ParentElement == (int)CCTMXProperty.Object) { // The parent element is the last object List <CCTMXObjectGroup> objectGroups = pTMXMapInfo.ObjectGroups; int objGroupsCount = objectGroups != null ? objectGroups.Count : 0; CCTMXObjectGroup objectGroup = objGroupsCount > 0 ? objectGroups[objGroupsCount - 1] : null; List <Dictionary <string, string> > objects = objectGroup.Objects; int objCount = objects != null ? objects.Count : 0; Dictionary <string, string> dict = objCount > 0 ? objects[objCount - 1] : null; string propertyName = attributeDict["name"]; string propertyValue = attributeDict["value"]; dict.Add(propertyName, propertyValue); } else if (pTMXMapInfo.ParentElement == (int)CCTMXProperty.Tile) { Dictionary <string, string> dict = pTMXMapInfo.TileProperties[pTMXMapInfo.ParentGID]; string propertyName = attributeDict["name"]; string propertyValue = attributeDict["value"]; dict.Add(propertyName, propertyValue); } } else if (elementName == "polygon") { // find parent object's dict and add polygon-points to it int objGroupsCount = ObjectGroups != null ? ObjectGroups.Count : 0; CCTMXObjectGroup objectGroup = objGroupsCount > 0 ? ObjectGroups[objGroupsCount - 1] : null; List <Dictionary <string, string> > objects = objectGroup.Objects; int objCount = objects != null ? objects.Count : 0; Dictionary <string, string> dict = objCount > 0 ? objects[objCount - 1] : null; // get points value string var value = attributeDict["points"]; if (!String.IsNullOrEmpty(value)) { var pPointsArray = new List <CCPoint>(); var pointPairs = value.Split(' '); foreach (var pontPair in pointPairs) { //TODO: Parse points //CCPoint point; //point.X = x + objectGroup.PositionOffset.X; //point.Y = y + objectGroup.PositionOffset.Y; //pPointsArray.Add(point); } //dict.Add("points", pPointsArray); } } else if (elementName == "polyline") { // find parent object's dict and add polyline-points to it // CCTMXObjectGroup* objectGroup = (CCTMXObjectGroup*)ObjectGroups->lastObject(); // CCDictionary* dict = (CCDictionary*)objectGroup->getObjects()->lastObject(); // TODO: dict->setObject:[attributeDict objectForKey:@"points"] forKey:@"polylinePoints"]; } }
internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { if (string.IsNullOrEmpty(text)) { return(new CCTexture2D()); } int imageWidth; int imageHeight; var textDef = textDefinition; var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width; var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height; textDef.FontSize *= contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; //bool hasPremultipliedAlpha; // font NSFont font = null; var ext = System.IO.Path.GetExtension(textDef.FontName); if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf") { try { textDef.FontName = LoadFontFile(textDef.FontName); font = NSFont.FromFontName(textDef.FontName, textDef.FontSize); } catch { CCLog.Log(".ttf {0} file not found or can not be loaded.", textDef.FontName); } } else { // font font = NSFontManager.SharedFontManager.FontWithFamily(textDef.FontName, NSFontTraitMask.Unbold | NSFontTraitMask.Unitalic, 0, textDef.FontSize); } if (font == null) { font = NSFontManager.SharedFontManager.FontWithFamily("Arial", NSFontTraitMask.Unbold | NSFontTraitMask.Unitalic, 0, textDef.FontSize); CCLog.Log("{0} not found. Defaulting to Arial.", textDef.FontName); } // color var foregroundColor = NSColor.White; // alignment var horizontalAlignment = textDef.Alignment; var verticleAlignement = textDef.LineAlignment; var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? NSTextAlignment.Right : (CCTextAlignment.Center == horizontalAlignment) ? NSTextAlignment.Center : NSTextAlignment.Left; // LineBreak var lineBreak = (CCLabelLineBreak.Character == textDef.LineBreak) ? NSLineBreakMode.CharWrapping : (CCLabelLineBreak.Word == textDef.LineBreak) ? NSLineBreakMode.ByWordWrapping : NSLineBreakMode.Clipping; var nsparagraphStyle = new NSMutableParagraphStyle(); nsparagraphStyle.SetParagraphStyle(NSMutableParagraphStyle.DefaultParagraphStyle); nsparagraphStyle.LineBreakMode = lineBreak; nsparagraphStyle.Alignment = textAlign; // Create a new attributed string definition var nsAttributes = new NSStringAttributes(); // Font attribute nsAttributes.Font = font; nsAttributes.ForegroundColor = foregroundColor; nsAttributes.ParagraphStyle = nsparagraphStyle; var stringWithAttributes = new NSAttributedString(text, nsAttributes); var realDimensions = stringWithAttributes.Size; // Mac crashes if the width or height is 0 if (realDimensions == SizeF.Empty) { CCLog.Log("Native string:", "Dimensions of native NSAttributedString can not be 0,0"); return(new CCTexture2D()); } var dimensions = new SizeF(textDef.Dimensions.Width, textDef.Dimensions.Height); var layoutAvailable = true; // // * Note * This seems to only effect Mac because iOS works fine without this work around. // Right Alignment BoundingRectWithSize does not seem to be working correctly when the following conditions are set: // 1) Alignment Right // 2) No dimensions // 3) There are new line characters embedded in the string. // // So we set alignment to Left, calculate our bounds and then restore alignement afterwards before drawing. // if (dimensions.Width <= 0) { dimensions.Width = 8388608; layoutAvailable = false; // Set our alignment variables to left - see notes above. nsparagraphStyle.Alignment = NSTextAlignment.Left; stringWithAttributes.Dispose(); stringWithAttributes = null; stringWithAttributes = new NSAttributedString(text, nsAttributes); } if (dimensions.Height <= 0) { dimensions.Height = 8388608; layoutAvailable = false; } // Calculate our bounding rectangle var boundingRect = stringWithAttributes.BoundingRectWithSize(new SizeF((int)dimensions.Width, (int)dimensions.Height), NSStringDrawingOptions.UsesLineFragmentOrigin); if (!layoutAvailable) { if (dimensions.Width == 8388608) { dimensions.Width = boundingRect.Width; // Restore our alignment before drawing - see notes above. nsparagraphStyle.Alignment = textAlign; stringWithAttributes.Dispose(); stringWithAttributes = null; stringWithAttributes = new NSAttributedString(text, nsAttributes); } if (dimensions.Height == 8388608) { dimensions.Height = boundingRect.Height; } } imageWidth = (int)dimensions.Width; imageHeight = (int)dimensions.Height; // Alignment var xOffset = 0.0f; switch (textAlign) { case NSTextAlignment.Left: xOffset = 0; break; case NSTextAlignment.Center: xOffset = (dimensions.Width - boundingRect.Width) / 2.0f; break; case NSTextAlignment.Right: xOffset = dimensions.Width - boundingRect.Width; break; default: break; } // Line alignment var yOffset = (CCVerticalTextAlignment.Top == verticleAlignement || boundingRect.Height >= dimensions.Height) ? (dimensions.Height - boundingRect.Height) // align to top : (CCVerticalTextAlignment.Bottom == verticleAlignement) ? 0 // align to bottom : (imageHeight - boundingRect.Height) / 2.0f; // align to center //Find the rect that the string will draw into inside the dimensions var drawRect = new RectangleF(xOffset , yOffset , boundingRect.Width , boundingRect.Height); NSImage image = null; try { //Set antialias or not NSGraphicsContext.CurrentContext.ShouldAntialias = textDef.isShouldAntialias; image = new NSImage(new SizeF(imageWidth, imageHeight)); image.LockFocus(); // set a default transform var transform = new NSAffineTransform(); transform.Set(); stringWithAttributes.DrawInRect(drawRect); image.UnlockFocus(); // We will use Texture2D from stream here instead of CCTexture2D stream. var tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, image); // Debugging purposes // var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // var fileName = Path.Combine(path, "Label3.png"); // using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write)) // { // tex.SaveAsPng(stream, imageWidth, imageHeight); // } // Create our texture of the label string. var texture = new CCTexture2D(tex); return(texture); } catch (Exception exc) { CCLog.Log("CCLabel: Error creating native label:{0}\n{1}", exc.Message, exc.StackTrace); } finally { // clean up the resources if (image != null) { image.Dispose(); image = null; } if (stringWithAttributes != null) { stringWithAttributes.Dispose(); stringWithAttributes = null; } } return(new CCTexture2D()); }
internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { if (string.IsNullOrEmpty(text)) { return(new CCTexture2D()); } int imageWidth; int imageHeight; var textDef = textDefinition; var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width; var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height; textDef.FontSize *= contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; // font UIFont font = null; var ext = System.IO.Path.GetExtension(textDef.FontName); if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf") { try { textDef.FontName = LoadFontFile(textDef.FontName); font = UIFont.FromName(textDef.FontName, textDef.FontSize); } catch (Exception exc) { CCLog.Log(".ttf {0} file not found or can not be loaded.", textDef.FontName); } } else { // font font = UIFont.FromName(textDef.FontName, textDef.FontSize); //NSFontManager.SharedFontManager.FontWithFamily(textDef.FontName, NSFontTraitMask.Unbold | NSFontTraitMask.Unitalic, 0, textDef.FontSize); } if (font == null) { font = UIFont.FromName("Arial", textDef.FontSize); CCLog.Log("{0} not found. Defaulting to Arial.", textDef.FontName); } // color var foregroundColor = UIColor.White; // alignment var horizontalAlignment = textDef.Alignment; var verticleAlignement = textDef.LineAlignment; var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? UITextAlignment.Right : (CCTextAlignment.Center == horizontalAlignment) ? UITextAlignment.Center : UITextAlignment.Left; // LineBreak var lineBreak = (CCLabelLineBreak.Character == textDef.LineBreak) ? UILineBreakMode.CharacterWrap : (CCLabelLineBreak.Word == textDef.LineBreak) ? UILineBreakMode.WordWrap : UILineBreakMode.Clip; var nsparagraphStyle = (NSMutableParagraphStyle)NSParagraphStyle.Default.MutableCopy(); nsparagraphStyle.LineBreakMode = lineBreak; nsparagraphStyle.Alignment = textAlign; // Create a new attributed string definition var nsAttributes = new UIStringAttributes(); // Font attribute nsAttributes.Font = font; nsAttributes.ForegroundColor = foregroundColor; nsAttributes.ParagraphStyle = nsparagraphStyle; var stringWithAttributes = new NSAttributedString(text, nsAttributes); var realDimensions = stringWithAttributes.Size; // Mac crashes if the width or height is 0 if (realDimensions == SizeF.Empty) { throw new ArgumentOutOfRangeException("Native string:", "Dimensions of native NSAttributedString can not be 0,0"); } var dimensions = new CGSize(textDef.Dimensions.Width, textDef.Dimensions.Height); var layoutAvailable = true; if (dimensions.Width <= 0) { dimensions.Width = 8388608; layoutAvailable = false; } if (dimensions.Height <= 0) { dimensions.Height = 8388608; layoutAvailable = false; } var boundingRect = stringWithAttributes.GetBoundingRect(new CGSize((int)dimensions.Width, (int)dimensions.Height), NSStringDrawingOptions.UsesLineFragmentOrigin, null); if (!layoutAvailable) { if (dimensions.Width == 8388608) { dimensions.Width = boundingRect.Width; } if (dimensions.Height == 8388608) { dimensions.Height = boundingRect.Height; } } imageWidth = (int)dimensions.Width; imageHeight = (int)dimensions.Height; // Alignment var xOffset = (nfloat)0.0f; switch (textAlign) { case UITextAlignment.Left: xOffset = 0; break; case UITextAlignment.Center: xOffset = (dimensions.Width - boundingRect.Width) / 2.0f; break; case UITextAlignment.Right: xOffset = dimensions.Width - boundingRect.Width; break; default: break; } // Line alignment var yOffset = (CCVerticalTextAlignment.Bottom == verticleAlignement || boundingRect.Height >= dimensions.Height) ? (dimensions.Height - boundingRect.Height) // align to bottom : (CCVerticalTextAlignment.Top == verticleAlignement) ? 0 // align to top : (imageHeight - boundingRect.Height) / 2.0f; // align to center //Find the rect that the string will draw into inside the dimensions var drawRect = new CGRect(xOffset , yOffset , boundingRect.Width , boundingRect.Height); UIImage image = null; CGContext context = null; try { UIGraphics.BeginImageContext(new CGSize(imageWidth, imageHeight)); context = UIGraphics.GetCurrentContext(); //Set antialias or not context.SetShouldAntialias(textDef.isShouldAntialias); stringWithAttributes.DrawString(drawRect); image = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); // We will use Texture2D from stream here instead of CCTexture2D stream. var tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, image); // Debugging purposes // var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // var fileName = Path.Combine(path, "Label3.png"); // using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write)) // { // tex.SaveAsPng(stream, imageWidth, imageHeight); // } // Create our texture of the label string. var texture = new CCTexture2D(tex); return(texture); } catch (Exception exc) { CCLog.Log("CCLabel: Error creating native label:{0}\n{1}", exc.Message, exc.StackTrace); } finally { // clean up the resources if (image != null) { image.Dispose(); image = null; } if (context != null) { context.Dispose(); context = null; } font.Dispose(); font = null; nsparagraphStyle.Dispose(); nsparagraphStyle = null; if (stringWithAttributes != null) { stringWithAttributes.Dispose(); stringWithAttributes = null; } } return(new CCTexture2D()); }
// Write out the current state of the director and all of its scenes. public void SerializeState() { // open up isolated storage using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication()) { // if our screen manager directory already exists, delete the contents if (storage.DirectoryExists(storageDirName)) { DeleteState(storage); } // otherwise just create the directory else { storage.CreateDirectory(storageDirName); } // create a file we'll use to store the list of screens in the stack CCLog.Log("Saving CCDirector state to file: " + Path.Combine(storageDirName, saveFileName)); try { using (IsolatedStorageFileStream stream = storage.OpenFile(Path.Combine(storageDirName, saveFileName), FileMode.OpenOrCreate)) { using (StreamWriter writer = new StreamWriter(stream)) { // write out the full name of all the types in our stack so we can // recreate them if needed. foreach (CCScene scene in scenesStack) { if (scene.IsSerializable) { writer.WriteLine(scene.GetType().AssemblyQualifiedName); } else { CCLog.Log("Scene is not serializable: " + scene.GetType().FullName); } } // Write out our local state if (RunningScene != null && RunningScene.IsSerializable) { writer.WriteLine("m_pRunningScene"); writer.WriteLine(RunningScene.GetType().AssemblyQualifiedName); } // Add my own state // [*]name=value // } } // now we create a new file stream for each screen so it can save its state // if it needs to. we name each file "ScreenX.dat" where X is the index of // the screen in the stack, to ensure the files are uniquely named int screenIndex = 0; string fileName = null; foreach (CCScene scene in scenesStack) { if (scene.IsSerializable) { fileName = string.Format(Path.Combine(storageDirName, sceneSaveFileName), screenIndex); // open up the stream and let the screen serialize whatever state it wants using (IsolatedStorageFileStream stream = storage.CreateFile(fileName)) { scene.Serialize(stream); } screenIndex++; } } // Write the current running scene if (RunningScene != null && RunningScene.IsSerializable) { fileName = string.Format(Path.Combine(storageDirName, sceneSaveFileName), "XX"); // open up the stream and let the screen serialize whatever state it wants using (IsolatedStorageFileStream stream = storage.CreateFile(fileName)) { RunningScene.Serialize(stream); } } } catch (Exception ex) { CCLog.Log("Failed to serialize the CCDirector state. Erasing the save files."); CCLog.Log(ex.ToString()); DeleteState(storage); } } }
static float dpiScale = 96f / 72f; // default but will be recalculated below #if WINDOWSGL internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { if (string.IsNullOrEmpty(text)) { return(new CCTexture2D()); } int imageWidth; int imageHeight; var textDef = textDefinition; var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width; var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height; textDef.FontSize *= (int)contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; bool hasPremultipliedAlpha; var font = CreateFont(textDef.FontName, textDef.FontSize / dpiScale); var fontColor = textDef.FontFillColor; var fontAlpha = textDef.FontAlpha; var foregroundColor = System.Drawing.Color.FromArgb(fontAlpha, fontColor.R, fontColor.G, fontColor.B); // alignment var horizontalAlignment = textDef.Alignment; var verticleAlignement = textDef.LineAlignment; var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? StringAlignment.Far : (CCTextAlignment.Center == horizontalAlignment) ? StringAlignment.Center : StringAlignment.Near; var paragraphAlign = (CCVerticalTextAlignment.Bottom == verticleAlignement) ? StringAlignment.Far : (CCVerticalTextAlignment.Center == verticleAlignement) ? StringAlignment.Center : StringAlignment.Near; // LineBreak var lineBreak = (CCLabelLineBreak.Character == textDef.LineBreak) ? StringTrimming.Character : (CCLabelLineBreak.Word == textDef.LineBreak) ? StringTrimming.Word : StringTrimming.None; var dimensions = new SizeF(textDef.Dimensions.Width, textDef.Dimensions.Height); var layoutAvailable = true; if (dimensions.Width <= 0) { dimensions.Width = 8388608; layoutAvailable = false; } if (dimensions.Height <= 0) { dimensions.Height = 8388608; layoutAvailable = false; } var stringFormat = StringFormat.GenericDefault; // We will set the Alignment to Near to begin with because of a calculation error of MeasureString // with a line of text with embedded newline '\n' characters after a number and Alignment = Center. // Example: "Alignment 1\nnew line" stringFormat.Alignment = StringAlignment.Near; stringFormat.LineAlignment = paragraphAlign; stringFormat.Trimming = lineBreak; int charactersFitted = 0; int lineCount = 0; var boundingRect = RectangleF.Empty; var textMetrics = _graphics.MeasureString(text, font, dimensions, stringFormat, out charactersFitted, out lineCount); // early out if something went wrong somewhere and nothing is to be drawn if (lineCount == 0) { return(new CCTexture2D()); } // We will set the real Alignement here before drawing the text - See comment above about calculation error // with Alignment. stringFormat.Alignment = textAlign; // Fill out the bounding rect width and height so we can calculate the yOffset later if needed boundingRect.X = 0; boundingRect.Y = 0; boundingRect.Width = textMetrics.Width; boundingRect.Height = textMetrics.Height; if (!layoutAvailable) { if (dimensions.Width == 8388608) { dimensions.Width = boundingRect.Width; } if (dimensions.Height == 8388608) { dimensions.Height = boundingRect.Height; } } imageWidth = (int)dimensions.Width; imageHeight = (int)dimensions.Height; CreateBitmap(imageWidth, imageHeight); if (textDefinition.isShouldAntialias) { _graphics.TextRenderingHint = TextRenderingHint.AntiAlias; } var _brush = new SolidBrush(foregroundColor); _graphics.Clear(System.Drawing.Color.Transparent); _graphics.DrawString(text, font, _brush, new RectangleF(PointF.Empty, dimensions), stringFormat); _graphics.Flush(); try { _bitmap = (Bitmap)_bitmap.RGBToBGR(); var data = new byte[_bitmap.Width * _bitmap.Height * 4]; BitmapData bitmapData = _bitmap.LockBits(new System.Drawing.Rectangle(0, 0, _bitmap.Width, _bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); if (bitmapData.Stride != _bitmap.Width * 4) { throw new NotImplementedException(); } Marshal.Copy(bitmapData.Scan0, data, 0, data.Length); _bitmap.UnlockBits(bitmapData); Texture2D texture = null; texture = new Texture2D(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, _bitmap.Width, _bitmap.Height); texture.SetData(data); return(new CCTexture2D(texture)); } catch (Exception ie) { CCLog.Log("CCLabel: internal error creating texture sprite: {0}\n{1}", ie.Message, ie.StackTrace); } finally { if (_bitmap != null) { _bitmap.Dispose(); _bitmap = null; } if (_graphics != null) { _graphics.Dispose(); _graphics = null; } if (_brush != null) { _brush.Dispose(); } } return(new CCTexture2D()); }
internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { if (string.IsNullOrEmpty(text)) { return(new CCTexture2D()); } int imageWidth; int imageHeight; var textDef = textDefinition; var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width; var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height; textDef.FontSize *= contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; bool hasPremultipliedAlpha; var font = CreateFont(textDef.FontName, textDef.FontSize); var _currentFontSizeEm = textDef.FontSize; var _currentDIP = ConvertPointSizeToDIP(_currentFontSizeEm); // color var foregroundColor = Color4.White; // alignment var horizontalAlignment = textDef.Alignment; var verticleAlignement = textDef.LineAlignment; var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? TextAlignment.Trailing : (CCTextAlignment.Center == horizontalAlignment) ? TextAlignment.Center : TextAlignment.Leading; var paragraphAlign = (CCVerticalTextAlignment.Bottom == vertAlignment) ? ParagraphAlignment.Far : (CCVerticalTextAlignment.Center == vertAlignment) ? ParagraphAlignment.Center : ParagraphAlignment.Near; // LineBreak var lineBreak = (CCLabelLineBreak.Character == textDef.LineBreak) ? WordWrapping.Wrap : (CCLabelLineBreak.Word == textDef.LineBreak) ? WordWrapping.Wrap : WordWrapping.NoWrap; // LineBreak // TODO: Find a way to specify the type of line breaking if possible. var dimensions = new CCSize(textDef.Dimensions.Width, textDef.Dimensions.Height); var layoutAvailable = true; if (dimensions.Width <= 0) { dimensions.Width = 8388608; layoutAvailable = false; } if (dimensions.Height <= 0) { dimensions.Height = 8388608; layoutAvailable = false; } var fontName = font.FontFamily.FamilyNames.GetString(0); var textFormat = new TextFormat(FactoryDWrite, fontName, _currentFontCollection, FontWeight.Regular, FontStyle.Normal, FontStretch.Normal, _currentDIP); textFormat.TextAlignment = textAlign; textFormat.ParagraphAlignment = paragraphAlign; var textLayout = new TextLayout(FactoryDWrite, text, textFormat, dimensions.Width, dimensions.Height); var boundingRect = new RectangleF(); // Loop through all the lines so we can find our drawing offsets var textMetrics = textLayout.Metrics; var lineCount = textMetrics.LineCount; // early out if something went wrong somewhere and nothing is to be drawn if (lineCount == 0) { return(new CCTexture2D()); } // Fill out the bounding rect width and height so we can calculate the yOffset later if needed boundingRect.X = 0; boundingRect.Y = 0; boundingRect.Width = textMetrics.Width; boundingRect.Height = textMetrics.Height; if (!layoutAvailable) { if (dimensions.Width == 8388608) { dimensions.Width = boundingRect.Width; } if (dimensions.Height == 8388608) { dimensions.Height = boundingRect.Height; } } imageWidth = (int)dimensions.Width; imageHeight = (int)dimensions.Height; // Recreate our layout based on calculated dimensions so that we can draw the text correctly // in our image when Alignment is not Left. if (textAlign != TextAlignment.Leading) { textLayout.MaxWidth = dimensions.Width; textLayout.MaxHeight = dimensions.Height; } // Line alignment var yOffset = (CCVerticalTextAlignment.Bottom == verticleAlignement || boundingRect.Bottom >= dimensions.Height) ? dimensions.Height - boundingRect.Bottom // align to bottom : (CCVerticalTextAlignment.Top == verticleAlignement) ? 0 // align to top : (imageHeight - boundingRect.Bottom) * 0.5f; // align to center SharpDX.WIC.Bitmap sharpBitmap = null; WicRenderTarget sharpRenderTarget = null; SolidColorBrush solidBrush = null; try { // Select our pixel format var pixelFormat = SharpDX.WIC.PixelFormat.Format32bppPRGBA; // create our backing bitmap sharpBitmap = new SharpDX.WIC.Bitmap(FactoryImaging, imageWidth, imageHeight, pixelFormat, BitmapCreateCacheOption.CacheOnLoad); // Create the render target that we will draw to sharpRenderTarget = new WicRenderTarget(Factory2D, sharpBitmap, new RenderTargetProperties()); // Create our brush to actually draw with solidBrush = new SolidColorBrush(sharpRenderTarget, foregroundColor); // Begin the drawing sharpRenderTarget.BeginDraw(); if (textDefinition.isShouldAntialias) { sharpRenderTarget.AntialiasMode = AntialiasMode.Aliased; } // Clear it sharpRenderTarget.Clear(TransparentColor); // Draw the text to the bitmap sharpRenderTarget.DrawTextLayout(new Vector2(boundingRect.X, yOffset), textLayout, solidBrush); // End our drawing which will commit the rendertarget to the bitmap sharpRenderTarget.EndDraw(); // Debugging purposes //var s = "Label4"; //SaveToFile(@"C:\Xamarin\" + s + ".png", _bitmap, _renderTarget); // The following code creates a .png stream in memory of our Bitmap and uses it to create our Textue2D Texture2D tex = null; using (var memStream = new MemoryStream()) { using (var encoder = new PngBitmapEncoder(FactoryImaging, memStream)) using (var frameEncoder = new BitmapFrameEncode(encoder)) { frameEncoder.Initialize(); frameEncoder.WriteSource(sharpBitmap); frameEncoder.Commit(); encoder.Commit(); } // Create the Texture2D from the png stream tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, memStream); } // Return our new CCTexture2D created from the Texture2D which will have our text drawn on it. return(new CCTexture2D(tex)); } catch (Exception exc) { CCLog.Log("CCLabel-Windows: Unable to create the backing image of our text. Message: {0}", exc.StackTrace); } finally { if (sharpBitmap != null) { sharpBitmap.Dispose(); sharpBitmap = null; } if (sharpRenderTarget != null) { sharpRenderTarget.Dispose(); sharpRenderTarget = null; } if (solidBrush != null) { solidBrush.Dispose(); solidBrush = null; } if (textFormat != null) { textFormat.Dispose(); textFormat = null; } if (textLayout != null) { textLayout.Dispose(); textLayout = null; } } // If we have reached here then something has gone wrong. return(new CCTexture2D()); }
protected void InitCCLabelBMFont(string theString, string fntFile, CCSize dimensions, CCTextAlignment hAlignment, CCVerticalTextAlignment vAlignment, CCPoint imageOffset, CCTexture2D texture) { Debug.Assert(FontConfiguration == null, "re-init is no longer supported"); Debug.Assert((theString == null && fntFile == null) || (theString != null && fntFile != null), "Invalid params for CCLabelBMFont"); if (!String.IsNullOrEmpty(fntFile)) { CCBMFontConfiguration newConf = FNTConfigLoadFile(fntFile); if (newConf == null) { CCLog.Log("CCLabelBMFont: Impossible to create font. Please check file: '{0}'", fntFile); return; } FontConfiguration = newConf; fntConfigFile = fntFile; if (texture == null) { try { texture = CCTextureCache.SharedTextureCache.AddImage(FontConfiguration.AtlasName); } catch (Exception) { // Try the 'images' ref location just in case. try { texture = CCTextureCache.SharedTextureCache.AddImage(System.IO.Path.Combine("images", FontConfiguration .AtlasName)); } catch (Exception) { // Lastly, try <font_path>/images/<font_name> string dir = System.IO.Path.GetDirectoryName(FontConfiguration.AtlasName); string fname = System.IO.Path.GetFileName(FontConfiguration.AtlasName); string newName = System.IO.Path.Combine(System.IO.Path.Combine(dir, "images"), fname); texture = CCTextureCache.SharedTextureCache.AddImage(newName); } } } } else { texture = new CCTexture2D(); } if (String.IsNullOrEmpty(theString)) { theString = String.Empty; } base.InitCCSpriteBatchNode(texture, theString.Length); this.labelDimensions = dimensions; horzAlignment = hAlignment; vertAlignment = vAlignment; IsOpacityCascaded = true; ContentSize = CCSize.Zero; IsColorModifiedByOpacity = TextureAtlas.Texture.HasPremultipliedAlpha; AnchorPoint = CCPoint.AnchorMiddle; ImageOffset = imageOffset; SetString(theString, true); }
void InitWithString(string text, CCSize dimensions, CCTextAlignment hAlignment, CCVerticalTextAlignment vAlignment, string fontName, float fontSize) { try { Debug.Assert(dimensions.Width >= 0 || dimensions.Height >= 0); if (string.IsNullOrEmpty(text)) { return; } float loadedSize = fontSize; SpriteFont font = CCSpriteFontCache.SharedInstance.TryLoadFont(fontName, fontSize, out loadedSize); if (font == null) { CCLog.Log("Failed to load default font. No font supported."); return; } float scale = 1f; if (loadedSize != 0) { scale = fontSize / loadedSize * CCSpriteFontCache.FontScale; } if (dimensions.Equals(CCSize.Zero)) { CCVector2 temp = font.MeasureString(text).ToCCVector2(); dimensions.Width = temp.X * scale; dimensions.Height = temp.Y * scale; } var textList = new List <String>(); var nextText = new StringBuilder(); string[] lineList = text.Split('\n'); float spaceWidth = font.MeasureString(" ").X *scale; for (int j = 0; j < lineList.Length; ++j) { string[] wordList = lineList[j].Split(' '); float lineWidth = 0; bool firstWord = true; for (int i = 0; i < wordList.Length; ++i) { float wordWidth = font.MeasureString(wordList[i]).X *scale; if ((lineWidth + wordWidth) > dimensions.Width) { lineWidth = wordWidth; if (nextText.Length > 0) { firstWord = true; textList.Add(nextText.ToString()); nextText.Length = 0; } else { lineWidth += wordWidth; firstWord = false; textList.Add(wordList[i]); continue; } } else { lineWidth += wordWidth; } if (!firstWord) { nextText.Append(' '); lineWidth += spaceWidth; } nextText.Append(wordList[i]); firstWord = false; } textList.Add(nextText.ToString()); nextText.Clear(); } if (dimensions.Height == 0) { dimensions.Height = textList.Count * font.LineSpacing * scale; } //* for render to texture RenderTarget2D renderTarget = CCDrawManager.SharedDrawManager.CreateRenderTarget( (int)dimensions.Width, (int)dimensions.Height, DefaultAlphaPixelFormat, CCRenderTargetUsage.DiscardContents ); CCDrawManager.SharedDrawManager.CurrentRenderTarget = renderTarget; CCDrawManager.SharedDrawManager.Clear(CCColor4B.Transparent); SpriteBatch sb = CCDrawManager.SharedDrawManager.SpriteBatch; sb.Begin(); float textHeight = textList.Count * font.LineSpacing * scale; float nextY = 0; if (vAlignment == CCVerticalTextAlignment.Bottom) { nextY = dimensions.Height - textHeight; } else if (vAlignment == CCVerticalTextAlignment.Center) { nextY = (dimensions.Height - textHeight) / 2.0f; } for (int j = 0; j < textList.Count; ++j) { string line = textList[j]; var position = new CCVector2(0, nextY); if (hAlignment == CCTextAlignment.Right) { position.X = dimensions.Width - font.MeasureString(line).X *scale; } else if (hAlignment == CCTextAlignment.Center) { position.X = (dimensions.Width - font.MeasureString(line).X *scale) / 2.0f; } sb.DrawString(font, line, position.ToVector2(), Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0); nextY += font.LineSpacing * scale; } sb.End(); CCDrawManager.SharedDrawManager.XnaGraphicsDevice.RasterizerState = RasterizerState.CullNone; CCDrawManager.SharedDrawManager.DepthStencilState = DepthStencilState.Default; CCDrawManager.SharedDrawManager.CurrentRenderTarget = (RenderTarget2D)null; InitWithTexture(renderTarget, (CCSurfaceFormat)renderTarget.Format, true, false); cacheInfo.CacheType = CCTextureCacheType.String; cacheInfo.Data = new CCStringCache() { Dimensions = dimensions, Text = text, FontName = fontName, FontSize = fontSize, HAlignment = hAlignment, VAlignment = vAlignment }; } catch (Exception ex) { CCLog.Log(ex.ToString()); } }
//private string CreateFont(string fontName, float fontSize, CCRawList<char> charset) private Font CreateFont(string fontName, float fontSize) { Font _currentFont; if (Factory2D == null) { Factory2D = new SharpDX.Direct2D1.Factory(); FactoryDWrite = new SharpDX.DirectWrite.Factory(); FactoryImaging = new SharpDX.WIC.ImagingFactory(); dpi = Factory2D.DesktopDpi; dpiScale = dpi.Height / 72f; } _currentFontCollection = FactoryDWrite.GetSystemFontCollection(true); if (_defaultFont == null) { _defaultFont = GenericSanSerif(); } FontFamily fontFamily = GetFontFamily(fontName); FontCollection fontCollection; if (!_fontCollectionCache.TryGetValue(fontName, out fontCollection)) { var ext = Path.GetExtension(fontName); if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf") { try { var fileFontLoader = new FileFontLoader(FactoryDWrite, fontName); var fileFontCollection = new FontCollection(FactoryDWrite, fileFontLoader, fileFontLoader.Key); _currentFontCollection = fileFontCollection; fontFamily = _currentFontCollection.GetFontFamily(0); var ffn = fontFamily.FamilyNames; _currentFont = fontFamily.GetFirstMatchingFont(FontWeight.Regular, FontStretch.Normal, FontStyle.Normal); _fontCollectionCache.Add(fontName, fileFontCollection); _currentFontCollection = fileFontCollection; } catch { _currentFont = GetFont(fontName, fontSize); CCLog.Log("{0} not found. Defaulting to {1}.", fontName, _currentFont.FontFamily.FamilyNames.GetString(0)); } } else { _currentFont = GetFont(fontName, fontSize); } } else { fontFamily = fontCollection.GetFontFamily(0); _currentFont = fontFamily.GetFirstMatchingFont(FontWeight.Regular, FontStretch.Normal, FontStyle.Normal); _currentFontCollection = fontCollection; } return(_currentFont); }
internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { if (string.IsNullOrEmpty(text)) { return(new CCTexture2D()); } int imageWidth; int imageHeight; var textDef = textDefinition; var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width; var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height; textDef.FontSize *= (int)contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; bool hasPremultipliedAlpha; var display = Game.Activity.WindowManager.DefaultDisplay; var metrics = new DisplayMetrics(); display.GetMetrics(metrics); // Do not take into account ScaleDensity for now. // var fontScaleFactor = metrics.ScaledDensity; // textDef.FontSize = (int)(textDef.FontSize * fontScaleFactor); // out paint object to hold our drawn text // var paintFlags = new PaintFlags(); // if (textDefinition.isShouldAntialias) // paintFlags = PaintFlags.AntiAlias | PaintFlags.SubpixelText; var textPaint = new TextPaint(); textPaint.Color = Android.Graphics.Color.White; textPaint.TextAlign = Paint.Align.Left; textPaint.AntiAlias = textDefinition.isShouldAntialias; textPaint.TextSize = textDef.FontSize; var fontName = textDef.FontName; var ext = System.IO.Path.GetExtension(fontName); if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf") { CCContentManager.SharedContentManager.GetAssetStreamAsBytes(fontName, out fontName); var activity = Game.Activity; try { var typeface = Typeface.CreateFromAsset(activity.Assets, fontName); textPaint.SetTypeface(typeface); } catch (Exception) { textPaint.SetTypeface(Typeface.Create(fontName, TypefaceStyle.Normal)); } } else { textPaint.SetTypeface(Typeface.Create(fontName, TypefaceStyle.Normal)); } // color var fontColor = textDef.FontFillColor; var fontAlpha = textDef.FontAlpha; var foregroundColor = new Android.Graphics.Color(fontColor.R, fontColor.G, fontColor.B, fontAlpha); textPaint.Color = foregroundColor; // alignment var horizontalAlignment = textDef.Alignment; var verticleAlignement = textDef.LineAlignment; var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? Layout.Alignment.AlignOpposite : (CCTextAlignment.Center == horizontalAlignment) ? Layout.Alignment.AlignCenter : Layout.Alignment.AlignNormal; // LineBreak // TODO: Find a way to specify the type of line breaking if possible. var dimensions = new CCSize(textDef.Dimensions.Width, textDef.Dimensions.Height); var layoutAvailable = true; if (dimensions.Width <= 0) { dimensions.Width = 8388608; layoutAvailable = false; } if (dimensions.Height <= 0) { dimensions.Height = 8388608; layoutAvailable = false; } // Get bounding rectangle - we need its attribute and method values var layout = new StaticLayout(text, textPaint, (int)dimensions.Width, textAlign, 1.0f, 0.0f, false); var boundingRect = new Rect(); var lineBounds = new Rect(); // Loop through all the lines so we can find our drawing offsets var lineCount = layout.LineCount; // early out if something went wrong somewhere and nothing is to be drawn if (lineCount == 0) { return(new CCTexture2D()); } for (int lc = 0; lc < lineCount; lc++) { layout.GetLineBounds(lc, lineBounds); var max = layout.GetLineMax(lc); if (boundingRect.Right < max) { boundingRect.Right = (int)max; } boundingRect.Bottom = lineBounds.Bottom; } if (!layoutAvailable) { if (dimensions.Width == 8388608) { dimensions.Width = boundingRect.Right; } if (dimensions.Height == 8388608) { dimensions.Height = boundingRect.Bottom; } } imageWidth = (int)dimensions.Width; imageHeight = (int)dimensions.Height; // Recreate our layout based on calculated dimensions so that we can draw the text correctly // in our image when Alignment is not Left. if (textAlign != Layout.Alignment.AlignNormal) { layout = new StaticLayout(text, textPaint, (int)dimensions.Width, textAlign, 1.0f, 0.0f, false); } // Line alignment var yOffset = (CCVerticalTextAlignment.Bottom == verticleAlignement || boundingRect.Bottom >= dimensions.Height) ? dimensions.Height - boundingRect.Bottom // align to bottom : (CCVerticalTextAlignment.Top == verticleAlignement) ? 0 // align to top : (imageHeight - boundingRect.Bottom) * 0.5f; // align to center try { // Create our platform dependant image to be drawn to. using (Bitmap textureBitmap = Bitmap.CreateBitmap(imageWidth, imageHeight, Bitmap.Config.Argb8888)) { using (Canvas drawingCanvas = new Canvas(textureBitmap)) { drawingCanvas.DrawARGB(0, 255, 255, 255); // Set our vertical alignment drawingCanvas.Translate(0, yOffset); // Now draw the text using our layout layout.Draw(drawingCanvas); // We will use Texture2D from stream here instead of CCTexture2D stream. var tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, textureBitmap); // Create our texture of the label string. // Note the use of the third parameter as premultiplied = false // be careful changing that parameter as it will cause problems with blending // later on. var texture = new CCTexture2D(tex, CCSurfaceFormat.Color, false); return(texture); } } } catch (Exception exc) { CCLog.Log("CCLabel Android: Error creating native label:{0}\n{1}", exc.Message, exc.StackTrace); return(new CCTexture2D()); } }
static internal CTFont CreateFont(string familyName, float emSize, FontStyle style, byte gdiCharSet, bool gdiVerticalFont) { if (emSize <= 0) { throw new ArgumentException("emSize is less than or equal to 0, evaluates to infinity, or is not a valid number.", "emSize"); } CTFont nativeFont; // convert to 96 Dpi to be consistent with Windows var dpiSize = emSize; // * dpiScale; var ext = System.IO.Path.GetExtension(familyName); if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf") { var fontName = familyName.Substring(0, familyName.Length - ext.Length); var path = CCContentManager.SharedContentManager.RootDirectory + Path.DirectorySeparatorChar + fontName; var pathForResource = NSBundle.MainBundle.PathForResource(path, ext.Substring(1)); try { var dataProvider = new CGDataProvider(pathForResource); var cgFont = CGFont.CreateFromProvider(dataProvider); try { nativeFont = new CTFont(cgFont, dpiSize, null); } catch { nativeFont = new CTFont("Helvetica", dpiSize); } } catch (Exception) { try { nativeFont = new CTFont(Path.GetFileNameWithoutExtension(familyName), dpiSize); } catch { nativeFont = new CTFont("Helvetica", dpiSize); } CCLog.Log(string.Format("Could not load font: {0} so will use default {1}.", familyName, nativeFont.DisplayName)); } } else { try { nativeFont = new CTFont(familyName, dpiSize); } catch { nativeFont = new CTFont("Helvetica", dpiSize); } } CTFontSymbolicTraits tMask = CTFontSymbolicTraits.None; if ((style & FontStyle.Bold) == FontStyle.Bold) { tMask |= CTFontSymbolicTraits.Bold; } if ((style & FontStyle.Italic) == FontStyle.Italic) { tMask |= CTFontSymbolicTraits.Italic; } strikeThrough = (style & FontStyle.Strikeout) == FontStyle.Strikeout; underLine = (style & FontStyle.Underline) == FontStyle.Underline; var nativeFont2 = nativeFont.WithSymbolicTraits(dpiSize, tMask, tMask); if (nativeFont2 != null) { nativeFont = nativeFont2; } return(nativeFont); }
public bool DeserializeState() { try { // open up isolated storage using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication()) { // see if our saved state directory exists if (storage.DirectoryExists(storageDirName)) { string saveFile = System.IO.Path.Combine(storageDirName, saveFileName); try { CCLog.Log("Loading director data file: {0}", saveFile); // see if we have a screen list if (storage.FileExists(saveFile)) { // load the list of screen types using (IsolatedStorageFileStream stream = storage.OpenFile(saveFile, FileMode.Open, FileAccess.Read)) { using (StreamReader reader = new StreamReader(stream)) { CCLog.Log("Director save file contains {0} bytes.", reader.BaseStream.Length); try { while (true) { // read a line from our file string line = reader.ReadLine(); if (line == null) { break; } CCLog.Log("Restoring: {0}", line); // if it isn't blank, we can create a screen from it if (!string.IsNullOrEmpty(line)) { if (line.StartsWith("[*]")) { // Reading my state string s = line.Substring(3); int idx = s.IndexOf('='); if (idx > -1) { string name = s.Substring(0, idx); string v = s.Substring(idx + 1); CCLog.Log("Restoring: {0} = {1}", name, v); DeserializeMyState(name, v); } } else { Type screenType = Type.GetType(line); CCScene scene = Activator.CreateInstance(screenType) as CCScene; PushScene(scene); // m_pobScenesStack.Add(scene); } } } } catch (Exception) { // EndOfStreamException // this is OK here. } } } // Now we deserialize our own state. } else { CCLog.Log("save file does not exist."); } // next we give each screen a chance to deserialize from the disk for (int i = 0; i < scenesStack.Count; i++) { string filename = System.IO.Path.Combine(storageDirName, string.Format(sceneSaveFileName, i)); if (storage.FileExists(filename)) { using (IsolatedStorageFileStream stream = storage.OpenFile(filename, FileMode.Open, FileAccess.Read)) { CCLog.Log("Restoring state for scene {0}", filename); scenesStack[i].Deserialize(stream); } } } if (scenesStack.Count > 0) { CCLog.Log("Director is running with scene.."); RunWithScene(scenesStack[scenesStack.Count - 1]); // always at the top of the stack } return(scenesStack.Count > 0 && RunningScene != null); } catch (Exception ex) { // if an exception was thrown while reading, odds are we cannot recover // from the saved state, so we will delete it so the game can correctly // launch. DeleteState(storage); CCLog.Log("Failed to deserialize the director state, removing old storage file."); CCLog.Log(ex.ToString()); } } } } catch (Exception ex) { CCLog.Log("Failed to deserialize director state."); CCLog.Log(ex.ToString()); } return(false); }
public void EndElement(object ctx, string elementName) { CCTMXMapInfo pTMXMapInfo = this; byte[] encoded = null; if (elementName == "data" && (pTMXMapInfo.LayerAttribs & (int)CCTMXLayerAttrib.Base64) != 0) { pTMXMapInfo.StoringCharacters = false; List <CCTMXLayerInfo> layers = pTMXMapInfo.Layers; int layersCount = layers != null ? layers.Count : 0; CCTMXLayerInfo layer = layersCount > 0 ? layers[layersCount - 1] : null; if ((pTMXMapInfo.LayerAttribs & ((int)(CCTMXLayerAttrib.Gzip) | (int)CCTMXLayerAttrib.Zlib)) != 0) { //gzip compress if ((pTMXMapInfo.LayerAttribs & (int)CCTMXLayerAttrib.Gzip) != 0) { try { encoded = ZipUtils.Inflate(new MemoryStream(pTMXMapInfo.CurrentString), ZipUtils.CompressionFormat.Gzip); } catch (Exception ex) { CCLog.Log("failed to decompress embedded data object in TMX file."); CCLog.Log(ex.ToString()); } } //zlib if ((pTMXMapInfo.LayerAttribs & (int)CCTMXLayerAttrib.Zlib) != 0) { encoded = ZipUtils.Inflate(new MemoryStream(pTMXMapInfo.CurrentString), ZipUtils.CompressionFormat.Zlib); } } else { encoded = pTMXMapInfo.CurrentString; } for (int i = 0; i < layer.Tiles.Length; i++) { int i4 = i * 4; var gid = (uint)( encoded[i4] | encoded[i4 + 1] << 8 | encoded[i4 + 2] << 16 | encoded[i4 + 3] << 24); layer.Tiles[i] = gid; } pTMXMapInfo.CurrentString = null; } else if (elementName == "map") { // The map element has ended pTMXMapInfo.ParentElement = (int)CCTMXProperty.None; } else if (elementName == "layer") { // The layer element has ended pTMXMapInfo.ParentElement = (int)CCTMXProperty.None; } else if (elementName == "objectgroup") { // The objectgroup element has ended pTMXMapInfo.ParentElement = (int)CCTMXProperty.None; } else if (elementName == "object") { // The object element has ended pTMXMapInfo.ParentElement = (int)CCTMXProperty.None; } }
internal void AddSpriteFrames(PlistDictionary pobDictionary, CCTexture2D pobTexture) { /* * Supported Zwoptex Formats: * * ZWTCoordinatesFormatOptionXMLLegacy = 0, // Flash Version * ZWTCoordinatesFormatOptionXML1_0 = 1, // Desktop Version 0.0 - 0.4b * ZWTCoordinatesFormatOptionXML1_1 = 2, // Desktop Version 1.0.0 - 1.0.1 * ZWTCoordinatesFormatOptionXML1_2 = 3, // Desktop Version 1.0.2+ */ PlistDictionary metadataDict = null; if (pobDictionary.ContainsKey("metadata")) { metadataDict = pobDictionary["metadata"].AsDictionary; } PlistDictionary framesDict = null; if (pobDictionary.ContainsKey("frames")) { framesDict = pobDictionary["frames"].AsDictionary; } int format = 0; // get the format if (metadataDict != null) { format = metadataDict["format"].AsInt; } // check the format if (format < 0 || format > 3) { throw (new NotSupportedException("PList format " + format + " is not supported.")); } foreach (var pair in framesDict) { PlistDictionary frameDict = pair.Value.AsDictionary; CCSpriteFrame spriteFrame = null; if (format == 0) { float x = 0f, y = 0f, w = 0f, h = 0f; x = frameDict["x"].AsFloat; y = frameDict["y"].AsFloat; w = frameDict["width"].AsFloat; h = frameDict["height"].AsFloat; float ox = 0f, oy = 0f; ox = frameDict["offsetX"].AsFloat; oy = frameDict["offsetY"].AsFloat; int ow = 0, oh = 0; ow = frameDict["originalWidth"].AsInt; oh = frameDict["originalHeight"].AsInt; // check ow/oh if (ow == 0 || oh == 0) { CCLog.Log( "cocos2d: WARNING: originalWidth/Height not found on the CCSpriteFrame. AnchorPoint won't work as expected. Regenerate the .plist or check the 'format' metatag"); } // abs ow/oh ow = Math.Abs(ow); oh = Math.Abs(oh); // create frame spriteFrame = new CCSpriteFrame( new CCSize(ow, oh), pobTexture, new CCRect(x, y, w, h), new CCSize(ow, oh), false, new CCPoint(ox, oy) ); } else if (format == 1 || format == 2) { CCRect frame = CCRect.Parse(frameDict["frame"].AsString); bool rotated = false; // rotation if (format == 2) { if (frameDict.ContainsKey("rotated")) { rotated = frameDict["rotated"].AsBool; } } CCPoint offset = CCPoint.Parse(frameDict["offset"].AsString); CCSize sourceSize = CCSize.Parse(frameDict["sourceSize"].AsString); // create frame spriteFrame = new CCSpriteFrame( sourceSize, pobTexture, frame, sourceSize, rotated, offset ); } else if (format == 3) { // get values CCSize spriteSize = CCSize.Parse(frameDict["spriteSize"].AsString); CCPoint spriteOffset = CCPoint.Parse(frameDict["spriteOffset"].AsString); CCSize spriteSourceSize = CCSize.Parse(frameDict["spriteSourceSize"].AsString); CCRect textureRect = CCRect.Parse(frameDict["textureRect"].AsString); bool textureRotated = false; if (frameDict.ContainsKey("textureRotated")) { textureRotated = frameDict["textureRotated"].AsBool; } // get aliases PlistArray aliases = frameDict["aliases"].AsArray; string frameKey = pair.Key; foreach (PlistObjectBase item2 in aliases) { string oneAlias = item2.AsString; if (spriteFramesAliases.ContainsKey(oneAlias)) { if (spriteFramesAliases[oneAlias] != null) { CCLog.Log("CocosSharp: WARNING: an alias with name {0} already exists", oneAlias); } } if (!spriteFramesAliases.ContainsKey(oneAlias)) { spriteFramesAliases.Add(oneAlias, frameKey); } } // create frame spriteFrame = new CCSpriteFrame( spriteSourceSize, pobTexture, new CCRect(textureRect.Origin.X, textureRect.Origin.Y, spriteSize.Width, spriteSize.Height), spriteSourceSize, textureRotated, spriteOffset ); } // add sprite frame string key = pair.Key; if (!AllowFrameOverwrite && spriteFrames.ContainsKey(key)) { CCLog.Log("Frame named " + key + " already exists in the animation cache. Not overwriting existing record."); } else if (AllowFrameOverwrite || !spriteFrames.ContainsKey(key)) { spriteFrames[key] = spriteFrame; } } }
void ParseDataEndElement() { byte[] encoded = null; if ((tileDataCompressionType & CCTileDataCompressionType.Base64) != 0) { storingCharacters = false; int layersCount = Layers != null ? Layers.Count : 0; CCTileLayerInfo layer = layersCount > 0 ? Layers[layersCount - 1] : null; if ((tileDataCompressionType & (CCTileDataCompressionType.Gzip | CCTileDataCompressionType.Zlib)) != 0) { if ((tileDataCompressionType & CCTileDataCompressionType.Gzip) != 0) { try { encoded = ZipUtils.Inflate(new MemoryStream(currentString), ZipUtils.CompressionFormat.Gzip); } catch (Exception ex) { CCLog.Log("failed to decompress embedded data object in TMX file."); CCLog.Log(ex.ToString()); } } if ((tileDataCompressionType & CCTileDataCompressionType.Zlib) != 0) { encoded = ZipUtils.Inflate(new MemoryStream(currentString), ZipUtils.CompressionFormat.Zlib); } } else { encoded = currentString; } for (int i = 0; i < layer.TileGIDAndFlags.Length; i++) { int i4 = i * 4; uint gidAndFlags = (uint)( (uint)encoded[i4] | (uint)encoded[(int)(i4 + 1)] << 8 | (uint)encoded[(int)(i4 + 2)] << 16 | (uint)encoded[(int)(i4 + 3)] << 24); layer.TileGIDAndFlags[i] = CCTileMapFileEncodedTileFlags.DecodeGidAndFlags(gidAndFlags); } currentString = null; } else if (tileDataCompressionType == CCTileDataCompressionType.Csv) { storingCharacters = false; int layersCount = Layers != null ? Layers.Count : 0; CCTileLayerInfo layer = layersCount > 0 ? Layers[layersCount - 1] : null; var str = System.Text.Encoding.UTF8.GetString(currentString, 0, currentString.Length).Split(','); for (int i = 0; i < layer.TileGIDAndFlags.Length; i++) { uint gidAndFlags = uint.Parse(str[i]); layer.TileGIDAndFlags[i] = CCTileMapFileEncodedTileFlags.DecodeGidAndFlags(gidAndFlags); } currentString = null; } else if ((tileDataCompressionType & CCTileDataCompressionType.None) != 0) { currentXmlTileIndex = 0; } }
void OnConfigLoad(CCParticleSystemConfig config, Action <CCParticleSystemConfig> action) { // Right now Mac can not load images with data defined asyncly so we want to short circuit this and // just load the data from disk. If not then we will perform an async load on the image #if MACOS config.LoadParticleTexture(); if (action != null) { action(config); } #else string textureData = config.TextureData; // We will try loading the texture data first if it exists. Hopefully we get lucky if (!string.IsNullOrEmpty(textureData)) { //Debug.Assert(!string.IsNullOrEmpty(textureData), // string.Format("CCParticleSystem: textureData does not exist : {0}", textureName)); int dataLen = textureData.Length; if (dataLen != 0) { var dataBytes = Convert.FromBase64String(textureData); Debug.Assert(dataBytes != null, string.Format("CCParticleSystem: error decoding textureImageData : {0}", config.TextureName)); var imageBytes = ZipUtils.Inflate(dataBytes); Debug.Assert(imageBytes != null, string.Format("CCParticleSystem: error init image with Data for texture : {0}", config.TextureName)); try { CCTextureCache.SharedTextureCache.AddImageAsync(imageBytes, config.TextureName, CCSurfaceFormat.Color, (loadedTexture) => { if (loadedTexture != null) { config.Texture = loadedTexture; if (action != null) { action(config); } } else { if (!string.IsNullOrEmpty(config.TextureName)) { bool bNotify = CCFileUtils.IsPopupNotify; CCFileUtils.IsPopupNotify = false; try { CCTextureCache.SharedTextureCache.AddImageAsync(config.TextureName, (tex2) => { config.Texture = tex2; if (config.Texture == null) { config.Texture = CCParticleExample.DefaultTexture; } if (action != null) { action(config); } }); } catch (Exception) { config.Texture = CCParticleExample.DefaultTexture; } CCFileUtils.IsPopupNotify = bNotify; if (config.Texture == null) { config.Texture = CCParticleExample.DefaultTexture; } } } } ); } catch (Exception ex) { CCLog.Log(ex.ToString()); config.Texture = CCParticleExample.DefaultTexture; } } } else { if (!string.IsNullOrEmpty(config.TextureName)) { bool bNotify = CCFileUtils.IsPopupNotify; CCFileUtils.IsPopupNotify = false; try { CCTextureCache.SharedTextureCache.AddImageAsync(config.TextureName, (tex2) => { config.Texture = tex2; if (config.Texture == null) { config.Texture = CCParticleExample.DefaultTexture; } if (action != null) { action(config); } }); } catch (Exception) { config.Texture = CCParticleExample.DefaultTexture; } CCFileUtils.IsPopupNotify = bNotify; } } #endif }
public void CreateFontChars() { int nextFontPositionX = 0; int nextFontPositionY = 0; char prev = (char)255; int kerningAmount = 0; CCSize tmpSize = CCSize.Zero; int longestLine = 0; int totalHeight = 0; int quantityOfLines = 1; if (String.IsNullOrEmpty(labelText)) { return; } int stringLen = labelText.Length; var charSet = FontConfiguration.CharacterSet; if (charSet.Count == 0) { throw (new InvalidOperationException( "Can not compute the size of the font because the character set is empty.")); } for (int i = 0; i < stringLen - 1; ++i) { if (labelText[i] == '\n') { quantityOfLines++; } } LineHeight = FontConfiguration.CommonHeight; totalHeight = LineHeight * quantityOfLines; nextFontPositionY = 0 - (LineHeight - LineHeight * quantityOfLines); CCBMFontConfiguration.CCBMGlyphDef fontDef = null; CCRect fontCharTextureRect; CCSize fontCharContentSize; for (int i = 0; i < stringLen; i++) { char c = labelText[i]; if (c == '\n') { nextFontPositionX = 0; nextFontPositionY -= LineHeight; continue; } if (charSet.IndexOf(c) == -1) { CCLog.Log("CocosSharp: CCLabelBMFont: Attempted to use character not defined in this bitmap: {0}", (int)c); continue; } kerningAmount = this.KerningAmountForFirst(prev, c); // unichar is a short, and an int is needed on HASH_FIND_INT if (!FontConfiguration.Glyphs.TryGetValue(c, out fontDef)) { CCLog.Log("CocosSharp: CCLabelBMFont: characer not found {0}", (int)c); continue; } fontCharTextureRect = fontDef.Subrect; fontCharTextureRect.Origin.X += ImageOffset.X; fontCharTextureRect.Origin.Y += ImageOffset.Y; fontCharContentSize = fontCharTextureRect.Size / DefaultTexelToContentSizeRatios; CCSprite fontChar; //bool hasSprite = true; fontChar = (CCSprite)(this[i]); if (fontChar != null) { // Reusing previous Sprite fontChar.Visible = true; // updating previous sprite fontChar.IsTextureRectRotated = false; fontChar.ContentSize = fontCharContentSize; fontChar.TextureRectInPixels = fontCharTextureRect; } else { // New Sprite ? Set correct color, opacity, etc... //if( false ) //{ // /* WIP: Doesn't support many features yet. // But this code is super fast. It doesn't create any sprite. // Ideal for big labels. // */ // fontChar = m_pReusedChar; // fontChar.BatchNode = null; // hasSprite = false; //} //else { fontChar = new CCSprite(TextureAtlas.Texture, fontCharTextureRect); fontChar.ContentSize = fontCharContentSize; AddChild(fontChar, i, i); } // Apply label properties fontChar.IsColorModifiedByOpacity = IsColorModifiedByOpacity; // Color MUST be set before opacity, since opacity might change color if OpacityModifyRGB is on fontChar.UpdateDisplayedColor(DisplayedColor); fontChar.UpdateDisplayedOpacity(DisplayedOpacity); } // See issue 1343. cast( signed short + unsigned integer ) == unsigned integer (sign is lost!) int yOffset = FontConfiguration.CommonHeight - fontDef.YOffset; var fontPos = new CCPoint( (float)nextFontPositionX + fontDef.XOffset + fontDef.Subrect.Size.Width * 0.5f + kerningAmount, (float)nextFontPositionY + yOffset - fontCharTextureRect.Size.Height * 0.5f); fontChar.Position = fontPos; // update kerning nextFontPositionX += fontDef.XAdvance + kerningAmount; prev = c; if (longestLine < nextFontPositionX) { longestLine = nextFontPositionX; } } // If the last character processed has an xAdvance which is less that the width of the characters image, then we need // to adjust the width of the string to take this into account, or the character will overlap the end of the bounding // box if (fontDef.XAdvance < fontDef.Subrect.Size.Width) { tmpSize.Width = longestLine + fontDef.Subrect.Size.Width - fontDef.XAdvance; } else { tmpSize.Width = longestLine; } tmpSize.Height = totalHeight; var tmpDimensions = labelDimensions; labelDimensions = new CCSize( labelDimensions.Width > 0 ? labelDimensions.Width : tmpSize.Width, labelDimensions.Height > 0 ? labelDimensions.Height : tmpSize.Height ); ContentSize = labelDimensions; labelDimensions = tmpDimensions; }
private CCBMFontConfiguration InitializeFont(string fontName, float fontSize, string charset) { if (Director == null) { return(null); } if (m_pData == null) { InitializeTTFAtlas(1024, 1024); } if (String.IsNullOrEmpty(charset)) { charset = " "; } var chars = new CCRawList <char>(); var fontKey = GetFontKey(fontName, fontSize); CCBMFontConfiguration fontConfig; if (!fontConfigurations.TryGetValue(fontKey, out fontConfig)) { fontConfig = new CCBMFontConfiguration(); fontConfigurations.Add(fontKey, fontConfig); } for (int i = 0; i < charset.Length; i++) { var ch = charset[i]; if (!fontConfig.Glyphs.ContainsKey(ch) && chars.IndexOf(ch) == -1) { chars.Add(ch); } } if (chars.Count == 0) { return(fontConfig); } CreateFont(fontName, fontSize, chars); fontConfig.CommonHeight = (int)Math.Ceiling(GetFontHeight()); int[] data = null; for (int i = 0; i < chars.Count; i++) { var s = chars[i].ToString(); var charSize = GetMeasureString(s); int w = (int)Math.Ceiling(charSize.Width + 2); int h = (int)Math.Ceiling(charSize.Height + 2); if (data == null || data.Length < (w * h)) { data = new int[w * h]; } unsafe { int stride; byte *pBase = GetBitmapData(s, out stride); int minX = w; int maxX = 0; int minY = h; int maxY = 0; for (int y = 0; y < h; y++) { var row = (int *)(pBase + y * stride); for (int x = 0; x < w; x++) { if (row[x] != 0) { minX = Math.Min(minX, x); maxX = Math.Max(maxX, x); minY = Math.Min(minY, y); maxY = Math.Max(maxY, y); } } } w = Math.Max(maxX - minX + 1, 1); h = Math.Max(maxY - minY + 1, 1); //maxX = minX + w; //maxY = minY + h; int index = 0; for (int y = minY; y <= maxY; y++) { var row = (int *)(pBase + y * stride); for (int x = minX; x <= maxX; x++) { data[index] = row[x]; index++; } } var region = AllocateRegion(w, h); if (region.x >= 0) { SetRegionData(region, data, w); var info = GetKerningInfo(chars[i]); var fontDef = new CCBMFontConfiguration.CCBMGlyphDef() { Character = chars[i], Subrect = new CCRect(region.x, region.y, region.width, region.height), XOffset = minX, // + (int)Math.Ceiling(info.A), YOffset = minY, XAdvance = (int)Math.Ceiling(info.A + info.B + info.C) }; fontConfig.CharacterSet.Add(chars[i]); fontConfig.Glyphs.Add(chars[i], fontDef); } else { CCLog.Log("Texture atlas is full"); } } } m_bTextureDirty = true; return(fontConfig); }