summaryrefslogtreecommitdiff
path: root/src/sdl-ft.c
diff options
context:
space:
mode:
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
commit3f4e12a866e99183358b751ac64e30e26672b2ee (patch)
tree5945e198beacd17eb4779183a3cafb65e3d97d26 /src/sdl-ft.c
import initial sources
Diffstat (limited to 'src/sdl-ft.c')
-rw-r--r--src/sdl-ft.c269
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;
+}