colleagueriley / rfont Goto Github PK
View Code? Open in Web Editor NEWSimple-to-use single header modular font rendering library written in C.
License: Other
Simple-to-use single header modular font rendering library written in C.
License: Other
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:
Using LibreOffice Writer, this is how I expect the text to look more or less:
And it isn't only with 'v'. "Button" suffers from the same issue, alongside many other random combinations of words.
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
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.
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.
RFont needs to do 2 things:
and
RFont_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.
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);
According to the TrueType font specification, the space and horizontal tabulation are required to be set to a glyph with a positive advance:
- Each of the following characters must map to a glyph with no contours and positive advance width:
0x0009 HORIZONTAL TABULATION
...
0x0020 SPACE
...- 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.
Implement the correct advance width for spaces and tabs when detected in a string.
RFont_draw_text_len
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
.
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?
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)
The texture for the fonts aren't rendering on windows, there are only rectangles being rendered.
Maybe this issue is related to how much memory the atlas is using?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.