Пример #1
0
void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const
{
    CPDF_Font* pFont = m_TextState.GetFont();
    FX_BOOL bVertWriting = FALSE;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    if (pCIDFont) {
        bVertWriting = pCIDFont->IsVertWriting();
    }
    FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
    int count = 0;
    for (int i = 0; i < m_nChars; ++i) {
        FX_DWORD charcode = m_nChars == 1 ?
                            (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
        if (charcode == (FX_DWORD) - 1) {
            continue;
        }
        if (count != index) {
            ++count;
            continue;
        }
        FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0;
        FX_RECT char_rect;
        pFont->GetCharBBox(charcode, char_rect, 0);
        if (!bVertWriting) {
            rect.left = curpos + char_rect.left * fontsize;
            rect.right = curpos + char_rect.right * fontsize;
            rect.top = char_rect.top * fontsize;
            rect.bottom = char_rect.bottom * fontsize;
        } else {
            FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
            short vx, vy;
            pCIDFont->GetVertOrigin(CID, vx, vy);
            char_rect.left -= vx;
            char_rect.right -= vx;
            char_rect.top -= vy;
            char_rect.bottom -= vy;
            rect.left = char_rect.left * fontsize;
            rect.right = char_rect.right * fontsize;
            rect.top = curpos + char_rect.top * fontsize;
            rect.bottom = curpos + char_rect.bottom * fontsize;
        }
        return;
    }
}
Пример #2
0
void CTextPage::ProcessObject(CPDF_PageObject* pObject)
{
    if (pObject->m_Type != PDFPAGE_TEXT) {
        return;
    }
    CPDF_TextObject* pText = (CPDF_TextObject*)pObject;
    CPDF_Font* pFont = pText->m_TextState.GetFont();
    int count = pText->CountItems();
    FX_FLOAT* pPosArray = FX_Alloc(FX_FLOAT, count * 2);
    if (pPosArray) {
        pText->CalcCharPos(pPosArray);
    }
    FX_FLOAT fontsize_h = pText->m_TextState.GetFontSizeH();
    FX_FLOAT fontsize_v = pText->m_TextState.GetFontSizeV();
    FX_DWORD space_charcode = pFont->CharCodeFromUnicode(' ');
    FX_FLOAT spacew = 0;
    if (space_charcode != -1) {
        spacew = fontsize_h * pFont->GetCharWidthF(space_charcode) / 1000;
    }
    if (spacew == 0) {
        spacew = fontsize_h / 4;
    }
    if (pText->m_TextState.GetBaselineAngle() != 0) {
        int cc = 0;
        CFX_AffineMatrix matrix;
        pText->GetTextMatrix(&matrix);
        for (int i = 0; i < pText->m_nChars; i ++) {
            FX_DWORD charcode = pText->m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)pText->m_pCharCodes : pText->m_pCharCodes[i];
            if (charcode == (FX_DWORD) - 1) {
                continue;
            }
            FX_RECT char_box;
            pFont->GetCharBBox(charcode, char_box);
            FX_FLOAT char_left = pPosArray ? pPosArray[cc * 2] : char_box.left * pText->m_TextState.GetFontSize() / 1000;
            FX_FLOAT char_right = pPosArray ? pPosArray[cc * 2 + 1] : char_box.right * pText->m_TextState.GetFontSize() / 1000;
            FX_FLOAT char_top = char_box.top * pText->m_TextState.GetFontSize() / 1000;
            FX_FLOAT char_bottom = char_box.bottom * pText->m_TextState.GetFontSize() / 1000;
            cc ++;
            FX_FLOAT char_origx, char_origy;
            matrix.Transform(char_left, 0, char_origx, char_origy);
            matrix.TransformRect(char_left, char_right, char_top, char_bottom);
            CFX_ByteString str;
            pFont->AppendChar(str, charcode);
            InsertTextBox(NULL, char_origy, char_left, char_right, char_top,
                          char_bottom, spacew, fontsize_v, str, pFont);
        }
        if (pPosArray) {
            FX_Free(pPosArray);
        }
        return;
    }
    FX_FLOAT ratio_h = fontsize_h / pText->m_TextState.GetFontSize();
    for (int ii = 0; ii < count * 2; ii ++) {
        pPosArray[ii] *= ratio_h;
    }
    FX_FLOAT baseline = pText->m_PosY;
    CTextBaseLine* pBaseLine = NULL;
    FX_FLOAT topy = pText->m_Top;
    FX_FLOAT bottomy = pText->m_Bottom;
    FX_FLOAT leftx = pText->m_Left;
    int cc = 0;
    CFX_ByteString segment;
    int space_count = 0;
    FX_FLOAT last_left = 0, last_right = 0, segment_left = 0, segment_right = 0;
    for (int i = 0; i < pText->m_nChars; i ++) {
        FX_DWORD charcode = pText->m_nChars == 1 ? (FX_DWORD)(FX_UINTPTR)pText->m_pCharCodes : pText->m_pCharCodes[i];
        if (charcode == (FX_DWORD) - 1) {
            continue;
        }
        FX_FLOAT char_left = pPosArray[cc * 2];
        FX_FLOAT char_right = pPosArray[cc * 2 + 1];
        cc ++;
        if (char_left < last_left || (char_left - last_right) > spacew / 2) {
            pBaseLine = InsertTextBox(pBaseLine, baseline, leftx + segment_left, leftx + segment_right,
                                      topy, bottomy, spacew, fontsize_v, segment, pFont);
            segment_left = char_left;
            segment = "";
        }
        if (space_count > 1) {
            pBaseLine = InsertTextBox(pBaseLine, baseline, leftx + segment_left, leftx + segment_right,
                                      topy, bottomy, spacew, fontsize_v, segment, pFont);
            segment = "";
        } else if (space_count == 1) {
            pFont->AppendChar(segment, ' ');
        }
        if (segment.GetLength() == 0) {
            segment_left = char_left;
        }
        segment_right = char_right;
        pFont->AppendChar(segment, charcode);
        space_count = 0;
        last_left = char_left;
        last_right = char_right;
    }
    if (segment.GetLength())
        pBaseLine = InsertTextBox(pBaseLine, baseline, leftx + segment_left, leftx + segment_right,
                                  topy, bottomy, spacew, fontsize_v, segment, pFont);
    FX_Free(pPosArray);
}
Пример #3
0
void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX,
                                       FX_FLOAT* pTextAdvanceY,
                                       FX_FLOAT horz_scale,
                                       int level)
{
    FX_FLOAT curpos = 0;
    FX_FLOAT min_x = 10000 * 1.0f;
    FX_FLOAT max_x = -10000 * 1.0f;
    FX_FLOAT min_y = 10000 * 1.0f;
    FX_FLOAT max_y = -10000 * 1.0f;
    CPDF_Font* pFont = m_TextState.GetFont();
    FX_BOOL bVertWriting = FALSE;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    if (pCIDFont) {
        bVertWriting = pCIDFont->IsVertWriting();
    }
    FX_FLOAT fontsize = m_TextState.GetFontSize();
    for (int i = 0; i < m_nChars; ++i) {
        FX_DWORD charcode = m_nChars == 1 ?
                            (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
        if (charcode == (FX_DWORD) - 1) {
            curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000;
            continue;
        }
        if (i) {
            m_pCharPos[i - 1] = curpos;
        }
        FX_RECT char_rect;
        pFont->GetCharBBox(charcode, char_rect, level);
        FX_FLOAT charwidth;
        if (!bVertWriting) {
            if (min_y > char_rect.top) {
                min_y = (FX_FLOAT)char_rect.top;
            }
            if (max_y < char_rect.top) {
                max_y = (FX_FLOAT)char_rect.top;
            }
            if (min_y > char_rect.bottom) {
                min_y = (FX_FLOAT)char_rect.bottom;
            }
            if (max_y < char_rect.bottom) {
                max_y = (FX_FLOAT)char_rect.bottom;
            }
            FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000;
            FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000;
            if (min_x > char_left) {
                min_x = char_left;
            }
            if (max_x < char_left) {
                max_x = char_left;
            }
            if (min_x > char_right) {
                min_x = char_right;
            }
            if (max_x < char_right) {
                max_x = char_right;
            }
            charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000;
        } else {
            FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
            short vx;
            short vy;
            pCIDFont->GetVertOrigin(CID, vx, vy);
            char_rect.left -= vx;
            char_rect.right -= vx;
            char_rect.top -= vy;
            char_rect.bottom -= vy;
            if (min_x > char_rect.left) {
                min_x = (FX_FLOAT)char_rect.left;
            }
            if (max_x < char_rect.left) {
                max_x = (FX_FLOAT)char_rect.left;
            }
            if (min_x > char_rect.right) {
                min_x = (FX_FLOAT)char_rect.right;
            }
            if (max_x < char_rect.right) {
                max_x = (FX_FLOAT)char_rect.right;
            }
            FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000;
            FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000;
            if (min_y > char_top) {
                min_y = char_top;
            }
            if (max_y < char_top) {
                max_y = char_top;
            }
            if (min_y > char_bottom) {
                min_y = char_bottom;
            }
            if (max_y < char_bottom) {
                max_y = char_bottom;
            }
            charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
        }
        curpos += charwidth;
        if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) {
            curpos += m_TextState.GetObject()->m_WordSpace;
        }
        curpos += m_TextState.GetObject()->m_CharSpace;
    }
    if (bVertWriting) {
        if (pTextAdvanceX) {
            *pTextAdvanceX = 0;
        }
        if (pTextAdvanceY) {
            *pTextAdvanceY = curpos;
        }
        min_x = min_x * fontsize / 1000;
        max_x = max_x * fontsize / 1000;
    } else {
        if (pTextAdvanceX) {
            *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale);
        }
        if (pTextAdvanceY) {
            *pTextAdvanceY = 0;
        }
        min_y = min_y * fontsize / 1000;
        max_y = max_y * fontsize / 1000;
    }
    CFX_AffineMatrix matrix;
    GetTextMatrix(&matrix);
    m_Left = min_x;
    m_Right = max_x;
    m_Bottom = min_y;
    m_Top = max_y;
    matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
    int textmode = m_TextState.GetObject()->m_TextMode;
    if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) {
        FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2;
        m_Left -= half_width;
        m_Right += half_width;
        m_Top += half_width;
        m_Bottom -= half_width;
    }
}