当前位置: 首页 > 工具软件 > CircleView > 使用案例 >

Comments on Apple Sample Code : CircleView

林烨烨
2023-12-01
//Add some comments to CircleView Sample Code.
//may help you understand the code or may be not.
</pre><pre name="code" class="objc">- (void)drawRect:(NSRect)rect {
    NSUInteger glyphIndex;
    NSRange glyphRange;
    NSRect usedRect;
     
    [[NSColor whiteColor] set];
    NSRectFill([self bounds]);

    // Note that usedRectForTextContainer: does not force layout, so it must 
    // be called after glyphRangeForTextContainer:, which does force layout.
    glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
    usedRect = [layoutManager usedRectForTextContainer:textContainer];

    for (glyphIndex = glyphRange.location; glyphIndex < NSMaxRange(glyphRange); glyphIndex++) {
        NSGraphicsContext *context = [NSGraphicsContext currentContext];
	NSRect lineFragmentRect = [layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex effectiveRange:NULL];
	NSPoint viewLocation, layoutLocation = [layoutManager locationForGlyphAtIndex:glyphIndex];
        CGFloat angle, distance;
        NSAffineTransform *transform = [NSAffineTransform transform];
    
        // Here layoutLocation is the location (in container coordinates) where the glyph was laid out. 
        layoutLocation.x += lineFragmentRect.origin.x;
        layoutLocation.y += lineFragmentRect.origin.y;

        // We then use the layoutLocation to calculate an appropriate position for the glyph 
        // around the circle (by angle and distance, or viewLocation in rectangular coordinates).
        distance = radius + usedRect.size.height - layoutLocation.y;    <span style="color:#33ff33;">//my: distance is a constant that a little larger than radius.</span>
        angle = startingAngle + layoutLocation.x / distance;
        
        <span style="color:#33ff33;">//my:
        //This is a confusing point.
        //In math, you calculate the coordinates of point of the circumference as:
        //viewLocation.x = center.x + radium * cos(angle);
        //viewLocation.y = center.y + radium * sin(angle);
        //sin(PI/2 - alpha) = cos(alpha); cos(PI/2 - alpha) = sin(alpha);</span>
        viewLocation.x = center.x + distance * sin(angle);  <span style="color:#33ff33;">//sin(angle) = cos(PI/2 - angle) = cos(PI/2 - startingAngle - layoutLocation.x / distance);</span>
        viewLocation.y = center.y + distance * cos(angle);  <span style="color:#33ff33;">//cos(angle) = sin(PI/2 - angle) = sin(PI/2 - startingAngle - layoutLocation.x / distance);</span>
        <span style="color:#33ff33;">//you can treat (PI/2 - startingAngle) as new startingAngle, the "-" before angle indicate
        //as angle increase, points in circle move not counterclockwise but clockwise.</span>
        
        // We use a different affine transform for each glyph, to position and rotate it
        // based on its calculated position around the circle.
        <span style="color:#33ff33;">// MY: If you don't known how the transformation works, you can refer to Cocoa Drawing Guide, search "Transform Basics".</span>
        [transform translateXBy:viewLocation.x yBy:viewLocation.y];
        [transform rotateByRadians:-angle];
        <span style="color:#33ff33;">//-angle = -startingAngle - layoutLocation.x / distance = (PI/2 - startingAngle) + (- PI/2) - layoutLocation.x / distance.
        //- layoutLocation.x / distance is alpha in my picture.</span>

        // We save and restore the graphics state so that the transform applies only to this glyph.
        [context saveGraphicsState];
        [transform concat];
        // drawGlyphsForGlyphRange: draws the glyph at its laid-out location in container coordinates.
        // Since we are using the transform to place the glyph, we subtract the laid-out location here.
        
        <span style="color:#33ff33;">//my:
        //when invoke drawGlyphsForGlyphRange:atPoint, the origin point is the glyph's laid-out location in container coordinates.
        //while x-direction and y-direction follows the transformed coordinate.
        //so we subtract the laid-out location here.</span>
        [layoutManager drawGlyphsForGlyphRange:NSMakeRange(glyphIndex, 1) atPoint:NSMakePoint(-layoutLocation.x, -layoutLocation.y)];
        [context restoreGraphicsState];
    }
}

//Comment: currently I can't upload my picture.

 类似资料:

相关阅读

相关文章

相关问答