-
Notifications
You must be signed in to change notification settings - Fork 109
Add NSFontAssetRequest implementation #361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
gcasa
wants to merge
34
commits into
master
Choose a base branch
from
NSFontAssetRequest_branch
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
da8e28f
Add NSFontAssetRequest implementation
gcasa bb5f649
Use older NS_HANDLER syntax
gcasa 09b7725
Add downloader as a separate class
gcasa 155b4c3
Add new files and update GNUmakefile
gcasa e6809cc
Add code to make it possible to replace the downloader
gcasa 817fedd
Comment out unsupported method calls against setLocalizedAdditionalDe…
gcasa 82ec9c0
Comment out unsupported method calls against setLocalizedAdditionalDe…
gcasa 3b23423
Add localized update
gcasa 421ba9f
Cleanup whitespace, indentation, etc
gcasa 405b59a
Add code to parse the JSON
gcasa e4406ef
Cleanup
gcasa 4e0b340
Correct download URL logic
gcasa eb88491
Prefer truetype/ttf fix download logic
gcasa bcb44c3
Clean up merge
gcasa dd91b86
Clean up and include NSProgress for the @protocol
gcasa 1d40405
Add panel to the Font downloader
gcasa 57c27ea
Remove demo method
gcasa 95c1748
Use the font name, clean it up as the file name that gets saved
gcasa 23179e4
White space and indentation cleanup
gcasa 20fd12a
Add semicolon after NS_ENDHANDLER so that indentation is proper after
gcasa 5d6c9d5
Fix indentation and whitespace issues
gcasa bb50457
Refresh font after download
gcasa 329b1cf
Update with methods to refresh
gcasa 71e04fd
Move GNUstep specific stuff to a category
gcasa 88ec32c
Move methods that are specific to GNUstep to a category
gcasa 26244ab
Move RELEASE to the proper place
gcasa 5bc90bd
Update Source/NSFontAssetRequest.m
gcasa a4c2338
Update Source/NSFontAssetRequest.m
gcasa 89b5ad0
Update Source/GSFontAssetDownloader.m
gcasa 4c5a628
Update Source/GSFontAssetDownloader.m
gcasa 7ac3eb0
Update Source/GSFontAssetDownloader.m
gcasa c3dd964
Update Headers/Additions/GNUstepGUI/GSFontAssetDownloader.h
gcasa d050945
Use older exception handling instead of @try/@catch
gcasa eca7f1e
Change ifdef so that UNIX systems (aside from macOS) use standard dir
gcasa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,287 @@ | ||
/* Definition of class GSFontAssetDownloader | ||
Copyright (C) 2024 Free Software Foundation, Inc. | ||
|
||
By: Gregory John Casamento <[email protected]> | ||
Date: September 5, 2024 | ||
|
||
This file is part of the GNUstep Library. | ||
|
||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
|
||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
Lesser General Public License for more details. | ||
|
||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free | ||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
Boston, MA 02110 USA. | ||
*/ | ||
|
||
#ifndef _GSFontAssetDownloader_h_GNUSTEP_GUI_INCLUDE | ||
#define _GSFontAssetDownloader_h_GNUSTEP_GUI_INCLUDE | ||
#import <AppKit/AppKitDefines.h> | ||
|
||
#import <Foundation/NSObject.h> | ||
#import <Foundation/NSError.h> | ||
|
||
@class NSFontDescriptor; | ||
@class NSURL; | ||
@class NSString; | ||
@class NSPanel; | ||
@class NSProgressIndicator; | ||
@class NSTextField; | ||
@class NSButton; | ||
|
||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_13, GS_API_LATEST) | ||
|
||
/** | ||
* GSFontAssetDownloader provides a pluggable mechanism for downloading | ||
* and installing font assets from various sources. This class can be | ||
* subclassed to implement custom font downloading strategies, such as | ||
* downloading from different font services, using authentication, or | ||
* implementing custom validation and installation procedures. | ||
* | ||
* The default implementation supports downloading fonts from HTTP/HTTPS | ||
* URLs and local file URLs, with basic validation and cross-platform | ||
* installation to standard font directories. | ||
* | ||
* Subclasses can override individual methods to customize specific | ||
* aspects of the download and installation process while reusing | ||
* other parts of the default implementation. | ||
* | ||
* CLASS REPLACEMENT SYSTEM: | ||
* | ||
* GSFontAssetDownloader supports a class replacement system that allows | ||
* applications to register a custom downloader class to be used globally. | ||
* This enables complete customization of font downloading behavior without | ||
* needing to modify every NSFontAssetRequest instance. | ||
* | ||
* Example usage: | ||
* | ||
* // Define a custom downloader class | ||
* @interface MyCustomFontDownloader : GSFontAssetDownloader | ||
* @end | ||
* | ||
* @implementation MyCustomFontDownloader | ||
* - (NSURL *) fontURLForDescriptor: (NSFontDescriptor *)descriptor { | ||
* // Custom URL resolution logic | ||
* return [NSURL URLWithString: @"https://my-font-service.com/..."]; | ||
* } | ||
* @end | ||
* | ||
* // Register the custom class globally | ||
* [GSFontAssetDownloader setDefaultDownloaderClass: [MyCustomFontDownloader class]]; | ||
* | ||
* // Or through NSFontAssetRequest | ||
* [NSFontAssetRequest setDefaultDownloaderClass: [MyCustomFontDownloader class]]; | ||
* | ||
* // All new font asset requests will now use the custom downloader | ||
* NSFontAssetRequest *request = [[NSFontAssetRequest alloc] | ||
* initWithFontDescriptors: descriptors options: 0]; | ||
* | ||
* PROGRESS PANEL USAGE: | ||
* | ||
* To show a progress panel during font download, use the NSFontAssetRequestOptionUsesStandardUI option: | ||
* | ||
* NSFontDescriptor *descriptor = [NSFontDescriptor fontDescriptorWithName: @"Inconsolata" size: 12]; | ||
* GSFontAssetDownloader *downloader = [GSFontAssetDownloader downloaderWithOptions: NSFontAssetRequestOptionUsesStandardUI]; | ||
* NSError *error = nil; | ||
* BOOL success = [downloader downloadAndInstallFontWithDescriptor: descriptor error: &error]; | ||
* | ||
* The progress panel will automatically appear with: | ||
* - A progress bar showing download/installation progress | ||
* - Status messages describing the current operation | ||
* - A cancel button (posts GSFontAssetDownloadCancelled notification when pressed) | ||
*/ | ||
GS_EXPORT_CLASS | ||
@interface GSFontAssetDownloader : NSObject | ||
{ | ||
NSUInteger _options; | ||
NSPanel *_progressPanel; | ||
NSProgressIndicator *_progressIndicator; | ||
NSTextField *_statusLabel; | ||
NSButton *_cancelButton; | ||
} | ||
|
||
/** | ||
* Registers a custom downloader class to be used instead of the default | ||
* GSFontAssetDownloader class. The registered class must be a subclass | ||
* of GSFontAssetDownloader. Pass nil to restore the default behavior. | ||
*/ | ||
+ (void) setDefaultDownloaderClass: (Class)downloaderClass; | ||
|
||
/** | ||
* Returns the currently registered downloader class, or GSFontAssetDownloader | ||
* if no custom class has been registered. | ||
*/ | ||
+ (Class) defaultDownloaderClass; | ||
|
||
/** | ||
* Creates a new font asset downloader instance using the currently | ||
* registered downloader class. This is the preferred method for creating | ||
* downloader instances as it respects any custom downloader class that | ||
* has been registered. | ||
*/ | ||
+ (instancetype) downloaderWithOptions: (NSUInteger)options; | ||
|
||
/** | ||
* Creates a new font asset downloader with the specified options. | ||
* The options parameter contains flags that control the download | ||
* and installation behavior, such as whether to use standard UI | ||
* or install to user vs system directories. | ||
*/ | ||
- (instancetype) initWithOptions: (NSUInteger)options; | ||
|
||
/** | ||
* Downloads and installs a font from the specified descriptor. | ||
* This is the main entry point for font downloading. The method | ||
* orchestrates the complete process: URL resolution, download, | ||
* validation, and installation. Returns YES if the font was | ||
* successfully downloaded and installed, NO otherwise. | ||
*/ | ||
- (BOOL) downloadAndInstallFontWithDescriptor: (NSFontDescriptor *)descriptor | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Downloads and installs a font from the specified descriptor with a preferred format. | ||
* This variant allows specifying the preferred font format (e.g., "woff2", "woff", "ttf") | ||
* when downloading from CSS URLs. For direct font URLs, the format parameter is ignored. | ||
* Returns YES if the font was successfully downloaded and installed, NO otherwise. | ||
*/ | ||
- (BOOL) downloadAndInstallFontWithDescriptor: (NSFontDescriptor *)descriptor | ||
preferredFormat: (NSString *)format | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Resolves a font URL from a font descriptor. | ||
* This method can be overridden to implement custom URL resolution | ||
* strategies, such as querying different font services or using | ||
* authentication tokens. The default implementation looks for a | ||
* custom URL attribute or constructs URLs from font names. | ||
*/ | ||
- (NSURL *) fontURLForDescriptor: (NSFontDescriptor *)descriptor; | ||
|
||
/** | ||
* Downloads a font file from the specified URL. | ||
* This method can be overridden to implement custom download | ||
* strategies, such as using authentication, custom headers, or | ||
* progress callbacks. Returns the path to the downloaded temporary | ||
* file, or nil on failure. | ||
*/ | ||
- (NSString *) downloadFontFromURL: (NSURL *)fontURL | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Downloads a font file from the specified URL with a given font name. | ||
* This variant allows specifying the font name for better filename generation. | ||
* The downloaded file will be saved with a name based on the font name and | ||
* appropriate extension. Returns the path to the downloaded temporary file, | ||
* or nil on failure. | ||
*/ | ||
- (NSString *) downloadFontFromURL: (NSURL *)fontURL | ||
fontName: (NSString *)fontName | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Extracts font URLs from CSS content based on the specified format. | ||
* This method parses CSS @font-face declarations and extracts URLs | ||
* that match the given format (e.g., "woff2", "woff", "ttf"). | ||
* Returns an array of NSURL objects, or nil on error. | ||
*/ | ||
- (NSArray *) extractFontURLsFromCSS: (NSString *)cssContent | ||
withFormat: (NSString *)format | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Downloads font data from a CSS URL that contains @font-face declarations. | ||
* This method first downloads the CSS content, parses it to extract font URLs | ||
* based on the specified format, and then downloads the first matching font. | ||
* Returns the path to the downloaded temporary file, or nil on failure. | ||
*/ | ||
- (NSString *) downloadFontDataFromCSSURL: (NSURL *)cssURL | ||
withFormat: (NSString *)format | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Downloads font data from a CSS URL with a given font name. | ||
* This variant allows specifying the font name for better filename generation. | ||
* The downloaded file will be saved with a name based on the font name and | ||
* appropriate extension. Returns the path to the downloaded temporary file, | ||
* or nil on failure. | ||
*/ | ||
- (NSString *) downloadFontDataFromCSSURL: (NSURL *)cssURL | ||
withFormat: (NSString *)format | ||
fontName: (NSString *)fontName | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Validates a downloaded font file. | ||
* This method can be overridden to implement custom validation | ||
* logic, such as checking font metadata, licensing information, | ||
* or performing security scans. The default implementation | ||
* checks file existence, size, and format signatures. | ||
*/ | ||
- (BOOL) validateFontFile: (NSString *)fontPath | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Installs a font file to the appropriate system location. | ||
* This method can be overridden to implement custom installation | ||
* strategies, such as using system APIs, registering with font | ||
* management services, or applying custom permissions. Returns | ||
* YES if installation was successful, NO otherwise. | ||
*/ | ||
- (BOOL) installFontAtPath: (NSString *)fontPath | ||
error: (NSError **)error; | ||
|
||
/** | ||
* Returns the system fonts directory for the current platform. | ||
* This method can be overridden to customize the system font | ||
* installation location or to support additional platforms. | ||
*/ | ||
- (NSString *) systemFontsDirectory; | ||
|
||
/** | ||
* Returns the user fonts directory for the current platform. | ||
* This method can be overridden to customize the user font | ||
* installation location or to support additional platforms. | ||
*/ | ||
- (NSString *) userFontsDirectory; | ||
|
||
/** | ||
* Returns the options that were specified when creating this downloader. | ||
*/ | ||
- (NSUInteger) options; | ||
|
||
/** | ||
* Shows a progress panel for font downloading when NSFontAssetRequestOptionUsesStandardUI is set. | ||
* This method creates and displays a modal panel with a progress indicator and status text. | ||
*/ | ||
- (void) showProgressPanelWithMessage: (NSString *)message; | ||
|
||
/** | ||
* Updates the progress panel with current status and progress value. | ||
* The progress parameter should be a value between 0.0 and 1.0. | ||
*/ | ||
- (void) updateProgressPanel: (double)progress withMessage: (NSString *)message; | ||
|
||
/** | ||
* Hides and releases the progress panel. | ||
*/ | ||
- (void) hideProgressPanel; | ||
|
||
/** | ||
* Action method called when the cancel button in the progress panel is pressed. | ||
*/ | ||
- (void) cancelDownload: (id)sender; | ||
|
||
@end | ||
|
||
#endif /* GS_API_MACOSX */ | ||
|
||
#endif /* _GSFontAssetDownloader_h_GNUSTEP_GUI_INCLUDE */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
|
||
Author: Adam Fedor <[email protected]> | ||
Date: Mar 2000 | ||
|
||
This file is part of the GNUstep. | ||
|
||
This library is free software; you can redistribute it and/or | ||
|
@@ -22,8 +22,8 @@ | |
|
||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; see the file COPYING.LIB. | ||
If not, see <http://www.gnu.org/licenses/> or write to the | ||
Free Software Foundation, 51 Franklin Street, Fifth Floor, | ||
If not, see <http://www.gnu.org/licenses/> or write to the | ||
Free Software Foundation, 51 Franklin Street, Fifth Floor, | ||
Boston, MA 02110-1301, USA. | ||
*/ | ||
|
||
|
@@ -48,18 +48,26 @@ APPKIT_EXPORT_CLASS | |
|
||
+ (void) setDefaultClass: (Class)defaultClass; | ||
+ (GSFontEnumerator*) sharedEnumerator; | ||
|
||
// Font enumeration and caching | ||
- (void) enumerateFontsAndFamilies; | ||
- (void) refreshFontCache; | ||
|
||
// Querying available fonts | ||
- (NSArray*) availableFonts; | ||
- (NSArray*) availableFontFamilies; | ||
- (NSArray*) availableMembersOfFontFamily: (NSString*)family; | ||
- (NSArray*) availableFontDescriptors; | ||
|
||
// Font matching and searching | ||
- (NSArray *) availableFontNamesMatchingFontDescriptor: (NSFontDescriptor *)descriptor; | ||
- (NSArray *) matchingFontDescriptorsFor: (NSDictionary *)attributes; | ||
- (NSArray *) matchingDescriptorsForFamily: (NSString *)family | ||
options: (NSDictionary *)options | ||
inclusion: (NSArray *)queryDescriptors | ||
exculsion: (NSArray *)exclusionDescriptors; | ||
|
||
// Default system font names (called once, backends may override) | ||
/* Note that these are only called once. NSFont will remember the returned | ||
values. Backends may override these. */ | ||
- (NSString *) defaultSystemFontName; | ||
|
@@ -97,7 +105,7 @@ APPKIT_EXPORT_CLASS | |
NSFontDescriptor *fontDescriptor; | ||
} | ||
|
||
+ (GSFontInfo*) fontInfoForFontName: (NSString*)fontName | ||
+ (GSFontInfo*) fontInfoForFontName: (NSString*)fontName | ||
matrix: (const CGFloat*)fmatrix | ||
screenFont: (BOOL)screenFont; | ||
+ (void) setDefaultClass: (Class)defaultClass; | ||
|
@@ -132,22 +140,22 @@ APPKIT_EXPORT_CLASS | |
- (NSSize) minimumAdvancement; | ||
- (NSStringEncoding) mostCompatibleStringEncoding; | ||
- (NSUInteger) numberOfGlyphs; | ||
- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph | ||
forCharacter: (unichar)aChar | ||
- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph | ||
forCharacter: (unichar)aChar | ||
struckOverRect: (NSRect)aRect; | ||
- (NSPoint) positionOfGlyph: (NSGlyph)curGlyph | ||
precededByGlyph: (NSGlyph)prevGlyph | ||
isNominal: (BOOL*)nominal; | ||
- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph | ||
struckOverGlyph: (NSGlyph)baseGlyph | ||
- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph | ||
struckOverGlyph: (NSGlyph)baseGlyph | ||
metricsExist: (BOOL *)flag; | ||
- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph | ||
struckOverRect: (NSRect)aRect | ||
- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph | ||
struckOverRect: (NSRect)aRect | ||
metricsExist: (BOOL *)flag; | ||
- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph | ||
withRelation: (NSGlyphRelation)relation | ||
- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph | ||
withRelation: (NSGlyphRelation)relation | ||
toBaseGlyph: (NSGlyph)baseGlyph | ||
totalAdvancement: (NSSize *)offset | ||
totalAdvancement: (NSSize *)offset | ||
metricsExist: (BOOL *)flag; | ||
- (NSFontTraitMask) traits; | ||
- (CGFloat) underlinePosition; | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.