// 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 "render_int.h"

#include "core/include/fpdfapi/fpdf_pageobj.h"
#include "core/include/fpdfapi/fpdf_render.h"
#include "core/include/fxge/fx_ge.h"
#include "core/src/fpdfapi/fpdf_page/pageint.h"

CPDF_Type3Cache::~CPDF_Type3Cache() {
  for (const auto& pair : m_SizeMap) {
    delete pair.second;
  }
  m_SizeMap.clear();
}
CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(FX_DWORD charcode,
                                            const CFX_Matrix* 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;
  auto it = m_SizeMap.find(FaceGlyphsKey);
  if (it == m_SizeMap.end()) {
    pSizeCache = new CPDF_Type3Glyphs;
    m_SizeMap[FaceGlyphsKey] = pSizeCache;
  } else {
    pSizeCache = it->second;
  }
  auto it2 = pSizeCache->m_GlyphMap.find(charcode);
  if (it2 != pSizeCache->m_GlyphMap.end())
    return it2->second;

  CFX_GlyphBitmap* pGlyphBitmap =
      RenderGlyph(pSizeCache, charcode, pMatrix, retinaScaleX, retinaScaleY);
  pSizeCache->m_GlyphMap[charcode] = pGlyphBitmap;
  return pGlyphBitmap;
}
CPDF_Type3Glyphs::~CPDF_Type3Glyphs() {
  for (const auto& pair : m_GlyphMap)
    delete pair.second;
}
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_Matrix* pMatrix,
                                              FX_FLOAT retinaScaleX,
                                              FX_FLOAT retinaScaleY) {
  const CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode);
  if (!pChar || !pChar->m_pBitmap)
    return nullptr;

  CFX_DIBitmap* pBitmap = pChar->m_pBitmap;
  CFX_Matrix 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) {
    image_matrix.Scale(retinaScaleX, retinaScaleY);
    pResBitmap = pBitmap->TransformTo(&image_matrix, left, top);
  }
  if (!pResBitmap) {
    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_Matrix* 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() &&
            !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
          bFill = TRUE;
        } else {
          bStroke = TRUE;
        }
        break;
      case 2:
      case 6:
        if (!pFont->GetFace() &&
            !(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_Matrix 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_Matrix* pDeviceMatrix = pObj2Device;
    CFX_Matrix device_matrix;
    if (bStroke) {
      const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM;
      if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) {
        CFX_Matrix 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) {
    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) {
    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 || !m_pForm) {
    return TRUE;
  }
  if (m_pForm->CountObjects() == 1 && !m_bColored) {
    CPDF_PageObject* pPageObj =
        m_pForm->GetObjectAt(m_pForm->GetFirstObjectPosition());
    if (pPageObj->m_Type == CPDF_PageObject::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_Matrix* pObj2Device) {
  CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font();
  for (int j = 0; j < m_Type3FontCache.GetSize(); j++) {
    if (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_Matrix text_matrix;
  textobj->GetTextMatrix(&text_matrix);
  CFX_Matrix 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) {
      continue;
    }
    CFX_Matrix 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) {
            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->GetDictBy("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) {
          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_Matrix 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) {
        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;
};

CPDF_CharPosList::CPDF_CharPosList() {
  m_pCharPos = NULL;
}
CPDF_CharPosList::~CPDF_CharPosList() {
  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) {
      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] = pCIDFont->CIDTransformToFloat(pTransform[0]);
      charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]);
      charpos.m_AdjustMatrix[1] = pCIDFont->CIDTransformToFloat(pTransform[1]);
      charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]);
      charpos.m_OriginX +=
          pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize;
      charpos.m_OriginY +=
          pCIDFont->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_Matrix* pText2User,
                                        const CFX_Matrix* 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_Matrix 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_Matrix* 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_Matrix 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_Matrix* 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_Matrix* pObj2Device,
                                                CPDF_Font* pFont,
                                                FX_FLOAT font_size,
                                                const CFX_Matrix* 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) {
      continue;
    }
    CPDF_PathObject path;
    path.m_GraphState = textobj->m_GraphState;
    path.m_ColorState = textobj->m_ColorState;
    CFX_Matrix 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.GetFace())
    return nullptr;
  return m_Font.LoadGlyphPath(glyph_index, dest_width);
}
