C:\home\SVGCats_src\src\Text_cpp.cpp
1|/*********************************************************************** 2| 1. <<< 文字列(表示用) (Text) >>> 3|************************************************************************/ 4| 5|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */ 6|// #pragma hdrstop 7| 8|#if defined(USES_MXP_AUTOINC) 9| #include "text.ah" /* Auto include header, Look at mixer-... folder */ 10|#endif 11| 12|/*-------------------------------------------------------------------------*/ 13|/* 2. <<<< ◆ (Text_Box) 枠付き文字列(ディスプレイ表示用) >>>> */ 14|/*-------------------------------------------------------------------------*/ 15| 16|#ifdef TEXT_USES_WINDOWS_DC 17| 18| 19| 20|Text_Box::Text_Box() 21|{ 22| m_bInUndoBuf = false; 23| m_bHold = false; 24| m_bSelected = false; 25| 26| m_Text = "abc"; 27| m_CenterX = 0, m_Y = 0; m_DiffW = 0; 28| m_W = 32, m_10H = 320; 29| m_10H1 = -1; /* Draw 前を示す */ 30| m_10Descent = 0; 31| m_Top = 0; 32| m_BetweenOfLine = 14; 33| m_RotateDegree = 0; 34| m_Color = 0x000000; 35| m_Font = "MS Pゴシック"; 36| m_Size = 12; 37| m_bBold = false; 38| m_bItalic = false; 39| m_BasePos = Text_Box_LeftAlign; 40| m_bTategaki = false; 41| 42| m_CaretStart = 0; 43| m_CaretEnd = 0; 44| 45| m_BoxShape = Text_Box_RectShape; 46| m_BoxMarginX = 2, m_BoxMarginY = 2; 47| m_BorderWidth = 1; 48| m_BorderColor = 0x000000; 49| m_FillColor = 0xFFFFFF; 50| m_FillNTrans = 100; 51| 52| m_URL = ""; 53| m_Target = "_blank"; 54| m_IdLabel = ""; 55| ListX_init( &m_Links ); 56| m_Controler = NULL; 57| m_Controler_id = 0; 58| StdPlus_onMalloc( this ); 59|} 60| 61| 62|Text_Box::~Text_Box() 63|{ 64| StdPlus_onFree( this ); 65| if ( ! m_bInUndoBuf ) UnlinkAll(); 66| ListX_finish2( &m_Links, CadPrim_Link, NULL ); 67|} 68| 69|/*********************************************************************** 70| 2-1. <<< [Text_Box::print] CadPrim::print の実装部 >>> 71|************************************************************************/ 72|void Text_Box::print( const char* title ) 73|{ 74| #ifndef NDEBUG 75| CadPrim_Link* link; 76| RECT rc; 77| int x, y; 78| 79| c_try { 80| GetBox( &rc ); 81| x = (rc.left + rc.right) / 2; 82| y = (rc.top + rc.bottom) / 2; 83| } 84| c_catch ( Errors_Msg*, msg ) { 85| if ( msg->code == SVGCat_Err_NotSetDrawParam ) { 86| x = -1; y = -1; 87| } 88| else c_throw_again(); 89| } c_end_catch; 90| 91| Errors_printf( "%sText_Box[%d:%p]: (%d,%d) %s, hold=%d, sel=%d, undo=%d center=(%d,%d)", 92| title, m_id, this, m_CenterX, m_Y, m_Text, m_bHold, m_bSelected, 93| m_bInUndoBuf, x,y ); 94| Errors_printf( "%s m_Controler = %p, id=%d", title, 95| m_Controler, m_Controler_id ); 96| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 97| link->print( title ); 98| } 99| #endif 100|} 101| 102| 103|/*********************************************************************** 104| 2-2. <<< [Text_Box::GetID] CadPrim::GetID の実装部 >>> 105|************************************************************************/ 106|int Text_Box::GetID() 107|{ 108| return m_id; 109|} 110| 111| 112|/*********************************************************************** 113| 2-3. <<< [Text_Box::SetID] CadPrim::SetID の実装部 >>> 114|************************************************************************/ 115|void Text_Box::SetID( int id ) 116|{ 117| m_id = id; 118|} 119| 120| 121|/*********************************************************************** 122| 2-4. <<< [Text_Box::OnChgedLinkID] CadPrim::OnChgedLinkID の実装部 >>> 123|************************************************************************/ 124|void Text_Box::OnChgedLinkID( int oldID, int newID ) 125|{ 126| CadPrim_Link* link; 127| 128| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 129| if ( link->prim_id == oldID ) link->prim_id = newID; 130| } 131| if ( m_Controler_id == oldID ) m_Controler_id = newID; 132|} 133| 134| 135|/*********************************************************************** 136| 2-5. <<< [Text_Box::GetTypeID] CadPrim::GetTypeID の実装部 >>> 137|************************************************************************/ 138|int Text_Box::GetTypeID() 139|{ 140| return Text_Box_TypeID; 141|} 142| 143| 144|/*********************************************************************** 145| 2-6. <<< [Text_Box::GetTypeNameJp] CadPrim::GetTypeNameJp の実装部 >>> 146|************************************************************************/ 147|char* Text_Box::GetTypeNameJp() 148|{ 149| return "テキスト"; 150|} 151| 152| 153|/*********************************************************************** 154| 2-7. <<< [Text_Box::GetTypeNameEn] CadPrim::GetTypeNameEn の実装部 >>> 155|************************************************************************/ 156|char* Text_Box::GetTypeNameEn() 157|{ 158| return "Text"; 159|} 160| 161| 162|/*********************************************************************** 163| 2-8. <<< [Text_Box::SetBInUndoBuf] CadPrim::SetBInUndoBuf の実装部 >>> 164|************************************************************************/ 165|void Text_Box::SetBInUndoBuf( bool b ) 166|{ 167| m_bInUndoBuf = b; 168|} 169| 170| 171|/*********************************************************************** 172| 2-9. <<< [Text_Box::GetLinkURL] CadPrim::GetLinkURL の実装部 >>> 173|************************************************************************/ 174|char* Text_Box::GetLinkURL() 175|{ 176| return (char*)(const char*)m_URL; 177|} 178| 179| 180|/*********************************************************************** 181| 2-10. <<< [Text_Box::GetIdLabel] CadPrim::GetIdLabel の実装部 >>> 182|************************************************************************/ 183|char* Text_Box::GetIdLabel() 184|{ 185| return (char*)(const char*)m_IdLabel; 186|} 187| 188| 189| 190|/*********************************************************************** 191| 2-11. <<< [Text_Box::OutSVG] SVGファイルに属性値を出力する >>> 192|【引数】 193| ・FILE* f; 出力先のテキスト・ファイル 194|************************************************************************/ 195|void Text_Box::OutSVG( CadPrim_SaveParam* p ) 196|{ 197| RECT rc; 198| char* urlFName = ( m_URL == "" ? strchr( m_URL, '\0' ) : StrX_refFName(m_URL) ); 199| bool bScript = ( strnicmp( urlFName, "script:", 7 ) == 0 ); 200| char* script = urlFName + 7; 201| char eng_name[256]; 202| char trans[20]; 203| 204| 205| /* フォントの英語名を取得する */ 206| if ( m_Font == "MS ゴシック" ) strcpy( eng_name, "MS-Gothic" ); 207| else if ( m_Font == "MS Pゴシック" ) strcpy( eng_name, "MS-PGothic" ); 208| else if ( m_Font == "MS 明朝" ) strcpy( eng_name, "MS-Mincho" ); 209| else if ( m_Font == "MS P明朝" ) strcpy( eng_name, "MS-PMincho" ); 210| else strcpy( eng_name, m_Font ); 211| 212| 213| /* <g> タグをファイルに出力する */ 214| if ( m_BoxShape != Text_Box_NoFrame || bScript || urlFName[0] == '#' ) { 215| fputs( "\t<g", p->f ); 216| if ( m_IdLabel != "" ) fprintf( p->f, " id=\"%s\"", m_IdLabel ); 217| if ( urlFName[0] == '#' ) fprintf( p->f, " href=\"%s\"", urlFName ); 218| if ( p->iTargetPage >= 1 ) fprintf( p->f, " onclick=\"chgPage( evt, %d )\"", p->iTargetPage ); 219| if ( bScript ) fprintf( p->f, " onclick=\"%s\"", script ); 220| fputs( ">\n", p->f ); 221| } 222| 223| /* <a> タグをファイルに出力する */ 224| if ( m_URL != "" ) { 225| if ( ! bScript && urlFName[0] != '#' ) { 226| char stepPath[_MAX_PATH]; 227| char stepPath2[_MAX_PATH*2]; 228| 229| StrX_cpyStepPath2( stepPath, m_URL, sizeof(stepPath), p->path ); 230| if ( p->bLower ) StrX_cpyLower( stepPath, stepPath ); 231| StrX_toHtmlTxt( stepPath, stepPath2, sizeof(stepPath2) ); 232| fprintf( p->f, "\t<a xlink:href=\"%s\"", stepPath2 ); 233| if ( m_Target != "" ) 234| fprintf( p->f, " target=\"%s\"", m_Target ); 235| fputs( ">\n", p->f ); 236| } 237| else { 238| fputs( "<a>\n", p->f ); 239| } 240| } 241| 242| /* 枠を出力する */ 243| if ( m_BoxShape != Text_Box_NoFrame ) { 244| GetBox( &rc ); 245| 246| switch ( m_BoxShape ) { 247| case Text_Box_RectShape: 248| fprintf( p->f, "\t<rect x=\"%d.5\" y=\"%d.5\" width=\"%d\" height=\"%d\"\n", 249| rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top ); 250| break; 251| 252| case Text_Box_RoundRectShape: 253| fprintf( p->f, "\t<rect x=\"%d.5\" y=\"%d.5\" width=\"%d\" height=\"%d\"" 254| " rx=\"10\" ry=\"10\"\n", 255| rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top ); 256| break; 257| 258| case Text_Box_CircleShape: 259| if ( rc.right - rc.left == rc.bottom - rc.top ) { 260| fprintf( p->f, "\t<circle cx=\"%d.5\" cy=\"%d.5\" r=\"%d\"\n", 261| (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2, 262| (rc.right - rc.left) / 2 ); 263| } 264| else { 265| fprintf( p->f, "\t<ellipse cx=\"%d.5\" cy=\"%d.5\" rx=\"%d\" ry=\"%d\"\n", 266| (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2, 267| (rc.right - rc.left) / 2, (rc.bottom - rc.top) / 2 ); 268| } 269| break; 270| 271| case Text_Box_DiamondShape: { 272| int hasuuX = ( rc.left + rc.right ) % 2; 273| int hasuuY = ( rc.top + rc.bottom ) % 2; 274| 275| fprintf( p->f, "\t<polygon points=\"%d.5,%d.5 %d.5,%d.5 %d.5,%d.5 %d.5,%d.5\"\n", 276| (rc.left + rc.right) / 2, rc.top, 277| rc.right + hasuuX, (rc.top + rc.bottom) / 2, 278| (rc.left + rc.right) / 2, rc.bottom + hasuuY, 279| rc.left, (rc.top + rc.bottom) / 2 ); 280| break; 281| } 282| 283| case Text_Box_Parallelogram: { 284| int slide = ( rc.bottom - rc.top ) / 4; 285| 286| fprintf( p->f, "\t<polygon points=\"%d.5,%d.5 %d.5,%d.5 %d.5,%d.5 %d.5,%d.5\"\n", 287| rc.left + slide, rc.top, rc.right + slide, rc.top, 288| rc.right - slide, rc.bottom, rc.left - slide, rc.bottom ); 289| break; 290| } 291| } 292| 293| sprintf( trans, ";fill-opacity:0.%02d", m_FillNTrans ); 294| 295| fprintf( p->f, "\t\tstyle=\"fill:rgb(%d,%d,%d);stroke:rgb(%d,%d,%d);" 296| "stroke-width:%d%s\"", 297| Color_WinRGB_getR( m_FillColor ), Color_WinRGB_getG( m_FillColor ), 298| Color_WinRGB_getB( m_FillColor ), 299| Color_WinRGB_getR( m_BorderColor ), Color_WinRGB_getG( m_BorderColor ), 300| Color_WinRGB_getB( m_BorderColor ), 301| m_BorderWidth, 302| m_FillNTrans == 100 ? "" : trans ); 303| 304| if ( m_RotateDegree != 0 ) { 305| fprintf( p->f, " transform=\"rotate(%d,%d,%d)\"", 306| m_RotateDegree, m_CenterX, m_Y ); 307| } 308| fputs( "/>\n", p->f ); 309| } 310| 311| 312| /* テキストを出力する */ 313| { 314| char* align; 315| 316| fputs( "\t<text", p->f ); 317| 318| if ( !( m_BoxShape != Text_Box_NoFrame || bScript || urlFName[0] == '#' ) ) 319| if ( m_IdLabel != "" ) fprintf( p->f, " id=\"%s\"", (const char*)m_IdLabel ); 320| 321| fprintf( p->f, " x=\"%d.5px\" y=\"%d.5px\"", m_CenterX, m_Y ); 322| 323| switch ( m_BasePos ) { 324| case Text_Box_LeftAlign: align = "start"; break; 325| case Text_Box_CenterAlign: align = "middle"; break; 326| case Text_Box_RightAlign: align = "end"; break; 327| } 328| 329| fprintf( p->f, " style=\"fill:rgb(%d,%d,%d);font-family:%s;" 330| "font-size:%dpt;%s%stext-anchor:%s\"", 331| Color_WinRGB_getR( m_Color ), Color_WinRGB_getG( m_Color ), 332| Color_WinRGB_getB( m_Color ), 333| eng_name, m_Size, 334| m_bBold ? "font-weight:bold;" : "", 335| m_bItalic ? "font-style:italic;" : "", 336| align ); 337| 338| if ( m_RotateDegree != 0 ) { 339| GetBox( &rc ); 340| fprintf( p->f, " transform=\"rotate(%d,%d,%d)\"", 341| m_RotateDegree, m_CenterX, m_Y ); 342| } 343| if ( m_bTategaki ) { 344| fprintf( p->f, " writing-mode=\"tb\"" ); 345| } 346| fputs( " xml:space=\"preserve\">", p->f ); 347| 348| { 349| const int len = m_Text.GetLength(); 350| char* s1 = (char*)malloc( len + 11 + 1 ); /* +11はページ番号分 */ 351| char* s2 = (char*)malloc( len * 5 + 11 + 1 ); 352| int i; 353| 354| StrX_cpy1Line( s1, len + 1, m_Text, 1 ); 355| if ( m_IdLabel == "pagenum" ) { 356| sprintf( s1, "%d", p->iPage ); 357| } 358| fputs( StrX_toHtmlTxt( s1, s2, len * 5 + 1 ), p->f ); 359| if ( m_bTategaki ) { 360| for ( i = 2; ; i++ ) { 361| if ( StrX_cpy1Line( s1, len + 1, m_Text, i ) == NULL ) break; 362| fprintf( p->f, "%s<tspan x=\"%d.5px\" y=\"%d.5px\">%s</tspan>", 363| ( i==2 ? "" : "\n\t" ), 364| m_CenterX - m_BetweenOfLine * (i - 1), m_Y, 365| StrX_toHtmlTxt( s1, s2, len * 5 + 1 ) ); 366| } 367| } 368| else { 369| for ( i = 2; ; i++ ) { 370| if ( StrX_cpy1Line( s1, len + 1, m_Text, i ) == NULL ) break; 371| fprintf( p->f, "%s<tspan x=\"%d.5px\" y=\"%d.5px\">%s</tspan>", 372| ( i==2 ? "" : "\n\t" ), 373| m_CenterX, m_Y + m_BetweenOfLine * (i - 1), 374| StrX_toHtmlTxt( s1, s2, len * 5 + 1 ) ); 375| } 376| } 377| fputs( "</text>\n", p->f ); 378| free( s2 ); 379| free( s1 ); 380| } 381| } 382| 383| 384| /* </a> タグをファイルに出力する */ 385| if ( m_URL != "" ) 386| fputs( "\t</a>\n", p->f ); 387| 388| /* </g> タグをファイルに出力する */ 389| if ( m_BoxShape != Text_Box_NoFrame || bScript || urlFName[0] == '#' ) 390| fprintf( p->f, "\t</g>\n" ); 391|} 392| 393|/*********************************************************************** 394| 2-12. <<< [Text_Box::Draw] CadPrim::Draw の実装部 >>> 395|************************************************************************/ 396|void Text_Box::Draw( CDC* dc, CadPrim_DrawParam* p ) 397|{ 398| int zoom = p->zoom; 399| RECT textRect; 400| RECT box; 401| CSize size; 402| LOGFONT logFont; 403| int nTextLine; 404| TEXTMETRIC tx; 405| int i; 406| TwoD_XY xy; 407| TwoD_XY center; 408| TwoD_XY center0; 409| ERRORS_FUNC_CPP_VAR( Text_Box_Draw ); 410| ERRORS_FUNC_START_CPP( Text_Box_Draw ); 411| 412| TwoD_XY_init( ¢er, m_CenterX, m_Y ); 413| TwoD_XY_init( ¢er0, 0, 0 ); 414| 415| 416| /* フォントの属性を取得する(10倍の大きさのフォントで SVG Viewer や印刷との誤差を無くしている) */ 417| { 418| CFont font; 419| CFont font2; 420| CFont* oldFont; 421| 422| font.CreatePointFont( m_Size*100, (m_bTategaki ? CString('@')+m_Font : m_Font), dc ); 423| font.GetLogFont( &logFont ); 424| logFont.lfWidth = 0; 425| logFont.lfHeight = m_Size * 100; 426| logFont.lfWeight = m_bBold ? FW_BOLD : FW_NORMAL; 427| logFont.lfItalic = m_bItalic; 428| logFont.lfEscapement = - m_RotateDegree * 10 + (m_bTategaki ? 2700 :0); 429| font2.CreatePointFontIndirect( &logFont, dc ); 430| oldFont = dc->SelectObject( &font2 ); 431| 432| m_W = 0; m_10H = 0; 433| for ( i = 1; i < 100; i++ ) { /* 100行目以降の幅と高さは調査しない */ 434| char s[Text_Box_nByteInLine+4]; 435| int w,h; 436| 437| if ( StrX_cpy1Line( s, sizeof(s), m_Text, i ) == NULL ) break; 438| if ( i == 1 && s[0] == '\0' ) strcpy( s, "X" ); 439| size = dc->GetOutputTextExtent( s ); /* 現在選択しているフォントに影響する */ 440| w = size.cx / 10; if ( w > m_W ) m_W = w; 441| h = size.cy; // if ( p->bPrint ) h = h * 100 / p->zoom; 442| if ( h > m_10H ) m_10H = h; 443| if ( i == 1 ) { 444| dc->GetOutputTextMetrics( &tx ); 445| if ( p->bPrint ) { 446| m_Top = m_Y + (tx.tmDescent - h) * 10 / p->zoom; 447| m_10H1 = h * 100 / p->zoom; 448| } 449| else { 450| m_Top = m_Y + (tx.tmDescent - h ) / 10; 451| m_10H1 = h; 452| } 453| } 454| } 455| if ( i == 100 ) i = StrX_getNLine( m_Text ); 456| if ( p->bPrint ) m_10H = m_10H + ( (i - 2) * m_BetweenOfLine * 10 ) * p->zoom / 100; 457| else m_10H = m_10H + ( (i - 2) * m_BetweenOfLine * 10 ); 458| nTextLine = i - 1; 459| dc->GetOutputTextMetrics( &tx ); 460| m_10Descent = tx.tmDescent; 461| dc->SelectObject( oldFont ); 462| 463| if ( p->bPrint ) { 464| m_W = m_W * 100 / p->zoom; 465| m_10H = m_10H * 100 / p->zoom; 466| m_10Descent = m_10Descent * 100 / p->zoom; 467| } 468| } 469| 470| 471| /* フォントの属性に応じて Text_Box の属性の再設定を行う */ 472| /* m_BoxMarginX, m_BoxMarginY を、Rect_Ex の左上座標からマージンに変える */ 473| if ( m_BoxShape < 0 ) { 474| m_BoxShape = - m_BoxShape; 475| if ( m_bTategaki ) { 476| switch ( m_BasePos ) { 477| case Text_Box_LeftAlign: 478| m_BoxMarginY = m_Y - m_BoxMarginY; 479| m_DiffW = m_DiffW - 1 - m_W - 2 * m_BoxMarginY; 480| break; 481| case Text_Box_CenterAlign: 482| m_BoxMarginY = m_Y - (m_W + 1) / 2 - m_BoxMarginY; 483| m_DiffW = 0; 484| break; 485| case Text_Box_RightAlign: 486| m_BoxMarginY = m_Y - m_W - m_BoxMarginY; 487| m_DiffW = m_W + 1 + 2 * m_BoxMarginY - m_DiffW; 488| m_BoxMarginY -= m_DiffW; 489| break; 490| } 491| m_BoxMarginX = m_CenterX - (m_10H1 + m_10Descent+1)/20 - (nTextLine-1) * m_BetweenOfLine - m_BoxMarginX; 492| { int i = m_BoxMarginX; m_BoxMarginX = m_BoxMarginY; m_BoxMarginY = i; } 493| } 494| else { 495| switch ( m_BasePos ) { 496| case Text_Box_LeftAlign: 497| m_BoxMarginX = m_CenterX - m_BoxMarginX; 498| m_DiffW = m_DiffW - m_W - 2 * m_BoxMarginX; 499| break; 500| case Text_Box_CenterAlign: 501| m_BoxMarginX = m_CenterX - m_W / 2 - m_BoxMarginX; 502| m_DiffW = 0; 503| break; 504| case Text_Box_RightAlign: 505| m_BoxMarginX = m_CenterX - m_W - m_BoxMarginX; 506| m_DiffW = m_W + 2 * m_BoxMarginX - m_DiffW; 507| m_BoxMarginX -= m_DiffW; 508| break; 509| } 510| m_BoxMarginY = m_Y + (nTextLine - 1) * m_BetweenOfLine + 511| (m_10Descent - m_10H) / 10 - m_BoxMarginY; 512| } 513| } 514| 515| 516| /* 枠を表示する */ 517| { 518| CPen pen( PS_SOLID, m_BorderWidth * zoom / 100, 519| p->bWhiteToBGColor && m_BorderColor == 0x000000 ? 520| GetSysColor( COLOR_WINDOWTEXT ) : m_BorderColor ); 521| CPen nullPen( PS_NULL, (int)0, (int)0 ); 522| CBrush brush( p->bWhiteToBGColor && m_FillColor == 0xFFFFFF ? 523| GetSysColor( COLOR_WINDOW ) : m_FillColor ); 524| CBrush nullBrush; 525| CBrush transBrush( HS_VERTICAL, p->bWhiteToBGColor && m_FillColor == 0xFFFFFF ? 526| GetSysColor( COLOR_WINDOW ) : m_FillColor ); 527| CPen* oldPen; 528| CBrush* oldBrush; 529| 530| nullBrush.CreateStockObject( NULL_BRUSH ); 531| 532| oldPen = dc->SelectObject( m_BorderWidth == 0 ? &nullPen : &pen ); 533| if ( m_FillNTrans == 100 ) 534| oldBrush = dc->SelectObject( &brush ); 535| else if ( m_FillNTrans == 0 ) 536| oldBrush = dc->SelectObject( &nullBrush ); 537| else { 538| dc->SetBkMode( TRANSPARENT ); 539| oldBrush = dc->SelectObject( &transBrush ); 540| } 541| 542| GetBox( &box ); 543| 544| switch ( m_BoxShape ) { 545| case Text_Box_RectShape: 546| if ( m_RotateDegree == 0 ) { 547| dc->Rectangle( box.left * zoom / 100 - p->x0, box.top * zoom / 100 - p->y0, 548| box.right * zoom / 100 + 1 - p->x0, box.bottom * zoom / 100 + 1 - p->y0 ); 549| } 550| else { 551| POINT pts[4]; 552| int i; 553| 554| pts[0].x = box.left; pts[0].y = box.top; 555| pts[1].x = box.right; pts[1].y = box.top; 556| pts[2].x = box.right; pts[2].y = box.bottom; 557| pts[3].x = box.left; pts[3].y = box.bottom; 558| for ( i = 0; i < 4; i++ ) { 559| TwoD_XY_init( &xy, pts[i].x, pts[i].y ); 560| TwoD_XY_rot( &xy, ¢er, m_RotateDegree * (2 * 3.141592) / 360 ); 561| pts[i].x = (long)(xy.x + 0.5) * zoom / 100 - p->x0; 562| pts[i].y = (long)(xy.y + 0.5) * zoom / 100 - p->y0; 563| } 564| dc->Polygon( pts, 4 ); 565| } 566| break; 567| 568| case Text_Box_RoundRectShape: 569| if ( m_RotateDegree == 0 ) { 570| dc->RoundRect( box.left * zoom / 100 - p->x0, box.top * zoom / 100 - p->y0, 571| box.right * zoom / 100 + 1 - p->x0, box.bottom * zoom / 100 + 1 - p->y0, 572| 20 * zoom / 100, 20 * zoom / 100 ); 573| } 574| else { 575| POINT pts[8]; 576| int i; 577| 578| pts[0].x = box.left; pts[0].y = box.top + 6; 579| pts[1].x = box.left + 6; pts[1].y = box.top; 580| pts[2].x = box.right - 6; pts[2].y = box.top; 581| pts[3].x = box.right; pts[3].y = box.top + 6; 582| pts[4].x = box.right; pts[4].y = box.bottom - 6; 583| pts[5].x = box.right - 6; pts[5].y = box.bottom; 584| pts[6].x = box.left + 6; pts[6].y = box.bottom; 585| pts[7].x = box.left; pts[7].y = box.bottom - 6; 586| for ( i = 0; i < 8; i++ ) { 587| TwoD_XY_init( &xy, pts[i].x, pts[i].y ); 588| TwoD_XY_rot( &xy, ¢er, m_RotateDegree * (2 * 3.141592) / 360 ); 589| pts[i].x = (long)(xy.x + 0.5) * zoom / 100 - p->x0; 590| pts[i].y = (long)(xy.y + 0.5) * zoom / 100 - p->y0; 591| } 592| dc->Polygon( pts, 8 ); 593| } 594| break; 595| 596| case Text_Box_CircleShape: 597| dc->Ellipse( box.left * zoom / 100 - p->x0, box.top * zoom / 100 - p->y0, 598| box.right * zoom / 100 + 1 - p->x0, box.bottom * zoom / 100 + 1 - p->y0 ); 599| break; 600| 601| case Text_Box_DiamondShape: { 602| POINT pts[4]; 603| int hasuuX = ( box.left + box.right ) % 2; 604| int hasuuY = ( box.top + box.bottom ) % 2; 605| int i; 606| 607| pts[0].x = ( box.left + box.right ) / 2; 608| pts[0].y = box.top; 609| pts[1].x = box.right - hasuuX; 610| pts[1].y = ( box.top + box.bottom ) / 2; 611| pts[2].x = ( box.left + box.right ) / 2; 612| pts[2].y = box.bottom + hasuuY; 613| pts[3].x = box.left; 614| pts[3].y = ( box.top + box.bottom ) / 2; 615| for ( i = 0; i < 4; i++ ) { 616| TwoD_XY_init( &xy, pts[i].x, pts[i].y ); 617| TwoD_XY_rot( &xy, ¢er, m_RotateDegree * (2 * 3.141592) / 360 ); 618| pts[i].x = (long)(xy.x + 0.5) * zoom / 100 - p->x0; 619| pts[i].y = (long)(xy.y + 0.5) * zoom / 100 - p->y0; 620| } 621| dc->Polygon( pts, 4 ); 622| break; 623| } 624| case Text_Box_Parallelogram: { 625| POINT pts[4]; 626| int i; 627| int slide = ( box.bottom - box.top ) / 4; 628| 629| pts[0].x = box.left + slide; 630| pts[0].y = box.top; 631| pts[1].x = box.right + slide; 632| pts[1].y = box.top; 633| pts[2].x = box.right - slide; 634| pts[2].y = box.bottom; 635| pts[3].x = box.left - slide; 636| pts[3].y = box.bottom; 637| for ( i = 0; i < 4; i++ ) { 638| TwoD_XY_init( &xy, pts[i].x, pts[i].y ); 639| TwoD_XY_rot( &xy, ¢er, m_RotateDegree * (2 * 3.141592) / 360 ); 640| pts[i].x = (long)(xy.x + 0.5) * zoom / 100 - p->x0; 641| pts[i].y = (long)(xy.y + 0.5) * zoom / 100 - p->y0; 642| } 643| dc->Polygon( pts, 4 ); 644| break; 645| } 646| } 647| 648| dc->SelectObject( oldBrush ); 649| dc->SelectObject( oldPen ); 650| } 651| 652| 653| { 654| /* フォントを設定する */ 655| CFont font; 656| CFont font2; 657| CFont* oldFont; 658| int size = m_Size* 10 * ( p->bPrint ? 100 : zoom ) / 100; if ( size == 0 ) size = 1; 659| 660| font.CreatePointFont( size, (m_bTategaki ? CString('@')+m_Font : m_Font), dc ); 661| font.GetLogFont( &logFont ); 662| logFont.lfWidth = 0; 663| logFont.lfHeight = size; 664| logFont.lfWeight = m_bBold ? FW_BOLD : FW_NORMAL; 665| logFont.lfItalic = m_bItalic; 666| logFont.lfEscapement = - m_RotateDegree * 10 + (m_bTategaki ? 2700 :0); 667| font2.CreatePointFontIndirect( &logFont, dc ); 668| oldFont = dc->SelectObject( &font2 ); 669| 670| if ( m_IdLabel == "pagenum" ) { 671| char s[12]; 672| 673| sprintf( s, "%d", p->iPage ); 674| m_Text = s; 675| } 676| 677| 678| /* 文字列を表示する */ 679| { 680| COLORREF textNormalColor = p->bWhiteToBGColor && m_Color == 0x000000 ? 681| GetSysColor( COLOR_WINDOWTEXT ) : m_Color; 682| COLORREF textHighColor = GetSysColor( COLOR_HIGHLIGHTTEXT ); 683| int hx1, hy1, hx2, hy2; /* ハイライト表示の区間(カラムと行)*/ 684| 685| if ( m_bTategaki ) { 686| TwoD_XY_init( &xy, m_10H1 / 20 - m_10Descent / 10, -2 ); 687| TwoD_XY_rot( &xy, ¢er0, m_RotateDegree * (2 * 3.141592) / 360 ); 688| 689| textRect.left = (m_CenterX - (long)(xy.x + 0.5)) * zoom / 100 - p->x0; 690| textRect.top = (m_Y - (long)(xy.y + 0.5)) * zoom / 100 - p->y0; 691| } 692| else { 693| textRect.left = m_CenterX * zoom / 100 + 1 - p->x0; 694| textRect.top = m_Y * zoom / 100 - p->y0; 695| } 696| textRect.right = textRect.left; 697| textRect.bottom = textRect.top; 698| 699| dc->SetTextColor( textNormalColor ); 700| dc->SetBkMode( TRANSPARENT ); 701| dc->SetBkColor( GetSysColor( COLOR_HIGHLIGHT ) ); 702| GetTXYByIndex( m_CaretStart < m_CaretEnd ? m_CaretStart : m_CaretEnd, &hx1, &hy1 ); 703| GetTXYByIndex( m_CaretStart < m_CaretEnd ? m_CaretEnd : m_CaretStart, &hx2, &hy2 ); 704| 705| switch ( m_BasePos ) { 706| case Text_Box_LeftAlign: 707| dc->SetTextAlign( TA_BASELINE | TA_LEFT ); 708| break; 709| case Text_Box_CenterAlign: 710| dc->SetTextAlign( TA_BASELINE | TA_CENTER ); 711| break; 712| case Text_Box_RightAlign: 713| dc->SetTextAlign( TA_BASELINE | TA_RIGHT ); 714| break; 715| } 716| dc->SetTextCharacterExtra( 0 ); 717| for ( i = 1; i <= nTextLine; i++ ) { 718| RECT rc; 719| char s[Text_Box_nByteInLine+4]; 720| 721| if ( m_RotateDegree == 0 ) { 722| rc.left = textRect.left; 723| rc.top = textRect.top; 724| if ( m_bTategaki ) { 725| rc.left -= ( (i - 1) * m_BetweenOfLine ) * zoom / 100; 726| if ( i > 100 ) break; 727| } 728| else { 729| rc.top += ( (i - 1) * m_BetweenOfLine ) * zoom / 100; 730| if ( rc.top + m_BetweenOfLine < p->clip_top ) 731| continue; 732| if ( rc.top - m_BetweenOfLine > p->clip_bottom ) 733| break; 734| } 735| } 736| else { 737| if ( m_bTategaki ) TwoD_XY_init( &xy, - (i - 1) * m_BetweenOfLine, 0 ); 738| else TwoD_XY_init( &xy, 0, (i - 1) * m_BetweenOfLine ); 739| TwoD_XY_rot( &xy, ¢er0, m_RotateDegree * (2 * 3.141592) / 360 ); 740| rc.left = (textRect.left + (long)(xy.x + 0.5)) * zoom / 100 - p->x0; 741| rc.top = (textRect.top + (long)(xy.y + 0.5)) * zoom / 100 - p->y0; 742| if ( i > 100 ) break; 743| } 744| rc.right = rc.left; 745| rc.bottom = rc.top; 746| 747| if ( StrX_cpy1Line( s, sizeof(s), m_Text, i ) == NULL ) break; 748| 749| #if 1 /* Highlight */ 750| { 751| char c; 752| int gx, gy, left; 753| DWORD flag = DT_LEFT | DT_SINGLELINE | DT_TOP | 754| DT_NOCLIP | DT_NOPREFIX | DT_EXTERNALLEADING; 755| 756| if ( hy1 == i - 1 ) { 757| if ( hx1 > 0 ) { 758| /* ハイライトより左を書く */ 759| c = s[hx1]; s[hx1] = '\0'; 760| dc->DrawText( s, -1, &rc, flag ); 761| s[hx1] = c; 762| } 763| 764| dc->SetTextColor( textHighColor ); 765| dc->SetBkMode( OPAQUE ); 766| 767| if ( hy2 == hy1 ) { 768| /* 行内のハイライトを書く */ 769| left = rc.left; 770| GetGXYByTXY( dc, hx1, hy1, &gx, &gy ); 771| rc.left = left + gx; 772| rc.right = rc.left; 773| c = s[hx2]; s[hx2] = '\0'; 774| dc->DrawText( s + hx1, -1, &rc, flag ); 775| s[hx2] = c; 776| 777| /* ハイライトより右を書く */ 778| dc->SetTextColor( textNormalColor ); 779| dc->SetBkMode( TRANSPARENT ); 780| GetGXYByTXY( dc, hx2, hy2, &gx, &gy ); 781| rc.left = left + gx; 782| rc.right = rc.left; 783| dc->DrawText( s + hx2, -1, &rc, flag ); 784| } 785| else { 786| /* 行末までハイライトを書く */ 787| GetGXYByTXY( dc, hx1, hy1, &gx, &gy ); 788| rc.left = left + gx; 789| rc.right = rc.left; 790| dc->DrawText( s + hx1, -1, &rc, flag ); 791| } 792| } 793| else if ( hy2 == i - 1 ) { 794| /* 行頭からハイライトを書く */ 795| c = s[hx2]; s[hx2] = '\0'; 796| dc->DrawText( s, -1, &rc, flag ); 797| s[hx2] = c; 798| 799| /* ハイライトより右を書く */ 800| dc->SetTextColor( textNormalColor ); 801| dc->SetBkMode( TRANSPARENT ); 802| GetGXYByTXY( dc, hx2, hy2, &gx, &gy ); 803| rc.left = left + gx; 804| rc.right = rc.left; 805| dc->DrawText( s + hx2, -1, &rc, flag ); 806| } 807| else { 808| /* ノーマルまたはハイライトで1行全体を書く */ 809| dc->DrawText( s, -1, &rc, flag ); 810| } 811| } 812| #else 813| dc->DrawText( s, -1, &rc, DT_LEFT | DT_SINGLELINE | DT_TOP | 814| DT_NOCLIP | DT_NOPREFIX | DT_EXTERNALLEADING ); 815| #endif 816| } 817| dc->SelectObject( oldFont ); 818| } 819| } 820| 821| if ( m_bHold && p->bDrawHandle ) 822| DrawHandles( dc, p, ~GetSysColor( COLOR_HIGHLIGHT ) & 0xFFFFFF, false ); 823| 824| ERRORS_FUNC_END_CPP( Text_Box_Draw ); 825|} 826| 827| 828| 829|/*********************************************************************** 830| 2-13. <<< [Text_Box::DrawHandles] CadPrim::DrawJamdles の実装部 >>> 831|【引数】 832| ・CDC* dc; デバイスコンテキスト 833| ・int color; ハンドルの色 834|************************************************************************/ 835|void Text_Box::DrawHandles( CDC* dc, CadPrim_DrawParam* p, COLORREF color, 836| bool bDrawFrame ) 837|{ 838| CPen pen( PS_SOLID, 1, color ^ 0xFFFFFF ); 839| CBrush brush( color ); 840| CPen* oldPen; 841| CBrush* oldBrush; 842| RECT box; 843| int x1, x2, x3, y1, y2, y3, x, y; 844| 845| oldPen = dc->SelectObject( &pen ); 846| oldBrush = dc->SelectObject( &brush ); 847| 848| GetBox( &box ); 849| x1 = box.left; 850| x3 = box.right; 851| y1 = box.top; 852| y3 = box.bottom; 853| x2 = (x1 + x3) / 2; 854| y2 = (y1 + y3) / 2; 855| 856| if ( m_RotateDegree == 0 && m_BoxShape != Text_Box_Parallelogram ) { 857| x1 = x1 * p->zoom / 100 - p->x0; y1 = y1 * p->zoom / 100 - p->y0; 858| x2 = x2 * p->zoom / 100 - p->x0; y2 = y2 * p->zoom / 100 - p->y0; 859| x3 = x3 * p->zoom / 100 - p->x0; y3 = y3 * p->zoom / 100 - p->y0; 860| 861| dc->Rectangle( x1 - 3, y1 - 3, x1 + 3, y1 + 3 ); 862| dc->Rectangle( x2 - 3, y1 - 3, x2 + 3, y1 + 3 ); 863| dc->Rectangle( x3 - 3, y1 - 3, x3 + 3, y1 + 3 ); 864| dc->Rectangle( x1 - 3, y2 - 3, x1 + 3, y2 + 3 ); 865| dc->Rectangle( x3 - 3, y2 - 3, x3 + 3, y2 + 3 ); 866| dc->Rectangle( x1 - 3, y3 - 3, x1 + 3, y3 + 3 ); 867| dc->Rectangle( x2 - 3, y3 - 3, x2 + 3, y3 + 3 ); 868| dc->Rectangle( x3 - 3, y3 - 3, x3 + 3, y3 + 3 ); 869| } 870| else { 871| TwoD_XY xy, center; 872| double angle = m_RotateDegree * (2 * 3.141592) / 360; 873| int slide; 874| CPen dashPen( PS_DOT, 1, color ); 875| TwoD_XY corner[4]; 876| 877| if ( m_BoxShape == Text_Box_Parallelogram ) slide = (y3 - y1) / 4; 878| else slide = 0; 879| 880| TwoD_XY_init( ¢er, m_CenterX, m_Y ); 881| 882| TwoD_XY_init( &xy, x1 + slide, y1 ); TwoD_XY_rot( &xy, ¢er, angle ); 883| x = (long)xy.x * p->zoom / 100 - p->x0; y = (long)xy.y * p->zoom / 100 - p->y0; 884| dc->Rectangle( x - 3, y - 3, x + 3, y + 3 ); 885| corner[0].x = x; corner[0].y = y; 886| 887| TwoD_XY_init( &xy, x2 + slide, y1 ); TwoD_XY_rot( &xy, ¢er, angle ); 888| x = (long)xy.x * p->zoom / 100 - p->x0; y = (long)xy.y * p->zoom / 100 - p->y0; 889| dc->Rectangle( x - 3, y - 3, x + 3, y + 3 ); 890| 891| TwoD_XY_init( &xy, x3 + slide, y1 ); TwoD_XY_rot( &xy, ¢er, angle ); 892| x = (long)xy.x * p->zoom / 100 - p->x0; y = (long)xy.y * p->zoom / 100 - p->y0; 893| dc->Rectangle( x - 3, y - 3, x + 3, y + 3 ); 894| corner[1].x = x; corner[1].y = y; 895| 896| TwoD_XY_init( &xy, x1, y2 ); TwoD_XY_rot( &xy, ¢er, angle ); 897| x = (long)xy.x * p->zoom / 100 - p->x0; y = (long)xy.y * p->zoom / 100 - p->y0; 898| dc->Rectangle( x - 3, y - 3, x + 3, y + 3 ); 899| 900| TwoD_XY_init( &xy, x3, y2 ); TwoD_XY_rot( &xy, ¢er, angle ); 901| x = (long)xy.x * p->zoom / 100 - p->x0; y = (long)xy.y * p->zoom / 100 - p->y0; 902| dc->Rectangle( x - 3, y - 3, x + 3, y + 3 ); 903| 904| TwoD_XY_init( &xy, x1 - slide, y3 ); TwoD_XY_rot( &xy, ¢er, angle ); 905| x = (long)xy.x * p->zoom / 100 - p->x0; y = (long)xy.y * p->zoom / 100 - p->y0; 906| dc->Rectangle( x - 3, y - 3, x + 3, y + 3 ); 907| corner[2].x = x; corner[2].y = y; 908| 909| TwoD_XY_init( &xy, x2 - slide, y3 ); TwoD_XY_rot( &xy, ¢er, angle ); 910| x = (long)xy.x * p->zoom / 100 - p->x0; y = (long)xy.y * p->zoom / 100 - p->y0; 911| dc->Rectangle( x - 3, y - 3, x + 3, y + 3 ); 912| 913| TwoD_XY_init( &xy, x3 - slide, y3 ); TwoD_XY_rot( &xy, ¢er, angle ); 914| x = (long)xy.x * p->zoom / 100 - p->x0; y = (long)xy.y * p->zoom / 100 - p->y0; 915| dc->Rectangle( x - 3, y - 3, x + 3, y + 3 ); 916| corner[3].x = x; corner[3].y = y; 917| 918| if ( bDrawFrame && m_RotateDegree != 0 && 919| ( m_BoxShape == Text_Box_RoundRectShape || m_BoxShape == Text_Box_CircleShape ) ) { 920| dc->SelectObject( dashPen ); 921| dc->MoveTo( (int)corner[0].x, (int)corner[0].y ); 922| dc->LineTo( (int)corner[1].x, (int)corner[1].y ); 923| dc->LineTo( (int)corner[3].x, (int)corner[3].y ); 924| dc->LineTo( (int)corner[2].x, (int)corner[2].y ); 925| dc->LineTo( (int)corner[0].x, (int)corner[0].y ); 926| } 927| } 928| 929| dc->SelectObject( oldBrush ); 930| dc->SelectObject( oldPen ); 931|} 932| 933| 934|/*********************************************************************** 935| 2-14. <<< [Text_Box::copy] CadPrim::copy の実装部 >>> 936|************************************************************************/ 937|void Text_Box::copy( CadPrim* a, ListX* prims ) 938|{ 939| CadPrim_Link* link1; 940| CadPrim_Link* link2; 941| Text_Box* t = (Text_Box*)a; 942| 943| m_id = t->m_id; 944| m_IdLabel = ""; 945| m_URL = t->m_URL; 946| m_Target = t->m_Target; 947| m_Text = t->m_Text; 948| m_CenterX = t->m_CenterX; 949| m_Y = t->m_Y; 950| m_DiffW = t->m_DiffW; 951| m_W = t->m_W; 952| m_10H = t->m_10H; 953| m_10Descent = t->m_10Descent; 954| m_BetweenOfLine = t->m_BetweenOfLine; 955| m_RotateDegree = t->m_RotateDegree; 956| m_Color = t->m_Color; 957| m_Font = t->m_Font; 958| m_Size = t->m_Size; 959| m_bBold = t->m_bBold; 960| m_bItalic = t->m_bItalic; 961| m_BasePos = t->m_BasePos; 962| m_bTategaki = t->m_bTategaki; 963| 964| m_BoxShape = t->m_BoxShape; 965| m_BoxMarginX = t->m_BoxMarginX; 966| m_BoxMarginY = t->m_BoxMarginY; 967| m_BorderWidth = t->m_BorderWidth; 968| m_BorderColor = t->m_BorderColor; 969| m_FillColor = t->m_FillColor; 970| m_FillNTrans = t->m_FillNTrans; 971| 972| ListX_toEmptyDelete( &m_Links, CadPrim_Link, NULL ); 973| for ( ListX_forEach( &t->m_Links, &link2, CadPrim_Link ) ) { 974| link1 = ListX_addLastMalloc( &m_Links, CadPrim_Link ); 975| CadPrim_Link_copy( link1, link2 ); 976| link1->prim = Undo_Uty_getPrimPtr( prims, link1->prim_id ); 977| } 978| m_Controler_id = t->m_Controler_id; 979| m_Controler = Undo_Uty_getPrimPtr( prims, m_Controler_id ); 980|} 981| 982|/*********************************************************************** 983| 2-15. <<< [Text_Box::copyStyle] CadPrim::copyStyle の実装部 >>> 984|************************************************************************/ 985|void Text_Box::copyStyle( CadPrim* a, ListX* prims ) 986|{ 987| Text_Box* t = (Text_Box*)a; 988| 989| m_BetweenOfLine = t->m_BetweenOfLine; 990| m_Color = t->m_Color; 991| m_Font = t->m_Font; 992| m_Size = t->m_Size; 993| m_bBold = t->m_bBold; 994| m_bItalic = t->m_bItalic; 995| 996| m_BoxMarginX = t->m_BoxMarginX; 997| m_BoxMarginY = t->m_BoxMarginY; 998| m_BorderWidth = t->m_BorderWidth; 999| m_BorderColor = t->m_BorderColor; 1000| m_FillColor = t->m_FillColor; 1001| m_FillNTrans = t->m_FillNTrans; 1002|} 1003| 1004|/*********************************************************************** 1005| 2-16. <<< [Text_Box::isEqual] CadPrim::isEqual の実装部 >>> 1006|************************************************************************/ 1007|bool Text_Box::isEqual( CadPrim* a ) 1008|{ 1009| Text_Box* t = (Text_Box*)a; 1010| CadPrim_Link* link; 1011| CadPrim_Link* link2; 1012| 1013| if ( a->GetTypeID() != Text_Box_TypeID ) return false; 1014| 1015| link2 = ListX_getFirst( &t->m_Links, CadPrim_Link ); 1016| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 1017| if ( link2 == NULL ) return false; 1018| if ( link->prim_id != link2->prim_id || 1019| link->iHandle != link2->iHandle || 1020| link->x != link2->x || link->y != link2->y ) 1021| return false; 1022| 1023| link2 = ListX_Elem_getNextT( link2, CadPrim_Link ); 1024| } 1025| if ( link2 != NULL ) return false; 1026| 1027| 1028| return ( 1029| m_Text == t->m_Text && 1030| m_IdLabel == t->m_IdLabel && 1031| m_URL == t->m_URL && 1032| m_Target == t->m_Target && 1033| m_CenterX == t->m_CenterX && 1034| m_Y == t->m_Y && 1035| m_DiffW == t->m_DiffW && 1036| m_BetweenOfLine == t->m_BetweenOfLine && 1037| m_RotateDegree == t->m_RotateDegree && 1038| m_Color == t->m_Color && 1039| m_Font == t->m_Font && 1040| m_Size == t->m_Size && 1041| m_bBold == t->m_bBold && 1042| m_bItalic == t->m_bItalic && 1043| m_BasePos == t->m_BasePos && 1044| m_bTategaki == t->m_bTategaki && 1045| m_BoxShape == t->m_BoxShape && 1046| m_BoxMarginX == t->m_BoxMarginX && 1047| m_BoxMarginY == t->m_BoxMarginY && 1048| m_BorderWidth == t->m_BorderWidth && 1049| m_BorderColor == t->m_BorderColor && 1050| m_FillColor == t->m_FillColor && 1051| m_FillNTrans == t->m_FillNTrans && 1052| 1053| m_Controler_id == t->m_Controler_id ); 1054|} 1055| 1056| 1057|/*********************************************************************** 1058| 2-17. <<< [Text_Box::GetNewCopy] CadPrim::GetNewCopy の実装部 >>> 1059|************************************************************************/ 1060|CadPrim* Text_Box::GetNewCopy( ListX* prims ) 1061|{ 1062| Text_Box* r = new Text_Box; 1063| 1064| r->copy( this, prims ); 1065| return r; 1066|} 1067| 1068| 1069|/*********************************************************************** 1070| 2-18. <<< [Text_Box::GetSerializedSize] CadPrim::GetSerializedSize の実装部 >>> 1071|************************************************************************/ 1072|int Text_Box::GetSerializedSize() 1073|{ 1074| return ( sizeof(Text_Box) + m_IdLabel.GetLength() + 1 + m_Text.GetLength() + 1 + 1075| m_URL.GetLength() + 1 + m_Target.GetLength() + 1 + m_Font.GetLength() + 1 + 1076| sizeof(CadPrim_Link) * ListX_getN( &m_Links, CadPrim_Link ) 1077| + 3 ) & ~3; 1078|} 1079| 1080| 1081|/*********************************************************************** 1082| 2-19. <<< [Text_Box::CopyToSerial] CadPrim::CopyToSerial の実装部 >>> 1083|************************************************************************/ 1084|void Text_Box::CopyToSerial( void* a ) 1085|{ 1086| Text_Box* t = (Text_Box*)a; 1087| char* s = (char*)a + sizeof(Text_Box); 1088| CadPrim_Link* link; 1089| 1090| t->m_id = m_id; 1091| // t->m_IdLabel = m_IdLabel; 1092| // t->m_Text = m_Text; 1093| // t->m_URL = m_URL; 1094| // t->m_Target = m_Target; 1095| t->m_CenterX = m_CenterX; 1096| t->m_Y = m_Y; 1097| t->m_DiffW = m_DiffW; 1098| t->m_W = m_W; 1099| t->m_10H = m_10H; 1100| t->m_10Descent = m_10Descent; 1101| t->m_BetweenOfLine = m_BetweenOfLine; 1102| t->m_RotateDegree = m_RotateDegree; 1103| t->m_Color = m_Color; 1104| // t->m_Font = m_Font; 1105| t->m_Size = m_Size; 1106| t->m_bBold = m_bBold; 1107| t->m_bItalic = m_bItalic; 1108| t->m_BasePos = m_BasePos; 1109| t->m_bTategaki = m_bTategaki; 1110| 1111| t->m_BoxShape = m_BoxShape; 1112| t->m_BoxMarginX = m_BoxMarginX; 1113| t->m_BoxMarginY = m_BoxMarginY; 1114| t->m_BorderWidth = m_BorderWidth; 1115| t->m_BorderColor = m_BorderColor; 1116| t->m_FillColor = m_FillColor; 1117| t->m_FillNTrans = m_FillNTrans; 1118| 1119| t->m_Links.first = (void*)ListX_getN( &m_Links, CadPrim_Link ); 1120| t->m_Controler_id = m_Controler_id; 1121| 1122| strcpy( s, m_Text ); 1123| s = strchr( s, '\0' ) + 1; 1124| strcpy( s, m_Font ); 1125| s = strchr( s, '\0' ) + 1; 1126| strcpy( s, m_IdLabel ); 1127| s = strchr( s, '\0' ) + 1; 1128| strcpy( s, m_URL ); 1129| s = strchr( s, '\0' ) + 1; 1130| strcpy( s, m_Target ); 1131| s = strchr( s, '\0' ) + 1; 1132| 1133| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 1134| CadPrim_Link_copy( (CadPrim_Link*)s, link ); 1135| s += sizeof(CadPrim_Link); 1136| } 1137|} 1138| 1139| 1140|/*********************************************************************** 1141| 2-20. <<< [Text_Box::CopyFromSerial] CadPrim::CopyFromSerial の実装部 >>> 1142|************************************************************************/ 1143|void Text_Box::CopyFromSerial( void* a ) 1144|{ 1145| Text_Box* t = (Text_Box*)a; 1146| char* s = (char*)a + sizeof(Text_Box); 1147| CadPrim_Link* link; 1148| int i, n; 1149| 1150| m_id = t->m_id; 1151| // m_IdLabel = t->m_IdLabel; 1152| // m_URL = t->m_URL; 1153| // m_Target = t->m_Target; 1154| // m_Text = t->m_Text; 1155| m_CenterX = t->m_CenterX; 1156| m_Y = t->m_Y; 1157| m_DiffW = t->m_DiffW; 1158| m_W = t->m_W; 1159| m_10H = t->m_10H; 1160| m_10Descent = t->m_10Descent; 1161| m_BetweenOfLine = t->m_BetweenOfLine; 1162| m_RotateDegree = t->m_RotateDegree; 1163| m_Color = t->m_Color; 1164| // m_Font = t->m_Font; 1165| m_Size = t->m_Size; 1166| m_bBold = t->m_bBold; 1167| m_bItalic = t->m_bItalic; 1168| m_BasePos = t->m_BasePos; 1169| m_bTategaki = t->m_bTategaki; 1170| 1171| m_BoxShape = t->m_BoxShape; 1172| m_BoxMarginX = t->m_BoxMarginX; 1173| m_BoxMarginY = t->m_BoxMarginY; 1174| m_BorderWidth = t->m_BorderWidth; 1175| m_BorderColor = t->m_BorderColor; 1176| m_FillColor = t->m_FillColor; 1177| m_FillNTrans = t->m_FillNTrans; 1178| 1179| // m_URL = t->m_URL; 1180| 1181| n = (int)t->m_Links.first; 1182| m_Controler_id = t->m_Controler_id; 1183| 1184| m_Text = s; 1185| s = strchr( s, '\0' ) + 1; 1186| m_Font = s; 1187| s = strchr( s, '\0' ) + 1; 1188| m_IdLabel = s; 1189| s = strchr( s, '\0' ) + 1; 1190| m_URL = s; 1191| s = strchr( s, '\0' ) + 1; 1192| m_Target = s; 1193| s = strchr( s, '\0' ) + 1; 1194| 1195| ListX_init( &m_Links ); 1196| for ( i = 0; i < n; i++ ) { 1197| link = ListX_addFirstMalloc( &m_Links, CadPrim_Link ); 1198| CadPrim_Link_copy( link, (CadPrim_Link*)s ); 1199| s += sizeof(CadPrim_Link); 1200| } 1201|} 1202| 1203| 1204|/*********************************************************************** 1205| 2-21. <<< [Text_Box::GetHitHandleNum] CadPrim::GetHitHandleNum の実装部 >>> 1206|【補足】 1207|・ハンドル番号は、1=左上、2=上、3=右上、4=左、5=右、6=左下、 1208| 7=下、8=右下 です。 1209|************************************************************************/ 1210|int Text_Box::GetHitHandleNum( int x, int y, int zoom, int mode, int* dx, int* dy, int* diff, int* arrow ) 1211|{ 1212| RECT box; 1213| int dx1, dy1, dx2, dy2, dx3, dy3; 1214| int diff1; 1215| int diff2; 1216| int minDiff; 1217| int d; 1218| int slide; 1219| int ret = 0; 1220| TwoD_XY xy, center; 1221| 1222| diff1 = 8 * 100 / zoom; if ( diff1 < 1 ) diff1 = 1; 1223| diff2 = 2 * 100 / zoom; if ( diff2 < 1 ) diff2 = 1; 1224| minDiff = 2 * diff1 + 1; 1225| 1226| TwoD_XY_init( &xy, x, y ); 1227| TwoD_XY_init( ¢er, m_CenterX, m_Y ); 1228| TwoD_XY_rot( &xy, ¢er, - m_RotateDegree * (2 * 3.141592) / 360 ); 1229| x = (int)xy.x; y = (int)xy.y; 1230| 1231| GetBox( &box ); 1232| dx1 = x - box.left; 1233| dy1 = y - box.top; 1234| dx2 = x - ( (box.left + box.right) / 2 ); 1235| dy2 = y - ( (box.top + box.bottom) / 2 ); 1236| dx3 = x - box.right; 1237| dy3 = y - box.bottom; 1238| if ( m_BoxShape == Text_Box_Parallelogram ) slide = (box.bottom - box.top) / 4; 1239| else slide = 0; 1240| 1241| *dx = 0; *dy = 0; 1242| 1243| /* 小さいときは、一部のハンドルのみ使えるようにする */ 1244| if ( box.right - box.left < diff1 && box.bottom - box.top < diff1 ) { 1245| if ( dx3 >= -diff2 && dx3 <= diff1 && dy3 >= -diff2 && dy3 <= diff1 ) 1246| { *arrow = CadPrim_RightDownArrow; ret = 8; } 1247| else 1248| { *arrow = CadPrim_NormalArrow; ret = 0; } 1249| } 1250| 1251| /* 通常の大きさのとき */ 1252| else { 1253| 1254| if ( m_BoxShape != Text_Box_NoFrame || mode == CadPrim_RotateMode ) { 1255| 1256| /* 8箇所のハンドルにヒットしたか確認する */ 1257| if ( dx3 >= -diff2 && dx3 <= diff1 && dy2 >= -diff1 && dy2 <= diff1 ) { 1258| d = abs(dx3) + abs(dy2); 1259| if ( d < minDiff ) /* 最も近いハンドルを採用する */ 1260| { *arrow = CadPrim_HorizontalArrow; minDiff = d; ret = 5; } 1261| } 1262| if ( dx2 + slide >= -diff1 && dx2 + slide <= diff1 && dy3 >= -diff2 && dy3 <= diff1 ) { 1263| d = abs(dx2 + slide) + abs(dy3); 1264| if ( d < minDiff ) 1265| { *arrow = CadPrim_VerticalArrow; minDiff = d; ret = 7; } 1266| } 1267| if ( dx1 >= -diff1 && dx1 <= diff2 && dy2 >= -diff1 && dy2 <= diff1 ) { 1268| d = abs(dx1) + abs(dy2); 1269| if ( d < minDiff ) 1270| { *arrow = CadPrim_HorizontalArrow; minDiff = d; ret = 4; } 1271| } 1272| if ( dx2 - slide >= -diff1 && dx2 - slide <= diff1 && dy1 >= -diff1 && dy1 <= diff2 ) { 1273| d = abs(dx2 - slide) + abs(dy1); 1274| if ( d < minDiff ) 1275| { *arrow = CadPrim_VerticalArrow; minDiff = d; ret = 2; } 1276| } 1277| if ( dx3 + slide >= -diff2 && dx3 + slide <= diff1 && dy3 >= -diff2 && dy3 <= diff1 ) { 1278| d = abs(dx3 + slide) + abs(dy3); 1279| if ( d < minDiff ) 1280| { *arrow = CadPrim_RightDownArrow; minDiff = d; ret = 8; } 1281| } 1282| if ( dx1 - slide >= -diff1 && dx1 - slide <= diff2 && dy1 >= -diff1 && dy1 <= diff2 ) { 1283| d = abs(dx1 - slide) + abs(dy1); 1284| if ( d < minDiff ) 1285| { *arrow = CadPrim_RightDownArrow; minDiff = d; ret = 1; } 1286| } 1287| if ( dx3 - slide >= -diff2 && dx3 - slide <= diff1 && dy1 >= -diff1 && dy1 <= diff2 ) { 1288| d = abs(dx3 - slide) + abs(dy1); 1289| if ( d < minDiff ) 1290| { *arrow = CadPrim_RightUpArrow; minDiff = d; ret = 3; } 1291| } 1292| if ( dx1 + slide >= -diff1 && dx1 + slide <= diff2 && dy3 >= -diff2 && dy3 <= diff1 ) { 1293| d = abs(dx1 + slide) + abs(dy3); 1294| if ( d < minDiff ) 1295| { *arrow = CadPrim_RightUpArrow; minDiff = d; ret = 6; } 1296| } 1297| } 1298| 1299| if ( ret == 0 ) { 1300| bool f; 1301| 1302| /* ハンドル以外(図形の上)にヒットしたか確かめる */ 1303| if ( m_BoxShape != Text_Box_Parallelogram ) 1304| f = ( box.left <= x && x <= box.right && box.top <= y && y <= box.bottom ); 1305| else { 1306| int dy = y - ( box.top + box.bottom ) / 2; 1307| 1308| f = ( box.left-dy/2 <= x && x <= box.right-dy/2 && box.top <= y && y <= box.bottom ); 1309| } 1310| 1311| if ( f ) { 1312| *dx = m_CenterX - x; 1313| *dy = m_Y - y; 1314| *arrow = CadPrim_MovableArrow; 1315| ret = -1; 1316| } 1317| else { 1318| *arrow = CadPrim_NormalArrow; 1319| ret = 0; 1320| } 1321| } 1322| } 1323| 1324| 1325| /* 角度編集モードのとき、カーソルを変更する */ 1326| if ( mode == CadPrim_RotateMode ) { 1327| if ( ret == -1 ) 1328| *arrow = CadPrim_NormalArrow; 1329| else if ( ret > 0 ) { 1330| if ( m_BoxShape == Text_Box_NoFrame || m_BoxShape == Text_Box_RectShape || 1331| m_BoxShape == Text_Box_RoundRectShape || m_BoxShape == Text_Box_DiamondShape || 1332| m_BoxShape == Text_Box_Parallelogram ) { 1333| *arrow = CadPrim_MovableArrow; 1334| } 1335| else { 1336| *arrow = CadPrim_NoArrow; 1337| } 1338| } 1339| } 1340| 1341| return ret; 1342|} 1343| 1344| 1345|/*********************************************************************** 1346| 2-22. <<< [Text_Box::Move] CadPrim::Move の実装部 >>> 1347|************************************************************************/ 1348|void Text_Box::Move( int dx, int dy ) 1349|{ 1350| m_CenterX += dx; m_Y += dy; 1351| MoveLinks( true ); 1352|} 1353| 1354| 1355| 1356|/*********************************************************************** 1357| 2-23. <<< [Text_Box::MoveByHandle] ハンドルを動かしてパラメータを変える >>> 1358|************************************************************************/ 1359|void Text_Box::MoveByHandle( int iHandle, int x, int y, bool bShift, bool bRotate ) 1360|{ 1361| RECT box; 1362| int n = StrX_getNLine( m_Text ); 1363| 1364| GetBox( &box ); 1365| 1366| /* 平行四辺形のずれを直す */ 1367| if ( m_BoxShape == Text_Box_Parallelogram ) { 1368| int slide = (box.bottom - box.top) / 4; 1369| 1370| if ( iHandle >= 1 && iHandle <= 3 ) x -= slide; 1371| else if ( iHandle >= 6 ) x += slide; 1372| } 1373| 1374| if ( bRotate ) { 1375| int x1, y1, x2, y2, x3, y3; 1376| int hx, hy; 1377| double curAng, hdlAng; 1378| 1379| x1 = box.left; 1380| y1 = box.top; 1381| x2 = (box.left + box.right) / 2; 1382| y2 = (box.top + box.bottom) / 2; 1383| x3 = box.right; 1384| y3 = box.bottom; 1385| 1386| switch ( iHandle ) { 1387| case 1: hx = x1; hy = y1; break; 1388| case 2: hx = x2; hy = y1; break; 1389| case 3: hx = x3; hy = y1; break; 1390| case 4: hx = x1; hy = y2; break; 1391| case 5: hx = x3; hy = y2; break; 1392| case 6: hx = x1; hy = y3; break; 1393| case 7: hx = x2; hy = y3; break; 1394| case 8: hx = x3; hy = y3; break; 1395| } 1396| 1397| curAng = atan2( y - y2, x - x2 ); 1398| hdlAng = atan2( hy - y2, hx - x2 ); 1399| m_RotateDegree = (int)( ( curAng - hdlAng ) * 360.0 / ( 2 * 3.141592 ) ); 1400| if ( ! bShift ) { 1401| hx = m_RotateDegree % 90; 1402| if ( hx < 0 ) hx += 90; 1403| if ( hx < 8 ) m_RotateDegree -= hx; 1404| else if ( hx > 82 ) m_RotateDegree += 90 - hx; 1405| } 1406| } 1407| else { 1408| if ( m_bTategaki && iHandle > 0 ) { 1409| int x1, y1, x2, y2, x3, y3; 1410| 1411| x1 = box.left; 1412| y1 = box.top; 1413| x2 = (box.left + box.right) / 2; 1414| y2 = (box.top + box.bottom) / 2; 1415| x3 = box.right; 1416| y3 = box.bottom; 1417| 1418| switch ( iHandle ) { 1419| case 1: m_BoxMarginX += y1 - y; m_BoxMarginY += x1 - x; break; 1420| case 2: m_BoxMarginX += y1 - y; break; 1421| case 3: m_BoxMarginX += y1 - y; m_BoxMarginY += x - x3; break; 1422| case 4: m_BoxMarginY += x1 - x; break; 1423| case 5: m_BoxMarginY += x - x3; break; 1424| case 6: m_BoxMarginX += y - y3; m_BoxMarginY += x1 - x; break; 1425| case 7: m_BoxMarginX += y - y3; break; 1426| case 8: m_BoxMarginX += y - y3; m_BoxMarginY += x - x3; break; 1427| } 1428| if ( m_BoxMarginX < 0 ) m_BoxMarginX = 0; 1429| if ( m_BoxMarginY < 0 ) m_BoxMarginY = 0; 1430| } 1431| else { 1432| if ( iHandle > 0 ) { 1433| switch ( m_BasePos ) { 1434| case Text_Box_LeftAlign: x -= (m_W + 1) / 2; break; 1435| case Text_Box_CenterAlign: break; 1436| case Text_Box_RightAlign: x += m_W / 2; break; 1437| } 1438| } 1439| switch ( iHandle ) { 1440| case 1: 1441| m_BoxMarginX = m_CenterX - (m_W + 1) / 2 - x; 1442| m_BoxMarginY = m_Y + m_10Descent/10 + (n-1) * m_BetweenOfLine - m_10H/10 - y; 1443| break; 1444| case 2: 1445| m_BoxMarginY = m_Y + m_10Descent/10 + (n-1) * m_BetweenOfLine - m_10H/10 - y; 1446| break; 1447| case 3: 1448| m_BoxMarginX = x - m_CenterX - m_W / 2; 1449| m_BoxMarginY = m_Y + m_10Descent/10 + (n-1) * m_BetweenOfLine - m_10H/10 - y; 1450| break; 1451| case 4: 1452| m_BoxMarginX = m_CenterX - (m_W + 1) / 2 - x; 1453| break; 1454| case 5: 1455| m_BoxMarginX = x - m_CenterX - m_W / 2; 1456| break; 1457| case 6: 1458| m_BoxMarginX = m_CenterX - (m_W + 1) / 2 - x; 1459| m_BoxMarginY = y - ( m_Y + m_10Descent/10 + (n-1) * m_BetweenOfLine ); 1460| break; 1461| case 7: 1462| m_BoxMarginY = y - ( m_Y + m_10Descent/10 + (n-1) * m_BetweenOfLine ); 1463| break; 1464| case 8: 1465| m_BoxMarginX = x - m_CenterX - m_W / 2; 1466| m_BoxMarginY = y - ( m_Y + m_10Descent/10 + (n-1) * m_BetweenOfLine ); 1467| break; 1468| case -1: 1469| if ( ! bShift ) AutoAdjustXY( &x, &y ); 1470| GetBox( &box ); 1471| switch ( m_BasePos ) { 1472| case Text_Box_LeftAlign: m_CenterX += x - box.left - m_BoxMarginX; break; 1473| case Text_Box_CenterAlign: m_CenterX += x - ( box.left + box.right ) / 2; break; 1474| case Text_Box_RightAlign: m_CenterX += x - box.right + m_BoxMarginX; break; 1475| } 1476| m_Y = y; 1477| break; 1478| } 1479| if ( m_BoxMarginX < 0 ) m_BoxMarginX = 0; 1480| if ( m_BoxMarginY < 0 ) m_BoxMarginY = 0; 1481| MoveLinks( true ); 1482| } 1483| } 1484|} 1485| 1486| 1487|/*********************************************************************** 1488| 2-24. <<< [Text_Box::GetCenterOfHandle] CadPrim::GetCenterOfHandle >>> 1489|************************************************************************/ 1490|void Text_Box::GetCenterOfHandle( int iHandle, int* x, int* y ) 1491|{ 1492| RECT box; 1493| 1494| GetBox( &box ); 1495| 1496| switch ( iHandle ) { 1497| case 1: *x = box.left; *y = box.top; break; 1498| case 2: *x = (box.left + box.right) / 2; *y = box.top; break; 1499| case 3: *x = box.right; *y = box.top; break; 1500| case 4: *x = box.left; *y = (box.top + box.bottom) / 2; break; 1501| case 5: *x = box.right; *y = (box.top + box.bottom) / 2; 1502| case 6: *x = box.left; *y = box.bottom; break; 1503| case 7: *x = (box.left + box.right) / 2; *y = box.bottom; break; 1504| case 8: *x = box.right; *y = box.bottom; break; 1505| } 1506|} 1507| 1508| 1509|/*********************************************************************** 1510| 2-25. <<< [Text_Box::MoveLinks] リンクしている図形への影響を処理する >>> 1511|************************************************************************/ 1512|void Text_Box::MoveLinks( bool bShift ) 1513|{ 1514| if ( ListX_getN( &m_Links, CadPrim_Link ) > 0 ) { 1515| RECT rc; 1516| int x,y; 1517| CadPrim_Link* link; 1518| 1519| GetBox( &rc ); 1520| x = (rc.left + rc.right) / 2; 1521| y = (rc.top + rc.bottom) / 2; 1522| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 1523| if ( link->prim->GetHold() ) continue; 1524| link->x = x; link->y = y; 1525| link->prim->MoveByHandle( link->iHandle, x, y, bShift, false ); 1526| } 1527| } 1528|} 1529| 1530| 1531|/*********************************************************************** 1532| 2-26. <<< [Text_Box::AutoAdjustXY] 位置を自動調整する >>> 1533|************************************************************************/ 1534|void Text_Box::AutoAdjustXY( int* x, int* y ) 1535|{ 1536| CSVGCatApp* app = (CSVGCatApp*)AfxGetApp(); 1537| CadPrim_Link* link; 1538| int xx, yy; 1539| bool bb; 1540| int dx = INT_MAX, dy = INT_MAX; 1541| int dcy; 1542| RECT rc; 1543| enum { diff = 6 }; 1544| 1545| GetBox( &rc ); 1546| dcy = ( rc.top + rc.bottom ) / 2 - m_Y; 1547| *y += dcy; 1548| 1549| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 1550| bb = false; 1551| switch ( link->prim->GetTypeID() ) { 1552| 1553| /* リンクラインの反対側の頂点の座標を xx, yy に格納する */ 1554| case Line_Ex_TypeID: { 1555| Line_Ex* line = (Line_Ex*)link->prim; 1556| 1557| if ( link->iHandle == 1 ) { xx = line->m_Line.x2; yy = line->m_Line.y2; } 1558| else { xx = line->m_Line.x1; yy = line->m_Line.y1; } 1559| bb = true; 1560| break; 1561| } 1562| case Line_Corner_TypeID: { 1563| Line_Corner* line = (Line_Corner*)link->prim; 1564| 1565| if ( link->iHandle == 1 ) { xx = line->m_Line.x2; yy = line->m_Line.y2; } 1566| else { xx = line->m_Line.x1; yy = line->m_Line.y1; } 1567| bb = true; 1568| break; 1569| } 1570| } 1571| 1572| /* 最も差の小さい dx, dy を得る */ 1573| if ( bb ) { 1574| if ( abs( xx - *x ) < abs( dx ) ) dx = xx - *x; 1575| if ( abs( yy - *y ) < abs( dy ) ) dy = yy - *y; 1576| } 1577| } 1578| 1579| if ( dx < diff && dx > -diff ) *x += dx; 1580| if ( dy < diff && dy > -diff ) *y += dy; 1581| 1582| *y -= dcy; 1583|} 1584| 1585| 1586| 1587| 1588|/*********************************************************************** 1589| 2-27. <<< [Text_Box::SetHold] CadPrim::SetHold の実装部 >>> 1590|************************************************************************/ 1591|void Text_Box::SetHold( bool b ) 1592|{ 1593| m_bHold = b; 1594|} 1595| 1596|/*********************************************************************** 1597| 2-28. <<< [Text_Box::GetHold] CadPrim::GetHold の実装部 >>> 1598|************************************************************************/ 1599|bool Text_Box::GetHold() 1600|{ 1601| return m_bHold; 1602|} 1603| 1604|/*********************************************************************** 1605| 2-29. <<< [Text_Box::IsHoldable] CadPrim::IsHoldable の実装部 >>> 1606|************************************************************************/ 1607|bool Text_Box::IsHoldable() 1608|{ 1609| CadPrim_Link* link; 1610| 1611| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 1612| if ( link->prim != NULL && link->prim->GetHold() ) { 1613| switch ( link->prim->GetTypeID() ) { 1614| case Line_Ex_TypeID: { 1615| Line_Ex* line = (Line_Ex*)link->prim; 1616| if ( line->m_Controler[0] != NULL && line->m_Controler[1] != NULL ) 1617| return false; 1618| } 1619| case Line_Corner_TypeID: { 1620| Line_Corner* line = (Line_Corner*)link->prim; 1621| if ( line->m_Controler[0] != NULL && line->m_Controler[1] != NULL ) 1622| return false; 1623| } 1624| } 1625| } 1626| } 1627| return true; 1628|} 1629| 1630|/*********************************************************************** 1631| 2-30. <<< [Text_Box::SetSelected] CadPrim::SetSelected の実装部 >>> 1632|************************************************************************/ 1633|void Text_Box::SetSelected( bool b ) 1634|{ 1635| m_bSelected = b; 1636|} 1637| 1638|/*********************************************************************** 1639| 2-31. <<< [Text_Box::GetSelected] CadPrim::GetSelected の実装部 >>> 1640|************************************************************************/ 1641|bool Text_Box::GetSelected() 1642|{ 1643| return m_bSelected; 1644|} 1645| 1646| 1647|/*********************************************************************** 1648| 2-32. <<< [Text_Box::IsMultiSelect] CadPrim::IsMultiSelect の実装部 >>> 1649|************************************************************************/ 1650|bool Text_Box::IsMultiSelect( Rect* rect ) 1651|{ 1652| Rect com; 1653| RECT me; 1654| Rect me2; 1655| 1656| GetBox( &me ); 1657| Rect_init( &me2, me.left, me.top, 1658| me.right - me.left + 1, me.bottom - me.top + 1 ); 1659| Rect_toAnd( &com, &me2, rect ); 1660| return ( com.w > 0 && com.h > 0 ); 1661|} 1662| 1663| 1664|/*********************************************************************** 1665| 2-33. <<< [Text_Box::GetForAlign] CadPrim::GetForAlign の実装部 >>> 1666|************************************************************************/ 1667|int Text_Box::GetForAlign( int iPos ) 1668|{ 1669| RECT me; 1670| GetBox( &me ); 1671| 1672| switch ( iPos ) { 1673| case CadPrim_AlignLeft: return me.left; 1674| case CadPrim_AlignRight: return me.right; 1675| case CadPrim_AlignTop: return me.top; 1676| case CadPrim_AlignBottom: return me.bottom; 1677| case CadPrim_AlignVertical: return ( me.left + me.right ) / 2; 1678| case CadPrim_AlignHorizontal: return ( me.top + me.bottom ) / 2; 1679| default: error(); return 0; 1680| } 1681|} 1682| 1683|/*********************************************************************** 1684| 2-34. <<< [Text_Box::SetForAlign] CadPrim::SetForAlign の実装部 >>> 1685|************************************************************************/ 1686|void Text_Box::SetForAlign( int iPos, int value ) 1687|{ 1688| RECT me; 1689| GetBox( &me ); 1690| 1691| switch ( iPos ) { 1692| case CadPrim_AlignLeft: m_CenterX += value - me.left; break; 1693| case CadPrim_AlignRight: m_CenterX += value - me.right; break; 1694| case CadPrim_AlignTop: m_Y += value - me.top; break; 1695| case CadPrim_AlignBottom: m_Y += value - me.bottom; break; 1696| case CadPrim_AlignVertical: m_CenterX += value - ( me.left + me.right ) / 2; break; 1697| case CadPrim_AlignHorizontal: m_Y += value - ( me.top + me.bottom ) / 2; break; 1698| default: error(); 1699| } 1700| MoveLinks( true ); 1701|} 1702| 1703|/*********************************************************************** 1704| 2-35. <<< [Text_Box::GetForFitSize] CadPrim::GetForFitSize の実装部 >>> 1705|************************************************************************/ 1706|int Text_Box::GetForFitSize( int iAttr ) 1707|{ 1708| RECT me; 1709| GetBox( &me ); 1710| 1711| if ( iAttr == CadPrim_Horizontal ) return me.right - me.left + 1; 1712| else return me.bottom - me.top + 1; 1713|} 1714| 1715|/*********************************************************************** 1716| 2-36. <<< [Text_Box::SetForFitSize] CadPrim::SetForFitSize の実装部 >>> 1717|************************************************************************/ 1718|void Text_Box::SetForFitSize( int iAttr, int value ) 1719|{ 1720| RECT me; 1721| GetBox( &me ); 1722| 1723| if ( iAttr == CadPrim_Horizontal ) 1724| m_BoxMarginX += ( value - (me.right - me.left + 1) ) / 2; 1725| else 1726| m_BoxMarginY += ( value - (me.bottom - me.top + 1) ) / 2; 1727| 1728| MoveLinks( true ); 1729|} 1730| 1731| 1732|/*********************************************************************** 1733| 2-37. <<< [Text_Box::GetNProp] プロパティの要素数を返す >>> 1734|************************************************************************/ 1735|int Text_Box::GetNProp() 1736|{ 1737| #ifdef NDEBUG 1738| return 23; 1739| #else 1740| return 26; 1741| #endif 1742|} 1743| 1744| 1745|/*********************************************************************** 1746| 2-38. <<< [Text_Box::GetProp] プロパティの名前と値を取得する >>> 1747|************************************************************************/ 1748|int Text_Box::GetProp( int iProp, bool bJapanese, char* name, int name_size, 1749| char* value, int value_size, const char* path, void** option ) 1750|{ 1751| int r = CadPrim_ReadOnly; 1752| 1753| static ListX list; 1754| static StrX_ListElem strs[6]; 1755| static int range[2]; 1756| 1757| switch ( iProp ) { 1758| case 0: 1759| if ( bJapanese ) 1760| strncpy( name, "テキスト", name_size ); 1761| else 1762| strncpy( name, "Text", name_size ); 1763| strncpy( value, m_Text, value_size ); 1764| r = CadPrim_TextML; 1765| break; 1766| case 1: 1767| strncpy( name, "id", name_size ); 1768| strncpy( value, m_IdLabel, value_size ); 1769| *option = NULL; 1770| r = CadPrim_Text; 1771| break; 1772| case 2: 1773| strncpy( name, "URL/onclick", name_size ); 1774| #if 1 1775| if ( path[0] == '\0' ) strcpy( value, m_URL ); 1776| else StrX_cpyStepPath2( value, m_URL, value_size, path ); 1777| if ( bJapanese ) 1778| *option = (void*)"すべてのファイル (*.*)|*.*||"; 1779| else 1780| *option = (void*)"All Files (*.*)|*.*||"; 1781| r = CadPrim_Path; 1782| #else 1783| strncpy( value, m_URL, value_size ); 1784| r = CadPrim_Text; 1785| #endif 1786| break; 1787| case 3: 1788| strncpy( name, "target", name_size ); 1789| strncpy( value, m_Target, value_size ); 1790| *option = NULL; 1791| r = CadPrim_Text; 1792| break; 1793| case 4: 1794| ListX_init( &list ); 1795| if ( bJapanese ) { 1796| strncpy( name, "枠の形状", name_size ); 1797| ListX_addLast( &list, &strs[0] ); strs[0].p = " 枠なし"; 1798| ListX_addLast( &list, &strs[1] ); strs[1].p = "□ 矩形、長方形"; 1799| ListX_addLast( &list, &strs[2] ); strs[2].p = "ロ 丸矩形"; 1800| ListX_addLast( &list, &strs[3] ); strs[3].p = "○ 円、楕円"; 1801| ListX_addLast( &list, &strs[4] ); strs[4].p = "◇ ひし形"; 1802| ListX_addLast( &list, &strs[5] ); strs[5].p = "// 平行四辺形"; 1803| } 1804| else { 1805| strncpy( name, "Shape of Frame", name_size ); 1806| ListX_addLast( &list, &strs[0] ); strs[0].p = "No Frame"; 1807| ListX_addLast( &list, &strs[1] ); strs[1].p = "Rectangle"; 1808| ListX_addLast( &list, &strs[2] ); strs[2].p = "Round Rectangle"; 1809| ListX_addLast( &list, &strs[3] ); strs[3].p = "Circle, Ellipse"; 1810| ListX_addLast( &list, &strs[4] ); strs[4].p = "Diamond"; 1811| ListX_addLast( &list, &strs[5] ); strs[5].p = "Parallelogram"; 1812| } 1813| sprintf( value, "%d", m_BoxShape ); 1814| *option = &list; 1815| r = CadPrim_Select; 1816| break; 1817| case 5: 1818| if ( bJapanese ) 1819| strncpy( name, "x (横基準点)", name_size ); 1820| else 1821| strncpy( name, "x (Base Point)", name_size ); 1822| sprintf( value, "%d", m_CenterX ); 1823| range[0] = INT_MIN; range[1] = INT_MAX; 1824| *option = range; 1825| r = CadPrim_Int; 1826| break; 1827| case 6: 1828| if ( bJapanese ) 1829| strncpy( name, "y (縦基準点)", name_size ); 1830| else 1831| strncpy( name, "y (Base Point)", name_size ); 1832| sprintf( value, "%d", m_Y ); 1833| range[0] = INT_MIN; range[1] = INT_MAX; 1834| *option = range; 1835| r = CadPrim_Int; 1836| break; 1837| case 7: 1838| if ( bJapanese ) 1839| strncpy( name, "幅の誤差", name_size ); 1840| else 1841| strncpy( name, "Difference of width", name_size ); 1842| sprintf( value, "%d", m_DiffW ); 1843| range[0] = INT_MIN; range[1] = INT_MAX; 1844| *option = range; 1845| r = CadPrim_Int; 1846| break; 1847| case 8: 1848| if ( bJapanese ) 1849| strncpy( name, "行間", name_size ); 1850| else 1851| strncpy( name, "Between of Line", name_size ); 1852| sprintf( value, "%d", m_BetweenOfLine ); 1853| range[0] = 1; range[1] = INT_MAX; 1854| *option = range; 1855| r = CadPrim_Int; 1856| break; 1857| case 9: 1858| ListX_init( &list ); 1859| if ( bJapanese ) { 1860| strncpy( name, "基準点位置", name_size ); 1861| if ( m_bTategaki ) { 1862| ListX_addLast( &list, &strs[0] ); strs[0].p = "上端"; 1863| ListX_addLast( &list, &strs[1] ); strs[1].p = "中央"; 1864| ListX_addLast( &list, &strs[2] ); strs[2].p = "下端"; 1865| } 1866| else { 1867| ListX_addLast( &list, &strs[0] ); strs[0].p = "左端"; 1868| ListX_addLast( &list, &strs[1] ); strs[1].p = "中央"; 1869| ListX_addLast( &list, &strs[2] ); strs[2].p = "右端"; 1870| } 1871| } 1872| else { 1873| strncpy( name, "Base Position", name_size ); 1874| if ( m_bTategaki ) { 1875| ListX_addLast( &list, &strs[0] ); strs[0].p = "Top"; 1876| ListX_addLast( &list, &strs[1] ); strs[1].p = "Center"; 1877| ListX_addLast( &list, &strs[2] ); strs[2].p = "Bottom"; 1878| } 1879| else { 1880| ListX_addLast( &list, &strs[0] ); strs[0].p = "Left"; 1881| ListX_addLast( &list, &strs[1] ); strs[1].p = "Center"; 1882| ListX_addLast( &list, &strs[2] ); strs[2].p = "Right"; 1883| } 1884| } 1885| sprintf( value, "%d", m_BasePos ); 1886| *option = &list; 1887| r = CadPrim_Select; 1888| break; 1889| case 10: 1890| if ( bJapanese ) 1891| strncpy( name, "角度", name_size ); 1892| else 1893| strncpy( name, "Angle", name_size ); 1894| sprintf( value, "%d", m_RotateDegree ); 1895| range[0] = INT_MIN; range[1] = INT_MAX; 1896| *option = range; 1897| r = CadPrim_Int; 1898| break; 1899| case 11: 1900| if ( bJapanese ) 1901| strncpy( name, "テキストの色", name_size ); 1902| else 1903| strncpy( name, "Text Color", name_size ); 1904| StrX_getColorStr( value, m_Color ); 1905| r = CadPrim_Color; 1906| break; 1907| case 12: 1908| if ( bJapanese ) 1909| strncpy( name, "フォント", name_size ); 1910| else 1911| strncpy( name, "Font", name_size ); 1912| StrX_getFontStr( value, m_Font, m_Size*10, m_bBold, m_bItalic ); 1913| r = CadPrim_Font; 1914| break; 1915| case 13: 1916| if ( bJapanese ) 1917| strncpy( name, "サイズ", name_size ); 1918| else 1919| strncpy( name, "Size", name_size ); 1920| sprintf( value, "%d", m_Size ); 1921| range[0] = 1; range[1] = INT_MAX; 1922| *option = range; 1923| r = CadPrim_Int; 1924| break; 1925| case 14: 1926| if ( bJapanese ) 1927| strncpy( name, "太字", name_size ); 1928| else 1929| strncpy( name, "Bold", name_size ); 1930| sprintf( value, "%d", m_bBold ); 1931| r = CadPrim_Bool; 1932| break; 1933| case 15: 1934| if ( bJapanese ) 1935| strncpy( name, "斜体", name_size ); 1936| else 1937| strncpy( name, "Itaric", name_size ); 1938| sprintf( value, "%d", m_bItalic ); 1939| r = CadPrim_Bool; 1940| break; 1941| case 16: 1942| ListX_init( &list ); 1943| if ( bJapanese ) { 1944| strncpy( name, "方向", name_size ); 1945| ListX_addLast( &list, &strs[0] ); strs[0].p = "横書き"; 1946| ListX_addLast( &list, &strs[1] ); strs[1].p = "縦書き"; 1947| } 1948| else { 1949| strncpy( name, "Direction", name_size ); 1950| ListX_addLast( &list, &strs[0] ); strs[0].p = "Horizontal"; 1951| ListX_addLast( &list, &strs[1] ); strs[1].p = "Vertical"; 1952| } 1953| sprintf( value, "%d", m_bTategaki ); 1954| *option = &list; 1955| r = CadPrim_Select; 1956| break; 1957| case 17: 1958| if ( bJapanese ) 1959| strncpy( name, "横マージン", name_size ); 1960| else 1961| strncpy( name, "Horizontal Mergin", name_size ); 1962| sprintf( value, "%d", m_bTategaki ? m_BoxMarginY : m_BoxMarginX ); 1963| range[0] = 0; range[1] = INT_MAX; 1964| *option = range; 1965| r = CadPrim_Int; 1966| break; 1967| case 18: 1968| if ( bJapanese ) 1969| strncpy( name, "縦マージン", name_size ); 1970| else 1971| strncpy( name, "Vertical Mergin", name_size ); 1972| sprintf( value, "%d", m_bTategaki ? m_BoxMarginX : m_BoxMarginY ); 1973| range[0] = 0; range[1] = INT_MAX; 1974| *option = range; 1975| r = CadPrim_Int; 1976| break; 1977| case 19: 1978| if ( bJapanese ) 1979| strncpy( name, "塗りつぶし色", name_size ); 1980| else 1981| strncpy( name, "Fill Color", name_size ); 1982| StrX_getColorStr( value, m_FillColor ); 1983| r = CadPrim_Color; 1984| break; 1985| case 20: 1986| if ( bJapanese ) 1987| strncpy( name, "濃さ(非透過%)", name_size ); 1988| else 1989| strncpy( name, "Transparent %", name_size ); 1990| sprintf( value, "%d", m_FillNTrans ); 1991| range[0] = 0; range[1] = 100; 1992| *option = range; 1993| r = CadPrim_Int; 1994| break; 1995| case 21: 1996| if ( bJapanese ) 1997| strncpy( name, "枠の色", name_size ); 1998| else 1999| strncpy( name, "Frame Color", name_size ); 2000| StrX_getColorStr( value, m_BorderColor ); 2001| r = CadPrim_Color; 2002| break; 2003| case 22: 2004| if ( bJapanese ) 2005| strncpy( name, "枠の幅", name_size ); 2006| else 2007| strncpy( name, "Frame Width", name_size ); 2008| sprintf( value, "%d", m_BorderWidth ); 2009| range[0] = 0; range[1] = INT_MAX; 2010| *option = range; 2011| r = CadPrim_Int; 2012| break; 2013| #ifndef NDEBUG 2014| case 23: 2015| strncpy( name, "id", name_size ); 2016| sprintf( value, "%d", m_id ); 2017| break; 2018| case 24: 2019| strncpy( name, "m_Controler_id", name_size ); 2020| sprintf( value, "%d", m_Controler_id ); 2021| break; 2022| case 25: { 2023| CadPrim_Link* link = ListX_getFirst( &m_Links, CadPrim_Link ); 2024| strncpy( name, "m_Links(0)", name_size ); 2025| if ( link == NULL ) strcpy( value, "NULL" ); 2026| else sprintf( value, "%d", link->prim_id ); 2027| break; 2028| } 2029| #endif 2030| } 2031| 2032| return r; 2033|} 2034| 2035|/*********************************************************************** 2036| 2-39. <<< [Text_Box::SetProp] プロパティの値を設定する >>> 2037|************************************************************************/ 2038|void Text_Box::SetProp( int iProp, const char* value, const char* path ) 2039|{ 2040| char s[256]; 2041| int i; 2042| 2043| switch ( iProp ) { 2044| case 0: 2045| m_Text = value; 2046| break; 2047| case 1: 2048| m_IdLabel = value; 2049| break; 2050| case 2: 2051| m_URL = value; 2052| break; 2053| case 3: 2054| m_Target = value; 2055| break; 2056| case 4: 2057| ChangeShape( atoi( value ) ); 2058| break; 2059| case 5: 2060| m_CenterX = atoi( value ); 2061| break; 2062| case 6: 2063| m_Y = atoi( value ); 2064| break; 2065| case 7: 2066| m_DiffW = atoi( value ); 2067| break; 2068| case 8: 2069| m_BetweenOfLine = atoi( value ); 2070| break; 2071| case 9: 2072| ChangeAlign( atoi( value ) ); 2073| break; 2074| case 10: 2075| m_RotateDegree = atoi( value ); 2076| break; 2077| case 11: 2078| m_Color = StrX_getColorValue( value ); 2079| break; 2080| case 12: 2081| i = m_Size; 2082| StrX_getFontValue( value, s, &m_Size, &m_bBold, &m_bItalic ); 2083| m_Size /= 10; 2084| m_BetweenOfLine += m_Size - i; 2085| m_Font = s; 2086| break; 2087| case 13: 2088| i = m_Size; 2089| m_Size = atoi( value ); 2090| m_BetweenOfLine += m_Size - i; 2091| break; 2092| case 14: 2093| m_bBold = atoi( value ) != 0; 2094| break; 2095| case 15: 2096| m_bItalic = atoi( value ) != 0; 2097| break; 2098| case 16: 2099| m_bTategaki = atoi( value ) != 0; 2100| break; 2101| case 17: 2102| if ( m_bTategaki ) m_BoxMarginY = atoi( value ); 2103| else m_BoxMarginX = atoi( value ); 2104| break; 2105| case 18: 2106| if ( m_bTategaki ) m_BoxMarginX = atoi( value ); 2107| else m_BoxMarginY = atoi( value ); 2108| break; 2109| case 19: 2110| m_FillColor = StrX_getColorValue( value ); 2111| break; 2112| case 20: 2113| m_FillNTrans = atoi( value ); 2114| break; 2115| case 21: 2116| m_BorderColor = StrX_getColorValue( value ); 2117| break; 2118| case 22: { 2119| int w = atoi( value ); 2120| 2121| if ( w == 0 ) { 2122| int shape = m_BoxShape; 2123| 2124| ChangeShape( Text_Box_NoFrame ); // マージンを枠なし用に小さくする 2125| m_BoxShape = shape; 2126| } 2127| m_BorderWidth = w; 2128| break; 2129| } 2130| } 2131|} 2132| 2133| 2134| 2135| 2136|/*********************************************************************** 2137| 2-40. <<< [Text_Box::IsNeedUnicode] CadPrim::IsNeedUnicode の実装部 >>> 2138|************************************************************************/ 2139|bool Text_Box::IsNeedUnicode() 2140|{ 2141| return ( StrX_isExist2byte( m_Text ) || StrX_isExist2byte( m_URL ) )!= 0; 2142|} 2143| 2144| 2145|/*********************************************************************** 2146| 2-41. <<< [Text_Box::OnCreated] CadPrim::OnCreated の実装部 >>> 2147|************************************************************************/ 2148|void Text_Box::OnCreated() 2149|{ 2150|} 2151| 2152| 2153|/*********************************************************************** 2154| 2-42. <<< [Text_Box::GetBox] 枠の座標を取得する >>> 2155|【補足】 2156|・Draw 実行後に使えます。 2157|************************************************************************/ 2158|void Text_Box::GetBox( RECT* rc ) 2159|{ 2160| int n; 2161| 2162| if ( IsNotSetDrawParam() ) 2163| error2_0( SVGCat_Err_NotSetDrawParam, "" ); 2164| 2165| switch ( m_BasePos ) { 2166| 2167| case Text_Box_LeftAlign: 2168| rc->left = m_CenterX - m_BoxMarginX; 2169| rc->right = m_CenterX + m_W + m_DiffW + m_BoxMarginX; 2170| break; 2171| 2172| case Text_Box_CenterAlign: 2173| rc->left = m_CenterX - ( m_W + m_DiffW ) / 2 - m_BoxMarginX; 2174| rc->right = rc->left + m_W + m_DiffW + 2 * m_BoxMarginX; 2175| break; 2176| 2177| case Text_Box_RightAlign: 2178| rc->left = m_CenterX - m_W - m_DiffW - m_BoxMarginX; 2179| rc->right = m_CenterX + m_BoxMarginX; 2180| break; 2181| } 2182| 2183| n = StrX_getNLine( m_Text ); 2184| rc->top = m_Top - m_BoxMarginY; 2185| rc->bottom = m_Top + m_10H/10 + m_BoxMarginY + 1; 2186| 2187| 2188| if ( m_bTategaki ) { 2189| POINT pts[2]; 2190| TwoD_XY center, xy; 2191| int i; 2192| 2193| pts[0].x = rc->left; pts[0].y = rc->top; 2194| pts[1].x = rc->right; pts[1].y = rc->bottom; 2195| TwoD_XY_init( ¢er, m_CenterX - 1, m_Y ); 2196| for ( i = 0; i < 2; i++ ) { 2197| TwoD_XY_init( &xy, pts[i].x, pts[i].y ); 2198| TwoD_XY_rot( &xy, ¢er, 90 * (2 * 3.141592) / 360 ); 2199| pts[i].x = (long)(xy.x + 0.5); 2200| pts[i].y = (long)(xy.y + 0.5); 2201| } 2202| rc->left = pts[1].x; rc->right = pts[0].x; 2203| rc->top = pts[0].y - 1; rc->bottom = pts[1].y; 2204| 2205| i = ( m_10H/10 - (StrX_getNLine( m_Text ) - 1) * m_BetweenOfLine ) / 2 - m_10Descent/10; 2206| rc->left -= i; 2207| rc->right -= i; 2208| } 2209|} 2210| 2211| 2212|/*********************************************************************** 2213| 2-43. <<< [Text_Box::GetTXYByIndex] 位置番号から位置座標(カラム&行)を得る >>> 2214|【引数】 2215| ・int index; 位置番号(テキストの先頭=0、改行は+2) 2216| ・int* cx,cy; (出力)位置座標(カラム&行、先頭は 0,0) 2217| ・char* 返り値; 行頭(m_Textの内部) 2218|************************************************************************/ 2219|char* Text_Box::GetTXYByIndex( int index, int* cx, int* cy ) 2220|{ 2221| char* p; 2222| 2223| *cy = StrX_getILine( m_Text, (const char*)m_Text + index ) - 1; 2224| p = StrX_refTopOfLine( m_Text, *cy+1 ); 2225| *cx = (const char*)m_Text + index - p; 2226| 2227| return p; 2228|} 2229| 2230| 2231| 2232| 2233| 2234|/*********************************************************************** 2235| 2-44. <<< [Text_Box::GetGXYByIndex] 位置番号から位置座標を得る >>> 2236|【引数】 2237| ・int index; 位置番号(テキストの先頭=0、改行は+2) 2238| ・int* dx,dy; (出力)テキストのベースライン左端の座標(原点は m_CenterX, m_Y) 2239|【補足】 2240|・現在、左詰しか対応していません。 2241|************************************************************************/ 2242|void Text_Box::GetGXYByIndex( CDC* dc, int index, int* dx, int* dy ) 2243|{ 2244| CFont font; 2245| CFont font2; 2246| CFont* oldFont; 2247| LOGFONT logFont; 2248| CSize size; 2249| int cx, cy; 2250| char* p; 2251| char s[1024]; 2252| 2253| font.CreatePointFont( m_Size*100, (m_bTategaki ? CString('@')+m_Font : m_Font), dc ); 2254| font.GetLogFont( &logFont ); 2255| logFont.lfWidth = 0; 2256| logFont.lfHeight = m_Size * 100; 2257| logFont.lfWeight = m_bBold ? FW_BOLD : FW_NORMAL; 2258| logFont.lfItalic = m_bItalic; 2259| logFont.lfEscapement = - m_RotateDegree * 10 + (m_bTategaki ? 2700 :0); 2260| font2.CreatePointFontIndirect( &logFont, dc ); 2261| oldFont = dc->SelectObject( &font2 ); 2262| 2263| p = GetTXYByIndex( index, &cx, &cy ); 2264| 2265| StrX_cpy( s, p, cx < sizeof(s) ? cx+1 : sizeof(s) ); 2266| 2267| size = dc->GetOutputTextExtent( s ); 2268| *dx = size.cx / 10; 2269| if ( cy == 0 ) *dy = 0; else *dy = m_BetweenOfLine * cy; 2270| 2271| dc->SelectObject( oldFont ); 2272|} 2273| 2274| 2275| 2276| 2277| 2278|/*********************************************************************** 2279| 2-45. <<< [Text_Box::GetGXYByTXY] カラム&行から位置座標を得る >>> 2280|【引数】 2281| ・int* cx,cy; 位置座標(カラム&行、先頭は 0,0) 2282| ・int* dx,dy; (出力)テキストのベースライン左端の座標(原点は m_CenterX, m_Y) 2283|【補足】 2284|・現在、左詰しか対応していません。 2285|************************************************************************/ 2286|void Text_Box::GetGXYByTXY( CDC* dc, int cx, int cy, int* dx, int* dy ) 2287|{ 2288| CFont font; 2289| CFont font2; 2290| CFont* oldFont; 2291| LOGFONT logFont; 2292| CSize size; 2293| char* p; 2294| char s[1024]; 2295| 2296| font.CreatePointFont( m_Size*100, (m_bTategaki ? CString('@')+m_Font : m_Font), dc ); 2297| font.GetLogFont( &logFont ); 2298| logFont.lfWidth = 0; 2299| logFont.lfHeight = m_Size * 100; 2300| logFont.lfWeight = m_bBold ? FW_BOLD : FW_NORMAL; 2301| logFont.lfItalic = m_bItalic; 2302| logFont.lfEscapement = - m_RotateDegree * 10 + (m_bTategaki ? 2700 :0); 2303| font2.CreatePointFontIndirect( &logFont, dc ); 2304| oldFont = dc->SelectObject( &font2 ); 2305| 2306| p = StrX_refTopOfLine( m_Text, cy+1 ); 2307| 2308| StrX_cpy( s, p, cx < sizeof(s) ? cx+1 : sizeof(s) ); 2309| 2310| size = dc->GetOutputTextExtent( s ); 2311| *dx = size.cx / 10; 2312| if ( cy == 0 ) *dy = 0; else *dy = m_BetweenOfLine * cy; 2313| 2314| dc->SelectObject( oldFont ); 2315|} 2316| 2317| 2318|/*********************************************************************** 2319| 2-46. <<< [Text_Box::GetLinkToHandle] CadPrim::GetLinkToHandle の実装部 >>> 2320|************************************************************************/ 2321|CadPrim_Link* Text_Box::GetLinkToHandle( int iHandle ) 2322|{ 2323| ASSERT( iHandle >= 1 && iHandle <= GetNumOfLinkToHandle() ); 2324| return ListX_get( &m_Links, iHandle - 1, CadPrim_Link ); 2325|} 2326| 2327|int Text_Box::GetNumOfLinkToHandle() 2328|{ 2329| return ListX_getN( &m_Links, CadPrim_Link ); 2330|} 2331| 2332| 2333|/*********************************************************************** 2334| 2-47. <<< [Text_Box::GetLinkOnReadHandleNum] CadPrim::GetLinkOnReadHandleNum の実装部 >>> 2335|************************************************************************/ 2336|int Text_Box::GetLinkOnReadHandleNum( int x, int y, int diff ) 2337|{ 2338| RECT rc; 2339| int cx, cy; 2340| 2341| GetBox( &rc ); 2342| cx = (rc.left + rc.right) / 2; 2343| cy = (rc.top + rc.bottom) / 2; 2344| return ( cx-diff <= x && x <= cx+diff && cy-diff <= y && y <= cy+diff ); 2345|} 2346| 2347|/*********************************************************************** 2348| 2-48. <<< [Text_Box::GetLinkableHandleNum] CadPrim::GetLinkableHandleNum の実装部 >>> 2349|************************************************************************/ 2350|int Text_Box::GetLinkableHandleNum( int x, int y ) 2351|{ 2352| RECT rc; 2353| 2354| GetBox( &rc ); 2355| return ( rc.left <= x && x <= rc.right && rc.top <= y && y <= rc.bottom ); 2356|} 2357| 2358| 2359|/*********************************************************************** 2360| 2-49. <<< [Text_Box::LinkToHandle] CadPrim::LinkToHandle の実装部 >>> 2361|************************************************************************/ 2362|void Text_Box::LinkToHandle( int iHandleOfThis, CadPrim* prim, int iHandleOfPrim ) 2363|{ 2364| CadPrim_Link* link; 2365| RECT rc; 2366| 2367| #ifndef NDEBUG 2368| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 2369| if ( link->prim == prim && link->iHandle != iHandleOfPrim ) 2370| error(); /* 重複リンク */ 2371| } 2372| #endif 2373| 2374| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 2375| if ( link->prim == prim && link->iHandle == iHandleOfPrim ) 2376| return; 2377| } 2378| 2379| GetBox( &rc ); 2380| 2381| link = ListX_addLastMalloc( &m_Links, CadPrim_Link ); 2382| link->iHandle = iHandleOfPrim; 2383| link->prim = prim; 2384| link->prim_id = prim->GetID(); 2385| link->x = (rc.left + rc.right) / 2; 2386| link->y = (rc.top + rc.bottom) / 2; 2387| 2388| prim->LinkToControler( iHandleOfPrim, this ); 2389| prim->MoveByHandle( iHandleOfPrim, link->x, link->y, false, false ); 2390|} 2391| 2392| 2393|/*********************************************************************** 2394| 2-50. <<< [Text_Box::UnlinkToHandle] CadPrim::UnlinkToHandle の実装部 >>> 2395|************************************************************************/ 2396|void Text_Box::UnlinkToHandle( CadPrim* prim, int iHandleOfPrim, bool mutual ) 2397|{ 2398| CadPrim_Link* link; 2399| 2400| 2401| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 2402| if ( link->prim == prim && link->iHandle == iHandleOfPrim ) { 2403| if ( mutual ) 2404| prim->UnlinkToControler( link->iHandle, this ); 2405| ListX_removeDelete( &m_Links, link, NULL ); 2406| break; 2407| } 2408| } 2409|} 2410| 2411| 2412|/*********************************************************************** 2413| 2-51. <<< [Text_Box::UnlinkAll] CadPrim::UnlinkAll の実装部 >>> 2414|************************************************************************/ 2415|void Text_Box::UnlinkAll() 2416|{ 2417| CadPrim_Link* link; 2418| CadPrim_Link* link2; 2419| 2420| for ( link = (CadPrim_Link*)m_Links.first; link != NULL; ) { 2421| link2 = ListX_Elem_getNextT( link, CadPrim_Link ); 2422| UnlinkToHandle( link->prim, link->iHandle ); 2423| link = link2; 2424| } 2425| if ( m_Controler != NULL ) 2426| m_Controler->UnlinkToHandle( this, 1 ); 2427|} 2428| 2429| 2430|/*********************************************************************** 2431| 2-52. <<< [Text_Box::LinkToControler] CadPrim::LinkToControler の実装部 >>> 2432|************************************************************************/ 2433|void Text_Box::LinkToControler( int iHandle, CadPrim* ctrl ) 2434|{ 2435| m_Controler = ctrl; 2436| m_Controler_id = ctrl->GetID(); 2437|} 2438| 2439| 2440|/*********************************************************************** 2441| 2-53. <<< [Text_Box::UnlinkToControler] CadPrim::UnlinkToControler の実装部 >>> 2442|************************************************************************/ 2443|void Text_Box::UnlinkToControler( int iHandle, CadPrim* ctrl ) 2444|{ 2445| m_Controler = NULL; 2446|} 2447| 2448| 2449|/*********************************************************************** 2450| 2-54. <<< [Text_Box::AdjustLinks] CadPrim::AdjustLinks の実装部 >>> 2451|【補足】 2452|・ファイルを開きなおしたときにリンク状態を維持するために、Text_Box::MoveLinks 2453| を別に呼ぶ必要があります。 2454|************************************************************************/ 2455|void Text_Box::AdjustLinks( ListX* prims ) 2456|{ 2457| CadPrim_Link* link; 2458| 2459| m_Controler = Undo_Uty_getPrimPtr( prims, m_Controler_id ); 2460| 2461| for ( link = ListX_getFirst( &m_Links, CadPrim_Link ); link != NULL; ) { 2462| link->prim = Undo_Uty_getPrimPtr( prims, link->prim_id ); 2463| 2464| if ( link->prim == NULL ) { 2465| CadPrim_Link* nextLink = ListX_Elem_getNextT( link, CadPrim_Link ); 2466| ListX_removeFree( &m_Links, link ); 2467| link = nextLink; 2468| } 2469| else { 2470| link = ListX_Elem_getNextT( link, CadPrim_Link ); 2471| } 2472| } 2473| 2474| for ( ListX_forEach( &m_Links, &link, CadPrim_Link ) ) { 2475| link->prim->AdjustLinks( prims ); 2476| } 2477|} 2478| 2479| 2480|/*********************************************************************** 2481| 2-55. <<< [Text_Box::GetArrowPoint] 枠と、リンクしているラインとの交点を取得する >>> 2482|【引数】 2483| ・int i; リンクしているラインが this とリンクしている頂点の番号 (1 or 2) 2484| ・int x1, y1; ラインの先端の座標(Text_Box の中) 2485| ・int x2, y2; ラインの尾の座標(Text_Box の外) 2486| ・int* x, y; (出力)交点の座標 2487|************************************************************************/ 2488|void Text_Box::GetArrowPoint( int i, int x1, int y1, int x2, int y2, int* x, int* y ) 2489|{ 2490| RECT rc; 2491| 2492| GetBox( &rc ); 2493| 2494| /* ボックスの上辺について */ 2495| if ( y1 > y2 ) { 2496| *x = ( x1 * (rc.top - y2) + x2 * (y1 - rc.top) ) / (y1 - y2); 2497| *y = rc.top; 2498| if ( *x >= rc.left && *x <= rc.right ) return; 2499| } 2500| 2501| /* ボックスの左辺について */ 2502| if ( x1 > x2 ) { 2503| *x = rc.left; 2504| *y = ( y1 * (rc.left - x2) + y2 * (x1 - rc.left) ) / (x1 - x2); 2505| if ( *y >= rc.top && *y <= rc.bottom ) { 2506| if ( m_BoxShape == Text_Box_Parallelogram ) 2507| *x -= (*y - (rc.top + rc.bottom) / 2 ) / 2; 2508| return; 2509| } 2510| } 2511| 2512| /* ボックスの右辺について */ 2513| if ( x1 < x2 ) { 2514| *x = rc.right; 2515| *y = ( y1 * (x2 - rc.right) + y2 * (rc.right - x1) ) / (x2 - x1); 2516| if ( *y >= rc.top && *y <= rc.bottom ) { 2517| if ( m_BoxShape == Text_Box_Parallelogram ) 2518| *x -= (*y - (rc.top + rc.bottom) / 2 ) / 2; 2519| return; 2520| } 2521| } 2522| 2523| /* ボックスの下辺について */ 2524| if ( y1 < y2 ) { 2525| *x = ( x1 * (y2 - rc.bottom) + x2 * (rc.bottom - y1) ) / (y2 - y1); 2526| *y = rc.bottom; 2527| if ( *x >= rc.left && *x <= rc.right ) return; 2528| } 2529| 2530| /* ボックスに交わらないとき */ 2531| if ( i == 1 ) 2532| { *x = x1; *y = y1; } 2533| else 2534| { *x = x2; *y = y2; } 2535|} 2536| 2537|/*********************************************************************** 2538| 2-56. <<< [Text_Box::GetClickedPos] クリックした位置のテキスト位置を返す >>> 2539|【引数】 2540| ・int x, y; クリック位置(クライアント座標) 2541| ・int 返り値; バイト位置 2542|************************************************************************/ 2543|int Text_Box::GetClickedPos( int x, int y, CadPrim_DrawParam* p ) 2544|{ 2545| int iLine; 2546| char* pTop; 2547| 2548| if ( m_bTategaki ) { 2549| return 0; 2550| } 2551| else { 2552| if ( y <= m_Y + m_10Descent / 10 ) return 0; 2553| iLine = ( y - m_Top ) / m_BetweenOfLine + 1; 2554| pTop = StrX_refTopOfLine( m_Text, iLine ); 2555| if ( pTop == NULL ) return strlen( m_Text ); 2556| else return (const char*)pTop - (const char*)m_Text; 2557| } 2558|} 2559| 2560| 2561|/*********************************************************************** 2562| 2-57. <<< [Text_Box::ChangeAlign] 表示位置を変えずに align を変える >>> 2563|************************************************************************/ 2564|void Text_Box::ChangeAlign( int align ) 2565|{ 2566| int diff = align - m_BasePos; 2567| 2568| if ( m_bTategaki ) { 2569| if ( diff == 1 || diff == -1 ) { 2570| if ( align + m_BasePos == 1 ) 2571| m_Y += (m_W + 1) / 2 * diff; 2572| else 2573| m_Y += m_W / 2 * diff; 2574| } 2575| else 2576| m_Y += m_W * ( diff / 2 ); 2577| } 2578| else { 2579| if ( diff == 1 || diff == -1 ) { 2580| if ( align + m_BasePos == 1 ) 2581| m_CenterX += (m_W + 1) / 2 * diff; 2582| else 2583| m_CenterX += m_W / 2 * diff; 2584| } 2585| else 2586| m_CenterX += m_W * ( diff / 2 ); 2587| } 2588| 2589| m_BasePos = align; 2590|} 2591| 2592| 2593| 2594|/*********************************************************************** 2595| 2-58. <<< [Text_Box::ChangeShape] マージンを変わったように見えない程度に枠の形状を変える >>> 2596|************************************************************************/ 2597|void Text_Box::ChangeShape( int shape ) 2598|{ 2599| const int mx[] = { -6, 0, 0, 2, 20, 2 }; 2600| const int my[] = { -4, 0, 0, 2, 2, 0 }; 2601| 2602| if ( m_BorderWidth == 0 ) { 2603| m_BoxMarginX += mx[shape] - mx[0]; 2604| m_BoxMarginY += my[shape] - my[0]; 2605| } 2606| else { 2607| m_BoxMarginX += mx[shape] - mx[m_BoxShape]; 2608| m_BoxMarginY += my[shape] - my[m_BoxShape]; 2609| } 2610| if ( m_BoxMarginX < 0 ) m_BoxMarginX = 0; 2611| if ( m_BoxMarginY < 0 ) m_BoxMarginY = 0; 2612| m_BoxShape = shape; 2613| if ( m_BorderWidth == 0 ) m_BorderWidth = 1; 2614|} 2615| 2616| 2617|/*********************************************************************** 2618| 2-59. <<< [Text_Box::IsNotSetDrawParam] 描画後に決まる属性がまだ決まっていないかどうか >>> 2619|************************************************************************/ 2620|bool Text_Box::IsNotSetDrawParam() 2621|{ 2622| return m_10H1 == -1; 2623|} 2624| 2625| 2626|#endif 2627| 2628|/*-------------------------------------------------------------------------*/ 2629|/* 3. <<<< ◆ (Text_Editor) インライン・テキストエディタ >>>> */ 2630|/*-------------------------------------------------------------------------*/ 2631| 2632|Text_Editor::Text_Editor() 2633|{ 2634| m_bCaretDisp = true; 2635|} 2636| 2637| 2638|/*********************************************************************** 2639| 3-1. <<< [Text_Editor::Attach] 編集対象のテキストに合わせる >>> 2640|************************************************************************/ 2641|void Text_Editor::Attach( Text_Box* text ) 2642|{ 2643| m_Text = text->m_Text; 2644| m_CenterX = text->m_CenterX + 1; 2645| m_Y = text->m_Y + 1; 2646| m_DiffW = text->m_DiffW; 2647| m_W = text->m_W; 2648| m_10H = text->m_10H; 2649| m_10H1 = text->m_10H1; 2650| m_10Descent = text->m_10Descent; 2651| m_Top = text->m_Top; 2652| m_BetweenOfLine = text->m_BetweenOfLine; 2653| m_RotateDegree = text->m_RotateDegree; 2654| m_Color = text->m_Color; 2655| m_Font = text->m_Font; 2656| m_Size = text->m_Size; 2657| m_bBold = text->m_bBold; 2658| m_bItalic = text->m_bItalic; 2659| m_BasePos = text->m_BasePos; 2660| m_bTategaki = text->m_bTategaki; 2661| 2662| m_BoxShape = text->m_BoxShape; 2663| m_BoxMarginX = text->m_BoxMarginX; 2664| m_BoxMarginY = text->m_BoxMarginY; 2665| m_BorderWidth = text->m_BorderWidth; 2666| m_BorderColor = text->m_BorderColor; 2667| m_FillColor = text->m_FillColor; 2668| m_FillNTrans = text->m_FillNTrans; 2669|} 2670| 2671|/*********************************************************************** 2672| 3-2. <<< [Text_Editor::Draw] CadPrim::Draw の実装部 >>> 2673|************************************************************************/ 2674|void Text_Editor::Draw( CDC* dc, CadPrim_DrawParam* p ) 2675|{ 2676| /* テキストを描く */ 2677| { 2678| int i = m_BorderWidth; m_BorderWidth = 0; 2679| Text_Box::Draw( dc, p ); 2680| m_BorderWidth = i; 2681| } 2682| 2683| 2684| /* 編集中を示す外枠を描く */ 2685| { 2686| CPen whitePen( PS_SOLID, 1, RGB(0x80,0x80,0x80) ); 2687| CPen blackPen( PS_SOLID, 1, RGB(0x20,0x20,0x20) ); 2688| CPen* oldPen; 2689| RECT box; 2690| 2691| GetBox( &box ); 2692| 2693| 2694| /* いちばん外の枠を描く */ 2695| dc->MoveTo( box.left, box.bottom - 2 ); 2696| 2697| oldPen = dc->SelectObject( &blackPen ); 2698| dc->LineTo( box.left, box.top ); 2699| dc->LineTo( box.right - 2, box.top ); 2700| 2701| dc->SelectObject( &whitePen ); 2702| dc->LineTo( box.right - 2, box.bottom - 2 ); 2703| dc->LineTo( box.left, box.bottom - 2 ); 2704| 2705| 2706| /* 1つ内の枠を描く */ 2707| dc->MoveTo( box.left + 1, box.bottom - 3 ); 2708| 2709| oldPen = dc->SelectObject( &blackPen ); 2710| dc->LineTo( box.left + 1, box.top + 1 ); 2711| dc->LineTo( box.right - 3, box.top + 1 ); 2712| 2713| dc->SelectObject( &whitePen ); 2714| dc->LineTo( box.right - 3, box.bottom - 3 ); 2715| dc->LineTo( box.left + 1, box.bottom - 3 ); 2716| 2717| 2718| /* 1つ外の枠を描く */ 2719| dc->MoveTo( box.left - 1, box.bottom - 1 ); 2720| 2721| oldPen = dc->SelectObject( &blackPen ); 2722| dc->LineTo( box.left - 1, box.top - 1 ); 2723| dc->LineTo( box.right - 1, box.top - 1 ); 2724| 2725| dc->SelectObject( &whitePen ); 2726| dc->LineTo( box.right - 1, box.bottom - 1 ); 2727| dc->LineTo( box.left - 1, box.bottom - 1 ); 2728| 2729| m_bCaretDisp = true; 2730| DrawCaretXor( dc, p ); 2731| 2732| dc->SelectObject( oldPen ); 2733| } 2734|} 2735| 2736| 2737| 2738|/*********************************************************************** 2739| 3-3. <<< [Text_Editor::DrawCaretXor] キャレット(テキスト入力位置)を反転描画する >>> 2740|************************************************************************/ 2741|void Text_Editor::DrawCaretXor( CDC* dc, CadPrim_DrawParam* p ) 2742|{ 2743| int gx1, gy1, gx2, gy2; 2744| 2745| GetGXYByIndex( dc, m_CaretStart, &gx1, &gy1 ); 2746| GetGXYByIndex( dc, m_CaretEnd, &gx2, &gy2 ); 2747| 2748| /* キャレットを反転する */ 2749| { 2750| CPen whitePen( PS_SOLID, 1, RGB(0xFF,0xFF,0xFF) ); 2751| int height; 2752| int x, y; 2753| int y_over; 2754| 2755| x = m_CenterX + gx2; 2756| height = m_Y - m_Top + m_10Descent / 10 + 2; 2757| y_over = m_Top - 1 + gy2 + height; 2758| 2759| for ( y = m_Top - 1 + gy2; y < y_over; y ++ ) { 2760| dc->SetPixel( x, y, dc->GetPixel( x, y ) ^ 0x00C0C0C0 ); 2761| dc->SetPixel( x+1, y, dc->GetPixel( x+1, y ) ^ 0x00C0C0C0 ); 2762| } 2763| } 2764|} 2765| 2766| 2767| 2768|/*********************************************************************** 2769| 3-4. <<< [Text_Editor::OnBlinkTiming] 点滅するタイミングで行う処理 >>> 2770|【補足】 2771|・CreateThread で、次のスレッド関数を実行します。 2772| blinkThread() 2773| { 2774| for (;;) { 2775| Sleep( GetCaretBlinkTime() ); // 点滅する時間だけ待つ API 2776| editor->OnBlinkTiming(); // 本関数 2777| } 2778| } 2779|************************************************************************/ 2780|void Text_Editor::OnBlinkTiming( CDC* dc, CadPrim_DrawParam* p ) 2781|{ 2782| m_bCaretDisp = ! m_bCaretDisp; 2783| 2784| if ( m_bCaretDisp ) { 2785| static int i = 0; 2786| static int j = 0; 2787| 2788| i++; if ( i == m_Text.GetLength()+1 ) { i = 0; 2789| j++; if ( j == m_Text.GetLength()+1 ) j = 0; 2790| } 2791| 2792| m_CaretEnd = i; 2793| m_CaretStart = j; 2794| Draw( dc, p ); 2795| } 2796| 2797| DrawCaretXor( dc, p ); 2798|} 2799| 2800| 2801| 2802|