-
Notifications
You must be signed in to change notification settings - Fork 103
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
Color fonts support #1799
base: master
Are you sure you want to change the base?
Color fonts support #1799
Conversation
and ClearFallbackFonts.
can still sometimes have it's own priorities.
This is only safe to do on recent fontconfig versions.
ReallocAtlases for that since it's aimed at something different.
// set render size | ||
if ((error = FT_Set_Pixel_Sizes(face, 0, size)) != 0) { | ||
if (!FT_IS_SCALABLE(facePtr->face) && facePtr->face->num_fixed_sizes >= 1) | ||
size = static_cast<unsigned int>(facePtr->face->available_sizes[0].y_ppem / 64.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does the magic 64 represent, and do we need double precision (i.e. 64.0
instead of 64.0f
) if it gets cast to int afterwards? consider static constexpr auto SOME_DESCRIPTIVE_NAME = 64.0f
@@ -575,10 +638,18 @@ CFontTexture::CFontTexture(const std::string& fontfile, int size, int _outlinesi | |||
|
|||
static constexpr int FT_INTERNAL_DPI = 64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps the magic constant in the review comment above is actually FT_INTERNAL_DPI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes it's that same one, i'll move that somewhere else so I can also use it
// don't preload for non alphanumeric | ||
if (!FT_Get_Char_Index(face, 65)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment sounds a bit like we didn't want to preload alphanumeric glyphs, which reverses the meaning (as far as i understand). Also could use an alphanumeric char explicitly:
// don't preload for non alphanumeric | |
if (!FT_Get_Char_Index(face, 65)) | |
// if given face doesn't contain alphanumerics, don't preload it | |
if (!FT_Get_Char_Index(face, 'a')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're right, wanted to say dont preload for non-alphanumeric fonts, but it can be misintrepreted
also, sorry this sneaked in... didn't really mean to add this part inside this PR, I think I'll move that to a separate PR ... I think that'd be great to have for next release, while color fonts don't think will make it.
in any case I'll follow your suggestion
glyphs.clear(); | ||
|
||
// clear atlases | ||
ClearAtlases(32, 32); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why 32?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's the same values initialization uses for CreateTexture
} | ||
} else if (src.channels == 1 && channels == 4 && dts == 1 && src.GetDataTypeSize() == 1) { | ||
// set rgb to 255 and alpha to src tex value | ||
constexpr uint32_t baseColor = ((255<<16)|(255<<8)|(255)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this depend on the color format? e.g. with RGBA vs ARGB you'd have <<24, <<16 and <<8 instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, will check for that as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This should become a generic
BitmapAction
. - I don't think we need to support anything but
RGBA
inCBitmap
, if it's ARGB or other abracadabra then it's up for a caller to normalize it, or do another Bitmap/BitmapAction routine to shuffle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lhog we can introduce more actions for this (like CopyConvertSubImage), and have CopySubImage work only for same format bitmaps. But using several actions when you can use one I'm not so sure it's best, in many cases if you can do it in just one action it's going to be more direct and likely more efficient.
For example when copying RGBA to BGRA or ARGB, you can shuffle first and then CopySubImage, but with the right algo it can be done in one go.
Likewise, in this case we're doing Grayscale to RGBA/BGRA where something similar happens, the Grayscale can be converted first to color, but here it's converted and the result placed directly at destination.
Let me know your final decision and I'll resolve this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what's the problem here, CBitmap doesn't have a pixel format field :P, so it knows nothing of RGBA vs ARGB (or RGBA vs BGRA, but that's not really an issue here).
Also, the CBitmap class has other actions/methods expecting alpha in the same place.
It does support 4 and 1 channels, so imo it should be fine to allow CBitmap(4channels).CopySubimage(cbitmap(1channel)) like I'm doing, at least while a more comprehensive solution for this is developed (I think an action system supporting two bitmaps with specific pixel formats could be designed so we can select the right action when two bitmaps are combined with different pixel formats).
So, supporting ARGB probably atm not worth it since CBitmap is RGBA only, and since destination is usually opengl, the channels can always be swizzled there. Maybe the need arises later on, but for now just RGBA/BGRA can be supported implicitly as is now and call it a day.
Co-authored-by: sprunk <[email protected]>
if (slot->bitmap.pitch != width) { | ||
LOG_L(L_ERROR, "invalid pitch"); | ||
if (slot->bitmap.pitch != width*channels) { | ||
LOG_L(L_ERROR, "invalid pitch %d (width %d channels %d)", slot->bitmap.pitch, width, channels); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm two concerns:
- pitch | its absolute value is the number of bytes per bitmap line; it can be either positive or negative depending on the bitmap's vertical orientation;
- To speed up memory access, pitch is in most cases a multiple of 16bit, 32bit, or even 64bit. It often happens that the pitch is thus larger than the necessary bits (or bytes) for a bitmap or pixmap row; in such cases, unused bits (or bytes) are at the very right (i.e., the end) of a row.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lhog, you're right, but also I think the test we're doing here holds, since in those cases it will complain about the non-matching pitch.
Maybe in that case we could bail out instead of just continuing, but just continue is the same logic we had here before, so I just adapted the test to also work on the four channels case similarly, but otherwise didn't change it. As I understood, the test is an alert in case we even encounter that issue, but it's also an issue that didn't pop up yet.
Personally, would rather keep as-is and later work on this to make it bail out in a separate PR if we want to have that, or see that's an issue, or even support the negative pitch or pitch!=width*channels
cases (to not complicate this PR further).
Also note the case where pitch!=width*channels
is easy to support although maybe not optimal through FT_Bitmap_Convert
Will need to test on AMD/Windows in various Recoil games. |
Indeed, also windows in general since it's yet untested there so even with nvidia there could be some unforeseen problem. |
always true, as intended.
Work done
Remarks
It's based on another branch, so here is a direct link to code comparison between lua-fallback-fonts-with-atlasclear and colored-fonts.
Implementation
Testing
After