// // WRChapterData.h // WeRead (读书) // // Reverse-engineered header reconstruction. // Chapter data model. Stores the typeset NSAttributedString. // Manages highlights, underlines, reviews/annotations. // Uses WRCoreTextLayouter for layout computation. // #import #import @class WRCoreTextLayouter; NS_ASSUME_NONNULL_BEGIN // ============================================================================ #pragma mark - Highlight / Underline Style Constants // ============================================================================ /// Style of underline drawn for highlights and annotations. typedef NS_ENUM(NSInteger, WRUnderlineStyle) { WRUnderlineStyleNone = 0, WRUnderlineStyleSolid = 1, WRUnderlineStyleDashed = 2, WRUnderlineStyleWavy = 3, }; /// Type of review / annotation. typedef NS_ENUM(NSInteger, WRReviewType) { WRReviewTypeHighlight = 0, // Color highlight WRReviewTypeUnderline = 1, // Underline only WRReviewTypeNote = 2, // Text note attached to range }; // ============================================================================ #pragma mark - WRChapterData // ============================================================================ @interface WRChapterData : NSObject // ---- Core content ---- /// The fully typeset attributed string for this chapter, with all fonts, /// colors, paragraph styles, and inline image attachments applied. @property (nonatomic, strong, nullable) NSMutableAttributedString *typesetAttributedString; /// The layouter that computes line breaks and page breaks for this chapter. @property (nonatomic, strong, nullable) WRCoreTextLayouter *layouter; // ---- Page ranges ---- /// Array of NSValue-wrapped NSRange values, one per page. /// Each range is a character range within typesetAttributedString. @property (nonatomic, strong, nullable) NSArray *pageRanges; // ---- Highlights and annotations ---- /// Array of highlight dictionaries. Each entry contains: /// @"range" : NSValue wrapping NSRange /// @"key" : NSString (unique highlight ID) /// @"itemId" : NSString (item identifier, e.g., bookmark ID) /// @"color" : UIColor @property (nonatomic, strong, nullable) NSArray *highlights; /// Array of underline / review dictionaries. Each entry contains: /// @"range" : NSValue wrapping NSRange /// @"itemId" : NSString /// @"type" : @(WRReviewType) /// @"style" : @(WRUnderlineStyle) /// @"color" : UIColor @property (nonatomic, strong, nullable) NSArray *underlines; /// Temporary review highlight (not yet saved), used during review creation. @property (nonatomic, strong, nullable) NSArray *tempReviewHighlights; /// Set of bookmarked page indices (NSSet of NSNumber). @property (nonatomic, strong, nullable) NSSet *bookmarkedPages; /// Raw chapter source text (before typesetting). @property (nonatomic, strong, nullable) NSAttributedString *sourceAttributedString; // ---- Chapter metadata ---- @property (nonatomic, copy, nullable) NSString *chapterId; @property (nonatomic, copy, nullable) NSString *chapterTitle; @property (nonatomic, assign) NSUInteger chapterIndex; // ---- Content insets for the reading area ---- @property (nonatomic, assign) UIEdgeInsets contentInsets; // ---- Outline / TOC ---- /// Array of outline entry dictionaries generated from headings in the chapter. /// Each entry: @"title", @"level", @"range" (NSValue wrapping NSRange). @property (nonatomic, strong, nullable) NSArray *outlineContents; // ---- Free trial cutoff ---- /// The string location (character index) at which the free trial ends. /// NSNotFound if the chapter is fully accessible. @property (nonatomic, assign) NSUInteger freeTrialCutOffLocation; // ============================================================================ #pragma mark - Class Methods // ============================================================================ /// Adds an underline decoration to the given attributed string at the specified /// range, with the given style, color, and associated item ID. + (void)addUnderLineToAttributedString:(NSMutableAttributedString *)attributedString range:(NSRange)range itemId:(NSString *)itemId style:(WRUnderlineStyle)style color:(UIColor *)color; /// Calculates the free trial cutoff string location within the attributed /// string for the given book. Returns the character index where content /// should be truncated for non-paying users. + (NSUInteger)freeTrialChapterCutOffStringLocaionWithAttributedString:(NSAttributedString *)attributedString book:(id)book; // ============================================================================ #pragma mark - Instance Methods — Highlights & Underlines // ============================================================================ /// Adds an auto-read underline (visual indicator for auto-scroll mode). - (void)addAutoReadUnderLineInRange:(NSRange)range style:(WRUnderlineStyle)style color:(UIColor *)color; /// Adds a highlight annotation. - (void)addHighlightInRange:(NSRange)range key:(NSString *)key itemId:(NSString *)itemId color:(UIColor *)color; /// Adds a review underline (e.g., from a friend's review). - (void)addReviewUnderlineInRange:(NSRange)range itemId:(NSString *)itemId type:(WRReviewType)type; /// Adds a temporary review highlight (not persisted until confirmed). - (void)addTempReviewHighlightInRange:(NSRange)range itemId:(NSString *)itemId; /// Adds a temporary review highlight with a custom color. - (void)addTempReviewHighlightInRange:(NSRange)range itemId:(NSString *)itemId color:(UIColor *)color; /// Removes a review underline by range and type. - (void)deleteReviewUnderlineInRange:(NSRange)range type:(WRReviewType)type; // ============================================================================ #pragma mark - Instance Methods — Page Queries // ============================================================================ /// Returns the character range within typesetAttributedString for the given /// page index (0-based). Uses the pageRanges array computed during layout. - (NSRange)rangeOfPage:(NSUInteger)pageIndex; // ============================================================================ #pragma mark - Instance Methods — Outline // ============================================================================ /// Scans the attributed string for heading styles and builds the /// outlineContents array. - (void)generateOutlineContents; // ============================================================================ #pragma mark - Instance Methods — Free Trial // ============================================================================ /// Returns the real (post-typeset) string location for the free trial cutoff. - (NSUInteger)freeTrialChapterCutOffRealStringLocation; /// Sets the free trial cutoff string location. - (void)markFreeTrialChapterCutOffStringLocation:(NSUInteger)location; @end NS_ASSUME_NONNULL_END