[cairo-commit] 6 commits - src/cairo-font-face-twin.c src/cairo-font-face-twin-data.c src/cairoint.h src/cairo-user-font.c util/cairo-view util/Makefile.am
Behdad Esfahbod
behdad at kemper.freedesktop.org
Tue Dec 23 10:49:09 PST 2008
src/cairo-font-face-twin-data.c | 2
src/cairo-font-face-twin.c | 228 +++++++++++++++++++++++++++++++++++++---
src/cairo-user-font.c | 4
src/cairoint.h | 6 -
util/Makefile.am | 3
util/cairo-view | 113 +++++++++++++++++++
6 files changed, 331 insertions(+), 25 deletions(-)
New commits:
commit 52cc31a7fa6570e538762631359a92e7b717710e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Dec 23 13:48:52 2008 -0500
[util] Add cairo-view
diff --git a/util/Makefile.am b/util/Makefile.am
index f272e4c..db40f17 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -27,4 +27,5 @@ malloc_stats_la_LIBADD = $(backtrace_symbols_la_LIBADD) backtrace-symbols.lo
EXTRA_DIST += \
COPYING \
xr2cairo \
- cairo-api-update
+ cairo-api-update \
+ cairo-view
diff --git a/util/cairo-view b/util/cairo-view
new file mode 100755
index 0000000..83d5702
--- /dev/null
+++ b/util/cairo-view
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+
+import sys
+import cairo
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gtk.gdk
+import pango
+import gobject
+
+class CairoView(gtk.Window):
+ def __init__(self, family="", slant=0, weight=0, size=18, text="The Quick Brown Fox Jumped Over The Lazy Dog!"):
+ gtk.Widget.__init__ (self)
+
+ self.family = family
+ if slant == "italic":
+ self.slant = cairo.FONT_SLANT_ITALIC
+ elif slant == "oblique":
+ self.slant = cairo.FONT_SLANT_OBLIQUE
+ else:
+ self.slant = cairo.FONT_SLANT_NORMAL
+ if weight == "bold":
+ self.weight = cairo.FONT_WEIGHT_BOLD
+ else:
+ self.weight = cairo.FONT_WEIGHT_NORMAL
+ self.size = float (size)
+ self.text = text
+
+ def do_realize(self):
+ self.set_flags(self.flags() | gtk.REALIZED)
+
+ self.window = gtk.gdk.Window(
+ self.get_parent_window(),
+ width=self.allocation.width,
+ height=self.allocation.height,
+ window_type=gtk.gdk.WINDOW_CHILD,
+ wclass=gtk.gdk.INPUT_OUTPUT,
+ event_mask=self.get_events() | gtk.gdk.EXPOSURE_MASK)
+
+ self.window.set_user_data(self)
+
+ self.style.attach(self.window)
+
+ self.style.set_background(self.window, gtk.STATE_NORMAL)
+
+ self.width, self.height = self.draw ()
+ self.window.move_resize(0, 0, self.width, self.height)
+
+ def do_unrealize(self):
+ self.window.destroy()
+
+ def do_expose_event(self, event):
+ self.draw (event)
+
+ return False
+
+ def draw(self, event = None):
+
+ cr = self.window.cairo_create()
+ if event:
+ cr.rectangle(event.area.x, event.area.y,
+ event.area.width, event.area.height)
+ cr.clip()
+
+ cr.set_source_rgb (1, 1, 1)
+ cr.paint ()
+
+ cr.select_font_face (self.family, self.slant, self.weight)
+ cr.set_font_size (self.size)
+
+ PAD = 30
+
+ extents = cr.text_extents (self.text)
+ cr.translate (PAD-extents[0], PAD-extents[1])
+
+ font_extents = cr.font_extents ()
+ cr.rectangle (0, -font_extents[0], extents[4], font_extents[2])
+ cr.move_to (-PAD, 0)
+ cr.line_to (extents[2]+PAD, 0)
+ cr.set_source_rgba (1, 0, 0, .7)
+ cr.stroke ()
+
+ cr.rectangle (*extents[:4])
+ cr.set_source_rgba (0, 1, 0, .7)
+ cr.stroke ()
+
+ cr.move_to (0, 0)
+ cr.set_source_rgb (0, 0, 0)
+ cr.show_text (self.text)
+
+ return int (extents[2]) + 2 * PAD, int (extents[3]) + 2 * PAD
+
+ def run(self):
+
+ self.props.allow_shrink = True
+ self.connect("destroy", gtk.main_quit)
+ self.show()
+
+ gtk.main()
+
+gobject.type_register(CairoView)
+
+def main(args):
+
+ if len (args) == 1:
+ print "usage: cairo-view family [slant [weight [size [text]]]]"
+ sys.exit (1)
+ cv= CairoView (*args[1:])
+ cv.run()
+
+if __name__ == "__main__":
+ main(sys.argv)
commit 418c7ef133840c10eb0be7e75c7dd11533fbe897
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Dec 23 02:39:17 2008 -0500
[twin] Adjust font extents
diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 83be2d5..ade41e6 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -234,8 +234,8 @@ FREE_PROPS:
#define SNAPI(p) (p)
#define SNAPH(p) (p)
-#define FX(g) ((g) / 64.)
-#define FY(g) ((g) / 64.)
+#define FX(g) ((g) / 72.)
+#define FY(g) ((g) / 72.)
static cairo_status_t
@@ -243,8 +243,8 @@ twin_scaled_font_init (cairo_scaled_font_t *scaled_font,
cairo_t *cr,
cairo_font_extents_t *metrics)
{
- metrics->ascent = FY (50);
- metrics->descent = FY (14);
+ metrics->ascent = FY (52);
+ metrics->descent = 1 - metrics->ascent;
return CAIRO_STATUS_SUCCESS;
}
commit 96e41c28e980f313c51a0eed81681e7e48752797
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Dec 20 23:30:59 2008 -0500
[twin] Minor cleanup
diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 52c951d..83be2d5 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -258,7 +258,7 @@ twin_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font,
* to map all unknown chars to a single unknown glyph to
* reduce pressure on cache. */
- if (unicode < ARRAY_LENGTH (_cairo_twin_charmap))
+ if (likely (unicode < ARRAY_LENGTH (_cairo_twin_charmap)))
*glyph = unicode;
else
*glyph = 0;
@@ -283,9 +283,8 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
{
double x1, y1, x2, y2, x3, y3;
twin_face_properties_t *props;
- const int8_t *b = _cairo_twin_outlines +
- _cairo_twin_charmap[glyph >= ARRAY_LENGTH (_cairo_twin_charmap) ? 0 : glyph];
- const int8_t *g = twin_glyph_draw(b);
+ const int8_t *b;
+ const int8_t *g;
struct {
cairo_bool_t snap;
@@ -295,6 +294,10 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
int n_snap_y;
} info = {FALSE};
+ b = _cairo_twin_outlines +
+ _cairo_twin_charmap[unlikely (glyph >= ARRAY_LENGTH (_cairo_twin_charmap)) ? 0 : glyph];
+ g = twin_glyph_draw(b);
+
props = cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
&twin_face_properties_key);
cairo_set_tolerance (cr, 0.01);
commit 556f6ce364d81f9309162d21deb86a3d5b8b9a6e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Dec 20 23:16:53 2008 -0500
[twin] close_path the Q
diff --git a/src/cairo-font-face-twin-data.c b/src/cairo-font-face-twin-data.c
index dbc1bd2..cc43870 100644
--- a/src/cairo-font-face-twin-data.c
+++ b/src/cairo-font-face-twin-data.c
@@ -541,7 +541,7 @@ const int8_t _cairo_twin_outlines[] = {
'c', 0, -13, 2, 0, 16, 0,
'c', 30, 0, 32, -13, 32, -21,
'c', 32, -29, 30, -42, 16, -42,
- 'm', 18, -8,
+ 'M', 18, -8,
'l', 30, 4,
'e',
/* 0x52 'R' offset 1981 */
commit 6929ed800d19f359af7436636e8adc6203083a10
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Dec 20 20:25:01 2008 -0500
[twin] Fix serif option parsing. Also make serif and weight do something
diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 5cdbdd5..52c951d 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -127,7 +127,7 @@ parse_field (twin_face_properties_t *props,
const char *s,
int len)
{
- cairo_bool_t sans, serif;
+ cairo_bool_t sans = FALSE, serif = FALSE;
#define MATCH(s1, var, value) \
if (field_matches (s1, s, len)) var = value
@@ -180,6 +180,8 @@ props_parse (twin_face_properties_t *props,
parse_field (props, start, end - start);
start = end + 1;
}
+ if (start < end)
+ parse_field (props, start, end - start);
}
static cairo_status_t
@@ -280,6 +282,7 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
cairo_text_extents_t *metrics)
{
double x1, y1, x2, y2, x3, y3;
+ twin_face_properties_t *props;
const int8_t *b = _cairo_twin_outlines +
_cairo_twin_charmap[glyph >= ARRAY_LENGTH (_cairo_twin_charmap) ? 0 : glyph];
const int8_t *g = twin_glyph_draw(b);
@@ -292,10 +295,19 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
int n_snap_y;
} info = {FALSE};
+ props = cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
+ &twin_face_properties_key);
cairo_set_tolerance (cr, 0.01);
- cairo_set_line_width (cr, 0.066);
- cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ /* The weight is tuned to match DejaVu Sans' */
+ cairo_set_line_width (cr, props->weight * (5.5 / 64 / TWIN_WEIGHT_NORMAL));
+
+ cairo_set_miter_limit (cr, M_SQRT2);
+ cairo_set_line_join (cr, props->serif ?
+ CAIRO_LINE_JOIN_MITER :
+ CAIRO_LINE_JOIN_ROUND);
+ cairo_set_line_cap (cr, props->serif ?
+ CAIRO_LINE_CAP_SQUARE :
+ CAIRO_LINE_CAP_ROUND);
for (;;) {
switch (*g++) {
commit d423339fcef3c41225196c4371fb2c133ca61144
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Dec 20 19:39:58 2008 -0500
[twin] Add face properties
Just parse them now. We don't use them yet.
diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 5ac2cd2..5cdbdd5 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -36,15 +36,188 @@
#include "cairoint.h"
+#include <ctype.h>
+
/*
* This file implements a user-font rendering the decendant of the Hershey
* font coded by Keith Packard for use in the Twin window system.
* The actual font data is in cairo-font-face-twin-data.c
*
- * Ported to cairo user font by Behdad Esfahbod.
+ * Ported to cairo user font and extended by Behdad Esfahbod.
*/
+
+/*
+ * Face properties
+ */
+
+/* We synthesize multiple faces from the twin data. Here is the parameters. */
+
+/* CSS weight */
+typedef enum {
+ TWIN_WEIGHT_ULTRALIGHT = 200,
+ TWIN_WEIGHT_LIGHT = 300,
+ TWIN_WEIGHT_NORMAL = 400,
+ TWIN_WEIGHT_MEDIUM = 500,
+ TWIN_WEIGHT_SEMIBOLD = 600,
+ TWIN_WEIGHT_BOLD = 700,
+ TWIN_WEIGHT_ULTRABOLD = 800,
+ TWIN_WEIGHT_HEAVY = 900
+} twin_face_wight;
+
+/* CSS stretch */
+typedef enum {
+ TWIN_STRETCH_ULTRA_CONDENSED,
+ TWIN_STRETCH_EXTRA_CONDENSED,
+ TWIN_STRETCH_CONDENSED,
+ TWIN_STRETCH_SEMI_CONDENSED,
+ TWIN_STRETCH_NORMAL,
+ TWIN_STRETCH_SEMI_EXPANDED,
+ TWIN_STRETCH_EXPANDED,
+ TWIN_STRETCH_EXTRA_EXPANDED,
+ TWIN_STRETCH_ULTRA_EXPANDED
+} twin_face_stretch;
+
+
+typedef struct _twin_face_properties {
+ cairo_font_slant_t slant;
+ twin_face_wight weight;
+ twin_face_stretch stretch;
+
+ /* lets have some fun */
+ cairo_bool_t monospace;
+ cairo_bool_t serif;
+ cairo_bool_t smallcaps;
+} twin_face_properties_t;
+
+cairo_user_data_key_t twin_face_properties_key;
+
+#define TOLOWER(c) \
+ (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
+
+static cairo_bool_t
+field_matches (const char *s1,
+ const char *s2,
+ int len)
+{
+ int c1, c2;
+
+ while (len && *s1 && *s2)
+ {
+ c1 = TOLOWER (*s1);
+ c2 = TOLOWER (*s2);
+ if (c1 != c2) {
+ if (c1 == '-') {
+ s1++;
+ continue;
+ }
+ return FALSE;
+ }
+ s1++; s2++;
+ len--;
+ }
+
+ return len == 0 && *s1 == '\0';
+}
+
+
+static void
+parse_field (twin_face_properties_t *props,
+ const char *s,
+ int len)
+{
+ cairo_bool_t sans, serif;
+
+#define MATCH(s1, var, value) \
+ if (field_matches (s1, s, len)) var = value
+
+
+ MATCH ("oblique", props->slant, CAIRO_FONT_SLANT_OBLIQUE);
+ else MATCH ("italic", props->slant, CAIRO_FONT_SLANT_ITALIC);
+
+
+ else MATCH ("ultra-light", props->weight, TWIN_WEIGHT_ULTRALIGHT);
+ else MATCH ("light", props->weight, TWIN_WEIGHT_LIGHT);
+ else MATCH ("medium", props->weight, TWIN_WEIGHT_NORMAL);
+ else MATCH ("semi-bold", props->weight, TWIN_WEIGHT_SEMIBOLD);
+ else MATCH ("bold", props->weight, TWIN_WEIGHT_BOLD);
+ else MATCH ("ultra-bold", props->weight, TWIN_WEIGHT_ULTRABOLD);
+ else MATCH ("heavy", props->weight, TWIN_WEIGHT_HEAVY);
+
+ else MATCH ("ultra-condensed", props->stretch, TWIN_STRETCH_ULTRA_CONDENSED);
+ else MATCH ("extra-condensed", props->stretch, TWIN_STRETCH_EXTRA_CONDENSED);
+ else MATCH ("condensed", props->stretch, TWIN_STRETCH_CONDENSED);
+ else MATCH ("semi-condensed", props->stretch, TWIN_STRETCH_SEMI_CONDENSED);
+ else MATCH ("semi-expanded", props->stretch, TWIN_STRETCH_SEMI_EXPANDED);
+ else MATCH ("expanded", props->stretch, TWIN_STRETCH_EXPANDED);
+ else MATCH ("extra-expanded", props->stretch, TWIN_STRETCH_EXTRA_EXPANDED);
+ else MATCH ("ultra-expanded", props->stretch, TWIN_STRETCH_ULTRA_EXPANDED);
+
+ else MATCH ("small-caps", props->smallcaps, TRUE);
+
+ else MATCH ("mono", props->monospace, TRUE);
+ else MATCH ("monospace", props->monospace, TRUE);
+
+ else MATCH ("sans", sans, TRUE);
+ else MATCH ("sans-serif", sans, TRUE);
+ else MATCH ("serif", serif, TRUE);
+
+ props->serif = serif && !sans;
+}
+
+static void
+props_parse (twin_face_properties_t *props,
+ const char *s)
+{
+ const char *start, *end;
+
+ for (start = end = s; *end; end++) {
+ if (isalpha (*end) || *end == '-')
+ continue;
+
+ if (start < end)
+ parse_field (props, start, end - start);
+ start = end + 1;
+ }
+}
+
+static cairo_status_t
+twin_set_face_properties_from_toy (cairo_font_face_t *twin_face,
+ cairo_toy_font_face_t *toy_face)
+{
+ cairo_status_t status;
+ twin_face_properties_t *props;
+
+ props = malloc (sizeof (twin_face_properties_t));
+ if (unlikely (props == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ props->stretch = TWIN_STRETCH_NORMAL;
+ props->monospace = FALSE;
+ props->serif = FALSE;
+ props->smallcaps = FALSE;
+
+ /* fill in props */
+ props->slant = toy_face->slant;
+ props->weight = toy_face->weight == CAIRO_FONT_WEIGHT_NORMAL ?
+ TWIN_WEIGHT_NORMAL : TWIN_WEIGHT_BOLD;
+ props_parse (props, toy_face->family);
+
+ status = cairo_font_face_set_user_data (twin_face,
+ &twin_face_properties_key,
+ props, free);
+ if (status)
+ goto FREE_PROPS;
+
+ return CAIRO_STATUS_SUCCESS;
+
+FREE_PROPS:
+ free (props);
+ return status;
+}
+
+
#define twin_glyph_left(g) ((g)[0])
#define twin_glyph_right(g) ((g)[1])
#define twin_glyph_ascent(g) ((g)[2])
@@ -187,7 +360,7 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
}
metrics->x_advance = FX(twin_glyph_right(b)) + cairo_get_line_width (cr);
- metrics->x_advance += cairo_get_line_width (cr)/* XXX 2*x.margin */;
+ metrics->x_advance += 2*cairo_get_line_width (cr)/* XXX 2*x.margin */;
if (info.snap)
metrics->x_advance = SNAPI (SNAPX (metrics->x_advance));
@@ -195,16 +368,22 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
return CAIRO_STATUS_SUCCESS;
}
-cairo_font_face_t *
-_cairo_font_face_twin_create (cairo_font_slant_t slant,
- cairo_font_weight_t weight)
+cairo_status_t
+_cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face,
+ cairo_font_face_t **font_face)
{
+ cairo_status_t status;
cairo_font_face_t *twin_font_face;
twin_font_face = cairo_user_font_face_create ();
cairo_user_font_face_set_init_func (twin_font_face, twin_scaled_font_init);
cairo_user_font_face_set_render_glyph_func (twin_font_face, twin_scaled_font_render_glyph);
cairo_user_font_face_set_unicode_to_glyph_func (twin_font_face, twin_scaled_font_unicode_to_glyph);
+ status = twin_set_face_properties_from_toy (twin_font_face, toy_face);
+ if (status)
+ return status;
+
+ *font_face = twin_font_face;
- return twin_font_face;
+ return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index 9bfdedc..fe475ab 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -339,9 +339,7 @@ static cairo_status_t
_cairo_user_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
cairo_font_face_t **font_face)
{
- *font_face = _cairo_font_face_twin_create (cairo_toy_font_face_get_slant (&toy_face->base),
- cairo_toy_font_face_get_weight (&toy_face->base));
- return CAIRO_STATUS_SUCCESS;
+ return _cairo_font_face_twin_create_for_toy (toy_face, font_face);
}
static const cairo_scaled_font_backend_t _cairo_user_scaled_font_backend = {
diff --git a/src/cairoint.h b/src/cairoint.h
index 6914b11..882cfe4 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1393,9 +1393,9 @@ _cairo_toy_font_face_get_implementation (cairo_font_face_t *font_face);
/* cairo-font-face-twin.c */
-cairo_private cairo_font_face_t *
-_cairo_font_face_twin_create (cairo_font_slant_t slant,
- cairo_font_weight_t weight);
+cairo_private cairo_status_t
+_cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face,
+ cairo_font_face_t **font_face);
/* cairo-font-face-twin-data.c */
More information about the cairo-commit
mailing list