summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-28 18:14:49 +0000
committerasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-28 18:14:49 +0000
commitcb0264c4a8443578418de54ac7278fdb9efcbe3d (patch)
tree69062d0fda021d25de3bad9f2175c92041a7af24 /ui
parent1adf1eb2d340b970b1713935a8c936de1b2e2a4d (diff)
downloadchromium_src-cb0264c4a8443578418de54ac7278fdb9efcbe3d.zip
chromium_src-cb0264c4a8443578418de54ac7278fdb9efcbe3d.tar.gz
chromium_src-cb0264c4a8443578418de54ac7278fdb9efcbe3d.tar.bz2
Implement font linking for RenderTextWin.
Font linking is needed for East Asian fonts where Windows font fallback doesn't work. This change adds support for font linking by making RenderTextWin read and cache the font link lists from the registry and use these when there are missing glyphs returned from ScriptShape(). BUG=90426, 105550 TEST=Build Chrome on Windows with use_canvas_skia_skia=1. Go to http://www.google.co.jp/shopping?hl=ja. The tab title should correctly display Japanese characters and not boxes. Review URL: https://chromiumcodereview.appspot.com/9429061 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123998 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/render_text_win.cc85
-rw-r--r--ui/gfx/render_text_win.h8
2 files changed, 93 insertions, 0 deletions
diff --git a/ui/gfx/render_text_win.cc b/ui/gfx/render_text_win.cc
index 608cc7d..ae31475 100644
--- a/ui/gfx/render_text_win.cc
+++ b/ui/gfx/render_text_win.cc
@@ -10,7 +10,9 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/string_util.h"
+#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
+#include "base/win/registry.h"
#include "ui/gfx/font_smoothing_win.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/canvas_skia.h"
@@ -84,6 +86,37 @@ bool ChooseFallbackFont(HDC hdc,
return found_fallback;
}
+// Queries the Registry to get a list of linked fonts for |font|.
+void QueryLinkedFontsFromRegistry(const gfx::Font& font,
+ std::vector<gfx::Font>* linked_fonts) {
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ const wchar_t* kSystemLink =
+ L"Software\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink";
+
+ base::win::RegKey key;
+ if (FAILED(key.Open(HKEY_LOCAL_MACHINE, kSystemLink, KEY_READ)))
+ return;
+
+ const std::wstring font_name = UTF8ToWide(font.GetFontName());
+ std::vector<std::wstring> values;
+ if (FAILED(key.ReadValues(font_name.c_str(), &values))) {
+ key.Close();
+ return;
+ }
+
+ for (size_t i = 0; i < values.size(); i++) {
+ // The font name follows the comma in each entry.
+ const size_t index = values[i].find(',');
+ if ((index != string16::npos) && (index + 1 != values[i].length())) {
+ const std::string linked_name = UTF16ToUTF8(values[i].substr(index + 1));
+ const gfx::Font linked_font(linked_name, font.GetFontSize());
+ linked_fonts->push_back(linked_font);
+ }
+ }
+
+ key.Close();
+}
+
} // namespace
namespace gfx {
@@ -110,6 +143,9 @@ TextRun::~TextRun() {
// static
HDC RenderTextWin::cached_hdc_ = NULL;
+// static
+std::map<std::string, std::vector<Font> > RenderTextWin::cached_linked_fonts_;
+
RenderTextWin::RenderTextWin()
: RenderText(),
string_width_(0),
@@ -603,10 +639,17 @@ void RenderTextWin::LayoutVisualText() {
size_t run_length = run->range.length();
const wchar_t* run_text = &(text()[run->range.start()]);
bool tried_fallback = false;
+ size_t linked_font_index = 0;
+ const std::vector<gfx::Font>* linked_fonts = NULL;
// Select the font desired for glyph generation.
SelectObject(cached_hdc_, run->font.GetNativeFont());
+ SCRIPT_FONTPROPERTIES font_properties;
+ memset(&font_properties, 0, sizeof(font_properties));
+ font_properties.cBytes = sizeof(SCRIPT_FONTPROPERTIES);
+ ScriptGetFontProperties(cached_hdc_, &run->script_cache, &font_properties);
+
run->logical_clusters.reset(new WORD[run_length]);
run->glyph_count = 0;
// Max glyph guess: http://msdn.microsoft.com/en-us/library/dd368564.aspx
@@ -626,6 +669,35 @@ void RenderTextWin::LayoutVisualText() {
&(run->glyph_count));
if (hr == E_OUTOFMEMORY) {
max_glyphs *= 2;
+ } else if (hr == S_OK) {
+ // If |hr| is S_OK, there could still be missing glyphs in the output,
+ // see: http://msdn.microsoft.com/en-us/library/windows/desktop/dd368564.aspx
+ //
+ // If there are missing glyphs, use font linking to try to find a
+ // matching font.
+ bool glyphs_missing = false;
+ for (int i = 0; i < run->glyph_count; i++) {
+ if (run->glyphs[i] == font_properties.wgDefault) {
+ glyphs_missing = true;
+ break;
+ }
+ }
+ // No glyphs missing - good to go.
+ if (!glyphs_missing)
+ break;
+
+ // First time through, get the linked fonts list.
+ if (linked_fonts == NULL)
+ linked_fonts = GetLinkedFonts(run->font);
+
+ // None of the linked fonts worked - break out of the loop.
+ if (linked_font_index == linked_fonts->size())
+ break;
+
+ // Try the next linked font.
+ run->font = linked_fonts->at(linked_font_index++);
+ ScriptFreeCache(&run->script_cache);
+ SelectObject(cached_hdc_, run->font.GetNativeFont());
} else if (hr == USP_E_SCRIPT_NOT_IN_FONT) {
// Only try font fallback if it hasn't yet been attempted for this run.
if (tried_fallback) {
@@ -702,6 +774,19 @@ void RenderTextWin::LayoutVisualText() {
string_width_ = preceding_run_widths;
}
+const std::vector<Font>* RenderTextWin::GetLinkedFonts(const Font& font) const {
+ const std::string& font_name = font.GetFontName();
+ std::map<std::string, std::vector<Font> >::const_iterator it =
+ cached_linked_fonts_.find(font_name);
+ if (it != cached_linked_fonts_.end())
+ return &it->second;
+
+ cached_linked_fonts_[font_name] = std::vector<Font>();
+ std::vector<Font>* linked_fonts = &cached_linked_fonts_[font_name];
+ QueryLinkedFontsFromRegistry(font, linked_fonts);
+ return linked_fonts;
+}
+
size_t RenderTextWin::GetRunContainingPosition(size_t position) const {
DCHECK(!needs_layout_);
// Find the text run containing the argument position.
diff --git a/ui/gfx/render_text_win.h b/ui/gfx/render_text_win.h
index d34c219..1b25171 100644
--- a/ui/gfx/render_text_win.h
+++ b/ui/gfx/render_text_win.h
@@ -8,6 +8,8 @@
#include <usp10.h>
+#include <map>
+#include <string>
#include <vector>
#include "base/memory/scoped_ptr.h"
@@ -95,6 +97,9 @@ class RenderTextWin : public RenderText {
void ItemizeLogicalText();
void LayoutVisualText();
+ // Returns a vector of linked fonts corresponding to |font|.
+ const std::vector<Font>* GetLinkedFonts(const Font& font) const;
+
// Return the run index that contains the argument; or the length of the
// |runs_| vector if argument exceeds the text length or width.
size_t GetRunContainingPosition(size_t position) const;
@@ -109,6 +114,9 @@ class RenderTextWin : public RenderText {
// Cached HDC for performing Uniscribe API calls.
static HDC cached_hdc_;
+ // Cached map from font names to vectors of linked fonts.
+ static std::map<std::string, std::vector<Font> > cached_linked_fonts_;
+
SCRIPT_CONTROL script_control_;
SCRIPT_STATE script_state_;