这是一个使用 CoreText 解决部分相似问题的示例。也许这会为你指明那个方向。
- (CFArrayRef)copyRectangularPathsForPath:(CGPathRef)path 
                                   height:(CGFloat)height {
    CFMutableArrayRef paths = CFArrayCreateMutable(NULL, 0, 
                                                   &kCFTypeArrayCallBacks);
    // First, check if we're a rectangle. If so, we can skip the hard parts.
    CGRect rect;
    if (CGPathIsRect(path, &rect)) {
        CFArrayAppendValue(paths, path);
    }
    else {
        // Build up the boxes one line at a time. If two boxes have the 
        // same width and offset, then merge them.
        CGRect boundingBox = CGPathGetPathBoundingBox(path);
        CGRect frameRect = CGRectZero;
        for (CGFloat y = CGRectGetMaxY(boundingBox) - height; 
                     y > height; y -= height) {
            CGRect lineRect =
                   CGRectMake(CGRectGetMinX(boundingBox), y, 
                              CGRectGetWidth(boundingBox), height);
            CGContextAddRect(UIGraphicsGetCurrentContext(), lineRect);
            // Do the math with full precision so we don't drift, 
            // but do final render on pixel boundaries.
            lineRect = CGRectIntegral(clipRectToPath(lineRect, path));
            CGContextAddRect(UIGraphicsGetCurrentContext(), lineRect);
            if (! CGRectIsEmpty(lineRect)) {
                if (CGRectIsEmpty(frameRect)) {
                    frameRect = lineRect;
                }
                else if (frameRect.origin.x == lineRect.origin.x && 
                         frameRect.size.width == lineRect.size.width) {
                    frameRect = CGRectMake(lineRect.origin.x,                                                                                                                                      lineRect.origin.y,                                                                                                                                      lineRect.size.width, 
                                CGRectGetMaxY(frameRect) - CGRectGetMinY(lineRect));
                }
                else {
                    CGMutablePathRef framePath =
                                         CGPathCreateMutable();
                    CGPathAddRect(framePath, NULL, frameRect);
                    CFArrayAppendValue(paths, framePath);
                    CFRelease(framePath);
                    frameRect = lineRect;
                }
            }
        }
        if (! CGRectIsEmpty(frameRect)) {
            CGMutablePathRef framePath = CGPathCreateMutable();
            CGPathAddRect(framePath, NULL, frameRect);
            CFArrayAppendValue(paths, framePath);
            CFRelease(framePath);
        }           
    }
    return paths;
}