Skip to content

feat: Added Support for Fonts #1259

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
wants to merge 6 commits into
base: flutter_app
Choose a base branch
from

Conversation

Vishveshwara
Copy link
Contributor

@Vishveshwara Vishveshwara commented Mar 26, 2025

Fixes #239
Fixes #1134

Changes

  • Created a Drop Down Menu with 7 google Fonts ('Roboto','Open Sans','Lato', 'Poppins','Montserrat','Orbitron', 'Lexend')
  • Optimized for characters exceeding the 11x8 grid by combining two characters into an 11x16 layout.
  • Dynamically adjusted height to ensure that characters with descenders, such as 'p' and 'q', are fully visible on the screen.
  • Enabled effortless font expansion by simply adding new entries to the FontProvider.
  • Guaranteed full compatibility with existing emojis while preserving the default font setting for a consistent user experience.

Screenshots / Recordings

Font.Support.mp4

Checklist:

  • No hard coding: I have used resources from constants.dart without hard coding any value.
  • No end of file edits: No modifications done at end of resource files.
  • Code reformatting: I have reformatted code and fixed indentation in every file included in this pull request.
  • Code analyzation: My code passes analyzations run in flutter analyze and tests run in flutter test.

Summary by Sourcery

Add support for custom fonts in the badge display, allowing users to select from a predefined list of Google Fonts and dynamically render text with improved character rendering

New Features:

  • Implemented a dropdown menu to select from 7 different Google Fonts
  • Added dynamic font rendering that supports characters with descenders
  • Created a flexible font system that can easily expand with new font options

Enhancements:

  • Optimized text rendering for LED matrix display
  • Implemented intelligent character scaling for wide characters
  • Added dynamic height adjustment for characters with descenders

Copy link
Contributor

sourcery-ai bot commented Mar 26, 2025

Reviewer's Guide by Sourcery

This pull request introduces support for custom fonts in the application. It adds a dropdown menu to select from a list of Google Fonts, and implements the logic to render text using the selected font. The implementation includes handling characters with descenders and optimizing for characters that exceed the grid size.

Sequence diagram for rendering text with a custom font

sequenceDiagram
    participant User
    participant HomeScreen
    participant FontProvider
    participant Converters

    User->>HomeScreen: Enters text and selects font
    HomeScreen->>FontProvider: changeFont(newFont)
    FontProvider-->>HomeScreen: Notifies listeners
    HomeScreen->>Converters: messageTohex(message, isInverted)
    Converters->>FontProvider: get selectedTextStyle
    Converters->>Converters: _processCustomFontChar(char, style)
    Converters-->>HomeScreen: Returns hex strings
    HomeScreen->>HomeScreen: Updates badge with new font
Loading

File-Level Changes

Change Details Files
Added a dropdown menu for selecting Google Fonts.
  • Integrated a dropdown menu in the UI.
  • Populated the dropdown with a list of available Google Fonts.
  • Implemented logic to update the selected font based on user selection.
  • Added a FontProvider to manage the selected font and available fonts.
lib/view/homescreen.dart
lib/providers/font_provider.dart
lib/main.dart
lib/providers/getitlocator.dart
Implemented text rendering using the selected font.
  • Created a function to render text into a matrix of boolean values representing the pixels of the text.
  • Implemented logic to handle characters with descenders, ensuring they are fully visible.
  • Optimized rendering for wide characters by combining two characters into a larger grid.
  • Added logic to preserve compatibility with existing emojis by using the default font when rendering emojis.
lib/bademagic_module/utils/converters.dart

Assessment against linked issues

Issue Objective Addressed Explanation
#239 Implement an option to change the font of the text.
#1134 Add support for selecting and using different fonts in the badge preview.
#1134 Ensure the selected font is transferred to the badge itself.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Vishveshwara - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider extracting the font rendering logic into a separate widget for better reusability and testability.
  • The _processCustomFontChar function has hardcoded character checks; consider using a more data-driven approach.
Here's what I looked at during the review
  • 🟡 General issues: 1 issue found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 141 to 148
bool hasDescender = false;
if (char == "y" ||
char == "g" ||
char == "p" ||
char == "q" ||
char == "j") {
hasDescender = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Simplify the descender character check.

Rather than checking each character individually (e.g. 'y', 'g', etc.), consider using a Set and a single contains check for better readability and easier maintenance.

Suggested change
bool hasDescender = false;
if (char == "y" ||
char == "g" ||
char == "p" ||
char == "q" ||
char == "j") {
hasDescender = true;
}
final descenders = {'y', 'g', 'p', 'q', 'j'};
bool hasDescender = descenders.contains(char);

@samruddhi-Rahegaonkar
Copy link
Contributor

@Vishveshwara Thanks for working !
just few changes the selected fonts should also display on the textfield area. and also noticed one thing there are inconsistent pixel distances between the characters which we don't want. after each character their should have only the distance of a 1 pixel. Please go through the code once and check it.

@Vishveshwara
Copy link
Contributor Author

@samruddhi-Rahegaonkar The issue with spacing of characters is due to the width of characters like "w","h","m" which does not fit in 11x8 grid which is the size we are using for the default font. so for now , I have written a code in which a wide character can occupy 11x16 grid and hence the character does not get cut off but the character occupies double the space.

app.vid.mp4

the Solutions for this issue:

  1. Using a smaller font (But causes poor visibility of text. Currently I am using font size 16, font size 14 seems to be fine but still has the spacing issue and anything lower is a problem)
  2. use 11x16 grid for all the characters (but the space between characters is very big, can be good for very wide fonts).
  3. using a variable grid dimension based on the character width (Best possible solution, but would need a different pipeline from how we are processing the text now)

I will try to work on this, @Jhalakupadhyay can you guide me on which possible solution would be the best

@samruddhi-Rahegaonkar
Copy link
Contributor

@Vishveshwara That’s a good temporary fix, but it introduces an inconsistency where some characters take double the space, breaking uniform alignment.

@samruddhi-Rahegaonkar
Copy link
Contributor

@Vishveshwara you might try
Scale down wide characters to fit within 11x8 without cutting off.

@Jhalakupadhyay
Copy link
Contributor

@Vishveshwara nice going but there are few changes needed.

  1. as suggested by @samruddhi-Rahegaonkar the font should also change in the textfield.
  2. Try to maintain a cache for the characters already render such that we don't need to process the characters whose hex is already generated once this will increase the speed of our solution
  3. Let's try scalling down the characters to fit into 11x8 grid and see how it looks I think it will be good option.

I will look closely to PR once and then can tell you better, but we can go for the above changes first.

@Vishveshwara
Copy link
Contributor Author

Vishveshwara commented Apr 1, 2025

font_support.mp4

Challenges

  • scaling down the characters to fit into 11x8 grid , makes the characters unreadable so I had to go with the variable column solution

@Jhalakupadhyay @adityastic please review this PR.

Changes

  1. Added Consistent spacing between characters by using variable columns for each character( for example 'i' uses 3 columns and 'W' uses 12 columns).
  2. Added Caching for all the fonts currently, and added a feature to generate cache in settings screen for newer fonts.
  3. Cache is currently stored as a 2d Binary Bool array.
  4. Font changes in the text field.

@adityastic
Copy link
Collaborator

Why do we have 13k loc changed?

Copy link
Collaborator

@adityastic adityastic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need 13k lines to have font support in our app.

@Vishveshwara
Copy link
Contributor Author

Vishveshwara commented Apr 9, 2025

I don't think we need 13k lines to have font support in our app.

@Vishveshwara nice going but there are few changes needed.

  1. as suggested by @samruddhi-Rahegaonkar the font should also change in the textfield.
  2. Try to maintain a cache for the characters already render such that we don't need to process the characters whose hex is already generated once this will increase the speed of our solution
  3. Let's try scalling down the characters to fit into 11x8 grid and see how it looks I think it will be good option.

I will look closely to PR once and then can tell you better, but we can go for the above changes first.

@adityastic
The 13k lines are a result of caching font characters as 2d bool matrices in lib/badgemagic_module/utils/font_cache.dart. As suggested by Jhalak, I implemented a caching mechanism to avoid regenerating character matrices repeatedly.

@adityastic
Copy link
Collaborator

I don't think we need 13k lines to have font support in our app.

@Vishveshwara nice going but there are few changes needed.

  1. as suggested by @samruddhi-Rahegaonkar the font should also change in the textfield.
  2. Try to maintain a cache for the characters already render such that we don't need to process the characters whose hex is already generated once this will increase the speed of our solution
  3. Let's try scalling down the characters to fit into 11x8 grid and see how it looks I think it will be good option.

I will look closely to PR once and then can tell you better, but we can go for the above changes first.

@adityastic
The 13k lines are a result of caching font characters as 2d bool matrices in lib/badgemagic_module/utils/font_cache.dart. As suggested by Jhalak, I implemented a caching mechanism to avoid regenerating character matrices repeatedly.

I don't think he meant caching it directly in the repository 😅

@Vishveshwara
Copy link
Contributor Author

Vishveshwara commented Apr 9, 2025

I don't think he meant caching it directly in the repository 😅

@adityastic

I'm sorry for the confusion. I noticed that the default font was being cached in "lib/badgemagic_module/utils/data_to_bytearray_converter.dart", and so I assumed it was acceptable to cache them directly. However, I understand that this might not be the ideal approach. The code can work without caching as well, so I would appreciate your guidance on where the best place to cache these characters would be.

@adityastic
Copy link
Collaborator

I don't think he meant caching it directly in the repository 😅

@adityastic

I'm sorry for the confusion. I noticed that the default font was being cached in "lib/badgemagic_module/utils/data_to_bytearray_converter.dart", and so I assumed it was acceptable to cache them directly. However, I understand that this might not be the ideal approach. The code can work without caching as well, so I would appreciate your guidance on where the best place to cache these characters would be.

We should cache every character in memory while conversation is being performed and reuse the character or the subset if we see repeated entries to improve execution time. That's all to it I guess. Let me know if you have any other thoughts.

@Vishveshwara
Copy link
Contributor Author

Vishveshwara commented Apr 10, 2025

I don't think he meant caching it directly in the repository 😅

@adityastic
I'm sorry for the confusion. I noticed that the default font was being cached in "lib/badgemagic_module/utils/data_to_bytearray_converter.dart", and so I assumed it was acceptable to cache them directly. However, I understand that this might not be the ideal approach. The code can work without caching as well, so I would appreciate your guidance on where the best place to cache these characters would be.

We should cache every character in memory while conversation is being performed and reuse the character or the subset if we see repeated entries to improve execution time. That's all to it I guess. Let me know if you have any other thoughts.

@adityastic
I've implemented the character caching as you suggested. Please review it, whenever you are available.

@Vishveshwara Vishveshwara requested a review from adityastic April 10, 2025 13:27
@Vishveshwara
Copy link
Contributor Author

Vishveshwara commented May 18, 2025

@adityastic can you please review this pr? I have done the changes you have mentioned.

Copy link
Contributor

Build Status

Build successful. APKs to test: https://github.com/fossasia/badgemagic-app/actions/runs/15227284094/artifacts/3190499738.

Screenshots (Android)

Screenshots (iPhone)

Screenshots (iPad)

@Vishveshwara
Copy link
Contributor Author

@nope3472 i have read your scrum update, as you are working on the font change feature , you can check this PR out and mention your comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for fonts Implement Option to Change Font
4 participants