Serenity Operating System
at master 68 lines 2.6 kB view raw
1/* 2 * Copyright (c) 2023, Rodrigo Tobar <rtobarc@gmail.com>. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibGfx/Forward.h> 8#include <LibPDF/CommonNames.h> 9#include <LibPDF/Error.h> 10#include <LibPDF/Fonts/PDFFont.h> 11#include <LibPDF/Fonts/SimpleFont.h> 12#include <LibPDF/Fonts/TrueTypeFont.h> 13#include <LibPDF/Fonts/Type1Font.h> 14 15namespace PDF { 16 17PDFErrorOr<void> SimpleFont::initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size) 18{ 19 TRY(PDFFont::initialize(document, dict, font_size)); 20 if (dict->contains(CommonNames::Encoding)) { 21 auto encoding_object = MUST(dict->get_object(document, CommonNames::Encoding)); 22 m_encoding = TRY(Encoding::from_object(document, encoding_object)); 23 } 24 25 if (dict->contains(CommonNames::ToUnicode)) 26 m_to_unicode = TRY(dict->get_stream(document, CommonNames::ToUnicode)); 27 28 if (dict->contains(CommonNames::FirstChar) && dict->contains(CommonNames::LastChar) && dict->contains(CommonNames::Widths)) { 29 auto first_char = dict->get_value(CommonNames::FirstChar).get<int>(); 30 auto last_char = dict->get_value(CommonNames::LastChar).get<int>(); 31 auto widths_array = TRY(dict->get_array(document, CommonNames::Widths)); 32 33 VERIFY(widths_array->size() == static_cast<size_t>(last_char - first_char + 1)); 34 35 for (size_t i = 0; i < widths_array->size(); i++) 36 m_widths.set(first_char + i, widths_array->at(i).to_int()); 37 } 38 39 if (dict->contains(CommonNames::FontDescriptor)) { 40 auto descriptor = TRY(dict->get_dict(document, CommonNames::FontDescriptor)); 41 if (descriptor->contains(CommonNames::MissingWidth)) 42 m_missing_width = descriptor->get_value(CommonNames::MissingWidth).to_int(); 43 } 44 45 return {}; 46} 47 48float SimpleFont::get_char_width(u8 char_code) const 49{ 50 return static_cast<float>(m_widths.get(char_code).value_or(m_missing_width)) / 1000.0f; 51} 52 53PDFErrorOr<Gfx::FloatPoint> SimpleFont::draw_string(Gfx::Painter& painter, Gfx::FloatPoint glyph_position, DeprecatedString const& string, Color const& paint_color, float font_size, float character_spacing, float horizontal_scaling) 54{ 55 auto so = make_object<StringObject>(string, true); 56 for (auto char_code : string.bytes()) { 57 auto char_width = get_char_width(char_code); 58 auto glyph_width = char_width * font_size; 59 draw_glyph(painter, glyph_position, glyph_width, char_code, paint_color); 60 auto tx = glyph_width; 61 tx += character_spacing; 62 tx *= horizontal_scaling; 63 glyph_position += { tx, 0.0f }; 64 } 65 return glyph_position; 66} 67 68}