예제 #1
0
		public override object CreateImageBuilder (int width, int height, ImageFormat format)
		{
			var flags = CGBitmapFlags.ByteOrderDefault;
			int bytesPerRow;
			switch (format) {

			case ImageFormat.ARGB32:
				bytesPerRow = width * 4;
				flags |= CGBitmapFlags.PremultipliedFirst;
				break;

			case ImageFormat.RGB24:
				bytesPerRow = width * 3;
				flags |= CGBitmapFlags.None;
				break;

			default:
				throw new NotImplementedException ("ImageFormat: " + format.ToString ());
			}

			var bmp = new CGBitmapContext (IntPtr.Zero, width, height, 8, bytesPerRow, Util.DeviceRGBColorSpace, flags);
			bmp.TranslateCTM (0, height);
			bmp.ScaleCTM (1, -1);
			return new CGContextBackend {
				Context = bmp,
				Size = new CGSize (width, height),
				InverseViewTransform = bmp.GetCTM ().Invert ()
			};
		}
		internal static void NativeDrawString (CGBitmapContext bitmapContext, string s, CTFont font, CCColor4B brush, CGRect layoutRectangle)
		{
			if (font == null)
				throw new ArgumentNullException ("font");

			if (s == null || s.Length == 0)
				return;

			bitmapContext.ConcatCTM (bitmapContext.GetCTM().Invert());

            // This is not needed here since the color is set in the attributed string.
			//bitmapContext.SetFillColor(brush.R/255f, brush.G/255f, brush.B/255f, brush.A/255f);

            // I think we only Fill the text with no Stroke surrounding
			//bitmapContext.SetTextDrawingMode(CGTextDrawingMode.Fill);

			var attributedString = buildAttributedString(s, font, brush);

			// Work out the geometry
			CGRect insetBounds = layoutRectangle;

			CGPoint textPosition = new CGPoint(insetBounds.X,
			                                 insetBounds.Y);

            float boundsWidth = (float)insetBounds.Width;

			// Calculate the lines
			nint start = 0;
            nint length = attributedString.Length;

			var typesetter = new CTTypesetter(attributedString);

			float baselineOffset = 0;

			// First we need to calculate the offset for Vertical Alignment if we 
			// are using anything but Top
			if (vertical != CCVerticalTextAlignment.Top) {
				while (start < length) {

                    nint count = typesetter.SuggestLineBreak((int)start, (double)boundsWidth);

                    var line = typesetter.GetLine (new NSRange(start, count));

					// Create and initialize some values from the bounds.
					nfloat ascent;
					nfloat descent;
					nfloat leading;
                    line.GetTypographicBounds(out ascent, out descent, out leading);
                    baselineOffset += (float)Math.Ceiling ((float)(ascent + descent + leading + 1)); // +1 matches best to CTFramesetter's behavior  
					line.Dispose ();
					start += count;
				}
			}

			start = 0;

			while (start < length && textPosition.Y < insetBounds.Bottom)
			{

				// Now we ask the typesetter to break off a line for us.
				// This also will take into account line feeds embedded in the text.
				//  Example: "This is text \n with a line feed embedded inside it"
                nint count = typesetter.SuggestLineBreak((int)start, (double)boundsWidth);
				var line = typesetter.GetLine(new NSRange(start, count));

				// Create and initialize some values from the bounds.
				nfloat ascent;
				nfloat descent;
				nfloat leading;
				line.GetTypographicBounds(out ascent, out descent, out leading);

				// Calculate the string format if need be
				var penFlushness = 0.0f;

				if (horizontal == CCTextAlignment.Right)
					penFlushness = (float)line.GetPenOffsetForFlush(1.0f, boundsWidth);
				else if (horizontal == CCTextAlignment.Center)
					penFlushness = (float)line.GetPenOffsetForFlush(0.5f, boundsWidth);

				// initialize our Text Matrix or we could get trash in here
				var textMatrix = CGAffineTransform.MakeIdentity();

				if (vertical == CCVerticalTextAlignment.Top)
					textMatrix.Translate(penFlushness, insetBounds.Height - textPosition.Y -(float)Math.Floor(ascent - 1));
				if (vertical == CCVerticalTextAlignment.Center)
					textMatrix.Translate(penFlushness, ((insetBounds.Height / 2) + (baselineOffset / 2)) - textPosition.Y -(float)Math.Floor(ascent - 1));
				if (vertical == CCVerticalTextAlignment.Bottom)
					textMatrix.Translate(penFlushness, baselineOffset - textPosition.Y -(float)Math.Floor(ascent - 1));

				// Set our matrix
				bitmapContext.TextMatrix = textMatrix;

				// and draw the line
				line.Draw(bitmapContext);

				// Move the index beyond the line break.
				start += count;
				textPosition.Y += (float)Math.Ceiling(ascent + descent + leading + 1); // +1 matches best to CTFramesetter's behavior  
				line.Dispose();

			}

		}	
예제 #3
0
        public override object ConvertToBitmap(object handle, double width, double height, double scaleFactor, ImageFormat format)
        {
            int pixelWidth = (int)(width * scaleFactor);
            int pixelHeight = (int)(height * scaleFactor);

            if (handle is CustomImage) {
                var flags = CGBitmapFlags.ByteOrderDefault;
                int bytesPerRow;
                switch (format) {
                case ImageFormat.ARGB32:
                    bytesPerRow = pixelWidth * 4;
                    flags |= CGBitmapFlags.PremultipliedFirst;
                    break;

                case ImageFormat.RGB24:
                    bytesPerRow = pixelWidth * 3;
                    flags |= CGBitmapFlags.None;
                    break;

                default:
                    throw new NotImplementedException ("ImageFormat: " + format.ToString ());
                }

                var bmp = new CGBitmapContext (IntPtr.Zero, pixelWidth, pixelHeight, 8, bytesPerRow, Util.DeviceRGBColorSpace, flags);
                bmp.TranslateCTM (0, pixelHeight);
                bmp.ScaleCTM ((float)scaleFactor, (float)-scaleFactor);

                var ctx = new CGContextBackend {
                    Context = bmp,
                    Size = new SizeF ((float)width, (float)height),
                    InverseViewTransform = bmp.GetCTM ().Invert (),
                    ScaleFactor = scaleFactor
                };

                var ci = (CustomImage)handle;
                ci.DrawInContext (ctx);

                var img = new NSImage (((CGBitmapContext)bmp).ToImage (), new SizeF (pixelWidth, pixelHeight));
                var imageData = img.AsTiff ();
                var imageRep = (NSBitmapImageRep)NSBitmapImageRep.ImageRepFromData (imageData);
                var im = new NSImage ();
                im.AddRepresentation (imageRep);
                im.Size = new SizeF ((float)width, (float)height);
                bmp.Dispose ();
                return im;
            }
            else {
                NSImage img = (NSImage)handle;
                NSBitmapImageRep bitmap = img.Representations ().OfType<NSBitmapImageRep> ().FirstOrDefault ();
                if (bitmap == null) {
                    var imageData = img.AsTiff ();
                    var imageRep = (NSBitmapImageRep)NSBitmapImageRep.ImageRepFromData (imageData);
                    var im = new NSImage ();
                    im.AddRepresentation (imageRep);
                    im.Size = new SizeF ((float)width, (float)height);
                    return im;
                }
                return handle;
            }
        }
예제 #4
0
        public override object ConvertToBitmap(object handle, int pixelWidth, int pixelHeight, ImageFormat format)
        {
            if (handle is CustomImage) {
                var flags = CGBitmapFlags.ByteOrderDefault;
                int bytesPerRow;
                switch (format) {
                case ImageFormat.ARGB32:
                    bytesPerRow = pixelWidth * 4;
                    flags |= CGBitmapFlags.PremultipliedFirst;
                    break;

                case ImageFormat.RGB24:
                    bytesPerRow = pixelWidth * 3;
                    flags |= CGBitmapFlags.None;
                    break;

                default:
                    throw new NotImplementedException ("ImageFormat: " + format.ToString ());
                }

                var bmp = new CGBitmapContext (IntPtr.Zero, pixelWidth, pixelHeight, 8, bytesPerRow, Util.DeviceRGBColorSpace, flags);
                bmp.TranslateCTM (0, pixelHeight);
                bmp.ScaleCTM (1, -1);

                var ctx = new CGContextBackend {
                    Context = bmp,
                    Size = new SizeF (pixelWidth, pixelHeight),
                    InverseViewTransform = bmp.GetCTM ().Invert ()
                };

                var ci = (CustomImage)handle;
                ci.DrawInContext (ctx);

                var img = new NSImage (((CGBitmapContext)bmp).ToImage (), new SizeF (pixelWidth, pixelHeight));
                var imageData = img.AsTiff ();
                var imageRep = (NSBitmapImageRep) NSBitmapImageRep.ImageRepFromData (imageData);
                var im = new NSImage ();
                im.AddRepresentation (imageRep);
                return im;
            }
            else
                return handle;
        }