FX_STRSIZE CFX_WideString::Replace(const FX_WCHAR* lpszOld, const FX_WCHAR* lpszNew)
{
    if (GetLength() < 1) {
        return 0;
    }
    if (lpszOld == NULL) {
        return 0;
    }
    FX_STRSIZE nSourceLen = FXSYS_wcslen(lpszOld);
    if (nSourceLen == 0) {
        return 0;
    }
    FX_STRSIZE nReplacementLen = lpszNew ? FXSYS_wcslen(lpszNew) : 0;
    FX_STRSIZE nCount = 0;
    FX_WCHAR* lpszStart = m_pData->m_String;
    FX_WCHAR* lpszEnd = m_pData->m_String + m_pData->m_nDataLength;
    FX_WCHAR* lpszTarget;
    {
        while ((lpszTarget = (FX_WCHAR*)FXSYS_wcsstr(lpszStart, lpszOld)) != NULL && lpszStart < lpszEnd) {
            nCount++;
            lpszStart = lpszTarget + nSourceLen;
        }
    }
    if (nCount > 0) {
        CopyBeforeWrite();
        FX_STRSIZE nOldLength = m_pData->m_nDataLength;
        FX_STRSIZE nNewLength =  nOldLength + (nReplacementLen - nSourceLen) * nCount;
        if (m_pData->m_nAllocLength < nNewLength || m_pData->m_nRefs > 1) {
            StringData* pOldData = m_pData;
            const FX_WCHAR* pstr = m_pData->m_String;
            m_pData = StringData::Create(nNewLength);
            if (!m_pData) {
                return 0;
            }
            FXSYS_memcpy(m_pData->m_String, pstr, pOldData->m_nDataLength * sizeof(FX_WCHAR));
            pOldData->Release();
        }
        lpszStart = m_pData->m_String;
        lpszEnd = m_pData->m_String + FX_MAX(m_pData->m_nDataLength, nNewLength);
        {
            while ((lpszTarget = (FX_WCHAR*)FXSYS_wcsstr(lpszStart, lpszOld)) != NULL && lpszStart < lpszEnd) {
                FX_STRSIZE nBalance = nOldLength - (FX_STRSIZE)(lpszTarget - m_pData->m_String + nSourceLen);
                FXSYS_memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen, nBalance * sizeof(FX_WCHAR));
                FXSYS_memcpy(lpszTarget, lpszNew, nReplacementLen * sizeof(FX_WCHAR));
                lpszStart = lpszTarget + nReplacementLen;
                lpszStart[nBalance] = 0;
                nOldLength += (nReplacementLen - nSourceLen);
            }
        }
        ASSERT(m_pData->m_String[nNewLength] == 0);
        m_pData->m_nDataLength = nNewLength;
    }
    return nCount;
}
Exemple #2
0
FX_BOOL CFPF_SkiaFont::GetGlyphBBox(FX_INT32 iGlyphIndex, FX_RECT &rtBBox)
{
    if (!m_Face) {
        return FALSE;
    }
    if (FXFT_Is_Face_Tricky(m_Face)) {
        if (FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72)) {
            return FALSE;
        }
        if (FXFT_Load_Glyph(m_Face, iGlyphIndex, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
            FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
            return FALSE;
        }
        FXFT_Glyph glyph;
        if (FXFT_Get_Glyph(m_Face->glyph, &glyph)) {
            FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
            return FALSE;
        }
        FXFT_BBox cbox;
        FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
        FX_INT32 x_ppem = m_Face->size->metrics.x_ppem;
        FX_INT32 y_ppem = m_Face->size->metrics.y_ppem;
        rtBBox.left = FPF_EM_ADJUST(x_ppem, cbox.xMin);
        rtBBox.right = FPF_EM_ADJUST(x_ppem, cbox.xMax);
        rtBBox.top = FPF_EM_ADJUST(y_ppem, cbox.yMax);
        rtBBox.bottom = FPF_EM_ADJUST(y_ppem, cbox.yMin);
        rtBBox.top = FX_MIN(rtBBox.top, GetAscent());
        rtBBox.bottom = FX_MAX(rtBBox.bottom, GetDescent());
        FXFT_Done_Glyph(glyph);
        return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
    }
    if (FXFT_Load_Glyph(m_Face, iGlyphIndex, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
        return FALSE;
    }
    rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriBearingX(m_Face));
    rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriBearingY(m_Face));
    rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face));
    rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face));
    return TRUE;
}