スケッチ風ドロー のアイコン

プログラムソース

ダウンロード: ソースコード

このドキュメントは日本語で書かれています。
This document is written in Japanese.
Dieses Dokument ist in Japanisch geschrieben.
Ce document est écrit en japonais.
Dit document is in het Japans geschreven.
Questo documento è scritto in giapponese.
Este documento está escrito en japonés.
Detta dokument är skrivet på japanska.

以下の部分は、プログラムソースを理解する為の文章ですのでアプリケーションを利用する際に読む必要はありません。
Sketchと主要な部分は同じにしてある。SKTDrawDocument,SKTGraphicView,SKTGraphicの働きは全く変えていない。
各クラスの働きについては、Sketchソースの中にあるReadme.rtfが参考になる。
Sketchのソース内にはReadme.rtf, ToDo.txtなどの参考文献がある。
SKTAppDelegateがNSApplicationのデレゲートになっている。
ドキュメントはSKTDocument
ドキュメントごとのviewはSKTGraphicView
view内の各オブジェクトはSKTGraphic
-[SKTDocument readFromData:]から+[SKTGraphic graphicsWithProperties:]から-[SKTGraphicのサブクラス initWithProperties:]でSKTDocumentのNSMutableArrayのgraphics変数に各描画オブジェクトが格納される。

OS10.5での変更点
_gFlags構造体が無くなった。_gFlags.drawsFill--_isDrawingFill, _lineWidth--_strokeWidth, _gFlags.drawsStroke--_isDrawingStroke, へ変わってしまった。
_gFlags構造体が無くなったことによる変更。_gFlags.windingRule--_windingRule, _gFlags.linejoin--_lineJoin, _gFlags.linecap--_lineCap, _gFlags.formEntry--_formEntry, _gFlags.localizeFormEntry--_localizeFormEntry, _gFlags.locked--_locked, _gFlags.shading--_shading,_shadowBlurRadius--shadowBlurRadiusValue,
loadPropertyListRepresentation が - (id)initWithProperties:(NSDictionary *)propertiesに変わった。
- (NSMutableDictionary *)propertyListRepresentation が - (NSMutableDictionary *)properties に変わった。
以前の_gFlags.arrowAtStartsと_gFlags.arrowAtEndとをまとめて、_arrowStateとした。
KVC,KVO でやるには、変数名の頭文字が小文字でないとかなり使いにくい。それに合わせてファイルのkeyも小文字に変更したのが複数ある。
bind: でmaindow.windowController.graphicController.・・・をModel Key Pathとしたとき、windowControllerにNSWindowがあってgraphicController以降の仕様が満たされていないときハングアップもしくは暴走する。これを防ぐにはwindowControllerのwindowをNSPanelにしなければならない。PreferencesControllerは此の方法を使っている。
SKTGraphic のundo の使い方は、属性値が変更されたときのアップデートと兼ねた方法でやらせる。+ (void)initializeの中の[self setKeys:triggerChangeNotificationForDependentKey:]に定義されているSKTGraphicDrawingBoundsKey, SKTGraphicDrawingContentsKey の値を変更すれば良い。setKeys:の引数は- (NSSet *)keysForValuesAffectingDrawingBounds と - (NSSet *)keysForValuesAffectingDrawingContents とで定義する。この2つのどちらかの配列に、アップデートさせる変数のkeyを追加定義する。undo させる変数のkey 追加は -(NSSet *)keysForValuesToObservForUndo で追加定義する。undoのlocalized文字列は - (NSString *)presentablePropertyNameForKey:で追加定義する。SKTGraphicからundoされる文字列には Change of (の変更)という文字がprefix される。
SKTGraphicView からのundoにはChange of がprefixされない。
- (NSBezierPath *)bezierPath が -(NSBezierPath *)bezierPathForDrawing に変わった。
- (void)drawInView:(SKTGraphicView *)view isSelected:(BOOL)flag が- (void)drawContentsInView:(NSView *)view isBeingCreateOrEdited:(BOOL)isBeingCreatedOrEditingに変わった。bezierPathForDrawingで作ったNSBezierPathをdrawInView::でfillとstrokeをしているだけなので複雑な描画をするときは両方ともオーバーライドしなければならない。
shading(グラデーション)のundoについては、かなり不完全である。ASShadingModelの定数を変更させているので、undoをうまく動作させることができなかった。
64ビットの実行環境では、copy:(id)senderによるペーストボードへの書き込みがOS10.5 64ビットのバグにより不完全である。SKTextのNSPostscriptPboardTypeとNSPDFPboardTypeへの書き込みができない。SKTsvgについてはNSPostscriptPboardTypeへの書き込みができない。SKTsvgはtextエレメントが含まれているとハングアップするバグがあるので書き込みしないようにしている。総てSKTRenderingView.mの中で処理しているので、バグが解消されたら修正すると使いやすくなる。
64ビットの実行環境で、SKTTextに漢字が含まれている場合に、プリントするとハングアップする。OS10.5のバグである。

以下はSketchの旧バージョンに関する解説です。旧バージョンとはMac OS X 10.4までに附属していたSketchです。
SKTDrawAppDelegateがNSApplicationのデレゲートになっている。
ドキュメントはSKTDrawDocument
ドキュメントごとのviewはSKTGraphicView
view内の各オブジェクトはSKTGraphic
SKTGraphicの各オブジェクトに変更があったときは、SKTGraphicのdidChange:により[[NSNotificationCenter defaultCenter] postNotificationName:SKTGraphicDidChangeNotification object:self]がpostされる。

起動
OPENSTEPのDrawのときは、NSApplicationのサブクラスDrawApp.mに applicationDidFinishLaunching: ,application: openFile:メソッドが実装されていた。Mac OS XになってNSDocumentクラスが実装され、NSApplicationのサブクラスSKTDrawAppDelegate.mにはそういった機能は無い。
スケッチ風ドローファイルのオープン
ファイルはプロパティリストがテキスト形式で格納された普通ファイル。
NSDocumentのloadDataRepresentationをオーバーライドしたSKTDrawDocument.mの- (BOOL)readFromData:ofType:error: → - (NSDictionary *)drawDocumentDictionaryFromData: → SKTGraphic.mの+(id)graphicWithPropertyLisrRepresentation: → - (void)loadPropertyListRepresentation:
スケッチ風ドローファイルのオープン
ファイルは普通ファイルである。OPENSTEPのDrawのときは、ディレクトリファイルも使われていた。
フォームフィールド或はファイルドラッグして作ったオブジェクトがあっても、普通ファイル形式になる。
NSDocumentのサブクラスSKTDrawDocument.mで管理されている。
sktdの拡張子がついたファイルで、プロパティリストがテキスト形式で格納される。
-(BOOL)loadFileWrapperRepresentation:(NSFileWrapper *)wrapper ofType:(NSString *)docTypeをオーバーライドしてある。
スケッチ風ドローウィンドウ
ドキュメントウィンドウはNSWindowControllerのサブクラスSKTDrawWindowController.m、NSDocumentのサブクラスSKTDrawDocument.mウィンドウ内のビューはNSViewのサブクラス SKTGraphicView.mが制御している。
ツールパネル
SKTToolPaletteController.mがマウスクリックを読んでSKTGraphicの対応するクラスを選択する。
選択
SKTGrpahicViewの- (void)mouseDown:(NSEvent *)eventがオブジェクトのリストに登録されたGraphicクラス又はGrpahicのサブクラスの-(BOOL)hit:(NSPoint)pを呼出し、それがYESを返すと、そのオブジェクトが選択された事になる。
リサイズはまず- (NSRect)drwingBoundsにより初期の矩形領域を取り出し、visibleRectにより矩形領域を可視化する。そしてマウスアップイベントが発生するまで SKTGraphicの- (int)resizeByMovingKnob:(int)knob toPoint:(NSPoint)pointを呼び出して。コーナーを移動させる。resizeByMovingKnobによる移動を行うごとにビューのリフレッシュを行う。
ノブの描画は位置を- (void)drawHandlesInView:(SKTGraphicView *)viewで計算しておいて- (void)drawHandleAtPoint:(NSPoint)point inView:(SKTGraphicView *)viewで描画する。
SKTPolygonとSKTCircleはhitTest:isSelected:でNSBezierPathのcontainsPointを利用して判断をする。[self bezierPath]とすると大量のエラーメッセージが出されるので、_cachedBezierPathを使用する。SKTBezierCurveもNSBezierPathのcontainsPointを利用するが、_cachedBezierPathを使用しなくてもエラーメッセージは出されない。
オブジェクト
NSObjectのサブクラスSKTGraphic.mが各オブジェクトの親クラス。
テキスト
SKTGraphicのサブクラスSKTTextArea.mのdrawTextインスタンス。
楕円形
SKTGraphicのサブクラスSKTCircle.m
曲線
SKTLineのサブクラスSKTCurve.m。
直線
SKTGraphicのサブクラスSKTLine.m。
多角形
SKTScribbleのサブクラスSKTPolygon.m。
長方形
SKTGraphicのサブクラスSKTRectangle.m。
フリーハンド
SKTGraphicのサブクラスSKTScribble.m
ベジェ曲線
SKTGraphicのサブクラスSKTBezierCurve.m
イメージ
SKTGraphicのサブクラスSKTImage.m。SKTImageのサブクラスにSKTpdf,SKTsvgがある。
グループ化
SKTGraphicのサブクラスSKTGroup.m
グリッドパネル
SKTGridPanelController.mがGUIの管理をしている。
アンドゥ
SKTGraphicViewのundoManagerはNSResponderのundoManagerメソッドから呼ばれるNSUndoManagerである。
SKTDrawDocumentのundoManagerはNSDocumentのundoManagerメソッドから呼ばれるNSUndoManagerである。
SKTGrahicのundoManagerはSKTDrawDocumentのundoManagerを呼び出しているだけである。
SKTGraphicViewから省いたundoはselectGraphic,deselectGraphic,clearSelectionである。
インスペクタパネル
インスペクタパネルを制御するのは、NSWindowControllerのサブクラスSKTInspectorControllerクラスである。
それぞれのインターフェースに対応する(IBAction)~Action:(id)senderというアクションメソドが実行される。
SKTGraphicViewクラスでは、アンドゥ用のデータを設定する。
破線パターンのテンプレートを示すPopUpボタンはSKTInspectorControllerの- (NSString *)dashTemplate:(int)itemから作られる。
Appleスクリプト
SKTDrawDocument.mに拡張したSKTGraphicのサブクラスに関するメソッドを実装すれば未対応部分がなくなる。
書き出し
SKTDrawDocument.mのwriteToFile:ofType:からdataRepresentation:が呼ばれ、保存先のタイプ別のメソッドが呼ばれる。
sktdはdrawDocumentDataForGraphics:からdrawDocumentDictionaryForGraphics:が呼ばれ、それぞれのgraphicのpropertyListRepresentationからNSDictionaryを得る。NSDictionaryのdescriptionをNSASCIIStringEncodingしたNSDataを得る。
TIFF,PDF,EPSはそれぞれの...RepresentationForGraphics:からNSDataを得る。
オブジェクトを寄せ集めた最大サイズの範囲で、データを書き出す。
SVGの書き出しは、SKTDrawDocument.mの- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outErrorから- (NSData *)SVGRepresentationForGraphics:(NSArray *)graphicsを呼び出して実行する。ここから、各SKTGraphicに実装された- (NSArray *)svgXMLElements:(NSRect)aRectを呼び出してSVGの要素を加えていく。実装していないときはSKTGraphic.mがnilを返す。
SKTImageのSVG書き出しは、NSBitmapImageRepを使うのでshadowは無視される。
矢印
各grpahicのbezierPathからは描かれない。SKTGraphic.mのdrawInView:isSelected:から各grpahicのbezierPathが呼ばれた後、各grpahicのarrowAtStartがYESのときに、arrowBezierPath:が呼ばれる。
arrowBezierPath:はSKTFoundationExtras.mのpdfArrow()を呼び出す。このpdfArrow()が実際の矢印の大きさと形を決める。
SKTRenderingView
SKTDrawDocumentから使われる。drawInview:isSelected:の第1引き数はnilとする。オリジナルでもnilとなっていた。SKTGraphic.mのサブクラスでdrawInView:view isSelected:を実装するときに、if ((nil != view) && (YES == [currentContext isDrawingToScreen]))という判断をするときに使える。NSImageをlockFocusするときなど有効である。