add qpf fonts sources and makeqpf utility

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2015-12-10 09:22:27 +02:00
parent 5c9327b224
commit 17b9025b34
49 changed files with 988259 additions and 0 deletions

24999
src/3rdparty/fonts/5x7.bdf vendored Normal file

File diff suppressed because it is too large Load diff

75535
src/3rdparty/fonts/6x13.bdf vendored Normal file

File diff suppressed because it is too large Load diff

1
src/3rdparty/fonts/COPYING.Cursor vendored Normal file
View file

@ -0,0 +1 @@
Copyright (c) 2000 XFree86, Inc.

19
src/3rdparty/fonts/COPYING.Helvetica vendored Normal file
View file

@ -0,0 +1,19 @@
Copyright 1984-1989, 1994 Adobe Systems Incorporated.
Copyright 1988, 1994 Digital Equipment Corporation.
Adobe is a trademark of Adobe Systems Incorporated which may be
registered in certain jurisdictions.
Permission to use these trademarks is hereby granted only in
association with the images described in this file.
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notices appear in all
copies and that both those copyright notices and this permission
notice appear in supporting documentation, and that the names of
Adobe Systems and Digital Equipment Corporation not be used in
advertising or publicity pertaining to distribution of the software
without specific, written prior permission. Adobe Systems and
Digital Equipment Corporation make no representations about the
suitability of this software for any purpose. It is provided "as
is" without express or implied warranty.

16
src/3rdparty/fonts/COPYING.Utopia vendored Normal file
View file

@ -0,0 +1,16 @@
Permission to use, reproduce, display and distribute the listed typefaces
is hereby granted, provided that the Adobe Copyright notice appears in all
whole and partial copies of the software and that the following trademark
symbol and attribution appear in all unmodified copies of the software:
Copyright (c) 1989 Adobe Systems Incorporated
Utopia (R)
Utopia is a registered trademark of Adobe Systems Incorporated
The Adobe typefaces (Type 1 font program, bitmaps and Adobe Font Metric
files) donated are:
Utopia Regular
Utopia Italic
Utopia Bold
Utopia Bold Italic

42
src/3rdparty/fonts/COPYRIGHT.BH vendored Normal file
View file

@ -0,0 +1,42 @@
Luxi fonts copyright (c) 2001 by Bigelow & Holmes Inc. Luxi font
instruction code copyright (c) 2001 by URW++ GmbH. All Rights
Reserved. Luxi is a registered trademark of Bigelow & Holmes Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of these Fonts and associated documentation files (the "Font
Software"), to deal in the Font Software, including without
limitation the rights to use, copy, merge, publish, distribute,
sublicense, and/or sell copies of the Font Software, and to permit
persons to whom the Font Software is furnished to do so, subject to
the following conditions:
The above copyright and trademark notices and this permission notice
shall be included in all copies of one or more of the Font Software.
The Font Software may not be modified, altered, or added to, and in
particular the designs of glyphs or characters in the Fonts may not
be modified nor may additional glyphs or characters be added to the
Fonts. This License becomes null and void when the Fonts or Font
Software have been modified.
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
BIGELOW & HOLMES INC. OR URW++ GMBH. BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR
INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT
SOFTWARE.
Except as contained in this notice, the names of Bigelow & Holmes
Inc. and URW++ GmbH. shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Font Software without
prior written authorization from Bigelow & Holmes Inc. and URW++ GmbH.
For further information, contact:
info@urwpp.de
or
design@bigelowandholmes.com

11
src/3rdparty/fonts/COPYRIGHT.Charter vendored Normal file
View file

@ -0,0 +1,11 @@
(c) Copyright 1989-1992, Bitstream Inc., Cambridge, MA.
You are hereby granted permission under all Bitstream propriety rights
to use, copy, modify, sublicense, sell, and redistribute the 4 Bitstream
Charter (r) Type 1 outline fonts and the 4 Courier Type 1 outline fonts
for any purpose and without restriction; provided, that this notice is
left intact on all copies of such fonts and that Bitstream's trademark
is acknowledged as shown below on all unmodified copies of the 4 Charter
Type 1 fonts.
BITSTREAM CHARTER is a registered trademark of Bitstream Inc.

11
src/3rdparty/fonts/COPYRIGHT.Courier vendored Normal file
View file

@ -0,0 +1,11 @@
(c) Copyright 1989-1992, Bitstream Inc., Cambridge, MA.
You are hereby granted permission under all Bitstream propriety rights
to use, copy, modify, sublicense, sell, and redistribute the 4 Bitstream
Charter (r) Type 1 outline fonts and the 4 Courier Type 1 outline fonts
for any purpose and without restriction; provided, that this notice is
left intact on all copies of such fonts and that Bitstream's trademark
is acknowledged as shown below on all unmodified copies of the 4 Charter
Type 1 fonts.
BITSTREAM CHARTER is a registered trademark of Bitstream Inc.

98
src/3rdparty/fonts/COPYRIGHT.DejaVu vendored Normal file
View file

@ -0,0 +1,98 @@
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. Glyphs imported from Arev fonts are (c) Tavmjung Bah (see below)
Bitstream Vera Fonts Copyright
------------------------------
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
a trademark of Bitstream, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of the fonts accompanying this license ("Fonts") and associated
documentation files (the "Font Software"), to reproduce and distribute the
Font Software, including without limitation the rights to use, copy, merge,
publish, distribute, and/or sell copies of the Font Software, and to permit
persons to whom the Font Software is furnished to do so, subject to the
following conditions:
The above copyright and trademark notices and this permission notice shall
be included in all copies of one or more of the Font Software typefaces.
The Font Software may be modified, altered, or added to, and in particular
the designs of glyphs or characters in the Fonts may be modified and
additional glyphs or characters may be added to the Fonts, only if the fonts
are renamed to names not containing either the words "Bitstream" or the word
"Vera".
This License becomes null and void to the extent applicable to Fonts or Font
Software that has been modified and is distributed under the "Bitstream
Vera" names.
The Font Software may be sold as part of a larger software package but no
copy of one or more of the Font Software typefaces may be sold by itself.
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
FONT SOFTWARE.
Except as contained in this notice, the names of Gnome, the Gnome
Foundation, and Bitstream Inc., shall not be used in advertising or
otherwise to promote the sale, use or other dealings in this Font Software
without prior written authorization from the Gnome Foundation or Bitstream
Inc., respectively. For further information, contact: fonts at gnome dot
org.
Arev Fonts Copyright
------------------------------
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of the fonts accompanying this license ("Fonts") and
associated documentation files (the "Font Software"), to reproduce
and distribute the modifications to the Bitstream Vera Font Software,
including without limitation the rights to use, copy, merge, publish,
distribute, and/or sell copies of the Font Software, and to permit
persons to whom the Font Software is furnished to do so, subject to
the following conditions:
The above copyright and trademark notices and this permission notice
shall be included in all copies of one or more of the Font Software
typefaces.
The Font Software may be modified, altered, or added to, and in
particular the designs of glyphs or characters in the Fonts may be
modified and additional glyphs or characters may be added to the
Fonts, only if the fonts are renamed to names not containing either
the words "Tavmjong Bah" or the word "Arev".
This License becomes null and void to the extent applicable to Fonts
or Font Software that has been modified and is distributed under the
"Tavmjong Bah Arev" names.
The Font Software may be sold as part of a larger software package but
no copy of one or more of the Font Software typefaces may be sold by
itself.
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Except as contained in this notice, the name of Tavmjong Bah shall not
be used in advertising or otherwise to promote the sale, use or other
dealings in this Font Software without prior written authorization
from Tavmjong Bah. For further information, contact: tavmjong @ free
. fr.
$Id: LICENSE 778 2006-04-20 18:14:24Z moyogo $

9
src/3rdparty/fonts/COPYRIGHT.IBM vendored Normal file
View file

@ -0,0 +1,9 @@
IBM Courier - Copyright (c) IBM Corporation 1990, 1991
You are hereby granted permission under the terms of the IBM/MIT X Consortium
Courier Typefont agreement to execute, reproduce, distribute, display, market,
sell and otherwise transfer copies of the IBM Courier font to third parties.
The font is provided "AS IS" without charge. NO WARRANTIES OR INDEMNIFICATION
ARE GIVEN, WHETHER EXPRESS OR IMPLIED INCLUDING, BUT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

7
src/3rdparty/fonts/COPYRIGHT.Unifont vendored Normal file
View file

@ -0,0 +1,7 @@
The Unifont font was originally obtained from http://www.czyborra.com/ under
the following license:
All of my works you find here are freeware. You may freely copy, use, quote,
modify or redistribute them as long as you properly attribute my contribution
and have given a quick thought about whether Roman might perhaps be interested
to read what you did with his stuff. Horizontal rules don't apply.

124
src/3rdparty/fonts/COPYRIGHT.Vera vendored Normal file
View file

@ -0,0 +1,124 @@
Bitstream Vera Fonts Copyright
The fonts have a generous copyright, allowing derivative works (as
long as "Bitstream" or "Vera" are not in the names), and full
redistribution (so long as they are not *sold* by themselves). They
can be be bundled, redistributed and sold with any software.
The fonts are distributed under the following copyright:
Copyright
=========
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream
Vera is a trademark of Bitstream, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of the fonts accompanying this license ("Fonts") and associated
documentation files (the "Font Software"), to reproduce and distribute
the Font Software, including without limitation the rights to use,
copy, merge, publish, distribute, and/or sell copies of the Font
Software, and to permit persons to whom the Font Software is furnished
to do so, subject to the following conditions:
The above copyright and trademark notices and this permission notice
shall be included in all copies of one or more of the Font Software
typefaces.
The Font Software may be modified, altered, or added to, and in
particular the designs of glyphs or characters in the Fonts may be
modified and additional glyphs or characters may be added to the
Fonts, only if the fonts are renamed to names not containing either
the words "Bitstream" or the word "Vera".
This License becomes null and void to the extent applicable to Fonts
or Font Software that has been modified and is distributed under the
"Bitstream Vera" names.
The Font Software may be sold as part of a larger software package but
no copy of one or more of the Font Software typefaces may be sold by
itself.
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT
SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
Except as contained in this notice, the names of Gnome, the Gnome
Foundation, and Bitstream Inc., shall not be used in advertising or
otherwise to promote the sale, use or other dealings in this Font
Software without prior written authorization from the Gnome Foundation
or Bitstream Inc., respectively. For further information, contact:
fonts at gnome dot org.
Copyright FAQ
=============
1. I don't understand the resale restriction... What gives?
Bitstream is giving away these fonts, but wishes to ensure its
competitors can't just drop the fonts as is into a font sale system
and sell them as is. It seems fair that if Bitstream can't make money
from the Bitstream Vera fonts, their competitors should not be able to
do so either. You can sell the fonts as part of any software package,
however.
2. I want to package these fonts separately for distribution and
sale as part of a larger software package or system. Can I do so?
Yes. A RPM or Debian package is a "larger software package" to begin
with, and you aren't selling them independently by themselves.
See 1. above.
3. Are derivative works allowed?
Yes!
4. Can I change or add to the font(s)?
Yes, but you must change the name(s) of the font(s).
5. Under what terms are derivative works allowed?
You must change the name(s) of the fonts. This is to ensure the
quality of the fonts, both to protect Bitstream and Gnome. We want to
ensure that if an application has opened a font specifically of these
names, it gets what it expects (though of course, using fontconfig,
substitutions could still could have occurred during font
opening). You must include the Bitstream copyright. Additional
copyrights can be added, as per copyright law. Happy Font Hacking!
6. If I have improvements for Bitstream Vera, is it possible they might get
adopted in future versions?
Yes. The contract between the Gnome Foundation and Bitstream has
provisions for working with Bitstream to ensure quality additions to
the Bitstream Vera font family. Please contact us if you have such
additions. Note, that in general, we will want such additions for the
entire family, not just a single font, and that you'll have to keep
both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add
glyphs to the font, they must be stylistically in keeping with Vera's
design. Vera cannot become a "ransom note" font. Jim Lyles will be
providing a document describing the design elements used in Vera, as a
guide and aid for people interested in contributing to Vera.
7. I want to sell a software package that uses these fonts: Can I do so?
Sure. Bundle the fonts with your software and sell your software
with the fonts. That is the intent of the copyright.
8. If applications have built the names "Bitstream Vera" into them,
can I override this somehow to use fonts of my choosing?
This depends on exact details of the software. Most open source
systems and software (e.g., Gnome, KDE, etc.) are now converting to
use fontconfig (see www.fontconfig.org) to handle font configuration,
selection and substitution; it has provisions for overriding font
names and subsituting alternatives. An example is provided by the
supplied local.conf file, which chooses the family Bitstream Vera for
"sans", "serif" and "monospace". Other software (e.g., the XFree86
core server) has other mechanisms for font substitution.

59
src/3rdparty/fonts/README.DejaVu vendored Normal file
View file

@ -0,0 +1,59 @@
DejaVu fonts 2.12 (c)2004-2006 DejaVu fonts team
-----------------------------------------------
The DejaVu fonts are a font family based on the Bitstream Vera Fonts
(http://gnome.org/fonts/). Its purpose is to provide a wider range of
characters (see status.txt for more information) while maintaining the
original look and feel.
DejaVu fonts are based on Bitstream Vera fonts version 1.10.
Available fonts (Sans = sans serif, Mono = monospaced):
DejaVu Sans Mono
DejaVu Sans Mono Bold
DejaVu Sans Mono Bold Oblique
DejaVu Sans Mono Oblique
DejaVu Sans
DejaVu Sans Bold
DejaVu Sans Bold Oblique
DejaVu Sans Oblique
DejaVu Sans ExtraLight (experimental)
DejaVu Serif
DejaVu Serif Bold
DejaVu Serif Bold Oblique (experimental)
DejaVu Serif Oblique (experimental)
DejaVu Sans Condensed (experimental)
DejaVu Sans Condensed Bold (experimental)
DejaVu Sans Condensed Bold Oblique (experimental)
DejaVu Sans Condensed Oblique (experimental)
DejaVu Serif Condensed (experimental)
DejaVu Serif Condensed Bold (experimental)
DejaVu Serif Condensed Bold Oblique (experimental)
DejaVu Serif Condensed Oblique (experimental)
All fonts are also available as derivative called DejaVu LGC with support
only for Latin, Greek and Cyrillic scripts.
For license information see LICENSE. What's new is described in NEWS. Known
bugs are in BUGS. All authors are mentioned in AUTHORS.
Fonts are published in source form as SFD files (Spline Font Database from
FontForge - http://fontforge.sf.net/) and in compiled form as TTF files
(TrueType fonts).
For more information go to http://dejavu.sourceforge.net/.
Characters from Arev fonts, Copyright (c) 2006 by Tavmjong Bah:
---------------------------
U+01ba, U+01bf, U+01f7, U+021c, U+021d, U+0220, U+0222, U+0223,
U+02b9, U+02ba, U+02bd, U+02c2, U+02c3, U+02c4, U+02c5, U+02d4,
U+02d5, U+02d7, U+02ec, U+02ed, U+02ee, U+0346-034e, U+0360, U+0362,
U+03e2-03ef, U+0460-0463, U+0466-0486, U+0488-0489, U+04a8-04a9,
U+0500-050f, U+2055-205e, U+20B0, U+20B2-20B3, U+2102, U+210D, U+210f,
U+2111, U+2113, U+2115, U+2118-U+211A, U+211c-211d, U+2124,U+2135,
U+213C-U+2140, U+2295-2298, U+2308-230b, U+26A2-U+26B1, U+2701-2704,
U+2706-2709, U+270c-274b, U+2758-275a, U+2761-2775, U+2780-2794,
U+2798-27af, U+27b1-27be, U+fb05-fb06
$Id: README 1288 2006-11-19 14:22:52Z ben_laenen $

2604
src/3rdparty/fonts/helvB08.bdf vendored Normal file

File diff suppressed because it is too large Load diff

2867
src/3rdparty/fonts/helvB10.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3057
src/3rdparty/fonts/helvB12.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3319
src/3rdparty/fonts/helvB14.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3864
src/3rdparty/fonts/helvB18.bdf vendored Normal file

File diff suppressed because it is too large Load diff

4718
src/3rdparty/fonts/helvB24.bdf vendored Normal file

File diff suppressed because it is too large Load diff

2597
src/3rdparty/fonts/helvBO08.bdf vendored Normal file

File diff suppressed because it is too large Load diff

2863
src/3rdparty/fonts/helvBO10.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3056
src/3rdparty/fonts/helvBO12.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3325
src/3rdparty/fonts/helvBO14.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3853
src/3rdparty/fonts/helvBO18.bdf vendored Normal file

File diff suppressed because it is too large Load diff

4709
src/3rdparty/fonts/helvBO24.bdf vendored Normal file

File diff suppressed because it is too large Load diff

2601
src/3rdparty/fonts/helvO08.bdf vendored Normal file

File diff suppressed because it is too large Load diff

2869
src/3rdparty/fonts/helvO10.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3042
src/3rdparty/fonts/helvO12.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3310
src/3rdparty/fonts/helvO14.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3837
src/3rdparty/fonts/helvO18.bdf vendored Normal file

File diff suppressed because it is too large Load diff

4713
src/3rdparty/fonts/helvO24.bdf vendored Normal file

File diff suppressed because it is too large Load diff

2595
src/3rdparty/fonts/helvR08.bdf vendored Normal file

File diff suppressed because it is too large Load diff

2864
src/3rdparty/fonts/helvR10.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3046
src/3rdparty/fonts/helvR12.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3313
src/3rdparty/fonts/helvR14.bdf vendored Normal file

File diff suppressed because it is too large Load diff

3861
src/3rdparty/fonts/helvR18.bdf vendored Normal file

File diff suppressed because it is too large Load diff

4715
src/3rdparty/fonts/helvR24.bdf vendored Normal file

File diff suppressed because it is too large Load diff

1548
src/3rdparty/fonts/micro.bdf vendored Normal file

File diff suppressed because it is too large Load diff

801998
src/3rdparty/fonts/unifont.bdf vendored Normal file

File diff suppressed because it is too large Load diff

185
util/makeqpf/Blocks.txt Normal file
View file

@ -0,0 +1,185 @@
# Blocks-5.0.0.txt
# Date: 2006-02-15, 15:40:00 [KW]
#
# Unicode Character Database
# Copyright (c) 1991-2006 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see UCD.html
#
# Note: The casing of block names is not normative.
# For example, "Basic Latin" and "BASIC LATIN" are equivalent.
#
# Format:
# Start Code..End Code; Block Name
# ================================================
# Note: When comparing block names, casing, whitespace, hyphens,
# and underbars are ignored.
# For example, "Latin Extended-A" and "latin extended a" are equivalent.
# For more information on the comparison of property values,
# see UCD.html.
#
# All code points not explicitly listed for Block
# have the value No_Block.
# Property: Block
#
# @missing: 0000..10FFFF; No_Block
0000..007F; Basic Latin
0080..00FF; Latin-1 Supplement
0100..017F; Latin Extended-A
0180..024F; Latin Extended-B
0250..02AF; IPA Extensions
02B0..02FF; Spacing Modifier Letters
0300..036F; Combining Diacritical Marks
0370..03FF; Greek and Coptic
0400..04FF; Cyrillic
0500..052F; Cyrillic Supplement
0530..058F; Armenian
0590..05FF; Hebrew
0600..06FF; Arabic
0700..074F; Syriac
0750..077F; Arabic Supplement
0780..07BF; Thaana
07C0..07FF; NKo
0900..097F; Devanagari
0980..09FF; Bengali
0A00..0A7F; Gurmukhi
0A80..0AFF; Gujarati
0B00..0B7F; Oriya
0B80..0BFF; Tamil
0C00..0C7F; Telugu
0C80..0CFF; Kannada
0D00..0D7F; Malayalam
0D80..0DFF; Sinhala
0E00..0E7F; Thai
0E80..0EFF; Lao
0F00..0FFF; Tibetan
1000..109F; Myanmar
10A0..10FF; Georgian
1100..11FF; Hangul Jamo
1200..137F; Ethiopic
1380..139F; Ethiopic Supplement
13A0..13FF; Cherokee
1400..167F; Unified Canadian Aboriginal Syllabics
1680..169F; Ogham
16A0..16FF; Runic
1700..171F; Tagalog
1720..173F; Hanunoo
1740..175F; Buhid
1760..177F; Tagbanwa
1780..17FF; Khmer
1800..18AF; Mongolian
1900..194F; Limbu
1950..197F; Tai Le
1980..19DF; New Tai Lue
19E0..19FF; Khmer Symbols
1A00..1A1F; Buginese
1B00..1B7F; Balinese
1D00..1D7F; Phonetic Extensions
1D80..1DBF; Phonetic Extensions Supplement
1DC0..1DFF; Combining Diacritical Marks Supplement
1E00..1EFF; Latin Extended Additional
1F00..1FFF; Greek Extended
2000..206F; General Punctuation
2070..209F; Superscripts and Subscripts
20A0..20CF; Currency Symbols
20D0..20FF; Combining Diacritical Marks for Symbols
2100..214F; Letterlike Symbols
2150..218F; Number Forms
2190..21FF; Arrows
2200..22FF; Mathematical Operators
2300..23FF; Miscellaneous Technical
2400..243F; Control Pictures
2440..245F; Optical Character Recognition
2460..24FF; Enclosed Alphanumerics
2500..257F; Box Drawing
2580..259F; Block Elements
25A0..25FF; Geometric Shapes
2600..26FF; Miscellaneous Symbols
2700..27BF; Dingbats
27C0..27EF; Miscellaneous Mathematical Symbols-A
27F0..27FF; Supplemental Arrows-A
2800..28FF; Braille Patterns
2900..297F; Supplemental Arrows-B
2980..29FF; Miscellaneous Mathematical Symbols-B
2A00..2AFF; Supplemental Mathematical Operators
2B00..2BFF; Miscellaneous Symbols and Arrows
2C00..2C5F; Glagolitic
2C60..2C7F; Latin Extended-C
2C80..2CFF; Coptic
2D00..2D2F; Georgian Supplement
2D30..2D7F; Tifinagh
2D80..2DDF; Ethiopic Extended
2E00..2E7F; Supplemental Punctuation
2E80..2EFF; CJK Radicals Supplement
2F00..2FDF; Kangxi Radicals
2FF0..2FFF; Ideographic Description Characters
3000..303F; CJK Symbols and Punctuation
3040..309F; Hiragana
30A0..30FF; Katakana
3100..312F; Bopomofo
3130..318F; Hangul Compatibility Jamo
3190..319F; Kanbun
31A0..31BF; Bopomofo Extended
31C0..31EF; CJK Strokes
31F0..31FF; Katakana Phonetic Extensions
3200..32FF; Enclosed CJK Letters and Months
3300..33FF; CJK Compatibility
3400..4DBF; CJK Unified Ideographs Extension A
4DC0..4DFF; Yijing Hexagram Symbols
4E00..9FFF; CJK Unified Ideographs
A000..A48F; Yi Syllables
A490..A4CF; Yi Radicals
A700..A71F; Modifier Tone Letters
A720..A7FF; Latin Extended-D
A800..A82F; Syloti Nagri
A840..A87F; Phags-pa
AC00..D7AF; Hangul Syllables
D800..DB7F; High Surrogates
DB80..DBFF; High Private Use Surrogates
DC00..DFFF; Low Surrogates
E000..F8FF; Private Use Area
F900..FAFF; CJK Compatibility Ideographs
FB00..FB4F; Alphabetic Presentation Forms
FB50..FDFF; Arabic Presentation Forms-A
FE00..FE0F; Variation Selectors
FE10..FE1F; Vertical Forms
FE20..FE2F; Combining Half Marks
FE30..FE4F; CJK Compatibility Forms
FE50..FE6F; Small Form Variants
FE70..FEFF; Arabic Presentation Forms-B
FF00..FFEF; Halfwidth and Fullwidth Forms
FFF0..FFFF; Specials
10000..1007F; Linear B Syllabary
10080..100FF; Linear B Ideograms
10100..1013F; Aegean Numbers
10140..1018F; Ancient Greek Numbers
10300..1032F; Old Italic
10330..1034F; Gothic
10380..1039F; Ugaritic
103A0..103DF; Old Persian
10400..1044F; Deseret
10450..1047F; Shavian
10480..104AF; Osmanya
10800..1083F; Cypriot Syllabary
10900..1091F; Phoenician
10A00..10A5F; Kharoshthi
12000..123FF; Cuneiform
12400..1247F; Cuneiform Numbers and Punctuation
1D000..1D0FF; Byzantine Musical Symbols
1D100..1D1FF; Musical Symbols
1D200..1D24F; Ancient Greek Musical Notation
1D300..1D35F; Tai Xuan Jing Symbols
1D360..1D37F; Counting Rod Numerals
1D400..1D7FF; Mathematical Alphanumeric Symbols
20000..2A6DF; CJK Unified Ideographs Extension B
2F800..2FA1F; CJK Compatibility Ideographs Supplement
E0000..E007F; Tags
E0100..E01EF; Variation Selectors Supplement
F0000..FFFFF; Supplementary Private Use Area-A
100000..10FFFF; Supplementary Private Use Area-B
# EOF

1
util/makeqpf/README Normal file
View file

@ -0,0 +1 @@
This tool is used to create pre-rendered fonts for use with Qtopia Core.

183
util/makeqpf/main.cpp Normal file
View file

@ -0,0 +1,183 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui>
#include "qpf2.h"
#include "mainwindow.h"
#include <private/qfontengine_p.h>
QT_BEGIN_NAMESPACE
static void help()
{
printf("usage:\n");
printf("makeqpf fontname pixelsize [italic] [bold] [--exclude-cmap] [-v]\n");
printf("makeqpf -dump [-v] file.qpf2\n");
exit(0);
}
static int gui(const QString &customFont = QString())
{
MainWindow mw(customFont);
mw.show();
return qApp->exec();
}
QT_END_NAMESPACE
int main(int argc, char **argv)
{
QT_USE_NAMESPACE
QApplication app(argc, argv);
app.setOrganizationName(QLatin1String("Trolltech"));
app.setApplicationName(QLatin1String("MakeQPF"));
const QStringList arguments = app.arguments();
if (arguments.count() <= 1) {
return gui();
} else if (arguments.count() == 2
&& QFile::exists(arguments.at(1))) {
return gui(arguments.at(1));
}
const QString &firstArg = arguments.at(1);
if (firstArg == QLatin1String("-h") || firstArg == QLatin1String("--help"))
help();
if (firstArg == QLatin1String("-dump")) {
QString file;
for (int i = 2; i < arguments.count(); ++i) {
if (arguments.at(i).startsWith(QLatin1String("-v")))
QPF::debugVerbosity += arguments.at(i).length() - 1;
else if (file.isEmpty())
file = arguments.at(i);
else
help();
}
if (file.isEmpty())
help();
QFile f(file);
if (!f.open(QIODevice::ReadOnly)) {
printf("cannot open %s\n", qPrintable(file));
exit(1);
}
QByteArray qpf = f.readAll();
f.close();
QPF::dump(qpf);
return 0;
}
if (arguments.count() < 3) help();
QFont font;
QString fontName = firstArg;
if (QFile::exists(fontName)) {
int id = QFontDatabase::addApplicationFont(fontName);
if (id == -1) {
printf("cannot open font %s", qPrintable(fontName));
help();
}
QStringList families = QFontDatabase::applicationFontFamilies(id);
if (families.isEmpty()) {
printf("cannot find any font families in %s", qPrintable(fontName));
help();
}
fontName = families.first();
}
font.setFamily(fontName);
bool ok = false;
int pixelSize = arguments.at(2).toInt(&ok);
if (!ok) help();
font.setPixelSize(pixelSize);
int generationOptions = QPF::IncludeCMap | QPF::RenderGlyphs;
for (int i = 3; i < arguments.count(); ++i) {
const QString &arg = arguments.at(i);
if (arg == QLatin1String("italic")) {
font.setItalic(true);
} else if (arg == QLatin1String("bold")) {
font.setBold(true);
} else if (arg == QLatin1String("--exclude-cmap")) {
generationOptions &= ~QPF::IncludeCMap;
} else if (arg == QLatin1String("--exclude-glyphs")) {
generationOptions &= ~QPF::RenderGlyphs;
} else if (arg == QLatin1String("-v")) {
++QPF::debugVerbosity;
} else {
printf("unknown option %s\n", qPrintable(arg));
help();
}
}
font.setStyleStrategy(QFont::NoFontMerging);
QList<QPF::CharacterRange> ranges;
ranges.append(QPF::CharacterRange()); // default range from 0 to 0xffff
QString origFont;
QByteArray qpf = QPF::generate(font, generationOptions, ranges, &origFont);
QString fileName = QPF::fileNameForFont(font);
QFile f(fileName);
f.open(QIODevice::WriteOnly | QIODevice::Truncate);
f.write(qpf);
f.close();
if (generationOptions & QPF::IncludeCMap) {
printf("Created %s from %s\n", qPrintable(fileName), qPrintable(origFont));
} else {
printf("Created %s from %s excluding the character-map\n", qPrintable(fileName), qPrintable(origFont));
printf("The TrueType font file is therefore required for the font to work\n");
}
return 0;
}

322
util/makeqpf/mainwindow.cpp Normal file
View file

@ -0,0 +1,322 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mainwindow.h"
#include <QFontComboBox>
#include <QFontDatabase>
#include <QFileDialog>
#include <QMessageBox>
#include <QListWidget>
#include <QDebug>
#include <QShortcut>
#include <QCompleter>
#include <QDirModel>
#include <QTextCodec>
QT_BEGIN_NAMESPACE
MainWindow::MainWindow(const QString &customFont)
{
setupUi(this);
pixelSize->setValue(QFontInfo(QFont()).pixelSize());
populateCharacterRanges();
{
weightCombo->addItem(QLatin1String("Light"), QVariant(int(QFont::Light)));
const int normalIdx = weightCombo->count();
weightCombo->addItem(QLatin1String("Normal"), QVariant(int(QFont::Normal)));
weightCombo->addItem(QLatin1String("DemiBold"), QVariant(int(QFont::DemiBold)));
weightCombo->addItem(QLatin1String("Bold"), QVariant(int(QFont::Bold)));
weightCombo->addItem(QLatin1String("Black"), QVariant(int(QFont::Black)));
weightCombo->setCurrentIndex(normalIdx);
}
QShortcut *sc = new QShortcut(Qt::ControlModifier + Qt::Key_A, this);
connect(sc, SIGNAL(activated()),
this, SLOT(on_selectAll_clicked()));
sc = new QShortcut(Qt::ControlModifier + Qt::Key_D, this);
connect(sc, SIGNAL(activated()),
this, SLOT(on_deselectAll_clicked()));
sc = new QShortcut(Qt::ControlModifier + Qt::Key_I, this);
connect(sc, SIGNAL(activated()),
this, SLOT(on_invertSelection_clicked()));
QCompleter *completer = new QCompleter(this);
completer->setModel(new QDirModel(this));
path->setCompleter(completer);
path->setText(QDir::currentPath());
completer = new QCompleter(this);
completer->setModel(new QDirModel(this));
sampleFile->setCompleter(completer);
charCount->setText(QString());
if (!customFont.isEmpty())
addCustomFont(customFont);
fontChanged();
connect(fontComboBox, SIGNAL(currentFontChanged(QFont)),
this, SLOT(fontChanged()));
connect(pixelSize, SIGNAL(valueChanged(int)),
this, SLOT(fontChanged()));
connect(italic, SIGNAL(stateChanged(int)),
this, SLOT(fontChanged()));
connect(weightCombo, SIGNAL(currentIndexChanged(int)),
this, SLOT(fontChanged()));
}
void MainWindow::on_actionAdd_Custom_Font_triggered()
{
QString fontFile = QFileDialog::getOpenFileName(this, tr("Add Custom Font"));
if (fontFile.isEmpty())
return;
addCustomFont(fontFile);
}
void MainWindow::on_selectAll_clicked()
{
for (int i = 0; i < characterRangeView->count(); ++i)
characterRangeView->item(i)->setCheckState(Qt::Checked);
}
void MainWindow::on_deselectAll_clicked()
{
for (int i = 0; i < characterRangeView->count(); ++i)
characterRangeView->item(i)->setCheckState(Qt::Unchecked);
}
void MainWindow::on_invertSelection_clicked()
{
for (int i = 0; i < characterRangeView->count(); ++i) {
QListWidgetItem *item = characterRangeView->item(i);
if (item->checkState() == Qt::Checked)
item->setCheckState(Qt::Unchecked);
else
item->setCheckState(Qt::Checked);
}
}
void MainWindow::fontChanged()
{
QFont f = preview->font();
f.setStyleStrategy(QFont::NoFontMerging);
f.setPixelSize(pixelSize->value());
f.setFamily(fontComboBox->currentFont().family());
f.setItalic(italic->isChecked());
f.setWeight(weightCombo->itemData(weightCombo->currentIndex()).toInt());
if (!preview->isModified()) {
QFontDatabase db;
QFontDatabase::WritingSystem ws = db.writingSystems(f.family()).value(0, QFontDatabase::Any);
QString sample = db.writingSystemSample(ws);
preview->setText(sample);
preview->setModified(false);
}
fileName->setText(QPF::fileNameForFont(f));
preview->setFont(f);
}
void MainWindow::on_browsePath_clicked()
{
QString dir = QFileDialog::getExistingDirectory(this, tr("Select Directory"));
if (!dir.isEmpty())
path->setText(dir);
}
void MainWindow::on_browseSampleFile_clicked()
{
QString dir = QFileDialog::getOpenFileName(this, tr("Select Sample File"));
if (!dir.isEmpty()) {
sampleFile->setText(dir);
on_sampleFile_editingFinished();
}
}
void MainWindow::on_generate_clicked()
{
QFile f(path->text() + QDir::separator() + fileName->text());
if (f.exists()) {
if (QMessageBox::warning(this, QString(),
tr("%1 already exists.\nDo you want to replace it?").arg(f.fileName()),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
!= QMessageBox::Yes) {
statusBar()->showMessage(tr("Pre-rendering aborted..."));
return;
}
}
QList<QPF::CharacterRange> ranges;
if (chooseFromSampleFile->isChecked()) {
ranges = sampleFileRanges;
} else if (chooseFromCodePoints->isChecked()) {
ranges.clear();
for (int i = 0; i < characterRangeView->count(); ++i) {
QListWidgetItem *item = characterRangeView->item(i);
if (item->checkState() != Qt::Checked)
continue;
QPF::CharacterRange range = qvariant_cast<QPF::CharacterRange>(item->data(Qt::UserRole));
ranges.append(range);
}
}
const int generationOptions = QPF::IncludeCMap | QPF::RenderGlyphs;
QByteArray qpf = QPF::generate(preview->font(), generationOptions, ranges);
f.open(QIODevice::WriteOnly | QIODevice::Truncate);
f.write(qpf);
f.close();
statusBar()->showMessage(tr("Font successfully pre-rendered to %1").arg(fileName->text()));
}
void MainWindow::on_sampleFile_editingFinished()
{
sampleFileRanges.clear();
QFile f(sampleFile->text());
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
sampleFileRanges.append(QPF::CharacterRange()); // default = all
return;
}
QTextStream stream(&f);
stream.setCodec(QTextCodec::codecForName("utf-8"));
stream.setAutoDetectUnicode(true);
QString text = stream.readAll();
QSet<QChar> coverage;
for (int i = 0; i < text.length(); ++i)
coverage.insert(text.at(i));
QList<QChar> sortedCoverage = QList<QChar>::fromSet(coverage);
qSort(sortedCoverage);
// play simple :)
foreach (QChar ch, sortedCoverage) {
QPF::CharacterRange r;
r.start = ch.unicode();
r.end = r.start;
sampleFileRanges.append(r);
}
charCount->setText(tr("(%1 unique characters found)").arg(sortedCoverage.count()));
}
void MainWindow::populateCharacterRanges()
{
QFile f(":/Blocks.txt");
if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QRegExp rangeExpr("([0-9a-f]+)\\.\\.([0-9a-f]+); (.+)");
rangeExpr.setCaseSensitivity(Qt::CaseInsensitive);
QString ellipsis(QChar(0x2026));
if (!characterRangeView->fontMetrics().inFont(ellipsis.at(0)))
ellipsis = QLatin1String("...");
while (!f.atEnd()) {
QString line = QString::fromAscii(f.readLine());
if (line.endsWith(QLatin1Char('\n')))
line.chop(1);
if (line.endsWith(QLatin1Char('\r')))
line.chop(1);
line = line.trimmed();
if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
continue;
if (!rangeExpr.exactMatch(line) || rangeExpr.captureCount() != 3)
continue;
QPF::CharacterRange range;
bool ok = false;
range.start = rangeExpr.cap(1).toUInt(&ok, /*base*/16);
if (!ok)
continue;
range.end = rangeExpr.cap(2).toUInt(&ok, /*base*/16);
if (!ok)
continue;
if (range.start >= 0xffff || range.end >= 0xffff)
continue;
QString description = rangeExpr.cap(3);
QListWidgetItem *item = new QListWidgetItem(characterRangeView);
QString text = description;
text.append(QLatin1String(" ("));
text.append(rangeExpr.cap(1));
text.append(ellipsis);
text.append(rangeExpr.cap(2));
text.append(QLatin1String(")"));
item->setText(text);
item->setCheckState(Qt::Checked);
item->setData(Qt::UserRole, QVariant::fromValue(range));
}
}
void MainWindow::addCustomFont(const QString &fontFile)
{
int id = QFontDatabase::addApplicationFont(fontFile);
if (id < 0) {
QMessageBox::warning(this, tr("Error Adding Custom Font"),
tr("The custom font %s could not be loaded.").arg(fontFile));
return;
}
const QStringList families = QFontDatabase::applicationFontFamilies(id);
if (families.isEmpty()) {
QMessageBox::warning(this, tr("Error Adding Custom Font"),
tr("The custom font %s provides no font families.").arg(fontFile));
return;
}
QFont f(families.first());
fontComboBox->setCurrentFont(f);
}
QT_END_NAMESPACE

80
util/makeqpf/mainwindow.h Normal file
View file

@ -0,0 +1,80 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "ui_mainwindow.h"
#include "qpf2.h"
QT_BEGIN_NAMESPACE
class QListWidgetItem;
class MainWindow : public QMainWindow, Ui::MainWindow
{
Q_OBJECT
public:
MainWindow(const QString &customFont);
private Q_SLOTS:
void on_actionAdd_Custom_Font_triggered();
void on_selectAll_clicked();
void on_deselectAll_clicked();
void on_invertSelection_clicked();
void fontChanged();
void on_browsePath_clicked();
void on_browseSampleFile_clicked();
void on_generate_clicked();
void on_sampleFile_editingFinished();
private:
void populateCharacterRanges();
void addCustomFont(const QString &fontFile);
private:
QList<QPF::CharacterRange> sampleFileRanges;
};
QT_END_NAMESPACE
#endif // MAINWINDOW_H

502
util/makeqpf/mainwindow.ui Normal file
View file

@ -0,0 +1,502 @@
<ui version="4.0" >
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>829</width>
<height>813</height>
</rect>
</property>
<property name="windowTitle" >
<string>MakeQPF</string>
</property>
<widget class="QWidget" name="centralwidget" >
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Font Properties</string>
</property>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label" >
<property name="text" >
<string>Family:</string>
</property>
</widget>
</item>
<item>
<widget class="QFontComboBox" name="fontComboBox" />
</item>
<item>
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Pixel Size:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="pixelSize" >
<property name="minimum" >
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7" >
<property name="text" >
<string>Weight:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="weightCombo" />
</item>
<item>
<widget class="QCheckBox" name="italic" >
<property name="text" >
<string>Italic</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2" >
<property name="title" >
<string>Glyph Coverage</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QRadioButton" name="chooseFromCodePoints" >
<property name="text" >
<string>Choose from Unicode Codepoints:</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QListWidget" name="characterRangeView" />
</item>
<item>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="selectAll" >
<property name="text" >
<string>Select &amp;All</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deselectAll" >
<property name="text" >
<string>&amp;Deselect All</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="invertSelection" >
<property name="text" >
<string>&amp;Invert Selection</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QRadioButton" name="chooseFromSampleFile" >
<property name="text" >
<string>Choose from Sample Text File (UTF-8 Encoded):</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_5" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Path:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="sampleFile" >
<property name="enabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="browseSampleFile" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Browse...</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="charCount" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3" >
<property name="title" >
<string>Preview</string>
</property>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLineEdit" name="preview" />
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4" >
<property name="title" >
<string>Output Options</string>
</property>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Path:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="path" />
</item>
<item>
<widget class="QPushButton" name="browsePath" >
<property name="text" >
<string>Browse...</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4" >
<property name="text" >
<string>Filename:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fileName" >
<property name="enabled" >
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="generate" >
<property name="text" >
<string>Generate Pre-Rendered Font...</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>829</width>
<height>29</height>
</rect>
</property>
<widget class="QMenu" name="menuFile" >
<property name="title" >
<string>File</string>
</property>
<addaction name="actionAdd_Custom_Font" />
<addaction name="separator" />
<addaction name="action_Exit" />
</widget>
<addaction name="menuFile" />
</widget>
<widget class="QStatusBar" name="statusbar" />
<action name="actionAdd_Custom_Font" >
<property name="text" >
<string>&amp;Add Custom Font...</string>
</property>
</action>
<action name="action_Exit" >
<property name="text" >
<string>&amp;Exit</string>
</property>
</action>
</widget>
<resources/>
<connections>
<connection>
<sender>action_Exit</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel" >
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel" >
<x>383</x>
<y>215</y>
</hint>
</hints>
</connection>
<connection>
<sender>chooseFromCodePoints</sender>
<signal>toggled(bool)</signal>
<receiver>characterRangeView</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>183</x>
<y>144</y>
</hint>
<hint type="destinationlabel" >
<x>146</x>
<y>295</y>
</hint>
</hints>
</connection>
<connection>
<sender>chooseFromCodePoints</sender>
<signal>toggled(bool)</signal>
<receiver>selectAll</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>236</x>
<y>146</y>
</hint>
<hint type="destinationlabel" >
<x>46</x>
<y>508</y>
</hint>
</hints>
</connection>
<connection>
<sender>chooseFromCodePoints</sender>
<signal>toggled(bool)</signal>
<receiver>deselectAll</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>280</x>
<y>147</y>
</hint>
<hint type="destinationlabel" >
<x>158</x>
<y>502</y>
</hint>
</hints>
</connection>
<connection>
<sender>chooseFromCodePoints</sender>
<signal>toggled(bool)</signal>
<receiver>invertSelection</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>364</x>
<y>143</y>
</hint>
<hint type="destinationlabel" >
<x>281</x>
<y>509</y>
</hint>
</hints>
</connection>
<connection>
<sender>chooseFromSampleFile</sender>
<signal>toggled(bool)</signal>
<receiver>sampleFile</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>134</x>
<y>544</y>
</hint>
<hint type="destinationlabel" >
<x>64</x>
<y>569</y>
</hint>
</hints>
</connection>
<connection>
<sender>chooseFromSampleFile</sender>
<signal>toggled(bool)</signal>
<receiver>browseSampleFile</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>79</x>
<y>545</y>
</hint>
<hint type="destinationlabel" >
<x>710</x>
<y>582</y>
</hint>
</hints>
</connection>
<connection>
<sender>chooseFromSampleFile</sender>
<signal>toggled(bool)</signal>
<receiver>charCount</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>274</x>
<y>544</y>
</hint>
<hint type="destinationlabel" >
<x>790</x>
<y>569</y>
</hint>
</hints>
</connection>
<connection>
<sender>chooseFromSampleFile</sender>
<signal>toggled(bool)</signal>
<receiver>label_5</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>112</x>
<y>541</y>
</hint>
<hint type="destinationlabel" >
<x>37</x>
<y>579</y>
</hint>
</hints>
</connection>
</connections>
</ui>

20
util/makeqpf/makeqpf.pro Normal file
View file

@ -0,0 +1,20 @@
######################################################################
# Automatically generated by qmake (2.01a) Wed Nov 29 16:21:49 2006
######################################################################
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += . ../../src/3rdparty/harfbuzz/src
CONFIG += console
DESTDIR = ../../bin
target.path=$$[QT_INSTALL_BINS]
INSTALLS += target
# Input
HEADERS += qpf2.h mainwindow.h
SOURCES += main.cpp qpf2.cpp mainwindow.cpp
DEFINES += QT_NO_FREETYPE
FORMS += mainwindow.ui
RESOURCES += makeqpf.qrc

5
util/makeqpf/makeqpf.qrc Normal file
View file

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>Blocks.txt</file>
</qresource>
</RCC>

767
util/makeqpf/qpf2.cpp Normal file
View file

@ -0,0 +1,767 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qpf2.h"
#include <math.h>
#include <private/qfontengine_p.h>
#include <QFile>
#include <qendian.h>
QT_BEGIN_NAMESPACE
#include "../../src/gui/text/qpfutil.cpp"
int QPF::debugVerbosity = 0;
// ### copied from qfontdatabase.cpp
// see the Unicode subset bitfields in the MSDN docs
static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
// Any,
{ 127, 127 },
// Latin,
{ 0, 127 },
// Greek,
{ 7, 127 },
// Cyrillic,
{ 9, 127 },
// Armenian,
{ 10, 127 },
// Hebrew,
{ 11, 127 },
// Arabic,
{ 13, 127 },
// Syriac,
{ 71, 127 },
//Thaana,
{ 72, 127 },
//Devanagari,
{ 15, 127 },
//Bengali,
{ 16, 127 },
//Gurmukhi,
{ 17, 127 },
//Gujarati,
{ 18, 127 },
//Oriya,
{ 19, 127 },
//Tamil,
{ 20, 127 },
//Telugu,
{ 21, 127 },
//Kannada,
{ 22, 127 },
//Malayalam,
{ 23, 127 },
//Sinhala,
{ 73, 127 },
//Thai,
{ 24, 127 },
//Lao,
{ 25, 127 },
//Tibetan,
{ 70, 127 },
//Myanmar,
{ 74, 127 },
// Georgian,
{ 26, 127 },
// Khmer,
{ 80, 127 },
// SimplifiedChinese,
{ 126, 127 },
// TraditionalChinese,
{ 126, 127 },
// Japanese,
{ 126, 127 },
// Korean,
{ 56, 127 },
// Vietnamese,
{ 0, 127 }, // same as latin1
// Other,
{ 126, 127 }
};
#define SimplifiedChineseCsbBit 18
#define TraditionalChineseCsbBit 20
#define JapaneseCsbBit 17
#define KoreanCsbBit 21
static QList<QFontDatabase::WritingSystem> determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
{
QList<QFontDatabase::WritingSystem> writingSystems;
bool hasScript = false;
int i;
for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
int bit = requiredUnicodeBits[i][0];
int index = bit/32;
int flag = 1 << (bit&31);
if (bit != 126 && unicodeRange[index] & flag) {
bit = requiredUnicodeBits[i][1];
index = bit/32;
flag = 1 << (bit&31);
if (bit == 127 || unicodeRange[index] & flag) {
writingSystems.append(QFontDatabase::WritingSystem(i));
hasScript = true;
// qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
}
}
}
if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
writingSystems.append(QFontDatabase::SimplifiedChinese);
hasScript = true;
//qDebug("font %s supports Simplified Chinese", familyName.latin1());
}
if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
writingSystems.append(QFontDatabase::TraditionalChinese);
hasScript = true;
//qDebug("font %s supports Traditional Chinese", familyName.latin1());
}
if(codePageRange[0] & (1 << JapaneseCsbBit)) {
writingSystems.append(QFontDatabase::Japanese);
hasScript = true;
//qDebug("font %s supports Japanese", familyName.latin1());
}
if(codePageRange[0] & (1 << KoreanCsbBit)) {
writingSystems.append(QFontDatabase::Korean);
hasScript = true;
//qDebug("font %s supports Korean", familyName.latin1());
}
if (!hasScript)
writingSystems.append(QFontDatabase::Symbol);
return writingSystems;
}
static QByteArray getWritingSystems(QFontEngine *fontEngine)
{
QByteArray os2Table = fontEngine->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
if (os2Table.isEmpty())
return QByteArray();
const uchar *data = reinterpret_cast<const uchar *>(os2Table.constData());
quint32 unicodeRange[4] = {
qFromBigEndian<quint32>(data + 42),
qFromBigEndian<quint32>(data + 46),
qFromBigEndian<quint32>(data + 50),
qFromBigEndian<quint32>(data + 54)
};
quint32 codePageRange[2] = { qFromBigEndian<quint32>(data + 78), qFromBigEndian<quint32>(data + 82) };
QList<QFontDatabase::WritingSystem> systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
QByteArray bitField((QFontDatabase::WritingSystemsCount + 7) / 8, 0);
for (int i = 0; i < systems.count(); ++i) {
int bitPos = systems.at(i);
bitField[bitPos / 8] = bitField.at(bitPos / 8) | (1 << (bitPos % 8));
}
return bitField;
}
static QString stringify(const QByteArray &bits)
{
QString result;
for (int i = 0; i < bits.count(); ++i) {
uchar currentByte = bits.at(i);
for (int j = 0; j < 8; ++j) {
if (currentByte & 1)
result += '1';
else
result += '0';
currentByte >>= 1;
}
}
return result;
}
static void dumpWritingSystems(const QByteArray &bits)
{
QStringList writingSystems;
QString bitString = stringify(bits);
for (int i = 0; i < qMin(int(QFontDatabase::WritingSystemsCount), bitString.length()); ++i) {
if (bitString.at(i) == QLatin1Char('1'))
writingSystems << QFontDatabase::writingSystemName(QFontDatabase::WritingSystem(i));
}
qDebug() << "Supported writing systems:" << writingSystems;
}
static const char *headerTagNames[QFontEngineQPF::NumTags] = {
"FontName",
"FileName",
"FileIndex",
"FontRevision",
"FreeText",
"Ascent",
"Descent",
"Leading",
"XHeight",
"AverageCharWidth",
"MaxCharWidth",
"LineThickness",
"MinLeftBearing",
"MinRightBearing",
"UnderlinePosition",
"GlyphFormat",
"PixelSize",
"Weight",
"Style",
"EndOfHeader",
"WritingSystems"
};
QString QPF::fileNameForFont(const QFont &f)
{
QString fileName = f.family().toLower() + "_" + QString::number(f.pixelSize())
+ "_" + QString::number(f.weight())
+ (f.italic() ? "_italic" : "")
+ ".qpf2";
fileName.replace(QLatin1Char(' '), QLatin1Char('_'));
return fileName;
}
QByteArray QPF::generate(const QFont &font, int options, const QList<CharacterRange> &ranges, QString *originalFontFile)
{
QTextEngine engine("Test", font);
engine.itemize();
engine.shape(0);
QFontEngine *fontEngine = engine.fontEngine(engine.layoutData->items[0]);
if (fontEngine->type() == QFontEngine::Multi)
fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(0);
if (originalFontFile)
*originalFontFile = QFile::decodeName(fontEngine->faceId().filename);
return generate(fontEngine, options, ranges);
}
QByteArray QPF::generate(QFontEngine *fontEngine, int options, const QList<CharacterRange> &ranges)
{
QPF font;
font.options = options;
font.addHeader(fontEngine);
if (options & IncludeCMap)
font.addCMap(fontEngine);
font.addGlyphs(fontEngine, ranges);
return font.qpf;
}
void QPF::addHeader(QFontEngine *fontEngine)
{
QFontEngineQPF::Header *header = reinterpret_cast<QFontEngineQPF::Header *>(addBytes(sizeof(QFontEngineQPF::Header)));
header->magic[0] = 'Q';
header->magic[1] = 'P';
header->magic[2] = 'F';
header->magic[3] = '2';
if (options & RenderGlyphs)
header->lock = 0xffffffff;
else
header->lock = 0;
header->majorVersion = QFontEngineQPF::CurrentMajorVersion;
header->minorVersion = QFontEngineQPF::CurrentMinorVersion;
header->dataSize = 0;
int oldSize = qpf.size();
addTaggedString(QFontEngineQPF::Tag_FontName, fontEngine->fontDef.family.toUtf8());
QFontEngine::FaceId face = fontEngine->faceId();
addTaggedString(QFontEngineQPF::Tag_FileName, face.filename);
addTaggedUInt32(QFontEngineQPF::Tag_FileIndex, face.index);
{
const QByteArray head = fontEngine->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));
const quint32 revision = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(head.constData()) + 4);
addTaggedUInt32(QFontEngineQPF::Tag_FontRevision, revision);
}
addTaggedQFixed(QFontEngineQPF::Tag_Ascent, fontEngine->ascent());
addTaggedQFixed(QFontEngineQPF::Tag_Descent, fontEngine->descent());
addTaggedQFixed(QFontEngineQPF::Tag_Leading, fontEngine->leading());
addTaggedQFixed(QFontEngineQPF::Tag_XHeight, fontEngine->xHeight());
addTaggedQFixed(QFontEngineQPF::Tag_AverageCharWidth, fontEngine->averageCharWidth());
addTaggedQFixed(QFontEngineQPF::Tag_MaxCharWidth, QFixed::fromReal(fontEngine->maxCharWidth()));
addTaggedQFixed(QFontEngineQPF::Tag_LineThickness, fontEngine->lineThickness());
addTaggedQFixed(QFontEngineQPF::Tag_MinLeftBearing, QFixed::fromReal(fontEngine->minLeftBearing()));
addTaggedQFixed(QFontEngineQPF::Tag_MinRightBearing, QFixed::fromReal(fontEngine->minRightBearing()));
addTaggedQFixed(QFontEngineQPF::Tag_UnderlinePosition, fontEngine->underlinePosition());
addTaggedUInt8(QFontEngineQPF::Tag_PixelSize, fontEngine->fontDef.pixelSize);
addTaggedUInt8(QFontEngineQPF::Tag_Weight, fontEngine->fontDef.weight);
addTaggedUInt8(QFontEngineQPF::Tag_Style, fontEngine->fontDef.style);
QByteArray writingSystemBitField = getWritingSystems(fontEngine);
if (!writingSystemBitField.isEmpty())
addTaggedString(QFontEngineQPF::Tag_WritingSystems, writingSystemBitField);
addTaggedUInt8(QFontEngineQPF::Tag_GlyphFormat, QFontEngineQPF::AlphamapGlyphs);
addTaggedString(QFontEngineQPF::Tag_EndOfHeader, QByteArray());
align4();
header = reinterpret_cast<QFontEngineQPF::Header *>(qpf.data());
header->dataSize = qToBigEndian<quint16>(qpf.size() - oldSize);
}
static uchar *appendBytes(QByteArray &array, int size)
{
int oldSize = array.size();
array.resize(array.size() + size);
return reinterpret_cast<uchar *>(array.data() + oldSize);
}
#define APPEND(type, value) \
qToBigEndian<type>(value, appendBytes(cmap, sizeof(type)))
struct CMapSegment
{
int start; // codepoints
int end;
int startGlyphIndex;
};
static QByteArray generateTrueTypeCMap(QFontEngine *fe)
{
QByteArray cmap;
const int glyphCount = fe->glyphCount();
if (!glyphCount)
return cmap;
// cmap header
APPEND(quint16, 0); // table version number
APPEND(quint16, 1); // number of tables
// encoding record
APPEND(quint16, 3); // platform-id
APPEND(quint16, 10); // encoding-id (ucs-4)
const int cmapOffset = cmap.size() + sizeof(quint32);
APPEND(quint32, cmapOffset); // offset to sub-table
APPEND(quint16, 4); // subtable format
const int cmapTableLengthOffset = cmap.size();
APPEND(quint16, 0); // length in bytes, will fill in later
APPEND(quint16, 0); // language field
QList<CMapSegment> segments;
CMapSegment currentSegment;
currentSegment.start = 0xffff;
currentSegment.end = 0;
currentSegment.startGlyphIndex = 0;
quint32 previousGlyphIndex = 0xfffffffe;
bool inSegment = false;
QGlyphLayoutArray<10> layout;
for (uint uc = 0; uc < 0x10000; ++uc) {
QChar ch(uc);
int nglyphs = 10;
bool validGlyph = fe->stringToCMap(&ch, 1, &layout, &nglyphs, /*flags*/ 0)
&& nglyphs == 1 && layout.glyphs[0];
// leaving a segment?
if (inSegment && (!validGlyph || layout.glyphs[0] != previousGlyphIndex + 1)) {
Q_ASSERT(currentSegment.start != 0xffff);
// store the current segment
currentSegment.end = uc - 1;
segments.append(currentSegment);
currentSegment.start = 0xffff;
inSegment = false;
}
// entering a new segment?
if (validGlyph && (!inSegment || layout.glyphs[0] != previousGlyphIndex + 1)) {
currentSegment.start = uc;
currentSegment.startGlyphIndex = layout.glyphs[0];
inSegment = true;
}
if (validGlyph)
previousGlyphIndex = layout.glyphs[0];
else
previousGlyphIndex = 0xfffffffe;
}
currentSegment.start = 0xffff;
currentSegment.end = 0xffff;
currentSegment.startGlyphIndex = 0;
segments.append(currentSegment);
if (QPF::debugVerbosity > 3)
qDebug() << "segments:" << segments.count();
Q_ASSERT(!inSegment);
const quint16 entrySelector = int(log2(segments.count()));
const quint16 searchRange = 2 * (1 << entrySelector);
const quint16 rangeShift = segments.count() * 2 - searchRange;
if (QPF::debugVerbosity > 3)
qDebug() << "entrySelector" << entrySelector << "searchRange" << searchRange
<< "rangeShift" << rangeShift;
APPEND(quint16, segments.count() * 2); // segCountX2
APPEND(quint16, searchRange);
APPEND(quint16, entrySelector);
APPEND(quint16, rangeShift);
// end character codes
for (int i = 0; i < segments.count(); ++i)
APPEND(quint16, segments.at(i).end);
APPEND(quint16, 0); // pad
// start character codes
for (int i = 0; i < segments.count(); ++i)
APPEND(quint16, segments.at(i).start);
// id deltas
for (int i = 0; i < segments.count(); ++i)
APPEND(quint16, segments.at(i).startGlyphIndex - segments.at(i).start);
// id range offsets
for (int i = 0; i < segments.count(); ++i)
APPEND(quint16, 0);
uchar *lengthPtr = reinterpret_cast<uchar *>(cmap.data()) + cmapTableLengthOffset;
qToBigEndian<quint16>(cmap.size() - cmapOffset, lengthPtr);
return cmap;
}
void QPF::addCMap(QFontEngine *fontEngine)
{
QByteArray cmapTable = fontEngine->getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
if (cmapTable.isEmpty())
cmapTable = generateTrueTypeCMap(fontEngine);
addBlock(QFontEngineQPF::CMapBlock, cmapTable);
}
void QPF::addGlyphs(QFontEngine *fe, const QList<CharacterRange> &ranges)
{
const quint16 glyphCount = fe->glyphCount();
QByteArray gmap;
gmap.resize(glyphCount * sizeof(quint32));
gmap.fill(char(0xff));
//qDebug() << "glyphCount" << glyphCount;
QByteArray glyphs;
if (options & RenderGlyphs) {
// this is only a rough estimation
glyphs.reserve(glyphCount
* (sizeof(QFontEngineQPF::Glyph)
+ qRound(fe->maxCharWidth() * (fe->ascent() + fe->descent()).toReal())));
QGlyphLayoutArray<10> layout;
foreach (CharacterRange range, ranges) {
if (debugVerbosity > 2)
qDebug() << "rendering range from" << range.start << "to" << range.end;
for (uint uc = range.start; uc <= range.end; ++uc) {
QChar ch(uc);
int nglyphs = 10;
if (!fe->stringToCMap(&ch, 1, &layout, &nglyphs, /*flags*/ 0))
continue;
if (nglyphs != 1)
continue;
const quint32 glyphIndex = layout.glyphs[0];
if (!glyphIndex)
continue;
Q_ASSERT(glyphIndex < glyphCount);
QImage img = fe->alphaMapForGlyph(glyphIndex).convertToFormat(QImage::Format_Indexed8);
glyph_metrics_t metrics = fe->boundingBox(glyphIndex);
const quint32 oldSize = glyphs.size();
glyphs.resize(glyphs.size() + sizeof(QFontEngineQPF::Glyph) + img.byteCount());
uchar *data = reinterpret_cast<uchar *>(glyphs.data() + oldSize);
uchar *gmapPtr = reinterpret_cast<uchar *>(gmap.data() + glyphIndex * sizeof(quint32));
qToBigEndian(oldSize, gmapPtr);
QFontEngineQPF::Glyph *glyph = reinterpret_cast<QFontEngineQPF::Glyph *>(data);
glyph->width = img.width();
glyph->height = img.height();
glyph->bytesPerLine = img.bytesPerLine();
glyph->x = qRound(metrics.x);
glyph->y = qRound(metrics.y);
glyph->advance = qRound(metrics.xoff);
data += sizeof(QFontEngineQPF::Glyph);
if (debugVerbosity && uc >= 'A' && uc <= 'z' || debugVerbosity > 1) {
qDebug() << "adding glyph with index" << glyphIndex << " uc =" << char(uc) << ":\n"
<< " glyph->x =" << glyph->x << "rounded from" << metrics.x << "\n"
<< " glyph->y =" << glyph->y << "rounded from" << metrics.y << "\n"
<< " width =" << glyph->width << "height =" << glyph->height
<< " advance =" << glyph->advance << "rounded from" << metrics.xoff
;
}
memcpy(data, img.bits(), img.byteCount());
}
}
}
addBlock(QFontEngineQPF::GMapBlock, gmap);
addBlock(QFontEngineQPF::GlyphBlock, glyphs);
}
void QPF::addBlock(QFontEngineQPF::BlockTag tag, const QByteArray &blockData)
{
addUInt16(tag);
addUInt16(0); // padding
const int padSize = ((blockData.size() + 3) / 4) * 4 - blockData.size();
addUInt32(blockData.size() + padSize);
addByteArray(blockData);
for (int i = 0; i < padSize; ++i)
addUInt8(0);
}
#define ADD_TAGGED_DATA(tag, qtype, type, value) \
addUInt16(tag); \
addUInt16(sizeof(qtype)); \
add##type(value)
void QPF::addTaggedString(QFontEngineQPF::HeaderTag tag, const QByteArray &string)
{
addUInt16(tag);
addUInt16(string.length());
addByteArray(string);
}
void QPF::addTaggedQFixed(QFontEngineQPF::HeaderTag tag, QFixed value)
{
ADD_TAGGED_DATA(tag, quint32, UInt32, value.value());
}
void QPF::addTaggedUInt8(QFontEngineQPF::HeaderTag tag, quint8 value)
{
ADD_TAGGED_DATA(tag, quint8, UInt8, value);
}
void QPF::addTaggedInt8(QFontEngineQPF::HeaderTag tag, qint8 value)
{
ADD_TAGGED_DATA(tag, qint8, Int8, value);
}
void QPF::addTaggedUInt16(QFontEngineQPF::HeaderTag tag, quint16 value)
{
ADD_TAGGED_DATA(tag, quint16, UInt16, value);
}
void QPF::addTaggedUInt32(QFontEngineQPF::HeaderTag tag, quint32 value)
{
ADD_TAGGED_DATA(tag, quint32, UInt32, value);
}
void QPF::dump(const QByteArray &qpf)
{
QPF font;
font.qpf = qpf;
const uchar *data = reinterpret_cast<const uchar *>(qpf.constData());
const uchar *endPtr = reinterpret_cast<const uchar *>(qpf.constData() + qpf.size());
data = font.dumpHeader(data);
const quint32 *gmap = 0;
quint32 glyphCount = 0;
while (data < endPtr) {
const QFontEngineQPF::Block *block = reinterpret_cast<const QFontEngineQPF::Block *>(data);
quint32 tag = qFromBigEndian(block->tag);
quint32 blockSize = qFromBigEndian(block->dataSize);
qDebug() << "Block: Tag =" << qFromBigEndian(block->tag) << "; Size =" << blockSize << "; Offset =" << hex << data - reinterpret_cast<const uchar *>(qpf.constData());
data += sizeof(QFontEngineQPF::Block);
if (debugVerbosity) {
if (tag == QFontEngineQPF::GMapBlock) {
gmap = reinterpret_cast<const quint32 *>(data);
glyphCount = blockSize / 4;
font.dumpGMapBlock(gmap, glyphCount);
} else if (tag == QFontEngineQPF::GlyphBlock
&& gmap && debugVerbosity > 1) {
font.dumpGlyphBlock(gmap, glyphCount, data, data + blockSize);
}
}
data += blockSize;
}
}
const uchar *QPF::dumpHeader(const uchar *data)
{
const QFontEngineQPF::Header *header = reinterpret_cast<const QFontEngineQPF::Header *>(data);
qDebug() << "Header:";
qDebug() << "magic ="
<< header->magic[0]
<< header->magic[1]
<< header->magic[2]
<< header->magic[3];
qDebug() << "lock =" << qFromBigEndian(header->lock);
qDebug() << "majorVersion =" << header->majorVersion;
qDebug() << "minorVersion =" << header->minorVersion;
qDebug() << "dataSize =" << qFromBigEndian(header->dataSize);
data += sizeof(QFontEngineQPF::Header);
const uchar *endPtr = data + qFromBigEndian(header->dataSize);
while (data && data < endPtr) {
data = dumpHeaderTag(data);
}
return endPtr;
}
const uchar *QPF::dumpHeaderTag(const uchar *data)
{
const QFontEngineQPF::Tag *tagPtr = reinterpret_cast<const QFontEngineQPF::Tag *>(data);
quint16 tag = qFromBigEndian(tagPtr->tag);
quint16 size = qFromBigEndian(tagPtr->size);
qDebug() << "Tag =" << tag << headerTagNames[tag];
qDebug() << "Size =" << size;
if (tag == QFontEngineQPF::Tag_EndOfHeader)
return 0;
data += sizeof(QFontEngineQPF::Tag);
Q_ASSERT(tag < QFontEngineQPF::NumTags);
switch (tagTypes[tag]) {
case QFontEngineQPF::StringType:
qDebug() << "Payload =" << QString::fromUtf8(QByteArray(reinterpret_cast<const char *>(data), size));
break;
case QFontEngineQPF::FixedType:
Q_ASSERT(size == sizeof(quint32));
qDebug() << "Payload =" << QFixed::fromFixed(qFromBigEndian<quint32>(data)).toReal();
break;
case QFontEngineQPF::UInt8Type:
Q_ASSERT(size == sizeof(quint8));
qDebug() << "Payload =" << *data;
break;
case QFontEngineQPF::UInt32Type:
Q_ASSERT(size == sizeof(quint32));
qDebug() << "Payload =" << qFromBigEndian<quint32>(data);
break;
case QFontEngineQPF::BitFieldType: {
QByteArray bits(reinterpret_cast<const char *>(data), size);
qDebug() << "Payload =" << stringify(bits);
if (QPF::debugVerbosity > 2 && tag == QFontEngineQPF::Tag_WritingSystems)
dumpWritingSystems(bits);
} break;
}
data += size;
return data;
}
void QPF::dumpGMapBlock(const quint32 *gmap, int glyphCount)
{
qDebug() << "glyphCount =" << glyphCount;
int renderedGlyphs = 0;
for (int i = 0; i < glyphCount; ++i) {
if (gmap[i] != 0xffffffff) {
const quint32 glyphPos = qFromBigEndian(gmap[i]);
qDebug("gmap[%d] = 0x%x / %u", i, glyphPos, glyphPos);
++renderedGlyphs;
}
}
qDebug() << "Glyphs rendered:" << renderedGlyphs << "; Glyphs missing from the font:" << glyphCount - renderedGlyphs;
}
void QPF::dumpGlyphBlock(const quint32 *gmap, int glyphCount, const uchar *data, const uchar *endPtr)
{
// glyphPos -> glyphIndex
QMap<quint32, quint32> reverseGlyphMap;
for (int i = 0; i < glyphCount; ++i) {
if (gmap[i] == 0xffffffff)
continue;
const quint32 glyphPos = qFromBigEndian(gmap[i]);
reverseGlyphMap[glyphPos] = i;
}
const uchar *glyphBlockBegin = data;
while (data < endPtr) {
const QFontEngineQPF::Glyph *g = reinterpret_cast<const QFontEngineQPF::Glyph *>(data);
const quint64 glyphOffset = data - glyphBlockBegin;
const quint32 glyphIndex = reverseGlyphMap.value(glyphOffset, 0xffffffff);
if (glyphIndex == 0xffffffff)
qDebug() << "############: Glyph present in glyph block is not listed in glyph map!";
qDebug("glyph at offset 0x%x glyphIndex = %u", quint32(glyphOffset), glyphIndex);
qDebug() << " width =" << g->width << "height =" << g->height << "x =" << g->x << "y =" << g->y;
qDebug() << " advance =" << g->advance << "bytesPerLine =" << g->bytesPerLine;
data += sizeof(*g);
if (glyphIndex == 0xffffffff || debugVerbosity > 4) {
dumpGlyph(data, g);
}
data += g->height * g->bytesPerLine;
}
}
void QPF::dumpGlyph(const uchar *data, const QFontEngineQPF::Glyph *glyph)
{
fprintf(stderr, "---- glyph data:\n");
const char *alphas = " .o#";
for (int y = 0; y < glyph->height; ++y) {
for (int x = 0; x < glyph->width; ++x) {
const uchar value = data[y * glyph->bytesPerLine + x];
fprintf(stderr, "%c", alphas[value >> 6]);
}
fprintf(stderr, "\n");
}
fprintf(stderr, "----\n");
}
QT_END_NAMESPACE

119
util/makeqpf/qpf2.h Normal file
View file

@ -0,0 +1,119 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPF2_H
#define QPF2_H
#include <private/qfontengine_qpf_p.h>
#include <qmetatype.h>
QT_BEGIN_NAMESPACE
class QFontEngine;
class QPF
{
public:
static int debugVerbosity;
enum GenerationOption {
IncludeCMap = 0x1,
RenderGlyphs = 0x2
};
struct CharacterRange
{
inline CharacterRange() : start(0), end(0xffff) {}
uint start;
uint end;
};
static QString fileNameForFont(const QFont &f);
static QByteArray generate(const QFont &font, int options,
const QList<CharacterRange> &ranges,
QString *originalFontFile = 0);
static QByteArray generate(QFontEngine *fontEngine, int options, const QList<CharacterRange> &ranges);
void addHeader(QFontEngine *fontEngine);
void addCMap(QFontEngine *fontEngine);
void addGlyphs(QFontEngine *fontEngine, const QList<CharacterRange> &ranges);
void addBlock(QFontEngineQPF::BlockTag tag, const QByteArray &data);
void addTaggedString(QFontEngineQPF::HeaderTag tag, const QByteArray &string);
void addTaggedQFixed(QFontEngineQPF::HeaderTag tag, QFixed value);
void addTaggedUInt8(QFontEngineQPF::HeaderTag tag, quint8 value);
void addTaggedInt8(QFontEngineQPF::HeaderTag tag, qint8 value);
void addTaggedUInt16(QFontEngineQPF::HeaderTag tag, quint16 value);
void addTaggedUInt32(QFontEngineQPF::HeaderTag tag, quint32 value);
static void dump(const QByteArray &qpf);
const uchar *dumpHeader(const uchar *data);
const uchar *dumpHeaderTag(const uchar *data);
void dumpGMapBlock(const quint32 *gmap, int glyphCount);
void dumpGlyphBlock(const quint32 *gmap, int glyphCount, const uchar *data, const uchar *endPtr);
void dumpGlyph(const uchar *data, const QFontEngineQPF::Glyph *glyph);
void addUInt16(quint16 value) { qToBigEndian(value, addBytes(sizeof(value))); }
void addUInt32(quint32 value) { qToBigEndian(value, addBytes(sizeof(value))); }
void addUInt8(quint8 value) { *addBytes(sizeof(value)) = value; }
void addInt8(qint8 value) { *addBytes(sizeof(value)) = quint8(value); }
void addByteArray(const QByteArray &string) {
uchar *data = addBytes(string.length());
qMemCopy(data, string.constData(), string.length());
}
void align4() { while (qpf.size() & 3) { addUInt8('\0'); } }
uchar *addBytes(int size) {
const int oldSize = qpf.size();
qpf.resize(qpf.size() + size);
return reinterpret_cast<uchar *>(qpf.data() + oldSize);
}
QByteArray qpf;
int options;
};
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QPF::CharacterRange)
#endif // QPF2_H