summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@tika.localdomain>2006-11-26 19:23:29 +1100
committerBenjamin Herrenschmidt <benh@tika.localdomain>2006-11-26 19:23:29 +1100
commitf58ed76153b4469c4241003e3371a0a2dfc9bf7e (patch)
treec9b6f4c67853967249b838ff3f36e8a7a6a14da9
parentedfcd07f8c11d1eea81781d782f6840dfeec8013 (diff)
Add back support for pre-converted ttf fonts. The metrics generated by
the converter might still be a bit dodgy, I'd appreciate somebody who knows that stuff better to have a look :-) Basically, I added back the type '2' operation to the glyph data parser that was used by the previous ttf parser before it got removed and fixed it up to work in the new context. I pondered using the 'c' "generic" curve operation instead and put the burden of conversion in the converter application, but that would have caused bigger converted font files, so I chose to keep the old op. Various bits & pieces of the font code are modified to cope with the non-stroke fonts (mostly there is no "pen" to account for and we don't convolve but just append the glyph path to the current path). Full support for unicode pages is back. The stroke font has only page 0 for now (the initial code seemed to have more tables I didn't feel like re-converting that so if you want stroke font with more unicode pages, it's up to you to dig the old format and convert it to detect snaps and use curves). We may want to add arguments to twin_ttf converter to only convert a subset of the pages in a font for compactness. Examples still use the built-in font but it's easy enough to change the g_twin_font global and link a generated font file in (tested with Vera.ttf). I still need to add a better way to deal with multiple fonts at once.
-rw-r--r--Makefile.am4
-rw-r--r--configure.ac37
-rw-r--r--twin.h51
-rw-r--r--twin_font.c224
-rw-r--r--twin_font_default.c (renamed from twin_glyphs.c)84
-rw-r--r--twin_pixmap.c3
-rw-r--r--twin_ttf/Makefile.am2
-rw-r--r--twin_ttf/twin_ttf.c136
-rw-r--r--twinint.h11
9 files changed, 343 insertions, 209 deletions
diff --git a/Makefile.am b/Makefile.am
index 99b2fc0..b6e9150 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,7 @@
INCLUDES= @X_CFLAGS@ @WARN_CFLAGS@
+SUBDIRS=twin_ttf
+
#libtwin_la_SOURCES = \
# twin.h \
# twin_draw.c \
@@ -21,12 +23,12 @@ base_SOURCES = \
twin_cursor.c \
twin_dispatch.c \
twin_draw.c \
- twin_glyphs.c \
twin_hull.c \
twin_icon.c \
twin_file.c \
twin_fixed.c \
twin_font.c \
+ twin_font_default.c \
twin_geom.c \
twin_label.c \
twin_matrix.c \
diff --git a/configure.ac b/configure.ac
index 1534838..e402f42 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,23 +50,24 @@ PKG_CHECK_MODULES(X, x11,
AC_SUBST(X_CFLAGS)
AC_SUBST(X_LIBS)
-#
-#AC_ARG_WITH(freetype-config, [ --with-freetype-config=PROG Use FreeType configuration program PROG], freetype_config=$withval, freetype_config=yes)
-#
-#if test "$freetype_config" = "yes"; then
-# AC_PATH_PROG(ft_config,freetype-config,no)
-# if test "$ft_config" = "no"; then
-# AC_MSG_ERROR([You must have freetype installed; see http://www.freetype.org/])
-# fi
-#else
-# ft_config="$freetype_config"
-#fi
-#
-#FREETYPE_CFLAGS="`$ft_config --cflags`"
-#FREETYPE_LIBS="`$ft_config --libs`"
-#
-#AC_SUBST(FREETYPE_LIBS)
-#AC_SUBST(FREETYPE_CFLAGS)
+
+AC_ARG_WITH(freetype-config, [ --with-freetype-config=PROG Use FreeType configuration program PROG], freetype_config=$withval, freetype_config=yes)
+
+if test "$freetype_config" = "yes"; then
+ AC_PATH_PROG(ft_config,freetype-config,no)
+ if test "$ft_config" = "no"; then
+ AC_MSG_ERROR([You must have freetype installed; see http://www.freetype.org/])
+ fi
+else
+ ft_config="$freetype_config"
+fi
+
+FREETYPE_CFLAGS="`$ft_config --cflags`"
+FREETYPE_LIBS="`$ft_config --libs`"
+
+AC_SUBST(FREETYPE_LIBS)
+AC_SUBST(FREETYPE_CFLAGS)
AC_OUTPUT([Makefile
- twin.pc])
+ twin.pc
+ twin_ttf/Makefile])
diff --git a/twin.h b/twin.h
index bb30ad4..de8f8d7 100644
--- a/twin.h
+++ b/twin.h
@@ -263,6 +263,54 @@ typedef struct _twin_text_metrics {
twin_fixed_t font_descent;
} twin_text_metrics_t;
+
+/*
+ * Fonts
+ */
+#define UCS_PAGE_SHIFT 7
+#define UCS_PER_PAGE (1 << UCS_PAGE_SHIFT)
+
+static inline int twin_ucs_page (uint32_t ucs4)
+{
+ return ucs4 >> UCS_PAGE_SHIFT;
+}
+
+static inline int twin_ucs_char_in_page (uint32_t ucs4)
+{
+ return ucs4 & (UCS_PER_PAGE - 1);
+}
+
+typedef struct _twin_charmap {
+ unsigned int page;
+ unsigned int offsets[UCS_PER_PAGE];
+} twin_charmap_t;
+
+#define TWIN_FONT_TYPE_STROKE 1
+#define TWIN_FONT_TYPE_TTF 2
+
+typedef struct _twin_font {
+ /* those fields have to be initialized */
+ int type;
+ const char *name;
+ const char *style;
+ const twin_charmap_t *charmap;
+ int n_charmap;
+ const signed char *outlines;
+ signed char ascender;
+ signed char descender;
+ signed char height;
+
+ /* those are used at runtime for caching */
+ const twin_charmap_t *cur_page;
+
+} twin_font_t;
+
+/* XXX one global font for now, to fix */
+extern twin_font_t *g_twin_font;
+
+/* Built-in default stroke font */
+extern twin_font_t twin_Default_Font_Roman;
+
/*
* Events
*/
@@ -608,8 +656,7 @@ twin_fixed_div (twin_fixed_t a, twin_fixed_t b);
* twin_font.c
*/
-twin_bool_t
-twin_has_ucs4 (twin_ucs4_t ucs4);
+twin_bool_t twin_has_ucs4 (twin_font_t* font, twin_ucs4_t ucs4);
#define TWIN_TEXT_ROMAN 0
#define TWIN_TEXT_BOLD 1
diff --git a/twin_font.c b/twin_font.c
index c923a2d..f7e5d70 100644
--- a/twin_font.c
+++ b/twin_font.c
@@ -50,8 +50,9 @@ typedef struct _twin_text_info {
twin_fixed_t snap_y[TWIN_GLYPH_MAX_SNAP_Y];
} twin_text_info_t;
-static void
-_twin_text_compute_info (twin_path_t *path, twin_text_info_t *info)
+static void _twin_text_compute_info (twin_path_t *path,
+ twin_font_t *font,
+ twin_text_info_t *info)
{
twin_spoint_t origin = _twin_path_current_spoint (path);
@@ -64,20 +65,27 @@ _twin_text_compute_info (twin_path_t *path, twin_text_info_t *info)
(path->state.matrix.m[0][0] == 0 &&
path->state.matrix.m[1][1] == 0)))
{
- int xi, yi;
+ int xi, yi;
+ twin_fixed_t margin_x;
if (path->state.matrix.m[0][0] != 0)
xi = 0;
else
xi = 1;
yi = 1-xi;
- info->snap = TWIN_TRUE;
info->matrix.m[xi][0] = TWIN_FIXED_ONE;
info->matrix.m[xi][1] = 0;
info->matrix.m[yi][0] = 0;
info->matrix.m[yi][1] = TWIN_FIXED_ONE;
- info->matrix.m[2][0] = SNAPI(twin_sfixed_to_fixed (origin.x));
- info->matrix.m[2][1] = SNAPI(twin_sfixed_to_fixed (origin.y));
+ if (font->type == TWIN_FONT_TYPE_STROKE) {
+ info->snap = TWIN_TRUE;
+ info->matrix.m[2][0] = SNAPI(twin_sfixed_to_fixed (origin.x));
+ info->matrix.m[2][1] = SNAPI(twin_sfixed_to_fixed (origin.y));
+ } else {
+ info->snap = TWIN_FALSE;
+ info->matrix.m[2][0] = twin_sfixed_to_fixed (origin.x);
+ info->matrix.m[2][1] = twin_sfixed_to_fixed (origin.y);
+ }
info->scale.x = twin_fixed_mul (path->state.font_size,
path->state.matrix.m[0][xi]);
info->reverse_scale.x = twin_fixed_div (TWIN_FIXED_ONE,
@@ -101,30 +109,41 @@ _twin_text_compute_info (twin_path_t *path, twin_text_info_t *info)
info->matrix.m[1][yi] = -info->matrix.m[1][yi];
}
- info->pen.x = SNAPH(info->scale.x / 24);
- info->pen.y = SNAPH(info->scale.y / 24);
- if (info->pen.x < TWIN_FIXED_HALF)
- info->pen.x = TWIN_FIXED_HALF;
- if (info->pen.y < TWIN_FIXED_HALF)
- info->pen.y = TWIN_FIXED_HALF;
+ if (font->type == TWIN_FONT_TYPE_STROKE) {
+ info->pen.x = SNAPH(info->scale.x / 24);
+ info->pen.y = SNAPH(info->scale.y / 24);
+ if (info->pen.x < TWIN_FIXED_HALF)
+ info->pen.x = TWIN_FIXED_HALF;
+ if (info->pen.y < TWIN_FIXED_HALF)
+ info->pen.y = TWIN_FIXED_HALF;
+ } else {
+ info->pen.x = 0;
+ info->pen.y = 0;
+ }
info->margin.x = info->pen.x;
info->margin.y = info->pen.y;
- if (path->state.font_style & TWIN_TEXT_BOLD)
+ if (font->type == TWIN_FONT_TYPE_STROKE &&
+ (path->state.font_style & TWIN_TEXT_BOLD))
{
- twin_fixed_t pen_x_add = SNAPH(info->pen.x >> 1);
- twin_fixed_t pen_y_add = SNAPH(info->pen.y >> 1);
+ twin_fixed_t pen_x_add;
+ twin_fixed_t pen_y_add;
+
+ pen_x_add = SNAPH(info->pen.x >> 1);
+ pen_y_add = SNAPH(info->pen.y >> 1);
if (pen_x_add < TWIN_FIXED_HALF)
- pen_x_add = TWIN_FIXED_HALF;
+ pen_x_add = TWIN_FIXED_HALF;
if (pen_y_add < TWIN_FIXED_HALF)
pen_y_add = TWIN_FIXED_HALF;
+
info->pen.x += pen_x_add;
info->pen.y += pen_y_add;
}
DBGMSG (("pen: %9.4f %9.4f\n", F(info->pen.x), F(info->pen.y)));
+ margin_x = info->snap ? SNAPI(info->margin.x) : info->margin.x;
twin_matrix_translate (&info->matrix,
- SNAPI(info->margin.x) + info->pen.x,
+ margin_x + info->pen.x,
-info->pen.y);
info->pen_matrix = info->matrix;
}
@@ -137,11 +156,15 @@ _twin_text_compute_info (twin_path_t *path, twin_text_info_t *info)
info->scale.x = path->state.font_size;
info->scale.y = path->state.font_size;
- if (path->state.font_style & TWIN_TEXT_BOLD)
- info->pen.x = path->state.font_size / 16;
- else
- info->pen.x = path->state.font_size / 24;
- info->pen.y = info->pen.x;
+ if (font->type != TWIN_FONT_TYPE_STROKE)
+ info->pen.x = info->pen.y = 0;
+ else {
+ if (path->state.font_style & TWIN_TEXT_BOLD)
+ info->pen.x = path->state.font_size / 16;
+ else
+ info->pen.x = path->state.font_size / 24;
+ info->pen.y = info->pen.x;
+ }
info->margin.x = path->state.font_size / 24;
info->margin.y = info->margin.x;
@@ -167,9 +190,8 @@ _twin_text_compute_info (twin_path_t *path, twin_text_info_t *info)
DBGMSG (("%9.4f %9.4f\n", F(info->matrix.m[2][0]), F(info->matrix.m[2][1])));
}
-static void
-_twin_text_compute_snap (twin_text_info_t *info,
- const signed char *b)
+static void _twin_text_compute_snap (twin_text_info_t *info,
+ const signed char *b)
{
int s, n;
const signed char *snap;
@@ -187,8 +209,7 @@ _twin_text_compute_snap (twin_text_info_t *info,
info->snap_y[s] = FY(snap[s], info);
}
-static twin_path_t *
-_twin_text_compute_pen (twin_text_info_t *info)
+static twin_path_t * _twin_text_compute_pen (twin_text_info_t *info)
{
twin_path_t *pen = twin_path_create ();
@@ -197,10 +218,9 @@ _twin_text_compute_pen (twin_text_info_t *info)
return pen;
}
-static twin_fixed_t
-_twin_snap (twin_fixed_t v,
- twin_fixed_t *snap,
- int n)
+static twin_fixed_t _twin_snap (twin_fixed_t v,
+ twin_fixed_t *snap,
+ int n)
{
int s;
@@ -230,26 +250,43 @@ _twin_snap (twin_fixed_t v,
return v;
}
-twin_bool_t
-twin_has_ucs4 (twin_ucs4_t ucs4)
+static twin_bool_t twin_find_ucs4_page(twin_font_t *font, uint32_t page)
{
- return ucs4 <= TWIN_FONT_MAX && _twin_g_offsets[ucs4] != 0;
+ int i;
+
+ if (font->cur_page && font->cur_page->page == page)
+ return TWIN_TRUE;
+
+ for (i = 0; i < font->n_charmap; i++)
+ if (font->charmap[i].page == page) {
+ font->cur_page = &font->charmap[i];
+ return TWIN_TRUE;
+ }
+
+ font->cur_page = &font->charmap[0];
+ return TWIN_FALSE;
+}
+
+twin_bool_t twin_has_ucs4 (twin_font_t *font, twin_ucs4_t ucs4)
+{
+ return twin_find_ucs4_page(font, twin_ucs_page(ucs4));
}
#define SNAPX(p) _snap (path, p, snap_x, nsnap_x)
#define SNAPY(p) _snap (path, p, snap_y, nsnap_y)
-static const signed char *
-_twin_g_base (twin_ucs4_t ucs4)
+static const signed char * _twin_g_base (twin_font_t *font, twin_ucs4_t ucs4)
{
- if (ucs4 > TWIN_FONT_MAX) ucs4 = 0;
+ int idx = twin_ucs_char_in_page(ucs4);
+
+ if (!twin_find_ucs4_page(font, twin_ucs_page(ucs4)))
+ idx = 0;
- return _twin_gtable + _twin_g_offsets[ucs4];
+ return font->outlines + font->cur_page->offsets[idx];
}
-static twin_fixed_t
-_twin_glyph_width (twin_text_info_t *info,
- const signed char *b)
+static twin_fixed_t _twin_glyph_width (twin_text_info_t *info,
+ const signed char *b)
{
twin_fixed_t right = FX(twin_glyph_right(b), info) + info->pen.x * 2;
twin_fixed_t right_side_bearing;
@@ -263,12 +300,12 @@ _twin_glyph_width (twin_text_info_t *info,
return width;
}
-void
-twin_text_metrics_ucs4 (twin_path_t *path,
- twin_ucs4_t ucs4,
- twin_text_metrics_t *m)
+void twin_text_metrics_ucs4 (twin_path_t *path,
+ twin_ucs4_t ucs4,
+ twin_text_metrics_t *m)
{
- const signed char *b = _twin_g_base (ucs4);
+ twin_font_t *font = g_twin_font;
+ const signed char *b = _twin_g_base (font, ucs4);
twin_text_info_t info;
twin_fixed_t left, right, ascent, descent;
twin_fixed_t font_spacing;
@@ -276,7 +313,7 @@ twin_text_metrics_ucs4 (twin_path_t *path,
twin_fixed_t font_ascent;
twin_fixed_t margin_x, margin_y;
- _twin_text_compute_info (path, &info);
+ _twin_text_compute_info (path, font, &info);
if (info.snap)
_twin_text_compute_snap (&info, b);
@@ -317,19 +354,28 @@ twin_text_metrics_ucs4 (twin_path_t *path,
m->font_descent = font_descent + margin_y;
}
-void
-twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
+static const signed char *twin_glyph_draw(twin_font_t *font,
+ const signed char *b)
+{
+ if (font->type == TWIN_FONT_TYPE_STROKE)
+ return twin_glyph_snap_y(b) + twin_glyph_n_snap_y(b);
+ return b + 4;
+}
+
+void twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
{
- const signed char *b = _twin_g_base (ucs4);
- const signed char *g = twin_glyph_draw(b);
+ twin_font_t *font = g_twin_font;
+ const signed char *b = _twin_g_base (font, ucs4);
+ const signed char *g = twin_glyph_draw(font, b);
twin_spoint_t origin;
- twin_fixed_t x1, y1, x2, y2, x3, y3;
+ twin_fixed_t x1, y1, x2, y2, x3, y3, _x1, _y1;
twin_path_t *stroke;
- twin_path_t *pen;
+ twin_path_t *pen = NULL;
twin_fixed_t width;
twin_text_info_t info;
-
- _twin_text_compute_info (path, &info);
+ signed char op;
+
+ _twin_text_compute_info (path, font, &info);
if (info.snap)
_twin_text_compute_snap (&info, b);
@@ -337,10 +383,13 @@ twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
stroke = twin_path_create ();
twin_path_set_matrix (stroke, info.matrix);
- pen = _twin_text_compute_pen (&info);
-
+
+ if (font->type == TWIN_FONT_TYPE_STROKE)
+ pen = _twin_text_compute_pen (&info);
+
+ x1 = y1 = 0;
for (;;) {
- switch (*g++) {
+ switch ((op = *g++)) {
case 'm':
x1 = FX(*g++, &info);
y1 = FY(*g++, &info);
@@ -368,31 +417,47 @@ twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
twin_path_draw (stroke, x1, y1);
continue;
case 'c':
- x1 = FX(*g++, &info);
- y1 = FY(*g++, &info);
- x2 = FX(*g++, &info);
- y2 = FY(*g++, &info);
x3 = FX(*g++, &info);
y3 = FY(*g++, &info);
+ x2 = FX(*g++, &info);
+ y2 = FY(*g++, &info);
+ x1 = FX(*g++, &info);
+ y1 = FY(*g++, &info);
if (info.snap)
{
- x1 = _twin_snap (x1, info.snap_x, info.n_snap_x);
- y1 = _twin_snap (y1, info.snap_y, info.n_snap_y);
- x2 = _twin_snap (x2, info.snap_x, info.n_snap_x);
- y2 = _twin_snap (y2, info.snap_y, info.n_snap_y);
x3 = _twin_snap (x3, info.snap_x, info.n_snap_x);
y3 = _twin_snap (y3, info.snap_y, info.n_snap_y);
+ x2 = _twin_snap (x2, info.snap_x, info.n_snap_x);
+ y2 = _twin_snap (y2, info.snap_y, info.n_snap_y);
+ x1 = _twin_snap (x1, info.snap_x, info.n_snap_x);
+ y1 = _twin_snap (y1, info.snap_y, info.n_snap_y);
}
- twin_path_curve (stroke, x1, y1, x2, y2, x3, y3);
+ twin_path_curve (stroke, x3, y3, x2, y2, x1, y1);
+ continue;
+ case '2':
+ _x1 = FX(*g++, &info);
+ _y1 = FY(*g++, &info);
+ x3 = x1 + 2 * (_x1 - x1) / 3;
+ y3 = y1 + 2 * (_y1 - y1) / 3;
+ x1 = FX(*g++, &info);
+ y1 = FY(*g++, &info);
+ x2 = x1 + 2 * (_x1 - x1) / 3;
+ y2 = y1 + 2 * (_y1 - y1) / 3;
+ twin_path_curve (stroke, x3, y3, x2, y2, x1, y1);
continue;
case 'e':
break;
+ default:
+ DBGMSG (("unknown font op 0x%02x '%c'\n", op, op));
}
break;
}
- twin_path_convolve (path, stroke, pen);
- twin_path_destroy (pen);
+ if (font->type == TWIN_FONT_TYPE_STROKE) {
+ twin_path_convolve (path, stroke, pen);
+ twin_path_destroy (pen);
+ } else
+ twin_path_append(path, stroke);
twin_path_destroy (stroke);
width = _twin_glyph_width (&info, b);
@@ -402,8 +467,7 @@ twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
origin.y + _twin_matrix_dy (&info.matrix, width, 0));
}
-twin_fixed_t
-twin_width_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
+twin_fixed_t twin_width_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
{
twin_text_metrics_t metrics;
@@ -411,9 +475,8 @@ twin_width_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
return metrics.width;
}
-static int
-_twin_utf8_to_ucs4 (const char *src_orig,
- twin_ucs4_t *dst)
+static int _twin_utf8_to_ucs4 (const char *src_orig,
+ twin_ucs4_t *dst)
{
const char *src = src_orig;
char s;
@@ -479,8 +542,7 @@ _twin_utf8_to_ucs4 (const char *src_orig,
return src - src_orig;
}
-void
-twin_path_utf8 (twin_path_t *path, const char *string)
+void twin_path_utf8 (twin_path_t *path, const char *string)
{
int len;
twin_ucs4_t ucs4;
@@ -492,8 +554,7 @@ twin_path_utf8 (twin_path_t *path, const char *string)
}
}
-twin_fixed_t
-twin_width_utf8 (twin_path_t *path, const char *string)
+twin_fixed_t twin_width_utf8 (twin_path_t *path, const char *string)
{
int len;
twin_ucs4_t ucs4;
@@ -507,10 +568,9 @@ twin_width_utf8 (twin_path_t *path, const char *string)
return w;
}
-void
-twin_text_metrics_utf8 (twin_path_t *path,
- const char *string,
- twin_text_metrics_t *m)
+void twin_text_metrics_utf8 (twin_path_t *path,
+ const char *string,
+ twin_text_metrics_t *m)
{
int len;
twin_ucs4_t ucs4;
diff --git a/twin_glyphs.c b/twin_font_default.c
index dab8b67..2b1c44c 100644
--- a/twin_glyphs.c
+++ b/twin_font_default.c
@@ -1,28 +1,31 @@
/*
- * Twin - A Tiny Window System
- * Copyright © 2004 Keith Packard <keithp@keithp.com>
- * All rights reserved.
+ * $Id: twin_glyphs.c,v 1.7 2004-10-29 17:33:03 keithp Exp $
*
- * This Library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
+ * Copyright © 2004 Keith Packard
*
- * This Library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
*
- * You should have received a copy of the GNU Library General Public
- * License along with the Twin Library; see the file COPYING. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
*/
-#include "twinint.h"
+#include "twin.h"
-const signed char _twin_gtable[] = {
+static const signed char outlines[] = {
/* 0x0 '\0' offset 0 */
0, 24, 42, 0, 2, 4,
0, 24, /* snap_x */
@@ -1029,21 +1032,34 @@ const signed char _twin_gtable[] = {
'e',
};
-const uint16_t _twin_g_offsets[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 28, 40, 90, 114, 152, 224, 323, 390,
- 419, 441, 463, 494, 520, 556, 575, 604,
- 622, 666, 691, 736, 780, 809, 860, 919,
- 944, 1004, 1063, 1109, 1162, 1183, 1209, 1230,
- 1288, 1375, 1406, 1455, 1499, 1534, 1572, 1604,
- 1655, 1686, 1703, 1731, 1761, 1785, 1821, 1851,
- 1895, 1931, 1981, 2023, 2074, 2100, 2128, 2152,
- 2188, 2212, 2240, 2271, 2296, 2314, 2339, 2363,
- 2381, 2417, 2467, 2517, 2561, 2611, 2659, 2693,
- 2758, 2790, 2826, 2870, 2900, 2917, 2963, 2995,
- 3039, 3089, 3139, 3168, 3219, 3252, 3283, 3307,
- 3343, 3367, 3399, 3430, 3474, 3491, 3535, 0,
+static const twin_charmap_t charmap[] = {
+ { 0x0000, {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 28, 40, 90, 114, 152, 224, 323, 390,
+ 419, 441, 463, 494, 520, 556, 575, 604,
+ 622, 666, 691, 736, 780, 809, 860, 919,
+ 944, 1004, 1063, 1109, 1162, 1183, 1209, 1230,
+ 1288, 1375, 1406, 1455, 1499, 1534, 1572, 1604,
+ 1655, 1686, 1703, 1731, 1761, 1785, 1821, 1851,
+ 1895, 1931, 1981, 2023, 2074, 2100, 2128, 2152,
+ 2188, 2212, 2240, 2271, 2296, 2314, 2339, 2363,
+ 2381, 2417, 2467, 2517, 2561, 2611, 2659, 2693,
+ 2758, 2790, 2826, 2870, 2900, 2917, 2963, 2995,
+ 3039, 3089, 3139, 3168, 3219, 3252, 3283, 3307,
+ 3343, 3367, 3399, 3430, 3474, 3491, 3535, 0,
+ }},
};
+
+twin_font_t twin_Default_Font_Roman = {
+ .type = TWIN_FONT_TYPE_STROKE,
+ .name = "Default",
+ .style = "Roman",
+ .n_charmap = 1,
+ .charmap = charmap,
+ .outlines = outlines,
+};
+
+twin_font_t *g_twin_font = &twin_Default_Font_Roman;
diff --git a/twin_pixmap.c b/twin_pixmap.c
index 6eabdfb..8cd00ac 100644
--- a/twin_pixmap.c
+++ b/twin_pixmap.c
@@ -66,6 +66,9 @@ twin_pixmap_create_const (twin_format_t format,
pixmap->format = format;
pixmap->width = width;
pixmap->height = height;
+ pixmap->clip.left = pixmap->clip.top = 0;
+ pixmap->clip.right = pixmap->width;
+ pixmap->clip.bottom = pixmap->height;
pixmap->stride = stride;
pixmap->disable = 0;
pixmap->p = pixels;
diff --git a/twin_ttf/Makefile.am b/twin_ttf/Makefile.am
index 89e9b32..c608c02 100644
--- a/twin_ttf/Makefile.am
+++ b/twin_ttf/Makefile.am
@@ -1,4 +1,4 @@
-CFLAGS=-g
+AM_CFLAGS=-g
INCLUDES= @WARN_CFLAGS@ @FREETYPE_CFLAGS@
bin_PROGRAMS = twin_ttf
diff --git a/twin_ttf/twin_ttf.c b/twin_ttf/twin_ttf.c
index d8fa3af..24a9d9b 100644
--- a/twin_ttf/twin_ttf.c
+++ b/twin_ttf/twin_ttf.c
@@ -24,31 +24,32 @@
#include "twin_ttf.h"
-static double
-pos (FT_Pos x, outline_closure_t *c)
+static double pos (FT_Pos x, outline_closure_t *c)
{
FT_Face face = c->face;
return (double) x / (double) face->units_per_EM;
}
-static void
-command (char cmd, outline_closure_t *c)
+static void command (char cmd, outline_closure_t *c)
{
printf ("\t'%c', ", cmd);
c->offset++;
}
-static void
-cpos (FT_Pos x, outline_closure_t *c)
+static int conv (FT_Pos x, outline_closure_t *c)
{
- printf ("0x%02x, ", ((int) (floor (64.0 * pos (x, c) + 0.5))) & 0xff);
+ return floor(64.0 * pos (x, c) + 0.5);
+}
+
+static void cpos (FT_Pos x, outline_closure_t *c)
+{
+ printf ("%d, ", conv(x, c));
c->offset++;
}
-static unsigned char *
-ucs4_to_utf8 (FT_ULong ucs4,
- unsigned char dest[8])
+static unsigned char * ucs4_to_utf8 (FT_ULong ucs4,
+ unsigned char dest[8])
{
int bits;
unsigned char *d = dest;
@@ -68,82 +69,98 @@ ucs4_to_utf8 (FT_ULong ucs4,
return dest;
}
-static void
-glyph (FT_Pos advance, FT_ULong ucs4, outline_closure_t *c)
+static void glyph (FT_GlyphSlot glyph, FT_ULong ucs4, outline_closure_t *c)
{
+ FT_Pos advance = glyph->linearHoriAdvance;
unsigned char utf8[8];
- printf (" /* 0x%lx (%s) */ ", ucs4, ucs4_to_utf8 (ucs4, utf8));
- cpos (advance, c);
+
+ printf (" /* 0x%lx (%s) */ \n", ucs4, ucs4_to_utf8 (ucs4, utf8));
+
+ /* I'm very unusre about the metrics here, mostly because I'm not 100%
+ * confident what twin expects in some of those fields
+ *
+ * twin wants: left, right, ascent, descent.
+ *
+ * For now, I'm setting "left" to horiBearingX though I'm not quite sure
+ * what this is used for, "right" to the full horizontal advance of
+ * the glyph as that's what twin uses as an advance between characters,
+ * "ascent" I set to horiBearingY (unsure there too though) and for the
+ * last, descent, I suppose I should use the total height minus the ascent
+ * though I'm not sure how to retreive the former (bbox ?).
+ *
+ * Note that currently, we only support horizontal text.
+ */
+ cpos (glyph->metrics.horiBearingX, c); /* left, not sure about that */
+ cpos (advance, c); /* right */
+ cpos (glyph->metrics.horiBearingY, c); /* ascent, not sure either */
+ cpos (0 /* XXX */, c); /* descent, not handled now */
printf ("\n");
}
-static int
-outline_moveto (FT_Vector *to, void *user)
+static int outline_moveto (const FT_Vector *to, void *user)
{
outline_closure_t *c = user;
- command ('m', c); cpos (to->x, c); cpos (to->y, c);
+ command ('m', c); cpos (to->x, c); cpos (-to->y, c);
printf ("\n");
return 0;
}
-static int
-outline_lineto (FT_Vector *to, void *user)
+static int outline_lineto (const FT_Vector *to, void *user)
{
outline_closure_t *c = user;
- command ('l', c); cpos (to->x, c); cpos (to->y, c);
+ command ('l', c); cpos (to->x, c); cpos (-to->y, c);
printf ("\n");
return 0;
}
-static int
-outline_conicto (FT_Vector *control, FT_Vector *to, void *user)
+static int outline_conicto (const FT_Vector *control, const FT_Vector *to,
+ void *user)
{
outline_closure_t *c = user;
command ('2', c);
- cpos (control->x, c); cpos (control->y, c);
- cpos (to->x, c); cpos (to->y, c);
+ cpos (control->x, c); cpos (0-control->y, c);
+ cpos (to->x, c); cpos (0-to->y, c);
printf ("\n");
return 0;
}
-static int
-outline_cubicto (FT_Vector *control1, FT_Vector *control2,
- FT_Vector *to, void *user)
+static int outline_cubicto (const FT_Vector *control1,
+ const FT_Vector *control2,
+ const FT_Vector *to,
+ void *user)
{
outline_closure_t *c = user;
command ('2', c);
- cpos (control1->x, c); cpos (control1->y, c);
- cpos (control2->x, c); cpos (control2->y, c);
- cpos (to->x, c); cpos (to->y, c);
+ cpos (control1->x, c); cpos (0-control1->y, c);
+ cpos (control2->x, c); cpos (0-control2->y, c);
+ cpos (to->x, c); cpos (0-to->y, c);
printf ("\n");
return 0;
}
static const FT_Outline_Funcs outline_funcs = {
- outline_moveto,
- outline_lineto,
- outline_conicto,
- outline_cubicto,
- 0, 0
+ .move_to = outline_moveto,
+ .line_to = outline_lineto,
+ .conic_to = outline_conicto,
+ .cubic_to = outline_cubicto,
+ .shift = 0,
+ .delta = 0
};
#define UCS_PAGE_SHIFT 7
#define UCS_PER_PAGE (1 << UCS_PAGE_SHIFT)
-static int
-ucs_page (FT_ULong ucs4)
+static int ucs_page (FT_ULong ucs4)
{
return ucs4 >> UCS_PAGE_SHIFT;
}
-static FT_ULong
-ucs_first_in_page (FT_ULong ucs4)
+static FT_ULong ucs_first_in_page (FT_ULong ucs4)
{
return ucs4 & ~(UCS_PER_PAGE - 1);
}
-static void
-sanitize (char *in, char *out, int first)
+static void sanitize (char *in, char *out, int first)
{
char c;
@@ -166,8 +183,7 @@ sanitize (char *in, char *out, int first)
*out++ = '\0';
}
-static char *
-facename (FT_Face face)
+static char * facename (FT_Face face)
{
char *family = face->family_name;
char *style = face->style_name;
@@ -181,8 +197,7 @@ facename (FT_Face face)
#define MAX_UCS4 0x1000000
-static int
-convert_font (char *in_name, int id)
+static int convert_font (char *in_name, int id)
{
FT_Library ftLibrary;
FT_Face face;
@@ -213,8 +228,8 @@ convert_font (char *in_name, int id)
min_ucs4 = 0xffffff;
max_ucs4 = 0;
printf ("/* Derived from %s */\n\n", in_name);
- printf ("#include \"twinint.h\"\n\n");
- printf ("static const char outlines[] = {\n");
+ printf ("#include \"twin.h\"\n\n");
+ printf ("static const signed char outlines[] = {\n");
for (ucs4 = FT_Get_First_Char (face, &gindex);
gindex != 0 && ucs4 < MAX_UCS4;
ucs4 = FT_Get_Next_Char (face, ucs4, &gindex))
@@ -225,8 +240,9 @@ convert_font (char *in_name, int id)
min_ucs4 = ucs4;
if (ucs4 > max_ucs4)
max_ucs4 = ucs4;
- offsets[gindex] = closure.offset + 1;
- glyph (face->glyph->linearHoriAdvance, ucs4, &closure);
+ //offsets[gindex] = closure.offset + 1;
+ offsets[gindex] = closure.offset;
+ glyph (face->glyph, ucs4, &closure);
FT_Outline_Decompose (&face->glyph->outline, &outline_funcs, &closure);
command ('e', &closure); printf ("\n");
}
@@ -255,21 +271,21 @@ convert_font (char *in_name, int id)
ncharmap++;
}
printf ("};\n\n");
- printf ("const twin_font_t twin_%s = {\n", facename (face));
- printf (" charmap, %d,\n", ncharmap);
- printf (" outlines,\n");
- printf (" ");
- cpos (face->ascender, &closure);
- cpos (face->descender, &closure);
- cpos (face->height, &closure);
- printf ("\n");
- printf (" \"%s\", \"%s\",\n", face->family_name, face->style_name);
+ printf ("twin_font_t twin_%s = {\n", facename (face));
+ printf ("\t.type\t\t= TWIN_FONT_TYPE_TTF,\n");
+ printf ("\t.name\t\t= \"%s\",\n", face->family_name);
+ printf ("\t.style\t\t= \"%s\",\n", face->style_name);
+ printf ("\t.n_charmap\t= %d,\n", ncharmap);
+ printf ("\t.charmap\t= charmap,\n");
+ printf ("\t.outlines\t= outlines,\n");
+ printf ("\t.ascender\t= %d,\n", conv (face->ascender, &closure));
+ printf ("\t.descender\t= %d,\n", conv (face->descender, &closure));
+ printf ("\t.height\t\t= %d,\n", conv (face->height, &closure));
printf ("};\n");
return 1;
}
-int
-main (int argc, char **argv)
+int main (int argc, char **argv)
{
convert_font (argv[1], 0);
return 0;
diff --git a/twinint.h b/twinint.h
index 80bd119..85d84de 100644
--- a/twinint.h
+++ b/twinint.h
@@ -349,16 +349,6 @@ _twin_path_sfinish (twin_path_t *path);
* Glyph stuff. Coordinates are stored in 2.6 fixed point format
*/
-#define TWIN_FONT_MAX 0x7f
-
-extern const twin_gpoint_t _twin_glyphs[];
-extern const uint16_t _twin_glyph_offsets[];
-
-#define TWIN_GLYPH_MAX_POINTS 56
-
-extern const signed char _twin_gtable[];
-extern const uint16_t _twin_g_offsets[];
-
/*
* Check these whenever glyphs are changed
*/
@@ -373,7 +363,6 @@ extern const uint16_t _twin_g_offsets[];
#define twin_glyph_n_snap_y(g) ((g)[5])
#define twin_glyph_snap_x(g) (&g[6])
#define twin_glyph_snap_y(g) (twin_glyph_snap_x(g) + twin_glyph_n_snap_x(g))
-#define twin_glyph_draw(g) (twin_glyph_snap_y(g) + twin_glyph_n_snap_y(g))
/*
* dispatch stuff