1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include <algorithm> 8 #include <limits> 9 #include <vector> 10 11 #include "core/fxcrt/fx_safe_types.h" 12 #include "core/fxge/cfx_pathdata.h" 13 #include "core/fxge/fx_font.h" 14 #include "core/fxge/fx_freetype.h" 15 #include "core/fxge/ifx_renderdevicedriver.h" 16 17 namespace { 18 19 void ResetTransform(FT_Face face) { 20 FXFT_Matrix matrix; 21 matrix.xx = 0x10000L; 22 matrix.xy = 0; 23 matrix.yx = 0; 24 matrix.yy = 0x10000L; 25 FXFT_Set_Transform(face, &matrix, 0); 26 } 27 28 } // namespace 29 30 FXTEXT_GLYPHPOS::FXTEXT_GLYPHPOS() : m_pGlyph(nullptr) {} 31 32 FXTEXT_GLYPHPOS::FXTEXT_GLYPHPOS(const FXTEXT_GLYPHPOS&) = default; 33 34 FXTEXT_GLYPHPOS::~FXTEXT_GLYPHPOS(){}; 35 36 ScopedFontTransform::ScopedFontTransform(FT_Face face, FXFT_Matrix* matrix) 37 : m_Face(face) { 38 FXFT_Set_Transform(m_Face, matrix, 0); 39 } 40 41 ScopedFontTransform::~ScopedFontTransform() { 42 ResetTransform(m_Face); 43 } 44 45 FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs, 46 int anti_alias, 47 float retinaScaleX, 48 float retinaScaleY) { 49 FX_RECT rect(0, 0, 0, 0); 50 bool bStarted = false; 51 for (const FXTEXT_GLYPHPOS& glyph : glyphs) { 52 const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph; 53 if (!pGlyph) 54 continue; 55 56 FX_SAFE_INT32 char_left = glyph.m_Origin.x; 57 char_left += pGlyph->m_Left; 58 if (!char_left.IsValid()) 59 continue; 60 61 FX_SAFE_INT32 char_width = pGlyph->m_pBitmap->GetWidth(); 62 char_width /= retinaScaleX; 63 if (anti_alias == FXFT_RENDER_MODE_LCD) 64 char_width /= 3; 65 if (!char_width.IsValid()) 66 continue; 67 68 FX_SAFE_INT32 char_right = char_left + char_width; 69 if (!char_right.IsValid()) 70 continue; 71 72 FX_SAFE_INT32 char_top = glyph.m_Origin.y; 73 char_top -= pGlyph->m_Top; 74 if (!char_top.IsValid()) 75 continue; 76 77 FX_SAFE_INT32 char_height = pGlyph->m_pBitmap->GetHeight(); 78 char_height /= retinaScaleY; 79 if (!char_height.IsValid()) 80 continue; 81 82 FX_SAFE_INT32 char_bottom = char_top + char_height; 83 if (!char_bottom.IsValid()) 84 continue; 85 86 if (bStarted) { 87 rect.left = pdfium::base::ValueOrDieForType<int32_t>( 88 pdfium::base::CheckMin(rect.left, char_left)); 89 rect.right = pdfium::base::ValueOrDieForType<int32_t>( 90 pdfium::base::CheckMax(rect.right, char_right)); 91 rect.top = pdfium::base::ValueOrDieForType<int32_t>( 92 pdfium::base::CheckMin(rect.top, char_top)); 93 rect.bottom = pdfium::base::ValueOrDieForType<int32_t>( 94 pdfium::base::CheckMax(rect.bottom, char_bottom)); 95 continue; 96 } 97 98 rect.left = char_left.ValueOrDie(); 99 rect.right = char_right.ValueOrDie(); 100 rect.top = char_top.ValueOrDie(); 101 rect.bottom = char_bottom.ValueOrDie(); 102 bStarted = true; 103 } 104 return rect; 105 } 106