目录
  • 主要代码
    • 字面量以及数据结构
    • 定义一个回调函数,刷新福字
    • 应用初始化程序
    • 主程序
  • 效果展示

    快新年了,支付宝扫福活动又开始了,每次都要百度找福,这次不想找了,自己写一个程序生成各种字体的福字。

    主要代码

    字面量以及数据结构

    #define FONT_DISPLAY "福"
    
     // g_fu_label中的每一个控件都是一个福字
    static GtkWidget *g_fu_label[3][3];
    
    // 记录所有的字体family
    typedef struct {
        int n_faces;
        PangoFontFace **faces;
    }custom_PangoFontFace_t;
    
    //字体family 的总数
    static int n_families=0;
    
    //当前正在使用的family 字体的索引
    static int family_id=0;
    
    // 记录每个字体family中的face(字模)
    static custom_PangoFontFace_t *custom_PangoFontFace;
    

    定义一个回调函数,刷新福字

    static void
    change_fu_cb(GtkButton *button , gpointer user_data)
    {
        char *markup_fu_str = NULL;
        
        // 3*3 的矩阵中一共有9个福字,分别设置每个福字的字体
        for(int i=0;i<3;++i)
        {
            for(int j=0;j<3;++j)
            {
        		// 获取当前family中的下一个字模,如果当前family中的字模都是用了,自动更新family_id 指向下一个family
                if(family_id >= n_families) family_id=0;
                if(++face_id >= custom_PangoFontFace[family_id].n_faces){
                    ++family_id;
                    if(family_id >= n_families)
                        family_id=0;
                    
                    face_id = 0;
                }
                
                
                markup_fu_str = g_markup_printf_escaped("<span font-weight=\"Bold\" font_desc=\"%s 99\">%s</span>",
                        pango_font_description_to_string(pango_font_face_describe(custom_PangoFontFace[family_id].faces[0])),
                        FONT_DISPLAY);
                
                gtk_label_set_markup(GTK_LABEL(g_fu_label[i][j]),markup_fu_str);
        
                g_free(markup_fu_str);
            }
        }
    }
    

    应用初始化程序

    static void
    activate (GtkApplication* app,
              gpointer user_data)
    {
        GtkWidget *window;
        GtkWidget *mainGrid;
        GtkWidget *overlay;
        GtkWidget *picture;
    	GtkCssProvider *cssProvider;
    	const char *cssMainGrid = "grid {background-color:#ed3c43;}";
    	const char *cssButton = "* {background-color:#FF0000;}";
    	PangoFontMap *pangoFontMap;
    	GtkWidget *box;
    	GtkWidget *button;
    	
        window = gtk_application_window_new (app);
        gtk_window_set_title (GTK_WINDOW (window), "");
        gtk_window_set_default_size (GTK_WINDOW (window), 900, 900);
        
        mainGrid = gtk_grid_new();
        gtk_widget_set_hexpand(mainGrid,TRUE);
        gtk_widget_set_vexpand(mainGrid,TRUE);
        
        box = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
        gtk_widget_set_hexpand(box,TRUE);
        gtk_widget_set_vexpand(box,TRUE);
        gtk_box_append(GTK_BOX(box),mainGrid);
        
        button = gtk_button_new_with_label("换一批");
        gtk_widget_set_hexpand(button,TRUE);
        gtk_widget_set_vexpand(button,TRUE);
        cssProvider = gtk_css_provider_new();
        gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cssProvider),
                                        cssButton,
                                        -1);
        gtk_style_context_add_provider(gtk_widget_get_style_context(button),
                GTK_STYLE_PROVIDER(cssProvider),
                GTK_STYLE_PROVIDER_PRIORITY_USER);
        gtk_style_context_add_provider(gtk_widget_get_style_context(gtk_widget_get_first_child(button)),
                                       GTK_STYLE_PROVIDER(cssProvider),
                                       GTK_STYLE_PROVIDER_PRIORITY_USER);
        g_object_unref(cssProvider);
        g_signal_connect(button,"clicked",G_CALLBACK(change_fu_cb),NULL);
        gtk_box_append(GTK_BOX(box),button);
        
        gtk_window_set_child(GTK_WINDOW(window),box);
        
        cssProvider = gtk_css_provider_new();
        gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cssProvider),
                                        cssMainGrid,
                                        -1);
        gtk_style_context_add_provider(gtk_widget_get_style_context(mainGrid),
                GTK_STYLE_PROVIDER(cssProvider),
                GTK_STYLE_PROVIDER_PRIORITY_USER);
        g_object_unref(cssProvider);
        
        
        //获取当前系统中可用的字体 family
        PangoFontFamily **families;
        pangoFontMap = pango_cairo_font_map_get_default();
        pango_font_map_list_families(pangoFontMap,&families,&n_families);
        
        custom_PangoFontFace = (custom_PangoFontFace_t *)g_malloc0(n_families*sizeof(custom_PangoFontFace_t));
        
        for(int i=0;i<n_families;++i)
        {
        	//获取每个字体 family 中可用的face
            pango_font_family_list_faces(families[i],
                    &custom_PangoFontFace[i].faces,
                    &custom_PangoFontFace[i].n_faces);
        }
        g_free(families);
        
        // 初始化每个福字控件
        for(int i=0;i<3;++i)
        {
            for(int j=0;j<3;++j)
            {
                overlay = gtk_overlay_new();
                gtk_widget_set_hexpand(overlay,TRUE);
                gtk_widget_set_vexpand(overlay,TRUE);
                
                // 福字的背景图,需要放在执行程序所在的目录
                picture = gtk_picture_new_for_filename("./fu.png");
                gtk_widget_set_hexpand(picture,TRUE);
                gtk_widget_set_vexpand(picture,TRUE);
                
                g_fu_label[i][j] = gtk_label_new("");
                gtk_widget_set_hexpand(g_fu_label[i][j],TRUE);
                gtk_widget_set_vexpand(g_fu_label[i][j],TRUE);
                
                gtk_overlay_set_child(GTK_OVERLAY(overlay),picture);
                gtk_overlay_add_overlay(GTK_OVERLAY(overlay),g_fu_label[i][j]);
                
                gtk_grid_attach(GTK_GRID(mainGrid),overlay,i,j,1,1);
            }
        }
        
        //初始化福字
        change_fu_cb(GTK_BUTTON(button) , NULL);
        
        gtk_window_set_resizable(GTK_WINDOW(window),FALSE);
        gtk_widget_show (window);
    }
    

    主程序

    int
    main(int argc, char *argv[])
    {
        GtkApplication *app;
        int status;
    
        app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
        g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
        
        status = g_application_run (G_APPLICATION (app), argc, argv);
        g_object_unref (app);
        
        //释放资源
        for(int i=0;i<n_families;++i){
            g_free(custom_PangoFontFace[i].faces);
        }
        g_free(custom_PangoFontFace);
    
        return status;
    }
    

    效果展示

    C语言实现生成新春福字的示例详解

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。