// // WRCoreTextLayouter.h // WeRead // // Reverse-engineered from binary analysis // CoreText typesetter wrapper for WeRead's reading engine // #import #import #import @class WRCoreTextLayoutFrame; @class WRMarkContentChapter; @class QMUITextField; @class WRButton; NS_ASSUME_NONNULL_BEGIN #pragma mark - Layout Configuration /** * Configuration options for text layout. * Controls how the typesetter processes attributed strings. */ @interface WRCoreTextLayoutConfig : NSObject @property (nonatomic, assign) CGFloat frameWidth; @property (nonatomic, assign) CGFloat frameHeight; @property (nonatomic, assign) UIEdgeInsets edgeInsets; @property (nonatomic, assign) NSUInteger numberOfColumns; @property (nonatomic, assign) CGFloat columnGap; @property (nonatomic, assign) BOOL avoidOrphans; @property (nonatomic, assign) BOOL avoidWidows; @property (nonatomic, assign) BOOL hyphenation; @end #pragma mark - WRCoreTextLayouter /** * WRCoreTextLayouter - CoreText typesetter wrapper for WeRead. * * This class wraps CTTypesetter and CTFramesetter to provide high-level * text layout functionality. It takes an NSAttributedString and produces * WRCoreTextLayoutFrame objects representing individual pages. * * Architecture: * - Creates CTTypesetter from attributed string * - Manages typesetter lifecycle and caching * - Produces layout frames for pagination * - Handles image resizing and page backgrounds * - Integrates with WeRead's theme system */ @interface WRCoreTextLayouter : NSObject #pragma mark - Text Content /** The original plain text string */ @property (nonatomic, strong, nullable) NSString *plainText; /** The attributed string to be laid out */ @property (nonatomic, strong, nullable) NSAttributedString *attributedString; /** A copy of the attributed string for internal modifications */ @property (nonatomic, strong, nullable) NSAttributedString *internalAttributedString; #pragma mark - UI Components (likely from parent view hierarchy) /** Reference to the containing view controller */ @property (nonatomic, weak, nullable) UIViewController *viewController; /** Reference to the scroll view for pagination */ @property (nonatomic, weak, nullable) UIScrollView *scrollView; /** Search text field (for find-in-book functionality) */ @property (nonatomic, strong, nullable) QMUITextField *searchField; /** Another text field (possibly for page jump) */ @property (nonatomic, strong, nullable) QMUITextField *pageInputField; /** Button for actions */ @property (nonatomic, strong, nullable) WRButton *actionButton; /** Layer for decorations */ @property (nonatomic, strong, nullable) CALayer *decorationLayer; /** Layer for shadow/overlay effects */ @property (nonatomic, strong, nullable) CALayer *shadowLayer; /** Title label */ @property (nonatomic, strong, nullable) UILabel *titleLabel; /** Subtitle/info label */ @property (nonatomic, strong, nullable) UILabel *infoLabel; #pragma mark - Theme and Appearance /** Background color for the text rendering area */ @property (nonatomic, strong, nullable) UIColor *backgroundColor; /** Text color */ @property (nonatomic, strong, nullable) UIColor *textColor; /** Primary font for body text */ @property (nonatomic, strong, nullable) UIFont *bodyFont; /** Secondary font (for headings, emphasis) */ @property (nonatomic, strong, nullable) UIFont *headingFont; /** Container view for rendered content */ @property (nonatomic, weak, nullable) UIView *containerView; #pragma mark - Content Metadata /** Chapter identifier */ @property (nonatomic, copy, nullable) NSString *chapterId; /** Book identifier */ @property (nonatomic, copy, nullable) NSString *bookId; /** Section identifier within chapter */ @property (nonatomic, copy, nullable) NSString *sectionId; /** Page identifier for current page */ @property (nonatomic, copy, nullable) NSString *pageId; /** Content source identifier */ @property (nonatomic, copy, nullable) NSString *sourceId; /** Unique layout identifier */ @property (nonatomic, copy, nullable) NSString *layoutId; /** Rendering mode identifier */ @property (nonatomic, copy, nullable) NSString *renderMode; /** Theme identifier */ @property (nonatomic, copy, nullable) NSString *themeId; /** Additional layout attributes dictionary */ @property (nonatomic, strong, nullable) NSDictionary *layoutAttributes; /** Array of embedded attachments (images, etc.) */ @property (nonatomic, strong, nullable) NSArray *attachments; /** Reference to the chapter content model */ @property (nonatomic, strong, nullable) WRMarkContentChapter *chapter; /** Current pagination cursor string */ @property (nonatomic, copy, nullable) NSString *paginationCursor; /** Mutable array of layout frames (pages) */ @property (nonatomic, strong, nullable) NSMutableArray *layoutFrames; #pragma mark - Initialization /** * Initialize with an attributed string for layout. * * @param attributedString The text with styling attributes * @return Initialized layouter instance */ - (instancetype)initWithAttributedString:(NSAttributedString *)attributedString; /** * Initialize with attributed string and layout configuration. * * @param attributedString The text with styling attributes * @param config Layout configuration options * @return Initialized layouter instance */ - (instancetype)initWithAttributedString:(NSAttributedString *)attributedString config:(WRCoreTextLayoutConfig *)config; #pragma mark - Typesetter Management /** * Create or recreate the internal CTTypesetter. * Called when the attributed string changes. */ - (void)createTypesetter; /** * Create or recreate the internal CTFramesetter. * Called when frame-based layout is needed. */ - (void)createFramesetter; /** * Invalidate the current typesetter, forcing recreation on next use. */ - (void)invalidateTypesetter; #pragma mark - Layout Frame Creation /** * Create a layout frame for a given string range within the specified rect. * * @param range The range of the attributed string to lay out * @param frame The bounding rectangle for the layout * @return A new WRCoreTextLayoutFrame for the given range */ - (WRCoreTextLayoutFrame *)layoutFrameWithRange:(NSRange)range frame:(CGRect)frame; /** * Create layout frames for the entire attributed string. * Breaks content into pages based on the frame size. * * @param pageSize The size of each page * @return Array of WRCoreTextLayoutFrame objects */ - (NSArray *)layoutFramesForPageSize:(CGSize)pageSize; /** * Create a single layout frame for the given range. * * @param range The range of text to lay out * @param rect The bounding rectangle * @param columns Number of columns * @return A layout frame or nil if range is invalid */ - (nullable WRCoreTextLayoutFrame *)layoutFrameForRange:(NSRange)range rect:(CGRect)rect columns:(NSUInteger)columns; #pragma mark - Page Background Images /** * Get the page background image for a given text range. * * @param range The range of text on the page * @param themeBgColor The current theme's background color * @return A UIImage for the page background, or nil */ - (nullable UIImage *)pageBackgroundImageAtRange:(NSRange)range themeBgColor:(UIColor *)themeBgColor; #pragma mark - Image Utilities /** * Resize an image for display within the layout. * * @param imagePath Path or URL string for the image * @param rect The target rectangle for the image * @param position The position within the layout * @param sizePattern The size pattern to apply * @param darkMode Whether dark mode is active * @param themeBgColor The theme background color for blending * @return A resized UIImage */ - (UIImage *)resizedImageForImagePath:(NSString *)imagePath rect:(CGRect)rect position:(NSUInteger)position sizePattern:(NSString *)sizePattern darkMode:(BOOL)darkMode themeBgColor:(UIColor *)themeBgColor; #pragma mark - Pagination /** * Calculate the number of pages for the given page size. * * @param pageSize The size of each page * @return The total number of pages */ - (NSUInteger)numberOfPagesForPageSize:(CGSize)pageSize; /** * Get the text range for a specific page. * * @param pageIndex The page index (0-based) * @param pageSize The size of each page * @return The NSRange of text on the specified page */ - (NSRange)rangeForPageAtIndex:(NSUInteger)pageIndex pageSize:(CGSize)pageSize; #pragma mark - Suggested Line Heights /** * Get suggested line fragment heights for the current content. * Used for precise pagination calculations. * * @return Array of NSNumber values representing line heights */ - (NSArray *)suggestedLineFragHeights; @end NS_ASSUME_NONNULL_END