◀ANSI版開発トップへ
  • 1412 ExtTextOutの制限?
    • 1413 Re: ExtTextOutの制限?
      • 1414 Re2: ExtTextOutの制限?
        • 1415 Re3: ExtTextOutの制限?
          • 1416 Re4: ExtTextOutの制限?
          • 1417 Re3: ExtTextOutの制限?
            • 1418 Re4: ExtTextOutの制限?
              • 1419 Re5: ExtTextOutの制限?
                • 1420 Re6: ExtTextOutの制限?
                  • 1434 Re6: ExtTextOutの制限?
                  • 1438 Re7: ExtTextOutの制限?
  • [1412] ExtTextOutの制限? やざき 2002年01月30日 13:31

    ある一定の文字数を超えると、行頭からダブって表示される問題ですが、どうもExtTextOutの制限に引っかかっている様子でした。
    ウィンドウの左右にあふれている文字のクリッピングをExtTextOutに一任していたものを、動作に支障が出ない程度に自前でクリッピングするようにしました。
    そしたら、不思議なことに行頭からダブって表示される問題は発生しなくなったように見えます。

    ExtTextOutについて詳しくは、
    http://www.microsoft.com/japan/developer/library/jpgdipf/_win32_exttextout.htm


    で、結局DispTextを次のように変更しました。

    int CEditView::DispText( HDC hdc, int x, int y, const unsigned char* pData, int nLength )
    {
    if( 0 >= nLength ){
    return 0;
    }
    RECT rcClip;
    int nLineHeight = m_nCharHeight + m_pcEditDoc->GetDocumentAttribute().m_nL
    ineSpace;
    int nCharWidth = m_nCharWidth + m_pcEditDoc->GetDocumentAttribute().m_nC
    olmSpace;
    UINT fuOptions = ETO_CLIPPED | ETO_OPAQUE;
    rcClip.left = x;
    rcClip.right = rcClip.left + ( nCharWidth ) * nLength;
    rcClip.top = y;
    if( rcClip.left < m_nViewAlignLeft ){
    rcClip.left = m_nViewAlignLeft;
    }
    if( rcClip.left < rcClip.right
    && rcClip.left < m_nViewAlignLeft + m_nViewCx && rcClip.right > m_nViewAlignLeft
    && rcClip.top >= m_nViewAlignTop
    ){
    rcClip.bottom = y + nLineHeight;
    /* if( rcClip.right - rcClip.left > 3000 ){
    rcClip.right = rcClip.left + 3000;
    }
    ::ExtTextOut( hdc, x, y, fuOptions, &rcClip, (const char *)pData, nLength, m_pnDx );
    */
    if( rcClip.right - rcClip.left > m_nViewCx ){
    rcClip.right = rcClip.left + m_nViewCx;
    }
    int nBefore = 0; // ウィンドウの左にあふれた文字数
    int nAfter = 0; // ウィンドウの右にあふれた文字数
    if ( x < 0 ){
    nBefore = ( 0 - x ) / nCharWidth;
    }
    if ( rcClip.right < x + nCharWidth * nLength ){
    nAfter = (x + nCharWidth * nLength - rcClip.right) / nCharWidth;
    }

    ::ExtTextOut( hdc, x + nBefore * nCharWidth, y, fuOptions, &rcClip, (const char *)&pData[nBefore], nLength - nBefore - nAfter, m_pnDx );

    }
    return nLength;

    }

    • [1413] Re: ExtTextOutの制限? げんた 2002年01月30日 14:48

      >自前でクリッピングするようにしました。
      2バイト文字の考慮が無いので,漢字コードの2バイト目から始まったときに表示がおかしくなる可能性があるような気がしますが大丈夫?
      • [1414] Re2: ExtTextOutの制限? やざき 2002年01月30日 15:31

        ▼ げんたさん
        > >自前でクリッピングするようにしました。
        > 2バイト文字の考慮が無いので,漢字コードの2バイト目から始まったときに表示がおかしくなる可能性があるような気がしますが大丈夫?

        うむ。行番号のところで隠してるから大丈夫だと思ってたけどだめみたい(苦笑)
        • [1415] Re3: ExtTextOutの制限? やざき 2002年01月30日 15:44

          ▼ やざきさん
          > うむ。行番号のところで隠してるから大丈夫だと思ってたけど、行番号を隠してたらだめみたい(苦笑)

          化けるところを、一文字前(ウィンドウの外側)にしたらどうかしらん?
          以下のように。

          if ( x < 0 ){
          nBefore = ( 0 - x ) / nCharWidth;
          nBefore = (nBefore > 0) ? nBefore - 1 : nBefore;// -1してごまかす。
          }
          • [1416] Re4: ExtTextOutの制限? やざき 2002年01月30日 15:46

            ▼ やざきさん
            > ▼ やざきさん
            > > うむ。行番号のところで隠してるから大丈夫だと思ってたけど、行番号を隠してたらだめみたい(苦笑)
            >
            > 化けるところを、一文字前(ウィンドウの外側)にしたらどうかしらん?
            > 以下のように。
            >
            > if ( x < 0 ){
            > nBefore = ( 0 - x ) / nCharWidth;
            > nBefore = (nBefore > 0) ? nBefore - 1 : nBefore;// -1してごまかす。
            > }

            いや、x<0ならいつもnBefore > 0だから、

            if ( x < 0 ){
            nBefore = ( 0 - x ) / nCharWidth - 1;
            }

            でいいのか。
          • [1417] Re3: ExtTextOutの制限? げんた 2002年01月30日 16:47

            >化けるところを、一文字前(ウィンドウの外側)にしたらどうかしらん?
            ぶったぎられた漢字の2バイト目が運悪く漢字の1バイト目としても認識されるもので,その次の1バイト目が2バイト目としても認識されるものだと立て続けに後ろの方まで化けるのでは?
            • [1418] Re4: ExtTextOutの制限? やざき 2002年01月30日 17:31

              ▼ げんたさん
              > >化けるところを、一文字前(ウィンドウの外側)にしたらどうかしらん?
              > ぶったぎられた漢字の2バイト目が運悪く漢字の1バイト目としても認識されるもので,その次の1バイト目が2バイト目としても認識されるものだと立て続けに後ろの方まで化けるのでは?

              そしたらこうか?
              int nBefore = 0; // ウィンドウの左にあふれた文字数
              int nAfter = 0; // ウィンドウの右にあふれた文字数
              if ( x < 0 ){
              int nCharChars;

              while (nBefore < ( 0 - x ) / nCharWidth - 1){
              nCharChars = CMemory::MemCharNext( (const char *)pData, nLength, (const char *)&pData[nBefore] ) - (const char *)&pData[nBefore];
              nBefore += nCharChars;
              }
              }
              if ( rcClip.right < x + nCharWidth * nLength ){
              nAfter = (x + nCharWidth * nLength - rcClip.right) / nCharWidth - 1; // -1してごまかす(うしろはいいよね?)
              }
              • [1419] Re5: ExtTextOutの制限? げんた 2002年01月30日 18:11

                >そしたらこうか?
                > while (nBefore < ( 0 - x ) / nCharWidth - 1){
                > nCharChars = CMemory::MemCharNext( (const char *)pData, nLength, (const char *)&pData[nBefore] ) - (const char *)&pData[nBefore];
                > nBefore += nCharChars;
                > }
                >}
                処理としてはOKですが,毎回サーチしないといけないので処理速度が気になる.
                とは言っても,ExtTextOutで先頭から指示するときは同じことがAPI内で行われているわけだから一緒か.
                • [1420] Re6: ExtTextOutの制限? やざき 2002年01月30日 18:39

                  ▼ げんたさん
                  > 処理としてはOKですが,毎回サーチしないといけないので処理速度が気になる.
                  > とは言っても,ExtTextOutで先頭から指示するときは同じことがAPI内で行われているわけだから一緒か.

                  okでましたね(^-^)
                  ほんとはDispTextを呼び出す側でせっかくスキャンしているのだから、きちんとクリッピングすれば、もっと無駄が省けると思いますが。。。
                  • [1434] Re6: ExtTextOutの制限? みく 2002年01月31日 19:36


                    TEditorの方の掲示板でタイムリーな話題が...

                    http://mcgi2.nifty.ne.jp/cgi-bin/thread.cgi?user_id=VYR01647&disp_no=2087&log_no=485&msg_per_page=50&def=10
                  • [1438] Re7: ExtTextOutの制限? げんた 2002年02月01日 00:50

                    ▼ やざきさん
                    > okでましたね(^-^)
                    バグ対応と言うことで今回のリリースに取り込みます。