summaryrefslogtreecommitdiff
path: root/nonworking/freenote
diff options
context:
space:
mode:
authorChris Larson <clarson@kergoth.com>2004-11-09 00:36:47 +0000
committerChris Larson <clarson@kergoth.com>2004-11-09 00:36:47 +0000
commitf96441b9faf769c9ecdd4d338b605ea3d0cc4010 (patch)
treeedb17ec2c4ea13c5acb1c7350957a249a820e28d /nonworking/freenote
parentb6588aa6851fb220cedc387d21c51513ef8d67f4 (diff)
Disable bk EOLN_NATIVE conversions on all files in packages FILESPATHs, to prevent it screwing up patches.
BKrev: 4190111fA4MuVozAqwE7xOSL9fr-TA
Diffstat (limited to 'nonworking/freenote')
-rw-r--r--nonworking/freenote/freenote-1.6.1/compile.patch3285
1 files changed, 3285 insertions, 0 deletions
diff --git a/nonworking/freenote/freenote-1.6.1/compile.patch b/nonworking/freenote/freenote-1.6.1/compile.patch
index e69de29bb2..de3e93ac9c 100644
--- a/nonworking/freenote/freenote-1.6.1/compile.patch
+++ b/nonworking/freenote/freenote-1.6.1/compile.patch
@@ -0,0 +1,3285 @@
+
+#
+# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
+#
+
+--- FreeNote_1.6.1_arm/FmtEngine.cpp~compile 2003-12-23 15:53:46.000000000 +0100
++++ FreeNote_1.6.1_arm/FmtEngine.cpp 2004-02-01 18:42:32.000000000 +0100
+@@ -1,409 +1,410 @@
+-/* FreeNote for Sharp SLA300, B500, C7x0 Linux PDA
+- Copyright (C) 2003 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
+-
+- 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
+-*/
+-/*
+-2003/12/16-19 FreeNote ver 1.5.5pre
+-・曲線描画ロジックの改良
+-
+-2003/12/14 FreeNote 1.5.4pre
+-・曲線描画ロジックの改良
+-
+-2003/11/30-2003/12/04 FreeNote 1.5.3pre
+-・ベジェ関数のスペルミスを修正
+-
+-2003/11/16 FreeNote 1.5.2pre
+-・円描画のロジックを追加
+-
+-2003/11/13 FreeNote 1.5.1pre
+-・スムージング追加
+-2003/11/10-12
+-・曲線整形モード追加
+-2003/11/09 追加
+-*/
+-#include "fmtengine.h"
+-#include <qpointarray.h>
+-#include <qpe/qmath.h>
+-#include <math.h>
+-int SNAP_SIZE = 32;
+-int PHASE1_ANGLE = 30;
+-int PHASE2_ANGLE = 30;
+-double Surface(const QPoint& p1, const QPoint& p2)
+-{
+- return 0.5 * abs(p1.x() * p2.y() - p1.y() * p2.x());
+-}
+-
+-bool IsLinear(const QPoint& p1, const QPoint& p2, const QPoint& p3)
+-{
+- double s1 = Surface(p1, p2);
+- double s2 = Surface(p2, p3);
+- double s3 = Surface(p1, p3);
+- if (s1 + s2 == s3) {
+- return true;
+- } else {
+- return false;
+- }
+-}
+-
+-const double Angle(const QPoint& p1, const QPoint& p2)
+-{
+- return qATan2((double)(p2.y() - p1.y()), (double)(p2.x() - p1.x()));
+-}
+-
+-const double DiffAngle(const QPoint& p1, const QPoint& p2, const QPoint& p3)
+-{
+- return fabs(Angle(p1, p2) - Angle(p2, p3));
+-}
+-
+-const double ToDegree(double t)
+-{
+- return t * 180 / M_PI;
+-}
+-
+-const double ToRadian(double d)
+-{
+- return d * M_PI / 180;
+-}
+-
+-const double Distance(const QPoint& p1, const QPoint& p2)
+-{
+- return hypot(p1.x() - p2.x(), p1.y() - p2.y());
+-}
+-
+-const QPoint SnapPoint(const QPoint& p)
+-{
+- int x = ((int)(p.x() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
+- int y = ((int)(p.y() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
+- return QPoint(x, y);
+-}
+-
+-const QPoint ArrangePoint(const QPoint& p1, const QPoint& p2)
+-{
+- int x = p2.x();
+- int y = p2.y();
+- if (p1.x() - SNAP_SIZE / 2 <= x && p1.x() + SNAP_SIZE / 2 >= x) {
+- x = p1.x();
+- }
+- if (p1.y() - SNAP_SIZE / 2 <= y && p1.y() + SNAP_SIZE / 2 >= y) {
+- y = p1.y();
+- }
+- return QPoint(x, y);
+-}
+-
+-FNPointList ReducePoints(FNPointList& p)
+-{
+- if (3 >= p.count()) {
+- return p;
+- }
+- FNPointList rt;
+- rt.append(p.first());
+- QPoint* p1 = p.first();
+- QPoint* p2 = p.at(1);
+- QPoint* p3 = NULL;
+- for (uint i = 2; i < p.count(); ++i) {
+- p3 = p.at(i);
+- if (false == IsLinear(*p1, *p2, *p3)) {
+- rt.append(p2);
+- p1 = p2;
+- }
+- p2 = p3;
+- }
+- rt.append(p3);
+- return rt;
+-}
+-
+-FNPointList ExtractAngle2(FNPointList& p, const int deg)
+-{
+- FNPointList rt;
+- rt.append(p.first());
+- QPoint* st = p.first();
+- QPoint* mp = p.at(1);
+- QPoint* ed = p.last();
+- for (uint i = 2; i < p.count(); ++i) {
+- ed = p.at(i);
+- if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
+- st = mp;
+- rt.append(mp);
+- }
+- mp = ed;
+- }
+- rt.append(ed);
+- return rt;
+-}
+-
+-FNPointList ExtractAngle(FNPointList& p, const int deg)
+-{
+- FNPointList rt;
+- rt.append(p.first());
+- QPoint* st = p.first();
+- QPoint* mp = p.at(1);
+- QPoint* ed = p.last();
+- for (uint i = 2; i < p.count(); ++i) {
+- ed = p.at(i);
+- if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
+- st = mp;
+- rt.append(mp);
+- }
+- mp = ed;
+- }
+- if (SNAP_SIZE / 2 > Distance(*p.first(), *p.last()) && 3 < p.count()) {
+- rt.append(p.first());
+- } else {
+- rt.append(ed);
+- }
+- return rt;
+-}
+-
+-FNPointList SumupPoints(FNPointList& p)
+-{
+- if (3 >= p.count()) {
+- return p;
+- }
+- FNPointList rt;
+- rt.append(p.first());
+- QPoint* p1 = p.first();
+- QPoint* p2 = NULL;
+- double pred = 0;
+- for (uint i = 1; i < p.count() - 1; ++i) {
+- p2 = p.at(i);
+- double d = Distance(*p1, *p2);
+- if (SNAP_SIZE / 2 < d || pred > d) {
+- rt.append(p2);
+- p1 = p2;
+- d = 0;
+- }
+- pred = d;
+- }
+- rt.append(p.last());
+- return rt;
+-}
+-
+-FNPointList SnapPoints(FNPointList& p)
+-{
+- FNPointList rt;
+- for (uint i = 0; i < p.count(); ++i) {
+- QPoint tp = SnapPoint(*p.at(i));
+- p.at(i)->setX(tp.x());
+- p.at(i)->setY(tp.y());
+- rt.append(p.at(i));
+- }
+- return rt;
+-}
+-
+-FNPointList ArrangePoints(FNPointList& p)
+-{
+- if (3 >= p.count() && 2 != p.count()) {
+- return p;
+- }
+- FNPointList rt;
+- rt.append(p.first());
+- QPoint* p1 = p.first();
+- QPoint* p2 = NULL;
+- for (uint i = 1; i < p.count(); ++i) {
+- p2 = p.at(i);
+- QPoint tp = ArrangePoint(*p1, *p2);
+- p2->setX(tp.x());
+- p2->setY(tp.y());
+- rt.append(p2);
+- p1 = p2;
+- }
+- if (*p.first() == *p.last()) {
+- QPoint tp = ArrangePoint(*p1, *p.first());
+- rt.first()->setX(tp.x());
+- rt.first()->setY(tp.y());
+- }
+- return rt;
+-}
+-
+-FNPointList TuningPoints(FNPointList& p)
+-{
+- FNPointList rt;
+- if (3 >= p.count()) {
+- for (uint i = 0; i < p.count(); ++i) {
+- rt.append(new QPoint(*p.at(i)));
+- }
+- return rt;
+- }
+- rt.append(new QPoint(*p.at(0)));
+- for (uint i = 1; i < p.count() - 1; ++i) {
+- QPoint* p1 = p.at(i);
+- QPoint* p2 = p.at(i + 1);
+- rt.append(new QPoint(*p1));
+- if (i < p.count() - 2) {
+- rt.append(new QPoint((p1->x() + p2->x())/2, (p1->y() + p2->y())/2));
+- }
+- }
+- rt.append(new QPoint(*p.at(p.count()-1)));
+- return rt;
+-}
+-
+-FNPointList ToBezier(FNPointList& p) {
+- FNPointList rt;
+- rt.append(new QPoint(*p.at(0)));
+- for (uint i = 0; i < p.count() - 2; i += 2) {
+- int x1 = p.at(i)->x();
+- int xa = p.at(i + 1)->x();
+- int x4 = p.at(i + 2)->x();
+-
+- int x2 = (x1 + xa) / 2;
+- int x3 = (xa + x4) / 2;
+-
+- int y1 = p.at(i)->y();
+- int ya = p.at(i + 1)->y();
+- int y4 = p.at(i + 2)->y();
+-
+- int y2 = (y1 + ya) / 2;
+- int y3 = (ya + y4) / 2;
+-
+- rt.append(new QPoint(x2 ,y2));
+- rt.append(new QPoint(x3 ,y3));
+- rt.append(new QPoint(x4 ,y4));
+- }
+- return rt;
+-}
+-
+-FNPointList ToCurves(FNPointList& p) {
+- if (3 <= p.count()) {
+- //ベジェによる補完
+- return ToBezier(p);
+- } else {
+- FNPointList rt;
+- for (uint i = 0; i < p.count(); ++i) {
+- rt.append(new QPoint(*p.at(i)));
+- }
+- return rt;
+- }
+-}
+-
+-FNPointList AutoFormat(FNPointList& p)
+-{
+- FNPointList tp = ExtractAngle(p, PHASE1_ANGLE);
+- uint n;
+- do {
+- n = tp.count();
+- tp = SumupPoints(tp);
+- tp = ExtractAngle(tp, PHASE1_ANGLE);
+- tp = ArrangePoints(tp);
+- } while (n > tp.count());
+- tp = SnapPoints(tp);
+- tp = ReducePoints(tp);
+- FNPointList rt;
+- if (2 == tp.count()) {
+- if (*tp.first() == *tp.last()) {
+- return rt;
+- }
+- }
+- for (uint i = 0; i < tp.count(); ++i) {
+- rt.append(new QPoint(*tp.at(i)));
+- }
+- return rt;
+-}
+-
+-FNPointList ToEllipse(int x, int y, int w, int h) {
+- FNPointList rt;
+- QPointArray pa;
+- pa.makeEllipse(x, y, w, h);
+- for (uint i = 0; i < pa.count(); ++i) {
+- rt.append(new QPoint(pa.point(i)));
+- }
+- return rt;
+-}
+-
+-FNPointList AutoCurve(FNPointList& p)
+-{
+- FNPointList tp2;
+- tp2.setAutoDelete(true);
+- FNPointList tp4;
+- tp4.setAutoDelete(true);
+- QPoint sp = SnapPoint(*p.at(0));
+- QPoint ep = SnapPoint(*p.at(p.count()-1));
+- if (sp == ep) {
+- //楕円
+- int sx = p.at(0)->x();
+- int sy = p.at(0)->y();
+- int ex = sx;
+- int ey = sy;
+- for (uint i = 1; i < p.count(); ++i) {
+- QPoint tp = *p.at(i);
+- if (sx > tp.x()) {
+- sx = tp.x();
+- } else if (ex < tp.x()) {
+- ex = tp.x();
+- }
+- if (sy > tp.y()) {
+- sy = tp.y();
+- } else if (ey < tp.y()) {
+- ey = tp.y();
+- }
+- }
+- sp = SnapPoint(QPoint(sx, sy));
+- ep = SnapPoint(QPoint(ex, ey));
+- tp2.append(new QPoint(sp.x(), sp.y()));
+- tp2.append(new QPoint(ep.x(), ep.y()));
+- } else {
+- FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
+- uint n;
+- do {
+- n = tp.count();
+- tp = SumupPoints(tp);
+- tp = ExtractAngle2(tp, PHASE2_ANGLE);
+- tp = SnapPoints(tp);
+- } while (n > tp.count());
+- tp = SumupPoints(tp);
+- tp = ReducePoints(tp);
+- tp4 = TuningPoints(tp);
+- tp2 = ToCurves(tp4);
+- }
+- FNPointList rt;
+- if (2 == tp2.count()) {
+- if (*tp2.first() == *tp2.last()) {
+- return rt;
+- }
+- }
+- for (uint i = 0; i < tp2.count(); ++i) {
+- rt.append(new QPoint(*tp2.at(i)));
+- }
+- return rt;
+-}
+-
+-FNPointList Smoothing(FNPointList& p)
+-{
+- int tsnap = SNAP_SIZE;
+- SNAP_SIZE=8;
+- FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
+- tp = SumupPoints(tp);
+- tp = ReducePoints(tp);
+- FNPointList tp4 = TuningPoints(tp);
+- tp4.setAutoDelete(true);
+- FNPointList tp2 = ToCurves(tp4);
+- tp2.setAutoDelete(true);
+- FNPointList rt;
+- for (uint i = 0; i < tp2.count(); ++i) {
+- rt.append(new QPoint(*tp2.at(i)));
+- }
+- SNAP_SIZE = tsnap;
+- return rt;
+-}
+-
+-FNPointList Reduce(FNPointList& p)
+-{
+- FNPointList tp = ReducePoints(p);
+- FNPointList rt;
+- for (uint i = 0; i < tp.count(); ++i) {
+- rt.append(new QPoint(*tp.at(i)));
+- }
+- return rt;
+-}
++/* FreeNote for Sharp SLA300, B500, C7x0 Linux PDA
++ Copyright (C) 2003 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
++
++ 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
++*/
++/*
++2003/12/16-19 FreeNote ver 1.5.5pre
++・曲線描画ロジックの改良
++
++2003/12/14 FreeNote 1.5.4pre
++・曲線描画ロジックの改良
++
++2003/11/30-2003/12/04 FreeNote 1.5.3pre
++・ベジェ関数のスペルミスを修正
++
++2003/11/16 FreeNote 1.5.2pre
++・円描画のロジックを追加
++
++2003/11/13 FreeNote 1.5.1pre
++・スムージング追加
++2003/11/10-12
++・曲線整形モード追加
++2003/11/09 追加
++*/
++#include "fmtengine.h"
++#include <qpointarray.h>
++#include <qpe/qmath.h>
++#include <math.h>
++#include <stdlib.h> // abs
++int SNAP_SIZE = 32;
++int PHASE1_ANGLE = 30;
++int PHASE2_ANGLE = 30;
++double Surface(const QPoint& p1, const QPoint& p2)
++{
++ return 0.5 * abs(p1.x() * p2.y() - p1.y() * p2.x());
++}
++
++bool IsLinear(const QPoint& p1, const QPoint& p2, const QPoint& p3)
++{
++ double s1 = Surface(p1, p2);
++ double s2 = Surface(p2, p3);
++ double s3 = Surface(p1, p3);
++ if (s1 + s2 == s3) {
++ return true;
++ } else {
++ return false;
++ }
++}
++
++const double Angle(const QPoint& p1, const QPoint& p2)
++{
++ return qATan2((double)(p2.y() - p1.y()), (double)(p2.x() - p1.x()));
++}
++
++const double DiffAngle(const QPoint& p1, const QPoint& p2, const QPoint& p3)
++{
++ return fabs(Angle(p1, p2) - Angle(p2, p3));
++}
++
++const double ToDegree(double t)
++{
++ return t * 180 / M_PI;
++}
++
++const double ToRadian(double d)
++{
++ return d * M_PI / 180;
++}
++
++const double Distance(const QPoint& p1, const QPoint& p2)
++{
++ return hypot(p1.x() - p2.x(), p1.y() - p2.y());
++}
++
++const QPoint SnapPoint(const QPoint& p)
++{
++ int x = ((int)(p.x() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
++ int y = ((int)(p.y() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
++ return QPoint(x, y);
++}
++
++const QPoint ArrangePoint(const QPoint& p1, const QPoint& p2)
++{
++ int x = p2.x();
++ int y = p2.y();
++ if (p1.x() - SNAP_SIZE / 2 <= x && p1.x() + SNAP_SIZE / 2 >= x) {
++ x = p1.x();
++ }
++ if (p1.y() - SNAP_SIZE / 2 <= y && p1.y() + SNAP_SIZE / 2 >= y) {
++ y = p1.y();
++ }
++ return QPoint(x, y);
++}
++
++FNPointList ReducePoints(FNPointList& p)
++{
++ if (3 >= p.count()) {
++ return p;
++ }
++ FNPointList rt;
++ rt.append(p.first());
++ QPoint* p1 = p.first();
++ QPoint* p2 = p.at(1);
++ QPoint* p3 = NULL;
++ for (uint i = 2; i < p.count(); ++i) {
++ p3 = p.at(i);
++ if (false == IsLinear(*p1, *p2, *p3)) {
++ rt.append(p2);
++ p1 = p2;
++ }
++ p2 = p3;
++ }
++ rt.append(p3);
++ return rt;
++}
++
++FNPointList ExtractAngle2(FNPointList& p, const int deg)
++{
++ FNPointList rt;
++ rt.append(p.first());
++ QPoint* st = p.first();
++ QPoint* mp = p.at(1);
++ QPoint* ed = p.last();
++ for (uint i = 2; i < p.count(); ++i) {
++ ed = p.at(i);
++ if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
++ st = mp;
++ rt.append(mp);
++ }
++ mp = ed;
++ }
++ rt.append(ed);
++ return rt;
++}
++
++FNPointList ExtractAngle(FNPointList& p, const int deg)
++{
++ FNPointList rt;
++ rt.append(p.first());
++ QPoint* st = p.first();
++ QPoint* mp = p.at(1);
++ QPoint* ed = p.last();
++ for (uint i = 2; i < p.count(); ++i) {
++ ed = p.at(i);
++ if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
++ st = mp;
++ rt.append(mp);
++ }
++ mp = ed;
++ }
++ if (SNAP_SIZE / 2 > Distance(*p.first(), *p.last()) && 3 < p.count()) {
++ rt.append(p.first());
++ } else {
++ rt.append(ed);
++ }
++ return rt;
++}
++
++FNPointList SumupPoints(FNPointList& p)
++{
++ if (3 >= p.count()) {
++ return p;
++ }
++ FNPointList rt;
++ rt.append(p.first());
++ QPoint* p1 = p.first();
++ QPoint* p2 = NULL;
++ double pred = 0;
++ for (uint i = 1; i < p.count() - 1; ++i) {
++ p2 = p.at(i);
++ double d = Distance(*p1, *p2);
++ if (SNAP_SIZE / 2 < d || pred > d) {
++ rt.append(p2);
++ p1 = p2;
++ d = 0;
++ }
++ pred = d;
++ }
++ rt.append(p.last());
++ return rt;
++}
++
++FNPointList SnapPoints(FNPointList& p)
++{
++ FNPointList rt;
++ for (uint i = 0; i < p.count(); ++i) {
++ QPoint tp = SnapPoint(*p.at(i));
++ p.at(i)->setX(tp.x());
++ p.at(i)->setY(tp.y());
++ rt.append(p.at(i));
++ }
++ return rt;
++}
++
++FNPointList ArrangePoints(FNPointList& p)
++{
++ if (3 >= p.count() && 2 != p.count()) {
++ return p;
++ }
++ FNPointList rt;
++ rt.append(p.first());
++ QPoint* p1 = p.first();
++ QPoint* p2 = NULL;
++ for (uint i = 1; i < p.count(); ++i) {
++ p2 = p.at(i);
++ QPoint tp = ArrangePoint(*p1, *p2);
++ p2->setX(tp.x());
++ p2->setY(tp.y());
++ rt.append(p2);
++ p1 = p2;
++ }
++ if (*p.first() == *p.last()) {
++ QPoint tp = ArrangePoint(*p1, *p.first());
++ rt.first()->setX(tp.x());
++ rt.first()->setY(tp.y());
++ }
++ return rt;
++}
++
++FNPointList TuningPoints(FNPointList& p)
++{
++ FNPointList rt;
++ if (3 >= p.count()) {
++ for (uint i = 0; i < p.count(); ++i) {
++ rt.append(new QPoint(*p.at(i)));
++ }
++ return rt;
++ }
++ rt.append(new QPoint(*p.at(0)));
++ for (uint i = 1; i < p.count() - 1; ++i) {
++ QPoint* p1 = p.at(i);
++ QPoint* p2 = p.at(i + 1);
++ rt.append(new QPoint(*p1));
++ if (i < p.count() - 2) {
++ rt.append(new QPoint((p1->x() + p2->x())/2, (p1->y() + p2->y())/2));
++ }
++ }
++ rt.append(new QPoint(*p.at(p.count()-1)));
++ return rt;
++}
++
++FNPointList ToBezier(FNPointList& p) {
++ FNPointList rt;
++ rt.append(new QPoint(*p.at(0)));
++ for (uint i = 0; i < p.count() - 2; i += 2) {
++ int x1 = p.at(i)->x();
++ int xa = p.at(i + 1)->x();
++ int x4 = p.at(i + 2)->x();
++
++ int x2 = (x1 + xa) / 2;
++ int x3 = (xa + x4) / 2;
++
++ int y1 = p.at(i)->y();
++ int ya = p.at(i + 1)->y();
++ int y4 = p.at(i + 2)->y();
++
++ int y2 = (y1 + ya) / 2;
++ int y3 = (ya + y4) / 2;
++
++ rt.append(new QPoint(x2 ,y2));
++ rt.append(new QPoint(x3 ,y3));
++ rt.append(new QPoint(x4 ,y4));
++ }
++ return rt;
++}
++
++FNPointList ToCurves(FNPointList& p) {
++ if (3 <= p.count()) {
++ //ベジェによる補完
++ return ToBezier(p);
++ } else {
++ FNPointList rt;
++ for (uint i = 0; i < p.count(); ++i) {
++ rt.append(new QPoint(*p.at(i)));
++ }
++ return rt;
++ }
++}
++
++FNPointList AutoFormat(FNPointList& p)
++{
++ FNPointList tp = ExtractAngle(p, PHASE1_ANGLE);
++ uint n;
++ do {
++ n = tp.count();
++ tp = SumupPoints(tp);
++ tp = ExtractAngle(tp, PHASE1_ANGLE);
++ tp = ArrangePoints(tp);
++ } while (n > tp.count());
++ tp = SnapPoints(tp);
++ tp = ReducePoints(tp);
++ FNPointList rt;
++ if (2 == tp.count()) {
++ if (*tp.first() == *tp.last()) {
++ return rt;
++ }
++ }
++ for (uint i = 0; i < tp.count(); ++i) {
++ rt.append(new QPoint(*tp.at(i)));
++ }
++ return rt;
++}
++
++FNPointList ToEllipse(int x, int y, int w, int h) {
++ FNPointList rt;
++ QPointArray pa;
++ pa.makeEllipse(x, y, w, h);
++ for (uint i = 0; i < pa.count(); ++i) {
++ rt.append(new QPoint(pa.point(i)));
++ }
++ return rt;
++}
++
++FNPointList AutoCurve(FNPointList& p)
++{
++ FNPointList tp2;
++ tp2.setAutoDelete(true);
++ FNPointList tp4;
++ tp4.setAutoDelete(true);
++ QPoint sp = SnapPoint(*p.at(0));
++ QPoint ep = SnapPoint(*p.at(p.count()-1));
++ if (sp == ep) {
++ //楕円
++ int sx = p.at(0)->x();
++ int sy = p.at(0)->y();
++ int ex = sx;
++ int ey = sy;
++ for (uint i = 1; i < p.count(); ++i) {
++ QPoint tp = *p.at(i);
++ if (sx > tp.x()) {
++ sx = tp.x();
++ } else if (ex < tp.x()) {
++ ex = tp.x();
++ }
++ if (sy > tp.y()) {
++ sy = tp.y();
++ } else if (ey < tp.y()) {
++ ey = tp.y();
++ }
++ }
++ sp = SnapPoint(QPoint(sx, sy));
++ ep = SnapPoint(QPoint(ex, ey));
++ tp2.append(new QPoint(sp.x(), sp.y()));
++ tp2.append(new QPoint(ep.x(), ep.y()));
++ } else {
++ FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
++ uint n;
++ do {
++ n = tp.count();
++ tp = SumupPoints(tp);
++ tp = ExtractAngle2(tp, PHASE2_ANGLE);
++ tp = SnapPoints(tp);
++ } while (n > tp.count());
++ tp = SumupPoints(tp);
++ tp = ReducePoints(tp);
++ tp4 = TuningPoints(tp);
++ tp2 = ToCurves(tp4);
++ }
++ FNPointList rt;
++ if (2 == tp2.count()) {
++ if (*tp2.first() == *tp2.last()) {
++ return rt;
++ }
++ }
++ for (uint i = 0; i < tp2.count(); ++i) {
++ rt.append(new QPoint(*tp2.at(i)));
++ }
++ return rt;
++}
++
++FNPointList Smoothing(FNPointList& p)
++{
++ int tsnap = SNAP_SIZE;
++ SNAP_SIZE=8;
++ FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
++ tp = SumupPoints(tp);
++ tp = ReducePoints(tp);
++ FNPointList tp4 = TuningPoints(tp);
++ tp4.setAutoDelete(true);
++ FNPointList tp2 = ToCurves(tp4);
++ tp2.setAutoDelete(true);
++ FNPointList rt;
++ for (uint i = 0; i < tp2.count(); ++i) {
++ rt.append(new QPoint(*tp2.at(i)));
++ }
++ SNAP_SIZE = tsnap;
++ return rt;
++}
++
++FNPointList Reduce(FNPointList& p)
++{
++ FNPointList tp = ReducePoints(p);
++ FNPointList rt;
++ for (uint i = 0; i < tp.count(); ++i) {
++ rt.append(new QPoint(*tp.at(i)));
++ }
++ return rt;
++}
+--- FreeNote_1.6.1_arm/FNCanvas.cpp~compile 2003-12-24 15:20:16.000000000 +0100
++++ FreeNote_1.6.1_arm/FNCanvas.cpp 2004-02-01 18:43:35.000000000 +0100
+@@ -1,1227 +1,1228 @@
+-/* FreeNote for Sharp SLA300, B500, C7x0 Linux PDA
+- Copyright (C) 2003 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
+-
+- 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
+-*/
+-/*
+-2003/12/23 ver 1.6.1
+-・保存情報のサイズ縮小
+-
+-2003/12/16-19 ver 1.5.5pre
+-・ペンサイズの追加(1-8)
+-・アンドゥ・リドゥの実装
+-
+-2003/12/14 ver 1.5.4pre
+-・ペンサイズを選択可能に。
+-
+-2003/12/05 ver 1.5.3Apre
+-・グリッドの色を修正
+-
+-2003/12/04 ver 1.5.3pre
+-・グリッドの描画を一部修正
+-
+-2003/11/10 ver 1.5.1pre
+-・曲線整形モード追加
+-
+-2003/11/09 ver 1.5.0pre
+-・自動整形モード追加
+-
+-2003/09/03 ver 1.3.4pre
+-・Use all quadrant OFF時に表示位置がリセットされる場合があるバグ対応。
+-
+-2003/09/01-03 ver 1.3.3pre
+-・スクロールの改良
+-・Use all quadrant(全象限を使用する)メニューを追加
+-
+-2003/08/31 FreeNote 1.3.2pre
+-・全方向スクロール
+-
+-2003/08/23 FreeNote 1.3.0pre
+-・CR動作の修正
+-
+-2003/08/15 FreeNote 1.2.1を公開
+-・保存時のバグ修正
+-・完了ダイアログの自動消去
+-・PNGファイルへの出力
+-
+-2003/08/15 FreeNote 1.2を公開
+-・オプション追加
+-・スクロールガイド
+-・Freeファイル関連付け
+-・アイコンの変更
+-
+-2003/08/05 FreeNote 1.1.1preを公開
+-・高速起動時に閉じた状態を保持
+-・描画モード切替え時に消しゴム表示
+-・保存時間短縮
+-・Viewモードの挙動を変更
+-・メニューの見た目を変更
+-*/
+-#include "fncanvas.h"
+-#include <stdio.h>
+-#include <qfile.h>
+-#include <qmessagebox.h>
+-#include <qtextstream.h>
+-#include <qpen.h>
+-#include <qcolor.h>
+-#include <qpoint.h>
+-#include <qthread.h>
+-#include <qimage.h>
+-#include <math.h>
+-#include "fnmessagebox.h"
+-#include "fmtengine.h"
+-
+-int snap(int v) {
+- int tv = abs(v);
+- tv = ((int)(tv + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
+- if (0 > v) {
+- return -tv;
+- } else {
+- return tv;
+- }
+-}
+-
+-FNCanvas::FNCanvas(QWidget* parent = 0, const char* name = 0, WFlags f = 0)
+- :QWidget(parent, name, f),
+- _pen(black, 1, SolidLine, RoundCap, RoundJoin),
+- _asMode(AS_NONE),
+- _drawMode(MODE_DRAW),
+- _disp_offset(0),
+- _eraser_l(50),
+- _eraser_s(10),
+- _h_step(100),
+- _v_step(100),
+- _margin(5),
+- _scrollTiming(800),
+- _viewMode(false),
+- _isWaiting(false),
+- _isDragging(false),
+- _isHeadingEnables(false),
+- _isShowGuide(false),
+- _isUseAllQuadrant(false),
+- _scale_x(1.0),
+- _scale_y(1.0)
+-{
+- _tracks.setAutoDelete(true);
+- this->setBackgroundMode(NoBackground);
+- _timer = new QTimer(this);
+- connect(_timer, SIGNAL(timeout()), this, SLOT(autoScroll()));
+-}
+-
+-FNCanvas::~FNCanvas()
+-{
+- _timer->stop();
+- delete _timer;
+-
+- _tracks.clear();
+- clearList(_draws);
+-}
+-
+-void FNCanvas::setScrollTiming(int v)
+-{
+- _scrollTiming = v;
+-}
+-
+-
+-void FNCanvas::setVStep(int v)
+-{
+- _v_step = v;
+-}
+-
+-void FNCanvas::setHStep(int v)
+-{
+- _h_step = v;
+-}
+-
+-void FNCanvas::setSEraser(int v)
+-{
+- _eraser_s = v;
+-}
+-
+-void FNCanvas::setLEraser(int v)
+-{
+- _eraser_l = v;
+-}
+-
+-
+-void FNCanvas::setMargin(int v)
+-{
+- if (v < 3) {
+- v = 3;
+- }
+- _margin = v;
+-}
+-
+-void FNCanvas::setScrollMode(int as)
+-{
+- _asMode = as;
+- redraw();
+-}
+-
+-void FNCanvas::autoScroll()
+-{
+- if (AS_NONE == _asMode) {
+- if (MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode || MODE_SMOOTH == _drawMode) {
+- setOrigin(_origin.x(), _origin.y());
+- }
+- return;
+- }
+- bool tmp = _isHeadingEnables;
+- int dx = 0;
+- int dy = 0;
+- if (AS_BOTH == _asMode || AS_HORIZONTAL == _asMode) {
+- if (_last.x() > width() * (_margin - 1) / _margin) {
+- dx = _h_step;
+- } else if (_last.x() < width() / _margin) {
+- dx = -_h_step;
+- }
+- }
+- if (AS_BOTH == _asMode || AS_VERTICAL == _asMode) {
+- if (_last.y() > height() * (_margin - 1) / _margin) {
+- dy = _v_step;
+- } else if (_last.y() < height() / _margin) {
+- dy = -_v_step;
+- }
+- }
+- setOrigin(_origin.x() + dx, _origin.y() + dy);
+- _isHeadingEnables = tmp;
+-}
+-
+-void FNCanvas::mousePressEvent(QMouseEvent* evt)
+-{
+- setFocus();
+- _timer->stop();
+- _tracks.clear();
+- if (_viewMode) {
+- _isWaiting = true;
+- _viewMode = false;
+- setOrigin((int)((evt->x()) / _scale_x) - width() / 2, (int)((evt->y()) / _scale_y) - height() / 2);
+- redraw();
+- emit resetViewMode();
+- } else if (MODE_ERASE != _drawMode) {
+- _last = evt->pos();
+- _tracks.append(new QPoint(_last));
+- } else {
+- redraw();
+- _last = evt->pos();
+- _tracks.append(new QPoint(_last));
+-
+- QPainter pbuf;
+- QPainter pwin;
+- pbuf.begin(&_buffer);
+- pwin.begin(this);
+-
+- int w = _eraser_s;
+- if (PENWIDTH_MAX / 2 < _pen.width()) {
+- w = _eraser_l;
+- }
+- pbuf.setRasterOp(XorROP);
+- pbuf.setPen(QPen(white, 1));
+- pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+-
+- pwin.setRasterOp(XorROP);
+- pwin.setPen(QPen(white, 1));
+- pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+-
+- pbuf.end();
+- pwin.end();
+- }
+- _isDragging = true;
+-}
+-
+-void FNCanvas::mouseMoveEvent(QMouseEvent* evt)
+-{
+- if (_isWaiting) {
+- return;
+- }
+- if (MODE_ERASE != _drawMode) {
+- QPainter pwin;
+- QPainter pbuf;
+-
+- pwin.begin(this);
+- pbuf.begin(&_buffer);
+-
+- pwin.setPen(_pen);
+- pbuf.setPen(_pen);
+-
+- pwin.drawLine(_last, evt->pos());
+- pbuf.drawLine(_last, evt->pos());
+-
+- pwin.end();
+- pbuf.end();
+- _last = evt->pos();
+- _tracks.append(new QPoint(_last));
+- } else {
+- //redraw();
+- if (_last.x() == -1) {
+- return;
+- }
+- QPainter pbuf;
+- QPainter pwin;
+-
+- pbuf.begin(&_buffer);
+- pwin.begin(this);
+-
+- int w = _eraser_s;
+- if (PENWIDTH_MAX / 2 < _pen.width()) {
+- w = _eraser_l;
+- }
+- pbuf.setRasterOp(XorROP);
+- pwin.setRasterOp(XorROP);
+- pbuf.setPen(QPen(white, 1));
+- pwin.setPen(QPen(white, 1));
+- pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+- pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+-
+- _tracks.append(new QPoint(evt->pos()));
+- _last = evt->pos();
+-
+- pbuf.setRasterOp(CopyROP);
+- pwin.setRasterOp(CopyROP);
+- QRect r = QRect(0, 0, width(), height());
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- FNPolygon* p = _draws.at(i);
+- if (r.intersects(p->boundingRect())) {
+- bool f = false;
+- QRect selected(_last.x() - w / 2, _last.y() - w / 2, w, w);
+- for (uint j = 0; j < p->points().count(); ++j) {
+- QPoint& pts = p->points().at(j);
+- if (selected.contains(pts)) {
+- f = true;
+- break;
+- }
+- }
+- if (f) {
+- p->drawShape(pbuf, f);
+- p->drawShape(pwin, f);
+- }
+- }
+- }
+- pbuf.setRasterOp(XorROP);
+- pwin.setRasterOp(XorROP);
+- pbuf.setPen(QPen(white, 1));
+- pwin.setPen(QPen(white, 1));
+- pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+- pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+- pbuf.end();
+- pwin.end();
+- }
+-}
+-
+-void FNCanvas::mouseReleaseEvent(QMouseEvent* evt)
+-{
+- _isDragging = false;
+- if (_isWaiting) {
+- _isWaiting = false;
+- return;
+- }
+- _last = evt->pos();
+- if (MODE_ERASE != _drawMode) {
+- if (1 < _tracks.count()) {
+- FNPolygon* p = NULL;
+- if (MODE_FORMAT == _drawMode) {
+- p = new FNPolygon(_pen);
+- _tracks = AutoFormat(_tracks);
+- } else if (MODE_CURVE == _drawMode) {
+- QPoint sp = SnapPoint(*_tracks.at(0));
+- QPoint ep = SnapPoint(*_tracks.at(_tracks.count()-1));
+- _tracks = AutoCurve(_tracks);
+- if (sp == ep) {
+- p = new FNEllipse(_pen);
+- } else if (2 < _tracks.count()) {
+- p = new FNBezier(_pen);
+- } else {
+- p = new FNPolygon(_pen);
+- }
+- } else if (MODE_SMOOTH == _drawMode) {
+- _tracks = Smoothing(_tracks);
+- if (2 < _tracks.count()) {
+- p = new FNBezier(_pen);
+- } else {
+- p = new FNPolygon(_pen);
+- }
+- } else {
+- _tracks = Reduce(_tracks);
+- p = new FNPolygon(_pen);
+- }
+- if (1 < _tracks.count()) {
+- p->setPoints(_tracks);
+- redobuf_flush();
+- _draws.append(p);
+- }
+- }
+- _tracks.clear();
+- _isHeadingEnables = true;
+- _timer->start(_scrollTiming, true);
+- } else {
+- _last = QPoint(-1, -1);
+- _tracks.append(new QPoint(evt->pos()));
+- redraw();
+- }
+-}
+-
+-void FNCanvas::paintEvent(QPaintEvent* evt)
+-{
+- bitBlt(this, 0, 0, &_buffer);
+-}
+-
+-void FNCanvas::resizeEvent(QResizeEvent* evt)
+-{
+- QPixmap save(_buffer);
+- _buffer.resize(evt->size());
+- _buffer.fill(white);
+- bitBlt(&_buffer, 0, 0, &save);
+- redraw();
+-}
+-
+-void FNCanvas::setOrigin(QPoint& o)
+-{
+- this->setOrigin(o.x(), o.y());
+-}
+-
+-QPoint FNCanvas::getTopLeft()
+-{
+- if (0 == _draws.count() || !_isUseAllQuadrant) {
+- return _origin;
+- }
+-
+- int dx = ((FNPolygon*)_draws.at(0))->boundingRect().x();
+- int dy = ((FNPolygon*)_draws.at(0))->boundingRect().y();
+- for (uint i = 1; i < _draws.count(); ++i) {
+- FNPolygon* p = _draws.at(i);
+- if (dx > p->boundingRect().x()) {
+- dx = p->boundingRect().x();
+- }
+- if (dy > p->boundingRect().y()) {
+- dy = p->boundingRect().y();
+- }
+- }
+- return QPoint(snap(dx), snap(dy));
+-}
+-
+-
+-void FNCanvas::rebuild()
+-{
+- if (0 == _draws.count() || !_isUseAllQuadrant) {
+- return;
+- }
+-
+- QPoint d = getTopLeft();
+- for (uint i = 0; i < _draws.count(); ++i) {
+- FNPolygon* p = _draws.at(i);
+- p->translate(-d.x(), -d.y());
+- }
+-
+- _origin = QPoint(0, 0);
+-}
+-
+-
+-void FNCanvas::setOrigin(int ox, int oy)
+-{
+- ox = snap(ox);
+- oy = snap(oy);
+- _isHeadingEnables = false;
+- _timer->stop();
+-
+-
+- int dx = 0;
+- int dy = 0;
+- if (!_isUseAllQuadrant) {
+- if (0 > ox) {
+- ox = 0;
+- }
+- if (0 > oy) {
+- oy = 0;
+- }
+- dx = _origin.x() - ox;
+- dy = _origin.y() - oy;
+- } else {
+- dx = _origin.x() - ox;
+- dy = _origin.y() - oy;
+- if (0 > ox) {
+- ox = 0;
+- }
+- if (0 > oy) {
+- oy = 0;
+- }
+- }
+- for (uint i = 0; i < _tracks.count(); ++i) {
+- QPoint* p = _tracks.at(i);
+- p->setX(p->x() + dx);
+- p->setY(p->y() + dy);
+- }
+-
+- for (uint i = 0; i < _draws.count(); ++i) {
+- FNPolygon* p = _draws.at(i);
+- p->translate(dx, dy);
+- }
+- _origin = QPoint(ox, oy);
+- emit originChanged(ox, oy);
+- redraw();
+-}
+-
+-void FNCanvas::redraw()
+-{
+- if (!this->isVisible()) {
+- return;
+- }
+- _buffer.fill(white);
+- QPainter pbuf;
+- QRect r = QRect(0, 0, width(), height());
+- pbuf.begin(&_buffer);
+- if (_viewMode) {
+- float wx = 0;
+- float wy = 0;
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- FNPolygon* p = _draws.at(i);
+- QRect r = p->boundingRect();
+- if (wx < r.right()) {
+- wx = r.right();
+- }
+- if (wy < r.bottom()) {
+- wy = r.bottom();
+- }
+- }
+- wx += SNAP_SIZE;
+- wy += SNAP_SIZE;
+- wx = snap((int)wx);
+- wy = snap((int)wy);
+- wx = wx + _origin.x();
+- wy = wy + _origin.y();
+- _scale_x = (float)width() / wx;
+- _scale_y = (float)height() / wy;
+- if (1.0f < _scale_x) {
+- _scale_x = 1.0f;
+- }
+- if (1.0f < _scale_y) {
+- _scale_y = 1.0f;
+- }
+- if (_scale_x > _scale_y) {
+- _scale_x = _scale_y;
+- } else if (_scale_x < _scale_y) {
+- _scale_y = _scale_x;
+- }
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- FNPolygon* p = _draws.at(i);
+- FNPolygon* t = NULL;
+- if (p->type() == FN_BEZIER) {
+- t = new FNBezier(*(FNBezier*)p);
+- } else if (p->type() == FN_ELLIPSE) {
+- t = new FNEllipse(*(FNEllipse*)p);
+- } else {
+- t = new FNPolygon(*p);
+- }
+- t->translate(-_origin.x(), -_origin.y());
+- for (uint j = 0; j < t->points().count(); ++j) {
+- QPoint& pts = t->points().at(j);
+- int x = (int)(pts.x() * _scale_x);
+- int y = (int)(pts.y() * _scale_y);
+- pts.setX(x);
+- pts.setY(y);
+- }
+- double pensize = t->pen().width();
+- if (_scale_x > _scale_y) {
+- pensize = pensize * _scale_y;
+- } else {
+- pensize = pensize * _scale_x;
+- }
+- if (0 >= pensize) {
+- pensize = 1;
+- }
+- t->pen().setWidth(pensize);
+- t->drawShape(pbuf);
+- delete t;
+- }
+- } else if (MODE_ERASE != _drawMode) {
+- if (MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode) {
+- QPen pen1(QColor(0, 240, 240), 1);
+- QPen pen2(QColor(0, 0, 0), 1);
+- pbuf.setPen(QPen(QColor(0, 240, 240), 1));
+- pbuf.setPen(pen1);
+- for (int x = 0; x < width() + SNAP_SIZE; x += SNAP_SIZE) {
+- pbuf.drawLine(x - SNAP_SIZE / 2, 0, x - SNAP_SIZE / 2, height());
+- for (int y = 0; y < height() + SNAP_SIZE; y += SNAP_SIZE) {
+- pbuf.drawLine(0, y - SNAP_SIZE / 2, width(), y - SNAP_SIZE / 2);
+- pbuf.drawRect(x-1,y-1,2,2);
+- }
+- }
+- }
+- if (_isShowGuide) {
+- pbuf.setPen(QPen(cyan, 1, DashLine));
+- if (AS_HORIZONTAL == _asMode || AS_BOTH == _asMode) {
+- if (0 != _origin.x() || _isUseAllQuadrant) {
+- pbuf.drawLine(width() / _margin, 0, width() / _margin, height());
+- }
+- pbuf.drawLine(width() * (_margin - 1) / _margin, 0, width() * (_margin - 1) / _margin, height());
+- }
+-
+- if (AS_VERTICAL == _asMode || AS_BOTH == _asMode) {
+- if (0 != _origin.y() || _isUseAllQuadrant) {
+- pbuf.drawLine(0, height() / _margin, width(), height() / _margin);
+- }
+- pbuf.drawLine(0, height() * (_margin - 1) / _margin, width(), height() * (_margin - 1) / _margin);
+- }
+- }
+-
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- FNPolygon* p = _draws.at(i);
+- if (r.intersects(p->boundingRect())) {
+- p->drawShape(pbuf);
+- }
+- }
+- } else {
+- int w = _eraser_s;
+- if (PENWIDTH_MAX / 2 < _pen.width()) {
+- w = _eraser_l;
+- }
+- FNPointList removes;
+- for (uint i = 0; i < _tracks.count(); ++i) {
+- removes.append(_tracks.at(i));
+- }
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- FNPolygon* p = _draws.at(i);
+- if (r.intersects(p->boundingRect())) {
+- bool f = false;
+- for (uint j = 0; j < _tracks.count(); ++j) {
+- QPoint* pts = _tracks.at(j);
+- QRect selected(pts->x() - w / 2, pts->y() - w / 2, w, w);
+- for (uint k = 0; k < p->points().count(); ++k) {
+- QPoint& pts2 = p->points().at(k);
+- if (selected.contains(pts2)) {
+- f = true;
+- removes.remove(pts);
+- break;
+- }
+- }
+- if (f) {
+- break;
+- }
+- }
+- p->drawShape(pbuf, f);
+- }
+- }
+- for (uint i = 0; i < removes.count(); ++i) {
+- _tracks.remove(removes.at(i));
+- }
+- /*
+- if (_isDragging) {
+- pbuf.setPen(QPen(black, 1));
+- pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+- }
+- */
+- }
+- pbuf.end();
+- repaint();
+-}
+-
+-void FNCanvas::changeColor(QRgb c)
+-{
+- _pen.setColor(QColor(c));
+-}
+-
+-void FNCanvas::undo()
+-{
+- if (MODE_ERASE != _drawMode) {
+- ++_disp_offset;
+- if (_disp_offset > _draws.count()) {
+- _disp_offset = _draws.count();
+- }
+- } else {
+- _draws = _undobuf;
+- _marks.clear();
+- }
+- redraw();
+-}
+-
+-void FNCanvas::redo()
+-{
+- if (MODE_ERASE != _drawMode) {
+- if (0 < _disp_offset) {
+- --_disp_offset;
+- }
+- }
+- redraw();
+-}
+-
+-void FNCanvas::clearList(FNPolygonList& list)
+-{
+- list.setAutoDelete(true);
+- list.clear();
+- list.setAutoDelete(false);
+-}
+-
+-void FNCanvas::clear()
+-{
+- _disp_offset = 0;
+- clearList(_draws);
+- _undobuf.clear();
+- setOrigin(0, 0);
+- redraw();
+-}
+-
+-void FNCanvas::viewChanged(bool flg)
+-{
+- _tracks.clear();
+- _viewMode = flg;
+- if (_viewMode) {
+- if (_isUseAllQuadrant) {
+- rebuild();
+- }
+- setOrigin(0, 0);
+- }
+- redraw();
+-}
+-
+-void FNCanvas::redobuf_flush()
+-{
+- for (uint i = 0; i < _disp_offset; ++i) {
+- FNPolygon* p = _draws.last();
+- _draws.remove(p);
+- delete p;
+- }
+- _disp_offset = 0;
+-}
+-
+-void FNCanvas::modeChanged(int mode)
+-{
+- _tracks.clear();
+- _drawMode = mode;
+- redobuf_flush();
+- if (MODE_ERASE == _drawMode) {
+- _marks.clear();
+- _undobuf = _draws;
+- } else {
+- if (_draws.count() != _undobuf.count()) {
+- for (uint i = 0; i < _marks.count(); ++i) {
+- FNPolygon* p = _marks.at(i);
+- _draws.remove(p);
+- }
+- clearList(_marks);
+- }
+- }
+- redraw();
+-}
+-
+-QRect FNCanvas::getMatrix(const QRect& r) const
+-{
+- int ox = _origin.x();
+- int oy = _origin.y();
+- const int wide = 100;
+-
+- int left = r.left() + ox;
+- int top = r.top() + oy;
+- int right = r.right() + ox;
+- int bottom = r.bottom() + oy;
+-
+- left = (int)(left / wide) * wide;
+- top = (int)(top / wide) * wide;
+- right = (right % wide == 0 && left != right) ? right : (int)((right + wide) / wide) * wide;
+- bottom = (bottom % wide == 0 && top != bottom) ? bottom : (int)((bottom + wide) / wide) * wide;
+-
+- return QRect(left - ox, top - oy, right - left, bottom - top);
+-}
+-
+-void FNCanvas::CR()
+-{
+- if (MODE_ERASE == _drawMode) {
+- return;
+- }
+- if (_isHeadingEnables) {
+- //lastから、左方向に向けて探索する。
+- QRect r = getMatrix(_draws.last()->boundingRect());
+- bool isSearching = true;
+- r.moveBy(-100, 0);
+- while (isSearching) {
+- isSearching = false;
+- for (uint i = 0; i < _draws.count(); ++i) {
+- FNPolygon* p = _draws.at(i);
+- const QRect& r2 = p->boundingRect();
+- if (r.intersects(r2)) {
+- if (r.left() + 100 > r2.left()) {
+- r = getMatrix(r2);
+- r.moveBy(-100, 0);
+- isSearching = true;
+- break;
+- }
+- }
+- }
+- }
+- r.moveBy(100, 0);
+- //lastが画面の4/5以下ならば、スクロールアップする。
+- //そうでなければ、ヘッディングのみ。
+- if (_last.y() > height() * 4 / 5) {
+- setOrigin(_origin.x() + r.x(), _origin.y() + 50);
+- } else {
+- setOrigin(_origin.x() + r.x(), _origin.y());
+- }
+- _isHeadingEnables = false;
+- } else {
+- //lastの周囲に何も無い場合は、縦にスクロールする。
+- setOrigin(_origin.x(), _origin.y() + 50);
+- }
+-}
+-
+-void FNCanvas::erase()
+-{
+- if (MODE_ERASE != _drawMode) {
+- return;
+- }
+- FNPolygonList temp;
+- int w = _eraser_s;
+- if (PENWIDTH_MAX / 2 < _pen.width()) {
+- w = _eraser_l;
+- }
+- QRect r = QRect(0, 0, width(), height());
+- for (uint i = 0; i < _draws.count(); ++i) {
+- FNPolygon* p = _draws.at(i);
+- bool f = false;
+- if (r.intersects(p->boundingRect())) {
+- for (uint j = 0; j < _tracks.count(); ++j) {
+- QPoint* pts = _tracks.at(j);
+- QRect selected(pts->x() - w / 2, pts->y() - w / 2, w, w);
+- for (uint k = 0; k < p->points().count(); ++k) {
+- QPoint& pts2 = p->points().at(k);
+- if (selected.contains(pts2)) {
+- temp.append(p);
+- f = true;
+- break;
+- }
+- }
+- if (f) {
+- break;
+- }
+- }
+- }
+- }
+- for (uint i = 0; i < temp.count(); ++i) {
+- _draws.remove(temp.at(i));
+- _marks.append(temp.at(i));
+- }
+- _tracks.clear();
+- redraw();
+-}
+-
+-void FNCanvas::setPensize(int sz)
+-{
+- _pen.setWidth(sz);
+-}
+-
+-bool FNCanvas::exportPNG(const QFileInfo& info, QPixmap& buf)
+-{
+- if (0 == info.fileName().length()) {
+- QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+- return false;
+- }
+- if (info.extension(false) != "png") {
+- QMessageBox::warning(0,"FreeNoteQt", "extension '.png' expected.");
+- return false;
+- }
+-
+- bool ret = buf.save(info.absFilePath(), "PNG");
+- if (ret) {
+- FNMessageBox::information(0,"FreeNoteQt", "export PNG complete.");
+- } else {
+- QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
+- }
+- return ret;
+-}
+-
+-QString FNCanvas::mkPDFscript(FNPolygon* elm)
+-{
+- QString s ="";
+- char buf[1024];
+-
+- float r = (float)elm->pen().color().red() / 255.0f;
+- float g = (float)elm->pen().color().green() / 255.0f;
+- float b = (float)elm->pen().color().blue() / 255.0f;
+- s += "q\n";
+- sprintf(buf, "%f %f %f RG\n", r, g, b);
+- s += buf;
+- QPointArray points = elm->points().copy();
+- points.translate(_origin.x(), _origin.y());
+- if (elm->type() == FN_BEZIER) {
+- sprintf(buf, "%d %d m\n", points[0].x(), points[0].y());
+- s += buf;
+- for (uint j = 1; j < points.count(); j += 3) {
+- sprintf(buf, "%d %d %d %d %d %d c\n",
+- points[j].x(), points[j].y(),
+- points[j + 1].x(), points[j + 1].y(),
+- points[j + 2].x(), points[j + 2].y()
+- );
+- s += buf;
+- }
+- } else if (elm->type() == FN_ELLIPSE) {
+- int x = points[0].x();
+- int y = points[0].y();
+- int ex = points[1].x();
+- int ey = points[1].y();
+- int w = ex - x;
+- int h = ey - y;
+- int cx = x + w/2;
+- int cy = y;
+- int x1 = x + 3*w/4;
+- int y1 = y;
+- int x2 = x + w;
+- int y2 = y + h/4;
+- int x3 = x + w;
+- int y3 = y + h/2;
+-
+- sprintf(buf, "%d %d m\n%d %d %d %d %d %d c\n", cx, cy, x1, y1, x2, y2, x3, y3);
+- s += buf;
+- x1 = x + w;
+- y1 = y + 3 * h / 4;
+- x2 = x + 3 * w / 4;
+- y2 = y + h;
+- x3 = x + w/2;
+- y3 = y + h;
+- sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
+- s += buf;
+-
+- x1 = x + w / 4;
+- y1 = y + h;
+- x2 = x;
+- y2 = y + 3 * h / 4;
+- x3 = x;
+- y3 = y + h / 2;
+- sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
+- s += buf;
+- x1 = x;
+- y1 = y + h / 4;
+- x2 = x + w / 4;
+- y2 = y;
+- x3 = x + w / 2;
+- y3 = y;
+- sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
+- s += buf;
+- } else {
+- sprintf(buf, "%d %d m\n", points[0].x(), points[0].y());
+- s += buf;
+- for (uint j = 1; j < points.count(); ++j) {
+- sprintf(buf, "%d %d l\n", points[j].x(), points[j].y());
+- s += buf;
+- }
+- }
+- sprintf(buf, "%d w\n", elm->pen().width());
+- s += buf;
+- s += "S\n";
+- s += "Q\n";
+- return s;
+-}
+-
+-bool FNCanvas::exportPDF(const QFileInfo& info)
+-{
+- if (0 == info.fileName().length()) {
+- QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+- return false;
+- }
+- if (info.extension(false) != "pdf") {
+- QMessageBox::warning(0,"FreeNoteQt", "extension '.pdf' expected.");
+- return false;
+- }
+-
+- FILE* fp = NULL;
+- if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
+- QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
+- return false;
+- }
+-
+- QPoint o = getTopLeft();
+- rebuild();
+- int wx = 595;
+- int wy = 842;
+- char buf[1024];
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- FNPolygon* p = _draws.at(i);
+- QRect r = p->boundingRect();
+- r.moveBy(_origin.x(), _origin.y());
+- if (wx < r.right()) {
+- wx =r.right();
+- }
+- if (wy < r.bottom()) {
+- wy = r.bottom();
+- }
+- }
+-
+- int len = 0;
+-
+- sprintf(buf, "1 0 0 -1 0 %d cm\n", wy);
+- QString cm = buf;
+- len += cm.length();
+-
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- QString s = mkPDFscript(_draws.at(i));
+- len += s.length();
+- }
+-
+- QString header = "";
+- header += "%PDF-1.3\n";
+- header += "1 0 obj\n";
+- header += "<<\n";
+- header += "/Type /Page\n";
+- header += "/Parent 3 0 R\n";
+- header += "/Resources\n";
+- header += "<<\n";
+- header += "/ProcSet [ /PDF ]\n";
+- header += ">>\n";
+- sprintf(buf, "/MediaBox [ 0 0 %010d %010d ]\n", wx, wy);
+- header += buf;
+- header += "/Contents 4 0 R\n";
+- header += ">>\n";
+- header += "endobj\n";
+- header += "2 0 obj\n";
+- header += "<<\n";
+- header += "/Type /Catalog\n";
+- header += "/Pages 3 0 R\n";
+- header += "/PageLayout /OneColumn\n";
+- header += "/OpenAction [1 0 R /XYZ null null 1 ]\n";
+- header += ">>\n";
+- header += "endobj\n";
+- header += "3 0 obj\n";
+- header += "<<\n";
+- header += "/Type /Pages\n";
+- header += "/Kids [ 1 0 R ]\n";
+- header += "/Count 1\n";
+- header += ">>\n";
+- header += "endobj\n";
+- header += "4 0 obj\n";
+- sprintf(buf, "<< /Length %010d >>\n", len);
+- header += buf;
+- header += "stream\n";
+-
+- QString footer = "";
+- footer += "xref\n";
+- footer += "0 5\n";
+- footer += "0000000000 65535 f \n";
+- footer += "0000000009 00000 n \n";
+- footer += "0000000147 00000 n \n";
+- footer += "0000000257 00000 n \n";
+- footer += "0000000316 00000 n \n";
+- footer += "trailer\n";
+- footer += "<<\n";
+- footer += "/Size 5\n";
+- footer += "/Root 2 0 R\n";
+- footer += ">>\n";
+- footer += "startxref\n";
+-
+- len = cm.length();
+- len += header.length();
+- fputs(header, fp);
+- fputs(cm, fp);
+-
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- QString s = mkPDFscript(_draws.at(i));
+- len += s.length();
+- fputs(s, fp);
+- }
+- QString streamfooter = "endstream\nendobj\n";
+- len += streamfooter.length();
+- fputs(streamfooter, fp);
+-
+- fputs(footer, fp);
+- sprintf(buf, "%d\n", len);
+- fputs(buf, fp);
+- fputs("%%EOF\n", fp);
+- fclose(fp);
+- if (_isUseAllQuadrant) {
+- setOrigin(-o.x(), -o.y());
+- }
+- FNMessageBox::information(0,"FreeNoteQt", "export PDF complete.");
+- return true;
+-}
+-
+-bool FNCanvas::save(const QFileInfo& info)
+-{
+- if (0 == info.fileName().length()) {
+- QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+- return false;
+- }
+- if (info.extension(false) != "free") {
+- QMessageBox::warning(0,"FreeNoteQt", "extension '.free' expected.");
+- return false;
+- }
+- FILE* fp = NULL;
+- if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
+- QMessageBox::warning(0,"FreeNoteQt", "could not save file.");
+- return false;
+- }
+- QPoint o = getTopLeft();
+- rebuild();
+- fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
+- fputs("<freenote version=\"2.0\">\n", fp);
+- char buf[1024];
+- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
+- FNPolygon p(*_draws.at(i));
+- p.translate(_origin.x(), _origin.y());
+- if (p.type() == FN_BEZIER) {
+- sprintf(buf, "\t<bz color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
+- } else if (p.type() == FN_ELLIPSE) {
+- sprintf(buf, "\t<el color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
+- } else {
+- sprintf(buf, "\t<po color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
+- }
+- fputs(buf, fp);
+- QPointArray& points = p.points();
+- for (uint j = 0; j < points.count(); ++j) {
+- QPoint point = points.point(j);
+- sprintf(buf, "\t\t<p x=\"%d\" y=\"%d\"/>\n", point.x(), point.y());
+- fputs(buf, fp);
+- }
+- if (p.type() == FN_BEZIER) {
+- fputs("\t</bz>\n", fp);
+- } else if (p.type() == FN_ELLIPSE) {
+- fputs("\t</el>\n", fp);
+- } else {
+- fputs("\t</po>\n", fp);
+- }
+- }
+- fputs("</freenote>\n", fp);
+- fclose(fp);
+- if (_isUseAllQuadrant) {
+- setOrigin(-o.x(), -o.y());
+- }
+- FNMessageBox::information(0, "FreeNoteQt", "save complete.");
+- return true;
+-}
+-
+-bool FNCanvas::load(const QFileInfo& info)
+-{
+- if (0 == info.fileName().length()) {
+- QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+- return false;
+- }
+- if (!info.exists()) {
+- QMessageBox::warning(0,"FreeNoteQt", "file not exists.");
+- return false;
+- }
+- FILE* fp = NULL;
+- if (!(fp = fopen(info.absFilePath().utf8(), "rt"))) {
+- QMessageBox::warning(0,"FreeNoteQt", "could not open file.");
+- return false;
+- }
+- clear();
+-
+- QString line;
+- FNPointList points;
+- points.setAutoDelete(true);
+- int c;
+- int w;
+- QPen pen(Qt::black, 1);
+- FNPolygon* polygon;
+-
+- char rdbuf[1024];
+- char buf[1024];
+- QString type = "";
+- while (!feof(fp)) {
+- fgets(rdbuf, sizeof(rdbuf), fp);
+- line = rdbuf;
+- if (-1 != line.find("<fnpolygon ") ||
+- -1 != line.find("<po ") ||
+- -1 != line.find("<bz ") ||
+- -1 != line.find("<el ")
+- ) {
+- if (-1 != line.find("<el ")) {
+- type = "Ellipse";
+- } else if (-1 != line.find("<bz ")) {
+- type = "Bezier";
+- } else {
+- type = "Polygon";
+- }
+- points.clear();
+- int st = line.find("color") + 7;
+- int ed = line.find("\"", st);
+- strcpy(buf, line.mid(st, ed - st).utf8());
+- sscanf(buf, "%x", &c);
+- st = line.find("width") + 7;
+- ed = line.find("\"", st);
+- strcpy(buf, line.mid(st, ed - st).utf8());
+- sscanf(buf, "%d", &w);
+- } else if (-1 != line.find("<point ") ||
+- -1 != line.find("<p ")
+- ) {
+- int st = line.find("x=") + 3;
+- int ed = line.find("\"", st);
+- strcpy(buf, line.mid(st, ed - st).utf8());
+- int x;
+- sscanf(buf, "%d", &x);
+-
+- st = line.find("y=") + 3;
+- ed = line.find("\"", st);
+- strcpy(buf, line.mid(st, ed - st).utf8());
+- int y;
+- sscanf(buf, "%d", &y);
+- points.append(createPts(x, y)); //バグ対策
+- } else if (-1 != line.find("</fnpolygon") ||
+- -1 != line.find("</bz") ||
+- -1 != line.find("</el") ||
+- -1 != line.find("</po")) {
+- pen.setColor((QRgb)c);
+- pen.setWidth(w);
+- if (type == "Bezier") {
+- _draws.append(polygon = createBezier(pen)); //バグ対策
+- } else if (type == "Ellipse") {
+- _draws.append(polygon = createEllipse(pen)); //バグ対策
+- } else {
+- _draws.append(polygon = createPolygon(pen)); //バグ対策
+- }
+- polygon->setPoints(points);
+- points.clear();
+- }
+- }
+- fclose(fp);
+- int x = 0;
+- int y = 0;
+- for (uint i = 0; i < _draws.count(); ++i) {
+- if (y > _draws.at(i)->boundingRect().top()) {
+- y = _draws.at(i)->boundingRect().top();
+- }
+- if (x > _draws.at(i)->boundingRect().left()) {
+- x = _draws.at(i)->boundingRect().left();
+- }
+- }
+- for (uint i = 0; i < _draws.count(); ++i) {
+- _draws.at(i)->translate(-x, -y);
+- }
+- redraw();
+- FNMessageBox::information(0,"FreeNoteQt", "load complete.");
+-
+- return true;
+-}
+-
+-FNPolygon* FNCanvas::createPolygon(QPen& pen)
+-{
+- return new FNPolygon(pen);
+-}
+-
+-FNPolygon* FNCanvas::createBezier(QPen& pen)
+-{
+- return new FNBezier(pen);
+-}
+-
+-
+-FNPolygon* FNCanvas::createEllipse(QPen& pen)
+-{
+- return new FNEllipse(pen);
+-}
+-
+-QPoint* FNCanvas::createPts(int x, int y)
+-{
+- return new QPoint(x, y);
+-}
+-
+-void FNCanvas::setGuide(bool f)
+-{
+- _isShowGuide = f;
+- redraw();
+-}
++/* FreeNote for Sharp SLA300, B500, C7x0 Linux PDA
++ Copyright (C) 2003 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
++
++ 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
++*/
++/*
++2003/12/23 ver 1.6.1
++・保存情報のサイズ縮小
++
++2003/12/16-19 ver 1.5.5pre
++・ペンサイズの追加(1-8)
++・アンドゥ・リドゥの実装
++
++2003/12/14 ver 1.5.4pre
++・ペンサイズを選択可能に。
++
++2003/12/05 ver 1.5.3Apre
++・グリッドの色を修正
++
++2003/12/04 ver 1.5.3pre
++・グリッドの描画を一部修正
++
++2003/11/10 ver 1.5.1pre
++・曲線整形モード追加
++
++2003/11/09 ver 1.5.0pre
++・自動整形モード追加
++
++2003/09/03 ver 1.3.4pre
++・Use all quadrant OFF時に表示位置がリセットされる場合があるバグ対応。
++
++2003/09/01-03 ver 1.3.3pre
++・スクロールの改良
++・Use all quadrant(全象限を使用する)メニューを追加
++
++2003/08/31 FreeNote 1.3.2pre
++・全方向スクロール
++
++2003/08/23 FreeNote 1.3.0pre
++・CR動作の修正
++
++2003/08/15 FreeNote 1.2.1を公開
++・保存時のバグ修正
++・完了ダイアログの自動消去
++・PNGファイルへの出力
++
++2003/08/15 FreeNote 1.2を公開
++・オプション追加
++・スクロールガイド
++・Freeファイル関連付け
++・アイコンの変更
++
++2003/08/05 FreeNote 1.1.1preを公開
++・高速起動時に閉じた状態を保持
++・描画モード切替え時に消しゴム表示
++・保存時間短縮
++・Viewモードの挙動を変更
++・メニューの見た目を変更
++*/
++#include "fncanvas.h"
++#include <stdio.h>
++#include <qfile.h>
++#include <qmessagebox.h>
++#include <qtextstream.h>
++#include <qpen.h>
++#include <qcolor.h>
++#include <qpoint.h>
++#include <qthread.h>
++#include <qimage.h>
++#include <math.h>
++#include <stdlib.h> // abs
++#include "fnmessagebox.h"
++#include "fmtengine.h"
++
++int snap(int v) {
++ int tv = abs(v);
++ tv = ((int)(tv + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
++ if (0 > v) {
++ return -tv;
++ } else {
++ return tv;
++ }
++}
++
++FNCanvas::FNCanvas(QWidget* parent, const char* name, WFlags f )
++ :QWidget(parent, name, f),
++ _pen(black, 1, SolidLine, RoundCap, RoundJoin),
++ _asMode(AS_NONE),
++ _drawMode(MODE_DRAW),
++ _disp_offset(0),
++ _eraser_l(50),
++ _eraser_s(10),
++ _h_step(100),
++ _v_step(100),
++ _margin(5),
++ _scrollTiming(800),
++ _viewMode(false),
++ _isWaiting(false),
++ _isDragging(false),
++ _isHeadingEnables(false),
++ _isShowGuide(false),
++ _isUseAllQuadrant(false),
++ _scale_x(1.0),
++ _scale_y(1.0)
++{
++ _tracks.setAutoDelete(true);
++ this->setBackgroundMode(NoBackground);
++ _timer = new QTimer(this);
++ connect(_timer, SIGNAL(timeout()), this, SLOT(autoScroll()));
++}
++
++FNCanvas::~FNCanvas()
++{
++ _timer->stop();
++ delete _timer;
++
++ _tracks.clear();
++ clearList(_draws);
++}
++
++void FNCanvas::setScrollTiming(int v)
++{
++ _scrollTiming = v;
++}
++
++
++void FNCanvas::setVStep(int v)
++{
++ _v_step = v;
++}
++
++void FNCanvas::setHStep(int v)
++{
++ _h_step = v;
++}
++
++void FNCanvas::setSEraser(int v)
++{
++ _eraser_s = v;
++}
++
++void FNCanvas::setLEraser(int v)
++{
++ _eraser_l = v;
++}
++
++
++void FNCanvas::setMargin(int v)
++{
++ if (v < 3) {
++ v = 3;
++ }
++ _margin = v;
++}
++
++void FNCanvas::setScrollMode(int as)
++{
++ _asMode = as;
++ redraw();
++}
++
++void FNCanvas::autoScroll()
++{
++ if (AS_NONE == _asMode) {
++ if (MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode || MODE_SMOOTH == _drawMode) {
++ setOrigin(_origin.x(), _origin.y());
++ }
++ return;
++ }
++ bool tmp = _isHeadingEnables;
++ int dx = 0;
++ int dy = 0;
++ if (AS_BOTH == _asMode || AS_HORIZONTAL == _asMode) {
++ if (_last.x() > width() * (_margin - 1) / _margin) {
++ dx = _h_step;
++ } else if (_last.x() < width() / _margin) {
++ dx = -_h_step;
++ }
++ }
++ if (AS_BOTH == _asMode || AS_VERTICAL == _asMode) {
++ if (_last.y() > height() * (_margin - 1) / _margin) {
++ dy = _v_step;
++ } else if (_last.y() < height() / _margin) {
++ dy = -_v_step;
++ }
++ }
++ setOrigin(_origin.x() + dx, _origin.y() + dy);
++ _isHeadingEnables = tmp;
++}
++
++void FNCanvas::mousePressEvent(QMouseEvent* evt)
++{
++ setFocus();
++ _timer->stop();
++ _tracks.clear();
++ if (_viewMode) {
++ _isWaiting = true;
++ _viewMode = false;
++ setOrigin((int)((evt->x()) / _scale_x) - width() / 2, (int)((evt->y()) / _scale_y) - height() / 2);
++ redraw();
++ emit resetViewMode();
++ } else if (MODE_ERASE != _drawMode) {
++ _last = evt->pos();
++ _tracks.append(new QPoint(_last));
++ } else {
++ redraw();
++ _last = evt->pos();
++ _tracks.append(new QPoint(_last));
++
++ QPainter pbuf;
++ QPainter pwin;
++ pbuf.begin(&_buffer);
++ pwin.begin(this);
++
++ int w = _eraser_s;
++ if (PENWIDTH_MAX / 2 < _pen.width()) {
++ w = _eraser_l;
++ }
++ pbuf.setRasterOp(XorROP);
++ pbuf.setPen(QPen(white, 1));
++ pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
++
++ pwin.setRasterOp(XorROP);
++ pwin.setPen(QPen(white, 1));
++ pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
++
++ pbuf.end();
++ pwin.end();
++ }
++ _isDragging = true;
++}
++
++void FNCanvas::mouseMoveEvent(QMouseEvent* evt)
++{
++ if (_isWaiting) {
++ return;
++ }
++ if (MODE_ERASE != _drawMode) {
++ QPainter pwin;
++ QPainter pbuf;
++
++ pwin.begin(this);
++ pbuf.begin(&_buffer);
++
++ pwin.setPen(_pen);
++ pbuf.setPen(_pen);
++
++ pwin.drawLine(_last, evt->pos());
++ pbuf.drawLine(_last, evt->pos());
++
++ pwin.end();
++ pbuf.end();
++ _last = evt->pos();
++ _tracks.append(new QPoint(_last));
++ } else {
++ //redraw();
++ if (_last.x() == -1) {
++ return;
++ }
++ QPainter pbuf;
++ QPainter pwin;
++
++ pbuf.begin(&_buffer);
++ pwin.begin(this);
++
++ int w = _eraser_s;
++ if (PENWIDTH_MAX / 2 < _pen.width()) {
++ w = _eraser_l;
++ }
++ pbuf.setRasterOp(XorROP);
++ pwin.setRasterOp(XorROP);
++ pbuf.setPen(QPen(white, 1));
++ pwin.setPen(QPen(white, 1));
++ pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
++ pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
++
++ _tracks.append(new QPoint(evt->pos()));
++ _last = evt->pos();
++
++ pbuf.setRasterOp(CopyROP);
++ pwin.setRasterOp(CopyROP);
++ QRect r = QRect(0, 0, width(), height());
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ FNPolygon* p = _draws.at(i);
++ if (r.intersects(p->boundingRect())) {
++ bool f = false;
++ QRect selected(_last.x() - w / 2, _last.y() - w / 2, w, w);
++ for (uint j = 0; j < p->points().count(); ++j) {
++ QPoint& pts = p->points().at(j);
++ if (selected.contains(pts)) {
++ f = true;
++ break;
++ }
++ }
++ if (f) {
++ p->drawShape(pbuf, f);
++ p->drawShape(pwin, f);
++ }
++ }
++ }
++ pbuf.setRasterOp(XorROP);
++ pwin.setRasterOp(XorROP);
++ pbuf.setPen(QPen(white, 1));
++ pwin.setPen(QPen(white, 1));
++ pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
++ pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
++ pbuf.end();
++ pwin.end();
++ }
++}
++
++void FNCanvas::mouseReleaseEvent(QMouseEvent* evt)
++{
++ _isDragging = false;
++ if (_isWaiting) {
++ _isWaiting = false;
++ return;
++ }
++ _last = evt->pos();
++ if (MODE_ERASE != _drawMode) {
++ if (1 < _tracks.count()) {
++ FNPolygon* p = NULL;
++ if (MODE_FORMAT == _drawMode) {
++ p = new FNPolygon(_pen);
++ _tracks = AutoFormat(_tracks);
++ } else if (MODE_CURVE == _drawMode) {
++ QPoint sp = SnapPoint(*_tracks.at(0));
++ QPoint ep = SnapPoint(*_tracks.at(_tracks.count()-1));
++ _tracks = AutoCurve(_tracks);
++ if (sp == ep) {
++ p = new FNEllipse(_pen);
++ } else if (2 < _tracks.count()) {
++ p = new FNBezier(_pen);
++ } else {
++ p = new FNPolygon(_pen);
++ }
++ } else if (MODE_SMOOTH == _drawMode) {
++ _tracks = Smoothing(_tracks);
++ if (2 < _tracks.count()) {
++ p = new FNBezier(_pen);
++ } else {
++ p = new FNPolygon(_pen);
++ }
++ } else {
++ _tracks = Reduce(_tracks);
++ p = new FNPolygon(_pen);
++ }
++ if (1 < _tracks.count()) {
++ p->setPoints(_tracks);
++ redobuf_flush();
++ _draws.append(p);
++ }
++ }
++ _tracks.clear();
++ _isHeadingEnables = true;
++ _timer->start(_scrollTiming, true);
++ } else {
++ _last = QPoint(-1, -1);
++ _tracks.append(new QPoint(evt->pos()));
++ redraw();
++ }
++}
++
++void FNCanvas::paintEvent(QPaintEvent* evt)
++{
++ bitBlt(this, 0, 0, &_buffer);
++}
++
++void FNCanvas::resizeEvent(QResizeEvent* evt)
++{
++ QPixmap save(_buffer);
++ _buffer.resize(evt->size());
++ _buffer.fill(white);
++ bitBlt(&_buffer, 0, 0, &save);
++ redraw();
++}
++
++void FNCanvas::setOrigin(QPoint& o)
++{
++ this->setOrigin(o.x(), o.y());
++}
++
++QPoint FNCanvas::getTopLeft()
++{
++ if (0 == _draws.count() || !_isUseAllQuadrant) {
++ return _origin;
++ }
++
++ int dx = ((FNPolygon*)_draws.at(0))->boundingRect().x();
++ int dy = ((FNPolygon*)_draws.at(0))->boundingRect().y();
++ for (uint i = 1; i < _draws.count(); ++i) {
++ FNPolygon* p = _draws.at(i);
++ if (dx > p->boundingRect().x()) {
++ dx = p->boundingRect().x();
++ }
++ if (dy > p->boundingRect().y()) {
++ dy = p->boundingRect().y();
++ }
++ }
++ return QPoint(snap(dx), snap(dy));
++}
++
++
++void FNCanvas::rebuild()
++{
++ if (0 == _draws.count() || !_isUseAllQuadrant) {
++ return;
++ }
++
++ QPoint d = getTopLeft();
++ for (uint i = 0; i < _draws.count(); ++i) {
++ FNPolygon* p = _draws.at(i);
++ p->translate(-d.x(), -d.y());
++ }
++
++ _origin = QPoint(0, 0);
++}
++
++
++void FNCanvas::setOrigin(int ox, int oy)
++{
++ ox = snap(ox);
++ oy = snap(oy);
++ _isHeadingEnables = false;
++ _timer->stop();
++
++
++ int dx = 0;
++ int dy = 0;
++ if (!_isUseAllQuadrant) {
++ if (0 > ox) {
++ ox = 0;
++ }
++ if (0 > oy) {
++ oy = 0;
++ }
++ dx = _origin.x() - ox;
++ dy = _origin.y() - oy;
++ } else {
++ dx = _origin.x() - ox;
++ dy = _origin.y() - oy;
++ if (0 > ox) {
++ ox = 0;
++ }
++ if (0 > oy) {
++ oy = 0;
++ }
++ }
++ for (uint i = 0; i < _tracks.count(); ++i) {
++ QPoint* p = _tracks.at(i);
++ p->setX(p->x() + dx);
++ p->setY(p->y() + dy);
++ }
++
++ for (uint i = 0; i < _draws.count(); ++i) {
++ FNPolygon* p = _draws.at(i);
++ p->translate(dx, dy);
++ }
++ _origin = QPoint(ox, oy);
++ emit originChanged(ox, oy);
++ redraw();
++}
++
++void FNCanvas::redraw()
++{
++ if (!this->isVisible()) {
++ return;
++ }
++ _buffer.fill(white);
++ QPainter pbuf;
++ QRect r = QRect(0, 0, width(), height());
++ pbuf.begin(&_buffer);
++ if (_viewMode) {
++ float wx = 0;
++ float wy = 0;
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ FNPolygon* p = _draws.at(i);
++ QRect r = p->boundingRect();
++ if (wx < r.right()) {
++ wx = r.right();
++ }
++ if (wy < r.bottom()) {
++ wy = r.bottom();
++ }
++ }
++ wx += SNAP_SIZE;
++ wy += SNAP_SIZE;
++ wx = snap((int)wx);
++ wy = snap((int)wy);
++ wx = wx + _origin.x();
++ wy = wy + _origin.y();
++ _scale_x = (float)width() / wx;
++ _scale_y = (float)height() / wy;
++ if (1.0f < _scale_x) {
++ _scale_x = 1.0f;
++ }
++ if (1.0f < _scale_y) {
++ _scale_y = 1.0f;
++ }
++ if (_scale_x > _scale_y) {
++ _scale_x = _scale_y;
++ } else if (_scale_x < _scale_y) {
++ _scale_y = _scale_x;
++ }
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ FNPolygon* p = _draws.at(i);
++ FNPolygon* t = NULL;
++ if (p->type() == FN_BEZIER) {
++ t = new FNBezier(*(FNBezier*)p);
++ } else if (p->type() == FN_ELLIPSE) {
++ t = new FNEllipse(*(FNEllipse*)p);
++ } else {
++ t = new FNPolygon(*p);
++ }
++ t->translate(-_origin.x(), -_origin.y());
++ for (uint j = 0; j < t->points().count(); ++j) {
++ QPoint& pts = t->points().at(j);
++ int x = (int)(pts.x() * _scale_x);
++ int y = (int)(pts.y() * _scale_y);
++ pts.setX(x);
++ pts.setY(y);
++ }
++ double pensize = t->pen().width();
++ if (_scale_x > _scale_y) {
++ pensize = pensize * _scale_y;
++ } else {
++ pensize = pensize * _scale_x;
++ }
++ if (0 >= pensize) {
++ pensize = 1;
++ }
++ t->pen().setWidth(pensize);
++ t->drawShape(pbuf);
++ delete t;
++ }
++ } else if (MODE_ERASE != _drawMode) {
++ if (MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode) {
++ QPen pen1(QColor(0, 240, 240), 1);
++ QPen pen2(QColor(0, 0, 0), 1);
++ pbuf.setPen(QPen(QColor(0, 240, 240), 1));
++ pbuf.setPen(pen1);
++ for (int x = 0; x < width() + SNAP_SIZE; x += SNAP_SIZE) {
++ pbuf.drawLine(x - SNAP_SIZE / 2, 0, x - SNAP_SIZE / 2, height());
++ for (int y = 0; y < height() + SNAP_SIZE; y += SNAP_SIZE) {
++ pbuf.drawLine(0, y - SNAP_SIZE / 2, width(), y - SNAP_SIZE / 2);
++ pbuf.drawRect(x-1,y-1,2,2);
++ }
++ }
++ }
++ if (_isShowGuide) {
++ pbuf.setPen(QPen(cyan, 1, DashLine));
++ if (AS_HORIZONTAL == _asMode || AS_BOTH == _asMode) {
++ if (0 != _origin.x() || _isUseAllQuadrant) {
++ pbuf.drawLine(width() / _margin, 0, width() / _margin, height());
++ }
++ pbuf.drawLine(width() * (_margin - 1) / _margin, 0, width() * (_margin - 1) / _margin, height());
++ }
++
++ if (AS_VERTICAL == _asMode || AS_BOTH == _asMode) {
++ if (0 != _origin.y() || _isUseAllQuadrant) {
++ pbuf.drawLine(0, height() / _margin, width(), height() / _margin);
++ }
++ pbuf.drawLine(0, height() * (_margin - 1) / _margin, width(), height() * (_margin - 1) / _margin);
++ }
++ }
++
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ FNPolygon* p = _draws.at(i);
++ if (r.intersects(p->boundingRect())) {
++ p->drawShape(pbuf);
++ }
++ }
++ } else {
++ int w = _eraser_s;
++ if (PENWIDTH_MAX / 2 < _pen.width()) {
++ w = _eraser_l;
++ }
++ FNPointList removes;
++ for (uint i = 0; i < _tracks.count(); ++i) {
++ removes.append(_tracks.at(i));
++ }
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ FNPolygon* p = _draws.at(i);
++ if (r.intersects(p->boundingRect())) {
++ bool f = false;
++ for (uint j = 0; j < _tracks.count(); ++j) {
++ QPoint* pts = _tracks.at(j);
++ QRect selected(pts->x() - w / 2, pts->y() - w / 2, w, w);
++ for (uint k = 0; k < p->points().count(); ++k) {
++ QPoint& pts2 = p->points().at(k);
++ if (selected.contains(pts2)) {
++ f = true;
++ removes.remove(pts);
++ break;
++ }
++ }
++ if (f) {
++ break;
++ }
++ }
++ p->drawShape(pbuf, f);
++ }
++ }
++ for (uint i = 0; i < removes.count(); ++i) {
++ _tracks.remove(removes.at(i));
++ }
++ /*
++ if (_isDragging) {
++ pbuf.setPen(QPen(black, 1));
++ pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
++ }
++ */
++ }
++ pbuf.end();
++ repaint();
++}
++
++void FNCanvas::changeColor(QRgb c)
++{
++ _pen.setColor(QColor(c));
++}
++
++void FNCanvas::undo()
++{
++ if (MODE_ERASE != _drawMode) {
++ ++_disp_offset;
++ if (_disp_offset > _draws.count()) {
++ _disp_offset = _draws.count();
++ }
++ } else {
++ _draws = _undobuf;
++ _marks.clear();
++ }
++ redraw();
++}
++
++void FNCanvas::redo()
++{
++ if (MODE_ERASE != _drawMode) {
++ if (0 < _disp_offset) {
++ --_disp_offset;
++ }
++ }
++ redraw();
++}
++
++void FNCanvas::clearList(FNPolygonList& list)
++{
++ list.setAutoDelete(true);
++ list.clear();
++ list.setAutoDelete(false);
++}
++
++void FNCanvas::clear()
++{
++ _disp_offset = 0;
++ clearList(_draws);
++ _undobuf.clear();
++ setOrigin(0, 0);
++ redraw();
++}
++
++void FNCanvas::viewChanged(bool flg)
++{
++ _tracks.clear();
++ _viewMode = flg;
++ if (_viewMode) {
++ if (_isUseAllQuadrant) {
++ rebuild();
++ }
++ setOrigin(0, 0);
++ }
++ redraw();
++}
++
++void FNCanvas::redobuf_flush()
++{
++ for (uint i = 0; i < _disp_offset; ++i) {
++ FNPolygon* p = _draws.last();
++ _draws.remove(p);
++ delete p;
++ }
++ _disp_offset = 0;
++}
++
++void FNCanvas::modeChanged(int mode)
++{
++ _tracks.clear();
++ _drawMode = mode;
++ redobuf_flush();
++ if (MODE_ERASE == _drawMode) {
++ _marks.clear();
++ _undobuf = _draws;
++ } else {
++ if (_draws.count() != _undobuf.count()) {
++ for (uint i = 0; i < _marks.count(); ++i) {
++ FNPolygon* p = _marks.at(i);
++ _draws.remove(p);
++ }
++ clearList(_marks);
++ }
++ }
++ redraw();
++}
++
++QRect FNCanvas::getMatrix(const QRect& r) const
++{
++ int ox = _origin.x();
++ int oy = _origin.y();
++ const int wide = 100;
++
++ int left = r.left() + ox;
++ int top = r.top() + oy;
++ int right = r.right() + ox;
++ int bottom = r.bottom() + oy;
++
++ left = (int)(left / wide) * wide;
++ top = (int)(top / wide) * wide;
++ right = (right % wide == 0 && left != right) ? right : (int)((right + wide) / wide) * wide;
++ bottom = (bottom % wide == 0 && top != bottom) ? bottom : (int)((bottom + wide) / wide) * wide;
++
++ return QRect(left - ox, top - oy, right - left, bottom - top);
++}
++
++void FNCanvas::CR()
++{
++ if (MODE_ERASE == _drawMode) {
++ return;
++ }
++ if (_isHeadingEnables) {
++ //lastから、左方向に向けて探索する。
++ QRect r = getMatrix(_draws.last()->boundingRect());
++ bool isSearching = true;
++ r.moveBy(-100, 0);
++ while (isSearching) {
++ isSearching = false;
++ for (uint i = 0; i < _draws.count(); ++i) {
++ FNPolygon* p = _draws.at(i);
++ const QRect& r2 = p->boundingRect();
++ if (r.intersects(r2)) {
++ if (r.left() + 100 > r2.left()) {
++ r = getMatrix(r2);
++ r.moveBy(-100, 0);
++ isSearching = true;
++ break;
++ }
++ }
++ }
++ }
++ r.moveBy(100, 0);
++ //lastが画面の4/5以下ならば、スクロールアップする。
++ //そうでなければ、ヘッディングのみ。
++ if (_last.y() > height() * 4 / 5) {
++ setOrigin(_origin.x() + r.x(), _origin.y() + 50);
++ } else {
++ setOrigin(_origin.x() + r.x(), _origin.y());
++ }
++ _isHeadingEnables = false;
++ } else {
++ //lastの周囲に何も無い場合は、縦にスクロールする。
++ setOrigin(_origin.x(), _origin.y() + 50);
++ }
++}
++
++void FNCanvas::erase()
++{
++ if (MODE_ERASE != _drawMode) {
++ return;
++ }
++ FNPolygonList temp;
++ int w = _eraser_s;
++ if (PENWIDTH_MAX / 2 < _pen.width()) {
++ w = _eraser_l;
++ }
++ QRect r = QRect(0, 0, width(), height());
++ for (uint i = 0; i < _draws.count(); ++i) {
++ FNPolygon* p = _draws.at(i);
++ bool f = false;
++ if (r.intersects(p->boundingRect())) {
++ for (uint j = 0; j < _tracks.count(); ++j) {
++ QPoint* pts = _tracks.at(j);
++ QRect selected(pts->x() - w / 2, pts->y() - w / 2, w, w);
++ for (uint k = 0; k < p->points().count(); ++k) {
++ QPoint& pts2 = p->points().at(k);
++ if (selected.contains(pts2)) {
++ temp.append(p);
++ f = true;
++ break;
++ }
++ }
++ if (f) {
++ break;
++ }
++ }
++ }
++ }
++ for (uint i = 0; i < temp.count(); ++i) {
++ _draws.remove(temp.at(i));
++ _marks.append(temp.at(i));
++ }
++ _tracks.clear();
++ redraw();
++}
++
++void FNCanvas::setPensize(int sz)
++{
++ _pen.setWidth(sz);
++}
++
++bool FNCanvas::exportPNG(const QFileInfo& info, QPixmap& buf)
++{
++ if (0 == info.fileName().length()) {
++ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
++ return false;
++ }
++ if (info.extension(false) != "png") {
++ QMessageBox::warning(0,"FreeNoteQt", "extension '.png' expected.");
++ return false;
++ }
++
++ bool ret = buf.save(info.absFilePath(), "PNG");
++ if (ret) {
++ FNMessageBox::information(0,"FreeNoteQt", "export PNG complete.");
++ } else {
++ QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
++ }
++ return ret;
++}
++
++QString FNCanvas::mkPDFscript(FNPolygon* elm)
++{
++ QString s ="";
++ char buf[1024];
++
++ float r = (float)elm->pen().color().red() / 255.0f;
++ float g = (float)elm->pen().color().green() / 255.0f;
++ float b = (float)elm->pen().color().blue() / 255.0f;
++ s += "q\n";
++ sprintf(buf, "%f %f %f RG\n", r, g, b);
++ s += buf;
++ QPointArray points = elm->points().copy();
++ points.translate(_origin.x(), _origin.y());
++ if (elm->type() == FN_BEZIER) {
++ sprintf(buf, "%d %d m\n", points[0].x(), points[0].y());
++ s += buf;
++ for (uint j = 1; j < points.count(); j += 3) {
++ sprintf(buf, "%d %d %d %d %d %d c\n",
++ points[j].x(), points[j].y(),
++ points[j + 1].x(), points[j + 1].y(),
++ points[j + 2].x(), points[j + 2].y()
++ );
++ s += buf;
++ }
++ } else if (elm->type() == FN_ELLIPSE) {
++ int x = points[0].x();
++ int y = points[0].y();
++ int ex = points[1].x();
++ int ey = points[1].y();
++ int w = ex - x;
++ int h = ey - y;
++ int cx = x + w/2;
++ int cy = y;
++ int x1 = x + 3*w/4;
++ int y1 = y;
++ int x2 = x + w;
++ int y2 = y + h/4;
++ int x3 = x + w;
++ int y3 = y + h/2;
++
++ sprintf(buf, "%d %d m\n%d %d %d %d %d %d c\n", cx, cy, x1, y1, x2, y2, x3, y3);
++ s += buf;
++ x1 = x + w;
++ y1 = y + 3 * h / 4;
++ x2 = x + 3 * w / 4;
++ y2 = y + h;
++ x3 = x + w/2;
++ y3 = y + h;
++ sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
++ s += buf;
++
++ x1 = x + w / 4;
++ y1 = y + h;
++ x2 = x;
++ y2 = y + 3 * h / 4;
++ x3 = x;
++ y3 = y + h / 2;
++ sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
++ s += buf;
++ x1 = x;
++ y1 = y + h / 4;
++ x2 = x + w / 4;
++ y2 = y;
++ x3 = x + w / 2;
++ y3 = y;
++ sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
++ s += buf;
++ } else {
++ sprintf(buf, "%d %d m\n", points[0].x(), points[0].y());
++ s += buf;
++ for (uint j = 1; j < points.count(); ++j) {
++ sprintf(buf, "%d %d l\n", points[j].x(), points[j].y());
++ s += buf;
++ }
++ }
++ sprintf(buf, "%d w\n", elm->pen().width());
++ s += buf;
++ s += "S\n";
++ s += "Q\n";
++ return s;
++}
++
++bool FNCanvas::exportPDF(const QFileInfo& info)
++{
++ if (0 == info.fileName().length()) {
++ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
++ return false;
++ }
++ if (info.extension(false) != "pdf") {
++ QMessageBox::warning(0,"FreeNoteQt", "extension '.pdf' expected.");
++ return false;
++ }
++
++ FILE* fp = NULL;
++ if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
++ QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
++ return false;
++ }
++
++ QPoint o = getTopLeft();
++ rebuild();
++ int wx = 595;
++ int wy = 842;
++ char buf[1024];
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ FNPolygon* p = _draws.at(i);
++ QRect r = p->boundingRect();
++ r.moveBy(_origin.x(), _origin.y());
++ if (wx < r.right()) {
++ wx =r.right();
++ }
++ if (wy < r.bottom()) {
++ wy = r.bottom();
++ }
++ }
++
++ int len = 0;
++
++ sprintf(buf, "1 0 0 -1 0 %d cm\n", wy);
++ QString cm = buf;
++ len += cm.length();
++
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ QString s = mkPDFscript(_draws.at(i));
++ len += s.length();
++ }
++
++ QString header = "";
++ header += "%PDF-1.3\n";
++ header += "1 0 obj\n";
++ header += "<<\n";
++ header += "/Type /Page\n";
++ header += "/Parent 3 0 R\n";
++ header += "/Resources\n";
++ header += "<<\n";
++ header += "/ProcSet [ /PDF ]\n";
++ header += ">>\n";
++ sprintf(buf, "/MediaBox [ 0 0 %010d %010d ]\n", wx, wy);
++ header += buf;
++ header += "/Contents 4 0 R\n";
++ header += ">>\n";
++ header += "endobj\n";
++ header += "2 0 obj\n";
++ header += "<<\n";
++ header += "/Type /Catalog\n";
++ header += "/Pages 3 0 R\n";
++ header += "/PageLayout /OneColumn\n";
++ header += "/OpenAction [1 0 R /XYZ null null 1 ]\n";
++ header += ">>\n";
++ header += "endobj\n";
++ header += "3 0 obj\n";
++ header += "<<\n";
++ header += "/Type /Pages\n";
++ header += "/Kids [ 1 0 R ]\n";
++ header += "/Count 1\n";
++ header += ">>\n";
++ header += "endobj\n";
++ header += "4 0 obj\n";
++ sprintf(buf, "<< /Length %010d >>\n", len);
++ header += buf;
++ header += "stream\n";
++
++ QString footer = "";
++ footer += "xref\n";
++ footer += "0 5\n";
++ footer += "0000000000 65535 f \n";
++ footer += "0000000009 00000 n \n";
++ footer += "0000000147 00000 n \n";
++ footer += "0000000257 00000 n \n";
++ footer += "0000000316 00000 n \n";
++ footer += "trailer\n";
++ footer += "<<\n";
++ footer += "/Size 5\n";
++ footer += "/Root 2 0 R\n";
++ footer += ">>\n";
++ footer += "startxref\n";
++
++ len = cm.length();
++ len += header.length();
++ fputs(header, fp);
++ fputs(cm, fp);
++
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ QString s = mkPDFscript(_draws.at(i));
++ len += s.length();
++ fputs(s, fp);
++ }
++ QString streamfooter = "endstream\nendobj\n";
++ len += streamfooter.length();
++ fputs(streamfooter, fp);
++
++ fputs(footer, fp);
++ sprintf(buf, "%d\n", len);
++ fputs(buf, fp);
++ fputs("%%EOF\n", fp);
++ fclose(fp);
++ if (_isUseAllQuadrant) {
++ setOrigin(-o.x(), -o.y());
++ }
++ FNMessageBox::information(0,"FreeNoteQt", "export PDF complete.");
++ return true;
++}
++
++bool FNCanvas::save(const QFileInfo& info)
++{
++ if (0 == info.fileName().length()) {
++ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
++ return false;
++ }
++ if (info.extension(false) != "free") {
++ QMessageBox::warning(0,"FreeNoteQt", "extension '.free' expected.");
++ return false;
++ }
++ FILE* fp = NULL;
++ if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
++ QMessageBox::warning(0,"FreeNoteQt", "could not save file.");
++ return false;
++ }
++ QPoint o = getTopLeft();
++ rebuild();
++ fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
++ fputs("<freenote version=\"2.0\">\n", fp);
++ char buf[1024];
++ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
++ FNPolygon p(*_draws.at(i));
++ p.translate(_origin.x(), _origin.y());
++ if (p.type() == FN_BEZIER) {
++ sprintf(buf, "\t<bz color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
++ } else if (p.type() == FN_ELLIPSE) {
++ sprintf(buf, "\t<el color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
++ } else {
++ sprintf(buf, "\t<po color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
++ }
++ fputs(buf, fp);
++ QPointArray& points = p.points();
++ for (uint j = 0; j < points.count(); ++j) {
++ QPoint point = points.point(j);
++ sprintf(buf, "\t\t<p x=\"%d\" y=\"%d\"/>\n", point.x(), point.y());
++ fputs(buf, fp);
++ }
++ if (p.type() == FN_BEZIER) {
++ fputs("\t</bz>\n", fp);
++ } else if (p.type() == FN_ELLIPSE) {
++ fputs("\t</el>\n", fp);
++ } else {
++ fputs("\t</po>\n", fp);
++ }
++ }
++ fputs("</freenote>\n", fp);
++ fclose(fp);
++ if (_isUseAllQuadrant) {
++ setOrigin(-o.x(), -o.y());
++ }
++ FNMessageBox::information(0, "FreeNoteQt", "save complete.");
++ return true;
++}
++
++bool FNCanvas::load(const QFileInfo& info)
++{
++ if (0 == info.fileName().length()) {
++ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
++ return false;
++ }
++ if (!info.exists()) {
++ QMessageBox::warning(0,"FreeNoteQt", "file not exists.");
++ return false;
++ }
++ FILE* fp = NULL;
++ if (!(fp = fopen(info.absFilePath().utf8(), "rt"))) {
++ QMessageBox::warning(0,"FreeNoteQt", "could not open file.");
++ return false;
++ }
++ clear();
++
++ QString line;
++ FNPointList points;
++ points.setAutoDelete(true);
++ int c;
++ int w;
++ QPen pen(Qt::black, 1);
++ FNPolygon* polygon;
++
++ char rdbuf[1024];
++ char buf[1024];
++ QString type = "";
++ while (!feof(fp)) {
++ fgets(rdbuf, sizeof(rdbuf), fp);
++ line = rdbuf;
++ if (-1 != line.find("<fnpolygon ") ||
++ -1 != line.find("<po ") ||
++ -1 != line.find("<bz ") ||
++ -1 != line.find("<el ")
++ ) {
++ if (-1 != line.find("<el ")) {
++ type = "Ellipse";
++ } else if (-1 != line.find("<bz ")) {
++ type = "Bezier";
++ } else {
++ type = "Polygon";
++ }
++ points.clear();
++ int st = line.find("color") + 7;
++ int ed = line.find("\"", st);
++ strcpy(buf, line.mid(st, ed - st).utf8());
++ sscanf(buf, "%x", &c);
++ st = line.find("width") + 7;
++ ed = line.find("\"", st);
++ strcpy(buf, line.mid(st, ed - st).utf8());
++ sscanf(buf, "%d", &w);
++ } else if (-1 != line.find("<point ") ||
++ -1 != line.find("<p ")
++ ) {
++ int st = line.find("x=") + 3;
++ int ed = line.find("\"", st);
++ strcpy(buf, line.mid(st, ed - st).utf8());
++ int x;
++ sscanf(buf, "%d", &x);
++
++ st = line.find("y=") + 3;
++ ed = line.find("\"", st);
++ strcpy(buf, line.mid(st, ed - st).utf8());
++ int y;
++ sscanf(buf, "%d", &y);
++ points.append(createPts(x, y)); //バグ対策
++ } else if (-1 != line.find("</fnpolygon") ||
++ -1 != line.find("</bz") ||
++ -1 != line.find("</el") ||
++ -1 != line.find("</po")) {
++ pen.setColor((QRgb)c);
++ pen.setWidth(w);
++ if (type == "Bezier") {
++ _draws.append(polygon = createBezier(pen)); //バグ対策
++ } else if (type == "Ellipse") {
++ _draws.append(polygon = createEllipse(pen)); //バグ対策
++ } else {
++ _draws.append(polygon = createPolygon(pen)); //バグ対策
++ }
++ polygon->setPoints(points);
++ points.clear();
++ }
++ }
++ fclose(fp);
++ int x = 0;
++ int y = 0;
++ for (uint i = 0; i < _draws.count(); ++i) {
++ if (y > _draws.at(i)->boundingRect().top()) {
++ y = _draws.at(i)->boundingRect().top();
++ }
++ if (x > _draws.at(i)->boundingRect().left()) {
++ x = _draws.at(i)->boundingRect().left();
++ }
++ }
++ for (uint i = 0; i < _draws.count(); ++i) {
++ _draws.at(i)->translate(-x, -y);
++ }
++ redraw();
++ FNMessageBox::information(0,"FreeNoteQt", "load complete.");
++
++ return true;
++}
++
++FNPolygon* FNCanvas::createPolygon(QPen& pen)
++{
++ return new FNPolygon(pen);
++}
++
++FNPolygon* FNCanvas::createBezier(QPen& pen)
++{
++ return new FNBezier(pen);
++}
++
++
++FNPolygon* FNCanvas::createEllipse(QPen& pen)
++{
++ return new FNEllipse(pen);
++}
++
++QPoint* FNCanvas::createPts(int x, int y)
++{
++ return new QPoint(x, y);
++}
++
++void FNCanvas::setGuide(bool f)
++{
++ _isShowGuide = f;
++ redraw();
++}