Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fx_font.cpp
Go to the documentation of this file.
1// Copyright 2018 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "core/fxge/fx_font.h"
6
7#include <algorithm>
8
9#include "core/fxcrt/fx_safe_types.h"
10#include "core/fxcrt/fx_system.h"
11#include "core/fxcrt/widestring.h"
12#include "core/fxge/cfx_glyphbitmap.h"
13#include "core/fxge/dib/cfx_dibitmap.h"
14#include "core/fxge/freetype/fx_freetype.h"
15#include "core/fxge/text_glyph_pos.h"
16
17namespace {
18
19// These numbers come from the OpenType name table specification.
20constexpr uint16_t kNameMacEncodingRoman = 0;
21constexpr uint16_t kNameWindowsEncodingUnicode = 1;
22
23ByteString GetStringFromTable(pdfium::span<const uint8_t> string_span,
24 uint16_t offset,
25 uint16_t length) {
26 if (string_span.size() < static_cast<uint32_t>(offset + length))
27 return ByteString();
28
29 string_span = string_span.subspan(offset, length);
30 return ByteString(string_span.data(), string_span.size());
31}
32
33} // namespace
34
35FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs, int anti_alias) {
36 FX_RECT rect;
37 bool bStarted = false;
38 for (const TextGlyphPos& glyph : glyphs) {
39 if (!glyph.m_pGlyph)
40 continue;
41
42 absl::optional<CFX_Point> point = glyph.GetOrigin({0, 0});
43 if (!point.has_value())
44 continue;
45
46 int char_width = glyph.m_pGlyph->GetBitmap()->GetWidth();
47 if (anti_alias == FT_RENDER_MODE_LCD)
48 char_width /= 3;
49
50 FX_SAFE_INT32 char_right = point.value().x;
51 char_right += char_width;
52 if (!char_right.IsValid())
53 continue;
54
55 FX_SAFE_INT32 char_bottom = point.value().y;
56 char_bottom += glyph.m_pGlyph->GetBitmap()->GetHeight();
57 if (!char_bottom.IsValid())
58 continue;
59
60 if (bStarted) {
61 rect.left = std::min(rect.left, point.value().x);
62 rect.top = std::min(rect.top, point.value().y);
63 rect.right = pdfium::base::ValueOrDieForType<int32_t>(
64 pdfium::base::CheckMax(rect.right, char_right));
65 rect.bottom = pdfium::base::ValueOrDieForType<int32_t>(
66 pdfium::base::CheckMax(rect.bottom, char_bottom));
67 continue;
68 }
69
70 rect.left = point.value().x;
71 rect.top = point.value().y;
72 rect.right = char_right.ValueOrDie();
73 rect.bottom = char_bottom.ValueOrDie();
74 bStarted = true;
75 }
76 return rect;
77}
78
79ByteString GetNameFromTT(pdfium::span<const uint8_t> name_table,
80 uint32_t name_id) {
81 if (name_table.size() < 6)
82 return ByteString();
83
84 uint32_t name_count = FXSYS_UINT16_GET_MSBFIRST(&name_table[2]);
85 uint32_t string_offset = FXSYS_UINT16_GET_MSBFIRST(&name_table[4]);
86 // We will ignore the possibility of overlap of structures and
87 // string table as if it's all corrupt there's not a lot we can do.
88 if (name_table.size() < string_offset)
89 return ByteString();
90
91 pdfium::span<const uint8_t> string_span = name_table.subspan(string_offset);
92 name_table = name_table.subspan(6);
93 if (name_table.size() < name_count * 12)
94 return ByteString();
95
96 for (uint32_t i = 0; i < name_count;
97 i++, name_table = name_table.subspan(12)) {
98 if (FXSYS_UINT16_GET_MSBFIRST(&name_table[6]) == name_id) {
99 const uint16_t platform_identifier =
100 FXSYS_UINT16_GET_MSBFIRST(name_table);
101 const uint16_t platform_encoding =
102 FXSYS_UINT16_GET_MSBFIRST(&name_table[2]);
103
104 if (platform_identifier == kNamePlatformMac &&
105 platform_encoding == kNameMacEncodingRoman) {
106 return GetStringFromTable(string_span,
107 FXSYS_UINT16_GET_MSBFIRST(&name_table[10]),
108 FXSYS_UINT16_GET_MSBFIRST(&name_table[8]));
109 }
110 if (platform_identifier == kNamePlatformWindows &&
111 platform_encoding == kNameWindowsEncodingUnicode) {
112 // This name is always UTF16-BE and we have to convert it to UTF8.
113 ByteString utf16_be = GetStringFromTable(
114 string_span, FXSYS_UINT16_GET_MSBFIRST(&name_table[10]),
115 FXSYS_UINT16_GET_MSBFIRST(&name_table[8]));
116 if (utf16_be.IsEmpty() || utf16_be.GetLength() % 2 != 0) {
117 return ByteString();
118 }
119
120 return WideString::FromUTF16BE(utf16_be.raw_span()).ToUTF8();
121 }
122 }
123 }
124 return ByteString();
125}
126
127size_t GetTTCIndex(pdfium::span<const uint8_t> pFontData, size_t font_offset) {
128 pdfium::span<const uint8_t> p = pFontData.subspan(8);
129 size_t nfont = FXSYS_UINT32_GET_MSBFIRST(p.data());
130 for (size_t index = 0; index < nfont; index++) {
131 p = pFontData.subspan(12 + index * 4);
132 if (FXSYS_UINT32_GET_MSBFIRST(p.data()) == font_offset)
133 return index;
134 }
135 return 0;
136}
137
138wchar_t UnicodeFromAdobeName(const char* name) {
139 return (wchar_t)(FXFT_unicode_from_adobe_name(name) & 0x7FFFFFFF);
140}
141
142ByteString AdobeNameFromUnicode(wchar_t unicode) {
143 char glyph_name[64];
144 FXFT_adobe_name_from_unicode(glyph_name, unicode);
145 return ByteString(glyph_name);
146}
ByteString(const char *ptr)
bool IsEmpty() const
Definition bytestring.h:119
static WideString FromUTF16BE(pdfium::span< const uint8_t > data)
constexpr uint16_t kNamePlatformMac
Definition fx_font.h:43
ByteString GetNameFromTT(pdfium::span< const uint8_t > name_table, uint32_t name)
Definition fx_font.cpp:79
wchar_t UnicodeFromAdobeName(const char *name)
Definition fx_font.cpp:138
FX_RECT GetGlyphsBBox(const std::vector< TextGlyphPos > &glyphs, int anti_alias)
Definition fx_font.cpp:35
size_t GetTTCIndex(pdfium::span< const uint8_t > pFontData, size_t font_offset)
Definition fx_font.cpp:127
ByteString AdobeNameFromUnicode(wchar_t unicode)
Definition fx_font.cpp:142
constexpr uint16_t kNamePlatformWindows
Definition fx_font.h:44
void FXFT_adobe_name_from_unicode(char *name, wchar_t unicode)
int FXFT_unicode_from_adobe_name(const char *glyph_name)