// // DTCoreTextGlyphRun.h // WeRead // // Reverse-engineered from binary analysis // Based on DTCoreText open-source library, customized by WeRead // // DTCoreText is an open-source library for rendering HTML with CoreText. // This class represents a glyph run within a line of text. // #import #import @class DTCoreTextLayoutLine; @class DTTextAttachment; NS_ASSUME_NONNULL_BEGIN /** * DTCoreTextGlyphRun - Represents a glyph run within a line. * * A glyph run is a sequence of glyphs that share the same attributes * (font, color, etc.). This class wraps CTRun and provides high-level * access to individual glyphs and their properties. * * Key features: * - Wraps CTRun for high-level access * - Contains glyph images and paths * - Handles text attachments (images, etc.) * - Provides hit testing within the run * - Supports custom drawing and effects */ @interface DTCoreTextGlyphRun : NSObject #pragma mark - Properties /** The CTRun reference */ @property (nonatomic, assign, readonly) CTRunRef ctRun; /** The frame (position and size) of this run */ @property (nonatomic, assign) CGRect frame; /** The range of characters in this run */ @property (nonatomic, assign, readonly) NSRange stringRange; /** The index of this run in its parent line */ @property (nonatomic, assign, readonly) NSUInteger runIndex; /** The attributes shared by all glyphs in this run */ @property (nonatomic, strong, readonly) NSDictionary *attributes; /** The parent layout line */ @property (nonatomic, weak, nullable) DTCoreTextLayoutLine *layoutLine; /** Array of glyph images (for custom rendering) */ @property (nonatomic, strong, nullable) NSArray *glyphImages; /** Array of attachment objects */ @property (nonatomic, strong, nullable) NSArray *attachments; /** The text attachment (if this run contains one) */ @property (nonatomic, strong, nullable) DTTextAttachment *attachment; /** Whether this run is a placeholder for an attachment */ @property (nonatomic, assign, readonly) BOOL isAttachment; /** Whether this run is a whitespace */ @property (nonatomic, assign, readonly) BOOL isWhitespace; /** Whether this run is a newline */ @property (nonatomic, assign, readonly) BOOL isNewline; /** The font used in this run */ @property (nonatomic, strong, nullable) UIFont *font; /** The text color */ @property (nonatomic, strong, nullable) UIColor *textColor; /** The background color */ @property (nonatomic, strong, nullable) UIColor *backgroundColor; /** The strikethrough color */ @property (nonatomic, strong, nullable) UIColor *strikethroughColor; /** Whether strikethrough is enabled */ @property (nonatomic, assign) BOOL hasStrikethrough; /** Whether underline is enabled */ @property (nonatomic, assign) BOOL hasUnderline; /** The underline style */ @property (nonatomic, assign) NSUnderlineStyle underlineStyle; /** The underline color */ @property (nonatomic, strong, nullable) UIColor *underlineColor; /** Number of glyphs in this run */ @property (nonatomic, assign, readonly) NSUInteger numberOfGlyphs; /** Array of glyph values */ @property (nonatomic, strong, readonly) NSArray *glyphs; /** Array of glyph positions */ @property (nonatomic, strong, readonly) NSArray *glyphPositions; /** Array of glyph advances */ @property (nonatomic, strong, readonly) NSArray *glyphAdvances; /** The writing direction */ @property (nonatomic, assign) CTWritingDirection writingDirection; /** Whether this run is right-to-left */ @property (nonatomic, assign, readonly) BOOL isRTL; #pragma mark - Initialization /** * Initialize with a CTRun. * * @param ctRun The CoreText run * @param frame The frame of the run * @param range The string range * @param attributes The run attributes * @param index The run index * @return Initialized glyph run */ - (instancetype)initWithCTRun:(CTRunRef)ctRun frame:(CGRect)frame range:(NSRange)range attributes:(NSDictionary *)attributes index:(NSUInteger)index; #pragma mark - Glyph Access /** * Returns the glyph at the specified index. * * @param index The glyph index * @return The glyph value */ - (CGGlyph)glyphAtIndex:(NSUInteger)index; /** * Returns the position of the glyph at the specified index. * * @param index The glyph index * @return The glyph position */ - (CGPoint)positionForGlyphAtIndex:(NSUInteger)index; /** * Returns the advance of the glyph at the specified index. * * @param index The glyph index * @return The glyph advance */ - (CGFloat)advanceForGlyphAtIndex:(NSUInteger)index; /** * Returns the rect for the glyph at the specified index. * * @param index The glyph index * @return The glyph rect */ - (CGRect)rectForGlyphAtIndex:(NSUInteger)index; #pragma mark - Path Operations /** * Creates a CGPath containing all glyphs in this run. * * This method creates a path that outlines all the glyphs. * It's used for custom drawing, hit testing, and effects. * * @return A CGPath containing the glyph outlines, or NULL */ - (nullable CGPathRef)newPathWithGlyphs; /** * Creates a CGPath for a specific glyph. * * @param index The glyph index * @return A CGPath for the glyph, or NULL */ - (nullable CGPathRef)newPathForGlyphAtIndex:(NSUInteger)index; /** * Creates a bounding path for all glyphs. * * @return A CGPath bounding all glyphs */ - (nullable CGPathRef)newBoundingPath; #pragma mark - Image Operations /** * Returns the image for the glyph at the specified index. * * @param index The glyph index * @return The glyph image, or nil */ - (nullable UIImage *)imageForGlyphAtIndex:(NSUInteger)index; /** * Returns the bounding rect for the glyph image. * * @param index The glyph index * @return The image rect */ - (CGRect)imageRectForGlyphAtIndex:(NSUInteger)index; #pragma mark - Hit Testing /** * Returns the glyph index at the given point. * * @param point The point to test * @return The glyph index, or NSNotFound */ - (NSUInteger)glyphIndexAtPoint:(CGPoint)point; /** * Returns the string index at the given point. * * @param point The point to test * @return The string index, or NSNotFound */ - (NSUInteger)stringIndexAtPoint:(CGPoint)point; /** * Returns the rect for a given string index. * * @param index The string index * @return The rect for the character */ - (CGRect)rectForStringIndex:(NSUInteger)index; #pragma mark - Drawing /** * Draws this run into a CGContext. * * @param context The CGContext to draw into */ - (void)drawInContext:(CGContextRef)context; /** * Draws this run with a specific color. * * @param context The CGContext to draw into * @param color The text color */ - (void)drawInContext:(CGContextRef)context withColor:(UIColor *)color; /** * Draws the attachment (if any) into the context. * * @param context The CGContext to draw into */ - (void)drawAttachmentInContext:(CGContextRef)context; #pragma mark - Run Comparison /** * Compares this run to another run for ordering. */ - (NSComparisonResult)compareToRun:(DTCoreTextGlyphRun *)otherRun; /** * Returns whether this run contains the given string index. */ - (BOOL)containsStringIndex:(NSUInteger)index; /** * Returns whether this run intersects with the given range. */ - (BOOL)intersectsRange:(NSRange)range; #pragma mark - Metrics /** * Returns the typographic bounds of this run. * * @param ascent Output parameter for ascent * @param descent Output parameter for descent * @param leading Output parameter for leading * @return The width of the run */ - (CGFloat)getTypographicBoundsAscent:(CGFloat *)ascent descent:(CGFloat *)descent leading:(CGFloat *)leading; /** * Returns the bounds of the run (bounding box). */ - (CGRect)bounds; /** * Returns the width of the run. */ - (CGFloat)width; /** * Returns the height of the run. */ - (CGFloat)height; @end NS_ASSUME_NONNULL_END