CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, FX_DWORD charcode, const CFX_AffineMatrix* 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_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; }