|
| 1 | +/* Definition of class GSFontAssetDownloader |
| 2 | + Copyright (C) 2024 Free Software Foundation, Inc. |
| 3 | +
|
| 4 | + By: Gregory John Casamento <greg.casamento@gmail.com> |
| 5 | + Date: September 5, 2024 |
| 6 | +
|
| 7 | + This file is part of the GNUstep Library. |
| 8 | +
|
| 9 | + This library is free software; you can redistribute it and/or |
| 10 | + modify it under the terms of the GNU Lesser General Public |
| 11 | + License as published by the Free Software Foundation; either |
| 12 | + version 2.1 of the License, or (at your option) any later version. |
| 13 | +
|
| 14 | + This library is distributed in the hope that it will be useful, |
| 15 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | + Lesser General Public License for more details. |
| 18 | +
|
| 19 | + You should have received a copy of the GNU Lesser General Public |
| 20 | + License along with this library; if not, write to the Free |
| 21 | + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 22 | + Boston, MA 02110 USA. |
| 23 | +*/ |
| 24 | + |
| 25 | +#ifndef _GSFontAssetDownloader_h_GNUSTEP_GUI_INCLUDE |
| 26 | +#define _GSFontAssetDownloader_h_GNUSTEP_GUI_INCLUDE |
| 27 | +#import <AppKit/AppKitDefines.h> |
| 28 | + |
| 29 | +#import <Foundation/NSObject.h> |
| 30 | +#import <Foundation/NSError.h> |
| 31 | + |
| 32 | +@class NSFontDescriptor; |
| 33 | +@class NSURL; |
| 34 | +@class NSString; |
| 35 | +@class NSPanel; |
| 36 | +@class NSProgressIndicator; |
| 37 | +@class NSTextField; |
| 38 | +@class NSButton; |
| 39 | + |
| 40 | +#if OS_API_VERSION(MAC_OS_X_VERSION_10_13, GS_API_LATEST) |
| 41 | + |
| 42 | +/** |
| 43 | + * GSFontAssetDownloader provides a pluggable mechanism for downloading |
| 44 | + * and installing font assets from various sources. This class can be |
| 45 | + * subclassed to implement custom font downloading strategies, such as |
| 46 | + * downloading from different font services, using authentication, or |
| 47 | + * implementing custom validation and installation procedures. |
| 48 | + * |
| 49 | + * The default implementation supports downloading fonts from HTTP/HTTPS |
| 50 | + * URLs and local file URLs, with basic validation and cross-platform |
| 51 | + * installation to standard font directories. |
| 52 | + * |
| 53 | + * Subclasses can override individual methods to customize specific |
| 54 | + * aspects of the download and installation process while reusing |
| 55 | + * other parts of the default implementation. |
| 56 | + * |
| 57 | + * CLASS REPLACEMENT SYSTEM: |
| 58 | + * |
| 59 | + * GSFontAssetDownloader supports a class replacement system that allows |
| 60 | + * applications to register a custom downloader class to be used globally. |
| 61 | + * This enables complete customization of font downloading behavior without |
| 62 | + * needing to modify every NSFontAssetRequest instance. |
| 63 | + * |
| 64 | + * Example usage: |
| 65 | + * |
| 66 | + * // Define a custom downloader class |
| 67 | + * @interface MyCustomFontDownloader : GSFontAssetDownloader |
| 68 | + * @end |
| 69 | + * |
| 70 | + * @implementation MyCustomFontDownloader |
| 71 | + * - (NSURL *) fontURLForDescriptor: (NSFontDescriptor *)descriptor { |
| 72 | + * // Custom URL resolution logic |
| 73 | + * return [NSURL URLWithString: @"https://my-font-service.com/..."]; |
| 74 | + * } |
| 75 | + * @end |
| 76 | + * |
| 77 | + * // Register the custom class globally |
| 78 | + * [GSFontAssetDownloader setDefaultDownloaderClass: [MyCustomFontDownloader class]]; |
| 79 | + * |
| 80 | + * // Or through NSFontAssetRequest |
| 81 | + * [NSFontAssetRequest setDefaultDownloaderClass: [MyCustomFontDownloader class]]; |
| 82 | + * |
| 83 | + * // All new font asset requests will now use the custom downloader |
| 84 | + * NSFontAssetRequest *request = [[NSFontAssetRequest alloc] |
| 85 | + * initWithFontDescriptors: descriptors options: 0]; |
| 86 | + * |
| 87 | + * PROGRESS PANEL USAGE: |
| 88 | + * |
| 89 | + * To show a progress panel during font download, use the NSFontAssetRequestOptionUsesStandardUI option: |
| 90 | + * |
| 91 | + * NSFontDescriptor *descriptor = [NSFontDescriptor fontDescriptorWithName: @"Inconsolata" size: 12]; |
| 92 | + * GSFontAssetDownloader *downloader = [GSFontAssetDownloader downloaderWithOptions: NSFontAssetRequestOptionUsesStandardUI]; |
| 93 | + * NSError *error = nil; |
| 94 | + * BOOL success = [downloader downloadAndInstallFontWithDescriptor: descriptor error: &error]; |
| 95 | + * |
| 96 | + * The progress panel will automatically appear with: |
| 97 | + * - A progress bar showing download/installation progress |
| 98 | + * - Status messages describing the current operation |
| 99 | + * - A cancel button (posts GSFontAssetDownloadCancelled notification when pressed) |
| 100 | + */ |
| 101 | +GS_EXPORT_CLASS |
| 102 | +@interface GSFontAssetDownloader : NSObject |
| 103 | +{ |
| 104 | + NSUInteger _options; |
| 105 | + NSPanel *_progressPanel; |
| 106 | + NSProgressIndicator *_progressIndicator; |
| 107 | + NSTextField *_statusLabel; |
| 108 | + NSButton *_cancelButton; |
| 109 | +} |
| 110 | + |
| 111 | +/** |
| 112 | + * Registers a custom downloader class to be used instead of the default |
| 113 | + * GSFontAssetDownloader class. The registered class must be a subclass |
| 114 | + * of GSFontAssetDownloader. Pass nil to restore the default behavior. |
| 115 | + */ |
| 116 | ++ (void) setDefaultDownloaderClass: (Class)downloaderClass; |
| 117 | + |
| 118 | +/** |
| 119 | + * Returns the currently registered downloader class, or GSFontAssetDownloader |
| 120 | + * if no custom class has been registered. |
| 121 | + */ |
| 122 | ++ (Class) defaultDownloaderClass; |
| 123 | + |
| 124 | +/** |
| 125 | + * Creates a new font asset downloader instance using the currently |
| 126 | + * registered downloader class. This is the preferred method for creating |
| 127 | + * downloader instances as it respects any custom downloader class that |
| 128 | + * has been registered. |
| 129 | + */ |
| 130 | ++ (instancetype) downloaderWithOptions: (NSUInteger)options; |
| 131 | + |
| 132 | +/** |
| 133 | + * Creates a new font asset downloader with the specified options. |
| 134 | + * The options parameter contains flags that control the download |
| 135 | + * and installation behavior, such as whether to use standard UI |
| 136 | + * or install to user vs system directories. |
| 137 | + */ |
| 138 | +- (instancetype) initWithOptions: (NSUInteger)options; |
| 139 | + |
| 140 | +/** |
| 141 | + * Downloads and installs a font from the specified descriptor. |
| 142 | + * This is the main entry point for font downloading. The method |
| 143 | + * orchestrates the complete process: URL resolution, download, |
| 144 | + * validation, and installation. Returns YES if the font was |
| 145 | + * successfully downloaded and installed, NO otherwise. |
| 146 | + */ |
| 147 | +- (BOOL) downloadAndInstallFontWithDescriptor: (NSFontDescriptor *)descriptor |
| 148 | + error: (NSError **)error; |
| 149 | + |
| 150 | +/** |
| 151 | + * Downloads and installs a font from the specified descriptor with a preferred format. |
| 152 | + * This variant allows specifying the preferred font format (e.g., "woff2", "woff", "ttf") |
| 153 | + * when downloading from CSS URLs. For direct font URLs, the format parameter is ignored. |
| 154 | + * Returns YES if the font was successfully downloaded and installed, NO otherwise. |
| 155 | + */ |
| 156 | +- (BOOL) downloadAndInstallFontWithDescriptor: (NSFontDescriptor *)descriptor |
| 157 | + preferredFormat: (NSString *)format |
| 158 | + error: (NSError **)error; |
| 159 | + |
| 160 | +/** |
| 161 | + * Resolves a font URL from a font descriptor. |
| 162 | + * This method can be overridden to implement custom URL resolution |
| 163 | + * strategies, such as querying different font services or using |
| 164 | + * authentication tokens. The default implementation looks for a |
| 165 | + * custom URL attribute or constructs URLs from font names. |
| 166 | + */ |
| 167 | +- (NSURL *) fontURLForDescriptor: (NSFontDescriptor *)descriptor; |
| 168 | + |
| 169 | +/** |
| 170 | + * Downloads a font file from the specified URL. |
| 171 | + * This method can be overridden to implement custom download |
| 172 | + * strategies, such as using authentication, custom headers, or |
| 173 | + * progress callbacks. Returns the path to the downloaded temporary |
| 174 | + * file, or nil on failure. |
| 175 | + */ |
| 176 | +- (NSString *) downloadFontFromURL: (NSURL *)fontURL |
| 177 | + error: (NSError **)error; |
| 178 | + |
| 179 | +/** |
| 180 | + * Downloads a font file from the specified URL with a given font name. |
| 181 | + * This variant allows specifying the font name for better filename generation. |
| 182 | + * The downloaded file will be saved with a name based on the font name and |
| 183 | + * appropriate extension. Returns the path to the downloaded temporary file, |
| 184 | + * or nil on failure. |
| 185 | + */ |
| 186 | +- (NSString *) downloadFontFromURL: (NSURL *)fontURL |
| 187 | + fontName: (NSString *)fontName |
| 188 | + error: (NSError **)error; |
| 189 | + |
| 190 | +/** |
| 191 | + * Extracts font URLs from CSS content based on the specified format. |
| 192 | + * This method parses CSS @font-face declarations and extracts URLs |
| 193 | + * that match the given format (e.g., "woff2", "woff", "ttf"). |
| 194 | + * Returns an array of NSURL objects, or nil on error. |
| 195 | + */ |
| 196 | +- (NSArray *) extractFontURLsFromCSS: (NSString *)cssContent |
| 197 | + withFormat: (NSString *)format |
| 198 | + error: (NSError **)error; |
| 199 | + |
| 200 | +/** |
| 201 | + * Downloads font data from a CSS URL that contains @font-face declarations. |
| 202 | + * This method first downloads the CSS content, parses it to extract font URLs |
| 203 | + * based on the specified format, and then downloads the first matching font. |
| 204 | + * Returns the path to the downloaded temporary file, or nil on failure. |
| 205 | + */ |
| 206 | +- (NSString *) downloadFontDataFromCSSURL: (NSURL *)cssURL |
| 207 | + withFormat: (NSString *)format |
| 208 | + error: (NSError **)error; |
| 209 | + |
| 210 | +/** |
| 211 | + * Downloads font data from a CSS URL with a given font name. |
| 212 | + * This variant allows specifying the font name for better filename generation. |
| 213 | + * The downloaded file will be saved with a name based on the font name and |
| 214 | + * appropriate extension. Returns the path to the downloaded temporary file, |
| 215 | + * or nil on failure. |
| 216 | + */ |
| 217 | +- (NSString *) downloadFontDataFromCSSURL: (NSURL *)cssURL |
| 218 | + withFormat: (NSString *)format |
| 219 | + fontName: (NSString *)fontName |
| 220 | + error: (NSError **)error; |
| 221 | + |
| 222 | +/** |
| 223 | + * Validates a downloaded font file. |
| 224 | + * This method can be overridden to implement custom validation |
| 225 | + * logic, such as checking font metadata, licensing information, |
| 226 | + * or performing security scans. The default implementation |
| 227 | + * checks file existence, size, and format signatures. |
| 228 | + */ |
| 229 | +- (BOOL) validateFontFile: (NSString *)fontPath |
| 230 | + error: (NSError **)error; |
| 231 | + |
| 232 | +/** |
| 233 | + * Installs a font file to the appropriate system location. |
| 234 | + * This method can be overridden to implement custom installation |
| 235 | + * strategies, such as using system APIs, registering with font |
| 236 | + * management services, or applying custom permissions. Returns |
| 237 | + * YES if installation was successful, NO otherwise. |
| 238 | + */ |
| 239 | +- (BOOL) installFontAtPath: (NSString *)fontPath |
| 240 | + error: (NSError **)error; |
| 241 | + |
| 242 | +/** |
| 243 | + * Returns the system fonts directory for the current platform. |
| 244 | + * This method can be overridden to customize the system font |
| 245 | + * installation location or to support additional platforms. |
| 246 | + */ |
| 247 | +- (NSString *) systemFontsDirectory; |
| 248 | + |
| 249 | +/** |
| 250 | + * Returns the user fonts directory for the current platform. |
| 251 | + * This method can be overridden to customize the user font |
| 252 | + * installation location or to support additional platforms. |
| 253 | + */ |
| 254 | +- (NSString *) userFontsDirectory; |
| 255 | + |
| 256 | +/** |
| 257 | + * Returns the options that were specified when creating this downloader. |
| 258 | + */ |
| 259 | +- (NSUInteger) options; |
| 260 | + |
| 261 | +/** |
| 262 | + * Shows a progress panel for font downloading when NSFontAssetRequestOptionUsesStandardUI is set. |
| 263 | + * This method creates and displays a modal panel with a progress indicator and status text. |
| 264 | + */ |
| 265 | +- (void) showProgressPanelWithMessage: (NSString *)message; |
| 266 | + |
| 267 | +/** |
| 268 | + * Updates the progress panel with current status and progress value. |
| 269 | + * The progress parameter should be a value between 0.0 and 1.0. |
| 270 | + */ |
| 271 | +- (void) updateProgressPanel: (double)progress withMessage: (NSString *)message; |
| 272 | + |
| 273 | +/** |
| 274 | + * Hides and releases the progress panel. |
| 275 | + */ |
| 276 | +- (void) hideProgressPanel; |
| 277 | + |
| 278 | +/** |
| 279 | + * Action method called when the cancel button in the progress panel is pressed. |
| 280 | + */ |
| 281 | +- (void) cancelDownload: (id)sender; |
| 282 | + |
| 283 | +@end |
| 284 | + |
| 285 | +#endif /* GS_API_MACOSX */ |
| 286 | + |
| 287 | +#endif /* _GSFontAssetDownloader_h_GNUSTEP_GUI_INCLUDE */ |
0 commit comments