Fix some 64 to 32 truncations in cfx_font.cpp
In particular, use the actual types returned by freetype where
appropriate. Also de-duplicate some code into helper functions,
permuting arguments to match LTRB-ordering.
Change-Id: Iab0cf989e7c1d4834b29b213a7046eb73d7a4dcd
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/88490
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 7a4e8eb..a298301 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -27,6 +27,7 @@
#include "core/fxge/scoped_font_transform.h"
#include "third_party/base/check.h"
#include "third_party/base/cxx17_backports.h"
+#include "third_party/base/numerics/safe_conversions.h"
#include "third_party/base/span.h"
#define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em)
@@ -38,11 +39,31 @@
struct OUTLINE_PARAMS {
UnownedPtr<CFX_Path> m_pPath;
- int m_CurX;
- int m_CurY;
+ FT_Pos m_CurX;
+ FT_Pos m_CurY;
float m_CoordUnit;
};
+FX_RECT FXRectFromFTPos(FT_Pos left, FT_Pos top, FT_Pos right, FT_Pos bottom) {
+ return FX_RECT(pdfium::base::checked_cast<int32_t>(left),
+ pdfium::base::checked_cast<int32_t>(top),
+ pdfium::base::checked_cast<int32_t>(right),
+ pdfium::base::checked_cast<int32_t>(bottom));
+}
+
+FX_RECT ScaledFXRectFromFTPos(FT_Pos left,
+ FT_Pos top,
+ FT_Pos right,
+ FT_Pos bottom,
+ int x_scale,
+ int y_scale) {
+ if (x_scale == 0 || y_scale == 0)
+ return FXRectFromFTPos(left, top, right, bottom);
+
+ return FXRectFromFTPos(left * 1000 / x_scale, top * 1000 / y_scale,
+ right * 1000 / x_scale, bottom * 1000 / y_scale);
+}
+
#ifdef PDF_ENABLE_XFA
unsigned long FTStreamRead(FXFT_StreamRec* stream,
unsigned long offset,
@@ -376,11 +397,12 @@
if (err)
return 0;
- int horiAdvance = FXFT_Get_Glyph_HoriAdvance(m_Face->GetRec());
+ FT_Pos horiAdvance = FXFT_Get_Glyph_HoriAdvance(m_Face->GetRec());
if (horiAdvance < kThousandthMinInt || horiAdvance > kThousandthMaxInt)
return 0;
- return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face->GetRec()), horiAdvance);
+ return static_cast<int>(
+ EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face->GetRec()), horiAdvance));
}
bool CFX_Font::LoadEmbedded(pdfium::span<const uint8_t> src_span,
@@ -427,7 +449,6 @@
if (!m_Face)
return absl::nullopt;
- FX_RECT result;
if (FXFT_Is_Face_Tricky(m_Face->GetRec())) {
int error = FT_Set_Char_Size(m_Face->GetRec(), 0, 1000 * 64, 72, 72);
if (error)
@@ -447,23 +468,14 @@
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &cbox);
int pixel_size_x = m_Face->GetRec()->size->metrics.x_ppem;
int pixel_size_y = m_Face->GetRec()->size->metrics.y_ppem;
- if (pixel_size_x == 0 || pixel_size_y == 0) {
- result.left = cbox.xMin;
- result.right = cbox.xMax;
- result.top = cbox.yMax;
- result.bottom = cbox.yMin;
- } else {
- result.left = cbox.xMin * 1000 / pixel_size_x;
- result.right = cbox.xMax * 1000 / pixel_size_x;
- result.top = cbox.yMax * 1000 / pixel_size_y;
- result.bottom = cbox.yMin * 1000 / pixel_size_y;
- }
- result.top = std::min(
- result.top,
- static_cast<int32_t>(FXFT_Get_Face_Ascender(m_Face->GetRec())));
- result.bottom = std::max(
- result.bottom,
- static_cast<int32_t>(FXFT_Get_Face_Descender(m_Face->GetRec())));
+ FX_RECT result = ScaledFXRectFromFTPos(
+ cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin, pixel_size_x, pixel_size_y);
+ result.top =
+ std::min(result.top, pdfium::base::checked_cast<int32_t>(
+ FXFT_Get_Face_Ascender(m_Face->GetRec())));
+ result.bottom =
+ std::max(result.bottom, pdfium::base::checked_cast<int32_t>(
+ FXFT_Get_Face_Descender(m_Face->GetRec())));
FT_Done_Glyph(glyph);
if (FT_Set_Pixel_Sizes(m_Face->GetRec(), 0, 64) != 0)
return absl::nullopt;
@@ -473,22 +485,13 @@
if (FT_Load_Glyph(m_Face->GetRec(), glyph_index, kFlag) != 0)
return absl::nullopt;
int em = FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
- if (em == 0) {
- result.left = FXFT_Get_Glyph_HoriBearingX(m_Face->GetRec());
- result.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face->GetRec());
- result.top = result.bottom - FXFT_Get_Glyph_Height(m_Face->GetRec());
- result.right = result.left + FXFT_Get_Glyph_Width(m_Face->GetRec());
- } else {
- result.left = FXFT_Get_Glyph_HoriBearingX(m_Face->GetRec()) * 1000 / em;
- result.top = (FXFT_Get_Glyph_HoriBearingY(m_Face->GetRec()) -
- FXFT_Get_Glyph_Height(m_Face->GetRec())) *
- 1000 / em;
- result.right = (FXFT_Get_Glyph_HoriBearingX(m_Face->GetRec()) +
- FXFT_Get_Glyph_Width(m_Face->GetRec())) *
- 1000 / em;
- result.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face->GetRec())) * 1000 / em;
- }
- return result;
+ return ScaledFXRectFromFTPos(FXFT_Get_Glyph_HoriBearingX(m_Face->GetRec()),
+ FXFT_Get_Glyph_HoriBearingY(m_Face->GetRec()) -
+ FXFT_Get_Glyph_Height(m_Face->GetRec()),
+ FXFT_Get_Glyph_HoriBearingX(m_Face->GetRec()) +
+ FXFT_Get_Glyph_Width(m_Face->GetRec()),
+ FXFT_Get_Glyph_HoriBearingY(m_Face->GetRec()),
+ em, em);
}
bool CFX_Font::IsItalic() const {
@@ -575,10 +578,10 @@
if (!m_Face)
return absl::nullopt;
- return FX_RECT(FXFT_Get_Face_xMin(m_Face->GetRec()),
- FXFT_Get_Face_yMin(m_Face->GetRec()),
- FXFT_Get_Face_xMax(m_Face->GetRec()),
- FXFT_Get_Face_yMax(m_Face->GetRec()));
+ return FXRectFromFTPos(FXFT_Get_Face_xMin(m_Face->GetRec()),
+ FXFT_Get_Face_yMin(m_Face->GetRec()),
+ FXFT_Get_Face_xMax(m_Face->GetRec()),
+ FXFT_Get_Face_yMax(m_Face->GetRec()));
}
absl::optional<FX_RECT> CFX_Font::GetBBox() const {
@@ -616,7 +619,7 @@
if (!pMasters)
return;
- long coords[2];
+ FT_Pos coords[2];
if (weight == 0)
coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536;
else
@@ -625,26 +628,29 @@
if (dest_width == 0) {
coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
} else {
- int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
- int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
+ FT_Long min_param =
+ FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
+ FT_Long max_param =
+ FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
coords[1] = min_param;
FT_Set_MM_Design_Coordinates(m_Face->GetRec(), 2, coords);
FT_Load_Glyph(m_Face->GetRec(), glyph_index,
FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face->GetRec()) * 1000 /
- FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
+ FT_Pos min_width = FXFT_Get_Glyph_HoriAdvance(m_Face->GetRec()) * 1000 /
+ FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
coords[1] = max_param;
FT_Set_MM_Design_Coordinates(m_Face->GetRec(), 2, coords);
FT_Load_Glyph(m_Face->GetRec(), glyph_index,
FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face->GetRec()) * 1000 /
- FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
+ FT_Pos max_width = FXFT_Get_Glyph_HoriAdvance(m_Face->GetRec()) * 1000 /
+ FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
if (max_width == min_width) {
FXFT_Free(m_Face->GetRec(), pMasters);
return;
}
- int param = min_param + (max_param - min_param) * (dest_width - min_width) /
- (max_width - min_width);
+ FT_Pos param = min_param + (max_param - min_param) *
+ (dest_width - min_width) /
+ (max_width - min_width);
coords[1] = param;
}
FXFT_Free(m_Face->GetRec(), pMasters);