|
| 1 | +/* |
| 2 | + * This program is free software; you can redistribute it and/or modify |
| 3 | + * it under the terms of the GNU General Public License as published by |
| 4 | + * the Free Software Foundation; either version 2 of the License, or |
| 5 | + * (at your option) any later version. |
| 6 | + * |
| 7 | + * This program is distributed in the hope that it will be useful, |
| 8 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 10 | + * GNU General Public License for more details. |
| 11 | + * |
| 12 | + * You should have received a copy of the GNU General Public License |
| 13 | + * along with this program; if not, write to the Free Software |
| 14 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
| 15 | + * MA 02110-1301, USA. |
| 16 | + * |
| 17 | + */ |
| 18 | +#include <stdio.h> |
| 19 | +#include <unistd.h> |
| 20 | + |
| 21 | +#include <cairo-svg.h> |
| 22 | +#include <pango/pangocairo.h> |
| 23 | + |
| 24 | +#define THIS_VERSION "0.0.1" |
| 25 | + |
| 26 | +void usage() { |
| 27 | + printf("mklabwall\n" |
| 28 | + "\t-f font[str]\n" |
| 29 | + "\t-s fontsize[int]\n" |
| 30 | + "\t-v font_vertical_position[int]\n" |
| 31 | + "\t-h font_horizontal_position[int]\n" |
| 32 | + "\t-n filename[str]\n" |
| 33 | + "\t-z fancy xD [no arg] (an easter egg!)\n" |
| 34 | + "\t-b background color[\"float float float\"]\n" |
| 35 | + "\t-p save as png [no arg - default is svg]\n" |
| 36 | + "\t-l logo only [no arg]\n" |
| 37 | + "\t-r resolution [\"int int\"]\n\n" |
| 38 | + "at least 1 option is required\n" |
| 39 | + "file is saved to \"HOME/labwcwall\" or \"HOME/myfile\" with -n [arg] option\n" |
| 40 | + "Version %s\n", THIS_VERSION); |
| 41 | + exit (EXIT_SUCCESS); |
| 42 | +} |
| 43 | + |
| 44 | +int main(int argc, char **argv) { |
| 45 | + if (argc < 2) { |
| 46 | + usage(); |
| 47 | + return 0; |
| 48 | + } |
| 49 | + char *res = NULL; |
| 50 | + char *font = "Sans"; |
| 51 | + char *bg = NULL; |
| 52 | + int f_size = 116; |
| 53 | + char *name = "labwcwall"; |
| 54 | + int fnt_vert = 32; |
| 55 | + int fnt_hor = 290; |
| 56 | + int zflag = 0; |
| 57 | + int pflag = 0; |
| 58 | + int lflag = 0; |
| 59 | + int d; |
| 60 | + while ((d = getopt (argc, argv, "r:f:b:s:n:v:h:zpl")) != -1) { |
| 61 | + switch (d) |
| 62 | + { |
| 63 | + case 'r': |
| 64 | + res = optarg; |
| 65 | + break; |
| 66 | + case 'f': |
| 67 | + font = optarg; |
| 68 | + break; |
| 69 | + case 'b': |
| 70 | + bg = optarg; |
| 71 | + break; |
| 72 | + case 's': |
| 73 | + f_size = atoi(optarg); |
| 74 | + break; |
| 75 | + case 'n': |
| 76 | + name = optarg; |
| 77 | + break; |
| 78 | + case 'v': |
| 79 | + fnt_vert = atoi(optarg); |
| 80 | + break; |
| 81 | + case 'h': |
| 82 | + fnt_hor = atoi(optarg); |
| 83 | + break; |
| 84 | + case 'z': |
| 85 | + zflag = 1; |
| 86 | + break; |
| 87 | + case 'p': |
| 88 | + pflag = 1; |
| 89 | + break; |
| 90 | + case 'l': |
| 91 | + lflag = 1; |
| 92 | + break; |
| 93 | + default: |
| 94 | + usage(); |
| 95 | + |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + /* resolution */ |
| 100 | + |
| 101 | + float w, h; |
| 102 | + if (!res) { |
| 103 | + w = 1366; |
| 104 | + h = 768; |
| 105 | + } else { |
| 106 | + char pre_w[8]; |
| 107 | + char pre_h[8]; |
| 108 | + int res_result = sscanf(res, "%s %s", pre_w, pre_h); |
| 109 | + if (res_result < 2) { |
| 110 | + fprintf(stderr,"ERROR: less than 2 x y resolution aguments!\n"); |
| 111 | + exit (EXIT_FAILURE); |
| 112 | + } |
| 113 | + w = atof(pre_w); |
| 114 | + h = atof(pre_h); |
| 115 | + } |
| 116 | + /* /resolution */ |
| 117 | + |
| 118 | + /* logo and text dims*/ |
| 119 | + int img_wdth = 600; |
| 120 | + int img_hght = 184; |
| 121 | + int xh = 0; |
| 122 | + if (zflag == 1) { |
| 123 | + xh = 52; |
| 124 | + img_hght = img_hght + xh; |
| 125 | + } |
| 126 | + if (lflag == 1) { |
| 127 | + img_wdth = 250; |
| 128 | + } |
| 129 | + /* /logo and text dims*/ |
| 130 | + |
| 131 | + /* file save name/fmt */ |
| 132 | + char destimg[PATH_MAX]; |
| 133 | + char *dest = getenv("HOME"); |
| 134 | + cairo_surface_t *cs; |
| 135 | + if (pflag == 0) { |
| 136 | + snprintf(destimg, sizeof(destimg), "%s/%s.svg", dest, name); |
| 137 | + cs = cairo_svg_surface_create(destimg, w, h); |
| 138 | + } else { |
| 139 | + cs = cairo_image_surface_create |
| 140 | + (CAIRO_FORMAT_ARGB32, w, h); |
| 141 | + snprintf(destimg, sizeof(destimg), "%s/%s.png", dest, name); |
| 142 | + } |
| 143 | + /* /file save name/fmt */ |
| 144 | + |
| 145 | + cairo_t *c; |
| 146 | + c = cairo_create(cs); |
| 147 | + |
| 148 | + /* icon and position */ |
| 149 | + if (!bg) { |
| 150 | + cairo_set_source_rgb (c, 0.05, 0.06, 0.09); /* default #0d1117 */ |
| 151 | + } else { |
| 152 | + float r, g , b; |
| 153 | + char red[8]; |
| 154 | + char green[8]; |
| 155 | + char blue[8]; |
| 156 | + int result = sscanf(bg, "%s %s %s", red, green, blue); |
| 157 | + if (result < 3) { |
| 158 | + fprintf(stderr,"ERROR: less than 3 colour aguments!\n"); |
| 159 | + exit (EXIT_FAILURE); |
| 160 | + } |
| 161 | + r = atof(red); |
| 162 | + g = atof(green); |
| 163 | + b = atof(blue); |
| 164 | + cairo_set_source_rgb (c, r, g, b); |
| 165 | + } |
| 166 | + cairo_rectangle(c, 0.0, 0.0, w, h); |
| 167 | + cairo_fill(c); |
| 168 | + |
| 169 | + /** The image and text size are hard coded to 600 * (184 + xh) |
| 170 | + * and the image only is hard coded to 250 * (184 + xh) |
| 171 | + * so just need to scale that to suit the resolution with a scale |
| 172 | + * factor. We'll use 1366 x 768 as 1:1, well 1366 anyway as to |
| 173 | + * account for different aspect ratios. |
| 174 | + * Then work out where to place the image and text in the centre |
| 175 | + * of our wallpaper |
| 176 | + */ |
| 177 | + |
| 178 | + float sf = w / 1366; |
| 179 | + printf("scale factor: %f\n", sf); |
| 180 | + float x_pos = w / 2; |
| 181 | + float y_pos = h / 2; |
| 182 | + float new_wdth = (float)img_wdth * sf; |
| 183 | + float new_hght = (float)img_hght * sf; |
| 184 | + x_pos = x_pos - (new_wdth / 2); |
| 185 | + y_pos = y_pos - (new_hght / 2); |
| 186 | + xh = (float)xh * sf; |
| 187 | + |
| 188 | + /* fancy */ |
| 189 | + if (zflag == 1) { |
| 190 | + cairo_set_source_rgba (c, 0.81, 0.18, 0.56, 0.3); |
| 191 | + cairo_move_to (c, x_pos + (102 * sf), y_pos + (24 * sf)); |
| 192 | + cairo_line_to (c, x_pos + (26 * sf), y_pos + (45 * sf)); |
| 193 | + cairo_curve_to (c, x_pos + (19 * sf), y_pos + (46 * sf), x_pos + (19 * sf), y_pos + (51 * sf), x_pos + (20 * sf), y_pos + (57 * sf)); |
| 194 | + cairo_line_to (c, x_pos + (31 * sf), y_pos + (146 * sf)); |
| 195 | + cairo_line_to (c, x_pos + (112 * sf),y_pos + (114 * sf)); |
| 196 | + cairo_line_to (c, x_pos + (112 * sf), y_pos + (28 * sf)); |
| 197 | + cairo_curve_to (c, x_pos + (111 * sf), y_pos + (24 * sf), x_pos + (107 * sf), y_pos + (23 * sf), x_pos + (102 * sf), y_pos + (24 * sf)); |
| 198 | + cairo_close_path (c); |
| 199 | + cairo_fill (c); |
| 200 | + |
| 201 | + cairo_set_source_rgba (c, 0.94, 0.84, 0.05, 0.3); |
| 202 | + cairo_move_to (c, x_pos + (131 * sf), y_pos + (24 * sf)); |
| 203 | + cairo_line_to (c, x_pos + (207 * sf), y_pos + (45 * sf)); |
| 204 | + cairo_curve_to (c, x_pos + (214 * sf), y_pos + (46 * sf), x_pos + (214 * sf), y_pos + (51 * sf), x_pos + (213 * sf), y_pos + (57 * sf)); |
| 205 | + cairo_line_to (c, x_pos + (201 * sf), y_pos + (146 * sf)); |
| 206 | + cairo_line_to (c, x_pos + (121 * sf), y_pos + (114 * sf)); |
| 207 | + cairo_line_to (c, x_pos + (121 * sf), y_pos + (28 * sf)); |
| 208 | + cairo_curve_to (c, x_pos + (122 * sf), y_pos + (24 * sf), x_pos + (126 * sf), y_pos + (23 * sf), x_pos + (131 * sf), y_pos + (24 * sf)); |
| 209 | + cairo_close_path (c); |
| 210 | + cairo_fill (c); |
| 211 | + } /* /fancy */ |
| 212 | + |
| 213 | + cairo_set_source_rgb (c, 0.94, 0.84, 0.05); |
| 214 | + cairo_set_line_cap (c, CAIRO_LINE_CAP_ROUND); |
| 215 | + cairo_set_line_join (c, CAIRO_LINE_JOIN_ROUND); |
| 216 | + |
| 217 | + cairo_move_to (c, x_pos + (7 * sf), y_pos + (6 * sf) + xh); |
| 218 | + cairo_line_to (c, x_pos + (106 * sf), y_pos + (64 * sf) + xh); |
| 219 | + cairo_line_to (c, x_pos + (106 * sf), y_pos + (178 * sf) + xh); |
| 220 | + cairo_line_to (c, x_pos + (24 * sf), y_pos + (113 * sf) + xh); |
| 221 | + cairo_line_to (c, x_pos + (7 * sf), y_pos + (6 * sf) + xh); |
| 222 | + cairo_close_path (c); |
| 223 | + cairo_fill(c); |
| 224 | + |
| 225 | + cairo_set_line_width (c, 12.0 * sf); |
| 226 | + cairo_move_to (c, x_pos + (7 * sf), y_pos + (6 * sf) + xh); |
| 227 | + cairo_line_to (c, x_pos + (106 * sf), y_pos + (64 * sf) + xh); |
| 228 | + cairo_line_to (c, x_pos + (106 * sf), y_pos + (178 * sf) + xh); |
| 229 | + cairo_line_to (c, x_pos + (24 * sf), y_pos + (113 * sf) + xh); |
| 230 | + cairo_line_to (c, x_pos + (7 * sf), y_pos + (6 * sf) + xh); |
| 231 | + cairo_close_path (c); |
| 232 | + cairo_stroke (c); |
| 233 | + |
| 234 | + cairo_set_source_rgb (c, 0.81, 0.18, 0.56); |
| 235 | + cairo_move_to (c, x_pos + (226 * sf), y_pos + (6 * sf) + xh); |
| 236 | + cairo_line_to (c, x_pos + (127 * sf), y_pos + (64 * sf) + xh); |
| 237 | + cairo_line_to (c, x_pos + (127 * sf), y_pos + (178 * sf) + xh); |
| 238 | + cairo_line_to (c, x_pos + (209 * sf), y_pos + (113 * sf) + xh); |
| 239 | + cairo_line_to (c, x_pos + (226 * sf), y_pos + (6 * sf) + xh); |
| 240 | + cairo_close_path (c); |
| 241 | + cairo_fill (c); |
| 242 | + |
| 243 | + cairo_move_to (c, x_pos + (226 * sf), y_pos + (6 * sf) + xh); |
| 244 | + cairo_line_to (c, x_pos + (127 * sf), y_pos + (64 * sf) + xh); |
| 245 | + cairo_line_to (c, x_pos + (127 * sf), y_pos + (178 * sf) + xh); |
| 246 | + cairo_line_to (c, x_pos + (209 * sf), y_pos + (113 * sf) + xh); |
| 247 | + cairo_line_to (c, x_pos + (226 * sf), y_pos + (6 * sf) + xh); |
| 248 | + cairo_close_path (c); |
| 249 | + cairo_stroke (c); |
| 250 | + |
| 251 | + if (lflag == 0) { |
| 252 | + /* font */ |
| 253 | + float rgb = 0.97; /* font color */ |
| 254 | + char *label = "labwc"; |
| 255 | + |
| 256 | + PangoLayout *layout; |
| 257 | + PangoFontDescription *font_description; |
| 258 | + |
| 259 | + font_description = pango_font_description_new (); |
| 260 | + pango_font_description_set_family (font_description, font); |
| 261 | + pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL ); /*PANGO_STYLE_NORMAL = 0, PANGO_STYLE_OBLIQUE = 1*/ |
| 262 | + pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL); /*PANGO_WEIGHT_NORMAL = 400, PANGO_WEIGHT_BOLD = 700*/ |
| 263 | + pango_font_description_set_absolute_size (font_description, f_size * sf * PANGO_SCALE); |
| 264 | + layout = pango_cairo_create_layout (c); |
| 265 | + pango_layout_set_font_description (layout, font_description); |
| 266 | + pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT); /*PANGO_ALIGN_LEFT, PANGO_ALIGN_CENTER, PANGO_ALIGN_RIGHT)*/ |
| 267 | + pango_layout_set_wrap (layout, PANGO_WRAP_WORD); |
| 268 | + pango_layout_set_text (layout, label, -1); |
| 269 | + |
| 270 | + /* position of text */ |
| 271 | + int xposi = x_pos + (fnt_hor * sf); |
| 272 | + int yposi = y_pos + (fnt_vert * sf) + xh; |
| 273 | + cairo_move_to (c, xposi , 1 * yposi); |
| 274 | + cairo_set_source_rgb (c, rgb, rgb, rgb); |
| 275 | + pango_cairo_show_layout (c, layout); |
| 276 | + pango_font_description_free (font_description); |
| 277 | + g_object_unref (layout); |
| 278 | + } |
| 279 | + cairo_status_t rest = cairo_surface_status(cs); |
| 280 | + const char *ret; |
| 281 | + ret = cairo_status_to_string (rest); |
| 282 | + if (rest != CAIRO_STATUS_SUCCESS) { |
| 283 | + cairo_surface_destroy (cs); |
| 284 | + cairo_destroy (c); |
| 285 | + fprintf (stderr, "Cairo : %s\n", ret); |
| 286 | + exit (EXIT_FAILURE); |
| 287 | + } |
| 288 | + /* cleanup */ |
| 289 | + cairo_surface_destroy (cs); |
| 290 | + cairo_destroy (c); |
| 291 | + fprintf (stdout, "image saved to %s\n", destimg); |
| 292 | + |
| 293 | + return 0; |
| 294 | +} |
0 commit comments