☆JWWファイルの超簡易表示 その4
ここ数日は、ブロックデータに挑戦していましたが、ブロックデータクラスや回転、
倍率処理・・・どれもややこし過ぎです。ブロックデータクラスの内容がいまいち理解
できていないので、基本的なところで間違っている可能性もありますが、
とりあえず回転、倍率処理を見送り、なんとか表示できるようになりました(^^;
そこで前回のソリッド描画と斜め楕円の描画も追加してコードをまとめてみました。
※斜め楕円の描画は、旧FDelphi 16番会議室「玉石混淆みんなで作るSample蔵」 斜め楕円の描画(裏目小僧さん、凛さん)を使わせて頂きました。
Peter's Room
jww data read & save unit Ver1.31β
http://www5b.biglobe.ne.jp/~peter/
AFsoft WebSite
CAD作ろ!
http://afsoft.jp/
※斜め楕円の描画は、旧FDelphi 16番会議室「玉石混淆みんなで作るSample蔵」 斜め楕円の描画(裏目小僧さん、凛さん)を使わせて頂きました。
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ComCtrls, Clipbrd, jwwunit, jwwDraw; type TForm1 = class(TForm) TreeView1: TTreeView; Panel1: TPanel; PaintBox1: TPaintBox; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure PaintBox1Paint(Sender: TObject); procedure FormResize(Sender: TObject); procedure TreeView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} uses Commctrl, ShlObj; // 初期設定 procedure TForm1.FormCreate(Sender: TObject); var FileName: String; WindowStyles: Integer; begin // TreeViewにCheckBoxを表示させます。 WindowStyles := GetWindowLong(TreeView1.Handle, GWL_STYLE); SetWindowLong(TreeView1.Handle, GWL_STYLE, WindowStyles or TVS_CHECKBOXES); JWWBlockList := TJWWBlockList.Create; FileName := 'c:\jww\Aマンション平面例.jww'; JwwDataLoadFromFile(FileName); SetLayerName(TreeView1); JWWDataDraw(PaintBox1); end; procedure TForm1.FormDestroy(Sender: TObject); begin JWWBlockList.Free; end; procedure TForm1.FormResize(Sender: TObject); begin JWWDataDraw(PaintBox1); end; procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin if ((MousePos.X > 0) and (MousePos.X < PaintBox1.Width)) and ((MousePos.Y > 0) and (MousePos.Y < PaintBox1.Height)) then begin Handled := True; // TreeView1とPaintBox1を独立してスクロール処理させるために必要 ZoomUp(PaintBox1.Canvas); end; end; procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin if ((MousePos.x > PaintBox1.Left) and (MousePos.x < PaintBox1.Left + PaintBox1.Width)) and ((MousePos.y > PaintBox1.Top) and (MousePos.y < PaintBox1.Top + PaintBox1.Height)) then begin Handled := True; // TreeView1とPaintBox1を独立してスクロール処理させるために必要 ZoomDown(PaintBox1.Canvas); end; end; procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if not CanDraw then Exit; if (ssLeft in Shift) or (ssRight in Shift) then begin DraggingNow := True; RubberBandShow := False; DragStartPoint := Point(X,Y); DragEndPoint := Point(0,0); if (ssLeft in Shift) then DragEndPoint.X := 1; if (ssRight in Shift) then DragEndPoint.Y := 1; end; end; procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if DraggingNow then begin if RubberBandShow then RubberBand(PaintBox1.Canvas, DragStartPoint, DragEndPoint); if (ssLeft in Shift) and (ssRight in Shift) then begin DragEndPoint := Point(X,Y); RubberBand(PaintBox1.Canvas, DragStartPoint, DragEndPoint); RubberBandShow := True; end else begin RubberBandShow := False; if (ssLeft in Shift) then DragEndPoint.X := 1; if (ssRight in Shift) then DragEndPoint.Y := 1; end; end end; procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); function GetDragModeKind: Integer; begin if (Abs(DragStartPoint.X - X) <= 5) and (Abs(DragStartPoint.Y - Y) <= 5) then Result := 0 // 移動 else begin if (DragStartPoint.X <= X) then Result := 1 // 拡大 else Result := 2; // 縮小 end; end; var x1, y1, x2, y2: Double; cx, cy: Double; dx, dy: Double; bx, by: Double; P1, P2: Double; begin if (not RubberBandShow) and ((DragEndPoint.X = 0) or (DragEndPoint.Y = 0)) then begin DraggingNow := False; Exit; end; if DraggingNow then begin DraggingNow := False; if RubberBandShow then RubberBand(PaintBox1.Canvas, DragStartPoint, DragEndPoint); DragModeKind := GetDragModeKind; x1 := ViewArea.Left + (DragStartPoint.X / mm_dot); // ドラッグ開始位置の左上X座標 y1 := ViewArea.Bottom - (DragStartPoint.Y / mm_dot); // ドラッグ開始位置の左下Y座標 x2 := ViewArea.Left + (X / mm_dot); // ドラッグ終了位置の左上X座標 y2 := ViewArea.Bottom - (Y / mm_dot); // ドラッグ終了位置の左下Y座標 dx := Abs(ViewArea.Right - ViewArea.Left); // ビューの幅 dy := Abs(ViewArea.Bottom - ViewArea.Top ); // ビューの高さ bx := Abs(x1 - x2); // 長方形の大きさ X by := Abs(y1 - y2); // 長方形の大きさ Y cx := (x1 + x2) / 2.0; // 長方形の中央の座標 X cy := (y1 + y2) / 2.0; // 長方形の中央の座標 Y case (DragModeKind) of 0: begin // 移動 cx := (ViewArea.Left + ViewArea.Right ) / 2.0; // 現在のビューの中心座標 X cy := (ViewArea.Top + ViewArea.Bottom) / 2.0; // 現在のビューの中心座標 Y dx := x2 - cx; // 移動量 dy := y2 - cy; // 移動量 ViewArea.Left := ViewArea.Left + dx; // 移動計算 ViewArea.Top := ViewArea.Top + dy; // 移動計算 ViewArea.Right := ViewArea.Right + dx; // 移動計算 ViewArea.Bottom := ViewArea.Bottom + dy; // 移動計算 end; 1: begin // 拡大 if (bx < 0.000001) then bx:=0.000001; if (by < 0.000001) then by:=0.000001; P1 := dx / bx; P2 := dy / by; if (P1 < P2) then mm_dot := mm_dot * P1 else mm_dot := mm_dot * P2; ViewArea.Left := cx - ((ImageSize.Width / 2.0) / mm_dot); ViewArea.Top := cy - ((ImageSize.Height / 2.0) / mm_dot); ViewArea.Right := cx + ((ImageSize.Width / 2.0) / mm_dot); ViewArea.Bottom := cy + ((ImageSize.Height / 2.0) / mm_dot); end; 2: begin // 縮小 P1 := bx / dx; P2 := by / dy; if (P1 > P2) then mm_dot := mm_dot * P1 else mm_dot := mm_dot * P2; ViewArea.Left := cx - ((ImageSize.Width / 2.0) / mm_dot); ViewArea.Top := cy - ((ImageSize.Height / 2.0) / mm_dot); ViewArea.Right := cx + ((ImageSize.Width / 2.0) / mm_dot); ViewArea.Bottom := cy + ((ImageSize.Height / 2.0) / mm_dot); end; end; DrawData(PaintBox1.Canvas); end end; procedure TForm1.PaintBox1Paint(Sender: TObject); begin DrawData(PaintBox1.Canvas); end; // TreeViewのチェックボックス処理 procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var HitTest: TTVHitTestInfo; Node: TTreeNode; I, J, K: Integer; begin // クリックした位置のノードを取得します。 Node := TreeView1.GetNodeAt(X, Y); if Node = nil then Exit; HitTest.pt.x := X; HitTest.pt.y := Y; TreeView_HitTest(TreeView1.Handle, HitTest); if (HitTest.flags = TVHT_ONITEMSTATEICON) then begin if TreeView_GetCheckState(TreeView1.Handle, Node.ItemId) > 0 then K := 1 else K := 0; if Node.Level = 0 then begin I := Node.AbsoluteIndex mod 16; JWWHd.GLay[I].m_anGLay := K; end else begin I := Node.Parent.AbsoluteIndex mod 16; J := Node.Index; JWWHd.GLay[I].m_nLay[J].m_aanLay := K; end; PaintBox1.Invalidate; end; end; end.描画のユニットです。
unit jwwDraw; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ComCtrls, jwwunit, Math; type TPointEx = packed record X: Double; Y: Double; end; TRectEx = packed record case Integer of 0: (Left, Top, Right, Bottom: Double); 1: (TopLeft, BottomRight: TPointEx); end; TSize = packed record Height: Integer; Width: Integer; end; TSizeEx = packed record Height: Double; Width: Double; end; var OriginPoint: TPoint; // 原点 ImageSize: TSize; // 画面ドットサイズ PaperSize: TSizeEx; // 用紙サイズ mm_dot: Double; // mm_dot比 ViewArea: TRectEx; // ビューエリア DragStartPoint: TPoint; // ドラッグ開始点 DragEndPoint: TPoint; // ドラッグ終了点 DragModeKind : Integer; // ドラッグモード 0:移動 1:拡大 2:縮小 DraggingNow : Boolean; // ドラッグ中かどうかのフラグ RubberBandShow : Boolean; // ラバーバンド表示フラグ CanDraw: Boolean; // 描画可能かどうかのフラグ function PointEx(X, Y: Double): TPointEx; // PointEx型を作成します。 procedure JWWDataDraw(APaintBox: TPaintBox); procedure DrawData(ACanvas: TCanvas); // 図面の描画 procedure SetPaperSize(Size: Integer); // 用紙サイズの設定 procedure ZoomUp(ACanvas: TCanvas); // 拡大 procedure ZoomDown(ACanvas: TCanvas); // 縮小 procedure RubberBand(ACanvas: TCanvas; P1, P2: TPoint); // ラバーバンドの描画 procedure SetLayerName(ATreeView: TTreeView); // レイヤー名及び表示/非表示の設定 procedure JwwDataLoadFromFile(FileName: String); implementation uses Commctrl, ShlObj; const TVIS_CHECKED = $2000; procedure JwwDataLoadFromFile(FileName: String); begin DraggingNow := False; RubberBandShow := False; jwwRead(FileName); SetPaperSize(JWWHd.m_nZumen); CanDraw := True; mm_dot := 0; end; function PointEx(X, Y: Double): TPointEx; begin Result.X := X; Result.Y := Y; end; // ラバーバンド長方形描画 procedure RubberBand(ACanvas: TCanvas; P1, P2: TPoint); begin ACanvas.Pen.Mode := pmXor; ACanvas.Pen.Color := clAqua; ACanvas.Pen.Width := 0; ACanvas.Pen.Style := psSolid; ACanvas.Brush.Style := bsClear; ACanvas.Rectangle(P1.X, P1.Y, P2.X, P2.Y); end; // 用紙サイズの設定 procedure SetPaperSize(Size: Integer); begin case Size of 0: begin // A0 PaperSize.Width :=1189; PaperSize.Height := 841; end; 1: begin // A1 PaperSize.Width := 841; PaperSize.Height := 594; end; 2: begin // A2 PaperSize.Width := 594; PaperSize.Height := 420; end; 3: begin // A3 PaperSize.Width := 420; PaperSize.Height := 297; end; 4: begin // A4 PaperSize.Width := 297; PaperSize.Height := 210; end; else PaperSize.Width :=1189; PaperSize.Height := 841; end; end; // JWWデータを描画します。 procedure JWWDataDraw(APaintBox: TPaintBox); procedure Calc_mm_dot; var P1, P2: Double; begin ImageSize.Width := APaintBox.Width; ImageSize.Height := APaintBox.Height; P1 := ImageSize.Width / PaperSize.Width; P2 := ImageSize.Height / PaperSize.Height; if mm_dot = 0 then begin if (P1 < P2) then mm_dot := P1 else mm_dot := P2; end; end; procedure Calc_ViewArea; begin ViewArea.Left := - (ImageSize.Width / 2.0) / mm_dot; ViewArea.Top := - (ImageSize.Height / 2.0) / mm_dot; ViewArea.Right := (ImageSize.Width / 2.0) / mm_dot; ViewArea.Bottom := (ImageSize.Height / 2.0) / mm_dot; end; begin if not CanDraw then Exit; Calc_mm_dot; Calc_ViewArea; APaintBox.Invalidate; end; // CADデータの描画 procedure DrawData(ACanvas: TCanvas); // 画面の消去 procedure CLS; begin ACanvas.Pen.Mode := pmCopy; ACanvas.Pen.Color := clWhite; ACanvas.Pen.Style := psSolid; ACanvas.Pen.Width := 1; ACanvas.Brush.Color := clWhite; ACanvas.Brush.Style := bsSolid; ACanvas.Rectangle(0, 0, ImageSize.Width, ImageSize.Height); end; // 用紙枠の描画 procedure Draw_Paper_Frame; var ARect: TRect; begin // 原点の計算 OriginPoint.X := Round( (0.0 - ViewArea.Left ) * mm_dot); OriginPoint.Y := Round(-(0.0 - ViewArea.Bottom) * mm_dot); // 用紙枠の描画 ARect.Left := Round( (-PaperSize.Width / 2 - ViewArea.Left ) * mm_dot); ARect.Top := Round(-(-PaperSize.Height/ 2 - ViewArea.Bottom) * mm_dot); ARect.Right := Round( ( PaperSize.Width / 2 - ViewArea.Left ) * mm_dot); ARect.Bottom := Round(-( PaperSize.Height/ 2 - ViewArea.Bottom) * mm_dot); ACanvas.Pen.Color := clBlue; ACanvas.Brush.Style := bsClear; ACanvas.Rectangle(ARect); end; // 座標を変換 procedure Change_mm_dot_Point(PEx: TPointEx; var P: TPoint); begin P.x := Round( PEx.x * mm_dot + OriginPoint.X ); P.y := Round(-PEx.y * mm_dot + OriginPoint.Y ); end; // 線及び円弧の線種・線色の設定 procedure LineSetting(Root: CData); begin ACanvas.Pen.Width := 0; case Root.m_nPenStyle of 1: ACanvas.Pen.Style := psSolid; 2,3,4,9: ACanvas.Pen.Style := psDot; 5,6,7,8: ACanvas.Pen.Style := psDashDot; end; case Root.m_nPenColor of 1: ACanvas.Pen.Color := RGB(0,192,192); 2: ACanvas.Pen.Color := clBlack; 3: ACanvas.Pen.Color := RGB(0,192,0); 4: ACanvas.Pen.Color := RGB(192,192,0); 5: ACanvas.Pen.Color := RGB(192,0,192); 6: ACanvas.Pen.Color := RGB(0,0,255); 7: ACanvas.Pen.Color := RGB(0,128,128); 8: ACanvas.Pen.Color := RGB(255,0,128); 9: ACanvas.Pen.Color := RGB(255,128,255); end; end; // フォントの設定 function FontSetting(ACDataMoji: CDataMoji): Boolean; var I: Integer; begin Result := True; ACanvas.Font.Name := ACDataMoji.m_strFontName; ACanvas.Font.Height := Round(ACDataMoji.m_dSizeY * mm_dot); if ACanvas.Font.Height = 0 then begin Result := False; Exit; end; // フォントのスタイルの設定 I := ACDataMoji.m_nMojiShu; if I >= 30000 then // ボールド + 斜体文字 begin ACanvas.Font.Style := [fsBold,fsItalic]; I := I - 30000 end else if I >= 20000 then // ボールド begin ACanvas.Font.Style := [fsBold]; I := I -20000 end else if I >= 10000 then // 斜体文字 begin ACanvas.Font.Style := [fsItalic]; I := I -10000; end else ACanvas.Font.Style := []; // フォントの色の設定 case JWWHd.m_Moji[I].m_anMojiCol of 1: ACanvas.Font.Color := RGB(0,192,192); 2: ACanvas.Font.Color := clBlack; 3: ACanvas.Font.Color := RGB(0,192,0); 4: ACanvas.Font.Color := RGB(192,192,0); 5: ACanvas.Font.Color := RGB(192,0,192); 6: ACanvas.Font.Color := RGB(0,0,255); 7: ACanvas.Font.Color := RGB(0,128,128); 8: ACanvas.Font.Color := RGB(255,0,128); 9: ACanvas.Font.Color := RGB(255,128,255); 10: ACanvas.Font.Color := clBlack; // 不明 end; end; // レイヤーの表示/非表示 function LayerCheck(Root: CData): Boolean; var I, J: Integer; F1, F2: Boolean; begin I := Root.m_nGLayer; J := Root.m_nLayer; F1 := JWWHd.GLay[I].m_anGLay <> 0; F2 := JWWHd.GLay[I].m_nLay[J].m_aanLay <> 0; Result := F1 and F2; end; // 補助線かどうか function IsSupportLine(Root: CData): Boolean; begin Result := (Root.m_nPenStyle = 9); end; // 線の描画 procedure DrawSen(Sen: CDataSen); var P1, P2: TPoint; begin if (not IsSupportLine(Sen.Root)) and LayerCheck(Sen.Root) then begin Change_mm_dot_Point(PointEx(Sen.m_start_x, Sen.m_start_y), P1); Change_mm_dot_Point(PointEx(Sen.m_end_x , Sen.m_end_y ), P2); LineSetting(Sen.Root); ACanvas.MoveTo(P1.X, P1.Y); ACanvas.LineTo(P2.X, P2.Y); end; end; { 旧FDelphi 玉石混淆みんなで作るSample蔵「斜め楕円の描画 」 } // 凛さん、裏目小僧さんのコード procedure Ellipse2(Center: TPoint; LongRadius, ShortRadius, Angle, angleFrom, angleTo: Extended); function rot(x,y: Extended; rad: Extended):TPointEx;//rad:radian var ss, cc: Extended; begin ss := sin(rad); cc := cos(rad); Result.x := cc*x-ss*y; Result.y := ss*x+cc*y; end; procedure drawDeclinedEllipsePP(aFrom, aTo: Extended); var I: Integer; bufP: array[0..3] of TPointEx; thePoints:array[0..3] of TPoint; s,c,xc,yc,fa: Extended; begin fa := aTo-aFrom; s := sin(fa); c := cos(fa); xc := cos(fa/2); yc := sin(fa/2); bufP[0].x := 1; bufP[0].y := 0; bufP[1].x := 1; bufP[1].y := -4*c*(1+c-2*xc)/s/3+4*(2*yc-s)/3; bufP[2].x := (-4-c+8*xc)/3; bufP[2].y := 4*c*(1+c-2*xc)/s/3+s; bufP[3].x := c; bufP[3].y := s; for I:= 0 to 3 do begin bufP[I]:=rot(BufP[I].x,bufP[I].y,aFrom); bufP[I]:=rot(LongRadius*BufP[I].x,shortRadius*BufP[I].y,angle); thePoints[I].x:=round(bufP[I].x + Center.X); thePoints[I].y:=round(bufP[I].y + Center.Y); end; PolyBezier(ACanvas.Handle, thePoints, 4); end; const Err=0.001; var sep, I: Integer; division: Extended; begin division := PI/3; sep := Trunc((AngleTo-AngleFrom)/division); for I := 0 to sep-1 do drawDeclinedEllipsePP(angleFrom+ I*division, angleFrom+(I+1)*division); if (AngleTo-AngleFrom)-(sep*division) > Err then drawDeclinedEllipsePP(angleFrom+sep*division, angleTo); end; // 円弧の描画 procedure DrawEnko(Enko: CDataEnko; IsSolid: Boolean=False); var Center: TPointEx; x1, y1, Hankei: Double; LongRadius, ShortRadius: Double; Hajime, Owari, Inclination: Double; PEx1, PEx2: TPointEx; P1, P2, P3,P4: TPoint; begin Hajime := Enko.m_radKaishiKaku + Enko.m_radKatamukiKaku; Owari := Enko.m_radKaishiKaku + Enko.m_radEnkoKaku + Enko.m_radKatamukiKaku; if (not IsSupportLine(Enko.Root)) and LayerCheck(Enko.Root) then begin x1 := Enko.m_start_x; y1 := Enko.m_start_y; Center.X := X1; Center.Y := Y1; Hankei := Enko.m_dHankei; if Enko.m_radKatamukiKaku < 0 then begin PEx1.X := X1-Hankei * Enko.m_dHenpeiRitsu; PEx1.Y := Y1-Hankei; PEx2.X := X1+Hankei * Enko.m_dHenpeiRitsu; PEx2.Y := Y1+Hankei; end else begin PEx1.X := X1-Hankei; PEx1.Y := Y1-Hankei*Enko.m_dHenpeiRitsu; PEx2.X := X1+Hankei; PEx2.Y := Y1+Hankei*Enko.m_dHenpeiRitsu; end; // 円弧の設定 LineSetting(Enko.Root); // mm→dot変換 Change_mm_dot_Point(PEx1, P1); Change_mm_dot_Point(PEx2, P2); // ソリッドかどうか if IsSolid then ACanvas.Brush.Style := bsSolid else ACanvas.Brush.Style := bsClear; // 円弧の描画 if Enko.m_bZenEnFlg = 1 then // 円・楕円の場合 begin begin if Enko.m_radKatamukiKaku = 0 then begin // 斜め描画しない // 円(楕円)・全円(全楕円)ソリッド ACanvas.Ellipse(P1.X,P1.Y,P2.X,P2.Y); end else begin // 斜め描画する Change_mm_dot_Point(Center, P3); if Enko.m_radKatamukiKaku < 0 then Inclination := (PI /2) - Enko.m_radKatamukiKaku else Inclination := - Enko.m_radKatamukiKaku; LongRadius := (P2.X-P1.X) div 2; ShortRadius := (P2.Y-P1.Y) div 2; Hajime := DegToRad(0); Owari := DegToRad(360); Ellipse2(P3, LongRadius, ShortRadius, Inclination, Hajime, Owari); end; end; end else begin // 楕円弧の場合 if Enko.m_dHenpeiRitsu <> 1.0 then begin Change_mm_dot_Point(Center, P3); if Enko.m_radKatamukiKaku < 0 then Inclination := (PI /2) - Enko.m_radKatamukiKaku else Inclination := -Enko.m_radKatamukiKaku; LongRadius := (P2.X-P1.X) div 2; ShortRadius := (P2.Y-P1.Y) div 2; Hajime := (Inclination+Enko.m_radKatamukiKaku+Enko.m_radKaishiKaku); Owari := (Inclination+Enko.m_radKatamukiKaku+Enko.m_radKaishiKaku + Enko.m_radEnkoKaku); Ellipse2(P3, LongRadius, ShortRadius, Inclination, Hajime, Owari); end else begin // 円弧 P3.X := Round( ((x1+Hankei*Cos(Hajime)))*MM_dot+OriginPoint.X); P3.Y := Round(-((y1+Hankei*Sin(Hajime)))*MM_dot+OriginPoint.Y); P4.X := Round( ((x1+Hankei*Cos(Owari )))*MM_dot+OriginPoint.X); P4.Y := Round(-((y1+Hankei*Sin(Owari )))*MM_dot+OriginPoint.Y); if (P3.X <> P4.X) or (P3.Y <> P4.Y) then begin if (Enko.m_radEnkoKaku < 0) then SetArcDirection(ACanvas.Handle, AD_CLOCKWISE) // 時計回り else SetArcDirection(ACanvas.Handle, AD_COUNTERCLOCKWISE); // 反時計回り if Enko.m_bZenEnFlg = 0 then ACanvas.Arc(P1.X,P1.Y,P2.X,P2.Y,P3.X,P3.Y,P4.X,P4.Y) // 円弧 else if Enko.m_bZenEnFlg = 2 then ACanvas.Chord(P1.X,P1.Y,P2.X,P2.Y,P3.X,P3.Y,P4.X,P4.Y) // 弓形ソリッド else if Enko.m_bZenEnFlg = 3 then ACanvas.Pie(P1.X,P1.Y,P2.X,P2.Y,P3.X,P3.Y,P4.X,P4.Y); // 扇形ソリッド end; end; end; end; end; // ソリッド図形の描画 procedure DrawSolid(Solid: CDataSolid); var poly: array[0..3] of TPoint; Enko: CDataEnko; begin if LayerCheck(Solid.Root) then begin if Solid.Root.m_nPenStyle > 100 then begin if Solid.Root.m_nPenStyle = 101 then begin //円のソリッド Enko.Root := Solid.Root; Enko.m_start_x := Solid.m_start_x; Enko.m_start_y := Solid.m_start_y; Enko.m_dHankei := Solid.m_end_x; Enko.m_radKaishiKaku := Solid.m_DPoint2_y; Enko.m_radEnkoKaku := Solid.m_DPoint3_x; Enko.m_radKatamukiKaku := Solid.m_DPoint2_x; Enko.m_dHenpeiRitsu := Solid.m_end_y; ACanvas.Pen.Color := Solid.m_Color; ACanvas.Brush.Color := ACanvas.Pen.Color; if Solid.m_DPoint3_y = 100 then Enko.m_bZenEnFlg := 1 // 全円ソリッド else if Solid.m_DPoint3_y = 5 then Enko.m_bZenEnFlg := 2 // 弓形ソリッド ※2は適当 else if Solid.m_DPoint3_y = 0 then Enko.m_bZenEnFlg := 3 // 扇形ソリッド ※3は適当 else if Solid.m_DPoint3_y = -1 then Enko.m_bZenEnFlg := 4 // 外側円弧ソリッド・・・どんな処理? else Enko.m_bZenEnFlg := 10; // 処理しない ※10は適当 if Enko.m_bZenEnFlg < 10 then DrawEnko(Enko, True); end else if Solid.Root.m_nPenStyle = 101 then begin //円環ソリッド・・・どんな処理? end else if Solid.Root.m_nPenStyle = 111 then begin //円周ソリッド・・・どんな処理? end; end else begin /// 線のソリッド // mm→dot変換 Change_mm_dot_Point(PointEx(Solid.m_start_x , Solid.m_start_y ), Poly[0]); Change_mm_dot_Point(PointEx(Solid.m_end_x , Solid.m_end_y ), Poly[1]); Change_mm_dot_Point(PointEx(Solid.m_DPoint2_x, Solid.m_DPoint2_y), Poly[2]); Change_mm_dot_Point(PointEx(Solid.m_DPoint3_x, Solid.m_DPoint3_y), Poly[3]); ACanvas.Pen.Color := Solid.m_Color; ACanvas.Brush.Color := ACanvas.Pen.Color; ACanvas.Polygon(poly); end; end; end; // 文字の描画 procedure DrawMoji(Moji: CDataMoji); var S: String; LF: TLogFont; P1, P2: TPoint; begin if LayerCheck(Moji.Root) then begin S := Moji.m_string; // mm→dot変換 Change_mm_dot_Point(PointEx(Moji.m_start_x, Moji.m_start_y), P1); Change_mm_dot_Point(PointEx(Moji.m_end_x , Moji.m_end_y ), P2); // フォントの設定 if FontSetting(Moji) then begin // 文字の描画 GetObject(ACanvas.Font.Handle, SizeOf(LF), @LF); SetTextAlign(ACanvas.Handle,TA_LEFT or TA_BOTTOM); LF.lfEscapement := Round(Moji.m_degKakudo*10); ACanvas.Font.Handle := CreateFontIndirect(LF); ACanvas.TextOut(P1.X, P1.Y, S); end; end; end; // ブロック図形の描画---回転や倍率は未対応です。 // いまいち理解できていないので、間違った処理かも?? var x1, y1: Double; procedure DrawBlock(CDB: CDataBlock); var I,J: Integer; Sen1: CDataSen; Enko1: CDataEnko; Moji1: CDataMoji; Solid1: CDataSolid; begin I := CDB.m_n_Number; x1 := CDB.m_DPKijunTen_x+x1; y1 := CDB.m_DPKijunTen_y+y1; for J := JWWBlockList.BlockList[I].Count-1 downto 0 do begin case JWWBlockList.DataType[I,J] of Sen: begin Sen1 := JWWBlockList.DataSen[I,J]; Sen1.m_start_x := Sen1.m_start_x+x1; Sen1.m_start_y := Sen1.m_start_y+y1; Sen1.m_end_x := Sen1.m_end_x +x1; Sen1.m_end_y := Sen1.m_end_y +y1; DrawSen(Sen1); end; Enko: begin Enko1 := JWWBlockList.DataEnko[I,J]; Enko1.m_start_x := Enko1.m_start_x+x1; Enko1.m_start_y := Enko1.m_start_y+y1; DrawEnko(Enko1); end; Moji: begin Moji1 := JWWBlockList.DataMoji[I,J]; Moji1.m_start_x := Moji1.m_start_x+x1; Moji1.m_start_y := Moji1.m_start_y+y1; DrawMoji(Moji1); end; Solid: begin Solid1 := JWWBlockList.DataSolid[I,J]; Solid1.m_start_x := Solid1.m_start_x+x1; Solid1.m_start_y := Solid1.m_start_y+y1; Solid1.m_end_x := Solid1.m_end_x+x1; Solid1.m_end_y := Solid1.m_end_y+y1; Solid1.m_DPoint2_x := Solid1.m_DPoint2_x+x1; Solid1.m_DPoint2_y := Solid1.m_DPoint2_y+y1; Solid1.m_DPoint3_x := Solid1.m_DPoint3_x+x1; Solid1.m_DPoint3_y := Solid1.m_DPoint3_y+y1; DrawSolid(Solid1); end; Block: begin DrawBlock(JWWBlockList.DataBlock[I,J]); end; end; end; end; var I: Integer; begin // 画面の消去 CLS; // 用紙枠の描画 Draw_Paper_Frame; // 線の描画 for I := Low(JWWSen) to High(JWWSen) do DrawSen(JWWSen[I]); // 円弧の描画 for I := Low(JWWEnko) to High(JWWEnko) do DrawEnko(JWWEnko[I]); // 文字の描画 for I := Low(JWWMoji) to High(JWWMoji) do DrawMoji(JWWMoji[I]); // ソリッド図形 for I := Low(JWWSolid) to High(JWWSolid) do DrawSolid(JWWSolid[I]); // ブロックデータの描画 for I:= Low(JWWBlock) to High(JWWBlock) do begin x1:= 0; y1 := 0; DrawBlock(JWWBlock[I]); end; end; // ビュー中央の座標、ビューの幅、高さを取得 procedure GetViewInfo(var View_CenterPoint: TPointEx; var View_Width, View_Height: Double); begin View_CenterPoint.X := (ViewArea.Left + ViewArea.Right) / 2.0; View_CenterPoint.Y := (ViewArea.Top + ViewArea.Bottom) / 2.0; View_Width := Abs(ViewArea.Right - ViewArea.Left); View_Height := Abs(ViewArea.Bottom - ViewArea.Top); end; // 用紙枠の描画サイズ procedure GetPaperFrameDrawSize(var ARect: TRect; AView_x1, AView_y1, Amm_dot: Double); begin ARect.Left := Round( (-PaperSize.Width /2.0 - AView_x1) * Amm_dot); ARect.Bottom := Round(-(-PaperSize.Height/2.0 - AView_y1) * Amm_dot); ARect.Right := Round( ( PaperSize.Width /2.0 - AView_x1) * Amm_dot); ARect.Top := Round(-( PaperSize.Height/2.0 - AView_y1) * Amm_dot); end; // 拡大 procedure ZoomUp(ACanvas: TCanvas); var View_Width, View_Height: Double; View_CenterPoint: TPointEx; // 一定以上大きくさせない。 function LargeCheck: Boolean; const Max = 80000; var Check_mm_dot, Check_view_x1, Check_view_y1: Double; ARect: TRect; begin Result := False; //2倍に拡大 Check_mm_dot := mm_dot * 2.0; Check_view_x1 := View_CenterPoint.x - (View_Width / 4.0); Check_view_y1 := View_CenterPoint.y + (View_Height / 4.0); // 用紙枠の描画サイズ GetPaperFrameDrawSize(ARect,Check_view_x1,Check_view_y1,Check_mm_dot); if (ARect.Right-ARect.Left > Max) or (ARect.Bottom- ARect.Top >Max) then Exit; Result := True; end; begin // ビュー中央の座標、ビューの幅、高さを取得 GetViewInfo(View_CenterPoint, View_Width, View_Height); // 一定以上拡大させない。 if not LargeCheck then Exit; //2倍に拡大 mm_dot := mm_dot * 2.0; ViewArea.Left := View_CenterPoint.X - (View_Width /4.0); ViewArea.Top := View_CenterPoint.Y - (View_Height/4.0); ViewArea.Right := View_CenterPoint.X + (View_Width /4.0); ViewArea.Bottom := View_CenterPoint.Y + (View_Height/4.0); DrawData(ACanvas); end; // 縮小 procedure ZoomDown(ACanvas: TCanvas); var View_Width, View_Height: Double; View_CenterPoint: TPointEx; // 一定以上縮小させない。 function SmallCheck: Boolean; const Min = 10; var Check_mm_dot, Check_view_x1, Check_view_y1: Double; ARect: TRect; begin Result := False; // 1/2倍に縮小 Check_mm_dot := mm_dot * 0.5; Check_view_x1 := View_CenterPoint.X - View_Width; Check_view_y1 := View_CenterPoint.Y + View_Height; // 用紙枠の描画サイズ GetPaperFrameDrawSize(ARect,Check_view_x1,Check_view_y1,Check_mm_dot); if (ARect.Right-ARect.Left < Min) or (ARect.Bottom-ARect.Top <Min) then Exit; Result := True; end; begin // ビュー中央の座標、ビューの幅、高さを取得 GetViewInfo(View_CenterPoint, View_Width, View_Height); // 一定以上縮小させない。 if not SmallCheck then Exit; // 1/2倍に縮小 mm_dot := mm_dot * 0.5; ViewArea.Left := View_CenterPoint.X - View_Width; ViewArea.Top := View_CenterPoint.Y - View_Height; ViewArea.Right := View_CenterPoint.X + View_Width; ViewArea.Bottom := View_CenterPoint.Y + View_Height; DrawData(ACanvas); end; // レイヤー名及び表示/非表示の設定 procedure SetLayerName(ATreeView: TTreeView); // ノードのチェックボックス設定 procedure NodeCheckBox(Node: TTreeNode; F: Boolean); var TvItem: TTVItem; begin TvItem.hItem := Node.ItemId; TvItem.stateMask := TVIS_STATEIMAGEMASK; TvItem.mask := TVIF_HANDLE or TVIF_STATE; if F then TvItem.state := TVIS_CHECKED else TvItem.state := TVIS_CHECKED shr 1; TreeView_SetItem(ATreeView.Handle, TvItem); end; // 太字設定 procedure SetBold(Node: TTreeNode); var TvItem: TTVItem; begin TvItem.hItem := Node.ItemId; TvItem.stateMask := TVIS_BOLD; TvItem.mask := TVIF_HANDLE or TVIF_STATE; TvItem.state := TVIS_BOLD; TreeView_SetItem(ATreeView.Handle, TvItem); end; var I, J, K, SNo, ENo: Integer; NodeA, NodeB: TTreeNode; LayerNo, Scale, LayerName: String; F: Boolean; begin ATreeView.Items.BeginUpdate; try ATreeView.Items.Clear; // レイヤーグループの設定 for I := Low(JWWHd.m_aStrGLayName) to High(JWWHd.m_aStrGLayName) do begin // レイヤーグループ番号 LayerNo := '[' + IntToHex(I, 1) +'] '; // 縮尺 if JWWHd.GLay[I].m_adScale < 1 then Scale := IntToStr(Round(1 / JWWHd.GLay[I].m_adScale)) + '/1' else Scale := '1/'+ IntToStr(Trunc(JWWHd.GLay[I].m_adScale)); // レイヤーグループ名 LayerName := ' ' + JWWHd.m_aStrGLayName[I]; // ノードの追加及び表示/非表示の設定 NodeA := ATreeView.Items.Add(nil, LayerNo + Scale + LayerName); F := JWWHd.GLay[I].m_anGLay <> 0; NodeCheckBox(NodeA, F); SetBold(NodeA); // レイヤーの設定 SNo := I * 16; // 読み取り開始番号 ENo := SNo + 15; // 読み取り終了番号 for J := SNo to ENo do begin K := J - SNo; LayerNo := '[' + IntToHex(K, 1) +'] '; // レイヤーグループ番号 LayerName := ' ' + JWWHd.m_aStrLayName[J]; // レイヤー名 // ノードの追加及び表示/非表示の設定 NodeB := ATreeView.Items.AddChild(NodeA, LayerNo + LayerName); F := JWWHd.GLay[I].m_nLay[K].m_aanLay <> 0; NodeCheckBox(NodeB, F); end; end; finally ATreeView.Items.EndUpdate; end; end; end.
Peter's Room
jww data read & save unit Ver1.31β
http://www5b.biglobe.ne.jp/~peter/
AFsoft WebSite
CAD作ろ!
http://afsoft.jp/
| 固定リンク