From 13a06349251874bd35d2f03c3fc93217cee749a2 Mon Sep 17 00:00:00 2001 From: Nickolay V. Shmyrev Date: Mon, 08 Jan 2007 12:25:31 +0000 Subject: Reorganize source tree. 2007-01-08 Nickolay V. Shmyrev * Makefile.am: * backend/Makefile.am: * backend/comics/Makefile.am: * backend/djvu/Makefile.am: * backend/dvi/Makefile.am: * backend/ev-async-renderer.c: * backend/ev-async-renderer.h: * backend/ev-attachment.c: * backend/ev-attachment.h: * backend/ev-backend-marshal.c: * backend/ev-document-factory.c: * backend/ev-document-factory.h: * backend/ev-document-find.c: * backend/ev-document-find.h: * backend/ev-document-fonts.c: * backend/ev-document-fonts.h: * backend/ev-document-images.c: * backend/ev-document-images.h: * backend/ev-document-info.h: * backend/ev-document-links.c: * backend/ev-document-links.h: * backend/ev-document-misc.c: * backend/ev-document-misc.h: * backend/ev-document-security.c: * backend/ev-document-security.h: * backend/ev-document-thumbnails.c: * backend/ev-document-thumbnails.h: * backend/ev-document-transition.c: * backend/ev-document-transition.h: * backend/ev-document.c: * backend/ev-document.h: * backend/ev-file-exporter.c: * backend/ev-file-exporter.h: * backend/ev-image.c: * backend/ev-image.h: * backend/ev-link-action.c: * backend/ev-link-action.h: * backend/ev-link-dest.c: * backend/ev-link-dest.h: * backend/ev-link.c: * backend/ev-link.h: * backend/ev-render-context.c: * backend/ev-render-context.h: * backend/ev-selection.c: * backend/ev-selection.h: * backend/impress/Makefile.am: * backend/pdf/Makefile.am: * backend/pixbuf/Makefile.am: * backend/ps/Makefile.am: * backend/ps/ps-document.c: (push_pixbuf), (interpreter_failed), (ps_document_widget_event), (setup_pixmap), (setup_page), (input), (start_interpreter), (stop_interpreter), (document_load), (ps_document_next_page), (render_page): * backend/tiff/Makefile.am: * comics/Makefile.am: * comics/comics-document.c: * comics/comics-document.h: * configure.ac: * cut-n-paste/zoom-control/ephy-zoom-control.c: * djvu/Makefile.am: * djvu/djvu-document-private.h: * djvu/djvu-document.c: * djvu/djvu-document.h: * djvu/djvu-links.c: * djvu/djvu-links.h: * djvu/djvu-text-page.c: * djvu/djvu-text-page.h: * djvu/djvu-text.c: * djvu/djvu-text.h: * dvi/Makefile.am: * dvi/dvi-document.c: * dvi/dvi-document.h: * dvi/fonts.c: * dvi/fonts.h: * dvi/mdvi-lib/Makefile.am: * dvi/mdvi-lib/afmparse.c: * dvi/mdvi-lib/afmparse.h: * dvi/mdvi-lib/bitmap.c: * dvi/mdvi-lib/bitmap.h: * dvi/mdvi-lib/color.c: * dvi/mdvi-lib/color.h: * dvi/mdvi-lib/common.c: * dvi/mdvi-lib/common.h: * dvi/mdvi-lib/defaults.h: * dvi/mdvi-lib/dvimisc.c: * dvi/mdvi-lib/dviopcodes.h: * dvi/mdvi-lib/dviread.c: * dvi/mdvi-lib/files.c: * dvi/mdvi-lib/font.c: * dvi/mdvi-lib/fontmap.c: * dvi/mdvi-lib/fontmap.h: * dvi/mdvi-lib/fontsrch.c: * dvi/mdvi-lib/gf.c: * dvi/mdvi-lib/hash.c: * dvi/mdvi-lib/hash.h: * dvi/mdvi-lib/list.c: * dvi/mdvi-lib/mdvi.h: * dvi/mdvi-lib/pagesel.c: * dvi/mdvi-lib/paper.c: * dvi/mdvi-lib/paper.h: * dvi/mdvi-lib/pk.c: * dvi/mdvi-lib/private.h: * dvi/mdvi-lib/setup.c: * dvi/mdvi-lib/sp-epsf.c: * dvi/mdvi-lib/special.c: * dvi/mdvi-lib/sysdeps.h: * dvi/mdvi-lib/t1.c: * dvi/mdvi-lib/tfm.c: * dvi/mdvi-lib/tfmfile.c: * dvi/mdvi-lib/tt.c: * dvi/mdvi-lib/util.c: * dvi/mdvi-lib/vf.c: * dvi/pixbuf-device.c: * dvi/pixbuf-device.h: * impress/Makefile.am: * impress/common.h: * impress/document.c: * impress/f_oasis.c: * impress/f_oo13.c: * impress/iksemel.c: * impress/iksemel.h: * impress/imposter.h: * impress/impress-document.c: * impress/impress-document.h: * impress/internal.h: * impress/r_back.c: * impress/r_draw.c: * impress/r_geometry.c: * impress/r_gradient.c: * impress/r_style.c: * impress/r_text.c: * impress/render.c: * impress/render.h: * impress/zip.c: * impress/zip.h: * lib/Makefile.am: * lib/ev-debug.c: * lib/ev-debug.h: * lib/ev-file-helpers.c: * lib/ev-file-helpers.h: * lib/ev-gui.c: * lib/ev-gui.h: * lib/ev-tooltip.c: * lib/ev-tooltip.h: * libdocument/Makefile.am: * libdocument/ev-file-helpers.c: * pdf/Makefile.am: * pdf/ev-poppler.cc: * pdf/ev-poppler.h: * pixbuf/Makefile.am: * pixbuf/pixbuf-document.c: * pixbuf/pixbuf-document.h: * properties/Makefile.am: * ps/Makefile.am: * ps/gsdefaults.c: * ps/gsdefaults.h: * ps/gsio.c: * ps/gsio.h: * ps/gstypes.h: * ps/ps-document.c: * ps/ps-document.h: * ps/ps.c: * ps/ps.h: * shell/Makefile.am: * shell/ev-application.h: * shell/ev-sidebar-links.c: * shell/ev-sidebar-links.h: * shell/ev-utils.c: (ev_gui_sanitise_popup_position), (ev_gui_menu_position_tree_selection): * shell/ev-utils.h: * shell/ev-view.c: (ev_view_finalize): * shell/ev-window.c: * shell/main.c: (main): * thumbnailer/Makefile.am: * tiff/Makefile.am: * tiff/tiff-document.c: * tiff/tiff-document.h: * tiff/tiff2ps.c: * tiff/tiff2ps.h: Reorganize source tree. svn path=/trunk/; revision=2197 --- (limited to 'dvi') diff --git a/dvi/Makefile.am b/dvi/Makefile.am deleted file mode 100644 index 169ef13..0000000 --- a/dvi/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -SUBDIRS = mdvi-lib - -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/backend \ - -I$(top_srcdir)/lib \ - -I$(srcdir)/mdvi-lib \ - $(LIB_CFLAGS) - -noinst_LTLIBRARIES = libgtkdvi.la - -libgtkdvi_la_SOURCES = \ - dvi-document.c \ - dvi-document.h \ - pixbuf-device.c \ - pixbuf-device.h \ - fonts.c \ - fonts.h - -libgtkdvi_la_LIBADD = mdvi-lib/libmdvi.la - - - - diff --git a/dvi/dvi-document.c b/dvi/dvi-document.c deleted file mode 100644 index 4de5e64..0000000 --- a/dvi/dvi-document.c +++ /dev/null @@ -1,376 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ -/* - * Copyright (C) 2005, Nickolay V. Shmyrev - * - * 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, 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. - */ - -#include - -#include "dvi-document.h" -#include "ev-document-thumbnails.h" -#include "ev-document-misc.h" - -#include "mdvi.h" -#include "fonts.h" -#include "pixbuf-device.h" - -#include -#include - -GMutex *dvi_context_mutex = NULL; - -enum { - PROP_0, - PROP_TITLE -}; - -struct _DviDocumentClass -{ - GObjectClass parent_class; -}; - -struct _DviDocument -{ - GObject parent_instance; - - DviContext *context; - DviPageSpec *spec; - DviParams *params; - - /* To let document scale we should remember width and height */ - - double base_width; - double base_height; - - gchar *uri; -}; - -typedef struct _DviDocumentClass DviDocumentClass; - -static void dvi_document_document_iface_init (EvDocumentIface *iface); -static void dvi_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface); -static void dvi_document_get_page_size (EvDocument *document, - int page, - double *width, - double *height); - -G_DEFINE_TYPE_WITH_CODE - (DviDocument, dvi_document, G_TYPE_OBJECT, - { - G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT, dvi_document_document_iface_init); - G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, dvi_document_document_thumbnails_iface_init) - }); - -static gboolean -dvi_document_load (EvDocument *document, - const char *uri, - GError **error) -{ - gchar *filename; - DviDocument *dvi_document = DVI_DOCUMENT(document); - - filename = g_filename_from_uri (uri, NULL, error); - - if (!filename) { - g_set_error (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("File not available")); - return FALSE; - } - - g_mutex_lock (dvi_context_mutex); - if (dvi_document->context) - mdvi_destroy_context (dvi_document->context); - - dvi_document->context = mdvi_init_context(dvi_document->params, dvi_document->spec, filename); - g_mutex_unlock (dvi_context_mutex); - - if (!dvi_document->context) { - g_set_error (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("DVI document has incorrect format")); - return FALSE; - } - - mdvi_pixbuf_device_init (&dvi_document->context->device); - - dvi_document->base_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv - + 2 * unit2pix(dvi_document->params->dpi, MDVI_HMARGIN) / dvi_document->params->hshrink; - - dvi_document->base_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv - + 2 * unit2pix(dvi_document->params->vdpi, MDVI_VMARGIN) / dvi_document->params->vshrink; - - g_free (dvi_document->uri); - dvi_document->uri = g_strdup (uri); - - return TRUE; -} - - -static gboolean -dvi_document_save (EvDocument *document, - const char *uri, - GError **error) -{ - DviDocument *dvi_document = DVI_DOCUMENT (document); - - return ev_xfer_uri_simple (dvi_document->uri, uri, error); -} - -static int -dvi_document_get_n_pages (EvDocument *document) -{ - DviDocument *dvi_document = DVI_DOCUMENT (document); - return dvi_document->context->npages; -} - -static void -dvi_document_get_page_size (EvDocument *document, - int page, - double *width, - double *height) -{ - DviDocument * dvi_document = DVI_DOCUMENT (document); - - *width = dvi_document->base_width; - *height = dvi_document->base_height;; - - return; -} - -static GdkPixbuf * -dvi_document_render_pixbuf (EvDocument *document, - EvRenderContext *rc) -{ - GdkPixbuf *pixbuf; - GdkPixbuf *rotated_pixbuf; - - DviDocument *dvi_document = DVI_DOCUMENT(document); - - gint required_width, required_height; - gint proposed_width, proposed_height; - gint xmargin = 0, ymargin = 0; - - /* We should protect our context since it's not - * thread safe. The work to the future - - * let context render page independently - */ - g_mutex_lock (dvi_context_mutex); - - mdvi_setpage(dvi_document->context, rc->page); - - mdvi_set_shrink (dvi_document->context, - (int)((dvi_document->params->hshrink - 1) / rc->scale) + 1, - (int)((dvi_document->params->vshrink - 1) / rc->scale) + 1); - - required_width = dvi_document->base_width * rc->scale; - required_height = dvi_document->base_height * rc->scale; - proposed_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv; - proposed_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv; - - if (required_width >= proposed_width) - xmargin = (required_width - proposed_width) / 2; - if (required_height >= proposed_height) - ymargin = (required_height - proposed_height) / 2; - - mdvi_pixbuf_device_set_margins (&dvi_document->context->device, xmargin, ymargin); - - mdvi_pixbuf_device_render (dvi_document->context); - - pixbuf = mdvi_pixbuf_device_get_pixbuf (&dvi_document->context->device); - - g_mutex_unlock (dvi_context_mutex); - - rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, 360 - rc->rotation); - g_object_unref (pixbuf); - - return rotated_pixbuf; -} - -static void -dvi_document_finalize (GObject *object) -{ - DviDocument *dvi_document = DVI_DOCUMENT(object); - - g_mutex_lock (dvi_context_mutex); - if (dvi_document->context) - { - mdvi_pixbuf_device_free (&dvi_document->context->device); - mdvi_destroy_context (dvi_document->context); - } - g_mutex_unlock (dvi_context_mutex); - - if (dvi_document->params) - g_free (dvi_document->params); - - g_free (dvi_document->uri); - - G_OBJECT_CLASS (dvi_document_parent_class)->finalize (object); -} - - -static void -dvi_document_class_init (DviDocumentClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = dvi_document_finalize; - - mdvi_init_kpathsea("evince", MDVI_MFMODE, MDVI_FALLBACK_FONT, MDVI_DPI); - mdvi_register_fonts (); - - dvi_context_mutex = g_mutex_new (); -} - -static gboolean -dvi_document_can_get_text (EvDocument *document) -{ - return FALSE; -} - -static EvDocumentInfo * -dvi_document_get_info (EvDocument *document) -{ - EvDocumentInfo *info; - - info = g_new0 (EvDocumentInfo, 1); - - return info; -} - -static void -dvi_document_document_iface_init (EvDocumentIface *iface) -{ - iface->load = dvi_document_load; - iface->save = dvi_document_save; - iface->can_get_text = dvi_document_can_get_text; - iface->get_n_pages = dvi_document_get_n_pages; - iface->get_page_size = dvi_document_get_page_size; - iface->render_pixbuf = dvi_document_render_pixbuf; - iface->get_info = dvi_document_get_info; -} - -static void -dvi_document_thumbnails_get_dimensions (EvDocumentThumbnails *document, - gint page, - gint suggested_width, - gint *width, - gint *height) -{ - DviDocument *dvi_document = DVI_DOCUMENT (document); - gdouble page_ratio; - - page_ratio = dvi_document->base_height / dvi_document->base_width; - *width = suggested_width; - *height = (gint) (suggested_width * page_ratio); - - return; -} - -static GdkPixbuf * -dvi_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, - gint page, - gint rotation, - gint width, - gboolean border) -{ - DviDocument *dvi_document = DVI_DOCUMENT (document); - GdkPixbuf *pixbuf; - GdkPixbuf *border_pixbuf; - GdkPixbuf *rotated_pixbuf; - gint thumb_width, thumb_height; - gint proposed_width, proposed_height; - - dvi_document_thumbnails_get_dimensions (document, page, width, &thumb_width, &thumb_height); - - g_mutex_lock (dvi_context_mutex); - - mdvi_setpage(dvi_document->context, page); - - mdvi_set_shrink (dvi_document->context, - (int)dvi_document->base_width * dvi_document->params->hshrink / thumb_width, - (int)dvi_document->base_height * dvi_document->params->vshrink / thumb_height); - - proposed_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv; - proposed_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv; - - if (border) { - mdvi_pixbuf_device_set_margins (&dvi_document->context->device, - MAX (thumb_width - proposed_width, 0) / 2, - MAX (thumb_height - proposed_height, 0) / 2); - } else { - mdvi_pixbuf_device_set_margins (&dvi_document->context->device, - MAX (thumb_width - proposed_width - 2, 0) / 2, - MAX (thumb_height - proposed_height - 2, 0) / 2); - } - - - mdvi_pixbuf_device_render (dvi_document->context); - pixbuf = mdvi_pixbuf_device_get_pixbuf (&dvi_document->context->device); - - g_mutex_unlock (dvi_context_mutex); - - rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, 360 - rotation); - g_object_unref (pixbuf); - - if (border) { - GdkPixbuf *tmp_pixbuf = rotated_pixbuf; - rotated_pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, 0, tmp_pixbuf); - g_object_unref (tmp_pixbuf); - } - - return rotated_pixbuf; -} - -static void -dvi_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface) -{ - iface->get_thumbnail = dvi_document_thumbnails_get_thumbnail; - iface->get_dimensions = dvi_document_thumbnails_get_dimensions; -} - - -static void -dvi_document_init_params (DviDocument *dvi_document) -{ - dvi_document->params = g_new0 (DviParams, 1); - - dvi_document->params->dpi = MDVI_DPI; - dvi_document->params->vdpi = MDVI_VDPI; - dvi_document->params->mag = MDVI_MAGNIFICATION; - dvi_document->params->density = MDVI_DEFAULT_DENSITY; - dvi_document->params->gamma = MDVI_DEFAULT_GAMMA; - dvi_document->params->flags = MDVI_PARAM_ANTIALIASED; - dvi_document->params->hdrift = 0; - dvi_document->params->vdrift = 0; - dvi_document->params->hshrink = MDVI_SHRINK_FROM_DPI(dvi_document->params->dpi); - dvi_document->params->vshrink = MDVI_SHRINK_FROM_DPI(dvi_document->params->vdpi); - dvi_document->params->orientation = MDVI_ORIENT_TBLR; - - dvi_document->spec = NULL; - - dvi_document->params->bg = 0xffffffff; - dvi_document->params->fg = 0xff000000; -} - -static void -dvi_document_init (DviDocument *dvi_document) -{ - dvi_document->context = NULL; - dvi_document_init_params (dvi_document); -} diff --git a/dvi/dvi-document.h b/dvi/dvi-document.h deleted file mode 100644 index d92d474..0000000 --- a/dvi/dvi-document.h +++ /dev/null @@ -1,38 +0,0 @@ -/* dvi-document.h: Implementation of EvDocument for dvi documents - * Copyright (C) 2005, Nickolay V. Shmyrev - * - * 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, 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. - */ - -#ifndef __DVI_DOCUMENT_H__ -#define __DVI_DOCUMENT_H__ - -#include "ev-document.h" - -G_BEGIN_DECLS - -#define DVI_TYPE_DOCUMENT (dvi_document_get_type ()) -#define DVI_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DVI_TYPE_DOCUMENT, DviDocument)) -#define DVI_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DVI_TYPE_DOCUMENT)) - -typedef struct _DviDocument DviDocument; - -DviDocument *dvi_document_new (void); - -GType dvi_document_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __DVI_DOCUMENT_H__ */ diff --git a/dvi/fonts.c b/dvi/fonts.c deleted file mode 100644 index 99be63c..0000000 --- a/dvi/fonts.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "config.h" -#include "fonts.h" -#include "mdvi.h" - -static int registered = 0; - -extern DviFontInfo pk_font_info; -extern DviFontInfo pkn_font_info; -extern DviFontInfo gf_font_info; -extern DviFontInfo vf_font_info; -extern DviFontInfo ovf_font_info; -#if 0 -extern DviFontInfo tt_font_info; -#endif -#ifdef WITH_TYPE1_FONTS -extern DviFontInfo t1_font_info; -#endif -extern DviFontInfo afm_font_info; -extern DviFontInfo tfm_font_info; -extern DviFontInfo ofm_font_info; - -static struct fontinfo { - DviFontInfo *info; - char *desc; - int klass; -} known_fonts[] = { - {&vf_font_info, "Virtual fonts", 0}, - {&ovf_font_info, "Omega's virtual fonts", 0}, -#if 0 - {&tt_font_info, "TrueType fonts", 0}, -#endif -#ifdef WITH_TYPE1_FONTS - {&t1_font_info, "Type1 PostScript fonts", 0}, -#endif - {&pk_font_info, "Packed bitmap (auto-generated)", 1}, - {&pkn_font_info, "Packed bitmap", -2}, - {&gf_font_info, "Metafont's generic font format", 1}, - {&ofm_font_info, "Omega font metrics", -1}, - {&tfm_font_info, "TeX font metrics", -1}, - {&afm_font_info, "Adobe font metrics", -1}, - {0, 0} -}; - -void mdvi_register_fonts (void) -{ - struct fontinfo *type; - - if (!registered) { - for(type = known_fonts; type->info; type++) { - mdvi_register_font_type(type->info, type->klass); - } - registered = 1; - } - return; -} - - diff --git a/dvi/fonts.h b/dvi/fonts.h deleted file mode 100644 index e55a8dd..0000000 --- a/dvi/fonts.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef MDVI_FONTS_REGISTRATION_H -#define MDVI_FONTS_REGISTRATION_H - -void mdvi_register_fonts (void); - -#endif /* MDVI_FONTS_REGISTRATION_H */ diff --git a/dvi/mdvi-lib/Makefile.am b/dvi/mdvi-lib/Makefile.am deleted file mode 100644 index 73417e1..0000000 --- a/dvi/mdvi-lib/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -noinst_LTLIBRARIES = libmdvi.la - -libmdvi_la_SOURCES = \ - afmparse.c \ - afmparse.h \ - bitmap.c \ - bitmap.h \ - color.c \ - color.h \ - common.c \ - common.h \ - defaults.h \ - dviopcodes.h \ - dviread.c \ - files.c \ - font.c \ - fontmap.c \ - fontmap.h \ - fontsrch.c \ - gf.c \ - hash.c \ - hash.h \ - list.c \ - mdvi.h \ - pagesel.c \ - paper.c \ - paper.h \ - pk.c \ - private.h \ - setup.c \ - special.c \ - sp-epsf.c \ - sysdeps.h \ - t1.c \ - tfm.c \ - tfmfile.c \ - tt.c \ - util.c \ - vf.c - diff --git a/dvi/mdvi-lib/afmparse.c b/dvi/mdvi-lib/afmparse.c deleted file mode 100644 index 5b8ac68..0000000 --- a/dvi/mdvi-lib/afmparse.c +++ /dev/null @@ -1,1302 +0,0 @@ -/* - * (C) 1988, 1989, 1990 by Adobe Systems Incorporated. All rights reserved. - * - * This file may be freely copied and redistributed as long as: - * 1) This entire notice continues to be included in the file, - * 2) If the file has been modified in any way, a notice of such - * modification is conspicuously indicated. - * - * PostScript, Display PostScript, and Adobe are registered trademarks of - * Adobe Systems Incorporated. - * - * ************************************************************************ - * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUT - * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMS - * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR - * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY - * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION, - * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * ************************************************************************ - */ - -/* - * modified for MDVI: - * - some names changed to avoid conflicts with T1lib - * - changed to ANSI C prototypes, as used by MDVI - * mal - 3/01 - */ - -/* parseAFM.c - * - * This file is used in conjuction with the parseAFM.h header file. - * This file contains several procedures that are used to parse AFM - * files. It is intended to work with an application program that needs - * font metric information. The program can be used as is by making a - * procedure call to "parseFile" (passing in the expected parameters) - * and having it fill in a data structure with the data from the - * AFM file, or an application developer may wish to customize this - * code. - * - * There is also a file, parseAFMclient.c, that is a sample application - * showing how to call the "parseFile" procedure and how to use the data - * after "parseFile" has returned. - * - * Please read the comments in parseAFM.h and parseAFMclient.c. - * - * History: - * original: DSM Thu Oct 20 17:39:59 PDT 1988 - * modified: DSM Mon Jul 3 14:17:50 PDT 1989 - * - added 'storageProblem' return code - * - fixed bug of not allocating extra byte for string duplication - * - fixed typos - * modified: DSM Tue Apr 3 11:18:34 PDT 1990 - * - added free(ident) at end of parseFile routine - * modified: DSM Tue Jun 19 10:16:29 PDT 1990 - * - changed (width == 250) to (width = 250) in initializeArray - */ - -#include "sysdeps.h" - -#ifdef WITH_AFM_FILES - -#include /* added for MDVI */ -#include /* added for MDVI */ - -#include -#include -#include -#include -#include "afmparse.h" -#undef VERSION - -#define lineterm EOL /* line terminating character */ -#define normalEOF 1 /* return code from parsing routines used only */ - /* in this module */ -#define Space "space" /* used in string comparison to look for the width */ - /* of the space character to init the widths array */ -#define False "false" /* used in string comparison to check the value of */ - /* boolean keys (e.g. IsFixedPitch) */ - -#define MATCH(A,B) (strncmp((A),(B), MAX_NAME) == 0) - - - -/*************************** GLOBALS ***********************/ - -static char *ident = NULL; /* storage buffer for keywords */ - - -/* "shorts" for fast case statement - * The values of each of these enumerated items correspond to an entry in the - * table of strings defined below. Therefore, if you add a new string as - * new keyword into the keyStrings table, you must also add a corresponding - * parseKey AND it MUST be in the same position! - * - * IMPORTANT: since the sorting algorithm is a binary search, the strings of - * keywords must be placed in lexicographical order, below. [Therefore, the - * enumerated items are not necessarily in lexicographical order, depending - * on the name chosen. BUT, they must be placed in the same position as the - * corresponding key string.] The NOPE shall remain in the last position, - * since it does not correspond to any key string, and it is used in the - * "recognize" procedure to calculate how many possible keys there are. - */ - -enum parseKey { - ASCENDER, CHARBBOX, CODE, COMPCHAR, CAPHEIGHT, COMMENT, - DESCENDER, ENCODINGSCHEME, ENDCHARMETRICS, ENDCOMPOSITES, - ENDFONTMETRICS, ENDKERNDATA, ENDKERNPAIRS, ENDTRACKKERN, - FAMILYNAME, FONTBBOX, FONTNAME, FULLNAME, ISFIXEDPITCH, - ITALICANGLE, KERNPAIR, KERNPAIRXAMT, LIGATURE, CHARNAME, - NOTICE, COMPCHARPIECE, STARTCHARMETRICS, STARTCOMPOSITES, - STARTFONTMETRICS, STARTKERNDATA, STARTKERNPAIRS, - STARTTRACKKERN, TRACKKERN, UNDERLINEPOSITION, - UNDERLINETHICKNESS, VERSION, XYWIDTH, XWIDTH, WEIGHT, XHEIGHT, - NOPE } ; - -/* keywords for the system: - * This a table of all of the current strings that are vaild AFM keys. - * Each entry can be referenced by the appropriate parseKey value (an - * enumerated data type defined above). If you add a new keyword here, - * a corresponding parseKey MUST be added to the enumerated data type - * defined above, AND it MUST be added in the same position as the - * string is in this table. - * - * IMPORTANT: since the sorting algorithm is a binary search, the keywords - * must be placed in lexicographical order. And, NULL should remain at the - * end. - */ - -static char *keyStrings[] = { - "Ascender", "B", "C", "CC", "CapHeight", "Comment", - "Descender", "EncodingScheme", "EndCharMetrics", "EndComposites", - "EndFontMetrics", "EndKernData", "EndKernPairs", "EndTrackKern", - "FamilyName", "FontBBox", "FontName", "FullName", "IsFixedPitch", - "ItalicAngle", "KP", "KPX", "L", "N", - "Notice", "PCC", "StartCharMetrics", "StartComposites", - "StartFontMetrics", "StartKernData", "StartKernPairs", - "StartTrackKern", "TrackKern", "UnderlinePosition", - "UnderlineThickness", "Version", "W", "WX", "Weight", "XHeight", - NULL }; - -/*************************** PARSING ROUTINES **************/ - -/*************************** token *************************/ - -/* A "AFM File Conventions" tokenizer. That means that it will - * return the next token delimited by white space. See also - * the `linetoken' routine, which does a similar thing but - * reads all tokens until the next end-of-line. - */ - -static char *token(FILE *stream) -{ - int ch, idx; - - /* skip over white space */ - while ((ch = fgetc(stream)) == ' ' || ch == lineterm || - ch == ',' || ch == '\t' || ch == ';'); - - idx = 0; - while (ch != EOF && ch != ' ' && ch != lineterm - && ch != '\t' && ch != ':' && ch != ';') - { - ident[idx++] = ch; - ch = fgetc(stream); - } /* while */ - - if (ch == EOF && idx < 1) return ((char *)NULL); - if (idx >= 1 && ch != ':' ) ungetc(ch, stream); - if (idx < 1 ) ident[idx++] = ch; /* single-character token */ - ident[idx] = 0; - - return(ident); /* returns pointer to the token */ - -} /* token */ - - -/*************************** linetoken *************************/ - -/* "linetoken" will get read all tokens until the EOL character from - * the given stream. This is used to get any arguments that can be - * more than one word (like Comment lines and FullName). - */ - -static char *linetoken(FILE *stream) -{ - int ch, idx; - - while ((ch = fgetc(stream)) == ' ' || ch == '\t' ); - - idx = 0; - while (ch != EOF && ch != lineterm) - { - ident[idx++] = ch; - ch = fgetc(stream); - } /* while */ - - ungetc(ch, stream); - ident[idx] = 0; - - return(ident); /* returns pointer to the token */ - -} /* linetoken */ - - -/*************************** recognize *************************/ - -/* This function tries to match a string to a known list of - * valid AFM entries (check the keyStrings array above). - * "ident" contains everything from white space through the - * next space, tab, or ":" character. - * - * The algorithm is a standard Knuth binary search. - */ - -static enum parseKey recognize(char *ident) -{ - int lower = 0, upper = (int) NOPE, midpoint, cmpvalue; - BOOL found = FALSE; - - while ((upper >= lower) && !found) - { - midpoint = (lower + upper)/2; - if (keyStrings[midpoint] == NULL) break; - cmpvalue = strncmp(ident, keyStrings[midpoint], MAX_NAME); - if (cmpvalue == 0) found = TRUE; - else if (cmpvalue < 0) upper = midpoint - 1; - else lower = midpoint + 1; - } /* while */ - - if (found) return (enum parseKey) midpoint; - else return NOPE; - -} /* recognize */ - - -/************************* parseGlobals *****************************/ - -/* This function is called by "parseFile". It will parse the AFM File - * up to the "StartCharMetrics" keyword, which essentially marks the - * end of the Global Font Information and the beginning of the character - * metrics information. - * - * If the caller of "parseFile" specified that it wanted the Global - * Font Information (as defined by the "AFM File Specification" - * document), then that information will be stored in the returned - * data structure. - * - * Any Global Font Information entries that are not found in a - * given file, will have the usual default initialization value - * for its type (i.e. entries of type int will be 0, etc). - * - * This function returns an error code specifying whether there was - * a premature EOF or a parsing error. This return value is used by - * parseFile to determine if there is more file to parse. - */ - -static BOOL parseGlobals(FILE *fp, GlobalFontInfo *gfi) -{ - BOOL cont = TRUE, save = (gfi != NULL); - int error = ok; - register char *keyword; - - while (cont) - { - keyword = token(fp); - - if (keyword == NULL) - /* Have reached an early and unexpected EOF. */ - /* Set flag and stop parsing */ - { - error = earlyEOF; - break; /* get out of loop */ - } - if (!save) - /* get tokens until the end of the Global Font info section */ - /* without saving any of the data */ - switch (recognize(keyword)) - { - case STARTCHARMETRICS: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - default: - break; - } /* switch */ - else - /* otherwise parse entire global font info section, */ - /* saving the data */ - switch(recognize(keyword)) - { - case STARTFONTMETRICS: - keyword = token(fp); - gfi->afmVersion = (char *) malloc(strlen(keyword) + 1); - strcpy(gfi->afmVersion, keyword); - break; - case COMMENT: - keyword = linetoken(fp); - break; - case FONTNAME: - keyword = token(fp); - gfi->fontName = (char *) malloc(strlen(keyword) + 1); - strcpy(gfi->fontName, keyword); - break; - case ENCODINGSCHEME: - keyword = token(fp); - gfi->encodingScheme = (char *) - malloc(strlen(keyword) + 1); - strcpy(gfi->encodingScheme, keyword); - break; - case FULLNAME: - keyword = linetoken(fp); - gfi->fullName = (char *) malloc(strlen(keyword) + 1); - strcpy(gfi->fullName, keyword); - break; - case FAMILYNAME: - keyword = linetoken(fp); - gfi->familyName = (char *) malloc(strlen(keyword) + 1); - strcpy(gfi->familyName, keyword); - break; - case WEIGHT: - keyword = token(fp); - gfi->weight = (char *) malloc(strlen(keyword) + 1); - strcpy(gfi->weight, keyword); - break; - case ITALICANGLE: - keyword = token(fp); - gfi->italicAngle = atof(keyword); - if (errno == ERANGE) error = parseError; - break; - case ISFIXEDPITCH: - keyword = token(fp); - if (MATCH(keyword, False)) - gfi->isFixedPitch = 0; - else - gfi->isFixedPitch = 1; - break; - case UNDERLINEPOSITION: - keyword = token(fp); - gfi->underlinePosition = atoi(keyword); - break; - case UNDERLINETHICKNESS: - keyword = token(fp); - gfi->underlineThickness = atoi(keyword); - break; - case VERSION: - keyword = token(fp); - gfi->version = (char *) malloc(strlen(keyword) + 1); - strcpy(gfi->version, keyword); - break; - case NOTICE: - keyword = linetoken(fp); - gfi->notice = (char *) malloc(strlen(keyword) + 1); - strcpy(gfi->notice, keyword); - break; - case FONTBBOX: - keyword = token(fp); - gfi->fontBBox.llx = atoi(keyword); - keyword = token(fp); - gfi->fontBBox.lly = atoi(keyword); - keyword = token(fp); - gfi->fontBBox.urx = atoi(keyword); - keyword = token(fp); - gfi->fontBBox.ury = atoi(keyword); - break; - case CAPHEIGHT: - keyword = token(fp); - gfi->capHeight = atoi(keyword); - break; - case XHEIGHT: - keyword = token(fp); - gfi->xHeight = atoi(keyword); - break; - case DESCENDER: - keyword = token(fp); - gfi->descender = atoi(keyword); - break; - case ASCENDER: - keyword = token(fp); - gfi->ascender = atoi(keyword); - break; - case STARTCHARMETRICS: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - case NOPE: - default: - error = parseError; - break; - } /* switch */ - } /* while */ - - return(error); - -} /* parseGlobals */ - - - -#if 0 /* this function does not seem to be used anywhere */ -/************************* initializeArray ************************/ - -/* Unmapped character codes are (at Adobe Systems) assigned the - * width of the space character (if one exists) else they get the - * value of 250 ems. This function initializes all entries in the - * char widths array to have this value. Then any mapped character - * codes will be replaced with the width of the appropriate character - * when parsing the character metric section. - - * This function parses the Character Metrics Section looking - * for a space character (by comparing character names). If found, - * the width of the space character will be used to initialize the - * values in the array of character widths. - * - * Before returning, the position of the read/write pointer of the - * file is reset to be where it was upon entering this function. - */ - -static int initializeArray(FILE *fp, int *cwi) -{ - BOOL cont = TRUE, found = FALSE; - long opos = ftell(fp); - int code = 0, width = 0, i = 0, error = 0; - register char *keyword; - - while (cont) - { - keyword = token(fp); - if (keyword == NULL) - { - error = earlyEOF; - break; /* get out of loop */ - } - switch(recognize(keyword)) - { - case COMMENT: - keyword = linetoken(fp); - break; - case CODE: - code = atoi(token(fp)); - break; - case XWIDTH: - width = atoi(token(fp)); - break; - case CHARNAME: - keyword = token(fp); - if (MATCH(keyword, Space)) - { - cont = FALSE; - found = TRUE; - } - break; - case ENDCHARMETRICS: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - case NOPE: - default: - error = parseError; - break; - } /* switch */ - } /* while */ - - if (!found) - width = 250; - - for (i = 0; i < 256; ++i) - cwi[i] = width; - - fseek(fp, opos, 0); - - return(error); - -} /* initializeArray */ -#endif /* unused */ - -/************************* parseCharWidths **************************/ - -/* This function is called by "parseFile". It will parse the AFM File - * up to the "EndCharMetrics" keyword. It will save the character - * width info (as opposed to all of the character metric information) - * if requested by the caller of parseFile. Otherwise, it will just - * parse through the section without saving any information. - * - * If data is to be saved, parseCharWidths is passed in a pointer - * to an array of widths that has already been initialized by the - * standard value for unmapped character codes. This function parses - * the Character Metrics section only storing the width information - * for the encoded characters into the array using the character code - * as the index into that array. - * - * This function returns an error code specifying whether there was - * a premature EOF or a parsing error. This return value is used by - * parseFile to determine if there is more file to parse. - */ - -static int parseCharWidths(FILE *fp, int *cwi) -{ - BOOL cont = TRUE, save = (cwi != NULL); - int pos = 0, error = ok; - register char *keyword; - - while (cont) - { - keyword = token(fp); - /* Have reached an early and unexpected EOF. */ - /* Set flag and stop parsing */ - if (keyword == NULL) - { - error = earlyEOF; - break; /* get out of loop */ - } - if (!save) - /* get tokens until the end of the Char Metrics section without */ - /* saving any of the data*/ - switch (recognize(keyword)) - { - case ENDCHARMETRICS: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - default: - break; - } /* switch */ - else - /* otherwise parse entire char metrics section, saving */ - /* only the char x-width info */ - switch(recognize(keyword)) - { - case COMMENT: - keyword = linetoken(fp); - break; - case CODE: - keyword = token(fp); - pos = atoi(keyword); - break; - case XYWIDTH: - /* PROBLEM: Should be no Y-WIDTH when doing "quick & dirty" */ - keyword = token(fp); keyword = token(fp); /* eat values */ - error = parseError; - break; - case XWIDTH: - keyword = token(fp); - if (pos >= 0) /* ignore unmapped chars */ - cwi[pos] = atoi(keyword); - break; - case ENDCHARMETRICS: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - case CHARNAME: /* eat values (so doesn't cause parseError) */ - keyword = token(fp); - break; - case CHARBBOX: - keyword = token(fp); keyword = token(fp); - keyword = token(fp); keyword = token(fp); - break; - case LIGATURE: - keyword = token(fp); keyword = token(fp); - break; - case NOPE: - default: - error = parseError; - break; - } /* switch */ - } /* while */ - - return(error); - -} /* parseCharWidths */ - - -/************************* parseCharMetrics ************************/ - -/* This function is called by parseFile if the caller of parseFile - * requested that all character metric information be saved - * (as opposed to only the character width information). - * - * parseCharMetrics is passed in a pointer to an array of records - * to hold information on a per character basis. This function - * parses the Character Metrics section storing all character - * metric information for the ALL characters (mapped and unmapped) - * into the array. - * - * This function returns an error code specifying whether there was - * a premature EOF or a parsing error. This return value is used by - * parseFile to determine if there is more file to parse. - */ - -static int parseCharMetrics(FILE *fp, FontInfo *fi) -{ - BOOL cont = TRUE, firstTime = TRUE; - int error = ok, count = 0; - register CharMetricInfo *temp = fi->cmi; - register char *keyword; - - while (cont) - { - keyword = token(fp); - if (keyword == NULL) - { - error = earlyEOF; - break; /* get out of loop */ - } - switch(recognize(keyword)) - { - case COMMENT: - keyword = linetoken(fp); - break; - case CODE: - if (count < fi->numOfChars) - { - if (firstTime) firstTime = FALSE; - else temp++; - temp->code = atoi(token(fp)); - count++; - } - else - { - error = parseError; - cont = FALSE; - } - break; - case XYWIDTH: - temp->wx = atoi(token(fp)); - temp->wy = atoi(token(fp)); - break; - case XWIDTH: - temp->wx = atoi(token(fp)); - break; - case CHARNAME: - keyword = token(fp); - temp->name = (char *) malloc(strlen(keyword) + 1); - strcpy(temp->name, keyword); - break; - case CHARBBOX: - temp->charBBox.llx = atoi(token(fp)); - temp->charBBox.lly = atoi(token(fp)); - temp->charBBox.urx = atoi(token(fp)); - temp->charBBox.ury = atoi(token(fp)); - break; - case LIGATURE: { - Ligature **tail = &(temp->ligs); - Ligature *node = *tail; - - if (*tail != NULL) - { - while (node->next != NULL) - node = node->next; - tail = &(node->next); - } - - *tail = (Ligature *) calloc(1, sizeof(Ligature)); - keyword = token(fp); - (*tail)->succ = (char *) malloc(strlen(keyword) + 1); - strcpy((*tail)->succ, keyword); - keyword = token(fp); - (*tail)->lig = (char *) malloc(strlen(keyword) + 1); - strcpy((*tail)->lig, keyword); - break; } - case ENDCHARMETRICS: - cont = FALSE;; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - case NOPE: - default: - error = parseError; - break; - } /* switch */ - } /* while */ - - if ((error == ok) && (count != fi->numOfChars)) - error = parseError; - - return(error); - -} /* parseCharMetrics */ - - - -/************************* parseTrackKernData ***********************/ - -/* This function is called by "parseFile". It will parse the AFM File - * up to the "EndTrackKern" or "EndKernData" keywords. It will save the - * track kerning data if requested by the caller of parseFile. - * - * parseTrackKernData is passed in a pointer to the FontInfo record. - * If data is to be saved, the FontInfo record will already contain - * a valid pointer to storage for the track kerning data. - * - * This function returns an error code specifying whether there was - * a premature EOF or a parsing error. This return value is used by - * parseFile to determine if there is more file to parse. - */ - -static int parseTrackKernData(FILE *fp, FontInfo *fi) -{ - BOOL cont = TRUE, save = (fi->tkd != NULL); - int pos = 0, error = ok, tcount = 0; - register char *keyword; - - while (cont) - { - keyword = token(fp); - - if (keyword == NULL) - { - error = earlyEOF; - break; /* get out of loop */ - } - if (!save) - /* get tokens until the end of the Track Kerning Data */ - /* section without saving any of the data */ - switch(recognize(keyword)) - { - case ENDTRACKKERN: - case ENDKERNDATA: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - default: - break; - } /* switch */ - else - /* otherwise parse entire Track Kerning Data section, */ - /* saving the data */ - switch(recognize(keyword)) - { - case COMMENT: - keyword = linetoken(fp); - break; - case TRACKKERN: - if (tcount < fi->numOfTracks) - { - keyword = token(fp); - fi->tkd[pos].degree = atoi(keyword); - keyword = token(fp); - fi->tkd[pos].minPtSize = atof(keyword); - if (errno == ERANGE) error = parseError; - keyword = token(fp); - fi->tkd[pos].minKernAmt = atof(keyword); - if (errno == ERANGE) error = parseError; - keyword = token(fp); - fi->tkd[pos].maxPtSize = atof(keyword); - if (errno == ERANGE) error = parseError; - keyword = token(fp); - fi->tkd[pos++].maxKernAmt = atof(keyword); - if (errno == ERANGE) error = parseError; - tcount++; - } - else - { - error = parseError; - cont = FALSE; - } - break; - case ENDTRACKKERN: - case ENDKERNDATA: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - case NOPE: - default: - error = parseError; - break; - } /* switch */ - } /* while */ - - if (error == ok && tcount != fi->numOfTracks) - error = parseError; - - return(error); - -} /* parseTrackKernData */ - - -/************************* parsePairKernData ************************/ - -/* This function is called by "parseFile". It will parse the AFM File - * up to the "EndKernPairs" or "EndKernData" keywords. It will save - * the pair kerning data if requested by the caller of parseFile. - * - * parsePairKernData is passed in a pointer to the FontInfo record. - * If data is to be saved, the FontInfo record will already contain - * a valid pointer to storage for the pair kerning data. - * - * This function returns an error code specifying whether there was - * a premature EOF or a parsing error. This return value is used by - * parseFile to determine if there is more file to parse. - */ - -static int parsePairKernData(FILE *fp, FontInfo *fi) -{ - BOOL cont = TRUE, save = (fi->pkd != NULL); - int pos = 0, error = ok, pcount = 0; - register char *keyword; - - while (cont) - { - keyword = token(fp); - - if (keyword == NULL) - { - error = earlyEOF; - break; /* get out of loop */ - } - if (!save) - /* get tokens until the end of the Pair Kerning Data */ - /* section without saving any of the data */ - switch(recognize(keyword)) - { - case ENDKERNPAIRS: - case ENDKERNDATA: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - default: - break; - } /* switch */ - else - /* otherwise parse entire Pair Kerning Data section, */ - /* saving the data */ - switch(recognize(keyword)) - { - case COMMENT: - keyword = linetoken(fp); - break; - case KERNPAIR: - if (pcount < fi->numOfPairs) - { - keyword = token(fp); - fi->pkd[pos].name1 = (char *) - malloc(strlen(keyword) + 1); - strcpy(fi->pkd[pos].name1, keyword); - keyword = token(fp); - fi->pkd[pos].name2 = (char *) - malloc(strlen(keyword) + 1); - strcpy(fi->pkd[pos].name2, keyword); - keyword = token(fp); - fi->pkd[pos].xamt = atoi(keyword); - keyword = token(fp); - fi->pkd[pos++].yamt = atoi(keyword); - pcount++; - } - else - { - error = parseError; - cont = FALSE; - } - break; - case KERNPAIRXAMT: - if (pcount < fi->numOfPairs) - { - keyword = token(fp); - fi->pkd[pos].name1 = (char *) - malloc(strlen(keyword) + 1); - strcpy(fi->pkd[pos].name1, keyword); - keyword = token(fp); - fi->pkd[pos].name2 = (char *) - malloc(strlen(keyword) + 1); - strcpy(fi->pkd[pos].name2, keyword); - keyword = token(fp); - fi->pkd[pos++].xamt = atoi(keyword); - pcount++; - } - else - { - error = parseError; - cont = FALSE; - } - break; - case ENDKERNPAIRS: - case ENDKERNDATA: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - case NOPE: - default: - error = parseError; - break; - } /* switch */ - } /* while */ - - if (error == ok && pcount != fi->numOfPairs) - error = parseError; - - return(error); - -} /* parsePairKernData */ - - -/************************* parseCompCharData **************************/ - -/* This function is called by "parseFile". It will parse the AFM File - * up to the "EndComposites" keyword. It will save the composite - * character data if requested by the caller of parseFile. - * - * parseCompCharData is passed in a pointer to the FontInfo record, and - * a boolean representing if the data should be saved. - * - * This function will create the appropriate amount of storage for - * the composite character data and store a pointer to the storage - * in the FontInfo record. - * - * This function returns an error code specifying whether there was - * a premature EOF or a parsing error. This return value is used by - * parseFile to determine if there is more file to parse. - */ - -static int parseCompCharData(FILE *fp, FontInfo *fi) -{ - BOOL cont = TRUE, firstTime = TRUE, save = (fi->ccd != NULL); - int pos = 0, j = 0, error = ok, ccount = 0, pcount = 0; - register char *keyword; - - while (cont) - { - keyword = token(fp); - if (keyword == NULL) - /* Have reached an early and unexpected EOF. */ - /* Set flag and stop parsing */ - { - error = earlyEOF; - break; /* get out of loop */ - } - if (ccount > fi->numOfComps) - { - error = parseError; - break; /* get out of loop */ - } - if (!save) - /* get tokens until the end of the Composite Character info */ - /* section without saving any of the data */ - switch(recognize(keyword)) - { - case ENDCOMPOSITES: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - default: - break; - } /* switch */ - else - /* otherwise parse entire Composite Character info section, */ - /* saving the data */ - switch(recognize(keyword)) - { - case COMMENT: - keyword = linetoken(fp); - break; - case COMPCHAR: - if (ccount < fi->numOfComps) - { - keyword = token(fp); - if (pcount != fi->ccd[pos].numOfPieces) - error = parseError; - pcount = 0; - if (firstTime) firstTime = FALSE; - else pos++; - fi->ccd[pos].ccName = (char *) - malloc(strlen(keyword) + 1); - strcpy(fi->ccd[pos].ccName, keyword); - keyword = token(fp); - fi->ccd[pos].numOfPieces = atoi(keyword); - fi->ccd[pos].pieces = (Pcc *) - calloc(fi->ccd[pos].numOfPieces, sizeof(Pcc)); - j = 0; - ccount++; - } - else - { - error = parseError; - cont = FALSE; - } - break; - case COMPCHARPIECE: - if (pcount < fi->ccd[pos].numOfPieces) - { - keyword = token(fp); - fi->ccd[pos].pieces[j].pccName = (char *) - malloc(strlen(keyword) + 1); - strcpy(fi->ccd[pos].pieces[j].pccName, keyword); - keyword = token(fp); - fi->ccd[pos].pieces[j].deltax = atoi(keyword); - keyword = token(fp); - fi->ccd[pos].pieces[j++].deltay = atoi(keyword); - pcount++; - } - else - error = parseError; - break; - case ENDCOMPOSITES: - cont = FALSE; - break; - case ENDFONTMETRICS: - cont = FALSE; - error = normalEOF; - break; - case NOPE: - default: - error = parseError; - break; - } /* switch */ - } /* while */ - - if (error == ok && ccount != fi->numOfComps) - error = parseError; - - return(error); - -} /* parseCompCharData */ - - - - -/*************************** 'PUBLIC' FUNCTION ********************/ - - -/*************************** parseFile *****************************/ - -/* parseFile is the only 'public' procedure available. It is called - * from an application wishing to get information from an AFM file. - * The caller of this function is responsible for locating and opening - * an AFM file and handling all errors associated with that task. - * - * parseFile expects 3 parameters: a vaild file pointer, a pointer - * to a (FontInfo *) variable (for which storage will be allocated and - * the data requested filled in), and a mask specifying which - * data from the AFM File should be saved in the FontInfo structure. - * - * The file will be parsed and the requested data will be stored in - * a record of type FontInfo (refer to ParseAFM.h). - * - * parseFile returns an error code as defined in parseAFM.h. - * - * The position of the read/write pointer associated with the file - * pointer upon return of this function is undefined. - */ - -extern int afm_parse_file(FILE *fp, FontInfo **fi, FLAGS flags) -{ - - int code = ok; /* return code from each of the parsing routines */ - int error = ok; /* used as the return code from this function */ - - register char *keyword; /* used to store a token */ - - - /* storage data for the global variable ident */ - ident = (char *) calloc(MAX_NAME, sizeof(char)); - if (ident == NULL) {error = storageProblem; return(error);} - - (*fi) = (FontInfo *) calloc(1, sizeof(FontInfo)); - if ((*fi) == NULL) {error = storageProblem; return(error);} - - if (flags & P_G) - { - (*fi)->gfi = (GlobalFontInfo *) calloc(1, sizeof(GlobalFontInfo)); - if ((*fi)->gfi == NULL) {error = storageProblem; return(error);} - } - - /* The AFM File begins with Global Font Information. This section */ - /* will be parsed whether or not information should be saved. */ - code = parseGlobals(fp, (*fi)->gfi); - - if (code < 0) error = code; - - /* The Global Font Information is followed by the Character Metrics */ - /* section. Which procedure is used to parse this section depends on */ - /* how much information should be saved. If all of the metrics info */ - /* is wanted, parseCharMetrics is called. If only the character widths */ - /* is wanted, parseCharWidths is called. parseCharWidths will also */ - /* be called in the case that no character data is to be saved, just */ - /* to parse through the section. */ - - if ((code != normalEOF) && (code != earlyEOF)) - { - (*fi)->numOfChars = atoi(token(fp)); - if (flags & (P_M ^ P_W)) - { - (*fi)->cmi = (CharMetricInfo *) - calloc((*fi)->numOfChars, sizeof(CharMetricInfo)); - if ((*fi)->cmi == NULL) {error = storageProblem; return(error);} - code = parseCharMetrics(fp, *fi); - } - else - { - if (flags & P_W) - { - (*fi)->cwi = (int *) calloc(256, sizeof(int)); - if ((*fi)->cwi == NULL) - { - error = storageProblem; - return(error); - } - } - /* parse section regardless */ - code = parseCharWidths(fp, (*fi)->cwi); - } /* else */ - } /* if */ - - if ((error != earlyEOF) && (code < 0)) error = code; - - /* The remaining sections of the AFM are optional. This code will */ - /* look at the next keyword in the file to determine what section */ - /* is next, and then allocate the appropriate amount of storage */ - /* for the data (if the data is to be saved) and call the */ - /* appropriate parsing routine to parse the section. */ - - while ((code != normalEOF) && (code != earlyEOF)) - { - keyword = token(fp); - if (keyword == NULL) - /* Have reached an early and unexpected EOF. */ - /* Set flag and stop parsing */ - { - code = earlyEOF; - break; /* get out of loop */ - } - switch(recognize(keyword)) - { - case STARTKERNDATA: - break; - case ENDKERNDATA: - break; - case STARTTRACKKERN: - keyword = token(fp); - if (flags & P_T) - { - (*fi)->numOfTracks = atoi(keyword); - (*fi)->tkd = (TrackKernData *) - calloc((*fi)->numOfTracks, sizeof(TrackKernData)); - if ((*fi)->tkd == NULL) - { - error = storageProblem; - return(error); - } - } /* if */ - code = parseTrackKernData(fp, *fi); - break; - case STARTKERNPAIRS: - keyword = token(fp); - if (flags & P_P) - { - (*fi)->numOfPairs = atoi(keyword); - (*fi)->pkd = (PairKernData *) - calloc((*fi)->numOfPairs, sizeof(PairKernData)); - if ((*fi)->pkd == NULL) - { - error = storageProblem; - return(error); - } - } /* if */ - code = parsePairKernData(fp, *fi); - break; - case STARTCOMPOSITES: - keyword = token(fp); - if (flags & P_C) - { - (*fi)->numOfComps = atoi(keyword); - (*fi)->ccd = (CompCharData *) - calloc((*fi)->numOfComps, sizeof(CompCharData)); - if ((*fi)->ccd == NULL) - { - error = storageProblem; - return(error); - } - } /* if */ - code = parseCompCharData(fp, *fi); - break; - case ENDFONTMETRICS: - code = normalEOF; - break; - case NOPE: - default: - code = parseError; - break; - } /* switch */ - - if ((error != earlyEOF) && (code < 0)) error = code; - - } /* while */ - - if ((error != earlyEOF) && (code < 0)) error = code; - - if (ident != NULL) { free(ident); ident = NULL; } - - return(error); - -} /* parseFile */ - -/* added for MDVI: this function was copied from `parseAFMclient.c' */ - -void afm_free_fontinfo(FontInfo *fi) -{ - if (fi != NULL) - { - if (fi->gfi != NULL) - { - free(fi->gfi->afmVersion); fi->gfi->afmVersion = NULL; - free(fi->gfi->fontName); fi->gfi->fontName = NULL; - free(fi->gfi->fullName); fi->gfi->fullName = NULL; - free(fi->gfi->familyName); fi->gfi->familyName = NULL; - free(fi->gfi->weight); fi->gfi->weight = NULL; - free(fi->gfi->version); fi->gfi->version = NULL; - free(fi->gfi->notice); fi->gfi->notice = NULL; - free(fi->gfi->encodingScheme); fi->gfi->encodingScheme = NULL; - free(fi->gfi); fi->gfi = NULL; - } - - if (fi->cwi != NULL) - { free(fi->cwi); fi->cwi = NULL; } - - if (fi->cmi != NULL) - { - int i = 0; - CharMetricInfo *temp = fi->cmi; - Ligature *node = temp->ligs; - - for (i = 0; i < fi->numOfChars; ++i) - { - for (node = temp->ligs; node != NULL; node = node->next) - { - free(node->succ); node->succ = NULL; - free(node->lig); node->lig = NULL; - } - - free(temp->name); temp->name = NULL; - temp++; - } - - free(fi->cmi); fi->cmi = NULL; - } - - if (fi->tkd != NULL) - { free(fi->tkd); fi->tkd = NULL; } - - if (fi->pkd != NULL) - { - free(fi->pkd->name1); fi->pkd->name1 = NULL; - free(fi->pkd->name2); fi->pkd->name2 = NULL; - free(fi->pkd); fi->pkd = NULL; - } - - if (fi->ccd != NULL) - { - int i = 0, j = 0; - CompCharData *ccd = fi->ccd; - - for (i = 0; i < fi->numOfComps; ++i) - { - for (j = 0; j < ccd[i].numOfPieces; ++j) - { - free(ccd[i].pieces[j].pccName); - ccd[i].pieces[j].pccName = NULL; - } - - free(ccd[i].ccName); ccd[i].ccName = NULL; - } - - free(fi->ccd); fi->ccd = NULL; - } - - free(fi); - - } /* if */ - -} /* afm_free_fontinfo */ - -#endif /* WITH_AFM_FILES */ diff --git a/dvi/mdvi-lib/afmparse.h b/dvi/mdvi-lib/afmparse.h deleted file mode 100644 index 6cce780..0000000 --- a/dvi/mdvi-lib/afmparse.h +++ /dev/null @@ -1,307 +0,0 @@ -/* modified for MDVI -- some names changed to avoid conflicts with T1lib */ -/* - * (C) 1988, 1989 by Adobe Systems Incorporated. All rights reserved. - * - * This file may be freely copied and redistributed as long as: - * 1) This entire notice continues to be included in the file, - * 2) If the file has been modified in any way, a notice of such - * modification is conspicuously indicated. - * - * PostScript, Display PostScript, and Adobe are registered trademarks of - * Adobe Systems Incorporated. - * - * ************************************************************************ - * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUT - * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMS - * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR - * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY - * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION, - * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * ************************************************************************ - */ - -/* ParseAFM.h - * - * This header file is used in conjuction with the parseAFM.c file. - * Together these files provide the functionality to parse Adobe Font - * Metrics files and store the information in predefined data structures. - * It is intended to work with an application program that needs font metric - * information. The program can be used as is by making a procedure call to - * parse an AFM file and have the data stored, or an application developer - * may wish to customize the code. - * - * This header file defines the data structures used as well as the key - * strings that are currently recognized by this version of the AFM parser. - * This program is based on the document "Adobe Font Metrics Files, - * Specification Version 2.0". - * - * AFM files are separated into distinct sections of different data. Because - * of this, the parseAFM program can parse a specified file to only save - * certain sections of information based on the application's needs. A record - * containing the requested information will be returned to the application. - * - * AFM files are divided into five sections of data: - * 1) The Global Font Information - * 2) The Character Metrics Information - * 3) The Track Kerning Data - * 4) The Pair-Wise Kerning Data - * 5) The Composite Character Data - * - * Basically, the application can request any of these sections independent - * of what other sections are requested. In addition, in recognizing that - * many applications will want ONLY the x-width of characters and not all - * of the other character metrics information, there is a way to receive - * only the width information so as not to pay the storage cost for the - * unwanted data. An application should never request both the - * "quick and dirty" char metrics (widths only) and the Character Metrics - * Information since the Character Metrics Information will contain all - * of the character widths as well. - * - * There is a procedure in parseAFM.c, called parseFile, that can be - * called from any application wishing to get information from the AFM File. - * This procedure expects 3 parameters: a vaild file descriptor, a pointer - * to a (FontInfo *) variable (for which space will be allocated and then - * will be filled in with the data requested), and a mask specifying - * which data from the AFM File should be saved in the FontInfo structure. - * - * The flags that can be used to set the appropriate mask are defined below. - * In addition, several commonly used masks have already been defined. - * - * History: - * original: DSM Thu Oct 20 17:39:59 PDT 1988 - * modified: DSM Mon Jul 3 14:17:50 PDT 1989 - * - added 'storageProblem' return code - * - fixed typos - */ -#ifndef _MDVI_PARSEAFM_H -#define _MDVI_PARSEAFM_H 1 - -#include "sysdeps.h" - -#include - -/* your basic constants */ -#define TRUE 1 -#define FALSE 0 -#define EOL '\n' /* end-of-line indicator */ -#define MAX_NAME 4096 /* max length for identifiers */ -#define BOOL int -#define FLAGS int - -/* Flags that can be AND'ed together to specify exactly what - * information from the AFM file should be saved. */ -#define P_G 0x01 /* 0000 0001 */ /* Global Font Info */ -#define P_W 0x02 /* 0000 0010 */ /* Character Widths ONLY */ -#define P_M 0x06 /* 0000 0110 */ /* All Char Metric Info */ -#define P_P 0x08 /* 0000 1000 */ /* Pair Kerning Info */ -#define P_T 0x10 /* 0001 0000 */ /* Track Kerning Info */ -#define P_C 0x20 /* 0010 0000 */ /* Composite Char Info */ - -/* Commonly used flags */ -#define P_GW (P_G | P_W) -#define P_GM (P_G | P_M) -#define P_GMP (P_G | P_M | P_P) -#define P_GMK (P_G | P_M | P_P | P_T) -#define P_ALL (P_G | P_M | P_P | P_T | P_C) - -/* Possible return codes from the parseFile procedure. - * - * ok means there were no problems parsing the file. - * - * parseError means that there was some kind of parsing error, but the - * parser went on. This could include problems like the count for any given - * section does not add up to how many entries there actually were, or - * there was a key that was not recognized. The return record may contain - * vaild data or it may not. - * - * earlyEOF means that an End of File was encountered before expected. This - * may mean that the AFM file had been truncated, or improperly formed. - * - * storageProblem means that there were problems allocating storage for - * the data structures that would have contained the AFM data. - */ -#define ok 0 -#define parseError -1 -#define earlyEOF -2 -#define storageProblem -3 - -/************************* TYPES *********************************/ -/* Below are all of the data structure definitions. These structures - * try to map as closely as possible to grouping and naming of data - * in the AFM Files. - */ - -/* Bounding box definition. Used for the Font BBox as well as the - * Character BBox. - */ -typedef struct -{ - int llx; /* lower left x-position */ - int lly; /* lower left y-position */ - int urx; /* upper right x-position */ - int ury; /* upper right y-position */ -} BBox; - -/* Global Font information. - * The key that each field is associated with is in comments. For an - * explanation about each key and its value please refer to the AFM - * documentation (full title & version given above). - */ -typedef struct -{ - char *afmVersion; /* key: StartFontMetrics */ - char *fontName; /* key: FontName */ - char *fullName; /* key: FullName */ - char *familyName; /* key: FamilyName */ - char *weight; /* key: Weight */ - float italicAngle; /* key: ItalicAngle */ - BOOL isFixedPitch; /* key: IsFixedPitch */ - BBox fontBBox; /* key: FontBBox */ - int underlinePosition; /* key: UnderlinePosition */ - int underlineThickness; /* key: UnderlineThickness */ - char *version; /* key: Version */ - char *notice; /* key: Notice */ - char *encodingScheme; /* key: EncodingScheme */ - int capHeight; /* key: CapHeight */ - int xHeight; /* key: XHeight */ - int ascender; /* key: Ascender */ - int descender; /* key: Descender */ -} GlobalFontInfo; - -/* Ligature definition is a linked list since any character can have - * any number of ligatures. - */ -typedef struct _t_ligature -{ - char *succ, *lig; - struct _t_ligature *next; -} Ligature; - -/* Character Metric Information. This structure is used only if ALL - * character metric information is requested. If only the character - * widths is requested, then only an array of the character x-widths - * is returned. - * - * The key that each field is associated with is in comments. For an - * explanation about each key and its value please refer to the - * Character Metrics section of the AFM documentation (full title - * & version given above). - */ -typedef struct -{ - int code, /* key: C */ - wx, /* key: WX */ - wy; /* together wx and wy are associated with key: W */ - char *name; /* key: N */ - BBox charBBox; /* key: B */ - Ligature *ligs; /* key: L (linked list; not a fixed number of Ls */ -} CharMetricInfo; - -/* Track kerning data structure. - * The fields of this record are the five values associated with every - * TrackKern entry. - * - * For an explanation about each value please refer to the - * Track Kerning section of the AFM documentation (full title - * & version given above). - */ -typedef struct -{ - int degree; - float minPtSize, - minKernAmt, - maxPtSize, - maxKernAmt; -} TrackKernData; - -/* Pair Kerning data structure. - * The fields of this record are the four values associated with every - * KP entry. For KPX entries, the yamt will be zero. - * - * For an explanation about each value please refer to the - * Pair Kerning section of the AFM documentation (full title - * & version given above). - */ -typedef struct -{ - char *name1; - char *name2; - int xamt, - yamt; -} PairKernData; - -/* PCC is a piece of a composite character. This is a sub structure of a - * compCharData described below. - * These fields will be filled in with the values from the key PCC. - * - * For an explanation about each key and its value please refer to the - * Composite Character section of the AFM documentation (full title - * & version given above). - */ -typedef struct -{ - char *pccName; - int deltax, - deltay; -} Pcc; - -/* Composite Character Information data structure. - * The fields ccName and numOfPieces are filled with the values associated - * with the key CC. The field pieces points to an array (size = numOfPieces) - * of information about each of the parts of the composite character. That - * array is filled in with the values from the key PCC. - * - * For an explanation about each key and its value please refer to the - * Composite Character section of the AFM documentation (full title - * & version given above). - */ -typedef struct -{ - char *ccName; - int numOfPieces; - Pcc *pieces; -} CompCharData; - -/* FontInfo - * Record type containing pointers to all of the other data - * structures containing information about a font. - * A a record of this type is filled with data by the - * parseFile function. - */ -typedef struct -{ - GlobalFontInfo *gfi; /* ptr to a GlobalFontInfo record */ - int *cwi; /* ptr to 256 element array of just char widths */ - int numOfChars; /* number of entries in char metrics array */ - CharMetricInfo *cmi; /* ptr to char metrics array */ - int numOfTracks; /* number to entries in track kerning array */ - TrackKernData *tkd; /* ptr to track kerning array */ - int numOfPairs; /* number to entries in pair kerning array */ - PairKernData *pkd; /* ptr to pair kerning array */ - int numOfComps; /* number to entries in comp char array */ - CompCharData *ccd; /* ptr to comp char array */ -} FontInfo; - -/************************* PROCEDURES ****************************/ - -/* Call this procedure to do the grunt work of parsing an AFM file. - * - * "fp" should be a valid file pointer to an AFM file. - * - * "fi" is a pointer to a pointer to a FontInfo record sturcture - * (defined above). Storage for the FontInfo structure will be - * allocated in parseFile and the structure will be filled in - * with the requested data from the AFM File. - * - * "flags" is a mask with bits set representing what data should - * be saved. Defined above are valid flags that can be used to set - * the mask, as well as a few commonly used masks. - * - * The possible return codes from parseFile are defined above. - */ - -extern int afm_parse_file __PROTO((FILE *, FontInfo **, FLAGS)); -extern void afm_free_fontinfo __PROTO((FontInfo *)); - -#endif /* _MDVI_PARSEAFM_H */ diff --git a/dvi/mdvi-lib/bitmap.c b/dvi/mdvi-lib/bitmap.c deleted file mode 100644 index 9014dba..0000000 --- a/dvi/mdvi-lib/bitmap.c +++ /dev/null @@ -1,1032 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -/* Bitmap manipulation routines */ - -#include - -#include "mdvi.h" -#include "color.h" - -/* bit_masks[n] contains a BmUnit with `n' contiguous bits */ - -static BmUnit bit_masks[] = { - 0x0, 0x1, 0x3, 0x7, - 0xf, 0x1f, 0x3f, 0x7f, - 0xff, -#if BITMAP_BYTES > 1 - 0x1ff, 0x3ff, 0x7ff, - 0xfff, 0x1fff, 0x3fff, 0x7fff, - 0xffff, -#if BITMAP_BYTES > 2 - 0x1ffff, 0x3ffff, 0x7ffff, - 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, - 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, - 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, - 0xffffffff -#endif /* BITMAP_BYTES > 2 */ -#endif /* BITMAP_BYTES > 1 */ -}; - -#ifndef NODEBUG -#define SHOW_OP_DATA (DEBUGGING(BITMAP_OPS) && DEBUGGING(BITMAP_DATA)) -#endif - -/* - * Some useful macros to manipulate bitmap data - * SEGMENT(m,n) = bit mask for a segment of `m' contiguous bits - * starting at column `n'. These macros assume that - * m + n <= BITMAP_BITS, 0 <= m, n. - */ -#ifdef WORD_BIG_ENDIAN -#define SEGMENT(m,n) (bit_masks[m] << (BITMAP_BITS - (m) - (n))) -#else -#define SEGMENT(m,n) (bit_masks[m] << (n)) -#endif - -/* sampling and shrinking routines shamelessly stolen from xdvi */ - -static int sample_count[] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - -/* bit_swap[j] = j with all bits inverted (i.e. msb -> lsb) */ -static Uchar bit_swap[] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; - - -/* - * next we have three bitmap functions to convert bitmaps in LSB bit order - * with 8, 16 and 32 bits per unit, to our internal format. The differences - * are minimal, but writing a generic function to handle all unit sizes is - * hopelessly slow. - */ - -BITMAP *bitmap_convert_lsb8(Uchar *bits, int w, int h) -{ - BITMAP *bm; - int i; - Uchar *unit; - register Uchar *curr; - Uchar *end; - int bytes; - - DEBUG((DBG_BITMAP_OPS, "convert LSB %dx%d@8 -> bitmap\n", w, h)); - - bm = bitmap_alloc_raw(w, h); - - /* this is the number of bytes in the original bitmap */ - bytes = ROUND(w, 8); - unit = (Uchar *)bm->data; - end = unit + bm->stride; - curr = bits; - /* we try to do this as fast as we can */ - for(i = 0; i < h; i++) { -#ifdef WORD_LITTLE_ENDIAN - memcpy(unit, curr, bytes); - curr += bytes; -#else - int j; - - for(j = 0; j < bytes; curr++, j++) - unit[j] = bit_swap[*curr]; -#endif - memzero(unit + bytes, bm->stride - bytes); - unit += bm->stride; - } - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); - return bm; -} - -BITMAP *bitmap_convert_msb8(Uchar *data, int w, int h) -{ - BITMAP *bm; - Uchar *unit; - Uchar *curr; - int i; - int bytes; - - bm = bitmap_alloc(w, h); - bytes = ROUND(w, 8); - unit = (Uchar *)bm->data; - curr = data; - for(i = 0; i < h; i++) { -#ifdef WORD_LITTLE_ENDIAN - int j; - - for(j = 0; j < bytes; curr++, j++) - unit[j] = bit_swap[*curr]; -#else - memcpy(unit, curr, bytes); - curr += bytes; -#endif - memzero(unit + bytes, bm->stride - bytes); - unit += bm->stride; - } - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); - return bm; -} - - -BITMAP *bitmap_copy(BITMAP *bm) -{ - BITMAP *nb = bitmap_alloc(bm->width, bm->height); - - DEBUG((DBG_BITMAP_OPS, "copy %dx%d\n", bm->width, bm->height)); - memcpy(nb->data, bm->data, bm->height * bm->stride); - return nb; -} - -BITMAP *bitmap_alloc(int w, int h) -{ - BITMAP *bm; - - bm = xalloc(BITMAP); - bm->width = w; - bm->height = h; - bm->stride = BM_BYTES_PER_LINE(bm); - if(h && bm->stride) - bm->data = (BmUnit *)mdvi_calloc(h, bm->stride); - else - bm->data = NULL; - - return bm; -} - -BITMAP *bitmap_alloc_raw(int w, int h) -{ - BITMAP *bm; - - bm = xalloc(BITMAP); - bm->width = w; - bm->height = h; - bm->stride = BM_BYTES_PER_LINE(bm); - if(h && bm->stride) - bm->data = (BmUnit *)mdvi_malloc(h * bm->stride); - else - bm->data = NULL; - - return bm; -} - -void bitmap_destroy(BITMAP *bm) -{ - if(bm->data) - free(bm->data); - free(bm); -} - -void bitmap_print(FILE *out, BITMAP *bm) -{ - int i, j; - BmUnit *a, mask; - static const char labels[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' - }; - int sub; - - a = bm->data; - fprintf(out, " "); - if(bm->width > 10) { - putchar('0'); - sub = 0; - for(j = 2; j <= bm->width; j++) - if((j %10) == 0) { - if((j % 100) == 0) { - fprintf(out, "*"); - sub += 100; - } else - fprintf(out, "%d", (j - sub)/10); - } else - putc(' ', out); - fprintf(out, "\n "); - } - for(j = 0; j < bm->width; j++) - putc(labels[j % 10], out); - putchar('\n'); - for(i = 0; i < bm->height; i++) { - mask = FIRSTMASK; - a = (BmUnit *)((char *)bm->data + i * bm->stride); - fprintf(out, "%3d ", i+1); - for(j = 0; j < bm->width; j++) { - if(*a & mask) - putc('#', out); - else - putc('.', out); - if(mask == LASTMASK) { - a++; - mask = FIRSTMASK; - } else - NEXTMASK(mask); - } - putchar('\n'); - } -} - -void bitmap_set_col(BITMAP *bm, int row, int col, int count, int state) -{ - BmUnit *ptr; - BmUnit mask; - - ptr = __bm_unit_ptr(bm, col, row); - mask = FIRSTMASKAT(col); - - while(count-- > 0) { - if(state) - *ptr |= mask; - else - *ptr &= ~mask; - /* move to next row */ - ptr = bm_offset(ptr, bm->stride); - } -} - -/* - * to use this function you should first make sure that - * there is room for `count' bits in the scanline - * - * A general-purpose (but not very efficient) function to paint `n' pixels - * on a bitmap, starting at position (x, y) would be: - * - * bitmap_paint_bits(__bm_unit_ptr(bitmap, x, y), x % BITMAP_BITS, n) - * - */ -void bitmap_paint_bits(BmUnit *ptr, int n, int count) -{ - /* paint the head */ - if(n + count > BITMAP_BITS) { - *ptr |= SEGMENT(BITMAP_BITS - n, n); - count -= BITMAP_BITS - n; - ptr++; - } else { - *ptr |= SEGMENT(count, n); - return; - } - - /* paint the middle */ - for(; count >= BITMAP_BITS; count -= BITMAP_BITS) - *ptr++ = bit_masks[BITMAP_BITS]; - - /* paint the tail */ - if(count > 0) - *ptr |= SEGMENT(count, 0); -} - -/* - * same as paint_bits but clears pixels instead of painting them. Written - * as a separate function for efficiency reasons. - */ -void bitmap_clear_bits(BmUnit *ptr, int n, int count) -{ - if(n + count > BITMAP_BITS) { - *ptr &= ~SEGMENT(BITMAP_BITS - n, n); - count -= BITMAP_BITS; - ptr++; - } else { - *ptr &= ~SEGMENT(count, n); - return; - } - - for(; count >= BITMAP_BITS; count -= BITMAP_BITS) - *ptr++ = 0; - - if(count > 0) - *ptr &= ~SEGMENT(count, 0); -} - -/* the general function to paint rows. Still used by the PK reader, but that - * will change soon (The GF reader already uses bitmap_paint_bits()). - */ -void bitmap_set_row(BITMAP *bm, int row, int col, int count, int state) -{ - BmUnit *ptr; - - ptr = __bm_unit_ptr(bm, col, row); - if(state) - bitmap_paint_bits(ptr, col & (BITMAP_BITS-1), count); - else - bitmap_clear_bits(ptr, col & (BITMAP_BITS-1), count); -} - -/* - * Now several `flipping' operations - */ - -void bitmap_flip_horizontally(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->width; - nb.height = bm->height; - nb.stride = bm->stride; - nb.data = mdvi_calloc(bm->height, bm->stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, nb.width-1, 0); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fline = fptr; - tline = tptr; - fmask = FIRSTMASK; - tmask = FIRSTMASKAT(nb.width-1); - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - if(tmask == FIRSTMASK) { - tmask = LASTMASK; - tline--; - } else - PREVMASK(tmask); - } - fptr = bm_offset(fptr, bm->stride); - tptr = bm_offset(tptr, bm->stride); - } - DEBUG((DBG_BITMAP_OPS, "flip_horizontally (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_flip_vertically(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask; - int w, h; - - nb.width = bm->width; - nb.height = bm->height; - nb.stride = bm->stride; - nb.data = mdvi_calloc(bm->height, bm->stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, 0, nb.height-1); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fline = fptr; - tline = tptr; - fmask = FIRSTMASK; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= fmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - tline++; - } else - NEXTMASK(fmask); - } - fptr = bm_offset(fptr, bm->stride); - tptr = (BmUnit *)((char *)tptr - bm->stride); - } - DEBUG((DBG_BITMAP_OPS, "flip_vertically (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_flip_diagonally(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->width; - nb.height = bm->height; - nb.stride = bm->stride; - nb.data = mdvi_calloc(bm->height, bm->stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fline = fptr; - tline = tptr; - fmask = FIRSTMASK; - tmask = FIRSTMASKAT(nb.width-1); - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - if(tmask == FIRSTMASK) { - tmask = LASTMASK; - tline--; - } else - PREVMASK(tmask); - } - fptr = bm_offset(fptr, bm->stride); - tptr = bm_offset(tptr, -nb.stride); - } - DEBUG((DBG_BITMAP_OPS, "flip_diagonally (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_rotate_clockwise(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->height; - nb.height = bm->width; - nb.stride = BM_BYTES_PER_LINE(&nb); - nb.data = mdvi_calloc(nb.height, nb.stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, nb.width - 1, 0); - - tmask = FIRSTMASKAT(nb.width-1); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fmask = FIRSTMASK; - fline = fptr; - tline = tptr; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - /* go to next row */ - tline = bm_offset(tline, nb.stride); - } - fptr = bm_offset(fptr, bm->stride); - if(tmask == FIRSTMASK) { - tmask = LASTMASK; - tptr--; - } else - PREVMASK(tmask); - } - - DEBUG((DBG_BITMAP_OPS, "rotate_clockwise (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - bm->width = nb.width; - bm->height = nb.height; - bm->stride = nb.stride; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_rotate_counter_clockwise(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->height; - nb.height = bm->width; - nb.stride = BM_BYTES_PER_LINE(&nb); - nb.data = mdvi_calloc(nb.height, nb.stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, 0, nb.height - 1); - - tmask = FIRSTMASK; - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fmask = FIRSTMASK; - fline = fptr; - tline = tptr; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - /* go to previous row */ - tline = bm_offset(tline, -nb.stride); - } - fptr = bm_offset(fptr, bm->stride); - if(tmask == LASTMASK) { - tmask = FIRSTMASK; - tptr++; - } else - NEXTMASK(tmask); - } - - DEBUG((DBG_BITMAP_OPS, "rotate_counter_clockwise (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - bm->width = nb.width; - bm->height = nb.height; - bm->stride = nb.stride; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_flip_rotate_clockwise(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->height; - nb.height = bm->width; - nb.stride = BM_BYTES_PER_LINE(&nb); - nb.data = mdvi_calloc(nb.height, nb.stride); - - fptr = bm->data; - tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1); - - tmask = FIRSTMASKAT(nb.width-1); - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fmask = FIRSTMASK; - fline = fptr; - tline = tptr; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - /* go to previous line */ - tline = bm_offset(tline, -nb.stride); - } - fptr = bm_offset(fptr, bm->stride); - if(tmask == FIRSTMASK) { - tmask = LASTMASK; - tptr--; - } else - PREVMASK(tmask); - } - DEBUG((DBG_BITMAP_OPS, "flip_rotate_clockwise (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - bm->width = nb.width; - bm->height = nb.height; - bm->stride = nb.stride; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -void bitmap_flip_rotate_counter_clockwise(BITMAP *bm) -{ - BITMAP nb; - BmUnit *fptr, *tptr; - BmUnit fmask, tmask; - int w, h; - - nb.width = bm->height; - nb.height = bm->width; - nb.stride = BM_BYTES_PER_LINE(&nb); - nb.data = mdvi_calloc(nb.height, nb.stride); - - fptr = bm->data; - tptr = nb.data; - tmask = FIRSTMASK; - - for(h = 0; h < bm->height; h++) { - BmUnit *fline, *tline; - - fmask = FIRSTMASK; - fline = fptr; - tline = tptr; - for(w = 0; w < bm->width; w++) { - if(*fline & fmask) - *tline |= tmask; - if(fmask == LASTMASK) { - fmask = FIRSTMASK; - fline++; - } else - NEXTMASK(fmask); - /* go to next line */ - tline = bm_offset(tline, nb.stride); - } - fptr = bm_offset(fptr, bm->stride); - if(tmask == LASTMASK) { - tmask = FIRSTMASK; - tptr++; - } else - NEXTMASK(tmask); - } - - DEBUG((DBG_BITMAP_OPS, "flip_rotate_counter_clockwise (%d,%d) -> (%d,%d)\n", - bm->width, bm->height, nb.width, nb.height)); - mdvi_free(bm->data); - bm->data = nb.data; - bm->width = nb.width; - bm->height = nb.height; - bm->stride = nb.stride; - if(SHOW_OP_DATA) - bitmap_print(stderr, bm); -} - -#if 0 -void bitmap_transform(BITMAP *map, DviOrientation orient) -{ - switch(orient) { - case MDVI_ORIENT_TBLR: - break; - case MDVI_ORIENT_TBRL: - bitmap_flip_horizontally(map); - break; - case MDVI_ORIENT_BTLR: - bitmap_flip_vertically(map); - break; - case MDVI_ORIENT_BTRL: - bitmap_flip_diagonally(map); - break; - case MDVI_ORIENT_RP90: - bitmap_rotate_counter_clockwise(map); - break; - case MDVI_ORIENT_RM90: - bitmap_rotate_clockwise(map); - break; - case MDVI_ORIENT_IRP90: - bitmap_flip_rotate_counter_clockwise(map); - break; - case MDVI_ORIENT_IRM90: - bitmap_flip_rotate_clockwise(map); - break; - } -} -#endif - -/* - * Count the number of non-zero bits in a box of dimensions w x h, starting - * at column `step' in row `data'. - * - * Shamelessly stolen from xdvi. - */ -static int do_sample(BmUnit *data, int stride, int step, int w, int h) -{ - BmUnit *ptr, *end, *cp; - int shift, n; - int bits_left; - int wid; - - ptr = data + step / BITMAP_BITS; - end = bm_offset(data, h * stride); - shift = FIRSTSHIFTAT(step); - bits_left = w; - n = 0; - while(bits_left) { -#ifndef WORD_BIG_ENDIAN - wid = BITMAP_BITS - shift; -#else - wid = shift; -#endif - if(wid > bits_left) - wid = bits_left; - if(wid > 8) - wid = 8; -#ifdef WORD_BIG_ENDIAN - shift -= wid; -#endif - for(cp = ptr; cp < end; cp = bm_offset(cp, stride)) - n += sample_count[(*cp >> shift) & bit_masks[wid]]; -#ifndef WORD_BIG_ENDIAN - shift += wid; -#endif -#ifdef WORD_BIG_ENDIAN - if(shift == 0) { - shift = BITMAP_BITS; - ptr++; - } -#else - if(shift == BITMAP_BITS) { - shift = 0; - ptr++; - } -#endif - bits_left -= wid; - } - return n; -} - -void mdvi_shrink_box(DviContext *dvi, DviFont *font, - DviFontChar *pk, DviGlyph *dest) -{ - int x, y, z; - DviGlyph *glyph; - int hs, vs; - - hs = dvi->params.hshrink; - vs = dvi->params.vshrink; - glyph = &pk->glyph; - - x = (int)glyph->x / hs; - if((int)glyph->x - x * hs > 0) - x++; - dest->w = x + ROUND((int)glyph->w - glyph->x, hs); - - z = (int)glyph->y + 1; - y = z / vs; - if(z - y * vs <= 0) - y--; - dest->h = y + ROUND((int)glyph->h - z, vs) + 1; - dest->x = x; - dest->y = glyph->y / vs; - dest->data = MDVI_GLYPH_EMPTY; - DEBUG((DBG_BITMAPS, "shrink_box: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n", - glyph->w, glyph->h, glyph->x, glyph->y, - dest->w, dest->h, dest->x, dest->y)); -} - -void mdvi_shrink_glyph(DviContext *dvi, DviFont *font, - DviFontChar *pk, DviGlyph *dest) -{ - int rows_left, rows, init_cols; - int cols_left, cols; - BmUnit *old_ptr, *new_ptr; - BITMAP *oldmap, *newmap; - BmUnit m, *cp; - DviGlyph *glyph; - int sample, min_sample; - int old_stride; - int new_stride; - int x, y; - int w, h; - int hs, vs; - - hs = dvi->params.hshrink; - vs = dvi->params.vshrink; - - min_sample = vs * hs * dvi->params.density / 100; - - glyph = &pk->glyph; - oldmap = (BITMAP *)glyph->data; - - x = (int)glyph->x / hs; - init_cols = (int)glyph->x - x * hs; - if(init_cols <= 0) - init_cols += hs; - else - x++; - w = x + ROUND((int)glyph->w - glyph->x, hs); - - cols = (int)glyph->y + 1; - y = cols / vs; - rows = cols - y * vs; - if(rows <= 0) { - rows += vs; - y--; - } - h = y + ROUND((int)glyph->h - cols, vs) + 1; - - /* create the new glyph */ - newmap = bitmap_alloc(w, h); - dest->data = newmap; - dest->x = x; - dest->y = glyph->y / vs; - dest->w = w; - dest->h = h; - - old_ptr = oldmap->data; - old_stride = oldmap->stride; - new_ptr = newmap->data; - new_stride = newmap->stride; - rows_left = glyph->h; - - while(rows_left) { - if(rows > rows_left) - rows = rows_left; - cols_left = glyph->w; - m = FIRSTMASK; - cp = new_ptr; - cols = init_cols; - while(cols_left > 0) { - if(cols > cols_left) - cols = cols_left; - sample = do_sample(old_ptr, old_stride, - glyph->w - cols_left, cols, rows); - if(sample >= min_sample) - *cp |= m; - if(m == LASTMASK) { - m = FIRSTMASK; - cp++; - } else - NEXTMASK(m); - cols_left -= cols; - cols = hs; - } - new_ptr = bm_offset(new_ptr, new_stride); - old_ptr = bm_offset(old_ptr, rows * old_stride); - rows_left -= rows; - rows = vs; - } - DEBUG((DBG_BITMAPS, "shrink_glyph: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n", - glyph->w, glyph->h, glyph->x, glyph->y, - dest->w, dest->h, dest->x, dest->y)); - if(DEBUGGING(BITMAP_DATA)) - bitmap_print(stderr, newmap); -} - -void mdvi_shrink_glyph_grey(DviContext *dvi, DviFont *font, - DviFontChar *pk, DviGlyph *dest) -{ - int rows_left, rows; - int cols_left, cols, init_cols; - long sampleval, samplemax; - BmUnit *old_ptr; - void *image; - int w, h; - int x, y; - DviGlyph *glyph; - BITMAP *map; - Ulong *pixels; - int npixels; - Ulong colortab[2]; - int hs, vs; - DviDevice *dev; - - hs = dvi->params.hshrink; - vs = dvi->params.vshrink; - dev = &dvi->device; - - glyph = &pk->glyph; - map = (BITMAP *)glyph->data; - - x = (int)glyph->x / hs; - init_cols = (int)glyph->x - x * hs; - if(init_cols <= 0) - init_cols += hs; - else - x++; - w = x + ROUND((int)glyph->w - glyph->x, hs); - - cols = (int)glyph->y + 1; - y = cols / vs; - rows = cols - y * vs; - if(rows <= 0) { - rows += vs; - y--; - } - h = y + ROUND((int)glyph->h - cols, vs) + 1; - ASSERT(w && h); - - /* before touching anything, do this */ - image = dev->create_image(dev->device_data, w, h, BITMAP_BITS); - if(image == NULL) { - mdvi_shrink_glyph(dvi, font, pk, dest); - return; - } - - /* save these colors */ - pk->fg = MDVI_CURRFG(dvi); - pk->bg = MDVI_CURRBG(dvi); - - samplemax = vs * hs; - npixels = samplemax + 1; - pixels = get_color_table(&dvi->device, npixels, pk->fg, pk->bg, - dvi->params.gamma, dvi->params.density); - if(pixels == NULL) { - npixels = 2; - colortab[0] = pk->fg; - colortab[1] = pk->bg; - pixels = &colortab[0]; - } - - /* setup the new glyph */ - dest->data = image; - dest->x = x; - dest->y = glyph->y / vs; - dest->w = w; - dest->h = h; - - y = 0; - old_ptr = map->data; - rows_left = glyph->h; - - while(rows_left && y < h) { - x = 0; - if(rows > rows_left) - rows = rows_left; - cols_left = glyph->w; - cols = init_cols; - while(cols_left && x < w) { - if(cols > cols_left) - cols = cols_left; - sampleval = do_sample(old_ptr, map->stride, - glyph->w - cols_left, cols, rows); - /* scale the sample value by the number of grey levels */ - if(npixels - 1 != samplemax) - sampleval = ((npixels-1) * sampleval) / samplemax; - ASSERT(sampleval < npixels); - dev->put_pixel(image, x, y, pixels[sampleval]); - cols_left -= cols; - cols = hs; - x++; - } - for(; x < w; x++) - dev->put_pixel(image, x, y, pixels[0]); - old_ptr = bm_offset(old_ptr, rows * map->stride); - rows_left -= rows; - rows = vs; - y++; - } - - for(; y < h; y++) { - for(x = 0; x < w; x++) - dev->put_pixel(image, x, y, pixels[0]); - } - DEBUG((DBG_BITMAPS, "shrink_glyph_grey: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n", - glyph->w, glyph->h, glyph->x, glyph->y, - dest->w, dest->h, dest->x, dest->y)); -} - diff --git a/dvi/mdvi-lib/bitmap.h b/dvi/mdvi-lib/bitmap.h deleted file mode 100644 index 4d5f23a..0000000 --- a/dvi/mdvi-lib/bitmap.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ -#ifndef _BITMAP_H -#define _BITMAP_H 1 - -#include "sysdeps.h" - -/* Structures and functions to manipulate bitmaps */ - -/* bitmap unit (as in X's docs) */ -typedef Uint32 BmUnit; - -/* size (in bytes) of a bitmap atom */ -#define BITMAP_BYTES 4 - -/* size (in bits) of a bitmap atom */ -#define BITMAP_BITS (BITMAP_BYTES << 3) - -typedef struct { - int width; - int height; - int stride; - BmUnit *data; -} BITMAP; - -#define BM_BYTES_PER_LINE(b) \ - (ROUND((b)->width, BITMAP_BITS) * BITMAP_BYTES) -#define BM_WIDTH(b) (((BITMAP *)(b))->width) -#define BM_HEIGHT(b) (((BITMAP *)(b))->height) - -#define BMBIT(n) ((BmUnit)1 << (n)) - -/* Macros to manipulate individual pixels in a bitmap - * (they are slow, don't use them) - */ - -#define bm_offset(b,o) (BmUnit *)((Uchar *)(b) + (o)) - -#define __bm_unit_ptr(b,x,y) \ - bm_offset((b)->data, (y) * (b)->stride + \ - ((x) / BITMAP_BITS) * BITMAP_BYTES) - -#define __bm_unit(b,x,y) __bm_unit_ptr((b), (x), (y))[0] - -#define BM_GETPIXEL(b,x,y) __bm_unit((b), (x), (y)) -#define BM_SETPIXEL(b,x,y) (__bm_unit((b), (x), (y)) |= FIRSTMASKAT(x)) -#define BM_CLRPIXEL(b,x,y) (__bm_unit((b), (x), (y)) &= ~FIRSTMASKAT(x)) - -/* - * These macros are used to access pixels in a bitmap. They are supposed - * to be used like this: - */ -#if 0 - BmUnit *row, mask; - - mask = FIRSTMASK; - - /* position `unit' at coordinates (column_number, row_number) */ - unit = (BmUnit *)((char *)bitmap->data + row_number * bitmap->stride - + (column_number / BITMAP_BITS); - /* loop over all pixels IN THE SAME ROW */ - for(i = 0; i < number_of_pixels; i++) { - /* to test if a pixel is set */ - if(*unit & mask) { - /* yes, it is, do something with it */ - } - /* to set/clear a pixel */ - if(painting) - *unit |= mask; /* now you see it */ - else - *unit &= ~mask; /* now you don't */ - /* move to next pixel */ - if(mask == LASTMASK) { - unit++; - UPDATEMASK(mask); - } - } -/* end of sample code */ -#endif - -/* bitmaps are stored in native byte order */ -#ifdef WORD_BIG_ENDIAN -#define FIRSTSHIFT (BITMAP_BITS - 1) -#define LASTSHIFT 0 -#define NEXTMASK(m) ((m) >>= 1) -#define PREVMASK(m) ((m) <<= 1) -#define FIRSTSHIFTAT(c) (BITMAP_BITS - ((c) % BITMAP_BITS) - 1) -#else -#define FIRSTSHIFT 0 -#define LASTSHIFT (BITMAP_BITS - 1) -#define NEXTMASK(m) ((m) <<= 1) -#define PREVMASK(m) ((m) >>= 1) -#define FIRSTSHIFTAT(c) ((c) % BITMAP_BITS) -#endif - -#define FIRSTMASK BMBIT(FIRSTSHIFT) -#define FIRSTMASKAT(c) BMBIT(FIRSTSHIFTAT(c)) -#define LASTMASK BMBIT(LASTSHIFT) - -extern BITMAP *bitmap_alloc __PROTO((int, int)); -extern BITMAP *bitmap_alloc_raw __PROTO((int, int)); -extern void bitmap_destroy __PROTO((BITMAP *)); - -/* - * set_row(bm, row, col, count, state): - * sets `count' pixels to state `onoff', starting from pixel - * at position (col, row). All pixels must lie in the same - * row. - */ -extern void bitmap_set_col __PROTO((BITMAP *, int, int, int, int)); -extern void bitmap_set_row __PROTO((BITMAP *, int, int, int, int)); - -extern void bitmap_paint_bits __PROTO((BmUnit *, int, int)); -extern void bitmap_clear_bits __PROTO((BmUnit *, int, int)); - -extern BITMAP *bitmap_copy __PROTO((BITMAP *)); -extern void bitmap_flip_horizontally __PROTO((BITMAP *)); -extern void bitmap_flip_vertically __PROTO((BITMAP *)); -extern void bitmap_flip_diagonally __PROTO((BITMAP *)); -extern void bitmap_rotate_clockwise __PROTO((BITMAP *)); -extern void bitmap_rotate_counter_clockwise __PROTO((BITMAP *)); -extern void bitmap_flip_rotate_clockwise __PROTO((BITMAP *)); -extern void bitmap_flip_rotate_counter_clockwise __PROTO((BITMAP *)); -extern BITMAP *bitmap_convert_lsb8 __PROTO((Uchar *, int, int)); -extern BITMAP *bitmap_convert_msb8 __PROTO((Uchar *, int, int)); - -#include -extern void bitmap_print __PROTO((FILE *, BITMAP *)); - -#endif /* _BITMAP_H */ diff --git a/dvi/mdvi-lib/color.c b/dvi/mdvi-lib/color.c deleted file mode 100644 index 366b0ea..0000000 --- a/dvi/mdvi-lib/color.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include "mdvi.h" -#include "color.h" - -void mdvi_set_color(DviContext *dvi, Ulong fg, Ulong bg) -{ - if(dvi->curr_fg != fg || dvi->curr_bg != bg) { - DEBUG((DBG_DEVICE, "setting color to (%lu,%lu)\n", fg, bg)); - if(dvi->device.set_color) - dvi->device.set_color(dvi->device.device_data, fg, bg); - dvi->curr_fg = fg; - dvi->curr_bg = bg; - } -} - -void mdvi_push_color(DviContext *dvi, Ulong fg, Ulong bg) -{ - if(dvi->color_top == dvi->color_size) { - dvi->color_size += 32; - dvi->color_stack = mdvi_realloc(dvi->color_stack, - dvi->color_size * sizeof(DviColorPair)); - } - dvi->color_stack[dvi->color_top].fg = dvi->curr_fg; - dvi->color_stack[dvi->color_top].bg = dvi->curr_bg; - dvi->color_top++; - mdvi_set_color(dvi, fg, bg); -} - -void mdvi_pop_color(DviContext *dvi) -{ - Ulong fg, bg; - - if(dvi->color_top == 0) - return; - dvi->color_top--; - fg = dvi->color_stack[dvi->color_top].fg; - bg = dvi->color_stack[dvi->color_top].bg; - mdvi_set_color(dvi, fg, bg); -} - -void mdvi_reset_color(DviContext *dvi) -{ - dvi->color_top = 0; - mdvi_set_color(dvi, dvi->params.fg, dvi->params.bg); -} - -/* cache for color tables, to avoid creating them for every glyph */ -typedef struct { - Ulong fg; - Ulong bg; - Uint nlevels; - Ulong *pixels; - int density; - double gamma; - Uint hits; -} ColorCache; - -#define CCSIZE 256 -static ColorCache color_cache[CCSIZE]; -static int cc_entries; - -#define GAMMA_DIFF 0.005 - - -/* create a color table */ -Ulong *get_color_table(DviDevice *dev, - int nlevels, Ulong fg, Ulong bg, double gamma, int density) -{ - ColorCache *cc, *tofree; - int lohits; - Ulong *pixels; - int status; - - lohits = color_cache[0].hits; - tofree = &color_cache[0]; - /* look in the cache and see if we have one that matches this request */ - for(cc = &color_cache[0]; cc < &color_cache[cc_entries]; cc++) { - if(cc->hits < lohits) { - lohits = cc->hits; - tofree = cc; - } - if(cc->fg == fg && cc->bg == bg && cc->density == density && - cc->nlevels == nlevels && fabs(cc->gamma - gamma) <= GAMMA_DIFF) - break; - } - - if(cc < &color_cache[cc_entries]) { - cc->hits++; - return cc->pixels; - } - - DEBUG((DBG_DEVICE, "Adding color table to cache (fg=%lu, bg=%lu, n=%d)\n", - fg, bg, nlevels)); - - /* no entry was found in the cache, create a new one */ - if(cc_entries < CCSIZE) { - cc = &color_cache[cc_entries++]; - cc->pixels = NULL; - } else { - cc = tofree; - mdvi_free(cc->pixels); - } - pixels = xnalloc(Ulong, nlevels); - status = dev->alloc_colors(dev->device_data, - pixels, nlevels, fg, bg, gamma, density); - if(status < 0) { - mdvi_free(pixels); - return NULL; - } - cc->fg = fg; - cc->bg = bg; - cc->gamma = gamma; - cc->density = density; - cc->nlevels = nlevels; - cc->pixels = pixels; - cc->hits = 1; - return pixels; -} diff --git a/dvi/mdvi-lib/color.h b/dvi/mdvi-lib/color.h deleted file mode 100644 index 363776e..0000000 --- a/dvi/mdvi-lib/color.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - - -#ifndef _COLOR_H_ -#define _COLOR_H_ - -#include "common.h" - -extern Ulong *get_color_table(DviDevice *dev, - int nlevels, Ulong fg, Ulong bg, double gamma, int density); - -extern void mdvi_set_color __PROTO((DviContext *, Ulong, Ulong)); -extern void mdvi_push_color __PROTO((DviContext *, Ulong, Ulong)); -extern void mdvi_pop_color __PROTO((DviContext *)); -extern void mdvi_reset_color __PROTO((DviContext *)); - -#endif /* _COLOR_H_ */ - diff --git a/dvi/mdvi-lib/common.c b/dvi/mdvi-lib/common.c deleted file mode 100644 index 7006682..0000000 --- a/dvi/mdvi-lib/common.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include - -#include "common.h" - -static Int32 scaled_width(Int32 fix, int scale); - -long fsgetn(FILE *p, size_t n) -{ - long v; - - v = fgetbyte(p); - if(v & 0x80) - v -= 0x100; - while(--n > 0) - v = (v << 8) | fgetbyte(p); - return v; -} - -Ulong fugetn(FILE *p, size_t n) -{ - Ulong v; - - v = fgetbyte(p); - while(--n > 0) - v = (v << 8) | fgetbyte(p); - return v; -} - -long msgetn(const Uchar *p, size_t n) -{ - long v = (long)*p++; - - if(v & 0x80) - v -= 0x100; - while(--n > 0) - v = (v << 8) | *p++; - return v; -} - -Ulong mugetn(const Uchar *p, size_t n) -{ - Ulong v = (Ulong)*p++; - - while(--n > 0) - v = (v << 8) | *p++; - return v; -} - -char *read_string(FILE *in, int s, char *buffer, size_t len) -{ - int n; - char *str; - - n = fugetn(in, s ? s : 1); - if((str = buffer) == NULL || n + 1 > len) - str = mdvi_malloc(n + 1); - if(fread(str, 1, n, in) != n) { - if(str != buffer) mdvi_free(str); - return NULL; - } - str[n] = 0; - return str; -} - -size_t read_bcpl(FILE *in, char *buffer, size_t maxlen, size_t wanted) -{ - size_t i; - - i = (int)fuget1(in); - if(maxlen && i > maxlen) - i = maxlen; - if(fread(buffer, i, 1, in) != 1) - return -1; - buffer[i] = '\0'; - while(wanted-- > i) - (void)fgetc(in); - return i; -} - -char *read_alloc_bcpl(FILE *in, size_t maxlen, size_t *size) -{ - size_t i; - char *buffer; - - i = (size_t)fuget1(in); - if(maxlen && i > maxlen) - i = maxlen; - buffer = (char *)malloc(i + 1); - if(buffer == NULL) - return NULL; - if(fread(buffer, i, 1, in) != 1) { - free(buffer); - return NULL; - } - buffer[i] = '\0'; - if(size) *size = i; - return buffer; -} - -/* stolen from dvips */ -static Int32 scaled_width(Int32 fix, int scale) -{ - Int32 al, bl; - - if(fix < 0) - return -scaled_width(-fix, scale); - if(scale < 0) - return -scaled_width(fix, -scale); - al = fix & 32767; - bl = scale & 32767; - al >>= 15; - bl >>= 15; - - return (((al*bl / 32768) + fix*bl + al*scale) / 32 + - fix * scale / 1024); -} - -/* buffers */ - -void buff_free(Buffer *buf) -{ - if(buf->data) - mdvi_free(buf->data); - buff_init(buf); -} - -void buff_init(Buffer *buf) -{ - buf->data = NULL; - buf->size = 0; - buf->length = 0; -} - -size_t buff_add(Buffer *buf, const char *data, size_t len) -{ - if(!len && data) - len = strlen(data); - if(buf->length + len + 1 > buf->size) { - buf->size = buf->length + len + 256; - buf->data = mdvi_realloc(buf->data, buf->size); - } - memcpy(buf->data + buf->length, data, len); - buf->length += len; - return buf->length; -} - -char *buff_gets(Buffer *buf, size_t *length) -{ - char *ptr; - char *ret; - size_t len; - - ptr = strchr(buf->data, '\n'); - if(ptr == NULL) - return NULL; - ptr++; /* include newline */ - len = ptr - buf->data; - ret = mdvi_malloc(len + 1); - if(len > 0) { - memcpy(ret, buf->data, len); - memmove(buf->data, buf->data + len, buf->length - len); - buf->length -= len; - } - ret[len] = 0; - if(length) *length = len; - return ret; -} - diff --git a/dvi/mdvi-lib/common.h b/dvi/mdvi-lib/common.h deleted file mode 100644 index fe4d6f7..0000000 --- a/dvi/mdvi-lib/common.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ -#ifndef _MDVI_COMMON_H -#define _MDVI_COMMON_H 1 - -#include -#include -#include - -#include "sysdeps.h" - -#if STDC_HEADERS -# include -#endif - -#if !defined(STDC_HEADERS) || defined(__STRICT_ANSI__) -# ifndef HAVE_STRCHR -# define strchr index -# define strrchr rindex -# endif -# ifndef HAVE_MEMCPY -# define memcpy(a,b,n) bcopy((b), (a), (n)) -# define memmove(a,b,n) bcopy((b), (a), (n)) -# endif -#endif - -#ifdef HAVE_MEMCPY -#define memzero(a,n) memset((a), 0, (n)) -#else -#define memzero(a,n) bzero((a), (n)) -#endif - -typedef struct _List { - struct _List *next; - struct _List *prev; -} List; -#define LIST(x) ((List *)(x)) - -typedef struct { - char *data; - size_t size; - size_t length; -} Buffer; - -typedef struct { - List *head; - List *tail; - int count; -} ListHead; -#define MDVI_EMPTY_LIST_HEAD {NULL, NULL, 0} - -typedef struct { - char *data; - size_t size; - size_t length; -} Dstring; - -/* Functions to read numbers from streams and memory */ - -#define fgetbyte(p) ((unsigned)getc(p)) - -extern char *program_name; - -extern Ulong fugetn __PROTO((FILE *, size_t)); -extern long fsgetn __PROTO((FILE *, size_t)); -extern Ulong mugetn __PROTO((const Uchar *, size_t)); -extern long msgetn __PROTO((const Uchar *, size_t)); - -/* To read from a stream (fu: unsigned, fs: signed) */ -#define fuget4(p) fugetn((p), 4) -#define fuget3(p) fugetn((p), 3) -#define fuget2(p) fugetn((p), 2) -#define fuget1(p) fgetbyte(p) -#define fsget4(p) fsgetn((p), 4) -#define fsget3(p) fsgetn((p), 3) -#define fsget2(p) fsgetn((p), 2) -#define fsget1(p) fsgetn((p), 1) - -/* To read from memory (mu: unsigned, ms: signed) */ -#define MUGETN(p,n) ((p) += (n), mugetn((p)-(n), (n))) -#define MSGETN(p,n) ((p) += (n), msgetn((p)-(n), (n))) -#define muget4(p) MUGETN((p), 4) -#define muget3(p) MUGETN((p), 3) -#define muget2(p) MUGETN((p), 2) -#define muget1(p) MUGETN((p), 1) -#define msget4(p) MSGETN((p), 4) -#define msget3(p) MSGETN((p), 3) -#define msget2(p) MSGETN((p), 2) -#define msget1(p) MSGETN((p), 1) - -#define ROUND(x,y) (((x) + (y) - 1) / (y)) -#define FROUND(x) (int)((x) + 0.5) -#define SFROUND(x) (int)((x) >= 0 ? floor((x) + 0.5) : ceil((x) + 0.5)) - -#define Max(a,b) (((a) > (b)) ? (a) : (b)) -#define Min(a,b) (((a) < (b)) ? (a) : (b)) - -/* make 2byte number from 2 8bit quantities */ -#define HALFWORD(a,b) ((((a) << 8) & 0xf) | (b)) -#define FULLWORD(a,b,c,d) \ - ((((Int8)(a) << 24) & 0xff000000) | \ - (((Uint8)(b) << 16) & 0x00ff0000) | \ - (((Uint8)(c) << 8) & 0x0000ff00) | \ - ((Uint8)(d) & 0xff)) - -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -#define SWAPINT(a,b) \ - ({ int _s = a; a = b; b = _s; }) -#else -#define SWAPINT(a,b) do { int _s = a; a = b; b = _s; } while(0) -#endif - -#define STREQ(a,b) (strcmp((a), (b)) == 0) -#define STRNEQ(a,b,n) (strncmp((a), (b), (n)) == 0) -#define STRCEQ(a,b) (strcasecmp((a), (b)) == 0) -#define STRNCEQ(a,b,n) (strncasecmp((a), (b), (n)) == 0) - -extern char *read_string __PROTO((FILE *, int, char *, size_t)); -extern size_t read_bcpl __PROTO((FILE *, char *, size_t, size_t)); -extern char *read_alloc_bcpl __PROTO((FILE *, size_t, size_t *)); - -/* miscellaneous */ - -extern void message __PROTO((const char *, ...)); -extern void crash __PROTO((const char *, ...)); -extern void fatal __PROTO((const char *, ...)); -extern void error __PROTO((const char *, ...)); -extern void warning __PROTO((const char *, ...)); -extern int unit2pix __PROTO((int, const char *)); -extern double unit2pix_factor __PROTO((const char *)); - -#define LOG_NONE -1 -#define LOG_INFO 0 -#define LOG_WARN 1 -#define LOG_ERROR 2 -#define LOG_DEBUG 3 - -#define DBG_OPCODE (1 << 0) -#define DBG_FONTS (1 << 1) -#define DBG_FILES (1 << 2) -#define DBG_DVI (1 << 3) -#define DBG_PARAMS (1 << 4) -#define DBG_SPECIAL (1 << 5) -#define DBG_DEVICE (1 << 6) -#define DBG_GLYPHS (1 << 7) -#define DBG_BITMAPS (1 << 8) -#define DBG_PATHS (1 << 9) -#define DBG_SEARCH (1 << 10) -#define DBG_VARS (1 << 11) -#define DBG_BITMAP_OPS (1 << 12) -#define DBG_BITMAP_DATA (1 << 13) -#define DBG_TYPE1 (1 << 14) -#define DBG_TT (1 << 15) -#define DBG_FT2 (1 << 16) -#define DBG_FMAP (1 << 17) - -#define DBG_SILENT (1 << 31) - -#ifdef NODEBUG -#define DEBUGGING(x) 0 -#else -#define DEBUGGING(x) (_mdvi_debug_mask & DBG_##x) -#endif - -#ifndef NODEBUG -extern Uint32 _mdvi_debug_mask; -extern void __debug __PROTO((int, const char *, ...)); -#define DEBUG(x) __debug x -#define ASSERT(x) do { \ - if(!(x)) crash("%s:%d: Assertion %s failed\n", \ - __FILE__, __LINE__, #x); \ - } while(0) -#define ASSERT_VALUE(x,y) do { \ - if((x) != (y)) \ - crash("%s:%d: Assertion failed (%d = %s != %s)\n", \ - __FILE__, __LINE__, (x), #x, #x); \ - } while(0) -#else -#define DEBUG(x) do { } while(0) -#define ASSERT(x) do { } while(0) -#define ASSERT_VALUE(x,y) do { } while(0) -#endif - -#define set_debug_mask(m) (_mdvi_debug_mask = (Uint32)(m)) -#define add_debug_mask(m) (_mdvi_debug_mask |= (Uint32)(m)) -#define get_debug_mask() _mdvi_debug_mask - -/* memory allocation */ - -extern void mdvi_free __PROTO((void *)); -extern void *mdvi_malloc __PROTO((size_t)); -extern void *mdvi_realloc __PROTO((void *, size_t)); -extern void *mdvi_calloc __PROTO((size_t, size_t)); -extern char *mdvi_strncpy __PROTO((char *, const char *, size_t)); -extern char *mdvi_strdup __PROTO((const char *)); -extern char *mdvi_strndup __PROTO((const char *, size_t)); -extern void *mdvi_memdup __PROTO((const void *, size_t)); - -/* macros to make memory allocation nicer */ -#define xalloc(t) (t *)mdvi_malloc(sizeof(t)) -#define xnalloc(t,n) (t *)mdvi_calloc((n), sizeof(t)) -#define xresize(p,t,n) (t *)mdvi_realloc((p), (n) * sizeof(t)) - -extern char *xstradd __PROTO((char *, size_t *, size_t, const char *, size_t)); - -extern Ulong get_mtime __PROTO((int)); - -/* lists */ -extern void listh_init __PROTO((ListHead *)); -extern void listh_prepend __PROTO((ListHead *, List *)); -extern void listh_append __PROTO((ListHead *, List *)); -extern void listh_add_before __PROTO((ListHead *, List *, List *)); -extern void listh_add_after __PROTO((ListHead *, List *, List *)); -extern void listh_remove __PROTO((ListHead *, List *)); -extern void listh_concat __PROTO((ListHead *, ListHead *)); -extern void listh_catcon __PROTO((ListHead *, ListHead *)); - -extern void buff_init __PROTO((Buffer *)); -extern size_t buff_add __PROTO((Buffer *, const char *, size_t)); -extern char *buff_gets __PROTO((Buffer *, size_t *)); -extern void buff_free __PROTO((Buffer *)); - -extern char *getword __PROTO((char *, const char *, char **)); -extern char *getstring __PROTO((char *, const char *, char **)); - -extern void dstring_init __PROTO((Dstring *)); -extern int dstring_new __PROTO((Dstring *, const char *, int)); -extern int dstring_append __PROTO((Dstring *, const char *, int)); -extern int dstring_copy __PROTO((Dstring *, int, const char *, int)); -extern int dstring_insert __PROTO((Dstring *, int, const char *, int)); -extern void dstring_reset __PROTO((Dstring *)); - -#define dstring_length(d) ((d)->length) -#define dstring_strcat(d,s) dstring_append((d), (s), -1) - -extern char *dgets __PROTO((Dstring *, FILE *)); -extern int file_readable __PROTO((const char *)); -extern int file_exists __PROTO((const char *)); -extern const char *file_basename __PROTO((const char *)); -extern const char *file_extension __PROTO((const char *)); - -/* - * Miscellaneous macros - */ - -#define LIST_FOREACH(ptr, type, list) \ - for(ptr = (type *)(list)->head; ptr; ptr = (ptr)->next) - -#define Size(x) (sizeof(x) / sizeof((x)[0])) - -/* multiply a fix_word by a 32bit number */ -#define B0(x) ((x) & 0xff) -#define B1(x) B0((x) >> 8) -#define B2(x) B0((x) >> 16) -#define B3(x) B0((x) >> 24) -#define __tfm_mul(z,t) \ - (((((B0(t) * (z)) >> 8) + (B1(t) * (z))) >> 8) + B2(t) * (z)) -#define TFMSCALE(z,t,a,b) \ - ((B3(t) == 255) ? \ - __tfm_mul((z), (t)) / (b) - (a) : \ - __tfm_mul((z), (t)) / (b)) -#define TFMPREPARE(x,z,a,b) do { \ - a = 16; z = (x); \ - while(z > 040000000L) { z >>= 1; a <<= 1; } \ - b = 256 / a; a *= z; \ - } while(0) - -#endif /* _MDVI_COMMON_H */ diff --git a/dvi/mdvi-lib/defaults.h b/dvi/mdvi-lib/defaults.h deleted file mode 100644 index 46ce6ce..0000000 --- a/dvi/mdvi-lib/defaults.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ -#ifndef _MDVI_DEFAULTS_H -#define _MDVI_DEFAULTS_H 1 - -/* resolution */ -#define MDVI_DPI 600 -#define MDVI_VDPI MDVI_DPI - -/* horizontal margins */ -#define MDVI_HMARGIN "1in" - -/* vertical margins */ -#define MDVI_VMARGIN "1in" - -/* rulers */ -#define MDVI_HRUNITS "1in" -#define MDVI_VRUNITS "1in" - -/* paper */ -#define MDVI_PAPERNAME "letter" - -/* magnification */ -#define MDVI_MAGNIFICATION 1.0 - -/* fallback font */ -#define MDVI_FALLBACK_FONT "cmr10" - -/* metafont mode */ -#define MDVI_MFMODE NULL - -/* default shrinking factor */ -#define MDVI_DEFAULT_SHRINKING -1 /* based on resolution */ - -/* default pixel density */ -#define MDVI_DEFAULT_DENSITY 50 - -/* default gamma correction */ -#define MDVI_DEFAULT_GAMMA 1.0 - -/* default window geometry */ -#define MDVI_GEOMETRY NULL - -/* default orientation */ -#define MDVI_ORIENTATION "tblr" - -/* colors */ -#define MDVI_FOREGROUND "black" -#define MDVI_BACKGROUND "white" - -/* flags */ -#define MDVI_DEFAULT_FLAGS MDVI_ANTIALIASED - -#define MDVI_DEFAULT_CONFIG "mdvi.conf" - -#endif /* _MDVI_DEAFAULTS_H */ diff --git a/dvi/mdvi-lib/dvimisc.c b/dvi/mdvi-lib/dvimisc.c deleted file mode 100644 index 06250ca..0000000 --- a/dvi/mdvi-lib/dvimisc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include "mdvi.h" - -void mdvi_set_color(DviContext *dvi, Ulong fg, Ulong bg) -{ - if(dvi->curr_fg != fg || dvi->curr_bg != bg) { - DEBUG((DBG_DEVICE, "setting color to (%lu,%lu)\n", fg, bg)); - if(dvi->device.set_color) - dvi->device.set_color(dvi->device.device_data, fg, bg); - dvi->curr_fg = fg; - dvi->curr_bg = bg; - } -} - -void mdvi_push_color(DviContext *dvi, Ulong fg, Ulong bg) -{ - if(dvi->color_top == dvi->color_size) { - dvi->color_size += 32; - dvi->color_stack = mdvi_realloc(dvi->color_stack, - dvi->color_size * sizeof(DviColorPair)); - } - dvi->color_stack[dvi->color_top].fg = dvi->curr_fg; - dvi->color_stack[dvi->color_top].bg = dvi->curr_bg; - dvi->color_top++; - mdvi_set_color(dvi, fg, bg); -} - -void mdvi_pop_color(DviContext *dvi) -{ - Ulong fg, bg; - - if(dvi->color_top == 0) - return; - dvi->color_top--; - fg = dvi->color_stack[dvi->color_top].fg; - bg = dvi->color_stack[dvi->color_top].bg; - mdvi_set_color(dvi, fg, bg); -} - -void mdvi_reset_color(DviContext *dvi) -{ - dvi->color_top = 0; - mdvi_set_color(dvi, dvi->params.fg, dvi->params.bg); -} - diff --git a/dvi/mdvi-lib/dviopcodes.h b/dvi/mdvi-lib/dviopcodes.h deleted file mode 100644 index f99af05..0000000 --- a/dvi/mdvi-lib/dviopcodes.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _MDVI_DVIOPCODES_H -#define _MDVI_DVIOPCODES_H 1 - -#define DVI_SET_CHAR0 0 -#define DVI_SET_CHAR1 1 -#define DVI_SET_CHAR_MAX 127 -#define DVI_SET1 128 -#define DVI_SET2 129 -#define DVI_SET3 130 -#define DVI_SET4 131 -#define DVI_SET_RULE 132 -#define DVI_PUT1 133 -#define DVI_PUT2 134 -#define DVI_PUT3 135 -#define DVI_PUT4 136 -#define DVI_PUT_RULE 137 -#define DVI_NOOP 138 -#define DVI_BOP 139 -#define DVI_EOP 140 -#define DVI_PUSH 141 -#define DVI_POP 142 -#define DVI_RIGHT1 143 -#define DVI_RIGHT2 144 -#define DVI_RIGHT3 145 -#define DVI_RIGHT4 146 -#define DVI_W0 147 -#define DVI_W1 148 -#define DVI_W2 149 -#define DVI_W3 150 -#define DVI_W4 151 -#define DVI_X0 152 -#define DVI_X1 153 -#define DVI_X2 154 -#define DVI_X3 155 -#define DVI_X4 156 -#define DVI_DOWN1 157 -#define DVI_DOWN2 158 -#define DVI_DOWN3 159 -#define DVI_DOWN4 160 -#define DVI_Y0 161 -#define DVI_Y1 162 -#define DVI_Y2 163 -#define DVI_Y3 164 -#define DVI_Y4 165 -#define DVI_Z0 166 -#define DVI_Z1 167 -#define DVI_Z2 168 -#define DVI_Z3 169 -#define DVI_Z4 170 -#define DVI_FNT_NUM0 171 -#define DVI_FNT_NUM1 172 -#define DVI_FNT_NUM_MAX 234 -#define DVI_FNT1 235 -#define DVI_FNT2 236 -#define DVI_FNT3 237 -#define DVI_FNT4 238 -#define DVI_XXX1 239 -#define DVI_XXX2 240 -#define DVI_XXX3 241 -#define DVI_XXX4 242 -#define DVI_FNT_DEF1 243 -#define DVI_FNT_DEF2 244 -#define DVI_FNT_DEF3 245 -#define DVI_FNT_DEF4 246 -#define DVI_PRE 247 -#define DVI_POST 248 -#define DVI_POST_POST 249 - -#define DVI_ID 2 -#define DVI_TRAILER 223 - -#endif /* _MDVI_DVIOPCODES_H */ diff --git a/dvi/mdvi-lib/dviread.c b/dvi/mdvi-lib/dviread.c deleted file mode 100644 index 8398c27..0000000 --- a/dvi/mdvi-lib/dviread.c +++ /dev/null @@ -1,1584 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mdvi.h" -#include "private.h" -#include "color.h" - -typedef int (*DviCommand) __PROTO((DviContext *, int)); - -#define DVICMDDEF(x) static int x __PROTO((DviContext *, int)) - -DVICMDDEF(set_char); -DVICMDDEF(set_rule); -DVICMDDEF(no_op); -DVICMDDEF(push); -DVICMDDEF(pop); -DVICMDDEF(move_right); -DVICMDDEF(move_down); -DVICMDDEF(move_w); -DVICMDDEF(move_x); -DVICMDDEF(move_y); -DVICMDDEF(move_z); -DVICMDDEF(sel_font); -DVICMDDEF(sel_fontn); -DVICMDDEF(special); -DVICMDDEF(def_font); -DVICMDDEF(undefined); -DVICMDDEF(unexpected); - -static const DviCommand dvi_commands[] = { - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, - set_char, set_char, set_char, set_char, /* 0 - 127 */ - set_char, set_char, set_char, set_char, /* 128 - 131 */ - set_rule, /* 132 */ - set_char, set_char, set_char, set_char, /* 133 - 136 */ - set_rule, /* 137 */ - no_op, /* 138 */ - unexpected, /* 139 (BOP) */ - unexpected, /* 140 (EOP) */ - push, /* 141 */ - pop, /* 142 */ - move_right, move_right, move_right, move_right, /* 143 - 146 */ - move_w, move_w, move_w, move_w, move_w, /* 147 - 151 */ - move_x, move_x, move_x, move_x, move_x, /* 152 - 156 */ - move_down, move_down, move_down, move_down, /* 157 - 160 */ - move_y, move_y, move_y, move_y, move_y, /* 161 - 165 */ - move_z, move_z, move_z, move_z, move_z, /* 166 - 170 */ - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, - sel_font, sel_font, sel_font, sel_font, /* 171 - 234 */ - sel_fontn, sel_fontn, sel_fontn, sel_fontn, /* 235 - 238 */ - special, special, special, special, /* 239 - 242 */ - def_font, def_font, def_font, def_font, /* 243 - 246 */ - unexpected, /* 247 (PRE) */ - unexpected, /* 248 (POST) */ - unexpected, /* 249 (POST_POST) */ - undefined, undefined, undefined, - undefined, undefined, undefined /* 250 - 255 */ -}; - -#define DVI_BUFLEN 4096 - -static int mdvi_run_macro(DviContext *dvi, Uchar *macro, size_t len); - -static void dummy_draw_glyph(DviContext *dvi, DviFontChar *ch, int x, int y) -{ -} - -static void dummy_draw_rule(DviContext *dvi, int x, int y, Uint w, Uint h, int f) -{ -} - -static int dummy_alloc_colors(void *a, Ulong *b, int c, Ulong d, Ulong e, double f, int g) -{ - return -1; -} - -static void *dummy_create_image(void *a, Uint b, Uint c, Uint d) -{ - return NULL; -} - -static void dummy_free_image(void *a) -{ -} - -static void dummy_dev_destroy(void *a) -{ -} - -static void dummy_dev_putpixel(void *a, int x, int y, Ulong c) -{ -} - -static void dummy_dev_refresh(DviContext *a, void *b) -{ -} - -static void dummy_dev_set_color(void *a, Ulong b, Ulong c) -{ -} - -/* functions to report errors */ -static void dvierr(DviContext *dvi, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - fprintf(stderr, "%s[%d]: Error: ", - dvi->filename, dvi->currpage); - vfprintf(stderr, format, ap); - va_end(ap); -} - -static void dviwarn(DviContext *dvi, const char *format, ...) -{ - va_list ap; - - fprintf(stderr, "%s[%d]: Warning: ", - dvi->filename, dvi->currpage); - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); -} - -#define NEEDBYTES(d,n) \ - ((d)->buffer.pos + (n) > (d)->buffer.length) - -static int get_bytes(DviContext *dvi, size_t n) -{ - /* - * caller wants to read `n' bytes from dvi->buffer + dvi->pos. - * Make sure there is enough data to satisfy the request - */ - if(NEEDBYTES(dvi, n)) { - size_t required; - int newlen; - - if(dvi->buffer.frozen || dvi->in == NULL || feof(dvi->in)) { - /* this is EOF */ - dviwarn(dvi, _("unexpected EOF\n")); - return -1; - } - /* get more data */ - if(dvi->buffer.data == NULL) { - /* first allocation */ - dvi->buffer.size = Max(DVI_BUFLEN, n); - dvi->buffer.data = (Uchar *)mdvi_malloc(dvi->buffer.size); - dvi->buffer.length = 0; - dvi->buffer.frozen = 0; - } else if(dvi->buffer.pos < dvi->buffer.length) { - /* move whatever we want to keep */ - dvi->buffer.length -= dvi->buffer.pos; - memmove(dvi->buffer.data, - dvi->buffer.data + dvi->buffer.pos, - dvi->buffer.length); - } else { - /* we can discard all the data in this buffer */ - dvi->buffer.length = 0; - } - - required = n - dvi->buffer.length; - if(required > dvi->buffer.size - dvi->buffer.length) { - /* need to allocate more memory */ - dvi->buffer.size = dvi->buffer.length + required + 128; - dvi->buffer.data = (Uchar *)xresize(dvi->buffer.data, - char, dvi->buffer.size); - } - /* now read into the buffer */ - newlen = fread(dvi->buffer.data + dvi->buffer.length, - 1, dvi->buffer.size - dvi->buffer.length, dvi->in); - if(newlen == -1) { - error("%s: %s\n", dvi->filename, strerror(errno)); - return -1; - } - dvi->buffer.length += newlen; - dvi->buffer.pos = 0; - } - return 0; -} - -/* only relative forward seeks are supported by this function */ -static int dskip(DviContext *dvi, long offset) -{ - ASSERT(offset > 0); - - if(NEEDBYTES(dvi, offset) && get_bytes(dvi, offset) == -1) - return -1; - dvi->buffer.pos += offset; - return 0; -} - -/* DVI I/O functions (note: here `n' must be <= 4) */ -static long dsgetn(DviContext *dvi, size_t n) -{ - long val; - - if(NEEDBYTES(dvi, n) && get_bytes(dvi, n) == -1) - return -1; - val = msgetn(dvi->buffer.data + dvi->buffer.pos, n); - dvi->buffer.pos += n; - return val; -} - -static int dread(DviContext *dvi, char *buffer, size_t len) -{ - if(NEEDBYTES(dvi, len) && get_bytes(dvi, len) == -1) - return -1; - memcpy(buffer, dvi->buffer.data + dvi->buffer.pos, len); - dvi->buffer.pos += len; - return 0; -} - -static long dugetn(DviContext *dvi, size_t n) -{ - long val; - - if(NEEDBYTES(dvi, n) && get_bytes(dvi, n) == -1) - return -1; - val = mugetn(dvi->buffer.data + dvi->buffer.pos, n); - dvi->buffer.pos += n; - return val; -} - -static long dtell(DviContext *dvi) -{ - return dvi->depth ? - dvi->buffer.pos : - ftell(dvi->in) - dvi->buffer.length + dvi->buffer.pos; -} - -static void dreset(DviContext *dvi) -{ - if(!dvi->buffer.frozen && dvi->buffer.data) - mdvi_free(dvi->buffer.data); - dvi->buffer.data = NULL; - dvi->buffer.size = 0; - dvi->buffer.length = 0; - dvi->buffer.pos = 0; -} - -#define dsget1(d) dsgetn((d), 1) -#define dsget2(d) dsgetn((d), 2) -#define dsget3(d) dsgetn((d), 3) -#define dsget4(d) dsgetn((d), 4) -#define duget1(d) dugetn((d), 1) -#define duget2(d) dugetn((d), 2) -#define duget3(d) dugetn((d), 3) -#define duget4(d) dugetn((d), 4) - -#ifndef NODEBUG -static void dviprint(DviContext *dvi, const char *command, int sub, const char *fmt, ...) -{ - int i; - va_list ap; - - printf("%s: ", dvi->filename); - for(i = 0; i < dvi->depth; i++) - printf(" "); - printf("%4lu: %s", dtell(dvi), command); - if(sub >= 0) printf("%d", sub); - if(*fmt) printf(": "); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); -} -#define SHOWCMD(x) \ - if(_mdvi_debug_mask & DBG_OPCODE) do { dviprint x; } while(0) -#else -#define SHOWCMD(x) do { } while(0) -#endif - -int mdvi_find_tex_page(DviContext *dvi, int tex_page) -{ - int i; - - for(i = 0; i < dvi->npages; i++) - if(dvi->pagemap[i][1] == tex_page) - return i; - return -1; -} - -/* page sorting functions */ -static int sort_up(const void *p1, const void *p2) -{ - return ((long *)p1)[1] - ((long *)p2)[1]; -} -static int sort_down(const void *p1, const void *p2) -{ - return ((long *)p2)[1] - ((long *)p1)[1]; -} -static int sort_random(const void *p1, const void *p2) -{ - return (random() % 1) ? -1 : 1; -} -static int sort_dvi_up(const void *p1, const void *p2) -{ - return ((long *)p1)[0] - ((long *)p2)[0]; -} -static int sort_dvi_down(const void *p1, const void *p2) -{ - return ((long *)p1)[0] - ((long *)p2)[0]; -} - -void mdvi_sort_pages(DviContext *dvi, DviPageSort type) -{ - int (*sortfunc) __PROTO((const void *, const void *)); - - switch(type) { - case MDVI_PAGE_SORT_UP: - sortfunc = sort_up; - break; - case MDVI_PAGE_SORT_DOWN: - sortfunc = sort_down; - break; - case MDVI_PAGE_SORT_RANDOM: - sortfunc = sort_random; - break; - case MDVI_PAGE_SORT_DVI_UP: - sortfunc = sort_dvi_up; - break; - case MDVI_PAGE_SORT_DVI_DOWN: - sortfunc = sort_dvi_down; - break; - case MDVI_PAGE_SORT_NONE: - default: - sortfunc = NULL; - break; - } - - if(sortfunc) - qsort(dvi->pagemap, dvi->npages, sizeof(PageNum), sortfunc); -} - -static DviFontRef *define_font(DviContext *dvi, int op) -{ - Int32 arg; - Int32 scale; - Int32 dsize; - Int32 checksum; - int hdpi; - int vdpi; - int n; - char *name; - DviFontRef *ref; - - arg = dugetn(dvi, op - DVI_FNT_DEF1 + 1); - checksum = duget4(dvi); - scale = duget4(dvi); - dsize = duget4(dvi); - hdpi = FROUND(dvi->params.mag * dvi->params.dpi * scale / dsize); - vdpi = FROUND(dvi->params.mag * dvi->params.vdpi * scale / dsize); - n = duget1(dvi) + duget1(dvi); - name = mdvi_malloc(n + 1); - dread(dvi, name, n); - name[n] = 0; - DEBUG((DBG_FONTS, "requesting font %d = `%s' at %.1fpt (%dx%d dpi)\n", - arg, name, (double)scale / (dvi->params.tfm_conv * 0x100000), - hdpi, vdpi)); - ref = font_reference(&dvi->params, arg, name, checksum, hdpi, vdpi, scale); - if(ref == NULL) { - error(_("could not load font `%s'\n"), name); - mdvi_free(name); - return NULL; - } - mdvi_free(name); - return ref; -} - -static char *opendvi(const char *name) -{ - int len; - char *file; - - len = strlen(name); - /* if file ends with .dvi and it exists, that's it */ - if(len >= 4 && STREQ(name+len-4, ".dvi")) { - DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", name)); - if(access(name, R_OK) == 0) - return mdvi_strdup(name); - } - - /* try appending .dvi */ - file = mdvi_malloc(len + 5); - strcpy(file, name); - strcpy(file+len, ".dvi"); - DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", file)); - if(access(file, R_OK) == 0) - return file; - /* try the given name */ - file[len] = 0; - DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", file)); - if(access(file, R_OK) == 0) - return file; - mdvi_free(file); - return NULL; -} - -int mdvi_reload(DviContext *dvi, DviParams *np) -{ - DviContext *newdvi; - DviParams *pars; - - /* close our file */ - if(dvi->in) { - fclose(dvi->in); - dvi->in = NULL; - } - - pars = np ? np : &dvi->params; - DEBUG((DBG_DVI, "%s: reloading\n", dvi->filename)); - - /* load it again */ - newdvi = mdvi_init_context(pars, dvi->pagesel, dvi->filename); - if(newdvi == NULL) { - warning(_("could not reload `%s'\n"), dvi->filename); - return -1; - } - - /* drop all our font references */ - font_drop_chain(dvi->fonts); - /* destroy our font map */ - if(dvi->fontmap) - mdvi_free(dvi->fontmap); - dvi->currfont = NULL; - - /* and use the ones we just loaded */ - dvi->fonts = newdvi->fonts; - dvi->fontmap = newdvi->fontmap; - dvi->nfonts = newdvi->nfonts; - - /* copy the new information */ - dvi->params = newdvi->params; - dvi->num = newdvi->num; - dvi->den = newdvi->den; - dvi->dvimag = newdvi->dvimag; - dvi->dviconv = newdvi->dviconv; - dvi->dvivconv = newdvi->dvivconv; - dvi->modtime = newdvi->modtime; - - if(dvi->fileid) mdvi_free(dvi->fileid); - dvi->fileid = newdvi->fileid; - - dvi->dvi_page_w = newdvi->dvi_page_w; - dvi->dvi_page_h = newdvi->dvi_page_h; - - mdvi_free(dvi->pagemap); - dvi->pagemap = newdvi->pagemap; - dvi->npages = newdvi->npages; - if(dvi->currpage > dvi->npages-1) - dvi->currpage = 0; - - mdvi_free(dvi->stack); - dvi->stack = newdvi->stack; - dvi->stacksize = newdvi->stacksize; - - /* remove fonts that are not being used anymore */ - font_free_unused(&dvi->device); - - mdvi_free(newdvi->filename); - mdvi_free(newdvi); - - DEBUG((DBG_DVI, "%s: reload successful\n", dvi->filename)); - if(dvi->device.refresh) - dvi->device.refresh(dvi, dvi->device.device_data); - - return 0; -} - -/* function to change parameters ia DVI context - * The DVI context is modified ONLY if this function is successful */ -int mdvi_configure(DviContext *dvi, DviParamCode option, ...) -{ - va_list ap; - int reset_all; - int reset_font; - DviParams np; - - va_start(ap, option); - - reset_font = 0; - reset_all = 0; - np = dvi->params; /* structure copy */ - while(option != MDVI_PARAM_LAST) { - switch(option) { - case MDVI_SET_DPI: - np.dpi = np.vdpi = va_arg(ap, Uint); - reset_all = 1; - break; - case MDVI_SET_XDPI: - np.dpi = va_arg(ap, Uint); - reset_all = 1; - break; - case MDVI_SET_YDPI: - np.vdpi = va_arg(ap, Uint); - break; - case MDVI_SET_SHRINK: - np.hshrink = np.vshrink = va_arg(ap, Uint); - reset_font = MDVI_FONTSEL_GREY|MDVI_FONTSEL_BITMAP; - break; - case MDVI_SET_XSHRINK: - np.hshrink = va_arg(ap, Uint); - reset_font = MDVI_FONTSEL_GREY|MDVI_FONTSEL_BITMAP; - break; - case MDVI_SET_YSHRINK: - np.vshrink = va_arg(ap, Uint); - reset_font = MDVI_FONTSEL_GREY|MDVI_FONTSEL_BITMAP; - break; - case MDVI_SET_ORIENTATION: - np.orientation = va_arg(ap, DviOrientation); - reset_font = MDVI_FONTSEL_GLYPH; - break; - case MDVI_SET_GAMMA: - np.gamma = va_arg(ap, double); - reset_font = MDVI_FONTSEL_GREY; - break; - case MDVI_SET_DENSITY: - np.density = va_arg(ap, Uint); - reset_font = MDVI_FONTSEL_BITMAP; - break; - case MDVI_SET_MAGNIFICATION: - np.mag = va_arg(ap, double); - reset_all = 1; - break; - case MDVI_SET_DRIFT: - np.hdrift = np.vdrift = va_arg(ap, int); - break; - case MDVI_SET_HDRIFT: - np.hdrift = va_arg(ap, int); - break; - case MDVI_SET_VDRIFT: - np.vdrift = va_arg(ap, int); - break; - case MDVI_SET_FOREGROUND: - np.fg = va_arg(ap, Ulong); - reset_font = MDVI_FONTSEL_GREY; - break; - case MDVI_SET_BACKGROUND: - np.bg = va_arg(ap, Ulong); - reset_font = MDVI_FONTSEL_GREY; - break; - default: - break; - } - option = va_arg(ap, DviParamCode); - } - va_end(ap); - - /* check that all values make sense */ - if(np.dpi <= 0 || np.vdpi <= 0) - return -1; - if(np.mag <= 0.0) - return -1; - if(np.density < 0) - return -1; - if(np.hshrink < 1 || np.vshrink < 1) - return -1; - if(np.hdrift < 0 || np.vdrift < 0) - return -1; - if(np.fg == np.bg) - return -1; - - /* - * If the dpi or the magnification change, we basically have to reload - * the DVI file again from scratch. - */ - - if(reset_all) - return (mdvi_reload(dvi, &np) == 0); - - if(np.hshrink != dvi->params.hshrink) { - np.conv = dvi->dviconv; - if(np.hshrink) - np.conv /= np.hshrink; - } - if(np.vshrink != dvi->params.vshrink) { - np.vconv = dvi->dvivconv; - if(np.vshrink) - np.vconv /= np.vshrink; - } - - if(reset_font) { - font_reset_chain_glyphs(&dvi->device, dvi->fonts, reset_font); - } - dvi->params = np; - if((reset_font & MDVI_FONTSEL_GLYPH) && dvi->device.refresh) { - dvi->device.refresh(dvi, dvi->device.device_data); - return 0; - } - - return 1; -} -/* - * Read the initial data from the DVI file. If something is wrong with the - * file, we just spit out an error message and refuse to load the file, - * without giving any details. This makes sense because DVI files are ok - * 99.99% of the time, and dvitype(1) can be used to check the other 0.01%. - */ -DviContext *mdvi_init_context(DviParams *par, DviPageSpec *spec, const char *file) -{ - FILE *p; - Int32 arg; - int op; - long offset; - int n; - DviContext *dvi; - char *filename; - int pagecount; - - /* - * 1. Open the file and initialize the DVI context - */ - - filename = opendvi(file); - if(filename == NULL) { - perror(file); - return NULL; - } - p = fopen(filename, "r"); - if(p == NULL) { - perror(file); - mdvi_free(filename); - return NULL; - } - dvi = xalloc(DviContext); - memzero(dvi, sizeof(DviContext)); - dvi->pagemap = NULL; - dvi->filename = filename; - dvi->stack = NULL; - dvi->modtime = get_mtime(fileno(p)); - dvi->buffer.data = NULL; - dvi->pagesel = spec; - dvi->in = p; /* now we can use the dget*() functions */ - - /* - * 2. Read the preamble, extract scaling information, and - * setup the DVI parameters. - */ - - if(fuget1(p) != DVI_PRE) - goto bad_dvi; - if((arg = fuget1(p)) != DVI_ID) { - error(_("%s: unsupported DVI format (version %u)\n"), - file, arg); - goto error; /* jump to the end of this routine, - * where we handle errors */ - } - /* get dimensions */ - dvi->num = fuget4(p); - dvi->den = fuget4(p); - dvi->dvimag = fuget4(p); - - /* check that these numbers make sense */ - if(!dvi->num || !dvi->den || !dvi->dvimag) - goto bad_dvi; - - dvi->params.mag = - (par->mag > 0 ? par->mag : (double)dvi->dvimag / 1000.0); - dvi->params.hdrift = par->hdrift; - dvi->params.vdrift = par->vdrift; - dvi->params.dpi = par->dpi ? par->dpi : MDVI_DPI; - dvi->params.vdpi = par->vdpi ? par->vdpi : par->dpi; - dvi->params.hshrink = par->hshrink; - dvi->params.vshrink = par->vshrink; - dvi->params.density = par->density; - dvi->params.gamma = par->gamma; - dvi->params.conv = (double)dvi->num / dvi->den; - dvi->params.conv *= (dvi->params.dpi / 254000.0) * dvi->params.mag; - dvi->params.vconv = (double)dvi->num / dvi->den; - dvi->params.vconv *= (dvi->params.vdpi / 254000.0) * dvi->params.mag; - dvi->params.tfm_conv = (25400000.0 / dvi->num) * - ((double)dvi->den / 473628672) / 16.0; - dvi->params.flags = par->flags; - dvi->params.orientation = par->orientation; - dvi->params.fg = par->fg; - dvi->params.bg = par->bg; - - /* initialize colors */ - dvi->curr_fg = par->fg; - dvi->curr_bg = par->bg; - dvi->color_stack = NULL; - dvi->color_top = 0; - dvi->color_size = 0; - - /* pixel conversion factors */ - dvi->dviconv = dvi->params.conv; - dvi->dvivconv = dvi->params.vconv; - if(dvi->params.hshrink) - dvi->params.conv /= dvi->params.hshrink; - if(dvi->params.vshrink) - dvi->params.vconv /= dvi->params.vshrink; - - /* get the comment from the preamble */ - n = fuget1(p); - dvi->fileid = mdvi_malloc(n + 1); - fread(dvi->fileid, 1, n, p); - dvi->fileid[n] = 0; - DEBUG((DBG_DVI, "%s: %s\n", filename, dvi->fileid)); - - /* - * 3. Read postamble, extract page information (number of - * pages, dimensions) and stack depth. - */ - - /* jump to the end of the file */ - if(fseek(p, (long)-1, SEEK_END) == -1) - goto error; - for(n = 0; (op = fuget1(p)) == DVI_TRAILER; n++) - if(fseek(p, (long)-2, SEEK_CUR) < 0) - break; - if(op != arg || n < 4) - goto bad_dvi; - /* get the pointer to postamble */ - fseek(p, (long)-5, SEEK_CUR); - arg = fuget4(p); - /* jump to it */ - fseek(p, (long)arg, SEEK_SET); - if(fuget1(p) != DVI_POST) - goto bad_dvi; - offset = fuget4(p); - if(dvi->num != fuget4(p) || dvi->den != fuget4(p) || - dvi->dvimag != fuget4(p)) - goto bad_dvi; - dvi->dvi_page_h = fuget4(p); - dvi->dvi_page_w = fuget4(p); - dvi->stacksize = fuget2(p); - dvi->npages = fuget2(p); - DEBUG((DBG_DVI, "%s: from postamble: stack depth %d, %d page%s\n", - filename, dvi->stacksize, dvi->npages, dvi->npages > 1 ? "s" : "")); - - /* - * 4. Process font definitions. - */ - - /* process font definitions */ - dvi->nfonts = 0; - dvi->fontmap = NULL; - /* - * CAREFUL: here we need to use the dvi->buffer, but it might leave the - * the file cursor in the wrong position after reading fonts (because of - * buffering). It's ok, though, because after the font definitions we read - * the page offsets, and we fseek() to the relevant part of the file with - * SEEK_SET. Nothing is read after the page offsets. - */ - while((op = duget1(dvi)) != DVI_POST_POST) { - DviFontRef *ref; - - if(op == DVI_NOOP) - continue; - else if(op < DVI_FNT_DEF1 || op > DVI_FNT_DEF4) - goto error; - ref = define_font(dvi, op); - if(ref == NULL) - goto error; - ref->next = dvi->fonts; - dvi->fonts = ref; - dvi->nfonts++; - } - /* we don't need the buffer anymore */ - dreset(dvi); - - if(op != DVI_POST_POST) - goto bad_dvi; - font_finish_definitions(dvi); - DEBUG((DBG_DVI, "%s: %d font%s required by this job\n", - filename, dvi->nfonts, dvi->nfonts > 1 ? "s" : "")); - dvi->findref = font_find_mapped; - - /* - * 5. Build the page map. - */ - - dvi->pagemap = xnalloc(PageNum, dvi->npages); - memzero(dvi->pagemap, sizeof(PageNum) * dvi->npages); - - n = dvi->npages - 1; - pagecount = n; - while(offset != -1) { - int i; - PageNum page; - - fseek(p, offset, SEEK_SET); - op = fuget1(p); - if(op != DVI_BOP || n < 0) - goto bad_dvi; - for(i = 1; i <= 10; i++) - page[i] = fsget4(p); - page[0] = offset; - offset = fsget4(p); - /* check if the page is selected */ - if(spec && mdvi_page_selected(spec, page, n) == 0) { - DEBUG((DBG_DVI, "Page %d (%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld) ignored by request\n", - n, page[1], page[2], page[3], page[4], page[5], - page[6], page[7], page[8], page[9], page[10])); - } else { - memcpy(&dvi->pagemap[pagecount], page, sizeof(PageNum)); - pagecount--; - } - n--; - } - pagecount++; - if(pagecount >= dvi->npages) { - error(_("no pages selected\n")); - goto error; - } - if(pagecount) { - DEBUG((DBG_DVI, "%d of %d pages selected\n", - dvi->npages - pagecount, dvi->npages)); - dvi->npages -= pagecount; - memmove(dvi->pagemap, &dvi->pagemap[pagecount], - dvi->npages * sizeof(PageNum)); - } - - /* - * 6. Setup stack, initialize device functions - */ - - dvi->curr_layer = 0; - dvi->stack = xnalloc(DviState, dvi->stacksize + 8); - - dvi->device.draw_glyph = dummy_draw_glyph; - dvi->device.draw_rule = dummy_draw_rule; - dvi->device.alloc_colors = dummy_alloc_colors; - dvi->device.create_image = dummy_create_image; - dvi->device.free_image = dummy_free_image; - dvi->device.dev_destroy = dummy_dev_destroy; - dvi->device.put_pixel = dummy_dev_putpixel; - dvi->device.refresh = dummy_dev_refresh; - dvi->device.set_color = dummy_dev_set_color; - dvi->device.device_data = NULL; - - DEBUG((DBG_DVI, "%s read successfully\n", filename)); - return dvi; - -bad_dvi: - error(_("%s: File corrupted, or not a DVI file\n"), file); -error: - /* if we came from the font definitions, this will be non-trivial */ - dreset(dvi); - mdvi_destroy_context(dvi); - return NULL; -} - -void mdvi_destroy_context(DviContext *dvi) -{ - if(dvi->device.dev_destroy) - dvi->device.dev_destroy(dvi->device.device_data); - /* release all fonts */ - if(dvi->fonts) { - font_drop_chain(dvi->fonts); - font_free_unused(&dvi->device); - } - if(dvi->fontmap) - mdvi_free(dvi->fontmap); - if(dvi->filename) - mdvi_free(dvi->filename); - if(dvi->stack) - mdvi_free(dvi->stack); - if(dvi->pagemap) - mdvi_free(dvi->pagemap); - if(dvi->fileid) - mdvi_free(dvi->fileid); - if(dvi->in) - fclose(dvi->in); - if(dvi->buffer.data && !dvi->buffer.frozen) - mdvi_free(dvi->buffer.data); - if(dvi->color_stack) - mdvi_free(dvi->color_stack); - - mdvi_free(dvi); -} - -void mdvi_setpage(DviContext *dvi, int pageno) -{ - if(pageno < 0) - pageno = 0; - if(pageno > dvi->npages-1) - pageno = dvi->npages - 1; - dvi->currpage = pageno; -} - -static int mdvi_run_macro(DviContext *dvi, Uchar *macro, size_t len) -{ - DviFontRef *curr, *fonts; - DviBuffer saved_buffer; - FILE *saved_file; - int opcode; - int oldtop; - - dvi->depth++; - push(dvi, DVI_PUSH); - dvi->pos.w = 0; - dvi->pos.x = 0; - dvi->pos.y = 0; - dvi->pos.z = 0; - - /* save our state */ - curr = dvi->currfont; - fonts = dvi->fonts; - saved_buffer = dvi->buffer; - saved_file = dvi->in; - dvi->currfont = curr->ref->subfonts; - dvi->fonts = curr->ref->subfonts; - dvi->buffer.data = macro; - dvi->buffer.pos = 0; - dvi->buffer.length = len; - dvi->buffer.frozen = 1; - dvi->in = NULL; - oldtop = dvi->stacktop; - - /* execute commands */ - while((opcode = duget1(dvi)) != DVI_EOP) { - if(dvi_commands[opcode](dvi, opcode) < 0) - break; - } - if(opcode != DVI_EOP) - dviwarn(dvi, _("%s: vf macro had errors\n"), - curr->ref->fontname); - if(dvi->stacktop != oldtop) - dviwarn(dvi, _("%s: stack not empty after vf macro\n"), - curr->ref->fontname); - - /* restore things */ - pop(dvi, DVI_POP); - dvi->currfont = curr; - dvi->fonts = fonts; - dvi->buffer = saved_buffer; - dvi->in = saved_file; - dvi->depth--; - - return (opcode != DVI_EOP ? -1 : 0); -} - -int mdvi_dopage(DviContext *dvi, int pageno) -{ - int op; - int ppi; - int reloaded = 0; - -again: - if(dvi->in == NULL) { - /* try reopening the file */ - dvi->in = fopen(dvi->filename, "r"); - if(dvi->in == NULL) { - warning(_("%s: could not reopen file (%s)\n"), - dvi->filename, - strerror(errno)); - return -1; - } - DEBUG((DBG_FILES, "reopen(%s) -> Ok\n", dvi->filename)); - } - - /* check if we need to reload the file */ - if(!reloaded && get_mtime(fileno(dvi->in)) > dvi->modtime) { - mdvi_reload(dvi, &dvi->params); - /* we have to reopen the file, again */ - reloaded = 1; - goto again; - } - - if(pageno < 0 || pageno > dvi->npages-1) { - error(_("%s: page %d out of range\n"), - dvi->filename, pageno); - return -1; - } - - fseek(dvi->in, (long)dvi->pagemap[pageno][0], SEEK_SET); - if((op = fuget1(dvi->in)) != DVI_BOP) { - error(_("%s: bad offset at page %d\n"), - dvi->filename, pageno+1); - return -1; - } - - /* skip bop */ - fseek(dvi->in, (long)44, SEEK_CUR); - - /* reset state */ - dvi->currfont = NULL; - memzero(&dvi->pos, sizeof(DviState)); - dvi->stacktop = 0; - dvi->currpage = pageno; - dvi->curr_layer = 0; - - if(dvi->buffer.data && !dvi->buffer.frozen) - mdvi_free(dvi->buffer.data); - - /* reset our buffer */ - dvi->buffer.data = NULL; - dvi->buffer.length = 0; - dvi->buffer.pos = 0; - dvi->buffer.frozen = 0; - -#if 0 /* make colors survive page breaks */ - /* reset color stack */ - mdvi_reset_color(dvi); -#endif - - /* set max horizontal and vertical drift (from dvips) */ - if(dvi->params.hdrift < 0) { - ppi = dvi->params.dpi / dvi->params.hshrink; /* shrunk pixels per inch */ - if(ppi < 600) - dvi->params.hdrift = ppi / 100; - else if(ppi < 1200) - dvi->params.hdrift = ppi / 200; - else - dvi->params.hdrift = ppi / 400; - } - if(dvi->params.vdrift < 0) { - ppi = dvi->params.vdpi / dvi->params.vshrink; /* shrunk pixels per inch */ - if(ppi < 600) - dvi->params.vdrift = ppi / 100; - else if(ppi < 1200) - dvi->params.vdrift = ppi / 200; - else - dvi->params.vdrift = ppi / 400; - } - - dvi->params.thinsp = FROUND(0.025 * dvi->params.dpi / dvi->params.conv); - dvi->params.vsmallsp = FROUND(0.025 * dvi->params.vdpi / dvi->params.vconv); - - /* execute all the commands in the page */ - while((op = duget1(dvi)) != DVI_EOP) { - if(dvi_commands[op](dvi, op) < 0) - break; - } - - fflush(stdout); - fflush(stderr); - if(op != DVI_EOP) - return -1; - if(dvi->stacktop) - dviwarn(dvi, _("stack not empty at end of page\n")); - return 0; -} - -static int inline move_vertical(DviContext *dvi, int amount) -{ - int rvv; - - dvi->pos.v += amount; - rvv = vpixel_round(dvi, dvi->pos.v); - if(!dvi->params.vdrift) - return rvv; - if(amount > dvi->params.vsmallsp || amount <= -dvi->params.vsmallsp) - return rvv; - else { - int newvv; - - newvv = dvi->pos.vv + vpixel_round(dvi, amount); - if(rvv - newvv > dvi->params.vdrift) - return rvv - dvi->params.vdrift; - else if(newvv - rvv > dvi->params.vdrift) - return rvv + dvi->params.vdrift; - else - return newvv; - } -} - -static int inline move_horizontal(DviContext *dvi, int amount) -{ - int rhh; - - dvi->pos.h += amount; - rhh = pixel_round(dvi, dvi->pos.h); - if(!dvi->params.hdrift) - return rhh; - else if(amount > dvi->params.thinsp || amount <= -6 * dvi->params.thinsp) - return rhh; - else { - int newhh; - - newhh = dvi->pos.hh + pixel_round(dvi, amount); - if(rhh - newhh > dvi->params.hdrift) - return rhh - dvi->params.hdrift; - else if(newhh - rhh > dvi->params.hdrift) - return rhh + dvi->params.hdrift; - else - return newhh; - } -} - -static void inline fix_after_horizontal(DviContext *dvi) -{ - int rhh; - - rhh = pixel_round(dvi, dvi->pos.h); - if(!dvi->params.hdrift) - dvi->pos.hh = rhh; - else if(rhh - dvi->pos.hh > dvi->params.hdrift) - dvi->pos.hh = rhh - dvi->params.hdrift; - else if(dvi->pos.hh - rhh > dvi->params.hdrift) - dvi->pos.hh = rhh + dvi->params.hdrift; -} - -/* commands */ - -#define DBGSUM(a,b,c) \ - (a), (b) > 0 ? '+' : '-', \ - (b) > 0 ? (b) : -(b), (c) - -/* - * Draw rules with some sort of antialias support. Usefult for high-rate - * scale factors. - */ - -static void draw_shrink_rule (DviContext *dvi, int x, int y, Uint w, Uint h, int f) -{ - int hs, vs, npixels; - Ulong fg, bg; - Ulong *pixels; - - hs = dvi->params.hshrink; - vs = dvi->params.vshrink; - fg = dvi->params.fg; - bg = dvi->params.bg; - - if (MDVI_ENABLED(dvi, MDVI_PARAM_ANTIALIASED)) { - npixels = vs * hs + 1; - pixels = get_color_table(&dvi->device, npixels, bg, fg, - dvi->params.gamma, dvi->params.density); - - if (pixels) { - int color; - - /* Lines with width 1 should be perfectly visible - * in shrink about 15. That is the reason of constant - */ - - color = (pow (vs / h * hs, 2) + pow (hs / w * vs, 2)) / 225; - if (color < npixels) { - fg = pixels[color]; - } else { - fg = pixels[npixels - 1]; - } - } - } - - mdvi_push_color (dvi, fg, bg); - dvi->device.draw_rule(dvi, x, y, w, h, f); - mdvi_pop_color (dvi); - - return; -} - -/* - * The only commands that actually draw something are: - * set_char, set_rule - */ - -static void draw_box(DviContext *dvi, DviFontChar *ch) -{ - DviGlyph *glyph = NULL; - int x, y, w, h; - - if(!MDVI_GLYPH_UNSET(ch->shrunk.data)) - glyph = &ch->shrunk; - else if(!MDVI_GLYPH_UNSET(ch->grey.data)) - glyph = &ch->grey; - else if(!MDVI_GLYPH_UNSET(ch->glyph.data)) - glyph = &ch->glyph; - if(glyph == NULL) - return; - x = glyph->x; - y = glyph->y; - w = glyph->w; - h = glyph->h; - /* this is bad -- we have to undo the orientation */ - switch(dvi->params.orientation) { - case MDVI_ORIENT_TBLR: - break; - case MDVI_ORIENT_TBRL: - x = w - x; - break; - case MDVI_ORIENT_BTLR: - y = h - y; - break; - case MDVI_ORIENT_BTRL: - x = w - x; - y = h - y; - break; - case MDVI_ORIENT_RP90: - SWAPINT(w, h); - SWAPINT(x, y); - x = w - x; - break; - case MDVI_ORIENT_RM90: - SWAPINT(w, h); - SWAPINT(x, y); - y = h - y; - break; - case MDVI_ORIENT_IRP90: - SWAPINT(w, h); - SWAPINT(x, y); - break; - case MDVI_ORIENT_IRM90: - SWAPINT(w, h); - SWAPINT(x, y); - x = w - x; - y = h - y; - break; - } - - draw_shrink_rule(dvi, dvi->pos.hh - x, dvi->pos.vv - y, w, h, 1); -} - -int set_char(DviContext *dvi, int opcode) -{ - int num; - int h; - int hh; - DviFontChar *ch; - DviFont *font; - - if(opcode < 128) - num = opcode; - else - num = dugetn(dvi, opcode - DVI_SET1 + 1); - if(dvi->currfont == NULL) { - dvierr(dvi, _("no default font set yet\n")); - return -1; - } - font = dvi->currfont->ref; - ch = font_get_glyph(dvi, font, num); - if(ch == NULL || ch->missing) { - /* try to display something anyway */ - ch = FONTCHAR(font, num); - if(!glyph_present(ch)) { - dviwarn(dvi, - _("requested character %d does not exist in `%s'\n"), - num, font->fontname); - return 0; - } - draw_box(dvi, ch); - } else if(dvi->curr_layer <= dvi->params.layer) { - if(ISVIRTUAL(font)) - mdvi_run_macro(dvi, (Uchar *)font->private + - ch->offset, ch->width); - else if(ch->width && ch->height) - dvi->device.draw_glyph(dvi, ch, - dvi->pos.hh, dvi->pos.vv); - } - if(opcode >= DVI_PUT1 && opcode <= DVI_PUT4) { - SHOWCMD((dvi, "putchar", opcode - DVI_PUT1 + 1, - "char %d (%s)\n", - num, dvi->currfont->ref->fontname)); - } else { - h = dvi->pos.h + ch->tfmwidth; - hh = dvi->pos.hh + pixel_round(dvi, ch->tfmwidth); - SHOWCMD((dvi, "setchar", num, "(%d,%d) h:=%d%c%d=%d, hh:=%d (%s)\n", - dvi->pos.hh, dvi->pos.vv, - DBGSUM(dvi->pos.h, ch->tfmwidth, h), hh, - font->fontname)); - dvi->pos.h = h; - dvi->pos.hh = hh; - fix_after_horizontal(dvi); - } - - return 0; -} - -int set_rule(DviContext *dvi, int opcode) -{ - Int32 a, b; - int h, w; - - a = dsget4(dvi); - b = dsget4(dvi); w = rule_round(dvi, b); - if(a > 0 && b > 0) { - h = vrule_round(dvi, a); - SHOWCMD((dvi, opcode == DVI_SET_RULE ? "setrule" : "putrule", -1, - "width %d, height %d (%dx%d pixels)\n", - b, a, w, h)); - /* the `draw' functions expect the origin to be at the top left - * corner of the rule, not the bottom left, as in DVI files */ - if(dvi->curr_layer <= dvi->params.layer) { - draw_shrink_rule(dvi, - dvi->pos.hh, dvi->pos.vv - h + 1, w, h, 1); - } - } else { - SHOWCMD((dvi, opcode == DVI_SET_RULE ? "setrule" : "putrule", -1, - "(moving left only, by %d)\n", b)); - } - - if(opcode == DVI_SET_RULE) { - dvi->pos.h += b; - dvi->pos.hh += w; - fix_after_horizontal(dvi); - } - return 0; -} - -int no_op(DviContext *dvi, int opcode) -{ - SHOWCMD((dvi, "noop", -1, "")); - return 0; -} - -int push(DviContext *dvi, int opcode) -{ - if(dvi->stacktop == dvi->stacksize) { - if(!dvi->depth) - dviwarn(dvi, _("enlarging stack\n")); - dvi->stacksize += 8; - dvi->stack = xresize(dvi->stack, - DviState, dvi->stacksize); - } - memcpy(&dvi->stack[dvi->stacktop], &dvi->pos, sizeof(DviState)); - SHOWCMD((dvi, "push", -1, - "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n", - dvi->stacktop, - dvi->pos.h, dvi->pos.v, dvi->pos.w, dvi->pos.x, - dvi->pos.y, dvi->pos.z, dvi->pos.hh, dvi->pos.vv)); - dvi->stacktop++; - return 0; -} - -int pop(DviContext *dvi, int opcode) -{ - if(dvi->stacktop == 0) { - dvierr(dvi, _("stack underflow\n")); - return -1; - } - memcpy(&dvi->pos, &dvi->stack[dvi->stacktop-1], sizeof(DviState)); - SHOWCMD((dvi, "pop", -1, - "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n", - dvi->stacktop, - dvi->pos.h, dvi->pos.v, dvi->pos.w, dvi->pos.x, - dvi->pos.y, dvi->pos.z, dvi->pos.hh, dvi->pos.vv)); - dvi->stacktop--; - return 0; -} - -int move_right(DviContext *dvi, int opcode) -{ - Int32 arg; - int h, hh; - - arg = dsgetn(dvi, opcode - DVI_RIGHT1 + 1); - h = dvi->pos.h; - hh = move_horizontal(dvi, arg); - SHOWCMD((dvi, "right", opcode - DVI_RIGHT1 + 1, - "%d h:=%d%c%d=%d, hh:=%d\n", - arg, DBGSUM(h, arg, dvi->pos.h), hh)); - dvi->pos.hh = hh; - return 0; -} - -int move_down(DviContext *dvi, int opcode) -{ - Int32 arg; - int v, vv; - - arg = dsgetn(dvi, opcode - DVI_DOWN1 + 1); - v = dvi->pos.v; - vv = move_vertical(dvi, arg); - SHOWCMD((dvi, "down", opcode - DVI_DOWN1 + 1, - "%d v:=%d%c%d=%d, vv:=%d\n", - arg, DBGSUM(v, arg, dvi->pos.v), vv)); - dvi->pos.vv = vv; - return 0; -} - -int move_w(DviContext *dvi, int opcode) -{ - int h, hh; - - if(opcode != DVI_W0) - dvi->pos.w = dsgetn(dvi, opcode - DVI_W0); - h = dvi->pos.h; - hh = move_horizontal(dvi, dvi->pos.w); - SHOWCMD((dvi, "w", opcode - DVI_W0, - "%d h:=%d%c%d=%d, hh:=%d\n", - dvi->pos.w, DBGSUM(h, dvi->pos.w, dvi->pos.h), hh)); - dvi->pos.hh = hh; - return 0; -} - -int move_x(DviContext *dvi, int opcode) -{ - int h, hh; - - if(opcode != DVI_X0) - dvi->pos.x = dsgetn(dvi, opcode - DVI_X0); - h = dvi->pos.h; - hh = move_horizontal(dvi, dvi->pos.x); - SHOWCMD((dvi, "x", opcode - DVI_X0, - "%d h:=%d%c%d=%d, hh:=%d\n", - dvi->pos.x, DBGSUM(h, dvi->pos.x, dvi->pos.h), hh)); - dvi->pos.hh = hh; - return 0; -} - -int move_y(DviContext *dvi, int opcode) -{ - int v, vv; - - if(opcode != DVI_Y0) - dvi->pos.y = dsgetn(dvi, opcode - DVI_Y0); - v = dvi->pos.v; - vv = move_vertical(dvi, dvi->pos.y); - SHOWCMD((dvi, "y", opcode - DVI_Y0, - "%d h:=%d%c%d=%d, hh:=%d\n", - dvi->pos.y, DBGSUM(v, dvi->pos.y, dvi->pos.v), vv)); - dvi->pos.vv = vv; - return 0; -} - -int move_z(DviContext *dvi, int opcode) -{ - int v, vv; - - if(opcode != DVI_Z0) - dvi->pos.z = dsgetn(dvi, opcode - DVI_Z0); - v = dvi->pos.v; - vv = move_vertical(dvi, dvi->pos.z); - SHOWCMD((dvi, "z", opcode - DVI_Z0, - "%d h:=%d%c%d=%d, hh:=%d\n", - dvi->pos.z, DBGSUM(v, dvi->pos.z, dvi->pos.v), vv)); - dvi->pos.vv = vv; - return 0; -} - -int sel_font(DviContext *dvi, int opcode) -{ - DviFontRef *ref; - int ndx; - - ndx = opcode - DVI_FNT_NUM0; - if(dvi->depth) - ref = font_find_flat(dvi, ndx); - else - ref = dvi->findref(dvi, ndx); - if(ref == NULL) { - dvierr(dvi, _("font %d is not defined\n"), - opcode - DVI_FNT_NUM0); - return -1; - } - SHOWCMD((dvi, "fntnum", opcode - DVI_FNT_NUM0, - "current font is %s\n", - ref->ref->fontname)); - dvi->currfont = ref; - return 0; -} - -int sel_fontn(DviContext *dvi, int opcode) -{ - Int32 arg; - DviFontRef *ref; - - arg = dugetn(dvi, opcode - DVI_FNT1 + 1); - if(dvi->depth) - ref = font_find_flat(dvi, arg); - else - ref = dvi->findref(dvi, arg); - if(ref == NULL) { - dvierr(dvi, _("font %d is not defined\n"), arg); - return -1; - } - SHOWCMD((dvi, "fnt", opcode - DVI_FNT1 + 1, - "current font is %s (id %d)\n", - ref->ref->fontname, arg)); - dvi->currfont = ref; - return 0; -} - -int special(DviContext *dvi, int opcode) -{ - char *s; - Int32 arg; - - arg = dugetn(dvi, opcode - DVI_XXX1 + 1); - s = mdvi_malloc(arg + 1); - dread(dvi, s, arg); - s[arg] = 0; - mdvi_do_special(dvi, s); - SHOWCMD((dvi, "XXXX", opcode - DVI_XXX1 + 1, - "[%s]", s)); - mdvi_free(s); - return 0; -} - -int def_font(DviContext *dvi, int opcode) -{ - DviFontRef *ref; - Int32 arg; - - arg = dugetn(dvi, opcode - DVI_FNT_DEF1 + 1); - if(dvi->depth) - ref = font_find_flat(dvi, arg); - else - ref = dvi->findref(dvi, arg); - /* skip the rest */ - dskip(dvi, 12); - dskip(dvi, duget1(dvi) + duget1(dvi)); - if(ref == NULL) { - dvierr(dvi, _("font %d is not defined in postamble\n"), arg); - return -1; - } - SHOWCMD((dvi, "fntdef", opcode - DVI_FNT_DEF1 + 1, - "%d -> %s (%d links)\n", - ref->fontid, ref->ref->fontname, - ref->ref->links)); - return 0; -} - -int unexpected(DviContext *dvi, int opcode) -{ - dvierr(dvi, _("unexpected opcode %d\n"), opcode); - return -1; -} - -int undefined(DviContext *dvi, int opcode) -{ - dvierr(dvi, _("undefined opcode %d\n"), opcode); - return -1; -} - diff --git a/dvi/mdvi-lib/files.c b/dvi/mdvi-lib/files.c deleted file mode 100644 index 0ed893b..0000000 --- a/dvi/mdvi-lib/files.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include -#include - -#include "common.h" - -char *dgets(Dstring *dstr, FILE *in) -{ - char buffer[256]; - - dstr->length = 0; - if(feof(in)) - return NULL; - while(fgets(buffer, 256, in) != NULL) { - int len = strlen(buffer); - - if(buffer[len-1] == '\n') { - dstring_append(dstr, buffer, len - 1); - break; - } - dstring_append(dstr, buffer, len); - } - if(dstr->data) - dstr->data[dstr->length] = 0; - return dstr->data; -} - -/* some simple helper functions to manipulate file names */ - -const char *file_basename(const char *filename) -{ - const char *ptr = strrchr(filename, '/'); - - return (ptr ? ptr + 1 : filename); -} - -const char *file_extension(const char *filename) -{ - const char *ptr = strchr(file_basename(filename), '.'); - - return (ptr ? ptr + 1 : NULL); -} - -int file_readable(const char *filename) -{ - int status = (access(filename, R_OK) == 0); - - DEBUG((DBG_FILES, "file_redable(%s) -> %s\n", - filename, status ? "Yes" : "No")); - return status; -} - -int file_exists(const char *filename) -{ - int status = (access(filename, F_OK) == 0); - - DEBUG((DBG_FILES, "file_exists(%s) -> %s\n", - filename, status ? "Yes" : "No")); - return status; -} - diff --git a/dvi/mdvi-lib/font.c b/dvi/mdvi-lib/font.c deleted file mode 100644 index fedb7e7..0000000 --- a/dvi/mdvi-lib/font.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include - -#include "mdvi.h" -#include "private.h" - -static ListHead fontlist; - -extern char *_mdvi_fallback_font; - -extern void vf_free_macros(DviFont *); - -#define finfo search.info -#define TYPENAME(font) \ - ((font)->finfo ? (font)->finfo->name : "none") - -int font_reopen(DviFont *font) -{ - if(font->in) - fseek(font->in, (long)0, SEEK_SET); - else if((font->in = fopen(font->filename, "r")) == NULL) { - DEBUG((DBG_FILES, "reopen(%s) -> Error\n", font->filename)); - return -1; - } - DEBUG((DBG_FILES, "reopen(%s) -> Ok.\n", font->filename)); - return 0; -} - -/* used from context: params and device */ -static int load_font_file(DviParams *params, DviFont *font) -{ - int status; - - if(SEARCH_DONE(font->search)) - return -1; - if(font->in == NULL && font_reopen(font) < 0) - return -1; - DEBUG((DBG_FONTS, "%s: loading %s font from `%s'\n", - font->fontname, - font->finfo->name, font->filename)); - do { - status = font->finfo->load(params, font); - } while(status < 0 && mdvi_font_retry(params, font) == 0); - if(status < 0) - return -1; - if(font->in) { - fclose(font->in); - font->in = NULL; - } - DEBUG((DBG_FONTS, "reload_font(%s) -> %s\n", - font->fontname, status < 0 ? "Error" : "Ok")); - return 0; -} - -void font_drop_one(DviFontRef *ref) -{ - DviFont *font; - - font = ref->ref; - mdvi_free(ref); - /* drop all children */ - for(ref = font->subfonts; ref; ref = ref->next) { - /* just adjust the reference counts */ - ref->ref->links--; - } - if(--font->links == 0) { - /* - * this font doesn't have any more references, but - * we still keep it around in case a virtual font - * requests it. - */ - if(font->in) { - fclose(font->in); - font->in = NULL; - } - if(LIST(font) != fontlist.tail) { - /* move it to the end of the list */ - listh_remove(&fontlist, LIST(font)); - listh_append(&fontlist, LIST(font)); - } - } - DEBUG((DBG_FONTS, "%s: reference dropped, %d more left\n", - font->fontname, font->links)); -} - -void font_drop_chain(DviFontRef *head) -{ - DviFontRef *ptr; - - for(; (ptr = head); ) { - head = ptr->next; - font_drop_one(ptr); - } -} - -int font_free_unused(DviDevice *dev) -{ - DviFont *font, *next; - int count = 0; - - DEBUG((DBG_FONTS, "destroying unused fonts\n")); - for(font = (DviFont *)fontlist.head; font; font = next) { - DviFontRef *ref; - - next = font->next; - if(font->links) - continue; - count++; - DEBUG((DBG_FONTS, "removing unused %s font `%s'\n", - TYPENAME(font), font->fontname)); - listh_remove(&fontlist, LIST(font)); - if(font->in) - fclose(font->in); - /* get rid of subfonts (but can't use `drop_chain' here) */ - for(; (ref = font->subfonts); ) { - font->subfonts = ref->next; - mdvi_free(ref); - } - /* remove this font */ - font_reset_font_glyphs(dev, font, MDVI_FONTSEL_GLYPH); - /* let the font destroy its private data */ - if(font->finfo->freedata) - font->finfo->freedata(font); - /* destroy characters */ - if(font->chars) - mdvi_free(font->chars); - mdvi_free(font->fontname); - mdvi_free(font->filename); - mdvi_free(font); - } - DEBUG((DBG_FONTS, "%d unused fonts removed\n", count)); - return count; -} - -/* used from context: params and device */ -DviFontRef * -font_reference( - DviParams *params, /* rendering parameters */ - Int32 id, /* external id number */ - const char *name, /* font name */ - Int32 sum, /* checksum (from DVI of VF) */ - int hdpi, /* resolution */ - int vdpi, - Int32 scale) /* scaling factor (from DVI or VF) */ -{ - DviFont *font; - DviFontRef *ref; - DviFontRef *subfont_ref; - - /* see if there is a font with the same characteristics */ - for(font = (DviFont *)fontlist.head; font; font = font->next) { - if(strcmp(name, font->fontname) == 0 - && (!sum || !font->checksum || font->checksum == sum) - && font->hdpi == hdpi - && font->vdpi == vdpi - && font->scale == scale) - break; - } - /* try to load the font */ - if(font == NULL) { - font = mdvi_add_font(name, sum, hdpi, vdpi, scale); - if(font == NULL) - return NULL; - listh_append(&fontlist, LIST(font)); - } - if(!font->links && !font->chars && load_font_file(params, font) < 0) { - DEBUG((DBG_FONTS, "font_reference(%s) -> Error\n", name)); - return NULL; - } - ref = xalloc(DviFontRef); - ref->ref = font; - - font->links++; - for(subfont_ref = font->subfonts; subfont_ref; subfont_ref = subfont_ref->next) { - /* just adjust the reference counts */ - subfont_ref->ref->links++; - } - - ref->fontid = id; - - if(LIST(font) != fontlist.head) { - listh_remove(&fontlist, LIST(font)); - listh_prepend(&fontlist, LIST(font)); - } - - DEBUG((DBG_FONTS, "font_reference(%s) -> %d links\n", - font->fontname, font->links)); - return ref; -} - -void font_transform_glyph(DviOrientation orient, DviGlyph *g) -{ - BITMAP *map; - int x, y; - - map = (BITMAP *)g->data; - if(MDVI_GLYPH_ISEMPTY(map)) - map = NULL; - - /* put the glyph in the right orientation */ - switch(orient) { - case MDVI_ORIENT_TBLR: - break; - case MDVI_ORIENT_TBRL: - g->x = g->w - g->x; - if(map) bitmap_flip_horizontally(map); - break; - case MDVI_ORIENT_BTLR: - g->y = g->h - g->y; - if(map) bitmap_flip_vertically(map); - break; - case MDVI_ORIENT_BTRL: - g->x = g->w - g->x; - g->y = g->h - g->y; - if(map) bitmap_flip_diagonally(map); - break; - case MDVI_ORIENT_RP90: - if(map) bitmap_rotate_counter_clockwise(map); - y = g->y; - x = g->w - g->x; - g->x = y; - g->y = x; - SWAPINT(g->w, g->h); - break; - case MDVI_ORIENT_RM90: - if(map) bitmap_rotate_clockwise(map); - y = g->h - g->y; - x = g->x; - g->x = y; - g->y = x; - SWAPINT(g->w, g->h); - break; - case MDVI_ORIENT_IRP90: - if(map) bitmap_flip_rotate_counter_clockwise(map); - y = g->y; - x = g->x; - g->x = y; - g->y = x; - SWAPINT(g->w, g->h); - break; - case MDVI_ORIENT_IRM90: - if(map) bitmap_flip_rotate_clockwise(map); - y = g->h - g->y; - x = g->w - g->x; - g->x = y; - g->y = x; - SWAPINT(g->w, g->h); - break; - } -} - -static int load_one_glyph(DviContext *dvi, DviFont *font, int code) -{ - BITMAP *map; - DviFontChar *ch; - int status; - -#ifndef NODEBUG - ch = FONTCHAR(font, code); - DEBUG((DBG_GLYPHS, "loading glyph code %d in %s (at %u)\n", - code, font->fontname, ch->offset)); -#endif - if(font->finfo->getglyph == NULL) { - /* font type does not need to load glyphs (e.g. vf) */ - return 0; - } - - status = font->finfo->getglyph(&dvi->params, font, code); - if(status < 0) - return -1; - /* get the glyph again (font->chars may have changed) */ - ch = FONTCHAR(font, code); -#ifndef NODEBUG - map = (BITMAP *)ch->glyph.data; - if(DEBUGGING(BITMAP_DATA)) { - DEBUG((DBG_BITMAP_DATA, - "%s: new %s bitmap for character %d:\n", - font->fontname, TYPENAME(font), code)); - if(MDVI_GLYPH_ISEMPTY(map)) - DEBUG((DBG_BITMAP_DATA, "blank bitmap\n")); - else - bitmap_print(stderr, map); - } -#endif - /* check if we have to scale it */ - if(!font->finfo->scalable && font->hdpi != font->vdpi) { - int hs, vs, d; - - /* we scale it ourselves */ - d = Max(font->hdpi, font->vdpi); - hs = d / font->hdpi; - vs = d / font->vdpi; - if(ch->width && ch->height && (hs > 1 || vs > 1)) { - int h, v; - DviGlyph glyph; - - DEBUG((DBG_FONTS, - "%s: scaling glyph %d to resolution %dx%d\n", - font->fontname, code, font->hdpi, font->vdpi)); - h = dvi->params.hshrink; - v = dvi->params.vshrink; - d = dvi->params.density; - dvi->params.hshrink = hs; - dvi->params.vshrink = vs; - dvi->params.density = 50; - /* shrink it */ - font->finfo->shrink0(dvi, font, ch, &glyph); - /* restore parameters */ - dvi->params.hshrink = h; - dvi->params.vshrink = v; - dvi->params.density = d; - /* update glyph data */ - if(!MDVI_GLYPH_ISEMPTY(ch->glyph.data)) - bitmap_destroy((BITMAP *)ch->glyph.data); - ch->glyph.data = glyph.data; - ch->glyph.x = glyph.x; - ch->glyph.y = glyph.y; - ch->glyph.w = glyph.w; - ch->glyph.h = glyph.h; - } - - } - font_transform_glyph(dvi->params.orientation, &ch->glyph); - - return 0; -} - -DviFontChar *font_get_glyph(DviContext *dvi, DviFont *font, int code) -{ - DviFontChar *ch; - -again: - /* if we have not loaded the font yet, do so now */ - if(!font->chars && load_font_file(&dvi->params, font) < 0) - return NULL; - - /* get the unscaled glyph, maybe loading it from disk */ - ch = FONTCHAR(font, code); - if(!ch || !glyph_present(ch)) - return NULL; - if(!ch->loaded && load_one_glyph(dvi, font, code) == -1) { - if(font->chars == NULL) { - /* we need to try another font class */ - goto again; - } - return NULL; - } - /* yes, we have to do this again */ - ch = FONTCHAR(font, code); - - /* Got the glyph. If we also have the right scaled glyph, do no more */ - if(!ch->width || !ch->height || - font->finfo->getglyph == NULL || - (dvi->params.hshrink == 1 && dvi->params.vshrink == 1)) - return ch; - - /* If the glyph is empty, we just need to shrink the box */ - if(ch->missing || MDVI_GLYPH_ISEMPTY(ch->glyph.data)) { - if(MDVI_GLYPH_UNSET(ch->shrunk.data)) - mdvi_shrink_box(dvi, font, ch, &ch->shrunk); - return ch; - } else if(MDVI_ENABLED(dvi, MDVI_PARAM_ANTIALIASED)) { - if(ch->grey.data && - ch->fg == dvi->curr_fg && - ch->bg == dvi->curr_bg) - return ch; - if(ch->grey.data) { - if(dvi->device.free_image) - dvi->device.free_image(ch->grey.data); - ch->grey.data = NULL; - } - font->finfo->shrink1(dvi, font, ch, &ch->grey); - } else if(!ch->shrunk.data) - font->finfo->shrink0(dvi, font, ch, &ch->shrunk); - - return ch; -} - -void font_reset_one_glyph(DviDevice *dev, DviFontChar *ch, int what) -{ - if(!glyph_present(ch)) - return; - if(what & MDVI_FONTSEL_BITMAP) { - if(MDVI_GLYPH_NONEMPTY(ch->shrunk.data)) - bitmap_destroy((BITMAP *)ch->shrunk.data); - ch->shrunk.data = NULL; - } - if(what & MDVI_FONTSEL_GREY) { - if(MDVI_GLYPH_NONEMPTY(ch->grey.data)) { - if(dev->free_image) - dev->free_image(ch->grey.data); - } - ch->grey.data = NULL; - } - if(what & MDVI_FONTSEL_GLYPH) { - if(MDVI_GLYPH_NONEMPTY(ch->glyph.data)) - bitmap_destroy((BITMAP *)ch->glyph.data); - ch->glyph.data = NULL; - ch->loaded = 0; - } -} - -void font_reset_font_glyphs(DviDevice *dev, DviFont *font, int what) -{ - int i; - DviFontChar *ch; - - if(what & MDVI_FONTSEL_GLYPH) - what |= MDVI_FONTSEL_BITMAP|MDVI_FONTSEL_GREY; - if(font->subfonts) { - DviFontRef *ref; - - for(ref = font->subfonts; ref; ref = ref->next) - font_reset_font_glyphs(dev, ref->ref, what); - } - if(font->in) { - DEBUG((DBG_FILES, "close(%s)\n", font->filename)); - fclose(font->in); - font->in = NULL; - } - if(font->finfo->getglyph == NULL) - return; - DEBUG((DBG_FONTS, "resetting glyphs in font `%s'\n", font->fontname)); - for(ch = font->chars, i = font->loc; i <= font->hic; ch++, i++) { - if(glyph_present(ch)) - font_reset_one_glyph(dev, ch, what); - } - if((what & MDVI_FONTSEL_GLYPH) && font->finfo->reset) - font->finfo->reset(font); -} - -void font_reset_chain_glyphs(DviDevice *dev, DviFontRef *head, int what) -{ - DviFontRef *ref; - - for(ref = head; ref; ref = ref->next) - font_reset_font_glyphs(dev, ref->ref, what); -} - -static int compare_refs(const void *p1, const void *p2) -{ - return ((*(DviFontRef **)p1)->fontid - (*(DviFontRef **)p2)->fontid); -} - -void font_finish_definitions(DviContext *dvi) -{ - int count; - DviFontRef **map, *ref; - - /* first get rid of unused fonts */ - font_free_unused(&dvi->device); - - if(dvi->fonts == NULL) { - warning(_("%s: no fonts defined\n"), dvi->filename); - return; - } - map = xnalloc(DviFontRef *, dvi->nfonts); - for(count = 0, ref = dvi->fonts; ref; ref = ref->next) - map[count++] = ref; - /* sort the array by font id */ - qsort(map, dvi->nfonts, sizeof(DviFontRef *), compare_refs); - dvi->fontmap = map; -} - -DviFontRef *font_find_flat(DviContext *dvi, Int32 id) -{ - DviFontRef *ref; - - for(ref = dvi->fonts; ref; ref = ref->next) - if(ref->fontid == id) - break; - return ref; -} - -DviFontRef *font_find_mapped(DviContext *dvi, Int32 id) -{ - int lo, hi, n; - DviFontRef **map; - - /* do a binary search */ - lo = 0; hi = dvi->nfonts; - map = dvi->fontmap; - while(lo < hi) { - int sign; - - n = (hi + lo) >> 1; - sign = (map[n]->fontid - id); - if(sign == 0) - break; - else if(sign < 0) - lo = n; - else - hi = n; - } - if(lo >= hi) - return NULL; - return map[n]; -} - diff --git a/dvi/mdvi-lib/fontmap.c b/dvi/mdvi-lib/fontmap.c deleted file mode 100644 index cc61064..0000000 --- a/dvi/mdvi-lib/fontmap.c +++ /dev/null @@ -1,1172 +0,0 @@ -/* encoding.c - functions to manipulate encodings and fontmaps */ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include -#include -#include -#include - -#include "mdvi.h" -#include "private.h" - -#include -#include - -typedef struct _DviFontMap DviFontMap; - -struct _DviFontMap { - ListHead entries; - DviHashTable fonts; -}; - -typedef struct _PSFontMap { - struct _PSFontMap *next; - struct _PSFontMap *prev; - char *psname; - char *mapname; - char *fullname; -} PSFontMap; - -/* these variables control PS font maps */ -static char *pslibdir = NULL; /* path where we look for PS font maps */ -static char *psfontdir = NULL; /* PS font search path */ -static int psinitialized = 0; /* did we expand the path already? */ - -static ListHead psfonts = MDVI_EMPTY_LIST_HEAD; -static DviHashTable pstable = MDVI_EMPTY_HASH_TABLE; - -static ListHead fontmaps; -static DviHashTable maptable; -static int fontmaps_loaded = 0; - -#define MAP_HASH_SIZE 57 -#define ENC_HASH_SIZE 31 -#define PSMAP_HASH_SIZE 57 - -/* this hash table should be big enough to - * hold (ideally) one glyph name per bucket */ -#define ENCNAME_HASH_SIZE 131 /* most TeX fonts have 128 glyphs */ - -static ListHead encodings = MDVI_EMPTY_LIST_HEAD; -static DviEncoding *tex_text_encoding = NULL; -static DviEncoding *default_encoding = NULL; - -/* we keep two hash tables for encodings: one for their base files (e.g. - * "8r.enc"), and another one for their names (e.g. "TeXBase1Encoding") */ -static DviHashTable enctable = MDVI_EMPTY_HASH_TABLE; -static DviHashTable enctable_file = MDVI_EMPTY_HASH_TABLE; - -/* the TeX text encoding, from dvips */ -static char *tex_text_vector[256] = { - "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma", "Upsilon", - "Phi", "Psi", "Omega", "arrowup", "arrowdown", "quotesingle", - "exclamdown", "questiondown", "dotlessi", "dotlessj", "grave", - "acute", "caron", "breve", "macron", "ring", "cedilla", - "germandbls", "ae", "oe", "oslash", "AE", "OE", "Oslash", "space", - "exclam", "quotedbl", "numbersign", "dollar", "percent", - "ampersand", "quoteright", "parenleft", "parenright", "asterisk", - "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", - "three", "four", "five", "six", "seven", "eight", "nine", "colon", - "semicolon", "less", "equal", "greater", "question", "at", "A", "B", - "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", - "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", - "bracketleft", "backslash", "bracketright", "circumflex", - "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", - "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", - "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "tilde", - "dieresis", 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, 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, 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, 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 -}; - -static void ps_init_default_paths __PROTO((void)); -static int mdvi_set_default_encoding __PROTO((const char *name)); -static int mdvi_init_fontmaps __PROTO((void)); - -/* - * What we do here is allocate one block large enough to hold the entire - * file (these files are small) minus the leading comments. This is much - * better than allocating up to 256 tiny strings per encoding vector. */ -static int read_encoding(DviEncoding *enc) -{ - FILE *in; - int curr; - char *line; - char *name; - char *next; - struct stat st; - - ASSERT(enc->private == NULL); - - in = fopen(enc->filename, "r"); - if(in == NULL) { - DEBUG((DBG_FMAP, "%s: could not read `%s' (%s)\n", - enc->name, enc->filename, strerror(errno))); - return -1; - } - if(fstat(fileno(in), &st) < 0) { - /* should not happen */ - fclose(in); - return -1; - } - st.st_size -= enc->offset; - - /* this will be one big string */ - enc->private = (char *)malloc(st.st_size + 1); - /* setup the hash table */ - mdvi_hash_create(&enc->nametab, ENCNAME_HASH_SIZE); - /* setup the encoding vector */ - enc->vector = (char **)mdvi_malloc(256 * sizeof(char *)); - - /* jump to the beginning of the interesting part */ - fseek(in, enc->offset, SEEK_SET); - /* and read everything */ - if(fread(enc->private, st.st_size, 1, in) != 1) { - fclose(in); - mdvi_free(enc->private); - enc->private = NULL; - return -1; - } - /* we don't need this anymore */ - fclose(in); - curr = 0; - - next = name = NULL; - DEBUG((DBG_FMAP, "%s: reading encoding vector\n", enc->name)); - for(line = enc->private; *line && curr < 256; line = next) { - SKIPSP(line); - if(*line == ']') { - line++; SKIPSP(line); - if(STRNEQ(line, "def", 3)) - break; - } - name = getword(line, " \t\n", &next); - if(name == NULL) - break; - /* next > line */ - if(*name < ' ') - continue; - if(*name == '%') { - while(*next && *next != '\n') - next++; - if(*next) next++; /* skip \n */ - continue; - } - - /* got a name */ - if(*next) *next++ = 0; - - if(*name == '/') - name++; - enc->vector[curr] = name; - /* add it to the hash table */ - if(!STREQ(name, ".notdef")) { - mdvi_hash_add(&enc->nametab, MDVI_KEY(name), - Int2Ptr(curr + 1), MDVI_HASH_REPLACE); - } - curr++; - } - if(curr == 0) { - mdvi_hash_reset(&enc->nametab, 0); - mdvi_free(enc->private); - mdvi_free(enc); - return -1; - } - while(curr < 256) - enc->vector[curr++] = NULL; - return 0; -} - -static DviEncoding *find_encoding(const char *name) -{ - return (DviEncoding *)(encodings.count ? - mdvi_hash_lookup(&enctable, MDVI_KEY(name)) : NULL); -} - -static void destroy_encoding(DviEncoding *enc) -{ - if(enc == default_encoding) { - default_encoding = tex_text_encoding; - /* now we use reference counts again */ - mdvi_release_encoding(enc, 1); - } - if(enc != tex_text_encoding) { - mdvi_hash_reset(&enc->nametab, 0); - if(enc->private) { - mdvi_free(enc->private); - mdvi_free(enc->vector); - } - if(enc->name) - mdvi_free(enc->name); - if(enc->filename) - mdvi_free(enc->filename); - mdvi_free(enc); - } -} - -/* this is used for the `enctable_file' hash table */ -static void file_hash_free(DviHashKey key, void *data) -{ - mdvi_free(key); -} - -static DviEncoding *register_encoding(const char *basefile, int replace) -{ - DviEncoding *enc; - FILE *in; - char *filename; - char *name; - Dstring input; - char *line; - long offset; - - DEBUG((DBG_FMAP, "register_encoding(%s)\n", basefile)); - - if(encodings.count) { - enc = mdvi_hash_lookup(&enctable_file, MDVI_KEY(basefile)); - if(enc != NULL) { - DEBUG((DBG_FMAP, "%s: already there\n", basefile)); - return enc; /* no error */ - } - } - - /* try our own files first */ - filename = kpse_find_file(basefile, - kpse_program_text_format, 0); - - /* then try the system-wide ones */ - if(filename == NULL) - filename = kpse_find_file(basefile, - kpse_tex_ps_header_format, 0); - if(filename == NULL) - filename = kpse_find_file(basefile, - kpse_dvips_config_format, 0); - - /* finally try the given name */ - if(filename == NULL) - filename = mdvi_strdup(basefile); - - in = fopen(filename, "r"); - if(in == NULL) { - mdvi_free(filename); - return NULL; - } - - /* just lookup the name of the encoding */ - name = NULL; - dstring_init(&input); - while((line = dgets(&input, in)) != NULL) { - if(STRNEQ(line, "Encoding=", 9)) { - name = getword(line + 9, " \t", &line); - if(*line) *line++ = 0; - break; - } else if(*line == '/') { - char *label = getword(line + 1, " \t", &line); - if(*line) { - *line++ = 0; - SKIPSP(line); - if(*line == '[') { - *line = 0; - name = label; - break; - } - } - } - } - offset = ftell(in); - fclose(in); - if(name == NULL || *name == 0) { - DEBUG((DBG_FMAP, - "%s: could not determine name of encoding\n", - basefile)); - mdvi_free(filename); - return NULL; - } - - /* check if the encoding is already there */ - enc = find_encoding(name); - if(enc == tex_text_encoding) { - /* A special case: if the vector we found is the static one, - * allow the user to override it with an external file */ - listh_remove(&encodings, LIST(enc)); - mdvi_hash_remove(&enctable, MDVI_KEY(enc->name)); - if(enc == default_encoding) - default_encoding = NULL; - } else if(enc) { - /* if the encoding is being used, refuse to remove it */ - if(enc->links) { - mdvi_free(filename); - dstring_reset(&input); - return NULL; - } - if(replace) { - mdvi_hash_remove(&enctable, MDVI_KEY(name)); - mdvi_hash_remove(&enctable_file, MDVI_KEY(basefile)); - listh_remove(&encodings, LIST(enc)); - if(enc == default_encoding) { - default_encoding = NULL; - mdvi_release_encoding(enc, 1); - } - DEBUG((DBG_FMAP, "%s: overriding encoding\n", name)); - destroy_encoding(enc); - } else { - mdvi_free(filename); - dstring_reset(&input); - return enc; /* no error */ - } - } - enc = xalloc(DviEncoding); - enc->name = mdvi_strdup(name); - enc->filename = filename; - enc->links = 0; - enc->offset = offset; - enc->private = NULL; - enc->vector = NULL; - mdvi_hash_init(&enc->nametab); - dstring_reset(&input); - if(default_encoding == NULL) - default_encoding = enc; - mdvi_hash_add(&enctable, MDVI_KEY(enc->name), - enc, MDVI_HASH_UNCHECKED); - mdvi_hash_add(&enctable_file, MDVI_KEY(mdvi_strdup(basefile)), - enc, MDVI_HASH_REPLACE); - listh_prepend(&encodings, LIST(enc)); - DEBUG((DBG_FMAP, "%s: encoding `%s' registered\n", - basefile, enc->name)); - return enc; -} - -DviEncoding *mdvi_request_encoding(const char *name) -{ - DviEncoding *enc = find_encoding(name); - - if(enc == NULL) { - DEBUG((DBG_FMAP, "%s: encoding not found, returning default `%s'\n", - name, default_encoding->name)); - return default_encoding; - } - /* we don't keep reference counts for this */ - if(enc == tex_text_encoding) - return enc; - if(!enc->private && read_encoding(enc) < 0) - return NULL; - enc->links++; - - /* if the hash table is empty, rebuild it */ - if(enc->nametab.nkeys == 0) { - int i; - - DEBUG((DBG_FMAP, "%s: rehashing\n", enc->name)); - for(i = 0; i < 256; i++) { - if(enc->vector[i] == NULL) - continue; - mdvi_hash_add(&enc->nametab, - MDVI_KEY(enc->vector[i]), - (DviHashKey)Int2Ptr(i), - MDVI_HASH_REPLACE); - } - } - return enc; -} - -void mdvi_release_encoding(DviEncoding *enc, int should_free) -{ - /* ignore our static encoding */ - if(enc == tex_text_encoding) - return; - if(!enc->links || --enc->links > 0 || !should_free) - return; - DEBUG((DBG_FMAP, "%s: resetting encoding vector\n", enc->name)); - mdvi_hash_reset(&enc->nametab, 1); /* we'll reuse it */ -} - -int mdvi_encode_glyph(DviEncoding *enc, const char *name) -{ - void *data; - - data = mdvi_hash_lookup(&enc->nametab, MDVI_KEY(name)); - if(data == NULL) - return -1; - /* we added +1 to the hashed index just to distinguish - * a failed lookup from a zero index. Adjust it now. */ - return (Ptr2Int(data) - 1); -} - -/**************** - * Fontmaps * - ****************/ - -static void parse_spec(DviFontMapEnt *ent, char *spec) -{ - char *arg, *command; - - /* this is a ridiculously simple parser, and recognizes only - * things of the form . Of these, only - * command=SlantFont, ExtendFont and ReEncodeFont are handled */ - while(*spec) { - arg = getword(spec, " \t", &spec); - if(*spec) *spec++ = 0; - command = getword(spec, " \t", &spec); - if(*spec) *spec++ = 0; - if(!arg || !command) - continue; - if(STREQ(command, "SlantFont")) { - double x = 10000 * strtod(arg, 0); - - /* SFROUND evaluates arguments twice */ - ent->slant = SFROUND(x); - } else if(STREQ(command, "ExtendFont")) { - double x = 10000 * strtod(arg, 0); - - ent->extend = SFROUND(x); - } else if(STREQ(command, "ReEncodeFont")) { - if(ent->encoding) - mdvi_free(ent->encoding); - ent->encoding = mdvi_strdup(arg); - } - } -} - -#if 0 -static void print_ent(DviFontMapEnt *ent) -{ - printf("Entry for `%s':\n", ent->fontname); - printf(" PS name: %s\n", ent->psname ? ent->psname : "(none)"); - printf(" Encoding: %s\n", ent->encoding ? ent->encoding : "(default)"); - printf(" EncFile: %s\n", ent->encfile ? ent->encfile : "(none)"); - printf(" FontFile: %s\n", ent->fontfile ? ent->fontfile : "(same)"); - printf(" Extend: %ld\n", ent->extend); - printf(" Slant: %ld\n", ent->slant); -} -#endif - -DviFontMapEnt *mdvi_load_fontmap(const char *file) -{ - char *ptr; - FILE *in; - int lineno = 1; - Dstring input; - ListHead list; - DviFontMapEnt *ent; - DviEncoding *last_encoding; - char *last_encfile; - - ptr = kpse_find_file(file, kpse_program_text_format, 0); - if(ptr == NULL) - ptr = kpse_find_file(file, kpse_tex_ps_header_format, 0); - if(ptr == NULL) - ptr = kpse_find_file(file, kpse_dvips_config_format, 0); - if(ptr == NULL) - in = fopen(file, "r"); - else { - in = fopen(ptr, "r"); - mdvi_free(ptr); - } - if(in == NULL) - return NULL; - - ent = NULL; - listh_init(&list); - dstring_init(&input); - last_encoding = NULL; - last_encfile = NULL; - - while((ptr = dgets(&input, in)) != NULL) { - char *font_file; - char *tex_name; - char *ps_name; - char *vec_name; - int is_encoding; - DviEncoding *enc; - - lineno++; - SKIPSP(ptr); - - /* we skip what dvips does */ - if(*ptr <= ' ' || *ptr == '*' || *ptr == '#' || - *ptr == ';' || *ptr == '%') - continue; - - font_file = NULL; - tex_name = NULL; - ps_name = NULL; - vec_name = NULL; - is_encoding = 0; - - if(ent == NULL) { - ent = xalloc(DviFontMapEnt); - ent->encoding = NULL; - ent->slant = 0; - ent->extend = 0; - } - while(*ptr) { - char *hdr_name = NULL; - - while(*ptr && *ptr <= ' ') - ptr++; - if(*ptr == 0) - break; - if(*ptr == '"') { - char *str; - - str = getstring(ptr, " \t", &ptr); - if(*ptr) *ptr++ = 0; - parse_spec(ent, str); - continue; - } else if(*ptr == '<') { - ptr++; - if(*ptr == '<') - ptr++; - else if(*ptr == '[') { - is_encoding = 1; - ptr++; - } - SKIPSP(ptr); - hdr_name = ptr; - } else if(!tex_name) - tex_name = ptr; - else if(!ps_name) - ps_name = ptr; - else - hdr_name = ptr; - - /* get next word */ - getword(ptr, " \t", &ptr); - if(*ptr) *ptr++ = 0; - - if(hdr_name) { - const char *ext = file_extension(hdr_name); - - if(is_encoding || (ext && STRCEQ(ext, "enc"))) - vec_name = hdr_name; - else - font_file = hdr_name; - } - } - - if(tex_name == NULL) - continue; - ent->fontname = mdvi_strdup(tex_name); - ent->psname = ps_name ? mdvi_strdup(ps_name) : NULL; - ent->fontfile = font_file ? mdvi_strdup(font_file) : NULL; - ent->encfile = vec_name ? mdvi_strdup(vec_name) : NULL; - ent->fullfile = NULL; - enc = NULL; /* we don't have this yet */ - - /* if we have an encoding file, register it */ - if(ent->encfile) { - /* register_encoding is smart enough not to load the - * same file twice */ - if(!last_encfile || !STREQ(last_encfile, ent->encfile)) { - last_encfile = ent->encfile; - last_encoding = register_encoding(ent->encfile, 1); - } - enc = last_encoding; - } - if(ent->encfile && enc){ - if(ent->encoding && !STREQ(ent->encoding, enc->name)) { - warning( - _("%s: %d: [%s] requested encoding `%s' does not match vector `%s'\n"), - file, lineno); - } else if(!ent->encoding) - ent->encoding = mdvi_strdup(enc->name); - } - - /* add it to the list */ - /*print_ent(ent);*/ - listh_append(&list, LIST(ent)); - ent = NULL; - } - dstring_reset(&input); - fclose(in); - - return (DviFontMapEnt *)list.head; -} - -static void free_ent(DviFontMapEnt *ent) -{ - ASSERT(ent->fontname != NULL); - mdvi_free(ent->fontname); - if(ent->psname) - mdvi_free(ent->psname); - if(ent->fontfile) - mdvi_free(ent->fontfile); - if(ent->encoding) - mdvi_free(ent->encoding); - if(ent->encfile) - mdvi_free(ent->encfile); - if(ent->fullfile) - mdvi_free(ent->fullfile); - mdvi_free(ent); -} - -void mdvi_install_fontmap(DviFontMapEnt *head) -{ - DviFontMapEnt *ent, *next; - - for(ent = head; ent; ent = next) { - /* add all the entries, overriding old ones */ - DviFontMapEnt *old; - - old = (DviFontMapEnt *) - mdvi_hash_remove(&maptable, MDVI_KEY(ent->fontname)); - if(old != NULL) { - DEBUG((DBG_FMAP, "%s: overriding fontmap entry\n", - old->fontname)); - listh_remove(&fontmaps, LIST(old)); - free_ent(old); - } - next = ent->next; - mdvi_hash_add(&maptable, MDVI_KEY(ent->fontname), - ent, MDVI_HASH_UNCHECKED); - listh_append(&fontmaps, LIST(ent)); - } -} - -static void init_static_encoding() -{ - DviEncoding *encoding; - int i; - - DEBUG((DBG_FMAP, "installing static TeX text encoding\n")); - encoding = xalloc(DviEncoding); - encoding->private = ""; - encoding->filename = ""; - encoding->name = "TeXTextEncoding"; - encoding->vector = tex_text_vector; - encoding->links = 1; - encoding->offset = 0; - mdvi_hash_create(&encoding->nametab, ENCNAME_HASH_SIZE); - for(i = 0; i < 256; i++) { - if(encoding->vector[i]) { - mdvi_hash_add(&encoding->nametab, - MDVI_KEY(encoding->vector[i]), - (DviHashKey)Int2Ptr(i), - MDVI_HASH_UNCHECKED); - } - } - ASSERT_VALUE(encodings.count, 0); - mdvi_hash_create(&enctable, ENC_HASH_SIZE); - mdvi_hash_create(&enctable_file, ENC_HASH_SIZE); - enctable_file.hash_free = file_hash_free; - mdvi_hash_add(&enctable, MDVI_KEY(encoding->name), - encoding, MDVI_HASH_UNCHECKED); - listh_prepend(&encodings, LIST(encoding)); - tex_text_encoding = encoding; - default_encoding = tex_text_encoding; -} - -static int mdvi_set_default_encoding(const char *name) -{ - DviEncoding *enc, *old; - - enc = find_encoding(name); - if(enc == NULL) - return -1; - if(enc == default_encoding) - return 0; - /* this will read it from file if necessary, - * but it can fail if the file is corrupted */ - enc = mdvi_request_encoding(name); - if(enc == NULL) - return -1; - old = default_encoding; - default_encoding = enc; - if(old != tex_text_encoding) - mdvi_release_encoding(old, 1); - return 0; -} - -static int mdvi_init_fontmaps(void) -{ - char *file; - char *line; - FILE *in; - Dstring input; - int count = 0; - char *config; - - if(fontmaps_loaded) - return 0; - /* we will only try this once */ - fontmaps_loaded = 1; - - DEBUG((DBG_FMAP, "reading fontmaps\n")); - - /* make sure the static encoding is there */ - init_static_encoding(); - - /* create the fontmap hash table */ - mdvi_hash_create(&maptable, MAP_HASH_SIZE); - - /* get the name of our configuration file */ - config = kpse_cnf_get("mdvi-config"); - if(config == NULL) - config = MDVI_DEFAULT_CONFIG; - /* let's ask kpathsea for the file first */ - file = kpse_find_file(config, kpse_program_text_format, 0); - if(file == NULL) - in = fopen(config, "r"); - else { - in = fopen(file, "r"); - mdvi_free(file); - } - if(in == NULL) - return -1; - dstring_init(&input); - while((line = dgets(&input, in)) != NULL) { - char *arg; - - SKIPSP(line); - if(*line < ' ' || *line == '#' || *line == '%') - continue; - if(STRNEQ(line, "fontmap", 7)) { - DviFontMapEnt *ent; - - arg = getstring(line + 7, " \t", &line); *line = 0; - DEBUG((DBG_FMAP, "%s: loading fontmap\n", arg)); - ent = mdvi_load_fontmap(arg); - if(ent == NULL) - warning(_("%s: could not load fontmap\n"), arg); - else { - DEBUG((DBG_FMAP, - "%s: installing fontmap\n", arg)); - mdvi_install_fontmap(ent); - count++; - } - } else if(STRNEQ(line, "encoding", 8)) { - arg = getstring(line + 8, " \t", &line); *line = 0; - if(arg && *arg) - register_encoding(arg, 1); - } else if(STRNEQ(line, "default-encoding", 16)) { - arg = getstring(line + 16, " \t", &line); *line = 0; - if(mdvi_set_default_encoding(arg) < 0) - warning(_("%s: could not set as default encoding\n"), - arg); - } else if(STRNEQ(line, "psfontpath", 10)) { - arg = getstring(line + 11, " \t", &line); *line = 0; - if(!psinitialized) - ps_init_default_paths(); - if(psfontdir) - mdvi_free(psfontdir); - psfontdir = kpse_path_expand(arg); - } else if(STRNEQ(line, "pslibpath", 9)) { - arg = getstring(line + 10, " \t", &line); *line = 0; - if(!psinitialized) - ps_init_default_paths(); - if(pslibdir) - mdvi_free(pslibdir); - pslibdir = kpse_path_expand(arg); - } else if(STRNEQ(line, "psfontmap", 9)) { - arg = getstring(line + 9, " \t", &line); *line = 0; - if(mdvi_ps_read_fontmap(arg) < 0) - warning("%s: %s: could not read PS fontmap\n", - config, arg); - } - } - fclose(in); - dstring_reset(&input); - fontmaps_loaded = 1; - DEBUG((DBG_FMAP, "%d files installed, %d fontmaps\n", - count, fontmaps.count)); - return count; -} - -int mdvi_query_fontmap(DviFontMapInfo *info, const char *fontname) -{ - DviFontMapEnt *ent; - - if(!fontmaps_loaded && mdvi_init_fontmaps() < 0) - return -1; - ent = (DviFontMapEnt *)mdvi_hash_lookup(&maptable, MDVI_KEY(fontname)); - - if(ent == NULL) - return -1; - info->psname = ent->psname; - info->encoding = ent->encoding; - info->fontfile = ent->fontfile; - info->extend = ent->extend; - info->slant = ent->slant; - info->fullfile = ent->fullfile; - - return 0; -} - -int mdvi_add_fontmap_file(const char *name, const char *fullpath) -{ - DviFontMapEnt *ent; - - if(!fontmaps_loaded && mdvi_init_fontmaps() < 0) - return -1; - ent = (DviFontMapEnt *)mdvi_hash_lookup(&maptable, MDVI_KEY(name)); - if(ent == NULL) - return -1; - if(ent->fullfile) - mdvi_free(ent->fullfile); - ent->fullfile = mdvi_strdup(fullpath); - return 0; -} - - -void mdvi_flush_encodings(void) -{ - DviEncoding *enc; - - if(enctable.nbucks == 0) - return; - - DEBUG((DBG_FMAP, "flushing %d encodings\n", encodings.count)); - /* asked to remove all encodings */ - for(; (enc = (DviEncoding *)encodings.head); ) { - encodings.head = LIST(enc->next); - if((enc != tex_text_encoding && enc->links) || enc->links > 1) { - warning(_("encoding vector `%s' is in use\n"), - enc->name); - } - destroy_encoding(enc); - } - /* destroy the static encoding */ - if(tex_text_encoding->nametab.buckets) - mdvi_hash_reset(&tex_text_encoding->nametab, 0); - mdvi_hash_reset(&enctable, 0); - mdvi_hash_reset(&enctable_file, 0); -} - -void mdvi_flush_fontmaps(void) -{ - DviFontMapEnt *ent; - - if(!fontmaps_loaded) - return; - - DEBUG((DBG_FMAP, "flushing %d fontmaps\n", fontmaps.count)); - for(; (ent = (DviFontMapEnt *)fontmaps.head); ) { - fontmaps.head = LIST(ent->next); - free_ent(ent); - } - mdvi_hash_reset(&maptable, 0); - fontmaps_loaded = 0; -} - -/* reading of PS fontmaps */ - -void ps_init_default_paths(void) -{ - char *kppath; - char *kfpath; - - ASSERT(psinitialized == 0); - - kppath = getenv("GS_LIB"); - kfpath = getenv("GS_FONTPATH"); - - if(kppath != NULL) - pslibdir = kpse_path_expand(kppath); - if(kfpath != NULL) - psfontdir = kpse_path_expand(kfpath); - - listh_init(&psfonts); - mdvi_hash_create(&pstable, PSMAP_HASH_SIZE); - psinitialized = 1; -} - -int mdvi_ps_read_fontmap(const char *name) -{ - char *fullname; - FILE *in; - Dstring dstr; - char *line; - int count = 0; - - if(!psinitialized) - ps_init_default_paths(); - if(pslibdir) - fullname = kpse_path_search(pslibdir, name, 1); - else - fullname = (char *)name; - in = fopen(fullname, "r"); - if(in == NULL) { - if(fullname != name) - mdvi_free(fullname); - return -1; - } - dstring_init(&dstr); - - while((line = dgets(&dstr, in)) != NULL) { - char *name; - char *mapname; - const char *ext; - PSFontMap *ps; - - SKIPSP(line); - /* we're looking for lines of the form - * /FONT-NAME (fontfile) - * /FONT-NAME /FONT-ALIAS - */ - if(*line != '/') - continue; - name = getword(line + 1, " \t", &line); - if(*line) *line++ = 0; - mapname = getword(line, " \t", &line); - if(*line) *line++ = 0; - - if(!name || !mapname || !*name) - continue; - if(*mapname == '(') { - char *end; - - mapname++; - for(end = mapname; *end && *end != ')'; end++); - *end = 0; - } - if(!*mapname) - continue; - /* dont add `.gsf' fonts, which require a full blown - * PostScript interpreter */ - ext = file_extension(mapname); - if(ext && STREQ(ext, "gsf")) { - DEBUG((DBG_FMAP, "(ps) %s: font `%s' ignored\n", - name, mapname)); - continue; - } - ps = (PSFontMap *)mdvi_hash_lookup(&pstable, MDVI_KEY(name)); - if(ps != NULL) { - if(STREQ(ps->mapname, mapname)) - continue; - DEBUG((DBG_FMAP, - "(ps) replacing font `%s' (%s) by `%s'\n", - name, ps->mapname, mapname)); - mdvi_free(ps->mapname); - ps->mapname = mdvi_strdup(mapname); - if(ps->fullname) { - mdvi_free(ps->fullname); - ps->fullname = NULL; - } - } else { - DEBUG((DBG_FMAP, "(ps) adding font `%s' as `%s'\n", - name, mapname)); - ps = xalloc(PSFontMap); - ps->psname = mdvi_strdup(name); - ps->mapname = mdvi_strdup(mapname); - ps->fullname = NULL; - listh_append(&psfonts, LIST(ps)); - mdvi_hash_add(&pstable, MDVI_KEY(ps->psname), - ps, MDVI_HASH_UNCHECKED); - count++; - } - } - fclose(in); - dstring_reset(&dstr); - - DEBUG((DBG_FMAP, "(ps) %s: %d PostScript fonts registered\n", - fullname, count)); - return 0; -} - -void mdvi_ps_flush_fonts(void) -{ - PSFontMap *map; - - if(!psinitialized) - return; - DEBUG((DBG_FMAP, "(ps) flushing PS font map (%d) entries\n", - psfonts.count)); - mdvi_hash_reset(&pstable, 0); - for(; (map = (PSFontMap *)psfonts.head); ) { - psfonts.head = LIST(map->next); - mdvi_free(map->psname); - mdvi_free(map->mapname); - if(map->fullname) - mdvi_free(map->fullname); - mdvi_free(map); - } - listh_init(&psfonts); - if(pslibdir) { - mdvi_free(pslibdir); - pslibdir = NULL; - } - if(psfontdir) { - mdvi_free(psfontdir); - psfontdir = NULL; - } - psinitialized = 0; -} - -char *mdvi_ps_find_font(const char *psname) -{ - PSFontMap *map, *smap; - char *filename; - int recursion_limit = 32; - - DEBUG((DBG_FMAP, "(ps) resolving PS font `%s'\n", psname)); - if(!psinitialized) - return NULL; - map = (PSFontMap *)mdvi_hash_lookup(&pstable, MDVI_KEY(psname)); - if(map == NULL) - return NULL; - if(map->fullname) - return mdvi_strdup(map->fullname); - - /* is it an alias? */ - smap = map; - while(recursion_limit-- > 0 && smap && *smap->mapname == '/') - smap = (PSFontMap *)mdvi_hash_lookup(&pstable, - MDVI_KEY(smap->mapname + 1)); - if(smap == NULL) { - if(recursion_limit == 0) - DEBUG((DBG_FMAP, - "(ps) %s: possible loop in PS font map\n", - psname)); - return NULL; - } - - if(psfontdir) - filename = kpse_path_search(psfontdir, smap->mapname, 1); - else if(file_exists(map->mapname)) - filename = mdvi_strdup(map->mapname); - else - filename = NULL; - if(filename) - map->fullname = mdvi_strdup(filename); - - return filename; -} - -/* - * To get metric info for a font, we proceed as follows: - * - We try to find NAME.. - * - We query the fontmap for NAME. - * - We get back a PSNAME, and use to find the file in the PS font map. - * - We get the PSFONT file name, replace its extension by "afm" and - * lookup the file in GS's font search path. - * - We finally read the data, transform it as specified in our font map, - * and return it to the caller. The new data is left in the font metrics - * cache, so the next time it will be found at the first step (when we look - * up NAME.afm). - * - * The name `_ps_' in this function is not meant to imply that it can be - * used for Type1 fonts only. It should be usable for TrueType fonts as well. - * - * The returned metric info is subjected to the same caching mechanism as - * all the other metric data, as returned by get_font_metrics(). One should - * not modify the returned data at all, and it should be disposed with - * free_font_metrics(). - */ -TFMInfo *mdvi_ps_get_metrics(const char *fontname) -{ - TFMInfo *info; - DviFontMapInfo map; - char buffer[64]; /* to avoid mallocs */ - char *psfont; - char *basefile; - char *afmfile; - char *ext; - int baselen; - int nc; - TFMChar *ch; - double efactor; - double sfactor; - - DEBUG((DBG_FMAP, "(ps) %s: looking for metric data\n", fontname)); - info = get_font_metrics(fontname, DviFontAny, NULL); - if(info != NULL) - return info; - - /* query the fontmap */ - if(mdvi_query_fontmap(&map, fontname) < 0 || !map.psname) - return NULL; - - /* get the PS font */ - psfont = mdvi_ps_find_font(map.psname); - if(psfont == NULL) - return NULL; - DEBUG((DBG_FMAP, "(ps) %s: found as PS font `%s'\n", - fontname, psfont)); - /* replace its extension */ - basefile = strrchr(psfont, '/'); - if(basefile == NULL) - basefile = psfont; - baselen = strlen(basefile); - ext = strrchr(basefile, '.'); - if(ext != NULL) - *ext = 0; - if(baselen + 4 < 64) - afmfile = &buffer[0]; - else - afmfile = mdvi_malloc(baselen + 5); - strcpy(afmfile, basefile); - strcpy(afmfile + baselen, ".afm"); - /* we don't need this anymore */ - mdvi_free(psfont); - DEBUG((DBG_FMAP, "(ps) %s: looking for `%s'\n", - fontname, afmfile)); - /* lookup the file */ - psfont = kpse_path_search(psfontdir, afmfile, 1); - /* don't need this anymore */ - if(afmfile != &buffer[0]) - mdvi_free(afmfile); - if(psfont != NULL) { - info = get_font_metrics(fontname, DviFontAFM, psfont); - mdvi_free(psfont); - } else - info = NULL; - if(info == NULL || (!map.extend && !map.slant)) - return info; - - /* - * transform the data as prescribed -- keep in mind that `info' - * points to CACHED data, so we're modifying the metric cache - * in place. - */ - -#define DROUND(x) ((x) >= 0 ? floor((x) + 0.5) : ceil((x) - 0.5)) -#define TRANSFORM(x,y) DROUND(efactor * (x) + sfactor * (y)) - - efactor = (double)map.extend / 10000.0; - sfactor = (double)map.slant / 10000.0; - DEBUG((DBG_FMAP, "(ps) %s: applying extend=%f, slant=%f\n", - efactor, sfactor)); - - nc = info->hic - info->loc + 1; - for(ch = info->chars; ch < info->chars + nc; ch++) { - /* the AFM bounding box is: - * wx = ch->advance - * llx = ch->left - * lly = -ch->depth - * urx = ch->right - * ury = ch->height - * what we do here is transform wx, llx, and urx by - * newX = efactor * oldX + sfactor * oldY - * where for `wx' oldY = 0. Also, these numbers are all in - * TFM units (i.e. TFM's fix-words, which is just the actual - * number times 2^20, no need to do anything to it). - */ - if(ch->present) { - ch->advance = TRANSFORM(ch->advance, 0); - ch->left = TRANSFORM(ch->left, -ch->depth); - ch->right = TRANSFORM(ch->right, ch->height); - } - } - - return info; -} diff --git a/dvi/mdvi-lib/fontmap.h b/dvi/mdvi-lib/fontmap.h deleted file mode 100644 index 0a901ec..0000000 --- a/dvi/mdvi-lib/fontmap.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ -#ifndef _MDVI_FONTMAP_H -#define _MDVI_FONTMAP_H 1 - -typedef struct _DviFontMapEnt DviFontMapEnt; -typedef struct _DviEncoding DviEncoding; - -typedef struct { - const char *psname; - const char *encoding; - const char *fontfile; - const char *fullfile; - const char *fmfile; - int fmtype; - long extend; - long slant; -} DviFontMapInfo; - -struct _DviEncoding { - DviEncoding *next; - DviEncoding *prev; - char *private; - char *filename; - char *name; - char **vector; /* table with exactly 256 strings */ - int links; - long offset; - DviHashTable nametab; -}; - -struct _DviFontMapEnt { - DviFontMapEnt *next; - DviFontMapEnt *prev; - char *private; - char *fontname; - char *psname; - char *encoding; - char *encfile; - char *fontfile; - char *fullfile; - long extend; - long slant; -}; - -#define MDVI_FMAP_SLANT(x) ((double)(x)->slant / 10000.0) -#define MDVI_FMAP_EXTEND(x) ((double)(x)->extend / 10000.0) - -extern DviEncoding *mdvi_request_encoding __PROTO((const char *)); -extern void mdvi_release_encoding __PROTO((DviEncoding *, int)); -extern int mdvi_encode_glyph __PROTO((DviEncoding *, const char *)); -extern DviFontMapEnt *mdvi_load_fontmap __PROTO((const char *)); -extern void mdvi_install_fontmap __PROTO((DviFontMapEnt *)); -extern int mdvi_load_fontmaps __PROTO((void)); -extern int mdvi_query_fontmap __PROTO((DviFontMapInfo *, const char *)); -extern void mdvi_flush_encodings __PROTO((void)); -extern void mdvi_flush_fontmaps __PROTO((void)); - -extern int mdvi_add_fontmap_file __PROTO((const char *, const char *)); - -/* PS font maps */ -extern int mdvi_ps_read_fontmap __PROTO((const char *)); -extern char *mdvi_ps_find_font __PROTO((const char *)); -extern TFMInfo *mdvi_ps_get_metrics __PROTO((const char *)); -extern void mdvi_ps_flush_fonts __PROTO((void)); - -#endif /* _MDVI_FONTMAP_H */ diff --git a/dvi/mdvi-lib/fontsrch.c b/dvi/mdvi-lib/fontsrch.c deleted file mode 100644 index 415ed91..0000000 --- a/dvi/mdvi-lib/fontsrch.c +++ /dev/null @@ -1,370 +0,0 @@ -/* fontsearch.c -- implements the font lookup mechanism in MDVI */ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -/* - * How this works: - * Fonts are divided into MAX_CLASS priority classes. The first - * MAX_CLASS-1 ones correspond to `real' fonts (pk, gf, vf, type1, truetype, - * etc). The last one corresponds to `metric' fonts that are used as a last - * resort (tfm, afm, ofm, ...). When a font is looked up, it is tried in a - * `high' priority class (0 being the highest priority). The priority is - * lowered until it reaches MAX_CLASS-1. Then the whole thing is repeated - * for the fallback font. When the search reaches MAX_CLASS-1, we lookup the - * original font, and then the fallback font. The search can be done - * incrementally, with several calls to mdvi_lookup_font(). If this function - * is called again to continue a search, the function assumes the previous - * font it returned was not valid, and it goes on to the next step. - * - * Reason for this: - * Some font types are quite expensive to load (e.g. Type1), so loading - * them is deferred until the last possible moment. This means that a font that - * was supposed to exist may have to be discarded. Until now, MDVI had no ability to - * "resume" a search, so in this case it would have produced an error, regardless - * of whether the offending font existed in other formats. - * Also, given the large number of font types supported by MDVI, some mechanism - * was necessary to bring some order into the chaos. - * - * This mechanism fixes these two problems. For the first one, a search can - * be "resumed" and all the font formats tried for the missing font, and - * again for the fallback font (see above). As for the second, the - * hierarchical division in classes gives a lot of flexibility in how the - * fonts are configured. - */ - -#include "mdvi.h" - -#define HAVE_PROTOTYPES 1 -#include -#include - -struct _DviFontClass { - DviFontClass *next; - DviFontClass *prev; - DviFontInfo info; - int links; - int id; -}; - -char *_mdvi_fallback_font = MDVI_FALLBACK_FONT; - -/* this leaves classes 0 and 1 for `real' fonts */ -#define MAX_CLASS 3 -static ListHead font_classes[MAX_CLASS]; -static int initialized = 0; - -static void init_font_classes(void) -{ - int i; - - for(i = 0; i < MAX_CLASS; i++) - listh_init(&font_classes[i]); - initialized = 1; -} - -int mdvi_get_font_classes(void) -{ - return (MAX_CLASS - 2); -} - -char **mdvi_list_font_class(int klass) -{ - char **list; - int i, n; - DviFontClass *fc; - - if(klass == -1) - klass = MAX_CLASS-1; - if(klass < 0 || klass >= MAX_CLASS) - return NULL; - n = font_classes[klass].count; - list = xnalloc(char *, n + 1); - fc = (DviFontClass *)font_classes[klass].head; - for(i = 0; i < n; fc = fc->next, i++) { - list[i] = mdvi_strdup(fc->info.name); - } - list[i] = NULL; - return list; -} - -int mdvi_register_font_type(DviFontInfo *info, int klass) -{ - DviFontClass *fc; - - if(klass == -1) - klass = MAX_CLASS-1; - if(klass < 0 || klass >= MAX_CLASS) - return -1; - if(!initialized) - init_font_classes(); - fc = xalloc(struct _DviFontClass); - fc->links = 0; - fc->id = klass; - fc->info.name = mdvi_strdup(info->name); - fc->info.scalable = info->scalable; - fc->info.load = info->load; - fc->info.getglyph = info->getglyph; - fc->info.shrink0 = info->shrink0; - fc->info.shrink1 = info->shrink1; - fc->info.freedata = info->freedata; - fc->info.reset = info->reset; - fc->info.lookup = info->lookup; - fc->info.kpse_type = info->kpse_type; - listh_append(&font_classes[klass], LIST(fc)); - return 0; -} - -int mdvi_unregister_font_type(const char *name, int klass) -{ - DviFontClass *fc; - int k; - - if(klass == -1) - klass = MAX_CLASS - 1; - - if(klass >= 0 && klass < MAX_CLASS) { - k = klass; - LIST_FOREACH(fc, DviFontClass, &font_classes[k]) { - if(STREQ(fc->info.name, name)) - break; - } - } else if(klass < 0) { - for(k = 0; k < MAX_CLASS; k++) { - LIST_FOREACH(fc, DviFontClass, &font_classes[k]) { - if(STREQ(fc->info.name, name)) - break; - } - if(fc) break; - } - } else - return -1; - - if(fc == NULL || fc->links) - return -1; - /* remove it */ - listh_remove(&font_classes[k], LIST(fc)); - - /* and destroy it */ - mdvi_free(fc->info.name); - mdvi_free(fc); - return 0; -} - -static char *lookup_font(DviFontClass *ptr, const char *name, Ushort *h, Ushort *v) -{ - char *filename; - - /* - * If the font type registered a function to do the lookup, use that. - * Otherwise we use kpathsea. - */ - if(ptr->info.lookup) - filename = ptr->info.lookup(name, h, v); - else if(ptr->info.kpse_type <= kpse_any_glyph_format) { - kpse_glyph_file_type type; - - filename = kpse_find_glyph(name, Max(*h, *v), - ptr->info.kpse_type, &type); - /* if kpathsea returned a fallback font, reject it */ - if(filename && type.source == kpse_glyph_source_fallback) { - mdvi_free(filename); - filename = NULL; - } else if(filename) - *h = *v = type.dpi; - } else - filename = kpse_find_file(name, ptr->info.kpse_type, 1); - return filename; -} - -/* - * Class MAX_CLASS-1 is special: it consists of `metric' fonts that should - * be tried as a last resort - */ -char *mdvi_lookup_font(DviFontSearch *search) -{ - int kid; - int k; - DviFontClass *ptr; - DviFontClass *last; - char *filename = NULL; - const char *name; - Ushort hdpi, vdpi; - - if(search->id < 0) - return NULL; - - if(search->curr == NULL) { - /* this is the initial search */ - name = search->wanted_name; - hdpi = search->hdpi; - vdpi = search->vdpi; - kid = 0; - last = NULL; - } else { - name = search->actual_name; - hdpi = search->actual_hdpi; - vdpi = search->actual_vdpi; - kid = search->id; - last = search->curr; - } - - ptr = NULL; -again: - /* try all classes except MAX_CLASS-1 */ - for(k = kid; !filename && k < MAX_CLASS-1; k++) { - if(last == NULL) - ptr = (DviFontClass *)font_classes[k].head; - else - ptr = last->next; - while(ptr) { - DEBUG((DBG_FONTS, "%d: trying `%s' at (%d,%d)dpi as `%s'\n", - k, name, hdpi, vdpi, ptr->info.name)); - /* lookup the font in this class */ - filename = lookup_font(ptr, name, &hdpi, &vdpi); - if(filename) - break; - ptr = ptr->next; - } - last = NULL; - } - if(filename != NULL) { - search->id = k-1; - search->curr = ptr; - search->actual_name = name; - search->actual_hdpi = hdpi; - search->actual_vdpi = vdpi; - search->info = &ptr->info; - ptr->links++; - return filename; - } - - if(kid < MAX_CLASS - 1 && !STREQ(name, _mdvi_fallback_font)) { - warning("font `%s' at %dx%d not found, trying `%s' instead\n", - name, hdpi, vdpi, _mdvi_fallback_font); - name = _mdvi_fallback_font; - kid = 0; - goto again; - } - - /* we tried the fallback font, and all the `real' classes. Let's - * try the `metric' class now */ - name = search->wanted_name; - hdpi = search->hdpi; - vdpi = search->vdpi; - if(kid == MAX_CLASS-1) { - /* we were looking into this class from the beginning */ - if(last == NULL) { - /* no more fonts to try */ - return NULL; - } - ptr = last->next; - } else { - warning("font `%s' not found, trying metric files instead\n", - name); - ptr = (DviFontClass *)font_classes[MAX_CLASS-1].head; - } - -metrics: - while(ptr) { - DEBUG((DBG_FONTS, "metric: trying `%s' at (%d,%d)dpi as `%s'\n", - name, hdpi, vdpi, ptr->info.name)); - filename = lookup_font(ptr, name, &hdpi, &vdpi); - if(filename) - break; - ptr = ptr->next; - } - if(filename != NULL) { - if(STREQ(name, _mdvi_fallback_font)) - search->id = MAX_CLASS; - else - search->id = MAX_CLASS - 1; - search->curr = ptr; - search->actual_name = name; - search->actual_hdpi = hdpi; - search->actual_vdpi = vdpi; - search->info = &ptr->info; - ptr->links++; - return filename; - } - if(!STREQ(name, _mdvi_fallback_font)) { - warning("metric file for `%s' not found, trying `%s' instead\n", - name, _mdvi_fallback_font); - name = _mdvi_fallback_font; - ptr = (DviFontClass *)font_classes[MAX_CLASS-1].head; - goto metrics; - } - - search->id = -1; - search->actual_name = NULL; - - /* tough luck, nothing found */ - return NULL; -} - -/* called by `font_reference' to do the initial lookup */ -DviFont *mdvi_add_font(const char *name, Int32 sum, - int hdpi, int vdpi, Int32 scale) -{ - DviFont *font; - - font = xalloc(DviFont); - font->fontname = mdvi_strdup(name); - SEARCH_INIT(font->search, font->fontname, hdpi, vdpi); - font->filename = mdvi_lookup_font(&font->search); - if(font->filename == NULL) { - /* this answer is final */ - mdvi_free(font->fontname); - mdvi_free(font); - return NULL; - } - font->hdpi = font->search.actual_hdpi; - font->vdpi = font->search.actual_vdpi; - font->scale = scale; - font->design = 0; - font->checksum = sum; - font->type = 0; - font->links = 0; - font->loc = 0; - font->hic = 0; - font->in = NULL; - font->chars = NULL; - font->subfonts = NULL; - - return font; -} - -int mdvi_font_retry(DviParams *params, DviFont *font) -{ - /* try the search again */ - char *filename; - - ASSERT(font->search.curr != NULL); - /* we won't be using this class anymore */ - font->search.curr->links--; - - filename = mdvi_lookup_font(&font->search); - if(filename == NULL) - return -1; - mdvi_free(font->filename); - font->filename = filename; - /* copy the new information */ - font->hdpi = font->search.actual_hdpi; - font->vdpi = font->search.actual_vdpi; - - return 0; -} diff --git a/dvi/mdvi-lib/gf.c b/dvi/mdvi-lib/gf.c deleted file mode 100644 index 2c147ec..0000000 --- a/dvi/mdvi-lib/gf.c +++ /dev/null @@ -1,394 +0,0 @@ -/* gf.c - GF font support */ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -/* functions to read GF fonts */ - -#include -#include "common.h" -#include "mdvi.h" -#include "private.h" - -/* opcodes */ - -#define GF_PAINT0 0 -#define GF_PAINT1 64 -#define GF_PAINT2 65 -#define GF_PAINT3 66 -#define GF_BOC 67 -#define GF_BOC1 68 -#define GF_EOC 69 -#define GF_SKIP0 70 -#define GF_SKIP1 71 -#define GF_SKIP2 72 -#define GF_SKIP3 73 -#define GF_NEW_ROW_0 74 -#define GF_NEW_ROW_1 75 -#define GF_NEW_ROW_MAX 238 -#define GF_XXX1 239 -#define GF_XXX2 240 -#define GF_XXX3 241 -#define GF_XXX4 242 -#define GF_YYY 243 -#define GF_NOOP 244 -#define GF_LOC 245 -#define GF_LOC0 246 -#define GF_PRE 247 -#define GF_POST 248 -#define GF_POST_POST 249 - -#define GF_ID 131 -#define GF_TRAILER 223 - -#define BLACK 1 -#define WHITE 0 - -static int gf_load_font __PROTO((DviParams *, DviFont *)); -static int gf_font_get_glyph __PROTO((DviParams *, DviFont *, int)); - -/* only symbol exported by this file */ -DviFontInfo gf_font_info = { - "GF", - 0, /* scaling not supported natively */ - gf_load_font, - gf_font_get_glyph, - mdvi_shrink_glyph, - mdvi_shrink_glyph_grey, - NULL, /* free */ - NULL, /* reset */ - NULL, /* lookup */ - kpse_gf_format, - NULL -}; - -static int gf_read_bitmap(FILE *p, DviFontChar *ch) -{ - int op; - int min_n, max_n; - int min_m, max_m; - int paint_switch; - int x, y; - int bpl; - Int32 par; - BmUnit *line; - BITMAP *map; - - fseek(p, (long)ch->offset, SEEK_SET); - op = fuget1(p); - if(op == GF_BOC) { - /* skip character code */ - fuget4(p); - /* skip pointer */ - fuget4(p); - min_m = fsget4(p); - max_m = fsget4(p); - min_n = fsget4(p); - max_n = fsget4(p); - } else if(op == GF_BOC1) { - /* skip character code */ - fuget1(p); - min_m = fuget1(p); /* this is max_m - min_m */ - max_m = fuget1(p); - min_n = fuget1(p); /* this is max_n - min_n */ - max_n = fuget1(p); - min_m = max_m - min_m; - min_n = max_n - min_n; - } else { - error(_("GF: invalid opcode %d in character %d\n"), - op, ch->code); - return -1; - } - - ch->x = -min_m; - ch->y = max_n; - ch->width = max_m - min_m + 1; - ch->height = max_n - min_n + 1; - map = bitmap_alloc(ch->width, ch->height); - - ch->glyph.data = map; - ch->glyph.x = ch->x; - ch->glyph.y = ch->y; - ch->glyph.w = ch->width; - ch->glyph.h = ch->height; - -#define COLOR(x) ((x) ? "BLACK" : "WHITE") - - paint_switch = WHITE; - x = y = 0; - line = map->data; - bpl = map->stride; - DEBUG((DBG_BITMAPS, "(gf) reading character %d\n", ch->code)); - while((op = fuget1(p)) != GF_EOC) { - Int32 n; - - if(feof(p)) - break; - if(op == GF_PAINT0) { - DEBUG((DBG_BITMAPS, "(gf) Paint0 %s -> %s\n", - COLOR(paint_switch), COLOR(!paint_switch))); - paint_switch = !paint_switch; - } else if(op <= GF_PAINT3) { - if(op < GF_PAINT1) - par = op; - else - par = fugetn(p, op - GF_PAINT1 + 1); - if(y >= ch->height || x + par >= ch->width) - goto toobig; - /* paint everything between columns x and x + par - 1 */ - DEBUG((DBG_BITMAPS, "(gf) Paint %d %s from (%d,%d)\n", - par, COLOR(paint_switch), x, y)); - if(paint_switch == BLACK) - bitmap_paint_bits(line + (x / BITMAP_BITS), - x % BITMAP_BITS, par); - paint_switch = !paint_switch; - x += par; - } else if(op >= GF_NEW_ROW_0 && op <= GF_NEW_ROW_MAX) { - y++; - line = bm_offset(line, bpl); - x = op - GF_NEW_ROW_0; - paint_switch = BLACK; - DEBUG((DBG_BITMAPS, "(gf) new_row_%d\n", x)); - } else switch(op) { - case GF_SKIP0: - y++; - line = bm_offset(line, bpl); - x = 0; - paint_switch = WHITE; - DEBUG((DBG_BITMAPS, "(gf) skip_0\n")); - break; - case GF_SKIP1: - case GF_SKIP2: - case GF_SKIP3: - par = fugetn(p, op - GF_SKIP1 + 1); - y += par + 1; - line = bm_offset(line, (par + 1) * bpl); - x = 0; - paint_switch = WHITE; - DEBUG((DBG_BITMAPS, "(gf) skip_%d\n", op - GF_SKIP1)); - break; - case GF_XXX1: - case GF_XXX2: - case GF_XXX3: - case GF_XXX4: { -#ifndef NODEBUG - char *s; - - s = read_string(p, op - GF_XXX1 + 1, NULL, 0); - DEBUG((DBG_SPECIAL, "(gf) Character %d: Special \"%s\"\n", - ch->code, s)); - mdvi_free(s); -#else - n = fugetn(p, op - GF_XXX1 + 1); - fseek(p, (long)n, SEEK_CUR); -#endif - break; - } - case GF_YYY: - n = fuget4(p); - DEBUG((DBG_SPECIAL, "(gf) Character %d: MF special %u\n", - ch->code, n)); - break; - case GF_NOOP: - DEBUG((DBG_BITMAPS, "(gf) no_op\n")); - break; - default: - error(_("(gf) Character %d: invalid opcode %d\n"), - ch->code, op); - goto error; - } - /* chech that we're still inside the bitmap */ - if(x > ch->width || y > ch->height) - goto toobig; - DEBUG((DBG_BITMAPS, "(gf) curr_loc @ (%d,%d)\n", x, y)); - } - - if(op != GF_EOC) - goto error; - DEBUG((DBG_BITMAPS, "(gf) end of character %d\n", ch->code)); - return 0; - -toobig: - error(_("(gf) character %d has an incorrect bounding box\n"), - ch->code); -error: - bitmap_destroy(map); - ch->glyph.data = NULL; - return -1; -} - -static int gf_load_font(DviParams *unused, DviFont *font) -{ - int i; - int n; - int loc; - int hic; - FILE *p; - Int32 word; - int op; - long alpha, beta, z; -#ifndef NODEBUG - char s[256]; -#endif - - p = font->in; - - /* check preamble */ - loc = fuget1(p); hic = fuget1(p); - if(loc != GF_PRE || hic != GF_ID) - goto badgf; - loc = fuget1(p); -#ifndef NODEBUG - for(i = 0; i < loc; i++) - s[i] = fuget1(p); - s[i] = 0; - DEBUG((DBG_FONTS, "(gf) %s: %s\n", font->fontname, s)); -#else - fseek(p, (long)loc, SEEK_CUR); -#endif - /* now read character locators in postamble */ - if(fseek(p, (long)-1, SEEK_END) == -1) - return -1; - - n = 0; - while((op = fuget1(p)) == GF_TRAILER) { - if(fseek(p, (long)-2, SEEK_CUR) < 0) - break; - n++; - } - if(op != GF_ID || n < 4) - goto badgf; - /* get the pointer to the postamble */ - fseek(p, (long)-5, SEEK_CUR); - op = fuget4(p); - /* jump to it */ - fseek(p, (long)op, SEEK_SET); - if(fuget1(p) != GF_POST) - goto badgf; - /* skip pointer to last EOC */ - fuget4(p); - /* get the design size */ - font->design = fuget4(p); - /* the checksum */ - word = fuget4(p); - if(word && font->checksum && font->checksum != word) { - warning(_("%s: bad checksum (expected %u, found %u)\n"), - font->fontname, font->checksum, word); - } else if(!font->checksum) - font->checksum = word; - /* skip pixels per point ratio */ - fuget4(p); - fuget4(p); - font->chars = xnalloc(DviFontChar, 256); - for(loc = 0; loc < 256; loc++) - font->chars[loc].offset = 0; - /* skip glyph "bounding box" */ - fseek(p, (long)16, SEEK_CUR); - loc = 256; - hic = -1; - TFMPREPARE(font->scale, z, alpha, beta); - while((op = fuget1(p)) != GF_POST_POST) { - DviFontChar *ch; - int cc; - - /* get the character code */ - cc = fuget1(p); - if(cc < loc) - loc = cc; - if(cc > hic) - hic = cc; - ch = &font->chars[cc]; - switch(op) { - case GF_LOC: - fsget4(p); /* skip dx */ - fsget4(p); /* skip dy */ - break; - case GF_LOC0: - fuget1(p); /* skip dx */ - /* dy assumed 0 */ - break; - default: - error(_("%s: junk in postamble\n"), font->fontname); - goto error; - } - ch->code = cc; - ch->tfmwidth = fuget4(p); - ch->tfmwidth = TFMSCALE(ch->tfmwidth, z, alpha, beta); - ch->offset = fuget4(p); - if(ch->offset == -1) - ch->offset = 0; - /* initialize the rest of the glyph information */ - ch->x = 0; - ch->y = 0; - ch->width = 0; - ch->height = 0; - ch->glyph.data = NULL; - ch->shrunk.data = NULL; - ch->grey.data = NULL; - ch->flags = 0; - ch->loaded = 0; - } - - if(op != GF_POST_POST) - goto badgf; - - if(loc > 0 || hic < 255) { - /* shrink to optimal size */ - memmove(font->chars, font->chars + loc, - (hic - loc + 1) * sizeof(DviFontChar)); - font->chars = xresize(font->chars, - DviFontChar, hic - loc + 1); - } - font->loc = loc; - font->hic = hic; - - return 0; - -badgf: - error(_("%s: File corrupted, or not a GF file\n"), font->fontname); -error: - if(font->chars) { - mdvi_free(font->chars); - font->chars = NULL; - } - font->loc = font->hic = 0; - return -1; -} - -static int gf_font_get_glyph(DviParams *params, DviFont *font, int code) -{ - DviFontChar *ch; - - if(code < font->loc || code > font->hic || !font->chars) - return -1; - ch = &font->chars[code - font->loc]; - - if(!ch->loaded) { - if(ch->offset == 0) - return -1; - DEBUG((DBG_GLYPHS, "(gf) %s: loading GF glyph for character %d\n", - font->fontname, code)); - if(font->in == NULL && font_reopen(font) < 0) - return -1; - if(fseek(font->in, ch->offset, SEEK_SET) == -1) - return -1; - if(gf_read_bitmap(font->in, ch) < 0) - return -1; - ch->loaded = 1; - } - return 0; -} diff --git a/dvi/mdvi-lib/hash.c b/dvi/mdvi-lib/hash.c deleted file mode 100644 index d030650..0000000 --- a/dvi/mdvi-lib/hash.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include "mdvi.h" - -/* simple hash tables for MDVI */ - - -struct _DviHashBucket { - DviHashBucket *next; - DviHashKey key; - Ulong hvalue; - void *data; -}; - -static Ulong hash_string(DviHashKey key) -{ - Uchar *p; - Ulong h, g; - - for(h = 0, p = (Uchar *)key; *p; p++) { - h = (h << 4UL) + *p; - if((g = h & 0xf0000000L) != 0) { - h ^= (g >> 24UL); - h ^= g; - } - } - - return h; -} - -static int hash_compare(DviHashKey k1, DviHashKey k2) -{ - return strcmp((char *)k1, (char *)k2); -} - -void mdvi_hash_init(DviHashTable *hash) -{ - hash->buckets = NULL; - hash->nbucks = 0; - hash->nkeys = 0; - hash->hash_func = NULL; - hash->hash_comp = NULL; - hash->hash_free = NULL; -} - -void mdvi_hash_create(DviHashTable *hash, int size) -{ - int i; - - hash->nbucks = size; - hash->buckets = xnalloc(DviHashBucket *, size); - for(i = 0; i < size; i++) - hash->buckets[i] = NULL; - hash->hash_func = hash_string; - hash->hash_comp = hash_compare; - hash->hash_free = NULL; - hash->nkeys = 0; -} - -static DviHashBucket *hash_find(DviHashTable *hash, DviHashKey key) -{ - Ulong hval; - DviHashBucket *buck; - - hval = (hash->hash_func(key) % hash->nbucks); - - for(buck = hash->buckets[hval]; buck; buck = buck->next) - if(hash->hash_comp(buck->key, key) == 0) - break; - return buck; -} - -/* Neither keys nor data are duplicated */ -int mdvi_hash_add(DviHashTable *hash, DviHashKey key, void *data, int rep) -{ - DviHashBucket *buck = NULL; - Ulong hval; - - if(rep != MDVI_HASH_UNCHECKED) { - buck = hash_find(hash, key); - if(buck != NULL) { - if(buck->data == data) - return 0; - if(rep == MDVI_HASH_UNIQUE) - return -1; - if(hash->hash_free != NULL) - hash->hash_free(buck->key, buck->data); - } - } - if(buck == NULL) { - buck = xalloc(DviHashBucket); - buck->hvalue = hash->hash_func(key); - hval = (buck->hvalue % hash->nbucks); - buck->next = hash->buckets[hval]; - hash->buckets[hval] = buck; - hash->nkeys++; - } - - /* save key and data */ - buck->key = key; - buck->data = data; - - return 0; -} - -void *mdvi_hash_lookup(DviHashTable *hash, DviHashKey key) -{ - DviHashBucket *buck = hash_find(hash, key); - - return buck ? buck->data : NULL; -} - -static DviHashBucket *hash_remove(DviHashTable *hash, DviHashKey key) -{ - DviHashBucket *buck, *last; - Ulong hval; - - hval = hash->hash_func(key); - hval %= hash->nbucks; - - for(last = NULL, buck = hash->buckets[hval]; buck; buck = buck->next) { - if(hash->hash_comp(buck->key, key) == 0) - break; - last = buck; - } - if(buck == NULL) - return NULL; - if(last) - last->next = buck->next; - else - hash->buckets[hval] = buck->next; - hash->nkeys--; - return buck; -} - -void *mdvi_hash_remove(DviHashTable *hash, DviHashKey key) -{ - DviHashBucket *buck = hash_remove(hash, key); - void *data = NULL; - - if(buck) { - data = buck->data; - mdvi_free(buck); - } - return data; -} - -void *mdvi_hash_remove_ptr(DviHashTable *hash, DviHashKey key) -{ - DviHashBucket *buck, *last; - Ulong hval; - void *ptr; - - hval = hash->hash_func(key); - hval %= hash->nbucks; - - for(last = NULL, buck = hash->buckets[hval]; buck; buck = buck->next) { - if(buck->key == key) - break; - last = buck; - } - if(buck == NULL) - return NULL; - if(last) - last->next = buck->next; - else - hash->buckets[hval] = buck->next; - hash->nkeys--; - /* destroy the bucket */ - ptr = buck->data; - mdvi_free(buck); - return ptr; -} - -int mdvi_hash_destroy_key(DviHashTable *hash, DviHashKey key) -{ - DviHashBucket *buck = hash_remove(hash, key); - - if(buck == NULL) - return -1; - if(hash->hash_free) - hash->hash_free(buck->key, buck->data); - mdvi_free(buck); - return 0; -} - -void mdvi_hash_reset(DviHashTable *hash, int reuse) -{ - int i; - DviHashBucket *buck; - - /* remove all keys in the hash table */ - for(i = 0; i < hash->nbucks; i++) { - for(; (buck = hash->buckets[i]); ) { - hash->buckets[i] = buck->next; - if(hash->hash_free) - hash->hash_free(buck->key, buck->data); - mdvi_free(buck); - } - } - hash->nkeys = 0; - if(!reuse && hash->buckets) { - mdvi_free(hash->buckets); - hash->buckets = NULL; - hash->nbucks = 0; - } /* otherwise, it is left empty, ready to be reused */ -} diff --git a/dvi/mdvi-lib/hash.h b/dvi/mdvi-lib/hash.h deleted file mode 100644 index b10afd6..0000000 --- a/dvi/mdvi-lib/hash.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef MDVI_HASH -#define MDVI_HASH - -/* Hash tables */ - - -typedef struct _DviHashBucket DviHashBucket; -typedef struct _DviHashTable DviHashTable; - -/* - * Hash tables - */ - -typedef Uchar *DviHashKey; -#define MDVI_KEY(x) ((DviHashKey)(x)) - -typedef Ulong (*DviHashFunc) __PROTO((DviHashKey key)); -typedef int (*DviHashComp) __PROTO((DviHashKey key1, DviHashKey key2)); -typedef void (*DviHashFree) __PROTO((DviHashKey key, void *data)); - - -struct _DviHashTable { - DviHashBucket **buckets; - int nbucks; - int nkeys; - DviHashFunc hash_func; - DviHashComp hash_comp; - DviHashFree hash_free; -}; -#define MDVI_EMPTY_HASH_TABLE {NULL, 0, 0, NULL, NULL, NULL} - -#define MDVI_HASH_REPLACE 0 -#define MDVI_HASH_UNIQUE 1 -#define MDVI_HASH_UNCHECKED 2 - -extern void mdvi_hash_init __PROTO((DviHashTable *)); -extern void mdvi_hash_create __PROTO((DviHashTable *, int)); -extern int mdvi_hash_add __PROTO((DviHashTable *, DviHashKey, void *, int)); -extern int mdvi_hash_destroy_key __PROTO((DviHashTable *, DviHashKey)); -extern void mdvi_hash_reset __PROTO((DviHashTable *, int)); -extern void *mdvi_hash_lookup __PROTO((DviHashTable *, DviHashKey)); -extern void *mdvi_hash_remove __PROTO((DviHashTable *, DviHashKey)); -extern void *mdvi_hash_remove_ptr __PROTO((DviHashTable *, DviHashKey)); - -#define mdvi_hash_flush(h) mdvi_hash_reset((h), 1) -#define mdvi_hash_destroy(h) mdvi_hash_reset((h), 0) - -#endif - diff --git a/dvi/mdvi-lib/list.c b/dvi/mdvi-lib/list.c deleted file mode 100644 index c434e2b..0000000 --- a/dvi/mdvi-lib/list.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include "common.h" - -void listh_init(ListHead *head) -{ - head->head = head->tail = NULL; - head->count = 0; -} - -void listh_prepend(ListHead *head, List *list) -{ - list->prev = NULL; - list->next = head->head; - if(head->head) - head->head->prev = list; - head->head = list; - if(!head->tail) - head->tail = list; - head->count++; -} - -void listh_append(ListHead *head, List *list) -{ - list->next = NULL; - list->prev = head->tail; - if(head->tail) - head->tail->next = list; - else - head->head = list; - head->tail = list; - head->count++; -} - -void listh_add_before(ListHead *head, List *at, List *list) -{ - if(at == head->head || head->head == NULL) - listh_prepend(head, list); - else { - list->next = at; - list->prev = at->prev; - at->prev = list; - head->count++; - } -} - -void listh_add_after(ListHead *head, List *at, List *list) -{ - if(at == head->tail || !head->tail) - listh_append(head, list); - else { - list->prev = at; - list->next = at->next; - at->next = list; - head->count++; - } -} - -void listh_remove(ListHead *head, List *list) -{ - if(list == head->head) { - head->head = list->next; - if(head->head) - head->head->prev = NULL; - } else if(list == head->tail) { - head->tail = list->prev; - if(head->tail) - head->tail->next = NULL; - } else { - list->next->prev = list->prev; - list->prev->next = list->next; - } - if(--head->count == 0) - head->head = head->tail = NULL; -} - -void listh_concat(ListHead *h1, ListHead *h2) -{ - if(h2->head == NULL) - ; /* do nothing */ - else if(h1->tail == NULL) - h1->head = h2->head; - else { - h1->tail->next = h2->head; - h2->head->prev = h1->tail; - } - h1->tail = h2->tail; - h1->count += h2->count; -} - -void listh_catcon(ListHead *h1, ListHead *h2) -{ - if(h2->head == NULL) - ; /* do nothing */ - else if(h1->head == NULL) - h1->tail = h2->tail; - else { - h1->head->prev = h2->tail; - h2->tail->next = h1->head; - } - h1->head = h2->head; - h1->count += h2->count; -} diff --git a/dvi/mdvi-lib/mdvi.h b/dvi/mdvi-lib/mdvi.h deleted file mode 100644 index 961689a..0000000 --- a/dvi/mdvi-lib/mdvi.h +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ -#ifndef _MDVI_DVI_H -#define _MDVI_DVI_H 1 - -#include -#include -#include - -#include "sysdeps.h" -#include "bitmap.h" -#include "common.h" -#include "defaults.h" -#include "dviopcodes.h" - -typedef struct _DviGlyph DviGlyph; -typedef struct _DviDevice DviDevice; -typedef struct _DviFontChar DviFontChar; -typedef struct _DviFontRef DviFontRef; -typedef struct _DviFontInfo DviFontInfo; -typedef struct _DviFont DviFont; -typedef struct _DviState DviState; -typedef struct _DviPageSpec *DviPageSpec; -typedef struct _DviParams DviParams; -typedef struct _DviBuffer DviBuffer; -typedef struct _DviContext DviContext; -typedef struct _DviRange DviRange; -typedef struct _DviColorPair DviColorPair; -typedef struct _DviSection DviSection; -typedef struct _TFMChar TFMChar; -typedef struct _TFMInfo TFMInfo; -typedef struct _DviFontSearch DviFontSearch; -/* this is an opaque type */ -typedef struct _DviFontClass DviFontClass; - -typedef void (*DviFreeFunc) __PROTO((void *)); -typedef void (*DviFree2Func) __PROTO((void *, void *)); - -typedef Ulong DviColor; - -#ifdef TRUE -#undef TRUE -#endif -#ifdef FALSE -#undef FALSE -#endif - -typedef enum { - FALSE = 0, - TRUE = 1 -} DviBool; - -#include "hash.h" -#include "paper.h" - -/* - * information about a page: - * pagenum[0] = offset to BOP - * pagenum[1], ..., pagenum[10] = TeX \counters - */ -typedef long PageNum[11]; - -/* this structure contains the platform-specific information - * required to interpret a DVI file */ - -typedef void (*DviGlyphDraw) __PROTO((DviContext *context, - DviFontChar *glyph, - int x, int y)); - -typedef void (*DviRuleDraw) __PROTO((DviContext *context, - int x, int y, - Uint width, Uint height, int fill)); - -typedef int (*DviColorScale) __PROTO((void *device_data, - Ulong *pixels, - int npixels, - Ulong foreground, - Ulong background, - double gamma, - int density)); -typedef void *(*DviCreateImage) __PROTO((void *device_data, - Uint width, - Uint height, - Uint bpp)); -typedef void (*DviFreeImage) __PROTO((void *image)); -typedef void (*DviPutPixel) __PROTO((void *image, int x, int y, Ulong color)); -typedef void (*DviDevDestroy) __PROTO((void *data)); -typedef void (*DviRefresh) __PROTO((DviContext *dvi, void *device_data)); -typedef void (*DviSetColor) __PROTO((void *device_data, Ulong, Ulong)); - -struct _DviDevice { - DviGlyphDraw draw_glyph; - DviRuleDraw draw_rule; - DviColorScale alloc_colors; - DviCreateImage create_image; - DviFreeImage free_image; - DviPutPixel put_pixel; - DviDevDestroy dev_destroy; - DviRefresh refresh; - DviSetColor set_color; - void * device_data; -}; - -/* - * Fonts - */ - -#include "fontmap.h" - -struct _TFMChar { - Int32 present; - Int32 advance; /* advance */ - Int32 height; /* ascent */ - Int32 depth; /* descent */ - Int32 left; /* leftSideBearing */ - Int32 right; /* rightSideBearing */ -}; - -struct _TFMInfo { - int type; /* DviFontAFM, DviFontTFM, DviFontOFM */ - Uint32 checksum; - Uint32 design; - int loc; - int hic; - char coding[64]; - char family[64]; - TFMChar *chars; -}; - -struct _DviGlyph { - short x, y; /* origin */ - Uint w, h; /* dimensions */ - void *data; /* bitmap or XImage */ -}; - -typedef void (*DviFontShrinkFunc) - __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); -typedef int (*DviFontLoadFunc) __PROTO((DviParams *, DviFont *)); -typedef int (*DviFontGetGlyphFunc) __PROTO((DviParams *, DviFont *, int)); -typedef void (*DviFontFreeFunc) __PROTO((DviFont *)); -typedef void (*DviFontResetFunc) __PROTO((DviFont *)); -typedef char *(*DviFontLookupFunc) __PROTO((const char *, Ushort *, Ushort *)); -typedef int (*DviFontEncodeFunc) __PROTO((DviParams *, DviFont *, DviEncoding *)); - -struct _DviFontInfo { - char *name; /* human-readable format identifying string */ - int scalable; /* does it support scaling natively? */ - DviFontLoadFunc load; - DviFontGetGlyphFunc getglyph; - DviFontShrinkFunc shrink0; - DviFontShrinkFunc shrink1; - DviFontFreeFunc freedata; - DviFontResetFunc reset; - DviFontLookupFunc lookup; - int kpse_type; - void * private; -}; - -struct _DviFontChar { - Uint32 offset; - Int16 code; /* format-dependent, not used by MDVI */ - Int16 width; - Int16 height; - Int16 x; - Int16 y; - Int32 tfmwidth; - Ushort flags; -#ifdef __STRICT_ANSI__ - Ushort loaded; - Ushort missing; -#else - Ushort loaded : 1, - missing : 1; -#endif - Ulong fg; - Ulong bg; - BITMAP *glyph_data; - /* data for shrunk bitimaps */ - DviGlyph glyph; - DviGlyph shrunk; - DviGlyph grey; -}; - -struct _DviFontRef { - DviFontRef *next; - DviFont *ref; - Int32 fontid; -}; - -typedef enum { - DviFontAny = -1, - DviFontPK = 0, - DviFontGF = 1, - DviFontVF = 2, - DviFontTFM = 3, - DviFontT1 = 4, - DviFontTT = 5, - DviFontAFM = 6, - DviFontOFM = 7 -} DviFontType; - -struct _DviFontSearch { - int id; - Ushort hdpi; - Ushort vdpi; - Ushort actual_hdpi; - Ushort actual_vdpi; - const char *wanted_name; - const char *actual_name; - DviFontClass *curr; - DviFontInfo *info; -}; - -/* this is a kludge, I know */ -#define ISVIRTUAL(font) ((font)->search.info->getglyph == NULL) -#define SEARCH_DONE(s) ((s).id < 0) -#define SEARCH_INIT(s, name, h, v) do { \ - (s).id = 0; \ - (s).curr = NULL; \ - (s).hdpi = (h); \ - (s).vdpi = (v); \ - (s).wanted_name = (name); \ - (s).actual_name = NULL; \ - } while(0) - -struct _DviFont { - DviFont *next; - DviFont *prev; - int type; - Int32 checksum; - int hdpi; - int vdpi; - Int32 scale; - Int32 design; - FILE *in; - char *fontname; - char *filename; - int links; - int loc; - int hic; - Uint flags; - DviFontSearch search; - DviFontChar *chars; - DviFontRef *subfonts; - void *private; -}; - -/* - * Dvi context - */ - -typedef enum { - MDVI_ORIENT_TBLR = 0, /* top to bottom, left to right */ - MDVI_ORIENT_TBRL = 1, /* top to bottom, right to left */ - MDVI_ORIENT_BTLR = 2, /* bottom to top, left to right */ - MDVI_ORIENT_BTRL = 3, /* bottom to top, right to left */ - MDVI_ORIENT_RP90 = 4, /* rotated +90 degrees (counter-clockwise) */ - MDVI_ORIENT_RM90 = 5, /* rotated -90 degrees (clockwise) */ - MDVI_ORIENT_IRP90 = 6, /* flip horizontally, then rotate by +90 */ - MDVI_ORIENT_IRM90 = 7 /* rotate by -90, then flip horizontally */ -} DviOrientation; - -typedef enum { - MDVI_PAGE_SORT_UP, /* up, using \counter0 */ - MDVI_PAGE_SORT_DOWN, /* down, using \counter0 */ - MDVI_PAGE_SORT_RANDOM, /* randomly */ - MDVI_PAGE_SORT_DVI_UP, /* up, by location in DVI file */ - MDVI_PAGE_SORT_DVI_DOWN, /* down, by location in DVI file */ - MDVI_PAGE_SORT_NONE /* don't sort */ -} DviPageSort; - -struct _DviParams { - double mag; /* magnification */ - double conv; /* horizontal DVI -> pixel */ - double vconv; /* vertical DVI -> pixel */ - double tfm_conv; /* TFM -> DVI */ - double gamma; /* gamma correction factor */ - Uint dpi; /* horizontal resolution */ - Uint vdpi; /* vertical resolution */ - int hshrink; /* horizontal shrinking factor */ - int vshrink; /* vertical shrinking factor */ - Uint density; /* pixel density */ - Uint flags; /* flags (see MDVI_PARAM macros) */ - int hdrift; /* max. horizontal drift */ - int vdrift; /* max. vertical drift */ - int vsmallsp; /* small vertical space */ - int thinsp; /* small horizontal space */ - int layer; /* visible layer (for layered DVI files) */ - Ulong fg; /* foreground color */ - Ulong bg; /* background color */ - DviOrientation orientation; /* page orientation */ - int base_x; - int base_y; -}; - -typedef enum { - MDVI_PARAM_LAST = 0, - MDVI_SET_DPI = 1, - MDVI_SET_XDPI = 2, - MDVI_SET_YDPI = 3, - MDVI_SET_SHRINK = 4, - MDVI_SET_XSHRINK = 5, - MDVI_SET_YSHRINK = 6, - MDVI_SET_GAMMA = 7, - MDVI_SET_DENSITY = 8, - MDVI_SET_MAGNIFICATION = 9, - MDVI_SET_DRIFT = 10, - MDVI_SET_HDRIFT = 11, - MDVI_SET_VDRIFT = 12, - MDVI_SET_ORIENTATION = 13, - MDVI_SET_FOREGROUND = 14, - MDVI_SET_BACKGROUND = 15 -} DviParamCode; - -struct _DviBuffer { - Uchar *data; - size_t size; /* allocated size */ - size_t length; /* amount of data buffered */ - size_t pos; /* current position in buffer */ - int frozen; /* can we free this data? */ -}; - -/* DVI registers */ -struct _DviState { - int h; - int v; - int hh; - int vv; - int w; - int x; - int y; - int z; -}; - -struct _DviColorPair { - Ulong fg; - Ulong bg; -}; - -struct _DviContext { - char *filename; /* name of the DVI file */ - FILE *in; /* from here we read */ - char *fileid; /* from preamble */ - int npages; /* number of pages */ - int currpage; /* currrent page (0 based) */ - int depth; /* recursion depth */ - DviBuffer buffer; /* input buffer */ - DviParams params; /* parameters */ - DviPaper paper; /* paper type */ - Int32 num; /* numerator */ - Int32 den; /* denominator */ - DviFontRef *fonts; /* fonts used in this file */ - DviFontRef **fontmap; /* for faster id lookups */ - DviFontRef *currfont; /* current font */ - int nfonts; /* # of fonts used in this job */ - Int32 dvimag; /* original magnification */ - double dviconv; /* unshrunk scaling factor */ - double dvivconv; /* unshrunk scaling factor (vertical) */ - int dvi_page_w; /* unscaled page width */ - int dvi_page_h; /* unscaled page height */ - Ulong modtime; /* file modification time */ - PageNum *pagemap; /* page table */ - DviState pos; /* registers */ - DviPageSpec *pagesel; /* page selection data */ - int curr_layer; /* current layer */ - DviState *stack; /* DVI stack */ - int stacksize; /* stack depth */ - int stacktop; /* stack pointer */ - DviDevice device; /* device-specific routines */ - Ulong curr_fg; /* rendering color */ - Ulong curr_bg; - - DviColorPair *color_stack; - int color_top; - int color_size; - - DviFontRef *(*findref) __PROTO((DviContext *, Int32)); - void *user_data; /* client data attached to this context */ -}; - -typedef enum { - MDVI_RANGE_BOUNDED, /* range is finite */ - MDVI_RANGE_LOWER, /* range has a lower bound */ - MDVI_RANGE_UPPER, /* range has an upper bound */ - MDVI_RANGE_UNBOUNDED /* range has no bounds at all */ -} DviRangeType; - -struct _DviRange { - DviRangeType type; /* one of the above */ - int from; /* lower bound */ - int to; /* upper bound */ - int step; /* step */ -}; - - -typedef void (*DviSpecialHandler) - __PROTO((DviContext *dvi, const char *prefix, const char *arg)); - -#define RANGE_HAS_LOWER(x) \ - ((x) == MDVI_RANGE_BOUNDED || (x) == MDVI_RANGE_LOWER) -#define RANGE_HAS_UPPER(x) \ - ((x) == MDVI_RANGE_BOUNDED || (x) == MDVI_RANGE_UPPER) - -/* - * Macros and prototypes - */ - -#define MDVI_PARAM_ANTIALIASED 1 -#define MDVI_PARAM_MONO 2 -#define MDVI_PARAM_CHARBOXES 4 -#define MDVI_PARAM_SHOWUNDEF 8 -#define MDVI_PARAM_DELAYFONTS 16 - -/* - * The FALLBACK priority class is reserved for font formats that - * contain no glyph information and are to be used as a last - * resort (e.g. TFM, AFM) - */ -#define MDVI_FONTPRIO_FALLBACK -3 -#define MDVI_FONTPRIO_LOWEST -2 -#define MDVI_FONTPRIO_LOW -1 -#define MDVI_FONTPRIO_NORMAL 0 -#define MDVI_FONTPRIO_HIGH 1 -#define MDVI_FONTPRIO_HIGHEST 2 - -#define MDVI_FONT_ENCODED (1 << 0) - -#define MDVI_GLYPH_EMPTY ((void *)1) -/* does the glyph have a non-empty bitmap/image? */ -#define MDVI_GLYPH_NONEMPTY(x) ((x) && (x) != MDVI_GLYPH_EMPTY) -/* has the glyph been loaded from disk? */ -#define MDVI_GLYPH_UNSET(x) ((x) == NULL) -/* do we have only a bounding box for this glyph? */ -#define MDVI_GLYPH_ISEMPTY(x) ((x) == MDVI_GLYPH_EMPTY) - -#define MDVI_ENABLED(d,x) ((d)->params.flags & (x)) -#define MDVI_DISABLED(d,x) !MDVI_ENABLED((d), (x)) - -#define MDVI_LASTPAGE(d) ((d)->npages - 1) -#define MDVI_NPAGES(d) (d)->npages -#define MDVI_VALIDPAGE(d,p) ((p) >= 0 && (p) <= MDVI_LASTPAGE(d)) -#define MDVI_FLAGS(d) (d)->params.flags -#define MDVI_SHRINK_FROM_DPI(d) Max(1, (d) / 75) -#define MDVI_CURRFG(d) (d)->curr_fg -#define MDVI_CURRBG(d) (d)->curr_bg - -#define pixel_round(d,v) (int)((d)->params.conv * (v) + 0.5) -#define vpixel_round(d,v) (int)((d)->params.vconv * (v) + 0.5) -#define rule_round(d,v) (int)((d)->params.conv * (v) + 0.99999) /*9999999)*/ -#define vrule_round(d,v) (int)((d)->params.vconv * (v) + 0.99999) - -extern int mdvi_reload __PROTO((DviContext *, DviParams *)); -extern void mdvi_setpage __PROTO((DviContext *, int)); -extern int mdvi_dopage __PROTO((DviContext *, int)); -extern void mdvi_shrink_glyph __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); -extern void mdvi_shrink_box __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); -extern void mdvi_shrink_glyph_grey __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); -extern int mdvi_find_tex_page __PROTO((DviContext *, int)); -extern int mdvi_configure __PROTO((DviContext *, DviParamCode, ...)); - -extern int get_tfm_chars __PROTO((DviParams *, DviFont *, TFMInfo *, int)); -extern int tfm_load_file __PROTO((const char *, TFMInfo *)); -extern int afm_load_file __PROTO((const char *, TFMInfo *)); -extern TFMInfo *get_font_metrics __PROTO((const char *, int, const char *)); -extern char *lookup_font_metrics __PROTO((const char *, int *)); -extern void free_font_metrics __PROTO((TFMInfo *)); -extern void flush_font_metrics __PROTO((void)); - -#define get_metrics(name) get_font_metrics((name), DviFontAny, NULL) - -extern void mdvi_sort_pages __PROTO((DviContext *, DviPageSort)); - -extern void mdvi_init_kpathsea __PROTO((const char *, const char *, const char *, int)); - -extern DviContext* mdvi_init_context __PROTO((DviParams *, DviPageSpec *, const char *)); -extern void mdvi_destroy_context __PROTO((DviContext *)); - -/* helper macros that call mdvi_configure() */ -#define mdvi_config_one(d,x,y) mdvi_configure((d), (x), (y), MDVI_PARAM_LAST) -#define mdvi_set_dpi(d,x) mdvi_config_one((d), MDVI_SET_DPI, (x)) -#define mdvi_set_xdpi(d,x) mdvi_config_one((d), MDVI_SET_XDPI, (x)) -#define mdvi_set_ydpi(d,x) mdvi_config_one((d), MDVI_SET_YDPI, (x)) -#define mdvi_set_hshrink(d,h) mdvi_config_one((d), MDVI_SET_XSHRINK, (h)) -#define mdvi_set_vshrink(d,h) mdvi_config_one((d), MDVI_SET_YSHRINK, (h)) -#define mdvi_set_gamma(d,g) mdvi_config_one((d), MDVI_SET_GAMMA, (g)) -#define mdvi_set_density(d,x) mdvi_config_one((d), MDVI_SET_DENSITY, (x)) -#define mdvi_set_drift(d,x) mdvi_config_one((d), MDVI_SET_DRIFT, (x)) -#define mdvi_set_hdrift(d,h) mdvi_config_one((d), MDVI_SET_HDRIFT, (h)) -#define mdvi_set_vdrift(d,v) mdvi_config_one((d), MDVI_SET_VDRIFT, (v)) -#define mdvi_set_mag(d,m) \ - mdvi_config_one((d), MDVI_SET_MAGNIFICATION, (m)) -#define mdvi_set_foreground(d,x) \ - mdvi_config_one((d), MDVI_SET_FOREGROUND, (x)) -#define mdvi_set_background(d,x) \ - mdvi_config_one((d), MDVI_SET_BACKGROUND, (x)) -#define mdvi_set_orientation(d,x) \ - mdvi_config_one((d), MDVI_SET_ORIENTATION, (x)) -#define mdvi_set_shrink(d,h,v) \ - mdvi_configure((d), MDVI_SET_XSHRINK, (h), \ - MDVI_SET_YSHRINK, (v), MDVI_PARAM_LAST) - -extern DviRange* mdvi_parse_range __PROTO((const char *, DviRange *, int *, char **)); -extern DviPageSpec* mdvi_parse_page_spec __PROTO((const char *)); -extern void mdvi_free_page_spec __PROTO((DviPageSpec *)); -extern int mdvi_in_range __PROTO((DviRange *, int, int)); -extern int mdvi_range_length __PROTO((DviRange *, int)); -extern int mdvi_page_selected __PROTO((DviPageSpec *, PageNum, int)); - -/* Specials */ -extern int mdvi_register_special __PROTO(( - const char *label, - const char *prefix, - const char *regex, - DviSpecialHandler handler, - int replace)); -extern int mdvi_unregister_special __PROTO((const char *prefix)); -extern int mdvi_do_special __PROTO((DviContext *dvi, char *dvi_special)); -extern void mdvi_flush_specials __PROTO((void)); - -/* Fonts */ - -#define MDVI_FONTSEL_BITMAP (1 << 0) -#define MDVI_FONTSEL_GREY (1 << 1) -#define MDVI_FONTSEL_GLYPH (1 << 2) - -#define FONTCHAR(font, code) \ - (((code) < font->loc || (code) > font->hic || !(font)->chars) ? \ - NULL : &font->chars[(code) - (font)->loc]) -#define FONT_GLYPH_COUNT(font) ((font)->hic - (font)->loc + 1) - -#define glyph_present(x) ((x) && (x)->offset) - -/* create a reference to a font */ -extern DviFontRef *font_reference __PROTO((DviParams *params, - Int32 dvi_id, - const char *font_name, - Int32 checksum, - int xdpi, - int ydpi, - Int32 scale_factor)); - -/* drop a reference to a font */ -extern void font_drop_one __PROTO((DviFontRef *)); - -/* drop a chain of references */ -extern void font_drop_chain __PROTO((DviFontRef *)); - -/* destroy selected information for a glyph */ -extern void font_reset_one_glyph __PROTO((DviDevice *, DviFontChar *, int)); - -/* destroy selected information for all glyphs in a font */ -extern void font_reset_font_glyphs __PROTO((DviDevice *, DviFont *, int)); - -/* same for a chain of font references */ -extern void font_reset_chain_glyphs __PROTO((DviDevice *, DviFontRef *, int)); - -extern void font_finish_definitions __PROTO((DviContext *)); - -/* lookup an id # in a reference chain */ -extern DviFontRef* font_find_flat __PROTO((DviContext *, Int32)); -extern DviFontRef* font_find_mapped __PROTO((DviContext *, Int32)); - -/* called to reopen (or rewind) a font file */ -extern int font_reopen __PROTO((DviFont *)); - -/* reads a glyph from a font, and makes all necessary transformations */ -extern DviFontChar* font_get_glyph __PROTO((DviContext *, DviFont *, int)); - -/* transform a glyph according to the given orientation */ -extern void font_transform_glyph __PROTO((DviOrientation, DviGlyph *)); - -/* destroy all fonts that are not being used, returns number of fonts freed */ -extern int font_free_unused __PROTO((DviDevice *)); - -#define font_free_glyph(dev, font, code) \ - font_reset_one_glyph((dev), \ - FONTCHAR((font), (code)), MDVI_FONTSEL_GLYPH) - -extern int mdvi_encode_font __PROTO((DviParams *, DviFont *)); - - -/* font lookup functions */ -extern int mdvi_register_font_type __PROTO((DviFontInfo *, int)); -extern char **mdvi_list_font_class __PROTO((int)); -extern int mdvi_get_font_classes __PROTO((void)); -extern int mdvi_unregister_font_type __PROTO((const char *, int)); -extern char *mdvi_lookup_font __PROTO((DviFontSearch *)); -extern DviFont *mdvi_add_font __PROTO((const char *, Int32, int, int, Int32)); -extern int mdvi_font_retry __PROTO((DviParams *, DviFont *)); - -/* Miscellaneous */ - -extern int mdvi_set_logfile __PROTO((const char *)); -extern int mdvi_set_logstream __PROTO((FILE *)); -extern int mdvi_set_loglevel __PROTO((int)); - -#define mdvi_stop_logging(x) mdvi_set_logstream(NULL) - -/* this will check the environment and then `texmf.cnf' for - * the given name changed to lowercase, and `_' changed to `-' */ -extern char* mdvi_getenv __PROTO((const char *)); - -#endif /* _MDVI_DVI_H */ diff --git a/dvi/mdvi-lib/pagesel.c b/dvi/mdvi-lib/pagesel.c deleted file mode 100644 index b24157c..0000000 --- a/dvi/mdvi-lib/pagesel.c +++ /dev/null @@ -1,490 +0,0 @@ -/* pagesel.c -- Page selection mechanism */ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include -#include -#include - -#include "mdvi.h" -#include "private.h" - -char *program_name = "page"; - -struct _DviPageSpec { - DviRange *ranges; - int nranges; -}; - -DviRange *mdvi_parse_range(const char *format, DviRange *limit, int *nitems, char **endptr) -{ - int quoted; - int size; - int curr; - int done; - int lower; - int upper; - int type; - char * cp; - char * copy; - char * text; - DviRange one; - DviRange *range; - - quoted = (*format == '{'); - if(quoted) format++; - - size = 0; - curr = 0; - range = NULL; - copy = mdvi_strdup(format); - done = 0; - lower = 0; - upper = 0; - type = MDVI_RANGE_UNBOUNDED; - - if(limit) { - switch(limit->type) { - case MDVI_RANGE_BOUNDED: - lower = limit->from; - upper = limit->to; - break; - case MDVI_RANGE_UPPER: - lower = INT_MIN; - upper = limit->to; - break; - case MDVI_RANGE_LOWER: - lower = limit->from; - upper = INT_MAX; - break; - case MDVI_RANGE_UNBOUNDED: - lower = INT_MIN; - upper = INT_MAX; - break; - } - type = limit->type; - } else { - lower = INT_MIN; - upper = INT_MAX; - type = MDVI_RANGE_UNBOUNDED; - } - one.type = type; - one.from = lower; - one.to = upper; - one.step = 1; - for(cp = text = copy; !done; cp++) { - char *p; - int f, t, s; - int ch; - int this_type; - int lower_given = 0; - int upper_given = 0; - - if(*cp == 0 || *cp == '.' || (*cp == '}' && quoted)) - done = 1; - else if(*cp != ',') - continue; - - if(text == cp) - continue; - ch = *cp; - *cp = 0; - f = lower; - t = upper; - s = 1; - - p = strchr(text, ':'); - if(p) *p++ = 0; - if(*text) { - lower_given = 1; - f = strtol(text, NULL, 0); - } - if(p == NULL) { - if(lower_given) { - upper_given = 1; - t = f; s = 1; - } - goto finish; - } - text = p; - p = strchr(text, ':'); - if(p) *p++ = 0; - if(*text) { - upper_given = 1; - t = strtol(text, NULL, 0); - } - if(p == NULL) - goto finish; - text = p; - if(*text) - s = strtol(text, NULL, 0); -finish: - if(lower_given && upper_given) - this_type = MDVI_RANGE_BOUNDED; - else if(lower_given) { - if(!RANGE_HAS_UPPER(type)) - this_type = MDVI_RANGE_LOWER; - else - this_type = MDVI_RANGE_BOUNDED; - t = upper; - } else if(upper_given) { - if(RANGE_HAS_UPPER(one.type)) { - one.to++; - this_type = MDVI_RANGE_BOUNDED; - } else { - one.to = lower; - if(!RANGE_HAS_LOWER(type)) - this_type = MDVI_RANGE_UPPER; - else - this_type = MDVI_RANGE_BOUNDED; - } - f = one.to; - } else { - this_type = type; - f = lower; - t = upper; - } - one.type = this_type; - one.to = t; - one.from = f; - one.step = s; - - if(curr == size) { - size += 8; - range = mdvi_realloc(range, size * sizeof(DviRange)); - } - memcpy(&range[curr++], &one, sizeof(DviRange)); - *cp = ch; - text = cp + 1; - } - if(done) - cp--; - if(quoted && *cp == '}') - cp++; - if(endptr) - *endptr = (char *)format + (cp - copy); - if(curr && curr < size) - range = mdvi_realloc(range, curr * sizeof(DviRange)); - *nitems = curr; - mdvi_free(copy); - return range; -} - -DviPageSpec *mdvi_parse_page_spec(const char *format) -{ - /* - * a page specification looks like this: - * '{'RANGE_SPEC'}' for a DVI spec - * '{'RANGE_SPEC'}' '.' ... for a TeX spec - */ - DviPageSpec *spec; - DviRange *range; - int count; - int i; - char *ptr; - - spec = xnalloc(struct _DviPageSpec *, 11); - for(i = 0; i < 11; i++) - spec[i] = NULL; - - /* check what kind of spec we're parsing */ - if(*format != '*') { - range = mdvi_parse_range(format, NULL, &count, &ptr); - if(ptr == format) { - if(range) mdvi_free(range); - error(_("invalid page specification `%s'\n"), format); - return NULL; - } - } else - range = NULL; - - if(*format == 'D' || *format == 'd' || *ptr != '.') - i = 0; - else - i = 1; - - if(range) { - spec[i] = xalloc(struct _DviPageSpec); - spec[i]->ranges = range; - spec[i]->nranges = count; - } else - spec[i] = NULL; - - if(*ptr != '.') { - if(*ptr) - warning(_("garbage after DVI page specification ignored\n")); - return spec; - } - - for(i++; *ptr == '.' && i <= 10; i++) { - ptr++; - if(*ptr == '*') { - ptr++; - range = NULL; - } else { - char *end; - - range = mdvi_parse_range(ptr, NULL, &count, &end); - if(end == ptr) { - if(range) mdvi_free(range); - range = NULL; - } else - ptr = end; - } - if(range != NULL) { - spec[i] = xalloc(struct _DviPageSpec); - spec[i]->ranges = range; - spec[i]->nranges = count; - } else - spec[i] = NULL; - } - - if(i > 10) - warning(_("more than 10 counters in page specification\n")); - else if(*ptr) - warning(_("garbage after TeX page specification ignored\n")); - - return spec; -} - -/* returns non-zero if the given page is included by `spec' */ -int mdvi_page_selected(DviPageSpec *spec, PageNum page, int dvipage) -{ - int i; - int not_found; - - if(spec == NULL) - return 1; - if(spec[0]) { - not_found = mdvi_in_range(spec[0]->ranges, - spec[0]->nranges, dvipage); - if(not_found < 0) - return 0; - } - for(i = 1; i <= 10; i++) { - if(spec[i] == NULL) - continue; - not_found = mdvi_in_range(spec[i]->ranges, - spec[i]->nranges, (int)page[i]); - if(not_found < 0) - return 0; - } - return 1; -} - -void mdvi_free_page_spec(DviPageSpec *spec) -{ - int i; - - for(i = 0; i < 11; i++) - if(spec[i]) { - mdvi_free(spec[i]->ranges); - mdvi_free(spec[i]); - } - mdvi_free(spec); -} - -int mdvi_in_range(DviRange *range, int nitems, int value) -{ - DviRange *r; - - for(r = range; r < range + nitems; r++) { - int cond; - - switch(r->type) { - case MDVI_RANGE_BOUNDED: - if(value == r->from) - return (r - range); - if(r->step < 0) - cond = (value <= r->from) && (value >= r->to); - else - cond = (value <= r->to) && (value >= r->from); - if(cond && ((value - r->from) % r->step) == 0) - return (r - range); - break; - case MDVI_RANGE_LOWER: - if(value == r->from) - return (r - range); - if(r->step < 0) - cond = (value < r->from); - else - cond = (value > r->from); - if(cond && ((value - r->from) % r->step) == 0) - return (r - range); - break; - case MDVI_RANGE_UPPER: - if(value == r->to) - return (r - range); - if(r->step < 0) - cond = (value > r->to); - else - cond = (value < r->to); - if(cond && ((value - r->to) % r->step) == 0) - return (r - range); - break; - case MDVI_RANGE_UNBOUNDED: - if((value % r->step) == 0) - return (r - range); - break; - } - } - return -1; -} - -int mdvi_range_length(DviRange *range, int nitems) -{ - int count = 0; - DviRange *r; - - for(r = range; r < range + nitems; r++) { - int n; - - if(r->type != MDVI_RANGE_BOUNDED) - return -2; - n = (r->to - r->from) / r->step; - if(n < 0) - n = 0; - count += n + 1; - } - return count; -} - -#ifdef TEST - -void print_range(DviRange *range) -{ - switch(range->type) { - case MDVI_RANGE_BOUNDED: - printf("From %d to %d, step %d\n", - range->from, range->to, range->step); - break; - case MDVI_RANGE_LOWER: - printf("From %d, step %d\n", - range->from, range->step); - break; - case MDVI_RANGE_UPPER: - printf("From %d, step -%d\n", - range->to, range->step); - break; - case MDVI_RANGE_UNBOUNDED: - printf("From 0, step %d and %d\n", - range->step, -range->step); - break; - } -} - -int main() -{ -#if 0 - char buf[256]; - DviRange limit; - - limit.from = 0; - limit.to = 100; - limit.step = 2; - limit.type = MDVI_RANGE_UNBOUNDED; - while(1) { - DviRange *range; - char *end; - int count; - int i; - - printf("Range> "); fflush(stdout); - if(fgets(buf, 256, stdin) == NULL) - break; - if(buf[strlen(buf)-1] == '\n') - buf[strlen(buf)-1] = 0; - if(buf[0] == 0) - continue; - end = NULL; - range = mdvi_parse_range(buf, &limit, &count, &end); - if(range == NULL) { - printf("range is empty\n"); - continue; - } - - for(i = 0; i < count; i++) { - printf("Range %d (%d elements):\n", - i, mdvi_range_length(&range[i], 1)); - print_range(&range[i]); - } - if(end && *end) - printf("Tail: [%s]\n", end); - printf("range has %d elements\n", - mdvi_range_length(range, count)); -#if 1 - while(1) { - int v; - - printf("Value: "); fflush(stdout); - if(fgets(buf, 256, stdin) == NULL) - break; - if(buf[strlen(buf)-1] == '\n') - buf[strlen(buf)-1] = 0; - if(buf[0] == 0) - break; - v = atoi(buf); - i = mdvi_in_range(range, count, v); - if(i == -1) - printf("%d not in range\n", v); - else { - printf("%d in range: ", v); - print_range(&range[i]); - } - } -#endif - if(range) mdvi_free(range); - } -#else - DviPageSpec *spec; - char buf[256]; - - while(1) { - printf("Spec> "); fflush(stdout); - if(fgets(buf, 256, stdin) == NULL) - break; - if(buf[strlen(buf)-1] == '\n') - buf[strlen(buf)-1] = 0; - if(buf[0] == 0) - continue; - spec = mdvi_parse_page_spec(buf); - if(spec == NULL) - printf("no spec parsed\n"); - else { - int i; - - printf("spec = "); - for(i = 0; i < 11; i++) { - printf("Counter %d:\n", i); - if(spec[i]) { - int k; - - for(k = 0; k < spec[i]->nranges; k++) - print_range(&spec[i]->ranges[k]); - } else - printf("\t*\n"); - } - mdvi_free_page_spec(spec); - } - } -#endif - exit(0); - -} -#endif /* TEST */ diff --git a/dvi/mdvi-lib/paper.c b/dvi/mdvi-lib/paper.c deleted file mode 100644 index 7a7412d..0000000 --- a/dvi/mdvi-lib/paper.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include - -#include "common.h" -#include "mdvi.h" -#include "private.h" - -static const DviPaperSpec papers[] = { - {"ISO", 0, 0}, - {"4A0", "1682mm", "2378mm"}, - {"2A0", "1189mm", "1682mm"}, - {"A0", "841mm", "1189mm"}, - {"A1", "594mm", "841mm"}, - {"A2", "420mm", "594mm"}, - {"A3", "297mm", "420mm"}, - {"A4", "210mm", "297mm"}, - {"A5", "148mm", "210mm"}, - {"A6", "105mm", "148mm"}, - {"A7", "74mm", "105mm"}, - {"A8", "52mm", "74mm"}, - {"A9", "37mm", "52mm"}, - {"A10", "26mm", "37mm"}, - {"B0", "1000mm", "1414mm"}, - {"B1", "707mm", "1000mm"}, - {"B2", "500mm", "707mm"}, - {"B3", "353mm", "500mm"}, - {"B4", "250mm", "353mm"}, - {"B5", "176mm", "250mm"}, - {"B6", "125mm", "176mm"}, - {"B7", "88mm", "125mm"}, - {"B8", "62mm", "88mm"}, - {"B9", "44mm", "62mm"}, - {"B10", "31mm", "44mm"}, - {"C0", "917mm", "1297mm"}, - {"C1", "648mm", "917mm"}, - {"C2", "458mm", "648mm"}, - {"C3", "324mm", "458mm"}, - {"C4", "229mm", "324mm"}, - {"C5", "162mm", "229mm"}, - {"C6", "114mm", "162mm"}, - {"C7", "81mm", "114mm"}, - {"C8", "57mm", "81mm"}, - {"C9", "40mm", "57mm"}, - {"C10", "28mm", "40mm"}, - {"US", 0, 0}, - {"archA", "9in", "12in"}, - {"archB", "12in", "18in"}, - {"archC", "18in", "24in"}, - {"archD", "24in", "36in"}, - {"archE", "36in", "48in"}, - {"executive", "7.5in", "10in"}, - {"flsa", "8.5in", "13in"}, - {"flse", "8.5in", "13in"}, - {"halfletter", "5.5in", "8.5in"}, - {"letter", "8.5in", "11in"}, - {"legal", "8.5in", "14in"}, - {"ledger", "17in", "11in"}, - {"note", "7.5in", "10in"}, - {"tabloid", "11in", "17in"}, - {"statement", "5.5in", "8.5in"}, - {0, 0, 0} -}; - -static DviPaperClass str2class(const char *name) -{ - if(STRCEQ(name, "ISO")) - return MDVI_PAPER_CLASS_ISO; - else if(STRCEQ(name, "US")) - return MDVI_PAPER_CLASS_US; - return MDVI_PAPER_CLASS_CUSTOM; -} - -int mdvi_get_paper_size(const char *name, DviPaper *paper) -{ - const DviPaperSpec *sp; - double a, b; - char c, d, e, f; - char buf[32]; - - paper->pclass = MDVI_PAPER_CLASS_CUSTOM; - if(sscanf(name, "%lfx%lf%c%c", &a, &b, &c, &d) == 4) { - sprintf(buf, "%12.16f%c%c", a, c, d); - paper->inches_wide = unit2pix_factor(buf); - sprintf(buf, "%12.16f%c%c", b, c, d); - paper->inches_tall = unit2pix_factor(buf); - paper->name = _("custom"); - return 0; - } else if(sscanf(name, "%lf%c%c,%lf%c%c", &a, &c, &d, &b, &e, &f) == 6) { - sprintf(buf, "%12.16f%c%c", a, c, d); - paper->inches_wide = unit2pix_factor(buf); - sprintf(buf, "%12.16f%c%c", b, e, f); - paper->inches_tall = unit2pix_factor(buf); - paper->name = _("custom"); - return 0; - } - - for(sp = &papers[0]; sp->name; sp++) { - if(!sp->width || !sp->height) { - paper->pclass = str2class(sp->name); - continue; - } - if(strcasecmp(sp->name, name) == 0) { - paper->inches_wide = unit2pix_factor(sp->width); - paper->inches_tall = unit2pix_factor(sp->height); - paper->name = sp->name; - return 0; - } - } - return -1; -} - -DviPaperSpec *mdvi_get_paper_specs(DviPaperClass pclass) -{ - int i; - int first, count; - DviPaperSpec *spec, *ptr; - - first = -1; - count = 0; - if(pclass == MDVI_PAPER_CLASS_ANY || - pclass == MDVI_PAPER_CLASS_CUSTOM) { - first = 0; - count = (sizeof(papers) / sizeof(papers[0])) - 3; - } else for(i = 0; papers[i].name; i++) { - if(papers[i].width == NULL) { - if(str2class(papers[i].name) == pclass) - first = i; - else if(first >= 0) - break; - } else if(first >= 0) - count++; - } - ptr = spec = xnalloc(DviPaperSpec, count + 1); - for(i = first; papers[i].name&& count > 0; i++) { - if(papers[i].width) { - ptr->name = papers[i].name; - ptr->width = papers[i].width; - ptr->height = papers[i].height; - ptr++; - count--; - } - } - ptr->name = NULL; - ptr->width = NULL; - ptr->height = NULL; - - return spec; -} - -void mdvi_free_paper_specs(DviPaperSpec *spec) -{ - mdvi_free(spec); -} diff --git a/dvi/mdvi-lib/paper.h b/dvi/mdvi-lib/paper.h deleted file mode 100644 index d42ee07..0000000 --- a/dvi/mdvi-lib/paper.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef MDVI_PAPER -#define MDVI_PAPER - -typedef struct _DviPaper DviPaper; -typedef struct _DviPaperSpec DviPaperSpec; - -typedef enum { - MDVI_PAPER_CLASS_ISO, - MDVI_PAPER_CLASS_US, - MDVI_PAPER_CLASS_ANY, - MDVI_PAPER_CLASS_CUSTOM -} DviPaperClass; - -struct _DviPaper { - DviPaperClass pclass; - const char *name; - double inches_wide; - double inches_tall; -}; - -struct _DviPaperSpec { - const char *name; - const char *width; - const char *height; -}; - - -extern int mdvi_get_paper_size __PROTO((const char *, DviPaper *)); -extern DviPaperSpec* mdvi_get_paper_specs __PROTO((DviPaperClass)); -extern void mdvi_free_paper_specs __PROTO((DviPaperSpec *)); - -#endif diff --git a/dvi/mdvi-lib/pk.c b/dvi/mdvi-lib/pk.c deleted file mode 100644 index 48da008..0000000 --- a/dvi/mdvi-lib/pk.c +++ /dev/null @@ -1,569 +0,0 @@ - -/* Copyright (C) 2000, Matias Atria - * - * 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 - */ - -/* - * History: - * - * 11/3/2000: - * - First working version - * 11/4/2000: - * - FIXED: entirely white/black rows were missed. - * 11/8/2000: - * - TESTED: Glyphs are rendered correctly in different byte orders. - * - Made bitmap code much more efficient and compact. - */ - -#include -#include -#include -#include -#include - -#include "mdvi.h" -#include "private.h" - -#define PK_ID 89 -#define PK_CMD_START 240 -#define PK_X1 240 -#define PK_X2 241 -#define PK_X3 242 -#define PK_X4 243 -#define PK_Y 244 -#define PK_POST 245 -#define PK_NOOP 246 -#define PK_PRE 247 - -#define PK_DYN_F(x) (((x) >> 4) & 0xf) -#define PK_PACKED(x) (PK_DYN_F(x) != 14) - -static int pk_load_font __PROTO((DviParams *, DviFont *)); -static int pk_font_get_glyph __PROTO((DviParams *, DviFont *, int)); - -static int pk_auto_generate = 1; /* this is ON by default */ - -typedef struct { - char currbyte; - char nybpos; - int dyn_f; -} pkread; - -static char *pk_lookup __PROTO((const char *, Ushort *, Ushort *)); -static char *pk_lookupn __PROTO((const char *, Ushort *, Ushort *)); - -/* only symbols exported by this file */ -DviFontInfo pk_font_info = { - "PK", - 0, /* scaling not supported natively */ - pk_load_font, - pk_font_get_glyph, - mdvi_shrink_glyph, - mdvi_shrink_glyph_grey, - NULL, /* free */ - NULL, /* reset */ - pk_lookup, /* lookup */ - kpse_pk_format, - NULL -}; - -DviFontInfo pkn_font_info = { - "PKN", - 0, /* scaling not supported natively */ - pk_load_font, - pk_font_get_glyph, - mdvi_shrink_glyph, - mdvi_shrink_glyph_grey, - NULL, /* free */ - NULL, /* reset */ - pk_lookupn, /* lookup */ - kpse_pk_format, - NULL -}; - -static char *pk_lookup(const char *name, Ushort *hdpi, Ushort *vdpi) -{ - kpse_glyph_file_type type; - char *filename; - - if(pk_auto_generate == 0) { - kpse_set_program_enabled(kpse_pk_format, 1, kpse_src_cmdline); - pk_auto_generate = 1; - } - filename = kpse_find_glyph(name, Max(*hdpi, *vdpi), - kpse_pk_format, &type); - if(filename && type.source == kpse_glyph_source_fallback) { - mdvi_free(filename); - filename = NULL; - } else if(filename) { - *hdpi = *vdpi = type.dpi; - } - return filename; -} - -static char *pk_lookupn(const char *name, Ushort *hdpi, Ushort *vdpi) -{ - kpse_glyph_file_type type; - char *filename; - - if(pk_auto_generate) { - kpse_set_program_enabled(kpse_pk_format, 0, kpse_src_cmdline); - pk_auto_generate = 0; - } - filename = kpse_find_glyph(name, Max(*hdpi, *vdpi), - kpse_pk_format, &type); - if(filename && type.source == kpse_glyph_source_fallback) { - mdvi_free(filename); - filename = NULL; - } else if(filename) { - *hdpi = *vdpi = type.dpi; - } - return filename; -} - -static inline int pk_get_nyb(FILE *p, pkread *pk) -{ - unsigned t; - int nb; - char c; - - t = c = pk->currbyte; - nb = pk->nybpos; - - switch(nb) { - case 0: - c = pk->currbyte = fuget1(p); - t = (c >> 4); - break; - case 1: - t = c; - break; - } - pk->nybpos = !nb; - return (t & 0xf); -} - -/* - * this is a bit cumbersome because we have to pass around - * the `pkread' data... - */ -static int pk_packed_num(FILE *p, pkread *pkr, int *repeat) -{ - int i, j; - int dyn_f = pkr->dyn_f; - - i = pk_get_nyb(p, pkr); - if(i == 0) { - do { - j = pk_get_nyb(p, pkr); - i++; - } while(j == 0); - while(i-- > 0) - j = (j << 4) + pk_get_nyb(p, pkr); - return (j - 15 + ((13 - dyn_f) << 4) + - dyn_f); - } else if(i <= dyn_f) - return i; - else if(i < 14) - return ((i - dyn_f - 1) << 4) + - pk_get_nyb(p, pkr) + dyn_f + 1; - else { - *repeat = 1; - if(i == 14) - *repeat = pk_packed_num(p, pkr, repeat); - return pk_packed_num(p, pkr, repeat); - } -} - -#define ROUND(x,y) (((x) + (y) - 1) / (y)) - -static BITMAP *get_bitmap(FILE *p, int w, int h, int flags) -{ - int i, j; - BmUnit *ptr; - BITMAP *bm; - int bitpos; - int currch; - - flags = 0; /* shut up that compiler */ - bitpos = -1; - if((bm = bitmap_alloc(w, h)) == NULL) - return NULL; - DEBUG((DBG_BITMAPS, "get_bitmap(%d,%d,%d): reading raw bitmap\n", - w, h, flags)); - ptr = bm->data; - currch = 0; - for(i = 0; i < h; i++) { - BmUnit mask; - - mask = FIRSTMASK; - for(j = 0; j < w; j++) { - if(bitpos < 0) { - currch = fuget1(p); - bitpos = 7; - } - if(currch & (1 << bitpos)) - *ptr |= mask; - bitpos--; - if(mask == LASTMASK) { - ptr++; - mask = FIRSTMASK; - } else - NEXTMASK(mask); - } - ptr = bm_offset(ptr, bm->stride); - } - return bm; -} - -static BITMAP *get_packed(FILE *p, int w, int h, int flags) -{ - int inrow, count; - int row; - BITMAP *bm; - int repeat_count; - int paint; - pkread pkr; - - pkr.nybpos = 0; - pkr.currbyte = 0; - pkr.dyn_f = PK_DYN_F(flags); - paint = !!(flags & 0x8); - - repeat_count = 0; - row = 0; - inrow = w; - if((bm = bitmap_alloc(w, h)) == NULL) - return NULL; - DEBUG((DBG_BITMAPS, "get_packed(%d,%d,%d): reading packed glyph\n", - w, h, flags)); - while(row < h) { - int i = 0; - - count = pk_packed_num(p, &pkr, &i); - if(i > 0) { - if(repeat_count) - fprintf(stderr, "second repeat count for this row (had %d and got %d)\n", - repeat_count, i); - repeat_count = i; - } - - if(count >= inrow) { - Uchar *r, *t; - BmUnit *a, mask; - - /* first finish current row */ - if(paint) - bitmap_set_row(bm, row, w - inrow, inrow, paint); - /* now copy it as many times as required */ - r = (Uchar *)bm->data + row * bm->stride; - while(repeat_count-- > 0) { - t = r + bm->stride; - /* copy entire lines */ - memcpy(t, r, bm->stride); - r = t; - row++; - } - repeat_count = 0; - /* count first row we drew */ - row++; - /* update run count */ - count -= inrow; - /* now r points to the beginning of the last row we finished */ - if(paint) - mask = ~((BmUnit)0); - else - mask = 0; - /* goto next row */ - a = (BmUnit *)(r + bm->stride); - /* deal with entirely with/black rows */ - while(count >= w) { - /* count number of atoms in a row */ - i = ROUND(w, BITMAP_BITS); - while(i-- > 0) - *a++ = mask; - count -= w; - row++; - } - inrow = w; - } - if(count > 0) - bitmap_set_row(bm, row, w - inrow, count, paint); - inrow -= count; - paint = !paint; - } - if(row != h || inrow != w) { - error(_("Bad PK file: More bits than required\n")); - bitmap_destroy(bm); - return NULL; - } - return bm; -} - -static BITMAP *get_char(FILE *p, int w, int h, int flags) -{ - /* check if dyn_f == 14 */ - if(((flags >> 4) & 0xf) == 14) - return get_bitmap(p, w, h, flags); - else - return get_packed(p, w, h, flags); -} - -/* supports any number of characters in a font */ -static int pk_load_font(DviParams *unused, DviFont *font) -{ - int i; - int flag_byte; - int loc, hic, maxch; - Int32 checksum; - FILE *p; -#ifndef NODEBUG - char s[256]; -#endif - long alpha, beta, z; - - font->chars = xnalloc(DviFontChar, 256); - p = font->in; - memzero(font->chars, 256 * sizeof(DviFontChar)); - for(i = 0; i < 256; i++) - font->chars[i].offset = 0; - - /* check the preamble */ - loc = fuget1(p); hic = fuget1(p); - if(loc != PK_PRE || hic != PK_ID) - goto badpk; - i = fuget1(p); -#ifndef NODEBUG - for(loc = 0; loc < i; loc++) - s[loc] = fuget1(p); - s[loc] = 0; - DEBUG((DBG_FONTS, "(pk) %s: %s\n", font->fontname, s)); -#else - fseek(in, (long)i, SEEK_CUR); -#endif - /* get the design size */ - font->design = fuget4(p); - /* get the checksum */ - checksum = fuget4(p); - if(checksum && font->checksum && font->checksum != checksum) { - warning(_("%s: checksum mismatch (expected %u, got %u)\n"), - font->fontname, font->checksum, checksum); - } else if(!font->checksum) - font->checksum = checksum; - /* skip pixel per point ratios */ - fuget4(p); - fuget4(p); - if(feof(p)) - goto badpk; - - /* now start reading the font */ - loc = 256; hic = -1; maxch = 256; - - /* initialize alpha and beta for TFM width computation */ - TFMPREPARE(font->scale, z, alpha, beta); - - while((flag_byte = fuget1(p)) != PK_POST) { - if(feof(p)) - break; - if(flag_byte >= PK_CMD_START) { - switch(flag_byte) { - case PK_X1: - case PK_X2: - case PK_X3: - case PK_X4: { -#ifndef NODEBUG - char *t; - int n; - - i = fugetn(p, flag_byte - PK_X1 + 1); - if(i < 256) - t = &s[0]; - else - t = mdvi_malloc(i + 1); - for(n = 0; n < i; n++) - t[n] = fuget1(p); - t[n] = 0; - DEBUG((DBG_SPECIAL, "(pk) %s: Special \"%s\"\n", - font->fontname, t)); - if(t != &s[0]) - mdvi_free(t); -#else - i = fugetn(p, flag_byte - PK_X1 + 1); - while(i-- > 0) - fuget1(p); -#endif - break; - } - case PK_Y: - i = fuget4(p); - DEBUG((DBG_SPECIAL, "(pk) %s: MF special %u\n", - font->fontname, (unsigned)i)); - break; - case PK_POST: - case PK_NOOP: - break; - case PK_PRE: - error(_("%s: unexpected preamble\n"), font->fontname); - goto error; - } - } else { - int pl; - int cc; - int w, h; - int x, y; - int offset; - long tfm; - - switch(flag_byte & 0x7) { - case 7: - pl = fuget4(p); - cc = fuget4(p); - offset = ftell(p) + pl; - tfm = fuget4(p); - fsget4(p); /* skip dx */ - fsget4(p); /* skip dy */ - w = fuget4(p); - h = fuget4(p); - x = fsget4(p); - y = fsget4(p); - break; - case 4: - case 5: - case 6: - pl = (flag_byte % 4) * 65536 + fuget2(p); - cc = fuget1(p); - offset = ftell(p) + pl; - tfm = fuget3(p); - fsget2(p); /* skip dx */ - /* dy assumed 0 */ - w = fuget2(p); - h = fuget2(p); - x = fsget2(p); - y = fsget2(p); - break; - default: - pl = (flag_byte % 4) * 256 + fuget1(p); - cc = fuget1(p); - offset = ftell(p) + pl; - tfm = fuget3(p); - fsget1(p); /* skip dx */ - /* dy assumed 0 */ - w = fuget1(p); - h = fuget1(p); - x = fsget1(p); - y = fsget1(p); - } - if(feof(p)) - break; - if(cc < loc) - loc = cc; - if(cc > hic) - hic = cc; - if(cc > maxch) { - font->chars = xresize(font->chars, - DviFontChar, cc + 16); - for(i = maxch; i < cc + 16; i++) - font->chars[i].offset = 0; - maxch = cc + 16; - } - font->chars[cc].code = cc; - font->chars[cc].flags = flag_byte; - font->chars[cc].offset = ftell(p); - font->chars[cc].width = w; - font->chars[cc].height = h; - font->chars[cc].glyph.data = NULL; - font->chars[cc].x = x; - font->chars[cc].y = y; - font->chars[cc].glyph.x = x; - font->chars[cc].glyph.y = y; - font->chars[cc].glyph.w = w; - font->chars[cc].glyph.h = h; - font->chars[cc].grey.data = NULL; - font->chars[cc].shrunk.data = NULL; - font->chars[cc].tfmwidth = TFMSCALE(z, tfm, alpha, beta); - font->chars[cc].loaded = 0; - fseek(p, (long)offset, SEEK_SET); - } - } - if(flag_byte != PK_POST) { - error(_("%s: unexpected end of file (no postamble)\n"), - font->fontname); - goto error; - } - while((flag_byte = fuget1(p)) != EOF) { - if(flag_byte != PK_NOOP) { - error(_("invalid PK file! (junk in postamble)\n")); - goto error; - } - } - - /* resize font char data */ - if(loc > 0 || hic < maxch-1) { - memmove(font->chars, font->chars + loc, - (hic - loc + 1) * sizeof(DviFontChar)); - font->chars = xresize(font->chars, - DviFontChar, hic - loc + 1); - } - font->loc = loc; - font->hic = hic; - return 0; - -badpk: - error(_("%s: File corrupted, or not a PK file\n"), font->fontname); -error: - mdvi_free(font->chars); - font->chars = NULL; - font->loc = font->hic = 0; - return -1; -} - -static int pk_font_get_glyph(DviParams *params, DviFont *font, int code) -{ - DviFontChar *ch; - - if((ch = FONTCHAR(font, code)) == NULL) - return -1; - - if(ch->offset == 0) - return -1; - DEBUG((DBG_GLYPHS, "(pk) loading glyph for character %d (%dx%d) in font `%s'\n", - code, ch->width, ch->height, font->fontname)); - if(font->in == NULL && font_reopen(font) < 0) - return -1; - if(!ch->width || !ch->height) { - /* this happens for ` ' (ASCII 32) in some fonts */ - ch->glyph.x = ch->x; - ch->glyph.y = ch->y; - ch->glyph.w = ch->width; - ch->glyph.h = ch->height; - ch->glyph.data = NULL; - return 0; - } - if(fseek(font->in, ch->offset, SEEK_SET) == -1) - return -1; - ch->glyph.data = get_char(font->in, - ch->width, ch->height, ch->flags); - if(ch->glyph.data) { - /* restore original settings */ - ch->glyph.x = ch->x; - ch->glyph.y = ch->y; - ch->glyph.w = ch->width; - ch->glyph.h = ch->height; - } else - return -1; - ch->loaded = 1; - return 0; -} diff --git a/dvi/mdvi-lib/private.h b/dvi/mdvi-lib/private.h deleted file mode 100644 index c547cd2..0000000 --- a/dvi/mdvi-lib/private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ -#ifndef _MDVI_PRIVATE_H -#define _MDVI_PRIVATE_H 1 - -#define HAVE_PROTOTYPES 1 -#include -#include -#include -#include -#include -#include -#include - -#define ISSP(p) (*(p) == ' ' || *(p) == '\t') -#define SKIPSP(p) while(ISSP(p)) p++ -#define SKIPNSP(p) while(*(p) && !ISSP(p)) p++ - -#ifdef ENABLE_NLS -#include -#define _(x) gettext(x) -#define _G(x) x -#else -#define _(x) x -#define _G(x) x -#endif /* ENABLE_NLS */ - -#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2 -#define _BREAKPOINT() do { __asm__ __volatile__ ("int $03"); } while(0) -#elif defined (__alpha__) && defined (__GNUC__) && __GNUC__ >= 2 -#define _BREAKPOINT() do { __asm__ __volatile__ ("bpt"); } while(0) -#else /* !__i386__ && !__alpha__ */ -#define _BREAKPOINT() -#endif /* __i386__ */ - -#endif /* _MDVI_PRIVATE_H */ diff --git a/dvi/mdvi-lib/setup.c b/dvi/mdvi-lib/setup.c deleted file mode 100644 index dea26e6..0000000 --- a/dvi/mdvi-lib/setup.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include -#include -#include - -#include "mdvi.h" -#include "private.h" - -void mdvi_init_kpathsea(const char *program, - const char *mfmode, const char *font, int dpi) -{ - const char *p; - - /* Stop meaningless output generation. */ - kpse_make_tex_discard_errors = FALSE; - - p = strrchr(program, '/'); - p = (p ? p + 1 : program); - kpse_set_program_name(program, p); - kpse_init_prog(p, dpi, mfmode, font); - kpse_set_program_enabled(kpse_any_glyph_format, 1, kpse_src_compile); - kpse_set_program_enabled(kpse_pk_format, 1, kpse_src_compile); - kpse_set_program_enabled(kpse_tfm_format, 1, kpse_src_compile); - kpse_set_program_enabled(kpse_ofm_format, 1, kpse_src_compile); -} - diff --git a/dvi/mdvi-lib/sp-epsf.c b/dvi/mdvi-lib/sp-epsf.c deleted file mode 100644 index ca13c86..0000000 --- a/dvi/mdvi-lib/sp-epsf.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -/* postscript specials */ - -#include -#include - -#include "mdvi.h" -#include "private.h" - -typedef struct { - double ox; - double oy; - double bw; - double bh; - double angle; -} EpsfBox; - -#define LLX 0 -#define LLY 1 -#define URX 2 -#define URY 3 -#define RWI 4 -#define RHI 5 -#define HOFF 6 -#define VOFF 7 -#define HSIZE 8 -#define VSIZE 9 -#define HSCALE 10 -#define VSCALE 11 -#define ANGLE 12 -#define CLIP 13 - -void epsf_special __PROTO((DviContext *dvi, char *prefix, char *arg)); - -/* Note: the given strings are modified in place */ -static char *parse_epsf_special(EpsfBox *box, char **ret, - char *prefix, char *arg) -{ - static struct { - char *name; - int has_arg; - char *value; - } keys[] = { - {"llx", 1, "0"}, - {"lly", 1, "0"}, - {"urx", 1, "0"}, - {"ury", 1, "0"}, - {"rwi", 1, "0"}, - {"rhi", 1, "0"}, - {"hoffset", 1, "0"}, - {"voffset", 1, "0"}, - {"hsize", 1, "612"}, - {"vsize", 1, "792"}, - {"hscale", 1, "100"}, - {"vscale", 1, "100"}, - {"angle", 1, "0"}, - {"clip", 0, "0"} - }; -#define NKEYS (sizeof(keys) / sizeof(keys[0])) - char *ptr; - char *filename; - int quoted; - double value[NKEYS]; - Uchar present[NKEYS]; - Buffer buffer; - char *name; - int i; - double originx; - double originy; - double hsize; - double vsize; - double hscale; - double vscale; - - /* this special has the form - * ["]file.ps["] [key=valye]* - */ - - /* scan the filename */ - while(*arg == ' ' || *arg == '\t') - arg++; - - /* make a copy of the string */ - ptr = arg; - - if(*ptr == '"') - for(name = ++ptr; *ptr && *ptr != '"'; ptr++); - else - for(name = ptr; *ptr && *ptr != ' ' && *ptr != '\t'; ptr++); - if(ptr == name) - return NULL; - *ptr++ = 0; - filename = name; - - /* reset values to defaults */ - for(i = 0; i < NKEYS; i++) { - value[i] = atof(keys[i].value); - present[i] = 0; - } - - buff_init(&buffer); - buff_add(&buffer, "@beginspecial ", 0); - - quoted = 0; - while(*ptr) { - const char *keyname; - char *val; - char *p; - - while(*ptr == ' ' || *ptr == '\t') - ptr++; - keyname = ptr; - - /* get the whole key=value pair */ - for(; *ptr && *ptr != ' ' && *ptr != '\t'; ptr++); - - if(*ptr) *ptr++ = 0; - /* now we shouldn't touch `ptr' anymore */ - - /* now work on this pair */ - p = strchr(keyname, '='); - if(p == NULL) - val = NULL; - else { - *p++ = 0; - if(*p == '"') { - val = ++p; - /* skip until closing quote */ - while(*p && *p != '"') - p++; - if(*p != '"') - warning( - _("%s: malformed value for key `%s'\n"), - filename, keyname); - } else - val = p; - } - - /* lookup the key */ - for(i = 0; i < NKEYS; i++) - if(STRCEQ(keys[i].name, keyname)) - break; - if(i == NKEYS) { - warning(_("%s: unknown key `%s' ignored\n"), - filename, keyname); - continue; - } - if(keys[i].has_arg && val == NULL) { - warning(_("%s: no argument for key `%s', using defaults\n"), - filename, keyname); - val = keys[i].value; - } else if(!keys[i].has_arg && val) { - warning(_("%s: argument `%s' ignored for key `%s'\n"), - filename, val, keyname); - val = NULL; - } - if(val) - value[i] = atof(val); - - /* put the argument */ - buff_add(&buffer, val, 0); - buff_add(&buffer, " @", 2); - buff_add(&buffer, keyname, 0); - buff_add(&buffer, " ", 1); - - /* remember that this option was given */ - present[i] = 0xff; - } - buff_add(&buffer, " @setspecial", 0); - - /* now compute the bounding box (code comes from dvips) */ - originx = 0; - originy = 0; - hscale = 1; - vscale = 1; - hsize = 0; - vsize = 0; - - if(present[HSIZE]) - hsize = value[HSIZE]; - if(present[VSIZE]) - vsize = value[VSIZE]; - if(present[HOFF]) - originx = value[HOFF]; - if(present[VOFF]) - originy = value[VOFF]; - if(present[HSCALE]) - hscale = value[HSCALE] / 100.0; - if(present[VSCALE]) - vscale = value[VSCALE] / 100.0; - if(present[URX] && present[LLX]) - hsize = value[URX] - value[LLX]; - if(present[URY] && present[LLY]) - vsize = value[URY] - value[LLY]; - if(present[RWI] || present[RHI]) { - if(present[RWI] && !present[RHI]) - hscale = vscale = value[RWI] / (10.0 * hsize); - else if(present[RHI] && !present[RWI]) - hscale = vscale = value[RHI] / (10.0 * vsize); - else { - hscale = value[RWI] / (10.0 * hsize); - vscale = value[RHI] / (10.0 * vsize); - } - } - - box->ox = originx; - box->oy = originy; - box->bw = hsize * hscale; - box->bh = vsize * vscale; - box->angle = value[ANGLE]; - - *ret = buffer.data; - - return filename; -} - -void epsf_special(DviContext *dvi, char *prefix, char *arg) -{ - char *file; - char *special; - EpsfBox box = {0, 0, 0, 0}; - int x, y; - int w, h; - double xf, vf; - - file = parse_epsf_special(&box, &special, prefix, arg); - if(file != NULL) - mdvi_free(special); - /* - * draw the bounding box. Notice that it is in PostScript units, - * so we have to convert it into pixels - */ - xf = dvi->params.dpi * dvi->params.mag / (72.0 * dvi->params.hshrink); - vf = dvi->params.vdpi * dvi->params.mag / (72.0 * dvi->params.vshrink); - x = FROUND(box.ox * xf); - y = FROUND(box.oy * vf); - w = FROUND(box.bw * xf); - h = FROUND(box.bh * vf); - dvi->device.draw_rule(dvi, dvi->pos.hh + x, dvi->pos.vv + y - h + 1, w, h, 0); -} diff --git a/dvi/mdvi-lib/special.c b/dvi/mdvi-lib/special.c deleted file mode 100644 index 23c070e..0000000 --- a/dvi/mdvi-lib/special.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include - -#include "mdvi.h" -#include "private.h" - -#if defined(WITH_REGEX_SPECIALS) && defined(HAVE_REGEX_H) -#include -#endif - -typedef struct _DviSpecial { - struct _DviSpecial *next; - struct _DviSpecial *prev; - char *label; - char *prefix; - size_t plen; -#ifdef WITH_REGEX_SPECIALS - regex_t reg; - int has_reg; -#endif - DviSpecialHandler handler; -} DviSpecial; - -static ListHead specials = {NULL, NULL, 0}; - -#define SPECIAL(x) \ - void x __PROTO((DviContext *, const char *, const char *)) - -static SPECIAL(sp_layer); -extern SPECIAL(epsf_special); -extern SPECIAL(do_color_special); - -static struct { - char *label; - char *prefix; - char *regex; - DviSpecialHandler handler; -} builtins[] = { - {"Layers", "layer", NULL, sp_layer}, - {"EPSF", "psfile", NULL, epsf_special} -}; -#define NSPECIALS (sizeof(builtins) / sizeof(builtins[0])) -static int registered_builtins = 0; - -static void register_builtin_specials(void) -{ - int i; - - ASSERT(registered_builtins == 0); - for(i = 0; i < NSPECIALS; i++) - mdvi_register_special( - builtins[i].label, - builtins[i].prefix, - builtins[i].regex, - builtins[i].handler, - 1 /* replace if exists */); - registered_builtins = 1; -} - -static DviSpecial *find_special_prefix(const char *prefix) -{ - DviSpecial *sp; - - /* should have a hash table here, but I'm so lazy */ - for(sp = (DviSpecial *)specials.head; sp; sp = sp->next) { - if(STRCEQ(sp->prefix, prefix)) - break; - } - return sp; -} - -int mdvi_register_special(const char *label, const char *prefix, - const char *regex, DviSpecialHandler handler, int replace) -{ - DviSpecial *sp; - int newsp = 0; - - if(!registered_builtins) - register_builtin_specials(); - - sp = find_special_prefix(prefix); - if(sp == NULL) { - sp = xalloc(DviSpecial); - sp->prefix = mdvi_strdup(prefix); - newsp = 1; - } else if(!replace) - return -1; - else { - mdvi_free(sp->label); - sp->label = NULL; - } - -#ifdef WITH_REGEX_SPECIALS - if(!newsp && sp->has_reg) { - regfree(&sp->reg); - sp->has_reg = 0; - } - if(regex && regcomp(&sp->reg, regex, REG_NOSUB) != 0) { - if(newsp) { - mdvi_free(sp->prefix); - mdvi_free(sp); - } - return -1; - } - sp->has_reg = (regex != NULL); -#endif - sp->handler = handler; - sp->label = mdvi_strdup(label); - sp->plen = strlen(prefix); - if(newsp) - listh_prepend(&specials, LIST(sp)); - DEBUG((DBG_SPECIAL, - "New \\special handler `%s' with prefix `%s'\n", - label, prefix)); - return 0; -} - -int mdvi_unregister_special(const char *prefix) -{ - DviSpecial *sp; - - sp = find_special_prefix(prefix); - if(sp == NULL) - return -1; - mdvi_free(sp->prefix); -#ifdef WITH_REGEX_SPECIALS - if(sp->has_reg) - regfree(&sp->reg); -#endif - listh_remove(&specials, LIST(sp)); - mdvi_free(sp); - return 0; -} - -#define IS_PREFIX_DELIMITER(x) (strchr(" \t\n:=", (x)) != NULL) - -int mdvi_do_special(DviContext *dvi, char *string) -{ - char *prefix; - char *ptr; - DviSpecial *sp; - - if(!registered_builtins) { - } - - if(!string || !*string) - return 0; - - /* skip leading spaces */ - while(*string && isspace(*string)) - string++; - - DEBUG((DBG_SPECIAL, "Looking for a handler for `%s'\n", string)); - - /* now try to find a match */ - ptr = string; - for(sp = (DviSpecial *)specials.head; sp; sp = sp->next) { -#ifdef WITH_REGEX_SPECIALS - if(sp->has_reg && !regexec(&sp->reg, ptr, 0, 0, 0)) - break; -#endif - /* check the prefix */ - if(STRNCEQ(sp->prefix, ptr, sp->plen)) { - ptr += sp->plen; - break; - } - } - - if(sp == NULL) { - DEBUG((DBG_SPECIAL, "None found\n")); - return -1; - } - - /* extract the prefix */ - if(ptr == string) { - prefix = NULL; - DEBUG((DBG_SPECIAL, - "REGEX match with `%s' (arg `%s')\n", - sp->label, ptr)); - } else { - if(*ptr) *ptr++ = 0; - prefix = string; - DEBUG((DBG_SPECIAL, - "PREFIX match with `%s' (prefix `%s', arg `%s')\n", - sp->label, prefix, ptr)); - } - - /* invoke the handler */ - sp->handler(dvi, prefix, ptr); - - return 0; -} - -void mdvi_flush_specials(void) -{ - DviSpecial *sp, *list; - - - for(list = (DviSpecial *)specials.head; (sp = list); ) { - list = sp->next; - if(sp->prefix) mdvi_free(sp->prefix); - if(sp->label) mdvi_free(sp->label); -#ifdef WITH_REGEX_SPECIALS - if(sp->has_reg) - regfree(&sp->reg); -#endif - mdvi_free(sp); - } - specials.head = NULL; - specials.tail = NULL; - specials.count = 0; -} - -/* some builtin specials */ - -void sp_layer(DviContext *dvi, const char *prefix, const char *arg) -{ - if(STREQ("push", arg)) - dvi->curr_layer++; - else if(STREQ("pop", arg)) { - if(dvi->curr_layer) - dvi->curr_layer--; - else - warning(_("%s: tried to pop top level layer\n"), - dvi->filename); - } else if(STREQ("reset", arg)) - dvi->curr_layer = 0; - DEBUG((DBG_SPECIAL, "Layer level: %d\n", dvi->curr_layer)); -} - diff --git a/dvi/mdvi-lib/sysdeps.h b/dvi/mdvi-lib/sysdeps.h deleted file mode 100644 index 8f89178..0000000 --- a/dvi/mdvi-lib/sysdeps.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ -#ifndef _SYSDEP_H -#define _SYSDEP_H 1 - -/* - * The purpose of this file is to define symbols that describe the - * system-dependent features we use. Namely, byte order, native integer - * types of various sizes, and safe pointer<->integer conversion. - */ - -#include "config.h" - -#ifdef WORDS_BIGENDIAN -#define WORD_BIG_ENDIAN 1 -#else -#define WORD_LITTLE_ENDIAN 1 -#endif - -typedef unsigned long Ulong; -typedef unsigned int Uint; -typedef unsigned short Ushort; -typedef unsigned char Uchar; - -/* this one's easy */ -typedef unsigned char Uint8; -typedef char Int8; - -/* define a datatype for 32bit integers (either int or long) */ -#if SIZEOF_LONG == 4 -typedef unsigned long Uint32; -typedef long Int32; -#else /* SIZEOF_LONG != 4 */ -#if SIZEOF_INT == 4 -typedef unsigned int Uint32; -typedef int Int32; -#else /* SIZEOF_INT != 4 */ -#ifdef __cplusplus -#include "No.appropriate.32bit.native.type.found.Fix.sysdeps.h" -#else -#error No appropriate 32bit native type found. Fix sysdeps.h -#endif /* ! __cplusplus */ -#endif /* SIZEOF_INT != 4 */ -#endif /* SIZEOF_LONG != 4 */ - -/* now 16bit integers (one of long, int or short) */ -#if SIZEOF_SHORT == 2 -typedef unsigned short Uint16; -typedef short Int16; -#else /* SIZEOF_SHORT != 2 */ -#if SIZEOF_INT == 2 -typedef unsigned int Uint16; -typedef short Int16; -#else /* SIZEOF_INT != 2 */ -#ifdef __cplusplus -#include "No.appropriate.16bit.native.type.found.Fix.sysdeps.h" -#else -#error No appropriate 16bit native type found. Fix sysdeps.h -#endif /* ! __cplusplus */ -#endif /* SIZEOF_INT != 2 */ -#endif /* SIZEOF_SHORT != 2 */ - -/* - * An integer type to convert to and from pointers safely. All we do here is - * look for an integer type with the same size as a pointer. - */ -#if SIZEOF_LONG == SIZEOF_VOID_P -typedef unsigned long UINT; -typedef long INT; -#else -#if SIZEOF_INT == SIZEOF_VOID_P -typedef unsigned int UINT; -typedef int INT; -#else -#if SIZEOF_SHORT == SIZEOF_VOID_P -typedef unsigned short UINT; -typedef short INT; -#else -#ifdef __cplusplus -#include "No.native.pointer-compatible.integer.type.found.Fix.sysdeps.h" -#else -#error No native pointer-compatible integer type found. Fix sysdeps.h -#endif -#endif -#endif -#endif - -/* nice, uh? */ -typedef void *Pointer; - -/* macros to do the safe pointer <-> integer conversions */ -#define Ptr2Int(x) ((INT)((Pointer)(x))) -#define Int2Ptr(x) ((Pointer)((INT)(x))) - -#ifdef _NO_PROTO -#define __PROTO(x) () -#else -#define __PROTO(x) x -#endif - -#endif /* _SYSDEP_H */ diff --git a/dvi/mdvi-lib/t1.c b/dvi/mdvi-lib/t1.c deleted file mode 100644 index acbfa23..0000000 --- a/dvi/mdvi-lib/t1.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -/* - * Type1 font support for MDVI - * - * We use T1lib only as a rasterizer, not to draw glyphs. - */ - -#include "mdvi.h" - -#ifdef WITH_TYPE1_FONTS - -#include -#include -#include "private.h" - -static int t1lib_initialized = 0; - -typedef struct t1info { - struct t1info *next; - struct t1info *prev; - char *fontname; /* (short) name of this font */ - int t1id; /* T1lib's id for this font */ - int hasmetrics; /* have we processed this font? */ - TFMInfo *tfminfo; /* TFM data is shared */ - DviFontMapInfo mapinfo; - DviEncoding *encoding; -} T1Info; - -static void t1_font_remove __PROTO((T1Info *)); -static int t1_load_font __PROTO((DviParams *, DviFont *)); -static int t1_font_get_glyph __PROTO((DviParams *, DviFont *, int)); -static void t1_font_shrink_glyph - __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); -static void t1_free_data __PROTO((DviFont *)); -static void t1_reset_font __PROTO((DviFont *)); -static char *t1_lookup_font __PROTO((const char *, Ushort *, Ushort *)); - -/* only symbol exported by this file */ -DviFontInfo t1_font_info = { - "Type1", - 1, /* scaling supported by format */ - t1_load_font, - t1_font_get_glyph, - t1_font_shrink_glyph, - mdvi_shrink_glyph_grey, - t1_free_data, - t1_reset_font, - t1_lookup_font, /* lookup */ - kpse_type1_format, - NULL -}; - -/* this seems good enough for most DVI files */ -#define T1_HASH_SIZE 31 - -/* If these parameters change, we must delete all size information - * in all fonts, and reset the device resolutions in T1lib */ -static int t1lib_xdpi = -1; -static int t1lib_ydpi = -1; - -static ListHead t1fonts = {NULL, NULL, 0}; -static DviHashTable t1hash; - -/* Type1 fonts need their own `lookup' function. Here is how it works: - * First we try to find the font by its given name. If that fails, we - * query the font maps. A typical font map entry may contain the line - * - * ptmr8rn Times-Roman ".82 ExtendFont TeXBase1Encoding ReEncodeFont" <8r.enc private; - - if(info == NULL) - return; - DEBUG((DBG_FONTS, "(t1) resetting font `%s'\n", font->fontname)); - /* just mark the font as not having metric info. It will be reset - * automatically later */ - info->hasmetrics = 0; -} - -static void t1_transform_font(T1Info *info) -{ - if(!info->hasmetrics && info->encoding != NULL) { - DEBUG((DBG_TYPE1, "(t1) %s: encoding with vector `%s'\n", - info->fontname, info->encoding->name)); - T1_DeleteAllSizes(info->t1id); - if(T1_ReencodeFont(info->t1id, info->encoding->vector) < 0) - warning(_("%s: could not encode font\n"), info->fontname); - } - if(info->mapinfo.slant) { - DEBUG((DBG_TYPE1, "(t1) %s: slanting by %.3f\n", - info->fontname, - MDVI_FMAP_SLANT(&info->mapinfo))); - T1_SlantFont(info->t1id, - MDVI_FMAP_SLANT(&info->mapinfo)); - } - if(info->mapinfo.extend) { - DEBUG((DBG_TYPE1, "(t1) %s: extending by %.3f\n", - info->fontname, - MDVI_FMAP_EXTEND(&info->mapinfo))); - T1_ExtendFont(info->t1id, - MDVI_FMAP_EXTEND(&info->mapinfo)); - } -} - -/* if this function is called, we really need this font */ -static int t1_really_load_font(DviParams *params, DviFont *font, T1Info *info) -{ - int i; - T1Info *old; - int t1id; - int copied; - int status; - - DEBUG((DBG_TYPE1, "(t1) really_load_font(%s)\n", info->fontname)); - - /* if the parameters changed, reset T1lib */ - if(t1lib_xdpi != params->dpi || t1lib_ydpi != params->vdpi) - t1_reset_resolution(params->dpi, params->vdpi); - - /* if we already have a T1lib id, do nothing */ - if(info->t1id != -1) { - info->hasmetrics = 1; - /* apply slant and extend again */ - t1_transform_font(info); - return 0; - } - - /* before we even attempt to load the font, make sure we have metric - * data for it */ - info->tfminfo = mdvi_ps_get_metrics(info->fontname); - if(info->tfminfo == NULL) { - DEBUG((DBG_FONTS, - "(t1) %s: no metric data, font ignored\n", - info->fontname)); - goto t1_error; - } - /* fix this */ - font->design = info->tfminfo->design; - - /* check if we have a font with this name (maybe at a different size) */ - old = (T1Info *)mdvi_hash_lookup(&t1hash, (unsigned char *)info->fontname); - if(old == info) { - /* let's avoid confusion */ - old = NULL; - } - if(old && old->t1id != -1) { - /* let's take advantage of T1lib's font sharing */ - t1id = T1_CopyFont(old->t1id); - DEBUG((DBG_TYPE1, "(t1) %s -> %d (CopyFont)\n", - info->fontname, t1id)); - copied = 1; - } else { - t1id = T1_AddFont(font->filename); - DEBUG((DBG_TYPE1, "(t1) %s -> %d (AddFont)\n", - info->fontname, t1id)); - copied = 0; - } - if(t1id < 0) - goto t1_error; - info->t1id = t1id; - - /* - * a minor optimization: If the old font in the hash table has - * not been loaded yet, replace it by this one, so we can use - * CopyFont later. - */ - if(old && old->t1id == -1) { - DEBUG((DBG_TYPE1, "(t1) font `%s' exchanged in hash table\n", - info->fontname)); - mdvi_hash_remove(&t1hash, (unsigned char *)old->fontname); - mdvi_hash_add(&t1hash, (unsigned char *)info->fontname, - info, MDVI_HASH_UNCHECKED); - } - - /* now let T1lib load it */ - if(!copied && T1_LoadFont(info->t1id) < 0) { - DEBUG((DBG_TYPE1, "(t1) T1_LoadFont(%d) failed with error %d\n", - info->t1id, T1_errno)); - goto t1_error; - } - DEBUG((DBG_TYPE1, "(t1) T1_LoadFont(%d) -> Ok\n", info->t1id)); - - /* get information from the fontmap */ - status = mdvi_query_fontmap(&info->mapinfo, info->fontname); - if(!status && info->mapinfo.encoding) - info->encoding = mdvi_request_encoding(info->mapinfo.encoding); - t1_transform_font(info); - - i = info->tfminfo->hic - info->tfminfo->loc + 1; - if(i != font->hic - font->loc + 1) { - /* reset to optimal size */ - font->chars = mdvi_realloc(font->chars, i * sizeof(DviFontChar)); - } - - /* get the scaled characters metrics */ - get_tfm_chars(params, font, info->tfminfo, 0); - info->hasmetrics = 1; - - DEBUG((DBG_TYPE1, "(t1) font `%s' really-loaded\n", info->fontname)); - return 0; - -t1_error: - /* some error does not allows us to use this font. We need to reset - * the font structure, so the font system can try to read this - * font in a different class */ - - /* first destroy the private data */ - t1_font_remove(info); - /* now reset all chars -- this is the important part */ - mdvi_free(font->chars); - font->chars = NULL; - font->loc = font->hic = 0; - return -1; -} - -static int init_t1lib(DviParams *params) -{ - int t1flags; - -#ifdef WORD_LITTLE_ENDIAN - /* try making T1lib use bitmaps in our format, but if this - * fails we'll convert the bitmap ourselves */ - T1_SetBitmapPad(BITMAP_BITS); -#endif - T1_SetDeviceResolutions((float)params->dpi, (float)params->vdpi); - t1flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE|T1_NO_AFM; - if(DEBUGGING(TYPE1)) - t1flags |= LOGFILE; - if(T1_InitLib(t1flags) == NULL) - return (t1lib_initialized = -1); - if(DEBUGGING(TYPE1)) { - DEBUG((DBG_TYPE1, "T1lib debugging output saved in t1lib.log\n")); - T1_SetLogLevel(T1LOG_DEBUG); - } - /* initialize our hash table, but don't allocate memory for it - * until we use it */ - mdvi_hash_init(&t1hash); - DEBUG((DBG_TYPE1, "(t1) t1lib %s initialized -- resolution is (%d, %d), pad is %d bits\n", - T1_GetLibIdent(), params->dpi, params->vdpi, T1_GetBitmapPad())); - t1lib_initialized = 1; - t1lib_xdpi = params->dpi; - t1lib_ydpi = params->vdpi; - return 0; -} - -static int t1_load_font(DviParams *params, DviFont *font) -{ - T1Info *info; - int i; - - if(t1lib_initialized < 0) - return -1; - else if(t1lib_initialized == 0 && init_t1lib(params) < 0) - return -1; - - if(font->in != NULL) { - /* we don't need this */ - fclose(font->in); - font->in = NULL; - } - - info = xalloc(T1Info); - - /* - * mark the font as `unregistered' with T1lib. It will - * be added when we actually use it - */ - info->t1id = -1; - - /* add the font to our list */ - info->fontname = font->fontname; - info->hasmetrics = 0; - info->encoding = NULL; - info->mapinfo.psname = NULL; - info->mapinfo.encoding = NULL; - info->mapinfo.fontfile = NULL; - info->mapinfo.extend = 0; - info->mapinfo.slant = 0; - info->encoding = NULL; - - /* create the hash table if we have not done so yet */ - if(t1hash.nbucks == 0) - mdvi_hash_create(&t1hash, T1_HASH_SIZE); - mdvi_hash_add(&t1hash, (unsigned char *) info->fontname, info, MDVI_HASH_UNIQUE); - listh_append(&t1fonts, LIST(info)); - - font->private = info; - - /* reset everything */ - font->chars = xnalloc(DviFontChar, 256); - font->loc = 0; - font->hic = 255; - for(i = 0; i < 256; i++) { - font->chars[i].code = i; - font->chars[i].offset = 1; - font->chars[i].loaded = 0; - font->chars[i].glyph.data = NULL; - font->chars[i].shrunk.data = NULL; - font->chars[i].grey.data = NULL; - } - - return 0; -} - -#define GLYPH_WIDTH(g) \ - ((g)->metrics.rightSideBearing - (g)->metrics.leftSideBearing) -#define GLYPH_HEIGHT(g) \ - ((g)->metrics.ascent - (g)->metrics.descent) - -static inline BITMAP *t1_glyph_bitmap(GLYPH *glyph) -{ - BITMAP *bm; - int w, h; - - w = GLYPH_WIDTH(glyph); - h = GLYPH_HEIGHT(glyph); - - if(!w || !h) - return MDVI_GLYPH_EMPTY; - switch(glyph->bpp << 3) { - case 8: - bm = bitmap_convert_lsb8((unsigned char *)glyph->bits, w, h); - break; - default: - warning(_("(t1) unsupported bitmap pad size %d\n"), - glyph->bpp); - bm = MDVI_GLYPH_EMPTY; - break; - } - return bm; -} - -static void t1_font_shrink_glyph(DviContext *dvi, DviFont *font, DviFontChar *ch, DviGlyph *dest) -{ - double size; - GLYPH *glyph; - T1Info *info; - T1_TMATRIX matrix; - - info = (T1Info *)font->private; - ASSERT(info != NULL); - - DEBUG((DBG_TYPE1, "(t1) shrinking glyph for character %d in `%s' (%d,%d)\n", - ch->code, font->fontname, ch->width, ch->height)); - size = (double)font->scale / (dvi->params.tfm_conv * 0x100000); - size = 72.0 * size / 72.27; - matrix.cxx = 1.0/(double)dvi->params.hshrink; - matrix.cyy = 1.0/(double)dvi->params.vshrink; - matrix.cxy = 0.0; - matrix.cyx = 0.0; - glyph = T1_SetChar(info->t1id, ch->code, (float)size, &matrix); - - dest->data = t1_glyph_bitmap(glyph); - dest->x = -glyph->metrics.leftSideBearing; - dest->y = glyph->metrics.ascent; - dest->w = GLYPH_WIDTH(glyph); - dest->h = GLYPH_HEIGHT(glyph); - -#ifndef NODEBUG - if(DEBUGGING(BITMAP_DATA)) { - DEBUG((DBG_BITMAP_DATA, - "(t1) %s: t1_shrink_glyph(%d): (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n", - ch->glyph.w, ch->glyph.h, ch->glyph.x, ch->glyph.y, - dest->w, dest->h, dest->x, dest->y)); - bitmap_print(stderr, (BITMAP *)dest->data); - } -#endif - /* transform the glyph - we could do this with t1lib, but we do - * it ourselves for now */ - font_transform_glyph(dvi->params.orientation, dest); -} - -static int t1_font_get_glyph(DviParams *params, DviFont *font, int code) -{ - T1Info *info = (T1Info *)font->private; - GLYPH *glyph; - DviFontChar *ch; - double size; - T1_TMATRIX matrix; - int dpi; - - ASSERT(info != NULL); - if(!info->hasmetrics && t1_really_load_font(params, font, info) < 0) - return -1; - ch = FONTCHAR(font, code); - if(!ch || !glyph_present(ch)) - return -1; - ch->loaded = 1; - if(!ch->width || !ch->height) { - ch->glyph.x = ch->x; - ch->glyph.y = ch->y; - ch->glyph.w = ch->width; - ch->glyph.h = ch->height; - ch->glyph.data = NULL; - return 0; - } - - /* load the glyph with T1lib (this is done only once for each glyph) */ - - /* get size in TeX points (tfm_conv includes dpi and magnification) */ - size = (double)font->scale / (params->tfm_conv * 0x100000); - /* and transform into PostScript points */ - size = 72.0 * size / 72.27; - - dpi = Max(font->hdpi, font->vdpi); - /* we don't want the glyph to be cached twice (once by us, another by - * T1lib), so we use an identity matrix to tell T1lib not to keep the - * glyph around */ - matrix.cxx = (double)font->hdpi / dpi; - matrix.cyy = (double)font->vdpi / dpi; - matrix.cxy = matrix.cyx = 0.0; - glyph = T1_SetChar(info->t1id, ch->code, (float)size, &matrix); - if(glyph == NULL) { - ch->glyph.x = ch->x; - ch->glyph.y = ch->y; - ch->glyph.w = ch->width; - ch->glyph.h = ch->height; - ch->glyph.data = NULL; - ch->missing = 1; - return 0; - } - /* and make it a bitmap */ - ch->glyph.data = t1_glyph_bitmap(glyph); - ch->glyph.x = -glyph->metrics.leftSideBearing; - ch->glyph.y = glyph->metrics.ascent; - ch->glyph.w = GLYPH_WIDTH(glyph); - ch->glyph.h = GLYPH_HEIGHT(glyph); - - /* let's also fix the glyph's origin - * (which is not contained in the TFM) */ - ch->x = ch->glyph.x; - ch->y = ch->glyph.y; - /* let's fix these too */ - ch->width = ch->glyph.w; - ch->height = ch->glyph.h; - - return 0; -} - -static void t1_font_remove(T1Info *info) -{ - T1Info *old; - - /* first remove it from our list */ - listh_remove(&t1fonts, LIST(info)); - - /* it it's in the hash table, we may need to replace this by another font */ - old = (T1Info *)mdvi_hash_lookup(&t1hash, (unsigned char *)info->fontname); - if(old == info) { - mdvi_hash_remove(&t1hash, (unsigned char *) info->fontname); - /* go through the list and see if there is another - * font with this name */ - for(old = (T1Info *)t1fonts.head; old; old = old->next) - if(STREQ(old->fontname, info->fontname)) - break; - if(old != NULL) - mdvi_hash_add(&t1hash, (unsigned char *) old->fontname, old, - MDVI_HASH_UNCHECKED); - } - /* release our encoding vector */ - if(info->encoding) { - DEBUG((DBG_TYPE1, "(t1) %s: releasing vector `%s'\n", - info->fontname, info->encoding->name)); - mdvi_release_encoding(info->encoding, 1); - } - - /* now get rid of it */ - if(info->t1id != -1) { - DEBUG((DBG_TYPE1, "(t1) %s: T1_DeleteFont(%d)\n", - info->fontname, info->t1id)); - T1_DeleteFont(info->t1id); - } else - DEBUG((DBG_TYPE1, "(t1) %s: not loaded yet, DeleteFont skipped\n", - info->fontname)); - - if(info->tfminfo) - free_font_metrics(info->tfminfo); - /*mdvi_free(info->fontname);*/ - mdvi_free(info); -} - -static void t1_free_data(DviFont *font) -{ - /* called after all the glyphs are destroyed */ - - if(font->private == NULL) { - /* this is perfectly normal, it just means the font has - * not been requested by MDVI yet */ - return; - } - - /* destroy this data */ - - t1_font_remove((T1Info *)font->private); - font->private = NULL; - - /* - * if this is the last T1 font, reset the T1 library - * It is important that we do this, because this is will be called - * when the resolution or the magnification changes. - */ - if(t1fonts.count == 0) { - DEBUG((DBG_TYPE1, "(t1) last font removed -- closing T1lib\n")); - T1_CloseLib(); - t1lib_initialized = 0; - t1lib_xdpi = -1; - t1lib_ydpi = -1; - } -} - -#endif /* WITH_TYPE1_FONTS */ diff --git a/dvi/mdvi-lib/tfm.c b/dvi/mdvi-lib/tfm.c deleted file mode 100644 index 3779c6b..0000000 --- a/dvi/mdvi-lib/tfm.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include -#include -#include -#include - -#include "mdvi.h" -#include "private.h" - -static int tfm_load_font __PROTO((DviParams *, DviFont *)); -static int tfm_font_get_glyph __PROTO((DviParams *, DviFont *, int)); - -DviFontInfo tfm_font_info = { - "TFM", - 0, /* scaling not supported by format */ - tfm_load_font, - tfm_font_get_glyph, - mdvi_shrink_box, - mdvi_shrink_box, - NULL, /* free */ - NULL, /* reset */ - NULL, /* lookup */ - kpse_tfm_format, - NULL -}; - -DviFontInfo ofm_font_info = { - "OFM", - 0, /* scaling not supported by format */ - tfm_load_font, - tfm_font_get_glyph, - mdvi_shrink_box, - mdvi_shrink_box, - NULL, /* free */ - NULL, /* reset */ - NULL, /* lookup */ - kpse_ofm_format, - NULL -}; - -DviFontInfo afm_font_info = { - "AFM", - 0, /* scaling not supported by format */ - tfm_load_font, - tfm_font_get_glyph, - mdvi_shrink_box, - mdvi_shrink_box, - NULL, /* free */ - NULL, /* reset */ - NULL, /* lookup */ - kpse_afm_format, - NULL -}; - -#define TYPENAME(font) \ - ((font)->search.info ? (font)->search.info : "none") - -/* - * Although it does not seem that way, this conversion is independent of the - * shrinking factors, within roundoff (that's because `conv' and `vconv' - * have already been scaled by hshrink and vshrink, repsectively). We - * should really use `dviconv' and `dvivconv', but I'm not so sure those - * should be moved to the DviParams structure. - */ -#define XCONV(x) FROUND(params->conv * (x) * params->hshrink) -#define YCONV(y) FROUND(params->vconv * (y) * params->vshrink) - -/* this is used quite often in several places, so I made it standalone */ -int get_tfm_chars(DviParams *params, DviFont *font, TFMInfo *info, int loaded) -{ - Int32 z, alpha, beta; - int n; - DviFontChar *ch; - TFMChar *ptr; - - n = info->hic - info->loc + 1; - if(n != FONT_GLYPH_COUNT(font)) { - font->chars = mdvi_realloc(font->chars, - n * sizeof(DviFontChar)); - } - font->loc = info->loc; - font->hic = info->hic; - ch = font->chars; - ptr = info->chars; - - /* Prepare z, alpha and beta for TFM width computation */ - TFMPREPARE(font->scale, z, alpha, beta); - - /* get the character metrics */ - for(n = info->loc; n <= info->hic; ch++, ptr++, n++) { - int a, b, c, d; - - ch->offset = ptr->present; - if(ch->offset == 0) - continue; - /* this is what we came here for */ - ch->tfmwidth = TFMSCALE(z, ptr->advance, alpha, beta); - /* scale all other TFM units (so they are in DVI units) */ - a = TFMSCALE(z, ptr->left, alpha, beta); - b = TFMSCALE(z, ptr->right, alpha, beta); - c = TFMSCALE(z, ptr->height, alpha, beta); - d = TFMSCALE(z, ptr->depth, alpha, beta); - - /* now convert to unscaled pixels */ - ch->width = XCONV(b - a); - ch->height = YCONV(c - d); - if(ch->height < 0) ch->height = -ch->height; - ch->x = XCONV(a); - ch->y = YCONV(c); - /* - * the offset is not used, but we might as well set it to - * something meaningful (and it MUST be non-zero) - */ - ch->flags = 0; - ch->code = n; - ch->glyph.data = NULL; - ch->grey.data = NULL; - ch->shrunk.data = NULL; - ch->loaded = loaded; - } - - return 0; -} - -/* - * We use this function as a last resort to find the character widths in a - * font The DVI rendering code can correctly skip over a glyph if it knows - * its TFM width, which is what we try to find here. - */ -static int tfm_load_font(DviParams *params, DviFont *font) -{ - TFMInfo *tfm; - int type; - - switch(font->search.info->kpse_type) { - case kpse_tfm_format: - type = DviFontTFM; - break; - case kpse_afm_format: - type = DviFontAFM; - break; - case kpse_ofm_format: - type = DviFontOFM; - break; - default: - return -1; - } - - /* we don't need this */ - if(font->in) { - fclose(font->in); - font->in = NULL; - } - tfm = get_font_metrics(font->fontname, type, font->filename); - if(tfm == NULL) - return -1; - - if(tfm->checksum && font->checksum && tfm->checksum != font->checksum) { - warning(_("%s: Checksum mismatch (got %u, expected %u)\n"), - font->fontname, (unsigned)tfm->checksum, - (unsigned)font->checksum); - } - font->checksum = tfm->checksum; - font->design = tfm->design; - font->loc = 0; - font->hic = 0; - font->chars = NULL; - get_tfm_chars(params, font, tfm, 1); - - /* free everything */ - free_font_metrics(tfm); - - return 0; -} - -static int tfm_font_get_glyph(DviParams *params, DviFont *font, int code) -{ - DviFontChar *ch; - - ch = FONTCHAR(font, code); - if(!glyph_present(ch)) - return -1; - ch->glyph.x = ch->x; - ch->glyph.y = ch->y; - ch->glyph.w = ch->width; - ch->glyph.h = ch->height; - /* - * This has two purposes: (1) avoid unnecessary calls to this function, - * and (2) detect when the glyph data for a TFM font is actually used - * (we'll get a SEGV). Any occurrence of that is a bug. - */ - ch->glyph.data = MDVI_GLYPH_EMPTY; - - return 0; -} diff --git a/dvi/mdvi-lib/tfmfile.c b/dvi/mdvi-lib/tfmfile.c deleted file mode 100644 index 1ea1b13..0000000 --- a/dvi/mdvi-lib/tfmfile.c +++ /dev/null @@ -1,746 +0,0 @@ -/* tfmfile.c -- readers for TFM, AFM, OTFM-0 and OTFM-1 files */ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include /* tex-file.h needs this */ -#include -#include -#include -#include -#include - -#include "mdvi.h" -#include "private.h" - -#ifdef WITH_AFM_FILES -#undef TRUE -#undef FALSE -#include "afmparse.h" -#endif - -typedef struct tfmpool { - struct tfmpool *next; - struct tfmpool *prev; - char *short_name; - int links; - TFMInfo tfminfo; -} TFMPool; - -static ListHead tfmpool = {NULL, NULL, 0}; -static DviHashTable tfmhash; - -#define TFM_HASH_SIZE 31 - -#ifdef WORD_LITTLE_ENDIAN -static inline void swap_array(Uint32 *ptr, int n) -{ - Uint32 i; - - while(n-- > 0) { - i = *ptr; - *ptr++ = ((i & 0xff000000) >> 24) - | ((i & 0x00ff0000) >> 8) - | ((i & 0x0000ff00) << 8) - | ((i & 0x000000ff) << 24); - } -} -#endif - -#ifdef WITH_AFM_FILES - -static int __PROTO(ofm_load_file(const char *filename, TFMInfo *info)); - -/* reading of AFM files */ -/* macro to convert between AFM and TFM units */ -#define AFM2TFM(x) FROUND((double)(x) * 0x100000 / 1000) -int afm_load_file(const char *filename, TFMInfo *info) -{ - /* the information we want is: - * - tfmwidth - * - width and heights - * - character origins - */ - FontInfo *fi = NULL; - int status; - CharMetricInfo *cm; - FILE *in; - - in = fopen(filename, "r"); - if(in == NULL) - return -1; - status = afm_parse_file(in, &fi, P_GM); - fclose(in); - - if(status != ok) { - error(_("%s: Error reading AFM data\n"), filename); - return -1; - } - - /* aim high */ - info->chars = xnalloc(TFMChar, 256); - info->loc = 256; - info->hic = 0; - info->design = 0xa00000; /* fake -- 10pt */ - info->checksum = 0; /* no checksum */ - info->type = DviFontAFM; - mdvi_strncpy(info->coding, fi->gfi->encodingScheme, 63); - mdvi_strncpy(info->family, fi->gfi->familyName, 63); - - /* now get the data */ - for(cm = fi->cmi; cm < fi->cmi + fi->numOfChars; cm++) { - int code; - TFMChar *ch; - - code = cm->code; - if(code < 0 || code > 255) - continue; /* ignore it */ - ch = &info->chars[code]; - ch->present = 1; - if(code < info->loc) - info->loc = code; - if(code > info->hic) - info->hic = code; - ch->advance = AFM2TFM(cm->wx); - /* this is the `leftSideBearing' */ - ch->left = AFM2TFM(cm->charBBox.llx); - /* this is the height (ascent - descent) -- the sign is to follow - * TeX conventions, as opposed to Adobe's ones */ - ch->depth = -AFM2TFM(cm->charBBox.lly); - /* this is the width (rightSideBearing - leftSideBearing) */ - ch->right = AFM2TFM(cm->charBBox.urx); - /* this is the `ascent' */ - ch->height = AFM2TFM(cm->charBBox.ury); - } - - /* we don't need this anymore */ - afm_free_fontinfo(fi); - - /* optimize storage */ - if(info->loc > 0 || info->hic < 256) { - memmove(&info->chars[0], - &info->chars[info->loc], - (info->hic - info->loc + 1) * sizeof(TFMChar)); - info->chars = mdvi_realloc(info->chars, - (info->hic - info->loc + 1) * sizeof(TFMChar)); - } - - /* we're done */ - return 0; -} - -#endif /* WITH_AFM_FILES */ - -int tfm_load_file(const char *filename, TFMInfo *info) -{ - int lf, lh, bc, ec, nw, nh, nd, ne; - int i, n; - Uchar *tfm; - Uchar *ptr; - struct stat st; - int size; - FILE *in; - Int32 *cb; - Int32 *charinfo; - Int32 *widths; - Int32 *heights; - Int32 *depths; - Uint32 checksum; - - in = fopen(filename, "r"); - if(in == NULL) - return -1; - tfm = NULL; - - DEBUG((DBG_FONTS, "(mt) reading TFM file `%s'\n", - filename)); - /* We read the entire TFM file into core */ - if(fstat(fileno(in), &st) < 0) - return -1; - if(st.st_size == 0) - goto bad_tfm; - - /* allocate a word-aligned buffer to hold the file */ - size = 4 * ROUND(st.st_size, 4); - if(size != st.st_size) - warning(_("Warning: TFM file `%s' has suspicious size\n"), - filename); - tfm = (Uchar *)mdvi_malloc(size); - if(fread(tfm, st.st_size, 1, in) != 1) - goto error; - /* we don't need this anymore */ - fclose(in); - in = NULL; - - /* not a checksum, but serves a similar purpose */ - checksum = 0; - - ptr = tfm; - /* get the counters */ - lf = muget2(ptr); - lh = muget2(ptr); checksum += 6 + lh; - bc = muget2(ptr); - ec = muget2(ptr); checksum += ec - bc + 1; - nw = muget2(ptr); checksum += nw; - nh = muget2(ptr); checksum += nh; - nd = muget2(ptr); checksum += nd; - checksum += muget2(ptr); /* skip italics correction count */ - checksum += muget2(ptr); /* skip lig/kern table size */ - checksum += muget2(ptr); /* skip kern table size */ - ne = muget2(ptr); checksum += ne; - checksum += muget2(ptr); /* skip # of font parameters */ - - size = ec - bc + 1; - cb = (Int32 *)tfm; cb += 6 + lh; - charinfo = cb; cb += size; - widths = cb; cb += nw; - heights = cb; cb += nh; - depths = cb; - - if(widths[0] || heights[0] || depths[0] || - checksum != lf || bc - 1 > ec || ec > 255 || ne > 256) - goto bad_tfm; - - /* from this point on, no error checking is done */ - - /* now we're at the header */ - /* get the checksum */ - info->checksum = muget4(ptr); - /* get the design size */ - info->design = muget4(ptr); - /* get the coding scheme */ - if(lh > 2) { - /* get the coding scheme */ - i = n = msget1(ptr); - if(n < 0 || n > 39) { - warning(_("%s: font coding scheme truncated to 40 bytes\n"), - filename); - n = 39; - } - memcpy(info->coding, ptr, n); - info->coding[n] = 0; - ptr += i; - } else - strcpy(info->coding, "FontSpecific"); - /* get the font family */ - if(lh > 12) { - n = msget1(ptr); - if(n > 0) { - i = Max(n, 63); - memcpy(info->family, ptr, i); - info->family[i] = 0; - } else - strcpy(info->family, "unspecified"); - ptr += n; - } - /* now we don't read from `ptr' anymore */ - - info->loc = bc; - info->hic = ec; - info->type = DviFontTFM; - - /* allocate characters */ - info->chars = xnalloc(TFMChar, size); - - -#ifdef WORD_LITTLE_ENDIAN - /* byte-swap the three arrays at once (they are consecutive in memory) */ - swap_array((Uint32 *)widths, nw + nh + nd); -#endif - - /* get the relevant data */ - ptr = (Uchar *)charinfo; - for(i = bc; i <= ec; ptr += 3, i++) { - int ndx; - - ndx = (int)*ptr; ptr++; - info->chars[i-bc].advance = widths[ndx]; - /* TFM files lack this information */ - info->chars[i-bc].left = 0; - info->chars[i-bc].right = widths[ndx]; - info->chars[i-bc].present = (ndx != 0); - if(ndx) { - ndx = ((*ptr >> 4) & 0xf); - info->chars[i-bc].height = heights[ndx]; - ndx = (*ptr & 0xf); - info->chars[i-bc].depth = depths[ndx]; - } - } - - /* free everything */ - mdvi_free(tfm); - - return 0; - -bad_tfm: - error(_("%s: File corrupted, or not a TFM file\n"), filename); -error: - if(tfm) mdvi_free(tfm); - if(in) fclose(in); - return -1; -} - -static int ofm1_load_file(FILE *in, TFMInfo *info) -{ - int lf, lh, bc, ec, nw, nh, nd; - int nco, ncw, npc; - int i; - int n; - int size; - Int32 *tfm; - Int32 *widths; - Int32 *heights; - Int32 *depths; - TFMChar *tch; - TFMChar *end; - - lf = fuget4(in); - lh = fuget4(in); - bc = fuget4(in); - ec = fuget4(in); - nw = fuget4(in); - nh = fuget4(in); - nd = fuget4(in); - fuget4(in); /* italics */ - fuget4(in); /* lig-kern */ - fuget4(in); /* kern */ - fuget4(in); /* extensible recipe */ - fuget4(in); /* parameters */ - fuget4(in); /* direction */ - nco = fuget4(in); - ncw = fuget4(in); - npc = fuget4(in); - - /* get the checksum */ - info->checksum = fuget4(in); - /* the design size */ - info->design = fuget4(in); - /* get the coding scheme */ - if(lh > 2) { - /* get the coding scheme */ - i = n = fsget1(in); - if(n < 0 || n > 39) - n = 39; - fread(info->coding, 39, 1, in); - info->coding[n] = 0; - } else - strcpy(info->coding, "FontSpecific"); - /* get the font family */ - if(lh > 12) { - n = fsget1(in); - if(n > 0) { - i = Max(n, 63); - fread(info->family, i, 1, in); - info->family[i] = 0; - } else - strcpy(info->family, "unspecified"); - } - tfm = NULL; - - /* jump to the beginning of the char-info table */ - fseek(in, 4L*nco, SEEK_SET); - - size = ec - bc + 1; - info->loc = bc; - info->hic = ec; - info->chars = xnalloc(TFMChar, size); - end = info->chars + size; - - for(tch = info->chars, i = 0; i < ncw; i++) { - TFMChar ch; - int nr; - - /* in the characters we store the actual indices */ - ch.advance = fuget2(in); - ch.height = fuget1(in); - ch.depth = fuget1(in); - /* skip 2nd word */ - fuget4(in); - /* get # of repeats */ - nr = fuget2(in); - /* skip parameters */ - fseek(in, (long)npc * 2, SEEK_CUR); - /* if npc is odd, skip padding */ - if(npc & 1) fuget2(in); - - /* now repeat the character */ - while(nr-- >= 0 && tch < end) - memcpy(tch++, &ch, sizeof(TFMChar)); - if(tch == end) - goto bad_tfm; - } - - /* I wish we were done, but we aren't */ - - /* get the widths, heights and depths */ - size = nw + nh + nd; - tfm = xnalloc(Int32, size); - /* read them in one sweep */ - if(fread(tfm, 4, size, in) != size) { - mdvi_free(tfm); - goto bad_tfm; - } - - /* byte-swap things if necessary */ -#ifdef WORD_LITTLE_ENDIAN - swap_array((Uint32 *)tfm, size); -#endif - widths = tfm; - heights = widths + nw; - depths = heights + nh; - - if(widths[0] || heights[0] || depths[0]) - goto bad_tfm; - - /* now fix the characters */ - size = ec - bc + 1; - for(tch = info->chars; tch < end; tch++) { - tch->present = (tch->advance != 0); - tch->advance = widths[tch->advance]; - tch->height = heights[tch->height]; - tch->depth = depths[tch->depth]; - tch->left = 0; - tch->right = tch->advance; - } - - /* NOW we're done */ - mdvi_free(tfm); - return 0; - -bad_tfm: - if(tfm) mdvi_free(tfm); - return -1; -} - -/* we don't read OFM files into memory, because they can potentially be large */ -static int ofm_load_file(const char *filename, TFMInfo *info) -{ - int lf, lh, bc, ec, nw, nh, nd; - int i, n; - Int32 *tfm; - Uchar *ptr; - int size; - FILE *in; - Int32 *cb; - Int32 *charinfo; - Int32 *widths; - Int32 *heights; - Int32 *depths; - Uint32 checksum; - int olevel; - int nwords; - - in = fopen(filename, "r"); - if(in == NULL) - return -1; - - /* not a checksum, but serves a similar purpose */ - checksum = 0; - - /* get the counters */ - /* get file level */ - olevel = fsget2(in); - if(olevel != 0) - goto bad_tfm; - olevel = fsget2(in); - if(olevel != 0) { - DEBUG((DBG_FONTS, "(mt) reading Level-1 OFM file `%s'\n", - filename)); - /* we handle level-1 files separately */ - if(ofm1_load_file(in, info) < 0) - goto bad_tfm; - return 0; - } - - DEBUG((DBG_FONTS, "(mt) reading Level-0 OFM file `%s'\n", filename)); - nwords = 14; - lf = fuget4(in); checksum = nwords; - lh = fuget4(in); checksum += lh; - bc = fuget4(in); - ec = fuget4(in); checksum += 2 * (ec - bc + 1); - nw = fuget4(in); checksum += nw; - nh = fuget4(in); checksum += nh; - nd = fuget4(in); checksum += nd; - checksum += fuget4(in); /* skip italics correction count */ - checksum += 2*fuget4(in); /* skip lig/kern table size */ - checksum += fuget4(in); /* skip kern table size */ - checksum += 2*fuget4(in); /* skip extensible recipe count */ - checksum += fuget4(in); /* skip # of font parameters */ - - /* I have found several .ofm files that seem to have the - * font-direction word missing, so we try to detect that here */ - if(checksum == lf + 1) { - DEBUG((DBG_FONTS, "(mt) font direction missing in `%s'\n", - filename)); - checksum--; - nwords--; - } else { - /* skip font direction */ - fuget4(in); - } - - if(checksum != lf || bc > ec + 1 || ec > 65535) - goto bad_tfm; - - /* now we're at the header */ - - /* get the checksum */ - info->checksum = fuget4(in); - /* get the design size */ - info->design = fuget4(in); - - /* get the coding scheme */ - if(lh > 2) { - /* get the coding scheme */ - i = n = fsget1(in); - if(n < 0 || n > 39) { - warning(_("%s: font coding scheme truncated to 40 bytes\n"), - filename); - n = 39; - } - fread(info->coding, 39, 1, in); - info->coding[n] = 0; - } else - strcpy(info->coding, "FontSpecific"); - /* get the font family */ - if(lh > 12) { - n = fsget1(in); - if(n > 0) { - i = Max(n, 63); - fread(info->family, i, 1, in); - info->family[i] = 0; - } else - strcpy(info->family, "unspecified"); - } - - /* now skip anything else in the header */ - fseek(in, 4L*(nwords + lh), SEEK_SET); - /* and read everything at once */ - size = 2*(ec - bc + 1) + nw + nh + nd; - tfm = xnalloc(Int32, size * sizeof(Int32)); - if(fread(tfm, 4, size, in) != size) { - mdvi_free(tfm); - goto bad_tfm; - } - /* byte-swap all the tables at once */ -#ifdef WORD_LITTLE_ENDIAN - swap_array((Uint32 *)tfm, size); -#endif - cb = tfm; - charinfo = cb; cb += 2*(ec - bc + 1); - widths = cb; cb += nw; - heights = cb; cb += nh; - depths = cb; - - if(widths[0] || heights[0] || depths[0]) { - mdvi_free(tfm); - goto bad_tfm; - } - - /* from this point on, no error checking is done */ - - /* we don't need this anymore */ - fclose(in); - - /* now we don't read from `ptr' anymore */ - - info->loc = bc; - info->hic = ec; - info->type = DviFontTFM; - - /* allocate characters */ - info->chars = xnalloc(TFMChar, size); - - /* get the relevant data */ - ptr = (Uchar *)charinfo; - for(i = bc; i <= ec; ptr += 4, i++) { - int ndx; - - ndx = muget2(ptr); - info->chars[i-bc].advance = widths[ndx]; - /* TFM files lack this information */ - info->chars[i-bc].left = 0; - info->chars[i-bc].right = widths[ndx]; - info->chars[i-bc].present = (ndx != 0); - ndx = muget1(ptr); - info->chars[i-bc].height = heights[ndx]; - ndx = muget1(ptr); - info->chars[i-bc].depth = depths[ndx]; - } - - mdvi_free(tfm); - return 0; - -bad_tfm: - error(_("%s: File corrupted, or not a TFM file\n"), filename); - fclose(in); - return -1; -} - -char *lookup_font_metrics(const char *name, int *type) -{ - char *file; - - switch(*type) { -#ifndef WITH_AFM_FILES - case DviFontAny: -#endif - case DviFontTFM: - file = kpse_find_tfm(name); - *type = DviFontTFM; - break; - case DviFontOFM: { - file = kpse_find_ofm(name); - /* we may have gotten a TFM back */ - if(file != NULL) { - const char *ext = file_extension(file); - if(ext && STREQ(ext, "tfm")) - *type = DviFontTFM; - } - break; - } -#ifdef WITH_AFM_FILES - case DviFontAFM: - file = kpse_find_file(name, kpse_afm_format, 0); - break; - case DviFontAny: - file = kpse_find_file(name, kpse_afm_format, 0); - *type = DviFontAFM; - if(file == NULL) { - file = kpse_find_tfm(name); - *type = DviFontTFM; - } - break; -#endif - default: - return NULL; - } - - return file; -} - -/* - * The next two functions are just wrappers for the font metric loaders, - * and use the pool of TFM data - */ - -/* this is how we interpret arguments: - * - if filename is NULL, we look for files of the given type, - * unless type is DviFontAny, in which case we try all the - * types we know of. - * - if filename is not NULL, we look at `type' to decide - * how to read the file. If type is DviFontAny, we just - * return an error. - */ -TFMInfo *get_font_metrics(const char *short_name, int type, const char *filename) -{ - TFMPool *tfm = NULL; - int status; - char *file; - - if(tfmpool.count) { - tfm = (TFMPool *)mdvi_hash_lookup(&tfmhash, - MDVI_KEY(short_name)); - if(tfm != NULL) { - DEBUG((DBG_FONTS, "(mt) reusing metric file `%s' (%d links)\n", - short_name, tfm->links)); - tfm->links++; - return &tfm->tfminfo; - } - } - - file = filename ? (char *)filename : lookup_font_metrics(short_name, &type); - if(file == NULL) - return NULL; - - tfm = xalloc(TFMPool); - DEBUG((DBG_FONTS, "(mt) loading font metric data from `%s'\n", file, file)); - switch(type) { - case DviFontTFM: - status = tfm_load_file(file, &tfm->tfminfo); - break; - case DviFontOFM: - status = ofm_load_file(file, &tfm->tfminfo); - break; -#ifdef WITH_AFM_FILES - case DviFontAFM: - status = afm_load_file(file, &tfm->tfminfo); - break; -#endif - default: - status = -1; - break; - } - if(file != filename) - mdvi_free(file); - if(status < 0) { - mdvi_free(tfm); - return NULL; - } - tfm->short_name = mdvi_strdup(short_name); - - /* add it to the pool */ - if(tfmpool.count == 0) - mdvi_hash_create(&tfmhash, TFM_HASH_SIZE); - mdvi_hash_add(&tfmhash, MDVI_KEY(tfm->short_name), - tfm, MDVI_HASH_UNCHECKED); - listh_prepend(&tfmpool, LIST(tfm)); - tfm->links = 1; - - return &tfm->tfminfo; -} - -void free_font_metrics(TFMInfo *info) -{ - TFMPool *tfm; - - if(tfmpool.count == 0) - return; - /* get the entry -- can't use the hash table for this, because - * we don't have the short name */ - for(tfm = (TFMPool *)tfmpool.head; tfm; tfm = tfm->next) - if(info == &tfm->tfminfo) - break; - if(tfm == NULL) - return; - if(--tfm->links > 0) { - DEBUG((DBG_FONTS, "(mt) %s not removed, still in use\n", - tfm->short_name)); - return; - } - mdvi_hash_remove_ptr(&tfmhash, MDVI_KEY(tfm->short_name)); - - DEBUG((DBG_FONTS, "(mt) removing unused TFM data for `%s'\n", tfm->short_name)); - listh_remove(&tfmpool, LIST(tfm)); - mdvi_free(tfm->short_name); - mdvi_free(tfm->tfminfo.chars); - mdvi_free(tfm); -} - -void flush_font_metrics(void) -{ - TFMPool *ptr; - - for(; (ptr = (TFMPool *)tfmpool.head); ) { - tfmpool.head = LIST(ptr->next); - - mdvi_free(ptr->short_name); - mdvi_free(ptr->tfminfo.chars); - mdvi_free(ptr); - } - mdvi_hash_reset(&tfmhash, 0); -} diff --git a/dvi/mdvi-lib/tt.c b/dvi/mdvi-lib/tt.c deleted file mode 100644 index 2e69940..0000000 --- a/dvi/mdvi-lib/tt.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include "mdvi.h" - -#ifdef WITH_TRUETYPE_FONTS - -#include -#include -#include -#include - -#include "private.h" - -static TT_Engine tt_handle; -static int initialized = 0; - -typedef struct ftinfo { - struct ftinfo *next; - struct ftinfo *prev; - char *fontname; - char *fmfname; - TT_Face face; - TT_Instance instance; - TT_Glyph glyph; - int hasmetrics; - int loaded; - int fmftype; - TFMInfo *tfminfo; - DviFontMapInfo mapinfo; - DviEncoding *encoding; -} FTInfo; - -static int tt_load_font __PROTO((DviParams *, DviFont *)); -static int tt_font_get_glyph __PROTO((DviParams *, DviFont *, int)); -static void tt_free_data __PROTO((DviFont *)); -static void tt_reset_font __PROTO((DviFont *)); -static void tt_shrink_glyph - __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *)); -static void tt_font_remove __PROTO((FTInfo *)); - -DviFontInfo tt_font_info = { - "TT", - 0, - tt_load_font, - tt_font_get_glyph, - tt_shrink_glyph, - mdvi_shrink_glyph_grey, - tt_free_data, /* free */ - tt_reset_font, /* reset */ - NULL, /* lookup */ - kpse_truetype_format, - NULL -}; - -#define FT_HASH_SIZE 31 - -static ListHead ttfonts = {NULL, NULL, 0}; - -static int init_freetype(void) -{ - TT_Error code; - - ASSERT(initialized == 0); - code = TT_Init_FreeType(&tt_handle); - if(code) { - DEBUG((DBG_TT, "(tt) Init_Freetype: error %d\n", code)); - return -1; - } - code = TT_Init_Post_Extension(tt_handle); - if(code) { - TT_Done_FreeType(tt_handle); - return -1; - } - /* we're on */ - initialized = 1; - return 0; -} - -static void tt_encode_font(DviFont *font, FTInfo *info) -{ - TT_Face_Properties prop; - int i; - - if(TT_Get_Face_Properties(info->face, &prop)) - return; - - for(i = 0; i < prop.num_Glyphs; i++) { - char *string; - int ndx; - - if(TT_Get_PS_Name(info->face, i, &string)) - continue; - ndx = mdvi_encode_glyph(info->encoding, string); - if(ndx < font->loc || ndx > font->hic) - continue; - font->chars[ndx - font->loc].code = i; - } -} - -static int tt_really_load_font(DviParams *params, DviFont *font, FTInfo *info) -{ - DviFontChar *ch; - TFMChar *ptr; - Int32 z, alpha, beta; - int i; - FTInfo *old; - TT_Error status; - double point_size; - static int warned = 0; - TT_CharMap cmap; - TT_Face_Properties props; - int map_found; - - DEBUG((DBG_TT, "(tt) really_load_font(%s)\n", info->fontname)); - - /* get the point size */ - point_size = (double)font->scale / (params->tfm_conv * 0x100000); - point_size = 72.0 * point_size / 72.27; - if(info->loaded) { - /* just reset the size info */ - TT_Set_Instance_Resolutions(info->instance, - params->dpi, params->vdpi); - TT_Set_Instance_CharSize(info->instance, FROUND(point_size * 64)); - /* FIXME: should extend/slant again */ - info->hasmetrics = 1; - return 0; - } - - /* load the face */ - DEBUG((DBG_TT, "(tt) loading new face `%s'\n", - info->fontname)); - status = TT_Open_Face(tt_handle, font->filename, &info->face); - if(status) { - warning(_("(tt) %s: could not load face: %s\n"), - info->fontname, TT_ErrToString18(status)); - return -1; - } - - /* create a new instance of this face */ - status = TT_New_Instance(info->face, &info->instance); - if(status) { - warning(_("(tt) %s: could not create face: %s\n"), - info->fontname, TT_ErrToString18(status)); - TT_Close_Face(info->face); - return -1; - } - - /* create a glyph */ - status = TT_New_Glyph(info->face, &info->glyph); - if(status) { - warning(_("(tt) %s: could not create glyph: %s\n"), - info->fontname, TT_ErrToString18(status)); - goto tt_error; - } - - /* - * We'll try to find a Unicode charmap. It's not that important that we - * actually find one, especially if the fontmap files are installed - * properly, but it's good to have some predefined behaviour - */ - TT_Get_Face_Properties(info->face, &props); - - map_found = -1; - for(i = 0; map_found < 0 && i < props.num_CharMaps; i++) { - TT_UShort pid, eid; - - TT_Get_CharMap_ID(info->face, i, &pid, &eid); - switch(pid) { - case TT_PLATFORM_APPLE_UNICODE: - map_found = i; - break; - case TT_PLATFORM_ISO: - if(eid == TT_ISO_ID_7BIT_ASCII || - eid == TT_ISO_ID_8859_1) - map_found = 1; - break; - case TT_PLATFORM_MICROSOFT: - if(eid == TT_MS_ID_UNICODE_CS) - map_found = 1; - break; - } - } - if(map_found < 0) { - warning(_("(tt) %s: no acceptable map found, using #0\n"), - info->fontname); - map_found = 0; - } - DEBUG((DBG_TT, "(tt) %s: using charmap #%d\n", - info->fontname, map_found)); - TT_Get_CharMap(info->face, map_found, &cmap); - - DEBUG((DBG_TT, "(tt) %s: Set_Char_Size(%.2f, %d, %d)\n", - font->fontname, point_size, font->hdpi, font->vdpi)); - status = TT_Set_Instance_Resolutions(info->instance, - params->dpi, params->vdpi); - if(status) { - error(_("(tt) %s: could not set resolution: %s\n"), - info->fontname, TT_ErrToString18(status)); - goto tt_error; - } - status = TT_Set_Instance_CharSize(info->instance, - FROUND(point_size * 64)); - if(status) { - error(_("(tt) %s: could not set point size: %s\n"), - info->fontname, TT_ErrToString18(status)); - goto tt_error; - } - - /* after this point we don't fail */ - - /* get information from the fontmap */ - status = mdvi_query_fontmap(&info->mapinfo, info->fontname); - if(!status && info->mapinfo.encoding) - info->encoding = mdvi_request_encoding(info->mapinfo.encoding); - else - info->encoding = NULL; - - if(info->encoding != NULL) { - TT_Post post; - - status = TT_Load_PS_Names(info->face, &post); - if(status) { - warning(_("(tt) %s: could not load PS name table\n"), - info->fontname); - mdvi_release_encoding(info->encoding, 0); - info->encoding = NULL; - } - } - - /* get the metrics. If this fails, it's not fatal, but certainly bad */ - info->tfminfo = get_font_metrics(info->fontname, - info->fmftype, info->fmfname); - - if(info->tfminfo == NULL) { - warning("(tt) %s: no metrics data, font ignored\n", - info->fontname); - goto tt_error; - } - /* fix this */ - font->design = info->tfminfo->design; - - /* get the scaled character metrics */ - get_tfm_chars(params, font, info->tfminfo, 0); - - if(info->encoding) - tt_encode_font(font, info); - else { - warning(_("%s: no encoding vector found, expect bad output\n"), - info->fontname); - /* this is better than nothing */ - for(i = font->loc; i <= font->hic; i++) - font->chars[i - font->loc].code = TT_Char_Index(cmap, i); - } - - info->loaded = 1; - info->hasmetrics = 1; - return 0; - -tt_error: - tt_font_remove(info); - mdvi_free(font->chars); - font->chars = NULL; - font->loc = font->hic = 0; - return -1; -} - -static int tt_load_font(DviParams *params, DviFont *font) -{ - int i; - FTInfo *info; - - if(!initialized && init_freetype() < 0) - return -1; - - if(font->in != NULL) { - fclose(font->in); - font->in = NULL; - } - - info = xalloc(FTInfo); - - memzero(info, sizeof(FTInfo)); - info->fmftype = DviFontAny; /* any metrics type will do */ - info->fmfname = lookup_font_metrics(font->fontname, &info->fmftype); - info->fontname = font->fontname; - info->hasmetrics = 0; - info->loaded = 0; - - /* these will be obtained from the fontmaps */ - info->mapinfo.psname = NULL; - info->mapinfo.encoding = NULL; - info->mapinfo.fontfile = NULL; - info->mapinfo.extend = 0; - info->mapinfo.slant = 0; - - /* initialize these */ - font->chars = xnalloc(DviFontChar, 256); - font->loc = 0; - font->hic = 255; - for(i = 0; i < 256; i++) { - font->chars[i].offset = 1; - font->chars[i].glyph.data = NULL; - font->chars[i].shrunk.data = NULL; - font->chars[i].grey.data = NULL; - } - - if(info->fmfname == NULL) - warning(_("(tt) %s: no font metric data\n"), font->fontname); - - listh_append(&ttfonts, LIST(info)); - font->private = info; - - return 0; -} - -static int tt_get_bitmap(DviParams *params, DviFont *font, - int code, double xscale, double yscale, DviGlyph *glyph) -{ - TT_Outline outline; - TT_Raster_Map raster; - TT_BBox bbox; - TT_Glyph_Metrics metrics; - TT_Matrix mat; - FTInfo *info; - int error; - int have_outline = 0; - int w, h; - - info = (FTInfo *)font->private; - if(info == NULL) - return -1; - - error = TT_Load_Glyph(info->instance, info->glyph, - code, TTLOAD_DEFAULT); - if(error) goto tt_error; - error = TT_Get_Glyph_Outline(info->glyph, &outline); - if(error) goto tt_error; - have_outline = 1; - mat.xx = FROUND(xscale * 65536); - mat.yy = FROUND(yscale * 65536); - mat.yx = 0; - mat.xy = 0; - TT_Transform_Outline(&outline, &mat); - error = TT_Get_Outline_BBox(&outline, &bbox); - if(error) goto tt_error; - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = (bbox.xMax + 63) & -64; - bbox.yMax = (bbox.yMax + 63) & -64; - w = (bbox.xMax - bbox.xMin) / 64; - h = (bbox.yMax - bbox.yMin) / 64; - - glyph->w = w; - glyph->h = h; - glyph->x = -bbox.xMin / 64; - glyph->y = bbox.yMax / 64; - if(!w || !h) - goto tt_error; - raster.rows = h; - raster.width = w; - raster.cols = ROUND(w, 8); - raster.size = h * raster.cols; - raster.flow = TT_Flow_Down; - raster.bitmap = mdvi_calloc(h, raster.cols); - - TT_Translate_Outline(&outline, -bbox.xMin, -bbox.yMin); - TT_Get_Outline_Bitmap(tt_handle, &outline, &raster); - glyph->data = bitmap_convert_msb8(raster.bitmap, w, h); - TT_Done_Outline(&outline); - mdvi_free(raster.bitmap); - - return 0; -tt_error: - if(have_outline) - TT_Done_Outline(&outline); - return -1; -} - -static int tt_font_get_glyph(DviParams *params, DviFont *font, int code) -{ - FTInfo *info = (FTInfo *)font->private; - DviFontChar *ch; - int error; - double xs, ys; - int dpi; - - ASSERT(info != NULL); - if(!info->hasmetrics && tt_really_load_font(params, font, info) < 0) - return -1; - ch = FONTCHAR(font, code); - if(!ch || !glyph_present(ch)) - return -1; - ch->loaded = 1; - if(!ch->width || !ch->height) - goto blank; - if(ch->code == 0) { - ch->glyph.data = NULL; - goto missing; - } - /* get the glyph */ - dpi = Max(font->hdpi, font->vdpi); - error = tt_get_bitmap(params, font, ch->code, - (double)font->hdpi / dpi, - (double)font->vdpi / dpi, - &ch->glyph); - if(error) - goto missing; - ch->x = ch->glyph.x; - ch->y = ch->glyph.y; - - return 0; - -missing: - ch->glyph.data = MDVI_GLYPH_EMPTY; - ch->missing = 1; -blank: - ch->glyph.w = ch->width; - ch->glyph.h = ch->height; - ch->glyph.x = ch->x; - ch->glyph.y = ch->y; - return 0; -} - -static void tt_shrink_glyph(DviContext *dvi, DviFont *font, DviFontChar *ch, DviGlyph *dest) -{ - tt_get_bitmap(&dvi->params, font, - ch->code, - (double)font->hdpi / (dvi->params.dpi * dvi->params.hshrink), - (double)font->vdpi / (dvi->params.vdpi * dvi->params.vshrink), - dest); - /* transform the glyph for the current orientation */ - font_transform_glyph(dvi->params.orientation, dest); -} - -static void tt_reset_font(DviFont *font) -{ - FTInfo *info = (FTInfo *)font->private; - - if(info == NULL) - return; - info->hasmetrics = 0; -} - -static void tt_font_remove(FTInfo *info) -{ - FTInfo *old; - - if(info->loaded) { - /* all fonts in the hash table have called TT_Open_Face */ - TT_Done_Instance(info->instance); - TT_Close_Face(info->face); - } - listh_remove(&ttfonts, LIST(info)); - /* release our encodings */ - if(info->encoding) - mdvi_release_encoding(info->encoding, 1); - /* and destroy the font */ - if(info->tfminfo) - free_font_metrics(info->tfminfo); - if(info->fmfname) - mdvi_free(info->fmfname); - mdvi_free(info); -} - -static void tt_free_data(DviFont *font) -{ - if(font->private == NULL) - return; - - tt_font_remove((FTInfo *)font->private); - if(initialized && ttfonts.count == 0) { - DEBUG((DBG_TT, "(tt) last font removed -- closing FreeType\n")); - TT_Done_FreeType(tt_handle); - initialized = 0; - } -} - -#endif /* WITH_TRUETYPE_FONTS */ diff --git a/dvi/mdvi-lib/util.c b/dvi/mdvi-lib/util.c deleted file mode 100644 index c1cc649..0000000 --- a/dvi/mdvi-lib/util.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "private.h" - -static char *const messages[] = { - _G("Ooops!"), - _G("Aieeeee!!"), - _G("Ouch!"), - _G("Houston, we have a problem"), - _G("3.. 2.. 1.. BOOM!"), - _G("I'm history"), - _G("I'm going down"), - _G("I smell a rat") -}; -#define NMSGS (sizeof(messages) / sizeof(char *)) - -static FILE *logfile = NULL; -static int _mdvi_log_level; - -int mdvi_set_logfile(const char *filename); -int mdvi_set_logstream(FILE *file); -int mdvi_set_loglevel(int level); - -static void vputlog(int level, const char *head, const char *format, va_list ap) -{ - if(logfile != NULL && _mdvi_log_level >= level) { - if(head != NULL) - fprintf(logfile, "%s: ", head); - vfprintf(logfile, format, ap); - } -} - -int mdvi_set_logfile(const char *filename) -{ - FILE *f = NULL; - - if(filename && (f = fopen(filename, "w")) == NULL) - return -1; - if(logfile != NULL && !isatty(fileno(logfile))) { - fclose(logfile); - logfile = NULL; - } - if(filename) - logfile = f; - return 0; -} - -int mdvi_set_logstream(FILE *file) -{ - if(logfile && !isatty(fileno(logfile))) { - fclose(logfile); - logfile = NULL; - } - logfile = file; - return 0; -} - -int mdvi_set_loglevel(int level) -{ - int old = _mdvi_log_level; - - _mdvi_log_level = level; - return old; -} - -#ifndef NODEBUG -Uint32 _mdvi_debug_mask = 0; - -void __debug(int mask, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - if(_mdvi_debug_mask & mask) { - if(!DEBUGGING(SILENT)) { - fprintf(stderr, "Debug: "); - vfprintf(stderr, format, ap); - fflush(stderr); - } -#ifndef __GNUC__ - /* let's be portable */ - va_end(ap); - va_start(ap, format); -#endif - vputlog(LOG_DEBUG, "Debug", format, ap); - } - va_end(ap); -} -#endif - -void message(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - if(_mdvi_log_level >= LOG_INFO) { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, ap); -#ifndef __GNUC__ - va_end(ap); - va_start(ap, format); -#endif - } - vputlog(LOG_INFO, NULL, format, ap); - va_end(ap); -} - -void crash(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - fprintf(stderr, "%s: %s: ", - program_name, - gettext(messages[(int)time(NULL) % NMSGS])); - vfprintf(stderr, format, ap); -#ifndef __GNUC__ - /* let's be portable */ - va_end(ap); - va_start(ap, format); -#endif - vputlog(LOG_ERROR, _("Crashing"), format, ap); - va_end(ap); - abort(); -} - -void error(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - fprintf(stderr, _("%s: Error: "), program_name); - vfprintf(stderr, format, ap); -#ifndef __GNUC__ - /* let's be portable */ - va_end(ap); - va_start(ap, format); -#endif - vputlog(LOG_ERROR, _("Error"), format, ap); - va_end(ap); -} - -void warning(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - fprintf(stderr, _("%s: Warning: "), program_name); - vfprintf(stderr, format, ap); -#ifndef __GNUC__ - /* let's be portable */ - va_end(ap); - va_start(ap, format); -#endif - vputlog(LOG_WARN, _("Warning"), format, ap); - va_end(ap); -} - -void fatal(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - fprintf(stderr, _("%s: Fatal: "), program_name); - vfprintf(stderr, format, ap); -#ifndef __GNUC__ - /* let's be portable */ - va_end(ap); - va_start(ap, format); -#endif - vputlog(LOG_ERROR, _("Fatal"), format, ap); - va_end(ap); -#ifndef NODEBUG - abort(); -#else - exit(EXIT_FAILURE); -#endif -} - -void *mdvi_malloc(size_t nelems) -{ - void *ptr = malloc(nelems); - - if(ptr == NULL) - fatal(_("out of memory allocating %u bytes\n"), - (unsigned)nelems); - return ptr; -} - -void *mdvi_realloc(void *data, size_t newsize) -{ - void *ptr; - - if(newsize == 0) - crash(_("attempted to reallocate with zero size\n")); - ptr = realloc(data, newsize); - if(ptr == NULL) - fatal(_("failed to reallocate %u bytes\n"), (unsigned)newsize); - return ptr; -} - -void *mdvi_calloc(size_t nmemb, size_t size) -{ - void *ptr; - - if(nmemb == 0) - crash(_("attempted to callocate 0 members\n")); - if(size == 0) - crash(_("attempted to callocate %u members with size 0\n"), - (unsigned)nmemb); - ptr = calloc(nmemb, size); - if(ptr == 0) - fatal(_("failed to allocate %ux%u bytes\n"), - (unsigned)nmemb, (unsigned)size); - return ptr; -} - -void mdvi_free(void *ptr) -{ - if(ptr == NULL) - crash(_("attempted to free NULL pointer\n")); - free(ptr); -} - -char *mdvi_strdup(const char *string) -{ - int length; - char *ptr; - - length = strlen(string) + 1; - ptr = (char *)mdvi_malloc(length); - memcpy(ptr, string, length); - return ptr; -} - -/* `to' should have room for length+1 bytes */ -char *mdvi_strncpy(char *to, const char *from, size_t length) -{ - strncpy(to, from, length); - to[length] = '\0'; - return to; -} - -char *mdvi_strndup(const char *string, size_t length) -{ - int n; - char *ptr; - - n = strlen(string); - if(n > length) - n = length; - ptr = (char *)mdvi_malloc(n + 1); - memcpy(ptr, string, n); - return ptr; -} - -void *mdvi_memdup(const void *data, size_t length) -{ - void *ptr = mdvi_malloc(length); - - memcpy(ptr, data, length); - return ptr; -} - -double unit2pix_factor(const char *spec) -{ - double val; - double factor; - const char *p, *q; - static const char *units = "incmmmmtptpcddccspbpftydcs"; - - val = 0.0; - - for(p = spec; *p >= '0' && *p <= '9'; p++) - val = 10.0 * val + (double)(*p - '0'); - if(*p == '.') { - p++; - factor = 0.1; - while(*p && *p >= '0' && *p <= '9') { - val += (*p++ - '0') * factor; - factor = factor * 0.1; - } - } - factor = 1.0; - for(q = units; *q; q += 2) { - if(p[0] == q[0] && p[1] == q[1]) - break; - } - switch((int)(q - units)) { - /*in*/ case 0: factor = 1.0; break; - /*cm*/ case 2: factor = 1.0 / 2.54; break; - /*mm*/ case 4: factor = 1.0 / 25.4; break; - /*mt*/ case 6: factor = 1.0 / 0.0254; break; - /*pt*/ case 8: factor = 1.0 / 72.27; break; - /*pc*/ case 10: factor = 12.0 / 72.27; break; - /*dd*/ case 12: factor = (1238.0 / 1157.0) / 72.27; break; - /*cc*/ case 14: factor = 12 * (1238.0 / 1157.0) / 72.27; break; - /*sp*/ case 16: factor = 1.0 / (72.27 * 65536); break; - /*bp*/ case 18: factor = 1.0 / 72.0; break; - /*ft*/ case 20: factor = 12.0; break; - /*yd*/ case 22: factor = 36.0; break; - /*cs*/ case 24: factor = 1.0 / 72000.0; break; - default: factor = 1.0; - } - return factor * val; -} - -int unit2pix(int dpi, const char *spec) -{ - double factor = unit2pix_factor(spec); - - return (int)(factor * dpi + 0.5); -} - -Ulong get_mtime(int fd) -{ - struct stat st; - - if(fstat(fd, &st) == 0) - return (Ulong)st.st_mtime; - return 0; -} - -char *xstradd(char *dest, size_t *size, size_t n, const char *src, size_t m) -{ - if(m == 0) - m = strlen(src); - if(n + m >= *size) { - dest = mdvi_realloc(dest, n + m + 1); - *size = n + m + 1; - } - memcpy(dest + n, src, m); - dest[n + m] = 0; - return dest; -} - -char *getword(char *string, const char *delim, char **end) -{ - char *ptr; - char *word; - - /* skip leading delimiters */ - for(ptr = string; *ptr && strchr(delim, *ptr); ptr++); - - if(*ptr == 0) - return NULL; - word = ptr++; - /* skip non-delimiters */ - while(*ptr && !strchr(delim, *ptr)) - ptr++; - *end = (char *)ptr; - return word; -} - -char *getstring(char *string, const char *delim, char **end) -{ - char *ptr; - char *word; - int quoted = 0; - - /* skip leading delimiters */ - for(ptr = string; *ptr && strchr(delim, *ptr); ptr++); - - if(ptr == NULL) - return NULL; - quoted = (*ptr == '"'); - if(quoted) - for(word = ++ptr; *ptr && *ptr != '"'; ptr++); - else - for(word = ptr; *ptr && !strchr(delim, *ptr); ptr++); - *end = (char *)ptr; - return word; -} - -static long pow2(size_t n) -{ - long x = 8; /* don't bother allocating less than this */ - - while(x < n) - x <<= 1L; - return x; -} - -void dstring_init(Dstring *dstr) -{ - dstr->data = NULL; - dstr->size = 0; - dstr->length = 0; -} - -int dstring_append(Dstring *dstr, const char *string, int len) -{ - if(len < 0) - len = strlen(string); - if(len) { - if(dstr->length + len >= dstr->size) { - dstr->size = pow2(dstr->length + len + 1); - dstr->data = mdvi_realloc(dstr->data, dstr->size); - } - memcpy(dstr->data + dstr->length, string, len); - dstr->length += len; - dstr->data[dstr->length] = 0; - } else if(dstr->size == 0) { - ASSERT(dstr->data == NULL); - dstr->size = 8; - dstr->data = mdvi_malloc(8); - dstr->data[0] = 0; - } - - return dstr->length; -} - -int dstring_copy(Dstring *dstr, int pos, const char *string, int len) -{ - ASSERT(pos >= 0); - if(len < 0) - len = strlen(string); - if(len) { - if(pos + len >= dstr->length) { - dstr->length = pos; - return dstring_append(dstr, string, len); - } - memcpy(dstr->data + pos, string, len); - } - return dstr->length; -} - -int dstring_insert(Dstring *dstr, int pos, const char *string, int len) -{ - ASSERT(pos >= 0); - if(pos == dstr->length) - return dstring_append(dstr, string, len); - if(len < 0) - len = strlen(string); - if(len) { - if(dstr->length + len >= dstr->size) { - dstr->size = pow2(dstr->length + len + 1); - dstr->data = mdvi_realloc(dstr->data, dstr->size); - } - /* make room */ - memmove(dstr->data + pos, dstr->data + pos + len, len); - /* now copy */ - memcpy(dstr->data + pos, string, len); - dstr->length += len; - dstr->data[dstr->length] = 0; - } - return dstr->length; -} - -int dstring_new(Dstring *dstr, const char *string, int len) -{ - if(len < 0) - len = strlen(string); - if(len) { - dstr->size = pow2(len + 1); - dstr->data = mdvi_malloc(dstr->size * len); - memcpy(dstr->data, string, len); - } else - dstring_init(dstr); - return dstr->length; -} - -void dstring_reset(Dstring *dstr) -{ - if(dstr->data) - mdvi_free(dstr->data); - dstring_init(dstr); -} - diff --git a/dvi/mdvi-lib/vf.c b/dvi/mdvi-lib/vf.c deleted file mode 100644 index e1397fd..0000000 --- a/dvi/mdvi-lib/vf.c +++ /dev/null @@ -1,240 +0,0 @@ -/* vf.c -- VF font support */ -/* - * Copyright (C) 2000, Matias Atria - * - * 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 - */ - -#include - -#include "mdvi.h" -#include "private.h" - -static int vf_load_font __PROTO((DviParams *, DviFont *)); -static void vf_free_macros __PROTO((DviFont *)); - -/* only symbol exported by this file */ -DviFontInfo vf_font_info = { - "VF", - 1, /* virtual fonts scale just fine */ - vf_load_font, - NULL, /* get_glyph */ - NULL, /* shrink0 */ - NULL, /* shrink1 */ - vf_free_macros, - NULL, /* reset */ - NULL, /* lookup */ - kpse_vf_format, - NULL -}; - -DviFontInfo ovf_font_info = { - "OVF", - 1, /* virtual fonts scale just fine */ - vf_load_font, - NULL, /* get_glyph */ - NULL, /* shrink0 */ - NULL, /* shrink1 */ - vf_free_macros, - NULL, /* reset */ - NULL, /* lookup */ - kpse_ovf_format, - NULL -}; - -static int vf_load_font(DviParams *params, DviFont *font) -{ - FILE *p; - Uchar *macros; - int msize; - int mlen; - Int32 checksum; - long alpha, beta, z; - int op; - int i; - int nchars; - int loc, hic; - DviFontRef *last; - - macros = NULL; - msize = mlen = 0; - p = font->in; - - if(fuget1(p) != 247 || fuget1(p) != 202) - goto badvf; - mlen = fuget1(p); - fseek(p, (long)mlen, SEEK_CUR); - checksum = fuget4(p); - if(checksum && font->checksum && checksum != font->checksum) { - warning(_("%s: Checksum mismatch (expected %u, got %u)\n"), - font->fontname, font->checksum, checksum); - } else if(!font->checksum) - font->checksum = checksum; - font->design = fuget4(p); - - /* read all the fonts in the preamble */ - last = NULL; - - /* initialize alpha, beta and z for TFM width computation */ - TFMPREPARE(font->scale, z, alpha, beta); - - op = fuget1(p); - while(op >= DVI_FNT_DEF1 && op <= DVI_FNT_DEF4) { - DviFontRef *ref; - Int32 scale, design; - Uint32 checksum; - int id; - int n; - int hdpi; - int vdpi; - char *name; - - /* process fnt_def commands */ - - id = fugetn(p, op - DVI_FNT_DEF1 + 1); - checksum = fuget4(p); - scale = fuget4(p); - design = fuget4(p); - - /* scale this font according to our parent's scale */ - scale = TFMSCALE(scale, z, alpha, beta); - design = FROUND(params->tfm_conv * design); - - /* compute the resolution */ - hdpi = FROUND(params->mag * params->dpi * scale / design); - vdpi = FROUND(params->mag * params->vdpi * scale / design); - n = fuget1(p) + fuget1(p); - name = mdvi_malloc(n + 1); - fread(name, 1, n, p); - name[n] = 0; - DEBUG((DBG_FONTS, "(vf) %s: defined font `%s' at %.1fpt (%dx%d dpi)\n", - font->fontname, name, - (double)scale / (params->tfm_conv * 0x100000), hdpi, vdpi)); - - /* get the font */ - ref = font_reference(params, id, name, checksum, hdpi, vdpi, scale); - if(ref == NULL) { - error(_("(vf) %s: could not load font `%s'\n"), - font->fontname, name); - goto error; - } - mdvi_free(name); - if(last == NULL) - font->subfonts = last = ref; - else - last->next = ref; - ref->next = NULL; - op = fuget1(p); - } - - if(op >= DVI_FNT_DEF1 && op <= DVI_FNT_DEF4) - goto error; - - /* This function correctly reads both .vf and .ovf files */ - - font->chars = xnalloc(DviFontChar, 256); - for(i = 0; i < 256; i++) - font->chars[i].offset = 0; - nchars = 256; - loc = -1; hic = -1; - /* now read the characters themselves */ - while(op <= 242) { - int pl; - Int32 cc; - Int32 tfm; - - if(op == 242) { - pl = fuget4(p); - cc = fuget4(p); - tfm = fuget4(p); - } else { - pl = op; - cc = fuget1(p); - tfm = fuget3(p); - } - if(loc < 0 || cc < loc) - loc = cc; - if(hic < 0 || cc > hic) - hic = cc; - if(cc >= nchars) { - font->chars = xresize(font->chars, - DviFontChar, cc + 16); - for(i = nchars; i < cc + 16; i++) - font->chars[i].offset = 0; - nchars = cc + 16; - } - if(font->chars[cc].offset) { - error(_("(vf) %s: character %d redefined\n"), - font->fontname, cc); - goto error; - } - - DEBUG((DBG_GLYPHS, "(vf) %s: defined character %d (macro length %d)\n", - font->fontname, cc, pl)); - font->chars[cc].width = pl + 1; - font->chars[cc].code = cc; - font->chars[cc].tfmwidth = TFMSCALE(tfm, z, alpha, beta); - font->chars[cc].offset = mlen; - font->chars[cc].loaded = 1; - if(mlen + pl + 1 > msize) { - msize = mlen + pl + 256; - macros = xresize(macros, Uchar, msize); - } - if(pl && fread(macros + mlen, 1, pl, p) != pl) - break; - macros[mlen+pl] = DVI_EOP; - mlen += pl + 1; - op = fuget1(p); - } - if(op != 248) { - error(_("(vf) %s: no postamble\n"), font->fontname); - goto error; - } - - /* make macro memory just big enough */ - if(msize > mlen) { - macros = xresize(macros, Uchar, mlen); - msize = mlen; - } - - DEBUG((DBG_FONTS|DBG_GLYPHS, - "(vf) %s: macros use %d bytes\n", font->fontname, msize)); - - if(loc > 0 || hic < nchars-1) { - memmove(font->chars, font->chars + loc, - (hic - loc + 1) * sizeof(DviFontChar)); - font->chars = xresize(font->chars, - DviFontChar, hic - loc + 1); - } - font->loc = loc; - font->hic = hic; - font->private = macros; - - return 0; - -badvf: - error(_("%s: File corrupted, or not a VF file.\n"), font->fontname); -error: - if(font->chars) - mdvi_free(font->chars); - if(macros) - mdvi_free(macros); - return -1; -} - -static void vf_free_macros(DviFont *font) -{ - mdvi_free(font->private); -} diff --git a/dvi/pixbuf-device.c b/dvi/pixbuf-device.c deleted file mode 100644 index 1ef4365..0000000 --- a/dvi/pixbuf-device.c +++ /dev/null @@ -1,220 +0,0 @@ -#include "pixbuf-device.h" -#include - -typedef struct _DviPixbufDevice -{ - GdkPixbuf *pixbuf; - - gboolean valid; - - gint xmargin; - gint ymargin; - - Ulong fg; - Ulong bg; - -} DviPixbufDevice; - -static void dvi_pixbuf_draw_rule(DviContext *dvi, int x, int y, Uint w, Uint h, int fill); - -static void dvi_pixbuf_draw_glyph(DviContext *dvi, DviFontChar *ch, int x0, int y0) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) dvi->device.device_data; - - int x, y, w, h; - int isbox; - DviGlyph *glyph; - - glyph = &ch->grey; - - isbox = (glyph->data == NULL || (dvi->params.flags & MDVI_PARAM_CHARBOXES)); - - x = - glyph->x + x0 + c_device->xmargin; - y = - glyph->y + y0 + c_device->ymargin; - w = glyph->w; - h = glyph->h; - - if (x < 0 || y < 0 - || x + w > gdk_pixbuf_get_width (c_device->pixbuf) - || y + h > gdk_pixbuf_get_height (c_device->pixbuf)) - return; - - if (isbox) { - dvi_pixbuf_draw_rule(dvi, x - c_device->xmargin, y - c_device->ymargin, w, h, FALSE); - } - else { - gdk_pixbuf_copy_area (GDK_PIXBUF (glyph->data), - 0, 0, - w, h, - c_device->pixbuf, x, y); - } -} - -static void dvi_pixbuf_draw_rule(DviContext *dvi, int x, int y, Uint w, Uint h, int fill) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) dvi->device.device_data; - gint rowstride; - guchar *p; - gint i, j; - gint red, green, blue; - - red = (c_device->fg >> 16) & 0xff; - green = (c_device->fg >> 8) & 0xff; - blue = c_device->fg & 0xff; - - x += c_device->xmargin; y += c_device->ymargin; - - if (x < 0 || y < 0 - || x + w > gdk_pixbuf_get_width (c_device->pixbuf) - || y + h > gdk_pixbuf_get_height (c_device->pixbuf)) - return; - - rowstride = gdk_pixbuf_get_rowstride (c_device->pixbuf); - p = gdk_pixbuf_get_pixels (c_device->pixbuf) + rowstride * y + 3 * x; - - for (i = 0; i < h; i++) { - if (i == 0 || i == h - 1 || fill) { - for (j = 0; j < w; j++) { - p[j * 3] = red; - p[j * 3 + 1] = green; - p[j * 3 + 2] = blue; - } - } else { - p[0] = red; - p[1] = green; - p[2] = blue; - p[(w - 1) * 3] = red; - p[(w - 1) * 3 + 1] = green; - p[(w - 1) * 3 + 2] = blue; - } - p += rowstride; - } -} - -static int dvi_pixbuf_interpolate_colors(void *device_data, - Ulong *pixels, int nlevels, Ulong fg, Ulong bg, double g, int density) -{ - double frac; - GdkColor color, color_fg, color_bg; - int i, n; - - color_bg.red = (bg >> 16) & 0xff; - color_bg.green = (bg >> 8) & 0xff; - color_bg.blue = bg & 0xff; - - color_fg.red = fg >> 16 & 0xff; - color_fg.green = fg >> 8 & 0xff; - color_fg.blue = fg & 0xff; - - n = nlevels - 1; - for(i = 0; i < nlevels; i++) { - if(g > 0) - frac = pow((double)i / n, 1 / g); - else - frac = 1 - pow((double)(n - i) / n, -g); - color.red = frac * ((double)color_fg.red - color_bg.red) + color_bg.red; - color.green = frac * ((double)color_fg.green - color_bg.green) + color_bg.green; - color.blue = frac * ((double)color_fg.blue - color_bg.blue) + color_bg.blue; - - pixels[i] = (color.red << 16) + (color.green << 8) + color.blue + 0xff000000; - } - - return nlevels; -} - -static void *dvi_pixbuf_create_image(void *device_data, Uint w, Uint h, Uint bpp) -{ - - return gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, w, h); - - return NULL; -} - -static void dvi_pixbuf_free_image(void *ptr) -{ - g_object_unref (GDK_PIXBUF(ptr)); -} - -static void dvi_pixbuf_put_pixel(void *image, int x, int y, Ulong color) -{ - guchar *p; - - p = gdk_pixbuf_get_pixels (GDK_PIXBUF(image)) + y * gdk_pixbuf_get_rowstride(GDK_PIXBUF(image)) + x * 3; - - p[0] = (color >> 16) & 0xff; - p[1] = (color >> 8) & 0xff; - p[2] = color & 0xff; -} - -static void dvi_pixbuf_set_color(void *device_data, Ulong fg, Ulong bg) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) device_data; - - c_device->fg = fg; - - return; -} - -void mdvi_pixbuf_device_init (DviDevice *device) -{ - device->device_data = - g_new0 (DviPixbufDevice, 1); - - device->draw_glyph = dvi_pixbuf_draw_glyph; - device->draw_rule = dvi_pixbuf_draw_rule; - device->alloc_colors = dvi_pixbuf_interpolate_colors; - device->create_image = dvi_pixbuf_create_image; - device->free_image = dvi_pixbuf_free_image; - device->put_pixel = dvi_pixbuf_put_pixel; - device->set_color = dvi_pixbuf_set_color; - device->refresh = NULL; - - return; -} - -void mdvi_pixbuf_device_free (DviDevice *device) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) device->device_data; - - if (c_device->pixbuf) - g_object_unref (c_device->pixbuf); - - g_free (c_device); -} - -GdkPixbuf * -mdvi_pixbuf_device_get_pixbuf (DviDevice *device) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) device->device_data; - - return g_object_ref (c_device->pixbuf); -} - -void -mdvi_pixbuf_device_render (DviContext * dvi) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) dvi->device.device_data; - gint page_width; - gint page_height; - - if (c_device->pixbuf) - g_object_unref (c_device->pixbuf); - - page_width = dvi->dvi_page_w * dvi->params.conv + 2 * c_device->xmargin; - page_height = dvi->dvi_page_h * dvi->params.vconv + 2 * c_device->ymargin; - - c_device->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, page_width, page_height); - gdk_pixbuf_fill (c_device->pixbuf, 0xffffffff); - - mdvi_dopage (dvi, dvi->currpage); -} - - -void -mdvi_pixbuf_device_set_margins (DviDevice *device, gint xmargin, gint ymargin) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) device->device_data; - - c_device->xmargin = xmargin; - c_device->ymargin = ymargin; -} diff --git a/dvi/pixbuf-device.h b/dvi/pixbuf-device.h deleted file mode 100644 index bacae4b..0000000 --- a/dvi/pixbuf-device.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef MDVI_PIXBUF_DEVICE -#define MDVI_PIXBUF_DEVICE - -#include "mdvi.h" -#include - -void -mdvi_pixbuf_device_init (DviDevice *device); - -void -mdvi_pixbuf_device_free (DviDevice *device); - -GdkPixbuf * -mdvi_pixbuf_device_get_pixbuf (DviDevice *device); - -void -mdvi_pixbuf_device_render (DviContext *dvi); - -void -mdvi_pixbuf_device_set_margins (DviDevice *device, gint xmargin, gint ymargin); - -#endif /* MDVI_PIXBUF_DEVICE */ - - -- cgit v0.9.1