⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-ft-font.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 5 页
字号:
    cbox.yMax = (cbox.yMax + 63) & -64;    width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);    height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);    stride = (width * hmul + 3) & ~3;    if (width * height == 0) {	cairo_format_t format;	/* Looks like fb handles zero-sized images just fine */	switch (font_options->antialias) {	case CAIRO_ANTIALIAS_NONE:	    format = CAIRO_FORMAT_A1;	    break;	case CAIRO_ANTIALIAS_SUBPIXEL:	    format= CAIRO_FORMAT_ARGB32;	    break;	case CAIRO_ANTIALIAS_DEFAULT:	case CAIRO_ANTIALIAS_GRAY:	default:	    format = CAIRO_FORMAT_A8;	    break;	}	(*surface) = (cairo_image_surface_t *)	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);	if ((*surface)->base.status)	    return CAIRO_STATUS_NO_MEMORY;    } else  {	matrix.xx = matrix.yy = 0x10000L;	matrix.xy = matrix.yx = 0;	switch (font_options->antialias) {	case CAIRO_ANTIALIAS_NONE:	    bitmap.pixel_mode = FT_PIXEL_MODE_MONO;	    bitmap.num_grays  = 1;	    stride = ((width + 31) & -32) >> 3;	    break;	case CAIRO_ANTIALIAS_DEFAULT:	case CAIRO_ANTIALIAS_GRAY:	    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;	    bitmap.num_grays  = 256;	    stride = (width + 3) & -4;	    break;	case CAIRO_ANTIALIAS_SUBPIXEL:	    switch (font_options->subpixel_order) {	    case CAIRO_SUBPIXEL_ORDER_RGB:	    case CAIRO_SUBPIXEL_ORDER_BGR:	    default:		matrix.xx *= 3;		hmul = 3;		subpixel = TRUE;		break;	    case CAIRO_SUBPIXEL_ORDER_VRGB:	    case CAIRO_SUBPIXEL_ORDER_VBGR:		matrix.yy *= 3;		vmul = 3;		subpixel = TRUE;		break;	    }	    FT_Outline_Transform (outline, &matrix);	    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;	    bitmap.num_grays  = 256;	    stride = (width * hmul + 3) & -4;	}	bitmap.pitch = stride;	bitmap.width = width * hmul;	bitmap.rows = height * vmul;	bitmap.buffer = calloc (1, stride * bitmap.rows);	if (bitmap.buffer == NULL) {	    return CAIRO_STATUS_NO_MEMORY;	}	FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);	if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {	    free (bitmap.buffer);	    return CAIRO_STATUS_NO_MEMORY;	}	status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);	if (status)	    return status;    }    /*     * Note: the font's coordinate system is upside down from ours, so the     * Y coordinate of the control box needs to be negated.     */    cairo_surface_set_device_offset (&(*surface)->base,				     floor ((double) cbox.xMin / 64.0),				     floor (-(double) cbox.yMax / 64.0));    return CAIRO_STATUS_SUCCESS;}/* Converts a bitmap (or other) FT_GlyphSlot into an image */static cairo_status_t_render_glyph_bitmap (FT_Face		      face,		      cairo_font_options_t   *font_options,		      cairo_image_surface_t **surface){    FT_GlyphSlot glyphslot = face->glyph;    cairo_status_t status = CAIRO_STATUS_SUCCESS;    FT_Error error;    /* According to the FreeType docs, glyphslot->format could be     * something other than FT_GLYPH_FORMAT_OUTLINE or     * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType     * the opportunity to convert such to     * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since     * we avoid the FT_LOAD_NO_RECURSE flag.     */    error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);    if (error)	return CAIRO_STATUS_NO_MEMORY;    status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);    if (status)	return status;    /*     * Note: the font's coordinate system is upside down from ours, so the     * Y coordinate of the control box needs to be negated.     */    cairo_surface_set_device_offset (&(*surface)->base,				     glyphslot->bitmap_left,				     -glyphslot->bitmap_top);    return status;}static cairo_status_t_transform_glyph_bitmap (cairo_matrix_t         * shape,			 cairo_image_surface_t ** surface){    cairo_matrix_t original_to_transformed;    cairo_matrix_t transformed_to_original;    cairo_image_surface_t *old_image;    cairo_surface_t *image;    double x[4], y[4];    double origin_x, origin_y;    int origin_width, origin_height;    int i;    int x_min, y_min, x_max, y_max;    int width, height;    cairo_status_t status;    cairo_surface_pattern_t pattern;    /* We want to compute a transform that takes the origin     * (device_x_offset, device_y_offset) to 0,0, then applies     * the "shape" portion of the font transform     */    original_to_transformed = *shape;        cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);    origin_width = cairo_image_surface_get_width (&(*surface)->base);    origin_height = cairo_image_surface_get_height (&(*surface)->base);    cairo_matrix_translate (&original_to_transformed,			    origin_x, origin_y);    /* Find the bounding box of the original bitmap under that     * transform     */    x[0] = 0;            y[0] = 0;    x[1] = origin_width; y[1] = 0;    x[2] = origin_width; y[2] = origin_height;    x[3] = 0;            y[3] = origin_height;    for (i = 0; i < 4; i++)      cairo_matrix_transform_point (&original_to_transformed,				    &x[i], &y[i]);    x_min = floor (x[0]);   y_min = floor (y[0]);    x_max =  ceil (x[0]);   y_max =  ceil (y[0]);    for (i = 1; i < 4; i++) {	if (x[i] < x_min)	    x_min = floor (x[i]);	if (x[i] > x_max)	    x_max = ceil (x[i]);	if (y[i] < y_min)	    y_min = floor (y[i]);	if (y[i] > y_max)	    y_max = ceil (y[i]);    }    /* Adjust the transform so that the bounding box starts at 0,0 ...     * this gives our final transform from original bitmap to transformed     * bitmap.     */    original_to_transformed.x0 -= x_min;    original_to_transformed.y0 -= y_min;    /* Create the transformed bitmap     */    width = x_max - x_min;    height = y_max - y_min;    transformed_to_original = original_to_transformed;    status = cairo_matrix_invert (&transformed_to_original);    if (status)	return status;    /* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */    width = (width + 3) & ~3;    image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);    if (image->status)	return CAIRO_STATUS_NO_MEMORY;    /* Initialize it to empty     */    _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,				   CAIRO_COLOR_TRANSPARENT,				   0, 0,				   width, height);    /* Draw the original bitmap transformed into the new bitmap     */    _cairo_pattern_init_for_surface (&pattern, &(*surface)->base);    cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);    _cairo_surface_composite (CAIRO_OPERATOR_OVER,			      &pattern.base, NULL, image,			      0, 0, 0, 0, 0, 0,			      width,			      height);    _cairo_pattern_fini (&pattern.base);    /* Now update the cache entry for the new bitmap, recomputing     * the origin based on the final transform.     */    origin_x = - origin_x;    origin_y = - origin_y;    cairo_matrix_transform_point (&original_to_transformed,				  &origin_x, &origin_y);    old_image = (*surface);    (*surface) = (cairo_image_surface_t *)image;    cairo_surface_destroy (&old_image->base);    cairo_surface_set_device_offset (&(*surface)->base,				     - floor (origin_x + 0.5),				     - floor (origin_y + 0.5));    return status;}static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {    _cairo_ft_unscaled_font_destroy,#if 0    _cairo_ft_unscaled_font_create_glyph#endif};/* cairo_ft_scaled_font_t */typedef struct _cairo_ft_scaled_font {    cairo_scaled_font_t base;    cairo_ft_unscaled_font_t *unscaled;    cairo_ft_options_t ft_options;} cairo_ft_scaled_font_t;const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend;/* The load flags passed to FT_Load_Glyph control aspects like hinting and * antialiasing. Here we compute them from the fields of a FcPattern. */static cairo_ft_options_t_get_pattern_ft_options (FcPattern *pattern){    FcBool antialias, vertical_layout, hinting, autohint, bitmap, embolden;    cairo_ft_options_t ft_options;    int rgba;#ifdef FC_HINT_STYLE    int hintstyle;#endif    _cairo_font_options_init_default (&ft_options.base);    ft_options.load_flags = FT_LOAD_DEFAULT;    ft_options.extra_flags = 0;#ifndef FC_EMBEDDED_BITMAP#define FC_EMBEDDED_BITMAP "embeddedbitmap"#endif    /* Check whether to force use of embedded bitmaps */    if (FcPatternGetBool (pattern,			  FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch)	bitmap = FcFalse;    /* disable antialiasing if requested */    if (FcPatternGetBool (pattern,			  FC_ANTIALIAS, 0, &antialias) != FcResultMatch)	antialias = FcTrue;        if (antialias) {	if (!bitmap)	    ft_options.load_flags |= FT_LOAD_NO_BITMAP;		/* disable hinting if requested */	if (FcPatternGetBool (pattern,			      FC_HINTING, 0, &hinting) != FcResultMatch)	    hinting = FcTrue;	if (FcPatternGetInteger (pattern,				 FC_RGBA, 0, &rgba) != FcResultMatch)	    rgba = FC_RGBA_UNKNOWN;	switch (rgba) {	case FC_RGBA_RGB:	    ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;	    break;	case FC_RGBA_BGR:	    ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;	    break;	case FC_RGBA_VRGB:	    ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;	    break;	case FC_RGBA_VBGR:	    ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;	    break;	case FC_RGBA_UNKNOWN:	case FC_RGBA_NONE:	default:	    break;	}	if (ft_options.base.subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)	    ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;#ifdef FC_HINT_STYLE    	if (FcPatternGetInteger (pattern, 				 FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)	    hintstyle = FC_HINT_FULL;	if (!hinting)	    hintstyle = FC_HINT_NONE;	switch (hintstyle) {	case FC_HINT_NONE:	    ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;		    break;	case FC_HINT_SLIGHT:	    ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT;	    break;	case FC_HINT_MEDIUM:	default:	    ft_options.base.hint_style = CAIRO_HINT_STYLE_MEDIUM;	    break;	case FC_HINT_FULL:	    ft_options.base.hint_style = CAIRO_HINT_STYLE_FULL;	    break;	}#else /* !FC_HINT_STYLE */	if (!hinting) {	    ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;	}#endif /* FC_FHINT_STYLE */    } else {	ft_options.base.antialias = CAIRO_ANTIALIAS_NONE;    }    /* force autohinting if requested */    if (FcPatternGetBool (pattern,			  FC_AUTOHINT, 0, &autohint) != FcResultMatch)	autohint = FcFalse;    if (autohint)	ft_options.load_flags |= FT_LOAD_FORCE_AUTOHINT;    if (FcPatternGetBool (pattern,			  FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch)	vertical_layout = FcFalse;    if (vertical_layout)	ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT;    #ifndef FC_EMBOLDEN#define FC_EMBOLDEN "embolden"#endif    if (FcPatternGetBool (pattern,			  FC_EMBOLDEN, 0, &embolden) != FcResultMatch)	embolden = FcFalse;        if (embolden)	ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;    return ft_options;}static void_cairo_ft_options_merge (cairo_ft_options_t *options,			 cairo_ft_options_t *other){    int load_flags = other->load_flags;    int load_target = FT_LOAD_TARGET_NORMAL;    /* clear load target mode */    load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags)));        if (load_flags & FT_LOAD_NO_HINTING)	other->base.hint_style = CAIRO_HINT_STYLE_NONE;    if (other->base.antialias == CAIRO_ANTIALIAS_NONE ||	options->base.antialias == CAIRO_ANTIALIAS_NONE) {	options->base.antialias = CAIRO_ANTIALIAS_NONE;	options->base.subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;    }    if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL &&	(options->base.antialias == CAIRO_ANTIALIAS_DEFAULT || 	 options->base.antialias == CAIRO_ANTIALIAS_GRAY)) {	options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;	options->base.subpixel_order = other->base.subpixel_order;    }    if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT)	options->base.hint_style = other->base.hint_style;    if (other->base.hint_style == CAIRO_HINT_STYLE_NONE)	options->base.hint_style = CAIRO_HINT_STYLE_NONE;    if (options->base.antialias == CAIRO_ANTIALIAS_NONE) {	if (options->base.hint_style == CAIRO_HINT_STYLE_NONE)	    load_flags |= FT_LOAD_NO_HINTING;	else	    load_target = FT_LOAD_TARGET_MONO;	load_flags |= FT_LOAD_MONOCHROME;    } else {	switch (options->base.hint_style) {	case CAIRO_HINT_STYLE_NONE:	    load_flags |= FT_LOAD_NO_HINTING;	    break;	case CAIRO_HINT_STYLE_SLIGHT:	    load_target = FT_LOAD_TARGET_LIGHT;	    break;	case CAIRO_HINT_STYLE_MEDIUM:	    break;	case CAIRO_HINT_STYLE_FULL:	case CAIRO_HINT_STYLE_DEFAULT:	    if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) {		switch (options->base.subpixel_order) {		case CAIRO_SUBPIXEL_ORDER_DEFAULT:		case CAIRO_SUBPIXEL_ORDER_RGB:		case CAIRO_SUBPIXEL_ORDER_BGR:		    load_target |= FT_LOAD_TARGET_LCD;		    break;		case CAIRO_SUBPIXEL_ORDER_VRGB:		case CAIRO_SUBPIXEL_ORDER_VBGR:		    load_target |= FT_LOAD_TARGET_LCD_V;		break;		}	    }	    break;	}    }    options->load_flags = load_flags | load_target;    options->extra_flags = other->extra_flags;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -