I have an NSView that is rotated using -setFrameRotation. (This is necessary because the view responds to mouse events, and you don't get correct behavior if you merely draw the view with a rotated NSAffineTransform.)
Given a rect in the rotated view's superview coordinates, how can I determine what portion of the rect intersects the rotated view's frame?
Use case: the Cocoa text system proposes to draw text in a line fragment rectangle. I need to determine how much of that rectangle may be filled with text without overlapping the rotated view.
Take the point, use an affine transform to rotate into the coordinate system of the bounds of the rect and then rect-test that.
Related
I know Win2D allows you to draw text within a specific rectangle and you can set it so that text not within that rectangle is clipped so that it isn't drawn.
I was wondering if it would be possible to do this with not just a rectangle but any Geometry (which may include curved lines)
What I get with rectangular clipping:
What I want (clipping by the white rounded rectangle with the curved bottom):
One of the CreateLayer overloads will probably do what you want:
http://microsoft.github.io/Win2D/html/Overload_Microsoft_Graphics_Canvas_CanvasDrawingSession_CreateLayer.htm
I need to rotate the frame of an instance of NSView in such a way that its width becomes its height and its height becomes its width. The view contains a string and it is important that this string is rotated as well.
I had a look at NSView's setFrameRotation: but this rotates around the frame origin which is not what I want. I suppose that technically my requirement is not a rotation but more a mirroring at a 45 degree angle from the origin.
How can I accomplish this?
Try Desire to rotate around centre
This piece of could should helper.
[NSView rotateByAngle]
If I use a standard NSWindow to host a NSOpenGLView which extends for all the window frame, the two bottom corners of the window are automatically rounded.
When swithcing to NSBorderlessWindowMask I have to handle corner rounding myself.
I have already implemented a transparent custom NSWindow and a rounded custom NSView and they both work fine.
After that I have implemented a transparent NSOpenGLContext by setting NSOpenGLCPSurfaceOpacity to 0.
If I set a color background for the OpenGL context, the view is drawn correctly and I obtain the desired rounded corner.
But, since the app is a movie player, I need to draw the texture corresponding to every movie frame.
When I do this (using glTexCoord2f and glVertex2f) the texture is drawn till corners and therefore the image is drawn till outside of the rounded corners and I loose the rounded aspect of my window.
What does the system do when the window is standard and non NSBorderlessWindowMask that I can't seem to be able to reproduce?
What is the best way to round the corner of the texture while drawing it to the frame buffer?
You could apply the texture to a geometry with rounded corners, use an additional alpha mask on the movie texture with rounded corners, or use the stencil test to round off your viewport's corners.
I need to limit the drawing of an object to a rectangle. I can't just change the viewport to match the rectangle becouse the ModelView matrix (that should change the rectangle, but not the content) may not be identity. A solution that would work is to draw to a FBO that match the rectangle, then draw the FBO to the screen, but it seems to slow. Is there any better option to do that?
If I understood you correctly, glScissor should be the function you are looking for. It crops the rendering to a selected sub-rectangle of the viewport. This does not modify the viewport. So the objects cover the same size on the screen, it just prevents you from drawing any pixels outside of the scissor region. If this is not what you want and you want the sub-rectangle to contain the whole scene and thus your objects to shrink, then changing the viewport is the solution of choice.
EDIT: If you want the rectangle to be transformable and especially rotatable (and therefore not a rectangle anymore on the screen), then rendering into an FBO and using this as texture on a quad is probably the best solution. Otherwise you could probably also just modify the vertex coordinates after projection, thus multiplying the transformation matrix of the target rectangle with the projection matrix and using this as new projection matrix, but I'm not completely sure about that (but at least something similar should do it.
I'm using GDI+ in my application, and I need to use a rotated LinearGradientBrush to paint several rects in the exact same way. However, although I'm calling the same code to fill each rect, the results aren't what I expect. Here's the code to create the gradient fill, where rcDraw is the rect containing the area to paint for each rect. These coordinates are in the parent window's coordinates, so they are not identical for the 2 rects.
g_hbrLinear = new LinearGradientBrush( Rect( 0, rcDraw.top, 0, rcDraw.bottom - rcDraw.top ),
clrStart, clrEnd, (REAL) 80, FALSE );
What I see on screen looks like this (http://www.nnanime.com/bugs/LinGradBrush-rotate10.png). You can see that it's as if the fill from the first rect continues into the second one. What I really want is to have the 2 rects look identical. I think I can do that if I paint each rect separately using its own client coordinates, but for the purposes of my app, I need to use the parent window's coordinates.
I guess what I'm asking is, how does GDI+ calculate the "origin" of a fill? Is it always based on 0,0 in the coordinate system you use? Is there a way to shift it? I tried TranslateTransform, but it doesn't seem to shift the fill in a way that I find predictable or understandable.
The rect passed to the linear gradient brush determines the where the left and right colors will sit, and the gradient will be painted within this rectangle.
So, I think you need to create a brush for each rectangle you are painting, where the rectangle you are painting is also passed to the constructor for the linear gradient brush.
My experience with the "transform" of linear gradient brushes matches yours; I haven't been able to understand what it's supposed to do.
You can think of a brush in GDI+ as a function mapping world co-ordinates to a color. What the brush looks like at a given point does not change based on the shape being filled.
It does change with the transform of the Graphics object you're drawing on. So, if you don't want to change the brush, you could temporarily change the transform of the Graphics object so that the rectangle you're drawing has a specific, known size and position in world coordinates. The BeginContainer and EndContainer methods should make this easy.
(There is also the RenderingOrigin property but it only affects hatch brushes, which oddly are unaffected by world transforms.)