Skip to content
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

Experimental support for font hinting #6295

Merged
merged 17 commits into from
Oct 15, 2017

Conversation

AaronVanGeffen
Copy link
Member

Traditionally, RCT2 has used a sprite-based font to render its strings. Since OpenRCT2's inception, support has been added for rendering with TrueType fonts to accomodate languages that do not use a Western script, such as Chinese, Korean, and Japanese.

In the past, OpenRCT2's palette has been a point of frustration, as it prevented implementation of direct font hinting ('anti-aliasing'), leading the Korean community to raise their minimum font size from 8 to 11 points (cf. #2317). This is not an ideal solution, however, as it leads text strings to overflow from their containing UI elements, since widgets are currently not flexible.

This PR, while a work in progress, is a crude attempt of implementing support for font hinting in OpenRCT2. Let me start off with some examples.

Screenshots

(Before on the left, after on the right.)

scenario_ru_before scenario_ru_after

settings_jp_before settings_jp_after

settings_ru_before settings_ru_after

Known issues

The current implementation does not play nicely with all window background colours — in some cases even overflowing into the wrong colour family entirely. I am hopeful we can resolve this as my understanding of the palette system deepens, however.

I have been eyeing ColourMapA in colour.c — it seems to be exactly what is needed. One caveat: in some cases a darker shade is needed, while the others require a lighter one. Outlined texts, like in window titles, are probably related here.

In conclusion

Ideas or other contributions would be most appreciated! I'm stuck right now, but excited for the possibilities, so I thought I'd put it the code out here for now.

@janisozaur
Copy link
Member

We already have [font] section in config.ini describing various font properties, can the shaded v. solid option be included there as well?

@Gymnasiast
Copy link
Member

And if you add it, probably best to turn it on by default (assuming it won't be used for the sprite font).

@marijnvdwerf
Copy link
Contributor

Maybe we could create a function (with a cache) that calculates the blend between two colours. And then gets the closest palette index based on the closest colour.

@AaronVanGeffen
Copy link
Member Author

@janisozaur Making it optional was fairly straightforward (da4dae6), although I'm not too keen on the added compile-time dependency. Perhaps it's no big deal, though?

@marijnvdwerf Hmm, I was hoping to avoid blending altogether, but rather work from the background colour. Depending on the intensity of the foreground colour, we'd either use a darker or lighter shade. Would clamping on the colour palette in such a fashion be feasible?

@AaronVanGeffen AaronVanGeffen force-pushed the fonthinting branch 2 times, most recently from 6130d74 to e309107 Compare September 23, 2017 23:46
@AaronVanGeffen
Copy link
Member Author

Getting there. Here's what things look like as of e309107:

screen shot 2017-09-24 at 01 44 00

@janisozaur
Copy link
Member

@telk5093 @YJSoft @daihakken @izhangfei can you guys check how it works for you?

@YJSoft
Copy link
Contributor

YJSoft commented Sep 25, 2017

2017-09-25 18-14-22
image

Looks OK except IME part(where background is black)

tested with below config

[font]
file_name = "NanumGothic.ttf"
font_name = "NanumGothic"
x_offset = 0
y_offset = -2
size_tiny = 9
size_small = 11
size_medium = 12
size_big = 13
height_tiny = 14
height_small = 14
height_medium = 14
height_big = 20
enable_hinting = true

@AaronVanGeffen
Copy link
Member Author

Thank you for testing, @YJSoft. I'm sure at one point the IME looked alright, so I should be able to fix it.

@Gymnasiast
Copy link
Member

@AaronVanGeffen Any update on fixing the IME?

@AaronVanGeffen
Copy link
Member Author

I had a quick look the other day, and while I'm sure I can fix it, it's a little less trivial than I assumed. Regrettably, I'm a little busy this week, but I'm hopeful can have another go at it this weekend.

@AaronVanGeffen AaronVanGeffen force-pushed the fonthinting branch 3 times, most recently from 25bcea6 to 8e7e1d2 Compare October 5, 2017 12:14
@AaronVanGeffen
Copy link
Member Author

The IME issue should be fixed with 4bff727 adding support for black backgrounds. @YJSoft, could you confirm?

While doing some more thorough testing myself (sparking #6372, since merged), I encountered two more rare cases: the bright red text displaying losses in the finances window, and the light sea green colour in the theme window. Regrettably, I've had to add exceptions for both of them.

I think this is ready for review and testing, once more.

@@ -812,6 +812,12 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te
} else if (*dst < 10) {
// For black backgrounds, hint using grey pixels.
*dst = 13;
} else if (colour == 153) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no constant for this? I remember @marijnvdwerf replacing all instances.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interface/colour.h has a few colour constants, but not for any of these. Please correct me if I'm overlooking any, of course.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to add the appropriate PALETTE_INDEX_x entries in the enum, but I'd like to hear from @marijnvdwerf first.

Copy link
Contributor

@marijnvdwerf marijnvdwerf Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either use ColourMap, or add a new PALETTE_INDEX entry. (Same for the other palette indexes)

Copy link
Member Author

@AaronVanGeffen AaronVanGeffen Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've applied ColourMapA where possible per e8d2aee. Suggestions for the other cases are welcome, too... I tried fiddling with the BASE_COLOUR macro as well, but I'm pressed for time and it wasn't quite working out yet, so I've left that out for now.

@YJSoft
Copy link
Contributor

YJSoft commented Oct 7, 2017

screenshot 2017-10-07 07 02 48

some letters are still hard to read, but I think it's font file's problem(letter too complex for small sizes)

@AaronVanGeffen
Copy link
Member Author

Thanks for testing! You're right that the glyphs are a little complicated for this font size, but there may be something we can do still — I have an idea. Could you check back here in, say, 15 minutes?

@AaronVanGeffen
Copy link
Member Author

@YJSoft Does abe79b7 make things a little better for you? (It doesn't seem to make much of a difference when I test Japanese, but it's worth a shot...)

@YJSoft
Copy link
Contributor

YJSoft commented Oct 7, 2017

screenshot 2017-10-07 07 49 00

much better

@AaronVanGeffen
Copy link
Member Author

AaronVanGeffen commented Oct 7, 2017

@YJSoft Thanks again! It still doesn't look ideal, but at least the strokes are all visible, I guess.

@Gymnasiast, @marijnvdwerf Any more suggestions for improvement?

@@ -1567,7 +1567,9 @@ void scrolling_text_set_bitmap_for_ttf(utf8 *text, sint32 scroll, uint8 *bitmap,
uint8 *dst = &bitmap[scrollPosition];

for (sint32 y = 0; y < height; y++) {
if (src[y * pitch + x] != 0) *dst = colour;
if (src[y * pitch + x] > 92 || (src[y * pitch + x] != 0 && !gConfigFonts.enable_hinting)) {
Copy link
Member

@Gymnasiast Gymnasiast Oct 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brace placement. There are more occurrences, but I'm not going to spam line notes.

dst_check = (uint8*)textbuf->pixels + textbuf->pitch * textbuf->h;

/* Fill the palette with NUM_GRAYS levels of shading from bg to fg */
/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out code; should be removed.

*/

/* check kerning */
use_kerning = FT_HAS_KERNING( font->face ) && font->kerning;
Copy link
Member

@Gymnasiast Gymnasiast Oct 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FT_HAS_KERNING(font->face)
Again, saying this only wence.

@marijnvdwerf
Copy link
Contributor

Seems fine to me. Probably should revert the logo though.

@AaronVanGeffen
Copy link
Member Author

Haha, yes, absolutely. Thanks. I'll do a rebase onto develop in the morning, squashing and dropping a commit here and there, then.

{
sint16 closest = -1;
sint32 closestDistance = INT32_MAX;
double closestDistance = INT32_MAX;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marijnvdwerf Do you reckon we should drop the doubles in favour of going back to sint32s? They don't seem to have made much of an impact.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just ran a test on all colours, int or double always produce the same outcome.

@AaronVanGeffen
Copy link
Member Author

Rebased the lot on top of develop. Merged and dropped a few commits, too. Wondering whether I should squash 8c1ae5e, 253b525, 899fe2f? Personally, I really like having the history around.

@marijnvdwerf, what do you think?

@@ -148,6 +151,10 @@ extern rct_colour_map ColourMapA[COLOUR_COUNT];

void colours_init_maps();

#ifndef NO_TTF
uint8 blend(const uint8 paletteIndex1, const uint8 paletteIndex2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this to something more verbose?

@marijnvdwerf
Copy link
Contributor

I'm fine with the history as-is. I'll merge it once you renamed the blend function 👍

@AaronVanGeffen
Copy link
Member Author

Done! Thanks for the help and review!

@marijnvdwerf marijnvdwerf merged commit 08f7aba into OpenRCT2:develop Oct 15, 2017
@AaronVanGeffen AaronVanGeffen deleted the fonthinting branch October 15, 2017 20:38
Gymnasiast pushed a commit that referenced this pull request Oct 24, 2017
janisozaur added a commit that referenced this pull request Mar 18, 2018
- Feature: [#2893] Object selection filters for items from RCT1, Added Attractions and Loopy Landscapes.
- Feature: [#3505] Allow up to 1024 items per scenery tab.
- Feature: [#3510] Auto-append extension if none is specified.
- Feature: [#3994] Show bottom toolbar with map tooltip (theme option).
- Feature: [#4184] Add command and cheat to alter the date.
- Feature: [#4906] Add follow sprite command to title sequences.
- Feature: [#4984] Add option to highlight path issues: full bins, vandalism & vomit.
- Feature: [#5826] Add the show_limits command to show map data counts and limits.
- Feature: [#6078] Game now converts mp.dat to SC21.SC4 (Mega Park) automatically.
- Feature: [#6125] Path can now be placed in park entrances.
- Feature: [#6181] Map generator now allows adjusting random terrain and tree placement in Simplex Noise tab.
- Feature: [#6235] Add drawing debug option for showing visuals when and where blocks of the screen are painted.
- Feature: [#6290] Arabic translation (experimental).
- Feature: [#6292] Allow building queue lines in the Scenario Editor.
- Feature: [#6295] TrueType fonts are now rendered with light font hinting by default.
- Feature: [#6307] Arrows are now shown when placing park entrances.
- Feature: [#6313] Add keyboard shortcut for toggle gridlines.
- Feature: [#6324] Add command to deselect unused objects from the object selection.
- Feature: [#6325] Allow using g1.dat from RCT Classic.
- Feature: [#6329] Render level crossings when the Miniature Railway crossed a path.
- Feature: [#6338] Virtual floor to help positioning objects vertically.
- Feature: [#6353] Show custom RCT1 scenarios in New Scenario window.
- Feature: [#6411] Add command to remove the park fence.
- Feature: [#6414] Raise maximum launch speed of the Corkscrew RC back to 96 km/h (for RCT1 parity).
- Feature: [#6433] Turn 'unlock all prices' into a regular (non-cheat, persistent) option.
- Feature: [#6516] Ability to search by filename in the object selection window.
- Feature: [#6530] Land rights tool no longer blocks when a tile is not for purchase.
- Feature: [#6568] Add smooth nearest neighbour scaling.
- Feature: [#6651, #6658] Integrate Discord Rich Presence.
- Feature: [#6709] The New Ride window now shows available vehicles for a ride type.
- Feature: [#6731] Object indexing progress is now reported via command line output.
- Feature: [#6779] On-ride photo segment for Splash Boats.
- Feature: [#6838] Ability to auto-pause server when no clients are connected.
- Feature: [#7031] Better support for displaced ride entrances and exits.
- Feature: Add search box to track design window.
- Feature: Allow using object files from RCT Classic.
- Feature: Title sequences now testable in-game.
- Feature: Vehicles with matching capabilities are now always switchable.
- Feature: Add search box to track design window.
- Feature: Add load scenario command to title sequences.
- Fix: [#816] In the map window, there are more peeps flickering than there are selected (original bug).
- Fix: [#996, #2589, #2875] Viewport scrolling no longer shakes or gets stuck.
- Fix: [#1185] Close button colour of prompt windows does not match.
- Fix: [#1833, #4937, #6138] 'Too low!' warning when building rides and shops on the lowest land level (original bug).
- Fix: [#2254] Edge scrolling horizontally now has the same speed as vertical edge scrolling.
- Fix: [#2607] Rain rendered incorrectly in additional viewport.
- Fix: [#3171] Guests entering from the corner of the tile in Amity Airfield (original bug).
- Fix: [#3330] Current number of passengers overflows when over 255 (original bug).
- Fix: [#4760] Asia - Great Wall of China and South America - Rio Carnival have incorrect guest entry points (original bug).
- Fix: [#4953, #6277] Unable to advertise to master servers over IPv6.
- Fix: [#4991] Inverted helices can be built on the Lay Down RC, but are not drawn.
- Fix: [#5190] Cannot build Wild Mouse - Flying Dutchman Gold Mine.
- Fix: [#5224] Multiplayer window is not closed when server shuts down.
- Fix: [#5228] Top toolbar disappears when opening SC4 file.
- Fix: [#5261] Deleting a banner sign after copy/pasting it will crash the game.
- Fix: [#5398] Attempting to place Mini Maze.TD4 results in weird behaviour and crashes.
- Fix: [#5417] Hacked Crooked House tracked rides do not dispatch vehicles.
- Fix: [#5445] Patrol area not imported from RCT1 saves and scenarios.
- Fix: [#5585] Inconsistent zooming with mouse wheel.
- Fix: [#5609] Vehicle switching may cause '0 cars per train' to be set.
- Fix: [#5636] Pausing the game shows mute button as active.
- Fix: [#5741] Land rights indicators disappear when switching views.
- Fix: [#5761] Mini coaster doesn't appear despite being selected.
- Fix: [#5788] Empty scenario names cause invisible entries in scenario list.
- Fix: [#5809] Support Steam RCT1 file layout when loading CSG images.
- Fix: [#5838] Crash when saving very large track designs.
- Fix: [#5901] Placing peep spawn not synced across multiplayer.
- Fix: [#6101] Rides remain in ride list window briefly after demolition.
- Fix: [#6114] Crash when using a non-LL CSG1.DAT.
- Fix: [#6115] Random title screen music not random on launch.
- Fix: [#6118, #6245, #6366] Tracked animated vehicles not animating.
- Fix: [#6129] Guest List summary not updating after a ride rename.
- Fix: [#6133] Construction rights not shown after selecting buy mode.
- Fix: [#6188] Viewports not being clipped properly when zoomed out in OpenGL mode.
- Fix: [#6193] All rings in Space Rings use the same secondary colour.
- Fix: [#6196, #6223] Guest's energy underflows and never decreases.
- Fix: [#6198] You cannot cancel RCT1 directory selection.
- Fix: [#6199] Inverted Hairpin Coaster vehicle tab is not centred.
- Fix: [#6202] Guests can break occupied benches (original bug).
- Fix: [#6251] Splash Boats renders flat-to-25-degree pieces in tunnels incorrectly.
- Fix: [#6261, #6344, #6520] Broken pathfinding after removing park entrances with the tile inspector.
- Fix: [#6271] Wrong booster speed tooltip text.
- Fix: [#6293] Restored interface sounds while gameplay is paused.
- Fix: [#6301] Track list freezes after deleting track in Track Manager.
- Fix: [#6308] Cannot create title sequence if title sequences folder does not exist.
- Fix: [#6314] Imported SV4 files do not mark their scenarios as completed.
- Fix: [#6318] Cannot sack staff that have not been placed.
- Fix: [#6320] Crash when CSS1.DAT is absent.
- Fix: [#6331] Scenery costs nothing in track designs.
- Fix: [#6358] HTTP requests can point to invalid URL string.
- Fix: [#6360] Off-by-one filenames when exporting all sprites.
- Fix: [#6388] Construction rights tool erroneously enabled in some RCT1 scenarios even when no rights are available.
- Fix: [#6413] Maze previews only showing scenery.
- Fix: [#6423] Importing parks containing names with Polish characters.
- Fix: [#6423] Polish characters now correctly drawn when using the sprite font.
- Fix: [#6445] Guests' favourite ride improperly set when importing from RCT1 or AA.
- Fix: [#6452] Scenario text cut off when switching between 32 and 64-bit builds.
- Fix: [#6460] Crash when reading corrupt object files.
- Fix: [#6481] Can't take screenshots of parks with colons in the name.
- Fix: [#6500] Failure to load resources when config file is missing.
- Fix: [#6547] The server log is not logged if the server name contains CJK.
- Fix: [#6593] Cannot hire entertainers when default scenery groups are not selected (original bug).
- Fix: [#6657] Guest list is missing tracking icon after reopening.
- Fix: [#6803] Symbolic links to directories are not descended by FileScanner.
- Fix: [#6830] Crash when using mountain tool due to ride with no ride entry.
- Fix: [#6833] Shops in corrupted files not imported correctly.
- Fix: [#6846] Zoom level in some ride overview windows was erroneously set too high.
- Fix: [#6904] Manually added multiplayer servers not saved.
- Fix: [#7003] Building sloped paths through flat paths with clearance checks off causes glitches.
- Fix: [#7011] Swinging and bobsleigh cars going backwards swing in the wrong direction (original bug).
- Fix: [#7042, #7077] Paths sometimes disconnect when building them with clearance checks off.
- Fix: [#7125] No entry signs not correctly handled in pathfinding.
- Fix: [#7223] Vehicle mass not correctly recalculated when using remove all guests cheat.
- Fix: [#7229] Exploding guests cheat causes rides to get stuck and freezes game.
- Fix: [#7295] peep_should_go_on_ride_again() checked balloon colour instead of toilet need.
- Fix: [#7301] Sprite compiler dithering checks transparency of wrong pixel.
- Fix: Infinite loop when removing scenery elements with >127 base height.
- Fix: Ghosting of transparent map elements when the viewport is moved in OpenGL mode.
- Fix: Clear IME buffer after committing composed text.
- Fix: RCT1 mazes with wooden fences not imported correctly.
- Fix: Title sequence editor now gracefully fails to preview a title sequence and lets the user know with an error message.
- Fix: When preset title sequence fails to load, the preset will forcibly be changed to the first sequence to successfully load.
- Fix: Remove consecutive thoughts about a ride being demolished.
- Fix: Water raft vehicles stop spinning when going up slopes.
- Fix: Incorrect spin is applied to coasters on S-bends and other turns.
- Improved: [#5962] Use AVX2 instruction set where supported, resulting in a performance boost.
- Improved: [#5964] Use SSE 4.1 instruction set where supported, resulting in a performance boost.
- Improved: [#6186] Transparent menu items now draw properly in OpenGL mode.
- Improved: [#6218] Speed up game start up time by saving scenario index to file.
- Improved: [#6242] Prevent scenery aging and grass growth causing tile invalidation unless necessary - slight performance boost.
- Improved: [#6423] Polish is now rendered using the sprite font, rather than TTF.
- Improved: [#6746] Draw friction wheels instead of chain lift on Looping Roller Coaster stations.
- Improved: Load/save window now refreshes list if native file dialog is closed/cancelled.
- Improved: Major translation updates for Japanese and Polish.
- Improved: Added 24x24, 48x48, and 96x96 icon resolutions.
- Technical: [#6384] On macOS, address NSFileHandlingPanel deprecation by using NSModalResponse instead.
- Technical: [#6772] RCT2 interop removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants