diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 13:19:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 13:20:02 +0000 |
commit | 58daab21cd043e1dc37024a7f99b396788372918 (patch) | |
tree | 96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /ml/dlib/dlib/gui_widgets/fonts.cpp | |
parent | Releasing debian version 1.43.2-1. (diff) | |
download | netdata-58daab21cd043e1dc37024a7f99b396788372918.tar.xz netdata-58daab21cd043e1dc37024a7f99b396788372918.zip |
Merging upstream version 1.44.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ml/dlib/dlib/gui_widgets/fonts.cpp')
-rw-r--r-- | ml/dlib/dlib/gui_widgets/fonts.cpp | 673 |
1 files changed, 673 insertions, 0 deletions
diff --git a/ml/dlib/dlib/gui_widgets/fonts.cpp b/ml/dlib/dlib/gui_widgets/fonts.cpp new file mode 100644 index 000000000..dfbf9f720 --- /dev/null +++ b/ml/dlib/dlib/gui_widgets/fonts.cpp @@ -0,0 +1,673 @@ +// Copyright (C) 2005 Davis E. King (davis@dlib.net), and Nils Labugt, Keita Mochizuki +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_FONTs_CPP_ +#define DLIB_FONTs_CPP_ + +#include "fonts.h" + +#include <fstream> +#include <memory> +#include <sstream> + +#include "../serialize.h" +#include "../base64.h" +#include "../compress_stream.h" +#include "../tokenizer.h" +#include "nativefont.h" + +namespace dlib +{ + +// ---------------------------------------------------------------------------------------- + + const std::string get_decoded_string_with_default_font_data() + { + dlib::base64::kernel_1a base64_coder; + dlib::compress_stream::kernel_1ea compressor; + std::ostringstream sout; + std::istringstream sin; + + /* + SOURCE BDF FILE (helvR12.bdf) COMMENTS + COMMENT $XConsortium: helvR12.bdf,v 1.15 95/01/26 18:02:58 gildea Exp $ + COMMENT $Id: helvR12.bdf,v 1.26 2004-11-28 20:08:46+00 mgk25 Rel $ + COMMENT + COMMENT + + COMMENT Copyright 1984-1989, 1994 Adobe Systems Incorporated. + COMMENT Copyright 1988, 1994 Digital Equipment Corporation. + COMMENT + COMMENT Adobe is a trademark of Adobe Systems Incorporated which may be + COMMENT registered in certain jurisdictions. + COMMENT Permission to use these trademarks is hereby granted only in + COMMENT association with the images described in this file. + COMMENT + COMMENT Permission to use, copy, modify, distribute and sell this software + COMMENT and its documentation for any purpose and without fee is hereby + COMMENT granted, provided that the above copyright notices appear in all + COMMENT copies and that both those copyright notices and this permission + COMMENT notice appear in supporting documentation, and that the names of + COMMENT Adobe Systems and Digital Equipment Corporation not be used in + COMMENT advertising or publicity pertaining to distribution of the software + COMMENT without specific, written prior permission. Adobe Systems and + COMMENT Digital Equipment Corporation make no representations about the + COMMENT suitability of this software for any purpose. It is provided "as + COMMENT is" without express or implied warranty. + COMMENT - + */ + + // The base64 encoded data we want to decode and return. + sout << "AXF+zOQzCgGitrKiOCGEL4hlIv1ZenWJyjMQ4rJ6f/oPMeHqsZn+8XnpehwFQTz3dtUGlZRAUoOa"; + sout << "uVo8UiplcFxuK69A+94rpMCMAyEeeOwZ/tRzkX4eKuU3L4xtsJDknMiYUNKaMrYimb1QJ0E+SRqQ"; + sout << "wATrMTecYNZvJJm02WibiwE4cJ5scvkHNl4KJT5QfdwRdGopTyUVdZvRvtbTLLjsJP0fQEQLqemf"; + sout << "qPE4kDD79ehrBIwLO1Y6TzxtrrIoQR57zlwTUyLenqRtSN3VLtjWYd82cehRIlTLtuxBg2s+zZVq"; + sout << "jNlNnYTSM+Swy06qnQgg+Dt0lhtlB9shR1OAlcfCtTW6HKoBk/FGeDmjTGW4bNCGv7RjgM6TlLDg"; + sout << "ZYSSA6ZCCAKBgE++U32gLHCCiVkPTkkp9P6ioR+e3SSKRNm9p5MHf+ZQ3LJkW8KFJ/K9gKT1yvyv"; + sout << "F99pAvOOq16tHRFvzBs+xZj/mUpH0lGIS7kLWr9oP2KuccVrz25aJn3kDruwTYoD+CYlOqtPO0Mv"; + sout << "dEI0LUR0Ykp1M2rWo76fJ/fpzHjV7737hjkNPJ13nO72RMDr4R5V3uG7Dw7Ng+vGX3WgJZ4wh1JX"; + sout << "pl2VMqC5JXccctzvnQvnuvBvRm7THgwQUgMKKT3WK6afUUVlJy8DHKuU4k1ibfVMxAmrwKdTUX2w"; + sout << "cje3A05Qji3aop65qEdwgI5O17HIVoRQOG/na+XRMowOfUvI4H8Z4+JGACfRrQctgYDAM9eJzm8i"; + sout << "PibyutmJfZBGg0a3oC75S5R9lTxEjPocnEyJRYNnmVnVAmKKbTbTsznuaD+D1XhPdr2t3A4bRTsp"; + sout << "toKKtlFnd9YGwLWwONDwLnoQ/IXwyF7txrRHNSVToh772U0Aih/yn5vnmcMF750eiMzRAgXu5sbR"; + sout << "VXEOVCiLgVevN5umkvjZt1eGTSSzDMrIvnv4nyOfaFsD+I76wQfgLqd71rheozGtjNc0AOTx4Ggc"; + sout << "eUSFHTDAVfTExBzckurtyuIAqF986a0JLHCtsDpBa2wWNuiQYOH3/LX1zkdU2hdamhBW774bpEwr"; + sout << "dguMxxOeDGOBgIlM5gxXGYXSf5IN3fUAEPfOPRxB7T+tpjFnWd7cg+JMabci3zhJ9ANaYT7HGeTX"; + sout << "bulKnGHjYrR1BxdK3YeliogQRU4ytmxlyL5zlNFU/759mA8XSfIPMEZn9Vxkb00q1htF7REiDcr3"; + sout << "kW1rtPAc7VQNEhT54vK/YF6rMvjO7kBZ/vLYo7E8e8hDKEnY8ucrC3KGmeo31Gei74BBcEbvJBd3"; + sout << "/YAaIKgXWwU2wSUw9wLq2RwGwyguvKBx0J/gn27tjcVAHorRBwxzPpk8r+YPyN+SifSzEL7LEy1G"; + sout << "lPHxmXTrcqnH9qraeAqXJUJvU8SJJpf/tmsAE+XSKD/kpVBnT5qXsJ1SRFS7MtfPjE1j/NYbaQBI"; + sout << "bOrh81zaYCEJR0IKHWCIsu/MC3zKXfkxFgQ9XpYAuWjSSK64YpgkxSMe8VG8yYvigOw2ODg/z4FU"; + sout << "+HpnEKF/M/mKfLKK1i/8BV7xcYVHrhEww1QznoFklJs/pEg3Kd5PE1lRii6hvTn6McVAkw+YbH9q"; + sout << "/sg4gFIAvai64hMcZ1oIZYppj3ZN6KMdyhK5s4++ZS/YOV2nNhW73ovivyi2Tjg7lxjJJtsYrLKb"; + sout << "zIN1slOICKYwBq42TFBcFXaZ6rf0Czd09tL+q6A1Ztgr3BNuhCenjhWN5ji0LccGYZo6bLTggRG/"; + sout << "Uz6K3CBBU/byLs79c5qCohrr7rlpDSdbuR+aJgNiWoU6T0i2Tvua6h51LcWEHy5P2n146/Ae2di4"; + sout << "eh20WQvclrsgm1oFTGD0Oe85GKOTA7vvwKmLBc1wwA0foTuxzVgj0TMTFBiYLTLG4ujUyBYy1N6e"; + sout << "H8EKi8H+ZAlqezrjABO3BQr33ewdZL5IeJ4w7gdGUDA6+P+7cODcBW50X9++6YTnKctuEw6aXBpy"; + sout << "GgcMfPE61G8YKBbFGFic3TVvGCLvre1iURv+F+hU4/ee6ILuPnpYnSXX2iCIK/kmkBse8805d4Qe"; + sout << "DG/8rBW9ojvAgc0jX7CatPEMHGkcz+KIZoKMI7XXK4PJpGQUdq6EdIhJC4koXEynjwwXMeC+jJqH"; + sout << "agwrlDNssq/8AA=="; + + + + // Put the data into the istream sin + sin.str(sout.str()); + sout.str(""); + + // Decode the base64 text into its compressed binary form + base64_coder.decode(sin,sout); + sin.clear(); + sin.str(sout.str()); + sout.str(""); + + // Decompress the data into its original form + compressor.decompress(sin,sout); + + // Return the decoded and decompressed data + return sout.str(); + } + + + default_font:: + default_font ( + ) + { + using namespace std; + l = new letter[256]; + + try + { + istringstream sin(get_decoded_string_with_default_font_data()); + + for (int i = 0; i < 256; ++i) + { + deserialize(l[i],sin); + } + + } + catch (...) + { + delete [] l; + throw; + } + } + +// ---------------------------------------------------------------------------------------- + + void serialize ( + const letter& item, + std::ostream& out + ) + { + try + { + serialize(item.w,out); + serialize(item.count,out); + + for (unsigned long i = 0; i < item.count; ++i) + { + serialize(item.points[i].x,out); + serialize(item.points[i].y,out); + } + } + catch (serialization_error e) + { + throw serialization_error(e.info + "\n while serializing object of type letter"); + } + } + + void deserialize ( + letter& item, + std::istream& in + ) + { + try + { + if (item.points) + delete [] item.points; + + deserialize(item.w,in); + deserialize(item.count,in); + + if (item.count > 0) + item.points = new letter::point[item.count]; + else + item.points = 0; + + for (unsigned long i = 0; i < item.count; ++i) + { + deserialize(item.points[i].x,in); + deserialize(item.points[i].y,in); + } + } + catch (serialization_error e) + { + item.w = 0; + item.count = 0; + item.points = 0; + throw serialization_error(e.info + "\n while deserializing object of type letter"); + } + } + +// ---------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------- + + namespace bdf_font_helpers + { + class bdf_parser + { + public: + bdf_parser( std::istream& in ) : in_( in ) + { + std::string str_tmp; + int int_tmp; + + str_tmp = "STARTFONT"; int_tmp = STARTFONT; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "FONTBOUNDINGBOX";int_tmp = FONTBOUNDINGBOX; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "DWIDTH"; int_tmp = DWIDTH; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "CHARS"; int_tmp = CHARS; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "STARTCHAR"; int_tmp = STARTCHAR; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "ENCODING"; int_tmp = ENCODING; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "BBX"; int_tmp = BBX; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "BITMAP"; int_tmp = BITMAP; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "ENDCHAR"; int_tmp = ENDCHAR; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "ENDFONT"; int_tmp = ENDFONT; keyword_map.add( str_tmp, int_tmp ); + str_tmp = "DEFAULT_CHAR"; int_tmp = DEFAULT_CHAR; keyword_map.add( str_tmp, int_tmp ); + + tokzr.set_identifier_token( tokzr.uppercase_letters(), tokzr.uppercase_letters() + "_" ); + tokzr.set_stream( in ); + + } + + enum bdf_enums + { + NO_KEYWORD = 0, + STARTFONT = 1, + FONTBOUNDINGBOX = 2, + DWIDTH = 4, + DEFAULT_CHAR = 8, + CHARS = 16, + STARTCHAR = 32, + ENCODING = 64, + BBX = 128, + BITMAP = 256, + ENDCHAR = 512, + ENDFONT = 1024 + + }; + struct header_info + { + int FBBx, FBBy, Xoff, Yoff; + int dwx0, dwy0; + bool has_global_dw; + long default_char; + }; + struct char_info + { + int dwx0, dwy0; + int BBw, BBh, BBxoff0x, BByoff0y; + array2d<char> bitmap; + bool has_dw; + }; + bool parse_header( header_info& info ) + { + if ( required_keyword( STARTFONT ) == false ) + return false; // parse_error: required keyword missing + info.has_global_dw = false; + int find = FONTBOUNDINGBOX | DWIDTH | DEFAULT_CHAR; + int stop = CHARS | STARTCHAR | ENCODING | BBX | BITMAP | ENDCHAR | ENDFONT; + int res; + while ( 1 ) + { + res = find_keywords( find | stop ); + if ( res & FONTBOUNDINGBOX ) + { + in_ >> info.FBBx >> info.FBBy >> info.Xoff >> info.Yoff; + if ( in_.fail() ) + return false; // parse_error + find &= ~FONTBOUNDINGBOX; + continue; + } + if ( res & DWIDTH ) + { + in_ >> info.dwx0 >> info.dwy0; + if ( in_.fail() ) + return false; // parse_error + find &= ~DWIDTH; + info.has_global_dw = true; + continue; + } + if ( res & DEFAULT_CHAR ) + { + in_ >> info.default_char; + if ( in_.fail() ) + return false; // parse_error + find &= ~DEFAULT_CHAR; + continue; + } + if ( res & NO_KEYWORD ) + return false; // parse_error: unexpected EOF + break; + } + if ( res != CHARS || ( find & FONTBOUNDINGBOX ) ) + return false; // parse_error: required keyword missing or unexpeced keyword + return true; + } + int parse_glyph( char_info& info, unichar& enc ) + { + info.has_dw = false; + int e; + int res; + while ( 1 ) + { + res = find_keywords( ENCODING ); + if ( res != ENCODING ) + return 0; // no more glyphs + in_ >> e; + if ( in_.fail() ) + return -1; // parse_error + if ( e >= static_cast<int>(enc) ) + break; + } + int find = BBX | DWIDTH; + int stop = STARTCHAR | ENCODING | BITMAP | ENDCHAR | ENDFONT; + while ( 1 ) + { + res = find_keywords( find | stop ); + if ( res & BBX ) + { + in_ >> info.BBw >> info.BBh >> info.BBxoff0x >> info.BByoff0y; + if ( in_.fail() ) + return -1; // parse_error + find &= ~BBX; + continue; + } + if ( res & DWIDTH ) + { + in_ >> info.dwx0 >> info.dwy0; + if ( in_.fail() ) + return -1; // parse_error + find &= ~DWIDTH; + info.has_dw = true; + continue; + } + if ( res & NO_KEYWORD ) + return -1; // parse_error: unexpected EOF + break; + } + if ( res != BITMAP || ( find != NO_KEYWORD ) ) + return -1; // parse_error: required keyword missing or unexpeced keyword + unsigned h = info.BBh; + unsigned w = ( info.BBw + 7 ) / 8 * 2; + info.bitmap.set_size( h, w ); + for ( unsigned r = 0;r < h;r++ ) + { + trim(); + std::string str = ""; + extract_hex(str); + if(str.size() < w) + return -1; // parse_error + for ( unsigned c = 0;c < w;c++ ) + info.bitmap[r][c] = str[c]; + } + if ( in_.fail() ) + return -1; // parse_error + if ( required_keyword( ENDCHAR ) == false ) + return -1; // parse_error: required keyword missing + enc = e; + return 1; + } + private: + map<std::string, int>::kernel_1a_c keyword_map; + tokenizer::kernel_1a_c tokzr; + std::istream& in_; + void extract_hex(std::string& str) + { + int type; + std::string token; + while ( 1 ) + { + type = tokzr.peek_type(); + if ( type == tokenizer::kernel_1a_c::IDENTIFIER || type == tokenizer::kernel_1a_c::NUMBER ) + { + tokzr.get_token( type, token ); + str += token; + continue; + } + break; + } + } + void trim() + { + int type; + std::string token; + while ( 1 ) + { + type = tokzr.peek_type(); + if ( type == tokenizer::kernel_1a_c::WHITE_SPACE || type == tokenizer::kernel_1a_c::END_OF_LINE ) + { + tokzr.get_token( type, token ); + continue; + } + break; + } + } + bool required_keyword( int kw ) + { + int type; + std::string token; + while ( 1 ) + { + tokzr.get_token( type, token ); + if ( type == tokenizer::kernel_1a_c::WHITE_SPACE || type == tokenizer::kernel_1a_c::END_OF_LINE ) + continue; + if ( type != tokenizer::kernel_1a_c::IDENTIFIER || keyword_map.is_in_domain( token ) == false || ( keyword_map[token] & kw ) == 0 ) + return false; + break; + } + return true; + } + int find_keywords( int find ) + { + int type; + std::string token; + while ( 1 ) + { + tokzr.get_token( type, token ); + if ( type == tokenizer::kernel_1a_c::END_OF_FILE ) + return NO_KEYWORD; + if ( type == tokenizer::kernel_1a_c::IDENTIFIER && keyword_map.is_in_domain( token ) == true ) + { + int kw = keyword_map[token]; + if ( kw & find ) + return kw; + } + } + return true; + } + + }; + + } + +// ---------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------- +// bdf_font functions +// ---------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------- + + bdf_font::bdf_font( + long default_char_ + ) : + default_char(0), + is_initialized( false ), + right_overflow_( 0 ), + has_global_width( false ), + specified_default_char( default_char_ ) + { + // make sure gl contains at least one letter + gl.resize(1); + } + +// ---------------------------------------------------------------------------------------- + + void bdf_font::adjust_metrics( + ) + { + if ( is_initialized == false ) + return; + // set starting values for fbb + if ( gl[default_char].num_of_points() > 0 ) + { + letter& g = gl[default_char]; + fbb.set_top( g[0].y ); + fbb.set_bottom( g[0].y ); + fbb.set_left( g[0].x ); + fbb.set_right( g[0].x ); + } + else + { + // ok, the default char was a space + // let's just choose some safe arbitrary values then... + fbb.set_top( 10000 ); + fbb.set_bottom( -10000 ); + fbb.set_left( 10000 ); + fbb.set_right( -10000 ); + } + right_overflow_ = 0; + for ( unichar n = 0; n < gl.size(); n++ ) + { + letter& g = gl[n]; + unsigned short nr_pts = g.num_of_points(); + for ( unsigned short k = 0;k < nr_pts;k++ ) + { + fbb.set_top( std::min( fbb.top(), (long)g[k].y ) ); + fbb.set_left( std::min( fbb.left(), (long)g[k].x ) ); + fbb.set_bottom( std::max( fbb.bottom(), (long)g[k].y ) ); + fbb.set_right( std::max( fbb.right(), (long)g[k].x ) ); + right_overflow_ = std::max( right_overflow_, (unsigned long)(g[k].x - g.width()) ); // superfluous? + } + } + } + +// ---------------------------------------------------------------------------------------- + + long bdf_font:: + read_bdf_file( + std::istream& in, + unichar max_enc, + unichar min_enc + ) + { + using namespace bdf_font_helpers; + + bdf_parser parser( in ); + bdf_parser::header_info hinfo; + bdf_parser::char_info cinfo; + + gl.resize(max_enc+1); + hinfo.default_char = - 1; + if ( is_initialized == false || static_cast<std::streamoff>(in.tellg()) == std::ios::beg ) + { + if ( parser.parse_header( hinfo ) == false ) + return 0; // parse_error: invalid or missing header + } + else + { + // not start of file, so use values from previous read. + hinfo.has_global_dw = has_global_width; + hinfo.dwx0 = global_width; + } + int res; + unichar nr_letters_added = 0; + unsigned width; + for ( unichar n = min_enc; n <= max_enc; n++ ) + { + if ( in.eof() ) + break; + long pos = in.tellg(); + res = parser.parse_glyph( cinfo, n ); + if ( res < 0 ) + return 0; // parse_error + if ( res == 0 ) + continue; + if ( n > max_enc ) + { + in.seekg( pos ); + break; + } + + if ( cinfo.has_dw == false ) + { + if ( hinfo.has_global_dw == false ) + return 0; // neither width info for the glyph, nor for the font as a whole (monospace). + width = hinfo.dwx0; + } + else + width = cinfo.dwx0; + + + if ( bitmap_to_letter( cinfo.bitmap, n, width, cinfo.BBxoff0x, cinfo.BByoff0y ) == false ) + return 0; + nr_letters_added++; + + if ( is_initialized == false ) + { + // Bonding rectangle for the font. + fbb.set_top( -( hinfo.Yoff + hinfo.FBBy - 1 ) ); + fbb.set_bottom( -hinfo.Yoff ); + fbb.set_left( hinfo.Xoff ); + fbb.set_right( hinfo.Xoff + hinfo.FBBx - 1 ); + // We need to compute this after all the glyphs are loaded. + right_overflow_ = 0; + // set this to something valid now, just in case. + default_char = n; + // Save any global width in case we later read from the same file. + has_global_width = hinfo.has_global_dw; + if ( has_global_width ) + global_width = hinfo.dwx0; + // dont override value specified in the constructor with value specified in the file + if ( specified_default_char < 0 && hinfo.default_char >= 0 ) + specified_default_char = hinfo.default_char; + + is_initialized = true; + } + } + if ( is_initialized == false ) + return 0; // Not a single glyph was found within the specified range. + + if ( specified_default_char >= 0 ) + default_char = specified_default_char; + // no default char specified, try find something sane. + else + default_char = 0; + + return nr_letters_added; + } + +// ---------------------------------------------------------------------------------------- + + bool bdf_font:: + bitmap_to_letter( + array2d<char>& bitmap, + unichar enc, + unsigned long width, + int x_offset, + int y_offset + ) + { + unsigned nr_points = 0; + bitmap.reset(); + while ( bitmap.move_next() ) + { + unsigned char ch = bitmap.element(); + if ( ch > '9' ) + ch -= 'A' - '9' - 1; + ch -= '0'; + if ( ch > 0xF ) + return false; // parse error: invalid hex digit + bitmap.element() = ch; + if ( ch & 8 ) + nr_points++; + if ( ch & 4 ) + nr_points++; + if ( ch & 2 ) + nr_points++; + if ( ch & 1 ) + nr_points++; + } + + letter( width, nr_points ).swap(gl[enc]); + + unsigned index = 0; + for ( int r = 0;r < bitmap.nr();r++ ) + { + for ( int c = 0;c < bitmap.nc();c++ ) + { + int x = x_offset + c * 4; + int y = -( y_offset + bitmap.nr() - r - 1 ); + char ch = bitmap[r][c]; + letter& glyph = gl[enc]; + if ( ch & 8 ) + { + glyph[index] = letter::point( x, y ); + right_overflow_ = std::max( right_overflow_, x - width ); + index++; + } + if ( ch & 4 ) + { + glyph[index] = letter::point( x + 1, y ); + right_overflow_ = std::max( right_overflow_, x + 1 - width ); + index++; + } + if ( ch & 2 ) + { + glyph[index] = letter::point( x + 2, y ); + right_overflow_ = std::max( right_overflow_, x + 2 - width ); + index++; + } + if ( ch & 1 ) + { + glyph[index] = letter::point( x + 3, y ); + right_overflow_ = std::max( right_overflow_, x + 3 - width ); + index++; + } + } + } + return true; + } + +// ---------------------------------------------------------------------------------------- + + const std::shared_ptr<font> get_native_font ( + ) + { + return nativefont::native_font::get_font(); + } + +// ---------------------------------------------------------------------------------------- + +} + +#endif // DLIB_FONTs_CPP_ + |