public Font(int size, FontStyle style = 0) { UIFont uiFont = UIFont.SystemFontOfSize(size); CTFontDescriptorAttributes fda = new CTFontDescriptorAttributes() { FamilyName = uiFont.FamilyName, Size = (float)uiFont.PointSize }; uiFont.Dispose(); if ((style & FontStyle.Bold) != 0) { fda.StyleName = "Bold"; } else if ((style & FontStyle.Italic) != 0) { fda.StyleName = "Italic"; } CTFontDescriptor fd = new CTFontDescriptor(fda); nativeFont = new CTFont(fd, 0); fd.Dispose(); }
public Font(Xamarin.Forms.NamedSize namedSize, FontStyle style = 0) { UIFont uiFont = UIFont.SystemFontOfSize((float)Xamarin.Forms.Device.GetNamedSize(namedSize, typeof(Xamarin.Forms.Label))); CTFontDescriptorAttributes fda = new CTFontDescriptorAttributes() { FamilyName = uiFont.FamilyName, Size = (float)uiFont.PointSize }; uiFont.Dispose(); if ((style & FontStyle.Bold) != 0) { fda.StyleName = "Bold"; } else if ((style & FontStyle.Italic) != 0) { fda.StyleName = "Italic"; } CTFontDescriptor fd = new CTFontDescriptor(fda); nativeFont = new CTFont(fd, 0); fd.Dispose(); }
public Xamarin.Forms.Size GetTextSize( string text, double maxWidth, double fontSize = 0, string fontName = null) { if (fontSize <= 0) { fontSize = UIFont.SystemFontSize; } UIFont font = null; if (string.IsNullOrEmpty(fontName)) { font = UIFont.SystemFontOfSize((nfloat)fontSize); } else { font = UIFont.FromName(fontName, (nfloat)fontSize); } var attributes = new UIStringAttributes { Font = font }; var boundSize = new SizeF((float)maxWidth, float.MaxValue); var options = NSStringDrawingOptions.UsesFontLeading | NSStringDrawingOptions.UsesLineFragmentOrigin; var nsText = new NSString(text); var resultSize = nsText.GetBoundingRect( boundSize, options, attributes, null).Size; font.Dispose(); nsText.Dispose(); return(new Xamarin.Forms.Size( Math.Ceiling((double)resultSize.Width), Math.Ceiling((double)resultSize.Height))); }
// WHAT IS THE DEFAULT FONT FOR ANDROID? #endif // Partial class implementation of draw() in c# to allow use of unsafe code.. public unsafe void draw(IBitmapDrawable source, flash.geom.Matrix matrix = null, ColorTransform colorTransform = null, string blendMode = null, Rectangle clipRect = null, Boolean smoothing = false) { #if PLATFORM_MONOMAC || PLATFORM_MONOTOUCH if (source is flash.text.TextField) { flash.text.TextField tf = source as flash.text.TextField; flash.text.TextFormat format = tf.defaultTextFormat; // $$TODO figure out how to get rid of this extra data copy var sizeToDraw = (width * height) << 2; if (sizeToDraw == 0) { return; } string fontName = format.font; float fontSize = (format.size is double) ? (float)(double)format.size : ((format.size is int) ? (float)(int)format.size : 10); // Check if the font is installed? bool hasFont = true; if (!sHasFont.TryGetValue(fontName, out hasFont)) { #if PLATFORM_MONOTOUCH UIFont font = UIFont.FromName(fontName, 10); sHasFont[fontName] = hasFont = font != null; if (font != null) { font.Dispose(); } #elif PLATFORM_MONOMAC NSFont font = NSFont.FromFontName(fontName, 10); sHasFont[fontName] = hasFont = font != null; if (font != null) { font.Dispose(); } #else sHasFont[fontName] = false; #endif } if (!hasFont) { fontName = DEFAULT_FONT; } fixed(uint *data = mData) { using (CGBitmapContext context = new CGBitmapContext(new IntPtr(data), width, height, 8, 4 * width, CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedLast)) { uint tfColor = format.color != null ? (uint)(format.color) : 0; float r = (float)((tfColor >> 16) & 0xFF) / 255.0f; float g = (float)((tfColor >> 8) & 0xFF) / 255.0f; float b = (float)((tfColor >> 0) & 0xFF) / 255.0f; float a = (float)(tf.alpha); CGColor color = new CGColor(r, g, b, a); context.SetFillColor(color); context.SetStrokeColor(color); context.SelectFont(fontName, fontSize, CGTextEncoding.MacRoman); context.SetAllowsAntialiasing(((tf.antiAliasType as string) == flash.text.AntiAliasType.ADVANCED)); double x = matrix.tx; double y = matrix.ty; // invert y because the CG origin is bottom,left y = height - tf.textHeight - y; // align text switch (format.align) { case TextFormatAlign.LEFT: // no adjustment required break; case TextFormatAlign.CENTER: // center x x += width / 2; x -= tf.textWidth / 2; break; case TextFormatAlign.RIGHT: // right justify x x += width; x -= tf.textWidth; break; default: throw new System.NotImplementedException(); } // draw text context.ShowTextAtPoint((float)x, (float)y, tf.text); } } } else #elif PLATFORM_MONODROID if (source is flash.text.TextField) { flash.text.TextField tf = source as flash.text.TextField; flash.text.TextFormat format = tf.defaultTextFormat; // $$TODO figure out how to get rid of this extra data copy var data = new byte[width * height * 4]; System.Buffer.BlockCopy(mData, 0, data, 0, data.Length); Android.Graphics.Bitmap.Config config = Android.Graphics.Bitmap.Config.Argb8888; Android.Graphics.Bitmap bitmap = Android.Graphics.Bitmap.CreateBitmap(width, height, config); Canvas canvas = new Canvas(bitmap); var x = matrix.tx; var y = matrix.ty; // invert y because the CG origin is bottom,left // y = height - tf.textHeight - y; // align text switch (format.align) { case TextFormatAlign.LEFT: // no adjustment required break; case TextFormatAlign.CENTER: // center x x += width / 2; x -= tf.textWidth / 2; break; case TextFormatAlign.RIGHT: // right justify x x += width; x -= tf.textWidth; break; default: throw new System.NotImplementedException(); } Paint paint = new Paint(PaintFlags.AntiAlias); paint.Color = Color.Black; paint.TextSize = (float)format.size; paint.SetTypeface(Typeface.Create(format.font, TypefaceStyle.Normal)); paint.TextAlign = Paint.Align.Center; canvas.DrawText(tf.text, (float)x, (float)y, paint); mData = new uint[bitmap.Width * bitmap.Height]; var buffer = new int[bitmap.Width * bitmap.Height]; bitmap.GetPixels(buffer, 0, width, 0, 0, width, height); for (int i = 0; i < buffer.Length; i++) { mData[i] = (uint)buffer[i]; } } else #endif if (source is flash.display.BitmapData) { //naive implementation , //to be implemented: // -smoothing / antialiasing, // -blend mode // -colorTransform // -cliprect BitmapData sourceBitmap = source as BitmapData; flash.geom.Matrix matInverse = (matrix != null) ? matrix.clone() : new flash.geom.Matrix(); matInverse.invert(); for (int y = 0; y < mHeight; y++) { for (int x = 0; x < mWidth; x++) { int x2 = (int)(x * matInverse.a + y * matInverse.c + matInverse.tx); int y2 = (int)(x * matInverse.b + y * matInverse.d + matInverse.ty); if (x2 >= 0 && y2 >= 0 && x2 < sourceBitmap.width && y2 < sourceBitmap.height) { mData[x + y * mWidth] = sourceBitmap.mData[x2 + y2 * sourceBitmap.mWidth]; } } } } else { _root.trace_fn.trace("NotImplementedWarning: BitmapData.draw()"); } }
internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition) { if (string.IsNullOrEmpty(text)) { return(new CCTexture2D()); } int imageWidth; int imageHeight; var textDef = textDefinition; var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width; var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height; textDef.FontSize *= contentScaleFactorWidth; textDef.Dimensions.Width *= contentScaleFactorWidth; textDef.Dimensions.Height *= contentScaleFactorHeight; // font UIFont font = null; var ext = System.IO.Path.GetExtension(textDef.FontName); if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf") { try { textDef.FontName = LoadFontFile(textDef.FontName); font = UIFont.FromName(textDef.FontName, textDef.FontSize); } catch (Exception exc) { CCLog.Log(".ttf {0} file not found or can not be loaded.", textDef.FontName); } } else { // font font = UIFont.FromName(textDef.FontName, textDef.FontSize); //NSFontManager.SharedFontManager.FontWithFamily(textDef.FontName, NSFontTraitMask.Unbold | NSFontTraitMask.Unitalic, 0, textDef.FontSize); } if (font == null) { font = UIFont.FromName("Arial", textDef.FontSize); CCLog.Log("{0} not found. Defaulting to Arial.", textDef.FontName); } // color var foregroundColor = UIColor.White; // alignment var horizontalAlignment = textDef.Alignment; var verticleAlignement = textDef.LineAlignment; var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? UITextAlignment.Right : (CCTextAlignment.Center == horizontalAlignment) ? UITextAlignment.Center : UITextAlignment.Left; // LineBreak var lineBreak = (CCLabelLineBreak.Character == textDef.LineBreak) ? UILineBreakMode.CharacterWrap : (CCLabelLineBreak.Word == textDef.LineBreak) ? UILineBreakMode.WordWrap : UILineBreakMode.Clip; var nsparagraphStyle = (NSMutableParagraphStyle)NSParagraphStyle.Default.MutableCopy(); nsparagraphStyle.LineBreakMode = lineBreak; nsparagraphStyle.Alignment = textAlign; // Create a new attributed string definition var nsAttributes = new UIStringAttributes(); // Font attribute nsAttributes.Font = font; nsAttributes.ForegroundColor = foregroundColor; nsAttributes.ParagraphStyle = nsparagraphStyle; var stringWithAttributes = new NSAttributedString(text, nsAttributes); var realDimensions = stringWithAttributes.Size; // Mac crashes if the width or height is 0 if (realDimensions == SizeF.Empty) { throw new ArgumentOutOfRangeException("Native string:", "Dimensions of native NSAttributedString can not be 0,0"); } var dimensions = new CGSize(textDef.Dimensions.Width, textDef.Dimensions.Height); var layoutAvailable = true; if (dimensions.Width <= 0) { dimensions.Width = 8388608; layoutAvailable = false; } if (dimensions.Height <= 0) { dimensions.Height = 8388608; layoutAvailable = false; } var boundingRect = stringWithAttributes.GetBoundingRect(new CGSize((int)dimensions.Width, (int)dimensions.Height), NSStringDrawingOptions.UsesLineFragmentOrigin, null); if (!layoutAvailable) { if (dimensions.Width == 8388608) { dimensions.Width = boundingRect.Width; } if (dimensions.Height == 8388608) { dimensions.Height = boundingRect.Height; } } imageWidth = (int)dimensions.Width; imageHeight = (int)dimensions.Height; // Alignment var xOffset = (nfloat)0.0f; switch (textAlign) { case UITextAlignment.Left: xOffset = 0; break; case UITextAlignment.Center: xOffset = (dimensions.Width - boundingRect.Width) / 2.0f; break; case UITextAlignment.Right: xOffset = dimensions.Width - boundingRect.Width; break; default: break; } // Line alignment var yOffset = (CCVerticalTextAlignment.Bottom == verticleAlignement || boundingRect.Height >= dimensions.Height) ? (dimensions.Height - boundingRect.Height) // align to bottom : (CCVerticalTextAlignment.Top == verticleAlignement) ? 0 // align to top : (imageHeight - boundingRect.Height) / 2.0f; // align to center //Find the rect that the string will draw into inside the dimensions var drawRect = new CGRect(xOffset , yOffset , boundingRect.Width , boundingRect.Height); UIImage image = null; CGContext context = null; try { UIGraphics.BeginImageContext(new CGSize(imageWidth, imageHeight)); context = UIGraphics.GetCurrentContext(); //Set antialias or not context.SetShouldAntialias(textDef.isShouldAntialias); stringWithAttributes.DrawString(drawRect); image = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); // We will use Texture2D from stream here instead of CCTexture2D stream. var tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, image); // Debugging purposes // var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // var fileName = Path.Combine(path, "Label3.png"); // using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write)) // { // tex.SaveAsPng(stream, imageWidth, imageHeight); // } // Create our texture of the label string. var texture = new CCTexture2D(tex); return(texture); } catch (Exception exc) { CCLog.Log("CCLabel: Error creating native label:{0}\n{1}", exc.Message, exc.StackTrace); } finally { // clean up the resources if (image != null) { image.Dispose(); image = null; } if (context != null) { context.Dispose(); context = null; } font.Dispose(); font = null; nsparagraphStyle.Dispose(); nsparagraphStyle = null; if (stringWithAttributes != null) { stringWithAttributes.Dispose(); stringWithAttributes = null; } } return(new CCTexture2D()); }