Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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;
        }
Ejemplo n.º 6
0
        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();
            }
        }
Ejemplo n.º 7
0
        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());
        }
Ejemplo n.º 8
0
        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 ();


        }
Ejemplo n.º 10
0
 internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition)
 {
     return(new CCTexture2D());
 }
Ejemplo n.º 11
0
        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());
        }
Ejemplo n.º 12
0
        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();
        }
Ejemplo n.º 13
0
        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());
        }
Ejemplo n.º 14
0
        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();
 }
Ejemplo n.º 18
0
        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();
        }
Ejemplo n.º 19
0
        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());
        }
Ejemplo n.º 20
0
        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());
            }
        }