Git Product home page Git Product logo

rfont's Issues

Very odd 'X' coordinate spacing for a few letters using a Helvetica font

Text using the Helvetica font in RFont usually looks fine, however in some instances some letters have very odd spacing that makes them look very awkward compared to the rest of the string. In the example below you can see that happening with the letter 'v', where it's off by a few pixels:
image

Using LibreOffice Writer, this is how I expect the text to look more or less:
image

And it isn't only with 'v'. "Button" suffers from the same issue, alongside many other random combinations of words.
image

Render Background gets overwritten?

Hello, Im using RFont with GLFW and Glad (openGL 3.3) when I render my Font the Background gets set to black, and everything I render afterwards (like draw cycles, rectangles and so on) is not beeing displayed. If I place the draw text before my other render stuff, only the text with black background is displayed in the window ... and if i do my rendering first and then the text... its again just displayed the text on black background.

Is there a thing needs to done before? For example hook in the GLFW Context or the Glad RFont context pointer into Glad (like this GLFW load user pointer)?

Edit: Im doing Bindings right now, and not expericing it in a C example... so it should be a binding error i will look into that

A list of errors and suggestions

Introduction

This is a compilation of issues that I've noticed and had to deal with when developing siliapp and siliui. I bring this up because the text rendering for those libraries were partially based on RFont and as such, said mistakes in my libraries also exist within RFont.

Issue 1: No way of getting the correct height for text

Description

This is quite a huge issue in regards to using RFont for UIs. RFont assumes that the specified user's size is equivalent to the actual total height of the text, which is often not true for both English and especially international text. This can either result in A) some characters looking slightly awkward and too cramped or B) a very noticeable misalignment to appear when the text is suppose to be centered in a larger object.

Solution

RFont needs to do 2 things:

  • Update the Y advancement of a newline.
  • Update the return values of 'RFont_draw_textandRFont_text_width_len`

Currently RFont sets every newlines' vertical advancement to the user-specified size, which is only partially correct. The formula to calculate the actual line height is:

f32 newline = font.size * (-descent * font.scale)

descent is available when RFont is calculating font.scale, so implementing this wouldn't be difficult. Note that the newline should then be scaled down to the user-specified size for it to work properly.

To make sure that the issues of UI misalignment or cropping text doesn't appear, it is advisable to also provide the full height of the text alongside its width. It won't be too difficult to calculate it as all it would be is scaledNewline * (numOfNewLines + 1).

PS I've provided two screenshots of how long a newline should be using the Helvetica font, which were taken from the Kate text editor as well as from my siliapp library.

Code to reproduce the bug

void drawRectangle(RGFW_rect rect, int windowWidth, int windowHeight) {
    float x1 = 2.0f * rect.x / windowWidth - 1.0f;
    float y1 = 1.0f - 2.0f * rect.y / windowHeight;
    float x2 = 2.0f * (rect.x + rect.w) / windowWidth - 1.0f;
    float y2 = 1.0f - 2.0f * (rect.y + rect.h) / windowHeight;

    rglColor4f(0, 0, 0, 1);
    rglBegin(RGL_TRIANGLES_2D);
        rglVertex2f(x1, y1);
        rglVertex2f(x1, y2);
        rglVertex2f(x2, y2);

        rglVertex2f(x1, y1);
        rglVertex2f(x2, y2);
        rglVertex2f(x2, y1);
    rglEnd();
}
...
drawRectangle(RGFW_RECT(0, 0, 300, 60), win->r.w, win->r.h);
rglRenderBatch();
RFont_set_color(0.0f, 1.0f, 0, 1.0f);
RFont_draw_text(font, "jjabcdefghijklmnopqrstuvwxyz\nล ", 0, 0, 60);

Screenshots

Bug

image

Expected behaviour

image
image

Extras (Citation)

Issue 2: Advance width for space and tab

Description

According to the TrueType font specification, the space and horizontal tabulation are required to be set to a glyph with a positive advance:

  1. Each of the following characters must map to a glyph with no contours and positive advance width:
    0x0009 HORIZONTAL TABULATION
    ...
    0x0020 SPACE
    ...
  2. The following groups of characters must have the same width
    0x0009 (HORIZONTAL TABULATION) and 0x0020 (SPACE)

Currently RFont bases the space based on the user-specified size divided by four, which might not look good for every font.

Solution:

Implement the correct advance width for spaces and tabs when detected in a string.

Extras (Citation)

Suggestion 1: A small improvement for RFont_draw_text_len

Description

RFont_draw_text_len has a rather convoluted loop condition to take account the length if it isn't 0

   char* str;

   for (str = (char*)text; (len == 0 || (size_t)(str - text) < len) && *str; str++) {
         if (*str == '\n') {
         x = startX;
         y += size;
         continue;
      }

      if (*str == ' ' || *str == '\t') {
         x += (size / 4);
         continue;
      }
      ...

This works, but clearly is less than ideal. I would suggest that instead of this you would transform the start of the for loop into:

   const char* str = text;
   while ((str - text) < len) {
       char x = *str;
       str += 1;
       
       switch (x)  {
           case '\0': { ...; break; }
           case '\n': { ...; break; }
           case '\t':
           case ' ': { ...; break; }
       }
       ...
   }

And for the RFont_draw_text/RFont_draw_text_spacing functions, you would replace 0 with USIZE_MAX or some other equivalent that would give you the maximum value of size_t (((size_t)0 - 1) could work, but that's stingy). The ending result would be this:

size_t RFont_draw_text(RFont_font* font, const char* text, float x, float y, u32 size) {
   return RFont_draw_text_len(font, text, USIZE_MAX, x, y, size, 0.0f);
}

size_t RFont_draw_text_spacing(RFont_font* font, const char* text, float x, float y, u32 size, float spacing) {
   return RFont_draw_text_len(font, text, USIZE_MAX, x, y, size, spacing);
}

These few changes makes the code more clean and slightly more efficient, while also retaining the original intent in a different way.

PS This suggestion also applies to RFont_text_width.

stb_truetype CVEs?

If I understand correctly there are a number of internal offsets in the code that don't validate against the overall buffer size, so there isn't any robustness to unsafe data (which is why stb_truetype.h warns users about that in their comments.) I would imagine RFont has the same limitations, since it uses stb_truetype code? If so, I was wondering if there might be any plans to make RFont more robust by adding the offset validations?

Crashes when certain UTF-8 Text is sent

The library poorly renders the unsupported text and then crashes.

This text is "๐™ธ mฬตฬอ„eฬทฬ‰ฬ‹aฬดอ’ฬ‹nฬดฬ“ฬš ๐•ด ๐‘ช๐’‚๐’ ๐““๐“ธ ๐•‹๐•™๐•š๐•ค"

(Again, I will solve this issue, this is just here for organization's sake)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.