static av_cold int init(AVFilterContext *ctx) { int err; DrawTextContext *s = ctx->priv; Glyph *glyph; if ((err = parse_font(ctx)) < 0) return err; if (s->textfile) { uint8_t *textbuf; size_t textbuf_size; if (s->text) { av_log(ctx, AV_LOG_ERROR, "Both text and text file provided. Please provide only one\n"); return AVERROR(EINVAL); } if ((err = av_file_map(s->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) { av_log(ctx, AV_LOG_ERROR, "The text file '%s' could not be read or is empty\n", s->textfile); return err; } if (textbuf_size > SIZE_MAX - 1 || !(s->text = av_malloc(textbuf_size + 1))) { av_file_unmap(textbuf, textbuf_size); return AVERROR(ENOMEM); } memcpy(s->text, textbuf, textbuf_size); s->text[textbuf_size] = 0; av_file_unmap(textbuf, textbuf_size); } if (!s->text) { av_log(ctx, AV_LOG_ERROR, "Either text or a valid file must be provided\n"); return AVERROR(EINVAL); } if ((err = av_parse_color(s->fontcolor_rgba, s->fontcolor_string, -1, ctx))) { av_log(ctx, AV_LOG_ERROR, "Invalid font color '%s'\n", s->fontcolor_string); return err; } if ((err = av_parse_color(s->boxcolor_rgba, s->boxcolor_string, -1, ctx))) { av_log(ctx, AV_LOG_ERROR, "Invalid box color '%s'\n", s->boxcolor_string); return err; } if ((err = av_parse_color(s->shadowcolor_rgba, s->shadowcolor_string, -1, ctx))) { av_log(ctx, AV_LOG_ERROR, "Invalid shadow color '%s'\n", s->shadowcolor_string); return err; } if ((err = FT_Init_FreeType(&(s->library)))) { av_log(ctx, AV_LOG_ERROR, "Could not load FreeType: %s\n", FT_ERRMSG(err)); return AVERROR(EINVAL); } /* load the face, and set up the encoding, which is by default UTF-8 */ if ((err = FT_New_Face(s->library, s->fontfile, 0, &s->face))) { av_log(ctx, AV_LOG_ERROR, "Could not load fontface from file '%s': %s\n", s->fontfile, FT_ERRMSG(err)); return AVERROR(EINVAL); } if ((err = FT_Set_Pixel_Sizes(s->face, 0, s->fontsize))) { av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels: %s\n", s->fontsize, FT_ERRMSG(err)); return AVERROR(EINVAL); } s->use_kerning = FT_HAS_KERNING(s->face); /* load the fallback glyph with code 0 */ load_glyph(ctx, NULL, 0); /* set the tabsize in pixels */ if ((err = load_glyph(ctx, &glyph, ' ') < 0)) { av_log(ctx, AV_LOG_ERROR, "Could not set tabsize.\n"); return err; } s->tabsize *= glyph->advance; #if !HAVE_LOCALTIME_R av_log(ctx, AV_LOG_WARNING, "strftime() expansion unavailable!\n"); #endif return 0; }
status ws_create_font(FontObj f, DisplayObj d) { WsFont wsf = alloc(sizeof(ws_font)); #ifdef __WINDOWS__ int widths[FONTTABLESIZE]; #else short widths[FONTTABLESIZE]; #endif HDC hdc; HFONT old; int n; TEXTMETRIC tm; int stock; if ( sscanf(strName(f->x_name), STOCKFMT, &stock) == 1 ) { wsf->hfont = GetStockObject(stock); wsf->from_stock = TRUE; } else { LOGFONT lfont; Real scale = getClassVariableValueObject(f, NAME_scale); float fscale = (scale ? valReal(scale) : 1.4); memset(&lfont, 0, sizeof(lfont)); lfont.lfHeight = (int)((float) valInt(f->points) * fscale); lfont.lfWeight = (f->style == NAME_bold ? FW_BOLD : FW_NORMAL); lfont.lfItalic = ((f->style == NAME_italic || f->style == NAME_oblique) ? 1 : 0); lfont.lfPitchAndFamily = (f->family == NAME_screen ? FIXED_PITCH : DEFAULT_PITCH); lfont.lfPitchAndFamily |= (f->family == NAME_helvetica ? FF_SWISS : f->family == NAME_times ? FF_ROMAN : f->family == NAME_screen ? FF_MODERN : FF_DONTCARE); if ( f->family == NAME_symbol ) strcpy(lfont.lfFaceName, "symbol"); if ( instanceOfObject(f->x_name, ClassCharArray) ) { strcpy(lfont.lfFaceName, strName(f->family)); parse_font(strName(f->x_name), &lfont); } else { lfont.lfOutPrecision = OUT_TT_ONLY_PRECIS; lfont.lfQuality = PROOF_QUALITY; } if ( !(wsf->hfont = CreateFontIndirect(&lfont)) ) { Cprintf("Failed to create logical font; replacing with stock font\n"); if ( f->family == NAME_screen ) { if ( f->style == NAME_bold ) stock = SYSTEM_FIXED_FONT; else stock = ANSI_FIXED_FONT; } else { if ( f->style == NAME_bold ) stock = SYSTEM_FONT; else stock = ANSI_VAR_FONT; } wsf->hfont = GetStockObject(stock); wsf->from_stock = TRUE; } else wsf->from_stock = FALSE; } wsf->widths = alloc(FONTTABLESIZE * sizeof(cwidth)); assign(f, iswide, OFF); hdc = GetDC(NULL); old = SelectObject(hdc, wsf->hfont); GetCharWidth(hdc, 0, FONTTABLESIZE-1, widths); for(n=0; n<FONTTABLESIZE; n++) wsf->widths[n] = widths[n]; GetTextMetrics(hdc, &tm); wsf->ascent = tm.tmAscent + tm.tmExternalLeading; wsf->descent = tm.tmDescent; /*if ( !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && f->family != NAME_win ) Cprintf("%s (%s/%s): not a TrueType font\n", pp(f), pp(f->family), pp(f->style)); */ if ( isDefault(f->x_name) ) { char buf[256]; if ( GetTextFace(hdc, sizeof(buf), buf) ) assign(f, x_name, CtoName(buf)); } SelectObject(hdc, old); ReleaseDC(NULL, hdc); if ( wsf->widths['i'] == wsf->widths['w'] ) assign(f, fixed_width, ON); else assign(f, fixed_width, OFF); registerXrefObject(f, d, wsf); succeed; }
int fswc_grab(fswebcam_config_t *config) { uint32_t frame; uint32_t x, y; avgbmp_t *abitmap, *pbitmap; gdImage *image, *original; uint8_t modified; src_t src; /* Record the start time. */ config->start = time(NULL); /* Set source options... */ memset(&src, 0, sizeof(src)); src.input = config->input; src.tuner = config->tuner; src.frequency = config->frequency; src.delay = config->delay; src.timeout = 10; /* seconds */ src.use_read = config->use_read; src.list = config->list; src.palette = config->palette; src.width = config->width; src.height = config->height; src.fps = config->fps; src.option = config->option; HEAD("--- Opening %s...", config->device); if(src_open(&src, config->device) == -1) return(-1); /* The source may have adjusted the width and height we passed * to it. Update the main config to match. */ config->width = src.width; config->height = src.height; /* Allocate memory for the average bitmap buffer. */ abitmap = calloc(config->width * config->height * 3, sizeof(avgbmp_t)); if(!abitmap) { ERROR("Out of memory."); return(-1); } if(config->frames == 1) HEAD("--- Capturing frame..."); else HEAD("--- Capturing %i frames...", config->frames); if(config->skipframes == 1) MSG("Skipping frame..."); else if(config->skipframes > 1) MSG("Skipping %i frames...", config->skipframes); /* Grab (and do nothing with) the skipped frames. */ for(frame = 0; frame < config->skipframes; frame++) if(src_grab(&src) == -1) break; /* If frames where skipped, inform when normal capture begins. */ if(config->skipframes) MSG("Capturing %i frames...", config->frames); /* Grab the requested number of frames. */ for(frame = 0; frame < config->frames; frame++) { if(src_grab(&src) == -1) break; if(!frame && config->dumpframe) { /* Dump the raw data from the first frame to file. */ FILE *f; MSG("Dumping raw frame to '%s'...", config->dumpframe); f = fopen(config->dumpframe, "wb"); if(!f) ERROR("fopen: %s", strerror(errno)); else { fwrite(src.img, 1, src.length, f); fclose(f); } } /* Add frame to the average bitmap. */ switch(src.palette) { case SRC_PAL_PNG: fswc_add_image_png(&src, abitmap); break; case SRC_PAL_JPEG: case SRC_PAL_MJPEG: fswc_add_image_jpeg(&src, abitmap); break; case SRC_PAL_S561: fswc_add_image_s561(abitmap, src.img, src.length, src.width, src.height, src.palette); break; case SRC_PAL_RGB32: fswc_add_image_rgb32(&src, abitmap); break; case SRC_PAL_BGR32: fswc_add_image_bgr32(&src, abitmap); break; case SRC_PAL_RGB24: fswc_add_image_rgb24(&src, abitmap); break; case SRC_PAL_BGR24: fswc_add_image_bgr24(&src, abitmap); break; case SRC_PAL_BAYER: case SRC_PAL_SGBRG8: case SRC_PAL_SGRBG8: fswc_add_image_bayer(abitmap, src.img, src.length, src.width, src.height, src.palette); break; case SRC_PAL_YUYV: case SRC_PAL_UYVY: fswc_add_image_yuyv(&src, abitmap); break; case SRC_PAL_YUV420P: fswc_add_image_yuv420p(&src, abitmap); break; case SRC_PAL_NV12MB: fswc_add_image_nv12mb(&src, abitmap); break; case SRC_PAL_RGB565: fswc_add_image_rgb565(&src, abitmap); break; case SRC_PAL_RGB555: fswc_add_image_rgb555(&src, abitmap); break; case SRC_PAL_Y16: fswc_add_image_y16(&src, abitmap); break; case SRC_PAL_GREY: fswc_add_image_grey(&src, abitmap); break; } } /* We are now finished with the capture card. */ src_close(&src); /* Fail if no frames where captured. */ if(!frame) { ERROR("No frames captured."); free(abitmap); return(-1); } HEAD("--- Processing captured image..."); /* Copy the average bitmap image to a gdImage. */ original = gdImageCreateTrueColor(config->width, config->height); if(!original) { ERROR("Out of memory."); free(abitmap); return(-1); } pbitmap = abitmap; for(y = 0; y < config->height; y++) for(x = 0; x < config->width; x++) { int px = x; int py = y; int colour; colour = (*(pbitmap++) / config->frames) << 16; colour += (*(pbitmap++) / config->frames) << 8; colour += (*(pbitmap++) / config->frames); gdImageSetPixel(original, px, py, colour); } free(abitmap); /* Make a copy of the original image. */ image = fswc_gdImageDuplicate(original); if(!image) { ERROR("Out of memory."); gdImageDestroy(image); return(-1); } /* Set the default values for this run. */ if(config->font) free(config->font); if(config->title) free(config->title); if(config->subtitle) free(config->subtitle); if(config->timestamp) free(config->timestamp); if(config->info) free(config->info); if(config->underlay) free(config->underlay); if(config->overlay) free(config->overlay); if(config->filename) free(config->filename); config->banner = BOTTOM_BANNER; config->bg_colour = 0x40263A93; config->bl_colour = 0x00FF0000; config->fg_colour = 0x00FFFFFF; config->font = strdup("sans"); config->fontsize = 10; config->shadow = 1; config->title = NULL; config->subtitle = NULL; config->timestamp = strdup("%Y-%m-%d %H:%M (%Z)"); config->info = NULL; config->underlay = NULL; config->overlay = NULL; config->filename = NULL; config->format = FORMAT_JPEG; config->compression = -1; modified = 1; /* Run through the jobs list. */ for(x = 0; x < config->jobs; x++) { uint16_t id = config->job[x]->id; char *options = config->job[x]->options; switch(id) { case 1: /* A non-option argument: a filename. */ case OPT_SAVE: fswc_output(config, options, image); modified = 0; break; case OPT_EXEC: fswc_exec(config, options); break; case OPT_REVERT: modified = 1; gdImageDestroy(image); image = fswc_gdImageDuplicate(original); break; case OPT_FLIP: modified = 1; image = fx_flip(image, options); break; case OPT_CROP: modified = 1; image = fx_crop(image, options); break; case OPT_SCALE: modified = 1; image = fx_scale(image, options); break; case OPT_ROTATE: modified = 1; image = fx_rotate(image, options); break; case OPT_DEINTERLACE: modified = 1; image = fx_deinterlace(image, options); break; case OPT_INVERT: modified = 1; image = fx_invert(image, options); break; case OPT_GREYSCALE: modified = 1; image = fx_greyscale(image, options); break; case OPT_SWAPCHANNELS: modified = 1; image = fx_swapchannels(image, options); break; case OPT_NO_BANNER: modified = 1; MSG("Disabling banner."); config->banner = NO_BANNER; break; case OPT_TOP_BANNER: modified = 1; MSG("Putting banner at the top."); config->banner = TOP_BANNER; break; case OPT_BOTTOM_BANNER: modified = 1; MSG("Putting banner at the bottom."); config->banner = BOTTOM_BANNER; break; case OPT_BG_COLOUR: modified = 1; MSG("Setting banner background colour to %s.", options); if(sscanf(options, "#%X", &config->bg_colour) != 1) WARN("Bad background colour: %s", options); break; case OPT_BL_COLOUR: modified = 1; MSG("Setting banner line colour to %s.", options); if(sscanf(options, "#%X", &config->bl_colour) != 1) WARN("Bad line colour: %s", options); break; case OPT_FG_COLOUR: modified = 1; MSG("Setting banner text colour to %s.", options); if(sscanf(options, "#%X", &config->fg_colour) != 1) WARN("Bad text colour: %s", options); break; case OPT_FONT: modified = 1; MSG("Setting font to %s.", options); if(parse_font(options, &config->font, &config->fontsize)) WARN("Bad font: %s", options); break; case OPT_NO_SHADOW: modified = 1; MSG("Disabling text shadow."); config->shadow = 0; break; case OPT_SHADOW: modified = 1; MSG("Enabling text shadow."); config->shadow = 1; break; case OPT_TITLE: modified = 1; MSG("Setting title \"%s\".", options); if(config->title) free(config->title); config->title = strdup(options); break; case OPT_NO_TITLE: modified = 1; MSG("Clearing title."); if(config->title) free(config->title); config->title = NULL; break; case OPT_SUBTITLE: modified = 1; MSG("Setting subtitle \"%s\".", options); if(config->subtitle) free(config->subtitle); config->subtitle = strdup(options); break; case OPT_NO_SUBTITLE: modified = 1; MSG("Clearing subtitle."); if(config->subtitle) free(config->subtitle); config->subtitle = NULL; break; case OPT_TIMESTAMP: modified = 1; MSG("Setting timestamp \"%s\".", options); if(config->timestamp) free(config->timestamp); config->timestamp = strdup(options); break; case OPT_NO_TIMESTAMP: modified = 1; MSG("Clearing timestamp."); if(config->timestamp) free(config->timestamp); config->timestamp = NULL; break; case OPT_INFO: modified = 1; MSG("Setting info text \"%s\".", options); if(config->info) free(config->info); config->info = strdup(options); break; case OPT_NO_INFO: modified = 1; MSG("Clearing info text."); if(config->info) free(config->info); config->info = NULL; break; case OPT_UNDERLAY: modified = 1; MSG("Setting underlay image: %s", options); if(config->underlay) free(config->underlay); config->underlay = strdup(options); break; case OPT_NO_UNDERLAY: modified = 1; MSG("Clearing underlay."); if(config->underlay) free(config->underlay); config->underlay = NULL; break; case OPT_OVERLAY: modified = 1; MSG("Setting overlay image: %s", options); if(config->overlay) free(config->overlay); config->overlay = strdup(options); break; case OPT_NO_OVERLAY: modified = 1; MSG("Clearing overlay image."); if(config->overlay) free(config->overlay); config->overlay = NULL; break; case OPT_JPEG: modified = 1; MSG("Setting output format to JPEG, quality %i", atoi(options)); config->format = FORMAT_JPEG; config->compression = atoi(options); break; case OPT_PNG: modified = 1; MSG("Setting output format to PNG, quality %i", atoi(options)); config->format = FORMAT_PNG; config->compression = atoi(options); break; } } gdImageDestroy(image); gdImageDestroy(original); if(modified) WARN("There are unsaved changes to the image."); return(0); }
static void ipc_parse_config(struct config *config, const char *payload) { json_object *bar_config = json_tokener_parse(payload); json_object *markup, *mode, *hidden_bar, *position, *status_command; json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers; json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; #ifdef ENABLE_TRAY json_object *tray_output, *icon_theme, *tray_padding, *activate_button, *context_button; json_object *secondary_button; json_object_object_get_ex(bar_config, "tray_output", &tray_output); json_object_object_get_ex(bar_config, "icon_theme", &icon_theme); json_object_object_get_ex(bar_config, "tray_padding", &tray_padding); json_object_object_get_ex(bar_config, "activate_button", &activate_button); json_object_object_get_ex(bar_config, "context_button", &context_button); json_object_object_get_ex(bar_config, "secondary_button", &secondary_button); #endif json_object_object_get_ex(bar_config, "mode", &mode); json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar); json_object_object_get_ex(bar_config, "position", &position); json_object_object_get_ex(bar_config, "status_command", &status_command); json_object_object_get_ex(bar_config, "font", &font); json_object_object_get_ex(bar_config, "bar_height", &bar_height); json_object_object_get_ex(bar_config, "wrap_scroll", &wrap_scroll); json_object_object_get_ex(bar_config, "workspace_buttons", &workspace_buttons); json_object_object_get_ex(bar_config, "strip_workspace_numbers", &strip_workspace_numbers); json_object_object_get_ex(bar_config, "binding_mode_indicator", &binding_mode_indicator); json_object_object_get_ex(bar_config, "verbose", &verbose); json_object_object_get_ex(bar_config, "separator_symbol", &sep_symbol); json_object_object_get_ex(bar_config, "colors", &colors); json_object_object_get_ex(bar_config, "outputs", &outputs); json_object_object_get_ex(bar_config, "pango_markup", &markup); if (status_command) { free(config->status_command); config->status_command = strdup(json_object_get_string(status_command)); } if (position) { config->position = parse_position(json_object_get_string(position)); } if (font) { free(config->font); config->font = parse_font(json_object_get_string(font)); } if (sep_symbol) { free(config->sep_symbol); config->sep_symbol = strdup(json_object_get_string(sep_symbol)); } if (strip_workspace_numbers) { config->strip_workspace_numbers = json_object_get_boolean(strip_workspace_numbers); } if (binding_mode_indicator) { config->binding_mode_indicator = json_object_get_boolean(binding_mode_indicator); } if (wrap_scroll) { config->wrap_scroll = json_object_get_boolean(wrap_scroll); } if (workspace_buttons) { config->workspace_buttons = json_object_get_boolean(workspace_buttons); } if (bar_height) { config->height = json_object_get_int(bar_height); } if (markup) { config->pango_markup = json_object_get_boolean(markup); } #ifdef ENABLE_TRAY if (tray_output) { free(config->tray_output); config->tray_output = strdup(json_object_get_string(tray_output)); } if (icon_theme) { free(config->icon_theme); config->icon_theme = strdup(json_object_get_string(icon_theme)); } if (tray_padding) { config->tray_padding = json_object_get_int(tray_padding); } if (activate_button) { config->activate_button = json_object_get_int(activate_button); } if (context_button) { config->context_button = json_object_get_int(context_button); } if (secondary_button) { config->secondary_button = json_object_get_int(secondary_button); } #endif // free previous outputs list int i; for (i = 0; i < config->outputs->length; ++i) { free(config->outputs->items[i]); } list_free(config->outputs); config->outputs = create_list(); if (outputs) { int length = json_object_array_length(outputs); json_object *output; const char *output_str; for (i = 0; i < length; ++i) { output = json_object_array_get_idx(outputs, i); output_str = json_object_get_string(output); if (strcmp("*", output_str) == 0) { config->all_outputs = true; break; } list_add(config->outputs, strdup(output_str)); } } else { config->all_outputs = true; } if (colors) { json_object *background, *statusline, *separator; json_object *focused_background, *focused_statusline, *focused_separator; json_object *focused_workspace_border, *focused_workspace_bg, *focused_workspace_text; json_object *inactive_workspace_border, *inactive_workspace_bg, *inactive_workspace_text; json_object *active_workspace_border, *active_workspace_bg, *active_workspace_text; json_object *urgent_workspace_border, *urgent_workspace_bg, *urgent_workspace_text; json_object *binding_mode_border, *binding_mode_bg, *binding_mode_text; json_object_object_get_ex(colors, "background", &background); json_object_object_get_ex(colors, "statusline", &statusline); json_object_object_get_ex(colors, "separator", &separator); json_object_object_get_ex(colors, "focused_background", &focused_background); json_object_object_get_ex(colors, "focused_statusline", &focused_statusline); json_object_object_get_ex(colors, "focused_separator", &focused_separator); json_object_object_get_ex(colors, "focused_workspace_border", &focused_workspace_border); json_object_object_get_ex(colors, "focused_workspace_bg", &focused_workspace_bg); json_object_object_get_ex(colors, "focused_workspace_text", &focused_workspace_text); json_object_object_get_ex(colors, "active_workspace_border", &active_workspace_border); json_object_object_get_ex(colors, "active_workspace_bg", &active_workspace_bg); json_object_object_get_ex(colors, "active_workspace_text", &active_workspace_text); json_object_object_get_ex(colors, "inactive_workspace_border", &inactive_workspace_border); json_object_object_get_ex(colors, "inactive_workspace_bg", &inactive_workspace_bg); json_object_object_get_ex(colors, "inactive_workspace_text", &inactive_workspace_text); json_object_object_get_ex(colors, "urgent_workspace_border", &urgent_workspace_border); json_object_object_get_ex(colors, "urgent_workspace_bg", &urgent_workspace_bg); json_object_object_get_ex(colors, "urgent_workspace_text", &urgent_workspace_text); json_object_object_get_ex(colors, "binding_mode_border", &binding_mode_border); json_object_object_get_ex(colors, "binding_mode_bg", &binding_mode_bg); json_object_object_get_ex(colors, "binding_mode_text", &binding_mode_text); if (background) { config->colors.background = parse_color(json_object_get_string(background)); } if (statusline) { config->colors.statusline = parse_color(json_object_get_string(statusline)); } if (separator) { config->colors.separator = parse_color(json_object_get_string(separator)); } if (focused_background) { config->colors.focused_background = parse_color(json_object_get_string(focused_background)); } if (focused_statusline) { config->colors.focused_statusline = parse_color(json_object_get_string(focused_statusline)); } if (focused_separator) { config->colors.focused_separator = parse_color(json_object_get_string(focused_separator)); } if (focused_workspace_border) { config->colors.focused_workspace.border = parse_color(json_object_get_string(focused_workspace_border)); } if (focused_workspace_bg) { config->colors.focused_workspace.background = parse_color(json_object_get_string(focused_workspace_bg)); } if (focused_workspace_text) { config->colors.focused_workspace.text = parse_color(json_object_get_string(focused_workspace_text)); } if (active_workspace_border) { config->colors.active_workspace.border = parse_color(json_object_get_string(active_workspace_border)); } if (active_workspace_bg) { config->colors.active_workspace.background = parse_color(json_object_get_string(active_workspace_bg)); } if (active_workspace_text) { config->colors.active_workspace.text = parse_color(json_object_get_string(active_workspace_text)); } if (inactive_workspace_border) { config->colors.inactive_workspace.border = parse_color(json_object_get_string(inactive_workspace_border)); } if (inactive_workspace_bg) { config->colors.inactive_workspace.background = parse_color(json_object_get_string(inactive_workspace_bg)); } if (inactive_workspace_text) { config->colors.inactive_workspace.text = parse_color(json_object_get_string(inactive_workspace_text)); } if (binding_mode_border) { config->colors.binding_mode.border = parse_color(json_object_get_string(binding_mode_border)); } if (binding_mode_bg) { config->colors.binding_mode.background = parse_color(json_object_get_string(binding_mode_bg)); } if (binding_mode_text) { config->colors.binding_mode.text = parse_color(json_object_get_string(binding_mode_text)); } } json_object_put(bar_config); }