SVGCat.cpp

C:\home\SVGCats_src\src\SVGCat.cpp

[目次 | 型・クラス・構造体 | 関数 | マクロ]

目次

型・クラス・構造体一覧

関数一覧

マクロ一覧


   1|// SVGCat.cpp : アプリケーション用クラスの機能定義を行います。 
   2|//
   3|
   4|#include "mixer_precomp.h"
   5|#include <locale.h>
   6|
   7|#ifdef  USES_MXP_AUTOINC
   8| #include  "SVGCat.ah"
   9|#endif
  10|
  11|#include <direct.h>
  12|
  13|#ifdef _DEBUG
  14|#define new DEBUG_NEW
  15|#undef THIS_FILE
  16|static char THIS_FILE[] = __FILE__;
  17|#endif
  18|
  19|
  20|char*  CSVGCatApp_meltSvgz( const char* svgz_path );
  21|char*  CSVGCatApp_compressSvgz( const char* svgz_path );
  22|
  23|
  24|/////////////////////////////////////////////////////////////////////////////
  25|// CSVGCatApp
  26|
  27|BEGIN_MESSAGE_MAP(CSVGCatApp, CWinApp)
  28|  //{{AFX_MSG_MAP(CSVGCatApp)
  29|  ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  30|  //}}AFX_MSG_MAP
  31|END_MESSAGE_MAP()
  32|
  33|
  34|CLIPFORMAT  SVGCats_ClipFormat;
  35|CLIPFORMAT  SVGCats_ClipFormat2;
  36|
  37|void  CSVGCatApp_onDdeMsg( int type, char* data );
  38|volatile  bool  CSVGCatApp_bAcceptDdeMsg = false;
  39|int   CSVGCatApp_stdErrHandler( int id, int code, char* msg );
  40|
  41|/////////////////////////////////////////////////////////////////////////////
  42|// CSVGCatApp クラスの構築
  43|
  44|CSVGCatApp::CSVGCatApp()
  45|{
  46|}
  47|
  48|CSVGCatApp::~CSVGCatApp()
  49|{
  50|}
  51|
  52|/////////////////////////////////////////////////////////////////////////////
  53|// 唯一の CSVGCatApp オブジェクト
  54|
  55|CSVGCatApp theApp;
  56|
  57|/////////////////////////////////////////////////////////////////////////////
  58|// CSVGCatApp クラスの初期化
  59|
  60|
  61| 
  62|/***********************************************************************
  63|  1. <<< [CSVGCatApp::InitInstance] 初期化する >>> 
  64|************************************************************************/
  65|BOOL CSVGCatApp::InitInstance()
  66|{
  67|  // 標準的な初期化処理
  68|  // もしこれらの機能を使用せず、実行ファイルのサイズを小さく
  69|  // したければ以下の特定の初期化ルーチンの中から不必要なもの
  70|  // を削除してください。
  71|  bool    bUseTemplate = false;
  72|	HANDLE  sema;
  73|  CString  out_path;
  74|  int  out_mode = '\0';  /* '\0'=not output, 'j'=JPEG, 'p'=PNG */
  75|  #ifdef NDEBUG
  76|    enum { timeout = 180000 };
  77|  #else
  78|    enum { timeout = 1000 };
  79|  #endif
  80|  m_pMainWnd = NULL;
  81|  m_ErrorLevel = 0;
  82|
  83|  sema = CreateSemaphore( NULL, 1,1, "SVGCats_InitialSema" );
  84|  WaitForSingleObject( sema, timeout );
  85|
  86|
  87|  /* ファイルセマフォが取られたまま異常終了したときの対処のため、強制開放する */
  88|  m_FileSema = CreateSemaphore( NULL, 1,1, "SVGCats_FileSema" );
  89|  WaitForSingleObject( m_FileSema, 10000 );
  90|  ReleaseSemaphore( m_FileSema, 1, NULL );
  91|
  92|
  93|  /* コマンドラインを解析する */
  94|  m_bJapanese = ( GetACP() == 932 );
  95|  m_bHideMain = false;
  96|  m_bTaskTray = false;
  97|  m_bAutoSave = false;
  98|  m_bUpdsk = false;
  99|  m_bCtrlRet = true;
 100|  m_SplitX = 120;
 101|  m_SplitMode = 0;
 102|
 103|  {
 104|    char*  p = m_lpCmdLine;
 105|
 106|    for(;;) {
 107|      if ( *p == '\0' )  break;
 108|      else if ( strncmp( p, "-j", 2 ) == 0 ) { m_bJapanese = true;  p += 2; }
 109|      else if ( strncmp( p, "-e", 2 ) == 0 ) { m_bJapanese = false; p += 2; }
 110|      else if ( strncmp( p, "-t", 2 ) == 0 ) { m_bTaskTray = true;  p += 2; }
 111|      else if ( strncmp( p, "-s", 2 ) == 0 ) { m_bAutoSave = true;  p += 2; }
 112|      else if ( strncmp( p, "-u", 2 ) == 0 ) { m_bUpdsk = true;     p += 2; }
 113|      else if ( strncmp( p, "-p", 2 ) == 0 ) { bUseTemplate = true; p += 2; }
 114|      else if ( strncmp( p, "-n", 2 ) == 0 )
 115|        { m_bTaskTray = true;  m_bNewTaskTray = true;  m_bAutoSave = true;  p += 2; }
 116|      else if ( strncmp( p, "-cj", 3 ) == 0 ) { out_mode = 'j';  p += 3; }
 117|      else if ( strncmp( p, "-cp", 3 ) == 0 ) { out_mode = 'p';  p += 3; }
 118|      else  break;
 119|
 120|      while ( *p == ' ' )  p++;
 121|    }
 122|
 123|    if ( out_mode == '\0' ) {
 124|      strcpy( m_path, p );
 125|      if ( m_path[0] == '\"' )  StrX_del( m_path, 1 );
 126|      StrX_cutLastOf( m_path, '\"' );
 127|    }
 128|    else {
 129|      char  path[_MAX_PATH];
 130|
 131|      p  = StrX_getCmdWord( m_path, p );
 132|      StrX_getCmdWord( path, p );
 133|      out_path = path;
 134|    }
 135|  }
 136|
 137|//  if ( m_bNewTaskTray )
 138|//    WinX_DdeServ_init( &m_DdeServ, "SVGCats", "Open", "", CSVGCatApp_onDdeMsg );
 139|
 140|
 141|  /* 地域の設定をする */
 142|  if ( m_bJapanese ) {
 143|    setlocale( LC_ALL,"Japanese" );
 144|  }
 145|  else {
 146|    setlocale( LC_ALL,"English" );
 147|  }
 148|  m_BackupInterval = 1;
 149|  /* ツールボタンのヒントなど、リソースでしか国を選択できないものは、 */
 150|  /* リソースの国を「ニュートラル(標準)」にする。ただし、Win98系では日本でも英語になる。 */
 151|
 152|
 153|  if ( m_path[0] != '\0' && ! FileX_isExist( m_path ) ) {
 154|    MessageBox( NULL, CString(m_path) + ( m_bJapanese ? " を開こうとしましたが見つかりません。" :
 155|      " can not open." ), "SVG Cats", MB_OK );
 156|    if ( ! m_bTaskTray ) {
 157|      ReleaseSemaphore( sema, 1, NULL );
 158|      CloseHandle( sema );
 159|      return  FALSE;
 160|    }
 161|  }
 162|
 163|  AfxEnableControlContainer();
 164|  CoInitialize( NULL );  /* COM インターフェイス全般の初期化 */
 165|
 166|#ifdef _AFXDLL
 167|  Enable3dControls();    // 共有 DLL の中で MFC を使用する場合にはここを呼び出してください。
 168|#else
 169|  Enable3dControlsStatic();  // MFC と静的にリンクしている場合にはここを呼び出してください。
 170|#endif
 171|
 172|  // 設定が保存される下のレジストリ キーを変更します。
 173|  // TODO: この文字列を、会社名または所属など適切なものに
 174|  // 変更してください。
 175|  SetRegistryKey(_T("Ts-Neko"));
 176|
 177|
 178|  // メイン ウインドウを作成するとき、このコードは新しいフレーム ウインドウ オブジェクトを作成し、
 179|  // それをアプリケーションのメイン ウインドウにセットします
 180|  CMainFrame*  pFrame = new CMainFrame;
 181|  m_pMainWnd = pFrame;
 182|
 183|  static char  module_fname[_MAX_PATH];
 184|  static char  bigstack[6000];
 185|  char  path[_MAX_PATH];
 186|
 187|  GetModuleFileName( AfxGetApp()->m_hInstance, module_fname, sizeof(module_fname) );
 188|  StrX_argv0 = module_fname;
 189|  Errors_appName = SVGCats_AppName;
 190|  Errors_appVersion = TimeDate_getCompileStrF( "%y.%m.%d" );
 191|  Except3_initEasy( CSVGCatApp_stdErrHandler /*Errors_stdErrHandler*/ );
 192|  BigStack_init( bigstack, sizeof(bigstack) );
 193|  #define  SVGCATS_REGPATH  "stacgvs\\date"
 194|
 195|
 196|#ifdef  SVGCats_NewFileAccess
 197|Errors_startPool();
 198|#endif
 199|
 200|//Errors_startPool();
 201|//IFC(0);
 202|//ERRORS_FUNCLOG_INIT();
 203|//m_nCmdShow=7;  BK
 204|
 205|  SVGCats_ClipFormat = RegisterClipboardFormat( "SVGCats" );
 206|  SVGCats_ClipFormat2 = RegisterClipboardFormat( "SVGCats2" );
 207|  if ( m_path[0] == '"' ) {
 208|    StrX_del( m_path, 1 );
 209|    *strchr( m_path, '"' ) = '\0';
 210|  }
 211|  if ( m_bNewTaskTray && m_path[0] == '\0' ) {
 212|    strcpy( m_path, WinX_getMyDocPath() );
 213|    StrX_addFName( m_path, "cats_memo.svg" );
 214|    if ( ! FileX_isExist( m_path ) ) {
 215|      StrX_getExeFullPath( path, "system\\first.svg", sizeof(path) );
 216|      FileX_copy( m_path, path );
 217|    }
 218|  }
 219|  ReadRecentFile();
 220|  StrX_getExeFullPath( m_ImgFolderPath, ".", sizeof(m_ImgFolderPath) );
 221|
 222|
 223|  m_bAvoidPatent = true;
 224|  LoadSVGCatsIni();  /* m_Canvas の初期化はこの内部で行っている */
 225|
 226|
 227|  StrX_getExeFullPath( path, _work_path, sizeof(path) );
 228|  FileX_mkdir2( path, false );
 229|  StrX_getExeFullPath( path, _backup_path, sizeof(path) );
 230|  FileX_mkdir2( path, false );
 231|
 232|
 233|  /* ページ管理をまっさらな状態に初期化する */
 234|  m_file.m_bPagesExist = false;
 235|  NewEmpty();
 236|
 237|
 238|  /* フレームをリソースからロードして作成します */
 239|  if ( m_bJapanese ) {
 240|    pFrame->LoadFrame(IDR_MAINFRAME,
 241|      WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
 242|      NULL);
 243|  }
 244|  else {
 245|    pFrame->LoadFrame(IDR_MAINFRAME_E,  /* Accelerator, Menu, Icon */
 246|      WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
 247|      NULL);
 248|  }
 249|
 250|  Errors_parentWnd = pFrame->m_hWnd;
 251|  Errors_parentCWnd = (void*)pFrame;
 252|
 253|
 254|  /* 初期ページのインクファイルに pFrame->m_hWnd を反映させる */
 255|  m_file.m_id = (long)pFrame->m_hWnd;
 256|  strcpy( path, GetInkWorkFilePath( m_file.m_id, 1, IRO_MaskPen ) );
 257|  MoveFile( GetInkWorkFilePath( 0, 1, IRO_MaskPen ), path );
 258|  strcpy( path, GetInkWorkFilePath( m_file.m_id, 1, IRO_CopyPen ) );
 259|  MoveFile( GetInkWorkFilePath( 0, 1, IRO_CopyPen ), path );
 260|
 261|
 262|  /* 表示を開始する */
 263|  pFrame->ShowWindow(m_nCmdShow);
 264|  pFrame->UpdateWindow();
 265|
 266|
 267|  /* メイン ウィンドウが初期化されたので、表示と更新を行う */
 268|  StrX_getExeFullPath( path, "svgcats.ini", sizeof(path) );
 269|  m_bForTheFirstTime = ! FileX_isExist( path );
 270|  if ( m_bForTheFirstTime && ! m_bTaskTray ) {
 271|    MessageBox( NULL, "F1 キーを押すと、クイックツアー(ビジュアル・ヘルプ)が表示されます。\n"
 272|      "(このメッセージは、初めて起動したときだけ表示されます。)",
 273|      "SVG Cats 2 へようこそ!", MB_OK );
 274|  }
 275|
 276|  /* SVG ファイルを開く */
 277|  if ( m_path[0] == '\0' )  ((CMainFrame*)m_pMainWnd)->New();
 278|  else if ( FileX_isExist(m_path) ) {
 279|    c_try {
 280|      ((CMainFrame*)m_pMainWnd)->Load( m_path, true );
 281|    }
 282|    c_catch ( Errors_Msg*, msg ) {
 283|      if ( msg->code != CSVGCatApp_Err_Format )  c_throw_again();
 284|      ((CMainFrame*)m_pMainWnd)->New();
 285|    } c_end_catch;
 286|  }
 287|
 288|
 289|  /* 初期モードを設定する */
 290|  pFrame->ResetAttr();
 291|  pFrame->ReadDefDesign( false );
 292|
 293|  if ( m_bTaskTray ) {
 294|    pFrame->SendMessage( WM_CLOSE, 0, 0 );
 295|
 296|    if ( m_bNewTaskTray ) {
 297|      if ( ListX_getN( &m_file.m_prims, SVGCat_Page ) != 0 ||
 298|           pFrame->m_wndView->GetStrokeCount() != 0 ) {
 299|        if ( ! m_bForTheFirstTime )  pFrame->OnNewPrevPage();
 300|        Save( m_path, false );
 301|      }
 302|    }
 303|  }
 304|  if ( bUseTemplate ) {
 305|    m_path[0] = '\0';
 306|    pFrame->UpdateWindowText();
 307|  }
 308|
 309|
 310|  /* 古いバックアップファイルを消す */
 311|  {
 312|    time_t  t, yes;
 313|    NestFind  f;
 314|    char*  p;
 315|    char  path[_MAX_PATH];
 316|    HWND*  hs;
 317|    int    hs_n, hs_i;
 318|    HWND   id;
 319|
 320|    time( &yes );
 321|    TimeDate_setDiff( &t, 0, 0, 2, 0, 0, 0 );
 322|    yes -= t;
 323|
 324|    hs_n = WinX_getNumOfWnd();
 325|    hs = (HWND*)malloc( hs_n * sizeof(HWND) );
 326|    hs_n = WinX_getAllAppHWnd( hs, hs_n * sizeof(HWND), "SVGCats.exe" );
 327|
 328|    /* backup- */
 329|    StrX_getExeFullPath( path, _backup_path, sizeof(path) );
 330|    NestFind_init( &f, path, false );
 331|    while ( NestFind_next( &f ) ) {
 332|      p = NestFind_getAbsPath( &f );
 333|
 334|      if ( strncmp( StrX_refFName( p ), "backup-", 7 ) != 0 ||
 335|           stricmp( StrX_refExt( p ), "svg" ) != 0 )
 336|        continue;
 337|
 338|      FileX_getUpdate( p, &t );
 339|      if ( t < yes )  remove( p );
 340|    }
 341|    NestFind_finish( &f );
 342|
 343|    /* work フォルダ */
 344|    StrX_getExeFullPath( path, _work_path, sizeof(path) );
 345|    NestFind_init( &f, path, false );
 346|    while ( NestFind_next( &f ) ) {
 347|      p = NestFind_getAbsPath( &f );
 348|
 349|      FileX_getUpdate( p, &t );
 350|      if ( t < yes ) {
 351|        sscanf( StrX_refFName( p ) + 4, "%X", &id );
 352|        for ( hs_i = 0; hs_i < hs_n; hs_i++ ) {
 353|          if ( hs[hs_i] == id )  break;  /* 起動中は削除しない */
 354|        }
 355|        if ( hs_i == hs_n )
 356|          remove( p );
 357|      }
 358|    }
 359|    NestFind_finish( &f );
 360|
 361|    free( hs );
 362|  }
 363|
 364|
 365|  /* すぐにバックアップを取る */
 366|  m_backPath[0] = '\0';
 367|  ChangeBackup();
 368|  pFrame->TakeBackup();
 369|  pFrame->TakeBackup();  /* 2回目で backup\backup へ */
 370|
 371|  /* バックアップファイルの設定をする */
 372|  if ( m_BackupInterval > 0 )
 373|    pFrame->m_Timer = pFrame->SetTimer( CMainFrame_Timer_Backup, 60*1000*m_BackupInterval , NULL );
 374|  else
 375|    pFrame->m_Timer = 0;
 376|
 377|  Errors_setErrorExitHandler( (Errors_ExitHandler)CSVGCatApp_onErrorExit, this );
 378|
 379|  CSVGCatApp_bAcceptDdeMsg = true;
 380|
 381|  #if ERRORS_DEBUG_FALSE
 382|    printPages( "#" );
 383|    SVGCat_Page* page;
 384|    for ( ListX_forEach( &m_file.m_pages, &page, SVGCat_Page ) ) {
 385|      Errors_printf( "================================================" );
 386|      printPrims( &page->prims, "" );
 387|    }
 388|  #endif
 389|
 390|  ReleaseSemaphore( sema, 1, NULL );
 391|  CloseHandle( sema );
 392|
 393|  if ( ! WinX_isExistReg( HKEY_CLASSES_ROOT, SVGCATS_REGPATH, true, true ) ) {
 394|    time_t  t;
 395|    WinX_RegData  data;
 396|
 397|    time(&t);
 398|    WinX_RegData_init( &data, (char*)&t, sizeof(t) );
 399|    data.type = REG_BINARY;  data.size = sizeof(t);
 400|    WinX_setReg( HKEY_CLASSES_ROOT, SVGCATS_REGPATH, true, &data );
 401|  }
 402|  else {
 403|    OpenCommercial2();  /* カットしちゃ駄目よ */
 404|  }
 405|
 406|  m_bForTheFirstTime = false;
 407|
 408|
 409|  /* 画像変換する */
 410|  if ( out_mode != '\0' ) {
 411|    c_try {
 412|      ((CMainFrame*)m_pMainWnd)->SaveToImage( out_path, out_mode );
 413|    }
 414|    c_catch( Errors_Msg*, err ) {
 415|      if ( err->code == FileX_Err_CannotWrite ) {
 416|        MessageBox( NULL, err->msg, "Error", MB_OK );
 417|        m_ErrorLevel = 4;
 418|      }
 419|      else
 420|        c_throw_again();
 421|    } c_end_catch;
 422|    m_pMainWnd->PostMessage( WM_CLOSE, 0, 0 );
 423|  }
 424|
 425|  return TRUE;
 426|}
 427|
 428|
 429| 
 430|/***************************************************************************
 431|  2. <<< [CSVGCatApp_onDdeMsg] DDE メッセージを受け取ったときの処理 >>> 
 432|****************************************************************************/
 433|void  CSVGCatApp_onDdeMsg( int type, char* data )
 434|{
 435|  if ( ! CSVGCatApp_bAcceptDdeMsg )  return;
 436|  else {
 437|    CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
 438|    CMainFrame*  frame = (CMainFrame*)app->m_pMainWnd;
 439|
 440|    frame->RestoreWindow( true, data );
 441|  }
 442|}
 443|
 444|
 445| 
 446|/***************************************************************************
 447|  3. <<< [CSVGCatApp_stdErrHandler] 標準的なエラーハンドラ >>> 
 448|****************************************************************************/
 449|int  CSVGCatApp_stdErrHandler( int id, int code, char* msg )
 450|{
 451|  #ifndef  NDEBUG
 452|    if ( code == Errors_ASSERT )
 453|      Errors_break( 0xEEEE );  /* [EXIT_POINT] */
 454|  #endif
 455|
 456|  #ifdef  USES_EXCEPT3
 457|    if ( code != Errors_ASSERT && code != Except3_Err_OutOfTry )
 458|      c_throw( Errors_Msg_getGlobl() );
 459|  #endif
 460|
 461|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
 462|  CMainFrame*  frame = (CMainFrame*)app->m_pMainWnd;
 463|  if ( frame->m_Timer != 0 )  { frame->KillTimer( frame->m_Timer );  frame->m_Timer = 0; }
 464|
 465|
 466|//  #ifdef  NDEBUG
 467|    /* 下の2行のうちどちらか */
 468|    Errors_printf_release( "%s", msg );
 469|    Errors_MsgPool_print( Errors_MsgPool_getGlobl() );
 470|//  #endif
 471|
 472|  return  ERRORS_EXIT;
 473|}
 474|
 475|
 476| 
 477|/***********************************************************************
 478|  4. <<< [CSVGCatApp_onErrorExit] 異常終了したとき、保存を試みる >>> 
 479|************************************************************************/
 480|void  CSVGCatApp_onErrorExit( CSVGCatApp* m )
 481|{
 482|  CMainFrame*  frame = (CMainFrame*)m->m_pMainWnd;
 483|  char  path[_MAX_PATH];
 484|  char  msg[_MAX_PATH+100];
 485|
 486|  frame->RemoveFromTaskTray();
 487|
 488|  strcpy( path, m->m_path );
 489|  if ( path[0] == '\0' ) {
 490|    StrX_cpyAbsPath( path, ".onExit.svg", sizeof(path), WinX_getDesktopPath() );
 491|  }
 492|  else
 493|    strcat( path, ".onExit.svg" );
 494|
 495|  sprintf( msg, (m->m_bJapanese ? "エラーが発生したので %s に保存を試みます。" :
 496|    "Error occured ! SVGCats trys to save at %s") , path );
 497|  MessageBox( NULL, msg, NULL, MB_OK );
 498|  m->Save( path, true );
 499|  MessageBox( NULL, (m->m_bJapanese ? "保存しました" : "Saved."), NULL, MB_OK );
 500|}
 501|
 502|
 503| 
 504|/***********************************************************************
 505|  5. <<< [CSVGCatApp::printPrims] 全図形をデバッグ表示する >>> 
 506|************************************************************************/
 507|#ifndef  ERRORS_CUT_DEBUG_TOOL
 508|void  CSVGCatApp::printPrims( ListX* prims, const char* title )
 509|{
 510|  ListX_ElemX*  p;
 511|
 512|  Errors_printf( "---- All Prims ----------------------" );
 513|  for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
 514|    WP(p);
 515|    ((CadPrim*)p->p)->print( title );
 516|  }
 517|  Errors_printf( "-------------------------------------" );
 518|}
 519|#endif
 520|
 521|
 522| 
 523|/***********************************************************************
 524|  6. <<< [CSVGCatApp::printPages] デバッグ表示する >>> 
 525|************************************************************************/
 526|#ifndef  ERRORS_CUT_DEBUG_TOOL
 527|void  CSVGCatApp::printPages( const char* title )
 528|{
 529|  printPages2( &m_file, title );
 530|}
 531|
 532|void  CSVGCatApp::printPages2( SVGCat_File* file, const char* title )
 533|{
 534|  SVGCat_Page*  page;
 535|  int  iPage = file->m_StartPageNum;
 536|
 537|  Errors_printf("%sPages -----------------------", title );
 538|  for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
 539|    Errors_printf("%sPage[%p] num=%d, next=%p, prev=%p, parent=%p, firstChild=%p"
 540|      ", prims first=0x%08X",
 541|      title, page, iPage, page->next, page->prev, page->parent, page->firstChild,
 542|      ListX_getFirst( &page->prims, CadPrim ) );
 543|    iPage ++;
 544|  }
 545|}
 546|
 547|void  CSVGCatApp::printPages3( const char* title )  /* 全てのページの全ての要素を表示する */
 548|{
 549|  SVGCat_Page*  page;
 550|  int  iPage = m_file.m_StartPageNum;
 551|
 552|  Errors_printf("%sPages -----------------------", title );
 553|  for ( ListX_forEach( &m_file.m_pages, &page, SVGCat_Page ) ) {
 554|    Errors_printf("%sPage[%p] ------------------------------------", title, iPage );
 555|    printPrims( &page->prims, title );
 556|    iPage ++;
 557|  }
 558|}
 559|#endif
 560|
 561|
 562|
 563| 
 564|/***********************************************************************
 565|  7. <<< [CSVGCatApp::LoadSVGCatsIni] SVGCats 設定ファイルを開く >>> 
 566|************************************************************************/
 567|void  CSVGCatApp::LoadSVGCatsIni()
 568|{
 569|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
 570|  IniFile_Read  f;
 571|  char  f_buf[256];
 572|  char  path[_MAX_PATH];
 573|  time_t  dummy_time;
 574|  bool  b;
 575|
 576|  StrX_getExeFullPath( path, "svgcats.ini", sizeof(path) );
 577|
 578|  if ( ! FileX_isExist( path ) )  return;
 579|
 580|  IniFile_Read_init( &f, path, f_buf, sizeof(f_buf) );
 581|
 582|  IniFile_Read_setSection( &f, "main" );
 583|  IniFile_Read_checkTypeInfo( &f, "SVGCats", 100, 200 );
 584|
 585|  IniFile_Read_setSection( &f, "view" );
 586|  IniFile_Read_getVar( &f, "PropBox", "b", &frame->m_PropBarDisp );
 587|  {
 588|    POINT  pt;
 589|
 590|    IniFile_Read_getPlusVar( &f, "PropBoxX", "i", &pt.x, -200 );
 591|    IniFile_Read_getPlusVar( &f, "PropBoxY", "i", &pt.y, 80 );
 592|
 593|    //frame->GetWindowRect( &rc );  // ここでは起動前に通ることがあるのでできない
 594|    //pt.x += rc.right;  pt.y += rc.top;
 595|
 596|    frame->m_PropBar.SetFloatPos( pt.x, pt.y );
 597|  }
 598|  IniFile_Read_getPlusVar( &f, "PropBoxIsFloat", "b", &b, true );
 599|  frame->m_PropBar.SetDocking( !b );
 600|  IniFile_Read_getPlusVar( &f, "PropBoxStyle", "x", &frame->m_PropBarStyle, 0 );
 601|  IniFile_Read_getVar( &f, "WindowColor", "b", &m_bBackTransparent );
 602|  IniFile_Read_getPlusVar( &f, "CanvasWidth", "i", &m_file.m_Canvas.m_Width, m_file.m_Canvas.m_DefWidth );
 603|  IniFile_Read_getPlusVar( &f, "CanvasHeight", "i", &m_file.m_Canvas.m_Height, m_file.m_Canvas.m_DefHeight );
 604|  IniFile_Read_getVar( &f, "ImgFolderPath", "S", m_ImgFolderPath );
 605|  IniFile_Read_getVar( &f, "LowerPath", "b", &m_bLowerPath );
 606|  IniFile_Read_getPlusVar( &f, "GridOn", "b", &m_file.m_Canvas.m_bGridOn, false );
 607|  IniFile_Read_getPlusVar( &f, "GridDisp", "i", &m_file.m_Canvas.m_GridDrawType, Canvas_NoGrid );
 608|  IniFile_Read_getPlusVar( &f, "PrevComTime", "t", &dummy_time, 0 );
 609|  IniFile_Read_getPlusVar( &f, "KeyNumber", "s", m_KeyNumber, "" );
 610|  IniFile_Read_getPlusVar( &f, "BackupInterval", "i", &m_BackupInterval, 1 );
 611|  IniFile_Read_getPlusVar( &f, "SingleClick", "b", &m_bSingleClick, false );
 612|  IniFile_Read_getPlusVar( &f, "CtrlRet", "b", &m_bCtrlRet, true );
 613|  IniFile_Read_getPlusVar( &f, "SplitX", "i", &m_SplitX, 120 );
 614|  IniFile_Read_getPlusVar( &f, "DefaultImageType", "i", &m_DefaultImageType, 1 );
 615|  IniFile_Read_getPlusVar( &f, "NoInkForDebug", "b", &m_bNoInkForDebug, false );
 616|  IniFile_Read_finish( &f );
 617|}
 618|
 619| 
 620|/***********************************************************************
 621|  8. <<< [CSVGCatApp::SaveSVGCatsIni] SVGCats 設定ファイルを保存する >>> 
 622|【補足】
 623|・CMainFrame::m_PropBar.SyncXY() してから呼び出してください。
 624|************************************************************************/
 625|void  CSVGCatApp::SaveSVGCatsIni( bool bReloadKeyNumber )
 626|{
 627|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
 628|  IniFile_Write  f;
 629|  char  path[_MAX_PATH];
 630|  POINT  pt;
 631|  bool  PropBox_bVisible = frame->m_PropBar.m_bVisible;
 632|  bool  PropBoxIsFloat = ! frame->m_PropBar.m_bDocking;
 633|  DWORD PropBoxStyle = frame->m_PropBar.GetBarStyle();
 634|
 635|  if ( bReloadKeyNumber )  ReloadKeyNumber();
 636|
 637|  pt.x = frame->m_PropBar.GetFloatStepX();
 638|  pt.y = frame->m_PropBar.GetFloatStepY();
 639|
 640|  StrX_getExeFullPath( path, "svgcats.ini", sizeof(path) );
 641|
 642|  IniFile_Write_init( &f, path );
 643|
 644|  IniFile_Write_putSection( &f, "main" );
 645|  IniFile_Write_putTypeInfo( &f, "SVGCats", 200 );
 646|
 647|  IniFile_Write_putSection( &f, "view" );
 648|  IniFile_Write_putVar( &f, "PropBox", "b", PropBox_bVisible );
 649|
 650|  IniFile_Write_putVar( &f, "PropBoxX", "i", pt.x );
 651|  IniFile_Write_putVar( &f, "PropBoxY", "i", pt.y );
 652|
 653|  IniFile_Write_putVar( &f, "PropBoxIsFloat", "b", PropBoxIsFloat );
 654|  IniFile_Write_putVar( &f, "PropBoxStyle", "x", PropBoxStyle );
 655|
 656|  IniFile_Write_putVar( &f, "WindowColor", "b", m_bBackTransparent );
 657|  IniFile_Write_putVar( &f, "CanvasWidth", "i", m_file.m_Canvas.m_Width );
 658|  IniFile_Write_putVar( &f, "CanvasHeight", "i", m_file.m_Canvas.m_Height );
 659|
 660|  StrX_cpyAbsPath( path, "svgcats.exe", sizeof(path), m_ImgFolderPath );
 661|  if ( stricmp( path, StrX_argv0 ) == 0 )
 662|    IniFile_Write_putVar( &f, "ImgFolderPath", "s", "" );
 663|  else
 664|    IniFile_Write_putVar( &f, "ImgFolderPath", "s", m_ImgFolderPath );
 665|
 666|  IniFile_Write_putVar( &f, "LowerPath", "b", m_bLowerPath );
 667|  IniFile_Write_putVar( &f, "GridOn", "b", m_file.m_Canvas.m_bGridOn );
 668|  IniFile_Write_putVar( &f, "GridDisp", "i", m_file.m_Canvas.m_GridDrawType );
 669|  IniFile_Write_putVar( &f, "KeyNumber", "s", &m_KeyNumber );
 670|  IniFile_Write_putVar( &f, "BackupInterval", "i", m_BackupInterval );
 671|  IniFile_Write_putVar( &f, "SingleClick", "b", m_bSingleClick );
 672|  IniFile_Write_putVar( &f, "CtrlRet", "b", m_bCtrlRet );
 673|  IniFile_Write_putVar( &f, "SplitX", "i", m_SplitX );
 674|  IniFile_Write_putVar( &f, "DefaultImageType", "i", m_DefaultImageType );
 675|  if ( m_bNoInkForDebug )
 676|    IniFile_Write_putVar( &f, "NoInkForDebug", "b", m_bNoInkForDebug );
 677|
 678|  IniFile_Write_finish( &f );
 679|}
 680|
 681|
 682| 
 683|/***********************************************************************
 684|  9. <<< [CSVGCatApp::ReloadKeyNumber] キーナンバーだけ再読み込みする >>> 
 685|************************************************************************/
 686|void  CSVGCatApp::ReloadKeyNumber()
 687|{
 688|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
 689|  IniFile_Read  f;
 690|  char  f_buf[256];
 691|  char  path[_MAX_PATH];
 692|  char  attr_name[256];
 693|  char  value[256];
 694|
 695|  StrX_getExeFullPath( path, "svgcats.ini", sizeof(path) );
 696|
 697|  if ( ! FileX_isExist( path ) )  return;
 698|
 699|  IniFile_Read_init( &f, path, f_buf, sizeof(f_buf) );
 700|
 701|  IniFile_Read_setSection( &f, "main" );
 702|  IniFile_Read_checkTypeInfo( &f, "SVGCats", 100, 200 );
 703|
 704|  IniFile_Read_setSection( &f, "view" );
 705|
 706|  strcpy( m_KeyNumber, "" );
 707|  for (;;) {
 708|    if ( IniFile_Read_getNextVar( &f, attr_name, "s", value ) == -1 )  break;
 709|    if ( strcmp( attr_name, "KeyNumber" ) == 0 )
 710|      { strcpy( m_KeyNumber, value );  break; }
 711|  }
 712|  IniFile_Read_finish( &f );
 713|}
 714|
 715| 
 716|/***********************************************************************
 717|  10. <<< [CSVGCatApp::MeltKeyNumber] キーナンバーを解読する >>> 
 718|************************************************************************/
 719|time_t  CSVGCatApp::MeltKeyNumber( const char* keyNumber )
 720|{
 721|  char  s[32];
 722|  int   len;
 723|
 724|  strncpy( s, keyNumber, 31 );  s[31] = '\0';
 725|  StrX_trim( s );
 726|  len = strlen( s );
 727|  if ( len > 3 ) {
 728|    int  day;
 729|    int  n;
 730|    time_t  t;
 731|    struct tm*  t2;
 732|
 733|    day = ( 96 - atoi( s+len-2 ) ) / 2;
 734|    s[len-2] = '\0';
 735|    n = atoi( s ) / day;
 736|    t = (time_t)( n / 32 * (24*60*60) );
 737|    t2 = gmtime( &t );  /*localtime ( &t );*/
 738|    t2->tm_isdst = 1;
 739|    t = mktime( t2 );
 740|    if ( t2 != NULL && t2->tm_mday == day && n % 32 == day ) {
 741|      if ( n / 32 == 12237 )  time( &t );
 742|      return  t;
 743|    }
 744|  }
 745|  return  (time_t)0;
 746|}
 747|
 748| 
 749|/***********************************************************************
 750|  11. <<< [CSVGCatApp::Load] SVG ファイルを開く >>> 
 751|【引数】
 752|  ・char*  path;   SVG ファイルパス
 753|【補足】
 754|・枠付きテキスト、矢印は、グループ化されています。</g>で構成する部品から
 755|  枠付きテキストテキストなどに変換します。
 756|************************************************************************/
 757|#if  ERRORS_DEBUG_FALSE
 758|#define  SVGCATS_LOAD_TRACE
 759|#endif
 760|
 761|int  atoi2( const char* s, int def ) {
 762|  if ( s == NULL )  return  def;
 763|  else  return  atoi( s );
 764|}
 765|
 766|#ifdef  SVGCATS_LOAD_TRACE
 767|  int  CSVGCatApp_LoadCount;
 768|#endif
 769|
 770|void  CSVGCatApp::Load( const char* path )
 771|{
 772|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
 773|
 774|  ASSERT( m_file.m_bPagesExist );
 775|
 776|  m_UndoBuf->ClearAll();
 777|  delete  m_UndoBuf;
 778|
 779|  Load_imp( (long)frame->m_hWnd, &m_file, path );
 780|
 781|
 782|  m_bBackTransparent = false;
 783|  m_UndoBuf = new Undo_Buf();
 784|  StrX_cpyFolder( m_SaveFolderPath, path );
 785|}
 786|
 787|
 788|void  CSVGCatApp::Load_imp( long id_hWnd, SVGCat_File* file, const char* path )
 789|{
 790|  COLORREF   lineColor, fillColor;
 791|  FileX_UniRead  ufile;
 792|  bool       bUfile = false;
 793|  char*      style;
 794|  char*      transform;
 795|  char*      id;
 796|  char*      p;
 797|  bool       bInPageTag;
 798|
 799|  XMLPars  xmlp;
 800|  bool     bXmlp = false;
 801|  char     xmlp_buf[3072];
 802|  ListX    group;  /* ListX_ElemX:CadPrim* */
 803|  ListX*   pGroup;  /* 現在所属しているグループ、NULL=無所属 */
 804|  ListX    groupStack;  /* 親の段の最後の要素の集合、ListX_ElemX:ListX_ElemX*:CadPrim* */
 805|  ListX_ElemX*  elem;
 806|  Text_Box*    text = NULL;  /* タグ内のパラメータとタグ間テキストとの伝達用 */
 807|  bool    bInInk = false;
 808|  int     nInkInPage = 0;
 809|  int     ink_start = 0;
 810|  InkRasterOperation  ink_raster;
 811|  char    href[_MAX_PATH];
 812|  char    label[_MAX_PATH];
 813|  char    target[_MAX_PATH];
 814|  char*   svgzMeltedPath = NULL;
 815|
 816|  int     iMaxPage = 1;   /* ページ構成を行った最大のページ番号 */
 817|  int     iPrevPage = 0;  /* 同じ深さの前のページ番号 */
 818|  int     iTextLine;
 819|
 820|  if ( ! FileX_isExist( path ) )
 821|    error2_0( FileX_Err_CannotReadOpen, "" );
 822|
 823|  c_try {
 824|
 825|    Finish_imp( file );
 826|    NewEmpty_imp( file, id_hWnd, file->m_bShowing );
 827|    if ( file->m_bShowing )
 828|      ((CMainFrame*)m_pMainWnd)->m_wndView->NewInkOverlay();
 829|
 830|    lineColor = GetSysColor( COLOR_WINDOWTEXT );
 831|    fillColor = GetSysColor( COLOR_BTNFACE );
 832|
 833|    #ifdef  SVGCATS_LOAD_TRACE
 834|       Errors_startPool();
 835|       CSVGCatApp_LoadCount = 0;
 836|       IFC(0) BK
 837|    #endif
 838|
 839|    ListX_init( &group );
 840|    pGroup = NULL;
 841|    ListX_init( &groupStack );
 842|    bInPageTag = false;
 843|
 844|    if ( stricmp( StrX_refExt( path ), "svgz" ) == 0 ) {
 845|      svgzMeltedPath = CSVGCatApp_meltSvgz( path );
 846|      p = FileX_UniRead_init( &ufile, svgzMeltedPath );  bUfile = true;
 847|    }
 848|    else
 849|      { p = FileX_UniRead_init( &ufile, path );  bUfile = true; }
 850|
 851|    href[0] = '\0';
 852|    label[0] = '\0';
 853|    target[0] = '\0';
 854|    XMLPars_init( &xmlp, p, xmlp_buf, sizeof(xmlp_buf) );  bXmlp = true;
 855|    while ( XMLPars_parse( &xmlp ) ) {
 856|
 857|      #ifdef  SVGCATS_LOAD_TRACE
 858|       CSVGCatApp_LoadCount++;
 859|       Errors_printf("[%d:0x%X] ==========================================",CSVGCatApp_LoadCount,
 860|         xmlp.htmlPars.parsedPos.pos );
 861|       Errors_printf("m_prims -------------" );
 862|       for ( ListX_forEach( &file->m_prims, &elem, ListX_ElemX ) )
 863|         Errors_printf( "%d", ((CadPrim*)elem->p)->GetID() );
 864|       Errors_printf("group ----------------" );
 865|       for ( ListX_forEach( &group, &elem, ListX_ElemX ) )
 866|         Errors_printf( "%d", ((CadPrim*)elem->p)->GetID() );
 867|       Errors_printf("groupStack ---------------" );
 868|       for ( ListX_forEach( &groupStack, &elem, ListX_ElemX ) ) {
 869|         if ( elem->p == NULL )  Errors_printf( "NULL" );
 870|         else  Errors_printf( "%d", ((CadPrim*)((ListX_ElemX*)elem->p)->p)->GetID() );
 871|       }
 872|       Errors_printf("parse -----------------" );
 873|
 874|       IFC( xmlp.htmlPars.parsedPos.pos >= 0x58 )
 875|         BK
 876|       IFC( CSVGCatApp_LoadCount >= 562 )
 877|         BK
 878|      #endif
 879|
 880|
 881|      switch ( XMLPars_getTokenType( &xmlp ) ) {
 882|
 883|       case XMLPars_StartAndEndTag:   /*================================================== */
 884|        p = XMLPars_getTagName( &xmlp );
 885|
 886|        if ( stricmp( p, "page" ) == 0 ) {  /* pagesタグ内, 単独タグ */
 887|          SVGCat_Page*  prevPage = ListX_get( &file->m_pages, iPrevPage - file->m_StartPageNum, SVGCat_Page );
 888|          SVGCat_Page*  page;
 889|
 890|          if ( iPrevPage == 0 )  prevPage = NULL;
 891|
 892|          iMaxPage = atoi( XMLPars_getValue( &xmlp, "num" ) );
 893|          page = ListX_get( &file->m_pages, iMaxPage - file->m_StartPageNum, SVGCat_Page );
 894|          page->prev = prevPage;
 895|          if ( prevPage != NULL ) {
 896|            prevPage->next = page;
 897|            page->parent = prevPage->parent;
 898|          }
 899|          page->next = NULL;  /* デフォルト(次のページ)とは限らないため */
 900|          StrX_cpy( page->title, XMLPars_getValue( &xmlp, "title" ), sizeof(page->title) );
 901|          if ( page->title[0] == '\0' )  strcpy( page->title, "Page" );
 902|
 903|          iPrevPage = iMaxPage;
 904|        }
 905|        else if ( stricmp( p, "line" ) == 0 && ! bInInk ) {
 906|          int   x1, y1, x2, y2, width, dash;
 907|          char*  p;
 908|          char   v[256];
 909|
 910|          #ifdef  SVGCATS_LOAD_TRACE
 911|           Errors_printf( "line id=%d", m_NextID );
 912|          #endif
 913|
 914|          if ( XMLPars_getValue( &xmlp, "x1" ) == NULL )  formatError();
 915|          x1 = atoi( XMLPars_getValue( &xmlp, "x1" ) );
 916|          y1 = atoi( XMLPars_getValue( &xmlp, "y1" ) );
 917|          x2 = atoi( XMLPars_getValue( &xmlp, "x2" ) );
 918|          y2 = atoi( XMLPars_getValue( &xmlp, "y2" ) );
 919|          width = 1;
 920|          style = XMLPars_getValue( &xmlp, "style" );
 921|          if ( style != NULL ) {
 922|            StrX_getCSSValueOfColor( style, "stroke", &lineColor );
 923|            StrX_getCSSValueOfInt( style, "stroke-width", &width );
 924|          }
 925|
 926|          Line_Ex*  l = new Line_Ex;
 927|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
 928|          elem->p = l;
 929|          if ( pGroup != NULL ) {
 930|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
 931|            elem->p = l;
 932|          }
 933|
 934|          l->m_id = GetNewPrimID();
 935|          Line_init( &l->m_Line, x1, y1, x2, y2 );
 936|          l->m_Width = width;
 937|          l->m_Color = lineColor;
 938|          dash = -50;  StrX_getCSSValueOfInt( style, "stroke-dasharray", &dash );
 939|          l->m_bDash = ( dash != -50 );
 940|
 941|          p = XMLPars_getValue( &xmlp, "p1" );
 942|          if ( p != NULL ) {
 943|            if ( StrX_getCSV( p, 1, v, sizeof(v) ) != NULL )  l->m_Line.x1 = atoi( v );
 944|            if ( StrX_getCSV( p, 2, v, sizeof(v) ) != NULL )  l->m_Line.y1 = atoi( v );
 945|            if ( StrX_getCSV( p, 3, v, sizeof(v) ) != NULL )  l->m_Arrow1 = atoi( v );
 946|            if ( StrX_getCSV( p, 4, v, sizeof(v) ) != NULL )  l->m_Controler_id[0] = -1;
 947|            l->m_ArrowsInReading = (Line*)1;
 948|          }
 949|          p = XMLPars_getValue( &xmlp, "p2" );
 950|          if ( p != NULL ) {
 951|            if ( StrX_getCSV( p, 1, v, sizeof(v) ) != NULL )  l->m_Line.x2 = atoi( v );
 952|            if ( StrX_getCSV( p, 2, v, sizeof(v) ) != NULL )  l->m_Line.y2 = atoi( v );
 953|            if ( StrX_getCSV( p, 3, v, sizeof(v) ) != NULL )  l->m_Arrow2 = atoi( v );
 954|            if ( StrX_getCSV( p, 4, v, sizeof(v) ) != NULL )  l->m_Controler_id[1] = -1;
 955|            l->m_ArrowsInReading = (Line*)1;
 956|          }
 957|        }
 958|        else if ( stricmp( p, "rect" ) == 0 ) {
 959|          int  left, top, right, bottom, width, rx = 0, ry = 0;
 960|          double  opacity;
 961|
 962|          #ifdef  SVGCATS_LOAD_TRACE
 963|           Errors_printf( "rect id=%d", m_NextID );
 964|          #endif
 965|
 966|          id = XMLPars_getValue( &xmlp, "id" );
 967|          if ( XMLPars_getValue( &xmlp, "x" ) == NULL )  formatError();
 968|          left = atoi( XMLPars_getValue( &xmlp, "x" ) );
 969|          top = atoi( XMLPars_getValue( &xmlp, "y" ) );
 970|          right = left + atoi( XMLPars_getValue( &xmlp, "width" ) ) - 1;
 971|          bottom = top + atoi( XMLPars_getValue( &xmlp, "height" ) ) - 1;
 972|          if ( XMLPars_getValue( &xmlp, "rx" ) != NULL )
 973|            rx = atoi( XMLPars_getValue( &xmlp, "rx" ) );
 974|          if ( XMLPars_getValue( &xmlp, "ry" ) != NULL )
 975|            ry = atoi( XMLPars_getValue( &xmlp, "ry" ) );
 976|          style = XMLPars_getValue( &xmlp, "style" );
 977|          transform = XMLPars_getValue( &xmlp, "transform" );
 978|          width = 1;  opacity = 1.0;
 979|          if ( style != NULL ) {
 980|            StrX_getCSSValueOfColor( style, "fill", &fillColor );
 981|            StrX_getCSSValueOfColor( style, "stroke", &lineColor );
 982|            StrX_getCSSValueOfInt( style, "stroke-width", &width );
 983|            StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
 984|          }
 985|          if ( transform != NULL )
 986|            transform = strchr( transform, '(' );
 987|
 988|          Rect_Ex*  r = new Rect_Ex;
 989|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
 990|          elem->p = r;
 991|          if ( pGroup != NULL ) {
 992|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
 993|            elem->p = r;
 994|          }
 995|
 996|          r->m_id = GetNewPrimID();
 997|          r->m_IdLabel = ( id == NULL ? label : id );
 998|          r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
 999|          r->m_Target = target;
1000|          Rect_init_by2XY( &r->m_Rect, left, top, right, bottom );
1001|          r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
1002|          if ( rx > 0 )
1003|            r->m_ShapeType = Rect_RoundRectShape;
1004|          else
1005|            r->m_ShapeType = Rect_RectShape;
1006|          r->m_BorderWidth = width;
1007|          r->m_BorderColor = lineColor;
1008|          r->m_FillColor = fillColor;
1009|          r->m_NTrans = (int)(opacity * 100);
1010|        }
1011|        else if ( stricmp( p, "circle" ) == 0 ) {
1012|          int  x, y, rr, width;
1013|          double  opacity;
1014|
1015|          #ifdef  SVGCATS_LOAD_TRACE
1016|           Errors_printf( "circle(rect) id=%d", m_NextID );
1017|          #endif
1018|
1019|          id = XMLPars_getValue( &xmlp, "id" );
1020|          if ( XMLPars_getValue( &xmlp, "cx" ) == NULL )  formatError();
1021|          x = atoi( XMLPars_getValue( &xmlp, "cx" ) );
1022|          y = atoi( XMLPars_getValue( &xmlp, "cy" ) );
1023|          rr = atoi( XMLPars_getValue( &xmlp, "r" ) ) ;
1024|          style = XMLPars_getValue( &xmlp, "style" );
1025|          transform = XMLPars_getValue( &xmlp, "transform" );
1026|          width = 1;  opacity = 1.0;
1027|          if ( style != NULL ) {
1028|            StrX_getCSSValueOfColor( style, "fill", &fillColor );
1029|            StrX_getCSSValueOfColor( style, "stroke", &lineColor );
1030|            StrX_getCSSValueOfInt( style, "stroke-width", &width );
1031|            StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
1032|          }
1033|          if ( transform != NULL )
1034|            transform = strchr( transform, '(' );
1035|
1036|          Rect_Ex*  r = new Rect_Ex;
1037|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1038|          elem->p = r;
1039|          if ( pGroup != NULL ) {
1040|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
1041|            elem->p = r;
1042|          }
1043|
1044|          r->m_id = GetNewPrimID();
1045|          r->m_IdLabel = ( id == NULL ? label : id );
1046|          r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
1047|          r->m_Target = target;
1048|          Rect_init_by2XY( &r->m_Rect, x - rr, y - rr, x + rr, y + rr );
1049|          r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
1050|          r->m_ShapeType = Rect_CircleShape;
1051|          r->m_BorderWidth = width;
1052|          r->m_BorderColor = lineColor;
1053|          r->m_FillColor = fillColor;
1054|          r->m_NTrans = (int)(opacity * 100);
1055|        }
1056|        else if ( stricmp( p, "ellipse" ) == 0 ) {
1057|          int  cx, cy, rx, ry, width;
1058|          double  opacity;
1059|
1060|          #ifdef  SVGCATS_LOAD_TRACE
1061|           Errors_printf( "ellipse(rect) id=%d", m_NextID );
1062|          #endif
1063|
1064|          id = XMLPars_getValue( &xmlp, "id" );
1065|          if ( XMLPars_getValue( &xmlp, "cx" ) == NULL )  formatError();
1066|          cx = atoi( XMLPars_getValue( &xmlp, "cx" ) );
1067|          cy = atoi( XMLPars_getValue( &xmlp, "cy" ) );
1068|          rx = atoi( XMLPars_getValue( &xmlp, "rx" ) ) ;
1069|          ry = atoi( XMLPars_getValue( &xmlp, "ry" ) ) ;
1070|          style = XMLPars_getValue( &xmlp, "style" );
1071|          transform = XMLPars_getValue( &xmlp, "transform" );
1072|          width = 1;  opacity = 1.0;
1073|          if ( style != NULL ) {
1074|            StrX_getCSSValueOfColor( style, "fill", &fillColor );
1075|            StrX_getCSSValueOfColor( style, "stroke", &lineColor );
1076|            StrX_getCSSValueOfInt( style, "stroke-width", &width );
1077|            StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
1078|          }
1079|          if ( transform != NULL )
1080|            transform = strchr( transform, '(' );
1081|
1082|          Rect_Ex*  r = new Rect_Ex;
1083|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1084|          elem->p = r;
1085|          if ( pGroup != NULL ) {
1086|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
1087|            elem->p = r;
1088|          }
1089|
1090|          r->m_id = GetNewPrimID();
1091|          r->m_IdLabel = ( id == NULL ? label : id );
1092|          r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
1093|          r->m_Target = target;
1094|          Rect_init_by2XY( &r->m_Rect, cx - rx, cy - ry, cx + rx, cy + ry );
1095|          r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
1096|          r->m_ShapeType = Rect_CircleShape;
1097|          r->m_BorderWidth = width;
1098|          r->m_BorderColor = lineColor;
1099|          r->m_FillColor = fillColor;
1100|          r->m_NTrans = (int)(opacity * 100);
1101|        }
1102|        else if ( stricmp( p, "image" ) == 0 ) {
1103|          int  x, y, width, height;
1104|          char  imgPath[_MAX_PATH];
1105|          char  imgWorkPath[_MAX_PATH];
1106|          char  src[_MAX_PATH];
1107|          long  img_base64pos = -1;
1108|          bool  bEmbedImg = true;
1109|
1110|          #ifdef  SVGCATS_LOAD_TRACE
1111|           Errors_printf( "image(rect) id=%d", m_NextID );
1112|          #endif
1113|
1114|          id = XMLPars_getValue( &xmlp, "id" );
1115|          if ( XMLPars_getValue( &xmlp, "x" ) == NULL )  formatError();
1116|          x = atoi( XMLPars_getValue( &xmlp, "x" ) );
1117|          y = atoi( XMLPars_getValue( &xmlp, "y" ) );
1118|          width = atoi( XMLPars_getValue( &xmlp, "width" ) ) ;
1119|          height = atoi( XMLPars_getValue( &xmlp, "height" ) ) ;
1120|          transform = XMLPars_getValue( &xmlp, "transform" );
1121|          c_try {
1122|            StrX_cpy( src, XMLPars_getValue( &xmlp, "xlink:href" ), sizeof(src) );
1123|            if ( strncmp( src, "data:;base64,", 13 ) == 0 ) {
1124|              BLex3_Pos  pos;
1125|              long  pos2;
1126|              FILE*  f = xmlp.engU.inherit_BLex3_Engine.f;
1127|              char*  p;
1128|
1129|              /* img_base64pos を得る */
1130|              pos2 = ftell( f );
1131|              XMLPars_getPos( &xmlp, &pos );
1132|              fseek( f, pos.pos, SEEK_SET );
1133|              while ( ! feof( f ) ) {
1134|                fgets( src, sizeof(src), f );
1135|                p = strstr( src, "xlink:href=" );
1136|                if ( p != NULL ) {
1137|                  p += 25;
1138|                  while ( *p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')  p++;
1139|                  img_base64pos = pos.pos + (p - src);
1140|                  break;
1141|                }
1142|                pos.pos = ftell( f );
1143|              }
1144|              fseek( f, pos2, SEEK_SET );
1145|
1146|              StrX_cpy( src, XMLPars_getValue( &xmlp, "src" ), sizeof(src) );
1147|            }
1148|            else  bEmbedImg = false;
1149|
1150|            StrX_cpyAbsPath2( imgPath, src, sizeof(imgPath), path );
1151|            if ( FileX_isExist( imgPath ) )  StrX_toLongPath( imgPath, imgPath );
1152|          }
1153|          c_catch ( Errors_Msg*, msg ) {
1154|            if ( msg->code == StrX_Err_NoMoreParentDir )
1155|              strcpy( imgPath, src );  /* 上記 StrX_cpyAbsPath2 より */
1156|            else
1157|              c_throw_again();
1158|          } c_end_catch;
1159|          if ( transform != NULL )
1160|            transform = strchr( transform, '(' );
1161|
1162|          /* 埋め込み画像ファイルを復活する */
1163|          strcpy( imgWorkPath, GetImgWorkFilePath( id_hWnd ) );
1164|          if ( ( strcmp( imgPath, Rect_Ex_EmbedImg ) == 0 || ! FileX_isExist( imgPath ) ) &&
1165|               img_base64pos != -1 ) {
1166|            FileX_scanBase64( xmlp.engU.inherit_BLex3_Engine.f, img_base64pos, imgWorkPath );
1167|            FileX_repairExt( imgWorkPath );
1168|          }
1169|          else {
1170|            StrX_chgExt( imgWorkPath, StrX_refExt( imgPath ) );
1171|          }
1172|
1173|          /* 図形を生成する */
1174|          Rect_Ex*  r = new Rect_Ex;
1175|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1176|          elem->p = r;
1177|          if ( pGroup != NULL ) {
1178|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
1179|            elem->p = r;
1180|          }
1181|
1182|          r->m_id = GetNewPrimID();
1183|          r->m_IdLabel = ( id == NULL ? label : id );
1184|          r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
1185|          r->m_Target = target;
1186|          Rect_init( &r->m_Rect, x, y, width, height );
1187|          r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
1188|          r->m_ShapeType = Rect_ImageShape;
1189|          r->m_ImgPath = imgPath;
1190|          r->m_ImgWorkPath = imgWorkPath;
1191|          strcpy( r->m_ddb.path, imgWorkPath );  StrX_chgExt( r->m_ddb.path, "ddb" );
1192|          r->m_bEmbedImg = bEmbedImg;
1193|          r->m_BorderWidth = 1;
1194|          r->m_BorderColor = lineColor;
1195|          r->m_FillColor = fillColor;
1196|          r->m_bNeedReadImgProp = false;
1197|        }
1198|        else if ( stricmp( p, "polygon" ) == 0 ) {
1199|          int  n, dx, dy, width;
1200|          int  x[4], y[4];
1201|          double  opacity;
1202|
1203|          #ifdef  SVGCATS_LOAD_TRACE
1204|           Errors_printf( "polygon(rect) id=%d", m_NextID );
1205|          #endif
1206|
1207|          id = XMLPars_getValue( &xmlp, "id" );
1208|          p = XMLPars_getValue( &xmlp, "points" );
1209|          n = StrX_getSVGPoints( p, x, y, 4 );
1210|          if ( n == 4 ) {
1211|            dx = (x[1] + x[3])/2 - x[0];
1212|            dy = (y[0] + y[2])/2 - y[1];
1213|          }
1214|          if ( n == 4 && x[0] == x[2] && y[1] == y[3] &&
1215|               -1 <= dx && dx <= 1 && -1 <= dy && dy <= 1 ) {  /* Diamond */
1216|            style = XMLPars_getValue( &xmlp, "style" );
1217|            transform = XMLPars_getValue( &xmlp, "transform" );
1218|            width = 1;  opacity = 1.0;
1219|            if ( style != NULL ) {
1220|              StrX_getCSSValueOfColor( style, "fill", &fillColor );
1221|              StrX_getCSSValueOfColor( style, "stroke", &lineColor );
1222|              StrX_getCSSValueOfInt( style, "stroke-width", &width );
1223|              StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
1224|            }
1225|            if ( transform != NULL )
1226|              transform = strchr( transform, '(' );
1227|
1228|            Rect_Ex*  r = new Rect_Ex;
1229|            elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1230|            elem->p = r;
1231|            if ( pGroup != NULL ) {
1232|              elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
1233|              elem->p = r;
1234|            }
1235|
1236|            r->m_id = GetNewPrimID();
1237|            r->m_IdLabel = ( id == NULL ? label : id );
1238|            r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
1239|            r->m_Target = target;
1240|            Rect_init_by2XY( &r->m_Rect, x[3], y[0], x[1]-1, y[2]-1 );
1241|            r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
1242|            r->m_ShapeType = Rect_DiamondShape;
1243|            r->m_BorderWidth = width;
1244|            r->m_BorderColor = lineColor;
1245|            r->m_FillColor = fillColor;
1246|            r->m_NTrans = (int)(opacity * 100);
1247|          }
1248|          else if ( n == 4 && y[0] == y[1] && y[2] == y[3] &&
1249|               x[1] - x[0] == x[2] - x[3] &&
1250|               ( 2 * ( x[0] - x[3] + 1 ) == y[3] - y[0] ||
1251|                 2 * ( x[0] - x[3] ) == y[3] - y[0] ||
1252|                 2 * ( x[0] - x[3] + 1 ) + 1 == y[3] - y[0] ||
1253|                 2 * ( x[0] - x[3] ) + 1 == y[3] - y[0] ) ) {  /* Parallelogram */
1254|            style = XMLPars_getValue( &xmlp, "style" );
1255|            transform = XMLPars_getValue( &xmlp, "transform" );
1256|            width = 1;  opacity = 1.0;
1257|            if ( style != NULL ) {
1258|              StrX_getCSSValueOfColor( style, "fill", &fillColor );
1259|              StrX_getCSSValueOfColor( style, "stroke", &lineColor );
1260|              StrX_getCSSValueOfInt( style, "stroke-width", &width );
1261|              StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
1262|            }
1263|            if ( transform != NULL )
1264|              transform = strchr( transform, '(' );
1265|
1266|            Rect_Ex*  r = new Rect_Ex;
1267|            elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1268|            elem->p = r;
1269|            if ( pGroup != NULL ) {
1270|              elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
1271|              elem->p = r;
1272|            }
1273|
1274|            r->m_id = GetNewPrimID();
1275|            r->m_IdLabel = ( id == NULL ? label : id );
1276|            r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
1277|            r->m_Target = target;
1278|            Rect_init_by2XY( &r->m_Rect, (x[0]+x[3])/2, y[0], (x[1]+x[2])/2-1, y[2]-1 );
1279|            r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
1280|            r->m_ShapeType = Rect_Parallelogram;
1281|            r->m_BorderWidth = width;
1282|            r->m_BorderColor = lineColor;
1283|            r->m_FillColor = fillColor;
1284|            r->m_NTrans = (int)(opacity * 100);
1285|          }
1286|          else {  /* Polygon */
1287|            style = XMLPars_getValue( &xmlp, "style" );
1288|            transform = XMLPars_getValue( &xmlp, "transform" );
1289|            width = 1;  opacity = 1.0;
1290|            if ( style != NULL ) {
1291|              StrX_getCSSValueOfColor( style, "fill", &fillColor );
1292|              StrX_getCSSValueOfColor( style, "stroke", &lineColor );
1293|              StrX_getCSSValueOfInt( style, "stroke-width", &width );
1294|              StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
1295|            }
1296|            if ( transform != NULL )
1297|              transform = strchr( transform, '(' );
1298|
1299|            Polygon_Ex*  p = new Polygon_Ex;
1300|            elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1301|            elem->p = p;
1302|            if ( pGroup != NULL ) {
1303|              elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
1304|              elem->p = p;
1305|            }
1306|
1307|            p->m_id = GetNewPrimID();
1308|            p->m_IdLabel = ( id == NULL ? label : id );
1309|            p->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
1310|            p->m_Target = target;
1311|            p->m_NPoint = n;
1312|            p->m_Points = (POINT*)malloc( n * sizeof(POINT) );
1313|            while ( --n >= 0 ) {
1314|              p->m_Points[n].x = x[n];  p->m_Points[n].y = y[n];
1315|            }
1316|            p->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
1317|            p->m_BorderWidth = width;
1318|            p->m_BorderColor = lineColor;
1319|            p->m_FillColor = fillColor;
1320|            p->m_NTrans = (int)(opacity * 100);
1321|          }
1322|        }
1323|        else if ( stricmp( p, "path" ) == 0 ) { /* Matome */
1324|          int  n, x1, y1, x2, y2, x3, y3, width;
1325|          char*  subtype;
1326|          char*  d;
1327|          Matome*  m;
1328|
1329|          #ifdef  SVGCATS_LOAD_TRACE
1330|           Errors_printf( "path" );
1331|          #endif
1332|
1333|          subtype = XMLPars_getValue( &xmlp, "subtype" );
1334|          if ( strcmp( subtype, "matome" ) == 0 ) {
1335|            d = XMLPars_getValue( &xmlp, "d" );
1336|            style = XMLPars_getValue( &xmlp, "style" );
1337|            width = 1;
1338|            if ( style != NULL ) {
1339|              StrX_getCSSValueOfColor( style, "stroke", &lineColor );
1340|              StrX_getCSSValueOfInt( style, "stroke-width", &width );
1341|            }
1342|
1343|            for ( n = 0; ; n++ ) {
1344|              if ( n == 0 )        x1 = atoi( d+1 );
1345|              else if ( n == 1 )   y1 = atoi( d );
1346|              else if ( n == 16 )  x2 = atoi( d );
1347|              else if ( n == 17 )  y2 = atoi( d );
1348|              else if ( n == 32 )  x3 = atoi( d );
1349|              else if ( n == 33 )  { y3 = atoi( d ); break; }
1350|              d = StrX_strchrs( d, ", " );
1351|              if ( d == NULL )  break;
1352|              do {
1353|                d++;
1354|              } while ( *d == ',' || *d == ' ' );
1355|            }
1356|            if ( n == 33 ) {
1357|              m = new Matome;
1358|
1359|              elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1360|              elem->p = m;
1361|              if ( pGroup != NULL ) {
1362|                elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
1363|                elem->p = m;
1364|              }
1365|
1366|              m->m_id = GetNewPrimID();
1367|              m->m_BorderWidth = width;
1368|              m->m_BorderColor = lineColor;
1369|              if ( x1 == x3 ) {
1370|                m->m_x1 = x2;  m->m_y1 = (y1 < y3) ? y1 : y3;
1371|                m->m_x2 = x3;  m->m_y2 = (y1 < y3) ? y3 : y1;
1372|              }
1373|              else {
1374|                m->m_x1 = (x1 < x3) ? x1 : x3;  m->m_y1 = y2;
1375|                m->m_x2 = (x1 < x3) ? x3 : x1;  m->m_y2 = y3;
1376|              }
1377|            }
1378|          }
1379|        }
1380|        break;
1381|
1382|       case XMLPars_StartTag:   /*================================================== */
1383|        p = XMLPars_getTagName( &xmlp );
1384|        if ( stricmp( p, "svg" ) == 0 ) {
1385|          char*  interval = XMLPars_getValue( &xmlp, "onload" );
1386|          char*  corr;
1387|
1388|          file->m_Canvas.m_Width = atoi2( XMLPars_getValue( &xmlp, "width" ), file->m_Canvas.m_DefWidth );
1389|          file->m_Canvas.m_Height = atoi2( XMLPars_getValue( &xmlp, "height" ), file->m_Canvas.m_DefHeight );
1390|          corr = XMLPars_getValue( &xmlp, "corr-image" );
1391|          if ( corr == NULL )
1392|            file->m_Canvas.m_CorrImagePath[0] = '\0';
1393|          else {
1394|            StrX_cpyAbsPath2( file->m_Canvas.m_CorrImagePath, corr,
1395|               sizeof(file->m_Canvas.m_CorrImagePath), path );
1396|          }
1397|          if ( interval != NULL )
1398|            file->m_Canvas.m_NextPageInterval = atoi( strchr( interval, ',' ) + 1 );
1399|        }
1400|        else if ( stricmp( p, "page" ) == 0 ) {  /* pagesタグの中, 開始タグ */
1401|          int  iPage = atoi( XMLPars_getValue( &xmlp, "num" ) );
1402|          SVGCat_Page*  page = ListX_get( &file->m_pages, iPage - file->m_StartPageNum, SVGCat_Page );
1403|          SVGCat_Page*  prevPage = ListX_get( &file->m_pages, iPrevPage - file->m_StartPageNum, SVGCat_Page );
1404|          SVGCat_Page*  childPage = ListX_Elem_getNextT( page, SVGCat_Page );
1405|
1406|          if ( iPrevPage == 0 )  prevPage = NULL;
1407|
1408|          page->firstChild = childPage;  childPage->parent = page;
1409|          page->prev = prevPage;
1410|          if ( prevPage != NULL ) {
1411|            prevPage->next = page;
1412|            page->parent = prevPage->parent;
1413|          }
1414|          page->next = NULL;  /* デフォルト(次のページ)とは限らないため */
1415|          StrX_cpy( page->title, XMLPars_getValue( &xmlp, "title" ), sizeof(page->title) );
1416|          if ( page->title[0] == '\0' )  strcpy( page->title, "Page" );
1417|          iMaxPage = ListX_getI( &file->m_pages, page );
1418|          iPrevPage = -1;
1419|        }
1420|        else if ( stricmp( p, "a" ) == 0 ) {
1421|          char*  target0;
1422|          char*  href0;
1423|
1424|          c_try {
1425|
1426|            href0 = XMLPars_getValue( &xmlp, "xlink:href" );
1427|            if ( href0 != NULL ) {
1428|              StrX_cpyAbsPath2( href, href0, sizeof(href), path );
1429|              if ( FileX_isExist( href ) )
1430|                StrX_toLongPath( href, href );
1431|            }
1432|          }
1433|          c_catch ( Errors_Msg*, msg ) {
1434|            if ( msg->code == StrX_Err_NoMoreParentDir )
1435|              strcpy( href, XMLPars_getValue( &xmlp, "xlink:href" ) );
1436|            else
1437|              c_throw_again();
1438|          } c_end_catch;
1439|          target0 = XMLPars_getValue( &xmlp, "target" );
1440|          strcpy( target, (target0 == NULL ? "" : target0) );
1441|        }
1442|        else if ( stricmp( p, "g" ) == 0 ) {
1443|          char*  id = XMLPars_getValue( &xmlp, "id" );
1444|          char*  onclick = XMLPars_getValue( &xmlp, "onclick" );
1445|          char*  href0 = XMLPars_getValue( &xmlp, "href" );
1446|          char*  type;
1447|          char*  corr;
1448|
1449|          #ifdef  SVGCATS_LOAD_TRACE
1450|           Errors_printf( "g" );
1451|          #endif
1452|
1453|          label[0] = '\0';
1454|
1455|          if ( id != NULL && strcmp( id, "svgcats-ink" ) == 0 ) {
1456|            bInInk = true;
1457|            nInkInPage++;
1458|            type = XMLPars_getValue( &xmlp, "type" );
1459|            if ( type == NULL )
1460|              ink_raster = ( ListX_isEmpty( &file->m_prims ) ? IRO_MaskPen : IRO_CopyPen );
1461|            else
1462|              ink_raster = ( strcmp( type, "front" ) == 0 ? IRO_CopyPen : IRO_MaskPen );
1463|            ink_start = xmlp.htmlPars.parsedPos.pos;
1464|          }
1465|
1466|          if ( id != NULL && ( ( strncmp( id, "page", 4 ) == 0 && atoi( id+4 ) != 0 ) ||
1467|               strcmp( id, "backpage" ) == 0 ) ) {
1468|            bInPageTag = true;
1469|            nInkInPage = 0;
1470|
1471|            if ( strcmp( id, "backpage" ) == 0 );
1472|            else if ( strcmp( id, "page1" ) != 0 ) {
1473|              NewPage( file, false );
1474|            }
1475|            else if ( ! ListX_isEmpty( &file->m_prims ) ) {
1476|              SVGCat_Page*  page;
1477|
1478|              ChgToBackPage( file );
1479|              SwapPage( file, 0, 1 );
1480|              ChgPage( file, -1 );
1481|              page = ListX_getFirst( &file->m_pages, SVGCat_Page );
1482|              page->next = NULL;
1483|              ListX_Elem_getNextT( page, SVGCat_Page )->prev = NULL;
1484|              ChgPage( file, 1 );
1485|            }
1486|            file->m_Canvas.m_Width = atoi( XMLPars_getValue( &xmlp, "width" ) );
1487|            file->m_Canvas.m_Height = atoi( XMLPars_getValue( &xmlp, "height" ) );
1488|            corr = XMLPars_getValue( &xmlp, "corr-image" );
1489|            if ( corr == NULL )
1490|              file->m_Canvas.m_CorrImagePath[0] = '\0';
1491|            else {
1492|              StrX_cpyAbsPath2( file->m_Canvas.m_CorrImagePath, corr,
1493|                 sizeof(file->m_Canvas.m_CorrImagePath), path );
1494|            }
1495|          }
1496|          else {
1497|            pGroup = &group;
1498|            elem = ListX_addFirstMalloc( &groupStack, ListX_ElemX );
1499|            elem->p = ListX_getLast( &group, ListX_ElemX );
1500|
1501|            if ( id != NULL && strcmp( id, "svgcats-ink" ) != 0 )
1502|              strcpy( label, id );
1503|          }
1504|
1505|          if ( href0 != NULL )
1506|            strcpy( href, href0 );
1507|          else if ( onclick != NULL )
1508|            sprintf( href, "script:%s", onclick );
1509|          else
1510|            href[0] = '\0';
1511|        }
1512|        else if ( stricmp( p, "text" ) == 0 ) {
1513|          char    font[40];
1514|          int     size;
1515|          RECT    textRect;
1516|          char    weight[40];
1517|          char    font_style[255];
1518|          char    text_anchor[40];
1519|          char*   writing_mode;
1520|
1521|          #ifdef  SVGCATS_LOAD_TRACE
1522|           Errors_printf( "text (tag)" );
1523|          #endif
1524|
1525|          /* default */
1526|          strcpy( font, m_bJapanese ? "MS Pゴシック" : "Arial" );
1527|          size = 8;
1528|          strcpy( weight, "normal" );
1529|          strcpy( font_style, "" );
1530|
1531|          /* read */
1532|          id = XMLPars_getValue( &xmlp, "id" );
1533|          textRect.left = atoi2( XMLPars_getValue( &xmlp, "x" ), 250 );
1534|          textRect.top = atoi2( XMLPars_getValue( &xmlp, "y" ), 150 );
1535|          textRect.right = textRect.left + 10;
1536|          textRect.bottom = textRect.top + 10;
1537|          style = XMLPars_getValue( &xmlp, "style" );
1538|          transform = XMLPars_getValue( &xmlp, "transform" );
1539|          writing_mode = XMLPars_getValue( &xmlp, "writing-mode" );
1540|          if ( style != NULL ) {
1541|            StrX_getCSSValueOfColor( style, "fill", &lineColor );
1542|            StrX_getCSSValueOfStr( style, "font-family", font, sizeof(font) );
1543|            StrX_getCSSValueOfInt( style, "font-size", &size );
1544|            StrX_getCSSValueOfStr( style, "font-weight", weight, sizeof(weight) );
1545|            StrX_getCSSValueOfStr( style, "font-style", font_style, sizeof(font_style) );
1546|            StrX_getCSSValueOfStr( style, "text-anchor", text_anchor, sizeof(text_anchor) );
1547|          }
1548|          if ( transform != NULL )
1549|            transform = strchr( transform, '(' );
1550|
1551|          if ( strcmp( font, "MS-Gothic" ) == 0 )  strcpy( font, "MS ゴシック" );
1552|          else if ( strcmp( font, "MS-PGothic" ) == 0 )  strcpy( font, "MS Pゴシック" );
1553|          else if ( strcmp( font, "MS-Mincho" ) == 0 )  strcpy( font, "MS 明朝" );
1554|          else if ( strcmp( font, "MS-PMincho" ) == 0 )  strcpy( font, "MS P明朝" );
1555|
1556|          /* construct */
1557|          text = new Text_Box;
1558|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1559|          elem->p = text;
1560|          if ( pGroup != NULL ) {
1561|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
1562|            elem->p = text;
1563|          }
1564|
1565|          text->m_id = GetNewPrimID();
1566|          text->m_IdLabel = ( id == NULL ? label : id );
1567|          text->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
1568|          text->m_Target = target;
1569|          text->m_CenterX = textRect.left;
1570|          text->m_Y = textRect.top;
1571|          text->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
1572|          text->m_Color = lineColor;
1573|          text->m_Font = font;
1574|          text->m_Size = size;
1575|          text->m_bBold = ( stricmp( weight, "bold" ) == 0 || atoi( weight ) > 400 );
1576|          text->m_bItalic = ( stricmp( font_style, "italic" ) == 0 );
1577|          if ( stricmp( text_anchor, "middle" ) == 0 )  text->m_BasePos = Text_Box_CenterAlign;
1578|          else if ( stricmp( text_anchor, "end" ) == 0 )  text->m_BasePos = Text_Box_RightAlign;
1579|          else  text->m_BasePos = Text_Box_LeftAlign;
1580|          text->m_bTategaki = ( writing_mode != NULL && stricmp( writing_mode, "tb" ) == 0 );
1581|          text->m_BoxShape = 0;
1582|          iTextLine = 1;
1583|        }
1584|        else if ( stricmp( p, "tspan" ) == 0 ) {
1585|          int  y = atoi2( XMLPars_getValue( &xmlp, "y" ), 0 );
1586|          iTextLine ++;
1587|
1588|          if ( text == NULL )  formatError();
1589|          if ( iTextLine == 2 ) {
1590|            text->m_BetweenOfLine = ( y - text->m_Y );
1591|          }
1592|        }
1593|        else if ( stricmp( p, "svgcats-ink-rawdata" ) == 0 ) {
1594|          FILE*    f = xmlp.engU.inherit_BLex3_Engine.f;
1595|          WCHAR*   data;
1596|          SVGCat_Page*  page =
1597|            ListX_get( &file->m_pages, file->m_CurrentPageNum - file->m_StartPageNum, SVGCat_Page );
1598|
1599|          fseek( f, xmlp.htmlPars.parsedPos.pos, SEEK_SET );
1600|          data = ((CMainFrame*)m_pMainWnd)->m_wndView->InInkRawData( f );
1601|          Variant_initBSTR( &page->ink, data );
1602|          free( data );
1603|        }
1604|
1605|        break;
1606|
1607|       case XMLPars_TextBetweenTags:
1608|        p = XMLPars_getTagName( &xmlp );
1609|        if ( stricmp( p, "text" ) == 0 ) {
1610|          char  s[Text_Box_nByteInLine + 4];
1611|
1612|          #ifdef  SVGCATS_LOAD_TRACE
1613|           Errors_printf( "text (data)" );
1614|          #endif
1615|
1616|          XMLPars_getText( &xmlp, 0, s, sizeof(s) );
1617|          StrX_resumeFromHtmlTxt( s, s, sizeof(s) );
1618|
1619|          text->m_Text = s;
1620|        }
1621|        else if ( stricmp( p, "tspan" ) == 0 ) {
1622|          char  s[Text_Box_nByteInLine + 4];
1623|
1624|          XMLPars_getText( &xmlp, 0, s, sizeof(s) );
1625|          StrX_resumeFromHtmlTxt( s, s, sizeof(s) );
1626|
1627|          if ( text == NULL )  formatError();
1628|          text->m_Text = text->m_Text + "\r\n" + s;
1629|        }
1630|        break;
1631|
1632|       case XMLPars_EndTag:
1633|        p = XMLPars_getTagName( &xmlp );
1634|
1635|        if ( stricmp( p, "/text" ) == 0 ) {
1636|          #ifdef  SVGCATS_LOAD_TRACE
1637|            Errors_printf( "/text" );
1638|          #endif
1639|        }
1640|
1641|        else if ( stricmp( p, "/a" ) == 0 ) {
1642|          href[0] = '\0';
1643|          target[0] = '\0';
1644|        }
1645|
1646|        else if ( stricmp( p, "/page" ) == 0 ) {  /* 終了タグ */
1647|          SVGCat_Page*  page = ListX_get( &file->m_pages, iPrevPage - file->m_StartPageNum, SVGCat_Page );
1648|
1649|          iPrevPage = ListX_getI( &file->m_pages, page->parent ) + file->m_StartPageNum;
1650|        }
1651|
1652|
1653|        /* グループを解析して複合図形に変更する ============================================*/
1654|        else if ( stricmp( p, "/g" ) == 0 ) {
1655|          ListX_ElemX*  first;
1656|          int  n;
1657|
1658|          if ( pGroup == NULL ) {
1659|            if ( bInPageTag )  { bInPageTag = false;  break; /* exit switch */  }
1660|            else  formatError();  /* </g> が多すぎる */
1661|          }
1662|
1663|          n = ListX_getN( pGroup, ListX_ElemX );
1664|
1665|          elem = ListX_getFirst( &groupStack, ListX_ElemX );
1666|          if ( elem == NULL )  formatError();
1667|
1668|          first = (ListX_ElemX*)elem->p;
1669|          if ( first == NULL )
1670|            first = ListX_getFirst( pGroup, ListX_ElemX );
1671|          else
1672|            first = ListX_Elem_getNextT( first, ListX_ElemX );
1673|
1674|          #ifdef  SVGCATS_LOAD_TRACE
1675|           if ( first == NULL )  Errors_printf( "/g  first = NULL" );
1676|           else Errors_printf( "/g  first id = %d", ((CadPrim*)first->p)->GetID() );
1677|          #endif
1678|
1679|          if ( bInInk && ListX_getN( &groupStack, ListX_ElemX ) == 1 ) {
1680|            FILE*  f = FileX_open( GetInkWorkFilePath( file->m_id,
1681|              file->m_CurrentPageNum, ink_raster ), "wb" );
1682|
1683|            fprintf( f, "\t<g id=\"svgcats-ink\" type=\"%s\">",
1684|              ink_raster == IRO_CopyPen ? "front" : "back" );
1685|            FileX_outPart( f, xmlp.engU.inherit_BLex3_Engine.f,
1686|              ink_start, xmlp.htmlPars.parsedPos.pos );
1687|            fprintf( f, "\r\n" );
1688|            fclose( f );
1689|            bInInk = false;
1690|          }
1691|          else if ( first == NULL );  /* 空のグループ */
1692|          else if ( n == 1 ) {
1693|
1694|            /* グループが1本のラインのときは、折れ線にする */
1695|            if ( ((CadPrim*)first->p)->GetTypeID() == Line_Ex_TypeID ) {
1696|              Line_Ex*  line = (Line_Ex*)first->p;
1697|              Line_Corner*  lc = new Line_Corner;
1698|              lc->m_id = GetNewPrimID();
1699|
1700|              lc->m_Line.x1 = line->m_Line.x1;  lc->m_Line.y1 = line->m_Line.y1;
1701|              lc->m_Line.x2 = line->m_Line.x2;  lc->m_Line.y2 = line->m_Line.y2;
1702|              lc->m_Arrow1 = line->m_Arrow1;
1703|              lc->m_Arrow2 = line->m_Arrow2;
1704|              lc->m_ArrowsInReading = line->m_ArrowsInReading;
1705|                line->m_ArrowsInReading = NULL;  /* avoid free in destructor */
1706|              lc->m_Width = line->m_Width;
1707|              lc->m_Color = line->m_Color;
1708|              lc->m_bDash = line->m_bDash;
1709|              lc->m_SlideCorner = false;
1710|              lc->m_Dir = Line_DirN;
1711|              lc->m_CornerX = (line->m_Line.x1 + line->m_Line.x2) / 2;
1712|              lc->m_CornerY = (line->m_Line.y1 + line->m_Line.y2) / 2;
1713|
1714|              RemovePrimI( file, (CadPrim*)first->p );
1715|              elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1716|              elem->p = lc;
1717|            }
1718|          }
1719|
1720|          /* Rect_Ex Text_Box のときは、枠付きテキストにする */
1721|          else if ( ((CadPrim*)first->p)->GetTypeID() == Rect_Ex_TypeID ) {
1722|
1723|            #ifdef  SVGCATS_LOAD_TRACE
1724|              Errors_printf( "Text_Box = rect + text" );
1725|            #endif
1726|
1727|            elem = ListX_Elem_getNextT( first, ListX_ElemX );
1728|            if ( elem != NULL && ((CadPrim*)elem->p)->GetTypeID() == Text_Box_TypeID && n == 2 ) {
1729|              Rect_Ex*   r = (Rect_Ex*)first->p;
1730|              Text_Box*  t = (Text_Box*)elem->p;
1731|              Text_Box*  b = new Text_Box;
1732|
1733|              b->m_id = GetNewPrimID();
1734|              b->m_Text = t->m_Text;
1735|              b->m_IdLabel = t->m_IdLabel;
1736|              b->m_URL = t->m_URL;
1737|              b->m_Target = t->m_Target;
1738|              b->m_CenterX = t->m_CenterX;
1739|              b->m_Y = t->m_Y;
1740|              b->m_BetweenOfLine = t->m_BetweenOfLine;
1741|              b->m_RotateDegree = t->m_RotateDegree;
1742|              b->m_Color = t->m_Color;
1743|              b->m_Font = t->m_Font;
1744|              b->m_Size = t->m_Size;
1745|              b->m_bBold = t->m_bBold;
1746|              b->m_bItalic = t->m_bItalic;
1747|              b->m_BasePos = t->m_BasePos;
1748|              b->m_bTategaki = t->m_bTategaki;
1749|              switch ( r->m_ShapeType ) {  /* マイナスは、Text_Box::Draw時に下記の再設定をすることを示す */
1750|                case Rect_RectShape:      b->m_BoxShape = - Text_Box_RectShape;  break;
1751|                case Rect_RoundRectShape: b->m_BoxShape = - Text_Box_RoundRectShape;  break;
1752|                case Rect_CircleShape:    b->m_BoxShape = - Text_Box_CircleShape;  break;
1753|                case Rect_DiamondShape:   b->m_BoxShape = - Text_Box_DiamondShape;  break;
1754|                case Rect_ImageShape:     b->m_BoxShape = - Text_Box_RectShape;  break;
1755|                case Rect_Parallelogram:  b->m_BoxShape = - Text_Box_Parallelogram;  break;
1756|              }
1757|              b->m_BoxMarginX = r->m_Rect.x;  /* Text_Box::Draw時に再設定 */
1758|              b->m_BoxMarginY = r->m_Rect.y;  /* Text_Box::Draw時に再設定 */
1759|              b->m_DiffW = ( b->m_bTategaki ? r->m_Rect.h : r->m_Rect.w );
1760|              b->m_BorderWidth = r->m_BorderWidth;
1761|              b->m_BorderColor = r->m_BorderColor;
1762|              b->m_FillColor = r->m_FillColor;
1763|              b->m_FillNTrans = r->m_NTrans;
1764|
1765|              RemovePrimI( file, r );
1766|              RemovePrimI( file, t );
1767|              ListX_removeFree( &group, first );
1768|              ListX_removeFree( &group, elem );
1769|
1770|              elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1771|              elem->p = b;
1772|            }
1773|          }
1774|          else if ( ((CadPrim*)first->p)->GetTypeID() == Line_Ex_TypeID ) {
1775|            Line_Ex*  line;
1776|
1777|            for ( ListX_forEach( pGroup, &elem, ListX_ElemX ) ) {
1778|              if ( ((CadPrim*)elem->p)->GetTypeID() != Line_Ex_TypeID )
1779|                break;
1780|              line = (Line_Ex*)elem->p;
1781|              if ( line->m_Line.x1 != line->m_Line.x2 &&line->m_Line.y1 != line->m_Line.y2 )
1782|                break;
1783|            }
1784|
1785|            /* すべて水平か垂直のラインのとき、折れ線として解析する */
1786|            if ( elem == NULL ) {
1787|              Line_Corner*  lc = new Line_Corner;
1788|
1789|              #ifdef  SVGCATS_LOAD_TRACE
1790|                Errors_printf( "Line_Corner" );
1791|              #endif
1792|
1793|              lc->m_id = GetNewPrimID();
1794|
1795|              line = (Line_Ex*)ListX_getFirst( pGroup, ListX_ElemX )->p;
1796|              lc->m_Line.x1 = line->m_Line.x1;  lc->m_Line.y1 = line->m_Line.y1;
1797|              if ( (int)line->m_ArrowsInReading == 1 ) {
1798|                if ( line->m_Arrow1 != 0 )  lc->m_Arrow1 = line->m_Arrow1;
1799|                if ( line->m_Arrow2 != 0 )  lc->m_Arrow1 = line->m_Arrow2;
1800|                if ( line->m_Controler_id[0] != 0 )  lc->m_Controler_id[0] = line->m_Controler_id[0];
1801|                if ( line->m_Controler_id[1] != 0 )  lc->m_Controler_id[0] = line->m_Controler_id[1];
1802|                line->m_ArrowsInReading = NULL;
1803|              }
1804|              else if ( line->m_ArrowsInReading != NULL ) {
1805|                lc->m_ArrowsInReading = line->m_ArrowsInReading;
1806|                line->m_ArrowsInReading = NULL;
1807|                lc->m_Arrow1 = line->m_Arrow1;
1808|              }
1809|
1810|              line = (Line_Ex*)ListX_getLast( pGroup, ListX_ElemX )->p;
1811|              lc->m_Line.x2 = line->m_Line.x2;  lc->m_Line.y2 = line->m_Line.y2;
1812|              if ( (int)line->m_ArrowsInReading == 1 ) {
1813|                if ( line->m_Arrow1 != 0 )  lc->m_Arrow2 = line->m_Arrow1;
1814|                if ( line->m_Arrow2 != 0 )  lc->m_Arrow2 = line->m_Arrow2;
1815|                if ( line->m_Controler_id[0] != 0 )  lc->m_Controler_id[1] = line->m_Controler_id[0];
1816|                if ( line->m_Controler_id[1] != 0 )  lc->m_Controler_id[1] = line->m_Controler_id[1];
1817|                line->m_ArrowsInReading = NULL;
1818|              }
1819|              else if ( line->m_ArrowsInReading != NULL ) {
1820|                if ( lc->m_Arrow1 == 0 ) {
1821|                  lc->m_ArrowsInReading = line->m_ArrowsInReading;
1822|                  line->m_ArrowsInReading = NULL;
1823|                  lc->m_Arrow1 = line->m_Arrow1;
1824|                }
1825|                else {
1826|                  free( line->m_ArrowsInReading );
1827|                  line->m_ArrowsInReading = NULL;
1828|                  lc->m_Arrow2 = line->m_Arrow1;
1829|                }
1830|              }
1831|              lc->m_Width = line->m_Width;
1832|              lc->m_Color = line->m_Color;
1833|              lc->m_bDash = line->m_bDash;
1834|              lc->m_SlideCorner = false;
1835|
1836|              line = (Line_Ex*)ListX_getFirst( pGroup, ListX_ElemX )->p;
1837|              if ( line->m_Line.x2 < line->m_Line.x1 ) {
1838|                line = (Line_Ex*)ListX_get( pGroup, 1,  ListX_ElemX )->p;
1839|                lc->m_CornerX = line->m_Line.x2;
1840|                if ( line->m_Line.y2 == lc->m_Line.y2 )
1841|                  lc->m_CornerY = (line->m_Line.y1 + line->m_Line.y2) / 2;
1842|                else
1843|                  lc->m_CornerY = line->m_Line.y2;
1844|                lc->m_Dir = Line_DirN;
1845|              }
1846|              else if ( line->m_Line.x1 == line->m_Line.x2 ) {
1847|                line = (Line_Ex*)ListX_get( pGroup, 1,  ListX_ElemX )->p;
1848|                if ( line->m_Line.x2 <= lc->m_Line.x2 )
1849|                  lc->m_CornerX = (line->m_Line.x1 + line->m_Line.x2) / 2;
1850|                else
1851|                  lc->m_CornerX = line->m_Line.x2;
1852|                lc->m_CornerY = line->m_Line.y1;
1853|                lc->m_Dir = Line_DirN;
1854|              }
1855|              else {
1856|                if ( line->m_Line.x2 < lc->m_Line.x2 ) {
1857|                  lc->m_CornerX = line->m_Line.x2;
1858|                  line = (Line_Ex*)ListX_get( pGroup, 1,  ListX_ElemX )->p;
1859|                  lc->m_CornerY = (line->m_Line.y1 + line->m_Line.y2) / 2;
1860|                }
1861|                else if ( line->m_Line.x2 == lc->m_Line.x2 ) {
1862|                  lc->m_CornerX = line->m_Line.x2;
1863|                  lc->m_CornerY = line->m_Line.y2;
1864|                }
1865|                else {
1866|                  line = (Line_Ex*)ListX_get( pGroup, 1,  ListX_ElemX )->p;
1867|                  if ( line->m_Line.y2 > lc->m_Line.y2 )
1868|                    { lc->m_CornerX = line->m_Line.x2;  lc->m_CornerY = line->m_Line.y2; }
1869|                  else {
1870|                    lc->m_CornerX = line->m_Line.x2;
1871|                    lc->m_CornerY = (line->m_Line.y1 + line->m_Line.y2) / 2;
1872|                  }
1873|                }
1874|                lc->m_Dir = Line_DirZ;
1875|              }
1876|
1877|              {
1878|                ListX_ElemX*  elem2;
1879|                int  i, n = 0;
1880|
1881|                elem2 = ListX_getFirst( &groupStack, ListX_ElemX );
1882|
1883|                for ( ListX_forEach( pGroup, &elem, ListX_ElemX ) ) {
1884|                  RemovePrimI( file, (CadPrim*)elem->p );
1885|                  n++;
1886|                }
1887|
1888|                first = (ListX_ElemX*)elem2->p;
1889|                if ( first == NULL )
1890|                  elem = ListX_getFirst( pGroup, ListX_ElemX );
1891|                else
1892|                  elem = ListX_Elem_getNextT( first, ListX_ElemX );
1893|
1894|                for ( i = 0; i < n; i++ ) {
1895|                  elem2 = ListX_Elem_getNextT( elem, ListX_ElemX );
1896|                  ListX_removeFree( &group, elem );
1897|                  elem = elem2;
1898|                }
1899|              }
1900|
1901|              elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
1902|              elem->p = lc;
1903|            }
1904|
1905|
1906|            /* 矢印付きラインを解析する */
1907|            else {
1908|              ListX_ElemX*  prim1;
1909|              ListX_ElemX*  prim2;
1910|              Line_Ex*  line = (Line_Ex*)first->p;
1911|
1912|              #ifdef  SVGCATS_LOAD_TRACE
1913|                Errors_printf( "Line m_ArrowX" );
1914|              #endif
1915|
1916|              if ( line->m_ArrowsInReading == NULL )
1917|                line->m_ArrowsInReading = (Line*)malloc( sizeof(Line) );
1918|
1919|              /* group をループする。groupStack の最初から */
1920|              for ( prim1 = ListX_Elem_getNextT( first, ListX_ElemX );  prim1 != NULL; ) {
1921|
1922|                /* Type1 の矢印を解析する */
1923|                if ( prim1 == NULL )  prim2 = NULL;
1924|                else   prim2 = ListX_Elem_getNextT( prim1, ListX_ElemX );
1925|
1926|                if ( ((CadPrim*)prim1->p)->GetTypeID() == Line_Ex_TypeID &&
1927|                     prim2 != NULL && ((CadPrim*)prim2->p)->GetTypeID() == Line_Ex_TypeID ) {
1928|                  Line_Ex*  line1 = (Line_Ex*)prim1->p;
1929|                  Line_Ex*  line2 = (Line_Ex*)prim2->p;
1930|
1931|                  if ( line1->m_Line.x1 == line2->m_Line.x1 && line1->m_Line.y1 == line2->m_Line.y1 ) {
1932|                    if ( (int)line->m_ArrowsInReading != 1 ) {
1933|                      if ( line->m_Arrow1 == 0 ) {
1934|                        line->m_Arrow1 = 1;  /* Load2 でどちらの頂点につくか決定する */
1935|                        line->m_ArrowsInReading->x1 = line1->m_Line.x1;
1936|                        line->m_ArrowsInReading->y1 = line1->m_Line.y1;
1937|                      }
1938|                      else {
1939|                        line->m_Arrow2 = 1;
1940|                        line->m_ArrowsInReading->x2 = line1->m_Line.x1;
1941|                        line->m_ArrowsInReading->y2 = line1->m_Line.y1;
1942|                      }
1943|                    }
1944|
1945|                    RemovePrimI( file, line1 );
1946|                    RemovePrimI( file, line2 );
1947|                    elem = ListX_Elem_getNextT( prim2, ListX_ElemX );
1948|                    ListX_removeFree( &group, prim1 );
1949|                    ListX_removeFree( &group, prim2 );
1950|                    prim1 = elem;
1951|                  }
1952|                  else
1953|                    prim1 = ListX_Elem_getNextT( prim2, ListX_ElemX );
1954|                }
1955|
1956|                /* Type2, Type4 の矢印を解析する */
1957|                else if ( ((CadPrim*)prim1->p)->GetTypeID() == Rect_Ex_TypeID ) {
1958|                  Rect_Ex*  rect = (Rect_Ex*)prim1->p;
1959|
1960|                  if ( rect->m_ShapeType == Rect_CircleShape ) {
1961|                    if ( (int)line->m_ArrowsInReading != 1 ) {
1962|                      if ( line->m_Arrow1 == 0 ) {
1963|                        line->m_Arrow1 = ( rect->m_FillColor == rect->m_BorderColor ? 2 : 5 );
1964|                        line->m_ArrowsInReading->x1 = rect->m_Rect.x + rect->m_Rect.w / 2;
1965|                        line->m_ArrowsInReading->y1 = rect->m_Rect.y + rect->m_Rect.h / 2;
1966|                      }
1967|                      else {
1968|                        line->m_Arrow2 = ( rect->m_FillColor == rect->m_BorderColor ? 2 : 5 );
1969|                        line->m_ArrowsInReading->x2 = rect->m_Rect.x + rect->m_Rect.w / 2;
1970|                        line->m_ArrowsInReading->y2 = rect->m_Rect.y + rect->m_Rect.h / 2;
1971|                      }
1972|                    }
1973|
1974|                    RemovePrimI( file, rect );
1975|                    ListX_removeFree( &group, prim1 );
1976|                  }
1977|                  else if ( rect->m_ShapeType == Rect_DiamondShape ) {
1978|                    if ( (int)line->m_ArrowsInReading != 1 ) {
1979|                      if ( line->m_Arrow1 == 0 ) {
1980|                        line->m_Arrow1 = ( rect->m_FillColor == rect->m_BorderColor ? 4 : 7 );
1981|                        line->m_ArrowsInReading->x1 = rect->m_Rect.x + rect->m_Rect.w / 2;
1982|                        line->m_ArrowsInReading->y1 = rect->m_Rect.y + rect->m_Rect.h / 2;
1983|                      }
1984|                      else {
1985|                        line->m_Arrow2 = ( rect->m_FillColor == rect->m_BorderColor ? 4 : 7 );
1986|                        line->m_ArrowsInReading->x2 = rect->m_Rect.x + rect->m_Rect.w / 2;
1987|                        line->m_ArrowsInReading->y2 = rect->m_Rect.y + rect->m_Rect.h / 2;
1988|                      }
1989|                    }
1990|
1991|                    RemovePrimI( file, rect );
1992|                    ListX_removeFree( &group, prim1 );
1993|                  }
1994|
1995|                  prim1 = prim2;
1996|                }
1997|
1998|                /* Type3, Type4 の矢印を解析する */
1999|                else if ( ((CadPrim*)prim1->p)->GetTypeID() == Polygon_Ex_TypeID ) {
2000|                  Polygon_Ex*  p = (Polygon_Ex*)prim1->p;
2001|
2002|                  if ( p->m_NPoint == 3 || p->m_NPoint == 4 ) {
2003|                    if ( (int)line->m_ArrowsInReading != 1 ) {
2004|                      if ( line->m_Arrow1 == 0 ) {
2005|                        line->m_Arrow1 = p->m_NPoint +
2006|                          ( p->m_FillColor == p->m_BorderColor ? 0 : 3 );
2007|                      }
2008|                      else {
2009|                        line->m_Arrow2 = p->m_NPoint +
2010|                          ( p->m_FillColor == p->m_BorderColor ? 0 : 3 );
2011|                      }
2012|                      line->m_ArrowsInReading->x1 = p->m_Points[0].x;
2013|                      line->m_ArrowsInReading->y1 = p->m_Points[0].y;
2014|                    }
2015|
2016|                    RemovePrimI( file, p );
2017|                    ListX_removeFree( &group, prim1 );
2018|                  }
2019|
2020|                  prim1 = prim2;
2021|                }
2022|
2023|                else {
2024|                  prim1 = prim2;
2025|                }
2026|              }
2027|            }
2028|          }
2029|
2030|          elem = ListX_getFirst( &groupStack, ListX_ElemX );
2031|          if ( elem == NULL )  formatError();
2032|  #if 0
2033|          else {
2034|            elem = ListX_Elem_getNextT( (ListX_ElemX*)elem->p, ListX_ElemX );
2035|            if ( elem != NULL )
2036|              ListX_removeDeleteAfters( &group, elem, NULL );
2037|          }
2038|  #endif
2039|          ListX_removeFree( &groupStack, elem );
2040|          if ( ListX_isEmpty( &groupStack ) ) {
2041|            ListX_toEmptyDelete( &group, ListX_ElemX, NULL );
2042|            pGroup = NULL;
2043|          }
2044|        }
2045|        break;
2046|      }
2047|    }
2048|  }
2049|  c_finally {
2050|    if ( bXmlp )  XMLPars_finish( &xmlp );
2051|    if ( bUfile ) FileX_UniRead_finish( &ufile );
2052|    if ( svgzMeltedPath != NULL )  remove( svgzMeltedPath );
2053|    ListX_finish2( &groupStack, ListX_ElemX, NULL );
2054|    ListX_finish2( &group, ListX_ElemX, NULL );
2055|  } c_end_finally;
2056|
2057|
2058|  /* α版インクフォーマットとの互換をとる */
2059|  if ( FileX_isExist( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_MaskPen ) ) ) {
2060|    if ( ! FileX_isExist( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_CopyPen ) ) ) {
2061|      FILE*  f = FileX_open( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_CopyPen ), "wt" );
2062|      fclose( f );
2063|    }
2064|  }
2065|  else {
2066|    if ( FileX_isExist( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_CopyPen ) ) ) {
2067|      FILE*  f = FileX_open( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_MaskPen ), "wt" );
2068|      fclose( f );
2069|    }
2070|  }
2071|
2072|  /* 1ページ目に戻す */
2073|  ChgPage( file, -1 );  /* これが無いと、ページ数が1のときに IInkOverlay に乗らない */
2074|  ChgPage( file, 1 );
2075|
2076|  #ifdef  SVGCATS_LOAD_TRACE
2077|     Errors_endPool();
2078|  #endif
2079|}
2080|
2081|
2082| 
2083|/***********************************************************************
2084|  12. <<< [CSVGCatApp::Load2] SVG ファイルを読み込む ver2 >>> 
2085|************************************************************************/
2086|void  CSVGCatApp::Load2( const char* path )
2087|{
2088|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
2089|
2090|  ASSERT( m_file.m_bPagesExist );
2091|
2092|  m_UndoBuf->ClearAll();
2093|  delete  m_UndoBuf;
2094|
2095|  Load_imp2( (long)frame->m_hWnd, &m_file, path );
2096|
2097|
2098|  m_bBackTransparent = false;
2099|  m_UndoBuf = new Undo_Buf();
2100|}
2101|
2102|
2103|void  CSVGCatApp::Load_imp2( long id_hWnd, SVGCat_File* file, const char* path )
2104|{
2105|  int     pos;
2106|
2107|  if ( ! FileX_isExist( path ) )
2108|    error2_0( FileX_Err_CannotReadOpen, "" );
2109|
2110|  {
2111|
2112|    Finish_imp( file );
2113|    NewEmpty_imp( file, id_hWnd, file->m_bShowing );
2114|    if ( file->m_bShowing )
2115|      ((CMainFrame*)m_pMainWnd)->m_wndView->NewInkOverlay();
2116|
2117|    pos = 0;
2118|
2119|    #ifdef  SVGCATS_LOAD_TRACE
2120|       Errors_startPool();
2121|       CSVGCatApp_LoadCount = 0;
2122|       IFC(0) BK
2123|    #endif
2124|
2125|
2126|    LoadPage( id_hWnd, file, path, &pos );
2127|  }
2128|
2129|#ifdef SVGCats_NewFileAccess
2130|printPages3( "" );
2131|#endif
2132|
2133|  /* α版インクフォーマットとの互換をとる */
2134|  if ( FileX_isExist( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_MaskPen ) ) ) {
2135|    if ( ! FileX_isExist( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_CopyPen ) ) ) {
2136|      FILE*  f = FileX_open( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_CopyPen ), "wt" );
2137|      fclose( f );
2138|    }
2139|  }
2140|  else {
2141|    if ( FileX_isExist( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_CopyPen ) ) ) {
2142|      FILE*  f = FileX_open( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_MaskPen ), "wt" );
2143|      fclose( f );
2144|    }
2145|  }
2146|
2147|  /* 1ページ目に戻す */
2148|  ChgPage( file, -1 );  /* これが無いと、ページ数が1のときに IInkOverlay に乗らない */
2149|  ChgPage( file, 1 );
2150|
2151|  #ifdef  SVGCATS_LOAD_TRACE
2152|     Errors_endPool();
2153|  #endif
2154|}
2155|
2156|
2157| 
2158|/***********************************************************************
2159|  13. <<< [CSVGCatApp::LoadPage] ページを解析する >>> 
2160|************************************************************************/
2161|void  CSVGCatApp::LoadPage( long id_hWnd, SVGCat_File* file, const char* path, int* pos )
2162|{
2163|  FileX_UniRead  ufile;
2164|  bool    bUfile = false;
2165|  char*   svgzMeltedPath = NULL;
2166|
2167|  char*      style;
2168|  char*      transform;
2169|  char*      id;
2170|  bool       bInPageTag;
2171|
2172|  char*   p;
2173|  XMLPars  xmlp;
2174|  bool     bXmlp = false;
2175|  char     xmlp_buf[3072];
2176|  ListX    group;  /* ListX_ElemX:CadPrim* */
2177|  ListX*   pGroup;  /* 現在所属しているグループ、NULL=無所属 */
2178|  ListX    groupStack;  /* 親の段の最後の要素の集合、ListX_ElemX:ListX_ElemX*:CadPrim* */
2179|  ListX_ElemX*  elem;
2180|  Text_Box*    text = NULL;  /* タグ内のパラメータとタグ間テキストとの伝達用 */
2181|  bool    bInInk = false;
2182|  int     nInkInPage = 0;
2183|  int     ink_start = 0;
2184|  InkRasterOperation  ink_raster;
2185|  char    href[_MAX_PATH];
2186|  char    label[_MAX_PATH];
2187|  char    target[_MAX_PATH];
2188|  COLORREF   lineColor, fillColor;
2189|
2190|  int     iMaxPage = 1;   /* ページ構成を行った最大のページ番号 */
2191|  int     iPrevPage = 0;  /* 同じ深さの前のページ番号 */
2192|  int     iTextLine;
2193|
2194|  c_try {
2195|
2196|    if ( stricmp( StrX_refExt( path ), "svgz" ) == 0 ) {
2197|      svgzMeltedPath = CSVGCatApp_meltSvgz( path );
2198|      p = FileX_UniRead_init( &ufile, svgzMeltedPath );  bUfile = true;
2199|    }
2200|    else
2201|      { p = FileX_UniRead_init( &ufile, path );  bUfile = true; }
2202|
2203|
2204|    lineColor = GetSysColor( COLOR_WINDOWTEXT );
2205|    fillColor = GetSysColor( COLOR_BTNFACE );
2206|
2207|    ListX_init( &group );
2208|    pGroup = NULL;
2209|    ListX_init( &groupStack );
2210|    bInPageTag = false;
2211|
2212|    href[0] = '\0';
2213|    label[0] = '\0';
2214|    target[0] = '\0';
2215|    XMLPars_init( &xmlp, p, xmlp_buf, sizeof(xmlp_buf) );  bXmlp = true;
2216|
2217|    XMLPars_setPos1( &xmlp, *pos );
2218|
2219|    while ( XMLPars_parse( &xmlp ) ) {
2220|
2221|      #ifdef  SVGCATS_LOAD_TRACE
2222|       CSVGCatApp_LoadCount++;
2223|       Errors_printf("[%d:0x%X] ==========================================",CSVGCatApp_LoadCount,
2224|         xmlp.htmlPars.parsedPos.pos );
2225|       Errors_printf("m_prims -------------" );
2226|       for ( ListX_forEach( &file->m_prims, &elem, ListX_ElemX ) )
2227|         Errors_printf( "%d", ((CadPrim*)elem->p)->GetID() );
2228|       Errors_printf("group ----------------" );
2229|       for ( ListX_forEach( &group, &elem, ListX_ElemX ) )
2230|         Errors_printf( "%d", ((CadPrim*)elem->p)->GetID() );
2231|       Errors_printf("groupStack ---------------" );
2232|       for ( ListX_forEach( &groupStack, &elem, ListX_ElemX ) ) {
2233|         if ( elem->p == NULL )  Errors_printf( "NULL" );
2234|         else  Errors_printf( "%d", ((CadPrim*)((ListX_ElemX*)elem->p)->p)->GetID() );
2235|       }
2236|       Errors_printf("parse -----------------" );
2237|
2238|       IFC( xmlp.htmlPars.parsedPos.pos >= 0x58 )
2239|         BK
2240|       IFC( CSVGCatApp_LoadCount >= 562 )
2241|         BK
2242|      #endif
2243|
2244|
2245|      switch ( XMLPars_getTokenType( &xmlp ) ) {
2246|
2247|       case XMLPars_StartAndEndTag:   /*================================================== */
2248|        p = XMLPars_getTagName( &xmlp );
2249|
2250|        if ( stricmp( p, "page" ) == 0 ) {  /* pagesタグ内, 単独タグ */
2251|          SVGCat_Page*  prevPage = ListX_get( &file->m_pages, iPrevPage - file->m_StartPageNum, SVGCat_Page );
2252|          SVGCat_Page*  page;
2253|
2254|          if ( iPrevPage == 0 )  prevPage = NULL;
2255|
2256|          iMaxPage = atoi( XMLPars_getValue( &xmlp, "num" ) );
2257|          page = ListX_get( &file->m_pages, iMaxPage - file->m_StartPageNum, SVGCat_Page );
2258|          page->prev = prevPage;
2259|          if ( prevPage != NULL ) {
2260|            prevPage->next = page;
2261|            page->parent = prevPage->parent;
2262|          }
2263|          page->next = NULL;  /* デフォルト(次のページ)とは限らないため */
2264|          StrX_cpy( page->title, XMLPars_getValue( &xmlp, "title" ), sizeof(page->title) );
2265|          if ( page->title[0] == '\0' )  strcpy( page->title, "Page" );
2266|
2267|          iPrevPage = iMaxPage;
2268|        }
2269|        else if ( stricmp( p, "line" ) == 0 && ! bInInk ) {
2270|          int   x1, y1, x2, y2, width, dash;
2271|          char*  p;
2272|          char   v[256];
2273|
2274|          #ifdef  SVGCATS_LOAD_TRACE
2275|           Errors_printf( "line id=%d", m_NextID );
2276|          #endif
2277|
2278|          if ( XMLPars_getValue( &xmlp, "x1" ) == NULL )  formatError();
2279|          x1 = atoi( XMLPars_getValue( &xmlp, "x1" ) );
2280|          y1 = atoi( XMLPars_getValue( &xmlp, "y1" ) );
2281|          x2 = atoi( XMLPars_getValue( &xmlp, "x2" ) );
2282|          y2 = atoi( XMLPars_getValue( &xmlp, "y2" ) );
2283|          width = 1;
2284|          style = XMLPars_getValue( &xmlp, "style" );
2285|          if ( style != NULL ) {
2286|            StrX_getCSSValueOfColor( style, "stroke", &lineColor );
2287|            StrX_getCSSValueOfInt( style, "stroke-width", &width );
2288|          }
2289|
2290|          Line_Ex*  l = new Line_Ex;
2291|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2292|          elem->p = l;
2293|          if ( pGroup != NULL ) {
2294|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2295|            elem->p = l;
2296|          }
2297|
2298|          l->m_id = GetNewPrimID();
2299|          Line_init( &l->m_Line, x1, y1, x2, y2 );
2300|          l->m_Width = width;
2301|          l->m_Color = lineColor;
2302|          dash = -50;  StrX_getCSSValueOfInt( style, "stroke-dasharray", &dash );
2303|          l->m_bDash = ( dash != -50 );
2304|
2305|          p = XMLPars_getValue( &xmlp, "p1" );
2306|          if ( p != NULL ) {
2307|            if ( StrX_getCSV( p, 1, v, sizeof(v) ) != NULL )  l->m_Line.x1 = atoi( v );
2308|            if ( StrX_getCSV( p, 2, v, sizeof(v) ) != NULL )  l->m_Line.y1 = atoi( v );
2309|            if ( StrX_getCSV( p, 3, v, sizeof(v) ) != NULL )  l->m_Arrow1 = atoi( v );
2310|            if ( StrX_getCSV( p, 4, v, sizeof(v) ) != NULL )  l->m_Controler_id[0] = -1;
2311|            l->m_ArrowsInReading = (Line*)1;
2312|          }
2313|          p = XMLPars_getValue( &xmlp, "p2" );
2314|          if ( p != NULL ) {
2315|            if ( StrX_getCSV( p, 1, v, sizeof(v) ) != NULL )  l->m_Line.x2 = atoi( v );
2316|            if ( StrX_getCSV( p, 2, v, sizeof(v) ) != NULL )  l->m_Line.y2 = atoi( v );
2317|            if ( StrX_getCSV( p, 3, v, sizeof(v) ) != NULL )  l->m_Arrow2 = atoi( v );
2318|            if ( StrX_getCSV( p, 4, v, sizeof(v) ) != NULL )  l->m_Controler_id[1] = -1;
2319|            l->m_ArrowsInReading = (Line*)1;
2320|          }
2321|        }
2322|        else if ( stricmp( p, "rect" ) == 0 ) {
2323|          int  left, top, right, bottom, width, rx = 0, ry = 0;
2324|          double  opacity;
2325|
2326|          #ifdef  SVGCATS_LOAD_TRACE
2327|           Errors_printf( "rect id=%d", m_NextID );
2328|          #endif
2329|
2330|          id = XMLPars_getValue( &xmlp, "id" );
2331|          if ( XMLPars_getValue( &xmlp, "x" ) == NULL )  formatError();
2332|          left = atoi( XMLPars_getValue( &xmlp, "x" ) );
2333|          top = atoi( XMLPars_getValue( &xmlp, "y" ) );
2334|          right = left + atoi( XMLPars_getValue( &xmlp, "width" ) ) - 1;
2335|          bottom = top + atoi( XMLPars_getValue( &xmlp, "height" ) ) - 1;
2336|          if ( XMLPars_getValue( &xmlp, "rx" ) != NULL )
2337|            rx = atoi( XMLPars_getValue( &xmlp, "rx" ) );
2338|          if ( XMLPars_getValue( &xmlp, "ry" ) != NULL )
2339|            ry = atoi( XMLPars_getValue( &xmlp, "ry" ) );
2340|          style = XMLPars_getValue( &xmlp, "style" );
2341|          transform = XMLPars_getValue( &xmlp, "transform" );
2342|          width = 1;  opacity = 1.0;
2343|          if ( style != NULL ) {
2344|            StrX_getCSSValueOfColor( style, "fill", &fillColor );
2345|            StrX_getCSSValueOfColor( style, "stroke", &lineColor );
2346|            StrX_getCSSValueOfInt( style, "stroke-width", &width );
2347|            StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
2348|          }
2349|          if ( transform != NULL )
2350|            transform = strchr( transform, '(' );
2351|
2352|          Rect_Ex*  r = new Rect_Ex;
2353|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2354|          elem->p = r;
2355|          if ( pGroup != NULL ) {
2356|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2357|            elem->p = r;
2358|          }
2359|
2360|          r->m_id = GetNewPrimID();
2361|          r->m_IdLabel = ( id == NULL ? label : id );
2362|          r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
2363|          r->m_Target = target;
2364|          Rect_init_by2XY( &r->m_Rect, left, top, right, bottom );
2365|          r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
2366|          if ( rx > 0 )
2367|            r->m_ShapeType = Rect_RoundRectShape;
2368|          else
2369|            r->m_ShapeType = Rect_RectShape;
2370|          r->m_BorderWidth = width;
2371|          r->m_BorderColor = lineColor;
2372|          r->m_FillColor = fillColor;
2373|          r->m_NTrans = (int)(opacity * 100);
2374|        }
2375|        else if ( stricmp( p, "circle" ) == 0 ) {
2376|          int  x, y, rr, width;
2377|          double  opacity;
2378|
2379|          #ifdef  SVGCATS_LOAD_TRACE
2380|           Errors_printf( "circle(rect) id=%d", m_NextID );
2381|          #endif
2382|
2383|          id = XMLPars_getValue( &xmlp, "id" );
2384|          if ( XMLPars_getValue( &xmlp, "cx" ) == NULL )  formatError();
2385|          x = atoi( XMLPars_getValue( &xmlp, "cx" ) );
2386|          y = atoi( XMLPars_getValue( &xmlp, "cy" ) );
2387|          rr = atoi( XMLPars_getValue( &xmlp, "r" ) ) ;
2388|          style = XMLPars_getValue( &xmlp, "style" );
2389|          transform = XMLPars_getValue( &xmlp, "transform" );
2390|          width = 1;  opacity = 1.0;
2391|          if ( style != NULL ) {
2392|            StrX_getCSSValueOfColor( style, "fill", &fillColor );
2393|            StrX_getCSSValueOfColor( style, "stroke", &lineColor );
2394|            StrX_getCSSValueOfInt( style, "stroke-width", &width );
2395|            StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
2396|          }
2397|          if ( transform != NULL )
2398|            transform = strchr( transform, '(' );
2399|
2400|          Rect_Ex*  r = new Rect_Ex;
2401|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2402|          elem->p = r;
2403|          if ( pGroup != NULL ) {
2404|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2405|            elem->p = r;
2406|          }
2407|
2408|          r->m_id = GetNewPrimID();
2409|          r->m_IdLabel = ( id == NULL ? label : id );
2410|          r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
2411|          r->m_Target = target;
2412|          Rect_init_by2XY( &r->m_Rect, x - rr, y - rr, x + rr, y + rr );
2413|          r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
2414|          r->m_ShapeType = Rect_CircleShape;
2415|          r->m_BorderWidth = width;
2416|          r->m_BorderColor = lineColor;
2417|          r->m_FillColor = fillColor;
2418|          r->m_NTrans = (int)(opacity * 100);
2419|        }
2420|        else if ( stricmp( p, "ellipse" ) == 0 ) {
2421|          int  cx, cy, rx, ry, width;
2422|          double  opacity;
2423|
2424|          #ifdef  SVGCATS_LOAD_TRACE
2425|           Errors_printf( "ellipse(rect) id=%d", m_NextID );
2426|          #endif
2427|
2428|          id = XMLPars_getValue( &xmlp, "id" );
2429|          if ( XMLPars_getValue( &xmlp, "cx" ) == NULL )  formatError();
2430|          cx = atoi( XMLPars_getValue( &xmlp, "cx" ) );
2431|          cy = atoi( XMLPars_getValue( &xmlp, "cy" ) );
2432|          rx = atoi( XMLPars_getValue( &xmlp, "rx" ) ) ;
2433|          ry = atoi( XMLPars_getValue( &xmlp, "ry" ) ) ;
2434|          style = XMLPars_getValue( &xmlp, "style" );
2435|          transform = XMLPars_getValue( &xmlp, "transform" );
2436|          width = 1;  opacity = 1.0;
2437|          if ( style != NULL ) {
2438|            StrX_getCSSValueOfColor( style, "fill", &fillColor );
2439|            StrX_getCSSValueOfColor( style, "stroke", &lineColor );
2440|            StrX_getCSSValueOfInt( style, "stroke-width", &width );
2441|            StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
2442|          }
2443|          if ( transform != NULL )
2444|            transform = strchr( transform, '(' );
2445|
2446|          Rect_Ex*  r = new Rect_Ex;
2447|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2448|          elem->p = r;
2449|          if ( pGroup != NULL ) {
2450|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2451|            elem->p = r;
2452|          }
2453|
2454|          r->m_id = GetNewPrimID();
2455|          r->m_IdLabel = ( id == NULL ? label : id );
2456|          r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
2457|          r->m_Target = target;
2458|          Rect_init_by2XY( &r->m_Rect, cx - rx, cy - ry, cx + rx, cy + ry );
2459|          r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
2460|          r->m_ShapeType = Rect_CircleShape;
2461|          r->m_BorderWidth = width;
2462|          r->m_BorderColor = lineColor;
2463|          r->m_FillColor = fillColor;
2464|          r->m_NTrans = (int)(opacity * 100);
2465|        }
2466|        else if ( stricmp( p, "image" ) == 0 ) {
2467|          int  x, y, width, height;
2468|          char  imgPath[_MAX_PATH];
2469|          char  imgWorkPath[_MAX_PATH];
2470|          char  src[_MAX_PATH];
2471|          long  img_base64pos = -1;
2472|          bool  bEmbedImg = true;
2473|
2474|          #ifdef  SVGCATS_LOAD_TRACE
2475|           Errors_printf( "image(rect) id=%d", m_NextID );
2476|          #endif
2477|
2478|          id = XMLPars_getValue( &xmlp, "id" );
2479|          if ( XMLPars_getValue( &xmlp, "x" ) == NULL )  formatError();
2480|          x = atoi( XMLPars_getValue( &xmlp, "x" ) );
2481|          y = atoi( XMLPars_getValue( &xmlp, "y" ) );
2482|          width = atoi( XMLPars_getValue( &xmlp, "width" ) ) ;
2483|          height = atoi( XMLPars_getValue( &xmlp, "height" ) ) ;
2484|          transform = XMLPars_getValue( &xmlp, "transform" );
2485|          c_try {
2486|            StrX_cpy( src, XMLPars_getValue( &xmlp, "xlink:href" ), sizeof(src) );
2487|            if ( strncmp( src, "data:;base64,", 13 ) == 0 ) {
2488|              BLex3_Pos  pos;
2489|              long  pos2;
2490|              FILE*  f = xmlp.engU.inherit_BLex3_Engine.f;
2491|              char*  p;
2492|
2493|              /* img_base64pos を得る */
2494|              pos2 = ftell( f );
2495|              XMLPars_getPos( &xmlp, &pos );
2496|              fseek( f, pos.pos, SEEK_SET );
2497|              while ( ! feof( f ) ) {
2498|                fgets( src, sizeof(src), f );
2499|                p = strstr( src, "xlink:href=" );
2500|                if ( p != NULL ) {
2501|                  p += 25;
2502|                  while ( *p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')  p++;
2503|                  img_base64pos = pos.pos + (p - src);
2504|                  break;
2505|                }
2506|                pos.pos = ftell( f );
2507|              }
2508|              fseek( f, pos2, SEEK_SET );
2509|
2510|              StrX_cpy( src, XMLPars_getValue( &xmlp, "src" ), sizeof(src) );
2511|            }
2512|            else  bEmbedImg = false;
2513|
2514|            StrX_cpyAbsPath2( imgPath, src, sizeof(imgPath), path );
2515|            if ( FileX_isExist( imgPath ) )  StrX_toLongPath( imgPath, imgPath );
2516|          }
2517|          c_catch ( Errors_Msg*, msg ) {
2518|            if ( msg->code == StrX_Err_NoMoreParentDir )
2519|              strcpy( imgPath, src );  /* 上記 StrX_cpyAbsPath2 より */
2520|            else
2521|              c_throw_again();
2522|          } c_end_catch;
2523|          if ( transform != NULL )
2524|            transform = strchr( transform, '(' );
2525|
2526|          /* 埋め込み画像ファイルを復活する */
2527|          strcpy( imgWorkPath, GetImgWorkFilePath( id_hWnd ) );
2528|          if ( ( strcmp( imgPath, Rect_Ex_EmbedImg ) == 0 || ! FileX_isExist( imgPath ) ) &&
2529|               img_base64pos != -1 ) {
2530|            FileX_scanBase64( xmlp.engU.inherit_BLex3_Engine.f, img_base64pos, imgWorkPath );
2531|            FileX_repairExt( imgWorkPath );
2532|          }
2533|          else {
2534|            StrX_chgExt( imgWorkPath, StrX_refExt( imgPath ) );
2535|          }
2536|
2537|          /* 図形を生成する */
2538|          Rect_Ex*  r = new Rect_Ex;
2539|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2540|          elem->p = r;
2541|          if ( pGroup != NULL ) {
2542|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2543|            elem->p = r;
2544|          }
2545|
2546|          r->m_id = GetNewPrimID();
2547|          r->m_IdLabel = ( id == NULL ? label : id );
2548|          r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
2549|          r->m_Target = target;
2550|          Rect_init( &r->m_Rect, x, y, width, height );
2551|          r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
2552|          r->m_ShapeType = Rect_ImageShape;
2553|          r->m_ImgPath = imgPath;
2554|          r->m_ImgWorkPath = imgWorkPath;
2555|          strcpy( r->m_ddb.path, imgWorkPath );  StrX_chgExt( r->m_ddb.path, "ddb" );
2556|          r->m_bEmbedImg = bEmbedImg;
2557|          r->m_BorderWidth = 1;
2558|          r->m_BorderColor = lineColor;
2559|          r->m_FillColor = fillColor;
2560|          r->m_bNeedReadImgProp = false;
2561|        }
2562|        else if ( stricmp( p, "polygon" ) == 0 ) {
2563|          int  n, dx, dy, width;
2564|          int  x[4], y[4];
2565|          double  opacity;
2566|
2567|          #ifdef  SVGCATS_LOAD_TRACE
2568|           Errors_printf( "polygon(rect) id=%d", m_NextID );
2569|          #endif
2570|
2571|          id = XMLPars_getValue( &xmlp, "id" );
2572|          p = XMLPars_getValue( &xmlp, "points" );
2573|          n = StrX_getSVGPoints( p, x, y, 4 );
2574|          if ( n == 4 ) {
2575|            dx = (x[1] + x[3])/2 - x[0];
2576|            dy = (y[0] + y[2])/2 - y[1];
2577|          }
2578|          if ( n == 4 && x[0] == x[2] && y[1] == y[3] &&
2579|               -1 <= dx && dx <= 1 && -1 <= dy && dy <= 1 ) {  /* Diamond */
2580|            style = XMLPars_getValue( &xmlp, "style" );
2581|            transform = XMLPars_getValue( &xmlp, "transform" );
2582|            width = 1;  opacity = 1.0;
2583|            if ( style != NULL ) {
2584|              StrX_getCSSValueOfColor( style, "fill", &fillColor );
2585|              StrX_getCSSValueOfColor( style, "stroke", &lineColor );
2586|              StrX_getCSSValueOfInt( style, "stroke-width", &width );
2587|              StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
2588|            }
2589|            if ( transform != NULL )
2590|              transform = strchr( transform, '(' );
2591|
2592|            Rect_Ex*  r = new Rect_Ex;
2593|            elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2594|            elem->p = r;
2595|            if ( pGroup != NULL ) {
2596|              elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2597|              elem->p = r;
2598|            }
2599|
2600|            r->m_id = GetNewPrimID();
2601|            r->m_IdLabel = ( id == NULL ? label : id );
2602|            r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
2603|            r->m_Target = target;
2604|            Rect_init_by2XY( &r->m_Rect, x[3], y[0], x[1]-1, y[2]-1 );
2605|            r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
2606|            r->m_ShapeType = Rect_DiamondShape;
2607|            r->m_BorderWidth = width;
2608|            r->m_BorderColor = lineColor;
2609|            r->m_FillColor = fillColor;
2610|            r->m_NTrans = (int)(opacity * 100);
2611|          }
2612|          else if ( n == 4 && y[0] == y[1] && y[2] == y[3] &&
2613|               x[1] - x[0] == x[2] - x[3] &&
2614|               ( 2 * ( x[0] - x[3] + 1 ) == y[3] - y[0] ||
2615|                 2 * ( x[0] - x[3] ) == y[3] - y[0] ||
2616|                 2 * ( x[0] - x[3] + 1 ) + 1 == y[3] - y[0] ||
2617|                 2 * ( x[0] - x[3] ) + 1 == y[3] - y[0] ) ) {  /* Parallelogram */
2618|            style = XMLPars_getValue( &xmlp, "style" );
2619|            transform = XMLPars_getValue( &xmlp, "transform" );
2620|            width = 1;  opacity = 1.0;
2621|            if ( style != NULL ) {
2622|              StrX_getCSSValueOfColor( style, "fill", &fillColor );
2623|              StrX_getCSSValueOfColor( style, "stroke", &lineColor );
2624|              StrX_getCSSValueOfInt( style, "stroke-width", &width );
2625|              StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
2626|            }
2627|            if ( transform != NULL )
2628|              transform = strchr( transform, '(' );
2629|
2630|            Rect_Ex*  r = new Rect_Ex;
2631|            elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2632|            elem->p = r;
2633|            if ( pGroup != NULL ) {
2634|              elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2635|              elem->p = r;
2636|            }
2637|
2638|            r->m_id = GetNewPrimID();
2639|            r->m_IdLabel = ( id == NULL ? label : id );
2640|            r->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
2641|            r->m_Target = target;
2642|            Rect_init_by2XY( &r->m_Rect, (x[0]+x[3])/2, y[0], (x[1]+x[2])/2-1, y[2]-1 );
2643|            r->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
2644|            r->m_ShapeType = Rect_Parallelogram;
2645|            r->m_BorderWidth = width;
2646|            r->m_BorderColor = lineColor;
2647|            r->m_FillColor = fillColor;
2648|            r->m_NTrans = (int)(opacity * 100);
2649|          }
2650|          else {  /* Polygon */
2651|            style = XMLPars_getValue( &xmlp, "style" );
2652|            transform = XMLPars_getValue( &xmlp, "transform" );
2653|            width = 1;  opacity = 1.0;
2654|            if ( style != NULL ) {
2655|              StrX_getCSSValueOfColor( style, "fill", &fillColor );
2656|              StrX_getCSSValueOfColor( style, "stroke", &lineColor );
2657|              StrX_getCSSValueOfInt( style, "stroke-width", &width );
2658|              StrX_getCSSValueOfDouble( style, "fill-opacity", &opacity );
2659|            }
2660|            if ( transform != NULL )
2661|              transform = strchr( transform, '(' );
2662|
2663|            Polygon_Ex*  p = new Polygon_Ex;
2664|            elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2665|            elem->p = p;
2666|            if ( pGroup != NULL ) {
2667|              elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2668|              elem->p = p;
2669|            }
2670|
2671|            p->m_id = GetNewPrimID();
2672|            p->m_IdLabel = ( id == NULL ? label : id );
2673|            p->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
2674|            p->m_Target = target;
2675|            p->m_NPoint = n;
2676|            p->m_Points = (POINT*)malloc( n * sizeof(POINT) );
2677|            while ( --n >= 0 ) {
2678|              p->m_Points[n].x = x[n];  p->m_Points[n].y = y[n];
2679|            }
2680|            p->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
2681|            p->m_BorderWidth = width;
2682|            p->m_BorderColor = lineColor;
2683|            p->m_FillColor = fillColor;
2684|            p->m_NTrans = (int)(opacity * 100);
2685|          }
2686|        }
2687|        else if ( stricmp( p, "path" ) == 0 ) { /* Matome */
2688|          int  n, x1, y1, x2, y2, x3, y3, width;
2689|          char*  subtype;
2690|          char*  d;
2691|          Matome*  m;
2692|
2693|          #ifdef  SVGCATS_LOAD_TRACE
2694|           Errors_printf( "path" );
2695|          #endif
2696|
2697|          subtype = XMLPars_getValue( &xmlp, "subtype" );
2698|          if ( strcmp( subtype, "matome" ) == 0 ) {
2699|            d = XMLPars_getValue( &xmlp, "d" );
2700|            style = XMLPars_getValue( &xmlp, "style" );
2701|            width = 1;
2702|            if ( style != NULL ) {
2703|              StrX_getCSSValueOfColor( style, "stroke", &lineColor );
2704|              StrX_getCSSValueOfInt( style, "stroke-width", &width );
2705|            }
2706|
2707|            for ( n = 0; ; n++ ) {
2708|              if ( n == 0 )        x1 = atoi( d+1 );
2709|              else if ( n == 1 )   y1 = atoi( d );
2710|              else if ( n == 16 )  x2 = atoi( d );
2711|              else if ( n == 17 )  y2 = atoi( d );
2712|              else if ( n == 32 )  x3 = atoi( d );
2713|              else if ( n == 33 )  { y3 = atoi( d ); break; }
2714|              d = StrX_strchrs( d, ", " );
2715|              if ( d == NULL )  break;
2716|              do {
2717|                d++;
2718|              } while ( *d == ',' || *d == ' ' );
2719|            }
2720|            if ( n == 33 ) {
2721|              m = new Matome;
2722|
2723|              elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2724|              elem->p = m;
2725|              if ( pGroup != NULL ) {
2726|                elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2727|                elem->p = m;
2728|              }
2729|
2730|              m->m_id = GetNewPrimID();
2731|              m->m_BorderWidth = width;
2732|              m->m_BorderColor = lineColor;
2733|              if ( x1 == x3 ) {
2734|                m->m_x1 = x2;  m->m_y1 = (y1 < y3) ? y1 : y3;
2735|                m->m_x2 = x3;  m->m_y2 = (y1 < y3) ? y3 : y1;
2736|              }
2737|              else {
2738|                m->m_x1 = (x1 < x3) ? x1 : x3;  m->m_y1 = y2;
2739|                m->m_x2 = (x1 < x3) ? x3 : x1;  m->m_y2 = y3;
2740|              }
2741|            }
2742|          }
2743|        }
2744|        break;
2745|
2746|       case XMLPars_StartTag:   /*================================================== */
2747|        p = XMLPars_getTagName( &xmlp );
2748|        if ( stricmp( p, "svg" ) == 0 ) {
2749|          char*  interval = XMLPars_getValue( &xmlp, "onload" );
2750|          char*  corr;
2751|
2752|          file->m_Canvas.m_Width = atoi2( XMLPars_getValue( &xmlp, "width" ), file->m_Canvas.m_DefWidth );
2753|          file->m_Canvas.m_Height = atoi2( XMLPars_getValue( &xmlp, "height" ), file->m_Canvas.m_DefHeight );
2754|          corr = XMLPars_getValue( &xmlp, "corr-image" );
2755|          if ( corr == NULL )
2756|            file->m_Canvas.m_CorrImagePath[0] = '\0';
2757|          else
2758|            strcpy( file->m_Canvas.m_CorrImagePath, corr );
2759|
2760|          if ( interval != NULL )
2761|            file->m_Canvas.m_NextPageInterval = atoi( strchr( interval, ',' ) + 1 );
2762|        }
2763|        else if ( stricmp( p, "page" ) == 0 ) {  /* pagesタグの中, 開始タグ */
2764|          int  iPage = atoi( XMLPars_getValue( &xmlp, "num" ) );
2765|          SVGCat_Page*  page = ListX_get( &file->m_pages, iPage - file->m_StartPageNum, SVGCat_Page );
2766|          SVGCat_Page*  prevPage = ListX_get( &file->m_pages, iPrevPage - file->m_StartPageNum, SVGCat_Page );
2767|          SVGCat_Page*  childPage = ListX_Elem_getNextT( page, SVGCat_Page );
2768|
2769|          if ( iPrevPage == 0 )  prevPage = NULL;
2770|
2771|          page->firstChild = childPage;  childPage->parent = page;
2772|          page->prev = prevPage;
2773|          if ( prevPage != NULL ) {
2774|            prevPage->next = page;
2775|            page->parent = prevPage->parent;
2776|          }
2777|          page->next = NULL;  /* デフォルト(次のページ)とは限らないため */
2778|          StrX_cpy( page->title, XMLPars_getValue( &xmlp, "title" ), sizeof(page->title) );
2779|          if ( page->title[0] == '\0' )  strcpy( page->title, "Page" );
2780|          iMaxPage = ListX_getI( &file->m_pages, page );
2781|          iPrevPage = -1;
2782|        }
2783|        else if ( stricmp( p, "a" ) == 0 ) {
2784|          char*  target0;
2785|          char*  href0;
2786|
2787|          c_try {
2788|
2789|            href0 = XMLPars_getValue( &xmlp, "xlink:href" );
2790|            if ( href0 != NULL ) {
2791|              StrX_cpyAbsPath2( href, href0, sizeof(href), path );
2792|              if ( FileX_isExist( href ) )
2793|                StrX_toLongPath( href, href );
2794|            }
2795|          }
2796|          c_catch ( Errors_Msg*, msg ) {
2797|            if ( msg->code == StrX_Err_NoMoreParentDir )
2798|              strcpy( href, XMLPars_getValue( &xmlp, "xlink:href" ) );
2799|            else
2800|              c_throw_again();
2801|          } c_end_catch;
2802|          target0 = XMLPars_getValue( &xmlp, "target" );
2803|          strcpy( target, (target0 == NULL ? "" : target0) );
2804|        }
2805|        else if ( stricmp( p, "g" ) == 0 ) {
2806|          char*  id = XMLPars_getValue( &xmlp, "id" );
2807|          char*  onclick = XMLPars_getValue( &xmlp, "onclick" );
2808|          char*  href0 = XMLPars_getValue( &xmlp, "href" );
2809|          char*  type;
2810|
2811|          #ifdef  SVGCATS_LOAD_TRACE
2812|           Errors_printf( "g" );
2813|          #endif
2814|
2815|          label[0] = '\0';
2816|
2817|          if ( id != NULL && strcmp( id, "svgcats-ink" ) == 0 ) {
2818|            bInInk = true;
2819|            nInkInPage++;
2820|            type = XMLPars_getValue( &xmlp, "type" );
2821|            if ( type == NULL )
2822|              ink_raster = ( ListX_isEmpty( &file->m_prims ) ? IRO_MaskPen : IRO_CopyPen );
2823|            else
2824|              ink_raster = ( strcmp( type, "front" ) == 0 ? IRO_CopyPen : IRO_MaskPen );
2825|            ink_start = xmlp.htmlPars.parsedPos.pos;
2826|          }
2827|
2828|          if ( id != NULL && ( ( strncmp( id, "page", 4 ) == 0 && atoi( id+4 ) != 0 ) ||
2829|               strcmp( id, "backpage" ) == 0 ) ) {
2830|            bInPageTag = true;
2831|            nInkInPage = 0;
2832|
2833|            if ( strcmp( id, "backpage" ) == 0 );
2834|            else if ( strcmp( id, "page1" ) != 0 ) {
2835|              NewPage( file, false );
2836|            }
2837|            else if ( ! ListX_isEmpty( &file->m_prims ) ) {
2838|              SVGCat_Page*  page;
2839|
2840|              ChgToBackPage( file );
2841|              SwapPage( file, 0, 1 );
2842|              ChgPage( file, -1 );
2843|              page = ListX_getFirst( &file->m_pages, SVGCat_Page );
2844|              page->next = NULL;
2845|              ListX_Elem_getNextT( page, SVGCat_Page )->prev = NULL;
2846|              ChgPage( file, 1 );
2847|            }
2848|            file->m_Canvas.m_Width = atoi( XMLPars_getValue( &xmlp, "width" ) );
2849|            file->m_Canvas.m_Height = atoi( XMLPars_getValue( &xmlp, "height" ) );
2850|            XMLPars_finish( &xmlp );  bXmlp = false;
2851|          }
2852|          else {
2853|            pGroup = &group;
2854|            elem = ListX_addFirstMalloc( &groupStack, ListX_ElemX );
2855|            elem->p = ListX_getLast( &group, ListX_ElemX );
2856|
2857|            if ( id != NULL && strcmp( id, "svgcats-ink" ) != 0 )
2858|              strcpy( label, id );
2859|          }
2860|
2861|          if ( href0 != NULL )
2862|            strcpy( href, href0 );
2863|          else if ( onclick != NULL )
2864|            sprintf( href, "script:%s", onclick );
2865|          else
2866|            href[0] = '\0';
2867|        }
2868|        else if ( stricmp( p, "text" ) == 0 ) {
2869|          char    font[40];
2870|          int     size;
2871|          RECT    textRect;
2872|          char    weight[40];
2873|          char    font_style[255];
2874|          char    text_anchor[40];
2875|          char*   writing_mode;
2876|
2877|          #ifdef  SVGCATS_LOAD_TRACE
2878|           Errors_printf( "text (tag)" );
2879|          #endif
2880|
2881|          /* default */
2882|          strcpy( font, m_bJapanese ? "MS Pゴシック" : "Arial" );
2883|          size = 8;
2884|          strcpy( weight, "normal" );
2885|          strcpy( font_style, "" );
2886|
2887|          /* read */
2888|          id = XMLPars_getValue( &xmlp, "id" );
2889|          textRect.left = atoi2( XMLPars_getValue( &xmlp, "x" ), 250 );
2890|          textRect.top = atoi2( XMLPars_getValue( &xmlp, "y" ), 150 );
2891|          textRect.right = textRect.left + 10;
2892|          textRect.bottom = textRect.top + 10;
2893|          style = XMLPars_getValue( &xmlp, "style" );
2894|          transform = XMLPars_getValue( &xmlp, "transform" );
2895|          writing_mode = XMLPars_getValue( &xmlp, "writing-mode" );
2896|          if ( style != NULL ) {
2897|            StrX_getCSSValueOfColor( style, "fill", &lineColor );
2898|            StrX_getCSSValueOfStr( style, "font-family", font, sizeof(font) );
2899|            StrX_getCSSValueOfInt( style, "font-size", &size );
2900|            StrX_getCSSValueOfStr( style, "font-weight", weight, sizeof(weight) );
2901|            StrX_getCSSValueOfStr( style, "font-style", font_style, sizeof(font_style) );
2902|            StrX_getCSSValueOfStr( style, "text-anchor", text_anchor, sizeof(text_anchor) );
2903|          }
2904|          if ( transform != NULL )
2905|            transform = strchr( transform, '(' );
2906|
2907|          if ( strcmp( font, "MS-Gothic" ) == 0 )  strcpy( font, "MS ゴシック" );
2908|          else if ( strcmp( font, "MS-PGothic" ) == 0 )  strcpy( font, "MS Pゴシック" );
2909|          else if ( strcmp( font, "MS-Mincho" ) == 0 )  strcpy( font, "MS 明朝" );
2910|          else if ( strcmp( font, "MS-PMincho" ) == 0 )  strcpy( font, "MS P明朝" );
2911|
2912|          /* construct */
2913|          text = new Text_Box;
2914|          elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
2915|          elem->p = text;
2916|          if ( pGroup != NULL ) {
2917|            elem = ListX_addLastMalloc( pGroup, ListX_ElemX );
2918|            elem->p = text;
2919|          }
2920|
2921|          text->m_id = GetNewPrimID();
2922|          text->m_IdLabel = ( id == NULL ? label : id );
2923|          text->m_URL = StrX_resumeFromHtmlTxt( href, href, sizeof(href) );
2924|          text->m_Target = target;
2925|          text->m_CenterX = textRect.left;
2926|          text->m_Y = textRect.top;
2927|          text->m_RotateDegree = ( transform == NULL ? 0 : atoi( transform + 1 ) );
2928|          text->m_Color = lineColor;
2929|          text->m_Font = font;
2930|          text->m_Size = size;
2931|          text->m_bBold = ( stricmp( weight, "bold" ) == 0 || atoi( weight ) > 400 );
2932|          text->m_bItalic = ( stricmp( font_style, "italic" ) == 0 );
2933|          if ( stricmp( text_anchor, "middle" ) == 0 )  text->m_BasePos = Text_Box_CenterAlign;
2934|          else if ( stricmp( text_anchor, "end" ) == 0 )  text->m_BasePos = Text_Box_RightAlign;
2935|          else  text->m_BasePos = Text_Box_LeftAlign;
2936|          text->m_bTategaki = ( writing_mode != NULL && stricmp( writing_mode, "tb" ) == 0 );
2937|          text->m_BoxShape = 0;
2938|          iTextLine = 1;
2939|        }
2940|        else if ( stricmp( p, "tspan" ) == 0 ) {
2941|          int  y = atoi2( XMLPars_getValue( &xmlp, "y" ), 0 );
2942|          iTextLine ++;
2943|
2944|          if ( text == NULL )  formatError();
2945|          if ( iTextLine == 2 ) {
2946|            text->m_BetweenOfLine = ( y - text->m_Y );
2947|          }
2948|        }
2949|        else if ( stricmp( p, "svgcats-ink-rawdata" ) == 0 ) {
2950|          FILE*    f = xmlp.engU.inherit_BLex3_Engine.f;
2951|          WCHAR*   data;
2952|          SVGCat_Page*  page =
2953|            ListX_get( &file->m_pages, file->m_CurrentPageNum - file->m_StartPageNum, SVGCat_Page );
2954|
2955|          fseek( f, xmlp.htmlPars.parsedPos.pos, SEEK_SET );
2956|          data = ((CMainFrame*)m_pMainWnd)->m_wndView->InInkRawData( f );
2957|          Variant_initBSTR( &page->ink, data );
2958|          free( data );
2959|        }
2960|
2961|        break;
2962|
2963|       case XMLPars_TextBetweenTags:
2964|        p = XMLPars_getTagName( &xmlp );
2965|        if ( stricmp( p, "text" ) == 0 ) {
2966|          char  s[Text_Box_nByteInLine + 4];
2967|
2968|          #ifdef  SVGCATS_LOAD_TRACE
2969|           Errors_printf( "text (data)" );
2970|          #endif
2971|
2972|          XMLPars_getText( &xmlp, 0, s, sizeof(s) );
2973|          StrX_resumeFromHtmlTxt( s, s, sizeof(s) );
2974|
2975|          text->m_Text = s;
2976|        }
2977|        else if ( stricmp( p, "tspan" ) == 0 ) {
2978|          char  s[Text_Box_nByteInLine + 4];
2979|
2980|          XMLPars_getText( &xmlp, 0, s, sizeof(s) );
2981|          StrX_resumeFromHtmlTxt( s, s, sizeof(s) );
2982|
2983|          if ( text == NULL )  formatError();
2984|          text->m_Text = text->m_Text + "\r\n" + s;
2985|        }
2986|        break;
2987|
2988|       case XMLPars_EndTag:
2989|        p = XMLPars_getTagName( &xmlp );
2990|
2991|        if ( stricmp( p, "/text" ) == 0 ) {
2992|          #ifdef  SVGCATS_LOAD_TRACE
2993|            Errors_printf( "/text" );
2994|          #endif
2995|        }
2996|
2997|        else if ( stricmp( p, "/a" ) == 0 ) {
2998|          href[0] = '\0';
2999|          target[0] = '\0';
3000|        }
3001|
3002|        else if ( stricmp( p, "/page" ) == 0 ) {  /* 終了タグ */
3003|          SVGCat_Page*  page = ListX_get( &file->m_pages, iPrevPage - file->m_StartPageNum, SVGCat_Page );
3004|
3005|          iPrevPage = ListX_getI( &file->m_pages, page->parent ) + file->m_StartPageNum;
3006|        }
3007|
3008|
3009|        /* グループを解析して複合図形に変更する ============================================*/
3010|        else if ( stricmp( p, "/g" ) == 0 ) {
3011|          ListX_ElemX*  first;
3012|          int  n;
3013|
3014|          if ( pGroup == NULL ) {
3015|            if ( bInPageTag )  { bInPageTag = false;  break; /* exit switch */  }
3016|            else  formatError();  /* </g> が多すぎる */
3017|          }
3018|
3019|          n = ListX_getN( pGroup, ListX_ElemX );
3020|
3021|          elem = ListX_getFirst( &groupStack, ListX_ElemX );
3022|          if ( elem == NULL )  formatError();
3023|
3024|          first = (ListX_ElemX*)elem->p;
3025|          if ( first == NULL )
3026|            first = ListX_getFirst( pGroup, ListX_ElemX );
3027|          else
3028|            first = ListX_Elem_getNextT( first, ListX_ElemX );
3029|
3030|          #ifdef  SVGCATS_LOAD_TRACE
3031|           if ( first == NULL )  Errors_printf( "/g  first = NULL" );
3032|           else Errors_printf( "/g  first id = %d", ((CadPrim*)first->p)->GetID() );
3033|          #endif
3034|
3035|          if ( bInInk && ListX_getN( &groupStack, ListX_ElemX ) == 1 ) {
3036|            FILE*  f = FileX_open( GetInkWorkFilePath( file->m_id,
3037|              file->m_CurrentPageNum, ink_raster ), "wb" );
3038|
3039|            fprintf( f, "\t<g id=\"svgcats-ink\" type=\"%s\">",
3040|              ink_raster == IRO_CopyPen ? "front" : "back" );
3041|            FileX_outPart( f, xmlp.engU.inherit_BLex3_Engine.f,
3042|              ink_start, xmlp.htmlPars.parsedPos.pos );
3043|            fprintf( f, "\r\n" );
3044|            fclose( f );
3045|            bInInk = false;
3046|          }
3047|          else if ( first == NULL );  /* 空のグループ */
3048|          else if ( n == 1 ) {
3049|
3050|            /* グループが1本のラインのときは、折れ線にする */
3051|            if ( ((CadPrim*)first->p)->GetTypeID() == Line_Ex_TypeID ) {
3052|              Line_Ex*  line = (Line_Ex*)first->p;
3053|              Line_Corner*  lc = new Line_Corner;
3054|              lc->m_id = GetNewPrimID();
3055|
3056|              lc->m_Line.x1 = line->m_Line.x1;  lc->m_Line.y1 = line->m_Line.y1;
3057|              lc->m_Line.x2 = line->m_Line.x2;  lc->m_Line.y2 = line->m_Line.y2;
3058|              lc->m_Arrow1 = line->m_Arrow1;
3059|              lc->m_Arrow2 = line->m_Arrow2;
3060|              lc->m_ArrowsInReading = line->m_ArrowsInReading;
3061|                line->m_ArrowsInReading = NULL;  /* avoid free in destructor */
3062|              lc->m_Width = line->m_Width;
3063|              lc->m_Color = line->m_Color;
3064|              lc->m_bDash = line->m_bDash;
3065|              lc->m_SlideCorner = false;
3066|              lc->m_Dir = Line_DirN;
3067|              lc->m_CornerX = (line->m_Line.x1 + line->m_Line.x2) / 2;
3068|              lc->m_CornerY = (line->m_Line.y1 + line->m_Line.y2) / 2;
3069|
3070|              RemovePrimI( file, (CadPrim*)first->p );
3071|              elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
3072|              elem->p = lc;
3073|            }
3074|          }
3075|
3076|          /* Rect_Ex Text_Box のときは、枠付きテキストにする */
3077|          else if ( ((CadPrim*)first->p)->GetTypeID() == Rect_Ex_TypeID ) {
3078|
3079|            #ifdef  SVGCATS_LOAD_TRACE
3080|              Errors_printf( "Text_Box = rect + text" );
3081|            #endif
3082|
3083|            elem = ListX_Elem_getNextT( first, ListX_ElemX );
3084|            if ( elem != NULL && ((CadPrim*)elem->p)->GetTypeID() == Text_Box_TypeID && n == 2 ) {
3085|              Rect_Ex*   r = (Rect_Ex*)first->p;
3086|              Text_Box*  t = (Text_Box*)elem->p;
3087|              Text_Box*  b = new Text_Box;
3088|
3089|              b->m_id = GetNewPrimID();
3090|              b->m_Text = t->m_Text;
3091|              b->m_IdLabel = t->m_IdLabel;
3092|              b->m_URL = t->m_URL;
3093|              b->m_Target = t->m_Target;
3094|              b->m_CenterX = t->m_CenterX;
3095|              b->m_Y = t->m_Y;
3096|              b->m_BetweenOfLine = t->m_BetweenOfLine;
3097|              b->m_RotateDegree = t->m_RotateDegree;
3098|              b->m_Color = t->m_Color;
3099|              b->m_Font = t->m_Font;
3100|              b->m_Size = t->m_Size;
3101|              b->m_bBold = t->m_bBold;
3102|              b->m_bItalic = t->m_bItalic;
3103|              b->m_BasePos = t->m_BasePos;
3104|              b->m_bTategaki = t->m_bTategaki;
3105|              switch ( r->m_ShapeType ) {  /* マイナスは、Text_Box::Draw時に下記の再設定をすることを示す */
3106|                case Rect_RectShape:      b->m_BoxShape = - Text_Box_RectShape;  break;
3107|                case Rect_RoundRectShape: b->m_BoxShape = - Text_Box_RoundRectShape;  break;
3108|                case Rect_CircleShape:    b->m_BoxShape = - Text_Box_CircleShape;  break;
3109|                case Rect_DiamondShape:   b->m_BoxShape = - Text_Box_DiamondShape;  break;
3110|                case Rect_ImageShape:     b->m_BoxShape = - Text_Box_RectShape;  break;
3111|                case Rect_Parallelogram:  b->m_BoxShape = - Text_Box_Parallelogram;  break;
3112|              }
3113|              b->m_BoxMarginX = r->m_Rect.x;  /* Text_Box::Draw時に再設定 */
3114|              b->m_BoxMarginY = r->m_Rect.y;  /* Text_Box::Draw時に再設定 */
3115|              b->m_DiffW = ( b->m_bTategaki ? r->m_Rect.h : r->m_Rect.w );
3116|              b->m_BorderWidth = r->m_BorderWidth;
3117|              b->m_BorderColor = r->m_BorderColor;
3118|              b->m_FillColor = r->m_FillColor;
3119|              b->m_FillNTrans = r->m_NTrans;
3120|
3121|              RemovePrimI( file, r );
3122|              RemovePrimI( file, t );
3123|              ListX_removeFree( &group, first );
3124|              ListX_removeFree( &group, elem );
3125|
3126|              elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
3127|              elem->p = b;
3128|            }
3129|          }
3130|          else if ( ((CadPrim*)first->p)->GetTypeID() == Line_Ex_TypeID ) {
3131|            Line_Ex*  line;
3132|
3133|            for ( ListX_forEach( pGroup, &elem, ListX_ElemX ) ) {
3134|              if ( ((CadPrim*)elem->p)->GetTypeID() != Line_Ex_TypeID )
3135|                break;
3136|              line = (Line_Ex*)elem->p;
3137|              if ( line->m_Line.x1 != line->m_Line.x2 &&line->m_Line.y1 != line->m_Line.y2 )
3138|                break;
3139|            }
3140|
3141|            /* すべて水平か垂直のラインのとき、折れ線として解析する */
3142|            if ( elem == NULL ) {
3143|              Line_Corner*  lc = new Line_Corner;
3144|
3145|              #ifdef  SVGCATS_LOAD_TRACE
3146|                Errors_printf( "Line_Corner" );
3147|              #endif
3148|
3149|              lc->m_id = GetNewPrimID();
3150|
3151|              line = (Line_Ex*)ListX_getFirst( pGroup, ListX_ElemX )->p;
3152|              lc->m_Line.x1 = line->m_Line.x1;  lc->m_Line.y1 = line->m_Line.y1;
3153|              if ( (int)line->m_ArrowsInReading == 1 ) {
3154|                if ( line->m_Arrow1 != 0 )  lc->m_Arrow1 = line->m_Arrow1;
3155|                if ( line->m_Arrow2 != 0 )  lc->m_Arrow1 = line->m_Arrow2;
3156|                if ( line->m_Controler_id[0] != 0 )  lc->m_Controler_id[0] = line->m_Controler_id[0];
3157|                if ( line->m_Controler_id[1] != 0 )  lc->m_Controler_id[0] = line->m_Controler_id[1];
3158|                line->m_ArrowsInReading = NULL;
3159|              }
3160|              else if ( line->m_ArrowsInReading != NULL ) {
3161|                lc->m_ArrowsInReading = line->m_ArrowsInReading;
3162|                line->m_ArrowsInReading = NULL;
3163|                lc->m_Arrow1 = line->m_Arrow1;
3164|              }
3165|
3166|              line = (Line_Ex*)ListX_getLast( pGroup, ListX_ElemX )->p;
3167|              lc->m_Line.x2 = line->m_Line.x2;  lc->m_Line.y2 = line->m_Line.y2;
3168|              if ( (int)line->m_ArrowsInReading == 1 ) {
3169|                if ( line->m_Arrow1 != 0 )  lc->m_Arrow2 = line->m_Arrow1;
3170|                if ( line->m_Arrow2 != 0 )  lc->m_Arrow2 = line->m_Arrow2;
3171|                if ( line->m_Controler_id[0] != 0 )  lc->m_Controler_id[1] = line->m_Controler_id[0];
3172|                if ( line->m_Controler_id[1] != 0 )  lc->m_Controler_id[1] = line->m_Controler_id[1];
3173|                line->m_ArrowsInReading = NULL;
3174|              }
3175|              else if ( line->m_ArrowsInReading != NULL ) {
3176|                if ( lc->m_Arrow1 == 0 ) {
3177|                  lc->m_ArrowsInReading = line->m_ArrowsInReading;
3178|                  line->m_ArrowsInReading = NULL;
3179|                  lc->m_Arrow1 = line->m_Arrow1;
3180|                }
3181|                else {
3182|                  free( line->m_ArrowsInReading );
3183|                  line->m_ArrowsInReading = NULL;
3184|                  lc->m_Arrow2 = line->m_Arrow1;
3185|                }
3186|              }
3187|              lc->m_Width = line->m_Width;
3188|              lc->m_Color = line->m_Color;
3189|              lc->m_bDash = line->m_bDash;
3190|              lc->m_SlideCorner = false;
3191|
3192|              line = (Line_Ex*)ListX_getFirst( pGroup, ListX_ElemX )->p;
3193|              if ( line->m_Line.x2 < line->m_Line.x1 ) {
3194|                line = (Line_Ex*)ListX_get( pGroup, 1,  ListX_ElemX )->p;
3195|                lc->m_CornerX = line->m_Line.x2;
3196|                if ( line->m_Line.y2 == lc->m_Line.y2 )
3197|                  lc->m_CornerY = (line->m_Line.y1 + line->m_Line.y2) / 2;
3198|                else
3199|                  lc->m_CornerY = line->m_Line.y2;
3200|                lc->m_Dir = Line_DirN;
3201|              }
3202|              else if ( line->m_Line.x1 == line->m_Line.x2 ) {
3203|                line = (Line_Ex*)ListX_get( pGroup, 1,  ListX_ElemX )->p;
3204|                if ( line->m_Line.x2 <= lc->m_Line.x2 )
3205|                  lc->m_CornerX = (line->m_Line.x1 + line->m_Line.x2) / 2;
3206|                else
3207|                  lc->m_CornerX = line->m_Line.x2;
3208|                lc->m_CornerY = line->m_Line.y1;
3209|                lc->m_Dir = Line_DirN;
3210|              }
3211|              else {
3212|                if ( line->m_Line.x2 < lc->m_Line.x2 ) {
3213|                  lc->m_CornerX = line->m_Line.x2;
3214|                  line = (Line_Ex*)ListX_get( pGroup, 1,  ListX_ElemX )->p;
3215|                  lc->m_CornerY = (line->m_Line.y1 + line->m_Line.y2) / 2;
3216|                }
3217|                else if ( line->m_Line.x2 == lc->m_Line.x2 ) {
3218|                  lc->m_CornerX = line->m_Line.x2;
3219|                  lc->m_CornerY = line->m_Line.y2;
3220|                }
3221|                else {
3222|                  line = (Line_Ex*)ListX_get( pGroup, 1,  ListX_ElemX )->p;
3223|                  if ( line->m_Line.y2 > lc->m_Line.y2 )
3224|                    { lc->m_CornerX = line->m_Line.x2;  lc->m_CornerY = line->m_Line.y2; }
3225|                  else {
3226|                    lc->m_CornerX = line->m_Line.x2;
3227|                    lc->m_CornerY = (line->m_Line.y1 + line->m_Line.y2) / 2;
3228|                  }
3229|                }
3230|                lc->m_Dir = Line_DirZ;
3231|              }
3232|
3233|              {
3234|                ListX_ElemX*  elem2;
3235|                int  i, n = 0;
3236|
3237|                elem2 = ListX_getFirst( &groupStack, ListX_ElemX );
3238|
3239|                for ( ListX_forEach( pGroup, &elem, ListX_ElemX ) ) {
3240|                  RemovePrimI( file, (CadPrim*)elem->p );
3241|                  n++;
3242|                }
3243|
3244|                first = (ListX_ElemX*)elem2->p;
3245|                if ( first == NULL )
3246|                  elem = ListX_getFirst( pGroup, ListX_ElemX );
3247|                else
3248|                  elem = ListX_Elem_getNextT( first, ListX_ElemX );
3249|
3250|                for ( i = 0; i < n; i++ ) {
3251|                  elem2 = ListX_Elem_getNextT( elem, ListX_ElemX );
3252|                  ListX_removeFree( &group, elem );
3253|                  elem = elem2;
3254|                }
3255|              }
3256|
3257|              elem = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
3258|              elem->p = lc;
3259|            }
3260|
3261|
3262|            /* 矢印付きラインを解析する */
3263|            else {
3264|              ListX_ElemX*  prim1;
3265|              ListX_ElemX*  prim2;
3266|              Line_Ex*  line = (Line_Ex*)first->p;
3267|
3268|              #ifdef  SVGCATS_LOAD_TRACE
3269|                Errors_printf( "Line m_ArrowX" );
3270|              #endif
3271|
3272|              if ( line->m_ArrowsInReading == NULL )
3273|                line->m_ArrowsInReading = (Line*)malloc( sizeof(Line) );
3274|
3275|              /* group をループする。groupStack の最初から */
3276|              for ( prim1 = ListX_Elem_getNextT( first, ListX_ElemX );  prim1 != NULL; ) {
3277|
3278|                /* Type1 の矢印を解析する */
3279|                if ( prim1 == NULL )  prim2 = NULL;
3280|                else   prim2 = ListX_Elem_getNextT( prim1, ListX_ElemX );
3281|
3282|                if ( ((CadPrim*)prim1->p)->GetTypeID() == Line_Ex_TypeID &&
3283|                     prim2 != NULL && ((CadPrim*)prim2->p)->GetTypeID() == Line_Ex_TypeID ) {
3284|                  Line_Ex*  line1 = (Line_Ex*)prim1->p;
3285|                  Line_Ex*  line2 = (Line_Ex*)prim2->p;
3286|
3287|                  if ( line1->m_Line.x1 == line2->m_Line.x1 && line1->m_Line.y1 == line2->m_Line.y1 ) {
3288|                    if ( (int)line->m_ArrowsInReading != 1 ) {
3289|                      if ( line->m_Arrow1 == 0 ) {
3290|                        line->m_Arrow1 = 1;  /* Load2 でどちらの頂点につくか決定する */
3291|                        line->m_ArrowsInReading->x1 = line1->m_Line.x1;
3292|                        line->m_ArrowsInReading->y1 = line1->m_Line.y1;
3293|                      }
3294|                      else {
3295|                        line->m_Arrow2 = 1;
3296|                        line->m_ArrowsInReading->x2 = line1->m_Line.x1;
3297|                        line->m_ArrowsInReading->y2 = line1->m_Line.y1;
3298|                      }
3299|                    }
3300|
3301|                    RemovePrimI( file, line1 );
3302|                    RemovePrimI( file, line2 );
3303|                    elem = ListX_Elem_getNextT( prim2, ListX_ElemX );
3304|                    ListX_removeFree( &group, prim1 );
3305|                    ListX_removeFree( &group, prim2 );
3306|                    prim1 = elem;
3307|                  }
3308|                  else
3309|                    prim1 = ListX_Elem_getNextT( prim2, ListX_ElemX );
3310|                }
3311|
3312|                /* Type2, Type4 の矢印を解析する */
3313|                else if ( ((CadPrim*)prim1->p)->GetTypeID() == Rect_Ex_TypeID ) {
3314|                  Rect_Ex*  rect = (Rect_Ex*)prim1->p;
3315|
3316|                  if ( rect->m_ShapeType == Rect_CircleShape ) {
3317|                    if ( (int)line->m_ArrowsInReading != 1 ) {
3318|                      if ( line->m_Arrow1 == 0 ) {
3319|                        line->m_Arrow1 = ( rect->m_FillColor == rect->m_BorderColor ? 2 : 5 );
3320|                        line->m_ArrowsInReading->x1 = rect->m_Rect.x + rect->m_Rect.w / 2;
3321|                        line->m_ArrowsInReading->y1 = rect->m_Rect.y + rect->m_Rect.h / 2;
3322|                      }
3323|                      else {
3324|                        line->m_Arrow2 = ( rect->m_FillColor == rect->m_BorderColor ? 2 : 5 );
3325|                        line->m_ArrowsInReading->x2 = rect->m_Rect.x + rect->m_Rect.w / 2;
3326|                        line->m_ArrowsInReading->y2 = rect->m_Rect.y + rect->m_Rect.h / 2;
3327|                      }
3328|                    }
3329|
3330|                    RemovePrimI( file, rect );
3331|                    ListX_removeFree( &group, prim1 );
3332|                  }
3333|                  else if ( rect->m_ShapeType == Rect_DiamondShape ) {
3334|                    if ( (int)line->m_ArrowsInReading != 1 ) {
3335|                      if ( line->m_Arrow1 == 0 ) {
3336|                        line->m_Arrow1 = ( rect->m_FillColor == rect->m_BorderColor ? 4 : 7 );
3337|                        line->m_ArrowsInReading->x1 = rect->m_Rect.x + rect->m_Rect.w / 2;
3338|                        line->m_ArrowsInReading->y1 = rect->m_Rect.y + rect->m_Rect.h / 2;
3339|                      }
3340|                      else {
3341|                        line->m_Arrow2 = ( rect->m_FillColor == rect->m_BorderColor ? 4 : 7 );
3342|                        line->m_ArrowsInReading->x2 = rect->m_Rect.x + rect->m_Rect.w / 2;
3343|                        line->m_ArrowsInReading->y2 = rect->m_Rect.y + rect->m_Rect.h / 2;
3344|                      }
3345|                    }
3346|
3347|                    RemovePrimI( file, rect );
3348|                    ListX_removeFree( &group, prim1 );
3349|                  }
3350|
3351|                  prim1 = prim2;
3352|                }
3353|
3354|                /* Type3, Type4 の矢印を解析する */
3355|                else if ( ((CadPrim*)prim1->p)->GetTypeID() == Polygon_Ex_TypeID ) {
3356|                  Polygon_Ex*  p = (Polygon_Ex*)prim1->p;
3357|
3358|                  if ( p->m_NPoint == 3 || p->m_NPoint == 4 ) {
3359|                    if ( (int)line->m_ArrowsInReading != 1 ) {
3360|                      if ( line->m_Arrow1 == 0 ) {
3361|                        line->m_Arrow1 = p->m_NPoint +
3362|                          ( p->m_FillColor == p->m_BorderColor ? 0 : 3 );
3363|                      }
3364|                      else {
3365|                        line->m_Arrow2 = p->m_NPoint +
3366|                          ( p->m_FillColor == p->m_BorderColor ? 0 : 3 );
3367|                      }
3368|                      line->m_ArrowsInReading->x1 = p->m_Points[0].x;
3369|                      line->m_ArrowsInReading->y1 = p->m_Points[0].y;
3370|                    }
3371|
3372|                    RemovePrimI( file, p );
3373|                    ListX_removeFree( &group, prim1 );
3374|                  }
3375|
3376|                  prim1 = prim2;
3377|                }
3378|
3379|                else {
3380|                  prim1 = prim2;
3381|                }
3382|              }
3383|            }
3384|          }
3385|
3386|          elem = ListX_getFirst( &groupStack, ListX_ElemX );
3387|          if ( elem == NULL )  formatError();
3388|  #if 0
3389|          else {
3390|            elem = ListX_Elem_getNextT( (ListX_ElemX*)elem->p, ListX_ElemX );
3391|            if ( elem != NULL )
3392|              ListX_removeDeleteAfters( &group, elem, NULL );
3393|          }
3394|  #endif
3395|          ListX_removeFree( &groupStack, elem );
3396|          if ( ListX_isEmpty( &groupStack ) ) {
3397|            ListX_toEmptyDelete( &group, ListX_ElemX, NULL );
3398|            pGroup = NULL;
3399|          }
3400|        }
3401|        break;
3402|      }
3403|    }
3404|  }
3405|  c_finally {
3406|    if ( bXmlp )  XMLPars_finish( &xmlp );
3407|    if ( bUfile ) FileX_UniRead_finish( &ufile );
3408|    if ( svgzMeltedPath != NULL )  remove( svgzMeltedPath );
3409|    ListX_finish2( &groupStack, ListX_ElemX, NULL );
3410|    ListX_finish2( &group, ListX_ElemX, NULL );
3411|  } c_end_finally;
3412|}
3413|
3414| 
3415|/***********************************************************************
3416|  14. <<< [CSVGCatApp::Load2] SVG ファイルを開く step2 >>> 
3417|【補足】
3418|・Draw した後で呼び出してください。
3419|************************************************************************/
3420|void  CSVGCatApp::Load2( ListX* prims )
3421|{
3422|  /* リンクが必要な部分をリンクする */
3423|  {
3424|    ListX_ElemX*  p;
3425|    ListX_ElemX*  p2;
3426|    int  iHandle, diff;
3427|
3428|    for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
3429|      if ( ((CadPrim*)p->p)->GetTypeID() == Line_Ex_TypeID ) {
3430|        Line_Ex*  line = (Line_Ex*)p->p;
3431|
3432|        for ( ListX_forEach( prims, &p2, ListX_ElemX ) ) {
3433|          if ( p == p2 )  continue;
3434|
3435|          if ( line->m_Controler_id[0] < 0 ) {
3436|            diff = ( (int)line->m_Controler_id[0] == -1 ) ? 5 : 1;
3437|            iHandle = ((CadPrim*)p2->p)->GetLinkOnReadHandleNum( line->m_Line.x1, line->m_Line.y1, diff );
3438|            if ( iHandle > 0 )
3439|              ((CadPrim*)p2->p)->LinkToHandle( iHandle, (CadPrim*)p->p, 1 );
3440|          }
3441|          if ( line->m_Controler_id[1] < 0 ) {
3442|            diff = ( (int)line->m_Controler_id[1] == -1 ) ? 5 : 1;
3443|            iHandle = ((CadPrim*)p2->p)->GetLinkOnReadHandleNum( line->m_Line.x2, line->m_Line.y2, diff );
3444|            if ( iHandle > 0 )
3445|              ((CadPrim*)p2->p)->LinkToHandle( iHandle, (CadPrim*)p->p, 2 );
3446|          }
3447|        }
3448|      }
3449|      else if ( ((CadPrim*)p->p)->GetTypeID() == Line_Corner_TypeID ) {
3450|        Line_Corner*  line = (Line_Corner*)p->p;
3451|
3452|        for ( ListX_forEach( prims, &p2, ListX_ElemX ) ) {
3453|          if ( p == p2 )  continue;
3454|
3455|          if ( line->m_Controler_id[0] < 0 ) {
3456|            diff = ( (int)line->m_Controler_id[0] == -1 ) ? 5 : 1;
3457|            if ( (int)line->m_Controler[0] == 1 )  line->m_Controler[0] = NULL;
3458|            iHandle = ((CadPrim*)p2->p)->GetLinkOnReadHandleNum( line->m_Line.x1, line->m_Line.y1, diff );
3459|            if ( iHandle > 0 )
3460|              ((CadPrim*)p2->p)->LinkToHandle( iHandle, (CadPrim*)p->p, 1 );
3461|          }
3462|
3463|          if ( line->m_Controler_id[1] < 0 ) {
3464|            diff = ( (int)line->m_Controler_id[1] == -1 ) ? 5 : 1;
3465|            if ( (int)line->m_Controler[1] == 1 )  line->m_Controler[1] = NULL;
3466|            iHandle = ((CadPrim*)p2->p)->GetLinkOnReadHandleNum( line->m_Line.x2, line->m_Line.y2, diff );
3467|            if ( iHandle > 0 )
3468|              ((CadPrim*)p2->p)->LinkToHandle( iHandle, (CadPrim*)p->p, 2 );
3469|          }
3470|        }
3471|      }
3472|    }
3473|  }
3474|
3475|  /* 矢印の対応(方向)を調節する */
3476|  {
3477|    ListX_ElemX*  p;
3478|    int   x, y, r;
3479|    int  dx, dy;
3480|
3481|    for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
3482|
3483|      if ( ((CadPrim*)p->p)->GetTypeID() == Line_Ex_TypeID ) {
3484|        Line_Ex*  line = (Line_Ex*)p->p;
3485|
3486|        if ( (int)line->m_ArrowsInReading == 1 )  line->m_ArrowsInReading = NULL;
3487|        if ( line->m_ArrowsInReading == NULL )  continue;
3488|
3489|        line->GetArrowParamType2( 2, &x, &y, &r );
3490|        dx = line->m_ArrowsInReading->x1 - x;
3491|        dy = line->m_ArrowsInReading->y1 - y;
3492|        if ( dx >= -1 && dx <= +1 && dy >= -1 && dy <= +1 ) {
3493|           r = line->m_Arrow1;  line->m_Arrow1 = line->m_Arrow2;  line->m_Arrow2 = r;
3494|        }
3495|        free( line->m_ArrowsInReading );
3496|        line->m_ArrowsInReading = NULL;
3497|      }
3498|
3499|      if ( ((CadPrim*)p->p)->GetTypeID() == Line_Corner_TypeID ) {
3500|        Line_Corner* line = (Line_Corner*)p->p;
3501|
3502|        if ( (int)line->m_ArrowsInReading == 1 )  line->m_ArrowsInReading = NULL;
3503|        if ( line->m_ArrowsInReading == NULL )  continue;
3504|
3505|        line->GetArrowParamType2( 2, &x, &y, &r );
3506|        dx = line->m_ArrowsInReading->x1 - x;
3507|        dy = line->m_ArrowsInReading->y1 - y;
3508|        if ( dx >= -1 && dx <= +1 && dy >= -1 && dy <= +1 ) {
3509|           r = line->m_Arrow1;  line->m_Arrow1 = line->m_Arrow2;  line->m_Arrow2 = r;
3510|        }
3511|        free( line->m_ArrowsInReading );
3512|        line->m_ArrowsInReading = NULL;
3513|      }
3514|    }
3515|  }
3516|}
3517|
3518|
3519| 
3520|/***********************************************************************
3521|  15. <<< [CSVGCatApp::Save] SVG ファイルを出力する >>> 
3522|【引数】
3523|  ・char*  path;   SVG ファイルパス
3524|  ・bool  bTest;   テストやバックアップ向けかどうか
3525|************************************************************************/
3526|void  CSVGCatApp::Save( const char* path, bool bTest )
3527|{
3528|  CChildView*  view = ((CMainFrame*)m_pMainWnd)->m_wndView;
3529|  SVGCat_Page*  page;
3530|  SVGCat_Page*  parentPage;
3531|  ListX_ElemX* pPrim;
3532|  FileX_UniWrite  ufile;
3533|  FILE*  f;
3534|  char*  p;
3535|  bool   bUnicode;
3536|  int    iPage, nPage, i;
3537|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
3538|  HWND  hWnd = frame->m_hWnd;
3539|  SVGCat_File*  file = &m_file;
3540|  CadPrim_SaveParam  sp;
3541|
3542|  ChgPage( file, file->m_CurrentPageNum );  /* 同期を取る */
3543|
3544|  WaitForSingleObject( m_FileSema, INFINITE );
3545|
3546|
3547|  /* SVG ファイルに保存する */
3548|  bUnicode = false;
3549|  for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
3550|    if ( StrX_isExist2byte( page->title ) )  { bUnicode = true;  goto exit_for; }
3551|    if ( StrX_isExist2byte( page->canvas.m_CorrImagePath ) )  { bUnicode = true;  goto exit_for; }
3552|    for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
3553|      if ( ((CadPrim*)pPrim->p)->IsNeedUnicode() )  { bUnicode = true;  goto exit_for; }
3554|    }
3555|  }
3556| exit_for:;
3557|
3558|  if ( bUnicode )  p = FileX_UniWrite_init( &ufile, path );
3559|  else  p = (char*)path;
3560|  f = FileX_open( p, "wt" );
3561|
3562|  fprintf( f, "<?xml version=\"1.0\" encoding=\"utf-%d\"?>\n\n", bUnicode ? 16 : 8 );
3563|
3564|  fprintf( f, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n"
3565|    "\t\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n\n" );
3566|
3567|  nPage = ListX_getN( &file->m_pages, SVGCat_Page );
3568|
3569|  {
3570|    int  maxWidth = 1, maxHeight = 1;
3571|
3572|    for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
3573|      if ( page->canvas.m_Width > maxWidth )  maxWidth = page->canvas.m_Width;
3574|      if ( page->canvas.m_Height > maxHeight )  maxHeight = page->canvas.m_Height;
3575|    }
3576|
3577|    fprintf( f, "<svg width=\"%d\" height=\"%d\" ", maxWidth, maxHeight );
3578|    if ( nPage == 1 && file->m_Canvas.m_CorrImagePath[0] != '\0' ) {
3579|      char  s[_MAX_PATH];
3580|
3581|      StrX_cpyStepPath2( s, file->m_Canvas.m_CorrImagePath, sizeof(s), path );
3582|      fprintf( f, " corr-image=\"%s\"", s );
3583|    }
3584|
3585|    if ( nPage + file->m_StartPageNum - 1 >= 2 )
3586|      fprintf( f, "onload=\"svg_onload( evt, %d );\"\n", file->m_Canvas.m_NextPageInterval );
3587|    fprintf( f, " %s=\"0 0 %d %d\" preserveAspectRatio=\"xMidYMid meet\"",
3588|      view->m_ZoomMode != CChildView_ZoomNormal ? "viewBox" : "__viewBox",
3589|      maxWidth, maxHeight );
3590|    fputs( "\n xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\n", f );
3591|  }
3592|
3593|
3594|  /* 表示ページを切り替えるスクリプトを出力する */
3595|  if ( nPage + file->m_StartPageNum - 1 >= 2 ) {
3596|    char  path[_MAX_PATH];
3597|
3598|    fprintf( f, "<script type=\"text/ecmascript\">\n" );
3599|    fprintf( f, "<![CDATA[\n" );
3600|    fprintf( f, "var  mPage=%d;\n", nPage + file->m_StartPageNum - 1 );
3601|
3602|    StrX_getExeFullPath( path, "system\\svg-script.txt", sizeof(path) );
3603|    FileX_include( f, path, 't' );
3604|
3605|    fprintf( f, "]]>\n" );
3606|    fprintf( f, "</script>\n\n" );
3607|  }
3608|
3609|
3610|  /* 各ページを出力する */
3611|  sp.f = f;
3612|  sp.path = (char*)path;
3613|  sp.bLower = m_bLowerPath;
3614|
3615|  for ( iPage = 0; iPage < nPage; iPage++ ) {
3616|    ListX*  prims;
3617|    Canvas* canvas;
3618|
3619|    page = ListX_get( &file->m_pages, iPage, SVGCat_Page );
3620|    prims = &page->prims;
3621|    canvas = &page->canvas;
3622|
3623|    if ( nPage >= 2 ) {
3624|      if ( iPage + file->m_StartPageNum == 0 )
3625|        fprintf( f, "<g id=\"backpage\" " );
3626|      else
3627|        fprintf( f, "<g id=\"page%d\" ", iPage + file->m_StartPageNum );
3628|
3629|      fprintf( f, "visibility=\"%s\" width=\"%d\" height=\"%d\"",
3630|        iPage + file->m_StartPageNum <= 1 ? "visible" : "hidden",
3631|        canvas->m_Width, canvas->m_Height );
3632|      if ( canvas->m_CorrImagePath[0] != '\0' ) {
3633|        char  s[_MAX_PATH];
3634|
3635|        StrX_cpyStepPath2( s, canvas->m_CorrImagePath, sizeof(s), path );
3636|        fprintf( f, " corr-image=\"%s\"", s );
3637|      }
3638|      fprintf( f, ">\n" );
3639|    }
3640|
3641|    //if ( iPage == 0 )
3642|    //  frame->m_wndView->OutInkSVG( f, IRO_MaskPen );  /* デジタルインク */
3643|    //    /* マーカーペンに必要な AND マスクの代わりに、背面描画を行う */
3644|//    FileX_include( f, GetInkWorkFilePath( file->m_id, iPage + file->m_StartPageNum, IRO_MaskPen ), 't' );  /* インク */
3645|
3646|    if ( page->bBeforeDraw ) {
3647|      view->SetDrawnParam( prims );  Load2( &file->m_prims );
3648|      page->bBeforeDraw = FALSE;
3649|    }
3650|
3651|    sp.iPage = iPage + file->m_StartPageNum;
3652|
3653|    for ( ListX_forEach( prims, &pPrim, ListX_ElemX ) ) {  /* 全図形 */
3654|      int    iTargetPage;
3655|      char*  url = ((CadPrim*)pPrim->p)->GetLinkURL();
3656|
3657|      if ( url[0] == '#' )  iTargetPage = SearchByID( file, url+1, NULL );
3658|      else  iTargetPage = -1;
3659|
3660|      sp.iTargetPage = iTargetPage;
3661|      ((CadPrim*)pPrim->p)-> OutSVG( &sp );
3662|    }
3663|
3664|    //if ( iPage == 0 )
3665|    //  frame->m_wndView->OutInkSVG( f, IRO_MaskPen );  /* デジタルインク */
3666|    FileX_include( f, GetInkWorkFilePath( file->m_id, iPage + file->m_StartPageNum, IRO_MaskPen ), 't' );  /* インク */
3667|
3668|    //if ( iPage == 0 )
3669|    //  frame->m_wndView->OutInkSVG( f, IRO_CopyPen );  /* デジタルインク */
3670|    FileX_include( f, GetInkWorkFilePath( file->m_id, iPage+ file->m_StartPageNum, IRO_CopyPen ), 't' );  /* インク */
3671|
3672|    if ( nPage >= 2 ) {
3673|      fputs( "</g>\n", f );
3674|    }
3675|  }
3676|
3677|  /* ページ構成を出力する */
3678|  iPage = file->m_StartPageNum;
3679|  nPage = 1;  /* タブ数 */
3680|  fputs( "<pages>\n", f );
3681|  for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
3682|    if ( iPage == 0 )  { iPage = 1;  continue; }
3683|
3684|    if ( page->firstChild == NULL ) {
3685|      for ( i = 0; i < nPage; i++ )  fputc( '\t', f );
3686|      fprintf( f, "<page num=\"%d\" title=\"%s\"/>\n", iPage, page->title );  /* 子なし */
3687|
3688|      if ( page->next == NULL ) {
3689|        parentPage = page->parent;
3690|        while ( parentPage != NULL ) {
3691|          nPage--;
3692|          for ( i = 0; i < nPage; i++ )  fputc( '\t', f );
3693|          fputs( "</page>\n", f );  /* 終了 */
3694|          if ( parentPage->next == ListX_Elem_getNextT( page, SVGCat_Page ) )
3695|            break;
3696|          parentPage = parentPage->parent;
3697|        }
3698|      }
3699|    }
3700|    else {
3701|      for ( i = 0; i < nPage; i++ )  fputc( '\t', f );
3702|      fprintf( f, "<page num=\"%d\" title=\"%s\">\n", iPage, page->title );  /* 開始 */
3703|      nPage++;
3704|    }
3705|    iPage++;
3706|  }
3707|  fputs( "</pages>\n", f );
3708|
3709|  fprintf( f, "</svg>\n" );
3710|  fclose( f );
3711|  if ( bUnicode )  FileX_UniWrite_finish( &ufile );
3712|
3713|  if ( stricmp( StrX_refExt( path ), "svgz" ) == 0 ) {
3714|    char*  svgzCompressedPath = CSVGCatApp_compressSvgz( path );
3715|    remove( path );
3716|    MoveFile( svgzCompressedPath, path );
3717|  }
3718|
3719|  /* キャンバス全体を画像に出力する */
3720|  if ( ! bTest ) {
3721|    int  i, n;
3722|    SVGCat_Page*  page;
3723|    char  s[_MAX_PATH];
3724|
3725|    n = SVGCat_File_getMaxPageNum( &m_file );
3726|    page = ListX_get( &m_file.m_pages, 1 - m_file.m_StartPageNum, SVGCat_Page );
3727|
3728|    for ( i = 1; i <= n; i++ ) {
3729|
3730|      sprintf( s, "画像出力中 (%d/%d) ...", i, n );
3731|      frame->SetWindowText( s );
3732|
3733|      if ( page->canvas.m_CorrImagePath[0] != '\0' ) {
3734|        StrX_cpyAbsPath2( s, page->canvas.m_CorrImagePath, sizeof(s), path );
3735|        frame->m_wndView->PaintToImage( i, s );
3736|      }
3737|
3738|      page = ListX_Elem_getNextT( page, SVGCat_Page );
3739|    }
3740|    frame->UpdateWindowText();
3741|  }
3742|
3743|
3744|  if ( ! bTest ) {
3745|    strcpy( m_path, path );
3746|    frame->UpdateWindowText();
3747|    SetRecentFile( path );
3748|    m_UndoBuf->OnSaveed();
3749|  }
3750|
3751|  ReleaseSemaphore( m_FileSema, 1, NULL );
3752|}
3753|
3754|
3755| 
3756|/***********************************************************************
3757|  16. <<< [CSVGCatApp::SaveHtml] サンプル HTML ファイルを出力する >>> 
3758|【引数】
3759|  ・char*  path;       HTML ファイルパス
3760|  ・char*  svg_fname;  SVG ファイルのファイル名
3761|  ・char*  title;      タイトル
3762|  ・int  type;         タイプ、(ファイル名 html%d-script1.txt)の%d
3763|************************************************************************/
3764|void  CSVGCatApp::SaveHtml( const char* path, const char* svg_fname,
3765|  const char* title, int type )
3766|{
3767|  FILE*  f;
3768|  int  mPage = ListX_getN( &m_file.m_pages, SVGCat_Page ) + m_file.m_StartPageNum - 1;
3769|  char  path2[_MAX_PATH];
3770|  char  fname2[_MAX_PATH];
3771|  int  i;
3772|
3773|  f = FileX_open( path, "wt" );
3774|
3775|  fprintf( f, "<html>\n" );
3776|  fprintf( f, "<head>\n" );
3777|  fprintf( f, "<title>%s</title>\n", title );
3778|  fprintf( f, "\n" );
3779|  fprintf( f, "<script language=\"JavaScript\"><!" "--\n" );
3780|  fprintf( f, "var  mPage=%d;\n", mPage );
3781|
3782|  sprintf( fname2, "system\\html%d-script1.txt", type );
3783|  StrX_getExeFullPath( path2, fname2, sizeof(path2) );
3784|  FileX_include( f, path2, 't' );
3785|
3786|  if ( type == 1 ) {
3787|    fprintf( f, "<embed src=\"%s\" width=\"100%%\" height=\"100%%\" name=\"svg\">\n",
3788|      svg_fname );
3789|  }
3790|  else if ( type == 2 ) {
3791|    fprintf( f, "<embed src=\"%s\" width=\"%dpx\" height=\"%dpx\" name=\"svg\">\n",
3792|      svg_fname, m_file.m_Canvas.m_Width, m_file.m_Canvas.m_Height );
3793|  }
3794|  else {
3795|    SVGCat_Page*  page;
3796|
3797|    if ( mPage >= 2 ) {
3798|      for ( ListX_forEach( &m_file.m_pages, &page, SVGCat_Page ) ) {
3799|        if ( strcmp( page->title, "New Page" ) != 0 )  break;
3800|      }
3801|      if ( page == NULL ) {
3802|        fprintf( f, "Page " );
3803|        for ( i = 1; i <= mPage; i++ ) {
3804|          fprintf( f, "<A href=\"#page%d\">[%d]</A> ", i, i );
3805|        }
3806|        fprintf( f, "<BR><BR>\n" );
3807|      }
3808|      else {
3809|        int  tab = 0;
3810|
3811|        fprintf( f, "<H3>%s</H3>\n\n", svg_fname );
3812|        fprintf( f, "<H4>目次</H4>\n<UL>\n" );
3813|        i = 1;
3814|        for ( ListX_forEach( &m_file.m_pages, &page, SVGCat_Page ) ) {
3815|          fprintf( f, "%*s<LI><A href=\"#page%d\">[%d] %s</A>\n", tab*2, "", i, i, page->title );
3816|          if ( page->firstChild != NULL ) {
3817|            tab++;
3818|            fprintf( f, "%*s<UL>\n", tab*2, "" );
3819|          }
3820|          if ( page->next == NULL && page->parent != NULL ) {
3821|            SVGCat_Page*  nextPage = ListX_Elem_getNextT( page, SVGCat_Page );
3822|            SVGCat_Page*  p = page;
3823|
3824|            while ( p->parent != NULL ) {
3825|              fprintf( f, "%*s</UL>\n", tab*2, "");
3826|              tab--;
3827|
3828|              for ( p = p->parent;  p->next != NULL;  p = p->next ) {
3829|                if ( p == nextPage )  goto exit_for;
3830|              }
3831|
3832|              if ( p == nextPage )  break;
3833|            }
3834|           exit_for:;
3835|          }
3836|          i++;
3837|        }
3838|        fprintf( f, "</UL>\n\n<H4>内容</H4>\n\n" );
3839|      }
3840|    }
3841|
3842|    page = ListX_getFirst( &m_file.m_pages, SVGCat_Page );
3843|
3844|    fprintf( f, "<NOBR><A name=\"page1\"><embed src=\"%s\" width=\"%dpx\" height=\"%dpx\" name=\"svg\"> 1</A></NOBR>\n",
3845|      svg_fname, page->canvas.m_Width, page->canvas.m_Height );
3846|    for ( i = 2; i <= mPage; i++ ) {
3847|      page = ListX_Elem_getNextT( page, SVGCat_Page );
3848|      fprintf( f, "<NOBR><A name=\"page%d\"><embed src=\"%s\" width=\"%dpx\" height=\"%dpx\" name=\"svg%d\"> %d</A></NOBR>\n",
3849|        i, svg_fname, page->canvas.m_Width, page->canvas.m_Height, i, i );
3850|    }
3851|  }
3852|
3853|  sprintf( fname2, "system\\html%d-script2.txt", type );
3854|  StrX_getExeFullPath( path2, fname2, sizeof(path2) );
3855|  FileX_include( f, path2, 't' );
3856|
3857|  fclose( f );
3858|}
3859|
3860|
3861| 
3862|/***********************************************************************
3863|  17. <<< [CSVGCatApp::formatError] エラー表示する >>> 
3864|************************************************************************/
3865|void  CSVGCatApp::formatError()
3866|{
3867|  CString  s;
3868|
3869|  if ( m_bJapanese )
3870|    s.LoadString( IDS_NotSupportElem );
3871|  else
3872|    s.LoadString( IDS_NotSupportElem_E );
3873|
3874|  MessageBox( NULL, s, "SVG Cats", MB_OK );
3875|  error2_0( CSVGCatApp_Err_Format, (char*)(const char*)s );
3876|}
3877|
3878|
3879| 
3880|/***********************************************************************
3881|  18. <<< [CSVGCatApp::OpenCommercial] >>> 
3882|************************************************************************/
3883|#if 0
3884|void  CSVGCatApp::OpenCommercial()
3885|{
3886|  time_t  now;
3887|  time_t  days10;
3888|  time_t  licensedDay;
3889|  char  path[_MAX_PATH];
3890|
3891|  if ( m_bForTheFirstTime )  return;
3892|
3893|  ReloadKeyNumber();
3894|
3895|  licensedDay = MeltKeyNumber( m_KeyNumber );
3896|  time( &now );
3897|  TimeDate_setDiff( &days10, 0, 0, 10, 0, 0, 0 );
3898|
3899|  if ( now - licensedDay > days10 || (signed)(now - licensedDay) < 0 ) {
3900|    StrX_getExeFullPath( path, "system\\getnewkey.html", sizeof(path) );
3901|    WinX_openHtml( path, true );
3902|  }
3903|}
3904|#endif
3905|
3906| 
3907|/***********************************************************************
3908|  19. <<< [CSVGCatApp::OpenCommercial2] >>> 
3909|************************************************************************/
3910|void  CSVGCatApp::OpenCommercial2()
3911|{
3912|  time_t  now;
3913|  time_t  days10;
3914|  time_t  licensedDay;
3915|  char  path[_MAX_PATH];
3916|  time_t  regt;
3917|
3918|  WinX_getReg_x( HKEY_CLASSES_ROOT, SVGCATS_REGPATH, NULL, &regt, sizeof(regt) );
3919|
3920|  ReloadKeyNumber();
3921|
3922|  licensedDay = MeltKeyNumber( m_KeyNumber );
3923|  time( &now );
3924|  TimeDate_setDiff( &days10, 0, 0, 10, 0, 0, 0 );
3925|
3926|  if ( now - licensedDay > days10 || (signed)(now - licensedDay) < 0 ) {
3927|    if ( now >= regt + days10 || now < regt ) {
3928|      StrX_getExeFullPath( path, "system\\getnewkey.html", sizeof(path) );
3929|      WinX_openIE( path );  // WinX_openHtml( path, false );
3930|      MessageBox( m_pMainWnd->m_hWnd,
3931|       "ライセンスが切れました。無料キーナンバーか購入キーナンバーを入力してください。",
3932|       "ライセンス切れ警告", MB_OK );
3933|      ((CMainFrame*)m_pMainWnd)->OnInputLicense();
3934|      licensedDay = MeltKeyNumber( m_KeyNumber );
3935|      if ( now - licensedDay > days10 || (signed)(now - licensedDay) < 0 ) {
3936|        ((CMainFrame*)m_pMainWnd)->PostMessage( WM_COMMAND, ID_CloseTaskTray, NULL );
3937|        ((CMainFrame*)m_pMainWnd)->PostMessage( WM_CLOSE, NULL, NULL );
3938|      }
3939|    }
3940|  }
3941|}
3942|
3943| 
3944|/***********************************************************************
3945|  20. <<< [CSVGCatApp::LoadDefaultDesign] ツールバーの図形の属性を読み込む >>> 
3946|【引数】
3947|  ・bool  返り値;  成功したかどうか
3948|************************************************************************/
3949|bool  CSVGCatApp::LoadDefaultDesign( const char* path )
3950|{
3951|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
3952|  CChildView*  view = ((CMainFrame*)m_pMainWnd)->m_wndView;
3953|  SVGCat_File  file;
3954|  CadPrim*  prim;
3955|  CadPrim*  prim2;
3956|  IInkStrokeDisp*  stroke;
3957|  IInkDrawingAttributes*  attr;
3958|  long  value;
3959|  float value_f;
3960|  VARIANT_BOOL  value_b;
3961|  HRESULT  hr;
3962|
3963|
3964|  file.m_bPagesExist = false;
3965|  NewEmpty_imp( &file, rand(), false );
3966|  Load_imp( file.m_id, &file, path );
3967|  view->SetDrawnParam( &file.m_prims );
3968|  Load2( &file.m_prims );
3969|
3970|
3971|  /* Defulat Text Design */
3972|  prim = NULL;
3973|  SearchByID( &file, "Text", &prim );
3974|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
3975|    if ( frame->m_TextDesign != NULL )  delete  frame->m_TextDesign;
3976|    frame->m_TextDesign = prim->GetNewCopy( &m_file.m_prims );
3977|  }
3978|  prim = NULL;
3979|  SearchByID( &file, "Text-Rect", &prim );
3980|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
3981|    if ( frame->m_TextRectDesign != NULL )  delete  frame->m_TextRectDesign;
3982|    frame->m_TextRectDesign = prim->GetNewCopy( &m_file.m_prims );
3983|  }
3984|  prim = NULL;
3985|  SearchByID( &file, "Text-Circle", &prim );
3986|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
3987|    if ( frame->m_TextCircleDesign != NULL )  delete  frame->m_TextCircleDesign;
3988|    frame->m_TextCircleDesign = prim->GetNewCopy( &m_file.m_prims );
3989|  }
3990|  prim = NULL;
3991|  SearchByID( &file, "Text-RoundRect", &prim );
3992|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
3993|    if ( frame->m_TextRoundRectDesign != NULL )  delete  frame->m_TextRoundRectDesign;
3994|    frame->m_TextRoundRectDesign = prim->GetNewCopy( &m_file.m_prims );
3995|  }
3996|  prim = NULL;
3997|  SearchByID( &file, "Text-Diamond", &prim );
3998|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
3999|    if ( frame->m_TextDiamondDesign != NULL )  delete  frame->m_TextDiamondDesign;
4000|    frame->m_TextDiamondDesign = prim->GetNewCopy( &m_file.m_prims );
4001|  }
4002|  prim = NULL;
4003|  SearchByID( &file, "Text-Parallel", &prim );
4004|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
4005|    if ( frame->m_TextParallelDesign != NULL )  delete  frame->m_TextParallelDesign;
4006|    frame->m_TextParallelDesign = prim->GetNewCopy( &m_file.m_prims );
4007|  }
4008|
4009|
4010|  /* Defulat Line Design */
4011|  prim2 = NULL;
4012|  SearchByID( &file, "Line", &prim2 );
4013|  if ( prim2 != NULL && prim2->GetTypeID() == Rect_Ex_TypeID ) {
4014|    prim = NULL;
4015|    SearchByRect( &file, 1, &((Rect_Ex*)prim2)->m_Rect, &prim );
4016|    if ( prim != NULL && prim->GetTypeID() == Line_Ex_TypeID ) {
4017|      if ( frame->m_LineDesign != NULL )  delete  frame->m_LineDesign;
4018|      frame->m_LineDesign = prim->GetNewCopy( &m_file.m_prims );
4019|      ((Line_Ex*)frame->m_LineDesign)->m_Controler_id[0] = 0;
4020|      ((Line_Ex*)frame->m_LineDesign)->m_Controler_id[1] = 0;
4021|    }
4022|  }
4023|  prim2 = NULL;
4024|  SearchByID( &file, "Arrow", &prim2 );
4025|  if ( prim2 != NULL && prim2->GetTypeID() == Rect_Ex_TypeID ) {
4026|    prim = NULL;
4027|    SearchByRect( &file, 1, &((Rect_Ex*)prim2)->m_Rect, &prim );
4028|    if ( prim != NULL && prim->GetTypeID() == Line_Ex_TypeID ) {
4029|      if ( frame->m_ArrowDesign != NULL )  delete  frame->m_ArrowDesign;
4030|      frame->m_ArrowDesign = prim->GetNewCopy( &m_file.m_prims );
4031|      ((Line_Ex*)frame->m_ArrowDesign)->m_Controler_id[0] = 0;
4032|      ((Line_Ex*)frame->m_ArrowDesign)->m_Controler_id[1] = 0;
4033|    }
4034|  }
4035|  prim2 = NULL;
4036|  SearchByID( &file, "CorneredLine", &prim2 );
4037|  if ( prim2 != NULL && prim2->GetTypeID() == Rect_Ex_TypeID ) {
4038|    prim = NULL;
4039|    SearchByRect( &file, 1, &((Rect_Ex*)prim2)->m_Rect, &prim );
4040|    if ( prim != NULL && prim->GetTypeID() == Line_Corner_TypeID ) {
4041|      if ( frame->m_CorneredLineDesign != NULL )  delete  frame->m_CorneredLineDesign;
4042|      frame->m_CorneredLineDesign = prim->GetNewCopy( &m_file.m_prims );
4043|      ((Line_Corner*)frame->m_CorneredLineDesign)->m_Controler_id[0] = 0;
4044|      ((Line_Corner*)frame->m_CorneredLineDesign)->m_Controler_id[1] = 0;
4045|    }
4046|  }
4047|  prim2 = NULL;
4048|  SearchByID( &file, "GuideLine", &prim2 );
4049|  if ( prim2 != NULL && prim2->GetTypeID() == Rect_Ex_TypeID ) {
4050|    int  i;
4051|
4052|    prim = NULL;
4053|    for ( i = 0; i < 2; i++ ) {
4054|      SearchByRect( &file, 1, &((Rect_Ex*)prim2)->m_Rect, &prim );
4055|      if ( prim != NULL && prim->GetTypeID() == Line_Ex_TypeID ) {
4056|        if ( frame->m_GuideLineArrowDesign != NULL )  delete  frame->m_GuideLineArrowDesign;
4057|        frame->m_GuideLineArrowDesign = prim->GetNewCopy( &m_file.m_prims );
4058|        ((Line_Ex*)frame->m_GuideLineArrowDesign)->UnlinkAll();
4059|        ((Line_Ex*)frame->m_GuideLineArrowDesign)->m_Controler_id[0] = 0;
4060|        ((Line_Ex*)frame->m_GuideLineArrowDesign)->m_Controler_id[1] = 0;
4061|      }
4062|      if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
4063|        if ( frame->m_GuideLineTextDesign != NULL )  delete  frame->m_GuideLineTextDesign;
4064|        frame->m_GuideLineTextDesign = prim->GetNewCopy( &m_file.m_prims );
4065|        ListX_toEmptyDelete( &((Text_Box*)frame->m_GuideLineTextDesign)->m_Links, CadPrim_Link, NULL );
4066|        ((Text_Box*)frame->m_GuideLineTextDesign)->UnlinkAll();
4067|      }
4068|    }
4069|  }
4070|
4071|
4072|  /* Defulat Primitive Design */
4073|  prim = NULL;
4074|  SearchByID( &file, "Rect", &prim );
4075|  if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4076|    if ( frame->m_RectDesign != NULL )  delete  frame->m_RectDesign;
4077|    frame->m_RectDesign = prim->GetNewCopy( &m_file.m_prims );
4078|  }
4079|  prim = NULL;
4080|  SearchByID( &file, "Circle", &prim );
4081|  if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4082|    if ( frame->m_CircleDesign != NULL )  delete  frame->m_CircleDesign;
4083|    frame->m_CircleDesign = prim->GetNewCopy( &m_file.m_prims );
4084|  }
4085|  prim = NULL;
4086|  SearchByID( &file, "RoundRect", &prim );
4087|  if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4088|    if ( frame->m_RoundRectDesign != NULL )  delete  frame->m_RoundRectDesign;
4089|    frame->m_RoundRectDesign = prim->GetNewCopy( &m_file.m_prims );
4090|  }
4091|  prim = NULL;
4092|  SearchByID( &file, "Diamond", &prim );
4093|  if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4094|    if ( frame->m_DiamondDesign != NULL )  delete  frame->m_DiamondDesign;
4095|    frame->m_DiamondDesign = prim->GetNewCopy( &m_file.m_prims );
4096|  }
4097|
4098|
4099|  /* Defulat Ink Design */
4100|  if ( view->m_InkOverlay != NULL ) {
4101|    prim = NULL;
4102|    SearchByID( &file, "BlackPen", &prim );
4103|    if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4104|      SearchStrokeByRect( &file, 1, &((Rect_Ex*)prim)->m_Rect, 0, &stroke );
4105|      if ( stroke != NULL ) {
4106|        hr = stroke->get_DrawingAttributes( &attr );  if ( hr != 0 )  error();
4107|        hr = attr->get_Width( &value_f ); if ( hr != 0 )  error();
4108|        hr = view->m_PenAttr->put_Width( value_f );  if ( hr != 0 )  error();
4109|        hr = attr->get_Height( &value_f );  if ( hr != 0 )  error();
4110|        hr = view->m_PenAttr->put_Height( value_f );  if ( hr != 0 )  error();
4111|        hr = attr->get_Color( &value );  if ( hr != 0 )  error();
4112|        hr = view->m_PenAttr->put_Color( value );  if ( hr != 0 )  error();
4113|        hr = attr->get_IgnorePressure( &value_b );  if ( hr != 0 )  error();
4114|        hr = view->m_PenAttr->put_IgnorePressure( value_b );  if ( hr != 0 )  error();
4115|        attr->Release();  attr = NULL;
4116|        stroke->Release();  stroke = NULL;
4117|      }
4118|    }
4119|    prim = NULL;
4120|    SearchByID( &file, "RedPen", &prim );
4121|    if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4122|      SearchStrokeByRect( &file, 1, &((Rect_Ex*)prim)->m_Rect, 0, &stroke );
4123|      if ( stroke != NULL ) {
4124|        hr = stroke->get_DrawingAttributes( &attr );  if ( hr != 0 )  error();
4125|        hr = attr->get_Width( &value_f ); if ( hr != 0 )  error();
4126|        hr = view->m_RedPenAttr->put_Width( value_f );  if ( hr != 0 )  error();
4127|        hr = attr->get_Height( &value_f );  if ( hr != 0 )  error();
4128|        hr = view->m_RedPenAttr->put_Height( value_f );  if ( hr != 0 )  error();
4129|        hr = attr->get_Color( &value );  if ( hr != 0 )  error();
4130|        hr = view->m_RedPenAttr->put_Color( value );  if ( hr != 0 )  error();
4131|        hr = attr->get_IgnorePressure( &value_b );  if ( hr != 0 )  error();
4132|        hr = view->m_RedPenAttr->put_IgnorePressure( value_b );  if ( hr != 0 )  error();
4133|        attr->Release();  attr = NULL;
4134|        stroke->Release();  stroke = NULL;
4135|      }
4136|    }
4137|    prim = NULL;
4138|    SearchByID( &file, "BluePen", &prim );
4139|    if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4140|      SearchStrokeByRect( &file, 1, &((Rect_Ex*)prim)->m_Rect, 0, &stroke );
4141|      if ( stroke != NULL ) {
4142|        hr = stroke->get_DrawingAttributes( &attr );  if ( hr != 0 )  error();
4143|        hr = attr->get_Width( &value_f ); if ( hr != 0 )  error();
4144|        hr = view->m_BluePenAttr->put_Width( value_f );  if ( hr != 0 )  error();
4145|        hr = attr->get_Height( &value_f );  if ( hr != 0 )  error();
4146|        hr = view->m_BluePenAttr->put_Height( value_f );  if ( hr != 0 )  error();
4147|        hr = attr->get_Color( &value );  if ( hr != 0 )  error();
4148|        hr = view->m_BluePenAttr->put_Color( value );  if ( hr != 0 )  error();
4149|        hr = attr->get_IgnorePressure( &value_b );  if ( hr != 0 )  error();
4150|        hr = view->m_BluePenAttr->put_IgnorePressure( value_b );  if ( hr != 0 )  error();
4151|        attr->Release();  attr = NULL;
4152|        stroke->Release();  stroke = NULL;
4153|      }
4154|    }
4155|    prim = NULL;
4156|    SearchByID( &file, "GreenMarker", &prim );
4157|    if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4158|      SearchStrokeByRect( &file, 1, &((Rect_Ex*)prim)->m_Rect, 0, &stroke );
4159|      if ( stroke != NULL ) {
4160|        hr = stroke->get_DrawingAttributes( &attr );  if ( hr != 0 )  error();
4161|        hr = attr->get_Width( &value_f ); if ( hr != 0 )  error();
4162|        hr = view->m_MarkerAttr->put_Width( value_f );  if ( hr != 0 )  error();
4163|        hr = attr->get_Height( &value_f );  if ( hr != 0 )  error();
4164|        hr = view->m_MarkerAttr->put_Height( value_f );  if ( hr != 0 )  error();
4165|        hr = attr->get_Color( &value );  if ( hr != 0 )  error();
4166|        hr = view->m_MarkerAttr->put_Color( value );  if ( hr != 0 )  error();
4167|        hr = attr->get_IgnorePressure( &value_b );  if ( hr != 0 )  error();
4168|        hr = view->m_MarkerAttr->put_IgnorePressure( value_b );  if ( hr != 0 )  error();
4169|        attr->Release();  attr = NULL;
4170|        stroke->Release();  stroke = NULL;
4171|      }
4172|    }
4173|    prim = NULL;
4174|    SearchByID( &file, "MazentaMarker", &prim );
4175|    if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4176|      SearchStrokeByRect( &file, 1, &((Rect_Ex*)prim)->m_Rect, 0, &stroke );
4177|      if ( stroke != NULL ) {
4178|        hr = stroke->get_DrawingAttributes( &attr );  if ( hr != 0 )  error();
4179|        hr = attr->get_Width( &value_f ); if ( hr != 0 )  error();
4180|        hr = view->m_RedMarkerAttr->put_Width( value_f );  if ( hr != 0 )  error();
4181|        hr = attr->get_Height( &value_f );  if ( hr != 0 )  error();
4182|        hr = view->m_RedMarkerAttr->put_Height( value_f );  if ( hr != 0 )  error();
4183|        hr = attr->get_Color( &value );  if ( hr != 0 )  error();
4184|        hr = view->m_RedMarkerAttr->put_Color( value );  if ( hr != 0 )  error();
4185|        hr = attr->get_IgnorePressure( &value_b );  if ( hr != 0 )  error();
4186|        hr = view->m_RedMarkerAttr->put_IgnorePressure( value_b );  if ( hr != 0 )  error();
4187|        attr->Release();  attr = NULL;
4188|        stroke->Release();  stroke = NULL;
4189|      }
4190|    }
4191|    prim = NULL;
4192|    SearchByID( &file, "YellowMarker", &prim );
4193|    if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4194|      SearchStrokeByRect( &file, 1, &((Rect_Ex*)prim)->m_Rect, 0, &stroke );
4195|      if ( stroke != NULL ) {
4196|        hr = stroke->get_DrawingAttributes( &attr );  if ( hr != 0 )  error();
4197|        hr = attr->get_Width( &value_f ); if ( hr != 0 )  error();
4198|        hr = view->m_YellowMarkerAttr->put_Width( value_f );  if ( hr != 0 )  error();
4199|        hr = attr->get_Height( &value_f );  if ( hr != 0 )  error();
4200|        hr = view->m_YellowMarkerAttr->put_Height( value_f );  if ( hr != 0 )  error();
4201|        hr = attr->get_Color( &value );  if ( hr != 0 )  error();
4202|        hr = view->m_YellowMarkerAttr->put_Color( value );  if ( hr != 0 )  error();
4203|        hr = attr->get_IgnorePressure( &value_b );  if ( hr != 0 )  error();
4204|        hr = view->m_YellowMarkerAttr->put_IgnorePressure( value_b );  if ( hr != 0 )  error();
4205|        attr->Release();  attr = NULL;
4206|        stroke->Release();  stroke = NULL;
4207|      }
4208|    }
4209|  }
4210|
4211|  /* Defulat Marking Text Design */
4212|  prim = NULL;
4213|  SearchByID( &file, "RedText", &prim );
4214|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
4215|    if ( frame->m_RedTextDesign != NULL )  delete  frame->m_RedTextDesign;
4216|    frame->m_RedTextDesign = prim->GetNewCopy( &m_file.m_prims );
4217|  }
4218|  prim = NULL;
4219|  SearchByID( &file, "BlueText", &prim );
4220|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
4221|    if ( frame->m_BlueTextDesign != NULL )  delete  frame->m_BlueTextDesign;
4222|    frame->m_BlueTextDesign = prim->GetNewCopy( &m_file.m_prims );
4223|  }
4224|  prim = NULL;
4225|  SearchByID( &file, "TimeStampText", &prim );
4226|  if ( prim != NULL && prim->GetTypeID() == Text_Box_TypeID ) {
4227|    if ( frame->m_TimeStampDesign != NULL )  delete  frame->m_TimeStampDesign;
4228|    frame->m_TimeStampDesign = prim->GetNewCopy( &m_file.m_prims );
4229|  }
4230|
4231|
4232|  /* Defualt Stronger Design */
4233|  prim = NULL;
4234|  SearchByID( &file, "Stronger", &prim );
4235|  if ( prim != NULL && prim->GetTypeID() == Rect_Ex_TypeID ) {
4236|    if ( frame->m_StrongerDesign != NULL )  delete  frame->m_StrongerDesign;
4237|    frame->m_StrongerDesign = prim->GetNewCopy( &m_file.m_prims );
4238|  }
4239|
4240|
4241|  Finish_imp( &file );
4242|
4243|  return  true;
4244|}
4245|
4246|
4247|
4248| 
4249|/***********************************************************************
4250|  21. <<< [CSVGCatApp::GetDisplayFName] 表示用ファイル名を取得する >>> 
4251|************************************************************************/
4252|void  CSVGCatApp::GetDisplayFName( char* fname )
4253|{
4254|  if ( m_path[0] == '\0' ) {
4255|    if ( m_bJapanese )  strcpy( fname, "新規" );
4256|    else  strcpy( fname, "New" );
4257|  }
4258|  else  StrX_cpyFName( fname, m_path );
4259|}
4260|
4261|
4262| 
4263|/***********************************************************************
4264|  22. <<< [CSVGCatApp::ChangeBackup] m_path に合わせてバックアップを設定する >>> 
4265|************************************************************************/
4266|void  CSVGCatApp::ChangeBackup()
4267|{
4268|  char  path[_MAX_PATH];
4269|  char  path2[_MAX_PATH];
4270|
4271|  strcpy( path, "backup-" );
4272|  strcpy( path+7, StrX_refFName(m_path) );
4273|  strcat( path+7, "-" );
4274|  StrX_getExeFullPath( path2, _backup_path, sizeof(path) );
4275|  FileX_getTmpPath3( path2, path, "svg", m_backPath );
4276|}
4277|
4278|
4279| 
4280|/***********************************************************************
4281|  23. <<< [CSVGCatApp::GetHtml] 埋め込みHTMLを取得する >>> 
4282|************************************************************************/
4283|void  CSVGCatApp::GetHtml( char* s )
4284|{
4285|  char  name[256];
4286|  char  fname[256];
4287|  CString  msg;
4288|  CString  url;
4289|  char  avoidPat1[30];
4290|  char  avoidPat2[30];
4291|  char  avoidPat3[30];
4292|  char  avoidPat4[30];
4293|
4294|  strcpy( fname, StrX_refFName( m_path ) );
4295|  strcpy( name, fname );
4296|  StrX_chgExt( name, "" );
4297|
4298|  if ( m_bLowerPath ) {
4299|    StrX_cpyLower( fname, fname );
4300|  }
4301|
4302|  if ( m_bJapanese ) {
4303|    msg.LoadString( IDS_NeedViewer );
4304|    url.LoadString( IDS_ViewerURL );
4305|  }
4306|  else {
4307|    msg.LoadString( IDS_NeedViewer_E );
4308|    url.LoadString( IDS_ViewerURL_E );
4309|  }
4310|
4311|  if ( m_bAvoidPatent ) {
4312|    strcpy( avoidPat1, "<SCRIPT><!--\r\n" );
4313|    strcpy( avoidPat2, "document.write('" );
4314|    strcpy( avoidPat3, "');" );
4315|    strcpy( avoidPat4, "//--></SCRIPT>\r\n" );
4316|  }
4317|  else {
4318|    avoidPat1[0] = avoidPat2[0] = avoidPat3[0] = avoidPat4[0] = '\0';
4319|  }
4320|
4321|  sprintf( s, "%s%s<span title=\"%s %s\">%s\r\n"
4322|    "%s<embed src=\"%s\" name=\"%s\" width=\"%d\" height=\"%d\" "
4323|    "%stype=\"image/svg+xml\" pluginspage=\"http://www.adobe.co.jp/svg/\">%s\r\n"
4324|    "%s</span>%s\r\n%s",
4325|    avoidPat1,
4326|    avoidPat2, msg, url, avoidPat3,
4327|    avoidPat2, fname, name, m_file.m_Canvas.m_Width, m_file.m_Canvas.m_Height,
4328|      m_bBackTransparent ? "wmode=\"transparent\" " : "", avoidPat3,
4329|    avoidPat2, avoidPat3, avoidPat4 );
4330|}
4331|
4332|
4333| 
4334|/***********************************************************************
4335|  24. <<< [CSVGCatApp::NewEmpty] まっさらなデータを生成する >>> 
4336|【補足】
4337|・ファイルを開いて生成するときは、Load を呼び出してください。
4338|・別途、((CMainFrame*)m_pMainWnd)->m_wndView->NewInkOverlay(); が必要です。
4339|************************************************************************/
4340|void  CSVGCatApp::NewEmpty()
4341|{
4342|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
4343|
4344|  NewEmpty_imp( &m_file, (long)frame->m_hWnd, true );
4345|
4346|  m_UndoBuf = new Undo_Buf();
4347|  m_NextID = 1;
4348|  strcpy( m_SaveFolderPath, WinX_getDesktopPath() );
4349|}
4350|
4351|
4352|void  CSVGCatApp::NewEmpty_imp( SVGCat_File* file, long id, bool bShowing )
4353|{
4354|  CChildView*  view = ((CMainFrame*)m_pMainWnd)->m_wndView;
4355|  SVGCat_Page*  page;
4356|  FILE*  f;
4357|
4358|  ASSERT( ! file->m_bPagesExist );
4359|
4360|  file->m_id = id;
4361|  file->m_bShowing = bShowing;
4362|
4363|  ListX_init( &file->m_pages );
4364|  page = ListX_addFirstMalloc( &file->m_pages, SVGCat_Page );
4365|  strcpy( page->title, "New Page" );
4366|
4367|  //page->canvas;
4368|  ListX_init( &page->prims );
4369|  page->parent = NULL;
4370|  page->firstChild = NULL;
4371|  page->next = NULL;
4372|  page->prev = NULL;
4373|  file->m_StartPageNum = 1;
4374|  file->m_CurrentPageNum = 1;
4375|  file->m_bExistBackPage = false;
4376|
4377|  Variant_initEmpty( &page->ink );
4378|
4379|  ListX_init( &file->m_prims );
4380|
4381|//  m_Canvas.m_Width = m_Canvas.m_DefWidth;
4382|//  m_Canvas.m_Height = m_Canvas.m_DefHeight;
4383|
4384|  file->m_bPagesExist = true;
4385|
4386|  f = FileX_open( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_MaskPen ), "wt" );
4387|  fclose( f );
4388|  f = FileX_open( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_CopyPen ), "wt" );
4389|  fclose( f );
4390|}
4391|
4392|
4393| 
4394|/***********************************************************************
4395|  25. <<< [CSVGCatApp::Finish] データを後始末する >>> 
4396|************************************************************************/
4397|void  CSVGCatApp::Finish()
4398|{
4399|  CMainFrame*  frame = (CMainFrame*)m_pMainWnd;
4400|
4401|  ASSERT( m_file.m_bPagesExist );
4402|
4403|  ChgPage( &m_file, -1 );
4404|  m_UndoBuf->ClearAll();
4405|  delete  m_UndoBuf;
4406|
4407|  Finish_imp( &m_file );
4408|}
4409|
4410|
4411|void  CSVGCatApp::Finish_imp( SVGCat_File* file )
4412|{
4413|  SVGCat_Page*  page;
4414|  ListX_ElemX*  pPrim;
4415|  ListX_ElemX*  nextPrim;
4416|
4417|  ASSERT( file->m_bPagesExist );
4418|
4419|  if ( ! ListX_isEmpty( &file->m_pages ) )
4420|    ChgPage( file, -1 );
4421|
4422|  for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
4423|    for ( pPrim = ListX_getFirst( &page->prims, ListX_ElemX ); pPrim != NULL;
4424|          pPrim = nextPrim ) {
4425|      nextPrim = ListX_Elem_getNextT( pPrim, ListX_ElemX );
4426|      delete  (CadPrim*)pPrim->p;
4427|      ListX_removeFree( &page->prims, pPrim );
4428|    }
4429|    Variant_finish( &page->ink );
4430|  }
4431|  ListX_finish2( &file->m_pages, SVGCat_Page, NULL );
4432|
4433|  {
4434|    char  path[_MAX_PATH];
4435|
4436|    sprintf( path, _work_path "\\ink_%08X_*", file->m_id );
4437|    StrX_getExeFullPath( path, path, sizeof(path) );
4438|    FileX_removeWild( path );
4439|
4440|    sprintf( path, _work_path "\\img_%08X_*", file->m_id );
4441|    StrX_getExeFullPath( path, path, sizeof(path) );
4442|    FileX_removeWild( path );
4443|  }
4444|
4445|  file->m_bPagesExist = false;
4446|}
4447|
4448|
4449| 
4450|/***********************************************************************
4451|  26. <<< [CSVGCatApp::ChgPage] ページを切り替える >>> 
4452|【補足】
4453|・CMainFrame::ChgPage から呼び出されます。
4454|・iNewPage == -1 のときは、m_pages に対する m_prim のロックを外します。
4455|************************************************************************/
4456|void  CSVGCatApp::ChgPage( SVGCat_File* file, int iNewPage )
4457|{
4458|  int  i;
4459|  SVGCat_Page*  page;
4460|  HRESULT  hr;
4461|  CChildView*  view = ((CMainFrame*)m_pMainWnd)->m_wndView;
4462|  IInkDisp*  ink;
4463|  VARIANT_BOOL  bDirty;
4464|  FILE*  f;
4465|
4466|
4467|  /* 画面から戻す */
4468|  if ( file->m_CurrentPageNum != -1 ) {
4469|    i = file->m_CurrentPageNum - file->m_StartPageNum;
4470|    page = ListX_get( &file->m_pages, i, SVGCat_Page );
4471|    SVGCat_File_savePage( file, page );
4472|
4473|    /* InkOverlay を保存する */
4474|    if ( view->m_InkOverlay != NULL && file == &m_file ) {
4475|      hr = view->m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error();
4476|      hr = ink->get_Dirty( &bDirty );  if ( hr != 0 )  error();
4477|      if ( bDirty || Variant_getStrlen( &page->ink ) == 0 ) {
4478|        Variant_finish( &page->ink );
4479|        hr = ink->Save( IPF_Base64InkSerializedFormat, IPCM_NoCompression, &page->ink );
4480|        if ( hr != S_OK )  error();
4481|        f = FileX_open( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_MaskPen ), "wt" );
4482|        view->OutInkSVG( f, IRO_MaskPen );
4483|        fclose( f );
4484|        f = FileX_open( GetInkWorkFilePath( file->m_id, file->m_CurrentPageNum, IRO_CopyPen ), "wt" );
4485|        view->OutInkSVG( f, IRO_CopyPen );
4486|        fclose( f );
4487|      }
4488|      hr = ink->Release();  ink = NULL;
4489|    }
4490|
4491|    /* 背景ページのときは、背景キャッシュを更新する */
4492|    if ( file->m_CurrentPageNum == 0 && file->m_bShowing ) {
4493|      view->DrawBackBitmap();
4494|    }
4495|  }
4496|
4497|
4498|  /* 画面に表示する */
4499|  if ( iNewPage != -1 && iNewPage != file->m_CurrentPageNum ) {
4500|
4501|    i = iNewPage - file->m_StartPageNum;
4502|    page = ListX_get( &file->m_pages, i, SVGCat_Page );
4503|    SVGCat_File_loadPage( file, page );
4504|
4505|    if ( file->m_bShowing && view->m_InkOverlay != NULL && file == &m_file ) {
4506|
4507|      /* InkOverlay を次のページの内容に変える */
4508|      view->NewInkOverlay();
4509|      hr = view->m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error();
4510|      ink->Load( page->ink );
4511|      if ( hr != S_OK )  error();
4512|      hr = ink->Release();  ink = NULL;
4513|
4514|      hr = view->m_InkRectangle->SetRectangle( /*top*/ 0, /*left*/ 0,
4515|        /*bottom*/ file->m_Canvas.m_Height * view->m_Zoom / 100,
4516|        /*right*/  file->m_Canvas.m_Width * view->m_Zoom / 100 );
4517|      if ( hr != 0 )  error();
4518|
4519|      hr = view->m_InkOverlay->SetWindowInputRectangle( view->m_InkRectangle );
4520|      if ( hr != 0 )  error();
4521|    }
4522|  }
4523|
4524|  file->m_CurrentPageNum = iNewPage;
4525|}
4526|
4527|
4528|void  CSVGCatApp::ChgPageByPrims( SVGCat_File* file, ListX* targetPrims )
4529|{
4530|  SVGCat_Page*  page;
4531|
4532|  for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
4533|    if ( &page->prims == targetPrims )  break;
4534|  }
4535|
4536|  ChgPage( file, ListX_getI( &file->m_pages, page ) + file->m_StartPageNum );
4537|}
4538|
4539|
4540| 
4541|/***********************************************************************
4542|  27. <<< [CSVGCatApp::NewPage] 新しいページを作成する >>> 
4543|【引数】
4544|  ・int  pos;    挿入位置  0=下, 1=子, 2=上
4545|************************************************************************/
4546|void  CSVGCatApp::NewPage( SVGCat_File* file, int pos )
4547|{
4548|  CChildView*  view = ((CMainFrame*)m_pMainWnd)->m_wndView;
4549|  SVGCat_Page*  page;
4550|  SVGCat_Page*  nextPage;
4551|  SVGCat_Page*  newPage;
4552|  int  iPage = file->m_CurrentPageNum - file->m_StartPageNum;
4553|  int  i, m;
4554|  FILE*  f;
4555|  char  path[_MAX_PATH];
4556|
4557|
4558|  ChgPage( file, -1 );
4559|
4560|
4561|  /* 新しいページを作成してツリーリンクを調節する */
4562|  page = ListX_get( &file->m_pages, iPage, SVGCat_Page );
4563|  if ( pos == 0 ) {  /* 下 */
4564|    if ( page->next == NULL ) {
4565|      nextPage = SVGCat_Page_getChildOver( page );
4566|    }
4567|    else {
4568|      nextPage = page->next;
4569|    }
4570|    newPage = ListX_insertMalloc( &file->m_pages, nextPage, SVGCat_Page );
4571|    newPage->parent = page->parent;
4572|    newPage->firstChild = NULL;
4573|    //newPage->next = NULL;
4574|    //newPage->prev = NULL;
4575|    newPage->next = page->next;  if ( page->next != NULL )  page->next->prev = newPage;
4576|    page->next = newPage;  newPage->prev = page;
4577|    iPage = ListX_getI( &file->m_pages, newPage ) + file->m_StartPageNum;
4578|  }
4579|  else if ( pos == 1 ) {  /* 子 */
4580|    nextPage = ListX_Elem_getNextT( page, SVGCat_Page );
4581|    newPage = ListX_insertMalloc( &file->m_pages, nextPage, SVGCat_Page );
4582|    newPage->parent = NULL;
4583|    newPage->firstChild = NULL;
4584|    //newPage->next = NULL;
4585|    newPage->prev = NULL;
4586|    nextPage = page->firstChild;
4587|    page->firstChild = newPage;  newPage->parent = page;
4588|    newPage->next = nextPage;  if ( nextPage != NULL )  nextPage->prev = newPage;
4589|    iPage = iPage + file->m_StartPageNum + 1;
4590|  }
4591|  else if ( pos == 2 ) {  /* 上 */
4592|    newPage = ListX_insertMalloc( &file->m_pages, page, SVGCat_Page );
4593|    newPage->parent = page->parent;
4594|    newPage->firstChild = NULL;
4595|    //newPage->next = NULL;
4596|    //newPage->prev = NULL;
4597|    newPage->prev = page->prev;  if ( page->prev != NULL )  page->prev->next= newPage;
4598|    page->prev = newPage;  newPage->next = page;
4599|    iPage = iPage + file->m_StartPageNum;
4600|  }
4601|
4602|  /* 新しいページを初期化する */
4603|  strcpy( newPage->title, "New Page" );
4604|  ListX_init( &newPage->prims );
4605|  newPage->canvas = page->canvas;
4606|  newPage->canvas.m_CorrImagePath[0] = '\0';
4607|  Variant_initEmpty( &newPage->ink );
4608|  newPage->bBeforeDraw = TRUE;
4609|
4610|
4611|  /* 新しいページより後のテンポラリファイルのファイル名を変える */
4612|  m = ListX_getN( &file->m_pages, SVGCat_Page ) + file->m_StartPageNum - 1;
4613|  for ( i = m - 1; i >= iPage; i-- ) {
4614|    strcpy( path, GetInkWorkFilePath( file->m_id, i+1, IRO_MaskPen ) );
4615|    MoveFile( GetInkWorkFilePath( file->m_id, i, IRO_MaskPen ), path );
4616|
4617|    strcpy( path, GetInkWorkFilePath( file->m_id, i+1, IRO_CopyPen ) );
4618|    MoveFile( GetInkWorkFilePath( file->m_id, i, IRO_CopyPen ), path );
4619|  }
4620|
4621|
4622|  /* 新しいページのインクのテンポラリファイルを生成する */
4623|  f = FileX_open( GetInkWorkFilePath( file->m_id, iPage, IRO_MaskPen ), "wt" );
4624|  fclose( f );
4625|  f = FileX_open( GetInkWorkFilePath( file->m_id, iPage, IRO_CopyPen ), "wt" );
4626|  fclose( f );
4627|
4628|
4629|
4630|  ChgPage( file, iPage );
4631|
4632|  //printPages("6");
4633|}
4634|
4635|
4636| 
4637|/***********************************************************************
4638|  28. <<< [CSVGCatApp::ChgToBackPage] 背景ページと通常ページを切り替える >>> 
4639|************************************************************************/
4640|void  CSVGCatApp::ChgToBackPage( SVGCat_File* file )
4641|{
4642|  int  currentPageNum = file->m_CurrentPageNum;
4643|
4644|  ChgPage( file, -1 );
4645|
4646|  /* 通常ページに切り替える */
4647|  if ( currentPageNum == 0 ) {
4648|    ChgPage( file, file->m_FrontPageNum );
4649|  }
4650|
4651|  /* 背景ページに切り替える */
4652|  else {
4653|    SVGCat_Page*  page;
4654|    SVGCat_Page*  newPage;
4655|    int  iPage = currentPageNum - file->m_StartPageNum;
4656|    FILE*  f;
4657|
4658|
4659|    if ( file->m_StartPageNum == 1 ) {
4660|      page = ListX_get( &file->m_pages, iPage, SVGCat_Page );
4661|      newPage = ListX_addFirstMalloc( &file->m_pages, SVGCat_Page );
4662|      strcpy( newPage->title, ( m_bJapanese ? "背景" : "Background" ) );
4663|      ListX_init( &newPage->prims );
4664|      newPage->canvas = page->canvas;
4665|      Variant_initEmpty( &newPage->ink );
4666|      newPage->bBeforeDraw = TRUE;
4667|      newPage->parent = NULL;
4668|      newPage->firstChild = NULL;
4669|      newPage->next = NULL;
4670|      newPage->prev = NULL;
4671|      file->m_StartPageNum = 0;
4672|      file->m_bExistBackPage = true;
4673|
4674|      /* 新しいページのインクのテンポラリファイルを生成する */
4675|      f = FileX_open( GetInkWorkFilePath( file->m_id, 0, IRO_MaskPen ), "wt" );
4676|      fclose( f );
4677|      f = FileX_open( GetInkWorkFilePath( file->m_id, 0, IRO_CopyPen ), "wt" );
4678|      fclose( f );
4679|    }
4680|
4681|    ChgPage( file, 0 );
4682|    file->m_FrontPageNum = currentPageNum;
4683|  }
4684|}
4685|
4686|
4687| 
4688|/***********************************************************************
4689|  29. <<< [CSVGCatApp::SwapPage] ページの内容を入れ替える >>> 
4690|************************************************************************/
4691|void  CSVGCatApp::SwapPage( SVGCat_File* file, int page1num, int page2num )
4692|{
4693|  SVGCat_Page*  page1;
4694|  SVGCat_Page*  page2;
4695|  SVGCat_Page   pageX;
4696|  char  path[_MAX_PATH];
4697|
4698|  if ( page1num == page2num )  return;
4699|
4700|  ChgPage( file, file->m_CurrentPageNum );  /* 同期を取る */
4701|
4702|  page1 = ListX_get( &file->m_pages, page1num - file->m_StartPageNum, SVGCat_Page );
4703|  page2 = ListX_get( &file->m_pages, page2num - file->m_StartPageNum, SVGCat_Page );
4704|
4705|  /* ページ情報を入れ替える */
4706|  pageX.prims = page1->prims;
4707|  pageX.canvas = page1->canvas;
4708|  pageX.ink = page1->ink;
4709|
4710|  page1->prims = page2->prims;
4711|  page1->canvas = page2->canvas;
4712|  page1->ink = page2->ink;
4713|
4714|  page2->prims = pageX.prims;
4715|  page2->canvas = pageX.canvas;
4716|  page2->ink = pageX.ink;
4717|
4718|  if ( page1num == file->m_CurrentPageNum ) {
4719|    SVGCat_File_loadPage( file, page1 );
4720|  }
4721|  else if ( page2num == file->m_CurrentPageNum ) {
4722|    SVGCat_File_loadPage( file, page2 );
4723|  }
4724|
4725|
4726|  /* インクの一時ファイルを入れ替える */
4727|  strcpy( path, GetInkWorkFilePath( file->m_id, -1, IRO_MaskPen ) );
4728|  MoveFile( GetInkWorkFilePath( file->m_id, page1num, IRO_MaskPen ), path );
4729|
4730|  strcpy( path, GetInkWorkFilePath( file->m_id, page1num, IRO_MaskPen ) );
4731|  MoveFile( GetInkWorkFilePath( file->m_id, page2num, IRO_MaskPen ), path );
4732|
4733|  strcpy( path, GetInkWorkFilePath( file->m_id, page2num, IRO_MaskPen ) );
4734|  MoveFile( GetInkWorkFilePath( file->m_id, -1, IRO_MaskPen ), path );
4735|
4736|  strcpy( path, GetInkWorkFilePath( file->m_id, -1, IRO_CopyPen ) );
4737|  MoveFile( GetInkWorkFilePath( file->m_id, page1num, IRO_CopyPen ), path );
4738|
4739|  strcpy( path, GetInkWorkFilePath( file->m_id, page1num, IRO_CopyPen ) );
4740|  MoveFile( GetInkWorkFilePath( file->m_id, page2num, IRO_CopyPen ), path );
4741|
4742|  strcpy( path, GetInkWorkFilePath( file->m_id, page2num, IRO_CopyPen ) );
4743|  MoveFile( GetInkWorkFilePath( file->m_id, -1, IRO_CopyPen ), path );
4744|
4745|
4746|  /* 背景ページのときは、背景キャッシュを更新する */
4747|  if ( ( page1num == 0 || page2num == 0 ) && file->m_bShowing ) {
4748|    CChildView*  view = ((CMainFrame*)m_pMainWnd)->m_wndView;
4749|    SVGCat_Page*  page = ListX_getFirst( &file->m_pages, SVGCat_Page );
4750|    IInkDisp*  ink;
4751|    HRESULT  hr;
4752|
4753|    file->m_CurrentPageNum = 0;
4754|    SVGCat_File_loadPage( file, page );
4755|
4756|    if ( view->m_InkOverlay != NULL ) {
4757|      view->NewInkOverlay();
4758|      hr = view->m_InkOverlay->get_Ink( &ink );  if ( hr != 0 )  error();
4759|      ink->Load( page->ink );  if ( hr != S_OK )  error();
4760|      hr = ink->Release();  ink = NULL;
4761|    }
4762|
4763|    view->DrawBackBitmap();
4764|  }
4765|}
4766|
4767|
4768| 
4769|/***********************************************************************
4770|  30. <<< [CSVGCatApp::DelPage] ページを削除する(ツリーの奥も含む) >>> 
4771|************************************************************************/
4772|void  CSVGCatApp::DelPage( SVGCat_File* file )
4773|{
4774|  SVGCat_Page*  page;
4775|  SVGCat_Page*  overPage;
4776|  SVGCat_Page*  prevPage;
4777|  SVGCat_Page*  nextPage;
4778|  SVGCat_Page*  parentPage;
4779|  SVGCat_Page*  parentPage2;
4780|  SVGCat_Page*  page2;
4781|  int  pageNum = file->m_CurrentPageNum;
4782|  int  nPage;
4783|  int  i, m;
4784|  char  path[_MAX_PATH];
4785|
4786|  ChgPage( file, -1 );
4787|
4788|  page = ListX_get( &file->m_pages, pageNum - file->m_StartPageNum, SVGCat_Page );
4789|  prevPage = page->prev;
4790|  nextPage = page->next;
4791|  parentPage = page->parent;
4792|
4793|  if ( nextPage != NULL )  overPage = nextPage;
4794|  else {
4795|    parentPage2 = parentPage;
4796|    for (;;) {
4797|      if ( parentPage2 == NULL )  { overPage = NULL;  break; }
4798|      overPage = parentPage2->next;
4799|      if ( overPage != NULL )  break;
4800|      parentPage2 = parentPage2->parent;
4801|    }
4802|  }
4803|
4804|
4805|  /* 削除するページをアンドゥバッファに移動する */
4806|  i = SVGCat_File_getPageNum( file, overPage );
4807|  page2 = ListX_removeSet( &file->m_pages, page,
4808|    ListX_getPrev( &file->m_pages, overPage, SVGCat_Page ), SVGCat_Page );
4809|  m = m_UndoBuf->AllocNewStep_Page( pageNum, i, -1, -1, -1, page2 );
4810|  nPage = i - pageNum;
4811|
4812|
4813|  /* 削除するインク・テンポラリファイルのファイル名を変える */
4814|  for ( i = 0; i < nPage; i++ ) {
4815|    strcpy( path, GetInkWorkFilePath( file->m_id, 10000+m+i, IRO_MaskPen ) );
4816|    MoveFile( GetInkWorkFilePath( file->m_id, pageNum+i, IRO_MaskPen ), path );
4817|    strcpy( path, GetInkWorkFilePath( file->m_id, 10000+m+i, IRO_CopyPen ) );
4818|    MoveFile( GetInkWorkFilePath( file->m_id, pageNum+i, IRO_CopyPen ), path );
4819|  }
4820|
4821|
4822|  /* 削除ページより後のインク・テンポラリファイルのファイル名を変える */
4823|  m = ListX_getN( &file->m_pages, SVGCat_Page ) + file->m_StartPageNum - 1;
4824|  for ( i = pageNum; i <= m; i++ ) {
4825|    strcpy( path, GetInkWorkFilePath( file->m_id, i, IRO_MaskPen ) );
4826|    MoveFile( GetInkWorkFilePath( file->m_id, i+nPage, IRO_MaskPen ), path );
4827|
4828|    strcpy( path, GetInkWorkFilePath( file->m_id, i, IRO_CopyPen ) );
4829|    MoveFile( GetInkWorkFilePath( file->m_id, i+nPage, IRO_CopyPen ), path );
4830|  }
4831|
4832|
4833|  /* ページ間リンクを調節する */
4834|  if ( prevPage != NULL )  prevPage->next = nextPage;
4835|  else  if ( parentPage != NULL )  parentPage->firstChild = nextPage;
4836|  if ( nextPage != NULL )  nextPage->prev = prevPage;
4837|  if ( prevPage == NULL && nextPage == NULL )
4838|    parentPage->firstChild = NULL;
4839|
4840|
4841|  if ( overPage == NULL )  ChgPage( file, pageNum - 1 );
4842|  else  ChgPage( file, pageNum );
4843|}
4844|
4845|
4846|
4847| 
4848|/***********************************************************************
4849|  31. <<< [CSVGCatApp::ImportSVG] SVG ファイルからページを追加する >>> 
4850|【引数】
4851|  ・SVGCat_File*  file;    追加するファイル
4852|  ・SVGCat_Page*  insPos;  追加する位置
4853|  ・char*         path;    追加するファイルのパス
4854|  ・SVGCat_Page*  addedLastTopLevelPage;  insPos と同じ深さの追加した最後のページ
4855|  ・SVGCat_Page*  addedLastPage;          追加した最後のページ
4856|  ・SVGCat_Page*  返り値;                 追加した最初のページ
4857|************************************************************************/
4858|SVGCat_Page*  CSVGCatApp::ImportSVG( SVGCat_File* file, SVGCat_Page* insPos, const char* path,
4859|  SVGCat_Page** addedLastTopLevelPage, SVGCat_Page** addedLastPage )
4860|{
4861|  CChildView*  view = ((CMainFrame*)m_pMainWnd)->m_wndView;
4862|  SVGCat_File  inpFile;
4863|  SVGCat_Page*  page;
4864|  SVGCat_Page*  newFirstPage;
4865|  SVGCat_Page*  newLastPage;  /* newFirstPage と同じ深さの最も最後のページ */
4866|  SVGCat_Page*  newLastChildPage;  /* 最後のページ */
4867|  int  currentPageNum = file->m_CurrentPageNum;
4868|  int  nImportPage;
4869|  int  importStartPageNum;
4870|  int  maxPageNum = SVGCat_File_getMaxPageNum( file );
4871|  int  i;
4872|
4873|
4874|  ChgPage( file, -1 );
4875|
4876|  /* インポートする SVG ファイルを読み込む */
4877|  {
4878|    ListX_ElemX*  pPrim;
4879|
4880|    inpFile.m_bPagesExist = false;
4881|    NewEmpty_imp( &inpFile, 0, false );
4882|    Load_imp( inpFile.m_id, &inpFile, path );
4883|
4884|    view->SetDrawnParam( &inpFile.m_prims );
4885|    Load2( &inpFile.m_prims );
4886|    nImportPage = 0;
4887|    for ( ListX_forEach( &inpFile.m_pages, &page, SVGCat_Page ) ) {
4888|      view->SetDrawnParam( &page->prims );
4889|      Load2( &page->prims );
4890|      nImportPage ++;
4891|    }
4892|
4893|    newFirstPage = ListX_getFirst( &inpFile.m_pages, SVGCat_Page );
4894|    newLastChildPage = ListX_getLast( &inpFile.m_pages, SVGCat_Page );
4895|    for ( newLastPage = newLastChildPage;  newLastPage->parent != NULL;
4896|          newLastPage = newLastPage->parent );
4897|
4898|    ListX_toEmpty( &inpFile.m_pages );  /* リストの要素はメモリに残したまま空にする */
4899|
4900|    /* 背景はインポートしない */
4901|    if ( inpFile.m_StartPageNum == 0 ) {
4902|      page = newFirstPage;
4903|      newFirstPage = ListX_Elem_getNextT( newFirstPage, SVGCat_Page );
4904|      nImportPage --;
4905|
4906|      for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
4907|        delete  (CadPrim*)pPrim->p;
4908|      }
4909|      ListX_toEmptyDelete( &page->prims, ListX_ElemX, NULL );
4910|      Variant_finish( &page->ink );
4911|      remove( GetInkWorkFilePath( inpFile.m_id, 0, IRO_MaskPen ) );
4912|      remove( GetInkWorkFilePath( inpFile.m_id, 0, IRO_CopyPen ) );
4913|    }
4914|    importStartPageNum = inpFile.m_StartPageNum;
4915|  }
4916|
4917|
4918|  /* 読み込んだ全てのページを file に移動する */
4919|  {
4920|    ListX_insertSet( &file->m_pages, insPos, newFirstPage );
4921|
4922|    if ( insPos->prev != NULL ) {
4923|      page = insPos->prev;
4924|      page->next = newFirstPage;  newFirstPage->prev = page;
4925|    }
4926|    else if ( insPos->parent != NULL ) {
4927|      page = insPos->parent;
4928|      page->firstChild = newFirstPage;  newFirstPage->parent = page;
4929|    }
4930|    newLastPage->next = insPos;  insPos->prev = newLastPage;
4931|  }
4932|
4933|  /* Ink 一時ファイルを改名する */
4934|  {
4935|    int  pageNum;
4936|    char  path[_MAX_PATH];
4937|
4938|    /* 下へスクロールする */
4939|    for ( pageNum = maxPageNum; pageNum >= currentPageNum; pageNum-- ) {
4940|      strcpy( path, GetInkWorkFilePath( file->m_id, pageNum + nImportPage, IRO_MaskPen ) );
4941|      MoveFile( GetInkWorkFilePath( file->m_id, pageNum, IRO_MaskPen ), path );
4942|      strcpy( path, GetInkWorkFilePath( file->m_id, pageNum + nImportPage, IRO_CopyPen ) );
4943|      MoveFile( GetInkWorkFilePath( file->m_id, pageNum, IRO_CopyPen ), path );
4944|    }
4945|
4946|    /* インポート分 */
4947|    for ( i = 0; i < nImportPage; i++ ) {
4948|      strcpy( path, GetInkWorkFilePath( file->m_id, currentPageNum + i, IRO_MaskPen ) );
4949|      MoveFile( GetInkWorkFilePath( 0, i+1, IRO_MaskPen ), path );
4950|      strcpy( path, GetInkWorkFilePath( file->m_id, currentPageNum + i, IRO_CopyPen ) );
4951|      MoveFile( GetInkWorkFilePath( 0, i+1, IRO_CopyPen ), path );
4952|    }
4953|  }
4954|
4955|  Finish_imp( &inpFile );  /* ink 一時ファイルの改名のため、ここまで遅らせている */
4956|
4957|  ChgPage( file, currentPageNum );
4958|
4959|  for ( i = 0; i < nImportPage; i++ )
4960|    m_UndoBuf->AllocNewStep_Page( -1, 2, -1, currentPageNum, -1, NULL );
4961|
4962|  if ( addedLastTopLevelPage != NULL )  *addedLastTopLevelPage = newLastPage;
4963|  if ( addedLastPage != NULL )  *addedLastPage = newLastChildPage;
4964|  return  newFirstPage;
4965|}
4966|
4967|
4968| 
4969|/***********************************************************************
4970|  32. <<< [CSVGCatApp::MoveInkWorkFile] インクデータのワークファイルのページを移動する >>> 
4971|【引数】
4972|  ・SVGCat_File*  file;   SVG ファイル
4973|  ・int  iSrcPage;        移動対象の先頭ページの番号(0〜or1〜)
4974|  ・int  iSrcOverPage;    移動対象の最後の次のページの番号(0〜or1〜)
4975|  ・int  iDstPage;        移動先のページの番号(0〜or1〜)、(移動前のもの)
4976|************************************************************************/
4977|void  CSVGCatApp::MoveInkWorkFile( SVGCat_File* file, int iSrcPage,
4978|  int iSrcOverPage, int iDstPage )
4979|{
4980|  int  iPage;
4981|  int  id = file->m_id;
4982|  int  nPage;
4983|  int  diff;
4984|  char  path[_MAX_PATH];
4985|
4986|  if ( iDstPage == iSrcPage || iDstPage == iSrcOverPage )  return;
4987|
4988|  ASSERT( iDstPage < iSrcPage || iDstPage > iSrcOverPage );
4989|
4990|  if ( iSrcOverPage < file->m_StartPageNum )
4991|    iSrcOverPage = ListX_getN( &file->m_pages, SVGCat_Page ) + file->m_StartPageNum;
4992|  if ( iDstPage < file->m_StartPageNum )
4993|    iDstPage = ListX_getN( &file->m_pages, SVGCat_Page ) + file->m_StartPageNum;
4994|
4995|  nPage = iSrcOverPage - iSrcPage;
4996|  diff = iDstPage - iSrcPage;
4997|
4998|
4999|  /* 移動対象をページ番号に 20000 足したものに一時的に変える */
5000|  for ( iPage = iSrcPage; iPage < iSrcOverPage; iPage++ ) {
5001|    strcpy( path, GetInkWorkFilePath( id, iPage + 20000, IRO_MaskPen ) );
5002|    MoveFile( GetInkWorkFilePath( id, iPage, IRO_MaskPen ), path );
5003|    strcpy( path, GetInkWorkFilePath( id, iPage + 20000, IRO_CopyPen ) );
5004|    MoveFile( GetInkWorkFilePath( id, iPage, IRO_CopyPen ), path );
5005|  }
5006|
5007|  /* 移動対象にページ番号が変わるもののファイル名を変える */
5008|  if ( iDstPage < iSrcPage ) {
5009|    for ( iPage = iSrcPage - 1; iPage >= iDstPage; iPage-- ) {
5010|      strcpy( path, GetInkWorkFilePath( id, iPage + nPage, IRO_MaskPen ) );
5011|      MoveFile( GetInkWorkFilePath( id, iPage, IRO_MaskPen ), path );
5012|      strcpy( path, GetInkWorkFilePath( id, iPage + nPage, IRO_CopyPen ) );
5013|      MoveFile( GetInkWorkFilePath( id, iPage, IRO_CopyPen ), path );
5014|    }
5015|  }
5016|  else {
5017|    for ( iPage = iSrcOverPage; iPage < iDstPage; iPage++ ) {
5018|      strcpy( path, GetInkWorkFilePath( id, iPage - nPage, IRO_MaskPen ) );
5019|      MoveFile( GetInkWorkFilePath( id, iPage, IRO_MaskPen ), path );
5020|      strcpy( path, GetInkWorkFilePath( id, iPage - nPage, IRO_CopyPen ) );
5021|      MoveFile( GetInkWorkFilePath( id, iPage, IRO_CopyPen ), path );
5022|    }
5023|    diff -= nPage;
5024|  }
5025|
5026|  /* 移動対象のファイル名を変える */
5027|  for ( iPage = iSrcPage; iPage < iSrcOverPage; iPage++ ) {
5028|    strcpy( path, GetInkWorkFilePath( id, iPage + diff, IRO_MaskPen ) );
5029|    MoveFile( GetInkWorkFilePath( id, iPage + 20000, IRO_MaskPen ), path );
5030|    strcpy( path, GetInkWorkFilePath( id, iPage + diff, IRO_CopyPen ) );
5031|    MoveFile( GetInkWorkFilePath( id, iPage + 20000, IRO_CopyPen ), path );
5032|  }
5033|}
5034|
5035|
5036|
5037| 
5038|/***********************************************************************
5039|  33. <<< [CSVGCatApp::SearchByID] ID で図形を検索する >>> 
5040|【引数】
5041|  ・char*  id;      ジャンプ先の記述(例:#shousai なら shousai のみを指定)
5042|  ・CadPrim** prim;  (in)前回ヒットした図形, *prim==NULL:初、(out)ヒットした図形
5043|  ・int  返り値;     ヒットした図形があるページ番号(-1=ヒットしなかった)
5044|【補足】
5045|・prim == NULL のとき、最初にヒットした図形のページのみ検索でき、
5046|  ヒットした図形は検索できません。
5047|・他の SVG の中の途中のページにジャンプすることには対応していません。
5048|************************************************************************/
5049|int  CSVGCatApp::SearchByID( SVGCat_File* file, const char* id, CadPrim** prim )
5050|{
5051|  SVGCat_Page*  page;
5052|  ListX_ElemX*  pPrim;
5053|  CadPrim*  prim2;
5054|  int  iPage;
5055|  bool  bStart;
5056|
5057|  if ( prim == NULL )  prim2 = NULL;
5058|  else  prim2 = *prim;
5059|  bStart = ( prim2 == NULL );
5060|
5061|  iPage = file->m_StartPageNum;
5062|  for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
5063|    for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
5064|      if ( bStart ) {
5065|        if ( stricmp( id, ((CadPrim*)pPrim->p)->GetIdLabel() ) == 0 ) {
5066|          if ( prim != NULL )  *prim = (CadPrim*)pPrim->p;
5067|          return  iPage;
5068|        }
5069|      }
5070|      else {
5071|        bStart = ( prim2 == (CadPrim*)pPrim->p );
5072|      }
5073|    }
5074|    iPage++;
5075|  }
5076|  if ( prim != NULL )  *prim = NULL;
5077|  return  -1;
5078|}
5079|
5080| 
5081|/***********************************************************************
5082|  34. <<< [CSVGCatApp::SearchByText] テキストで図形を検索する >>> 
5083|【引数】
5084|  ・char*  text;     ヒットするテキストの一部
5085|  ・CadPrim** prim;  (in)前回ヒットした図形, *prim==NULL:初、(out)ヒットした図形
5086|  ・int  返り値;     ヒットした図形があるページ番号(-1=ヒットしなかった)
5087|【補足】
5088|・参考:CSVGCatApp::SearchByID
5089|************************************************************************/
5090|int  CSVGCatApp::SearchByText( SVGCat_File* file, const char* text, CadPrim** prim )
5091|{
5092|  SVGCat_Page*  page;
5093|  ListX_ElemX*  pPrim;
5094|  CadPrim*  prim2;
5095|  int  iPage;
5096|  bool  bStart;
5097|
5098|  if ( prim == NULL )  prim2 = NULL;
5099|  else  prim2 = *prim;
5100|  bStart = ( prim2 == NULL );
5101|
5102|  iPage = file->m_StartPageNum;
5103|  for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
5104|    for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
5105|      if ( ((CadPrim*)pPrim->p)->GetTypeID() == Text_Box_TypeID &&
5106|           StrX_stristr3( ((Text_Box*)pPrim->p)->m_Text, text, false, NULL ) != NULL ) {
5107|        if ( bStart ) {
5108|          if ( prim != NULL )  *prim = (CadPrim*)pPrim->p;
5109|          return  iPage;
5110|        }
5111|        else {
5112|          bStart = ( prim2 == (CadPrim*)pPrim->p );
5113|        }
5114|      }
5115|    }
5116|    iPage++;
5117|  }
5118|
5119|  if ( prim != NULL )  *prim = NULL;
5120|  return  -1;
5121|}
5122|
5123| 
5124|/***********************************************************************
5125|  35. <<< [CSVGCatApp::SearchReverseByText] テキストで図形を検索する(逆順で) >>> 
5126|【引数】
5127|  ・char*  text;     ヒットするテキストの一部
5128|  ・CadPrim** prim;  (in)前回ヒットした図形, *prim==NULL:初、(out)ヒットした図形
5129|  ・int  返り値;     ヒットした図形があるページ番号(-1=ヒットしなかった)
5130|【補足】
5131|・参考:CSVGCatApp::SearchByID
5132|************************************************************************/
5133|int  CSVGCatApp::SearchReverseByText( SVGCat_File* file, const char* text, CadPrim** prim )
5134|{
5135|  SVGCat_Page*  page;
5136|  ListX_ElemX*  pPrim;
5137|  CadPrim*  prim2;
5138|  int  iPage;
5139|  int  ret = -1;
5140|
5141|  if ( prim == NULL )  prim2 = NULL;
5142|  else  prim2 = *prim;
5143|  *prim = NULL;
5144|
5145|  iPage = file->m_StartPageNum;
5146|  for ( ListX_forEach( &file->m_pages, &page, SVGCat_Page ) ) {
5147|    for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
5148|      if ( (CadPrim*)pPrim->p == prim2 )
5149|        return  ret;
5150|      if ( ((CadPrim*)pPrim->p)->GetTypeID() == Text_Box_TypeID &&
5151|           StrX_stristr3( ((Text_Box*)pPrim->p)->m_Text, text, false, NULL ) != NULL ) {
5152|        if ( prim != NULL )  *prim = (CadPrim*)pPrim->p;
5153|        ret = iPage;
5154|      }
5155|    }
5156|    iPage++;
5157|  }
5158|  return  ret;
5159|}
5160|
5161| 
5162|/***********************************************************************
5163|  36. <<< [CSVGCatApp::SearchByRect] 座標で図形を検索する >>> 
5164|【引数】
5165|  ・int  iPage;     検索するページ番号
5166|  ・RECT*  rc;      ヒットする座標の範囲
5167|  ・CadPrim** prim;  (in)前回ヒットした図形, *prim==NULL:初、(out)ヒットした図形
5168|  ・int  返り値;     ヒットした図形があるページ番号(-1=ヒットしなかった)
5169|【補足】
5170|・参考:CSVGCatApp::SearchByID
5171|・インクにはヒットしません。
5172|************************************************************************/
5173|int  CSVGCatApp::SearchByRect( SVGCat_File* file, int iPage, Rect* rc, CadPrim** prim )
5174|{
5175|  SVGCat_Page*  page = ListX_get( &file->m_pages, iPage, SVGCat_Page );
5176|  ListX_ElemX*  pPrim;
5177|  CadPrim*  prim2;
5178|  bool  bStart;
5179|
5180|  if ( prim == NULL )  prim2 = NULL;
5181|  else  prim2 = *prim;
5182|  bStart = ( prim2 == NULL );
5183|
5184|  for ( ListX_forEach( &page->prims, &pPrim, ListX_ElemX ) ) {
5185|    if ( bStart ) {
5186|      if ( ((CadPrim*)pPrim->p)->IsMultiSelect( rc ) ) {
5187|        if ( prim != NULL )  *prim = (CadPrim*)pPrim->p;
5188|        return  iPage;
5189|      }
5190|    }
5191|    else {
5192|      bStart = ( prim2 == (CadPrim*)pPrim->p );
5193|    }
5194|  }
5195|
5196|  if ( prim != NULL )  *prim = NULL;
5197|  return  -1;
5198|}
5199|
5200| 
5201|/***********************************************************************
5202|  37. <<< [CSVGCatApp::SearchStrokeByRect] 座標でストロークを1つ検索する >>> 
5203|【引数】
5204|  ・int  iPage;     検索するページ番号
5205|  ・RECT*  rc;      ヒットする座標の範囲
5206|  ・int  nSkip;     ヒットをスキップする回数
5207|  ・IInkStrokeDisp**  stroke;  ヒットしたストローク(出力)(要 IUnknown::Release)
5208|  ・int  返り値;     ヒットした図形があるページ番号(-1=ヒットしなかった)
5209|【補足】
5210|・複数のストロークを検索するときは、API: IInkDisp::HitTestWithRectangle
5211|  を使うといいでしょう。
5212|************************************************************************/
5213|int  CSVGCatApp::SearchStrokeByRect( SVGCat_File* file, int iPage, Rect* rc,
5214|  int nSkip, IInkStrokeDisp** stroke )
5215|{
5216|  SVGCat_Page*  page = ListX_get( &file->m_pages, iPage, SVGCat_Page );
5217|  CChildView*  view = ((CMainFrame*)m_pMainWnd)->m_wndView;
5218|  HRESULT  hr;
5219|  IInkRectangle*  rect;
5220|  RECT rectX;
5221|  IInkDisp*  ink;
5222|  IInkRenderer* render;
5223|  IInkStrokes*  strokes;
5224|  CClientDC  dc( view );
5225|  int  ret;
5226|
5227|  hr = view->m_InkOverlay->get_Renderer( &render );
5228|  if ( hr != 0 ) error();
5229|
5230|
5231|  hr = CoCreateInstance( CLSID_InkDisp, NULL, CLSCTX_INPROC_SERVER,
5232|                         IID_IInkDisp, (void**)&ink );
5233|  if ( hr != 0 )  error();
5234|  hr = ink->Load( page->ink );
5235|  if ( hr != 0 )  error();
5236|
5237|
5238|  rectX.left = rc->x;  rectX.top = rc->y;
5239|  rectX.right = rc->x + rc->w;  rectX.bottom = rc->y + rc->h;
5240|
5241|  hr = CoCreateInstance( CLSID_InkRectangle, NULL, CLSCTX_INPROC_SERVER,
5242|                         IID_IInkRectangle, (void**)&rect );
5243|  if ( hr != 0 )  error();
5244|  hr = render->PixelToInkSpace( (long)dc.m_hDC, &rectX.left, &rectX.top );
5245|  if ( hr != 0 )  error();
5246|  hr = render->PixelToInkSpace( (long)dc.m_hDC, &rectX.right, &rectX.bottom );
5247|  if ( hr != 0 )  error();
5248|  hr = rect->put_Data( rectX );
5249|  if ( hr != 0 )  error();
5250|
5251|  hr = ink->HitTestWithRectangle( rect, 0.0f, &strokes );
5252|  if ( hr != 0 )  error();
5253|
5254|  hr = strokes->Item( nSkip, stroke );
5255|  ret = ( hr == 0 ? iPage : -1 );
5256|
5257|  hr = strokes->Release();  strokes = NULL;
5258|  hr = rect->Release();  rect = NULL;
5259|  hr = ink->Release();  ink = NULL;
5260|  hr = render->Release();  render = NULL;
5261|
5262|  return  ret;
5263|}
5264|
5265| 
5266|/***********************************************************************
5267|  38. <<< [CSVGCatApp::GetCurPrims] m_pages の中でロックしている prims を返す >>> 
5268|************************************************************************/
5269|#if 0
5270|ListX*  CSVGCatApp::GetCurPrims()
5271|{
5272|  SVGCat_Page*  page;
5273|  int  i = file->m_CurrentPageNum - file->m_StartPageNum;
5274|
5275|  /* アンドゥ記録のために同期を取る */
5276|  page = ListX_get( &file->m_pages, i, SVGCat_Page );
5277|  page->prims = m_prims;
5278|  page->canvas = m_Canvas;  /* 高速化のため、ここで同期を取る */
5279|
5280|  return  &( ListX_get( &file->m_pages, file->m_CurrentPageNum - file->m_StartPageNum, SVGCat_Page )
5281|    ->prims );
5282|}
5283|#endif
5284|
5285|
5286|/***********************************************************************
5287|  39. <<< [CSVGCatApp::GetCurCanvas] m_pages の中でロックしている Canvas を返す >>>
5288|************************************************************************/
5289|#if 0
5290|Canvas* CSVGCatApp::GetCurCanvas()
5291|{
5292|  return  &( ListX_get( &file->m_pages, file->m_CurrentPageNum - file->m_StartPageNum, SVGCat_Page )
5293|    ->canvas );
5294|}
5295|#endif
5296|
5297| 
5298|/***********************************************************************
5299|  40. <<< [CSVGCatApp::GetImgWorkFilePath] 画像データのワークファイルのパスを返す >>> 
5300|【引数】
5301|  ・char*  返り値;  パス(関数内部の静的変数のアドレス)
5302|【補足】
5303|・パスの例:"image_01410433_1" ... アプリのインスタンスID=01410433, id=1
5304|・svgcats.exe のあるフォルダのサブフォルダに保存されるようになります。
5305|************************************************************************/
5306|char*  CSVGCatApp::GetImgWorkFilePath( long id_hWnd )
5307|{
5308|  static  char  path[_MAX_PATH];
5309|  static  int   id = 1;
5310|
5311|  sprintf( path, _work_path "\\img_%08X_%d", id_hWnd, id );
5312|  StrX_getExeFullPath( path, path, sizeof(path) );
5313|
5314|  id++;
5315|
5316|  return  path;
5317|}
5318|
5319|
5320| 
5321|/***********************************************************************
5322|  41. <<< [CSVGCatApp::GetInkWorkFilePath] インクデータのワークファイルのパスを返す >>> 
5323|【引数】
5324|  ・char*  返り値;  パス(関数内部の静的変数のアドレス)
5325|【補足】
5326|・パスの例:"ink_01410433_0_13" ... アプリのインスタンスID=01410433, ページ0, CopyPen
5327|・svgcats.exe のあるフォルダのサブフォルダに保存されるようになります。
5328|・自動バックアップを取るとき、IInkOverlay IInkDisp の内容を変えないために、
5329|  ページを切り替えるタイミングでインクに関する SVG ファイルの一部を
5330|  ワークファイルに出力しておきます。そのパスをこの関数で取得します。
5331|・ページ番号 10000 台は、削除アンドゥ用です。
5332|・ページ番号 20000 台は、一時的移動用です。
5333|************************************************************************/
5334|char*  CSVGCatApp::GetInkWorkFilePath( long id_hWnd, int iPage,
5335|  InkRasterOperation outRaster )
5336|{
5337|  static  char  path[_MAX_PATH];
5338|
5339|  sprintf( path, _work_path "\\ink_%08X_%d_%d", id_hWnd, iPage, (int)outRaster );
5340|  StrX_getExeFullPath( path, path, sizeof(path) );
5341|
5342|  return  path;
5343|}
5344|
5345|
5346| 
5347|/***********************************************************************
5348|  42. <<< [CSVGCatApp::SetRecentFile] 最近開いたファイルに登録する >>> 
5349|************************************************************************/
5350|void  CSVGCatApp::SetRecentFile( const char* path )
5351|{
5352|  int  i;
5353|
5354|  /* 最近開いた順に整列する */
5355|  if ( FileX_isExist( path ) ) {
5356|    for ( i = 0; i < m_nRecentPath; i++ ) {
5357|      if ( stricmp( path, m_RecentPath[i] ) == 0 ) {
5358|        if ( i == 0 )  goto  next;
5359|        memmove( m_RecentPath[1], m_RecentPath[0], i * sizeof(m_RecentPath[0]) );
5360|        strcpy( m_RecentPath[0], path );
5361|        break;
5362|      }
5363|    }
5364|    if ( i == m_nRecentPath ) {
5365|      if ( i < mRecent )  { i++;  m_nRecentPath = i; }
5366|      memmove( m_RecentPath[1], m_RecentPath[0], (i-1) * sizeof(m_RecentPath[0]) );
5367|      strcpy( m_RecentPath[0], path );
5368|    }
5369|  }
5370|
5371|#if 0
5372|  /* path のファイルが存在しないときは、履歴から削除する */
5373|  else {
5374|    for ( i = 0; i < m_nRecentPath; i++ ) {
5375|      if ( stricmp( path, m_RecentPath[i] ) == 0 ) {
5376|        memmove( m_RecentPath[i], m_RecentPath[i+1],
5377|          (m_nRecentPath-i-1) * sizeof(m_RecentPath[0]) );
5378|        m_nRecentPath --;
5379|        break;
5380|      }
5381|    }
5382|  }
5383|#endif
5384|
5385|next:
5386|
5387|  /* ファイルが存在しないものすべてを、履歴から削除する */
5388|  RemoveNoExistRecentFile();
5389|
5390|
5391|  /* データベース・ファイルに保存する */
5392|  WriteRecentFile();
5393|
5394|
5395|  /* 関連先への通知 */
5396|  ((CMainFrame*)m_pMainWnd)->SetRecentFileMenu();
5397|}
5398|
5399|/***********************************************************************
5400|  43. <<< [CSVGCatApp::RemoveRecentFile] 最近開いたファイルの登録から外す >>>
5401|************************************************************************/
5402|void  CSVGCatApp::RemoveRecentFile( const char* path )
5403|{
5404|  int  i;
5405|
5406|  for ( i = 0; i < m_nRecentPath; i++ ) {
5407|    if ( stricmp( m_RecentPath[i], path ) == 0 ) {
5408|      memmove( m_RecentPath[i], m_RecentPath[i+1],
5409|        (m_nRecentPath-i-1) * sizeof(m_RecentPath[0]) );
5410|      m_nRecentPath --;
5411|      return;
5412|    }
5413|  }
5414|}
5415|
5416|
5417|/***********************************************************************
5418|  44. <<< [CSVGCatApp::RemoveNoExistRecentFile] 存在しない最近開いたファイルを一覧から削除する >>>
5419|************************************************************************/
5420|void  CSVGCatApp::RemoveNoExistRecentFile()
5421|{
5422|  int  i;
5423|
5424|  for ( i = 0; i < m_nRecentPath; i++ ) {
5425|    if ( m_RecentPath[i][0] == '\\' && m_RecentPath[i][1] == '\\' )
5426|      continue;  /* ネットワークは時間がかかるためチェックしない */
5427|
5428|    if ( ! FileX_isExist( m_RecentPath[i] ) ) {
5429|      memmove( m_RecentPath[i], m_RecentPath[i+1],
5430|        (m_nRecentPath-i-1) * sizeof(m_RecentPath[0]) );
5431|      m_nRecentPath --;
5432|    }
5433|  }
5434|}
5435|
5436|
5437| 
5438|/***********************************************************************
5439|  45. <<< [CSVGCatApp::ReadRecentFile] 最近開いたファイルの一覧を取得する >>> 
5440|【補足】
5441|・m_nRecentPath, m_RecentPath に格納されます。
5442|************************************************************************/
5443|void  CSVGCatApp::ReadRecentFile()
5444|{
5445|  char  path[_MAX_PATH];
5446|
5447|  StrX_getExeFullPath( path, "recent.ini", sizeof(path) );
5448|
5449|  if ( FileX_isExist( path ) ) {
5450|    IniFile_Read  f;
5451|    int    i;
5452|    char   f_buf[256];
5453|
5454|    IniFile_Read_init( &f, path, f_buf, sizeof(f_buf) );
5455|    IniFile_Read_setSection( &f, "RecentFiles" );
5456|    m_nRecentPath = IniFile_Read_getCount( &f, "path" );
5457|    for ( i = 0; i < m_nRecentPath; i++ ) {
5458|      IniFile_Read_getVar( &f, "path", "s", m_RecentPath[i] );
5459|
5460|      /* 存在しないファイルは取得しない */
5461|      if ( m_RecentPath[i][0] == '\\' && m_RecentPath[i][1] == '\\' )
5462|        continue;  /* ネットワークは時間がかかるためチェックしない */
5463|      if ( ! FileX_isExist( m_RecentPath[i] ) )
5464|        { i--;  m_nRecentPath --; }
5465|    }
5466|    IniFile_Read_finish( &f );
5467|  }
5468|  else
5469|    m_nRecentPath = 0;
5470|}
5471|
5472|
5473| 
5474|/***********************************************************************
5475|  46. <<< [CSVGCatApp::WriteRecentFile] 最近開いたファイルの一覧を記録する >>> 
5476|************************************************************************/
5477|void  CSVGCatApp::WriteRecentFile()
5478|{
5479|  IniFile_Write  f;
5480|  char  db_path[_MAX_PATH];
5481|  int  i;
5482|
5483|  StrX_getExeFullPath( db_path, "recent.ini", sizeof(db_path) );
5484|  IniFile_Write_init( &f, db_path );
5485|  IniFile_Write_putSection( &f, "RecentFiles" );
5486|  for ( i = 0; i < m_nRecentPath; i++ )
5487|    IniFile_Write_putVar( &f, "path", "s", m_RecentPath[i] );
5488|  IniFile_Write_finish( &f );
5489|}
5490|
5491|
5492| 
5493|/***********************************************************************
5494|  47. <<< [CSVGCatApp::GetNewPrimID] 図形の ID を返す >>> 
5495|【補足】
5496|・図形に固有の ID を返します。生成破壊のアンドゥによってリンク関係を
5497|  戻すするために使用します。
5498|************************************************************************/
5499|int  CSVGCatApp::GetNewPrimID()
5500|{
5501|  return  m_NextID ++;
5502|}
5503|
5504|
5505| 
5506|/***********************************************************************
5507|  48. <<< [CSVGCatApp::AddPrim] 図形を追加する(追加位置は図形による) >>> 
5508|【引数】
5509|  ・CadPrim*  prim;  追加する図形
5510|************************************************************************/
5511|void  CSVGCatApp::AddPrim( SVGCat_File* file, CadPrim* prim )
5512|{
5513|  ListX_ElemX*  pPrim;
5514|
5515|  if ( prim->GetTypeID() == Rect_Ex_TypeID ) {
5516|    AddPrimToBottomLine( file, prim );
5517|    return;
5518|  }
5519|  else {
5520|    pPrim = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
5521|  }
5522|
5523|  pPrim->p = prim;
5524|}
5525|
5526|
5527| 
5528|/***********************************************************************
5529|  49. <<< [CSVGCatApp::AddPrimToBottomLine] 文字や線の最も奥に図形を追加する >>> 
5530|【引数】
5531|  ・CadPrim*  prim;  追加する図形
5532|************************************************************************/
5533|void  CSVGCatApp::AddPrimToBottomLine( SVGCat_File* file, CadPrim* prim )
5534|{
5535|  ListX_ElemX*  pPrim;
5536|
5537|  pPrim = GetBottomLine( file );
5538|  if ( pPrim == NULL )
5539|    pPrim = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
5540|  else
5541|    pPrim = ListX_insertMalloc( &file->m_prims, pPrim, ListX_ElemX );
5542|
5543|  pPrim->p = prim;
5544|}
5545|
5546|
5547| 
5548|/***********************************************************************
5549|  50. <<< [CSVGCatApp::AddPrimToTop] 図形を最も手前に >>> 
5550|【引数】
5551|  ・CadPrim*  prim;  追加する図形
5552|************************************************************************/
5553|void  CSVGCatApp::AddPrimToTop( SVGCat_File* file, CadPrim* prim )
5554|{
5555|  ListX_ElemX*  pPrim;
5556|
5557|  pPrim = ListX_addLastMalloc( &file->m_prims, ListX_ElemX );
5558|  pPrim->p = prim;
5559|}
5560|
5561|
5562| 
5563|/***********************************************************************
5564|  51. <<< [CSVGCatApp::RemovePrim] 図形を削除する(アンドゥ対応) >>> 
5565|【引数】
5566|  ・CadPrim*  prim;  削除する図形
5567|************************************************************************/
5568|void  CSVGCatApp::RemovePrim( SVGCat_File* file, CadPrim* prim )
5569|{
5570|  ListX_ElemX*  pPrim;
5571|
5572|  for ( ListX_forEach( &file->m_prims, &pPrim, ListX_ElemX ) ) {
5573|    if ( pPrim->p == prim )  break;
5574|  }
5575|  ASSERT( pPrim != NULL );
5576|
5577|  delete  (CadPrim*)pPrim->p;
5578|  ListX_removeDelete( &file->m_prims, pPrim, NULL );
5579|}
5580|
5581|
5582| 
5583|/***********************************************************************
5584|  52. <<< [CSVGCatApp::RemovePrimI] 図形を削除する(アンドゥ非対応) >>> 
5585|【引数】
5586|  ・CadPrim*  prim;  削除する図形
5587|************************************************************************/
5588|void  CSVGCatApp::RemovePrimI( SVGCat_File* file, CadPrim* prim )
5589|{
5590|  ListX_ElemX*  pPrim;
5591|
5592|  for ( ListX_forEach( &file->m_prims, &pPrim, ListX_ElemX ) ) {
5593|    if ( pPrim->p == prim )  break;
5594|  }
5595|  ASSERT( pPrim != NULL );
5596|  delete  prim;
5597|
5598|  ListX_removeDelete( &file->m_prims, pPrim, NULL );
5599|}
5600|
5601|
5602| 
5603|/***********************************************************************
5604|  53. <<< [CSVGCatApp::RemovePrims] 図形を複数削除する(アンドゥ未対応) >>> 
5605|【引数】
5606|  ・ListX*  prims;   ListX_ElemX::CadPrim* リスト、削除する図形
5607|************************************************************************/
5608|void  CSVGCatApp::RemovePrims( SVGCat_File* file, ListX* prims )
5609|{
5610|  ListX_ElemX*  pPrim;
5611|
5612|  for ( ListX_forEach( prims, &pPrim, ListX_ElemX ) ) {
5613|    RemovePrim( file, (CadPrim*)pPrim->p );
5614|  }
5615|}
5616|
5617|
5618| 
5619|/***********************************************************************
5620|  54. <<< [CSVGCatApp::GetBorromLine] 最も下のラインか文字を得る >>> 
5621|【補足】
5622|・図形とライン・文字の境界を取得します。
5623|・NULL を返すときは、ラインか文字が全く無いときです。
5624|************************************************************************/
5625|ListX_ElemX*  CSVGCatApp::GetBottomLine( SVGCat_File* file )
5626|{
5627|  ListX_ElemX*  pPrim;
5628|
5629|  for ( ListX_forEach( &file->m_prims, &pPrim, ListX_ElemX ) ) {
5630|    if ( ((CadPrim*)pPrim->p)->GetTypeID() != Rect_Ex_TypeID )
5631|      break;
5632|  }
5633|  return  pPrim;
5634|}
5635|
5636|
5637| 
5638|/***********************************************************************
5639|  55. <<< [CSVGCatApp::GetNextForUndoBuf] 1つ手前の図形を返す(アンドゥバッファ用) >>> 
5640|【引数】
5641|  ・CadPrim*  prim;    基準となる図形
5642|  ・ListX*  selPrims;  返り値としては除外する図形の集合、ListX_ElemX::CadPrim* 型リスト
5643|  ・CadPrim*  返り値;  1つ手前の図形、NULL を返すときは最も手前
5644|************************************************************************/
5645|CadPrim*  CSVGCatApp::GetNextForUndoBuf( CadPrim* prim, ListX* selPrims )
5646|{
5647|  ListX_ElemX*  p;
5648|  ListX_ElemX*  p2;
5649|
5650|  for ( ListX_forEach( &m_file.m_prims, &p, ListX_ElemX ) ) {
5651|    if ( (CadPrim*)p->p == prim )
5652|      break;
5653|  }
5654|  ASSERT( p != NULL );
5655|
5656|  for (;;) {
5657|    p = ListX_Elem_getNextT( p, ListX_ElemX );
5658|    if ( p == NULL )  return  NULL;
5659|
5660|    for ( ListX_forEach( selPrims, &p2, ListX_ElemX ) ) {
5661|      if ( p2->p == p->p )  break;
5662|    }
5663|    if ( p2 == NULL ) {
5664|      return  ((CadPrim*)p->p)->GetNewCopy( &m_file.m_prims );
5665|    }
5666|  }
5667|}
5668|
5669|
5670| 
5671|/***********************************************************************
5672|  56. <<< [CSVGCatApp::GetNearestHandle] 指定の位置に最も近いハンドルを取得する >>> 
5673|【引数】
5674|  ・int  x, y;         指定する位置
5675|  ・int  zoom;         拡大率(%)
5676|  ・int  mode;         編集モード(CadPrim_ResizeMode or CadPrim_RotateMode)
5677|  ・int  *iHandle;     (出力)返り値の図形のハンドル番号
5678|  ・int*  dx, dy;      (出力)マウスの位置を原点とした移動用ハンドルの位置
5679|  ・CadPrim* priorityPrim;  優先する図形(NULL=優先する図形はない)
5680|  ・CadPrim*  返り値;  指定の位置に最も近いハンドルを持つ図形(NULL=はずれ)
5681|【補足】
5682|・選択する図形を決定するパラメータ(diff)は、以下のようになります。
5683|  <A href="HandleDiff.svg">HandleDiffの図</A>
5684|************************************************************************/
5685|CadPrim*  CSVGCatApp::GetNearestHandle( int x, int y, int zoom, int mode, int* iHandle,
5686|  int* dx, int* dy, int* arrow, CadPrim* priorityPrim )
5687|{
5688|  ListX_ElemX*  pPrim;
5689|  CadPrim*  prim = NULL;
5690|  int  i, dx2, dy2, diff, arrow2;
5691|
5692|  *dx = 9999;  *dy = 9999;
5693|  *arrow = CadPrim_NormalArrow;
5694|  for ( ListX_forEach( &m_file.m_prims, &pPrim, ListX_ElemX ) ) {
5695|    i = ((CadPrim*)pPrim->p)->GetHitHandleNum( x, y, zoom, mode, &dx2, &dy2, &diff, &arrow2 );
5696|    if ( i < 0 || ( i > 0 && abs(dx2)+abs(dy2) <= abs(*dx)+abs(*dy) ) ) {
5697|      *iHandle = i;
5698|      *dx = dx2;  *dy = dy2;  *arrow = arrow2;
5699|      prim = (CadPrim*)pPrim->p;
5700|    }
5701|  }
5702|
5703|  if ( priorityPrim != NULL ) {
5704|    i = priorityPrim->GetHitHandleNum( x, y, zoom, mode, &dx2, &dy2, &diff, &arrow2 );
5705|    if ( i != 0 /*i < 0 || ( i > 0 && abs(dx2)+abs(dy2) <= abs(*dx)+abs(*dy) )*/ ) {
5706|      Rect  ra, rb, rc;
5707|
5708|      Rect_init_by2XY( &ra,
5709|        priorityPrim->GetForAlign( CadPrim_AlignLeft ),
5710|        priorityPrim->GetForAlign( CadPrim_AlignTop ),
5711|        priorityPrim->GetForAlign( CadPrim_AlignRight ),
5712|        priorityPrim->GetForAlign( CadPrim_AlignBottom ) );
5713|      Rect_init_by2XY( &rb,
5714|        prim->GetForAlign( CadPrim_AlignLeft ),
5715|        prim->GetForAlign( CadPrim_AlignTop ),
5716|        prim->GetForAlign( CadPrim_AlignRight ),
5717|        prim->GetForAlign( CadPrim_AlignBottom ) );
5718|      Rect_toAnd( &rc, &ra, &rb );
5719|      if ( ! Rect_isEqual( &rc, &rb ) ) {
5720|        *iHandle = i;
5721|        *dx = dx2;  *dy = dy2;  *arrow = arrow2;
5722|        prim = priorityPrim;
5723|      }
5724|    }
5725|  }
5726|
5727|  return  prim;
5728|}
5729|
5730|
5731| 
5732|/***********************************************************************
5733|  57. <<< [CSVGCatApp::Align] 整列する >>> 
5734|【引数】
5735|  ・int  iType;        整列位置、CadPrim_AlignLeft など
5736|  ・ListX*  prims;     ListX_ElemX::CadPrim* リスト、整列対象
5737|  ・CadPrim*  target;  水平、垂直時の基準(prims に含むものと同じもの)
5738|************************************************************************/
5739|void  CSVGCatApp::Align( int iType, ListX* prims, CadPrim* target )
5740|{
5741|  ListX_ElemX*  p;
5742|  int  target_value;
5743|
5744|  /* 基準となる図形を target に代入する */
5745|  if ( iType == CadPrim_AlignLeft || iType == CadPrim_AlignTop ) {
5746|    int  value;
5747|    CadPrim*  prim;
5748|
5749|    target = ((CadPrim*)ListX_getFirst( prims, ListX_ElemX )->p);
5750|    target_value = target->GetForAlign( iType );
5751|    for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
5752|      prim = (CadPrim*)p->p;
5753|      value = prim->GetForAlign( iType );
5754|      if ( value < target_value )
5755|        { target = prim;  target_value = value; }
5756|    }
5757|  }
5758|  else if ( iType == CadPrim_AlignRight || iType == CadPrim_AlignBottom ) {
5759|    int  value;
5760|    CadPrim*  prim;
5761|
5762|    target = ((CadPrim*)ListX_getFirst( prims, ListX_ElemX )->p);
5763|    target_value = target->GetForAlign( iType );
5764|    for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
5765|      prim = (CadPrim*)p->p;
5766|      value = prim->GetForAlign( iType );
5767|      if ( value > target_value )
5768|        { target = prim;  target_value = value; }
5769|    }
5770|  }
5771|  else {
5772|    target_value = target->GetForAlign( iType );
5773|  }
5774|
5775|  /* 整列する */
5776|  m_UndoBuf->StartMulti();
5777|  for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
5778|    CadPrim*  before = ((CadPrim*)p->p)->GetNewCopy( &m_file.m_prims );
5779|
5780|    ((CadPrim*)p->p)->SetForAlign( iType, target_value );
5781|    ((CadPrim*)p->p)->Move( 0, 0 );  /* ラインリンクの調整 */
5782|
5783|    m_UndoBuf->AllocNewStep( before, ((CadPrim*)p->p)->GetNewCopy( &m_file.m_prims ),
5784|      NULL, NULL, m_file.m_CurrentPageNum - m_file.m_StartPageNum );
5785|  }
5786|  m_UndoBuf->EndMulti();
5787|}
5788|
5789|
5790| 
5791|/***********************************************************************
5792|  58. <<< [CSVGCatApp::FitSize] サイズを同じくする >>> 
5793|【引数】
5794|  ・int  iType;        調整する属性、CadPrim_Horizontal など
5795|  ・ListX*  prims;     ListX_ElemX::CadPrim* リスト、整列対象
5796|  ・CadPrim*  target;  水平、垂直時の基準(prims に含むものと同じもの)
5797|************************************************************************/
5798|void  CSVGCatApp::FitSize( int iType, ListX* prims, CadPrim* target )
5799|{
5800|  ListX_ElemX*  p;
5801|  int  target_value = target->GetForFitSize( iType );
5802|
5803|  m_UndoBuf->StartMulti();
5804|  for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
5805|    CadPrim*  before = ((CadPrim*)p->p)->GetNewCopy( &m_file.m_prims );
5806|
5807|    ((CadPrim*)p->p)->SetForFitSize( iType, target_value );
5808|    ((CadPrim*)p->p)->Move( 0, 0 );  /* ラインリンクの調整 */
5809|
5810|    m_UndoBuf->AllocNewStep( before, ((CadPrim*)p->p)->GetNewCopy( &m_file.m_prims ),
5811|      NULL, NULL, m_file.m_CurrentPageNum - m_file.m_StartPageNum );
5812|  }
5813|  m_UndoBuf->EndMulti();
5814|}
5815|
5816|
5817| 
5818|/***********************************************************************
5819|  59. <<< [CSVGCatApp::AlignInterval] 等間隔にする >>> 
5820|【引数】
5821|  ・int  iType;        等間隔にする方向、CadPrim_Horizontal など
5822|  ・ListX*  prims;     ListX_ElemX::CadPrim* リスト、整列対象
5823|************************************************************************/
5824|void  CSVGCatApp::AlignInterval( int iType, ListX* prims )
5825|{
5826|  ListX_ElemX*  p;
5827|  ListX_ElemX*  p2;
5828|  ListX  sorted;
5829|  const int  lefts[] = { CadPrim_AlignLeft, CadPrim_AlignTop };
5830|  const int  rights[] = { CadPrim_AlignRight, CadPrim_AlignBottom };
5831|  const int  horizons[] = { CadPrim_Horizontal, CadPrim_Vertical };
5832|  int  iLeft, iRight, iHorizon;
5833|  CadPrim*  prim;
5834|  CadPrim*  first;
5835|  int  left, right, total_len;
5836|  int  nPrim;
5837|  int  interval;
5838|
5839|  iLeft = lefts[iType];
5840|  iRight = rights[iType];
5841|  iHorizon = horizons[iType];
5842|  first = (CadPrim*)ListX_getFirst( prims, ListX_ElemX )->p;
5843|
5844|  /* 図形の左または上の位置でソートする。sorted に */
5845|  ListX_init( &sorted );
5846|  for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
5847|    prim = (CadPrim*)p->p;
5848|    for ( ListX_forEach( &sorted, &p2, ListX_ElemX ) ) {
5849|      if ( prim->GetForAlign( iLeft ) <= ((CadPrim*)p2->p)->GetForAlign( iLeft ) ) {
5850|        p2 = ListX_insertMalloc( &sorted, p2, ListX_ElemX );
5851|        p2->p = p->p;
5852|        break;
5853|      }
5854|    }
5855|    if ( p2 == NULL ) {
5856|      p2 = ListX_addLastMalloc( &sorted, ListX_ElemX );
5857|      p2->p = p->p;
5858|    }
5859|  }
5860|
5861|  /* 最も端の位置 left, right と 図形部分の合計サイズ total_len を得る */
5862|  left = ( (CadPrim*)ListX_getFirst( &sorted, ListX_ElemX )->p )->GetForAlign( iLeft );
5863|  right = ( (CadPrim*)ListX_getLast( &sorted, ListX_ElemX )->p )->GetForAlign( iRight );
5864|  total_len = 0;
5865|  nPrim = 0;
5866|  for ( ListX_forEach( prims, &p, ListX_ElemX ) ) {
5867|    total_len += ((CadPrim*)p->p)->GetForFitSize( iHorizon ) - 1;
5868|    nPrim++;
5869|  }
5870|  p2 = ListX_getLast( &sorted, ListX_ElemX );
5871|  total_len = total_len - ((CadPrim*)p2->p)->GetForFitSize( iHorizon ) +
5872|    ((CadPrim*)p2->p)->GetForAlign( iRight ) - ((CadPrim*)p2->p)->GetForAlign( iLeft ) + 1;
5873|
5874|  /* 等間隔にそろえる */
5875|  interval = ( ( ( right - left ) - total_len ) << 8 ) / (nPrim-1);
5876|  left <<= 8;
5877|  m_UndoBuf->StartMulti();
5878|  for ( ListX_forEach( &sorted, &p, ListX_ElemX ) ) {
5879|    if ( p ==p2 )  continue;
5880|    CadPrim*  before = ((CadPrim*)p->p)->GetNewCopy( &m_file.m_prims );
5881|
5882|    ((CadPrim*)p->p)->SetForAlign( iLeft, left >> 8 );
5883|    ((CadPrim*)p->p)->Move( 0, 0 );  /* ラインリンクの調整 */
5884|
5885|    m_UndoBuf->AllocNewStep( before, ((CadPrim*)p->p)->GetNewCopy( &m_file.m_prims ),
5886|      NULL, NULL, m_file.m_CurrentPageNum - m_file.m_StartPageNum );
5887|
5888|    left += ( (((CadPrim*)p->p)->GetForFitSize( iHorizon ) - 1) << 8 )+ interval;
5889|  }
5890|
5891|  m_UndoBuf->AllocNewStep( ((CadPrim*)p2->p)->GetNewCopy( &m_file.m_prims ),
5892|    ((CadPrim*)p2->p)->GetNewCopy( &m_file.m_prims ), NULL, NULL, m_file.m_CurrentPageNum - m_file.m_StartPageNum );
5893|
5894|  m_UndoBuf->EndMulti();
5895|
5896|  ListX_finish2( &sorted, ListX_ElemX, NULL );
5897|}
5898|
5899|
5900| 
5901|/***********************************************************************
5902|  60. <<< [CSVGCatApp_meltSvgz] SVGZファイルを解凍する >>> 
5903|【引数】
5904|  ・char*  svgz_path;   SVGZファイルのパス
5905|  ・char*  返り値;      解凍してできたファイルのパス
5906|【補足】
5907|・解凍したファイルが不要になったら削除してください。
5908|************************************************************************/
5909|char*  CSVGCatApp_meltSvgz( const char* svgz_path )
5910|{
5911|  HINSTANCE  DLL;
5912|  typedef  int  (WINAPI *Tar_F)( HWND, char*, char*, int );
5913|  Tar_F  pTar;
5914|  static  char  path[_MAX_PATH];
5915|  char  path2[_MAX_PATH];
5916|  int  ret;
5917|  char  out[2048];
5918|
5919|
5920|  /* 実行ファイルのサブフォルダにある DLL をロードする */
5921|  _getcwd( out, sizeof(out) );
5922|
5923|  strcpy( path2, "system\\plugin" );
5924|  StrX_getExeFullPath( path2, path2, sizeof(path2) );
5925|
5926|  _chdir( path2 );  /* 拡張子が DLLのときに必要 */
5927|  DLL = LoadLibrary( "TAR32.dll" );
5928|  //_chdir( out );  // この関数の最後で戻すためコメントアウト
5929|
5930|  if ( DLL == NULL ) {
5931|    MessageBox( NULL, "TAR32.DLL が見つかりません。\n"
5932|      "Windows98/Me では、svgcats.exe と同じフォルダに TAR32.DLL を"
5933|      "入れておく必要があります。 system\\plugin フォルダからコピーしてください。",
5934|      "", MB_OK );
5935|    error2_0( Errors_Unofficial,
5936|       "svgz 形式の解凍には TAR32.DLL が必要です。" );
5937|  }
5938|
5939|
5940|  /* コマンドラインを作る */
5941|  StrX_cpyFolder( path2, svgz_path );
5942|  _chdir( path2 );
5943|  strcpy( path, "--display-dialog=0 -zxvf \"" );
5944|  strcat( path, StrX_refFName( svgz_path ) );
5945|  strcat( path, "\"" );
5946|
5947|  /* 解凍する */
5948|  pTar = (Tar_F)GetProcAddress( DLL, "Tar" );
5949|  ret = pTar( NULL, path, path2, sizeof(path2) );
5950|  // Errors_printf( "%s", path2 );
5951|  if ( ret != 0 ) {
5952|    error2_1( Errors_Unofficial, "Tar32.DLL エラーコード=%d", ret );
5953|  }
5954|  FreeLibrary( DLL );
5955|
5956|  strcpy( path, svgz_path );
5957|  strcat( path, "_extracted" );
5958|
5959|  _chdir( out );
5960|
5961|  return  path;
5962|}
5963|
5964|
5965| 
5966|/***********************************************************************
5967|  61. <<< [CSVGCatApp_compressSvgz] SVGZファイルに圧縮する >>> 
5968|【引数】
5969|  ・char*  svgz_path;   SVGZファイルのパス
5970|  ・char*  返り値;      圧縮してできたファイルのパス
5971|【補足】
5972|・解凍したファイルが不要になったら削除してください。
5973|************************************************************************/
5974|char*  CSVGCatApp_compressSvgz( const char* svgz_path )
5975|{
5976|  HINSTANCE  DLL;
5977|  typedef  int  (WINAPI *Tar_F)( HWND, char*, char*, int );
5978|  Tar_F  pTar;
5979|  static  char  path[_MAX_PATH*2];
5980|  int  ret;
5981|  char  out[256];
5982|
5983|
5984|  /* 実行ファイルのサブフォルダにある DLL をロードする */
5985|  _getcwd( out, sizeof(out) );
5986|
5987|  strcpy( path, "system\\plugin" );
5988|  StrX_getExeFullPath( path, path, sizeof(path) );
5989|
5990|  _chdir( path );  /* 拡張子が DLLのときに必要 */
5991|  DLL = LoadLibrary( "TAR32.dll" );
5992|  _chdir( out );
5993|
5994|  if ( DLL == NULL ) {
5995|    error2_0( Errors_Unofficial,
5996|       "svgz 形式の解凍には TAR32.DLL が必要です。" );
5997|  }
5998|
5999|
6000|  /* コマンドラインを作る */
6001|  StrX_cpyFolder( out, svgz_path );
6002|  _chdir( out );
6003|  strcpy( path, "--display-dialog=0 -Gcvf \"" );
6004|  strcat( path, StrX_refFName(svgz_path) );  strcat( path, ".gz\" \"" );
6005|  strcat( path, StrX_refFName(svgz_path) );
6006|  strcat( path, "\"" );
6007|
6008|  /* 解凍する */
6009|  pTar = (Tar_F)GetProcAddress( DLL, "Tar" );
6010|  ret = pTar( NULL, path, out, sizeof(out) );
6011|  // Errors_printf( "%s", out );
6012|  if ( ret != 0 ) {
6013|    error2_1( Errors_Unofficial, "Tar32.DLL エラーコード=%d", ret );
6014|  }
6015|  FreeLibrary( DLL );
6016|
6017|  strcpy( path, svgz_path );
6018|  strcat( path, ".gz" );
6019|
6020|  return  path;
6021|}
6022|
6023|
6024| 
6025|/////////////////////////////////////////////////////////////////////////////
6026|// アプリケーションのバージョン情報で使われる CAboutDlg ダイアログ 
6027|
6028|class CAboutDlg : public CDialog
6029|{
6030|public:
6031|  CAboutDlg( int id );
6032|
6033|// ダイアログ データ
6034|  //{{AFX_DATA(CAboutDlg)
6035|	enum { IDD = IDD_ABOUTBOX };
6036|	CEdit	m_Mail;
6037|	//}}AFX_DATA
6038|
6039|  // ClassWizard 仮想関数のオーバーライドを生成します。
6040|  //{{AFX_VIRTUAL(CAboutDlg)
6041|  protected:
6042|  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV のサポート
6043|  //}}AFX_VIRTUAL
6044|
6045|// インプリメンテーション
6046|protected:
6047|  //{{AFX_MSG(CAboutDlg)
6048|	afx_msg void OnUrl();
6049|	afx_msg void OnWatanabe();
6050|	afx_msg void OnProjTowns();
6051|	afx_msg void OnSusie();
6052|	virtual BOOL OnInitDialog();
6053|	afx_msg void OnIjg();
6054|	afx_msg void OnTar32();
6055|	afx_msg void OnEmil();
6056|	//}}AFX_MSG
6057|  DECLARE_MESSAGE_MAP()
6058|};
6059|
6060|CAboutDlg::CAboutDlg( int id ) : CDialog( id )
6061|{
6062|  //{{AFX_DATA_INIT(CAboutDlg)
6063|  //}}AFX_DATA_INIT
6064|}
6065|
6066|void CAboutDlg::DoDataExchange(CDataExchange* pDX)
6067|{
6068|  CDialog::DoDataExchange(pDX);
6069|  //{{AFX_DATA_MAP(CAboutDlg)
6070|	DDX_Control(pDX, IDC_Mail, m_Mail);
6071|	//}}AFX_DATA_MAP
6072|}
6073|
6074|BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
6075|  //{{AFX_MSG_MAP(CAboutDlg)
6076|	ON_BN_CLICKED(IDC_URL, OnUrl)
6077|	ON_BN_CLICKED(IDC_Watanabe, OnWatanabe)
6078|	ON_BN_CLICKED(IDC_ProjTowns, OnProjTowns)
6079|	ON_BN_CLICKED(IDC_Susie, OnSusie)
6080|	ON_BN_CLICKED(IDC_IJG, OnIjg)
6081|	ON_BN_CLICKED(IDC_Tar32, OnTar32)
6082|	ON_BN_CLICKED(IDC_Emil, OnEmil)
6083|	//}}AFX_MSG_MAP
6084|END_MESSAGE_MAP()
6085|
6086|// ダイアログを実行するためのアプリケーション コマンド
6087|void CSVGCatApp::OnAppAbout()
6088|{
6089|  CSVGCatApp*  app = (CSVGCatApp*)AfxGetApp();
6090|  CAboutDlg aboutDlg( app->m_bJapanese ? IDD_ABOUTBOX : IDD_ABOUTBOX_E );
6091|  aboutDlg.DoModal();
6092|}
6093|
6094|/////////////////////////////////////////////////////////////////////////////
6095|// CSVGCatApp メッセージ ハンドラ
6096|
6097|
6098| 
6099|void CAboutDlg::OnUrl() 
6100|{
6101|  WinX_openHtml( "http://www.sage-p.com/", true );
6102|}
6103|
6104|
6105| 
6106|
6107|void CAboutDlg::OnSusie()
6108|{
6109|  WinX_openHtml( "http://www.digitalpad.co.jp/~takechin/", true );
6110|}
6111|
6112|void CAboutDlg::OnIjg() 
6113|{
6114|  WinX_openHtml( "http://www.ijg.org/", true );
6115|}
6116|
6117|void CAboutDlg::OnWatanabe()
6118|{
6119|  WinX_openHtml( "http://www.asahi-net.or.jp/~ds8h-wtnb/", true );
6120|}
6121|
6122|void CAboutDlg::OnEmil()
6123|{
6124|  WinX_openHtml( "http://homepage1.nifty.com/emil/", true );
6125|}
6126|
6127|void CAboutDlg::OnProjTowns()
6128|{
6129|  WinX_openHtml( "http://homepage1.nifty.com/uchi/", true );
6130|}
6131|
6132|void CAboutDlg::OnTar32()
6133|{
6134|  WinX_openHtml( "http://openlab.ring.gr.jp/tsuneo/tar32/", true );
6135|}
6136|
6137|BOOL CAboutDlg::OnInitDialog()
6138|{
6139|	CDialog::OnInitDialog();
6140|
6141|  m_Mail.SetWindowText( "neko@manbow.com" );
6142|
6143|	return TRUE;  // コントロールにフォーカスを設定しないとき、戻り値は TRUE となります
6144|	              // 例外: OCX プロパティ ページの戻り値は FALSE となります
6145|}
6146|
6147|
6148| 
6149|void  chkOLE();
6150|
6151|
6152|int CSVGCatApp::ExitInstance() 
6153|{
6154|  int  r;
6155|
6156|  CloseHandle( m_FileSema );
6157|
6158|  WinX_DdeServ_finish( &m_DdeServ );
6159|
6160|  if ( m_pMainWnd != NULL )
6161|    chkOLE();
6162|
6163|  OleUninitialize();
6164|
6165|  CoUninitialize();  /* COM インターフェイス全般の後始末 */
6166|
6167|  r = CWinApp::ExitInstance();
6168|  if ( r == 0 )  r = m_ErrorLevel;
6169|  return  r;
6170|}
6171|
6172|
6173|void  chkOLE()
6174|{
6175|#ifndef  ERRORS_CUT_DEBUG_TOOL
6176|  HRESULT  hr;
6177|  bool  bTabletPC = false;
6178|
6179|  {
6180|    IInkTablets*  t;
6181|    hr = CoCreateInstance( CLSID_InkTablets, NULL, CLSCTX_INPROC_SERVER,
6182|                         IID_IInkTablets, (void**)&t );
6183|    if ( hr != 0 )  {WD(hr);}
6184|    else if ( hr != 0 )  error();
6185|  }
6186|  if ( ! bTabletPC ) {
6187|    IInkDisp*  t;
6188|    hr = CoCreateInstance( CLSID_InkDisp, NULL, CLSCTX_INPROC_SERVER,
6189|                         IID_IInkDisp, (void**)&t );
6190|    if ( hr != 0 )  {WD(hr);}
6191|    if ( hr != 0 )  error();
6192|  }
6193|/*
6194|  {
6195|    IInkStrokeDisp*  t;
6196|    hr = CoCreateInstance( CLSID_IInkStrokeDisp, NULL, CLSCTX_INPROC_SERVER,
6197|                         IID_IInkStrokeDisp, (void**)&t );
6198|    if ( hr != 0 )  {WD(hr);}
6199|  }
6200|*/
6201|#endif
6202|}
6203| 
6204|/***********************************************************************
6205|  62. <<< [SVGCat_File_loadPage] ページを復帰する >>> 
6206|************************************************************************/
6207|void  SVGCat_File_loadPage( SVGCat_File* file, SVGCat_Page* page )
6208|{
6209|  int  nextPageInterval;
6210|
6211|  file->m_prims = page->prims;
6212|
6213|  nextPageInterval = file->m_Canvas.m_NextPageInterval;
6214|  //file->m_Canvas.copy( &page->canvas, NULL );  ListX で addNew に対応し全て置換すること
6215|  {
6216|  file->m_Canvas.m_Width = page->canvas.m_Width;
6217|  file->m_Canvas.m_Height = page->canvas.m_Height;
6218|  file->m_Canvas.m_NextPageInterval = page->canvas.m_NextPageInterval;
6219|  strcpy( file->m_Canvas.m_CorrImagePath, page->canvas.m_CorrImagePath );
6220|  }
6221|  file->m_Canvas.m_NextPageInterval = nextPageInterval;
6222|
6223|  file->m_bBeforeDraw = page->bBeforeDraw;
6224|}
6225|
6226| 
6227|/***********************************************************************
6228|  63. <<< [SVGCat_File_savePage] ページを退避する >>> 
6229|************************************************************************/
6230|void  SVGCat_File_savePage( SVGCat_File* file, SVGCat_Page* page )
6231|{
6232|  int  nextPageInterval;
6233|
6234|  page->prims = file->m_prims;
6235|
6236|  nextPageInterval = page->canvas.m_NextPageInterval;
6237|  //page->canvas.copy( &file->m_Canvas, NULL );  ListX で addNew に対応し全て置換すること
6238|  {
6239|  page->canvas.m_Width = file->m_Canvas.m_Width;
6240|  page->canvas.m_Height = file->m_Canvas.m_Height;
6241|  page->canvas.m_NextPageInterval = file->m_Canvas.m_NextPageInterval;
6242|  strcpy( page->canvas.m_CorrImagePath, file->m_Canvas.m_CorrImagePath );
6243|  }
6244|  page->canvas.m_NextPageInterval = nextPageInterval;
6245|
6246|  page->bBeforeDraw = file->m_bBeforeDraw;
6247|}
6248|
6249| 
6250|/***********************************************************************
6251|  64. <<< [SVGCat_Page_getChildOver] すべての子ノードの次のノードを返す >>> 
6252|【補足】
6253|・page->next == NULL でも、page->parent != NULL なら、返り値は NULL では
6254|  ないことがあります。
6255|************************************************************************/
6256|SVGCat_Page*  SVGCat_Page_getChildOver( SVGCat_Page* page )
6257|{
6258|  if ( page->firstChild != NULL ) {
6259|    page = page->firstChild;
6260|    for (;;) {
6261|      if ( page->next != NULL )  page = page->next;
6262|      else if ( page->firstChild != NULL )  page = page->firstChild;
6263|      else  break;
6264|    }
6265|  }
6266|  return  ListX_Elem_getNextT( page, SVGCat_Page );
6267|}
6268| 
6269|