HarfBuzz Layout Test Failures: Gsub5, Context, And Urdu Issues
Hey everyone! We're diving into a tricky issue encountered while building HarfBuzz versions 11.3.3 and 11.4.1. Specifically, we're seeing test failures in layout.gsub5
, layout.context
, and layout.notonastaliqurdu
. Let's break down what's happening, analyze the error logs, and explore potential causes. This article aims to provide a comprehensive overview for developers and anyone interested in HarfBuzz's text shaping engine. Our goal is to help you understand the intricacies of these harfbuzz test failures and how they relate to font layout and subsetting.
Understanding the Test Failures in HarfBuzz
When we talk about harfbuzz test failures, especially those related to layout, it's crucial to grasp the core functionality of HarfBuzz. At its heart, HarfBuzz is a powerful library for complex text layout. It takes Unicode text and OpenType fonts as input and produces the information needed to render that text correctly. This involves shaping characters, applying ligatures, and handling complex scripts like Arabic and Urdu. The failures we're seeing suggest there might be discrepancies in how HarfBuzz is shaping text in specific scenarios, particularly when dealing with font subsetting.
Examining the layout.gsub5
Failure
The layout.gsub5
test failure is particularly interesting because it involves the GSUB
table in OpenType fonts. The GSUB
(Glyph Substitution) table is responsible for substituting glyphs based on context. This could involve replacing individual glyphs with ligatures or applying contextual substitutions based on neighboring characters. The error messages in the log point to a mismatch in the hash between the expected output and the actual output after subsetting the font. This suggests that the subsetting process might be incorrectly altering the GSUB
table, leading to incorrect glyph substitutions.
Specifically, the logs show failures related to the gsub_context2_multiple_subrules_f2.otf
font. This font likely contains complex contextual substitution rules, which are being mishandled during subsetting. The tests are failing for various Unicode sets, including "41,42", "41,42,43", and "*" (which likely means all characters). This indicates that the issue is not limited to specific character combinations but is more general, affecting the way contextual substitutions are handled across the board. The failure of tests with the -retain-gids
profile further suggests problems with glyph ID handling during subsetting, which is a critical aspect of preserving font functionality.
Decoding the layout.context
Failure
The layout.context
test failure is closely related to layout.gsub5
, but it implicates the GPOS
(Glyph Positioning) table as well. The GPOS
table is responsible for adjusting the positions of glyphs relative to each other. This includes kerning (adjusting the space between specific letter pairs) and contextual positioning (adjusting glyph positions based on their neighbors). Similar to the layout.gsub5
failures, the logs for layout.context
show hash mismatches between expected and actual outputs after subsetting.
The failures are occurring with the gpos_context2_multiple_subrules_f1.otf
font, which, like the gsub5
font, likely has complex contextual rules. This further reinforces the idea that the subsetting process is struggling with fonts that utilize intricate layout features. The consistent pattern of failures across different Unicode sets and profiles, including the -retain-gids
profile, indicates a fundamental issue in how HarfBuzz's subsetting tools are processing contextual layout rules. It's possible that the subsetting algorithm is either stripping out crucial rules or modifying them in a way that leads to incorrect glyph positioning. Analyzing the differences between the expected and actual output fonts will be key to pinpointing the exact cause of this harfbuzz test failure.
Investigating the layout.notonastaliqurdu
Failure
The layout.notonastaliqurdu
test failure presents a slightly different picture. This test involves the Noto Nastaliq Urdu font, which is designed for the Urdu language, a script known for its complex calligraphic forms and contextual ligatures. The error logs show a mix of hash mismatches and failures during the preprocessing stage of subsetting. Some messages indicate that the --preprocess
step failed, suggesting problems with initial font processing before the actual subsetting takes place.
The errors often involve commands like this:
--font-file=/path/to/NotoNastaliqUrdu-Regular.ttf --output-file=/tmp/temp_file.ttf-subset.ttf --unicodes=... --drop-tables+=DSIG,BASE --drop-tables-=sbix --preprocess
This command is attempting to subset the font, specifying a set of Unicode characters (--unicodes
), dropping certain tables (--drop-tables
), and using the preprocessing step (--preprocess
). The failure of this preprocessing step is a significant clue. It suggests that HarfBuzz might be encountering difficulties in parsing or preparing the Noto Nastaliq Urdu font for subsetting. This could be due to the font's specific structure, the complexity of its layout features, or potential bugs in the preprocessing logic. The hash mismatches, similar to the other test failures, point to inconsistencies between the expected and actual output fonts, further emphasizing the need for a thorough investigation into the subsetting process for complex scripts like Urdu. The logs also highlight issues with retaining glyph IDs (--retain-gids
), adding another layer of complexity to the problem.
Analyzing the Error Logs: Key Takeaways
After carefully reviewing the error logs, several key patterns emerge that help us narrow down the potential causes of these harfbuzz test failures:
-
Hash Mismatches: The predominant error message is "hash for expected and actual does not match." This indicates that the output of the font subsetting process is not identical to the expected output. This discrepancy could arise from various reasons, including incorrect glyph substitutions, positioning adjustments, or table manipulations.
-
Contextual Layout Issues: The failures consistently involve fonts with complex contextual layout rules (
gsub_context2_multiple_subrules_f2.otf
andgpos_context2_multiple_subrules_f1.otf
). This suggests that the subsetting algorithm might be struggling to preserve the integrity of these rules. -
Noto Nastaliq Urdu Specifics: The
layout.notonastaliqurdu
failures highlight issues with a complex script font. The preprocessing failures indicate problems with parsing or preparing the font for subsetting, possibly due to its unique structure and intricate layout features. -
Glyph ID Retention: The failures with the
-retain-gids
profile are particularly concerning. Retaining glyph IDs is crucial for maintaining font consistency and compatibility, and these failures suggest potential issues in how glyph IDs are handled during subsetting. -
Subsetting Command Failures: In the
layout.notonastaliqurdu
tests, the direct failure of the subsetting command (--preprocess failed
) points to a more fundamental problem, possibly in the parsing or initial processing of the font file.
Potential Causes and Troubleshooting Steps
Based on the error logs and the patterns we've identified, here are some potential causes for these harfbuzz test failures and the troubleshooting steps we can take:
-
Bug in Subsetting Algorithm: The most likely cause is a bug in HarfBuzz's subsetting algorithm, particularly in how it handles contextual substitutions and positioning rules. To investigate this, we can:
- Examine the Subsetting Code: Dive into the HarfBuzz source code responsible for subsetting (
hb-subset.c
or similar) and analyze the logic for handlingGSUB
andGPOS
tables. - Compare Expected and Actual Fonts: Use font editors or fontdiff tools to compare the expected and actual output fonts. This will help pinpoint the exact differences in glyph substitutions, positioning, and table structures.
- Simplify the Test Cases: Create minimal test cases that isolate the specific contextual rules that are failing. This can help in debugging the algorithm.
- Examine the Subsetting Code: Dive into the HarfBuzz source code responsible for subsetting (
-
Font Parsing Issues: The preprocessing failures in
layout.notonastaliqurdu
suggest potential issues with font parsing. We can:- Verify Font Format: Ensure that the Noto Nastaliq Urdu font is a valid OpenType font and doesn't have any format errors.
- Debug Font Parsing: Use debugging tools to step through the font parsing code in HarfBuzz and identify where the failure occurs.
- Try Different Font Parsers: If possible, try using different font parsing libraries to see if the issue is specific to HarfBuzz's parser.
-
Glyph ID Handling: The
-retain-gids
failures point to potential problems with glyph ID handling. We can:- Analyze Glyph ID Mapping: Check how glyph IDs are mapped during subsetting and ensure that the mapping is consistent and correct.
- Inspect Glyph Ordering: Verify that the glyph order is preserved correctly during subsetting, especially for fonts with complex scripts.
-
Compiler/Build Issues: Although less likely, compiler or build issues could also contribute to the failures. We can:
- Try Different Compilers: Build HarfBuzz with different compilers and compiler versions to see if the issue is compiler-specific.
- Check Build Flags: Review the build flags and ensure that they are correctly configured for the target platform.
-
Test Data Issues: It's also possible that the test data itself is incorrect. We can:
- Review Test Cases: Carefully review the test cases and ensure that the expected outputs are accurate.
- Generate New Test Data: If necessary, generate new test data to validate the subsetting algorithm.
Addressing the layout.notonastaliqurdu
Failure in Detail
Let's drill down a bit more on the layout.notonastaliqurdu
failure, given its unique characteristics. The logs show errors like:
message: "--font-file=/path/to/NotoNastaliqUrdu-Regular.ttf --output-file=/tmp/temp_file.ttf-subset.ttf --unicodes=... --drop-tables+=DSIG,BASE --drop-tables-=sbix --preprocess failed"
This specific error, where the --preprocess
step fails, is a strong indicator of a problem during the initial stages of font processing. Here's a detailed breakdown of the potential causes and how to tackle them:
Potential Cause 1: Font Structure Complexity
Noto Nastaliq Urdu is a font designed for a complex script, and its internal structure might be intricate. This complexity could be overwhelming HarfBuzz's preprocessing routines. For instance, the font might have a large number of tables, complex lookups, or unusual table structures that the preprocessing code isn't fully equipped to handle.
Troubleshooting Steps:
- Font Editor Inspection: Open the font in a font editor like FontForge or Glyphs and examine its structure. Look for anything unusual or overly complex, such as a vast number of lookups in the GSUB or GPOS tables, or non-standard table arrangements.
- Table Dump: Use tools like
hb-view
orotfinfo
to dump the font's tables and analyze their contents. This can help you identify if any particular table is causing the issue due to its size or structure.
Potential Cause 2: Parsing Bugs
There might be a bug in HarfBuzz's font parsing code that's triggered by specific aspects of the Noto Nastaliq Urdu font. This could be a subtle issue that only manifests with certain fonts or font structures.
Troubleshooting Steps:
- Debugging: Use a debugger to step through HarfBuzz's font parsing code (likely in files like
hb-ot-font.c
or similar) when it processes the Noto Nastaliq Urdu font. Set breakpoints at the start of table parsing routines and step through the code to identify where the process fails. - Simplified Test Case: Create a simplified version of the font that still exhibits the issue. This could involve removing tables or glyphs until you have a minimal font that triggers the parsing failure. This simplified test case can be invaluable for debugging.
Potential Cause 3: Table Processing Issues
The --preprocess
step might involve specific table processing routines that are failing for Noto Nastaliq Urdu. For example, if the font has a particularly large or complex GSUB
or GPOS
table, the preprocessing step might be running out of memory or hitting a performance bottleneck.
Troubleshooting Steps:
- Profiling: Use profiling tools to analyze the performance of the preprocessing step. This can help identify if any specific routines are consuming excessive time or memory.
- Disable Preprocessing: As a temporary workaround, try disabling the
--preprocess
step to see if the subsetting process can proceed without it. If it works, this confirms that the preprocessing step is the culprit.
Potential Cause 4: Dependency Issues
In some cases, failures during font processing can be caused by issues with external dependencies, such as zlib or other libraries used for font compression or decompression. If these libraries are outdated or have bugs, they might cause failures during font loading or processing.
Troubleshooting Steps:
- Dependency Check: Ensure that all of HarfBuzz's dependencies are up-to-date and compatible.
- Library Version Test: Try building HarfBuzz with different versions of its dependencies to see if the issue is dependency-specific.
Potential Cause 5: Font Corruption
Although less likely, it's possible that the Noto Nastaliq Urdu font file is corrupted. This could happen during download, storage, or file transfer.
Troubleshooting Steps:
- Font Verification: Try downloading the font again from a trusted source and compare its checksum with the original to ensure it's not corrupted.
- Font Validation Tools: Use font validation tools to check the font for structural errors or inconsistencies.
Next Steps and Community Collaboration
These harfbuzz test failures are complex and require a systematic approach to diagnose and resolve. The next steps involve a combination of code analysis, debugging, and potentially reaching out to the HarfBuzz community for assistance.
- Deep Dive into Code: The developers need to delve deep into the HarfBuzz source code, focusing on the subsetting algorithm and font parsing routines. This will involve stepping through the code with debugging tools and carefully examining the logic.
- Community Engagement: The HarfBuzz community is a valuable resource. Posting detailed information about the failures, along with the error logs and analysis, can attract the attention of experienced developers who might have insights or solutions.
- Reproducible Test Cases: Creating minimal, reproducible test cases is crucial for bug fixing. These test cases should isolate the specific scenarios that cause the failures, making it easier for developers to pinpoint the root cause.
By working collaboratively and systematically, the HarfBuzz team can address these test failures and ensure the library remains a reliable and robust text shaping engine. We'll continue to update this article as we learn more about the issue and potential solutions. Stay tuned for further insights into these harfbuzz test failures!
Conclusion
In conclusion, the test failures encountered while building HarfBuzz 11.3.3 and 11.4.1 in layout.gsub5
, layout.context
, and layout.notonastaliqurdu
highlight the complexities involved in font subsetting and text shaping, especially when dealing with contextual layout rules and complex scripts. The key to resolving these issues lies in a thorough analysis of the HarfBuzz source code, careful comparison of expected and actual outputs, and active collaboration with the HarfBuzz community. Understanding the nuances of GSUB and GPOS tables, font parsing, and glyph ID handling is crucial for identifying and addressing the root causes of these failures. By taking a systematic approach and leveraging the collective expertise of the community, we can ensure that HarfBuzz remains a robust and reliable library for text shaping and font manipulation. These harfbuzz test failures serve as a reminder of the intricate nature of font technology and the importance of rigorous testing in software development. We hope this deep dive has provided valuable insights into the issue and the steps required to address it. Remember, tackling complex problems like these requires patience, persistence, and a collaborative spirit. Let's work together to make HarfBuzz even better!