/*! ユニコードの使用不使用とか考慮しつつ埋め空白を作る @param[in] dTgtDot 作成するドット数 @return LPTSTR 作成したスペースの文字列・開放は呼んだ方で面倒見る */ LPTSTR DocPaddingSpaceMake( INT dTgtDot ) { LPTSTR ptReplc = NULL; INT dZenSp, dHanSp, dUniSp; // 幅0だと作れない if( 0 >= dTgtDot ) return NULL; if( gbUniPad ) { ptReplc = DocPaddingSpace( dTgtDot, &dZenSp, &dHanSp ); // 作成不可だったり半角多すぎたら、ユニコード使って作り直し if( !(ptReplc) || (dZenSp < dHanSp) ) // (dZenSp + 1) { FREE(ptReplc); ptReplc = DocPaddingSpaceUni( dTgtDot, &dZenSp, &dHanSp, &dUniSp ); } } else // ユニコード空白使わないなら { ptReplc = DocPaddingSpaceWithGap( dTgtDot, &dZenSp, &dHanSp ); } return ptReplc; }
/*! 指定されたドット幅を、ピリオドも使って綺麗に確保する・19幅までなら調整できる・これはこれで必要 @param[in] dTgtDot 作成するドット数 @param[out] pdZen 使用した全角スペースの個数入れる・NULLでもOK @param[out] pdHan 使用した半角スペースの個数入れる・NULLでもOK @param[out] pdPrd 使用したピリオドの個数入れる・NULLでもOK @param[in] bFull 固定テーブルつかって強引にあわせる? @return LPTSTR 作成したスペースの文字列・開放は呼んだ方で面倒見る・作成不可ならNULL */ LPTSTR DocPaddingSpaceWithPeriod( INT dTgtDot, PINT pdZen, PINT pdHan, PINT pdPrd, BOOLEAN bFull ) { INT dZenSp, dHanSp, dPrdSp, m, dPre; LPTSTR ptSpace = NULL, ptPlus = NULL; UINT cchSize, cchPlus; dPre = dTgtDot; dPrdSp = 0; do{ dZenSp = 0; dHanSp = 0; ptSpace = DocPaddingSpace( dTgtDot, &dZenSp, &dHanSp ); // 作成不可だった場合 半角多すぎても不可 if( !(ptSpace) || (dZenSp < dHanSp) ) // (dZenSp + 1) { FREE(ptSpace); if( gbUniPad ) // 上手くいかないようなら、ユニコード使ってやり直す { ptSpace = DocPaddingSpaceUni( dTgtDot, &dZenSp, &dHanSp, NULL ); break; } else { dPrdSp++; dTgtDot -= 3; // ピリオドは3ドット } } else // 問題無い文字列ならおk { break; } }while( dTgtDot >= 19 ); // これ以上は不可? if( !(ptSpace) && bFull ) // まだ制作できてなく、固定テーブル使うなら { dPrdSp = 0; dTgtDot = dPre; StringCchLength( gaatPaddingSpDot[dTgtDot], STRSAFE_MAX_CCH, &cchSize ); cchSize += 1; ptSpace = (LPTSTR)malloc( cchSize * sizeof(TCHAR) ); ZeroMemory( ptSpace, cchSize * sizeof(TCHAR) ); StringCchCopy( ptSpace, cchSize, gaatPaddingSpDot[dTgtDot] ); } if( ptSpace ) { StringCchLength( ptSpace, STRSAFE_MAX_CCH, &cchSize ); // ピリオド入れてサイズ調整 cchPlus = cchSize + dPrdSp + 1; ptPlus = (LPTSTR)malloc( cchPlus * sizeof(TCHAR) ); ZeroMemory( ptPlus, cchPlus * sizeof(TCHAR) ); StringCchCopy( ptPlus, cchPlus, ptSpace ); FREE(ptSpace); // スペースおしまい // 複数ピリオドあったら前後につけるようにしたい for( m = 0; dPrdSp > m; m++ ){ StringCchCat( ptPlus , cchPlus, TEXT(".") ); } } if( pdZen ) *pdZen = dZenSp; if( pdHan ) *pdHan = dHanSp; if( pdPrd ) *pdPrd = dPrdSp; return ptPlus; }
/*! 現在のドット位置を含んでいる空白エリアを1ドットずつずらす @param[in] vk 方向・右か左か @param[in] pXdot 今のドット位置を受けて戻す @param[in] dLine 今の行数 @param[in] dFirst アンドゥグループ・非0なら最初の一発 0続き @return UINT 非0ズレ値 0失敗 */ UINT DocSpaceDifference( UINT vk, PINT pXdot, INT dLine, UINT dFirst ) { INT dTgtDot, dNowDot; INT dBgnDot, dEndDot; INT dBgnCnt, dRngCnt; UINT_PTR cchSize; BOOLEAN bIsSpace; LPTSTR ptSpace;//, ptOldSp; INT dZenSp, dHanSp, dUniSp; INT iDots, iBytes; wstring wsBuffer; LETR_ITR vcLtrBgn, vcLtrEnd, vcItr; LINE_ITR itLine; itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin(); std::advance( itLine, dLine ); dNowDot = *pXdot; if( 0 == dNowDot ) // 0の場合は強引に移動 { dNowDot = itLine->vcLine.at( 0 ).rdWidth; } dTgtDot = DocLineStateCheckWithDot( dNowDot, dLine, &dBgnDot, &dEndDot, &dBgnCnt, &dRngCnt, &bIsSpace ); if( !(bIsSpace) ) return 0; // 非スペースエリアは意味が無い if( VK_RIGHT == vk ) dTgtDot++; // 右なら増やすってこと else if( VK_LEFT == vk ) dTgtDot--; else return 0; // 関係ないのはアウツ // 当てはめるアレを計算する ptSpace = DocPaddingSpace( dTgtDot, &dZenSp, &dHanSp ); if( gbUniPad ) { // 作成不可だったり半角多すぎたら、ユニコード使って作り直し if( !(ptSpace) || (dZenSp < dHanSp) ) // (dZenSp + 1) { FREE(ptSpace); ptSpace = DocPaddingSpaceUni( dTgtDot, &dZenSp, &dHanSp, &dUniSp ); } } if( !(ptSpace) ) return 0; // 作成不可だった場合 StringCchLength( ptSpace, STRSAFE_MAX_CCH, &cchSize ); vcLtrBgn = itLine->vcLine.begin( ); vcLtrBgn += dBgnCnt; // 該当位置まで移動して vcLtrEnd = vcLtrBgn; vcLtrEnd += dRngCnt; // そのエリアの終端も確認 iDots = 0; iBytes = 0; wsBuffer.clear(); for( vcItr = vcLtrBgn; vcLtrEnd != vcItr; vcItr++ ) { wsBuffer += vcItr->cchMozi; iDots += vcItr->rdWidth; iBytes += vcItr->mzByte; } // 該当部分を一旦削除・アンドゥリドゥするなら内容を記録する必要がある itLine->vcLine.erase( vcLtrBgn, vcLtrEnd ); itLine->iByteSz -= iBytes; if( 0 > itLine->iByteSz ){ itLine->iByteSz = 0; } itLine->iDotCnt -= iDots; if( 0 > itLine->iDotCnt ){ itLine->iDotCnt = 0; } // DocLineParamGet( yLine, NULL, NULL ); // 行内容の再計算 //あとの函数内で呼ばれまくってる // Space文字列を追加 dNowDot = dBgnDot; DocStringAdd( &dNowDot, &dLine, ptSpace, cchSize ); *pXdot = dNowDot; // cchSize = wsBuffer.size( ) + 1; // ptOldSp = (LPTSTR)malloc( cchSize * sizeof(TCHAR) ); // StringCchCopy( ptOldSp, cchSize, wsBuffer.c_str( ) ); SqnAppendString( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_DELETE, wsBuffer.c_str( ), dBgnDot, dLine, dFirst ); SqnAppendString( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_INSERT, ptSpace, dBgnDot, dLine, FALSE ); // 弐回目なので確定でよろし // FREE( ptOldSp ); FREE( ptSpace ); return dTgtDot; }
/*! 編集の選択範囲からいただく @param[in] hWnd ウインドウハンドル @param[in] bSqSel 矩形であるかどうか */ UINT DraughtItemAddFromSelect( HWND hWnd, UINT bSqSel ) { LPTSTR ptString = NULL; UINT cchSize, cbSize; LPPOINT pstPos = NULL; UINT_PTR i, j, iTexts; LONG dMin = 0; INT insDot, yLine, iLines = 0, dOffset; LPTSTR ptSpace = NULL; LPSTR pcArts; wstring wsString; // 内部処理なのでUnicode固定 cbSize = DocSelectTextGetAlloc( D_UNI | bSqSel, (LPVOID *)(&ptString), (bSqSel & D_SQUARE) ? &pstPos : NULL ); StringCchLength( ptString, STRSAFE_MAX_CCH, &cchSize ); if( 0 >= cchSize ) return 0; // 文字列ないならなにもしない // オフセット設定が有る場合、その分を埋める空白が必要 if( pstPos ) // 最小オフセット値を探して、そこを左端にする { dMin = pstPos[0].x; yLine = 0; for( i = 0; cchSize > i; i++ ) { if( CC_CR == ptString[i] && CC_LF == ptString[i+1] ) // 改行であったら { // オフセット最小をさがす if( dMin > pstPos[yLine].x ){ dMin = pstPos[yLine].x; } i++; // 0x0D,0x0Aだから、壱文字飛ばすのがポイント yLine++; // 改行したからFocusは次の行へ } } // この時点で、yLineは行数になってる iLines = yLine; // 壱行目の空白を作って閃光入力しておく insDot = 0; dOffset = pstPos[0].x - dMin; ptSpace = DocPaddingSpaceUni( dOffset, NULL, NULL, NULL ); // 前方空白は無視されるのでユニコード使って問題無い StringCchLength( ptSpace, STRSAFE_MAX_CCH, &iTexts ); for( j = 0; iTexts > j; j++ ){ wsString += ptSpace[j]; } FREE(ptSpace); } yLine = 0; insDot = 0; for( i = 0; cchSize > i; i++ ) { if( CC_CR == ptString[i] && CC_LF == ptString[i+1] ) // 改行であったら { wsString += wstring( TEXT("\r\n") ); i++; // 0x0D,0x0Aだから、壱文字飛ばすのがポイント yLine++; // 改行したからFocusは次の行へ // オフセット分の空白を作る if( pstPos && (iLines > yLine) ) { dOffset = pstPos[yLine].x - dMin; ptSpace = DocPaddingSpaceUni( dOffset, NULL, NULL, NULL ); // 前方空白は無視されるのでユニコード使って問題無い StringCchLength( ptSpace, STRSAFE_MAX_CCH, &iTexts ); for( j = 0; iTexts > j; j++ ){ wsString += ptSpace[j]; } FREE(ptSpace); } } else if( CC_TAB == ptString[i] ){ /* タブは挿入しない */ } else{ wsString += ptString[i]; } } FREE(ptString); FREE(pstPos); pcArts = SjisEncodeAlloc( wsString.c_str() ); DraughtItemAdding( hWnd, pcArts ); FREE(pcArts); return yLine; }