Bug 560546 - Differences between GC.drawText() and GC.drawString()

The rest of this commit message explains behavior on Windows.

`GC.drawString()` uses WINAPI `ExtTextOut()`.
`GC.drawText()` uses WINAPI `DrawText()`.

`DrawText()` does some additional font fallback resolving. When the
currently selected font doesn't have a glyph, it will use a hardcoded
table of fallback fonts, which seem to give good enough results.

The pseudocode for table lookup is:
  int iCandidate = gdi32full!iStandardFallbackCandidates[SCRIPT_ITEM.a.eScript];
  int iFallback  = gdi32full!iStandardFallback[iCandidate];
  gdi32full!StandardFallbackFont[iFallback];

`DrawText()` will then call `ExtTextOut()` with different fonts and
related string parts.

`ExtTextOut()` is a kernel-mode API. Its user-mode counterpart merely
queues a job for kernel. As a consequence, it's faster then `DrawText()`
which does additional processing. The kernel worker of `ExtTextOut()` is
`win32kfull.sys!GreBatchTextOut`.

`ExtTextOut()` does not try to find fallback fonts, but will process
font links defined in this registry key:
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink

However, this doesn't work as good: font link settings are different on
different Windows versions, and it also seems to do a poor job at
matching font size.

The attached snippet demonstrates the differences:
* On Win8.1, 'Segoe UI' is not linked to 'Segoe UI Symbol', and
  `GC.drawString()` will show a "missing glyph" (rectangle glyph).
* On Win10, 'Segoe UI' is linked, but the glyph's size is wrong.

Performance as measured on my Win10:
1-char string,   DrawText   - 0.741 sec
1-char string,   ExtTextOut - 0.101 sec
10-char string,  DrawText   - 0.962 sec
10-char string,  ExtTextOut - 0.225 sec
100-char string, DrawText   - 2.893 sec
100-char string, ExtTextOut - 1.533 sec

Change-Id: I0758a90fef9bc06f350d18d0f3e6fe79a43fb450
Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
4 files changed
tree: 051f8b0e2cac9b69f6d08b67fcc387a52d1f8f7d
  1. bundles/
  2. container/
  3. examples/
  4. features/
  5. local-build/
  6. tests/
  7. .gitignore
  8. CONTRIBUTING
  9. LICENSE
  10. NOTICE
  11. pom.xml
  12. README.md
README.md

Contributing to SWT

Thanks for your interest in this project.

Developer resources:

See the following description for how to contribute a feature or a bug fix to SWT.

Information regarding source code management, builds, coding standards, and more and be found under the following link.

Contributor License Agreement:

Before your contribution can be accepted by the project, you need to create and electronically sign the Eclipse Foundation Contributor License Agreement (CLA).

Contact:

Contact the project developers via the project's “dev” list.

Search for bugs:

This project uses Bugzilla to track ongoing development and issues.

Create a new bug:

Be sure to search for existing bugs before you create another one. Remember that contributions are always welcome!