[gtk/pango2] fontexplorer: Add a style tab



commit 8ebc9418e8371002815b47bf7c889aa50f79e84f
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jul 10 11:40:25 2022 -0400

    fontexplorer: Add a style tab
    
    This shows named instances, if they exist.

 demos/font-explorer/fontexplorer.css           |   3 +
 demos/font-explorer/fontexplorer.gresource.xml |   1 +
 demos/font-explorer/fontexplorerwin.c          |   6 +
 demos/font-explorer/fontexplorerwin.ui         |  28 ++
 demos/font-explorer/meson.build                |   1 +
 demos/font-explorer/styleview.c                | 439 +++++++++++++++++++++++++
 demos/font-explorer/styleview.h                |  14 +
 demos/font-explorer/styleview.ui               |  31 ++
 8 files changed, 523 insertions(+)
---
diff --git a/demos/font-explorer/fontexplorer.css b/demos/font-explorer/fontexplorer.css
index 4bbb9cb017..fc9db747a5 100644
--- a/demos/font-explorer/fontexplorer.css
+++ b/demos/font-explorer/fontexplorer.css
@@ -20,6 +20,9 @@ plainview .content {
 waterfallview .content {
   padding: 20px;
 }
+styleview .content {
+  padding: 20px;
+}
 glyphsview .content {
   padding: 20px;
 }
diff --git a/demos/font-explorer/fontexplorer.gresource.xml b/demos/font-explorer/fontexplorer.gresource.xml
index 052a0475e2..8c22c50c30 100644
--- a/demos/font-explorer/fontexplorer.gresource.xml
+++ b/demos/font-explorer/fontexplorer.gresource.xml
@@ -12,6 +12,7 @@
     <file preprocess="xml-stripblanks">rangeedit.ui</file>
     <file preprocess="xml-stripblanks">samplechooser.ui</file>
     <file preprocess="xml-stripblanks">sampleeditor.ui</file>
+    <file preprocess="xml-stripblanks">styleview.ui</file>
     <file preprocess="xml-stripblanks">waterfallview.ui</file>
     <file>fontexplorer.css</file>
   </gresource>
diff --git a/demos/font-explorer/fontexplorerwin.c b/demos/font-explorer/fontexplorerwin.c
index ed53f98e11..934b48974d 100644
--- a/demos/font-explorer/fontexplorerwin.c
+++ b/demos/font-explorer/fontexplorerwin.c
@@ -10,6 +10,7 @@
 #include "plainview.h"
 #include "samplechooser.h"
 #include "sampleeditor.h"
+#include "styleview.h"
 #include "waterfallview.h"
 
 #include <gtk/gtk.h>
@@ -31,6 +32,7 @@ struct _FontExplorerWindow
   GtkStack *stack;
   GtkToggleButton *plain_toggle;
   GtkToggleButton *waterfall_toggle;
+  GtkToggleButton *style_toggle;
   GtkToggleButton *glyphs_toggle;
   GtkToggleButton *info_toggle;
   GtkToggleButton *edit_toggle;
@@ -113,6 +115,8 @@ update_view (GtkToggleButton    *button,
     gtk_stack_set_visible_child_name (self->stack, "plain");
   else if (gtk_toggle_button_get_active (self->waterfall_toggle))
     gtk_stack_set_visible_child_name (self->stack, "waterfall");
+  else if (gtk_toggle_button_get_active (self->style_toggle))
+    gtk_stack_set_visible_child_name (self->stack, "style");
   else if (gtk_toggle_button_get_active (self->glyphs_toggle))
     gtk_stack_set_visible_child_name (self->stack, "glyphs");
   else if (gtk_toggle_button_get_active (self->info_toggle))
@@ -189,6 +193,7 @@ font_explorer_window_class_init (FontExplorerWindowClass *class)
   g_type_ensure (PLAIN_VIEW_TYPE);
   g_type_ensure (SAMPLE_CHOOSER_TYPE);
   g_type_ensure (SAMPLE_EDITOR_TYPE);
+  g_type_ensure (STYLE_VIEW_TYPE);
   g_type_ensure (WATERFALL_VIEW_TYPE);
 
   object_class->set_property = font_explorer_window_set_property;
@@ -215,6 +220,7 @@ font_explorer_window_class_init (FontExplorerWindowClass *class)
   gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, stack);
   gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, plain_toggle);
   gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, waterfall_toggle);
+  gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, style_toggle);
   gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, glyphs_toggle);
   gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, info_toggle);
   gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, edit_toggle);
diff --git a/demos/font-explorer/fontexplorerwin.ui b/demos/font-explorer/fontexplorerwin.ui
index eac3ca3b81..235829a159 100644
--- a/demos/font-explorer/fontexplorerwin.ui
+++ b/demos/font-explorer/fontexplorerwin.ui
@@ -46,6 +46,14 @@
                 <signal name="toggled" handler="update_view"/>
               </object>
             </child>
+            <child>
+              <object class="GtkToggleButton" id="style_toggle">
+                <property name="label">Styles</property>
+                <property name="group">plain_toggle</property>
+                <property name="sensitive" bind-source="styleview" bind-property="has-styles" 
bind-flags="sync-create"/>
+                <signal name="toggled" handler="update_view"/>
+              </object>
+            </child>
             <child>
               <object class="GtkToggleButton" id="glyphs_toggle">
                 <property name="label">Glyphs</property>
@@ -179,6 +187,26 @@
                 </property>
               </object>
             </child>
+            <child>
+              <object class="GtkStackPage">
+                <property name="name">style</property>
+                <property name="child">
+                  <object class="StyleView" id="styleview">
+                    <property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
+                    <property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
+                    <property name="size" bind-source="controls" bind-flags="sync-create"/>
+                    <property name="letterspacing" bind-source="controls" bind-flags="sync-create"/>
+                    <property name="line-height" bind-source="controls" bind-flags="sync-create"/>
+                    <property name="foreground" bind-source="controls" bind-flags="sync-create"/>
+                    <property name="background" bind-source="controls" bind-flags="sync-create"/>
+                    <property name="sample-text" bind-source="sampleeditor" bind-flags="sync-create"/>
+                    <property name="features" bind-source="features" bind-flags="sync-create"/>
+                    <property name="variations" bind-source="variations" bind-flags="sync-create"/>
+                    <property name="palette" bind-source="colors" bind-flags="sync-create"/>
+                  </object>
+                </property>
+              </object>
+            </child>
             <child>
               <object class="GtkStackPage">
                 <property name="name">glyphs</property>
diff --git a/demos/font-explorer/meson.build b/demos/font-explorer/meson.build
index d08eebac1e..1d7e07b497 100644
--- a/demos/font-explorer/meson.build
+++ b/demos/font-explorer/meson.build
@@ -16,6 +16,7 @@ fontexplorer_sources = [
   'rangeedit.c',
   'samplechooser.c',
   'sampleeditor.c',
+  'styleview.c',
   'waterfallview.c',
 ]
 
diff --git a/demos/font-explorer/styleview.c b/demos/font-explorer/styleview.c
new file mode 100644
index 0000000000..97f91f4272
--- /dev/null
+++ b/demos/font-explorer/styleview.c
@@ -0,0 +1,439 @@
+#include "styleview.h"
+#include "glyphitem.h"
+#include "glyphmodel.h"
+#include "glyphview.h"
+#include <gtk/gtk.h>
+
+#include <hb-ot.h>
+
+enum {
+  PROP_FONT_MAP = 1,
+  PROP_FONT_DESC,
+  PROP_SIZE,
+  PROP_LETTERSPACING,
+  PROP_LINE_HEIGHT,
+  PROP_FOREGROUND,
+  PROP_BACKGROUND,
+  PROP_VARIATIONS,
+  PROP_FEATURES,
+  PROP_PALETTE,
+  PROP_SAMPLE_TEXT,
+  PROP_HAS_STYLES,
+  NUM_PROPERTIES
+};
+
+static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
+
+struct _StyleView
+{
+  GtkWidget parent;
+
+  GtkLabel *content;
+  GtkScrolledWindow *swin;
+
+  Pango2FontMap *font_map;
+  Pango2FontDescription *font_desc;
+  float size;
+  char *variations;
+  char *features;
+  char *palette;
+  GQuark palette_quark;
+  int letterspacing;
+  float line_height;
+  GdkRGBA foreground;
+  GdkRGBA background;
+  GtkCssProvider *bg_provider;
+  char *sample_text;
+  gboolean has_styles;
+};
+
+struct _StyleViewClass
+{
+  GtkWidgetClass parent_class;
+};
+
+G_DEFINE_TYPE(StyleView, style_view, GTK_TYPE_WIDGET);
+
+static void
+style_view_init (StyleView *self)
+{
+  self->font_map = g_object_ref (pango2_font_map_get_default ());
+  self->font_desc = pango2_font_description_from_string ("sans 12");
+  self->size = 12.;
+  self->letterspacing = 0;
+  self->line_height = 1.;
+  self->variations = g_strdup ("");
+  self->features = g_strdup ("");
+  self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
+  self->palette_quark = g_quark_from_string (self->palette);
+  self->foreground = (GdkRGBA){0., 0., 0., 1. };
+  self->background = (GdkRGBA){1., 1., 1., 1. };
+  self->sample_text = g_strdup ("Some sample text is better than other sample text");
+  self->has_styles = FALSE;
+
+  gtk_widget_set_layout_manager (GTK_WIDGET (self),
+                                 gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  self->bg_provider = gtk_css_provider_new ();
+  gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (self->content)),
+                                  GTK_STYLE_PROVIDER (self->bg_provider), 800);
+}
+
+static void
+style_view_dispose (GObject *object)
+{
+  gtk_widget_clear_template (GTK_WIDGET (object), STYLE_VIEW_TYPE);
+
+  G_OBJECT_CLASS (style_view_parent_class)->dispose (object);
+}
+
+static void
+style_view_finalize (GObject *object)
+{
+  StyleView *self = STYLE_VIEW (object);
+
+  g_clear_object (&self->font_map);
+  pango2_font_description_free (self->font_desc);
+  g_free (self->variations);
+  g_free (self->features);
+  g_free (self->palette);
+
+  G_OBJECT_CLASS (style_view_parent_class)->finalize (object);
+}
+
+static Pango2Font *
+get_font (StyleView *self)
+{
+  Pango2Context *context;
+  Pango2FontDescription *desc;
+  Pango2Font *font;
+
+  context = pango2_context_new_with_font_map (self->font_map);
+  desc = pango2_font_description_copy_static (self->font_desc);
+  pango2_font_description_set_variations (desc, self->variations);
+  pango2_font_description_set_size (desc, self->size * PANGO2_SCALE);
+  font = pango2_context_load_font (context, desc);
+  pango2_font_description_free (desc);
+  g_object_unref (context);
+
+  return font;
+}
+
+static void
+update_has_styles (StyleView *self)
+{
+  Pango2Font *font = get_font (self);
+  hb_face_t *hb_face = hb_font_get_face (pango2_font_get_hb_font (font));
+  gboolean has_styles;
+
+  has_styles = hb_ot_var_get_named_instance_count (hb_face) > 0;
+  g_object_unref (font);
+
+  if (self->has_styles == has_styles)
+    return;
+
+  self->has_styles = has_styles;
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HAS_STYLES]);
+}
+
+static void
+update_view (StyleView *self)
+{
+  Pango2FontDescription *desc;
+  Pango2AttrList *attrs;
+  char *fg, *bg, *css;
+  GString *str;
+  int start, end, text_len;
+  Pango2Font *font = get_font (self);
+  hb_face_t *hb_face = hb_font_get_face (pango2_font_get_hb_font (font));
+  unsigned int n_axes;
+  float *coords = NULL;
+  hb_ot_var_axis_info_t *axes;
+
+  desc = pango2_font_description_copy_static (self->font_desc);
+  pango2_font_description_set_variations (desc, self->variations);
+  pango2_font_description_set_size (desc, self->size * PANGO2_SCALE);
+
+  attrs = pango2_attr_list_new ();
+  pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
+  pango2_attr_list_insert (attrs, pango2_attr_letter_spacing_new (self->letterspacing));
+  pango2_attr_list_insert (attrs, pango2_attr_line_height_new (self->line_height));
+  pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&(Pango2Color){65535 * self->foreground.red,
+                                                                             65535 * self->foreground.green,
+                                                                             65535 * self->foreground.blue,
+                                                                             65535 * 
self->foreground.alpha}));
+  pango2_attr_list_insert (attrs, pango2_attr_font_features_new (self->features));
+  pango2_attr_list_insert (attrs, pango2_attr_palette_new (self->palette));
+
+  str = g_string_new ("");
+  start = 0;
+  text_len = strlen (self->sample_text);
+
+  n_axes = hb_ot_var_get_axis_count (hb_face);
+  axes = g_newa (hb_ot_var_axis_info_t, n_axes);
+  hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, axes);
+  coords = g_newa (float, n_axes);
+
+  for (int i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
+    {
+      unsigned int n_coords = n_axes;
+      Pango2Attribute *attr;
+      GString *variations;
+
+      hb_ot_var_named_instance_get_design_coords (hb_face, i, &n_coords, coords);
+      variations = g_string_new ("");
+      for (int j = 0; j < n_axes; j++)
+        {
+          char buf[5] = { 0, };
+
+          if (variations->len > 0)
+            g_string_append_c (variations, ',');
+          hb_tag_to_string (axes[j].tag, buf);
+          g_string_append_printf (variations, "%s=%f", buf, coords[j]);
+        }
+
+      g_string_append (str, self->sample_text);
+      g_string_append (str, "
"); /* Unicode line separator */
+      end = start + text_len + strlen ("
");
+
+      pango2_font_description_set_variations (desc, variations->str);
+      g_string_free (variations, TRUE);
+
+      attr = pango2_attr_font_desc_new (desc);
+      pango2_attribute_set_range (attr, start, end);
+      pango2_attr_list_insert (attrs, attr);
+      start = end;
+    }
+
+  gtk_label_set_text (self->content, str->str);
+  gtk_label_set_attributes (self->content, attrs);
+  g_string_free (str, TRUE);
+
+  pango2_attr_list_unref (attrs);
+  pango2_font_description_free (desc);
+
+  fg = gdk_rgba_to_string (&self->foreground);
+  bg = gdk_rgba_to_string (&self->background);
+  css = g_strdup_printf (".content { caret-color: %s; background-color: %s; }", fg, bg);
+  gtk_css_provider_load_from_data (self->bg_provider, css, strlen (css));
+  g_free (css);
+  g_free (fg);
+  g_free (bg);
+
+  g_object_unref (font);
+}
+
+static void
+style_view_set_property (GObject      *object,
+                         guint         prop_id,
+                         const GValue *value,
+                         GParamSpec   *pspec)
+{
+  StyleView *self = STYLE_VIEW (object);
+
+  switch (prop_id)
+    {
+    case PROP_FONT_MAP:
+      g_set_object (&self->font_map, g_value_get_object (value));
+      gtk_widget_set_font_map (GTK_WIDGET (self->content), self->font_map);
+      update_has_styles (self);
+      break;
+
+    case PROP_FONT_DESC:
+      pango2_font_description_free (self->font_desc);
+      self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
+      update_has_styles (self);
+      break;
+
+    case PROP_SIZE:
+      self->size = g_value_get_float (value);
+      break;
+
+    case PROP_LETTERSPACING:
+      self->letterspacing = g_value_get_int (value);
+      break;
+
+    case PROP_LINE_HEIGHT:
+      self->line_height = g_value_get_float (value);
+      break;
+
+    case PROP_FOREGROUND:
+      self->foreground = *(GdkRGBA *)g_value_get_boxed (value);
+      break;
+
+    case PROP_BACKGROUND:
+      self->background = *(GdkRGBA *)g_value_get_boxed (value);
+      break;
+
+    case PROP_VARIATIONS:
+      g_free (self->variations);
+      self->variations = g_strdup (g_value_get_string (value));
+      break;
+
+    case PROP_FEATURES:
+      g_free (self->features);
+      self->features = g_strdup (g_value_get_string (value));
+      break;
+
+    case PROP_PALETTE:
+      g_free (self->palette);
+      self->palette = g_strdup (g_value_get_string (value));
+      self->palette_quark = g_quark_from_string (self->palette);
+      break;
+
+    case PROP_SAMPLE_TEXT:
+      g_free (self->sample_text);
+      self->sample_text = g_strdup (g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+
+  update_view (self);
+}
+
+static void
+style_view_get_property (GObject    *object,
+                         guint       prop_id,
+                         GValue     *value,
+                         GParamSpec *pspec)
+{
+  StyleView *self = STYLE_VIEW (object);
+
+  switch (prop_id)
+    {
+    case PROP_FONT_MAP:
+      g_value_set_object (value, self->font_map);
+      break;
+
+    case PROP_FONT_DESC:
+      g_value_set_boxed (value, self->font_desc);
+      break;
+
+    case PROP_SIZE:
+      g_value_set_float (value, self->size);
+      break;
+
+    case PROP_LETTERSPACING:
+      g_value_set_int (value, self->letterspacing);
+      break;
+
+    case PROP_LINE_HEIGHT:
+      g_value_set_float (value, self->line_height);
+      break;
+
+    case PROP_FOREGROUND:
+      g_value_set_boxed (value, &self->foreground);
+      break;
+
+    case PROP_BACKGROUND:
+      g_value_set_boxed (value, &self->background);
+      break;
+
+    case PROP_VARIATIONS:
+      g_value_set_string (value, self->variations);
+      break;
+
+    case PROP_FEATURES:
+      g_value_set_string (value, self->features);
+      break;
+
+    case PROP_PALETTE:
+      g_value_set_string (value, self->palette);
+      break;
+
+    case PROP_SAMPLE_TEXT:
+      g_value_set_string (value, self->sample_text);
+      break;
+
+    case PROP_HAS_STYLES:
+      g_value_set_boolean (value, self->has_styles);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+style_view_class_init (StyleViewClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->dispose = style_view_dispose;
+  object_class->finalize = style_view_finalize;
+  object_class->get_property = style_view_get_property;
+  object_class->set_property = style_view_set_property;
+
+  properties[PROP_FONT_MAP] =
+      g_param_spec_object ("font-map", "", "",
+                           PANGO2_TYPE_FONT_MAP,
+                           G_PARAM_READWRITE);
+
+  properties[PROP_FONT_DESC] =
+      g_param_spec_boxed ("font-desc", "", "",
+                          PANGO2_TYPE_FONT_DESCRIPTION,
+                          G_PARAM_READWRITE);
+
+  properties[PROP_SIZE] =
+      g_param_spec_float ("size", "", "",
+                          0., 100., 12.,
+                          G_PARAM_READWRITE);
+
+  properties[PROP_LETTERSPACING] =
+      g_param_spec_int ("letterspacing", "", "",
+                        -G_MAXINT, G_MAXINT, 0,
+                        G_PARAM_READWRITE);
+
+  properties[PROP_LINE_HEIGHT] =
+      g_param_spec_float ("line-height", "", "",
+                          0., 100., 1.,
+                          G_PARAM_READWRITE);
+
+  properties[PROP_FOREGROUND] =
+      g_param_spec_boxed ("foreground", "", "",
+                          GDK_TYPE_RGBA,
+                          G_PARAM_READWRITE);
+
+  properties[PROP_BACKGROUND] =
+      g_param_spec_boxed ("background", "", "",
+                          GDK_TYPE_RGBA,
+                          G_PARAM_READWRITE);
+
+  properties[PROP_VARIATIONS] =
+      g_param_spec_string ("variations", "", "",
+                           "",
+                           G_PARAM_READWRITE);
+
+  properties[PROP_FEATURES] =
+      g_param_spec_string ("features", "", "",
+                           "",
+                           G_PARAM_READWRITE);
+
+  properties[PROP_PALETTE] =
+      g_param_spec_string ("palette", "", "",
+                           PANGO2_COLOR_PALETTE_DEFAULT,
+                           G_PARAM_READWRITE);
+
+  properties[PROP_SAMPLE_TEXT] =
+      g_param_spec_string ("sample-text", "", "",
+                           "",
+                           G_PARAM_READWRITE);
+
+  properties[PROP_HAS_STYLES] =
+      g_param_spec_boolean ("has-styles", "", "",
+                            FALSE,
+                            G_PARAM_READABLE);
+
+  g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gtk/fontexplorer/styleview.ui");
+
+  gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), StyleView, swin);
+  gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), StyleView, content);
+
+  gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "styleview");
+}
diff --git a/demos/font-explorer/styleview.h b/demos/font-explorer/styleview.h
new file mode 100644
index 0000000000..71eccecfd8
--- /dev/null
+++ b/demos/font-explorer/styleview.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <gtk/gtk.h>
+
+
+#define STYLE_VIEW_TYPE (style_view_get_type ())
+#define STYLE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STYLE_VIEW_TYPE, StyleView))
+
+
+typedef struct _StyleView         StyleView;
+typedef struct _StyleViewClass    StyleViewClass;
+
+
+GType           style_view_get_type     (void);
diff --git a/demos/font-explorer/styleview.ui b/demos/font-explorer/styleview.ui
new file mode 100644
index 0000000000..863a5114b8
--- /dev/null
+++ b/demos/font-explorer/styleview.ui
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="StyleView" parent="GtkWidget">
+    <property name="hexpand">1</property>
+    <property name="vexpand">1</property>
+    <style>
+      <class name="view"/>
+    </style>
+    <child>
+      <object class="GtkScrolledWindow" id="swin">
+        <property name="hscrollbar-policy">automatic</property>
+        <property name="vscrollbar-policy">automatic</property>
+        <child>
+          <object class="GtkLabel" id="content">
+            <property name="label">Content</property>
+            <property name="wrap">0</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+            <property name="hexpand">1</property>
+            <property name="vexpand">1</property>
+            <property name="halign">fill</property>
+            <property name="valign">fill</property>
+            <style>
+              <class name="content"/>
+            </style>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]