Commit 7bc3df89 authored by Darin Adler's avatar Darin Adler

Remove. Remove.

	* Makefile.am:
	* configure.in:
	* librsvg-2.0.pc.in:
	* librsvg.spec.in:
	* rsvg-ft.c: Remove.
	* rsvg-ft.h: Remove.
	* rsvg.h:
	* test-ft-gtk.c: Remove.
	* test-ft.c: Remove.
	* test-rsvg.c:
	Remove direct FreeType dependency and also remove
	dependency on libpng. No more rsvg_set_fonts_dir
	or rsvg-ft.h header.

	* rsvg.c: (rsvg_state_clone), (rsvg_state_finalize),
	(rsvg_parse_style_arg), (rsvg_pop_opacity_group),
	(rsvg_text_handler_characters), (rsvg_handle_free):
	Port from direct FreeType use to Pango.
parent bd3bb9b9
2002-01-02 Darin Adler <darin@bentspoon.com>
* Makefile.am:
* configure.in:
* librsvg-2.0.pc.in:
* librsvg.spec.in:
* rsvg-ft.c: Remove.
* rsvg-ft.h: Remove.
* rsvg.h:
* test-ft-gtk.c: Remove.
* test-ft.c: Remove.
* test-rsvg.c:
Remove direct FreeType dependency and also remove
dependency on libpng. No more rsvg_set_fonts_dir
or rsvg-ft.h header.
* rsvg.c: (rsvg_state_clone), (rsvg_state_finalize),
(rsvg_parse_style_arg), (rsvg_pop_opacity_group),
(rsvg_text_handler_characters), (rsvg_handle_free):
Port from direct FreeType use to Pango.
2001-12-06 Darin Adler <darin@bentspoon.com>
* rsvg-paint-server.h: Add a dummy member since empty structs
......
noinst_PROGRAMS = test-ft-gtk test-ft test-rsvg
noinst_PROGRAMS = test-rsvg
EXTRA_DIST =\
COPYING.LIB \
......@@ -17,7 +17,6 @@ librsvg_2_la_SOURCES = \
rsvg-css.h \
rsvg-defs.c \
rsvg-defs.h \
rsvg-ft.c \
rsvg-paint-server.c \
rsvg-paint-server.h \
rsvg-path.c \
......@@ -29,43 +28,31 @@ librsvg_2_la_LDFLAGS = -version-info @VERSION_INFO@
librsvgincdir = $(includedir)/librsvg-2/librsvg
librsvginc_HEADERS = \
rsvg.h \
rsvg-ft.h \
librsvg-features.h
INCLUDES =\
-I$(top_srcdir) \
-I$(top_builddir) \
$(MODULES_CFLAGS) \
$(FREETYPE2_CFLAGS) \
$(LIBRSVG_CFLAGS) \
-DG_LOG_DOMAIN=\"librsvg\" \
-DG_DISABLE_DEPRECATED \
-DPANGO_DISABLE_DEPRECATED \
-DGDK_DISABLE_DEPRECATED \
-DGDK_PIXBUF_DISABLE_DEPRECATED \
-DGTK_DISABLE_DEPRECATED \
-DDATADIR="\"$(datadir)\""
DEPS = $(top_builddir)/librsvg-2.la
LDADDS = $(top_builddir)/librsvg-2.la \
$(MODULES_LIBS) \
$(FREETYPE2_LIBS) \
$(POPT_LIBS) \
$(LIBPNG)
test_ft_gtk_SOURCES=test-ft-gtk.c
test_ft_gtk_LDFLAGS =
test_ft_gtk_DEPENDENCIES = $(DEPS)
test_ft_gtk_LDADD = $(LDADDS) -lm
test_ft_SOURCES=test-ft.c
test_ft_LDFLAGS =
test_ft_DEPENDENCIES = $(DEPS)
test_ft_LDADD = $(LDADDS) -lm
$(LIBRSVG_LIBS) \
$(POPT_LIBS)
test_rsvg_SOURCES=test-rsvg.c
test_rsvg_LDFLAGS =
test_rsvg_DEPENDENCIES = $(DEPS)
test_rsvg_LDADD = $(LDADDS) -lm
tests: test-ft-gtk test-ft test-rsvg
tests: test-rsvg
## Put `exec' in the name because this should be installed by
## `install-exec', not `install-data'.
......
......@@ -5,6 +5,8 @@ AC_CONFIG_SRCDIR(rsvg.h)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
dnl ===========================================================================
LIBRSVG_MAJOR_VERSION=1
LIBRSVG_MINOR_VERSION=1
LIBRSVG_MICRO_VERSION=0
......@@ -15,6 +17,8 @@ AC_SUBST(LIBRSVG_MICRO_VERSION)
VERSION_INFO=`expr $LIBRSVG_MAJOR_VERSION + $LIBRSVG_MINOR_VERSION`:$LIBRSVG_MICRO_VERSION:$LIBRSVG_MINOR_VERSION
AC_SUBST(VERSION_INFO)
dnl ===========================================================================
GNOME_COMMON_INIT
AM_MAINTAINER_MODE
......@@ -26,10 +30,14 @@ AC_PROG_AWK
AM_PROG_LIBTOOL
AC_STDC_HEADERS
AC_C_BIGENDIAN
GNOME_REQUIRE_PKGCONFIG
GNOME_PLATFORM_GNOME_2(yes)
dnl ===========================================================================
GLIB_REQUIRED=1.3.1
XML_REQUIRED=2.2.8
ART_REQUIRED=2.3.5
......@@ -38,6 +46,7 @@ GDK_PIXBUF_REQUIRED=1.3.7
FREETYPE_REQUIRED=2.0.1
FREETYPE_LIBRARY_REQUIRED=6.1.0
POPT_REQUIRED=1.5
PANGO_REQUIRED=0.22
AC_SUBST(GLIB_REQUIRED)
AC_SUBST(XML_REQUIRED)
......@@ -46,76 +55,20 @@ AC_SUBST(GTK_REQUIRED)
AC_SUBST(GDK_PIXBUF_REQUIRED)
AC_SUBST(FREETYPE_REQUIRED)
AC_SUBST(POPT_REQUIRED)
AC_SUBST(PANGO_REQUIRED)
PKG_CHECK_MODULES(MODULES, glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gtk+-2.0 >= $GTK_REQUIRED gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED libxml-2.0 >= $XML_REQUIRED libart-2.0 >= $ART_REQUIRED)
AC_SUBST(MODULES_LIBS)
AC_SUBST(MODULES_CFLAGS)
dnl ===========================================================================
PKG_CHECK_MODULES(LIBRSVG, glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gtk+-2.0 >= $GTK_REQUIRED gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED libxml-2.0 >= $XML_REQUIRED libart-2.0 >= $ART_REQUIRED pango >= $PANGO_REQUIRED pangoft2 >= $PANGO_REQUIRED)
AC_SUBST(LIBRSVG_LIBS)
AC_SUBST(LIBRSVG_CFLAGS)
dnl ===========================================================================
dnl ====================================
dnl = Begin tests for popt
dnl ====================================
AC_CHECK_LIB(popt, poptParseArgvString, [POPT_LIBS="-lpopt"])
AC_SUBST(POPT_LIBS)
dnl ====================================
dnl = End tests for popt
dnl ====================================
dnl ====================================
dnl = Begin tests for libpng
dnl ====================================
if test -z "$LIBPNG"; then
AC_CHECK_LIB(png, png_read_info,
[AC_CHECK_HEADER(png.h,
png_ok=yes,
png_ok=no)],
AC_MSG_ERROR(*** (PNG library not found) ***), -lz -lm)
if test "$png_ok" = yes; then
AC_MSG_CHECKING([for png_structp in png.h])
AC_TRY_COMPILE([#include <png.h>],
[png_structp pp; png_infop info; png_colorp cmap; png_create_read_struct;],
png_ok=yes,
png_ok=no)
AC_MSG_RESULT($png_ok)
if test "$png_ok" = yes; then
PNG='png'; LIBPNG='-lpng -lz'
else
AC_MSG_WARN(*** PNG loader will not be built (PNG library is too old) ***)
fi
else
AC_MSG_WARN(*** PNG loader will not be built (PNG header file not found) ***)
fi
fi
AC_SUBST(LIBPNG)
dnl =======================
dnl = End tests for libpng
dnl =======================
dnl =======================
dnl = begin tests for FreeType2
dnl =======================
NAUTILUS_PATH_FREETYPE2($FREETYPE_LIBRARY_REQUIRED,,
AC_MSG_ERROR([
*** FreeType2 $FREETYPE_REQUIRED or better is required. You can obtain a
*** packaged version of FreeType2 over here:
*** http://developer.eazel.com/eazel-hacking/updates/freetype2
*** source versions are available from ftp://ftp.freetype.org]))
AC_SUBST(FREETYPE2_CFLAGS)
AC_SUBST(FREETYPE2_LIBS)
dnl =======================
dnl = End tests for FreeType2
dnl =======================
LIBRSVG_LIBDIR='-L${libdir}'
LIBRSVG_INCLUDEDIR='-I${includedir} ${FREETYPE2_CFLAGS}'
LIBRSVG_LIBS='-lrsvg -lart_lgpl ${FREETYPE2_LIBS}'
AC_SUBST(LIBRSVG_LIBDIR)
AC_SUBST(LIBRSVG_INCLUDEDIR)
AC_SUBST(LIBRSVG_LIBS)
AC_C_BIGENDIAN
dnl ===========================================================================
dnl Turn on the additional warnings last, so -Werror doesn't affect other tests.
......@@ -159,6 +112,8 @@ else
AC_MSG_RESULT(no)
fi
dnl ===========================================================================
AC_OUTPUT([
librsvg.spec
librsvg-features.h
......
......@@ -4,7 +4,8 @@ libdir=@libdir@
includedir=@includedir@
Name: librsvg
Description: LGPL version of the librsvg library
Description: library that renders svg files using libart and pango
Version: @VERSION@
Libs: -L${libdir} -lrsvg-2 -lart_lgpl_2
Requires: libart-2.0 glib-2.0 pango-2.0 pangoft2-2.0
Libs: -L${libdir} -lrsvg-2
Cflags: -I${includedir}/librsvg-2
......@@ -23,8 +23,7 @@ Requires: gtk+ >= @GTK_REQUIRED@
Requires: libxml >= @LIBXML_REQUIRED@
Requires: gdk-pixbuf >= @GDK_PIXBUF_REQUIRED@
Requires: popt >= @POPT_REQUIRED@
Requires: freetype >= @FREETYPE_REQUIRED@
Requires: libpng
Requires: pango >= @PANGO_REQUIRED@
%description
Eazel Extension Library
......
This diff is collapsed.
typedef struct _RsvgFTCtx RsvgFTCtx;
typedef struct _RsvgFTGlyph RsvgFTGlyph;
struct _RsvgFTGlyph {
int refcnt;
int width, height;
int underline_position, underline_thickness;
double xpen, ypen; /* relative location of pen after the glyph */
int rowstride;
guchar *buf;
};
typedef int RsvgFTFontHandle;
RsvgFTCtx *
rsvg_ft_ctx_new (void);
void
rsvg_ft_ctx_done (RsvgFTCtx *ctx);
RsvgFTFontHandle
rsvg_ft_intern (RsvgFTCtx *ctx, const char *font_file_name);
void
rsvg_ft_font_attach (RsvgFTCtx *ctx, RsvgFTFontHandle fh,
const char *font_file_name);
#if 0
void
rsvg_ft_font_ref (RsvgFTFont *font);
void
rsvg_ft_font_unref (RsvgFTFont *font);
#endif
RsvgFTGlyph *
rsvg_ft_render_string (RsvgFTCtx *ctx, RsvgFTFontHandle fh,
const char *str,
unsigned int length,
double sx, double sy,
const double affine[6], int xy[2]);
void
rsvg_ft_measure_string (RsvgFTCtx *ctx,
RsvgFTFontHandle fh,
const char *str,
unsigned int length,
double sx, double sy,
const double affine[6],
int xy[2],
unsigned int dimensions[2]);
void
rsvg_ft_glyph_unref (RsvgFTGlyph *glyph);
......@@ -48,12 +48,13 @@
#include <libxml/SAX.h>
#include <libxml/xmlmemory.h>
#include <pango/pangoft2.h>
#include "rsvg-bpath-util.h"
#include "rsvg-defs.h"
#include "rsvg-path.h"
#include "rsvg-css.h"
#include "rsvg-paint-server.h"
#include "rsvg-ft.h"
#define noVERBOSE
......@@ -77,6 +78,7 @@ struct _RsvgState {
ArtPathStrokeJoinType join;
double font_size;
char *font_family;
guint32 stop_color; /* rgb */
gint stop_opacity; /* 0..255 */
......@@ -111,13 +113,11 @@ struct RsvgHandle {
GHashTable *entities; /* g_malloc'd string -> xmlEntityPtr */
RsvgFTCtx *ft_ctx;
PangoContext *pango_context;
xmlParserCtxtPtr ctxt;
GError **error;
};
char *fonts_dir;
static void
rsvg_state_init (RsvgState *state)
{
......@@ -139,6 +139,7 @@ static void
rsvg_state_clone (RsvgState *dst, const RsvgState *src)
{
*dst = *src;
dst->font_family = g_strdup (src->font_family);
rsvg_paint_server_ref (dst->fill);
rsvg_paint_server_ref (dst->stroke);
dst->save_pixbuf = NULL;
......@@ -147,6 +148,7 @@ rsvg_state_clone (RsvgState *dst, const RsvgState *src)
static void
rsvg_state_finalize (RsvgState *state)
{
g_free (state->font_family);
rsvg_paint_server_unref (state->fill);
rsvg_paint_server_unref (state->stroke);
}
......@@ -288,7 +290,8 @@ rsvg_parse_style_arg (RsvgHandle *ctx, RsvgState *state, const char *str)
}
else if (rsvg_css_param_match (str, "font-family"))
{
/* state->font_family = g_strdup (str + arg_off); */
g_free (state->font_family);
state->font_family = g_strdup (str + arg_off);
}
else if (rsvg_css_param_match (str, "stop-color"))
{
......@@ -608,7 +611,7 @@ rsvg_pop_opacity_group (RsvgHandle *ctx, int opacity)
nos_pixels += rowstride;
}
gdk_pixbuf_unref (tos);
g_object_unref (tos);
ctx->pixbuf = nos;
}
......@@ -871,16 +874,16 @@ rsvg_text_handler_characters (RsvgSaxHandler *self, const xmlChar *ch, int len)
RsvgHandle *ctx = z->ctx;
char *string;
int beg, end;
RsvgFTFontHandle fh;
RsvgFTGlyph *glyph;
int glyph_xy[2];
RsvgState *state;
ArtRender *render;
GdkPixbuf *pixbuf;
gboolean has_alpha;
int opacity;
const char *dir;
char *path;
PangoLayout *layout;
PangoFontDescription *font;
PangoLayoutLine *line;
PangoRectangle ink_rect, line_ink_rect;
FT_Bitmap bitmap;
/* Copy ch into string, chopping off leading and trailing whitespace */
for (beg = 0; beg < len; beg++)
......@@ -899,24 +902,8 @@ rsvg_text_handler_characters (RsvgSaxHandler *self, const xmlChar *ch, int len)
fprintf (stderr, "text characters(%s, %d)\n", string, len);
#endif
if (ctx->ft_ctx == NULL)
ctx->ft_ctx = rsvg_ft_ctx_new ();
/* FIXME bugzilla.eazel.com 3904: We need to make rsvg use something
* like the Nautilus font mapping stuff in NautilusScalableFont. See
* bug for details.
*/
if (fonts_dir == NULL) {
dir = DATADIR "/eel-2/eel/fonts";
} else {
dir = fonts_dir;
}
path = g_strconcat (dir, "/urw/n019003l.pfb", NULL);
fh = rsvg_ft_intern (ctx->ft_ctx, path);
g_free (path);
path = g_strconcat (dir, "/urw/n019003l.afm", NULL);
rsvg_ft_font_attach (ctx->ft_ctx, fh, path);
g_free (path);
if (ctx->pango_context == NULL)
ctx->pango_context = pango_ft2_get_context (72, 72); /* FIXME: dpi? */
state = &ctx->state[ctx->n_state - 1];
......@@ -936,31 +923,48 @@ rsvg_text_handler_characters (RsvgSaxHandler *self, const xmlChar *ch, int len)
has_alpha ? ART_ALPHA_SEPARATE : ART_ALPHA_NONE,
NULL);
glyph = rsvg_ft_render_string (ctx->ft_ctx, fh,
string,
strlen (string),
state->font_size, state->font_size,
state->affine, glyph_xy);
layout = pango_layout_new (ctx->pango_context);
pango_layout_set_text (layout, string, -1);
font = pango_font_description_copy (pango_context_get_font_description (ctx->pango_context));
pango_font_description_set_family_static (font, state->font_family);
pango_font_description_set_size (font, state->font_size * PANGO_SCALE);
pango_layout_set_font_description (layout, font);
pango_font_description_free (font);
if (glyph == NULL)
{
}
pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
line = pango_layout_get_line (layout, 0);
if (line == NULL)
line_ink_rect = ink_rect; /* nothing to draw anyway */
else
{
rsvg_render_paint_server (render, state->fill, NULL); /* todo: paint server ctx */
opacity = state->fill_opacity * state->opacity;
opacity = opacity + (opacity >> 7) + (opacity >> 14);
pango_layout_line_get_pixel_extents (line, &line_ink_rect, NULL);
bitmap.rows = ink_rect.height;
bitmap.width = ink_rect.width;
bitmap.pitch = (bitmap.width + 3) & ~3;
bitmap.buffer = g_malloc0 (bitmap.rows * bitmap.pitch);
bitmap.num_grays = 0x100;
bitmap.pixel_mode = ft_pixel_mode_grays;
pango_ft2_render_layout (&bitmap, layout, -ink_rect.x, -ink_rect.y);
g_object_unref (layout);
rsvg_render_paint_server (render, state->fill, NULL); /* todo: paint server ctx */
opacity = state->fill_opacity * state->opacity;
opacity = opacity + (opacity >> 7) + (opacity >> 14);
#ifdef VERBOSE
fprintf (stderr, "opacity = %d\n", opacity);
fprintf (stderr, "opacity = %d\n", opacity);
#endif
art_render_mask_solid (render, opacity);
art_render_mask (render,
glyph_xy[0], glyph_xy[1],
glyph_xy[0] + glyph->width, glyph_xy[1] + glyph->height,
glyph->buf, glyph->rowstride);
art_render_invoke (render);
rsvg_ft_glyph_unref (glyph);
}
art_render_mask_solid (render, opacity);
art_render_mask (render,
state->affine[4] + line_ink_rect.x,
state->affine[5] + line_ink_rect.y,
state->affine[4] + line_ink_rect.x + bitmap.width,
state->affine[5] + line_ink_rect.y + bitmap.rows,
bitmap.buffer, bitmap.pitch);
art_render_invoke (render);
g_free (bitmap.buffer);
}
g_free (string);
......@@ -1403,13 +1407,6 @@ rsvg_handle_new (void)
return handle;
}
void
rsvg_set_fonts_dir (const char *new_fonts_dir)
{
g_free (fonts_dir);
fonts_dir = g_strdup (new_fonts_dir);
}
/**
* rsvg_handle_set_size_callback:
* @handle: An #RsvgHandle
......@@ -1551,8 +1548,8 @@ rsvg_handle_free (RsvgHandle *handle)
{
int i;
if (handle->ft_ctx != NULL)
rsvg_ft_ctx_done (handle->ft_ctx);
if (handle->pango_context != NULL)
g_object_unref (handle->pango_context);
rsvg_defs_free (handle->defs);
for (i = 0; i < handle->n_state; i++)
......@@ -1605,7 +1602,7 @@ rsvg_size_callback (gint *width,
* @error: return location for errors
*
* Loads a new #GdkPixbuf from @file_name and returns it. The caller must
* assume the referrence to the reurned pixbuf. If an error occurred, @error is
* assume the reference to the reurned pixbuf. If an error occurred, @error is
* set and %NULL is returned.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
......@@ -1627,7 +1624,7 @@ rsvg_pixbuf_from_file (const gchar *file_name,
*
* Loads a new #GdkPixbuf from @file_name and returns it. This pixbuf is scaled
* from the size indicated by the file by a factor of @x_zoom and @y_zoom. The
* caller must assume the referrence to the reurned pixbuf. If an error
* caller must assume the reference to the reurned pixbuf. If an error
* occurred, @error is set and %NULL is returned.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
......@@ -1681,7 +1678,7 @@ rsvg_pixbuf_from_file_at_zoom (const gchar *file_name,
* Loads a new #GdkPixbuf from @file_name and returns it. This pixbuf is scaled
* from the size indicated to the new size indicated by @width and @height. If
* either of these are -1, then the default size of the image being loaded is
* used. The caller must assume the referrence to the reurned pixbuf. If an
* used. The caller must assume the reference to the reurned pixbuf. If an
* error occurred, @error is set and %NULL is returned.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
......@@ -1715,7 +1712,6 @@ rsvg_pixbuf_from_file_at_size (const gchar *file_name,
rsvg_handle_write (handle, chars, result, error);
retval = rsvg_handle_get_pixbuf (handle);
gdk_pixbuf_ref (retval);
fclose (f);
rsvg_handle_free (handle);
......
......@@ -42,8 +42,6 @@ typedef void (* RsvgSizeFunc) (gint *width,
gpointer user_data);
void rsvg_set_fonts_dir (const char *fonts_dir);
RsvgHandle *rsvg_handle_new (void);
void rsvg_handle_set_size_callback (RsvgHandle *handle,
RsvgSizeFunc size_func,
......
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
test-ft-gtk.c: Testbed for freetype/libart integration.
Copyright (C) 2000 Eazel, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program 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
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Author: Raph Levien <raph@artofcode.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
#include <popt.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <freetype/freetype.h>
#include <libart_lgpl/art_misc.h>
#include <libart_lgpl/art_rect.h>
#include <libart_lgpl/art_alphagamma.h>
#include <libart_lgpl/art_affine.h>
#include <libart_lgpl/art_render.h>
#include "art_render_mask.h"
#include "rsvg.h"
#include "rsvg-ft.h"
typedef struct _TestCtx TestCtx;
struct _TestCtx {
RsvgFTCtx *ctx;
RsvgFTFontHandle fh;
int n_lines;
char **lines;
int y_sp;
int y_scroll;
GtkWidget *drawingarea;
GtkWidget *status;
double start_time;
gboolean do_drawing;
gboolean do_scrolling;
gboolean do_invert;
};
static double
timing_get_time (void)
{
struct timeval tv;
struct timezone tz;
gettimeofday (&tv, &tz);
return tv.tv_sec + 1e-6 * tv.tv_usec;
}
static void invert_glyph (guchar *buf, int rowstride, int width, int height)
{
int x, y;
int first;
int n_words;
int last;
guint32 *middle;
if (width >= 8 && ((rowstride & 3) == 0)) {
first = (-(long)buf) & 3;
n_words = (width - first) >> 2;
last = first + (n_words << 2);
for (y = 0; y < height; y++) {
middle = (guint32 *)(buf + first);
for (x = 0; x < first; x++)
buf[x] = ~buf[x];
for (x = 0; x < n_words; x++)
middle[x] = ~middle[x];
for (x = last; x < width; x++)
buf[x] = ~buf[x];
buf += rowstride;
}
} else {
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++)
buf[x] = ~buf[x];
buf += rowstride;
}
}
}
static void draw_line (TestCtx *ctx, int line_num, ArtIRect *rect)
{
GtkWidget *drawingarea = ctx->drawingarea;
int y0;
RsvgFTGlyph *glyph;
const double affine[6] = { 1, 0, 0, 1, 5, 12 };
int glyph_xy[2];
ArtIRect line_rect, clear_rect, glyph_rect, draw_rect;
int width;
width = drawingarea->allocation.width;
y0 = line_num * ctx->y_sp - ctx->y_scroll;
if (line_num < 0 || line_num >= ctx->n_lines) {
if (ctx->do_drawing) {
gdk_draw_rectangle (drawingarea->window,
drawingarea->style->white_gc,
TRUE,
0, y0, width, ctx->y_sp);
}
} else {
guchar *buf;
int rowstride;
glyph = rsvg_ft_render_string (ctx->ctx, ctx->fh,
ctx->lines[line_num],
strlen (ctx->lines[line_num]),
14, 14,
affine,
glyph_xy);
rowstride = glyph->rowstride;
glyph_rect.x0 = glyph_xy[0];
glyph_rect.y0 = y0 + glyph_xy[1];
glyph_rect.x1 = glyph_rect.x0 + glyph->width;
glyph_rect.y1 = glyph_rect.y0 + glyph->height;
line_rect.x0 = 0;
line_rect.y0 = y0;
line_rect.x1 = width;
line_rect.y1 = y0 + ctx->y_sp;
art_irect_intersect (&clear_rect, rect, &line_rect);
if (ctx->do_drawing)
gdk_draw_rectangle (drawingarea->window,
drawingarea->style->white_gc,
TRUE,
clear_rect.x0, clear_rect.y0,
clear_rect.x1 - clear_rect.x0,
clear_rect.y1 - clear_rect.y0);
art_irect_intersect (&draw_rect, rect, &glyph_rect);
if (!art_irect_empty (&draw_rect) && ctx->do_drawing) {
buf = glyph->buf +
draw_rect.x0 - glyph_rect.x0 +
rowstride * (draw_rect.y0 - glyph_rect.y0);
if (ctx->do_invert) {
invert_glyph (buf, rowstride,
draw_rect.x1 - draw_rect.x0,
draw_rect.y1 - draw_rect.y0);
}
gdk_draw_gray_image (drawingarea->window,
drawingarea->style->white_gc,
draw_rect.x0, draw_rect.y0,
draw_rect.x1 - draw_rect.x0,
draw_rect.y1 - draw_rect.y0,
GDK_RGB_DITHER_NONE,
buf,
rowstride);
}
rsvg_ft_glyph_unref (glyph);
}
}
static gint
test_expose (GtkWidget *widget, GdkEventExpose *event, TestCtx *ctx)
{
int line0, line1;
int line;
ArtIRect rect;
rect.x0 = event->area.x;
rect.y0 = event->area.y;
rect.x1 = rect.x0 + event->area.width;
rect.y1 = rect.y0 + event->area.height;
line0 = (rect.y0 + ctx->y_scroll) / ctx->y_sp;
line1 = (rect.y1 + ctx->y_scroll + ctx->y_sp - 1) / ctx->y_sp;
for (line = line0; line < line1; line++) {
#ifdef VERBOSE
g_print ("drawing line %d of [%d..%d]\n", line, line0, line1 - 1);
#endif
draw_line (ctx, line, &rect);
}
return FALSE;
}
static void
scroll_to (TestCtx *ctx, int new_y)
{
GtkWidget *drawingarea = ctx->drawingarea;
int scroll_amt = new_y - ctx->y_scroll;
int width = drawingarea->allocation.width;
int height = drawingarea->allocation.height;
int y0, y1;
GdkEventExpose expose;
if (scroll_amt == 0)
return;