[gnome-characters] characterList: Show invisible character names
- From: Daiki Ueno <dueno src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-characters] characterList: Show invisible character names
- Date: Thu, 10 Dec 2015 01:52:04 +0000 (UTC)
commit f62d9dda0be75ccb3f3eae42e6d92780d7803317
Author: Daiki Ueno <dueno src gnome org>
Date: Fri Dec 4 17:11:12 2015 +0900
characterList: Show invisible character names
https://bugzilla.gnome.org/show_bug.cgi?id=757815
lib/gc.c | 15 +++++++++++
lib/gc.h | 3 ++
src/characterList.js | 64 +++++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 76 insertions(+), 6 deletions(-)
---
diff --git a/lib/gc.c b/lib/gc.c
index 85138ec..c433e3f 100644
--- a/lib/gc.c
+++ b/lib/gc.c
@@ -494,6 +494,21 @@ gc_character_name (gunichar uc)
return unicode_character_name (uc, g_new0 (gchar, UNINAME_MAX));
}
+/**
+ * gc_character_is_invisible:
+ * @uc: a UCS-4 character
+ *
+ * Returns: %TRUE if @uc is an invisible character, %FALSE otherwise.
+ */
+gboolean
+gc_character_is_invisible (gunichar uc)
+{
+ return uc_is_property_space (uc)
+ || uc_is_property_iso_control (uc)
+ || uc_is_property_format_control (uc)
+ || uc_is_property_zero_width (uc);
+}
+
GQuark
gc_search_error_quark (void)
{
diff --git a/lib/gc.h b/lib/gc.h
index 5a074af..8164304 100644
--- a/lib/gc.h
+++ b/lib/gc.h
@@ -86,6 +86,9 @@ gboolean gc_search_context_is_finished
(GcSearchContext *context);
gchar *gc_character_name (gunichar uc);
+gboolean gc_character_is_invisible
+ (gunichar uc);
+
/* GTK+ support. gtk_clipboard_get() takes an GdkAtom as the first
argument, but GdkAtom is not accessible through GI. */
diff --git a/src/characterList.js b/src/characterList.js
index d39f9db..e43ef2c 100644
--- a/src/characterList.js
+++ b/src/characterList.js
@@ -23,6 +23,7 @@ const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
+const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
const Gc = imports.gi.Gc;
@@ -53,6 +54,9 @@ const CharacterListRow = new Lang.Class({
this.parent(params);
this._characters = filtered.characters;
this._fontDescription = filtered.fontDescription;
+ var fontDescription = filtered.fontDescription.copy();
+ fontDescription.set_size(fontDescription.get_size() * 0.18);
+ this._overlayFontDescription = fontDescription;
},
draw: function(cr, x, y, width, height) {
@@ -72,14 +76,62 @@ const CharacterListRow = new Lang.Class({
let cellSize = getCellSize(this._fontDescription);
for (let i in this._characters) {
layout.set_text(this._characters[i], -1);
- let layoutBaseline = layout.get_baseline() / Pango.SCALE;
- let [logicalRect, inkRect] = layout.get_extents();
- cr.moveTo(x + cellSize * i - logicalRect.x / Pango.SCALE +
- (cellSize - logicalRect.width / Pango.SCALE) / 2,
- y + BASELINE_OFFSET * height - layoutBaseline);
- PangoCairo.show_layout(cr, layout);
+ if (Gc.character_is_invisible (this._characters[i])) {
+ this._drawOverlay(cr, x + cellSize * i, y, cellSize, cellSize,
+ this._characters[i]);
+ } else {
+ let layoutBaseline = layout.get_baseline();
+ let [logicalRect, inkRect] = layout.get_extents();
+ cr.moveTo(x + cellSize * i - logicalRect.x / Pango.SCALE +
+ (cellSize - logicalRect.width / Pango.SCALE) / 2,
+ y + BASELINE_OFFSET * height -
+ layoutBaseline / Pango.SCALE);
+ PangoCairo.show_layout(cr, layout);
+ }
}
},
+
+ _drawOverlay: function(cr, x, y, width, height, uc) {
+ cr.save();
+ cr.rectangle(x, y, width, height);
+ cr.clip();
+
+ // Draw character shape as a gray rectangle.
+ let layout = PangoCairo.create_layout(cr);
+ layout.set_text(uc, -1);
+ layout.set_font_description(this._fontDescription);
+ let layoutBaseline = layout.get_baseline();
+ let [logicalRect, inkRect] = layout.get_extents();
+ let x0 = x - inkRect.x / Pango.SCALE +
+ (width - inkRect.width / Pango.SCALE) / 2;
+ let y0 = y + BASELINE_OFFSET * height - layoutBaseline / Pango.SCALE;
+ let borderWidth = 1;
+ cr.rectangle(x0 - borderWidth * 2,
+ y0 - borderWidth * 2,
+ inkRect.width / Pango.SCALE + borderWidth * 2,
+ inkRect.height / Pango.SCALE + borderWidth * 2);
+ cr.setSourceRGBA(239.0 / 255.0, 239.0 / 255.0, 239.0 / 255.0, 1.0);
+ cr.fill();
+
+ // Draw character name.
+ layout.set_width(width * Pango.SCALE * 0.8);
+ layout.set_height(height * Pango.SCALE * 0.8);
+ layout.set_wrap(Pango.WrapMode.WORD);
+ layout.set_ellipsize(Pango.EllipsizeMode.END);
+ layout.set_alignment(Pango.Alignment.CENTER);
+ layout.set_font_description(this._overlayFontDescription);
+ var name = Gc.character_name(uc);
+ layout.set_text(Util.capitalize(name), -1);
+ let [logicalRect, inkRect] = layout.get_extents();
+ cr.moveTo(x - logicalRect.x / Pango.SCALE +
+ (width - logicalRect.width / Pango.SCALE) / 2,
+ y - logicalRect.y / Pango.SCALE +
+ (height - logicalRect.height / Pango.SCALE) / 2);
+ cr.setSourceRGBA(0.0, 0.0, 0.0, 1.0);
+ PangoCairo.show_layout(cr, layout);
+
+ cr.restore();
+ }
});
const CharacterListWidget = new Lang.Class({
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]