/* $Id: guppi-metrics.c,v 1.7 2001/07/10 02:53:26 trow Exp $ */

/*
 * guppi-metrics.c
 *
 * Copyright (C) 2000 EMC Capital Management, Inc.
 *
 * Developed by Jon Trowbridge <trow@gnu.org>.
 *
 * 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 <config.h>
#include "guppi-metrics.h"

/* #include <gnome.h> */
#include <gdk/gdk.h>

#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-i18n.h>

#include <math.h>

/* Conversion factors */
#define PT_PER_IN 72.0
#define IN_PER_PT (1.0/PT_PER_IN)
#define CM_PER_IN 2.54
#define IN_PER_CM (1.0/CM_PER_IN)
#define MM_PER_IN 25.4
#define IN_PER_MM (1.0/MM_PER_IN)
#define PT_PER_CM (PT_PER_IN/CM_PER_IN)
#define CM_PER_PT (1.0/PT_PER_CM)
#define PT_PER_MM (PT_PER_IN/MM_PER_IN)
#define MM_PER_PT (1.0/PT_PER_MM)
#define PT_PER_PC 12.0
#define PC_PER_PT (1.0/PT_PER_PC)

static double monitor_x_dpi = -1;
static double monitor_y_dpi = -1;

void
guppi_set_monitor_dpi (double x, double y)
{
  g_return_if_fail (x > 0);
  g_return_if_fail (y > 0);

  monitor_x_dpi = x;
  monitor_y_dpi = y;
}

void
guppi_set_monitor_size (double x, double y, guppi_metric_t units)
{
  double xsz, ysz;

  g_return_if_fail (x > 0);
  g_return_if_fail (y > 0);
  g_return_if_fail (units != GUPPI_INVALID_METRIC);

  xsz = guppi_pt2in (guppi_to_pt (x, units));
  ysz = guppi_pt2in (guppi_to_pt (y, units));

  monitor_x_dpi = gdk_screen_width () / xsz;
  monitor_y_dpi = gdk_screen_height () / ysz;
}

static inline double
get_x_dpi (void)
{
  if (monitor_x_dpi <= 0) {
    monitor_x_dpi = gdk_screen_width () / (double) gdk_screen_width_mm ();
    monitor_x_dpi *= MM_PER_IN;	/* convert px/mm => px/in */
  }

  return monitor_x_dpi;
}

static inline double
get_y_dpi (void)
{
  if (monitor_y_dpi <= 0) {
    monitor_y_dpi = gdk_screen_height () / (double) gdk_screen_height_mm ();
    monitor_y_dpi *= MM_PER_IN;	/* convert px/mm => px/in */
  }

  return monitor_y_dpi;
}

double
guppi_pt2in (double pt)
{
  return pt * IN_PER_PT;
}

double
guppi_in2pt (double in)
{
  return in * PT_PER_IN;
}

double
guppi_pt2cm (double pt)
{
  return pt * CM_PER_PT;
}

double
guppi_cm2pt (double cm)
{
  return cm * PT_PER_CM;
}

double
guppi_pt2mm (double pt)
{
  return pt * MM_PER_PT;
}

double
guppi_mm2pt (double mm)
{
  return mm * PT_PER_MM;
}

double
guppi_pt2pc (double pt)
{
  return pt / PT_PER_PC;
}

double
guppi_pc2pt (double pc)
{
  return pc * PT_PER_PC;
}

double
guppi_x_pt2px (double pt)
{
  return pt * IN_PER_PT * get_x_dpi ();
}

double
guppi_x_px2pt (double px)
{
  return (px / get_x_dpi ()) * PT_PER_IN;
}

double
guppi_y_pt2px (double pt)
{
  return pt * IN_PER_PT * get_y_dpi ();
}

double
guppi_y_px2pt (double py)
{
  return (py / get_y_dpi ()) * PT_PER_IN;
}

double
guppi_pt2px (double pt)
{
  return (guppi_x_pt2px (pt) + guppi_y_pt2px (pt)) / 2;
}

double
guppi_px2pt (double px)
{
  return (guppi_x_px2pt (px) + guppi_y_px2pt (px)) / 2;
}

double
guppi_px_dist (double px0, double py0, double px1, double py1)
{
  double dx = guppi_x_px2pt (px1 - px0);
  double dy = guppi_y_px2pt (py1 - py0);

  return sqrt (dx * dx + dy * dy);
}

double
guppi_to_pt (double x, guppi_metric_t units)
{
  switch (units) {
  case GUPPI_PT:
    return x;
  case GUPPI_IN:
    return guppi_in2pt (x);
  case GUPPI_CM:
    return guppi_cm2pt (x);
  case GUPPI_MM:
    return guppi_mm2pt (x);
  case GUPPI_X_PX:
    return guppi_x_px2pt (x);
  case GUPPI_Y_PX:
    return guppi_y_px2pt (x);
  case GUPPI_PX:
    return guppi_px2pt (x);
  default:
    g_warning ("Unknown/invalid units");
    return 0;
  }
}

double
guppi_from_pt (double x, guppi_metric_t units)
{
  switch (units) {
  case GUPPI_PT:
    return x;
  case GUPPI_IN:
    return guppi_pt2in (x);
  case GUPPI_CM:
    return guppi_pt2cm (x);
  case GUPPI_MM:
    return guppi_pt2mm (x);
  case GUPPI_X_PX:
    return guppi_x_pt2px (x);
  case GUPPI_Y_PX:
    return guppi_y_pt2px (x);
  case GUPPI_PX:
    return guppi_pt2px (x);
  default:
    g_warning ("Unknown/invalid units");
    return 0;
  }
}

const gchar *
guppi_metric_name (guppi_metric_t units)
{
  switch (units) {
  case GUPPI_PT:
    return _("pt");
  case GUPPI_IN:
    return _("in");
  case GUPPI_CM:
    return _("cm");
  case GUPPI_MM:
    return _("mm");
  case GUPPI_X_PX:
  case GUPPI_Y_PX:
  case GUPPI_PX:
    return _("px");
  default:
    return NULL;
  }
}

/* $Id: guppi-metrics.c,v 1.7 2001/07/10 02:53:26 trow Exp $ */


syntax highlighted by Code2HTML, v. 0.9.1