/***************************************************************************
 *   Copyright (C) 2011 by Jeremy Burton   *
 *   jburton@39net-w04   *
 *                                                                         *
 *   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 <QFont>
#include <QPainter>

#include <stdio.h>

#include "dom.h"
#include "textitem.h"

//Rotate point about a centre
void CPoint::rotate(double ang)
{
  int
    xo,yo;
  double
    r,a;

  xo = x();
  yo = y();
//printf("CPoint: xo=%d,yo=%d\n",xo,yo);
  //Convert to polar
  r = sqrt(xo*xo+yo*yo);
  a = atan2(xo,yo);
//printf("\tr=%f,a=%f\n",r,RadToDeg(a));
  //Rotate
  a -= DegToRad(ang);
  //Convert to rectangular & re-apply offset
  setX(r*sin(a));
  setY(r*cos(a));
}

void CPoint::rotate(const QPoint &ctr, double ang)
{
  int
    xo,yo;
  double
    r,a;

  //Offset from centre
  xo = x()-ctr.x();
  yo = y()-ctr.y();
//printf("CPoint: xo=%d,yo=%d\n",xo,yo);
  //Convert to polar
  r = sqrt(xo*xo+yo*yo);
  a = atan2(xo,yo);
//printf("\tr=%f,a=%f\n",r,RadToDeg(a));
  //Rotate
  a -= DegToRad(ang);
  //Convert to rectangular & re-apply offset
  setX(r*sin(a)+ctr.x());
  setY(r*cos(a)+ctr.y());
}

/*
void CPoint::getPolar(int &r, double &a)
{
  r = sqrt(xo*xo+yo*yo);
  a = atan2(xo,yo);
}
*/

void CPoint::setPolar(const QPoint &ctr, int rx, int ry, double ang)
{
  double ang1 = DegToRad(ang);
  setX(ctr.x() + (double)rx*sin(ang1));
  setY(ctr.y() - (double)ry*cos(ang1));
}

void CPoint::setPolar(const QPoint &ctr, int r, double ang)
{
  double ang1 = DegToRad(ang);
  setX(ctr.x() + (double)r*sin(ang1));
  setY(ctr.y() - (double)r*cos(ang1));
}

CPoint &CPoint::operator=(const QPoint &p)
{
  setX(p.x());
  setY(p.y());
  return *this;
}

/*
void CPoint::setPolar(const QPointF &ctr, int r, double ang)
{
  setPolar(QPoint(ctr), int r, double ang);
}
*/

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Rotate point about a centre

void CPointF::rotate(double ang)
{
  double
    xo,yo;
  double
    r,a;

  xo = x();
  yo = y();
//printf("CPoint: xo=%d,yo=%d\n",xo,yo);
  //Convert to polar
  r = sqrt(xo*xo+yo*yo);
  a = atan2(xo,yo);
//printf("\tr=%f,a=%f\n",r,RadToDeg(a));
  //Rotate
  a -= DegToRad(ang);
  //Convert to rectangular & re-apply offset
  setX(r*sin(a));
  setY(r*cos(a));
}

void CPointF::rotate(const QPointF &ctr, double ang)
{
  double
    xo,yo;
  double
    r,a;

  //Offset from centre
  xo = x()-ctr.x();
  yo = y()-ctr.y();
//printf("CPoint: xo=%d,yo=%d\n",xo,yo);
  //Convert to polar
  r = sqrt(xo*xo+yo*yo);
  a = atan2(xo,yo);
//printf("\tr=%f,a=%f\n",r,RadToDeg(a));
  //Rotate
  a -= DegToRad(ang);
  //Convert to rectangular & re-apply offset
  setX(r*sin(a)+ctr.x());
  setY(r*cos(a)+ctr.y());
}

double CPointF::r()
{
  double
    xo,yo;

  xo = x();
  yo = y();

  return sqrt(xo*xo+yo*yo);
}

void CPointF::setPolar(const QPointF &ctr, double rx, double ry, double ang)
{
  double ang1 = DegToRad(ang);
  setX(ctr.x() + rx*sin(ang1));
  setY(ctr.y() - ry*cos(ang1));
}

void CPointF::setPolar(const QPointF &ctr, double r, double ang)
{
  double ang1 = DegToRad(ang);
  setX(ctr.x() + r*sin(ang1));
  setY(ctr.y() - r*cos(ang1));
}

CPointF &CPointF::operator=(const QPointF &p)
{
  setX(p.x());
  setY(p.y());
  return *this;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

polaritem::polaritem()
{
  radius1=radius2=40.0;
  circular=true;
}

polaritem::~polaritem() {}

void polaritem::toDom_content(QDomDocument &doc,QDomElement &element)
{
  baseitem::toDom_content(doc,element);

  element.setAttribute("circular",circular);

  toDom_Text(doc,element,"radius1",radius1);
  toDom_Text(doc,element,"radius2",radius2);
}

void polaritem::fromDom(QDomDocument &doc,QDomElement &element)
{
  baseitem::fromDom(doc,element);

  circular = element.attribute("circular", "1").toInt() != 0;

  QDomNode n = element.firstChild();
  while(!n.isNull()) 
  {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull())
    {
      if (e.tagName() == "radius1")
	radius1 = e.text().toDouble();
    }
    if(!e.isNull())
    {
      if (e.tagName() == "radius2")
	radius2 = e.text().toDouble();
    }
    n = n.nextSibling();
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*circleitem::circleitem()
{
  radius1=radius2=75.0;
  strokewidth=1.0;
  circular=true;
}

QString circleitem::describe()
{
  return QString("Circle");
}

void circleitem::toDom(QDomDocument &doc,QDomElement &parent)
{
  QDomElement aw = doc.createElement( "circleitem" );

  polaritem::toDom_content(doc,aw);

  //toDom_Text(doc,aw,"radius",radius);

  parent.appendChild(aw);
}

void circleitem::fromDom(QDomDocument &doc,QDomElement &element)
{
  polaritem::fromDom(doc,element);

/-*
  QDomNode n = element.firstChild();
  while(!n.isNull()) 
  {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull())
    {
      if (e.tagName() == "radius")
        radius = e.text().toDouble();
    }
    n = n.nextSibling();
  }
*-/
}

void circleitem::paint_handles(QPainter &painter, double zoom)
{
  double
    r = radius1*zoom;

  QPoint
    ctr(centre.x()*zoom,-centre.y()*zoom);

  if (!centrelock) move_handle = ctr;
  if (!sizelock)   radius1_handle.setPolar(ctr,r,45.0);

  paint_handle_move(painter,ctr);
  paint_handle_size(painter,ctr,r,r,45.0);
}

void circleitem::paint(QPainter &painter, bool selected, double zoom)
{
  //int
  //  dpix = painter.device()->logicalDpiX(),
  //  dpiy = painter.device()->logicalDpiY();
  int
    r = radius1*zoom;
  QPoint
    ctr(centre.x()*zoom,-centre.y()*zoom);

  QPen
    pen1(Qt::SolidLine);
  QColor
    scolor(strokecolor),
    fcolor(fillcolor);

  if (!selected)
  {
    scolor.setAlpha(127);
    fcolor.setAlpha(127);
  }

  if (stroke)
  {
    pen1.setWidth(strokewidth*zoom);
    pen1.setJoinStyle(Qt::MiterJoin);
    pen1.setColor(scolor);
    painter.setPen(pen1);
  }
  else
    painter.setPen(Qt::NoPen);

  if (fill)
    painter.setBrush(fcolor);
  else
    painter.setBrush(Qt::NoBrush);

  painter.drawEllipse(ctr,r,r);
}

void circleitem::output(QPainter &painter)
{
  int
    dpix = painter.device()->logicalDpiX(),
    dpiy = painter.device()->logicalDpiY(),
    r = realtodev(radius1,dpix);
  QPoint
    ctr(realtodev(centre.x(),dpix),realtodev(-centre.y(),dpiy));

//printf("DPI=%d,%d\n",dpix,dpiy);
  QPen
    pen1(strokecolor);

  if (stroke)
  {
    pen1.setWidth(realtodev(strokewidth,dpix));
    pen1.setJoinStyle(Qt::MiterJoin);
    painter.setPen(pen1);
  }
  else
    painter.setPen(Qt::NoPen);

  if (fill)
    painter.setBrush(fillcolor);
  else
    painter.setBrush(Qt::NoBrush);

  painter.drawEllipse(ctr,r,r);
}
*/

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

radialitem::radialitem()
{
  radius1=radius2=40.0;
  radius3=30.0;
  strokewidth=1.0;
}

////////////////////////////////////////////////////////////////////////////////

baseitem *radialitem::dup()
{
  radialitem *item = new radialitem;
  *item = *this;
  return item;
}

////////////////////////////////////////////////////////////////////////////////

double radialitem::extent()
{
  return std::max(radius1,radius2)+strokewidth/2.0;
}

////////////////////////////////////////////////////////////////////////////////

QString radialitem::describe()
{
  return QString("Radial");
}

void radialitem::toDom(QDomDocument &doc,QDomElement &parent)
{
  QDomElement aw = doc.createElement( "radialitem" );

  polaritem::toDom_content(doc,aw);

  toDom_Text(doc,aw,"radius3",radius3);

  parent.appendChild(aw);
}

void radialitem::fromDom(QDomDocument &doc,QDomElement &element)
{
  polaritem::fromDom(doc,element);

  QDomNode n = element.firstChild();
  while(!n.isNull()) 
  {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull())
    {
      if (e.tagName() == "radius3")
        radius3 = e.text().toDouble();
    }
    n = n.nextSibling();
  }
}

void radialitem::paint_handles(QPainter &painter, double zoom)
{
  double
    r1 = radius1*zoom,
    r3 = radius3*zoom;
  QPoint
    ctr(centre.x()*zoom,-centre.y()*zoom);

  move_handle = ctr;
  angle_handle.setPolar(ctr,r1+ANGLE_HANDLE_EXTEND,angle);
  radius1_handle.setPolar(ctr,r1,angle);
  radius3_handle.setPolar(ctr,r3,angle);

  paint_handle_move(painter,ctr);
  paint_handle_size(painter,ctr,r1,r1,angle);
  paint_handle_size(painter,ctr,r3,r3,angle);
  paint_handle_angle(painter,ctr,r1);
}

void radialitem::paint(QPainter &painter, bool selected, double zoom)
{
  //int
  //  dpix = painter.device()->logicalDpiX(),
  //  dpiy = painter.device()->logicalDpiY();
  double
    ang1 = DegToRad(angle);
  int
    r1 = radius1*zoom,
    r3 = radius3*zoom;
  QPoint
    ctr(centre.x()*zoom,-centre.y()*zoom),
    rad2(ctr.x()+r3*sin(ang1),ctr.y()-r3*cos(ang1)),
    rad1(ctr.x()+r1*sin(ang1),ctr.y()-r1*cos(ang1));
  QPen
    pen1(Qt::SolidLine);
  QColor
    scolor(strokecolor);

  if (!selected)
    scolor.setAlpha(127);

  pen1.setColor(scolor);
  pen1.setWidth(strokewidth*zoom);
  pen1.setJoinStyle(Qt::MiterJoin);

  painter.setPen(pen1);
  painter.drawLine(rad2,rad1);
}

void radialitem::output(QPainter &painter)
{
  double
    ang1 = DegToRad(angle);
  int
    dpix = painter.device()->logicalDpiX(),
    dpiy = painter.device()->logicalDpiY(),
    r1 = realtodev(radius1,dpix),
    r3 = realtodev(radius3,dpix);
  QPoint
    ctr(realtodev(centre.x(),dpix),realtodev(-centre.y(),dpiy)),
    rad2(ctr.x()+r3*sin(ang1),ctr.y()-r3*cos(ang1)),
    rad1(ctr.x()+r1*sin(ang1),ctr.y()-r1*cos(ang1));
  QPen
    pen1(strokecolor);

  pen1.setWidth(realtodev(strokewidth,dpix));
  //pen1.setJoinStyle(Qt::MiterJoin);
  painter.setPen(pen1);

  painter.drawLine(rad2,rad1);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

textitem::textitem(const QString &s)
{
  fontfamily = "Arial";
  fontweight = QFont::Normal;
  fontstretch = 100.0;
  spacing = 1.0;
  fontheight = 10.0;
  angle = 0.0;
  str = s;
  refchar = 'X';
  forward = true;
  smallcaps = false;
  drawpath = false;
  anchorangle=0.0;
  justify=JustifyCentre;
  fill = true;
  fillcolor = Qt::black;

  //radius1 = 60.0;
}

textitem::~textitem()
{
}

////////////////////////////////////////////////////////////////////////////////

double textitem::extent()
{
  return std::max(radius1,radius2) + (fontheight + (stroke?strokewidth:0.0))/2.0;
}

////////////////////////////////////////////////////////////////////////////////

int textitem::reftext_height(QPainter &painter,QFont &font)
{
  QFontMetrics *fontmetrics;
  QRect rect;
  int y1,y2,ymin=0,ymax=0;

  fontmetrics = new QFontMetrics(font,painter.device());

  for (int i=0;i<refchar.size();i++)
  {
    rect = fontmetrics->boundingRect(refchar.at(i));
    y1 = rect.y();
    y2 = y1+rect.height();
    if (i==0)
    {
      ymin = y1;
      ymax = y2;
    }
    else
    {
      if (y1<ymin) ymin=y1;
      if (y2>ymax) ymax=y2;
    }
  }

  delete fontmetrics;

  if (ymax==ymin)
    return 1;
  else
    return ymax-ymin;
}

void textitem::paint_handle_anchorangle(QPainter &painter,const QPoint &ctr,int rx1,int ry1)
{
  if (anglelock) return;

  double
    ang = DegToRad(anchorangle);
  QPen
    pen1(Qt::DashLine);
  QPoint
    rad1(ctr.x()+(rx1-ANGLE_HANDLE_SIZE*2)*sin(ang),ctr.y()-(ry1-ANGLE_HANDLE_SIZE*2)*cos(ang));

  pen1.setColor(Qt::darkMagenta);
  painter.setPen(pen1);
  //painter.drawLine(rad1,rad2);
  painter.drawLine(ctr,rad1);//anchorangle_handle
  painter.setBrush(Qt::darkMagenta);
  painter.setPen(Qt::NoPen);
  painter.drawEllipse(rad1,ANGLE_HANDLE_SIZE,ANGLE_HANDLE_SIZE);
}

void textitem::toDom_content(QDomDocument &doc,QDomElement &element)
{
  polaritem::toDom_content(doc,element);

  element.setAttribute(QString("forward"),forward);
  element.setAttribute(QString("smallcaps"),smallcaps);
  element.setAttribute(QString("drawpath"),drawpath);

  toDom_Text(doc,element,"text",str);
  toDom_Text(doc,element,"textheight",fontheight);
  toDom_Text(doc,element,"textspacing",spacing);
  toDom_Text(doc,element,"textref",refchar);
  //toDom_Text(doc,aw,"angle",angle);
  //toDom_Text(doc,aw,"radius",radius);
  toDom_Text(doc,element,"fontfamily",fontfamily);
  toDom_Text(doc,element,"fontweight",fontweight);
  toDom_Text(doc,element,"fontstretch",fontstretch);
  toDom_Text(doc,element,"anchorangle",anchorangle);
  toDom_Text(doc,element,"justify",justify);
}

void textitem::fromDom(QDomDocument &doc,QDomElement &element)
{
  polaritem::fromDom(doc,element);

  forward = element.attribute("forward", "1").toInt() != 0;
  smallcaps = element.attribute("smallcaps", "0").toInt() != 0;
  drawpath = element.attribute("drawpath", "0").toInt() != 0;

  QDomNode n = element.firstChild();
  while(!n.isNull()) 
  {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull())
    {
      if (e.tagName() == "text")
        str = e.text();
      else if (e.tagName() == "textheight")
	fontheight = e.text().toDouble();
      else if (e.tagName() == "textref")
	refchar = e.text();
      else if (e.tagName() == "textspacing")
	spacing = e.text().toDouble();
      else if (e.tagName() == "fontfamily")
	fontfamily = e.text();
      else if (e.tagName() == "fontweight")
	fontweight = e.text().toInt();
      else if (e.tagName() == "fontstretch")
	fontstretch = e.text().toInt();
      else if (e.tagName() == "anchorangle")
	anchorangle = e.text().toDouble();
      else if (e.tagName() == "justify")
	justify = (ETextJustify)e.text().toInt();
    }
    n = n.nextSibling();
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

textitem1::textitem1(const QString &s) : textitem(s)
{
  radius1 = 60.0;
}

////////////////////////////////////////////////////////////////////////////////

baseitem *textitem1::dup()
{
  textitem1 *item = new textitem1;
  *item = *this;
  return item;
}

////////////////////////////////////////////////////////////////////////////////

QString textitem1::describe()
{
  return QString("Text1: %1").arg(str);
}

void textitem1::paint_handles(QPainter &painter, double zoom)
{
//  double
//    ang1 = DegToRad(anchorangle);
    /*ang2 = 45.0/180.0*pi;*/
  int
    r1 = radius1*zoom,
    r2 = (radius1+fontheight)*zoom,
    outer = r2;

  QPoint
    ctr(centre.x()*zoom,-centre.y()*zoom);
//     rad1(ctr.x()+outer*sin(ang1),ctr.y()-outer*cos(ang1)),
//     rad2(ctr.x()+r1*sin(ang2)-5,ctr.y()-r1*cos(ang2)-5),
//     rad3(ctr.x()+r2*sin(ang2)-5,ctr.y()-r2*cos(ang2)-5);

  QPen
    pen1(Qt::DashLine);

  move_handle = ctr;
  anchorangle_handle.setPolar(ctr,r1-ANGLE_HANDLE_SIZE*2,anchorangle);
  radius1_handle.setPolar(ctr,r1,45.0);
  fontheight_handle.setPolar(ctr,r2,45.0);

  //Circles...
  pen1.setColor(Qt::blue);
  painter.setPen(pen1);
  painter.setBrush(Qt::NoBrush);
  painter.drawEllipse(ctr,r2,r2);
  painter.drawEllipse(ctr,r1,r1);

  //cross axes...
  pen1.setColor(Qt::gray);
  painter.setPen(pen1);
  painter.drawLine(ctr.x(),-outer,ctr.x(),outer);
  painter.drawLine(-outer,ctr.y(),outer,ctr.y());

  paint_handle_move(painter,ctr);
  paint_handle_size(painter,ctr,r1,r1,45.0);
  paint_handle_size(painter,ctr,r2,r2,45.0);
  //paint_handle_angle(painter,ctr,r2);
  paint_handle_anchorangle(painter,ctr,r1,r1);
/*
  //Move handle...
  painter.setBrush(Qt::green);
  painter.setPen(Qt::NoPen);
  painter.drawRect(ctr.x()-5,ctr.y()-5,10,10);

  //Circles...
    pen1.setColor(Qt::blue);
    painter.setPen(pen1);
    painter.setBrush(Qt::NoBrush);
    painter.drawEllipse(ctr,r2,r2);
    //painter.drawEllipse(ctr,radius+fontheight/2.0,radius+fontheight/2.0);
    painter.drawEllipse(ctr,r1,r1);
    //Circles handles...
    painter.setBrush(Qt::blue);
    painter.setPen(Qt::NoPen);
    painter.drawRect(rad2.x(),rad2.y(),10,10);
    painter.drawRect(rad3.x(),rad3.y(),10,10);

    //Anchor angle handle...
    pen1.setColor(Qt::red);
    painter.setPen(pen1);
    painter.drawLine(ctr,rad1);
    painter.setBrush(Qt::red);
    painter.setPen(Qt::NoPen);
    painter.drawEllipse(rad1,8,8);
*/
}

void textitem1::paint(QPainter &painter, bool selected, double zoom)
{
  double
    ang1 = anchorangle/180.0*pi;
    //ang2 = 45.0/180.0*pi;
  int
    dpix = painter.device()->logicalDpiX(),
    dpiy = painter.device()->logicalDpiY();
  int
    r1 = radius1*zoom,
    r2 = (radius1+fontheight)*zoom;
    //outer = r2+20;
  QPen
    pen1(Qt::SolidLine);
  QColor
    scolor(strokecolor),
    fcolor(fillcolor);
  QPoint txt1;
  QFont font;
  //QFontMetrics *fontmetrics;

  painter.translate(centre.x()*zoom,-centre.y()*zoom);

  QRectF rect;
  double ai,xi;
  double widths[str.size()], angles[str.size()];

// /font {2 copy selectfont dup (X) stringheight div mul selectfont} def % set exact height font (based on letter 'X')

  font = QFont(fontfamily, 72);
  font.setWeight(fontweight);
  font.setStretch(fontstretch);
  if (smallcaps)
    font.setCapitalization(QFont::SmallCaps);

  double n = /*20.0/72.0**/(double)dpiy/(double)reftext_height(painter,font);
//printf("Font n=%f, dpiy=%d\n",n,dpiy);
  font.setPixelSize(fontheight*n*zoom+0.5); //***** 1pix per mm scale *****//
  painter.setFont(font);

// go back 1/2 the angle of the whole string to centre it
//TODO: why not whole string at once??
  for (int i=0;i<str.size();i++)
  {
    rect = painter.boundingRect(0.0,0.0,500.0,500.0,Qt::TextSingleLine,str.at(i));
    widths[i] = rect.width();
    angles[i] = atan2(widths[i]/2.0,r1)*spacing;
    switch (justify)
    {
      case JustifyCentre: ang1 += forward ? -angles[i] : angles[i]; break;
      case JustifyLeft: break;
      case JustifyRight: ang1 += (forward ? -angles[i] : angles[i])*2.0; break;
    }
  }

  // Set up stroke & fill colors etc.
  if (!selected)
  {
    scolor.setAlpha(127);
    fcolor.setAlpha(127);
  }

  if (stroke)
  {
    pen1.setWidth(strokewidth*zoom);
    pen1.setJoinStyle(Qt::MiterJoin);
    pen1.setColor(scolor);
    painter.setPen(pen1);
  }
  else
    painter.setPen(Qt::NoPen);

  if (fill)
    painter.setBrush(fcolor);
  else
    painter.setBrush(Qt::NoBrush);

//Paint each char separately
  for (int i=0;i<str.size();i++)
  {
    painter.save();
//printf("rect=%f,%f,%f,%f\n",rect.x(),rect.y(),rect.width(),rect.height());
    xi = widths[i]/2.0;
    ai = angles[i];  // = half angular inc
//printf("xi=%f,ai=%.1f\n",xi,ai/pi*180);
    if (forward)
      ang1 += ai;
    else
      ang1 -= ai;
//printf("spacing=%.1f\n",spacing);
//printf("ang1=%.1f\n",ang1/pi*180);
/*  txt1.setX(-sin(180)*radius-xi);
  txt1.setY(-cos(180)*radius);*/
    txt1.setX(-xi);
    if (forward)
      txt1.setY(-r1);
    else
      txt1.setY(r2);
    painter.rotate(ang1/pi*180-(forward?0:180));

    if (drawpath)
    {
      QPainterPath path;
      path.addText(txt1,font,str.at(i));
      painter.drawPath(path);
    }
    else
      painter.drawText(txt1,str.at(i));

    if (forward)
      ang1 += ai;
    else
      ang1 -= ai;
    painter.restore();
  }
}

void textitem1::output(QPainter &painter)
{
  double
    ang1 = DegToRad(anchorangle);
  int
    dpix = painter.device()->logicalDpiX(),
    dpiy = painter.device()->logicalDpiY();
//printf("DPI=%d,%d\n",dpix,dpiy);
  QFont
    font;
  QPen
    pen1(strokecolor);

  //QPoint rad1(ctr.x()+(radius+fontheight+20)*sin(ang1),ctr.y()-(radius+fontheight+20)*cos(ang1));
  QPoint txt1;
  //QPointF ctr1(realtodev(ctr.x(),dpix)+painter.device()->width()/2.0,realtodev(ctr.y(),dpiy)+painter.device()->height()/2.0);

  painter.translate(realtodev(centre.x(),dpix),-realtodev(centre.y(),dpiy));

  QRectF rect;
  double ai,xi;
  double widths[str.size()], angles[str.size()];

// /font {2 copy selectfont dup (X) stringheight div mul selectfont} def % set exact height font (based on letter 'X')

  font = QFont(fontfamily, 72);
  font.setWeight(fontweight);
  font.setStretch(fontstretch);
  if (smallcaps)
    font.setCapitalization(QFont::SmallCaps);

/*v2*/
  double n = /*20.0/72.0**/(double)dpiy/(double)reftext_height(painter,font);

//printf("Font fontheight=%fmm, rect.height=%fmm\n",fontheight,devtoreal(rect.height(),dpiy));
printf("Font n=%f, dpiy=%d\n",n,dpiy);
  //font = QFont("Arial", fontheight/devtoreal(rect.height(),dpiy)*fontheight/25.4*72.0);
  font.setPointSizeF(mmtopt(fontheight)*n);
  //fontmetrics = new QFontMetrics(font,painter.device());
  painter.setFont(font);
printf("Font pointSizeF=%f\n",font.pointSizeF());

  if (drawpath)
{
    font.setPixelSize(realtodev(fontheight,dpiy)*n);
printf("Font pixelSize=%d\n",font.pixelSize());
}
  //QTransform trans;
  //trans.rotate(txtanchorang-90);
  //painter.setTransform(trans);

// go back 1/2 the angle of the whole string to centre it
//TODO: why not whole string at once??
  for (int i=0;i<str.size();i++)
  {
    rect = painter.boundingRect(painter.window(),Qt::TextSingleLine,str.at(i));
    widths[i] = devtoreal(rect.width(),dpix);
    angles[i] = atan2(widths[i]/2.0,radius1)*spacing;
    switch (justify)
    {
      case JustifyCentre: ang1 += forward ? -angles[i] : angles[i]; break;
      case JustifyLeft: break;
      case JustifyRight: ang1 += (forward ? -angles[i] : angles[i])*2.0; break;
    }
  }

  if (stroke)
  {
    pen1.setWidth(realtodev(strokewidth,dpix));
    pen1.setJoinStyle(Qt::MiterJoin);
    painter.setPen(pen1);
  }
  else
    painter.setPen(Qt::NoPen);

  if (fill)
    painter.setBrush(fillcolor);
  else
    painter.setBrush(Qt::NoBrush);

  //painter.setPen(strokecolor);

//Paint each char separately
for (int i=0;i<str.size();i++)
{
  painter.save();

//printf("rect=%f,%f,%f,%f\n",rect.x(),rect.y(),rect.width(),rect.height());
  xi = widths[i]/2.0;
  ai = angles[i];  // = half angular inc
//printf("xi=%f,ai=%.1f\n",xi,ai/pi*180);
  if (forward)
    ang1 += ai;
  else
    ang1 -= ai;
//printf("spacing=%.1f\n",spacing);
//printf("ang1=%.1f\n",ang1/pi*180);
/*  txt1.setX(-sin(180)*radius-xi);
  txt1.setY(-cos(180)*radius);*/
  txt1.setX(realtodev(-xi,dpix));
  if (forward)
    txt1.setY(realtodev(-radius1,dpiy));
  else
    txt1.setY(realtodev(radius1+fontheight,dpiy));
  painter.rotate(RadToDeg(ang1)-(forward?0:180));
  if (drawpath)
  {
    QPainterPath path;
    path.addText(txt1,font,str.at(i));
    painter.drawPath(path);
  }
  else
    painter.drawText(txt1,str.at(i));
/*
rect = fontmetrics->boundingRect(str.at(i));
rect.moveTo(txt1.x(),txt1.y()-rect.height());
painter.drawRect(rect);
*/
  if (forward)
    ang1 += ai;
  else
    ang1 -= ai;

  painter.restore();
}

  //delete fontmetrics;
}

void textitem1::toDom(QDomDocument &doc,QDomElement &parent)
{
  QDomElement aw = doc.createElement( "textitem1" );

  //aw.setAttribute(QString("forward"),forward);

  textitem::toDom_content(doc,aw);
/*
  toDom_Text(doc,aw,"text",str);
  toDom_Text(doc,aw,"textheight",fontheight);
  toDom_Text(doc,aw,"textspacing",spacing);
  toDom_Text(doc,aw,"textref",refchar);
  //toDom_Text(doc,aw,"angle",angle);
  //toDom_Text(doc,aw,"radius",radius);
  toDom_Text(doc,aw,"fontfamily",fontfamily);
  toDom_Text(doc,aw,"fontweight",fontweight);
  toDom_Text(doc,aw,"fontstretch",fontstretch);
*/
  parent.appendChild(aw);
}

void textitem1::fromDom(QDomDocument &doc,QDomElement &element)
{
  textitem::fromDom(doc,element);

  //forward = element.attribute("forward", "1").toInt() != 0;
/*
  QDomNode n = element.firstChild();
  while(!n.isNull()) 
  {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull())
    {
      if (e.tagName() == "text")
        str = e.text();
      else if (e.tagName() == "textheight")
	fontheight = e.text().toDouble();
      else if (e.tagName() == "textref")
	refchar = e.text();
      else if (e.tagName() == "textspacing")
	spacing = e.text().toDouble();
      else if (e.tagName() == "fontfamily")
	fontfamily = e.text();
      else if (e.tagName() == "fontweight")
	fontweight = e.text().toInt();
      else if (e.tagName() == "fontstretch")
	fontstretch = e.text().toInt();
    }
    n = n.nextSibling();
  }
*/
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

