FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT &bbox) { if (m_Face == NULL) { return FALSE; } if (FXFT_Is_Face_Tricky(m_Face)) { int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72); if (error) { return FALSE; } error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); if (error) { return FALSE; } FXFT_BBox cbox; FT_Glyph glyph; error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph); if (error) { return FALSE; } FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem, pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem; if (pixel_size_x == 0 || pixel_size_y == 0) { bbox.left = cbox.xMin; bbox.right = cbox.xMax; bbox.top = cbox.yMax; bbox.bottom = cbox.yMin; } else { bbox.left = cbox.xMin * 1000 / pixel_size_x; bbox.right = cbox.xMax * 1000 / pixel_size_x; bbox.top = cbox.yMax * 1000 / pixel_size_y; bbox.bottom = cbox.yMin * 1000 / pixel_size_y; } if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) { bbox.top = FXFT_Get_Face_Ascender(m_Face); } if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) { bbox.bottom = FXFT_Get_Face_Descender(m_Face); } FT_Done_Glyph(glyph); return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; } if (FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { return FALSE; } int em = FXFT_Get_Face_UnitsPerEM(m_Face); if (em == 0) { bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face); bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face); bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face); bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face); } else { bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em; bbox.top = (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) * 1000 / em; bbox.right = (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) * 1000 / em; bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em; } return TRUE; }
FX_INT32 CFPF_SkiaFont::GetDescent() const { if (!m_Face) { return 0; } return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Descender(m_Face)); }
int CFX_Font::GetDescent() const { if (m_Face == NULL) { return 0; } int descent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Descender(m_Face)); return descent; }
void CPDF_Font::CheckFontMetrics() { if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && m_FontBBox.right == 0) { FXFT_Face face = m_Font.GetFace(); if (face) { m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face); m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face); m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face); m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face); m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face); m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face); } else { bool bFirst = true; for (int i = 0; i < 256; i++) { FX_RECT rect = GetCharBBox(i); if (rect.left == rect.right) { continue; } if (bFirst) { m_FontBBox = rect; bFirst = false; } else { if (m_FontBBox.top < rect.top) { m_FontBBox.top = rect.top; } if (m_FontBBox.right < rect.right) { m_FontBBox.right = rect.right; } if (m_FontBBox.left > rect.left) { m_FontBBox.left = rect.left; } if (m_FontBBox.bottom > rect.bottom) { m_FontBBox.bottom = rect.bottom; } } } } } if (m_Ascent == 0 && m_Descent == 0) { FX_RECT rect = GetCharBBox('A'); m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top; rect = GetCharBBox('g'); m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom; } }
FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode) { if (charcode < 256 && m_CharBBox[charcode].right != -1) return m_CharBBox[charcode]; FX_RECT rect; bool bVert = false; int glyph_index = GlyphFromCharCode(charcode, &bVert); FXFT_Face face = m_Font.GetFace(); if (face) { if (FXFT_Is_Face_Tricky(face)) { int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); if (!err) { FXFT_BBox cbox; FXFT_Glyph glyph; err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph); if (!err) { FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem; int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem; if (pixel_size_x == 0 || pixel_size_y == 0) { rect = FX_RECT(cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin); } else { rect = FX_RECT(cbox.xMin * 1000 / pixel_size_x, cbox.yMax * 1000 / pixel_size_y, cbox.xMax * 1000 / pixel_size_x, cbox.yMin * 1000 / pixel_size_y); } rect.top = std::min(rect.top, static_cast<int>(FXFT_Get_Face_Ascender(face))); rect.bottom = std::max( rect.bottom, static_cast<int>(FXFT_Get_Face_Descender(face))); FXFT_Done_Glyph(glyph); } } } else { int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE); if (err == 0) { rect = FX_RECT(TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face), TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face), TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face), face), TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face), face)); rect.top += rect.top / 64; } } } if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) { uint16_t CID = CIDFromCharCode(charcode); const uint8_t* pTransform = GetCIDTransform(CID); if (pTransform && !bVert) { CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]), CIDTransformToFloat(pTransform[1]), CIDTransformToFloat(pTransform[2]), CIDTransformToFloat(pTransform[3]), CIDTransformToFloat(pTransform[4]) * 1000, CIDTransformToFloat(pTransform[5]) * 1000); CFX_FloatRect rect_f(rect); matrix.TransformRect(rect_f); rect = rect_f.GetOuterRect(); } } if (charcode < 256) m_CharBBox[charcode] = rect; return rect; }
int CFX_Font::GetDescent() const { if (!m_Face) return 0; return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Descender(m_Face)); }