Spaces:
Running
Running
/* | |
* Copyright (C) 2007 Carlos Garcia Campos <[email protected]> | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation; either version 2, or (at your option) | |
* any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. | |
*/ | |
enum | |
{ | |
FONTS_NAME_COLUMN, | |
FONTS_DETAILS_COLUMN, | |
N_COLUMNS | |
}; | |
typedef struct | |
{ | |
PopplerDocument *doc; | |
GtkWidget *treeview; | |
GtkWidget *progress; | |
guint idle_id; | |
} PgdFontsDemo; | |
static void pgd_fonts_free(PgdFontsDemo *demo) | |
{ | |
if (!demo) { | |
return; | |
} | |
if (demo->idle_id > 0) { | |
g_source_remove(demo->idle_id); | |
demo->idle_id = 0; | |
} | |
if (demo->doc) { | |
g_object_unref(demo->doc); | |
demo->doc = NULL; | |
} | |
g_free(demo); | |
} | |
static void pdg_fonts_cell_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) | |
{ | |
char *name; | |
char *details; | |
char *markup; | |
gtk_tree_model_get(model, iter, FONTS_NAME_COLUMN, &name, FONTS_DETAILS_COLUMN, &details, -1); | |
if (details) { | |
markup = g_strdup_printf("<b><big>%s</big></b>\n<small>%s</small>", name, details); | |
} else { | |
markup = g_strdup_printf("<b><big>%s</big></b>", name); | |
} | |
g_object_set(renderer, "markup", markup, NULL); | |
g_free(markup); | |
g_free(details); | |
g_free(name); | |
} | |
static const gchar *font_type_to_string(PopplerFontType type) | |
{ | |
switch (type) { | |
case POPPLER_FONT_TYPE_TYPE1: | |
return "Type 1"; | |
case POPPLER_FONT_TYPE_TYPE1C: | |
return "Type 1C"; | |
case POPPLER_FONT_TYPE_TYPE3: | |
return "Type 3"; | |
case POPPLER_FONT_TYPE_TRUETYPE: | |
return "TrueType"; | |
case POPPLER_FONT_TYPE_CID_TYPE0: | |
return "Type 1 (CID)"; | |
case POPPLER_FONT_TYPE_CID_TYPE0C: | |
return "Type 1C (CID)"; | |
case POPPLER_FONT_TYPE_CID_TYPE2: | |
return "TrueType (CID)"; | |
default: | |
return "Unknown font type"; | |
} | |
} | |
static void pgd_fonts_update_progress(PgdFontsDemo *demo, gint n_pages, gint scanned) | |
{ | |
gchar *str; | |
str = g_strdup_printf("Scanning fonts (%d%%)", MIN(scanned * 100 / n_pages, 100)); | |
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(demo->progress), str); | |
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(demo->progress), MIN((gdouble)scanned / n_pages, 1.0)); | |
g_free(str); | |
} | |
static gboolean pgd_fonts_fill_model(PgdFontsDemo *demo) | |
{ | |
GtkTreeModel *model; | |
PopplerFontInfo *font_info; | |
PopplerFontsIter *fonts_iter; | |
gint n_pages, scanned = 0; | |
n_pages = poppler_document_get_n_pages(demo->doc); | |
model = gtk_tree_view_get_model(GTK_TREE_VIEW(demo->treeview)); | |
g_object_ref(model); | |
gtk_list_store_clear(GTK_LIST_STORE(model)); | |
font_info = poppler_font_info_new(demo->doc); | |
while (poppler_font_info_scan(font_info, 20, &fonts_iter)) { | |
pgd_fonts_update_progress(demo, n_pages, scanned); | |
while (gtk_events_pending()) { | |
gtk_main_iteration(); | |
} | |
scanned += 20; | |
if (!fonts_iter) { | |
continue; | |
} | |
do { | |
GtkTreeIter iter; | |
const gchar *name; | |
const gchar *type; | |
const gchar *embedded; | |
const gchar *substitute; | |
const gchar *filename; | |
const gchar *encoding; | |
gchar *details; | |
name = poppler_fonts_iter_get_name(fonts_iter); | |
if (!name) { | |
name = "No name"; | |
} | |
encoding = poppler_fonts_iter_get_encoding(fonts_iter); | |
if (!encoding) { | |
encoding = "None"; | |
} | |
type = font_type_to_string(poppler_fonts_iter_get_font_type(fonts_iter)); | |
if (poppler_fonts_iter_is_embedded(fonts_iter)) { | |
if (poppler_fonts_iter_is_subset(fonts_iter)) { | |
embedded = "Embedded subset"; | |
} else { | |
embedded = "Embedded"; | |
} | |
} else { | |
embedded = "Not embedded"; | |
} | |
substitute = poppler_fonts_iter_get_substitute_name(fonts_iter); | |
filename = poppler_fonts_iter_get_file_name(fonts_iter); | |
if (substitute && filename) { | |
details = g_markup_printf_escaped("%s\nEncoding: %s\n%s, substituting with <b>%s</b>\n(%s)", type, encoding, embedded, substitute, filename); | |
} else { | |
details = g_markup_printf_escaped("%s\nEncoding: %s\n%s", type, encoding, embedded); | |
} | |
gtk_list_store_append(GTK_LIST_STORE(model), &iter); | |
gtk_list_store_set(GTK_LIST_STORE(model), &iter, FONTS_NAME_COLUMN, name, FONTS_DETAILS_COLUMN, details, -1); | |
g_free(details); | |
} while (poppler_fonts_iter_next(fonts_iter)); | |
poppler_fonts_iter_free(fonts_iter); | |
} | |
pgd_fonts_update_progress(demo, n_pages, scanned); | |
g_object_unref(font_info); | |
g_object_unref(model); | |
return FALSE; | |
} | |
static void pgd_fonts_scan_button_clicked(GtkButton *button, PgdFontsDemo *demo) | |
{ | |
demo->idle_id = g_idle_add((GSourceFunc)pgd_fonts_fill_model, demo); | |
} | |
GtkWidget *pgd_fonts_create_widget(PopplerDocument *document) | |
{ | |
PgdFontsDemo *demo; | |
GtkWidget *vbox; | |
GtkListStore *model; | |
GtkCellRenderer *renderer; | |
GtkTreeViewColumn *column; | |
GtkWidget *swindow; | |
GtkWidget *hbox, *button; | |
demo = g_new0(PgdFontsDemo, 1); | |
demo->doc = g_object_ref(document); | |
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12); | |
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); | |
demo->progress = gtk_progress_bar_new(); | |
gtk_progress_bar_set_ellipsize(GTK_PROGRESS_BAR(demo->progress), PANGO_ELLIPSIZE_END); | |
gtk_box_pack_start(GTK_BOX(hbox), demo->progress, TRUE, TRUE, 0); | |
gtk_widget_show(demo->progress); | |
button = gtk_button_new_with_label("Scan"); | |
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(pgd_fonts_scan_button_clicked), (gpointer)demo); | |
gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
gtk_widget_show(button); | |
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 6); | |
gtk_widget_show(hbox); | |
swindow = gtk_scrolled_window_new(NULL, NULL); | |
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
model = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING); | |
demo->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); | |
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(demo->treeview), FALSE); | |
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(demo->treeview)), GTK_SELECTION_NONE); | |
g_object_unref(model); | |
column = gtk_tree_view_column_new(); | |
gtk_tree_view_append_column(GTK_TREE_VIEW(demo->treeview), column); | |
renderer = gtk_cell_renderer_text_new(); | |
gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), renderer, FALSE); | |
gtk_tree_view_column_set_cell_data_func(column, renderer, pdg_fonts_cell_data_func, NULL, NULL); | |
gtk_container_add(GTK_CONTAINER(swindow), demo->treeview); | |
gtk_widget_show(demo->treeview); | |
gtk_box_pack_start(GTK_BOX(vbox), swindow, TRUE, TRUE, 0); | |
gtk_widget_show(swindow); | |
g_object_weak_ref(G_OBJECT(swindow), (GWeakNotify)pgd_fonts_free, (gpointer)demo); | |
return vbox; | |
} | |