292 lines
8.9 KiB
Objective-C
292 lines
8.9 KiB
Objective-C
//
|
|
// WRCoreTextLayouter.h
|
|
// WeRead
|
|
//
|
|
// Reverse-engineered from binary analysis
|
|
// CoreText typesetter wrapper for WeRead's reading engine
|
|
//
|
|
|
|
#import <Foundation/Foundation.h>
|
|
#import <UIKit/UIKit.h>
|
|
#import <CoreText/CoreText.h>
|
|
|
|
@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<WRCoreTextLayoutFrame *> *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<WRCoreTextLayoutFrame *> *)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<NSNumber *> *)suggestedLineFragHeights;
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|