From 007c005529f5cf15d05b076845fbd2cd12a547f4 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Sun, 21 May 2006 15:33:23 +0000 Subject: add freenote, an error correcting paint program for Opie. patch based on work by Enodr , thanks! closes #1018 --- packages/freenote/.mtn2git_empty | 0 packages/freenote/files/.mtn2git_empty | 0 packages/freenote/files/FreeNote/.mtn2git_empty | 0 .../files/FreeNote/FreeNote/.mtn2git_empty | 0 .../freenote/files/FreeNote/FreeNote/FNCanvas.cpp | 2244 +++++++++++++ .../files/FreeNote/FreeNote/FNFindDialog.cpp | 143 + .../files/FreeNote/FreeNote/FNMessageBox.cpp | 243 ++ .../files/FreeNote/FreeNote/FNTextDialog.cpp | 93 + .../freenote/files/FreeNote/FreeNote/FmtEngine.cpp | 512 +++ .../freenote/files/FreeNote/FreeNote/FrmMain.cpp | 1442 +++++++++ .../freenote/files/FreeNote/apps/.mtn2git_empty | 0 .../FreeNote/apps/Applications/.mtn2git_empty | 0 .../FreeNote/apps/Applications/FreeNote.desktop | 10 + .../files/FreeNote/apps/Settings/.mtn2git_empty | 0 .../FreeNote/apps/Settings/FreeNoteSetup.desktop | 9 + .../freenote/files/FreeNote/pics/.mtn2git_empty | 0 packages/freenote/files/FreeNote/pics/fnsetup.png | Bin 0 -> 1317 bytes packages/freenote/files/FreeNote/pics/freenote.png | Bin 0 -> 1024 bytes packages/freenote/freenote_1.12.0.bb | 33 + packages/nonworking/freenote/.mtn2git_empty | 0 .../freenote/freenote-1.6.1/.mtn2git_empty | 0 .../freenote/freenote-1.6.1/compile.patch | 3285 -------------------- packages/nonworking/freenote/freenote_1.6.1.bb | 22 - 23 files changed, 4729 insertions(+), 3307 deletions(-) create mode 100644 packages/freenote/.mtn2git_empty create mode 100644 packages/freenote/files/.mtn2git_empty create mode 100644 packages/freenote/files/FreeNote/.mtn2git_empty create mode 100644 packages/freenote/files/FreeNote/FreeNote/.mtn2git_empty create mode 100644 packages/freenote/files/FreeNote/FreeNote/FNCanvas.cpp create mode 100644 packages/freenote/files/FreeNote/FreeNote/FNFindDialog.cpp create mode 100644 packages/freenote/files/FreeNote/FreeNote/FNMessageBox.cpp create mode 100644 packages/freenote/files/FreeNote/FreeNote/FNTextDialog.cpp create mode 100644 packages/freenote/files/FreeNote/FreeNote/FmtEngine.cpp create mode 100644 packages/freenote/files/FreeNote/FreeNote/FrmMain.cpp create mode 100644 packages/freenote/files/FreeNote/apps/.mtn2git_empty create mode 100644 packages/freenote/files/FreeNote/apps/Applications/.mtn2git_empty create mode 100644 packages/freenote/files/FreeNote/apps/Applications/FreeNote.desktop create mode 100644 packages/freenote/files/FreeNote/apps/Settings/.mtn2git_empty create mode 100644 packages/freenote/files/FreeNote/apps/Settings/FreeNoteSetup.desktop create mode 100644 packages/freenote/files/FreeNote/pics/.mtn2git_empty create mode 100644 packages/freenote/files/FreeNote/pics/fnsetup.png create mode 100644 packages/freenote/files/FreeNote/pics/freenote.png create mode 100644 packages/freenote/freenote_1.12.0.bb delete mode 100644 packages/nonworking/freenote/.mtn2git_empty delete mode 100644 packages/nonworking/freenote/freenote-1.6.1/.mtn2git_empty delete mode 100644 packages/nonworking/freenote/freenote-1.6.1/compile.patch delete mode 100644 packages/nonworking/freenote/freenote_1.6.1.bb diff --git a/packages/freenote/.mtn2git_empty b/packages/freenote/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/freenote/files/.mtn2git_empty b/packages/freenote/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/freenote/files/FreeNote/.mtn2git_empty b/packages/freenote/files/FreeNote/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/freenote/files/FreeNote/FreeNote/.mtn2git_empty b/packages/freenote/files/FreeNote/FreeNote/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/freenote/files/FreeNote/FreeNote/FNCanvas.cpp b/packages/freenote/files/FreeNote/FreeNote/FNCanvas.cpp new file mode 100644 index 0000000000..6e7f615600 --- /dev/null +++ b/packages/freenote/files/FreeNote/FreeNote/FNCanvas.cpp @@ -0,0 +1,2244 @@ +/* FreeNote for Sharp SLA300, B500, C7x0, C860 Linux PDA + Copyright (C) 2003-2005 Joe Kanemori. + + 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 +*/ +/* +2005/06/04 FreeNote 1.11.12pre +・グリッドの枠線を実際の選択範囲よりも大きく表示するように変更。 +・範囲選択、グリッド、ガイド、罫線カラーのカスタマイズを可能に。 +・カラーピッカーモードの追加 + +2005/06/02 FreeNote 1.11.11Apre +・テキスト移動枠の不具合修正 +・罫線をグリッドの2倍で表示するように変更 +・消しゴム時の範囲指定時に、ペンオフしてワンテンポおいてから範囲確定するように変更 + +2005/03/18 FreeNote 1.11.10Bpre +・描画の最適化 + +2005/02/27 FreeNote 1.11.10pre +・PDFの出力形式を一部変更 +・インポート時のバグfix + +2005/01/04 FreeNote 1.11.6pre +・カーブモードで8の字がかけるように整形エンジンを改善 + +2005/01/04 FreeNote 1.11.5Apre +・バグフィックス + +2004/12/25 FreeNote 1.11.5pre +・レイヤー機能追加 + +2004/11/24 FreeNote 1.11.0pre +・テキストペースト機能 + +2004/10/17 FreeNote 1.10.0リリース +2004/08/26 ver 1.9.3pre +・罫線機能を追加 + +2004/05/23 ver 1.9.1Apre +・欧文環境対応 + +2004/02/16 ver 1.7.3pre +・編集機能強化 + +2004/02/14 ver 1.7.2pre +・検索機能追加 + +2004/02/12 ver 1.7.1pre +・フォント仕様の変更 +・テキスト処理の高速化 +・テキストボックスの多機能化 + +2003/02/10 ver 1.7.0pre +・文字入力 + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fnmessagebox.h" +#include "fmtengine.h" +#include "fntextdialog.h" +#include +#include +#include +#include "frmmain.h" +#include "fnlayerdlg.h" +#include + +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(FNColorDialog* dlg, QWidget* parent, const char* name, WFlags f) + :QWidget(parent, name, f), + _txtTmp(NULL), + _pen(black, 1, SolidLine, RoundCap, RoundJoin), + _asMode(AS_NONE), + _drawMode(MODE_DRAW), + _prevMode(MODE_DRAW), + _eraser_l(50), + _eraser_s(10), + _h_step(100), + _v_step(100), + _margin(5), + _scrollTiming(800), + _selIdx(0), + _viewMode(false), + _isWaiting(false), + _isDragging(false), + _isDrawing(false), + _isHeadingEnables(false), + _isShowGuide(false), + _isUseAllQuadrant(false), + _showRuler(false), + _isTinyPaging(false), + _scale_x(1.0), + _scale_y(1.0), + _tboxRect(0, 50, 220, 240), + _isEraseWaiting(false), + _colorSelector(dlg), + _isColorRevision(true) +{ + _tracks.setAutoDelete(true); + _clipboard.setAutoDelete(true); + _current = new FNLayer(); + _layers.append(_current); + _layers.setAutoDelete(true); + _undobuf.setAutoDelete(true); + _current->Name = "Layer0"; + this->setBackgroundMode(NoBackground); + _timer = new QTimer(this); + connect(_timer, SIGNAL(timeout()), this, SLOT(autoScroll())); + _dlgFind = new FNFindDialog(this, "Find"); + connect(_dlgFind, SIGNAL(originChanged(int, int)), this, SLOT(setOrigin(int, int))); + connect(_dlgFind, SIGNAL(resetOrigin()), this, SLOT(resetOrigin())); + +} + +FNCanvas::~FNCanvas() +{ + _timer->stop(); + delete _timer; + + _tracks.clear(); + _layers.clear(); + //clearList(_draws); + + delete _dlgFind; +} + + +void FNCanvas::addLayer() +{ + FNLayer* layer = new FNLayer(); + _current=layer; + uint cnt = _layers.count(); + while (1) { + QString name = "Layer"; + name += QString::number(cnt); + + bool nameExists = false; + for (uint i = 0; i < _layers.count(); ++i) { + if (_layers.at(i)->Name == name) { + nameExists = true; + break; + } + } + if (false == nameExists) { + layer->Name = name; + break; + } + ++cnt; + } + _layers.append(layer); + _selIdx = _layers.count() - 1; + redraw(); + +} + +//表示レイヤーを下に移動する +void FNCanvas::moveAboveLayer() +{ + --_selIdx; + if (0 > _selIdx) { + _selIdx = 0; + } + _current = _layers.at(_selIdx); + redraw(); +} + +//表示レイヤーを上に移動する +void FNCanvas::moveBelowLayer() +{ + ++_selIdx; + if (_layers.count() - 1 <= (uint)_selIdx) { + _selIdx = _layers.count() - 1; + } + _current = _layers.at(_selIdx); + redraw(); +} + + +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::find() +{ + if (_viewMode) { + return; + } + _dlgFind->setElements(_layers); + _dlgFind->show(); + _dlgFind->exec(); +} + +void FNCanvas::setScrollMode(int as) +{ + _asMode = as; + redraw(); +} + +void FNCanvas::autoScroll() +{ + if (MODE_ERASE == _drawMode) { + if (0 < _selection.width()) { + int hsn = SNAP_SIZE / 2; + int qsn = hsn / 2; + int x = ((_selection.x() - qsn) / hsn) * hsn; + int y = ((_selection.y() - qsn) / hsn) * hsn; + int dx = _selection.x() - x; + int dy = _selection.y() - y; + int w = ((_selection.width() + dx + hsn) / hsn) * hsn; + int h = ((_selection.height() + dy + hsn) / hsn) * hsn; + _selection.setRect(x, y, w, h); + _isSelected = true; + } + _last = QPoint(-1, -1); + _tracks.clear(); + _isHeadingEnables = false; + _isEraseWaiting = false; + redraw(); + } else { + if (AS_NONE == _asMode) { + setOrigin(_origin.x(), _origin.y(), false); + redraw(); + 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, false); + _isHeadingEnables = tmp; + redraw(); + } +} + +void FNCanvas::drawRect(QPainter& pa, const QRect& r) +{ + int w = width(); + int h = height(); + int sx = r.left(); + int sy = r.top(); + int ex = r.right(); + int ey = r.bottom(); + if (0 > sx) { + sx = 0; + } + if (0 > sy) { + sy = 0; + } + if (h < ey) { + ey = h; + } + if (w < ex) { + ex = w; + } + if (0 <= r.left()) { + pa.drawLine(sx, sy, sx, ey); + } + if (0 <= r.top()) { + pa.drawLine(sx, sy, ex, sy); + } + if (w >= r.right()) { + pa.drawLine(ex, sy, ex, ey); + } + if (h >= r.bottom()) { + pa.drawLine(sx, ey, ex, ey); + } +} + +void FNCanvas::mousePressEvent(QMouseEvent* evt) +{ + if (!_current->IsShow) { + return; + } + setFocus(); + _timer->stop(); + _tracks.clear(); + _txtwait = 10; + if (_viewMode) { + _isWaiting = true; + _viewMode = false; + setOrigin((int)((evt->x()) / _scale_x) - width() / 2, (int)((evt->y()) / _scale_y) - height() / 2, false); + //redraw(); + emit resetViewMode(); + } else if (MODE_CPICK == _drawMode) { + QRgb c = _buffer.convertToImage().pixel(evt->pos().x(), evt->pos().y()); + emit pickColor(c); + return; + } else if (MODE_TEXT == _drawMode) { + _txtTmp = NULL; +// _last = evt->pos(); + _last = SnapPoint(evt->pos(), SNAP_SIZE / 4); + int x = _last.x(); + int y = _last.y(); + for (int i = _current->draws.count() - _current->disp_offset() - 1; i >= 0; --i) { + FNPolygon* p = _current->draws.at((uint)i); + if (FN_TEXT == p->type()) { + QRect r = p->boundingRect(); + if (r.contains(x, y)) { + _txtTmp = (FNText*)p; + _selection.setRect(0, 0, -1, -1); + _tdx = _last.x() - r.x(); + _tdy = _last.y() - r.y(); + break; + } + } + } + } else if (MODE_ERASE == _drawMode) { + if (_isEraseWaiting) { + return; + } + _last = evt->pos(); + + if (0 >= _selection.width() || !_selection.contains(_last)) { + _isSelected = false; + } + if (!_isSelected) { + _selection = QRect(0, 0, -1, -1); + _selected.clear(); + redraw(); + + int w = _eraser_s; + if (PENWIDTH_MAX / 2 < _pen.width()) { + w = _eraser_l; + } + // 大バグ対策: + // 0 > xの座標に、縦150位の四角形を書くと、C系ザウのパフォーマンスが激落ちします。 + // 以降同様のロジックはこの対策のためです。 + QPainter pwin; + pwin.begin(this); + pwin.setRasterOp(XorROP); + pwin.setPen(QPen(white, 1)); + _preRect.setRect(_last.x() - w / 2, _last.y() - w / 2, w, w); + drawRect(pwin, _preRect); + pwin.flush(); + pwin.end(); + _selection = QRect(0, 0, -1, -1); + _selected.clear(); + } else { + QPainter pwin; + pwin.begin(this); + + pwin.setRasterOp(XorROP); + pwin.setPen(QPen(white, 1)); + _preRect.setRect(_selection.x(), _selection.y(), _selection.width(), _selection.height()); + drawRect(pwin, _preRect); + + pwin.flush(); + pwin.end(); + QPoint t = SnapPoint(QPoint(_selection.x(), _selection.y())); + _last = SnapPoint(_last); + + _tdx = _last.x() - t.x(); + _tdy = _last.y() - t.y(); + } + } else { + _last = evt->pos(); + _tracks.append(new QPoint(_last)); + } + _isDragging = true; +} + +void FNCanvas::mouseMoveEvent(QMouseEvent* evt) +{ + if (!_current->IsShow) { + return; + } + if (_isWaiting) { + return; + } + if (MODE_TEXT == _drawMode) { + if (NULL == _txtTmp) { + return; + } + if (0 < _txtwait) { + --_txtwait; + return; + } + QPainter pwin; + pwin.begin(this); + if (-1 != _selection.width()) { + pwin.setRasterOp(XorROP); + pwin.setPen(QPen(white, 1)); + drawRect(pwin, _selection); + } else { + _selection = _txtTmp->boundingRect(); + } + QPoint tmp = SnapPoint(evt->pos(), SNAP_SIZE / 4); + tmp.setX(tmp.x() - _tdx); + tmp.setY(tmp.y() - _tdy); + if (tmp != _last) { + _selection.moveTopLeft(tmp); + _last = tmp; + } + drawRect(pwin, _selection); + pwin.flush(); + pwin.end(); + } else if (MODE_CPICK == _drawMode) { + QRgb c = _buffer.convertToImage().pixel(evt->pos().x(), evt->pos().y()); + emit pickColor(c); + return; + } else if (MODE_ERASE == _drawMode) { + //redraw(); + if (_last.x() == -1) { + return; + } + if (!_isSelected) { + int w = _eraser_s; + if (PENWIDTH_MAX / 2 < _pen.width()) { + w = _eraser_l; + } + QPainter pwin; + pwin.begin(this); + + pwin.setRasterOp(XorROP); + pwin.setPen(QPen(white, 1)); + drawRect(pwin, _preRect); + + _last = evt->pos(); + + _preRect.setRect(_last.x() - w / 2, _last.y() - w / 2, w, w); + pwin.setRasterOp(CopyROP); + QRect r = QRect(0, 0, width(), height()); + for (uint i = 0; i < _current->draws.count() - _current->disp_offset(); ++i) { + FNPolygon* p = _current->draws.at(i); + QRect bounds = p->boundingRect(); + if (r.intersects(bounds)) { + bool f = false; + QRect& selected = _preRect; + for (uint j = 0; j < p->points().count(); ++j) { + QPoint& pts = p->points().at(j); + if (selected.contains(pts)) { + f = true; + if (-1 == _selection.width()) { + _selection = bounds; + } else { + if (bounds.x() < _selection.x()) { + _selection.setX(bounds.x()); + } + if (bounds.y() < _selection.y()) { + _selection.setY(bounds.y()); + } + if (bounds.right() > _selection.right()) { + _selection.setRight(bounds.right()); + } + if (bounds.bottom() > _selection.bottom()) { + _selection.setBottom(bounds.bottom()); + } + } + break; + } + } + if (f) { + if (0 == _selected.contains(p)) { + _selected.append(p); + } + p->drawShape(pwin, f); + } + } + } + pwin.setRasterOp(XorROP); + pwin.setPen(QPen(white, 1)); + drawRect(pwin, _preRect); + pwin.flush(); + pwin.end(); + } else { + if (0 >= _selection.width()) { + return; + } + //選択中(移動処理) + QPainter pwin; + pwin.begin(this); + pwin.setRasterOp(XorROP); + pwin.setPen(QPen(white, 1)); + drawRect(pwin, _preRect); + _last = SnapPoint(evt->pos(), SNAP_SIZE / 4); + _preRect.setRect(_last.x() - _tdx, _last.y() - _tdy, _selection.width(), _selection.height()); + drawRect(pwin, _preRect); + pwin.flush(); + pwin.end(); + } + } else { + QPainter pwin; + pwin.begin(this); + pwin.setPen(_pen); + + pwin.drawLine(_last, evt->pos()); + pwin.flush(); + + pwin.end(); + _last = evt->pos(); + _tracks.append(new QPoint(_last)); + } +} + +void FNCanvas::mouseReleaseEvent(QMouseEvent* evt) +{ + if (!_current->IsShow) { + return; + } + _isDragging = false; + if (_isWaiting) { + _isWaiting = false; + return; + } + if (MODE_ERASE == _drawMode) { + if (_isSelected) { + //_lastへ移動 + _last = SnapPoint(evt->pos(), SNAP_SIZE / 4); + int dx = _last.x() - _tdx - _selection.x(); + int dy = _last.y() - _tdy - _selection.y(); + for (uint i = 0; i < _selected.count(); ++i) { + FNPolygon* p = _selected.at(i); + p->translate(dx, dy); + } + _selection.moveBy(dx, dy); + redraw(); + } else { + if (false == _isEraseWaiting) { + _isEraseWaiting = true; + } + redraw(); + _timer->start(_scrollTiming, true); + } + } else if (MODE_CPICK == _drawMode) { + QRgb c = _buffer.convertToImage().pixel(evt->pos().x(), evt->pos().y()); + emit pickColor(c); + emit changeMode(_prevMode); + return; + } else { + if (1 < _tracks.count()) { + _last = evt->pos(); + 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)); + FNPointList tracks; + tracks.setAutoDelete(true); + for (uint i = 0; i < _tracks.count(); ++i) { + QPoint t = *_tracks.at(i); + tracks.append(new QPoint(t.x(), t.y())); + } + _tracks = AutoCurve(_tracks); + bool isEllipse = false; + if (sp == ep) { + if (0 < _tracks.count()) { + int vdconv = 0; //縦方向転換 + int vdir = 0; + int svdir = 0; + + int hdconv = 0; //横方向転換 + int hdir = 0; + int shdir = 0; + QPoint* st = _tracks.at(0); + QPoint* l = st; + for (uint i = 1; i < _tracks.count(); ++i) { + QPoint* p = _tracks.at(i); + int thdir = sign(p->x() - l->x()); + if (l->x() != p->x()) { + //水平方向転換 + if (0 != thdir) { + if (0 == hdir) { + shdir = thdir; + } else if (thdir != hdir) { + ++hdconv; + } + hdir = thdir; + } + } + int tvdir = sign(p->y() - l->y()); + if (l->y() != p->y()) { + //垂直方向転換 + if (0 != tvdir) { + if (0 == vdir) { + svdir = tvdir; + } else if (tvdir != vdir) { + ++vdconv; + } + vdir = tvdir; + } + } + l = p; + } + if (shdir == hdir) { + --hdconv; + } + if (svdir == vdir) { + --vdconv; + } + + if (1 >= hdconv && 1 >= vdconv) { + isEllipse = true; + int dircnt = 0; + //もう1判定 + tracks = AutoFormat(tracks); + if (2 < tracks.count()) { + int phdir = sign(tracks.at(1)->x() - tracks.at(0)->x()); + int pvdir = sign(tracks.at(1)->y() - tracks.at(0)->y()); + l = tracks.at(1); + for (uint i = 2; i < tracks.count(); ++i) { + QPoint* p = tracks.at(i); + int thdir = sign(p->x() - l->x()); + int tvdir = sign(p->y() - l->y()); + if ((0 == pvdir && 0 != tvdir && 0 != phdir && 0 == thdir) || + (0 != pvdir && 0 == tvdir && 0 == phdir && 0 != thdir)) + { + if (3 < dircnt) { + isEllipse = false; + break; + } + ++dircnt; + } + l = p; + phdir = thdir; + pvdir = tvdir; + } + } + } + } + } + if (isEllipse) { + QRect r = GetBounds(_tracks); + _tracks.clear(); + sp = SnapPoint(QPoint(r.x(), r.y())); + ep = SnapPoint(QPoint(r.x() + r.width(), r.y() + r.height())); + _tracks.append(new QPoint(sp.x(), sp.y())); + _tracks.append(new QPoint(ep.x(), ep.y())); + 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 (NULL != p) { + p->setFill(_fill); + if (1 < _tracks.count()) { + p->setPoints(_tracks); + redobuf_flush(); + _current->draws.append(p); + } + } + } else if (MODE_TEXT == _drawMode) { + if (NULL == _txtTmp) { + textEdit(_last.x(), _last.y()); + } else { + QRect r = _txtTmp->boundingRect(); + if (_selection == r || 0 < _txtwait) { + textEdit(r.x(), r.y(), _txtTmp); + } else { + if (-1 != _selection.width()) { + _txtTmp->translate(_last.x() - r.x(), _last.y() - r.y()); + } + } + } + _txtTmp = NULL; + } + _tracks.clear(); + _isHeadingEnables = true; + _timer->start(_scrollTiming, true); + } +} + +void FNCanvas::textEdit(int x, int y, FNText* obj) +{ + FNTextDialog dlg(fontname, _colorSelector, this); + dlg.show(); + /* + if (width() < _tboxRect.x()) { + _tboxRect.setX(0); + } + if (50 > _tboxRect.y()) { + _tboxRect.setY(50); + } + if (height() < _tboxRect.height()) { + _tboxRect.setHeight(height()); + } + if (width() < _tboxRect.width()) { + _tboxRect.setWidth(width()); + } + dlg.move(_tboxRect.x(), _tboxRect.y()); + dlg.resize(_tboxRect.width(), _tboxRect.height()); + */ + dlg.move(width() / 8, height() / 8); + dlg.resize(width() * 6 / 8, height() * 6 / 8); + QPen pen = _pen; + if (NULL != obj) { + for (uint i = 0; i < obj->lines.count(); ++i) { + dlg.lines->append(obj->lines[i]); + } + pen = obj->pen(); + } + dlg.setPen(pen); + + int mx = x; + int my = y; + if (dlg.exec()) { + pen = dlg.pen(); + if (0 < dlg.lines->text().length()) { + FNText* p = obj; + if (NULL == obj) { + p = new FNText(pen); + _current->draws.append((FNPolygon*)p); + } + p->pen() = pen; + p->lines.clear(); + FNPointList l; + l.append(new QPoint(x, y)); + QFont font(fontname); + font.setPointSize(FONTSIZE[pen.width()]); + QFontMetrics fm(font); + int h = fm.height(); + for (int i = 0; i < dlg.lines->numLines(); ++i) { + p->lines.append(dlg.lines->textLine(i)); + int w = fm.width(dlg.lines->textLine(i)) + x; + l.append(new QPoint(w, my)); + my += h; + l.append(new QPoint(w, my)); + l.append(new QPoint(x, my)); + if (mx < w) { + mx = w; + } + } + p->setPoints(l); + redobuf_flush(); + redraw(); + } else { + if (NULL != obj) { + _current->draws.remove(obj); + } + } + } + _tboxRect = QRect(dlg.x(), dlg.y(), dlg.width(), dlg.height()); +} +void FNCanvas::paintEvent(QPaintEvent*) +{ + 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() +{ + bool hasValue = false; + int dx = 0; + int dy = 0; + if (0 < _current->draws.count()) { + dx = ((FNPolygon*)_current->draws.at(0))->boundingRect().x(); + dy = ((FNPolygon*)_current->draws.at(0))->boundingRect().y(); + } + + for (uint j = 0; j < _layers.count(); ++j) { + FNPolygonList& draws = _layers.at(j)->draws; + for (uint i = 0; i < draws.count(); ++i) { + FNPolygon* p = draws.at(i); + hasValue = true; + if (dx > p->boundingRect().x()) { + dx = p->boundingRect().x(); + } + if (dy > p->boundingRect().y()) { + dy = p->boundingRect().y(); + } + } + } + if (!hasValue || !_isUseAllQuadrant) { + return _origin; + } + return QPoint(snap(dx), snap(dy)); +} + + +void FNCanvas::rebuild() +{ + if (!_isUseAllQuadrant) { + return; + } + + QPoint d = getTopLeft(); + d.setX(d.x() - SNAP_SIZE); + d.setY(d.y() - SNAP_SIZE); + for (uint j = 0; j < _layers.count(); ++j) { + FNPolygonList& draws = _layers.at(j)->draws; + 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::resetOrigin() +{ + int ox = 0; + int oy = 0; + _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 < _layers.count(); ++i) { + FNPolygonList& draws = _layers.at(i)->draws; + for (uint j = 0; j < draws.count(); ++j) { + FNPolygon* p = draws.at(j); + p->translate(dx, dy); + } + } + _origin = QPoint(ox, oy); +} + +void FNCanvas::setOrigin(int ox, int oy, bool isRedrawEnabled) +{ + 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; + } + } + if (dx == 0 && dy == 0) { + return; + } + 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 j = 0; j < _layers.count(); ++j) { + FNPolygonList& draws = _layers.at(j)->draws; + for (uint i = 0; i < draws.count(); ++i) { + FNPolygon* p = draws.at(i); + p->translate(dx, dy); + } + } + if (-1 != _selection.width()) { + _selection.moveBy(dx, dy); + } + + _origin = QPoint(ox, oy); + emit originChanged(ox, oy); + if (isRedrawEnabled) { + redraw(); + } +} + +void FNCanvas::redraw() +{ + if (_isDrawing) { + return; + } + if (_isDragging) { + return; + } + if (!this->isVisible()) { + return; + } + + _isDrawing = true; + for (uint l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + if (_isTinyPaging) { + if (_current == &layer) { + layer.IsShow = true; + } else { + layer.IsShow = false; + } + } + } + int h = height(); //(height() / 40) * 40; + _buffer.fill(white); + QRect r = QRect(0, 0, width(), height()); + QPainter pbuf; + pbuf.begin(&_buffer); + pbuf.setFont(QFont(fontname)); + pbuf.setClipRect(0, 0, width(), height()); + if (_viewMode) { + float wx = 0; + float wy = 0; + for (uint l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + if (layer.IsShow) { + FNPolygonList& draws = layer.draws; + for (uint i = 0; i < draws.count() - layer.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 l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + if (!layer.IsShow) { + continue; + } + FNPolygonList& draws = layer.draws; + for (uint i = 0; i < draws.count() - layer.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 if (p->type() == FN_TEXT) { + t = new FNText(*(FNText*)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; + } + if (p->type() == FN_TEXT) { + FNText* tp = (FNText*)t; + QPoint& sp = t->points().at(0); + + //default font size checking... + QFont f(fontname, FONTSIZE[p->pen().width()]); + QFontMetrics fm(f); + int h = fm.height(); + int wx = 0; + int wy = 0; + for (uint i = 0; i < tp->lines.count(); ++i) { + int tw = fm.width(tp->lines[i]); + if (tw > wx) { + wx = tw; + } + wy += h; + } + + //create default font image... + QRect r = tp->boundingRect(); + QPixmap tmp(wx + 1, wy + 1); + tmp.fill(Qt::white); + QPainter pt; + pt.begin(&tmp); + pt.setFont(f); + pt.setPen(p->pen()); + int y = h + 1; + for (uint i = 0; i < tp->lines.count(); ++i) { + pt.drawText(1, y, tp->lines[i]); + y += h; + } + pt.flush(); + pt.end(); + + //draw to font image + tmp = tmp.convertToImage().smoothScale(r.width(), r.height()); + tmp.setMask(tmp.createHeuristicMask()); + pbuf.drawPixmap(sp.x(), sp.y(), tmp); + pbuf.flush(); + } else { + t->pen().setWidth(pensize); + t->drawShape(pbuf); + } + delete t; + } + } + } else { + if (MODE_ERASE == _drawMode || MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode || MODE_TEXT == _drawMode) { + //グリッド描画 + //QPen pen2(QColor(0, 0, 0), 1); + //pbuf.setPen(QPen(QColor(50, 240, 240), 1)); + pbuf.setPen(QPen(GridColor)); + for (int x = 0; x < width() + SNAP_SIZE; x += SNAP_SIZE) { + pbuf.drawLine(x - SNAP_SIZE / 2, 0, x - SNAP_SIZE / 2, h); + for (int y = 0; y < h + 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 (MODE_ERASE != _drawMode) { + if (!(MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode || MODE_TEXT == _drawMode)) { + if (_showRuler) { + //罫線 + pbuf.setPen(QPen(RulerColor, 1, SolidLine)); + int step = SNAP_SIZE * 2; //SNAP_SIZEの2倍に。 + for (int i = 0; i < height(); i += step) { + pbuf.drawLine(0, i, width(), i); + } + } + } + + if (_isShowGuide) { + pbuf.setPen(QPen(GuideColor, 1, DashLine)); + if (AS_HORIZONTAL == _asMode || AS_BOTH == _asMode) { + if (0 != _origin.x() || _isUseAllQuadrant) { + pbuf.drawLine(width() / _margin, 0, width() / _margin, h); + } + pbuf.drawLine(width() * (_margin - 1) / _margin, 0, width() * (_margin - 1) / _margin, h); + } + + if (AS_VERTICAL == _asMode || AS_BOTH == _asMode) { + if (0 != _origin.y() || _isUseAllQuadrant) { + pbuf.drawLine(0, h / _margin, width(), h / _margin); + } + pbuf.drawLine(0, h * (_margin - 1) / _margin, width(), h * (_margin - 1) / _margin); + } + } + + for (uint l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + if (layer.IsShow) { + FNPolygonList& draws = layer.draws; + for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) { + FNPolygon* p = draws.at(i); + if (r.intersects(p->boundingRect())) { + p->drawShape(pbuf); + } + } + } + } + } else { + for (uint l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + if (layer.IsShow) { + FNPolygonList& draws = layer.draws; + for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) { + FNPolygon* p = draws.at(i); + if (!_selected.contains(p)) { + if (r.intersects(p->boundingRect())) { + p->drawShape(pbuf); + } + } + } + } + } + for (uint i = 0; i < _selected.count(); ++i) { + _selected.at(i)->drawShape(pbuf, true); + } + if (_isSelected) { + pbuf.setPen(QPen(SelectionFrameColor, 1, DashLine)); + pbuf.setBrush(NoBrush); + pbuf.drawRect(_selection); + } + } + } + pbuf.end(); + _isDrawing = false; + repaint(); +} + +void FNCanvas::changeColor(QRgb c) +{ + _pen.setColor(QColor(c)); + if (_isSelected && _drawMode == MODE_ERASE) { + for (uint i = 0; i < _selected.count(); ++i) { + _selected.at(i)->pen().setColor(QColor(c)); + } + } +} + +void FNCanvas::selectionMoveTo(int dx, int dy) +{ + if (_isSelected) { + for (uint i = 0; i < _selected.count(); ++i) { + _selected.at(i)->translate(dx, dy); + } + _selection.moveBy(dx, dy); + } + redraw(); +} + +void FNCanvas::copy() +{ + if (MODE_ERASE != _drawMode || _viewMode) { + return; + } + _clipboard.clear(); + int size = _selected.count(); + int a1[size]; + int a2[size]; + for (int i = 0; i < size; ++i) { + a1[i] = _current->draws.findRef(_selected.at(i)); + a2[i] = i; + } + + //ソート + FNPolygonList tmp; + for (int i = 0; i < size; ++i) { + int min = i; + for (int j = i + 1; j < size; ++j) { + if (a1[min] > a1[j]) { + min = j; + } + } + tmp.append(_selected.at(a2[min])); + a1[min] = a1[i]; + a2[min] = a2[i]; + } + + //並び順を保証してコピー + tmp.clone(_clipboard); + tmp.clear(); +} + +void FNCanvas::paste() +{ + if (_viewMode) { + return; + } + if (MODE_ERASE == _drawMode) { + _selected.clear(); + _clipboard.clone(_selected); + _selection = QRect(0, 0, -1, -1); + for (uint i = 0; i < _selected.count(); ++i) { + FNPolygon* o = _selected.at(i); + o->translate(10, 10); + QRect bounds = o->boundingRect(); + if (-1 == _selection.width()) { + _selection = bounds; + } else { + if (bounds.x() < _selection.x()) { + _selection.setX(bounds.x()); + } + if (bounds.y() < _selection.y()) { + _selection.setY(bounds.y()); + } + if (bounds.right() > _selection.right()) { + _selection.setRight(bounds.right()); + } + if (bounds.bottom() > _selection.bottom()) { + _selection.setBottom(bounds.bottom()); + } + } + } + _selected.copy(_current->draws); + _isSelected = true; + } else { + int my = 10; + int mx = 10; + int x = 10; + QStringList lines = QStringList::split("\n", QApplication::clipboard()->text()); + if (0 < lines.count()) { + FNText* p = new FNText(_pen); + _current->draws.append((FNPolygon*)p); + p->lines.clear(); + FNPointList l; + l.append(new QPoint(0, 0)); + QFont font(fontname); + font.setPointSize(FONTSIZE[_pen.width()]); + QFontMetrics fm(font); + int h = fm.height(); + for (uint i = 0; i < lines.count(); ++i) { + p->lines.append(lines[i]); + int w = fm.width(lines[i]) + x; + l.append(new QPoint(w, my)); + my += h; + l.append(new QPoint(w, my)); + l.append(new QPoint(x, my)); + if (mx < w) { + mx = w; + } + } + p->setPoints(l); + } + } + redraw(); +} + +void FNCanvas::redo() +{ + if (MODE_ERASE != _drawMode) { + _current->redo(); + } + redraw(); +} + +void FNCanvas::clearList(FNPolygonList& list) +{ + list.setAutoDelete(true); + list.clear(); + list.setAutoDelete(false); +} + +void FNCanvas::resetSelection() +{ + _selection = QRect(0, 0, -1, -1); + _selected.clear(); + _isSelected = false; +} + +void FNCanvas::clear() +{ + resetSelection(); + _layers.clear(); + _current = new FNLayer(); + _layers.append(_current); + _current->Name = "Layer0"; + _selIdx = 0; + _isTinyPaging = false; + //_undobuf.clear(); + setOrigin(0, 0); + redraw(); +} + +void FNCanvas::undo() +{ + _timer->stop(); + if (MODE_ERASE != _drawMode) { + _current->undo(); + } else { + _selected.clear(); + _isSelected = false; + _layers.clear(); + for (uint i = 0; i < _undobuf.count(); ++i) { + _layers.append(new FNLayer(*_undobuf.at(i))); + } + _current = _layers.at(0); + _selIdx = 0; + } + redraw(); +} + +void FNCanvas::viewChanged(bool flg) +{ + _tracks.clear(); + _viewMode = flg; + if (_viewMode) { + if (_isUseAllQuadrant) { + rebuild(); + } + setOrigin(0, 0, false); + } + redraw(); +} + +void FNCanvas::redobuf_flush() +{ + _current->redobuf_flush(); +} + +void FNCanvas::modeChanged(int mode) +{ + _tracks.clear(); + resetSelection(); + _drawMode = mode; + for (uint i = 0; i < _layers.count(); ++i) { + FNLayer* p = _layers.at(i); + p->modeChanged(); + } + _undobuf.clear(); + if (MODE_ERASE == mode) { + _isEraseWaiting = false; + for (uint i = 0; i < _layers.count(); ++i) { + _undobuf.append(new FNLayer(*_layers.at(i))); + } + } + if (MODE_CPICK != mode) { + _prevMode = mode; + } + 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; + } + int h = height(); //(height() / 40) * 40; + int step = snap(h) / _margin; + if (_isHeadingEnables) { + //lastから、左方向に向けて探索する。 + QRect r = getMatrix(_current->draws.last()->boundingRect()); + bool isSearching = true; + r.moveBy(-100, 0); + while (isSearching) { + isSearching = false; + for (uint i = 0; i < _current->draws.count(); ++i) { + FNPolygon* p = _current->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() > h * 4 / 5) { + setOrigin(_origin.x() + r.x(), _origin.y() + step); + } else { + setOrigin(_origin.x() + r.x(), _origin.y()); + } + _isHeadingEnables = false; + } else { + //lastの周囲に何も無い場合は、縦にスクロールする。 + setOrigin(_origin.x(), _origin.y() + step); + } +} + +void FNCanvas::erase() +{ + if (MODE_ERASE != _drawMode) { + return; + } + FNPolygonList temp; + int w = _eraser_s; + if (PENWIDTH_MAX / 2 < _pen.width()) { + w = _eraser_l; + } + for (uint i = 0; i < _selected.count(); ++i) { + _current->draws.remove(_selected.at(i)); + //_marks.append(_selected.at(i)); + } + resetSelection(); + _tracks.clear(); + _isEraseWaiting = false; + redraw(); +} + +void FNCanvas::setPensize(int sz) +{ + _pen.setWidth(sz); + if (_isSelected) { + for (uint i = 0; i < _selected.count(); ++i) { + if (FN_TEXT != _selected.at(i)->type()) { + _selected.at(i)->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; + if (_isColorRevision) { + QImage img = buf.convertToImage(); + int wd = buf.width(); + int ht = buf.height(); + for (int i = 0; i < ht; ++i) { + for (int j = 0; j < wd; ++j) { + QRgb c = img.pixel(j, i); + int r = qRed(c) >> 3; + int g = qGreen(c) >> 2; + int b = qBlue(c) >> 3; + r = (r << 3) | (r >> 2); + b = (b << 3) | (b >> 2); + g = (g << 2) | (g >> 4); + //float f1 = 248f / 255f; + //float f2 = 252f / 255f; + //img.setPixel(qRed(c) * f1, qGreen(c) * f2, qBlue(c) * f1); + img.setPixel(j, i, qRgb(r, g, b)); + } + } + ret = img.save(info.absFilePath(), "PNG"); + } else { + 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, int wy) +{ + QString s =""; + char buf[1024]; + float r; + float g; + float b; + if (_isColorRevision) { + r = (float)elm->pen().color().red() / 248.0f; + g = (float)elm->pen().color().green() / 252.0f; + b = (float)elm->pen().color().blue() / 248.0f; + } else { + r = (float)elm->pen().color().red() / 255.0f; + g = (float)elm->pen().color().green() / 255.0f; + b = (float)elm->pen().color().blue() / 255.0f; + } + if (elm->type() == FN_TEXT) { + FNText* t = (FNText*)elm; + sprintf(buf, "BT\r\n/F1 %d Tf\r\n", FONTSIZE[elm->pen().width()]); + s += buf; + sprintf(buf, "0 Tr\r\n%f %f %f rg\r\n", r, g, b); + s += buf; + QRect r = t->boundingRect(); + r.moveBy(_origin.x(), _origin.y()); + QFont font(fontname); + font.setPointSize(FONTSIZE[elm->pen().width()]); + QFontMetrics fm(font); + int h = fm.height(); + int y = r.y() + h; + for (uint i = 0; i < t->lines.count(); ++i) { + sprintf(buf, "1 0 0 1 %d %d Tm\r\n", r.x() + 3, wy - y); + s += buf; + y = y + h; + s += "<"; + for (uint j = 0; j < t->lines[i].length(); ++j) { + sprintf(buf, "%04X", (t->lines[i].at(j).unicode() & 0x0ffff)); + s += buf; + } + s += "> Tj\r\n"; + } + s += "ET\r\n"; + } else { + s += "q\r\n"; + if (elm->fill()) { + sprintf(buf, "%f %f %f rg\r\n", r, g, b); + } else { + sprintf(buf, "%f %f %f RG\r\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\r\n", points[0].x(), wy - points[0].y()); + s += buf; + for (uint j = 1; j < points.count(); j += 3) { + sprintf(buf, "%d %d %d %d %d %d c\r\n", + points[j].x(), wy - points[j].y(), + points[j + 1].x(), wy - points[j + 1].y(), + points[j + 2].x(), wy - 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\r\n%d %d %d %d %d %d c\r\n", cx, wy - cy, x1, wy - y1, x2, wy - y2, x3, wy - 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\r\n", x1, wy - y1, x2, wy - y2, x3, wy - 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\r\n", x1, wy - y1, x2, wy - y2, x3, wy - 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\r\n", x1, wy - y1, x2, wy - y2, x3, wy - y3); + s += buf; + } else { + sprintf(buf, "%d %d m\r\n", points[0].x(), wy - points[0].y()); + s += buf; + for (uint j = 1; j < points.count(); ++j) { + sprintf(buf, "%d %d l\r\n", points[j].x(), wy - points[j].y()); + s += buf; + } + } + sprintf(buf, "%d w\r\n", elm->pen().width()); + s += buf; + if (elm->fill()) { + s += "f*\r\n"; + } else { + s += "S\r\n"; + } + s += "Q\r\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]; + int bias = 0; + if (_isUseAllQuadrant) { + bias = SNAP_SIZE; + } + for (uint l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + FNPolygonList& draws = layer.draws; + for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) { + FNPolygon* p = draws.at(i); + QRect r = p->boundingRect(); + r.moveBy(_origin.x(), _origin.y()); + if (wx < r.right() + bias) { + wx = r.right() + bias; + } + if (wy < r.bottom() + bias) { + wy = r.bottom() + bias; + } + } + } + + int len = 0; + + /* + sprintf(buf, "1 0 0 -1 0 %d cm\r\n", wy); + QString cm = buf; + len += cm.length(); + */ + QString cm = ""; + + for (uint l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + if (layer.IsShow) { + FNPolygonList& draws = layer.draws; + for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) { + QString s = mkPDFscript(draws.at(i), wy); + len += s.length(); + } + } + } + + //int ref = 0; + QString header = ""; + QStringList xref; + xref.append("0000000000 65535 f\r\n"); + + header += "%PDF-1.3\r\n"; + sprintf(buf, "%010d 00000 n\r\n", header.length()); + xref.append(buf); + + header += "1 0 obj<>\r\n"; + header += "endobj\r\n"; + sprintf(buf, "%010d 00000 n\r\n", header.length()); + xref.append(buf); + + + header += "2 0 obj<>\r\n"; + header += "endobj\r\n"; + sprintf(buf, "%010d 00000 n\r\n", header.length()); + xref.append(buf); + + header += "3 0 obj<>\r\n"; + header += "endobj\r\n"; + sprintf(buf, "%010d 00000 n\r\n", header.length()); + xref.append(buf); + + header += "4 0 obj<>\r\n", len); + header += buf; + header += "stream\r\n"; + + QString footer = ""; + footer += "xref\r\n"; + sprintf(buf, "0 %d\r\n", xref.count()); + footer += buf; + for (uint i = 0; i < xref.count(); ++i) { + footer += xref[i]; + } + footer += "trailer\r\n"; + sprintf(buf, "<>\r\n", xref.count()); + footer += buf; + footer += "startxref\r\n"; + + len = cm.length(); + len += header.length(); + fputs(header, fp); + fputs(cm, fp); + + for (uint l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + if (layer.IsShow) { + FNPolygonList& draws = layer.draws; + for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) { + QString s = mkPDFscript(draws.at(i), wy); + len += s.length(); + fputs(s, fp); + } + } + } + QString streamfooter = "endstream\r\nendobj\r\n"; + len += streamfooter.length(); + fputs(streamfooter, fp); + + fputs(footer, fp); + sprintf(buf, "%d\r\n", len); + fputs(buf, fp); + fputs("%%EOF\r\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("\n", fp); + char buf[1024]; + sprintf(buf, "\n", _isTinyPaging, _selIdx); + fputs(buf, fp); + for (uint l = 0; l < _layers.count(); ++l) { + FNLayer& layer = *_layers.at(l); + FNPolygonList& draws = layer.draws; + QString s = "\n"; + fputs(s.utf8(), fp); + for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) { + FNPolygon p(*draws.at(i)); + p.translate(_origin.x(), _origin.y()); + if (p.type() == FN_BEZIER) { + sprintf(buf, "\t\n", (uint)p.pen().color().rgb(), p.pen().width(), p.fill()); + } else if (p.type() == FN_ELLIPSE) { + sprintf(buf, "\t\n", (uint)p.pen().color().rgb(), p.pen().width(), p.fill()); + } else if (p.type() == FN_TEXT) { + sprintf(buf, "\t\n", (uint)p.pen().color().rgb(), p.pen().width()); + } else { + sprintf(buf, "\t\n", (uint)p.pen().color().rgb(), p.pen().width(), p.fill()); + } + fputs(buf, fp); + QPointArray& points = p.points(); + for (uint j = 0; j < points.count(); ++j) { + QPoint point = points.point(j); + sprintf(buf, "\t\t

\n", point.x(), point.y()); + fputs(buf, fp); + } + if (p.type() == FN_BEZIER) { + fputs("\t\n", fp); + } else if (p.type() == FN_ELLIPSE) { + fputs("\t\n", fp); + } else if (p.type() == FN_TEXT) { + FNText* tp = (FNText*)draws.at(i); + for (uint j = 0; j < tp->lines.count(); ++j) { + s = "\t\tlines[j]; + s += "\"/>\n"; + fputs(s.utf8(), fp); + } + fputs("\t\n", fp); + } else { + fputs("\t\n", fp); + } + } + fputs("\n", fp); + } + fputs("\n", fp); + fclose(fp); + if (_isUseAllQuadrant) { + setOrigin(-o.x()+SNAP_SIZE, -o.y()+SNAP_SIZE); + } + 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(); + open(_layers, fp); + if ((uint)_selIdx >= _layers.count()) { + _selIdx = 0; + } + _current = _layers.at(_selIdx); + fclose(fp); + + redraw(); + FNMessageBox::information(0,"FreeNoteQt", "load complete."); + + return true; +} + +bool FNCanvas::import(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; + } + clearList(_clipboard); + open(_clipboard, fp); + fclose(fp); + if (0 < _clipboard.count()) { + int x = _clipboard.at(0)->boundingRect().left(); + int y = _clipboard.at(0)->boundingRect().top(); + for (uint i = 1; i < _clipboard.count(); ++i) { + if (y > _clipboard.at(i)->boundingRect().top()) { + y = _clipboard.at(i)->boundingRect().top(); + } + if (x > _clipboard.at(i)->boundingRect().left()) { + x = _clipboard.at(i)->boundingRect().left(); + } + } + for (uint i = 0; i < _clipboard.count(); ++i) { + _clipboard.at(i)->translate(-x, -y); + } + } + FNMessageBox::information(0,"FreeNoteQt", "import complete."); + + return true; +} +void FNCanvas::open(FNPolygonList& list, FILE* fp) +{ + clearList(list); + FNLayerList layers; + open(layers, fp); + for (uint i = 0; i < layers.count(); ++i) { + FNLayer& layer = *layers.at(i); + if (layer.IsShow) { + layer.draws.clone(list); + /* + FNPolygonList& elmlst = layer.draws; + for (uint j = 0; j < elmlst.count(); ++j) { + list.append(elmlst.at(j)); + } + elmlst.clear(); + */ + } + } + layers.clear(); +} + +void FNCanvas::open(FNLayerList& layers, FILE* fp) +{ + 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 = ""; + QStringList lines; + layers.setAutoDelete(true); + layers.clear(); + layers.setAutoDelete(false); + FNLayer* layer = new FNLayer(); + layer->IsShow = true; + layer->Name = "Layer0"; + //_current = layer; + layers.append(layer); + FNPolygonList* list = &layer->draws; + bool isFirstLayer = true; + bool fill = false; + while (!feof(fp)) { + fgets(rdbuf, sizeof(rdbuf), fp); + line = rdbuf; + if (-1 != line.find("draws; + layers.append(layer); + } + isFirstLayer = false; + + if (-1 != line.find("v=0")) { + layer->IsShow = false; + } else if (-1 != line.find("v=1")) { + layer->IsShow = true; + } + int st = line.find("name=") + 6; + int ed = line.find("\"", st); + strcpy(buf, line.mid(st, ed - st)); + QTextCodec *codec = QTextCodec::codecForName("utf8"); + layer->Name = codec->toUnicode(buf); + } else if (-1 != line.find("toUnicode(buf)); + } else if (-1 != line.find("append(polygon = createBezier(pen)); //バグ対策 + } else if (type == "Ellipse") { + list->append(polygon = createEllipse(pen)); //バグ対策 + } else if (type == "Text") { + list->append(polygon = createText(pen, lines)); + } else { + list->append(polygon = createPolygon(pen)); //バグ対策 + } + polygon->setFill(fill); + polygon->setPoints(points); + points.clear(); + } + } +} + +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); +} + +FNPolygon* FNCanvas::createText(QPen& pen, QStringList& lines) +{ + FNText* p = new FNText(pen); + p->lines = lines; + return p; +} + +QPoint* FNCanvas::createPts(int x, int y) +{ + return new QPoint(x, y); +} + +void FNCanvas::setGuide(bool f) +{ + _isShowGuide = f; + redraw(); +} + +void FNCanvas::fillChanged(bool f) { + _fill = f; + if (_isSelected) { + for (uint i = 0; i < _selected.count(); ++i) { + _selected.at(i)->setFill(f); + } + } +} diff --git a/packages/freenote/files/FreeNote/FreeNote/FNFindDialog.cpp b/packages/freenote/files/FreeNote/FreeNote/FNFindDialog.cpp new file mode 100644 index 0000000000..9d0998ad04 --- /dev/null +++ b/packages/freenote/files/FreeNote/FreeNote/FNFindDialog.cpp @@ -0,0 +1,143 @@ +/* FreeNote for Sharp SLA300, B500, C7x0, C860 Linux PDA + Copyright (C) 2003-2005 Joe Kanemori. + + 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 +*/ +/* +2005/02/27 FreeNote 1.11.10pre +・PDFの出力形式を一部変更 +・インポート時のバグfix + +2005/01/04 FreeNote 1.11.6pre +・カーブモードで8の字がかけるように整形エンジンを改善 + +2004/10/17 FreeNote 1.10.0リリース +2004/02/14 ver 1.7.2pre +・検索機能の追加 +*/ +#include "fnfinddialog.h" +#include "fmtengine.h" +#include +#include +#include +#include + +FNFindDialog::FNFindDialog( QWidget* parent, const char* name) + :FNFindDialogBase(parent, name, true, 0), _idx(0) +{ +} + +void FNFindDialog::setElements(FNLayerList& v) +{ + _texts.clear(); + for (uint i = 0; i < v.count(); ++i) { + FNLayer& layer = *v.at(i); + if (layer.IsShow) { + FNPolygonList& draws = layer.draws; + for (uint j = 0; j < draws.count(); ++j) { + FNPolygon* p = draws.at(j); + if (FN_TEXT == p->type()) { + _texts.append(p); + } + } + } + } + _idx = -1; +} + +void FNFindDialog::findPrev() +{ + QString sch = txtSearch->text(); + QRegExp rex(sch); + if (0 == sch.length()) { + return; + } + if (0 > _idx) { + _idx = _texts.count() - 1; + } + if ((uint)_idx >= _texts.count()) { + _idx = _texts.count() - 1; + } + for (; _idx >= 0; --_idx) { + FNText* p = (FNText*)_texts.at(_idx); + for (uint i = 0; i < p->lines.count(); ++i) { + if (ckbIsRegExp->isChecked()) { + for (uint i = 0; i < p->lines.count(); ++i) { + if (-1 != p->lines[i].find(rex)) { + emit resetOrigin(); + QPoint sp = p->points().point(0); + emit originChanged(sp.x() - SNAP_SIZE, sp.y() - SNAP_SIZE); + --_idx; + return; + } + } + } else { + for (uint i = 0; i < p->lines.count(); ++i) { + if (-1 != p->lines[i].find(sch)) { + emit resetOrigin(); + QPoint sp = p->points().point(0)