-
Notifications
You must be signed in to change notification settings - Fork 37
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
Sync to latest (v8.5.0) #115
Conversation
Thank you! It's not everyday that my baby is not shat upon in this project. :))) Thank you for your impressive work. As you have noticed, shaping hasn't been changing much in recent years. So I'm hopeful that after your work, we can keep rustybuzz up to date moving forward. |
I've never ever meant to throw shade at It's obviously very impressive, the fact that the code is so difficult to "translate" to Rust is obviously not something you can control. 😄 That's just the unavoidable complexity of text shaping. |
Oh you never did!
I want to eg. address @RazrFalcon's repeated mention of heavy C++ template use in the codebase. What are we supposed to do? Eg. the AAT state-machines are used, in slightly different ways, in |
Jesus! You're insane! I thought there is still work for months. I'm incredibly happy that so many people helped with this project. I wouldn't be able to do it myself. From all of the projects I wrote, this one has the most amount of contributed code. |
This one? And probably this one.
Yes, let's ignore.
Hm... yes, sort of.
No need to.
Yes, we should. Moreover we already use |
Done! |
The problem is not the usage of templates themselves, but the way they are used. You use CRTP quite a lot (I hope that's the right term), aka
You have your own ranges, arrays, hash maps, atomics, mutex implementation, which doesn't help with understanding the code, since people have to learn a new API. And I'm not saying this as a random C++ hater. Which I am. I did worked as a C++ developer for nearly a decade. I seen bad and good codebases. You can write human-readable C++ code. Look at Qt or Skia. Yes, it's rare, but possible. "Performance optimizations" in general make HB codebase hard to read. Do we really need The other problem with HB is that it's basically C with classes with all the classic C cryptic nonsense. And I wish it to be more of "modern C++". Like what is this code?! bool use_cache = font->num_coords; why not: bool use_cache = font->has_non_default_variation_coords(); Why it has to be so cryptic? What about this? if (var_table.get_length ()) {} oh, it's actually suppose to be: if (!var_table.is_empty()) {} or even better: std::optional<hb_blob_ptr_t<V>> var_table_opt;
if (var_table_opt.has_value()) {}
// or even
if (auto var_table = var_table_opt) {} Why we have the ugly: _hb_glyph_info_is_default_ignorable (&info[i]) instead of human-readable: info[i].is_default_ignorable() Why we have hb_ot_position_default (const hb_ot_shape_context_t *c) {} instead of hb_ot_position_default (const hb_ot_shape_context_t &c) {} in a C++ codebase? Why pointers everywhere?! Why: if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) {} instead of if (!buffer->has_non_ascii()) This alone would improve the code readability immensely. How about some FP? This: unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
set_khmer_properties (info[i]); is effectively: buffer.info.for_each(set_khmer_properties); And I'm not even asking the impossible, like having a decent code auto-formatting. Like using spaces instead of tabs-with-spaces. Like always using And I can go forever... HB codebase can be improved (imho) so much by a simple refactoring.
I just think that some code is objectively bad. And yes, this includes most of my code as well. |
@LaurenzV I just read your readme update and I completely agree. Test coverage improvement and performance optimizations are the main goals from now. |
@behdad Looks like there is a bug in |
Looks like it. Filed a bug for that. Thanks. |
I know it's hard to believe, but there's a good reason for most of those... String-to-number: IIRC there's no portable way to convert numbers in a locale-independent way. glib does the same. Cairo does the same. I want C++ ranges and concepts, but they are prohibitively new. We have mutex & atomics, mostly from before C++11 standardized them. Now they are mostly a wrapper around std, except when that's not feasible. Re std use, HB started from the GNOME project where linking to std was not desirable. That might have changed, but last time I tried to pull in std hash-table I hit other issues, like having to link to libstd which is something we still have not decided to do. Re pointers around, again, it comes from HarfBuzz's roots as a C library. Yes, a lot can be cleaned up if we had more resources. We're no Skia team. Speaking of Skia, I always hated becoming like Skia: having my own implementation of everything, but HB ended up like Skia as you observe. It's not the first library I've seen to do that. There are valid reasons that you cannot use all the various goodies in std. std also has no good memory-efficient equivalent of
That's where it came from, yes. And it still exposes a fully C API, which puts certain limitations on the core types. There's also the limitation from Chromium that we cannot have ctor-initializers.
That sounds like something that can be improved, yes.
I find that ugly. It's your rust sense of beauty that sees it as an improvement.
Because
I learned C++ while developing HarfBuzz. There's a lot of Cism left, as you pointed out.
You're right according to most people. I find it ugly to have to add two methods for each enum value though. The former reads perfectly fine to me coming from C background of course.
Interesting that you have said you find Qt and Skia to be excellent codebases. But they also reinvent everything, and reading their code my head hurts with all the unnecessary abstractions and indirections. My goal always was to use a selected subset of C++ for HarfBuzz. That subset evolved over time, but still a subset. Anyway. I agree the biggest problem with this style is the barrier to entry. |
That's just C/C++ curse due to a lack of proper dependency management.
rustybuzz has nearly zero templates. Except for AAT, which is just a copy of HB logic. First thing I did during porting is got rid of most of macros. I hate them even more then templates. I'm one of few people who doesn't use them even in Rust.
Beauty is subjective, but compile time guarantees are not. Yes, Also, I find Rust to be super ugly, but that's not the point. And no, "std::optional has an overhead" is not an argument I will accept. After all, rustybuzz is 100% memory safe. That's what is important to me and everyone else.
Can't we have an internal struct with the same size and simply cast it when needed? It would be great to have C API completely separated from the implementation.
Which is hurting porting process a lot. Well, C++ templates magic do not help much either...
Most people have no idea what
I was talking about code style specifically. Yes, "Java of C++". All I wan't from harfbuzz is too look more like modern C++/Java and not like fossil C.
And every C++ project has its own subset one have to learn... I know it all sounds like a hate thread or a holy war, but I want to point out that I've spend like half a year reading harfbuzz code. I have a right to be angry about it. |
Luckily for us, those last 1000+ commits once again were mostly about subsetting/instancing/accelerators/boring-expansion-spec, the shaping logic itself remained mostly the same. A couple of questions/uncertainties, but nothing major:
I've also updated the README and added some of my thoughts on future work for
rustybuzz
. :)P.S.: Thanks @behdad for keeping such a clean commit history, it really makes things 100x easier!