protected void UpdateContent() { if (string.IsNullOrEmpty(Text)) { return; } if (FontAtlas != null) { LayoutLabel(); } else { if (currentLabelType == CCLabelType.SystemFont) { var fontDefinition = new CCFontDefinition(); fontDefinition.FontName = systemFont; fontDefinition.FontSize = (int)systemFontSize; fontDefinition.Alignment = labelFormat.Alignment; fontDefinition.LineAlignment = labelFormat.LineAlignment; fontDefinition.Dimensions = Dimensions; fontDefinition.FontFillColor = DisplayedColor; fontDefinition.FontAlpha = DisplayedOpacity; fontDefinition.LineBreak = labelFormat.LineBreaking; CreateSpriteWithFontDefinition(fontDefinition); } } IsDirty = false; }
void CreateSpriteWithFontDefinition(CCFontDefinition fontDefinition) { var texture = CreateTextSprite(Text, fontDefinition); textSprite = new CCSprite(texture); textSprite.AnchorPoint = CCPoint.AnchorLowerLeft; ContentSize = textSprite.ContentSize; base.AddChild(textSprite, 0, TagInvalid); textSprite.UpdateDisplayedColor(DisplayedColor); textSprite.UpdateDisplayedOpacity(DisplayedOpacity); }
void CreateSpriteWithFontDefinition(CCFontDefinition fontDefinition) { if (textSprite != null) { textSprite.RemoveFromParent(); } var texture = CreateTextSprite(Text, fontDefinition); textSprite = new CCSprite(texture); textSprite.IsAntialiased = isAntialiased; textSprite.BlendFunc = BlendFunc; textSprite.AnchorPoint = CCPoint.AnchorLowerLeft; base.ContentSize = textSprite.ContentSize; base.AddChild(textSprite, 0, TagInvalid); textSprite.UpdateDisplayedColor(DisplayedColor); textSprite.UpdateDisplayedOpacity(DisplayedOpacity); }
void CreateSpriteWithFontDefinition(CCFontDefinition fontDefinition) { if (textSprite != null) textSprite.RemoveFromParent(); var texture = CreateTextSprite(Text, fontDefinition); textSprite = new CCSprite(texture); textSprite.IsAntialiased = isAntialiased; textSprite.BlendFunc = BlendFunc; textSprite.AnchorPoint = CCPoint.AnchorLowerLeft; base.ContentSize = textSprite.ContentSize; base.AddChild(textSprite,0,TagInvalid); textSprite.UpdateDisplayedColor(DisplayedColor); textSprite.UpdateDisplayedOpacity(DisplayedOpacity); }
protected void UpdateContent() { if (isUpdatingContent) return; isUpdatingContent = true; if (string.IsNullOrEmpty(Text)) { return; } if (FontAtlas != null) { LayoutLabel(); } else { if (LabelType == CCLabelType.SystemFont) { var fontDefinition = new CCFontDefinition(); fontDefinition.FontName = systemFont; fontDefinition.FontSize = systemFontSize; fontDefinition.Alignment = labelFormat.Alignment; fontDefinition.LineAlignment = labelFormat.LineAlignment; fontDefinition.Dimensions = Dimensions; fontDefinition.FontFillColor = DisplayedColor; fontDefinition.FontAlpha = DisplayedOpacity; fontDefinition.LineBreak = labelFormat.LineBreaking; fontDefinition.isShouldAntialias = IsAntialiased; CreateSpriteWithFontDefinition(fontDefinition); } } IsDirty = false; isUpdatingContent = false; }
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 = 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 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(); } }
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 = new Color4(1f, 1f, 1f, 1f); // 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 = (int)textMetrics.Width; boundingRect.Height = (int)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 if (labelRenderer == null) { labelRenderer = new CCLabel_Renderer81(); } try { // The following code creates a .png stream in memory of our Bitmap and uses it to create our Textue2D Texture2D tex = null; using (var pngStream = labelRenderer.RenderLabelToStream(imageWidth, imageHeight, foregroundColor, new Vector2(boundingRect.X, yOffset), textLayout).Result) { // Create the Texture2D from the png stream tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, pngStream); } // 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 (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()); }
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 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; } 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; //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) { 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 *= (int)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); var fontColor = textDef.FontFillColor; var fontAlpha = textDef.FontAlpha; var foregroundColor = new Color4(fontColor.R / 255.0f, fontColor.G / 255.0f, fontColor.B / 255.0f, fontAlpha / 255.0f); // 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()); }
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; var font = CreateFont(textDef.FontName, textDef.FontSize); if (font == null) { CCLog.Log("Can not create font {0} with size {1}.", textDef.FontName, textDef.FontSize); return new CCTexture2D(); } 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(); }
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 *= contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; bool hasPremultipliedAlpha; var font = CreateFont(textDef.FontName, textDef.FontSize / dpiScale); // color var foregroundColor = System.Drawing.Color.White; // 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 *= (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 textPaint = new TextPaint(PaintFlags.AntiAlias); textPaint.Color = Android.Graphics.Color.White; textPaint.TextAlign = Paint.Align.Left; textPaint.TextSize = textDef.FontSize; var fontName = textDef.FontName; var ext = System.IO.Path.GetExtension(fontName); if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf") { var path = System.IO.Path.Combine(CCContentManager.SharedContentManager.RootDirectory, fontName); var activity = Game.Activity; try { var typeface = Typeface.CreateFromAsset(activity.Assets, path); 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 // Create our platform dependant image to be drawn to. var textureBitmap = Bitmap.CreateBitmap(imageWidth, imageHeight, Bitmap.Config.Argb8888); var drawingCanvas = new Canvas(textureBitmap); // 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. var texture = new CCTexture2D(tex); return(texture); }
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 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; } 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; 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 if (labelRenderer == null) labelRenderer = new CCLabel_Renderer81(); try { // The following code creates a .png stream in memory of our Bitmap and uses it to create our Textue2D Texture2D tex = null; using (var pngStream = labelRenderer.RenderLabelToStream(imageWidth, imageHeight, foregroundColor, new Vector2(boundingRect.X, yOffset), textLayout).Result) { // Create the Texture2D from the png stream tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, pngStream); } // 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 (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(); }
internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { return new CCTexture2D(); }
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 *= contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; bool hasPremultipliedAlpha; var font = CreateFont(textDef.FontName, textDef.FontSize / dpiScale); // color var foregroundColor = System.Drawing.Color.White; // 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; // 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; 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()); } }