// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../../include/fxge/fx_ge.h"
#include "../../../include/fpdfapi/fpdf_render.h"
#include "../../../include/fpdfapi/fpdf_pageobj.h"
#include "../fpdf_page/pageint.h"
#include "render_int.h"
extern FX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix);
CPDF_Type3Cache::~CPDF_Type3Cache()
{
    FX_POSITION pos = m_SizeMap.GetStartPosition();
    CFX_ByteString Key;
    CPDF_Type3Glyphs* pSizeCache = NULL;
    while(pos) {
        pSizeCache = (CPDF_Type3Glyphs*)m_SizeMap.GetNextValue(pos);
        delete pSizeCache;
    }
    m_SizeMap.RemoveAll();
}
CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY)
{
    _CPDF_UniqueKeyGen keygen;
    keygen.Generate(4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000),
                    FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000));
    CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
    CPDF_Type3Glyphs* pSizeCache = NULL;
    if(!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
        pSizeCache = new CPDF_Type3Glyphs;
        m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
    }
    CFX_GlyphBitmap* pGlyphBitmap;
    if(pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)charcode, (void*&)pGlyphBitmap)) {
        return pGlyphBitmap;
    }
    pGlyphBitmap = RenderGlyph(pSizeCache, charcode, pMatrix, retinaScaleX, retinaScaleY);
    pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)charcode, pGlyphBitmap);
    return pGlyphBitmap;
}
CPDF_Type3Glyphs::~CPDF_Type3Glyphs()
{
    FX_POSITION pos = m_GlyphMap.GetStartPosition();
    void* Key;
    CFX_GlyphBitmap* pGlyphBitmap;
    while(pos) {
        m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap);
        delete pGlyphBitmap;
    }
}
static int _AdjustBlue(FX_FLOAT pos, int& count, int blues[])
{
    FX_FLOAT min_distance = 1000000.0f * 1.0f;
    int closest_pos = -1;
    for (int i = 0; i < count; i ++) {
        FX_FLOAT distance = (FX_FLOAT)FXSYS_fabs(pos - (FX_FLOAT)blues[i]);
        if (distance < 1.0f * 80.0f / 100.0f && distance < min_distance) {
            min_distance = distance;
            closest_pos = i;
        }
    }
    if (closest_pos >= 0) {
        return blues[closest_pos];
    }
    int new_pos = FXSYS_round(pos);
    if (count == TYPE3_MAX_BLUES) {
        return new_pos;
    }
    blues[count++] = new_pos;
    return new_pos;
}
void CPDF_Type3Glyphs::AdjustBlue(FX_FLOAT top, FX_FLOAT bottom, int& top_line, int& bottom_line)
{
    top_line = _AdjustBlue(top, m_TopBlueCount, m_TopBlue);
    bottom_line = _AdjustBlue(bottom, m_BottomBlueCount, m_BottomBlue);
}
static FX_BOOL _IsScanLine1bpp(uint8_t* pBuf, int width)
{
    int size = width / 8;
    for (int i = 0; i < size; i ++)
        if (pBuf[i]) {
            return TRUE;
        }
    if (width % 8)
        if (pBuf[width / 8] & (0xff << (8 - width % 8))) {
            return TRUE;
        }
    return FALSE;
}
static FX_BOOL _IsScanLine8bpp(uint8_t* pBuf, int width)
{
    for (int i = 0; i < width; i ++)
        if (pBuf[i] > 0x40) {
            return TRUE;
        }
    return FALSE;
}
static int _DetectFirstLastScan(const CFX_DIBitmap* pBitmap, FX_BOOL bFirst)
{
    int height = pBitmap->GetHeight(), pitch = pBitmap->GetPitch(), width = pBitmap->GetWidth();
    int bpp = pBitmap->GetBPP();
    if (bpp > 8) {
        width *= bpp / 8;
    }
    uint8_t* pBuf = pBitmap->GetBuffer();
    int line = bFirst ? 0 : height - 1;
    int line_step = bFirst ? 1 : -1;
    int line_end = bFirst ? height : -1;
    while (line != line_end) {
        if (bpp == 1) {
            if (_IsScanLine1bpp(pBuf + line * pitch, width)) {
                return line;
            }
        } else {
            if (_IsScanLine8bpp(pBuf + line * pitch, width)) {
                return line;
            }
        }
        line += line_step;
    }
    return -1;
}
CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY)
{
    CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode);
    if (pChar == NULL || pChar->m_pBitmap == NULL) {
        return NULL;
    }
    CFX_DIBitmap* pBitmap = pChar->m_pBitmap;
    CFX_AffineMatrix image_matrix, text_matrix;
    image_matrix = pChar->m_ImageMatrix;
    text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0);
    image_matrix.Concat(text_matrix);
    CFX_DIBitmap* pResBitmap = NULL;
    int left, top;
    if (FXSYS_fabs(image_matrix.b) < FXSYS_fabs(image_matrix.a) / 100 && FXSYS_fabs(image_matrix.c) < FXSYS_fabs(image_matrix.d) / 100) {
        int top_line, bottom_line;
        top_line = _DetectFirstLastScan(pBitmap, TRUE);
        bottom_line = _DetectFirstLastScan(pBitmap, FALSE);
        if (top_line == 0 && bottom_line == pBitmap->GetHeight() - 1) {
            FX_FLOAT top_y = image_matrix.d + image_matrix.f;
            FX_FLOAT bottom_y = image_matrix.f;
            FX_BOOL bFlipped = top_y > bottom_y;
            if (bFlipped) {
                FX_FLOAT temp = top_y;
                top_y = bottom_y;
                bottom_y = temp;
            }
            pSize->AdjustBlue(top_y, bottom_y, top_line, bottom_line);
            pResBitmap = pBitmap->StretchTo((int)(FXSYS_round(image_matrix.a) * retinaScaleX), (int)((bFlipped ? top_line - bottom_line : bottom_line - top_line) * retinaScaleY));
            top = top_line;
            if (image_matrix.a < 0) {
                image_matrix.Scale(retinaScaleX, retinaScaleY);
                left = FXSYS_round(image_matrix.e + image_matrix.a);
            } else {
                left = FXSYS_round(image_matrix.e);
            }
        } else {
        }
    }
    if (pResBitmap == NULL) {
        image_matrix.Scale(retinaScaleX, retinaScaleY);
        pResBitmap = pBitmap->TransformTo(&image_matrix, left, top);
    }
    if (pResBitmap == NULL) {
        return NULL;
    }
    CFX_GlyphBitmap* pGlyph = new CFX_GlyphBitmap;
    pGlyph->m_Left = left;
    pGlyph->m_Top = -top;
    pGlyph->m_Bitmap.TakeOver(pResBitmap);
    delete pResBitmap;
    return pGlyph;
}
void _CPDF_UniqueKeyGen::Generate(int count, ...)
{
    va_list argList;
    va_start(argList, count);
    for (int i = 0; i < count; i ++) {
        int p = va_arg(argList, int);
        ((FX_DWORD*)m_Key)[i] = p;
    }
    va_end(argList);
    m_KeyLen = count * sizeof(FX_DWORD);
}
FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, CFX_PathData* pClippingPath)
{
    if(textobj->m_nChars == 0) {
        return TRUE;
    }
    int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode;
    if (text_render_mode == 3) {
        return TRUE;
    }
    CPDF_Font* pFont = textobj->m_TextState.GetFont();
    if (pFont->GetFontType() == PDFFONT_TYPE3) {
        return ProcessType3Text(textobj, pObj2Device);
    }
    FX_BOOL bFill = FALSE, bStroke = FALSE, bClip = FALSE;
    if (pClippingPath) {
        bClip = TRUE;
    } else {
        switch (text_render_mode) {
            case 0:
            case 4:
                bFill = TRUE;
                break;
            case 1:
            case 5:
                if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
                    bFill = TRUE;
                } else {
                    bStroke = TRUE;
                }
                break;
            case 2:
            case 6:
                if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
                    bFill = TRUE;
                } else {
                    bFill = bStroke = TRUE;
                }
                break;
            case 3:
            case 7:
                return TRUE;
            default:
                bFill = TRUE;
        }
    }
    FX_ARGB stroke_argb = 0, fill_argb = 0;
    FX_BOOL bPattern = FALSE;
    if (bStroke) {
        if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) {
            bPattern = TRUE;
        } else {
            stroke_argb = GetStrokeArgb(textobj);
        }
    }
    if (bFill) {
        if (textobj->m_ColorState.GetFillColor()->IsPattern()) {
            bPattern = TRUE;
        } else {
            fill_argb = GetFillArgb(textobj);
        }
    }
    CFX_AffineMatrix text_matrix;
    textobj->GetTextMatrix(&text_matrix);
    if(IsAvailableMatrix(text_matrix) == FALSE) {
        return TRUE;
    }
    FX_FLOAT font_size = textobj->m_TextState.GetFontSize();
    if (bPattern) {
        DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, &text_matrix, bFill, bStroke);
        return TRUE;
    }
    if (bClip || bStroke) {
        const CFX_AffineMatrix* pDeviceMatrix = pObj2Device;
        CFX_AffineMatrix device_matrix;
        if (bStroke) {
            const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM;
            if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) {
                CFX_AffineMatrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0);
                text_matrix.ConcatInverse(ctm);
                device_matrix.Copy(ctm);
                device_matrix.Concat(*pObj2Device);
                pDeviceMatrix = &device_matrix;
            }
        }
        int flag = 0;
        if (bStroke && bFill) {
            flag |= FX_FILL_STROKE;
            flag |= FX_STROKE_TEXT_MODE;
        }
        const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)textobj)->m_GeneralState;
        if (pGeneralData && pGeneralData->m_StrokeAdjust) {
            flag |= FX_STROKE_ADJUST;
        }
        if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) {
            flag |= FXFILL_NOPATHSMOOTH;
        }
        return CPDF_TextRenderer::DrawTextPath(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size,
                                               &text_matrix, pDeviceMatrix, textobj->m_GraphState, fill_argb, stroke_argb, pClippingPath, flag);
    }
    text_matrix.Concat(*pObj2Device);
    return CPDF_TextRenderer::DrawNormalText(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size,
            &text_matrix, fill_argb, &m_Options);
}
CPDF_Type3Cache* CPDF_RenderStatus::GetCachedType3(CPDF_Type3Font* pFont)
{
    if (pFont->m_pDocument == NULL) {
        return NULL;
    }
    pFont->m_pDocument->GetPageData()->GetFont(pFont->GetFontDict(), FALSE);
    return pFont->m_pDocument->GetRenderData()->GetCachedType3(pFont);
}
static void ReleaseCachedType3(CPDF_Type3Font* pFont)
{
    if (pFont->m_pDocument == NULL) {
        return;
    }
    pFont->m_pDocument->GetRenderData()->ReleaseCachedType3(pFont);
    pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict());
}
FX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext)
{
    if (m_pBitmap != NULL || m_pForm == NULL) {
        return TRUE;
    }
    if (m_pForm->CountObjects() == 1 && !m_bColored) {
        CPDF_PageObject *pPageObj = m_pForm->GetObjectAt(m_pForm->GetFirstObjectPosition());
        if (pPageObj->m_Type == PDFPAGE_IMAGE) {
            CPDF_ImageObject* pImage = (CPDF_ImageObject*)pPageObj;
            m_ImageMatrix = pImage->m_Matrix;
            const CFX_DIBSource* pSource = pImage->m_pImage->LoadDIBSource();
            if (pSource) {
                m_pBitmap = pSource->Clone();
                delete pSource;
            }
            delete m_pForm;
            m_pForm = NULL;
            return TRUE;
        }
    }
    return FALSE;
}
class CPDF_RefType3Cache
{
public:
    CPDF_RefType3Cache(CPDF_Type3Font* pType3Font)
    {
        m_dwCount = 0;
        m_pType3Font = pType3Font;
    }
    ~CPDF_RefType3Cache()
    {
        while(m_dwCount--) {
            ReleaseCachedType3(m_pType3Font);
        }
    }
    FX_DWORD m_dwCount;
    CPDF_Type3Font* m_pType3Font;
};
FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device)
{
    CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font();
    for (int j = 0; j < m_Type3FontCache.GetSize(); j++)
        if ((CPDF_Type3Font*)m_Type3FontCache.GetAt(j) == pType3Font) {
            return TRUE;
        }
    CFX_Matrix dCTM = m_pDevice->GetCTM();
    FX_FLOAT sa = FXSYS_fabs(dCTM.a);
    FX_FLOAT sd = FXSYS_fabs(dCTM.d);
    CFX_AffineMatrix text_matrix;
    textobj->GetTextMatrix(&text_matrix);
    CFX_AffineMatrix char_matrix = pType3Font->GetFontMatrix();
    FX_FLOAT font_size = textobj->m_TextState.GetFontSize();
    char_matrix.Scale(font_size, font_size);
    FX_ARGB fill_argb = GetFillArgb(textobj, TRUE);
    int fill_alpha = FXARGB_A(fill_argb);
    int device_class = m_pDevice->GetDeviceClass();
    FXTEXT_GLYPHPOS* pGlyphAndPos = NULL;
    if (device_class == FXDC_DISPLAY) {
        pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars);
    } else if (fill_alpha < 255) {
        return FALSE;
    }
    CPDF_RefType3Cache refTypeCache(pType3Font);
    FX_DWORD *pChars = textobj->m_pCharCodes;
    if (textobj->m_nChars == 1) {
        pChars = (FX_DWORD*)(&textobj->m_pCharCodes);
    }
    for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) {
        FX_DWORD charcode = pChars[iChar];
        if (charcode == (FX_DWORD) - 1) {
            continue;
        }
        CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode);
        if (pType3Char == NULL) {
            continue;
        }
        CFX_AffineMatrix matrix = char_matrix;
        matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0;
        matrix.Concat(text_matrix);
        matrix.Concat(*pObj2Device);
        if (!pType3Char->LoadBitmap(m_pContext)) {
            if (pGlyphAndPos) {
                for (int i = 0; i < iChar; i ++) {
                    FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i];
                    if (glyph.m_pGlyph == NULL) {
                        continue;
                    }
                    m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap,
                                          glyph.m_OriginX + glyph.m_pGlyph->m_Left,
                                          glyph.m_OriginY - glyph.m_pGlyph->m_Top, fill_argb);
                }
                FX_Free(pGlyphAndPos);
                pGlyphAndPos = NULL;
            }
            CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE);
            CPDF_RenderOptions Options = m_Options;
            Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA;
            Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE;
            CPDF_Dictionary* pFormResource = NULL;
            if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) {
                pFormResource = pType3Char->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
            }
            if (fill_alpha == 255) {
                CPDF_RenderStatus status;
                status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, &Options,
                                  pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb);
                status.m_Type3FontCache.Append(m_Type3FontCache);
                status.m_Type3FontCache.Add(pType3Font);
                m_pDevice->SaveState();
                status.RenderObjectList(pType3Char->m_pForm, &matrix);
                m_pDevice->RestoreState();
            } else {
                CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox();
                rect_f.Transform(&matrix);
                FX_RECT rect = rect_f.GetOutterRect();
                CFX_FxgeDevice bitmap_device;
                if (!bitmap_device.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_Argb)) {
                    return TRUE;
                }
                bitmap_device.GetBitmap()->Clear(0);
                CPDF_RenderStatus status;
                status.Initialize(m_pContext, &bitmap_device, NULL, NULL, this, pStates, &Options,
                                  pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb);
                status.m_Type3FontCache.Append(m_Type3FontCache);
                status.m_Type3FontCache.Add(pType3Font);
                matrix.TranslateI(-rect.left, -rect.top);
                matrix.Scale(sa, sd);
                status.RenderObjectList(pType3Char->m_pForm, &matrix);
                m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top);
            }
            delete pStates;
        } else if (pType3Char->m_pBitmap) {
            if (device_class == FXDC_DISPLAY) {
                CPDF_Type3Cache* pCache = GetCachedType3(pType3Font);
                refTypeCache.m_dwCount++;
                CFX_GlyphBitmap* pBitmap = pCache->LoadGlyph(charcode, &matrix, sa, sd);
                if (pBitmap == NULL) {
                    continue;
                }
                int origin_x = FXSYS_round(matrix.e);
                int origin_y = FXSYS_round(matrix.f);
                if (pGlyphAndPos) {
                    pGlyphAndPos[iChar].m_pGlyph = pBitmap;
                    pGlyphAndPos[iChar].m_OriginX = origin_x;
                    pGlyphAndPos[iChar].m_OriginY = origin_y;
                } else {
                    m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, origin_y - pBitmap->m_Top, fill_argb);
                }
            } else {
                CFX_AffineMatrix image_matrix = pType3Char->m_ImageMatrix;
                image_matrix.Concat(matrix);
                CPDF_ImageRenderer renderer;
                if (renderer.Start(this, pType3Char->m_pBitmap, fill_argb, 255, &image_matrix, 0, FALSE)) {
                    renderer.Continue(NULL);
                }
                if (!renderer.m_Result) {
                    return FALSE;
                }
            }
        }
    }
    if (pGlyphAndPos) {
        FX_RECT rect = FXGE_GetGlyphsBBox(pGlyphAndPos, textobj->m_nChars, 0, sa, sd);
        CFX_DIBitmap bitmap;
        if (!bitmap.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_8bppMask)) {
            FX_Free(pGlyphAndPos);
            return TRUE;
        }
        bitmap.Clear(0);
        for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) {
            FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
            if (glyph.m_pGlyph == NULL) {
                continue;
            }
            bitmap.TransferBitmap((int)((glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa),
                                  (int)((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) * sd),
                                  glyph.m_pGlyph->m_Bitmap.GetWidth(), glyph.m_pGlyph->m_Bitmap.GetHeight(),
                                  &glyph.m_pGlyph->m_Bitmap, 0, 0);
        }
        m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb);
        FX_Free(pGlyphAndPos);
    }
    return TRUE;
}
class CPDF_CharPosList
{
public:
    CPDF_CharPosList();
    ~CPDF_CharPosList();
    void				Load(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, FX_FLOAT font_size);
    FXTEXT_CHARPOS*		m_pCharPos;
    FX_DWORD			m_nChars;
};
FX_FLOAT _CIDTransformToFloat(uint8_t ch);
CPDF_CharPosList::CPDF_CharPosList()
{
    m_pCharPos = NULL;
}
CPDF_CharPosList::~CPDF_CharPosList()
{
    if (m_pCharPos) {
        FX_Free(m_pCharPos);
    }
}
void CPDF_CharPosList::Load(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont,
                            FX_FLOAT FontSize)
{
    m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars);
    m_nChars = 0;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    FX_BOOL bVertWriting = pCIDFont && pCIDFont->IsVertWriting();
    for (int iChar = 0; iChar < nChars; iChar ++) {
        FX_DWORD CharCode = nChars == 1 ? (FX_DWORD)(uintptr_t)pCharCodes : pCharCodes[iChar];
        if (CharCode == (FX_DWORD) - 1) {
            continue;
        }
        FX_BOOL bVert = FALSE;
        FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++];
        if (pCIDFont) {
            charpos.m_bFontStyle = pCIDFont->IsFontStyleFromCharCode(CharCode);
        }
        charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert);
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
        charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode);
#endif
        if (!pFont->IsEmbedded() && pFont->GetFontType() != PDFFONT_CIDFONT) {
            charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode);
        } else {
            charpos.m_FontCharWidth = 0;
        }
        charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0;
        charpos.m_OriginY = 0;
        charpos.m_bGlyphAdjust = FALSE;
        if (pCIDFont == NULL) {
            continue;
        }
        FX_WORD CID = pCIDFont->CIDFromCharCode(CharCode);
        if (bVertWriting) {
            charpos.m_OriginY = charpos.m_OriginX;
            charpos.m_OriginX = 0;
            short vx, vy;
            pCIDFont->GetVertOrigin(CID, vx, vy);
            charpos.m_OriginX -= FontSize * vx / 1000;
            charpos.m_OriginY -= FontSize * vy / 1000;
        }
        const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID);
        if (pTransform && !bVert) {
            charpos.m_AdjustMatrix[0] = _CIDTransformToFloat(pTransform[0]);
            charpos.m_AdjustMatrix[2] = _CIDTransformToFloat(pTransform[2]);
            charpos.m_AdjustMatrix[1] = _CIDTransformToFloat(pTransform[1]);
            charpos.m_AdjustMatrix[3] = _CIDTransformToFloat(pTransform[3]);
            charpos.m_OriginX += _CIDTransformToFloat(pTransform[4]) * FontSize;
            charpos.m_OriginY += _CIDTransformToFloat(pTransform[5]) * FontSize;
            charpos.m_bGlyphAdjust = TRUE;
        }
    }
}
FX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos,
                                        CPDF_Font* pFont, FX_FLOAT font_size,
                                        const CFX_AffineMatrix* pText2User, const CFX_AffineMatrix* pUser2Device,
                                        const CFX_GraphStateData* pGraphState,
                                        FX_ARGB fill_argb, FX_ARGB stroke_argb, CFX_PathData* pClippingPath, int nFlag)
{
    CFX_FontCache* pCache = pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() : NULL;
    CPDF_CharPosList CharPosList;
    CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size);
    return pDevice->DrawTextPath(CharPosList.m_nChars, CharPosList.m_pCharPos,
                                 &pFont->m_Font, pCache, font_size, pText2User, pUser2Device,
                                 pGraphState, fill_argb, stroke_argb, pClippingPath, nFlag);
}
void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, int left, int top, CPDF_Font* pFont, int height,
                                       const CFX_ByteString& str, FX_ARGB argb)
{
    FX_RECT font_bbox;
    pFont->GetFontBBox(font_bbox);
    FX_FLOAT font_size = (FX_FLOAT)height * 1000.0f / (FX_FLOAT)(font_bbox.top - font_bbox.bottom);
    FX_FLOAT origin_x = (FX_FLOAT)left;
    FX_FLOAT origin_y = (FX_FLOAT)top + font_size * (FX_FLOAT)font_bbox.top / 1000.0f;
    CFX_AffineMatrix matrix(1.0f, 0, 0, -1.0f, 0, 0);
    DrawTextString(pDevice, origin_x, origin_y, pFont, font_size, &matrix, str, argb);
}
void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, FX_FLOAT origin_x, FX_FLOAT origin_y, CPDF_Font* pFont, FX_FLOAT font_size,
                                       const CFX_AffineMatrix* pMatrix, const CFX_ByteString& str, FX_ARGB fill_argb,
                                       FX_ARGB stroke_argb, const CFX_GraphStateData* pGraphState, const CPDF_RenderOptions* pOptions)
{
    int nChars = pFont->CountChar(str, str.GetLength());
    if (nChars == 0) {
        return;
    }
    FX_DWORD charcode;
    int offset = 0;
    FX_DWORD* pCharCodes;
    FX_FLOAT* pCharPos;
    if (nChars == 1) {
        charcode = pFont->GetNextChar(str, str.GetLength(), offset);
        pCharCodes = (FX_DWORD*)(uintptr_t)charcode;
        pCharPos = NULL;
    } else {
        pCharCodes = FX_Alloc(FX_DWORD, nChars);
        pCharPos = FX_Alloc(FX_FLOAT, nChars - 1);
        FX_FLOAT cur_pos = 0;
        for (int i = 0; i < nChars; i ++) {
            pCharCodes[i] = pFont->GetNextChar(str, str.GetLength(), offset);
            if (i) {
                pCharPos[i - 1] = cur_pos;
            }
            cur_pos += pFont->GetCharWidthF(pCharCodes[i]) * font_size / 1000;
        }
    }
    CFX_AffineMatrix matrix;
    if (pMatrix) {
        matrix = *pMatrix;
    }
    matrix.e = origin_x;
    matrix.f = origin_y;
    if (pFont->GetFontType() == PDFFONT_TYPE3)
        ;
    else if (stroke_argb == 0) {
        DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, &matrix, fill_argb, pOptions);
    } else
        DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, &matrix, NULL, pGraphState,
                     fill_argb, stroke_argb, NULL);
    if (nChars > 1) {
        FX_Free(pCharCodes);
        FX_Free(pCharPos);
    }
}
FX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos,
        CPDF_Font* pFont, FX_FLOAT font_size,
        const CFX_AffineMatrix* pText2Device,
        FX_ARGB fill_argb, const CPDF_RenderOptions* pOptions)
{
    CFX_FontCache* pCache = pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() : NULL;
    CPDF_CharPosList CharPosList;
    CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size);
    int FXGE_flags = 0;
    if (pOptions) {
        FX_DWORD dwFlags = pOptions->m_Flags;
        if (dwFlags & RENDER_CLEARTYPE) {
            FXGE_flags |= FXTEXT_CLEARTYPE;
            if (dwFlags & RENDER_BGR_STRIPE) {
                FXGE_flags |= FXTEXT_BGR_STRIPE;
            }
        }
        if (dwFlags & RENDER_NOTEXTSMOOTH) {
            FXGE_flags |= FXTEXT_NOSMOOTH;
        }
        if (dwFlags & RENDER_PRINTGRAPHICTEXT) {
            FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT;
        }
        if (dwFlags & RENDER_NO_NATIVETEXT) {
            FXGE_flags |= FXTEXT_NO_NATIVETEXT;
        }
        if (dwFlags & RENDER_PRINTIMAGETEXT) {
            FXGE_flags |= FXTEXT_PRINTIMAGETEXT;
        }
    } else {
        FXGE_flags = FXTEXT_CLEARTYPE;
    }
    if (pFont->GetFontType() & PDFFONT_CIDFONT) {
        FXGE_flags |= FXFONT_CIDFONT;
    }
    return pDevice->DrawNormalText(CharPosList.m_nChars, CharPosList.m_pCharPos, &pFont->m_Font, pCache, font_size, pText2Device, fill_argb, FXGE_flags);
}
void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device,
        CPDF_Font* pFont, FX_FLOAT font_size,
        const CFX_AffineMatrix* pTextMatrix, FX_BOOL bFill, FX_BOOL bStroke)
{
    if (!bStroke) {
        CPDF_PathObject path;
        CPDF_TextObject* pCopy = new CPDF_TextObject;
        pCopy->Copy(textobj);
        path.m_bStroke = FALSE;
        path.m_FillType = FXFILL_WINDING;
        path.m_ClipPath.AppendTexts(&pCopy, 1);
        path.m_ColorState = textobj->m_ColorState;
        path.m_Path.New()->AppendRect(textobj->m_Left, textobj->m_Bottom, textobj->m_Right, textobj->m_Top);
        path.m_Left = textobj->m_Left;
        path.m_Bottom = textobj->m_Bottom;
        path.m_Right = textobj->m_Right;
        path.m_Top = textobj->m_Top;
        RenderSingleObject(&path, pObj2Device);
        return;
    }
    CFX_FontCache* pCache;
    if (pFont->m_pDocument) {
        pCache = pFont->m_pDocument->GetRenderData()->GetFontCache();
    } else {
        pCache = CFX_GEModule::Get()->GetFontCache();
    }
    CFX_FaceCache* pFaceCache = pCache->GetCachedFace(&pFont->m_Font);
    FX_FONTCACHE_DEFINE(pCache, &pFont->m_Font);
    CPDF_CharPosList CharPosList;
    CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size);
    for (FX_DWORD i = 0; i < CharPosList.m_nChars; i ++) {
        FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i];
        const CFX_PathData* pPath = pFaceCache->LoadGlyphPath(&pFont->m_Font, charpos.m_GlyphIndex,
                                    charpos.m_FontCharWidth);
        if (pPath == NULL) {
            continue;
        }
        CPDF_PathObject path;
        path.m_GraphState = textobj->m_GraphState;
        path.m_ColorState = textobj->m_ColorState;
        CFX_AffineMatrix matrix;
        if (charpos.m_bGlyphAdjust)
            matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
                       charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
        matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_OriginY);
        path.m_Path.New()->Append(pPath, &matrix);
        path.m_Matrix = *pTextMatrix;
        path.m_bStroke = bStroke;
        path.m_FillType = bFill ? FXFILL_WINDING : 0;
        path.CalcBoundingBox();
        ProcessPath(&path, pObj2Device);
    }
}
CFX_PathData* CPDF_Font::LoadGlyphPath(FX_DWORD charcode, int dest_width)
{
    int glyph_index = GlyphFromCharCode(charcode);
    if (m_Font.m_Face == NULL) {
        return NULL;
    }
    return m_Font.LoadGlyphPath(glyph_index, dest_width);
}
