Don't bother checking pointers before delete[] and FX_Free().
[pdfium.git] / core / src / fpdfapi / fpdf_render / fpdf_render_text.cpp
index ad5dc58..d36125e 100644 (file)
 #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();
+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);
+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;
-    }
+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;
+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);
+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 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 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;
+static FX_BOOL _IsScanLine8bpp(uint8_t* pBuf, int width) {
+  for (int i = 0; i < width; i++)
+    if (pBuf[i] > 0x40) {
+      return TRUE;
     }
-    return -1;
+  return FALSE;
 }
-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 {
-        }
+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;
+      }
     }
-    if (pResBitmap == NULL) {
+    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);
-        pResBitmap = pBitmap->TransformTo(&image_matrix, left, top);
-    }
-    if (pResBitmap == NULL) {
-        return NULL;
+        left = FXSYS_round(image_matrix.e + image_matrix.a);
+      } else {
+        left = FXSYS_round(image_matrix.e);
+      }
+    } else {
     }
-    CFX_GlyphBitmap* pGlyph = new CFX_GlyphBitmap;
-    pGlyph->m_Left = left;
-    pGlyph->m_Top = -top;
-    pGlyph->m_Bitmap.TakeOver(pResBitmap);
-    delete pResBitmap;
-    return pGlyph;
+  }
+  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);
+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;
+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 {
-            stroke_argb = GetStrokeArgb(textobj);
-        }
-    }
-    if (bFill) {
-        if (textobj->m_ColorState.GetFillColor()->IsPattern()) {
-            bPattern = TRUE;
+          bStroke = TRUE;
+        }
+        break;
+      case 2:
+      case 6:
+        if (pFont->GetFace() == NULL &&
+            !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
+          bFill = TRUE;
         } else {
-            fill_argb = GetFillArgb(textobj);
+          bFill = bStroke = TRUE;
         }
-    }
-    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);
+        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 (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);
+  }
+  if (bFill) {
+    if (textobj->m_ColorState.GetFillColor()->IsPattern()) {
+      bPattern = TRUE;
+    } else {
+      fill_argb = GetFillArgb(textobj);
     }
-    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);
+  }
+  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);
+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());
+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;
+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;
+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) {
+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);
         }
-        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;
+        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;
+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() {
+  m_pCharPos = NULL;
 }
-CPDF_CharPosList::~CPDF_CharPosList()
-{
-    if (m_pCharPos) {
-        FX_Free(m_pCharPos);
-    }
+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);
+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;
-        }
-    }
+    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,
+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);
+                                        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,
+                                       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);
-    }
+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);
+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);
-    }
+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);
+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);
 }