184 lines
7.4 KiB
Objective-C
184 lines
7.4 KiB
Objective-C
//
|
|
// 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 <Foundation/Foundation.h>
|
|
#import <UIKit/UIKit.h>
|
|
|
|
@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<NSValue *> *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<NSDictionary *> *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<NSDictionary *> *underlines;
|
|
|
|
/// Temporary review highlight (not yet saved), used during review creation.
|
|
@property (nonatomic, strong, nullable) NSArray<NSDictionary *> *tempReviewHighlights;
|
|
|
|
/// Set of bookmarked page indices (NSSet of NSNumber).
|
|
@property (nonatomic, strong, nullable) NSSet<NSNumber *> *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<NSDictionary *> *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
|