diff options
author | 罗晶华 Jinghua Luo <jinghua@annarchy.freedesktop.org> | 2007-01-06 03:57:25 -0800 |
---|---|---|
committer | 罗晶华 Jinghua Luo <jinghua@annarchy.freedesktop.org> | 2007-01-06 03:57:25 -0800 |
commit | 3f4e12a866e99183358b751ac64e30e26672b2ee (patch) | |
tree | 5945e198beacd17eb4779183a3cafb65e3d97d26 /src/sdl-ft.c |
import initial sources
Diffstat (limited to 'src/sdl-ft.c')
-rw-r--r-- | src/sdl-ft.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/src/sdl-ft.c b/src/sdl-ft.c new file mode 100644 index 0000000..b51c694 --- /dev/null +++ b/src/sdl-ft.c @@ -0,0 +1,269 @@ +/* sdl-freetype, a text rendering library for SDL. + * Copyright (C) 2006 luojinghua <sunmoon1997@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * THANKS FOR ALL CAIRO AUTHORS, MOST OF IDEAS AND IMPLEMENT DTAILS ARE + * COME FROM CAIRO. + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "sdl-ft.h" +#include <math.h> + +#ifndef FC_EMBEDDED_BITMAP +#define FC_EMBEDDED_BITMAP "embeddedbitmap" +#endif + +#ifndef FC_EMBOLDEN +#define FC_EMBOLDEN "embolden" +#endif + +sdl_freetype_font_t * +sdl_ft_create_font_from_pattern (FcPattern * pattern) +{ + sdl_freetype_font_desc_t desc; + const char * file; + int index, mask; + FcBool antialias, vertical_layout, hinting, autohint, bitmap, embolden; + int rgba; +#ifdef FC_HINT_STYLE + int hintstyle; +#endif + double pixelsize; + FcMatrix * matrix; + + if (!pattern) + goto errquit0; + + mask = \ + SDL_FONT_ANTIALIAS_MASK | SDL_FONT_HINT_STYLE_MASK | \ + SDL_FONT_INDEX_MASK; + desc.antialias = SDL_FT_ANTIALIAS_DEFAULT; + + if (FcPatternGetString (pattern, FC_FILE, 0, + (FcChar8 **)&file) != FcResultMatch) + goto errquit0; + if (FcPatternGetInteger (pattern, FC_INDEX, 0, &desc.index) != FcResultMatch) + goto errquit0; + + if (FcPatternGetBool (pattern, + FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch) + bitmap = FcFalse; + + if (FcPatternGetBool (pattern, + FC_ANTIALIAS, 0, &antialias) != FcResultMatch) + antialias = FcTrue; + + if (antialias) { + sdl_freetype_subpixel_order_t subpixel_order; + + if (!bitmap) { + desc.embedded_bitmap = 1; + mask |= SDL_FONT_EMBEDDEDBITMAP_MASK; + } + + 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: + subpixel_order = SDL_FT_SUBPIXEL_ORDER_RGB; + break; + case FC_RGBA_BGR: + subpixel_order = SDL_FT_SUBPIXEL_ORDER_BGR; + break; + case FC_RGBA_VRGB: + subpixel_order = SDL_FT_SUBPIXEL_ORDER_VRGB; + break; + case FC_RGBA_VBGR: + subpixel_order = SDL_FT_SUBPIXEL_ORDER_VBGR; + break; + case FC_RGBA_UNKNOWN: + case FC_RGBA_NONE: + default: + subpixel_order = SDL_FT_SUBPIXEL_ORDER_DEFAULT; + break; + } + + if (subpixel_order != SDL_FT_SUBPIXEL_ORDER_DEFAULT) { + mask |= SDL_FONT_SUBPIXEL_ORDER_MASK; + desc.subpixel_order = subpixel_order; + desc.antialias = SDL_FT_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: + desc.hint = SDL_FT_HINT_STYLE_NONE; + break; + case FC_HINT_SLIGHT: + desc.hint = SDL_FT_HINT_STYLE_SLIGHT; + break; + case FC_HINT_MEDIUM: + default: + desc.hint = SDL_FT_HINT_STYLE_MEDIUM; + break; + case FC_HINT_FULL: + desc.hint = SDL_FT_HINT_STYLE_FULL; + break; + } +#else /* !FC_HINT_STYLE */ + if (!hinting) { + desc.hint = SDL_FT_HINT_STYLE_NONE; + } +#endif /* FC_FHINT_STYLE */ + } else { + desc.antialias = SDL_FT_ANTIALIAS_NONE; + } + + if (FcPatternGetBool (pattern, + FC_AUTOHINT, 0, &autohint) != FcResultMatch) + autohint = FcFalse; + + if (autohint) { + desc.autohint = 1; + mask = SDL_FONT_AUTOHINT_MASK; + } + + if (FcPatternGetBool (pattern, + FC_VERTICAL_LAYOUT, 0, + &vertical_layout) != FcResultMatch) + vertical_layout = FcFalse; + + if (vertical_layout) { + desc.vertical_layout = 1; + mask = SDL_FONT_VERTICAL_LAYOUT_MASK; + } + + if (FcPatternGetBool (pattern, + FC_EMBOLDEN, 0, &embolden) != FcResultMatch) + embolden = FcFalse; + + if (embolden) { + desc.embolden = 1; + mask = SDL_FONT_EMBOLDEN_MASK; + } + + FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixelsize); + if (FcPatternGetMatrix(pattern, FC_MATRIX, 0, &matrix) == FcResultMatch){ + desc.xform.xx = floor (matrix->xx * 65536 + 0.5); + desc.xform.xy = floor (-matrix->xy * 65536 + 0.5); + desc.xform.yx = floor (-matrix->yx * 65536 + 0.5); + desc.xform.yy = floor (matrix->yy * 65536 + 0.5); + mask |= SDL_FONT_TRANSFORM_MASK; + } + + return sdl_freetype_font_create_full (file, pixelsize, &desc, mask); + errquit0: + return NULL; +} + +static FcPattern * +fcpattern (const char * family, double size, + sdl_ft_weight_t weight, sdl_ft_slant_t slant, + double dpi) +{ + int fcweight, fcslant; + FcPattern * pattern; + + switch (weight) { + case SDL_FT_WEIGHT_BOLD: + fcweight = FC_WEIGHT_BOLD; + break; + /* case SDL_FT_WEIGHT_NORMAL: */ + default: + fcweight = FC_WEIGHT_NORMAL; + break; + } + + switch (slant) { + case SDL_FT_SLANT_ITALIC: + fcslant = FC_SLANT_ITALIC; + case SDL_FT_SLANT_OBLIQUE: + fcslant = FC_SLANT_OBLIQUE; + break; + /* case AKOFONT_SALNT_NORMAL: */ + default: + fcslant = FC_SLANT_ROMAN; + break; + } + + pattern = FcPatternBuild (NULL, + FC_FAMILY, FcTypeString, family, + FC_SLANT, FcTypeInteger, slant, + FC_WEIGHT, FcTypeInteger, weight, + FC_DPI, FcTypeDouble, dpi, + FC_SIZE, FcTypeDouble, size, + NULL); + return pattern; +} + +sdl_freetype_font_t * +sdl_ft_create_font (const char * family, + double size, + sdl_ft_weight_t weight, + sdl_ft_slant_t slant, + double dpi) +{ + FcPattern * pattern, * resolved; + FcResult result; + sdl_freetype_font_t * font; + + pattern = fcpattern (family, size, weight, slant, dpi); + if (!pattern) + goto errquit0; + + FcConfigSubstitute (NULL, pattern, FcMatchPattern); + FcDefaultSubstitute (pattern); + + resolved = FcFontMatch (NULL, pattern, &result); + if (!resolved) + goto errquit1; + + font = sdl_ft_create_font_from_pattern (resolved); + + FcPatternDestroy (pattern); + FcPatternDestroy (resolved); + return font; + errquit1: + FcPatternDestroy (pattern); + errquit0: + return NULL; +} |